@@ -66,11 +66,117 @@ describe('InputHandler', () => {
6666 optionsService = new MockOptionsService ( ) ;
6767 bufferService = new BufferService ( optionsService ) ;
6868 bufferService . resize ( 80 , 30 ) ;
69- coreService = new CoreService ( ( ) => { } , bufferService , new MockLogService ( ) , optionsService ) ;
69+ coreService = new CoreService ( ( ) => { } , bufferService , new MockLogService ( ) , optionsService ) ;
7070
7171 inputHandler = new TestInputHandler ( bufferService , new MockCharsetService ( ) , coreService , new MockDirtyRowService ( ) , new MockLogService ( ) , optionsService , new MockCoreMouseService ( ) , new MockUnicodeService ( ) ) ;
7272 } ) ;
7373
74+ describe ( 'SL/SR/DECIC/DECDC' , ( ) => {
75+ beforeEach ( ( ) => {
76+ bufferService . resize ( 5 , 5 ) ;
77+ optionsService . options . scrollback = 1 ;
78+ bufferService . reset ( ) ;
79+ } ) ;
80+ it ( 'SL (scrollLeft)' , async ( ) => {
81+ inputHandler . parseP ( '12345' . repeat ( 6 ) ) ;
82+ inputHandler . parseP ( '\x1b[ @' ) ;
83+ assert . deepEqual ( getLines ( bufferService , 6 ) , [ '12345' , '2345' , '2345' , '2345' , '2345' , '2345' ] ) ;
84+ inputHandler . parseP ( '\x1b[0 @' ) ;
85+ assert . deepEqual ( getLines ( bufferService , 6 ) , [ '12345' , '345' , '345' , '345' , '345' , '345' ] ) ;
86+ inputHandler . parseP ( '\x1b[2 @' ) ;
87+ assert . deepEqual ( getLines ( bufferService , 6 ) , [ '12345' , '5' , '5' , '5' , '5' , '5' ] ) ;
88+ } ) ;
89+ it ( 'SR (scrollRight)' , async ( ) => {
90+ inputHandler . parseP ( '12345' . repeat ( 6 ) ) ;
91+ inputHandler . parseP ( '\x1b[ A' ) ;
92+ assert . deepEqual ( getLines ( bufferService , 6 ) , [ '12345' , ' 1234' , ' 1234' , ' 1234' , ' 1234' , ' 1234' ] ) ;
93+ inputHandler . parseP ( '\x1b[0 A' ) ;
94+ assert . deepEqual ( getLines ( bufferService , 6 ) , [ '12345' , ' 123' , ' 123' , ' 123' , ' 123' , ' 123' ] ) ;
95+ inputHandler . parseP ( '\x1b[2 A' ) ;
96+ assert . deepEqual ( getLines ( bufferService , 6 ) , [ '12345' , ' 1' , ' 1' , ' 1' , ' 1' , ' 1' ] ) ;
97+ } ) ;
98+ it ( 'insertColumns (DECIC)' , async ( ) => {
99+ inputHandler . parseP ( '12345' . repeat ( 6 ) ) ;
100+ inputHandler . parseP ( '\x1b[3;3H' ) ;
101+ inputHandler . parseP ( '\x1b[\'}' ) ;
102+ assert . deepEqual ( getLines ( bufferService , 6 ) , [ '12345' , '12 34' , '12 34' , '12 34' , '12 34' , '12 34' ] ) ;
103+ bufferService . reset ( ) ;
104+ inputHandler . parseP ( '12345' . repeat ( 6 ) ) ;
105+ inputHandler . parseP ( '\x1b[3;3H' ) ;
106+ inputHandler . parseP ( '\x1b[1\'}' ) ;
107+ assert . deepEqual ( getLines ( bufferService , 6 ) , [ '12345' , '12 34' , '12 34' , '12 34' , '12 34' , '12 34' ] ) ;
108+ bufferService . reset ( ) ;
109+ inputHandler . parseP ( '12345' . repeat ( 6 ) ) ;
110+ inputHandler . parseP ( '\x1b[3;3H' ) ;
111+ inputHandler . parseP ( '\x1b[2\'}' ) ;
112+ assert . deepEqual ( getLines ( bufferService , 6 ) , [ '12345' , '12 3' , '12 3' , '12 3' , '12 3' , '12 3' ] ) ;
113+ } ) ;
114+ it ( 'deleteColumns (DECDC)' , async ( ) => {
115+ inputHandler . parseP ( '12345' . repeat ( 6 ) ) ;
116+ inputHandler . parseP ( '\x1b[3;3H' ) ;
117+ inputHandler . parseP ( '\x1b[\'~' ) ;
118+ assert . deepEqual ( getLines ( bufferService , 6 ) , [ '12345' , '1245' , '1245' , '1245' , '1245' , '1245' ] ) ;
119+ bufferService . reset ( ) ;
120+ inputHandler . parseP ( '12345' . repeat ( 6 ) ) ;
121+ inputHandler . parseP ( '\x1b[3;3H' ) ;
122+ inputHandler . parseP ( '\x1b[1\'~' ) ;
123+ assert . deepEqual ( getLines ( bufferService , 6 ) , [ '12345' , '1245' , '1245' , '1245' , '1245' , '1245' ] ) ;
124+ bufferService . reset ( ) ;
125+ inputHandler . parseP ( '12345' . repeat ( 6 ) ) ;
126+ inputHandler . parseP ( '\x1b[3;3H' ) ;
127+ inputHandler . parseP ( '\x1b[2\'~' ) ;
128+ assert . deepEqual ( getLines ( bufferService , 6 ) , [ '12345' , '125' , '125' , '125' , '125' , '125' ] ) ;
129+ } ) ;
130+ } ) ;
131+
132+ describe ( 'BS with reverseWraparound set/unset' , ( ) => {
133+ const ttyBS = '\x08 \x08' ; // tty ICANON sends <BS SP BS> on pressing BS
134+ beforeEach ( ( ) => {
135+ bufferService . resize ( 5 , 5 ) ;
136+ optionsService . options . scrollback = 1 ;
137+ bufferService . reset ( ) ;
138+ } ) ;
139+ describe ( 'reverseWraparound set' , ( ) => {
140+ it ( 'should not reverse outside of scroll margins' , async ( ) => {
141+ // prepare buffer content
142+ inputHandler . parseP ( '#####abcdefghijklmnopqrstuvwxy' ) ;
143+ assert . deepEqual ( getLines ( bufferService , 6 ) , [ '#####' , 'abcde' , 'fghij' , 'klmno' , 'pqrst' , 'uvwxy' ] ) ;
144+ assert . equal ( bufferService . buffers . active . ydisp , 1 ) ;
145+ assert . equal ( bufferService . buffers . active . x , 5 ) ;
146+ assert . equal ( bufferService . buffers . active . y , 4 ) ;
147+ inputHandler . parseP ( ttyBS . repeat ( 100 ) ) ;
148+ assert . deepEqual ( getLines ( bufferService , 6 ) , [ '#####' , 'abcde' , 'fghij' , 'klmno' , 'pqrst' , ' y' ] ) ;
149+
150+ inputHandler . parseP ( '\x1b[?45h' ) ;
151+ inputHandler . parseP ( 'uvwxy' ) ;
152+
153+ // set top/bottom to 1/3 (0-based)
154+ inputHandler . parseP ( '\x1b[2;4r' ) ;
155+ // place cursor below scroll bottom
156+ bufferService . buffers . active . x = 5 ;
157+ bufferService . buffers . active . y = 4 ;
158+ inputHandler . parseP ( ttyBS . repeat ( 100 ) ) ;
159+ assert . deepEqual ( getLines ( bufferService , 6 ) , [ '#####' , 'abcde' , 'fghij' , 'klmno' , 'pqrst' , ' ' ] ) ;
160+
161+ inputHandler . parseP ( 'uvwxy' ) ;
162+ // place cursor within scroll margins
163+ bufferService . buffers . active . x = 5 ;
164+ bufferService . buffers . active . y = 3 ;
165+ inputHandler . parseP ( ttyBS . repeat ( 100 ) ) ;
166+ assert . deepEqual ( getLines ( bufferService , 6 ) , [ '#####' , 'abcde' , ' ' , ' ' , ' ' , 'uvwxy' ] ) ;
167+ assert . equal ( bufferService . buffers . active . x , 0 ) ;
168+ assert . equal ( bufferService . buffers . active . y , bufferService . buffers . active . scrollTop ) ; // stops at 0, scrollTop
169+
170+ inputHandler . parseP ( 'fghijklmnopqrst' ) ;
171+ // place cursor above scroll top
172+ bufferService . buffers . active . x = 5 ;
173+ bufferService . buffers . active . y = 0 ;
174+ inputHandler . parseP ( ttyBS . repeat ( 100 ) ) ;
175+ assert . deepEqual ( getLines ( bufferService , 6 ) , [ '#####' , ' ' , 'fghij' , 'klmno' , 'pqrst' , 'uvwxy' ] ) ;
176+ } ) ;
177+ } ) ;
178+ } ) ;
179+
74180 it ( 'save and restore cursor' , ( ) => {
75181 bufferService . buffer . x = 1 ;
76182 bufferService . buffer . y = 2 ;
@@ -140,7 +246,7 @@ describe('InputHandler', () => {
140246 assert . equal ( coreService . decPrivateModes . bracketedPasteMode , false ) ;
141247 } ) ;
142248 } ) ;
143- describe ( 'regression tests' , function ( ) : void {
249+ describe ( 'regression tests' , function ( ) : void {
144250 function termContent ( bufferService : IBufferService , trim : boolean ) : string [ ] {
145251 const result = [ ] ;
146252 for ( let i = 0 ; i < bufferService . rows ; ++ i ) result . push ( bufferService . buffer . lines . get ( i ) ! . translateToString ( trim ) ) ;
@@ -1240,7 +1346,7 @@ describe('InputHandler', () => {
12401346 await inputHandler . parseP ( '\x1b[6H\x1b[2Mm' ) ;
12411347 assert . deepEqual ( getLines ( bufferService ) , [ '0' , '1' , '2' , '3' , '4' , 'm' , '6' , '7' , '8' , '9' ] ) ;
12421348 await inputHandler . parseP ( '\x1b[3H\x1b[2Mn' ) ;
1243- assert . deepEqual ( getLines ( bufferService ) , [ '0' , '1' , 'n' , 'm' , '' , '' , '6' , '7' , '8' , '9' ] ) ;
1349+ assert . deepEqual ( getLines ( bufferService ) , [ '0' , '1' , 'n' , 'm' , '' , '' , '6' , '7' , '8' , '9' ] ) ;
12441350 } ) ;
12451351 } ) ;
12461352 it ( 'should parse big chunks in smaller subchunks' , async ( ) => {
@@ -1820,7 +1926,7 @@ describe('InputHandler - async handlers', () => {
18201926 optionsService = new MockOptionsService ( ) ;
18211927 bufferService = new BufferService ( optionsService ) ;
18221928 bufferService . resize ( 80 , 30 ) ;
1823- coreService = new CoreService ( ( ) => { } , bufferService , new MockLogService ( ) , optionsService ) ;
1929+ coreService = new CoreService ( ( ) => { } , bufferService , new MockLogService ( ) , optionsService ) ;
18241930 coreService . onData ( data => { console . log ( data ) ; } ) ;
18251931
18261932 inputHandler = new TestInputHandler ( bufferService , new MockCharsetService ( ) , coreService , new MockDirtyRowService ( ) , new MockLogService ( ) , optionsService , new MockCoreMouseService ( ) , new MockUnicodeService ( ) ) ;
@@ -1829,7 +1935,7 @@ describe('InputHandler - async handlers', () => {
18291935 it ( 'async CUP with CPR check' , async ( ) => {
18301936 const cup : number [ ] [ ] = [ ] ;
18311937 const cpr : number [ ] [ ] = [ ] ;
1832- inputHandler . registerCsiHandler ( { final : 'H' } , async params => {
1938+ inputHandler . registerCsiHandler ( { final : 'H' } , async params => {
18331939 cup . push ( params . toArray ( ) as number [ ] ) ;
18341940 await new Promise ( res => setTimeout ( res , 50 ) ) ;
18351941 // late call of real repositioning
@@ -1855,7 +1961,7 @@ describe('InputHandler - async handlers', () => {
18551961 assert . deepEqual ( getLines ( bufferService , 2 ) , [ 'hello world!' , 'second line' ] ) ;
18561962 } ) ;
18571963 it ( 'async DCS between' , async ( ) => {
1858- inputHandler . registerDcsHandler ( { final : 'a' } , async ( data , params ) => {
1964+ inputHandler . registerDcsHandler ( { final : 'a' } , async ( data , params ) => {
18591965 await new Promise ( res => setTimeout ( res , 50 ) ) ;
18601966 assert . deepEqual ( getLines ( bufferService , 2 ) , [ 'hello world!' , '' ] ) ;
18611967 assert . equal ( data , 'some data' ) ;
0 commit comments