16.7 KB796 lines
Blame
1/**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8import type {Hash} from '../../types';
9
10import {Ancestor, AncestorType} from '../render';
11import {TextRenderer} from '../renderText';
12
13/* Ported from fbcode/eden/scm/lib/renderdag/src/box_drawing.rs */
14
15type TestFixture = {
16 rows: Array<[Hash, string[], string]>;
17 reserve?: Hash[];
18};
19
20/*
21 A----B-D-----E----------F-\
22 \-C--/ \-W \-X \-Y-Z
23*/
24export const TEST_ANCESTORS: TestFixture = {
25 reserve: ['F'],
26 rows: [
27 ['Z', ['P:Y'], 'Z'],
28 ['Y', ['P:F'], 'Y'],
29 ['F', ['A:E'], 'F'],
30 ['X', ['P:E'], 'X'],
31 ['W', ['P:E'], 'W'],
32 ['E', ['A:D'], 'E'],
33 ['D', ['P:B', 'A:C'], 'D'],
34 ['C', ['A:A'], 'C'],
35 ['B', ['P:A'], 'B'],
36 ['A', [], 'A'],
37 ],
38};
39
40/* A-B-C */
41export const TEST_BASIC: TestFixture = {
42 rows: [
43 ['C', ['P:B'], 'C'],
44 ['B', ['P:A'], 'B'],
45 ['A', [], 'A'],
46 ],
47};
48
49/*
50
51 T /---------------N--O---\ T
52 / / \ \
53 /----E-F-\ /-------L--M--------P--\ S--U---\
54 A-B-C-D------G--H--I--J--K---------------Q--R---------V--W
55 \--N
56
57*/
58export const TEST_BRANCHES_AND_MERGES: TestFixture = {
59 rows: [
60 ['W', ['P:V'], 'W'],
61 ['V', ['P:R', 'P:U'], 'V'],
62 ['U', ['P:S', 'P:T'], 'U'],
63 ['T', ['P:E'], 'T'],
64 ['S', [], 'S'],
65 ['R', ['P:Q'], 'R'],
66 ['Q', ['P:K', 'P:P'], 'Q'],
67 ['P', ['P:M', 'P:O'], 'P'],
68 ['O', ['P:N'], 'O'],
69 ['N', ['P:F', 'P:J'], 'N'],
70 ['M', ['P:L'], 'M'],
71 ['L', ['P:H'], 'L'],
72 ['K', ['P:J'], 'K'],
73 ['J', ['P:I'], 'J'],
74 ['I', ['P:H'], 'I'],
75 ['H', ['P:G'], 'H'],
76 ['G', ['P:D', 'P:F'], 'G'],
77 ['F', ['P:E'], 'F'],
78 ['E', ['P:B'], 'E'],
79 ['D', ['P:C'], 'D'],
80 ['C', ['P:B'], 'C'],
81 ['B', ['P:A'], 'B'],
82 ['A', [], 'A'],
83 ],
84};
85
86/*
87
88 K
89 /|
90 F J
91 / /|
92 | E I
93 |/ /|
94 | D H
95 |/ /|
96 | C G
97 |/ /|
98 | B Z
99 |/
100 A
101
102*/
103export const TEST_DIFFERENT_ORDERS1: TestFixture = {
104 rows: [
105 ['K', ['P:F', 'P:J'], 'K'],
106 ['J', ['P:E', 'P:I'], 'J'],
107 ['I', ['P:D', 'P:H'], 'I'],
108 ['H', ['P:C', 'P:G'], 'H'],
109 ['G', ['P:B', 'P:Z'], 'G'],
110 ['F', ['P:A'], 'F'],
111 ['E', ['P:A'], 'E'],
112 ['D', ['P:A'], 'D'],
113 ['C', ['P:A'], 'C'],
114 ['B', ['P:A'], 'B'],
115 ['Z', [], 'Z'],
116 ['A', [], 'A'],
117 ],
118};
119
120export const TEST_DIFFERENT_ORDERS2: TestFixture = {
121 rows: [
122 ['K', ['P:F', 'P:J'], 'K'],
123 ['J', ['P:E', 'P:I'], 'J'],
124 ['I', ['P:D', 'P:H'], 'I'],
125 ['H', ['P:C', 'P:G'], 'H'],
126 ['G', ['P:B', 'P:Z'], 'G'],
127 ['Z', [], 'Z'],
128 ['B', ['P:A'], 'B'],
129 ['C', ['P:A'], 'C'],
130 ['D', ['P:A'], 'D'],
131 ['E', ['P:A'], 'E'],
132 ['F', ['P:A'], 'F'],
133 ['A', [], 'A'],
134 ],
135};
136
137export const TEST_DIFFERENT_ORDERS3: TestFixture = {
138 rows: [
139 ['K', ['P:F', 'P:J'], 'K'],
140 ['J', ['P:A'], 'J'],
141 ['F', ['P:E', 'P:I'], 'F'],
142 ['I', ['P:A'], 'I'],
143 ['E', ['P:D', 'P:H'], 'E'],
144 ['H', ['P:A'], 'H'],
145 ['D', ['P:C', 'P:G'], 'D'],
146 ['G', ['P:A'], 'G'],
147 ['C', ['P:B', 'P:Z'], 'C'],
148 ['Z', [], 'Z'],
149 ['B', ['P:A'], 'B'],
150 ['A', [], 'A'],
151 ],
152};
153
154export const TEST_DIFFERENT_ORDERS4: TestFixture = {
155 rows: [
156 ['K', ['P:F', 'P:J'], 'K'],
157 ['F', ['P:A'], 'F'],
158 ['J', ['P:E', 'P:I'], 'J'],
159 ['E', ['P:A'], 'E'],
160 ['I', ['P:D', 'P:H'], 'I'],
161 ['D', ['P:A'], 'D'],
162 ['H', ['P:C', 'P:G'], 'H'],
163 ['C', ['P:A'], 'C'],
164 ['G', ['P:B', 'P:Z'], 'G'],
165 ['Z', [], 'Z'],
166 ['B', ['P:A'], 'B'],
167 ['A', [], 'A'],
168 ],
169};
170
171/*
172
173 Y-\
174 Z-A-B-D-E-F
175 \-C-/
176
177*/
178export const TEST_LONG_MESSAGES: TestFixture = {
179 rows: [
180 [
181 'F',
182 ['P:C', 'P:E', '~'],
183 'F\nvery long message 1\nvery long message 2\nvery long message 3\n\nvery long message 4\nvery long message 5\nvery long message 6\n\n',
184 ],
185 ['E', ['P:D'], 'E'],
186 ['D', ['P:B'], 'D'],
187 ['C', ['P:B'], 'C\nlong message 1\nlong message 2\nlong message 3\n\n'],
188 ['B', ['P:A'], 'B'],
189 ['A', ['~'], 'A\nlong message 1\nlong message 2\nlong message 3\n\n'],
190 ],
191};
192
193/*
194
195 /-----\
196 / \
197 D /--C--\ I
198 / /---D---\ \
199 A-B----E----H-J
200 \---F---/ /
201 \--G--/ F
202
203*/
204export const TEST_OCTOPUS_BRANCH_AND_MERGE: TestFixture = {
205 rows: [
206 ['J', ['P:F', 'P:H', 'P:I'], 'J'],
207 ['I', ['P:D'], 'I'],
208 ['H', ['P:C', 'P:D', 'P:E', 'P:F', 'P:G'], 'H'],
209 ['G', ['P:B'], 'G'],
210 ['E', ['P:B'], 'E'],
211 ['D', ['P:A', 'P:B'], 'D'],
212 ['C', ['P:B'], 'C'],
213 ['F', ['P:B'], 'F'],
214 ['B', ['P:A'], 'B'],
215 ['A', [], 'A'],
216 ],
217};
218
219/*
220
221 A-B-C-F-G----\
222 D-E-/ \-W \-X-Y-Z
223
224*/
225export const TEST_RESERVED_COLUMN: TestFixture = {
226 reserve: ['G'],
227 rows: [
228 ['Z', ['P:Y'], 'Z'],
229 ['Y', ['P:X'], 'Y'],
230 ['X', ['P:G'], 'X'],
231 ['W', ['P:G'], 'W'],
232 ['G', ['P:F'], 'G'],
233 ['F', ['P:C', 'P:E'], 'F'],
234 ['E', ['P:D'], 'E'],
235 ['D', [], 'D'],
236 ['C', ['P:B'], 'C'],
237 ['B', ['P:A'], 'B'],
238 ['A', [], 'A'],
239 ],
240};
241
242/*
243
244 /-B-\ A-\
245 A D-E B--E
246 \-C-/ C-/
247
248*/
249export const TEST_SPLIT_PARENTS: TestFixture = {
250 reserve: ['B', 'D', 'C'],
251 rows: [
252 ['E', ['A:A', 'A:B', 'P:C', 'P:D'], 'E'],
253 ['D', ['P:B', 'P:C'], 'D'],
254 ['C', ['P:A'], 'C'],
255 ['B', ['P:A'], 'B'],
256 ['A', [], 'A'],
257 ],
258};
259
260/*
261
262 A-B-C D-E-\
263 F---I--J
264 X-D-H-/ \-K
265
266*/
267export const TEST_TERMINATIONS: TestFixture = {
268 reserve: ['E'],
269 rows: [
270 ['K', ['P:I'], 'K'],
271 ['J', ['P:I'], 'J'],
272 ['I', ['P:E', '~', 'P:H'], 'I'],
273 ['E', ['P:D'], 'E'],
274 ['H', ['P:D'], 'H'],
275 ['D', ['~'], 'D'],
276 ['C', ['P:B'], 'C'],
277 ['B', ['~'], 'B'],
278 ],
279};
280
281describe('renderText', () => {
282 it('renders TEST_ANCESTORS', () => {
283 expect(render(TEST_ANCESTORS)).toMatchInlineSnapshot(`
284 "
285 o Z
286 │
287 o Y
288 │
289 ╭─╯
290 o F
291 │
292 :
293 │ o X
294 │ │
295 ├─╯
296 │ o W
297 │ │
298 ├─╯
299 o E
300 │
301 :
302 o D
303 │
304 ├─╮
305 │ :
306 │ o C
307 │ │
308 │ :
309 o │ B
310 │ │
311 ├─╯
312 o A"
313 `);
314 });
315
316 it('renders TEST_BASIC', () => {
317 expect(render(TEST_BASIC)).toMatchInlineSnapshot(`
318 "
319 o C
320 │
321 o B
322 │
323 o A"
324 `);
325 });
326
327 it('renders TEST_BRANCHES_AND_MERGES', () => {
328 expect(render(TEST_BRANCHES_AND_MERGES)).toMatchInlineSnapshot(`
329 "
330 o W
331 │
332 o V
333 │
334 ├─╮
335 │ o U
336 │ │
337 │ ├─╮
338 │ │ o T
339 │ │ │
340 │ o │ S
341 │ │
342 o │ R
343 │ │
344 o │ Q
345 │ │
346 ├─╮ │
347 │ o │ P
348 │ │ │
349 │ ├───╮
350 │ │ │ o O
351 │ │ │ │
352 │ │ │ o N
353 │ │ │ │
354 │ │ │ ├─╮
355 │ o │ │ │ M
356 │ │ │ │ │
357 │ o │ │ │ L
358 │ │ │ │ │
359 o │ │ │ │ K
360 │ │ │ │ │
361 ├───────╯
362 o │ │ │ J
363 │ │ │ │
364 o │ │ │ I
365 │ │ │ │
366 ├─╯ │ │
367 o │ │ H
368 │ │ │
369 o │ │ G
370 │ │ │
371 ├─────╮
372 │ │ o F
373 │ │ │
374 │ ├─╯
375 │ o E
376 │ │
377 o │ D
378 │ │
379 o │ C
380 │ │
381 ├───╯
382 o B
383 │
384 o A"
385 `);
386 });
387
388 it('renders TEST_DIFFERENT_ORDERS1', () => {
389 expect(render(TEST_DIFFERENT_ORDERS1)).toMatchInlineSnapshot(`
390 "
391 o K
392 │
393 ├─╮
394 │ o J
395 │ │
396 │ ├─╮
397 │ │ o I
398 │ │ │
399 │ │ ├─╮
400 │ │ │ o H
401 │ │ │ │
402 │ │ │ ├─╮
403 │ │ │ │ o G
404 │ │ │ │ │
405 │ │ │ │ ├─╮
406 o │ │ │ │ │ F
407 │ │ │ │ │ │
408 │ o │ │ │ │ E
409 │ │ │ │ │ │
410 ├─╯ │ │ │ │
411 │ o │ │ │ D
412 │ │ │ │ │
413 ├───╯ │ │ │
414 │ o │ │ C
415 │ │ │ │
416 ├─────╯ │ │
417 │ o │ B
418 │ │ │
419 ├───────╯ │
420 │ o Z
421 │
422 o A"
423 `);
424 });
425
426 it('renders TEST_DIFFERENT_ORDERS2', () => {
427 expect(render(TEST_DIFFERENT_ORDERS2)).toMatchInlineSnapshot(`
428 "
429 o K
430 │
431 ├─╮
432 │ o J
433 │ │
434 │ ├─╮
435 │ │ o I
436 │ │ │
437 │ │ ├─╮
438 │ │ │ o H
439 │ │ │ │
440 │ │ │ ├─╮
441 │ │ │ │ o G
442 │ │ │ │ │
443 │ │ │ │ ├─╮
444 │ │ │ │ │ o Z
445 │ │ │ │ │
446 │ │ │ │ o B
447 │ │ │ │ │
448 │ │ │ o │ C
449 │ │ │ │ │
450 │ │ │ ├─╯
451 │ │ o │ D
452 │ │ │ │
453 │ │ ├─╯
454 │ o │ E
455 │ │ │
456 │ ├─╯
457 o │ F
458 │ │
459 ├─╯
460 o A"
461 `);
462 });
463
464 it('renders TEST_DIFFERENT_ORDERS3', () => {
465 expect(render(TEST_DIFFERENT_ORDERS3)).toMatchInlineSnapshot(`
466 "
467 o K
468 │
469 ├─╮
470 │ o J
471 │ │
472 o │ F
473 │ │
474 ├───╮
475 │ │ o I
476 │ │ │
477 │ ├─╯
478 o │ E
479 │ │
480 ├───╮
481 │ │ o H
482 │ │ │
483 │ ├─╯
484 o │ D
485 │ │
486 ├───╮
487 │ │ o G
488 │ │ │
489 │ ├─╯
490 o │ C
491 │ │
492 ├───╮
493 │ │ o Z
494 │ │
495 o │ B
496 │ │
497 ├─╯
498 o A"
499 `);
500 });
501
502 it('renders TEST_DIFFERENT_ORDERS4', () => {
503 expect(render(TEST_DIFFERENT_ORDERS4)).toMatchInlineSnapshot(`
504 "
505 o K
506 │
507 ├─╮
508 o │ F
509 │ │
510 │ o J
511 │ │
512 │ ├─╮
513 │ o │ E
514 │ │ │
515 ├─╯ │
516 │ o I
517 │ │
518 │ ╭─┤
519 │ │ o D
520 │ │ │
521 ├───╯
522 │ o H
523 │ │
524 │ ├─╮
525 │ o │ C
526 │ │ │
527 ├─╯ │
528 │ o G
529 │ │
530 │ ╭─┤
531 │ o │ Z
532 │ │
533 │ o B
534 │ │
535 ├───╯
536 o A"
537 `);
538 expect(render(TEST_DIFFERENT_ORDERS4, true)).toMatchInlineSnapshot(`
539 "
540 o K
541 │ # top pad
542 ├─╮ # link line
543 │ │ # pad line
544 --------------------
545 o F
546 │ # top pad
547 │ # pad line
548 --------------------
549 o J
550 │ # top pad
551 ├─╮ # link line
552 │ │ # pad line
553 --------------------
554 o E
555 │ # top pad
556 ╭─╯ # link line
557 │ # pad line
558 --------------------
559 o I
560 │ # top pad
561 ╭─┤ # link line
562 │ │ # pad line
563 --------------------
564 o D
565 │ # top pad
566 ╭───╯ # link line
567 │ # pad line
568 --------------------
569 o H
570 │ # top pad
571 ├─╮ # link line
572 │ │ # pad line
573 --------------------
574 o C
575 │ # top pad
576 ╭─╯ # link line
577 │ # pad line
578 --------------------
579 o G
580 │ # top pad
581 ╭─┤ # link line
582 │ │ # pad line
583 --------------------
584 o Z
585 # top pad
586 # pad line
587 --------------------
588 o B
589 │ # top pad
590 ╭───╯ # link line
591 │ # pad line
592 --------------------
593 o A
594 # top pad
595 # pad line
596 --------------------"
597 `);
598 });
599
600 it('renders TEST_LONG_MESSAGES', () => {
601 expect(render(TEST_LONG_MESSAGES)).toMatchInlineSnapshot(`
602 "
603 o F
604 │ very long message 1
605 ├─┬─╮ very long message 2
606 │ │ │ very long message 3
607 │ │ ~
608 │ │ very long message 4
609 │ │ very long message 5
610 │ │ very long message 6
611 │ │
612 │ o E
613 │ │
614 │ o D
615 │ │
616 o │ C
617 │ │ long message 1
618 ├─╯ long message 2
619 │ long message 3
620 │
621 o B
622 │
623 o A
624 │ long message 1
625 │ long message 2
626 ~ long message 3"
627 `);
628 });
629
630 it('renders TEST_OCTOPUS_BRANCH_AND_MERGE', () => {
631 expect(render(TEST_OCTOPUS_BRANCH_AND_MERGE)).toMatchInlineSnapshot(`
632 "
633 o J
634 │
635 ├─┬─╮
636 │ │ o I
637 │ │ │
638 │ o │ H
639 │ │ │
640 ╭─┼─┬─┬─╮
641 │ │ │ │ o G
642 │ │ │ │ │
643 │ │ │ o │ E
644 │ │ │ │ │
645 │ │ │ ├─╯
646 │ │ o │ D
647 │ │ │ │
648 │ │ ├─╮
649 │ o │ │ C
650 │ │ │ │
651 │ ├───╯
652 o │ │ F
653 │ │ │
654 ├─╯ │
655 o │ B
656 │ │
657 ├───╯
658 o A"
659 `);
660 });
661
662 it('renders TEST_RESERVED_COLUMN', () => {
663 expect(render(TEST_RESERVED_COLUMN)).toMatchInlineSnapshot(`
664 "
665 o Z
666 │
667 o Y
668 │
669 o X
670 │
671 ╭─╯
672 │ o W
673 │ │
674 ├─╯
675 o G
676 │
677 o F
678 │
679 ├─╮
680 │ o E
681 │ │
682 │ o D
683 │
684 o C
685 │
686 o B
687 │
688 o A"
689 `);
690 });
691
692 it('renders TEST_SPLIT_PARENTS', () => {
693 expect(render(TEST_SPLIT_PARENTS)).toMatchInlineSnapshot(`
694 "
695 o E
696 │
697 ╭─┬─┬─┤
698 : │ │ :
699 │ o │ │ D
700 │ │ │ │
701 ╭─┴─╮ │
702 │ o │ C
703 │ │ │
704 │ ├─╯
705 o │ B
706 │ │
707 ├───╯
708 o A"
709 `);
710 expect(render(TEST_SPLIT_PARENTS, true)).toMatchInlineSnapshot(`
711 "
712 o E
713 │ # top pad
714 ╭─┬─┬─┤ # link line
715 : │ │ : # pad line
716 --------------------
717 o D
718 │ # top pad
719 ╭─┴─╮ # link line
720 │ │ # pad line
721 --------------------
722 o C
723 │ # top pad
724 │ # link line
725 │ # pad line
726 --------------------
727 o B
728 │ # top pad
729 │ # link line
730 │ # pad line
731 --------------------
732 o A
733 # top pad
734 # pad line
735 --------------------"
736 `);
737 });
738
739 it('renders TEST_TERMINATIONS', () => {
740 expect(render(TEST_TERMINATIONS)).toMatchInlineSnapshot(`
741 "
742 o K
743 │
744 │ o J
745 │ │
746 ├─╯
747 o I
748 │
749 ╭─┼─╮
750 │ │ │
751 │ ~ │
752 │ │
753 o │ E
754 │ │
755 │ o H
756 │ │
757 ├───╯
758 o D
759 │
760 │
761 ~
762
763 o C
764 │
765 o B
766 │
767 │
768 ~"
769 `);
770 });
771});
772
773function render(fixture: TestFixture, debugLinkLineFromNode = false): string {
774 const {rows, reserve} = fixture;
775 const renderer = new TextRenderer({debugLinkLineFromNode});
776 if (reserve != null) {
777 for (const h of reserve) {
778 renderer.reserve(h);
779 }
780 }
781 const rendered = rows.map(([hash, parents, message]) => {
782 // Convert parents from string to Ancestor[]
783 const ancestors = parents.map(p => {
784 if (p.startsWith('P:')) {
785 return new Ancestor({hash: p.substring(2), type: AncestorType.Parent});
786 } else if (p.startsWith('A:')) {
787 return new Ancestor({hash: p.substring(2), type: AncestorType.Ancestor});
788 } else {
789 return new Ancestor({hash: undefined, type: AncestorType.Anonymous});
790 }
791 });
792 return renderer.nextRow(hash, ancestors, message.trimEnd() + '\n');
793 });
794 return '\n' + rendered.join('').trimEnd();
795}
796