scriptty 0.5.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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