How to use lines method in ts-auto-mock

Best JavaScript code snippet using ts-auto-mock

linesLayout.test.ts

Source:linesLayout.test.ts Github

copy

Full Screen

1/*---------------------------------------------------------------------------------------------2 * Copyright (c) Microsoft Corporation. All rights reserved.3 * Licensed under the MIT License. See License.txt in the project root for license information.4 *--------------------------------------------------------------------------------------------*/5import * as assert from 'assert';6import { LinesLayout, EditorWhitespace } from 'vs/editor/common/viewLayout/linesLayout';7suite('Editor ViewLayout - LinesLayout', () => {8 function insertWhitespace(linesLayout: LinesLayout, afterLineNumber: number, ordinal: number, heightInPx: number, minWidth: number): string {9 let id: string;10 linesLayout.changeWhitespace((accessor) => {11 id = accessor.insertWhitespace(afterLineNumber, ordinal, heightInPx, minWidth);12 });13 return id!;14 }15 function changeOneWhitespace(linesLayout: LinesLayout, id: string, newAfterLineNumber: number, newHeight: number): void {16 linesLayout.changeWhitespace((accessor) => {17 accessor.changeOneWhitespace(id, newAfterLineNumber, newHeight);18 });19 }20 function removeWhitespace(linesLayout: LinesLayout, id: string): void {21 linesLayout.changeWhitespace((accessor) => {22 accessor.removeWhitespace(id);23 });24 }25 test('LinesLayout 1', () => {26 // Start off with 10 lines27 let linesLayout = new LinesLayout(10, 10, 0, 0);28 // lines: [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]29 // whitespace: -30 assert.equal(linesLayout.getLinesTotalHeight(), 100);31 assert.equal(linesLayout.getVerticalOffsetForLineNumber(1), 0);32 assert.equal(linesLayout.getVerticalOffsetForLineNumber(2), 10);33 assert.equal(linesLayout.getVerticalOffsetForLineNumber(3), 20);34 assert.equal(linesLayout.getVerticalOffsetForLineNumber(4), 30);35 assert.equal(linesLayout.getVerticalOffsetForLineNumber(5), 40);36 assert.equal(linesLayout.getVerticalOffsetForLineNumber(6), 50);37 assert.equal(linesLayout.getVerticalOffsetForLineNumber(7), 60);38 assert.equal(linesLayout.getVerticalOffsetForLineNumber(8), 70);39 assert.equal(linesLayout.getVerticalOffsetForLineNumber(9), 80);40 assert.equal(linesLayout.getVerticalOffsetForLineNumber(10), 90);41 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(0), 1);42 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(1), 1);43 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(5), 1);44 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(9), 1);45 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(10), 2);46 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(11), 2);47 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(15), 2);48 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(19), 2);49 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(20), 3);50 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(21), 3);51 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(29), 3);52 // Add whitespace of height 5px after 2nd line53 insertWhitespace(linesLayout, 2, 0, 5, 0);54 // lines: [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]55 // whitespace: a(2,5)56 assert.equal(linesLayout.getLinesTotalHeight(), 105);57 assert.equal(linesLayout.getVerticalOffsetForLineNumber(1), 0);58 assert.equal(linesLayout.getVerticalOffsetForLineNumber(2), 10);59 assert.equal(linesLayout.getVerticalOffsetForLineNumber(3), 25);60 assert.equal(linesLayout.getVerticalOffsetForLineNumber(4), 35);61 assert.equal(linesLayout.getVerticalOffsetForLineNumber(5), 45);62 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(0), 1);63 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(1), 1);64 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(9), 1);65 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(10), 2);66 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(20), 3);67 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(21), 3);68 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(24), 3);69 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(25), 3);70 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(35), 4);71 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(45), 5);72 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(104), 10);73 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(105), 10);74 // Add two more whitespaces of height 5px75 insertWhitespace(linesLayout, 3, 0, 5, 0);76 insertWhitespace(linesLayout, 4, 0, 5, 0);77 // lines: [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]78 // whitespace: a(2,5), b(3, 5), c(4, 5)79 assert.equal(linesLayout.getLinesTotalHeight(), 115);80 assert.equal(linesLayout.getVerticalOffsetForLineNumber(1), 0);81 assert.equal(linesLayout.getVerticalOffsetForLineNumber(2), 10);82 assert.equal(linesLayout.getVerticalOffsetForLineNumber(3), 25);83 assert.equal(linesLayout.getVerticalOffsetForLineNumber(4), 40);84 assert.equal(linesLayout.getVerticalOffsetForLineNumber(5), 55);85 assert.equal(linesLayout.getVerticalOffsetForLineNumber(6), 65);86 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(0), 1);87 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(1), 1);88 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(9), 1);89 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(10), 2);90 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(19), 2);91 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(20), 3);92 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(34), 3);93 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(35), 4);94 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(49), 4);95 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(50), 5);96 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(64), 5);97 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(65), 6);98 assert.equal(linesLayout.getVerticalOffsetForWhitespaceIndex(0), 20); // 20 -> 2599 assert.equal(linesLayout.getVerticalOffsetForWhitespaceIndex(1), 35); // 35 -> 40100 assert.equal(linesLayout.getVerticalOffsetForWhitespaceIndex(2), 50);101 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(0), 0);102 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(19), 0);103 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(20), 0);104 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(21), 0);105 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(22), 0);106 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(23), 0);107 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(24), 0);108 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(25), 1);109 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(26), 1);110 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(34), 1);111 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(35), 1);112 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(36), 1);113 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(39), 1);114 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(40), 2);115 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(41), 2);116 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(49), 2);117 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(50), 2);118 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(51), 2);119 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(54), 2);120 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(55), -1);121 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(1000), -1);122 });123 test('LinesLayout 2', () => {124 // Start off with 10 lines and one whitespace after line 2, of height 5125 let linesLayout = new LinesLayout(10, 1, 0, 0);126 let a = insertWhitespace(linesLayout, 2, 0, 5, 0);127 // 10 lines128 // whitespace: - a(2,5)129 assert.equal(linesLayout.getLinesTotalHeight(), 15);130 assert.equal(linesLayout.getVerticalOffsetForLineNumber(1), 0);131 assert.equal(linesLayout.getVerticalOffsetForLineNumber(2), 1);132 assert.equal(linesLayout.getVerticalOffsetForLineNumber(3), 7);133 assert.equal(linesLayout.getVerticalOffsetForLineNumber(4), 8);134 assert.equal(linesLayout.getVerticalOffsetForLineNumber(5), 9);135 assert.equal(linesLayout.getVerticalOffsetForLineNumber(6), 10);136 assert.equal(linesLayout.getVerticalOffsetForLineNumber(7), 11);137 assert.equal(linesLayout.getVerticalOffsetForLineNumber(8), 12);138 assert.equal(linesLayout.getVerticalOffsetForLineNumber(9), 13);139 assert.equal(linesLayout.getVerticalOffsetForLineNumber(10), 14);140 // Change whitespace height141 // 10 lines142 // whitespace: - a(2,10)143 changeOneWhitespace(linesLayout, a, 2, 10);144 assert.equal(linesLayout.getLinesTotalHeight(), 20);145 assert.equal(linesLayout.getVerticalOffsetForLineNumber(1), 0);146 assert.equal(linesLayout.getVerticalOffsetForLineNumber(2), 1);147 assert.equal(linesLayout.getVerticalOffsetForLineNumber(3), 12);148 assert.equal(linesLayout.getVerticalOffsetForLineNumber(4), 13);149 assert.equal(linesLayout.getVerticalOffsetForLineNumber(5), 14);150 assert.equal(linesLayout.getVerticalOffsetForLineNumber(6), 15);151 assert.equal(linesLayout.getVerticalOffsetForLineNumber(7), 16);152 assert.equal(linesLayout.getVerticalOffsetForLineNumber(8), 17);153 assert.equal(linesLayout.getVerticalOffsetForLineNumber(9), 18);154 assert.equal(linesLayout.getVerticalOffsetForLineNumber(10), 19);155 // Change whitespace position156 // 10 lines157 // whitespace: - a(5,10)158 changeOneWhitespace(linesLayout, a, 5, 10);159 assert.equal(linesLayout.getLinesTotalHeight(), 20);160 assert.equal(linesLayout.getVerticalOffsetForLineNumber(1), 0);161 assert.equal(linesLayout.getVerticalOffsetForLineNumber(2), 1);162 assert.equal(linesLayout.getVerticalOffsetForLineNumber(3), 2);163 assert.equal(linesLayout.getVerticalOffsetForLineNumber(4), 3);164 assert.equal(linesLayout.getVerticalOffsetForLineNumber(5), 4);165 assert.equal(linesLayout.getVerticalOffsetForLineNumber(6), 15);166 assert.equal(linesLayout.getVerticalOffsetForLineNumber(7), 16);167 assert.equal(linesLayout.getVerticalOffsetForLineNumber(8), 17);168 assert.equal(linesLayout.getVerticalOffsetForLineNumber(9), 18);169 assert.equal(linesLayout.getVerticalOffsetForLineNumber(10), 19);170 // Pretend that lines 5 and 6 were deleted171 // 8 lines172 // whitespace: - a(4,10)173 linesLayout.onLinesDeleted(5, 6);174 assert.equal(linesLayout.getLinesTotalHeight(), 18);175 assert.equal(linesLayout.getVerticalOffsetForLineNumber(1), 0);176 assert.equal(linesLayout.getVerticalOffsetForLineNumber(2), 1);177 assert.equal(linesLayout.getVerticalOffsetForLineNumber(3), 2);178 assert.equal(linesLayout.getVerticalOffsetForLineNumber(4), 3);179 assert.equal(linesLayout.getVerticalOffsetForLineNumber(5), 14);180 assert.equal(linesLayout.getVerticalOffsetForLineNumber(6), 15);181 assert.equal(linesLayout.getVerticalOffsetForLineNumber(7), 16);182 assert.equal(linesLayout.getVerticalOffsetForLineNumber(8), 17);183 // Insert two lines at the beginning184 // 10 lines185 // whitespace: - a(6,10)186 linesLayout.onLinesInserted(1, 2);187 assert.equal(linesLayout.getLinesTotalHeight(), 20);188 assert.equal(linesLayout.getVerticalOffsetForLineNumber(1), 0);189 assert.equal(linesLayout.getVerticalOffsetForLineNumber(2), 1);190 assert.equal(linesLayout.getVerticalOffsetForLineNumber(3), 2);191 assert.equal(linesLayout.getVerticalOffsetForLineNumber(4), 3);192 assert.equal(linesLayout.getVerticalOffsetForLineNumber(5), 4);193 assert.equal(linesLayout.getVerticalOffsetForLineNumber(6), 5);194 assert.equal(linesLayout.getVerticalOffsetForLineNumber(7), 16);195 assert.equal(linesLayout.getVerticalOffsetForLineNumber(8), 17);196 assert.equal(linesLayout.getVerticalOffsetForLineNumber(9), 18);197 assert.equal(linesLayout.getVerticalOffsetForLineNumber(10), 19);198 // Remove whitespace199 // 10 lines200 removeWhitespace(linesLayout, a);201 assert.equal(linesLayout.getLinesTotalHeight(), 10);202 assert.equal(linesLayout.getVerticalOffsetForLineNumber(1), 0);203 assert.equal(linesLayout.getVerticalOffsetForLineNumber(2), 1);204 assert.equal(linesLayout.getVerticalOffsetForLineNumber(3), 2);205 assert.equal(linesLayout.getVerticalOffsetForLineNumber(4), 3);206 assert.equal(linesLayout.getVerticalOffsetForLineNumber(5), 4);207 assert.equal(linesLayout.getVerticalOffsetForLineNumber(6), 5);208 assert.equal(linesLayout.getVerticalOffsetForLineNumber(7), 6);209 assert.equal(linesLayout.getVerticalOffsetForLineNumber(8), 7);210 assert.equal(linesLayout.getVerticalOffsetForLineNumber(9), 8);211 assert.equal(linesLayout.getVerticalOffsetForLineNumber(10), 9);212 });213 test('LinesLayout Padding', () => {214 // Start off with 10 lines215 let linesLayout = new LinesLayout(10, 10, 15, 20);216 // lines: [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]217 // whitespace: -218 assert.equal(linesLayout.getLinesTotalHeight(), 135);219 assert.equal(linesLayout.getVerticalOffsetForLineNumber(1), 15);220 assert.equal(linesLayout.getVerticalOffsetForLineNumber(2), 25);221 assert.equal(linesLayout.getVerticalOffsetForLineNumber(3), 35);222 assert.equal(linesLayout.getVerticalOffsetForLineNumber(4), 45);223 assert.equal(linesLayout.getVerticalOffsetForLineNumber(5), 55);224 assert.equal(linesLayout.getVerticalOffsetForLineNumber(6), 65);225 assert.equal(linesLayout.getVerticalOffsetForLineNumber(7), 75);226 assert.equal(linesLayout.getVerticalOffsetForLineNumber(8), 85);227 assert.equal(linesLayout.getVerticalOffsetForLineNumber(9), 95);228 assert.equal(linesLayout.getVerticalOffsetForLineNumber(10), 105);229 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(0), 1);230 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(10), 1);231 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(15), 1);232 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(24), 1);233 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(25), 2);234 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(34), 2);235 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(35), 3);236 // Add whitespace of height 5px after 2nd line237 insertWhitespace(linesLayout, 2, 0, 5, 0);238 // lines: [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]239 // whitespace: a(2,5)240 assert.equal(linesLayout.getLinesTotalHeight(), 140);241 assert.equal(linesLayout.getVerticalOffsetForLineNumber(1), 15);242 assert.equal(linesLayout.getVerticalOffsetForLineNumber(2), 25);243 assert.equal(linesLayout.getVerticalOffsetForLineNumber(3), 40);244 assert.equal(linesLayout.getVerticalOffsetForLineNumber(4), 50);245 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(0), 1);246 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(10), 1);247 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(25), 2);248 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(34), 2);249 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(35), 3);250 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(39), 3);251 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(40), 3);252 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(41), 3);253 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(49), 3);254 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(50), 4);255 // Add two more whitespaces of height 5px256 insertWhitespace(linesLayout, 3, 0, 5, 0);257 insertWhitespace(linesLayout, 4, 0, 5, 0);258 // lines: [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]259 // whitespace: a(2,5), b(3, 5), c(4, 5)260 assert.equal(linesLayout.getLinesTotalHeight(), 150);261 assert.equal(linesLayout.getVerticalOffsetForLineNumber(1), 15);262 assert.equal(linesLayout.getVerticalOffsetForLineNumber(2), 25);263 assert.equal(linesLayout.getVerticalOffsetForLineNumber(3), 40);264 assert.equal(linesLayout.getVerticalOffsetForLineNumber(4), 55);265 assert.equal(linesLayout.getVerticalOffsetForLineNumber(5), 70);266 assert.equal(linesLayout.getVerticalOffsetForLineNumber(6), 80);267 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(0), 1);268 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(15), 1);269 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(24), 1);270 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(30), 2);271 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(35), 3);272 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(39), 3);273 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(40), 3);274 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(49), 3);275 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(50), 4);276 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(54), 4);277 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(55), 4);278 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(64), 4);279 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(65), 5);280 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(69), 5);281 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(70), 5);282 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(80), 6);283 assert.equal(linesLayout.getVerticalOffsetForWhitespaceIndex(0), 35); // 35 -> 40284 assert.equal(linesLayout.getVerticalOffsetForWhitespaceIndex(1), 50); // 50 -> 55285 assert.equal(linesLayout.getVerticalOffsetForWhitespaceIndex(2), 65);286 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(0), 0);287 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(34), 0);288 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(35), 0);289 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(39), 0);290 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(40), 1);291 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(49), 1);292 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(50), 1);293 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(54), 1);294 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(55), 2);295 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(64), 2);296 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(65), 2);297 assert.equal(linesLayout.getWhitespaceIndexAtOrAfterVerticallOffset(70), -1);298 });299 test('LinesLayout getLineNumberAtOrAfterVerticalOffset', () => {300 let linesLayout = new LinesLayout(10, 1, 0, 0);301 insertWhitespace(linesLayout, 6, 0, 10, 0);302 // 10 lines303 // whitespace: - a(6,10)304 assert.equal(linesLayout.getLinesTotalHeight(), 20);305 assert.equal(linesLayout.getVerticalOffsetForLineNumber(1), 0);306 assert.equal(linesLayout.getVerticalOffsetForLineNumber(2), 1);307 assert.equal(linesLayout.getVerticalOffsetForLineNumber(3), 2);308 assert.equal(linesLayout.getVerticalOffsetForLineNumber(4), 3);309 assert.equal(linesLayout.getVerticalOffsetForLineNumber(5), 4);310 assert.equal(linesLayout.getVerticalOffsetForLineNumber(6), 5);311 assert.equal(linesLayout.getVerticalOffsetForLineNumber(7), 16);312 assert.equal(linesLayout.getVerticalOffsetForLineNumber(8), 17);313 assert.equal(linesLayout.getVerticalOffsetForLineNumber(9), 18);314 assert.equal(linesLayout.getVerticalOffsetForLineNumber(10), 19);315 // Do some hit testing316 // line [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]317 // vertical: [0, 1, 2, 3, 4, 5, 16, 17, 18, 19]318 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(-100), 1);319 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(-1), 1);320 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(0), 1);321 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(1), 2);322 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(2), 3);323 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(3), 4);324 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(4), 5);325 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(5), 6);326 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(6), 7);327 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(7), 7);328 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(8), 7);329 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(9), 7);330 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(10), 7);331 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(11), 7);332 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(12), 7);333 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(13), 7);334 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(14), 7);335 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(15), 7);336 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(16), 7);337 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(17), 8);338 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(18), 9);339 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(19), 10);340 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(20), 10);341 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(21), 10);342 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(22), 10);343 assert.equal(linesLayout.getLineNumberAtOrAfterVerticalOffset(23), 10);344 });345 test('LinesLayout getCenteredLineInViewport', () => {346 let linesLayout = new LinesLayout(10, 1, 0, 0);347 insertWhitespace(linesLayout, 6, 0, 10, 0);348 // 10 lines349 // whitespace: - a(6,10)350 assert.equal(linesLayout.getLinesTotalHeight(), 20);351 assert.equal(linesLayout.getVerticalOffsetForLineNumber(1), 0);352 assert.equal(linesLayout.getVerticalOffsetForLineNumber(2), 1);353 assert.equal(linesLayout.getVerticalOffsetForLineNumber(3), 2);354 assert.equal(linesLayout.getVerticalOffsetForLineNumber(4), 3);355 assert.equal(linesLayout.getVerticalOffsetForLineNumber(5), 4);356 assert.equal(linesLayout.getVerticalOffsetForLineNumber(6), 5);357 assert.equal(linesLayout.getVerticalOffsetForLineNumber(7), 16);358 assert.equal(linesLayout.getVerticalOffsetForLineNumber(8), 17);359 assert.equal(linesLayout.getVerticalOffsetForLineNumber(9), 18);360 assert.equal(linesLayout.getVerticalOffsetForLineNumber(10), 19);361 // Find centered line in viewport 1362 // line [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]363 // vertical: [0, 1, 2, 3, 4, 5, 16, 17, 18, 19]364 assert.equal(linesLayout.getLinesViewportData(0, 1).centeredLineNumber, 1);365 assert.equal(linesLayout.getLinesViewportData(0, 2).centeredLineNumber, 2);366 assert.equal(linesLayout.getLinesViewportData(0, 3).centeredLineNumber, 2);367 assert.equal(linesLayout.getLinesViewportData(0, 4).centeredLineNumber, 3);368 assert.equal(linesLayout.getLinesViewportData(0, 5).centeredLineNumber, 3);369 assert.equal(linesLayout.getLinesViewportData(0, 6).centeredLineNumber, 4);370 assert.equal(linesLayout.getLinesViewportData(0, 7).centeredLineNumber, 4);371 assert.equal(linesLayout.getLinesViewportData(0, 8).centeredLineNumber, 5);372 assert.equal(linesLayout.getLinesViewportData(0, 9).centeredLineNumber, 5);373 assert.equal(linesLayout.getLinesViewportData(0, 10).centeredLineNumber, 6);374 assert.equal(linesLayout.getLinesViewportData(0, 11).centeredLineNumber, 6);375 assert.equal(linesLayout.getLinesViewportData(0, 12).centeredLineNumber, 6);376 assert.equal(linesLayout.getLinesViewportData(0, 13).centeredLineNumber, 6);377 assert.equal(linesLayout.getLinesViewportData(0, 14).centeredLineNumber, 6);378 assert.equal(linesLayout.getLinesViewportData(0, 15).centeredLineNumber, 6);379 assert.equal(linesLayout.getLinesViewportData(0, 16).centeredLineNumber, 6);380 assert.equal(linesLayout.getLinesViewportData(0, 17).centeredLineNumber, 7);381 assert.equal(linesLayout.getLinesViewportData(0, 18).centeredLineNumber, 7);382 assert.equal(linesLayout.getLinesViewportData(0, 19).centeredLineNumber, 7);383 assert.equal(linesLayout.getLinesViewportData(0, 20).centeredLineNumber, 7);384 assert.equal(linesLayout.getLinesViewportData(0, 21).centeredLineNumber, 7);385 assert.equal(linesLayout.getLinesViewportData(0, 22).centeredLineNumber, 7);386 assert.equal(linesLayout.getLinesViewportData(0, 23).centeredLineNumber, 7);387 assert.equal(linesLayout.getLinesViewportData(0, 24).centeredLineNumber, 7);388 assert.equal(linesLayout.getLinesViewportData(0, 25).centeredLineNumber, 7);389 assert.equal(linesLayout.getLinesViewportData(0, 26).centeredLineNumber, 7);390 assert.equal(linesLayout.getLinesViewportData(0, 27).centeredLineNumber, 7);391 assert.equal(linesLayout.getLinesViewportData(0, 28).centeredLineNumber, 7);392 assert.equal(linesLayout.getLinesViewportData(0, 29).centeredLineNumber, 7);393 assert.equal(linesLayout.getLinesViewportData(0, 30).centeredLineNumber, 7);394 assert.equal(linesLayout.getLinesViewportData(0, 31).centeredLineNumber, 7);395 assert.equal(linesLayout.getLinesViewportData(0, 32).centeredLineNumber, 7);396 assert.equal(linesLayout.getLinesViewportData(0, 33).centeredLineNumber, 7);397 // Find centered line in viewport 2398 // line [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]399 // vertical: [0, 1, 2, 3, 4, 5, 16, 17, 18, 19]400 assert.equal(linesLayout.getLinesViewportData(0, 20).centeredLineNumber, 7);401 assert.equal(linesLayout.getLinesViewportData(1, 20).centeredLineNumber, 7);402 assert.equal(linesLayout.getLinesViewportData(2, 20).centeredLineNumber, 7);403 assert.equal(linesLayout.getLinesViewportData(3, 20).centeredLineNumber, 7);404 assert.equal(linesLayout.getLinesViewportData(4, 20).centeredLineNumber, 7);405 assert.equal(linesLayout.getLinesViewportData(5, 20).centeredLineNumber, 7);406 assert.equal(linesLayout.getLinesViewportData(6, 20).centeredLineNumber, 7);407 assert.equal(linesLayout.getLinesViewportData(7, 20).centeredLineNumber, 7);408 assert.equal(linesLayout.getLinesViewportData(8, 20).centeredLineNumber, 7);409 assert.equal(linesLayout.getLinesViewportData(9, 20).centeredLineNumber, 7);410 assert.equal(linesLayout.getLinesViewportData(10, 20).centeredLineNumber, 7);411 assert.equal(linesLayout.getLinesViewportData(11, 20).centeredLineNumber, 7);412 assert.equal(linesLayout.getLinesViewportData(12, 20).centeredLineNumber, 7);413 assert.equal(linesLayout.getLinesViewportData(13, 20).centeredLineNumber, 7);414 assert.equal(linesLayout.getLinesViewportData(14, 20).centeredLineNumber, 8);415 assert.equal(linesLayout.getLinesViewportData(15, 20).centeredLineNumber, 8);416 assert.equal(linesLayout.getLinesViewportData(16, 20).centeredLineNumber, 9);417 assert.equal(linesLayout.getLinesViewportData(17, 20).centeredLineNumber, 9);418 assert.equal(linesLayout.getLinesViewportData(18, 20).centeredLineNumber, 10);419 assert.equal(linesLayout.getLinesViewportData(19, 20).centeredLineNumber, 10);420 assert.equal(linesLayout.getLinesViewportData(20, 23).centeredLineNumber, 10);421 assert.equal(linesLayout.getLinesViewportData(21, 23).centeredLineNumber, 10);422 assert.equal(linesLayout.getLinesViewportData(22, 23).centeredLineNumber, 10);423 });424 test('LinesLayout getLinesViewportData 1', () => {425 let linesLayout = new LinesLayout(10, 10, 0, 0);426 insertWhitespace(linesLayout, 6, 0, 100, 0);427 // 10 lines428 // whitespace: - a(6,100)429 assert.equal(linesLayout.getLinesTotalHeight(), 200);430 assert.equal(linesLayout.getVerticalOffsetForLineNumber(1), 0);431 assert.equal(linesLayout.getVerticalOffsetForLineNumber(2), 10);432 assert.equal(linesLayout.getVerticalOffsetForLineNumber(3), 20);433 assert.equal(linesLayout.getVerticalOffsetForLineNumber(4), 30);434 assert.equal(linesLayout.getVerticalOffsetForLineNumber(5), 40);435 assert.equal(linesLayout.getVerticalOffsetForLineNumber(6), 50);436 assert.equal(linesLayout.getVerticalOffsetForLineNumber(7), 160);437 assert.equal(linesLayout.getVerticalOffsetForLineNumber(8), 170);438 assert.equal(linesLayout.getVerticalOffsetForLineNumber(9), 180);439 assert.equal(linesLayout.getVerticalOffsetForLineNumber(10), 190);440 // viewport 0->50441 let viewportData = linesLayout.getLinesViewportData(0, 50);442 assert.equal(viewportData.startLineNumber, 1);443 assert.equal(viewportData.endLineNumber, 5);444 assert.equal(viewportData.completelyVisibleStartLineNumber, 1);445 assert.equal(viewportData.completelyVisibleEndLineNumber, 5);446 assert.deepEqual(viewportData.relativeVerticalOffset, [0, 10, 20, 30, 40]);447 // viewport 1->51448 viewportData = linesLayout.getLinesViewportData(1, 51);449 assert.equal(viewportData.startLineNumber, 1);450 assert.equal(viewportData.endLineNumber, 6);451 assert.equal(viewportData.completelyVisibleStartLineNumber, 2);452 assert.equal(viewportData.completelyVisibleEndLineNumber, 5);453 assert.deepEqual(viewportData.relativeVerticalOffset, [0, 10, 20, 30, 40, 50]);454 // viewport 5->55455 viewportData = linesLayout.getLinesViewportData(5, 55);456 assert.equal(viewportData.startLineNumber, 1);457 assert.equal(viewportData.endLineNumber, 6);458 assert.equal(viewportData.completelyVisibleStartLineNumber, 2);459 assert.equal(viewportData.completelyVisibleEndLineNumber, 5);460 assert.deepEqual(viewportData.relativeVerticalOffset, [0, 10, 20, 30, 40, 50]);461 // viewport 10->60462 viewportData = linesLayout.getLinesViewportData(10, 60);463 assert.equal(viewportData.startLineNumber, 2);464 assert.equal(viewportData.endLineNumber, 6);465 assert.equal(viewportData.completelyVisibleStartLineNumber, 2);466 assert.equal(viewportData.completelyVisibleEndLineNumber, 6);467 assert.deepEqual(viewportData.relativeVerticalOffset, [10, 20, 30, 40, 50]);468 // viewport 50->100469 viewportData = linesLayout.getLinesViewportData(50, 100);470 assert.equal(viewportData.startLineNumber, 6);471 assert.equal(viewportData.endLineNumber, 6);472 assert.equal(viewportData.completelyVisibleStartLineNumber, 6);473 assert.equal(viewportData.completelyVisibleEndLineNumber, 6);474 assert.deepEqual(viewportData.relativeVerticalOffset, [50]);475 // viewport 60->110476 viewportData = linesLayout.getLinesViewportData(60, 110);477 assert.equal(viewportData.startLineNumber, 7);478 assert.equal(viewportData.endLineNumber, 7);479 assert.equal(viewportData.completelyVisibleStartLineNumber, 7);480 assert.equal(viewportData.completelyVisibleEndLineNumber, 7);481 assert.deepEqual(viewportData.relativeVerticalOffset, [160]);482 // viewport 65->115483 viewportData = linesLayout.getLinesViewportData(65, 115);484 assert.equal(viewportData.startLineNumber, 7);485 assert.equal(viewportData.endLineNumber, 7);486 assert.equal(viewportData.completelyVisibleStartLineNumber, 7);487 assert.equal(viewportData.completelyVisibleEndLineNumber, 7);488 assert.deepEqual(viewportData.relativeVerticalOffset, [160]);489 // viewport 50->159490 viewportData = linesLayout.getLinesViewportData(50, 159);491 assert.equal(viewportData.startLineNumber, 6);492 assert.equal(viewportData.endLineNumber, 6);493 assert.equal(viewportData.completelyVisibleStartLineNumber, 6);494 assert.equal(viewportData.completelyVisibleEndLineNumber, 6);495 assert.deepEqual(viewportData.relativeVerticalOffset, [50]);496 // viewport 50->160497 viewportData = linesLayout.getLinesViewportData(50, 160);498 assert.equal(viewportData.startLineNumber, 6);499 assert.equal(viewportData.endLineNumber, 6);500 assert.equal(viewportData.completelyVisibleStartLineNumber, 6);501 assert.equal(viewportData.completelyVisibleEndLineNumber, 6);502 assert.deepEqual(viewportData.relativeVerticalOffset, [50]);503 // viewport 51->161504 viewportData = linesLayout.getLinesViewportData(51, 161);505 assert.equal(viewportData.startLineNumber, 6);506 assert.equal(viewportData.endLineNumber, 7);507 assert.equal(viewportData.completelyVisibleStartLineNumber, 7);508 assert.equal(viewportData.completelyVisibleEndLineNumber, 7);509 assert.deepEqual(viewportData.relativeVerticalOffset, [50, 160]);510 // viewport 150->169511 viewportData = linesLayout.getLinesViewportData(150, 169);512 assert.equal(viewportData.startLineNumber, 7);513 assert.equal(viewportData.endLineNumber, 7);514 assert.equal(viewportData.completelyVisibleStartLineNumber, 7);515 assert.equal(viewportData.completelyVisibleEndLineNumber, 7);516 assert.deepEqual(viewportData.relativeVerticalOffset, [160]);517 // viewport 159->169518 viewportData = linesLayout.getLinesViewportData(159, 169);519 assert.equal(viewportData.startLineNumber, 7);520 assert.equal(viewportData.endLineNumber, 7);521 assert.equal(viewportData.completelyVisibleStartLineNumber, 7);522 assert.equal(viewportData.completelyVisibleEndLineNumber, 7);523 assert.deepEqual(viewportData.relativeVerticalOffset, [160]);524 // viewport 160->169525 viewportData = linesLayout.getLinesViewportData(160, 169);526 assert.equal(viewportData.startLineNumber, 7);527 assert.equal(viewportData.endLineNumber, 7);528 assert.equal(viewportData.completelyVisibleStartLineNumber, 7);529 assert.equal(viewportData.completelyVisibleEndLineNumber, 7);530 assert.deepEqual(viewportData.relativeVerticalOffset, [160]);531 // viewport 160->1000532 viewportData = linesLayout.getLinesViewportData(160, 1000);533 assert.equal(viewportData.startLineNumber, 7);534 assert.equal(viewportData.endLineNumber, 10);535 assert.equal(viewportData.completelyVisibleStartLineNumber, 7);536 assert.equal(viewportData.completelyVisibleEndLineNumber, 10);537 assert.deepEqual(viewportData.relativeVerticalOffset, [160, 170, 180, 190]);538 });539 test('LinesLayout getLinesViewportData 2 & getWhitespaceViewportData', () => {540 let linesLayout = new LinesLayout(10, 10, 0, 0);541 let a = insertWhitespace(linesLayout, 6, 0, 100, 0);542 let b = insertWhitespace(linesLayout, 7, 0, 50, 0);543 // 10 lines544 // whitespace: - a(6,100), b(7, 50)545 assert.equal(linesLayout.getLinesTotalHeight(), 250);546 assert.equal(linesLayout.getVerticalOffsetForLineNumber(1), 0);547 assert.equal(linesLayout.getVerticalOffsetForLineNumber(2), 10);548 assert.equal(linesLayout.getVerticalOffsetForLineNumber(3), 20);549 assert.equal(linesLayout.getVerticalOffsetForLineNumber(4), 30);550 assert.equal(linesLayout.getVerticalOffsetForLineNumber(5), 40);551 assert.equal(linesLayout.getVerticalOffsetForLineNumber(6), 50);552 assert.equal(linesLayout.getVerticalOffsetForLineNumber(7), 160);553 assert.equal(linesLayout.getVerticalOffsetForLineNumber(8), 220);554 assert.equal(linesLayout.getVerticalOffsetForLineNumber(9), 230);555 assert.equal(linesLayout.getVerticalOffsetForLineNumber(10), 240);556 // viewport 50->160557 let viewportData = linesLayout.getLinesViewportData(50, 160);558 assert.equal(viewportData.startLineNumber, 6);559 assert.equal(viewportData.endLineNumber, 6);560 assert.equal(viewportData.completelyVisibleStartLineNumber, 6);561 assert.equal(viewportData.completelyVisibleEndLineNumber, 6);562 assert.deepEqual(viewportData.relativeVerticalOffset, [50]);563 let whitespaceData = linesLayout.getWhitespaceViewportData(50, 160);564 assert.deepEqual(whitespaceData, [{565 id: a,566 afterLineNumber: 6,567 verticalOffset: 60,568 height: 100569 }]);570 // viewport 50->219571 viewportData = linesLayout.getLinesViewportData(50, 219);572 assert.equal(viewportData.startLineNumber, 6);573 assert.equal(viewportData.endLineNumber, 7);574 assert.equal(viewportData.completelyVisibleStartLineNumber, 6);575 assert.equal(viewportData.completelyVisibleEndLineNumber, 7);576 assert.deepEqual(viewportData.relativeVerticalOffset, [50, 160]);577 whitespaceData = linesLayout.getWhitespaceViewportData(50, 219);578 assert.deepEqual(whitespaceData, [{579 id: a,580 afterLineNumber: 6,581 verticalOffset: 60,582 height: 100583 }, {584 id: b,585 afterLineNumber: 7,586 verticalOffset: 170,587 height: 50588 }]);589 // viewport 50->220590 viewportData = linesLayout.getLinesViewportData(50, 220);591 assert.equal(viewportData.startLineNumber, 6);592 assert.equal(viewportData.endLineNumber, 7);593 assert.equal(viewportData.completelyVisibleStartLineNumber, 6);594 assert.equal(viewportData.completelyVisibleEndLineNumber, 7);595 assert.deepEqual(viewportData.relativeVerticalOffset, [50, 160]);596 // viewport 50->250597 viewportData = linesLayout.getLinesViewportData(50, 250);598 assert.equal(viewportData.startLineNumber, 6);599 assert.equal(viewportData.endLineNumber, 10);600 assert.equal(viewportData.completelyVisibleStartLineNumber, 6);601 assert.equal(viewportData.completelyVisibleEndLineNumber, 10);602 assert.deepEqual(viewportData.relativeVerticalOffset, [50, 160, 220, 230, 240]);603 });604 test('LinesLayout getWhitespaceAtVerticalOffset', () => {605 let linesLayout = new LinesLayout(10, 10, 0, 0);606 let a = insertWhitespace(linesLayout, 6, 0, 100, 0);607 let b = insertWhitespace(linesLayout, 7, 0, 50, 0);608 let whitespace = linesLayout.getWhitespaceAtVerticalOffset(0);609 assert.equal(whitespace, null);610 whitespace = linesLayout.getWhitespaceAtVerticalOffset(59);611 assert.equal(whitespace, null);612 whitespace = linesLayout.getWhitespaceAtVerticalOffset(60);613 assert.equal(whitespace!.id, a);614 whitespace = linesLayout.getWhitespaceAtVerticalOffset(61);615 assert.equal(whitespace!.id, a);616 whitespace = linesLayout.getWhitespaceAtVerticalOffset(159);617 assert.equal(whitespace!.id, a);618 whitespace = linesLayout.getWhitespaceAtVerticalOffset(160);619 assert.equal(whitespace, null);620 whitespace = linesLayout.getWhitespaceAtVerticalOffset(161);621 assert.equal(whitespace, null);622 whitespace = linesLayout.getWhitespaceAtVerticalOffset(169);623 assert.equal(whitespace, null);624 whitespace = linesLayout.getWhitespaceAtVerticalOffset(170);625 assert.equal(whitespace!.id, b);626 whitespace = linesLayout.getWhitespaceAtVerticalOffset(171);627 assert.equal(whitespace!.id, b);628 whitespace = linesLayout.getWhitespaceAtVerticalOffset(219);629 assert.equal(whitespace!.id, b);630 whitespace = linesLayout.getWhitespaceAtVerticalOffset(220);631 assert.equal(whitespace, null);632 });633 test('LinesLayout', () => {634 const linesLayout = new LinesLayout(100, 20, 0, 0);635 // Insert a whitespace after line number 2, of height 10636 const a = insertWhitespace(linesLayout, 2, 0, 10, 0);637 // whitespaces: a(2, 10)638 assert.equal(linesLayout.getWhitespacesCount(), 1);639 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 2);640 assert.equal(linesLayout.getHeightForWhitespaceIndex(0), 10);641 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(0), 10);642 assert.equal(linesLayout.getWhitespacesTotalHeight(), 10);643 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(1), 0);644 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(2), 0);645 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(3), 10);646 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(4), 10);647 // Insert a whitespace again after line number 2, of height 20648 let b = insertWhitespace(linesLayout, 2, 0, 20, 0);649 // whitespaces: a(2, 10), b(2, 20)650 assert.equal(linesLayout.getWhitespacesCount(), 2);651 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 2);652 assert.equal(linesLayout.getHeightForWhitespaceIndex(0), 10);653 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(1), 2);654 assert.equal(linesLayout.getHeightForWhitespaceIndex(1), 20);655 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(0), 10);656 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(1), 30);657 assert.equal(linesLayout.getWhitespacesTotalHeight(), 30);658 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(1), 0);659 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(2), 0);660 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(3), 30);661 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(4), 30);662 // Change last inserted whitespace height to 30663 changeOneWhitespace(linesLayout, b, 2, 30);664 // whitespaces: a(2, 10), b(2, 30)665 assert.equal(linesLayout.getWhitespacesCount(), 2);666 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 2);667 assert.equal(linesLayout.getHeightForWhitespaceIndex(0), 10);668 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(1), 2);669 assert.equal(linesLayout.getHeightForWhitespaceIndex(1), 30);670 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(0), 10);671 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(1), 40);672 assert.equal(linesLayout.getWhitespacesTotalHeight(), 40);673 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(1), 0);674 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(2), 0);675 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(3), 40);676 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(4), 40);677 // Remove last inserted whitespace678 removeWhitespace(linesLayout, b);679 // whitespaces: a(2, 10)680 assert.equal(linesLayout.getWhitespacesCount(), 1);681 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 2);682 assert.equal(linesLayout.getHeightForWhitespaceIndex(0), 10);683 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(0), 10);684 assert.equal(linesLayout.getWhitespacesTotalHeight(), 10);685 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(1), 0);686 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(2), 0);687 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(3), 10);688 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(4), 10);689 // Add a whitespace before the first line of height 50690 b = insertWhitespace(linesLayout, 0, 0, 50, 0);691 // whitespaces: b(0, 50), a(2, 10)692 assert.equal(linesLayout.getWhitespacesCount(), 2);693 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 0);694 assert.equal(linesLayout.getHeightForWhitespaceIndex(0), 50);695 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(1), 2);696 assert.equal(linesLayout.getHeightForWhitespaceIndex(1), 10);697 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(0), 50);698 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(1), 60);699 assert.equal(linesLayout.getWhitespacesTotalHeight(), 60);700 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(1), 50);701 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(2), 50);702 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(3), 60);703 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(4), 60);704 // Add a whitespace after line 4 of height 20705 insertWhitespace(linesLayout, 4, 0, 20, 0);706 // whitespaces: b(0, 50), a(2, 10), c(4, 20)707 assert.equal(linesLayout.getWhitespacesCount(), 3);708 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 0);709 assert.equal(linesLayout.getHeightForWhitespaceIndex(0), 50);710 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(1), 2);711 assert.equal(linesLayout.getHeightForWhitespaceIndex(1), 10);712 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(2), 4);713 assert.equal(linesLayout.getHeightForWhitespaceIndex(2), 20);714 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(0), 50);715 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(1), 60);716 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(2), 80);717 assert.equal(linesLayout.getWhitespacesTotalHeight(), 80);718 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(1), 50);719 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(2), 50);720 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(3), 60);721 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(4), 60);722 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(5), 80);723 // Add a whitespace after line 3 of height 30724 insertWhitespace(linesLayout, 3, 0, 30, 0);725 // whitespaces: b(0, 50), a(2, 10), d(3, 30), c(4, 20)726 assert.equal(linesLayout.getWhitespacesCount(), 4);727 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 0);728 assert.equal(linesLayout.getHeightForWhitespaceIndex(0), 50);729 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(1), 2);730 assert.equal(linesLayout.getHeightForWhitespaceIndex(1), 10);731 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(2), 3);732 assert.equal(linesLayout.getHeightForWhitespaceIndex(2), 30);733 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(3), 4);734 assert.equal(linesLayout.getHeightForWhitespaceIndex(3), 20);735 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(0), 50);736 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(1), 60);737 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(2), 90);738 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(3), 110);739 assert.equal(linesLayout.getWhitespacesTotalHeight(), 110);740 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(1), 50);741 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(2), 50);742 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(3), 60);743 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(4), 90);744 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(5), 110);745 // Change whitespace after line 2 to height of 100746 changeOneWhitespace(linesLayout, a, 2, 100);747 // whitespaces: b(0, 50), a(2, 100), d(3, 30), c(4, 20)748 assert.equal(linesLayout.getWhitespacesCount(), 4);749 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 0);750 assert.equal(linesLayout.getHeightForWhitespaceIndex(0), 50);751 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(1), 2);752 assert.equal(linesLayout.getHeightForWhitespaceIndex(1), 100);753 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(2), 3);754 assert.equal(linesLayout.getHeightForWhitespaceIndex(2), 30);755 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(3), 4);756 assert.equal(linesLayout.getHeightForWhitespaceIndex(3), 20);757 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(0), 50);758 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(1), 150);759 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(2), 180);760 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(3), 200);761 assert.equal(linesLayout.getWhitespacesTotalHeight(), 200);762 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(1), 50);763 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(2), 50);764 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(3), 150);765 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(4), 180);766 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(5), 200);767 // Remove whitespace after line 2768 removeWhitespace(linesLayout, a);769 // whitespaces: b(0, 50), d(3, 30), c(4, 20)770 assert.equal(linesLayout.getWhitespacesCount(), 3);771 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 0);772 assert.equal(linesLayout.getHeightForWhitespaceIndex(0), 50);773 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(1), 3);774 assert.equal(linesLayout.getHeightForWhitespaceIndex(1), 30);775 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(2), 4);776 assert.equal(linesLayout.getHeightForWhitespaceIndex(2), 20);777 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(0), 50);778 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(1), 80);779 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(2), 100);780 assert.equal(linesLayout.getWhitespacesTotalHeight(), 100);781 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(1), 50);782 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(2), 50);783 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(3), 50);784 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(4), 80);785 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(5), 100);786 // Remove whitespace before line 1787 removeWhitespace(linesLayout, b);788 // whitespaces: d(3, 30), c(4, 20)789 assert.equal(linesLayout.getWhitespacesCount(), 2);790 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 3);791 assert.equal(linesLayout.getHeightForWhitespaceIndex(0), 30);792 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(1), 4);793 assert.equal(linesLayout.getHeightForWhitespaceIndex(1), 20);794 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(0), 30);795 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(1), 50);796 assert.equal(linesLayout.getWhitespacesTotalHeight(), 50);797 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(1), 0);798 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(2), 0);799 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(3), 0);800 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(4), 30);801 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(5), 50);802 // Delete line 1803 linesLayout.onLinesDeleted(1, 1);804 // whitespaces: d(2, 30), c(3, 20)805 assert.equal(linesLayout.getWhitespacesCount(), 2);806 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 2);807 assert.equal(linesLayout.getHeightForWhitespaceIndex(0), 30);808 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(1), 3);809 assert.equal(linesLayout.getHeightForWhitespaceIndex(1), 20);810 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(0), 30);811 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(1), 50);812 assert.equal(linesLayout.getWhitespacesTotalHeight(), 50);813 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(1), 0);814 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(2), 0);815 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(3), 30);816 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(4), 50);817 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(5), 50);818 // Insert a line before line 1819 linesLayout.onLinesInserted(1, 1);820 // whitespaces: d(3, 30), c(4, 20)821 assert.equal(linesLayout.getWhitespacesCount(), 2);822 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 3);823 assert.equal(linesLayout.getHeightForWhitespaceIndex(0), 30);824 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(1), 4);825 assert.equal(linesLayout.getHeightForWhitespaceIndex(1), 20);826 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(0), 30);827 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(1), 50);828 assert.equal(linesLayout.getWhitespacesTotalHeight(), 50);829 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(1), 0);830 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(2), 0);831 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(3), 0);832 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(4), 30);833 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(5), 50);834 // Delete line 4835 linesLayout.onLinesDeleted(4, 4);836 // whitespaces: d(3, 30), c(3, 20)837 assert.equal(linesLayout.getWhitespacesCount(), 2);838 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 3);839 assert.equal(linesLayout.getHeightForWhitespaceIndex(0), 30);840 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(1), 3);841 assert.equal(linesLayout.getHeightForWhitespaceIndex(1), 20);842 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(0), 30);843 assert.equal(linesLayout.getWhitespacesAccumulatedHeight(1), 50);844 assert.equal(linesLayout.getWhitespacesTotalHeight(), 50);845 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(1), 0);846 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(2), 0);847 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(3), 0);848 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(4), 50);849 assert.equal(linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(5), 50);850 });851 test('LinesLayout findInsertionIndex', () => {852 const makeInternalWhitespace = (afterLineNumbers: number[], ordinal: number = 0) => {853 return afterLineNumbers.map((afterLineNumber) => new EditorWhitespace('', afterLineNumber, ordinal, 0, 0));854 };855 let arr: EditorWhitespace[];856 arr = makeInternalWhitespace([]);857 assert.equal(LinesLayout.findInsertionIndex(arr, 0, 0), 0);858 assert.equal(LinesLayout.findInsertionIndex(arr, 1, 0), 0);859 assert.equal(LinesLayout.findInsertionIndex(arr, 2, 0), 0);860 arr = makeInternalWhitespace([1]);861 assert.equal(LinesLayout.findInsertionIndex(arr, 0, 0), 0);862 assert.equal(LinesLayout.findInsertionIndex(arr, 1, 0), 1);863 assert.equal(LinesLayout.findInsertionIndex(arr, 2, 0), 1);864 arr = makeInternalWhitespace([1, 3]);865 assert.equal(LinesLayout.findInsertionIndex(arr, 0, 0), 0);866 assert.equal(LinesLayout.findInsertionIndex(arr, 1, 0), 1);867 assert.equal(LinesLayout.findInsertionIndex(arr, 2, 0), 1);868 assert.equal(LinesLayout.findInsertionIndex(arr, 3, 0), 2);869 assert.equal(LinesLayout.findInsertionIndex(arr, 4, 0), 2);870 arr = makeInternalWhitespace([1, 3, 5]);871 assert.equal(LinesLayout.findInsertionIndex(arr, 0, 0), 0);872 assert.equal(LinesLayout.findInsertionIndex(arr, 1, 0), 1);873 assert.equal(LinesLayout.findInsertionIndex(arr, 2, 0), 1);874 assert.equal(LinesLayout.findInsertionIndex(arr, 3, 0), 2);875 assert.equal(LinesLayout.findInsertionIndex(arr, 4, 0), 2);876 assert.equal(LinesLayout.findInsertionIndex(arr, 5, 0), 3);877 assert.equal(LinesLayout.findInsertionIndex(arr, 6, 0), 3);878 arr = makeInternalWhitespace([1, 3, 5], 3);879 assert.equal(LinesLayout.findInsertionIndex(arr, 0, 0), 0);880 assert.equal(LinesLayout.findInsertionIndex(arr, 1, 0), 0);881 assert.equal(LinesLayout.findInsertionIndex(arr, 2, 0), 1);882 assert.equal(LinesLayout.findInsertionIndex(arr, 3, 0), 1);883 assert.equal(LinesLayout.findInsertionIndex(arr, 4, 0), 2);884 assert.equal(LinesLayout.findInsertionIndex(arr, 5, 0), 2);885 assert.equal(LinesLayout.findInsertionIndex(arr, 6, 0), 3);886 arr = makeInternalWhitespace([1, 3, 5, 7]);887 assert.equal(LinesLayout.findInsertionIndex(arr, 0, 0), 0);888 assert.equal(LinesLayout.findInsertionIndex(arr, 1, 0), 1);889 assert.equal(LinesLayout.findInsertionIndex(arr, 2, 0), 1);890 assert.equal(LinesLayout.findInsertionIndex(arr, 3, 0), 2);891 assert.equal(LinesLayout.findInsertionIndex(arr, 4, 0), 2);892 assert.equal(LinesLayout.findInsertionIndex(arr, 5, 0), 3);893 assert.equal(LinesLayout.findInsertionIndex(arr, 6, 0), 3);894 assert.equal(LinesLayout.findInsertionIndex(arr, 7, 0), 4);895 assert.equal(LinesLayout.findInsertionIndex(arr, 8, 0), 4);896 arr = makeInternalWhitespace([1, 3, 5, 7, 9]);897 assert.equal(LinesLayout.findInsertionIndex(arr, 0, 0), 0);898 assert.equal(LinesLayout.findInsertionIndex(arr, 1, 0), 1);899 assert.equal(LinesLayout.findInsertionIndex(arr, 2, 0), 1);900 assert.equal(LinesLayout.findInsertionIndex(arr, 3, 0), 2);901 assert.equal(LinesLayout.findInsertionIndex(arr, 4, 0), 2);902 assert.equal(LinesLayout.findInsertionIndex(arr, 5, 0), 3);903 assert.equal(LinesLayout.findInsertionIndex(arr, 6, 0), 3);904 assert.equal(LinesLayout.findInsertionIndex(arr, 7, 0), 4);905 assert.equal(LinesLayout.findInsertionIndex(arr, 8, 0), 4);906 assert.equal(LinesLayout.findInsertionIndex(arr, 9, 0), 5);907 assert.equal(LinesLayout.findInsertionIndex(arr, 10, 0), 5);908 arr = makeInternalWhitespace([1, 3, 5, 7, 9, 11]);909 assert.equal(LinesLayout.findInsertionIndex(arr, 0, 0), 0);910 assert.equal(LinesLayout.findInsertionIndex(arr, 1, 0), 1);911 assert.equal(LinesLayout.findInsertionIndex(arr, 2, 0), 1);912 assert.equal(LinesLayout.findInsertionIndex(arr, 3, 0), 2);913 assert.equal(LinesLayout.findInsertionIndex(arr, 4, 0), 2);914 assert.equal(LinesLayout.findInsertionIndex(arr, 5, 0), 3);915 assert.equal(LinesLayout.findInsertionIndex(arr, 6, 0), 3);916 assert.equal(LinesLayout.findInsertionIndex(arr, 7, 0), 4);917 assert.equal(LinesLayout.findInsertionIndex(arr, 8, 0), 4);918 assert.equal(LinesLayout.findInsertionIndex(arr, 9, 0), 5);919 assert.equal(LinesLayout.findInsertionIndex(arr, 10, 0), 5);920 assert.equal(LinesLayout.findInsertionIndex(arr, 11, 0), 6);921 assert.equal(LinesLayout.findInsertionIndex(arr, 12, 0), 6);922 arr = makeInternalWhitespace([1, 3, 5, 7, 9, 11, 13]);923 assert.equal(LinesLayout.findInsertionIndex(arr, 0, 0), 0);924 assert.equal(LinesLayout.findInsertionIndex(arr, 1, 0), 1);925 assert.equal(LinesLayout.findInsertionIndex(arr, 2, 0), 1);926 assert.equal(LinesLayout.findInsertionIndex(arr, 3, 0), 2);927 assert.equal(LinesLayout.findInsertionIndex(arr, 4, 0), 2);928 assert.equal(LinesLayout.findInsertionIndex(arr, 5, 0), 3);929 assert.equal(LinesLayout.findInsertionIndex(arr, 6, 0), 3);930 assert.equal(LinesLayout.findInsertionIndex(arr, 7, 0), 4);931 assert.equal(LinesLayout.findInsertionIndex(arr, 8, 0), 4);932 assert.equal(LinesLayout.findInsertionIndex(arr, 9, 0), 5);933 assert.equal(LinesLayout.findInsertionIndex(arr, 10, 0), 5);934 assert.equal(LinesLayout.findInsertionIndex(arr, 11, 0), 6);935 assert.equal(LinesLayout.findInsertionIndex(arr, 12, 0), 6);936 assert.equal(LinesLayout.findInsertionIndex(arr, 13, 0), 7);937 assert.equal(LinesLayout.findInsertionIndex(arr, 14, 0), 7);938 arr = makeInternalWhitespace([1, 3, 5, 7, 9, 11, 13, 15]);939 assert.equal(LinesLayout.findInsertionIndex(arr, 0, 0), 0);940 assert.equal(LinesLayout.findInsertionIndex(arr, 1, 0), 1);941 assert.equal(LinesLayout.findInsertionIndex(arr, 2, 0), 1);942 assert.equal(LinesLayout.findInsertionIndex(arr, 3, 0), 2);943 assert.equal(LinesLayout.findInsertionIndex(arr, 4, 0), 2);944 assert.equal(LinesLayout.findInsertionIndex(arr, 5, 0), 3);945 assert.equal(LinesLayout.findInsertionIndex(arr, 6, 0), 3);946 assert.equal(LinesLayout.findInsertionIndex(arr, 7, 0), 4);947 assert.equal(LinesLayout.findInsertionIndex(arr, 8, 0), 4);948 assert.equal(LinesLayout.findInsertionIndex(arr, 9, 0), 5);949 assert.equal(LinesLayout.findInsertionIndex(arr, 10, 0), 5);950 assert.equal(LinesLayout.findInsertionIndex(arr, 11, 0), 6);951 assert.equal(LinesLayout.findInsertionIndex(arr, 12, 0), 6);952 assert.equal(LinesLayout.findInsertionIndex(arr, 13, 0), 7);953 assert.equal(LinesLayout.findInsertionIndex(arr, 14, 0), 7);954 assert.equal(LinesLayout.findInsertionIndex(arr, 15, 0), 8);955 assert.equal(LinesLayout.findInsertionIndex(arr, 16, 0), 8);956 });957 test('LinesLayout changeWhitespaceAfterLineNumber & getFirstWhitespaceIndexAfterLineNumber', () => {958 const linesLayout = new LinesLayout(100, 20, 0, 0);959 const a = insertWhitespace(linesLayout, 0, 0, 1, 0);960 const b = insertWhitespace(linesLayout, 7, 0, 1, 0);961 const c = insertWhitespace(linesLayout, 3, 0, 1, 0);962 assert.equal(linesLayout.getIdForWhitespaceIndex(0), a); // 0963 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 0);964 assert.equal(linesLayout.getIdForWhitespaceIndex(1), c); // 3965 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(1), 3);966 assert.equal(linesLayout.getIdForWhitespaceIndex(2), b); // 7967 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(2), 7);968 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(1), 1); // c969 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(2), 1); // c970 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(3), 1); // c971 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(4), 2); // b972 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(5), 2); // b973 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(6), 2); // b974 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(7), 2); // b975 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(8), -1); // --976 // Do not really move a977 changeOneWhitespace(linesLayout, a, 1, 1);978 assert.equal(linesLayout.getIdForWhitespaceIndex(0), a); // 1979 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 1);980 assert.equal(linesLayout.getIdForWhitespaceIndex(1), c); // 3981 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(1), 3);982 assert.equal(linesLayout.getIdForWhitespaceIndex(2), b); // 7983 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(2), 7);984 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(1), 0); // a985 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(2), 1); // c986 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(3), 1); // c987 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(4), 2); // b988 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(5), 2); // b989 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(6), 2); // b990 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(7), 2); // b991 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(8), -1); // --992 // Do not really move a993 changeOneWhitespace(linesLayout, a, 2, 1);994 assert.equal(linesLayout.getIdForWhitespaceIndex(0), a); // 2995 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 2);996 assert.equal(linesLayout.getIdForWhitespaceIndex(1), c); // 3997 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(1), 3);998 assert.equal(linesLayout.getIdForWhitespaceIndex(2), b); // 7999 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(2), 7);1000 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(1), 0); // a1001 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(2), 0); // a1002 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(3), 1); // c1003 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(4), 2); // b1004 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(5), 2); // b1005 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(6), 2); // b1006 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(7), 2); // b1007 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(8), -1); // --1008 // Change a to conflict with c => a gets placed after c1009 changeOneWhitespace(linesLayout, a, 3, 1);1010 assert.equal(linesLayout.getIdForWhitespaceIndex(0), c); // 31011 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 3);1012 assert.equal(linesLayout.getIdForWhitespaceIndex(1), a); // 31013 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(1), 3);1014 assert.equal(linesLayout.getIdForWhitespaceIndex(2), b); // 71015 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(2), 7);1016 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(1), 0); // c1017 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(2), 0); // c1018 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(3), 0); // c1019 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(4), 2); // b1020 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(5), 2); // b1021 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(6), 2); // b1022 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(7), 2); // b1023 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(8), -1); // --1024 // Make a no-op1025 changeOneWhitespace(linesLayout, c, 3, 1);1026 assert.equal(linesLayout.getIdForWhitespaceIndex(0), c); // 31027 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 3);1028 assert.equal(linesLayout.getIdForWhitespaceIndex(1), a); // 31029 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(1), 3);1030 assert.equal(linesLayout.getIdForWhitespaceIndex(2), b); // 71031 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(2), 7);1032 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(1), 0); // c1033 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(2), 0); // c1034 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(3), 0); // c1035 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(4), 2); // b1036 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(5), 2); // b1037 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(6), 2); // b1038 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(7), 2); // b1039 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(8), -1); // --1040 // Conflict c with b => c gets placed after b1041 changeOneWhitespace(linesLayout, c, 7, 1);1042 assert.equal(linesLayout.getIdForWhitespaceIndex(0), a); // 31043 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(0), 3);1044 assert.equal(linesLayout.getIdForWhitespaceIndex(1), b); // 71045 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(1), 7);1046 assert.equal(linesLayout.getIdForWhitespaceIndex(2), c); // 71047 assert.equal(linesLayout.getAfterLineNumberForWhitespaceIndex(2), 7);1048 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(1), 0); // a1049 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(2), 0); // a1050 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(3), 0); // a1051 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(4), 1); // b1052 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(5), 1); // b1053 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(6), 1); // b1054 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(7), 1); // b1055 assert.equal(linesLayout.getFirstWhitespaceIndexAfterLineNumber(8), -1); // --1056 });1057 test('LinesLayout Bug', () => {1058 const linesLayout = new LinesLayout(100, 20, 0, 0);1059 const a = insertWhitespace(linesLayout, 0, 0, 1, 0);1060 const b = insertWhitespace(linesLayout, 7, 0, 1, 0);1061 assert.equal(linesLayout.getIdForWhitespaceIndex(0), a); // 01062 assert.equal(linesLayout.getIdForWhitespaceIndex(1), b); // 71063 const c = insertWhitespace(linesLayout, 3, 0, 1, 0);1064 assert.equal(linesLayout.getIdForWhitespaceIndex(0), a); // 01065 assert.equal(linesLayout.getIdForWhitespaceIndex(1), c); // 31066 assert.equal(linesLayout.getIdForWhitespaceIndex(2), b); // 71067 const d = insertWhitespace(linesLayout, 2, 0, 1, 0);1068 assert.equal(linesLayout.getIdForWhitespaceIndex(0), a); // 01069 assert.equal(linesLayout.getIdForWhitespaceIndex(1), d); // 21070 assert.equal(linesLayout.getIdForWhitespaceIndex(2), c); // 31071 assert.equal(linesLayout.getIdForWhitespaceIndex(3), b); // 71072 const e = insertWhitespace(linesLayout, 8, 0, 1, 0);1073 assert.equal(linesLayout.getIdForWhitespaceIndex(0), a); // 01074 assert.equal(linesLayout.getIdForWhitespaceIndex(1), d); // 21075 assert.equal(linesLayout.getIdForWhitespaceIndex(2), c); // 31076 assert.equal(linesLayout.getIdForWhitespaceIndex(3), b); // 71077 assert.equal(linesLayout.getIdForWhitespaceIndex(4), e); // 81078 const f = insertWhitespace(linesLayout, 11, 0, 1, 0);1079 assert.equal(linesLayout.getIdForWhitespaceIndex(0), a); // 01080 assert.equal(linesLayout.getIdForWhitespaceIndex(1), d); // 21081 assert.equal(linesLayout.getIdForWhitespaceIndex(2), c); // 31082 assert.equal(linesLayout.getIdForWhitespaceIndex(3), b); // 71083 assert.equal(linesLayout.getIdForWhitespaceIndex(4), e); // 81084 assert.equal(linesLayout.getIdForWhitespaceIndex(5), f); // 111085 const g = insertWhitespace(linesLayout, 10, 0, 1, 0);1086 assert.equal(linesLayout.getIdForWhitespaceIndex(0), a); // 01087 assert.equal(linesLayout.getIdForWhitespaceIndex(1), d); // 21088 assert.equal(linesLayout.getIdForWhitespaceIndex(2), c); // 31089 assert.equal(linesLayout.getIdForWhitespaceIndex(3), b); // 71090 assert.equal(linesLayout.getIdForWhitespaceIndex(4), e); // 81091 assert.equal(linesLayout.getIdForWhitespaceIndex(5), g); // 101092 assert.equal(linesLayout.getIdForWhitespaceIndex(6), f); // 111093 const h = insertWhitespace(linesLayout, 0, 0, 1, 0);1094 assert.equal(linesLayout.getIdForWhitespaceIndex(0), a); // 01095 assert.equal(linesLayout.getIdForWhitespaceIndex(1), h); // 01096 assert.equal(linesLayout.getIdForWhitespaceIndex(2), d); // 21097 assert.equal(linesLayout.getIdForWhitespaceIndex(3), c); // 31098 assert.equal(linesLayout.getIdForWhitespaceIndex(4), b); // 71099 assert.equal(linesLayout.getIdForWhitespaceIndex(5), e); // 81100 assert.equal(linesLayout.getIdForWhitespaceIndex(6), g); // 101101 assert.equal(linesLayout.getIdForWhitespaceIndex(7), f); // 111102 });...

Full Screen

Full Screen

viewLayer.ts

Source:viewLayer.ts Github

copy

Full Screen

1/*---------------------------------------------------------------------------------------------2 * Copyright (c) Microsoft Corporation. All rights reserved.3 * Licensed under the MIT License. See License.txt in the project root for license information.4 *--------------------------------------------------------------------------------------------*/5import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';6import { IStringBuilder, createStringBuilder } from 'vs/editor/common/core/stringBuilder';7import * as viewEvents from 'vs/editor/common/view/viewEvents';8import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';9import { EditorOption } from 'vs/editor/common/config/editorOptions';10/**11 * Represents a visible line12 */13export interface IVisibleLine extends ILine {14 getDomNode(): HTMLElement | null;15 setDomNode(domNode: HTMLElement): void;16 /**17 * Return null if the HTML should not be touched.18 * Return the new HTML otherwise.19 */20 renderLine(lineNumber: number, deltaTop: number, viewportData: ViewportData, sb: IStringBuilder): boolean;21 /**22 * Layout the line.23 */24 layoutLine(lineNumber: number, deltaTop: number): void;25}26export interface ILine {27 onContentChanged(): void;28 onTokensChanged(): void;29}30export class RenderedLinesCollection<T extends ILine> {31 private readonly _createLine: () => T;32 private _lines!: T[];33 private _rendLineNumberStart!: number;34 constructor(createLine: () => T) {35 this._createLine = createLine;36 this._set(1, []);37 }38 public flush(): void {39 this._set(1, []);40 }41 _set(rendLineNumberStart: number, lines: T[]): void {42 this._lines = lines;43 this._rendLineNumberStart = rendLineNumberStart;44 }45 _get(): { rendLineNumberStart: number; lines: T[]; } {46 return {47 rendLineNumberStart: this._rendLineNumberStart,48 lines: this._lines49 };50 }51 /**52 * @returns Inclusive line number that is inside this collection53 */54 public getStartLineNumber(): number {55 return this._rendLineNumberStart;56 }57 /**58 * @returns Inclusive line number that is inside this collection59 */60 public getEndLineNumber(): number {61 return this._rendLineNumberStart + this._lines.length - 1;62 }63 public getCount(): number {64 return this._lines.length;65 }66 public getLine(lineNumber: number): T {67 const lineIndex = lineNumber - this._rendLineNumberStart;68 if (lineIndex < 0 || lineIndex >= this._lines.length) {69 throw new Error('Illegal value for lineNumber');70 }71 return this._lines[lineIndex];72 }73 /**74 * @returns Lines that were removed from this collection75 */76 public onLinesDeleted(deleteFromLineNumber: number, deleteToLineNumber: number): T[] | null {77 if (this.getCount() === 0) {78 // no lines79 return null;80 }81 const startLineNumber = this.getStartLineNumber();82 const endLineNumber = this.getEndLineNumber();83 if (deleteToLineNumber < startLineNumber) {84 // deleting above the viewport85 const deleteCnt = deleteToLineNumber - deleteFromLineNumber + 1;86 this._rendLineNumberStart -= deleteCnt;87 return null;88 }89 if (deleteFromLineNumber > endLineNumber) {90 // deleted below the viewport91 return null;92 }93 // Record what needs to be deleted94 let deleteStartIndex = 0;95 let deleteCount = 0;96 for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) {97 const lineIndex = lineNumber - this._rendLineNumberStart;98 if (deleteFromLineNumber <= lineNumber && lineNumber <= deleteToLineNumber) {99 // this is a line to be deleted100 if (deleteCount === 0) {101 // this is the first line to be deleted102 deleteStartIndex = lineIndex;103 deleteCount = 1;104 } else {105 deleteCount++;106 }107 }108 }109 // Adjust this._rendLineNumberStart for lines deleted above110 if (deleteFromLineNumber < startLineNumber) {111 // Something was deleted above112 let deleteAboveCount = 0;113 if (deleteToLineNumber < startLineNumber) {114 // the entire deleted lines are above115 deleteAboveCount = deleteToLineNumber - deleteFromLineNumber + 1;116 } else {117 deleteAboveCount = startLineNumber - deleteFromLineNumber;118 }119 this._rendLineNumberStart -= deleteAboveCount;120 }121 const deleted = this._lines.splice(deleteStartIndex, deleteCount);122 return deleted;123 }124 public onLinesChanged(changeFromLineNumber: number, changeToLineNumber: number): boolean {125 if (this.getCount() === 0) {126 // no lines127 return false;128 }129 const startLineNumber = this.getStartLineNumber();130 const endLineNumber = this.getEndLineNumber();131 let someoneNotified = false;132 for (let changedLineNumber = changeFromLineNumber; changedLineNumber <= changeToLineNumber; changedLineNumber++) {133 if (changedLineNumber >= startLineNumber && changedLineNumber <= endLineNumber) {134 // Notify the line135 this._lines[changedLineNumber - this._rendLineNumberStart].onContentChanged();136 someoneNotified = true;137 }138 }139 return someoneNotified;140 }141 public onLinesInserted(insertFromLineNumber: number, insertToLineNumber: number): T[] | null {142 if (this.getCount() === 0) {143 // no lines144 return null;145 }146 const insertCnt = insertToLineNumber - insertFromLineNumber + 1;147 const startLineNumber = this.getStartLineNumber();148 const endLineNumber = this.getEndLineNumber();149 if (insertFromLineNumber <= startLineNumber) {150 // inserting above the viewport151 this._rendLineNumberStart += insertCnt;152 return null;153 }154 if (insertFromLineNumber > endLineNumber) {155 // inserting below the viewport156 return null;157 }158 if (insertCnt + insertFromLineNumber > endLineNumber) {159 // insert inside the viewport in such a way that all remaining lines are pushed outside160 const deleted = this._lines.splice(insertFromLineNumber - this._rendLineNumberStart, endLineNumber - insertFromLineNumber + 1);161 return deleted;162 }163 // insert inside the viewport, push out some lines, but not all remaining lines164 const newLines: T[] = [];165 for (let i = 0; i < insertCnt; i++) {166 newLines[i] = this._createLine();167 }168 const insertIndex = insertFromLineNumber - this._rendLineNumberStart;169 const beforeLines = this._lines.slice(0, insertIndex);170 const afterLines = this._lines.slice(insertIndex, this._lines.length - insertCnt);171 const deletedLines = this._lines.slice(this._lines.length - insertCnt, this._lines.length);172 this._lines = beforeLines.concat(newLines).concat(afterLines);173 return deletedLines;174 }175 public onTokensChanged(ranges: { fromLineNumber: number; toLineNumber: number; }[]): boolean {176 if (this.getCount() === 0) {177 // no lines178 return false;179 }180 const startLineNumber = this.getStartLineNumber();181 const endLineNumber = this.getEndLineNumber();182 let notifiedSomeone = false;183 for (let i = 0, len = ranges.length; i < len; i++) {184 const rng = ranges[i];185 if (rng.toLineNumber < startLineNumber || rng.fromLineNumber > endLineNumber) {186 // range outside viewport187 continue;188 }189 const from = Math.max(startLineNumber, rng.fromLineNumber);190 const to = Math.min(endLineNumber, rng.toLineNumber);191 for (let lineNumber = from; lineNumber <= to; lineNumber++) {192 const lineIndex = lineNumber - this._rendLineNumberStart;193 this._lines[lineIndex].onTokensChanged();194 notifiedSomeone = true;195 }196 }197 return notifiedSomeone;198 }199}200export interface IVisibleLinesHost<T extends IVisibleLine> {201 createVisibleLine(): T;202}203export class VisibleLinesCollection<T extends IVisibleLine> {204 private readonly _host: IVisibleLinesHost<T>;205 public readonly domNode: FastDomNode<HTMLElement>;206 private readonly _linesCollection: RenderedLinesCollection<T>;207 constructor(host: IVisibleLinesHost<T>) {208 this._host = host;209 this.domNode = this._createDomNode();210 this._linesCollection = new RenderedLinesCollection<T>(() => this._host.createVisibleLine());211 }212 private _createDomNode(): FastDomNode<HTMLElement> {213 const domNode = createFastDomNode(document.createElement('div'));214 domNode.setClassName('view-layer');215 domNode.setPosition('absolute');216 domNode.domNode.setAttribute('role', 'presentation');217 domNode.domNode.setAttribute('aria-hidden', 'true');218 return domNode;219 }220 // ---- begin view event handlers221 public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean {222 if (e.hasChanged(EditorOption.layoutInfo)) {223 return true;224 }225 return false;226 }227 public onFlushed(e: viewEvents.ViewFlushedEvent): boolean {228 this._linesCollection.flush();229 // No need to clear the dom node because a full .innerHTML will occur in ViewLayerRenderer._render230 return true;231 }232 public onLinesChanged(e: viewEvents.ViewLinesChangedEvent): boolean {233 return this._linesCollection.onLinesChanged(e.fromLineNumber, e.toLineNumber);234 }235 public onLinesDeleted(e: viewEvents.ViewLinesDeletedEvent): boolean {236 const deleted = this._linesCollection.onLinesDeleted(e.fromLineNumber, e.toLineNumber);237 if (deleted) {238 // Remove from DOM239 for (let i = 0, len = deleted.length; i < len; i++) {240 const lineDomNode = deleted[i].getDomNode();241 if (lineDomNode) {242 this.domNode.domNode.removeChild(lineDomNode);243 }244 }245 }246 return true;247 }248 public onLinesInserted(e: viewEvents.ViewLinesInsertedEvent): boolean {249 const deleted = this._linesCollection.onLinesInserted(e.fromLineNumber, e.toLineNumber);250 if (deleted) {251 // Remove from DOM252 for (let i = 0, len = deleted.length; i < len; i++) {253 const lineDomNode = deleted[i].getDomNode();254 if (lineDomNode) {255 this.domNode.domNode.removeChild(lineDomNode);256 }257 }258 }259 return true;260 }261 public onScrollChanged(e: viewEvents.ViewScrollChangedEvent): boolean {262 return e.scrollTopChanged;263 }264 public onTokensChanged(e: viewEvents.ViewTokensChangedEvent): boolean {265 return this._linesCollection.onTokensChanged(e.ranges);266 }267 public onZonesChanged(e: viewEvents.ViewZonesChangedEvent): boolean {268 return true;269 }270 // ---- end view event handlers271 public getStartLineNumber(): number {272 return this._linesCollection.getStartLineNumber();273 }274 public getEndLineNumber(): number {275 return this._linesCollection.getEndLineNumber();276 }277 public getVisibleLine(lineNumber: number): T {278 return this._linesCollection.getLine(lineNumber);279 }280 public renderLines(viewportData: ViewportData): void {281 const inp = this._linesCollection._get();282 const renderer = new ViewLayerRenderer<T>(this.domNode.domNode, this._host, viewportData);283 const ctx: IRendererContext<T> = {284 rendLineNumberStart: inp.rendLineNumberStart,285 lines: inp.lines,286 linesLength: inp.lines.length287 };288 // Decide if this render will do a single update (single large .innerHTML) or many updates (inserting/removing dom nodes)289 const resCtx = renderer.render(ctx, viewportData.startLineNumber, viewportData.endLineNumber, viewportData.relativeVerticalOffset);290 this._linesCollection._set(resCtx.rendLineNumberStart, resCtx.lines);291 }292}293interface IRendererContext<T extends IVisibleLine> {294 rendLineNumberStart: number;295 lines: T[];296 linesLength: number;297}298class ViewLayerRenderer<T extends IVisibleLine> {299 readonly domNode: HTMLElement;300 readonly host: IVisibleLinesHost<T>;301 readonly viewportData: ViewportData;302 constructor(domNode: HTMLElement, host: IVisibleLinesHost<T>, viewportData: ViewportData) {303 this.domNode = domNode;304 this.host = host;305 this.viewportData = viewportData;306 }307 public render(inContext: IRendererContext<T>, startLineNumber: number, stopLineNumber: number, deltaTop: number[]): IRendererContext<T> {308 const ctx: IRendererContext<T> = {309 rendLineNumberStart: inContext.rendLineNumberStart,310 lines: inContext.lines.slice(0),311 linesLength: inContext.linesLength312 };313 if ((ctx.rendLineNumberStart + ctx.linesLength - 1 < startLineNumber) || (stopLineNumber < ctx.rendLineNumberStart)) {314 // There is no overlap whatsoever315 ctx.rendLineNumberStart = startLineNumber;316 ctx.linesLength = stopLineNumber - startLineNumber + 1;317 ctx.lines = [];318 for (let x = startLineNumber; x <= stopLineNumber; x++) {319 ctx.lines[x - startLineNumber] = this.host.createVisibleLine();320 }321 this._finishRendering(ctx, true, deltaTop);322 return ctx;323 }324 // Update lines which will remain untouched325 this._renderUntouchedLines(326 ctx,327 Math.max(startLineNumber - ctx.rendLineNumberStart, 0),328 Math.min(stopLineNumber - ctx.rendLineNumberStart, ctx.linesLength - 1),329 deltaTop,330 startLineNumber331 );332 if (ctx.rendLineNumberStart > startLineNumber) {333 // Insert lines before334 const fromLineNumber = startLineNumber;335 const toLineNumber = Math.min(stopLineNumber, ctx.rendLineNumberStart - 1);336 if (fromLineNumber <= toLineNumber) {337 this._insertLinesBefore(ctx, fromLineNumber, toLineNumber, deltaTop, startLineNumber);338 ctx.linesLength += toLineNumber - fromLineNumber + 1;339 }340 } else if (ctx.rendLineNumberStart < startLineNumber) {341 // Remove lines before342 const removeCnt = Math.min(ctx.linesLength, startLineNumber - ctx.rendLineNumberStart);343 if (removeCnt > 0) {344 this._removeLinesBefore(ctx, removeCnt);345 ctx.linesLength -= removeCnt;346 }347 }348 ctx.rendLineNumberStart = startLineNumber;349 if (ctx.rendLineNumberStart + ctx.linesLength - 1 < stopLineNumber) {350 // Insert lines after351 const fromLineNumber = ctx.rendLineNumberStart + ctx.linesLength;352 const toLineNumber = stopLineNumber;353 if (fromLineNumber <= toLineNumber) {354 this._insertLinesAfter(ctx, fromLineNumber, toLineNumber, deltaTop, startLineNumber);355 ctx.linesLength += toLineNumber - fromLineNumber + 1;356 }357 } else if (ctx.rendLineNumberStart + ctx.linesLength - 1 > stopLineNumber) {358 // Remove lines after359 const fromLineNumber = Math.max(0, stopLineNumber - ctx.rendLineNumberStart + 1);360 const toLineNumber = ctx.linesLength - 1;361 const removeCnt = toLineNumber - fromLineNumber + 1;362 if (removeCnt > 0) {363 this._removeLinesAfter(ctx, removeCnt);364 ctx.linesLength -= removeCnt;365 }366 }367 this._finishRendering(ctx, false, deltaTop);368 return ctx;369 }370 private _renderUntouchedLines(ctx: IRendererContext<T>, startIndex: number, endIndex: number, deltaTop: number[], deltaLN: number): void {371 const rendLineNumberStart = ctx.rendLineNumberStart;372 const lines = ctx.lines;373 for (let i = startIndex; i <= endIndex; i++) {374 const lineNumber = rendLineNumberStart + i;375 lines[i].layoutLine(lineNumber, deltaTop[lineNumber - deltaLN]);376 }377 }378 private _insertLinesBefore(ctx: IRendererContext<T>, fromLineNumber: number, toLineNumber: number, deltaTop: number[], deltaLN: number): void {379 const newLines: T[] = [];380 let newLinesLen = 0;381 for (let lineNumber = fromLineNumber; lineNumber <= toLineNumber; lineNumber++) {382 newLines[newLinesLen++] = this.host.createVisibleLine();383 }384 ctx.lines = newLines.concat(ctx.lines);385 }386 private _removeLinesBefore(ctx: IRendererContext<T>, removeCount: number): void {387 for (let i = 0; i < removeCount; i++) {388 const lineDomNode = ctx.lines[i].getDomNode();389 if (lineDomNode) {390 this.domNode.removeChild(lineDomNode);391 }392 }393 ctx.lines.splice(0, removeCount);394 }395 private _insertLinesAfter(ctx: IRendererContext<T>, fromLineNumber: number, toLineNumber: number, deltaTop: number[], deltaLN: number): void {396 const newLines: T[] = [];397 let newLinesLen = 0;398 for (let lineNumber = fromLineNumber; lineNumber <= toLineNumber; lineNumber++) {399 newLines[newLinesLen++] = this.host.createVisibleLine();400 }401 ctx.lines = ctx.lines.concat(newLines);402 }403 private _removeLinesAfter(ctx: IRendererContext<T>, removeCount: number): void {404 const removeIndex = ctx.linesLength - removeCount;405 for (let i = 0; i < removeCount; i++) {406 const lineDomNode = ctx.lines[removeIndex + i].getDomNode();407 if (lineDomNode) {408 this.domNode.removeChild(lineDomNode);409 }410 }411 ctx.lines.splice(removeIndex, removeCount);412 }413 private _finishRenderingNewLines(ctx: IRendererContext<T>, domNodeIsEmpty: boolean, newLinesHTML: string, wasNew: boolean[]): void {414 const lastChild = <HTMLElement>this.domNode.lastChild;415 if (domNodeIsEmpty || !lastChild) {416 this.domNode.innerHTML = newLinesHTML;417 } else {418 lastChild.insertAdjacentHTML('afterend', newLinesHTML);419 }420 let currChild = <HTMLElement>this.domNode.lastChild;421 for (let i = ctx.linesLength - 1; i >= 0; i--) {422 const line = ctx.lines[i];423 if (wasNew[i]) {424 line.setDomNode(currChild);425 currChild = <HTMLElement>currChild.previousSibling;426 }427 }428 }429 private _finishRenderingInvalidLines(ctx: IRendererContext<T>, invalidLinesHTML: string, wasInvalid: boolean[]): void {430 const hugeDomNode = document.createElement('div');431 hugeDomNode.innerHTML = invalidLinesHTML;432 for (let i = 0; i < ctx.linesLength; i++) {433 const line = ctx.lines[i];434 if (wasInvalid[i]) {435 const source = <HTMLElement>hugeDomNode.firstChild;436 const lineDomNode = line.getDomNode()!;437 lineDomNode.parentNode!.replaceChild(source, lineDomNode);438 line.setDomNode(source);439 }440 }441 }442 private static readonly _sb = createStringBuilder(100000);443 private _finishRendering(ctx: IRendererContext<T>, domNodeIsEmpty: boolean, deltaTop: number[]): void {444 const sb = ViewLayerRenderer._sb;445 const linesLength = ctx.linesLength;446 const lines = ctx.lines;447 const rendLineNumberStart = ctx.rendLineNumberStart;448 const wasNew: boolean[] = [];449 {450 sb.reset();451 let hadNewLine = false;452 for (let i = 0; i < linesLength; i++) {453 const line = lines[i];454 wasNew[i] = false;455 const lineDomNode = line.getDomNode();456 if (lineDomNode) {457 // line is not new458 continue;459 }460 const renderResult = line.renderLine(i + rendLineNumberStart, deltaTop[i], this.viewportData, sb);461 if (!renderResult) {462 // line does not need rendering463 continue;464 }465 wasNew[i] = true;466 hadNewLine = true;467 }468 if (hadNewLine) {469 this._finishRenderingNewLines(ctx, domNodeIsEmpty, sb.build(), wasNew);470 }471 }472 {473 sb.reset();474 let hadInvalidLine = false;475 const wasInvalid: boolean[] = [];476 for (let i = 0; i < linesLength; i++) {477 const line = lines[i];478 wasInvalid[i] = false;479 if (wasNew[i]) {480 // line was new481 continue;482 }483 const renderResult = line.renderLine(i + rendLineNumberStart, deltaTop[i], this.viewportData, sb);484 if (!renderResult) {485 // line does not need rendering486 continue;487 }488 wasInvalid[i] = true;489 hadInvalidLine = true;490 }491 if (hadInvalidLine) {492 this._finishRenderingInvalidLines(ctx, sb.build(), wasInvalid);493 }494 }495 }...

Full Screen

Full Screen

viewLayer.test.ts

Source:viewLayer.test.ts Github

copy

Full Screen

1/*---------------------------------------------------------------------------------------------2 * Copyright (c) Microsoft Corporation. All rights reserved.3 * Licensed under the MIT License. See License.txt in the project root for license information.4 *--------------------------------------------------------------------------------------------*/5import * as assert from 'assert';6import { ILine, RenderedLinesCollection } from 'vs/editor/browser/view/viewLayer';7class TestLine implements ILine {8 _pinged = false;9 constructor(public id: string) {10 }11 onContentChanged(): void {12 this._pinged = true;13 }14 onTokensChanged(): void {15 this._pinged = true;16 }17}18interface ILinesCollectionState {19 startLineNumber: number;20 lines: string[];21 pinged: boolean[];22}23function assertState(col: RenderedLinesCollection<TestLine>, state: ILinesCollectionState): void {24 let actualState: ILinesCollectionState = {25 startLineNumber: col.getStartLineNumber(),26 lines: [],27 pinged: []28 };29 for (let lineNumber = col.getStartLineNumber(); lineNumber <= col.getEndLineNumber(); lineNumber++) {30 actualState.lines.push(col.getLine(lineNumber).id);31 actualState.pinged.push(col.getLine(lineNumber)._pinged);32 }33 assert.deepEqual(actualState, state);34}35suite('RenderedLinesCollection onLinesDeleted', () => {36 function testOnModelLinesDeleted(deleteFromLineNumber: number, deleteToLineNumber: number, expectedDeleted: string[], expectedState: ILinesCollectionState): void {37 let col = new RenderedLinesCollection<TestLine>(() => new TestLine('new'));38 col._set(6, [39 new TestLine('old6'),40 new TestLine('old7'),41 new TestLine('old8'),42 new TestLine('old9')43 ]);44 let actualDeleted1 = col.onLinesDeleted(deleteFromLineNumber, deleteToLineNumber);45 let actualDeleted: string[] = [];46 if (actualDeleted1) {47 actualDeleted = actualDeleted1.map(line => line.id);48 }49 assert.deepEqual(actualDeleted, expectedDeleted);50 assertState(col, expectedState);51 }52 test('A1', () => {53 testOnModelLinesDeleted(3, 3, [], {54 startLineNumber: 5,55 lines: ['old6', 'old7', 'old8', 'old9'],56 pinged: [false, false, false, false]57 });58 });59 test('A2', () => {60 testOnModelLinesDeleted(3, 4, [], {61 startLineNumber: 4,62 lines: ['old6', 'old7', 'old8', 'old9'],63 pinged: [false, false, false, false]64 });65 });66 test('A3', () => {67 testOnModelLinesDeleted(3, 5, [], {68 startLineNumber: 3,69 lines: ['old6', 'old7', 'old8', 'old9'],70 pinged: [false, false, false, false]71 });72 });73 test('A4', () => {74 testOnModelLinesDeleted(3, 6, ['old6'], {75 startLineNumber: 3,76 lines: ['old7', 'old8', 'old9'],77 pinged: [false, false, false]78 });79 });80 test('A5', () => {81 testOnModelLinesDeleted(3, 7, ['old6', 'old7'], {82 startLineNumber: 3,83 lines: ['old8', 'old9'],84 pinged: [false, false]85 });86 });87 test('A6', () => {88 testOnModelLinesDeleted(3, 8, ['old6', 'old7', 'old8'], {89 startLineNumber: 3,90 lines: ['old9'],91 pinged: [false]92 });93 });94 test('A7', () => {95 testOnModelLinesDeleted(3, 9, ['old6', 'old7', 'old8', 'old9'], {96 startLineNumber: 3,97 lines: [],98 pinged: []99 });100 });101 test('A8', () => {102 testOnModelLinesDeleted(3, 10, ['old6', 'old7', 'old8', 'old9'], {103 startLineNumber: 3,104 lines: [],105 pinged: []106 });107 });108 test('B1', () => {109 testOnModelLinesDeleted(5, 5, [], {110 startLineNumber: 5,111 lines: ['old6', 'old7', 'old8', 'old9'],112 pinged: [false, false, false, false]113 });114 });115 test('B2', () => {116 testOnModelLinesDeleted(5, 6, ['old6'], {117 startLineNumber: 5,118 lines: ['old7', 'old8', 'old9'],119 pinged: [false, false, false]120 });121 });122 test('B3', () => {123 testOnModelLinesDeleted(5, 7, ['old6', 'old7'], {124 startLineNumber: 5,125 lines: ['old8', 'old9'],126 pinged: [false, false]127 });128 });129 test('B4', () => {130 testOnModelLinesDeleted(5, 8, ['old6', 'old7', 'old8'], {131 startLineNumber: 5,132 lines: ['old9'],133 pinged: [false]134 });135 });136 test('B5', () => {137 testOnModelLinesDeleted(5, 9, ['old6', 'old7', 'old8', 'old9'], {138 startLineNumber: 5,139 lines: [],140 pinged: []141 });142 });143 test('B6', () => {144 testOnModelLinesDeleted(5, 10, ['old6', 'old7', 'old8', 'old9'], {145 startLineNumber: 5,146 lines: [],147 pinged: []148 });149 });150 test('C1', () => {151 testOnModelLinesDeleted(6, 6, ['old6'], {152 startLineNumber: 6,153 lines: ['old7', 'old8', 'old9'],154 pinged: [false, false, false]155 });156 });157 test('C2', () => {158 testOnModelLinesDeleted(6, 7, ['old6', 'old7'], {159 startLineNumber: 6,160 lines: ['old8', 'old9'],161 pinged: [false, false]162 });163 });164 test('C3', () => {165 testOnModelLinesDeleted(6, 8, ['old6', 'old7', 'old8'], {166 startLineNumber: 6,167 lines: ['old9'],168 pinged: [false]169 });170 });171 test('C4', () => {172 testOnModelLinesDeleted(6, 9, ['old6', 'old7', 'old8', 'old9'], {173 startLineNumber: 6,174 lines: [],175 pinged: []176 });177 });178 test('C5', () => {179 testOnModelLinesDeleted(6, 10, ['old6', 'old7', 'old8', 'old9'], {180 startLineNumber: 6,181 lines: [],182 pinged: []183 });184 });185 test('D1', () => {186 testOnModelLinesDeleted(7, 7, ['old7'], {187 startLineNumber: 6,188 lines: ['old6', 'old8', 'old9'],189 pinged: [false, false, false]190 });191 });192 test('D2', () => {193 testOnModelLinesDeleted(7, 8, ['old7', 'old8'], {194 startLineNumber: 6,195 lines: ['old6', 'old9'],196 pinged: [false, false]197 });198 });199 test('D3', () => {200 testOnModelLinesDeleted(7, 9, ['old7', 'old8', 'old9'], {201 startLineNumber: 6,202 lines: ['old6'],203 pinged: [false]204 });205 });206 test('D4', () => {207 testOnModelLinesDeleted(7, 10, ['old7', 'old8', 'old9'], {208 startLineNumber: 6,209 lines: ['old6'],210 pinged: [false]211 });212 });213 test('E1', () => {214 testOnModelLinesDeleted(8, 8, ['old8'], {215 startLineNumber: 6,216 lines: ['old6', 'old7', 'old9'],217 pinged: [false, false, false]218 });219 });220 test('E2', () => {221 testOnModelLinesDeleted(8, 9, ['old8', 'old9'], {222 startLineNumber: 6,223 lines: ['old6', 'old7'],224 pinged: [false, false]225 });226 });227 test('E3', () => {228 testOnModelLinesDeleted(8, 10, ['old8', 'old9'], {229 startLineNumber: 6,230 lines: ['old6', 'old7'],231 pinged: [false, false]232 });233 });234 test('F1', () => {235 testOnModelLinesDeleted(9, 9, ['old9'], {236 startLineNumber: 6,237 lines: ['old6', 'old7', 'old8'],238 pinged: [false, false, false]239 });240 });241 test('F2', () => {242 testOnModelLinesDeleted(9, 10, ['old9'], {243 startLineNumber: 6,244 lines: ['old6', 'old7', 'old8'],245 pinged: [false, false, false]246 });247 });248 test('G1', () => {249 testOnModelLinesDeleted(10, 10, [], {250 startLineNumber: 6,251 lines: ['old6', 'old7', 'old8', 'old9'],252 pinged: [false, false, false, false]253 });254 });255 test('G2', () => {256 testOnModelLinesDeleted(10, 11, [], {257 startLineNumber: 6,258 lines: ['old6', 'old7', 'old8', 'old9'],259 pinged: [false, false, false, false]260 });261 });262 test('H1', () => {263 testOnModelLinesDeleted(11, 13, [], {264 startLineNumber: 6,265 lines: ['old6', 'old7', 'old8', 'old9'],266 pinged: [false, false, false, false]267 });268 });269});270suite('RenderedLinesCollection onLineChanged', () => {271 function testOnModelLineChanged(changedLineNumber: number, expectedPinged: boolean, expectedState: ILinesCollectionState): void {272 let col = new RenderedLinesCollection<TestLine>(() => new TestLine('new'));273 col._set(6, [274 new TestLine('old6'),275 new TestLine('old7'),276 new TestLine('old8'),277 new TestLine('old9')278 ]);279 let actualPinged = col.onLinesChanged(changedLineNumber, changedLineNumber);280 assert.deepEqual(actualPinged, expectedPinged);281 assertState(col, expectedState);282 }283 test('3', () => {284 testOnModelLineChanged(3, false, {285 startLineNumber: 6,286 lines: ['old6', 'old7', 'old8', 'old9'],287 pinged: [false, false, false, false]288 });289 });290 test('4', () => {291 testOnModelLineChanged(4, false, {292 startLineNumber: 6,293 lines: ['old6', 'old7', 'old8', 'old9'],294 pinged: [false, false, false, false]295 });296 });297 test('5', () => {298 testOnModelLineChanged(5, false, {299 startLineNumber: 6,300 lines: ['old6', 'old7', 'old8', 'old9'],301 pinged: [false, false, false, false]302 });303 });304 test('6', () => {305 testOnModelLineChanged(6, true, {306 startLineNumber: 6,307 lines: ['old6', 'old7', 'old8', 'old9'],308 pinged: [true, false, false, false]309 });310 });311 test('7', () => {312 testOnModelLineChanged(7, true, {313 startLineNumber: 6,314 lines: ['old6', 'old7', 'old8', 'old9'],315 pinged: [false, true, false, false]316 });317 });318 test('8', () => {319 testOnModelLineChanged(8, true, {320 startLineNumber: 6,321 lines: ['old6', 'old7', 'old8', 'old9'],322 pinged: [false, false, true, false]323 });324 });325 test('9', () => {326 testOnModelLineChanged(9, true, {327 startLineNumber: 6,328 lines: ['old6', 'old7', 'old8', 'old9'],329 pinged: [false, false, false, true]330 });331 });332 test('10', () => {333 testOnModelLineChanged(10, false, {334 startLineNumber: 6,335 lines: ['old6', 'old7', 'old8', 'old9'],336 pinged: [false, false, false, false]337 });338 });339 test('11', () => {340 testOnModelLineChanged(11, false, {341 startLineNumber: 6,342 lines: ['old6', 'old7', 'old8', 'old9'],343 pinged: [false, false, false, false]344 });345 });346});347suite('RenderedLinesCollection onLinesInserted', () => {348 function testOnModelLinesInserted(insertFromLineNumber: number, insertToLineNumber: number, expectedDeleted: string[], expectedState: ILinesCollectionState): void {349 let col = new RenderedLinesCollection<TestLine>(() => new TestLine('new'));350 col._set(6, [351 new TestLine('old6'),352 new TestLine('old7'),353 new TestLine('old8'),354 new TestLine('old9')355 ]);356 let actualDeleted1 = col.onLinesInserted(insertFromLineNumber, insertToLineNumber);357 let actualDeleted: string[] = [];358 if (actualDeleted1) {359 actualDeleted = actualDeleted1.map(line => line.id);360 }361 assert.deepEqual(actualDeleted, expectedDeleted);362 assertState(col, expectedState);363 }364 test('A1', () => {365 testOnModelLinesInserted(3, 3, [], {366 startLineNumber: 7,367 lines: ['old6', 'old7', 'old8', 'old9'],368 pinged: [false, false, false, false]369 });370 });371 test('A2', () => {372 testOnModelLinesInserted(3, 4, [], {373 startLineNumber: 8,374 lines: ['old6', 'old7', 'old8', 'old9'],375 pinged: [false, false, false, false]376 });377 });378 test('A3', () => {379 testOnModelLinesInserted(3, 5, [], {380 startLineNumber: 9,381 lines: ['old6', 'old7', 'old8', 'old9'],382 pinged: [false, false, false, false]383 });384 });385 test('A4', () => {386 testOnModelLinesInserted(3, 6, [], {387 startLineNumber: 10,388 lines: ['old6', 'old7', 'old8', 'old9'],389 pinged: [false, false, false, false]390 });391 });392 test('A5', () => {393 testOnModelLinesInserted(3, 7, [], {394 startLineNumber: 11,395 lines: ['old6', 'old7', 'old8', 'old9'],396 pinged: [false, false, false, false]397 });398 });399 test('A6', () => {400 testOnModelLinesInserted(3, 8, [], {401 startLineNumber: 12,402 lines: ['old6', 'old7', 'old8', 'old9'],403 pinged: [false, false, false, false]404 });405 });406 test('A7', () => {407 testOnModelLinesInserted(3, 9, [], {408 startLineNumber: 13,409 lines: ['old6', 'old7', 'old8', 'old9'],410 pinged: [false, false, false, false]411 });412 });413 test('A8', () => {414 testOnModelLinesInserted(3, 10, [], {415 startLineNumber: 14,416 lines: ['old6', 'old7', 'old8', 'old9'],417 pinged: [false, false, false, false]418 });419 });420 test('B1', () => {421 testOnModelLinesInserted(5, 5, [], {422 startLineNumber: 7,423 lines: ['old6', 'old7', 'old8', 'old9'],424 pinged: [false, false, false, false]425 });426 });427 test('B2', () => {428 testOnModelLinesInserted(5, 6, [], {429 startLineNumber: 8,430 lines: ['old6', 'old7', 'old8', 'old9'],431 pinged: [false, false, false, false]432 });433 });434 test('B3', () => {435 testOnModelLinesInserted(5, 7, [], {436 startLineNumber: 9,437 lines: ['old6', 'old7', 'old8', 'old9'],438 pinged: [false, false, false, false]439 });440 });441 test('B4', () => {442 testOnModelLinesInserted(5, 8, [], {443 startLineNumber: 10,444 lines: ['old6', 'old7', 'old8', 'old9'],445 pinged: [false, false, false, false]446 });447 });448 test('B5', () => {449 testOnModelLinesInserted(5, 9, [], {450 startLineNumber: 11,451 lines: ['old6', 'old7', 'old8', 'old9'],452 pinged: [false, false, false, false]453 });454 });455 test('B6', () => {456 testOnModelLinesInserted(5, 10, [], {457 startLineNumber: 12,458 lines: ['old6', 'old7', 'old8', 'old9'],459 pinged: [false, false, false, false]460 });461 });462 test('C1', () => {463 testOnModelLinesInserted(6, 6, [], {464 startLineNumber: 7,465 lines: ['old6', 'old7', 'old8', 'old9'],466 pinged: [false, false, false, false]467 });468 });469 test('C2', () => {470 testOnModelLinesInserted(6, 7, [], {471 startLineNumber: 8,472 lines: ['old6', 'old7', 'old8', 'old9'],473 pinged: [false, false, false, false]474 });475 });476 test('C3', () => {477 testOnModelLinesInserted(6, 8, [], {478 startLineNumber: 9,479 lines: ['old6', 'old7', 'old8', 'old9'],480 pinged: [false, false, false, false]481 });482 });483 test('C4', () => {484 testOnModelLinesInserted(6, 9, [], {485 startLineNumber: 10,486 lines: ['old6', 'old7', 'old8', 'old9'],487 pinged: [false, false, false, false]488 });489 });490 test('C5', () => {491 testOnModelLinesInserted(6, 10, [], {492 startLineNumber: 11,493 lines: ['old6', 'old7', 'old8', 'old9'],494 pinged: [false, false, false, false]495 });496 });497 test('D1', () => {498 testOnModelLinesInserted(7, 7, ['old9'], {499 startLineNumber: 6,500 lines: ['old6', 'new', 'old7', 'old8'],501 pinged: [false, false, false, false]502 });503 });504 test('D2', () => {505 testOnModelLinesInserted(7, 8, ['old8', 'old9'], {506 startLineNumber: 6,507 lines: ['old6', 'new', 'new', 'old7'],508 pinged: [false, false, false, false]509 });510 });511 test('D3', () => {512 testOnModelLinesInserted(7, 9, ['old7', 'old8', 'old9'], {513 startLineNumber: 6,514 lines: ['old6'],515 pinged: [false]516 });517 });518 test('D4', () => {519 testOnModelLinesInserted(7, 10, ['old7', 'old8', 'old9'], {520 startLineNumber: 6,521 lines: ['old6'],522 pinged: [false]523 });524 });525 test('E1', () => {526 testOnModelLinesInserted(8, 8, ['old9'], {527 startLineNumber: 6,528 lines: ['old6', 'old7', 'new', 'old8'],529 pinged: [false, false, false, false]530 });531 });532 test('E2', () => {533 testOnModelLinesInserted(8, 9, ['old8', 'old9'], {534 startLineNumber: 6,535 lines: ['old6', 'old7'],536 pinged: [false, false]537 });538 });539 test('E3', () => {540 testOnModelLinesInserted(8, 10, ['old8', 'old9'], {541 startLineNumber: 6,542 lines: ['old6', 'old7'],543 pinged: [false, false]544 });545 });546 test('F1', () => {547 testOnModelLinesInserted(9, 9, ['old9'], {548 startLineNumber: 6,549 lines: ['old6', 'old7', 'old8'],550 pinged: [false, false, false]551 });552 });553 test('F2', () => {554 testOnModelLinesInserted(9, 10, ['old9'], {555 startLineNumber: 6,556 lines: ['old6', 'old7', 'old8'],557 pinged: [false, false, false]558 });559 });560 test('G1', () => {561 testOnModelLinesInserted(10, 10, [], {562 startLineNumber: 6,563 lines: ['old6', 'old7', 'old8', 'old9'],564 pinged: [false, false, false, false]565 });566 });567 test('G2', () => {568 testOnModelLinesInserted(10, 11, [], {569 startLineNumber: 6,570 lines: ['old6', 'old7', 'old8', 'old9'],571 pinged: [false, false, false, false]572 });573 });574 test('H1', () => {575 testOnModelLinesInserted(11, 13, [], {576 startLineNumber: 6,577 lines: ['old6', 'old7', 'old8', 'old9'],578 pinged: [false, false, false, false]579 });580 });581});582suite('RenderedLinesCollection onTokensChanged', () => {583 function testOnModelTokensChanged(changedFromLineNumber: number, changedToLineNumber: number, expectedPinged: boolean, expectedState: ILinesCollectionState): void {584 let col = new RenderedLinesCollection<TestLine>(() => new TestLine('new'));585 col._set(6, [586 new TestLine('old6'),587 new TestLine('old7'),588 new TestLine('old8'),589 new TestLine('old9')590 ]);591 let actualPinged = col.onTokensChanged([{ fromLineNumber: changedFromLineNumber, toLineNumber: changedToLineNumber }]);592 assert.deepEqual(actualPinged, expectedPinged);593 assertState(col, expectedState);594 }595 test('A', () => {596 testOnModelTokensChanged(3, 3, false, {597 startLineNumber: 6,598 lines: ['old6', 'old7', 'old8', 'old9'],599 pinged: [false, false, false, false]600 });601 });602 test('B', () => {603 testOnModelTokensChanged(3, 5, false, {604 startLineNumber: 6,605 lines: ['old6', 'old7', 'old8', 'old9'],606 pinged: [false, false, false, false]607 });608 });609 test('C', () => {610 testOnModelTokensChanged(3, 6, true, {611 startLineNumber: 6,612 lines: ['old6', 'old7', 'old8', 'old9'],613 pinged: [true, false, false, false]614 });615 });616 test('D', () => {617 testOnModelTokensChanged(6, 6, true, {618 startLineNumber: 6,619 lines: ['old6', 'old7', 'old8', 'old9'],620 pinged: [true, false, false, false]621 });622 });623 test('E', () => {624 testOnModelTokensChanged(5, 10, true, {625 startLineNumber: 6,626 lines: ['old6', 'old7', 'old8', 'old9'],627 pinged: [true, true, true, true]628 });629 });630 test('F', () => {631 testOnModelTokensChanged(8, 9, true, {632 startLineNumber: 6,633 lines: ['old6', 'old7', 'old8', 'old9'],634 pinged: [false, false, true, true]635 });636 });637 test('G', () => {638 testOnModelTokensChanged(8, 11, true, {639 startLineNumber: 6,640 lines: ['old6', 'old7', 'old8', 'old9'],641 pinged: [false, false, true, true]642 });643 });644 test('H', () => {645 testOnModelTokensChanged(10, 10, false, {646 startLineNumber: 6,647 lines: ['old6', 'old7', 'old8', 'old9'],648 pinged: [false, false, false, false]649 });650 });651 test('I', () => {652 testOnModelTokensChanged(10, 11, false, {653 startLineNumber: 6,654 lines: ['old6', 'old7', 'old8', 'old9'],655 pinged: [false, false, false, false]656 });657 });...

Full Screen

Full Screen

command-apidoc.js

Source:command-apidoc.js Github

copy

Full Screen

1const { BaseCommand } = require('./base-command.js');2const BaseItem = require('lib/models/BaseItem');3const BaseModel = require('lib/BaseModel');4const { toTitleCase } = require('lib/string-utils.js');5const { reg } = require('lib/registry.js');6const markdownUtils = require('lib/markdownUtils');7const { Database } = require('lib/database.js');8class Command extends BaseCommand {9 usage() {10 return 'apidoc';11 }12 description() {13 return 'Build the API doc';14 }15 enabled() {16 return false;17 }18 createPropertiesTable(tableFields) {19 const headers = [20 { name: 'name', label: 'Name' },21 {22 name: 'type',23 label: 'Type',24 filter: value => {25 return Database.enumName('fieldType', value);26 },27 },28 { name: 'description', label: 'Description' },29 ];30 return markdownUtils.createMarkdownTable(headers, tableFields);31 }32 async action() {33 const models = [34 {35 type: BaseModel.TYPE_NOTE,36 },37 {38 type: BaseModel.TYPE_FOLDER,39 },40 {41 type: BaseModel.TYPE_RESOURCE,42 },43 {44 type: BaseModel.TYPE_TAG,45 },46 ];47 const lines = [];48 lines.push('# Joplin API');49 lines.push('');50 lines.push('');51 lines.push('In order to use it, you\'ll first need to find on which port the service is running. To do so, open the Web Clipper Options in Joplin and if the service is running it should tell you on which port. Normally it runs on port **41184**. If you want to find it programmatically, you may follow this kind of algorithm:');52 lines.push('');53 lines.push('```javascript');54 lines.push('let port = null;');55 lines.push('for (let portToTest = 41184; portToTest <= 41194; portToTest++) {');56 lines.push(' const result = pingPort(portToTest); // Call GET /ping');57 lines.push(' if (result == \'JoplinClipperServer\') {');58 lines.push(' port = portToTest; // Found the port');59 lines.push(' break;');60 lines.push(' }');61 lines.push('}');62 lines.push('```');63 lines.push('');64 lines.push('# Authorisation');65 lines.push('');66 lines.push('To prevent unauthorised applications from accessing the API, the calls must be authentified. To do so, you must provide a token as a query parameter for each API call. You can get this token from the Joplin desktop application, on the Web Clipper Options screen.');67 lines.push('');68 lines.push('This would be an example of valid cURL call using a token:');69 lines.push('');70 lines.push('\tcurl http://localhost:41184/notes?token=ABCD123ABCD123ABCD123ABCD123ABCD123');71 lines.push('');72 lines.push('In the documentation below, the token will not be specified every time however you will need to include it.');73 lines.push('');74 lines.push('# Using the API');75 lines.push('');76 lines.push('All the calls, unless noted otherwise, receives and send **JSON data**. For example to create a new note:');77 lines.push('');78 lines.push('\tcurl --data \'{ "title": "My note", "body": "Some note in **Markdown**"}\' http://localhost:41184/notes');79 lines.push('');80 lines.push('In the documentation below, the calls may include special parameters such as :id or :note_id. You would replace this with the item ID or note ID.');81 lines.push('');82 lines.push('For example, for the endpoint `DELETE /tags/:id/notes/:note_id`, to remove the tag with ID "ABCD1234" from the note with ID "EFGH789", you would run for example:');83 lines.push('');84 lines.push('\tcurl -X DELETE http://localhost:41184/tags/ABCD1234/notes/EFGH789');85 lines.push('');86 lines.push('The four verbs supported by the API are the following ones:');87 lines.push('');88 lines.push('* **GET**: To retrieve items (notes, notebooks, etc.).');89 lines.push('* **POST**: To create new items. In general most item properties are optional. If you omit any, a default value will be used.');90 lines.push('* **PUT**: To update an item. Note in a REST API, traditionally PUT is used to completely replace an item, however in this API it will only replace the properties that are provided. For example if you PUT {"title": "my new title"}, only the "title" property will be changed. The other properties will be left untouched (they won\'t be cleared nor changed).');91 lines.push('* **DELETE**: To delete items.');92 lines.push('');93 lines.push('# Filtering data');94 lines.push('');95 lines.push('You can change the fields that will be returned by the API using the `fields=` query parameter, which takes a list of comma separated fields. For example, to get the longitude and latitude of a note, use this:');96 lines.push('');97 lines.push('\tcurl http://localhost:41184/notes/ABCD123?fields=longitude,latitude');98 lines.push('');99 lines.push('To get the IDs only of all the tags:');100 lines.push('');101 lines.push('\tcurl http://localhost:41184/tags?fields=id');102 lines.push('');103 lines.push('# Error handling');104 lines.push('');105 lines.push('In case of an error, an HTTP status code >= 400 will be returned along with a JSON object that provides more info about the error. The JSON object is in the format `{ "error": "description of error" }`.');106 lines.push('');107 lines.push('# About the property types');108 lines.push('');109 lines.push('* Text is UTF-8.');110 lines.push('* All date/time are Unix timestamps in milliseconds.');111 lines.push('* Booleans are integer values 0 or 1.');112 lines.push('');113 lines.push('# Testing if the service is available');114 lines.push('');115 lines.push('Call **GET /ping** to check if the service is available. It should return "JoplinClipperServer" if it works.');116 lines.push('');117 lines.push('# Searching');118 lines.push('');119 lines.push('Call **GET /search?query=YOUR_QUERY** to search for notes. This end-point supports the `field` parameter which is recommended to use so that you only get the data that you need. The query syntax is as described in the main documentation: https://joplinapp.org/#searching');120 lines.push('');121 lines.push('To retrieve non-notes items, such as notebooks or tags, add a `type` parameter and set it to the required [item type name](#item-type-id). In that case, full text search will not be used - instead it will be a simple case-insensitive search. You can also use `*` as a wildcard. This is convenient for example to retrieve notebooks or tags by title.');122 lines.push('');123 lines.push('For example, to retrieve the notebook named `recipes`: **GET /search?query=recipes&type=folder**');124 lines.push('');125 lines.push('To retrieve all the tags that start with `project-`: **GET /search?query=project-*&type=tag**');126 lines.push('');127 lines.push('# Item type IDs');128 lines.push('');129 lines.push('Item type IDs might be refered to in certain object you will retrieve from the API. This is the correspondance between name and ID:');130 lines.push('');131 lines.push('Name | Value');132 lines.push('---- | -----');133 for (const t of BaseModel.typeEnum_) {134 const value = t[1];135 lines.push(`${BaseModel.modelTypeToName(value)} | ${value} `);136 }137 lines.push('');138 for (let i = 0; i < models.length; i++) {139 const model = models[i];140 const ModelClass = BaseItem.getClassByItemType(model.type);141 const tableName = ModelClass.tableName();142 let tableFields = reg.db().tableFields(tableName, { includeDescription: true });143 const singular = tableName.substr(0, tableName.length - 1);144 if (model.type === BaseModel.TYPE_NOTE) {145 tableFields = tableFields.slice();146 tableFields.push({147 name: 'body_html',148 type: Database.enumId('fieldType', 'text'),149 description: 'Note body, in HTML format',150 });151 tableFields.push({152 name: 'base_url',153 type: Database.enumId('fieldType', 'text'),154 description: 'If `body_html` is provided and contains relative URLs, provide the `base_url` parameter too so that all the URLs can be converted to absolute ones. The base URL is basically where the HTML was fetched from, minus the query (everything after the \'?\'). For example if the original page was `https://stackoverflow.com/search?q=%5Bjava%5D+test`, the base URL is `https://stackoverflow.com/search`.',155 });156 tableFields.push({157 name: 'image_data_url',158 type: Database.enumId('fieldType', 'text'),159 description: 'An image to attach to the note, in [Data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) format.',160 });161 tableFields.push({162 name: 'crop_rect',163 type: Database.enumId('fieldType', 'text'),164 description: 'If an image is provided, you can also specify an optional rectangle that will be used to crop the image. In format `{ x: x, y: y, width: width, height: height }`',165 });166 // tableFields.push({167 // name: 'tags',168 // type: Database.enumId('fieldType', 'text'),169 // description: 'Comma-separated list of tags. eg. `tag1,tag2`.',170 // });171 }172 lines.push(`# ${toTitleCase(tableName)}`);173 lines.push('');174 if (model.type === BaseModel.TYPE_FOLDER) {175 lines.push('This is actually a notebook. Internally notebooks are called "folders".');176 lines.push('');177 }178 lines.push('## Properties');179 lines.push('');180 lines.push(this.createPropertiesTable(tableFields));181 lines.push('');182 lines.push(`## GET /${tableName}`);183 lines.push('');184 lines.push(`Gets all ${tableName}`);185 lines.push('');186 if (model.type === BaseModel.TYPE_FOLDER) {187 lines.push('The folders are returned as a tree. The sub-notebooks of a notebook, if any, are under the `children` key.');188 lines.push('');189 }190 lines.push(`## GET /${tableName}/:id`);191 lines.push('');192 lines.push(`Gets ${singular} with ID :id`);193 lines.push('');194 if (model.type === BaseModel.TYPE_TAG) {195 lines.push('## GET /tags/:id/notes');196 lines.push('');197 lines.push('Gets all the notes with this tag.');198 lines.push('');199 }200 if (model.type === BaseModel.TYPE_NOTE) {201 lines.push('## GET /notes/:id/tags');202 lines.push('');203 lines.push('Gets all the tags attached to this note.');204 lines.push('');205 lines.push('## GET /notes/:id/resources');206 lines.push('');207 lines.push('Gets all the resources attached to this note.');208 lines.push('');209 }210 if (model.type === BaseModel.TYPE_FOLDER) {211 lines.push('## GET /folders/:id/notes');212 lines.push('');213 lines.push('Gets all the notes inside this folder.');214 lines.push('');215 }216 if (model.type === BaseModel.TYPE_RESOURCE) {217 lines.push('## GET /resources/:id/file');218 lines.push('');219 lines.push('Gets the actual file associated with this resource.');220 lines.push('');221 }222 lines.push(`## POST /${tableName}`);223 lines.push('');224 lines.push(`Creates a new ${singular}`);225 lines.push('');226 if (model.type === BaseModel.TYPE_RESOURCE) {227 lines.push('Creating a new resource is special because you also need to upload the file. Unlike other API calls, this one must have the "multipart/form-data" Content-Type. The file data must be passed to the "data" form field, and the other properties to the "props" form field. An example of a valid call with cURL would be:');228 lines.push('');229 lines.push('\tcurl -F \'data=@/path/to/file.jpg\' -F \'props={"title":"my resource title"}\' http://localhost:41184/resources');230 lines.push('');231 lines.push('The "data" field is required, while the "props" one is not. If not specified, default values will be used.');232 lines.push('');233 }234 if (model.type === BaseModel.TYPE_TAG) {235 lines.push('## POST /tags/:id/notes');236 lines.push('');237 lines.push('Post a note to this endpoint to add the tag to the note. The note data must at least contain an ID property (all other properties will be ignored).');238 lines.push('');239 }240 if (model.type === BaseModel.TYPE_NOTE) {241 lines.push('You can either specify the note body as Markdown by setting the `body` parameter, or in HTML by setting the `body_html`.');242 lines.push('');243 lines.push('Examples:');244 lines.push('');245 lines.push('* Create a note from some Markdown text');246 lines.push('');247 lines.push(' curl --data \'{ "title": "My note", "body": "Some note in **Markdown**"}\' http://127.0.0.1:41184/notes');248 lines.push('');249 lines.push('* Create a note from some HTML');250 lines.push('');251 lines.push(' curl --data \'{ "title": "My note", "body_html": "Some note in <b>HTML</b>"}\' http://127.0.0.1:41184/notes');252 lines.push('');253 lines.push('* Create a note and attach an image to it:');254 lines.push('');255 lines.push(' curl --data \'{ "title": "Image test", "body": "Here is Joplin icon:", "image_data_url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAANZJREFUeNoAyAA3/wFwtO3K6gUB/vz2+Prw9fj/+/r+/wBZKAAExOgF4/MC9ff+MRH6Ui4E+/0Bqc/zutj6AgT+/Pz7+vv7++nu82c4DlMqCvLs8goA/gL8/fz09fb59vXa6vzZ6vjT5fbn6voD/fwC8vX4UiT9Zi//APHyAP8ACgUBAPv5APz7BPj2+DIaC2o3E+3o6ywaC5fT6gD6/QD9/QEVf9kD+/dcLQgJA/7v8vqfwOf18wA1IAIEVycAyt//v9XvAPv7APz8LhoIAPz9Ri4OAgwARgx4W/6fVeEAAAAASUVORK5CYII="}\' http://127.0.0.1:41184/notes');256 lines.push('');257 lines.push('### Creating a note with a specific ID');258 lines.push('');259 lines.push('When a new note is created, it is automatically assigned a new unique ID so **normally you do not need to set the ID**. However, if for some reason you want to set it, you can supply it as the `id` property. It needs to be a **32 characters long string** in hexadecimal. **Make sure it is unique**, for example by generating it using whatever GUID function is available in your programming language.');260 lines.push('');261 lines.push(' curl --data \'{ "id": "00a87474082744c1a8515da6aa5792d2", "title": "My note with custom ID"}\' http://127.0.0.1:41184/notes');262 lines.push('');263 }264 lines.push(`## PUT /${tableName}/:id`);265 lines.push('');266 lines.push(`Sets the properties of the ${singular} with ID :id`);267 lines.push('');268 lines.push(`## DELETE /${tableName}/:id`);269 lines.push('');270 lines.push(`Deletes the ${singular} with ID :id`);271 lines.push('');272 if (model.type === BaseModel.TYPE_TAG) {273 lines.push('## DELETE /tags/:id/notes/:note_id');274 lines.push('');275 lines.push('Remove the tag from the note.');276 lines.push('');277 }278 }279 this.stdout(lines.join('\n'));280 }281}...

Full Screen

Full Screen

LineDetect.py

Source:LineDetect.py Github

copy

Full Screen

...19 'angle_limit': 15, # only lines which angle with horizontal or vertical lines are within this limit will be considered20 'max_num_lines': 5, # the max number of lines for outside each boundary of the bounding boxes, totoal number of lines will be max_num_lines*421 }22 # bbox = [x1, y1, x2, y2]23 def get_lines(self, img, bbox):24 img_h, img_w, _ = img.shape25 # find lines26 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)27 if self.config['enable_gaussian_blur']:28 blur_gray = cv2.GaussianBlur(gray,(self.config['blur_kernal_size'], self.config['blur_kernal_size']),0)29 else:30 blur_gray = gray31 edges = cv2.Canny( blur_gray, 32 self.config['canny_low_threshold'], 33 self.config['canny_high_threshold'])34 # Run Hough on edge detected image35 # Output "lines" is an array containing endpoints of detected line segments36 lines = cv2.HoughLinesP(edges, 37 self.config['hough_rho'], 38 np.pi / 180, 39 self.config['hough_threshold'], 40 np.array([]),41 self.config['hough_min_line_length'], 42 self.config['hough_max_line_gap'])43 44 #print('orig lines: ', lines)45 ##a = HoughBundler()46 ##lines1 = a.process_lines(lines, img)47 ##lines = np.array(lines1).reshape([-1,1,4])48 49 # remove the lines inside the bbox50 51 if type(lines)!=type(None):52 lines, _ = self.rm_lines_inside_bbox(lines, bbox)53 else:54 return None55 #print('rm inside lines: ', lines)56 # remove the lines intersect the bbox57 if lines.shape[0]:58 lines, _ = self.rm_lines_intersect_bbox(lines, bbox)59 else:60 return None61 62 #print('rm intersect lines: ', lines)63 64 if lines.shape[0]:65 lines_h, lines_v = self.get_horizontal_vertical_lines(lines, bbox)66 else:67 return None68 #print('lines_h: ', lines_h)69 #print('lines_v: ', lines_v)70 71 72 if lines_h.shape[0]:73 lines_h, _ = self.rm_lines_out_of_angle(lines_h, self.config['angle_limit'], orientation='x')74 if lines_v.shape[0]:75 lines_v, _ = self.rm_lines_out_of_angle(lines_v, self.config['angle_limit'], orientation='y')76 77 #print('rm angle lines_h: ', lines_h)78 #print('rm angle lines_v: ', lines_v)79 tmpData = self.prepare_lines_input( lines_h, 80 lines_v, 81 self.config['max_num_lines'], 82 bbox, 83 img_w, 84 img_h) 85 return tmpData86# 87 def rm_lines_inside_bbox(self, lines, bbox): 88 idx_to_rm = []89 bbx_x1, bbx_y1, bbx_x2, bbx_y2 = bbox90 for i, line in enumerate(lines):91 x1, y1, x2, y2 = line[0]92 if (x1 >= bbx_x1 and x1 <= bbx_x2) and \93 (x2 >= bbx_x1 and x2 <= bbx_x2) and \94 (y1 >= bbx_y1 and y1 <= bbx_y2) and \95 (y2 >= bbx_y1 and y2 <= bbx_y2):96 idx_to_rm += [i]97 return np.delete(lines,idx_to_rm,axis=0), lines[idx_to_rm,:,:]98 def one_segment(self, p, q, r):99 px,py = p 100 qx,qy = q 101 rx,ry = r 102 return qx<=max(px,rx) and qx>=min(px,rx) and qy<=max(py,ry) and qy>=min(py,ry)103 def orientation(self, p, q, r):104 px,py = p 105 qx,qy = q 106 rx,ry = r 107 val = int((qy-py)*(rx-qx)-(qx-px)*(ry-qy))108 if val ==0:109 return 0110 elif val >0:111 return 1112 else:113 return 2114 def do_intersect(self, p1,q1,p2,q2):115 o1 = self.orientation(p1,q1,p2)116 o2 = self.orientation(p1,q1,q2)117 o3 = self.orientation(p2,q2,p1)118 o4 = self.orientation(p2,q2,q1)119 if o1!=o2 and o3!=o4:120 return True121 if (o1==0 and self.one_segment(p1,p2,q1)) or \122 (o2==0 and self.one_segment(p1,q2,q1)) or \123 (o3==0 and self.one_segment(p2,p1,q2)) or \124 (o4==0 and self.one_segment(p2,q1,q2)):125 return True126 else:127 return False128 def rm_lines_intersect_bbox(self, lines, bbox):129 idx_to_rm = []130 bbx_x1, bbx_y1, bbx_x2, bbx_y2 = bbox131 for i, line in enumerate(lines):132 x1, y1, x2, y2 = line[0]133 if self.do_intersect((x1,y1),(x2,y2),(bbx_x1,bbx_y1),(bbx_x2,bbx_y1)) or \134 self.do_intersect((x1,y1),(x2,y2),(bbx_x1,bbx_y1),(bbx_x1,bbx_y2)) or \135 self.do_intersect((x1,y1),(x2,y2),(bbx_x2,bbx_y2),(bbx_x2,bbx_y1)) or \136 self.do_intersect((x1,y1),(x2,y2),(bbx_x2,bbx_y2),(bbx_x1,bbx_y2)):137 idx_to_rm += [i]138 return np.delete(lines,idx_to_rm,axis=0), lines[idx_to_rm,:,:]139 # divide all the lines into horizontal and vertial lines140 # lines directly above and below bbox are horizontal lines141 # lines directly on the left and right of bbox are vertical lines142 # one line can be horizontal and vertical at the same time143 def get_horizontal_vertical_lines(self, lines, bbox):144 idx_h = []145 idx_v = []146 bbx_x1, bbx_y1, bbx_x2, bbx_y2 = bbox147 for i, line in enumerate(lines):148 x1, y1, x2, y2 = line[0]149 if (x1 >= bbx_x1 and x1 <= bbx_x2) or (x2 >= bbx_x1 and x2 <= bbx_x2):150 idx_h += [i]151 if (y1 >= bbx_y1 and y1 <= bbx_y2) or (y2 >= bbx_y1 and y2 <= bbx_y2):152 idx_v += [i]153 return lines[idx_h,:,:], lines[idx_v,:,:]154 # return angle range is in (-90, 90)155 def angle(self, p, q):156 px,py = p 157 qx,qy = q ...

Full Screen

Full Screen

git.processCommits.js

Source:git.processCommits.js Github

copy

Full Screen

1"use strict";2var Q=require('q'),3 gitShow=require('git-show'),4 ss=require('simple-statistics'),5 async=require('async');6module.exports=function processCommits() {7 var _this=this;8 var log = require('./logger')(_this.module);9 var processPromise=Q.defer(), commits=_this.commits;10 log.info({cwd:process.cwd(), commits:commits}, "commits to be proccessed");11 if(!commits) {12 async.setImmediate(function rejectingPromise() {13 log.error({cwd:process.cwd(), err:new Error("missing commits argument")}, "error");14 processPromise.reject(new Error("missing argument"));15 });16 return processPromise.promise;17 }18 if( (!(commits instanceof Object)) || commits instanceof Array) {19 async.setImmediate(function rejectingPromise() {20 log.error({cwd:process.cwd(), err:new Error("first argument must be a hash")}, "error");21 processPromise.reject(new Error("first argument must be a hash"));22 });23 return processPromise.promise;24 }25 commits.commitAuthors=[];26 log.info({cwd:process.cwd(), commits:Object.keys(commits)}, "processing commits");27 async.eachLimit(Object.keys(commits), 1, function forEachCommit(commit,done) {28 var _commit=commit;29 log.info({ cwd:process.cwd(), commit:commits[_commit] }, "processing commit");30 if( _commit === "commitAuthors" ) {31 log.info({cwd:process.cwd(), authors:commits["commitAuthors"]}, "commit authors");32 return done();33 }34 var author=commits[_commit].author, 35 sha=_commit;36 37 if( author === undefined ) {38 log.info({cwd:process.cwd(), author:commits[_commit]}, "author");39 } else {40 log.info({cwd:process.cwd(), authors:commits["commitAuthors"]}, "adding author");41 if( commits["commitAuthors"].indexOf(author.email) === -1 ) {42 commits["commitAuthors"].push(author.email);43 }44 }45 log.info({cwd:process.cwd(), authors:commits["commitAuthors"]}, "commit authors");46 //process.chdir(_this.gitDir);47 gitShow({cwd:_this.gitDir, commit:sha})48 .then( function onGitShowSuccess(output) {49 log.info({cwd:process.cwd(), output: output}, "git show success");50 if( !output ) {51 delete commits[_commit];52 } else {53 commits[_commit].showStats=output;54 }55 done();56 }, function onGitShowError(err) {57 log.error({cwd:process.cwd(), err:err}, "error");58 done(err);59 });60 }, function afterAllCommitsGotten(err) {61 var authors=[], response;62 log.info({cwd:process.cwd(), commits:commits}, "calculating stats");63 if(err) {64 log.error({cwd:process.cwd(), err:err}, "error");65 return processPromise.reject(err.message);66 }67 var totalAverageLinesChanged=0, totalAverageLinesAdded=0, totalAverageLinesDeleted=0,68 totalVarianceLinesChanged=0, totalVarianceLinesAdded=0, totalVarianceLinesDeleted=0,69 totalStandardDeviationLinesChanged=0, totalStandardDeviationLinesAdded=0, totalStandardDeviationLinesDeleted=0;70 var linesChanged=[], linesDeleted=[], linesAdded=[], 71 varianceLinesChanged=[], varianceLinesDeleted=[], varianceLinesAdded=[],72 standardDeviationLinesChanged=[], standardDeviationLinesDeleted=[], standardDeviationLinesAdded=[], c;73 for( c in commits ) {74 if( "commitAuthors" === c ) continue;75 log.info({cwd:process.cwd(), hash:c, stats:commits[c].showStats}, "commit");76 linesChanged.push( commits[c].showStats.averageLinesChanged );77 linesDeleted.push( commits[c].showStats.averageLinesDeleted );78 linesAdded.push( commits[c].showStats.averageLinesAdded );79 varianceLinesChanged.push( commits[c].showStats.varianceLinesChanged );80 varianceLinesDeleted.push( commits[c].showStats.varianceLinesDeleted );81 varianceLinesAdded.push( commits[c].showStats.varianceLinesAdded );82 standardDeviationLinesChanged.push( commits[c].showStats.standardDeviationLinesChanged );83 standardDeviationLinesDeleted.push( commits[c].showStats.standardDeviationLinesDeleted );84 standardDeviationLinesAdded.push( commits[c].showStats.standardDeviationLinesAdded );85 }86 log.info({cwd:process.cwd(), lines:linesChanged}, "linesChanged");87 log.info({cwd:process.cwd(), lines:linesDeleted}, "linesDeleted");88 log.info({cwd:process.cwd(), lines:linesAdded}, "linesAdded");89 totalAverageLinesChanged=ss.mean(linesChanged);90 totalAverageLinesDeleted=ss.mean(linesDeleted);91 totalAverageLinesAdded=ss.mean(linesAdded);92 totalVarianceLinesChanged=ss.mean(varianceLinesChanged);93 totalVarianceLinesDeleted=ss.mean(varianceLinesDeleted);94 totalVarianceLinesAdded=ss.mean(varianceLinesAdded);95 totalStandardDeviationLinesChanged=ss.mean(standardDeviationLinesChanged);96 totalStandardDeviationLinesDeleted=ss.mean(standardDeviationLinesDeleted);97 totalStandardDeviationLinesAdded=ss.mean(standardDeviationLinesAdded);98 99 log.info({cwd:process.cwd(), commits:commits}, "commits");100 log.info({cwd:process.cwd(), authors:commits.commitAuthors}, "authors");101 commits.averageLinesChanged=totalAverageLinesChanged/commits.commitAuthors.length;102 commits.averageLinesDeleted=totalAverageLinesDeleted/commits.commitAuthors.length;103 commits.averageLinesAdded=totalAverageLinesAdded/commits.commitAuthors.length;104 105 commits.varianceLinesChanged=totalVarianceLinesChanged/commits.commitAuthors.length;106 commits.varianceLinesDeleted=totalVarianceLinesDeleted/commits.commitAuthors.length;107 commits.varianceLinesAdded=totalVarianceLinesAdded/commits.commitAuthors.length;108 109 commits.standardDeviationLinesChanged=totalStandardDeviationLinesChanged/commits.commitAuthors.length;110 commits.standardDeviationLinesDeleted=totalStandardDeviationLinesDeleted/commits.commitAuthors.length;111 commits.standardDeviationLinesAdded=totalStandardDeviationLinesAdded/commits.commitAuthors.length;112 response={113 "averageLinesChanged":1/commits.averageLinesChanged || 0,114 "averageLinesDeleted":1/commits.averageLinesDeleted || 0,115 "averageLinesAdded":1/commits.averageLinesAdded || 0,116 "standardDeviationLinesChanged":1/commits.standardDeviationLinesChanged || 0,117 "standardDeviationLinesDeleted":1/commits.standardDeviationLinesDeleted || 0,118 "standardDeviationLinesAdded":1/commits.standardDeviationLinesAdded || 0, 119 "varianceLinesChanged":1/commits.varianceLinesChanged || 0,120 "varianceLinesDeleted":1/commits.varianceLinesDeleted || 0,121 "varianceLinesAdded":1/commits.varianceLinesAdded || 0, 122 "numAuthors":commits.commitAuthors.length123 };124 log.info({cwd:process.cwd(), response:response}, "resolving promise");125 _this.processedCommits=response;126 log.info({cwd:process.cwd(), response:_this.processedCommits}, "resolving promise");127 processPromise.resolve("");128 });129 return processPromise.promise;...

Full Screen

Full Screen

diffLines.js

Source:diffLines.js Github

copy

Full Screen

1'use strict';2Object.defineProperty(exports, '__esModule', {3 value: true4});5exports.printDiffLines =6 exports.diffLinesUnified2 =7 exports.diffLinesUnified =8 exports.diffLinesRaw =9 void 0;10var _diffSequences = _interopRequireDefault(require('diff-sequences'));11var _cleanupSemantic = require('./cleanupSemantic');12var _joinAlignedDiffs = require('./joinAlignedDiffs');13var _normalizeDiffOptions = require('./normalizeDiffOptions');14function _interopRequireDefault(obj) {15 return obj && obj.__esModule ? obj : {default: obj};16}17/**18 * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.19 *20 * This source code is licensed under the MIT license found in the21 * LICENSE file in the root directory of this source tree.22 */23const isEmptyString = lines => lines.length === 1 && lines[0].length === 0;24const countChanges = diffs => {25 let a = 0;26 let b = 0;27 diffs.forEach(diff => {28 switch (diff[0]) {29 case _cleanupSemantic.DIFF_DELETE:30 a += 1;31 break;32 case _cleanupSemantic.DIFF_INSERT:33 b += 1;34 break;35 }36 });37 return {38 a,39 b40 };41};42const printAnnotation = (43 {44 aAnnotation,45 aColor,46 aIndicator,47 bAnnotation,48 bColor,49 bIndicator,50 includeChangeCounts,51 omitAnnotationLines52 },53 changeCounts54) => {55 if (omitAnnotationLines) {56 return '';57 }58 let aRest = '';59 let bRest = '';60 if (includeChangeCounts) {61 const aCount = String(changeCounts.a);62 const bCount = String(changeCounts.b); // Padding right aligns the ends of the annotations.63 const baAnnotationLengthDiff = bAnnotation.length - aAnnotation.length;64 const aAnnotationPadding = ' '.repeat(Math.max(0, baAnnotationLengthDiff));65 const bAnnotationPadding = ' '.repeat(Math.max(0, -baAnnotationLengthDiff)); // Padding left aligns the ends of the counts.66 const baCountLengthDiff = bCount.length - aCount.length;67 const aCountPadding = ' '.repeat(Math.max(0, baCountLengthDiff));68 const bCountPadding = ' '.repeat(Math.max(0, -baCountLengthDiff));69 aRest =70 aAnnotationPadding + ' ' + aIndicator + ' ' + aCountPadding + aCount;71 bRest =72 bAnnotationPadding + ' ' + bIndicator + ' ' + bCountPadding + bCount;73 }74 return (75 aColor(aIndicator + ' ' + aAnnotation + aRest) +76 '\n' +77 bColor(bIndicator + ' ' + bAnnotation + bRest) +78 '\n\n'79 );80};81const printDiffLines = (diffs, options) =>82 printAnnotation(options, countChanges(diffs)) +83 (options.expand84 ? (0, _joinAlignedDiffs.joinAlignedDiffsExpand)(diffs, options)85 : (0, _joinAlignedDiffs.joinAlignedDiffsNoExpand)(diffs, options)); // Compare two arrays of strings line-by-line. Format as comparison lines.86exports.printDiffLines = printDiffLines;87const diffLinesUnified = (aLines, bLines, options) =>88 printDiffLines(89 diffLinesRaw(90 isEmptyString(aLines) ? [] : aLines,91 isEmptyString(bLines) ? [] : bLines92 ),93 (0, _normalizeDiffOptions.normalizeDiffOptions)(options)94 ); // Given two pairs of arrays of strings:95// Compare the pair of comparison arrays line-by-line.96// Format the corresponding lines in the pair of displayable arrays.97exports.diffLinesUnified = diffLinesUnified;98const diffLinesUnified2 = (99 aLinesDisplay,100 bLinesDisplay,101 aLinesCompare,102 bLinesCompare,103 options104) => {105 if (isEmptyString(aLinesDisplay) && isEmptyString(aLinesCompare)) {106 aLinesDisplay = [];107 aLinesCompare = [];108 }109 if (isEmptyString(bLinesDisplay) && isEmptyString(bLinesCompare)) {110 bLinesDisplay = [];111 bLinesCompare = [];112 }113 if (114 aLinesDisplay.length !== aLinesCompare.length ||115 bLinesDisplay.length !== bLinesCompare.length116 ) {117 // Fall back to diff of display lines.118 return diffLinesUnified(aLinesDisplay, bLinesDisplay, options);119 }120 const diffs = diffLinesRaw(aLinesCompare, bLinesCompare); // Replace comparison lines with displayable lines.121 let aIndex = 0;122 let bIndex = 0;123 diffs.forEach(diff => {124 switch (diff[0]) {125 case _cleanupSemantic.DIFF_DELETE:126 diff[1] = aLinesDisplay[aIndex];127 aIndex += 1;128 break;129 case _cleanupSemantic.DIFF_INSERT:130 diff[1] = bLinesDisplay[bIndex];131 bIndex += 1;132 break;133 default:134 diff[1] = bLinesDisplay[bIndex];135 aIndex += 1;136 bIndex += 1;137 }138 });139 return printDiffLines(140 diffs,141 (0, _normalizeDiffOptions.normalizeDiffOptions)(options)142 );143}; // Compare two arrays of strings line-by-line.144exports.diffLinesUnified2 = diffLinesUnified2;145const diffLinesRaw = (aLines, bLines) => {146 const aLength = aLines.length;147 const bLength = bLines.length;148 const isCommon = (aIndex, bIndex) => aLines[aIndex] === bLines[bIndex];149 const diffs = [];150 let aIndex = 0;151 let bIndex = 0;152 const foundSubsequence = (nCommon, aCommon, bCommon) => {153 for (; aIndex !== aCommon; aIndex += 1) {154 diffs.push(155 new _cleanupSemantic.Diff(_cleanupSemantic.DIFF_DELETE, aLines[aIndex])156 );157 }158 for (; bIndex !== bCommon; bIndex += 1) {159 diffs.push(160 new _cleanupSemantic.Diff(_cleanupSemantic.DIFF_INSERT, bLines[bIndex])161 );162 }163 for (; nCommon !== 0; nCommon -= 1, aIndex += 1, bIndex += 1) {164 diffs.push(165 new _cleanupSemantic.Diff(_cleanupSemantic.DIFF_EQUAL, bLines[bIndex])166 );167 }168 };169 (0, _diffSequences.default)(aLength, bLength, isCommon, foundSubsequence); // After the last common subsequence, push remaining change items.170 for (; aIndex !== aLength; aIndex += 1) {171 diffs.push(172 new _cleanupSemantic.Diff(_cleanupSemantic.DIFF_DELETE, aLines[aIndex])173 );174 }175 for (; bIndex !== bLength; bIndex += 1) {176 diffs.push(177 new _cleanupSemantic.Diff(_cleanupSemantic.DIFF_INSERT, bLines[bIndex])178 );179 }180 return diffs;181};...

Full Screen

Full Screen

doc-md.js

Source:doc-md.js Github

copy

Full Screen

1const fs = require('fs'),2 path = require('path'),3 fsUtil = require('./fs-util'),4 readCommands = require('./read-commands'),5 commandDoc = function (command) {6 'use strict';7 const lines = [],8 indent = function (s, indent) {9 const result = [],10 filler = new Array(indent + 1).join(' ');11 if (Array.isArray(s)) {12 s.forEach(line => result.push(filler + line.trim()));13 } else {14 result.push(filler + s);15 }16 return result;17 },18 pushLines = function (arr) {19 arr.forEach(line => lines.push(line));20 };21 lines.push('# ' + command.command);22 lines.push('');23 lines.push(command.doc.description);24 lines.push('');25 lines.push('## Usage');26 lines.push('');27 lines.push('```bash');28 lines.push('claudia ' + command.command + ' {OPTIONS}');29 lines.push('```');30 lines.push('');31 lines.push('## Options');32 lines.push('');33 command.doc.args.forEach(argDoc => {34 const components = [],35 descLines = argDoc.description.split('\n');36 components.push('* `--' + argDoc.argument + '`: ');37 if (argDoc.optional) {38 components.push('(_optional_)');39 }40 components.push(descLines.shift());41 lines.push(components.join(' '));42 if (descLines.length) {43 pushLines(indent(descLines, 4));44 }45 if (argDoc.example) {46 pushLines(indent('* _For example_: ' + argDoc.example, 4));47 }48 if (argDoc.default) {49 pushLines(indent('* _Defaults to_: ' + argDoc.default, 4));50 }51 if (argDoc.since) {52 pushLines(indent('* _Introduced in version_: ' + argDoc.since, 4));53 }54 });55 lines.push('');56 return lines.join('\n');57 },58 index = function (commands) {59 'use strict';60 const lines = [];61 lines.push('# Claudia.js command line usage');62 lines.push('');63 lines.push('Deploy a Node.JS project to AWS as a lambda microservice, optionally updating APIs/event hooks.');64 lines.push('');65 lines.push('## Usage');66 lines.push('```bash');67 lines.push('claudia [command] {OPTIONS}');68 lines.push('```');69 lines.push('');70 lines.push('## Supported commands');71 lines.push('');72 Object.keys(commands)73 .map(key => commands[key])74 .sort((cmd1, cmd2) => cmd1.doc.priority - cmd2.doc.priority)75 .forEach(command => {76 const components = [],77 descLines = command.doc.description.split('\n');78 components.push('* [`');79 components.push(command.command);80 components.push('`](');81 components.push(command.command);82 components.push('.md) ');83 components.push(descLines.shift());84 lines.push(components.join(''));85 });86 lines.push('');87 lines.push('## Options:');88 lines.push('');89 lines.push(' * --help print this help screen');90 lines.push(' * --version print out the current version');91 lines.push(' * --quiet suppress output when executing commands');92 lines.push(' * --profile set AWS credentials profile');93 lines.push(' * --sts-role-arn set AWS STS Role for token-based authentication');94 lines.push(' * --mfa-serial set AWS MFA Serial Number (requires --sts-role-arn)');95 lines.push(' * --mfa-token set AWS MFA Token Code (requires --sts-role-arn)');96 lines.push(' * --mfa-duration set AWS MFA Duration in seconds (requires --sts-role-arn). Defaults to 3600');97 lines.push(' * --aws-client-timeout The number of milliseconds to wait before connection time out on AWS SDK Client. Defaults to two minutes (120000)');98 lines.push(' * --proxy set HTTP proxy for AWS commands');99 lines.push('');100 lines.push('Run with a command name to see options of a specific command, for example:');101 lines.push('```bash');102 lines.push('claudia create --help');103 lines.push('```');104 lines.push('');105 return lines.join('\n');106 },107 main = function () {108 'use strict';109 const docsDir = path.join(__dirname, '../../docs'),110 commands = readCommands();111 fsUtil.ensureCleanDir(docsDir);112 fs.writeFileSync(path.join(docsDir, 'README.md'), index(commands), 'utf8');113 Object.keys(commands).map(key => {114 const command = commands[key];115 fs.writeFileSync(path.join(docsDir, command.command + '.md'), commandDoc(command), 'utf8');116 });117 };...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1import {lines} from 'ts-auto-mock/extension';2lines(1, 2, 3, 4, 5);3import {lines} from 'ts-auto-mock/extension';4lines(1, 2, 3, 4, 5);5import {lines} from 'ts-auto-mock/extension';6lines(1, 2, 3, 4, 5);7import {lines} from 'ts-auto-mock/extension';8lines(1, 2, 3, 4, 5);9import {lines} from 'ts-auto-mock/extension';10lines(1, 2, 3, 4, 5);11import {lines} from 'ts-auto-mock/extension';12lines(1, 2, 3, 4, 5);13import {lines} from 'ts-auto-mock/extension';14lines(1, 2, 3, 4, 5);15import {lines} from 'ts-auto-mock/extension';16lines(1, 2, 3, 4, 5);17import {lines} from 'ts-auto-mock/extension';18lines(1, 2, 3, 4, 5);19import {lines} from 'ts-auto-mock/extension';20lines(1, 2, 3, 4, 5);21import {lines} from 'ts-auto-mock/extension';22lines(1,

Full Screen

Using AI Code Generation

copy

Full Screen

1import { lines } from 'ts-auto-mock/lines';2import { Test2 } from './test2';3export class Test1 {4 test2: Test2;5 constructor() {6 this.test2 = lines(Test2);7 }8}9import { lines } from 'ts-auto-mock/lines';10import { Test3 } from './test3';11export class Test2 {12 test3: Test3;13 constructor() {14 this.test3 = lines(Test3);15 }16}17import { lines } from 'ts-auto-mock/lines';18import { Test4 } from './test4';19export class Test3 {20 test4: Test4;21 constructor() {22 this.test4 = lines(Test4);23 }24}25import { lines } from 'ts-auto-mock/lines';26import { Test5 } from './test5';27export class Test4 {28 test5: Test5;29 constructor() {30 this.test5 = lines(Test5);31 }32}33import { lines } from 'ts-auto-mock/lines';34import { Test6 } from './test6';35export class Test5 {36 test6: Test6;37 constructor() {38 this.test6 = lines(Test6);39 }40}41import { lines } from 'ts-auto-mock/lines';42import { Test7 } from './test7';43export class Test6 {44 test7: Test7;45 constructor() {46 this.test7 = lines(Test7);47 }48}49import { lines } from 'ts-auto-mock/lines';50import { Test8 } from './test8';51export class Test7 {52 test8: Test8;53 constructor() {54 this.test8 = lines(Test8);55 }56}57import { lines } from 'ts-auto

Full Screen

Using AI Code Generation

copy

Full Screen

1import {lines} from 'ts-auto-mock';2import {lines} from 'ts-auto-mock';3export default function lines(name: string): number {4 return 1;5}6And then change the import in test1.js to:7import lines from 'ts-auto-mock';

Full Screen

Using AI Code Generation

copy

Full Screen

1import { lines } from 'ts-auto-mock';2lines('test1.ts', 'test2.ts');3import { lines } from 'ts-auto-mock';4lines('test1.ts', 'test2.ts');5import { lines } from 'ts-auto-mock';6lines('test1.ts', 'test2.ts');7import { lines } from 'ts-auto-mock';8lines('test1.ts', 'test2.ts');

Full Screen

Using AI Code Generation

copy

Full Screen

1import { lines } from 'ts-auto-mock';2const result = lines(`3 import {A} from './a';4 import {B} from './b';5 import {C} from './c';6 import {D} from './d';7 import {E} from './e';8 import {F} from './f';9 import {G} from './g';10 import {H} from './h';11 import {I} from './i';12 import {J} from './j';13 import {K} from './k';14 import {L} from './l';15 import {M} from './m';16 import {N} from './n';17 import {O} from './o';18 import {P} from './p';19 import {Q} from './q';20 import {R} from './r';21 import {S} from './s';22 import {T} from './t';23 import {U} from './u';24 import {V} from './v';25 import {W} from './w';26 import {X} from './x';27 import {Y} from './y';28 import {Z} from './z';29`);30console.log(result);31import {A} from './a';32import {B} from './b';33import {C} from './c';34import {D} from './d';35import {E} from './e';36import {F} from './f';37import {G} from './g';38import {H} from './h';39import {I} from './i';40import {J} from './j';41import {K} from './k';42import {L} from './l';43import {M} from './m';44import {N} from './n';45import {O} from './o';46import {P} from './p';47import {Q} from './q';48import {R} from './r';49import {S} from './s';50import {T} from './t';51import {U} from './u';52import {V} from './v';53import {W} from './w';54import {X} from './x';55import {Y} from './y';56import {Z} from './z';57import {A} from './a';58import {B} from './b';59import {C} from './c

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run ts-auto-mock automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful