progress 2.4.0 → 3.0.0
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.
- checksums.yaml +15 -0
- data/.gitignore +1 -0
- data/.travis.yml +12 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +1 -1
- data/README.markdown +8 -6
- data/lib/progress/active_record.rb +18 -20
- data/lib/progress/beeper.rb +24 -0
- data/lib/progress/eta.rb +48 -0
- data/lib/progress/with_progress.rb +42 -7
- data/lib/progress.rb +163 -151
- data/progress.gemspec +1 -1
- data/spec/progress_spec.rb +281 -240
- metadata +39 -57
- data/spec/spec_helper.rb +0 -3
data/spec/progress_spec.rb
CHANGED
@@ -1,321 +1,362 @@
|
|
1
|
-
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
2
|
+
require 'rspec'
|
3
|
+
require 'progress'
|
2
4
|
|
3
5
|
describe Progress do
|
4
|
-
let(:count){ 165 }
|
5
6
|
|
6
|
-
before
|
7
|
-
|
8
|
-
Progress.
|
9
|
-
|
10
|
-
end
|
11
|
-
|
12
|
-
def io_pop
|
13
|
-
@io.seek(0)
|
14
|
-
s = @io.read
|
15
|
-
@io.truncate(0)
|
16
|
-
@io.seek(0)
|
17
|
-
s
|
18
|
-
end
|
7
|
+
before do
|
8
|
+
Progress.stay_on_line = true
|
9
|
+
Progress.highlight = true
|
10
|
+
Progress.set_terminal_title = true
|
19
11
|
|
20
|
-
|
21
|
-
|
12
|
+
Progress.stub(:start_beeper)
|
13
|
+
Progress.stub(:time_to_print?).and_return(true)
|
14
|
+
Progress.stub(:eta)
|
15
|
+
Progress.stub(:elapsed).and_return('0s')
|
22
16
|
end
|
23
17
|
|
24
|
-
|
25
|
-
io_pop.should =~ /#{Regexp.quote(i == 0 ? '......' : '%5.1f' % (i / count.to_f * 100.0))}/
|
26
|
-
end
|
27
|
-
def verify_output_after_stop
|
28
|
-
io_pop.should =~ /100\.0.*\n$/
|
29
|
-
end
|
18
|
+
describe "integrity" do
|
30
19
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
count.times do |i|
|
36
|
-
verify_output_before_step(i, count)
|
37
|
-
Progress.step
|
38
|
-
end
|
39
|
-
Progress.stop
|
40
|
-
verify_output_after_stop
|
41
|
-
end
|
42
|
-
|
43
|
-
it "should show valid output when called as Progress" do
|
44
|
-
Progress('Test', count)
|
45
|
-
count.times do |i|
|
46
|
-
verify_output_before_step(i, count)
|
47
|
-
Progress.step
|
48
|
-
end
|
49
|
-
Progress.stop
|
50
|
-
verify_output_after_stop
|
51
|
-
end
|
20
|
+
before do
|
21
|
+
@io = double(:<< => nil, :tty? => true)
|
22
|
+
Progress.stub(:io).and_return(@io)
|
23
|
+
end
|
52
24
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
Progress.step
|
58
|
-
end
|
59
|
-
Progress.stop
|
60
|
-
verify_output_after_stop
|
61
|
-
end
|
25
|
+
it "should return result from start block" do
|
26
|
+
Progress.start('Test') do
|
27
|
+
'test'
|
28
|
+
end.should == 'test'
|
62
29
|
end
|
63
30
|
|
64
|
-
|
65
|
-
|
66
|
-
Progress.
|
67
|
-
count.times do |i|
|
68
|
-
verify_output_before_step(i, count)
|
69
|
-
Progress.step
|
70
|
-
end
|
71
|
-
end
|
72
|
-
verify_output_after_stop
|
31
|
+
it "should return result from step block" do
|
32
|
+
Progress.start 1 do
|
33
|
+
Progress.step{ 'test' }.should == 'test'
|
73
34
|
end
|
35
|
+
end
|
74
36
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
verify_output_before_step(i, count)
|
79
|
-
Progress.step
|
80
|
-
end
|
81
|
-
end
|
82
|
-
verify_output_after_stop
|
37
|
+
it "should return result from set block" do
|
38
|
+
Progress.start 1 do
|
39
|
+
Progress.set(1){ 'test' }.should == 'test'
|
83
40
|
end
|
41
|
+
end
|
84
42
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
Progress.step
|
90
|
-
end
|
43
|
+
it "should return result from nested block" do
|
44
|
+
[1, 2, 3].with_progress.map do |a|
|
45
|
+
[1, 2, 3].with_progress.map do |b|
|
46
|
+
a * b
|
91
47
|
end
|
92
|
-
|
93
|
-
end
|
48
|
+
end.should == [[1, 2, 3], [2, 4, 6], [3, 6, 9]]
|
94
49
|
end
|
95
|
-
end
|
96
50
|
|
97
|
-
|
98
|
-
it "should not raise errors on extra Progress.stop" do
|
51
|
+
it "should not raise errors on extra step or stop" do
|
99
52
|
proc{
|
100
|
-
|
53
|
+
3.times_with_progress do
|
101
54
|
Progress.start 'simple' do
|
102
|
-
Progress.
|
103
|
-
Progress.
|
104
|
-
Progress.
|
55
|
+
Progress.step
|
56
|
+
Progress.step
|
57
|
+
Progress.step
|
105
58
|
end
|
59
|
+
Progress.step
|
106
60
|
Progress.stop
|
107
61
|
end
|
62
|
+
Progress.step
|
108
63
|
Progress.stop
|
109
64
|
}.should_not raise_error
|
110
65
|
end
|
111
66
|
|
112
|
-
|
113
|
-
Progress.start('Test') do
|
114
|
-
'qwerty'
|
115
|
-
end.should == 'qwerty'
|
116
|
-
end
|
67
|
+
describe Enumerable do
|
117
68
|
|
118
|
-
|
119
|
-
|
120
|
-
Progress.step{ 'qwerty' }.should == 'qwerty'
|
69
|
+
before :each do
|
70
|
+
@a = 0...1000
|
121
71
|
end
|
122
|
-
end
|
123
72
|
|
124
|
-
|
125
|
-
Progress.start do
|
126
|
-
Progress.set(1){ 'qwerty' }.should == 'qwerty'
|
127
|
-
end
|
128
|
-
end
|
73
|
+
describe "with_progress" do
|
129
74
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
75
|
+
it "should not break each" do
|
76
|
+
reference = @a.each
|
77
|
+
@a.with_progress.each do |n|
|
78
|
+
n.should == reference.next
|
79
|
+
end
|
80
|
+
proc{ reference.next }.should raise_error(StopIteration)
|
134
81
|
end
|
135
|
-
end.should == [[1, 2, 3], [2, 4, 6], [3, 6, 9]]
|
136
|
-
end
|
137
82
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
end
|
83
|
+
it "should not break find" do
|
84
|
+
default = proc{ 'default' }
|
85
|
+
@a.with_progress.find{ |n| n == 100 }.should == @a.find{ |n| n == 100 }
|
86
|
+
@a.with_progress.find{ |n| n == 10000 }.should == @a.find{ |n| n == 10000 }
|
87
|
+
@a.with_progress.find(default){ |n| n == 10000 }.should == @a.find(default){ |n| n == 10000 }
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should not break map" do
|
91
|
+
@a.with_progress.map{ |n| n * n }.should == @a.map{ |n| n * n }
|
148
92
|
end
|
149
|
-
io_pop.should == "A: ......\n\n"
|
150
|
-
end
|
151
|
-
end
|
152
93
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
94
|
+
it "should not break grep" do
|
95
|
+
@a.with_progress.grep(100).should == @a.grep(100)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should not break each_cons" do
|
99
|
+
reference = @a.each_cons(3)
|
100
|
+
@a.with_progress.each_cons(3) do |values|
|
101
|
+
values.should == reference.next
|
159
102
|
end
|
160
|
-
|
103
|
+
proc{ reference.next }.should raise_error(StopIteration)
|
161
104
|
end
|
162
|
-
io_pop.should == "A: 100.0%\nA: 100.0%\n\n"
|
163
|
-
end
|
164
105
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
(
|
170
|
-
|
171
|
-
|
172
|
-
|
106
|
+
describe "with_progress.with_progress" do
|
107
|
+
|
108
|
+
it "should not change existing instance" do
|
109
|
+
wp = @a.with_progress('hello')
|
110
|
+
proc{ wp.with_progress('world') }.should_not change(wp, :title)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should create new instance with different title when called on WithProgress" do
|
114
|
+
wp = @a.with_progress('hello')
|
115
|
+
wp_wp = wp.with_progress('world')
|
116
|
+
wp.title.should == 'hello'
|
117
|
+
wp_wp.title.should == 'world'
|
118
|
+
wp_wp.should_not == wp
|
119
|
+
wp_wp.enumerable.should == wp.enumerable
|
173
120
|
end
|
174
|
-
|
121
|
+
|
175
122
|
end
|
176
|
-
io_pop.should == "A: 100.0%\nA: 100.0%\n\n"
|
177
|
-
end
|
178
123
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
124
|
+
describe "calls to each" do
|
125
|
+
|
126
|
+
def without_warnings
|
127
|
+
verbosity = $VERBOSE
|
128
|
+
$VERBOSE = nil
|
129
|
+
result = yield
|
130
|
+
$VERBOSE = verbosity
|
131
|
+
result
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should call each only once for Array" do
|
135
|
+
enum = [1, 2, 3]
|
136
|
+
enum.should_receive(:each).once
|
137
|
+
enum.with_progress.each{ }.should == enum
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should call each only once for Hash" do
|
141
|
+
enum = {1 => 1, 2 => 2, 3 => 3}
|
142
|
+
enum.should_receive(:each).once
|
143
|
+
enum.with_progress.each{ }.should == enum
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should call each only once for Set" do
|
147
|
+
enum = [1, 2, 3].to_set
|
148
|
+
enum.should_receive(:each).once
|
149
|
+
enum.with_progress.each{ }.should == enum
|
150
|
+
end
|
151
|
+
|
152
|
+
if ''.is_a?(Enumerable) # ruby1.8
|
153
|
+
it "should call each only once for String" do
|
154
|
+
enum = "a\nb\nc"
|
155
|
+
enum.should_receive(:each).once
|
156
|
+
without_warnings do
|
157
|
+
enum.with_progress.each{ }.should == enum
|
187
158
|
end
|
188
|
-
io_pop_no_eta.should == "A: %5.1f%% > B: 100.0%\n" % [(a + 1) * a_step.to_f / (100.0 * _a.to_f) * 100.0]
|
189
159
|
end
|
190
|
-
io_pop_no_eta.should == "A: %5.1f%%\n" % [(a + 1) * a_step.to_f / (100.0 * _a.to_f) * 100.0]
|
191
160
|
end
|
192
|
-
|
161
|
+
|
162
|
+
it "should call each only once for File (IO)" do
|
163
|
+
enum = File.open(__FILE__)
|
164
|
+
enum.should_receive(:each).once
|
165
|
+
without_warnings do
|
166
|
+
enum.with_progress.each{ }.should == enum
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should call each only once for StringIO" do
|
171
|
+
enum = StringIO.new("a\nb\nc")
|
172
|
+
enum.should_receive(:each).once
|
173
|
+
without_warnings do
|
174
|
+
enum.with_progress.each{ }.should == enum
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
193
178
|
end
|
194
|
-
io_pop.should == "A: 100.0%\nA: 100.0%\n\n"
|
195
179
|
end
|
196
180
|
end
|
197
|
-
end
|
198
181
|
|
199
|
-
|
200
|
-
|
201
|
-
|
182
|
+
describe Integer do
|
183
|
+
|
184
|
+
let(:count){ 108 }
|
185
|
+
|
186
|
+
it "should not break times_with_progress" do
|
187
|
+
reference = count.times
|
188
|
+
count.times_with_progress do |i|
|
189
|
+
i.should == reference.next
|
190
|
+
end
|
191
|
+
proc{ reference.next }.should raise_error(StopIteration)
|
192
|
+
end
|
193
|
+
|
194
|
+
it "should not break times.with_progress" do
|
195
|
+
reference = count.times
|
196
|
+
count.times.with_progress do |i|
|
197
|
+
i.should == reference.next
|
198
|
+
end
|
199
|
+
proc{ reference.next }.should raise_error(StopIteration)
|
200
|
+
end
|
201
|
+
|
202
202
|
end
|
203
203
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
204
|
+
end
|
205
|
+
|
206
|
+
describe "output" do
|
207
|
+
|
208
|
+
class ChunkIo
|
209
|
+
attr_reader :chunks
|
210
|
+
def initialize
|
211
|
+
@chunks = []
|
210
212
|
end
|
211
213
|
|
212
|
-
|
213
|
-
@
|
214
|
-
@a.with_progress('Hello').find{ |n| n == 10000 }.should == @a.find{ |n| n == 10000 }
|
215
|
-
default = proc{ 'default' }
|
216
|
-
@a.with_progress('Hello').find(default){ |n| n == 10000 }.should == @a.find(default){ |n| n == 10000 }
|
214
|
+
def <<(data)
|
215
|
+
@chunks << data.to_s
|
217
216
|
end
|
217
|
+
end
|
218
218
|
|
219
|
-
|
220
|
-
|
219
|
+
def stub_progress_io(klass)
|
220
|
+
io = klass.new
|
221
|
+
io.stub(:tty?).and_return(true)
|
222
|
+
Progress.stub(:io).and_return(io)
|
223
|
+
io
|
224
|
+
end
|
225
|
+
|
226
|
+
describe "validity" do
|
227
|
+
|
228
|
+
def run_example_progress
|
229
|
+
Progress.start 5, 'Test' do
|
230
|
+
Progress.step 2, 'simle'
|
231
|
+
|
232
|
+
Progress.step 2, 'times' do
|
233
|
+
3.times.with_progress {}
|
234
|
+
end
|
235
|
+
|
236
|
+
Progress.step 'enum' do
|
237
|
+
3.times.to_a.with_progress {}
|
238
|
+
end
|
239
|
+
end
|
221
240
|
end
|
222
241
|
|
223
|
-
|
224
|
-
|
242
|
+
def title(s)
|
243
|
+
"\e]0;#{s}\a"
|
225
244
|
end
|
226
245
|
|
227
|
-
|
228
|
-
|
229
|
-
@a.each_cons(3){ |values| without_progress << values }
|
230
|
-
with_progress = []
|
231
|
-
@a.with_progress('Hello').each_cons(3){ |values| with_progress << values }
|
232
|
-
without_progress.should == with_progress
|
246
|
+
def hl(s)
|
247
|
+
"\e[1m#{s}\e[0m"
|
233
248
|
end
|
234
249
|
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
proc{ wp.with_progress('world') }.should_not change(wp, :title)
|
239
|
-
end
|
250
|
+
def on_line(s)
|
251
|
+
"\r" + s + "\e[K"
|
252
|
+
end
|
240
253
|
|
241
|
-
|
242
|
-
|
243
|
-
wp_wp = wp.with_progress('world')
|
244
|
-
wp.title.should == 'hello'
|
245
|
-
wp_wp.title.should == 'world'
|
246
|
-
wp_wp.should_not == wp
|
247
|
-
wp_wp.enumerable.should == wp.enumerable
|
248
|
-
end
|
254
|
+
def line(s)
|
255
|
+
s + "\n"
|
249
256
|
end
|
250
257
|
|
251
|
-
|
252
|
-
|
253
|
-
|
258
|
+
it "should produce valid output when staying on line" do
|
259
|
+
Progress.stay_on_line = true
|
260
|
+
|
261
|
+
@io = stub_progress_io(ChunkIo)
|
262
|
+
run_example_progress
|
263
|
+
|
264
|
+
@io.chunks.should == [
|
265
|
+
on_line("Test: #{hl '......'}"), title('Test: ......'),
|
266
|
+
on_line("Test: #{hl ' 40.0%'} - simle"), title('Test: 40.0% - simle'),
|
267
|
+
on_line("Test: #{hl ' 40.0%'} > #{hl '......'}"), title('Test: 40.0% > ......'),
|
268
|
+
on_line("Test: #{hl ' 53.3%'} > #{hl ' 33.3%'}"), title('Test: 53.3% > 33.3%'),
|
269
|
+
on_line("Test: #{hl ' 66.7%'} > #{hl ' 66.7%'}"), title('Test: 66.7% > 66.7%'),
|
270
|
+
on_line("Test: #{hl ' 80.0%'} > 100.0%"), title('Test: 80.0% > 100.0%'),
|
271
|
+
on_line("Test: #{hl ' 80.0%'} - times"), title('Test: 80.0% - times'),
|
272
|
+
on_line("Test: #{hl ' 80.0%'} > #{hl '......'}"), title('Test: 80.0% > ......'),
|
273
|
+
on_line("Test: #{hl ' 86.7%'} > #{hl ' 33.3%'}"), title('Test: 86.7% > 33.3%'),
|
274
|
+
on_line("Test: #{hl ' 93.3%'} > #{hl ' 66.7%'}"), title('Test: 93.3% > 66.7%'),
|
275
|
+
on_line("Test: 100.0% > 100.0%"), title('Test: 100.0% > 100.0%'),
|
276
|
+
on_line("Test: 100.0% - enum"), title('Test: 100.0% - enum'),
|
277
|
+
on_line("Test: 100.0% (elapsed: 0s) - enum") + "\n", title(''),
|
278
|
+
]
|
279
|
+
end
|
254
280
|
|
255
|
-
|
256
|
-
|
281
|
+
it "should produce valid output when not staying on line" do
|
282
|
+
Progress.stay_on_line = false
|
283
|
+
|
284
|
+
@io = stub_progress_io(ChunkIo)
|
285
|
+
run_example_progress
|
286
|
+
|
287
|
+
@io.chunks.should == [
|
288
|
+
line("Test: #{hl '......'}"), title('Test: ......'),
|
289
|
+
line("Test: #{hl ' 40.0%'} - simle"), title('Test: 40.0% - simle'),
|
290
|
+
line("Test: #{hl ' 40.0%'} > #{hl '......'}"), title('Test: 40.0% > ......'),
|
291
|
+
line("Test: #{hl ' 53.3%'} > #{hl ' 33.3%'}"), title('Test: 53.3% > 33.3%'),
|
292
|
+
line("Test: #{hl ' 66.7%'} > #{hl ' 66.7%'}"), title('Test: 66.7% > 66.7%'),
|
293
|
+
line("Test: #{hl ' 80.0%'} > 100.0%"), title('Test: 80.0% > 100.0%'),
|
294
|
+
line("Test: #{hl ' 80.0%'} - times"), title('Test: 80.0% - times'),
|
295
|
+
line("Test: #{hl ' 80.0%'} > #{hl '......'}"), title('Test: 80.0% > ......'),
|
296
|
+
line("Test: #{hl ' 86.7%'} > #{hl ' 33.3%'}"), title('Test: 86.7% > 33.3%'),
|
297
|
+
line("Test: #{hl ' 93.3%'} > #{hl ' 66.7%'}"), title('Test: 93.3% > 66.7%'),
|
298
|
+
line("Test: 100.0% > 100.0%"), title('Test: 100.0% > 100.0%'),
|
299
|
+
line("Test: 100.0% - enum"), title('Test: 100.0% - enum'),
|
300
|
+
line("Test: 100.0% (elapsed: 0s) - enum"), title(''),
|
301
|
+
]
|
302
|
+
end
|
257
303
|
|
258
|
-
|
259
|
-
@enum = CallsToEach.new
|
260
|
-
@objects = 10.times.to_a
|
261
|
-
@enum.should_receive(:each).once{ |&block|
|
262
|
-
@objects.each(&block)
|
263
|
-
}
|
264
|
-
end
|
304
|
+
end
|
265
305
|
|
266
|
-
|
267
|
-
init_calls_to_each
|
268
|
-
@enum.should_receive(:length).and_return(10)
|
269
|
-
got = []
|
270
|
-
@enum.with_progress.each{ |o| got << o }.should == @enum
|
271
|
-
got.should == @objects
|
272
|
-
end
|
306
|
+
describe "different call styles" do
|
273
307
|
|
274
|
-
|
275
|
-
|
276
|
-
got = []
|
277
|
-
@enum.with_progress.each{ |o| got << o }.should == @enum
|
278
|
-
got.should == @objects
|
279
|
-
end
|
308
|
+
let(:count_a){ 13 }
|
309
|
+
let(:count_b){ 17 }
|
280
310
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
str.should_receive(:each).once{ |&block|
|
286
|
-
@objects.each(&block)
|
287
|
-
}
|
288
|
-
got = []
|
289
|
-
str.with_progress.each{ |o| got << o }.should == str
|
290
|
-
got.should == @objects
|
311
|
+
before do
|
312
|
+
reference_io = stub_progress_io(StringIO)
|
313
|
+
count_a.times.with_progress('Test') do
|
314
|
+
count_b.times.with_progress {}
|
291
315
|
end
|
316
|
+
@reference_output = reference_io.string
|
317
|
+
|
318
|
+
@io = stub_progress_io(StringIO)
|
292
319
|
end
|
293
|
-
end
|
294
|
-
end
|
295
320
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
321
|
+
it "should output same when called without block" do
|
322
|
+
Progress(count_a, 'Test')
|
323
|
+
count_a.times do
|
324
|
+
Progress.step do
|
325
|
+
Progress.start(count_b)
|
326
|
+
count_b.times do
|
327
|
+
Progress.step
|
328
|
+
end
|
329
|
+
Progress.stop
|
330
|
+
end
|
303
331
|
end
|
332
|
+
Progress.stop
|
333
|
+
@io.string.should == @reference_output
|
304
334
|
end
|
305
335
|
|
306
|
-
it "should
|
307
|
-
|
308
|
-
|
336
|
+
it "should output same when called with block" do
|
337
|
+
Progress(count_a, 'Test') do
|
338
|
+
count_a.times do
|
339
|
+
Progress.step do
|
340
|
+
Progress.start(count_b) do
|
341
|
+
count_b.times do
|
342
|
+
Progress.step
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
309
347
|
end
|
310
|
-
|
348
|
+
@io.string.should == @reference_output
|
311
349
|
end
|
312
350
|
|
313
|
-
it "should
|
314
|
-
|
315
|
-
|
351
|
+
it "should output same when called using with_progress on list" do
|
352
|
+
count_a.times.to_a.with_progress('Test') do
|
353
|
+
count_b.times.to_a.with_progress {}
|
316
354
|
end
|
317
|
-
|
355
|
+
@io.string.should == @reference_output
|
318
356
|
end
|
357
|
+
|
319
358
|
end
|
359
|
+
|
320
360
|
end
|
361
|
+
|
321
362
|
end
|