1use std::borrow::Cow;
2
3use ratatui_core::{
4 buffer::Buffer,
5 layout::Rect,
6 style::{Color, Modifier, Style},
7 widgets::Widget,
8};
9use ratatui_widgets::{block::Block, clear::Clear};
10
11use crate::state;
12
13pub trait Screen {
24 type C: Cell;
26
27 fn cell(&self, row: u16, col: u16) -> Option<&Self::C>;
31 fn hide_cursor(&self) -> bool;
33 fn cursor_position(&self) -> (u16, u16);
44}
45
46pub trait Cell {
48 fn has_contents(&self) -> bool;
50 fn apply(&self, cell: &mut ratatui_core::buffer::Cell);
52}
53
54#[non_exhaustive]
84pub struct PseudoTerminal<'a, S> {
85 screen: &'a S,
86 pub(crate) block: Option<Block<'a>>,
87 style: Option<Style>,
88 pub(crate) cursor: Cursor,
89}
90
91#[non_exhaustive]
92pub struct Cursor {
93 pub(crate) show: bool,
94 pub(crate) symbol: Cow<'static, str>,
95 pub(crate) style: Style,
96 pub(crate) overlay_style: Style,
97}
98
99impl Cursor {
100 #[inline]
115 #[must_use]
116 pub fn symbol(mut self, symbol: impl Into<Cow<'static, str>>) -> Self {
117 self.symbol = symbol.into();
118 self
119 }
120
121 #[inline]
136 #[must_use]
137 pub const fn style(mut self, style: Style) -> Self {
138 self.style = style;
139 self
140 }
141
142 #[inline]
159 #[must_use]
160 pub const fn overlay_style(mut self, overlay_style: Style) -> Self {
161 self.overlay_style = overlay_style;
162 self
163 }
164
165 #[inline]
167 #[must_use]
168 pub const fn visibility(mut self, show: bool) -> Self {
169 self.show = show;
170 self
171 }
172
173 #[inline]
175 pub fn show(&mut self) {
176 self.show = true;
177 }
178
179 #[inline]
181 pub fn hide(&mut self) {
182 self.show = false;
183 }
184}
185
186impl Default for Cursor {
187 #[inline]
188 fn default() -> Self {
189 Self {
190 show: true,
191 symbol: Cow::Borrowed("\u{2588}"), style: Style::default().fg(Color::Gray),
193 overlay_style: Style::default().add_modifier(Modifier::REVERSED),
194 }
195 }
196}
197
198impl<'a, S: Screen> PseudoTerminal<'a, S> {
199 #[inline]
215 #[must_use]
216 pub fn new(screen: &'a S) -> Self {
217 PseudoTerminal {
218 screen,
219 block: None,
220 style: None,
221 cursor: Cursor::default(),
222 }
223 }
224
225 #[inline]
243 #[must_use]
244 pub fn block(mut self, block: Block<'a>) -> Self {
245 self.block = Some(block);
246 self
247 }
248
249 #[inline]
269 #[must_use]
270 pub fn cursor(mut self, cursor: Cursor) -> Self {
271 self.cursor = cursor;
272 self
273 }
274
275 #[inline]
292 #[must_use]
293 pub const fn style(mut self, style: Style) -> Self {
294 self.style = Some(style);
295 self
296 }
297
298 #[inline]
299 #[must_use]
300 pub const fn screen(&self) -> &S {
301 self.screen
302 }
303}
304
305impl<S: Screen> Widget for &PseudoTerminal<'_, S> {
306 #[inline]
307 fn render(self, area: Rect, buf: &mut Buffer) {
308 Clear.render(area, buf);
309 let area = self.block.as_ref().map_or(area, |b| {
310 let inner_area = b.inner(area);
311 b.clone().render(area, buf);
312 inner_area
313 });
314 state::handle(self, area, buf);
315 }
316}
317
318impl<S: Screen> Widget for PseudoTerminal<'_, S> {
319 #[inline]
320 fn render(self, area: Rect, buf: &mut Buffer) {
321 (&self).render(area, buf);
322 }
323}
324
325#[cfg(all(test, feature = "vt100"))]
326mod tests {
327 use ratatui::Terminal;
328 use ratatui_core::backend::TestBackend;
329 use ratatui_widgets::borders::Borders;
330
331 use super::*;
332
333 fn snapshot_typescript(stream: &[u8]) -> String {
334 let backend = TestBackend::new(80, 24);
335 let mut terminal = Terminal::new(backend).unwrap();
336 let mut parser = vt100::Parser::new(24, 80, 0);
337 parser.process(stream);
338 let pseudo_term = PseudoTerminal::new(parser.screen());
339 terminal
340 .draw(|f| {
341 f.render_widget(pseudo_term, f.area());
342 })
343 .unwrap();
344 format!("{:?}", terminal.backend().buffer())
345 }
346
347 #[test]
348 fn scrollback_cursor_not_rendered_when_off_screen() {
349 let backend = TestBackend::new(40, 4);
350 let mut terminal = Terminal::new(backend).unwrap();
351 let mut parser = vt100::Parser::new(4, 40, 20);
352
353 for i in 0..10 {
356 parser.process(format!("[scrollback line {i}]\r\n").as_bytes());
357 }
358 parser.screen_mut().set_scrollback(4);
359
360 let pseudo_term = PseudoTerminal::new(parser.screen());
361 terminal
362 .draw(|f| {
363 f.render_widget(pseudo_term, f.area());
364 })
365 .unwrap();
366
367 let buf = terminal.backend().buffer();
368 for row in 0..4 {
369 for col in 0..40 {
370 let cell = &buf[(col, row)];
371 assert!(
372 !cell.modifier.contains(Modifier::REVERSED),
373 "REVERSED cursor style should not appear at ({col}, {row}) \
374 when cursor is off-screen due to scrollback"
375 );
376 }
377 }
378 let view = format!("{:?}", terminal.backend().buffer());
379 insta::assert_snapshot!(view);
380 }
381
382 #[test]
383 fn scrollback_partial_cursor_visible_at_adjusted_row() {
384 let backend = TestBackend::new(40, 6);
385 let mut terminal = Terminal::new(backend).unwrap();
386 let mut parser = vt100::Parser::new(6, 40, 20);
387
388 parser.process(b"[scrollback: hidden 1]\r\n");
391 parser.process(b"[scrollback: hidden 2]\r\n");
392 parser.process(b"[scrollback: shown at row 0]\r\n");
393 parser.process(b"[draw-0: cursor row]\r\n");
394 parser.process(b"[draw-1]\r\n");
395 parser.process(b"[draw-2]\r\n");
396 parser.process(b"[draw-3]\r\n");
397 parser.process(b"[draw-4]\r\n");
398 parser.process(b"\x1b[H");
399
400 parser.screen_mut().set_scrollback(1);
403
404 let pseudo_term = PseudoTerminal::new(parser.screen());
405 terminal
406 .draw(|f| {
407 f.render_widget(pseudo_term, f.area());
408 })
409 .unwrap();
410
411 let buf = terminal.backend().buffer();
412 for col in 0..40 {
413 let cell = &buf[(col, 0)];
414 assert!(
415 !cell.modifier.contains(Modifier::REVERSED),
416 "scrollback row 0 at col {col} should not have cursor styling"
417 );
418 }
419 let cursor_cell = &buf[(0, 1)];
420 assert!(
421 cursor_cell.modifier.contains(Modifier::REVERSED),
422 "cursor should render at visible row 1 (adjusted from drawing row 0)"
423 );
424 let view = format!("{:?}", terminal.backend().buffer());
425 insta::assert_snapshot!(view);
426 }
427
428 #[test]
429 fn scrollback_hide_cursor_suppresses_rendering() {
430 let backend = TestBackend::new(40, 6);
431 let mut terminal = Terminal::new(backend).unwrap();
432 let mut parser = vt100::Parser::new(6, 40, 20);
433
434 for i in 0..8 {
435 parser.process(format!("line {i}\r\n").as_bytes());
436 }
437 parser.process(b"\x1b[H");
438 parser.process(b"\x1b[?25l");
440 parser.screen_mut().set_scrollback(1);
441
442 let pseudo_term = PseudoTerminal::new(parser.screen());
443 terminal
444 .draw(|f| {
445 f.render_widget(pseudo_term, f.area());
446 })
447 .unwrap();
448
449 let buf = terminal.backend().buffer();
450 for row in 0..6 {
451 for col in 0..40 {
452 let cell = &buf[(col, row)];
453 assert!(
454 !cell.modifier.contains(Modifier::REVERSED),
455 "hidden cursor should not style ({col}, {row}) even with scrollback"
456 );
457 }
458 }
459 }
460
461 #[test]
462 fn scrollback_cursor_with_block() {
463 let backend = TestBackend::new(42, 8);
464 let mut terminal = Terminal::new(backend).unwrap();
465 let mut parser = vt100::Parser::new(6, 40, 20);
466
467 for i in 0..8 {
468 parser.process(format!("line {i}\r\n").as_bytes());
469 }
470 parser.process(b"\x1b[H");
471 parser.screen_mut().set_scrollback(1);
472
473 let block = Block::default().borders(Borders::ALL).title("pty");
474 let pseudo_term = PseudoTerminal::new(parser.screen()).block(block);
475 terminal
476 .draw(|f| {
477 f.render_widget(pseudo_term, f.area());
478 })
479 .unwrap();
480
481 let buf = terminal.backend().buffer();
485 let scrollback_cell = &buf[(1, 1)];
486 assert!(
487 !scrollback_cell.modifier.contains(Modifier::REVERSED),
488 "scrollback row inside block should not have cursor styling"
489 );
490 let cursor_cell = &buf[(1, 2)];
491 assert!(
492 cursor_cell.modifier.contains(Modifier::REVERSED),
493 "cursor should render at inner row 1 (buf row 2) with block border"
494 );
495 }
496
497 #[test]
498 fn empty_actions() {
499 let backend = TestBackend::new(80, 24);
500 let mut terminal = Terminal::new(backend).unwrap();
501 let mut parser = vt100::Parser::new(24, 80, 0);
502 parser.process(b" ");
503 let pseudo_term = PseudoTerminal::new(parser.screen());
504 terminal
505 .draw(|f| {
506 f.render_widget(pseudo_term, f.area());
507 })
508 .unwrap();
509 let view = format!("{:?}", terminal.backend().buffer());
510 insta::assert_snapshot!(view);
511 }
512 #[test]
513 fn boundary_rows_overshot_no_panic() {
514 let stream = include_bytes!("../test/typescript/simple_ls.typescript");
515 let backend = TestBackend::new(80, 4);
517 let mut terminal = Terminal::new(backend).unwrap();
518 let mut parser = vt100::Parser::new(24, 80, 0);
519 parser.process(stream);
520 let pseudo_term = PseudoTerminal::new(parser.screen());
521 terminal
522 .draw(|f| {
523 f.render_widget(pseudo_term, f.area());
524 })
525 .unwrap();
526 let view = format!("{:?}", terminal.backend().buffer());
527 insta::assert_snapshot!(view);
528 }
529
530 #[test]
531 fn simple_ls() {
532 let stream = include_bytes!("../test/typescript/simple_ls.typescript");
533 let view = snapshot_typescript(stream);
534 insta::assert_snapshot!(view);
535 }
536 #[test]
537 fn simple_cursor_alternate_symbol() {
538 let stream = include_bytes!("../test/typescript/simple_ls.typescript");
539 let backend = TestBackend::new(80, 24);
540 let mut terminal = Terminal::new(backend).unwrap();
541 let mut parser = vt100::Parser::new(24, 80, 0);
542 let cursor = Cursor::default().symbol("|");
543 parser.process(stream);
544 let pseudo_term = PseudoTerminal::new(parser.screen()).cursor(cursor);
545 terminal
546 .draw(|f| {
547 f.render_widget(pseudo_term, f.area());
548 })
549 .unwrap();
550 let view = format!("{:?}", terminal.backend().buffer());
551 insta::assert_snapshot!(view);
552 }
553 #[test]
554 fn simple_cursor_styled() {
555 let stream = include_bytes!("../test/typescript/simple_ls.typescript");
556 let backend = TestBackend::new(80, 24);
557 let mut terminal = Terminal::new(backend).unwrap();
558 let mut parser = vt100::Parser::new(24, 80, 0);
559 let style = Style::default().bg(Color::Cyan).fg(Color::LightRed);
560 let cursor = Cursor::default().symbol("|").style(style);
561 parser.process(stream);
562 let pseudo_term = PseudoTerminal::new(parser.screen()).cursor(cursor);
563 terminal
564 .draw(|f| {
565 f.render_widget(pseudo_term, f.area());
566 })
567 .unwrap();
568 let view = format!("{:?}", terminal.backend().buffer());
569 insta::assert_snapshot!(view);
570 }
571 #[test]
572 fn simple_cursor_hide() {
573 let stream = include_bytes!("../test/typescript/simple_ls.typescript");
574 let backend = TestBackend::new(80, 24);
575 let mut terminal = Terminal::new(backend).unwrap();
576 let mut parser = vt100::Parser::new(24, 80, 0);
577 let cursor = Cursor::default().visibility(false);
578 parser.process(stream);
579 let pseudo_term = PseudoTerminal::new(parser.screen()).cursor(cursor);
580 terminal
581 .draw(|f| {
582 f.render_widget(pseudo_term, f.area());
583 })
584 .unwrap();
585 let view = format!("{:?}", terminal.backend().buffer());
586 insta::assert_snapshot!(view);
587 }
588 #[test]
589 fn simple_cursor_hide_alt() {
590 let stream = include_bytes!("../test/typescript/simple_ls.typescript");
591 let backend = TestBackend::new(80, 24);
592 let mut terminal = Terminal::new(backend).unwrap();
593 let mut parser = vt100::Parser::new(24, 80, 0);
594 let mut cursor = Cursor::default();
595 cursor.hide();
596 parser.process(stream);
597 let pseudo_term = PseudoTerminal::new(parser.screen()).cursor(cursor);
598 terminal
599 .draw(|f| {
600 f.render_widget(pseudo_term, f.area());
601 })
602 .unwrap();
603 let view = format!("{:?}", terminal.backend().buffer());
604 insta::assert_snapshot!(view);
605 }
606 #[test]
607 fn overlapping_cursor() {
608 let stream = include_bytes!("../test/typescript/overlapping_cursor.typescript");
609 let view = snapshot_typescript(stream);
610 insta::assert_snapshot!(view);
611 }
612 #[test]
613 fn overlapping_cursor_alternate_style() {
614 let stream = include_bytes!("../test/typescript/overlapping_cursor.typescript");
615 let backend = TestBackend::new(80, 24);
616 let mut terminal = Terminal::new(backend).unwrap();
617 let mut parser = vt100::Parser::new(24, 80, 0);
618 let style = Style::default().bg(Color::Cyan).fg(Color::LightRed);
619 let cursor = Cursor::default().overlay_style(style);
620 parser.process(stream);
621 let pseudo_term = PseudoTerminal::new(parser.screen()).cursor(cursor);
622 terminal
623 .draw(|f| {
624 f.render_widget(pseudo_term, f.area());
625 })
626 .unwrap();
627 let view = format!("{:?}", terminal.backend().buffer());
628 insta::assert_snapshot!(view);
629 }
630 #[test]
631 fn simple_ls_with_block() {
632 let stream = include_bytes!("../test/typescript/simple_ls.typescript");
633 let backend = TestBackend::new(100, 24);
634 let mut terminal = Terminal::new(backend).unwrap();
635 let mut parser = vt100::Parser::new(24, 80, 0);
636 parser.process(stream);
637 let block = Block::default().borders(Borders::ALL).title("ls");
638 let pseudo_term = PseudoTerminal::new(parser.screen()).block(block);
639 terminal
640 .draw(|f| {
641 f.render_widget(pseudo_term, f.area());
642 })
643 .unwrap();
644 let view = format!("{:?}", terminal.backend().buffer());
645 insta::assert_snapshot!(view);
646 }
647 #[test]
648 fn simple_ls_no_style_from_block() {
649 let stream = include_bytes!("../test/typescript/simple_ls.typescript");
650 let backend = TestBackend::new(100, 24);
651 let mut terminal = Terminal::new(backend).unwrap();
652 let mut parser = vt100::Parser::new(24, 80, 0);
653 parser.process(stream);
654 let block = Block::default()
655 .borders(Borders::ALL)
656 .style(Style::default().add_modifier(Modifier::BOLD))
657 .title("ls");
658 let pseudo_term = PseudoTerminal::new(parser.screen()).block(block);
659 terminal
660 .draw(|f| {
661 f.render_widget(pseudo_term, f.area());
662 })
663 .unwrap();
664 let view = format!("{:?}", terminal.backend().buffer());
665 insta::assert_snapshot!(view);
666 }
667 #[test]
668 fn italic_text() {
669 let stream = b"[3mThis line will be displayed in italic.[0m This should have no style.";
670 let view = snapshot_typescript(stream);
671 insta::assert_snapshot!(view);
672 }
673 #[test]
674 fn underlined_text() {
675 let stream =
676 b"[4mThis line will be displayed with an underline.[0m This should have no style.";
677 let view = snapshot_typescript(stream);
678 insta::assert_snapshot!(view);
679 }
680 #[test]
681 fn bold_text() {
682 let stream = b"[1mThis line will be displayed bold.[0m This should have no style.";
683 let view = snapshot_typescript(stream);
684 insta::assert_snapshot!(view);
685 }
686 #[test]
687 fn inverse_text() {
688 let stream = b"[7mThis line will be displayed inversed.[0m This should have no style.";
689 let view = snapshot_typescript(stream);
690 insta::assert_snapshot!(view);
691 }
692 #[test]
693 fn dim_text() {
694 let stream =
695 b"\x1b[2mThis line will be displayed dim/faint.\x1b[0m This should have no style.";
696 let view = snapshot_typescript(stream);
697 insta::assert_snapshot!(view);
698 }
699 #[test]
700 fn combined_modifier_text() {
701 let stream =
702 b"[4m[3mThis line will be displayed in italic and underlined.[0m This should have no style.";
703 let view = snapshot_typescript(stream);
704 insta::assert_snapshot!(view);
705 }
706 #[test]
707 fn dim_bold_text() {
708 let stream = b"\x1b[2m\x1b[1mThis is dim and bold. Bold takes precedence.\x1b[0m Normal.";
709 let view = snapshot_typescript(stream);
710 insta::assert_snapshot!(view);
711 }
712
713 #[test]
714 fn vttest_02_01() {
715 let stream = include_bytes!("../test/typescript/vttest_02_01.typescript");
716 let view = snapshot_typescript(stream);
717 insta::assert_snapshot!(view);
718 }
719 #[test]
720 fn vttest_02_02() {
721 let stream = include_bytes!("../test/typescript/vttest_02_02.typescript");
722 let view = snapshot_typescript(stream);
723 insta::assert_snapshot!(view);
724 }
725 #[test]
726 fn vttest_02_03() {
727 let stream = include_bytes!("../test/typescript/vttest_02_03.typescript");
728 let view = snapshot_typescript(stream);
729 insta::assert_snapshot!(view);
730 }
731 #[test]
732 fn vttest_02_04() {
733 let stream = include_bytes!("../test/typescript/vttest_02_04.typescript");
734 let view = snapshot_typescript(stream);
735 insta::assert_snapshot!(view);
736 }
737 #[test]
738 fn vttest_02_05() {
739 let stream = include_bytes!("../test/typescript/vttest_02_05.typescript");
740 let view = snapshot_typescript(stream);
741 insta::assert_snapshot!(view);
742 }
743 #[test]
744 fn vttest_02_06() {
745 let stream = include_bytes!("../test/typescript/vttest_02_06.typescript");
746 let view = snapshot_typescript(stream);
747 insta::assert_snapshot!(view);
748 }
749 #[test]
750 fn vttest_02_07() {
751 let stream = include_bytes!("../test/typescript/vttest_02_07.typescript");
752 let view = snapshot_typescript(stream);
753 insta::assert_snapshot!(view);
754 }
755 #[test]
756 fn vttest_02_08() {
757 let stream = include_bytes!("../test/typescript/vttest_02_08.typescript");
758 let view = snapshot_typescript(stream);
759 insta::assert_snapshot!(view);
760 }
761 #[test]
762 fn vttest_02_09() {
763 let stream = include_bytes!("../test/typescript/vttest_02_09.typescript");
764 let view = snapshot_typescript(stream);
765 insta::assert_snapshot!(view);
766 }
767 #[test]
768 fn vttest_02_10() {
769 let stream = include_bytes!("../test/typescript/vttest_02_10.typescript");
770 let view = snapshot_typescript(stream);
771 insta::assert_snapshot!(view);
772 }
773 #[test]
774 fn vttest_02_11() {
775 let stream = include_bytes!("../test/typescript/vttest_02_11.typescript");
776 let view = snapshot_typescript(stream);
777 insta::assert_snapshot!(view);
778 }
779 #[test]
780 fn vttest_02_12() {
781 let stream = include_bytes!("../test/typescript/vttest_02_12.typescript");
782 let view = snapshot_typescript(stream);
783 insta::assert_snapshot!(view);
784 }
785 #[test]
786 fn vttest_02_13() {
787 let stream = include_bytes!("../test/typescript/vttest_02_13.typescript");
788 let view = snapshot_typescript(stream);
789 insta::assert_snapshot!(view);
790 }
791 #[test]
792 fn vttest_02_14() {
793 let stream = include_bytes!("../test/typescript/vttest_02_14.typescript");
794 let view = snapshot_typescript(stream);
795 insta::assert_snapshot!(view);
796 }
797 #[test]
798 fn vttest_02_15() {
799 let stream = include_bytes!("../test/typescript/vttest_02_15.typescript");
800 let view = snapshot_typescript(stream);
801 insta::assert_snapshot!(view);
802 }
803
804 #[test]
805 fn vttest_03_01() {
806 let stream = include_bytes!("../test/typescript/vttest_03_01.typescript");
807 let view = snapshot_typescript(stream);
808 insta::assert_snapshot!(view);
809 }
810
811 #[test]
812 fn vttest_01_01() {
813 let stream = include_bytes!("../test/typescript/vttest_01_01.typescript");
814 let view = snapshot_typescript(stream);
815 insta::assert_snapshot!(view);
816 }
817
818 #[test]
819 fn vttest_01_02() {
820 let stream = include_bytes!("../test/typescript/vttest_01_02.typescript");
821 let view = snapshot_typescript(stream);
822 insta::assert_snapshot!(view);
823 }
824
825 #[test]
826 fn vttest_01_03() {
827 let stream = include_bytes!("../test/typescript/vttest_01_03.typescript");
828 let view = snapshot_typescript(stream);
829 insta::assert_snapshot!(view);
830 }
831
832 #[test]
833 fn vttest_01_04() {
834 let stream = include_bytes!("../test/typescript/vttest_01_04.typescript");
835 let view = snapshot_typescript(stream);
836 insta::assert_snapshot!(view);
837 }
838
839 #[test]
840 fn vttest_01_05() {
841 let stream = include_bytes!("../test/typescript/vttest_01_05.typescript");
842 let view = snapshot_typescript(stream);
843 insta::assert_snapshot!(view);
844 }
845
846 #[test]
847 fn vttest_menu() {
848 let stream = include_bytes!("../test/typescript/vttest_menu.typescript");
849 let view = snapshot_typescript(stream);
850 insta::assert_snapshot!(view);
851 }
852
853 #[test]
854 fn vttest_08_01() {
855 let stream = include_bytes!("../test/typescript/vttest_08_01.typescript");
856 let view = snapshot_typescript(stream);
857 insta::assert_snapshot!(view);
858 }
859
860 #[test]
861 fn vttest_08_02() {
862 let stream = include_bytes!("../test/typescript/vttest_08_02.typescript");
863 let view = snapshot_typescript(stream);
864 insta::assert_snapshot!(view);
865 }
866
867 #[test]
868 fn vttest_08_03() {
869 let stream = include_bytes!("../test/typescript/vttest_08_03.typescript");
870 let view = snapshot_typescript(stream);
871 insta::assert_snapshot!(view);
872 }
873
874 #[test]
875 fn vttest_08_04() {
876 let stream = include_bytes!("../test/typescript/vttest_08_04.typescript");
877 let view = snapshot_typescript(stream);
878 insta::assert_snapshot!(view);
879 }
880
881 #[test]
882 fn vttest_08_05() {
883 let stream = include_bytes!("../test/typescript/vttest_08_05.typescript");
884 let view = snapshot_typescript(stream);
885 insta::assert_snapshot!(view);
886 }
887
888 #[test]
889 fn vttest_08_06() {
890 let stream = include_bytes!("../test/typescript/vttest_08_06.typescript");
891 let view = snapshot_typescript(stream);
892 insta::assert_snapshot!(view);
893 }
894
895 #[test]
896 fn vttest_08_07() {
897 let stream = include_bytes!("../test/typescript/vttest_08_07.typescript");
898 let view = snapshot_typescript(stream);
899 insta::assert_snapshot!(view);
900 }
901
902 #[test]
903 fn vttest_08_08() {
904 let stream = include_bytes!("../test/typescript/vttest_08_08.typescript");
905 let view = snapshot_typescript(stream);
906 insta::assert_snapshot!(view);
907 }
908
909 #[test]
910 fn vttest_08_09() {
911 let stream = include_bytes!("../test/typescript/vttest_08_09.typescript");
912 let view = snapshot_typescript(stream);
913 insta::assert_snapshot!(view);
914 }
915
916 #[test]
917 fn vttest_08_10() {
918 let stream = include_bytes!("../test/typescript/vttest_08_10.typescript");
919 let view = snapshot_typescript(stream);
920 insta::assert_snapshot!(view);
921 }
922
923 #[test]
924 fn vttest_08_11() {
925 let stream = include_bytes!("../test/typescript/vttest_08_11.typescript");
926 let view = snapshot_typescript(stream);
927 insta::assert_snapshot!(view);
928 }
929
930 #[test]
931 fn vttest_08_12() {
932 let stream = include_bytes!("../test/typescript/vttest_08_12.typescript");
933 let view = snapshot_typescript(stream);
934 insta::assert_snapshot!(view);
935 }
936
937 #[test]
938 fn vttest_08_13() {
939 let stream = include_bytes!("../test/typescript/vttest_08_13.typescript");
940 let view = snapshot_typescript(stream);
941 insta::assert_snapshot!(view);
942 }
943
944 #[test]
945 fn vttest_08_14() {
946 let stream = include_bytes!("../test/typescript/vttest_08_14.typescript");
947 let view = snapshot_typescript(stream);
948 insta::assert_snapshot!(view);
949 }
950
951 #[test]
952 fn vttest_11_06_02() {
953 let stream = include_bytes!("../test/typescript/vttest_11_06_02.typescript");
954 let view = snapshot_typescript(stream);
955 insta::assert_snapshot!(view);
956 }
957
958 #[test]
959 fn vttest_11_06_03() {
960 let stream = include_bytes!("../test/typescript/vttest_11_06_03.typescript");
961 let view = snapshot_typescript(stream);
962 insta::assert_snapshot!(view);
963 }
964
965 #[test]
966 fn vttest_11_06_04() {
967 let stream = include_bytes!("../test/typescript/vttest_11_06_04.typescript");
968 let view = snapshot_typescript(stream);
969 insta::assert_snapshot!(view);
970 }
971
972 #[test]
973 fn vttest_11_06_05() {
974 let stream = include_bytes!("../test/typescript/vttest_11_06_05.typescript");
975 let view = snapshot_typescript(stream);
976 insta::assert_snapshot!(view);
977 }
978
979 #[test]
980 fn vttest_09_01() {
981 let stream = include_bytes!("../test/typescript/vttest_09_01.typescript");
982 let view = snapshot_typescript(stream);
983 insta::assert_snapshot!(view);
984 }
985
986 #[test]
987 fn vttest_09_02() {
988 let stream = include_bytes!("../test/typescript/vttest_09_02.typescript");
989 let view = snapshot_typescript(stream);
990 insta::assert_snapshot!(view);
991 }
992
993 #[test]
994 fn vttest_09_03() {
995 let stream = include_bytes!("../test/typescript/vttest_09_03.typescript");
996 let view = snapshot_typescript(stream);
997 insta::assert_snapshot!(view);
998 }
999
1000 #[test]
1001 fn vttest_09_04() {
1002 let stream = include_bytes!("../test/typescript/vttest_09_04.typescript");
1003 let view = snapshot_typescript(stream);
1004 insta::assert_snapshot!(view);
1005 }
1006
1007 #[test]
1008 fn vttest_09_05() {
1009 let stream = include_bytes!("../test/typescript/vttest_09_05.typescript");
1010 let view = snapshot_typescript(stream);
1011 insta::assert_snapshot!(view);
1012 }
1013
1014 #[test]
1015 fn vttest_09_06() {
1016 let stream = include_bytes!("../test/typescript/vttest_09_06.typescript");
1017 let view = snapshot_typescript(stream);
1018 insta::assert_snapshot!(view);
1019 }
1020
1021 #[test]
1022 fn vttest_09_07() {
1023 let stream = include_bytes!("../test/typescript/vttest_09_07.typescript");
1024 let view = snapshot_typescript(stream);
1025 insta::assert_snapshot!(view);
1026 }
1027
1028 #[test]
1029 fn vttest_09_08() {
1030 let stream = include_bytes!("../test/typescript/vttest_09_08.typescript");
1031 let view = snapshot_typescript(stream);
1032 insta::assert_snapshot!(view);
1033 }
1034
1035 #[test]
1036 fn vttest_09_09() {
1037 let stream = include_bytes!("../test/typescript/vttest_09_09.typescript");
1038 let view = snapshot_typescript(stream);
1039 insta::assert_snapshot!(view);
1040 }
1041
1042 #[test]
1043 fn vttest_11_05_01() {
1044 let stream = include_bytes!("../test/typescript/vttest_11_05_01.typescript");
1045 let view = snapshot_typescript(stream);
1046 insta::assert_snapshot!(view);
1047 }
1048
1049 #[test]
1050 fn vttest_11_05_02() {
1051 let stream = include_bytes!("../test/typescript/vttest_11_05_02.typescript");
1052 let view = snapshot_typescript(stream);
1053 insta::assert_snapshot!(view);
1054 }
1055
1056 #[test]
1057 fn vttest_11_05_03() {
1058 let stream = include_bytes!("../test/typescript/vttest_11_05_03.typescript");
1059 let view = snapshot_typescript(stream);
1060 insta::assert_snapshot!(view);
1061 }
1062
1063 #[test]
1064 fn vttest_11_05_04() {
1065 let stream = include_bytes!("../test/typescript/vttest_11_05_04.typescript");
1066 let view = snapshot_typescript(stream);
1067 insta::assert_snapshot!(view);
1068 }
1069
1070 #[test]
1071 fn vttest_11_05_05() {
1072 let stream = include_bytes!("../test/typescript/vttest_11_05_05.typescript");
1073 let view = snapshot_typescript(stream);
1074 insta::assert_snapshot!(view);
1075 }
1076
1077 #[test]
1078 fn vttest_11_05_06() {
1079 let stream = include_bytes!("../test/typescript/vttest_11_05_06.typescript");
1080 let view = snapshot_typescript(stream);
1081 insta::assert_snapshot!(view);
1082 }
1083
1084 #[test]
1085 fn vttest_11_05_07() {
1086 let stream = include_bytes!("../test/typescript/vttest_11_05_07.typescript");
1087 let view = snapshot_typescript(stream);
1088 insta::assert_snapshot!(view);
1089 }
1090
1091 #[test]
1092 fn vttest_11_05_08() {
1093 let stream = include_bytes!("../test/typescript/vttest_11_05_08.typescript");
1094 let view = snapshot_typescript(stream);
1095 insta::assert_snapshot!(view);
1096 }
1097
1098 #[test]
1099 fn vttest_11_05_09() {
1100 let stream = include_bytes!("../test/typescript/vttest_11_05_09.typescript");
1101 let view = snapshot_typescript(stream);
1102 insta::assert_snapshot!(view);
1103 }
1104
1105 #[test]
1106 fn vttest_11_07_02() {
1107 let stream = include_bytes!("../test/typescript/vttest_11_07_02.typescript");
1108 let view = snapshot_typescript(stream);
1109 insta::assert_snapshot!(view);
1110 }
1111}