scriptty 0.5.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/.gitattributes +1 -0
  2. data/.gitignore +3 -0
  3. data/COPYING +674 -0
  4. data/COPYING.LESSER +165 -0
  5. data/README.rdoc +31 -0
  6. data/Rakefile +49 -0
  7. data/VERSION +1 -0
  8. data/bin/scriptty-capture +5 -0
  9. data/bin/scriptty-dump-screens +4 -0
  10. data/bin/scriptty-replay +5 -0
  11. data/bin/scriptty-term-test +4 -0
  12. data/bin/scriptty-transcript-parse +4 -0
  13. data/examples/captures/xterm-overlong-line-prompt.bin +9 -0
  14. data/examples/captures/xterm-vim-session.bin +262 -0
  15. data/examples/demo-capture.rb +19 -0
  16. data/examples/telnet-nego.rb +55 -0
  17. data/lib/scriptty/apps/capture_app/console.rb +104 -0
  18. data/lib/scriptty/apps/capture_app/password_prompt.rb +65 -0
  19. data/lib/scriptty/apps/capture_app.rb +213 -0
  20. data/lib/scriptty/apps/dump_screens_app.rb +166 -0
  21. data/lib/scriptty/apps/replay_app.rb +229 -0
  22. data/lib/scriptty/apps/term_test_app.rb +124 -0
  23. data/lib/scriptty/apps/transcript_parse_app.rb +143 -0
  24. data/lib/scriptty/cursor.rb +39 -0
  25. data/lib/scriptty/exception.rb +38 -0
  26. data/lib/scriptty/expect.rb +392 -0
  27. data/lib/scriptty/multiline_buffer.rb +192 -0
  28. data/lib/scriptty/net/event_loop.rb +610 -0
  29. data/lib/scriptty/screen_pattern/generator.rb +398 -0
  30. data/lib/scriptty/screen_pattern/parser.rb +558 -0
  31. data/lib/scriptty/screen_pattern.rb +104 -0
  32. data/lib/scriptty/term/dg410/dg410-client-escapes.txt +37 -0
  33. data/lib/scriptty/term/dg410/dg410-escapes.txt +82 -0
  34. data/lib/scriptty/term/dg410/parser.rb +162 -0
  35. data/lib/scriptty/term/dg410.rb +489 -0
  36. data/lib/scriptty/term/xterm/xterm-escapes.txt +73 -0
  37. data/lib/scriptty/term/xterm.rb +661 -0
  38. data/lib/scriptty/term.rb +40 -0
  39. data/lib/scriptty/util/fsm/definition_parser.rb +111 -0
  40. data/lib/scriptty/util/fsm/scriptty_fsm_definition.treetop +189 -0
  41. data/lib/scriptty/util/fsm.rb +177 -0
  42. data/lib/scriptty/util/transcript/reader.rb +96 -0
  43. data/lib/scriptty/util/transcript/writer.rb +111 -0
  44. data/test/apps/capture_app_test.rb +123 -0
  45. data/test/apps/transcript_parse_app_test.rb +118 -0
  46. data/test/cursor_test.rb +51 -0
  47. data/test/fsm_definition_parser_test.rb +220 -0
  48. data/test/fsm_test.rb +322 -0
  49. data/test/multiline_buffer_test.rb +275 -0
  50. data/test/net/event_loop_test.rb +402 -0
  51. data/test/screen_pattern/generator_test.rb +408 -0
  52. data/test/screen_pattern/parser_test/explicit_cursor_pattern.txt +14 -0
  53. data/test/screen_pattern/parser_test/explicit_fields.txt +22 -0
  54. data/test/screen_pattern/parser_test/multiple_patterns.txt +42 -0
  55. data/test/screen_pattern/parser_test/simple_pattern.txt +14 -0
  56. data/test/screen_pattern/parser_test/truncated_heredoc.txt +12 -0
  57. data/test/screen_pattern/parser_test/utf16bebom_pattern.bin +0 -0
  58. data/test/screen_pattern/parser_test/utf16lebom_pattern.bin +0 -0
  59. data/test/screen_pattern/parser_test/utf8_pattern.bin +14 -0
  60. data/test/screen_pattern/parser_test/utf8_unix_pattern.bin +14 -0
  61. data/test/screen_pattern/parser_test/utf8bom_pattern.bin +14 -0
  62. data/test/screen_pattern/parser_test.rb +266 -0
  63. data/test/term/dg410/parser_test.rb +139 -0
  64. data/test/term/xterm_test.rb +327 -0
  65. data/test/test_helper.rb +3 -0
  66. data/test/util/transcript/reader_test.rb +131 -0
  67. data/test/util/transcript/writer_test.rb +126 -0
  68. data/test.watchr +29 -0
  69. metadata +175 -0
data/test/fsm_test.rb ADDED
@@ -0,0 +1,322 @@
1
+ # = Tests for ScripTTY::Util::FSM
2
+ # Copyright (C) 2010 Infonium Inc.
3
+ #
4
+ # This file is part of ScripTTY.
5
+ #
6
+ # ScripTTY is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # ScripTTY is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public License
17
+ # along with ScripTTY. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ require File.dirname(__FILE__) + "/test_helper.rb"
20
+ require 'scriptty/util/fsm'
21
+
22
+ class FSMTest < Test::Unit::TestCase
23
+
24
+ # Test the basic operation of the FSM.
25
+ def test_simple
26
+ fsm = ScripTTY::Util::FSM.new(:definition => <<-EOF)
27
+ 'a' => eh
28
+ 'x' => {
29
+ 'y' => ex_why
30
+ }
31
+ EOF
32
+
33
+ fsm.process("a")
34
+ assert_equal 'a', fsm.input
35
+ assert_equal ['a'], fsm.input_sequence
36
+
37
+ fsm.process("x")
38
+ assert_equal 'x', fsm.input
39
+ assert_equal ['x'], fsm.input_sequence
40
+
41
+ fsm.process("y")
42
+ assert_equal 'y', fsm.input
43
+ assert_equal ['x', 'y'], fsm.input_sequence
44
+ end
45
+
46
+ def test_other
47
+ result = []
48
+ fsm = ScripTTY::Util::FSM.new(:definition => <<-EOF) { |event, fsm| result << event }
49
+ 'a' => eh
50
+ 'x' => {
51
+ 'y' => ex_why
52
+ * => ex_other
53
+ }
54
+ EOF
55
+
56
+ fsm.process("a")
57
+ assert_equal 'a', fsm.input
58
+ assert_equal ['a'], fsm.input_sequence
59
+
60
+ fsm.process("x")
61
+ assert_equal 'x', fsm.input
62
+ assert_equal ['x'], fsm.input_sequence
63
+
64
+ assert_nothing_raised do
65
+ fsm.process("z")
66
+ end
67
+ assert_equal 'z', fsm.input
68
+ assert_equal ['x', 'z'], fsm.input_sequence
69
+ assert_equal [:eh, :ex_other], result
70
+ end
71
+
72
+ def test_empty_state
73
+ fsm = ScripTTY::Util::FSM.new(:definition => <<-EOF)
74
+ 'x' => {
75
+ }
76
+ EOF
77
+ fsm.process("x")
78
+ assert_raise ScripTTY::Util::FSM::NoMatch do
79
+ fsm.process("y")
80
+ end
81
+ end
82
+
83
+ # The FSM should accept more than just single characters as inputs.
84
+ def test_string_inputs
85
+ fsm = ScripTTY::Util::FSM.new(:definition => <<-EOF)
86
+ "inputs" => {
87
+ "need not" => {
88
+ "be" => {
89
+ "single characters" => dummy
90
+ }
91
+ }
92
+ }
93
+ EOF
94
+
95
+ # The FSM should treat inputs as discrete units, not try to split them up
96
+ # into separate characters.
97
+ assert_raise ScripTTY::Util::FSM::NoMatch do
98
+ fsm.process("i")
99
+ end
100
+
101
+ # Test with longer words
102
+ fsm.process("inputs")
103
+ fsm.process("need not")
104
+ fsm.process("be")
105
+ fsm.process("single characters")
106
+ assert_equal ["inputs", "need not", "be", "single characters"], fsm.input_sequence
107
+ end
108
+
109
+ # Test that the FSM accepts a callback passed as a block to the constructor.
110
+ def test_callback_given_as_block
111
+ result = []
112
+ fsm = ScripTTY::Util::FSM.new(:definition => <<-EOF) { |event, fsm| result << [event, fsm.input_sequence] }
113
+ 'a' => eh
114
+ 'x' => {
115
+ 'y' => ex_why
116
+ }
117
+ EOF
118
+ fsm.process('a')
119
+ assert_equal [[:eh, ['a']]], result
120
+
121
+ fsm.process('x')
122
+ assert_equal [[:eh, ['a']]], result
123
+
124
+ fsm.process('y')
125
+ assert_equal [[:eh, ['a']], [:ex_why, ['x', 'y']]], result
126
+ end
127
+
128
+ # Test that the FSM accepts a callback passed as an option to the constructor.
129
+ def test_callback_given_as_option
130
+ result = []
131
+ callback_proc = Proc.new { |event, fsm| result << [event, fsm.input_sequence] }
132
+ fsm = ScripTTY::Util::FSM.new(:definition => <<-EOF, :callback => callback_proc)
133
+ 'a' => eh
134
+ 'x' => {
135
+ 'y' => ex_why
136
+ }
137
+ EOF
138
+ fsm.process('a')
139
+ assert_equal [[:eh, ['a']]], result
140
+
141
+ fsm.process('x')
142
+ assert_equal [[:eh, ['a']]], result
143
+
144
+ fsm.process('y')
145
+ assert_equal [[:eh, ['a']], [:ex_why, ['x', 'y']]], result
146
+ end
147
+
148
+ def test_intermediate_callback_with_redirect_proc
149
+ callback_class = Class.new do
150
+ attr_accessor :result
151
+ def csi(f)
152
+ f.redirect = lambda {|m| m.input =~ /[\d;]/}
153
+ end
154
+ def sgr(f)
155
+ @result ||= []
156
+ @result << f.input_sequence
157
+ end
158
+ def five(f)
159
+ @result ||= []
160
+ @result << :five
161
+ end
162
+ end
163
+ cb = callback_class.new
164
+ fsm = ScripTTY::Util::FSM.new(:callback => cb, :callback_method => :send, :definition => <<-EOF)
165
+ '\e' => {
166
+ '[' => csi => {
167
+ 'm' => sgr
168
+ }
169
+ }
170
+ '5' => five
171
+ EOF
172
+ "\e[33;42m".split("").each {|c| fsm.process(c)}
173
+ fsm.process("5")
174
+ assert_equal [["\e", "[", "3", "3", ";", "4", "2", "m"], :five], cb.result
175
+ end
176
+
177
+ # Regression test: If fsm.redirect was used with :next_state => 1,
178
+ # fsm.input_sequence would only contain the current input, rather than
179
+ # the whole sequence. This tests the fix.
180
+ def test_final_callback_with_redirect
181
+ callback_class = Class.new do
182
+ attr_accessor :result
183
+ def handle_a(f)
184
+ f.redirect = :redirected
185
+ end
186
+ def redirected(f)
187
+ case f.input_sequence
188
+ when ['a', 'p', 'p', 'l', 'e']
189
+ f.redirect = nil
190
+ apple(f)
191
+ when ['a', 'c', 'r', 'o', 'b', 'a', 't']
192
+ f.redirect = nil
193
+ acrobat(f)
194
+ end
195
+ true
196
+ end
197
+ def apple(f)
198
+ @result ||= []
199
+ @result << :apple
200
+ end
201
+ def acrobat(f)
202
+ @result ||= []
203
+ @result << :acrobat
204
+ end
205
+ end
206
+ cb = callback_class.new
207
+ fsm = ScripTTY::Util::FSM.new(:callback => cb, :callback_method => :send, :definition => <<-EOF)
208
+ 'a' => handle_a
209
+ EOF
210
+ "apple".split("").each {|c| fsm.process(c)}
211
+ "acrobat".split("").each {|c| fsm.process(c)}
212
+ assert_equal [:apple, :acrobat], cb.result
213
+ end
214
+
215
+ def test_intermediate_callback_with_redirect_symbol
216
+ callback_class = Class.new do
217
+ attr_accessor :result
218
+ def csi(f)
219
+ f.redirect = :csi_redirect
220
+ end
221
+ def csi_redirect(f)
222
+ f.input =~ /[\d;]/
223
+ end
224
+ def sgr(f)
225
+ @result ||= []
226
+ @result << f.input_sequence
227
+ end
228
+ def five(f)
229
+ @result ||= []
230
+ @result << :five
231
+ end
232
+ end
233
+ cb = callback_class.new
234
+ fsm = ScripTTY::Util::FSM.new(:callback => cb, :callback_method => :send, :definition => <<-EOF)
235
+ '\e' => {
236
+ '[' => csi => {
237
+ 'm' => sgr
238
+ }
239
+ }
240
+ '5' => five
241
+ EOF
242
+ "\e[33;42m".split("").each {|c| fsm.process(c)}
243
+ fsm.process("5")
244
+ assert_equal [["\e", "[", "3", "3", ";", "4", "2", "m"], :five], cb.result
245
+ end
246
+
247
+ def test_reset
248
+ fsm = ScripTTY::Util::FSM.new(:definition => <<-EOF)
249
+ 'a' => {
250
+ 'b' => ab
251
+ }
252
+ EOF
253
+ assert_equal 1, fsm.next_state
254
+ assert fsm.initial_state?
255
+
256
+ fsm.process("a")
257
+ assert_not_equal 1, fsm.next_state
258
+ assert fsm.initial_state?
259
+
260
+ fsm.reset!
261
+ assert_equal 1, fsm.next_state
262
+ assert fsm.initial_state?
263
+
264
+ assert_raise ScripTTY::Util::FSM::NoMatch do
265
+ fsm.process("b")
266
+ end
267
+ end
268
+
269
+ def test_reset_during_callback
270
+ callback_class = Class.new do
271
+ attr_accessor :result
272
+ def redirect_true(f)
273
+ @result ||= [] ; @result << :redirect_true
274
+ f.reset!
275
+ true
276
+ end
277
+ def redirect_false(f)
278
+ @result ||= [] ; @result << :redirect_false
279
+ f.reset!
280
+ false
281
+ end
282
+ def x(f)
283
+ @result ||= [] ; @result << :x
284
+ end
285
+ end
286
+ cb = callback_class.new
287
+ fsm = ScripTTY::Util::FSM.new(:callback => cb, :callback_method => :send, :definition => <<-EOF)
288
+ 'x' => x
289
+ EOF
290
+ assert_equal 1, fsm.next_state
291
+
292
+ cb.result = []
293
+ fsm.redirect = :redirect_true
294
+ fsm.process("x")
295
+ assert_equal [:redirect_true], cb.result
296
+ assert_equal 1, fsm.next_state
297
+ assert_nil fsm.redirect
298
+
299
+ cb.result = []
300
+ fsm.redirect = :redirect_false
301
+ fsm.process("x")
302
+ assert_equal [:redirect_false, :x], cb.result
303
+ assert_equal 1, fsm.next_state
304
+ assert_nil fsm.redirect
305
+ end
306
+
307
+ # Test the FSM#fire_event method
308
+ def test_fire_event
309
+ result = []
310
+ fsm = ScripTTY::Util::FSM.new(:definition => <<-EOF) { |event, fsm| result << event; fsm.fire_event(:xy) if event == :ex_why }
311
+ 'a' => eh
312
+ 'x' => {
313
+ 'y' => ex_why
314
+ }
315
+ EOF
316
+
317
+ fsm.process("a")
318
+ fsm.process("x")
319
+ fsm.process("y")
320
+ assert_equal [:eh, :ex_why, :xy], result
321
+ end
322
+ end
@@ -0,0 +1,275 @@
1
+ # = Tests for ScripTTY::MultilineBuffer
2
+ # Copyright (C) 2010 Infonium Inc.
3
+ #
4
+ # This file is part of ScripTTY.
5
+ #
6
+ # ScripTTY is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # ScripTTY is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public License
17
+ # along with ScripTTY. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ require File.dirname(__FILE__) + "/test_helper.rb"
20
+ require 'scriptty/multiline_buffer'
21
+
22
+ class MultilineBufferTest < Test::Unit::TestCase
23
+ def test_width_height
24
+ b = ScripTTY::MultilineBuffer.new(24,80)
25
+ assert_equal 24, b.height, "height should be 24 columns"
26
+ assert_equal 80, b.width, "width should be 80 columns"
27
+ end
28
+
29
+ def test_starts_blank
30
+ b = ScripTTY::MultilineBuffer.new(5,10)
31
+ expected = [
32
+ " "*10,
33
+ " "*10,
34
+ " "*10,
35
+ " "*10,
36
+ " "*10,
37
+ ]
38
+ assert_equal expected, b.content
39
+ end
40
+
41
+ def test_get_replace
42
+ b = ScripTTY::MultilineBuffer.new(5,10)
43
+ # Set up the buffer
44
+ assert_equal " "*10, b.replace_at(0, 0, "0123456789")
45
+ assert_equal " "*10, b.replace_at(1, 0, "ABCDEFGHIJ")
46
+ assert_equal " "*10, b.replace_at(2, 0, "KLMNOPQRST")
47
+ assert_equal " "*10, b.replace_at(3, 0, "UVWXYZabcd")
48
+ assert_equal " "*10, b.replace_at(4, 0, "efghijklmn")
49
+
50
+ # Test get_at
51
+ assert_equal "l", b.get_at(4,7), "default limit should be 1"
52
+ assert_equal "NOPQ", b.get_at(2,3,4), "basic get_at"
53
+ assert_equal "lmn", b.get_at(4,7,100), "overflowing length should be truncated"
54
+ assert_equal "lmn", b.get_at(4,7,-1), "negative limit"
55
+ end
56
+
57
+ def test_replace_at_array
58
+ b = ScripTTY::MultilineBuffer.new(5,10)
59
+ assert_equal [" "*10]*5, b.replace_at(0, 0, [
60
+ "0123456789",
61
+ "ABCDEFGHIJ",
62
+ "KLMNOPQRST",
63
+ "UVWXYZabcd",
64
+ "efghijklmn",
65
+ ])
66
+ end
67
+
68
+ def test_clear
69
+ before = [ "aaaaaaaaaa",
70
+ "bbbbbbbbbb",
71
+ "cccccccccc",
72
+ "dddddddddd",
73
+ "eeeeeeeeee" ]
74
+
75
+ after = [ " ",
76
+ " ",
77
+ " ",
78
+ " ",
79
+ " " ]
80
+
81
+ screen_modify_test(before, after) do |b|
82
+ b.clear!
83
+ end
84
+ end
85
+
86
+ def test_scroll_up_region_enclosed_1
87
+ before = [ "aaaaaaaaaa",
88
+ "bbbbbbbbbb",
89
+ "cccccccccc",
90
+ "dddddddddd",
91
+ "eeeeeeeeee" ]
92
+
93
+ after = [ "aaaaaaaaaa",
94
+ "bbcccccbbb",
95
+ "ccdddddccc",
96
+ "dd ddd",
97
+ "eeeeeeeeee" ]
98
+
99
+ screen_modify_test(before, after) do |b|
100
+ b.scroll_up_region( 1,2, 3,6, 1)
101
+ end
102
+ end
103
+
104
+ def test_scroll_up_region_enclosed_2
105
+ before = [ "aaaaaaaaaa",
106
+ "bbbbbbbbbb",
107
+ "cccccccccc",
108
+ "dddddddddd",
109
+ "eeeeeeeeee" ]
110
+
111
+ after = [ "aaaaaaaaaa",
112
+ "bbdddddbbb",
113
+ "cc ccc",
114
+ "dd ddd",
115
+ "eeeeeeeeee" ]
116
+
117
+ screen_modify_test(before, after) do |b|
118
+ b.scroll_up_region( 1,2, 3,6, 2)
119
+ end
120
+ end
121
+
122
+ def test_scroll_down_region_enclosed_1
123
+ before = [ "aaaaaaaaaa",
124
+ "bbbbbbbbbb",
125
+ "cccccccccc",
126
+ "dddddddddd",
127
+ "eeeeeeeeee" ]
128
+
129
+ after = [ "aaaaaaaaaa",
130
+ "bb bbb",
131
+ "ccbbbbbccc",
132
+ "ddcccccddd",
133
+ "eeeeeeeeee" ]
134
+
135
+ screen_modify_test(before, after) do |b|
136
+ b.scroll_down_region( 1,2, 3,6, 1)
137
+ end
138
+ end
139
+
140
+ def test_scroll_down_region_enclosed_2
141
+ before = [ "aaaaaaaaaa",
142
+ "bbbbbbbbbb",
143
+ "cccccccccc",
144
+ "dddddddddd",
145
+ "eeeeeeeeee" ]
146
+
147
+ after = [ "aaaaaaaaaa",
148
+ "bb bbb",
149
+ "cc ccc",
150
+ "ddbbbbbddd",
151
+ "eeeeeeeeee" ]
152
+
153
+ screen_modify_test(before, after) do |b|
154
+ b.scroll_down_region( 1,2, 3,6, 2)
155
+ end
156
+ end
157
+
158
+ def test_scroll_left_region_enclosed_1
159
+ before = [ "0123456789",
160
+ "ABCDEFGHIJ",
161
+ "KLMNOPQRST",
162
+ "UVWXYZabcd",
163
+ "efghjijklm" ]
164
+
165
+ after = [ "0123456789",
166
+ "ABDEFG HIJ",
167
+ "KLNOPQ RST",
168
+ "UVXYZa bcd",
169
+ "efghjijklm" ]
170
+
171
+ screen_modify_test(before, after) do |b|
172
+ b.scroll_left_region( 1,2, 3,6, 1)
173
+ end
174
+ end
175
+
176
+ def test_scroll_left_region_enclosed_3
177
+ before = [ "0123456789",
178
+ "ABCDEFGHIJ",
179
+ "KLMNOPQRST",
180
+ "UVWXYZabcd",
181
+ "efghjijklm" ]
182
+
183
+ after = [ "0123456789",
184
+ "ABFG HIJ",
185
+ "KLPQ RST",
186
+ "UVZa bcd",
187
+ "efghjijklm" ]
188
+
189
+ screen_modify_test(before, after) do |b|
190
+ b.scroll_left_region( 1,2, 3,6, 3)
191
+ end
192
+ end
193
+
194
+ def test_scroll_left_down_up_right_region_enclosed_zero
195
+ before = [ "aaaaaaaaaa",
196
+ "bbbbbbbbbb",
197
+ "cccccccccc",
198
+ "dddddddddd",
199
+ "eeeeeeeeee" ]
200
+
201
+ after = [ "aaaaaaaaaa",
202
+ "bbbbbbbbbb",
203
+ "cccccccccc",
204
+ "dddddddddd",
205
+ "eeeeeeeeee" ]
206
+ screen_modify_test(before, after, "scroll_left_region count=0") do |b|
207
+ b.scroll_left_region( 1,2, 3,6, 0)
208
+ end
209
+ screen_modify_test(before, after, "scroll_down_region count=0") do |b|
210
+ b.scroll_down_region( 1,2, 3,6, 0)
211
+ end
212
+ screen_modify_test(before, after, "scroll_up_region count=0") do |b|
213
+ b.scroll_up_region( 1,2, 3,6, 0)
214
+ end
215
+ screen_modify_test(before, after, "scroll_right_region count=0") do |b|
216
+ b.scroll_right_region( 1,2, 3,6, 0)
217
+ end
218
+ end
219
+
220
+ def test_scroll_left_down_up_right_region_enclosed_completely
221
+ before = [ "aaaaaaaaaa",
222
+ "bbbbbbbbbb",
223
+ "cccccccccc",
224
+ "dddddddddd",
225
+ "eeeeeeeeee" ]
226
+
227
+ after = [ "aaaaaaaaaa",
228
+ "bb bbb",
229
+ "cc ccc",
230
+ "dd ddd",
231
+ "eeeeeeeeee" ]
232
+
233
+ # Scroll left
234
+ (5..10).each do |count|
235
+ screen_modify_test(before, after, "scroll_left_region count=#{count}") do |b|
236
+ b.scroll_left_region( 1,2, 3,6, count)
237
+ end
238
+ end
239
+
240
+ # Scroll down
241
+ (3..10).each do |count|
242
+ screen_modify_test(before, after, "scroll_down_region count=#{count}") do |b|
243
+ b.scroll_down_region( 1,2, 3,6, count)
244
+ end
245
+ end
246
+
247
+ # Scroll up
248
+ (3..10).each do |count|
249
+ screen_modify_test(before, after, "scroll_up_region count=#{count}") do |b|
250
+ b.scroll_up_region( 1,2, 3,6, count)
251
+ end
252
+ end
253
+
254
+ # Scroll right
255
+ (5..10).each do |count|
256
+ screen_modify_test(before, after, "scroll_right_region count=#{count}") do |b|
257
+ b.scroll_right_region( 1,2, 3,6, count)
258
+ end
259
+ end
260
+ end
261
+ private
262
+
263
+ def screen_modify_test(start_with, expected, message=nil)
264
+ raise "no block given" unless block_given?
265
+
266
+ b = ScripTTY::MultilineBuffer.new(start_with.length, start_with[0].length)
267
+ b.replace_at(0, 0, start_with)
268
+
269
+ # Do the operation
270
+ yield b
271
+
272
+ # Compare
273
+ assert_equal expected, b.content, message
274
+ end
275
+ end