culturecode-roo 2.0.1

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 (114) hide show
  1. data/.gitignore +7 -0
  2. data/.simplecov +4 -0
  3. data/.travis.yml +13 -0
  4. data/CHANGELOG +438 -0
  5. data/Gemfile +24 -0
  6. data/Guardfile +24 -0
  7. data/LICENSE +22 -0
  8. data/README.md +121 -0
  9. data/Rakefile +23 -0
  10. data/examples/roo_soap_client.rb +50 -0
  11. data/examples/roo_soap_server.rb +26 -0
  12. data/examples/write_me.rb +31 -0
  13. data/lib/roo.rb +28 -0
  14. data/lib/roo/base.rb +717 -0
  15. data/lib/roo/csv.rb +110 -0
  16. data/lib/roo/excelx.rb +542 -0
  17. data/lib/roo/excelx/comments.rb +23 -0
  18. data/lib/roo/excelx/extractor.rb +20 -0
  19. data/lib/roo/excelx/relationships.rb +26 -0
  20. data/lib/roo/excelx/shared_strings.rb +40 -0
  21. data/lib/roo/excelx/sheet_doc.rb +175 -0
  22. data/lib/roo/excelx/styles.rb +62 -0
  23. data/lib/roo/excelx/workbook.rb +59 -0
  24. data/lib/roo/font.rb +17 -0
  25. data/lib/roo/libre_office.rb +5 -0
  26. data/lib/roo/link.rb +15 -0
  27. data/lib/roo/open_office.rb +652 -0
  28. data/lib/roo/spreadsheet.rb +31 -0
  29. data/lib/roo/utils.rb +81 -0
  30. data/lib/roo/version.rb +3 -0
  31. data/roo.gemspec +27 -0
  32. data/scripts/txt2html +67 -0
  33. data/spec/fixtures/vcr_cassettes/google_drive.yml +165 -0
  34. data/spec/fixtures/vcr_cassettes/google_drive_access_token.yml +73 -0
  35. data/spec/fixtures/vcr_cassettes/google_drive_set.yml +857 -0
  36. data/spec/lib/roo/base_spec.rb +4 -0
  37. data/spec/lib/roo/csv_spec.rb +48 -0
  38. data/spec/lib/roo/excelx/format_spec.rb +51 -0
  39. data/spec/lib/roo/excelx_spec.rb +363 -0
  40. data/spec/lib/roo/libreoffice_spec.rb +13 -0
  41. data/spec/lib/roo/openoffice_spec.rb +15 -0
  42. data/spec/lib/roo/spreadsheet_spec.rb +88 -0
  43. data/spec/lib/roo/utils_spec.rb +105 -0
  44. data/spec/spec_helper.rb +9 -0
  45. data/test/all_ss.rb +11 -0
  46. data/test/files/1900_base.xlsx +0 -0
  47. data/test/files/1904_base.xlsx +0 -0
  48. data/test/files/Bibelbund.csv +3741 -0
  49. data/test/files/Bibelbund.ods +0 -0
  50. data/test/files/Bibelbund.xlsx +0 -0
  51. data/test/files/Bibelbund1.ods +0 -0
  52. data/test/files/Pfand_from_windows_phone.xlsx +0 -0
  53. data/test/files/advanced_header.ods +0 -0
  54. data/test/files/bbu.ods +0 -0
  55. data/test/files/bbu.xlsx +0 -0
  56. data/test/files/bode-v1.ods.zip +0 -0
  57. data/test/files/bode-v1.xls.zip +0 -0
  58. data/test/files/boolean.csv +2 -0
  59. data/test/files/boolean.ods +0 -0
  60. data/test/files/boolean.xlsx +0 -0
  61. data/test/files/borders.ods +0 -0
  62. data/test/files/borders.xlsx +0 -0
  63. data/test/files/bug-numbered-sheet-names.xlsx +0 -0
  64. data/test/files/comments.ods +0 -0
  65. data/test/files/comments.xlsx +0 -0
  66. data/test/files/csvtypes.csv +1 -0
  67. data/test/files/datetime.ods +0 -0
  68. data/test/files/datetime.xlsx +0 -0
  69. data/test/files/dreimalvier.ods +0 -0
  70. data/test/files/emptysheets.ods +0 -0
  71. data/test/files/emptysheets.xlsx +0 -0
  72. data/test/files/encrypted-letmein.ods +0 -0
  73. data/test/files/file_item_error.xlsx +0 -0
  74. data/test/files/formula.ods +0 -0
  75. data/test/files/formula.xlsx +0 -0
  76. data/test/files/formula_string_error.xlsx +0 -0
  77. data/test/files/html-escape.ods +0 -0
  78. data/test/files/link.csv +1 -0
  79. data/test/files/link.xlsx +0 -0
  80. data/test/files/matrix.ods +0 -0
  81. data/test/files/named_cells.ods +0 -0
  82. data/test/files/named_cells.xlsx +0 -0
  83. data/test/files/no_spreadsheet_file.txt +1 -0
  84. data/test/files/numbers-export.xlsx +0 -0
  85. data/test/files/numbers1.csv +18 -0
  86. data/test/files/numbers1.ods +0 -0
  87. data/test/files/numbers1.xlsx +0 -0
  88. data/test/files/numbers1withnull.xlsx +0 -0
  89. data/test/files/numeric-link.xlsx +0 -0
  90. data/test/files/only_one_sheet.ods +0 -0
  91. data/test/files/only_one_sheet.xlsx +0 -0
  92. data/test/files/paragraph.ods +0 -0
  93. data/test/files/paragraph.xlsx +0 -0
  94. data/test/files/ric.ods +0 -0
  95. data/test/files/sheet1.xml +109 -0
  96. data/test/files/simple_spreadsheet.ods +0 -0
  97. data/test/files/simple_spreadsheet.xlsx +0 -0
  98. data/test/files/simple_spreadsheet_from_italo.ods +0 -0
  99. data/test/files/so_datetime.csv +8 -0
  100. data/test/files/style.ods +0 -0
  101. data/test/files/style.xlsx +0 -0
  102. data/test/files/time-test.csv +2 -0
  103. data/test/files/time-test.ods +0 -0
  104. data/test/files/time-test.xlsx +0 -0
  105. data/test/files/type_excel.ods +0 -0
  106. data/test/files/type_excel.xlsx +0 -0
  107. data/test/files/type_excelx.ods +0 -0
  108. data/test/files/type_openoffice.xlsx +0 -0
  109. data/test/files/whitespace.ods +0 -0
  110. data/test/files/whitespace.xlsx +0 -0
  111. data/test/test_generic_spreadsheet.rb +211 -0
  112. data/test/test_helper.rb +58 -0
  113. data/test/test_roo.rb +1977 -0
  114. metadata +329 -0
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe Roo::Base do
4
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe Roo::CSV do
4
+ let(:path) { 'test/files/csvtypes.csv' }
5
+ let(:csv) { Roo::CSV.new(path) }
6
+
7
+ describe '.new' do
8
+ it 'creates an instance' do
9
+ expect(csv).to be_a(Roo::CSV)
10
+ end
11
+ end
12
+
13
+ describe '#parse' do
14
+ subject do
15
+ csv.parse(options)
16
+ end
17
+ context 'with headers: true' do
18
+ let(:options) { { headers: true } }
19
+
20
+ it "doesn't blow up" do
21
+ expect { subject }.to_not raise_error
22
+ end
23
+ end
24
+ end
25
+
26
+ describe '#csv_options' do
27
+ context 'when created with the csv_options option' do
28
+ let(:options) do
29
+ {
30
+ col_sep: '\t',
31
+ quote_char: "'"
32
+ }
33
+ end
34
+
35
+ it 'returns the csv options' do
36
+ csv = Roo::CSV.new(path, csv_options: options)
37
+ expect(csv.csv_options).to eq(options)
38
+ end
39
+ end
40
+
41
+ context 'when created without the csv_options option' do
42
+ it 'returns a hash' do
43
+ csv = Roo::CSV.new(path)
44
+ expect(csv.csv_options).to eq({})
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe Roo::Excelx::Format do
4
+ describe '#to_type' do
5
+ FORMATS = {
6
+ 'General' => :float,
7
+ '0' => :float,
8
+ '0.00' => :float,
9
+ '#,##0' => :float,
10
+ '#,##0.00' => :float,
11
+ '0%' => :percentage,
12
+ '0.00%' => :percentage,
13
+ '0.00E+00' => :float,
14
+ '# ?/?' => :float, # ??? TODO:
15
+ '# ??/??' => :float, # ??? TODO:
16
+ 'mm-dd-yy' => :date,
17
+ 'd-mmm-yy' => :date,
18
+ 'd-mmm' => :date,
19
+ 'mmm-yy' => :date,
20
+ 'h:mm AM/PM' => :date,
21
+ 'h:mm:ss AM/PM' => :date,
22
+ 'h:mm' => :time,
23
+ 'h:mm:ss' => :time,
24
+ 'm/d/yy h:mm' => :datetime,
25
+ '#,##0 ;(#,##0)' => :float,
26
+ '#,##0 ;[Red](#,##0)' => :float,
27
+ '#,##0.00;(#,##0.00)' => :float,
28
+ '#,##0.00;[Red](#,##0.00)' => :float,
29
+ '#,##0_);[Red](#,##0)' => :float,
30
+ 'mm:ss' => :time,
31
+ '[h]:mm:ss' => :time,
32
+ 'mmss.0' => :time,
33
+ '##0.0E+0' => :float,
34
+ '@' => :float,
35
+ #-- zusaetzliche Formate, die nicht standardmaessig definiert sind:
36
+ 'yyyy\\-mm\\-dd' => :date,
37
+ 'dd/mm/yy' => :date,
38
+ 'hh:mm:ss' => :time,
39
+ 'dd/mm/yy\\ hh:mm' => :datetime,
40
+ 'dd/mmm/yy\\ hh:mm' => :datetime,
41
+ 'dd/mmm/yy' => :date, # 2011-05-21
42
+ 'yyyy-mm-dd' => :date, # 2011-09-16
43
+ 'yyyy-mm-dd;@' => :date,
44
+ '#0_);[Red]\(0\)' => :float
45
+ }.each do |format, type|
46
+ it "translates #{format} to #{type}" do
47
+ expect(Roo::Excelx::Format.to_type(format)).to eq(type)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,363 @@
1
+ require 'spec_helper'
2
+
3
+ describe Roo::Excelx do
4
+ subject(:xlsx) do
5
+ Roo::Excelx.new(path)
6
+ end
7
+
8
+ describe '.new' do
9
+ let(:path) { 'test/files/numeric-link.xlsx' }
10
+
11
+ it 'creates an instance' do
12
+ expect(subject).to be_a(Roo::Excelx)
13
+ end
14
+
15
+ context 'given a file with missing rels' do
16
+ let(:path) { 'test/files/file_item_error.xlsx' }
17
+
18
+ it 'creates an instance' do
19
+ expect(subject).to be_a(Roo::Excelx)
20
+ end
21
+ end
22
+
23
+ context 'with more cells than specified max' do
24
+ let(:path) { 'test/files/only_one_sheet.xlsx' }
25
+
26
+ it 'raises an appropriate error' do
27
+ expect { Roo::Excelx.new(path, cell_max: 1) }.to raise_error(Roo::Excelx::ExceedsMaxError)
28
+ end
29
+ end
30
+
31
+ context 'with fewer cells than specified max' do
32
+ let(:path) { 'test/files/only_one_sheet.xlsx' }
33
+
34
+ it 'creates an instance' do
35
+ expect(Roo::Excelx.new(path, cell_max: 100)).to be_a(Roo::Excelx)
36
+ end
37
+ end
38
+ end
39
+
40
+ describe '#cell' do
41
+ context 'for a link cell' do
42
+ context 'with numeric contents' do
43
+ let(:path) { 'test/files/numeric-link.xlsx' }
44
+
45
+ subject do
46
+ xlsx.cell('A', 1)
47
+ end
48
+
49
+ it 'returns a link with the number as a string value' do
50
+ expect(subject).to be_a(Roo::Link)
51
+ expect(subject).to eq('8675309.0')
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ describe '#parse' do
58
+ let(:path) { 'test/files/numeric-link.xlsx' }
59
+
60
+ context 'with a columns hash' do
61
+ context 'when not present in the sheet' do
62
+ it 'does not raise' do
63
+ expect do
64
+ xlsx.sheet(0).parse(
65
+ this: 'This',
66
+ that: 'That'
67
+ )
68
+ end.to raise_error("Couldn't find header row.")
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ describe '#sheets' do
75
+ let(:path) { 'test/files/numbers1.xlsx' }
76
+
77
+ it 'returns the expected result' do
78
+ expect(subject.sheets).to eq ["Tabelle1", "Name of Sheet 2", "Sheet3", "Sheet4", "Sheet5"]
79
+ end
80
+ end
81
+
82
+ describe '#sheet_for' do
83
+ let(:path) { 'test/files/numbers1.xlsx' }
84
+
85
+ # This is kinda gross
86
+ it 'returns the expected result' do
87
+ expect(subject.sheet_for("Tabelle1").instance_variable_get("@name")).to eq "Tabelle1"
88
+ end
89
+ end
90
+
91
+ describe '#row' do
92
+ let(:path) { 'test/files/numbers1.xlsx' }
93
+
94
+ it 'returns the expected result' do
95
+ expect(subject.row(1, "Sheet5")).to eq [1.0, 5.0, 5.0, nil, nil]
96
+ end
97
+ end
98
+
99
+ describe '#column' do
100
+ let(:path) { 'test/files/numbers1.xlsx' }
101
+
102
+ it 'returns the expected result' do
103
+ expect(subject.column(1, "Sheet5")).to eq [1.0, 2.0, 3.0, Date.new(2007,11,21), 42.0, "ABC"]
104
+ end
105
+ end
106
+
107
+ describe '#first_row' do
108
+ let(:path) { 'test/files/numbers1.xlsx' }
109
+
110
+ it 'returns the expected result' do
111
+ expect(subject.first_row("Sheet5")).to eq 1
112
+ end
113
+ end
114
+
115
+ describe '#last_row' do
116
+ let(:path) { 'test/files/numbers1.xlsx' }
117
+
118
+ it 'returns the expected result' do
119
+ expect(subject.last_row("Sheet5")).to eq 6
120
+ end
121
+ end
122
+
123
+ describe '#first_column' do
124
+ let(:path) { 'test/files/numbers1.xlsx' }
125
+
126
+ it 'returns the expected result' do
127
+ expect(subject.first_column("Sheet5")).to eq 1
128
+ end
129
+ end
130
+
131
+ describe '#last_column' do
132
+ let(:path) { 'test/files/numbers1.xlsx' }
133
+
134
+ it 'returns the expected result' do
135
+ expect(subject.last_column("Sheet5")).to eq 5
136
+ end
137
+ end
138
+
139
+ describe '#set' do
140
+
141
+ before do
142
+ subject.set(1, 2, "Foo", "Sheet5")
143
+ end
144
+
145
+ let(:path) { 'test/files/numbers1.xlsx' }
146
+ let(:cell) { subject.cell(1, 2, "Sheet5") }
147
+
148
+ it 'returns the expected result' do
149
+ expect(cell).to eq "Foo"
150
+ end
151
+ end
152
+
153
+ describe '#formula' do
154
+ let(:path) { 'test/files/formula.xlsx' }
155
+
156
+ it 'returns the expected result' do
157
+ expect(subject.formula(1, 1, "Sheet1")).to eq nil
158
+ expect(subject.formula(7, 2, "Sheet1")).to eq "SUM($A$1:B6)"
159
+ end
160
+ end
161
+
162
+ describe '#formula?' do
163
+ let(:path) { 'test/files/formula.xlsx' }
164
+
165
+ it 'returns the expected result' do
166
+ expect(subject.formula?(1, 1, "Sheet1")).to eq false
167
+ expect(subject.formula?(7, 2, "Sheet1")).to eq true
168
+ end
169
+ end
170
+
171
+ describe '#formulas' do
172
+ let(:path) { 'test/files/formula.xlsx' }
173
+
174
+ it 'returns the expected result' do
175
+ expect(subject.formulas("Sheet1")).to eq [[7, 1, "SUM(A1:A6)"], [7, 2, "SUM($A$1:B6)"]]
176
+ end
177
+ end
178
+
179
+ describe '#font' do
180
+ let(:path) { 'test/files/style.xlsx' }
181
+
182
+ it 'returns the expected result' do
183
+ expect(subject.font(1, 1).bold?).to eq true
184
+ expect(subject.font(1, 1).italic?).to eq false
185
+ expect(subject.font(1, 1).underline?).to eq false
186
+
187
+ expect(subject.font(7, 1).bold?).to eq false
188
+ expect(subject.font(7, 1).italic?).to eq true
189
+ expect(subject.font(7, 1).underline?).to eq true
190
+ end
191
+ end
192
+
193
+ describe '#celltype' do
194
+ let(:path) { 'test/files/numbers1.xlsx' }
195
+
196
+ it 'returns the expected result' do
197
+ expect(subject.celltype(1, 1, "Sheet4")).to eq :date
198
+ expect(subject.celltype(1, 2, "Sheet4")).to eq :float
199
+ expect(subject.celltype(6, 2, "Sheet5")).to eq :string
200
+ end
201
+ end
202
+
203
+ describe '#excelx_type' do
204
+ let(:path) { 'test/files/numbers1.xlsx' }
205
+
206
+ it 'returns the expected result' do
207
+ expect(subject.excelx_type(1, 1, "Sheet5")).to eq [:numeric_or_formula, "General"]
208
+ expect(subject.excelx_type(6, 2, "Sheet5")).to eq :string
209
+ end
210
+ end
211
+
212
+ describe '#excelx_value' do
213
+ let(:path) { 'test/files/numbers1.xlsx' }
214
+
215
+ it 'returns the expected result' do
216
+ # These values are the index in the shared strings table, might be a better
217
+ # way to get these rather than hardcoding.
218
+ expect(subject.excelx_value(1, 1, "Sheet5")).to eq "1"
219
+ expect(subject.excelx_value(6, 2, "Sheet5")).to eq "16"
220
+ end
221
+ end
222
+
223
+ describe '#excelx_format' do
224
+ let(:path) { 'test/files/style.xlsx' }
225
+
226
+ it 'returns the expected result' do
227
+ # These are the index of the style for a given document
228
+ # might be more reliable way to get this info.
229
+ expect(subject.excelx_value(1, 1)).to eq "0"
230
+ expect(subject.excelx_value(5, 1)).to eq "4"
231
+ end
232
+ end
233
+
234
+ describe '#empty?' do
235
+ let(:path) { 'test/files/style.xlsx' }
236
+
237
+ it 'returns the expected result' do
238
+ # These are the index of the style for a given document
239
+ # might be more reliable way to get this info.
240
+ expect(subject.empty?(1, 1)).to eq false
241
+ expect(subject.empty?(13, 1)).to eq true
242
+ end
243
+ end
244
+
245
+ describe '#label' do
246
+ let(:path) { 'test/files/named_cells.xlsx' }
247
+
248
+ it 'returns the expected result' do
249
+ expect(subject.label("berta")).to eq [4, 2, "Sheet1"]
250
+ expect(subject.label("dave")).to eq [nil, nil, nil]
251
+ end
252
+ end
253
+
254
+ describe '#labels' do
255
+ let(:path) { 'test/files/named_cells.xlsx' }
256
+
257
+ it 'returns the expected result' do
258
+ expect(subject.labels).to eq [["anton", [5, 3, "Sheet1"]], ["berta", [4, 2, "Sheet1"]], ["caesar", [7, 2, "Sheet1"]]]
259
+ end
260
+ end
261
+
262
+ describe '#hyperlink?' do
263
+ let(:path) { 'test/files/link.xlsx' }
264
+
265
+ it 'returns the expected result' do
266
+ expect(subject.hyperlink?(1, 1)).to eq true
267
+ expect(subject.hyperlink?(1, 2)).to eq false
268
+ end
269
+ end
270
+
271
+ describe '#hyperlink' do
272
+ let(:path) { 'test/files/link.xlsx' }
273
+
274
+ it 'returns the expected result' do
275
+ expect(subject.hyperlink(1, 1)).to eq "http://www.google.com"
276
+ expect(subject.hyperlink(1, 2)).to eq nil
277
+ end
278
+ end
279
+
280
+ describe '#comment' do
281
+ let(:path) { 'test/files/comments.xlsx' }
282
+
283
+ it 'returns the expected result' do
284
+ expect(subject.comment(4, 2)).to eq "Kommentar fuer B4"
285
+ expect(subject.comment(1, 2)).to eq nil
286
+ end
287
+ end
288
+
289
+ describe '#comment?' do
290
+ let(:path) { 'test/files/comments.xlsx' }
291
+
292
+ it 'returns the expected result' do
293
+ expect(subject.comment?(4, 2)).to eq true
294
+ expect(subject.comment?(1, 2)).to eq false
295
+ end
296
+ end
297
+
298
+ describe '#comments' do
299
+ let(:path) { 'test/files/comments.xlsx' }
300
+
301
+ it 'returns the expected result' do
302
+ expect(subject.comments).to eq [[4, 2, "Kommentar fuer B4"], [5, 2, "Kommentar fuer B5"]]
303
+ end
304
+ end
305
+
306
+ # nil, nil, nil, nil, nil
307
+ # nil, nil, nil, nil, nil
308
+ # Date Start time End time Pause Sum Comment
309
+ # 2007-05-07 9.25 10.25 0 1 Task 1
310
+ # 2007-05-07 10.75 12.50 0 1.75 Task 1
311
+ # 2007-05-07 18.00 19.00 0 1 Task 2
312
+ # 2007-05-08 9.25 10.25 0 1 Task 2
313
+ # 2007-05-08 14.50 15.50 0 1 Task 3
314
+ # 2007-05-08 8.75 9.25 0 0.5 Task 3
315
+ # 2007-05-14 21.75 22.25 0 0.5 Task 3
316
+ # 2007-05-14 22.50 23.00 0 0.5 Task 3
317
+ # 2007-05-15 11.75 12.75 0 1 Task 3
318
+ # 2007-05-07 10.75 10.75 0 0 Task 1
319
+ # nil
320
+ describe '#each_row_streaming' do
321
+ let(:path) { 'test/files/simple_spreadsheet.xlsx' }
322
+
323
+ let(:expected_rows) do
324
+ [
325
+ [nil, nil, nil, nil, nil],
326
+ [nil, nil, nil, nil, nil],
327
+ ["Date", "Start time", "End time", "Pause", "Sum", "Comment", nil, nil],
328
+ [Date.new(2007, 5, 7), 9.25, 10.25, 0.0, 1.0, "Task 1"],
329
+ [Date.new(2007, 5, 7), 10.75, 12.50, 0.0, 1.75, "Task 1"],
330
+ [Date.new(2007, 5, 7), 18.0, 19.0, 0.0, 1.0, "Task 2"],
331
+ [Date.new(2007, 5, 8), 9.25, 10.25, 0.0, 1.0, "Task 2"],
332
+ [Date.new(2007, 5, 8), 14.5, 15.5, 0.0, 1.0, "Task 3"],
333
+ [Date.new(2007, 5, 8), 8.75, 9.25, 0.0, 0.5, "Task 3"],
334
+ [Date.new(2007, 5, 14), 21.75, 22.25, 0.0, 0.5, "Task 3"],
335
+ [Date.new(2007, 5, 14), 22.5, 23.0, 0.0, 0.5, "Task 3"],
336
+ [Date.new(2007, 5, 15), 11.75, 12.75, 0.0, 1.0, "Task 3"],
337
+ [Date.new(2007, 5, 7), 10.75, 10.75, 0.0, 0.0, "Task 1"],
338
+ [nil]
339
+ ]
340
+ end
341
+
342
+ it 'returns the expected result' do
343
+ index = 0
344
+ subject.each_row_streaming do |row|
345
+ expect(row.map(&:value)).to eq expected_rows[index]
346
+ index += 1
347
+ end
348
+ end
349
+
350
+ context 'with max_rows options' do
351
+ it 'returns the expected result' do
352
+ index = 0
353
+ subject.each_row_streaming(max_rows: 3) do |row|
354
+ expect(row.map(&:value)).to eq expected_rows[index]
355
+ index += 1
356
+ end
357
+ # Expect this to get incremented one time more than max (because of the increment at the end of the block)
358
+ # but it should not be near expected_rows.size
359
+ expect(index).to eq 4
360
+ end
361
+ end
362
+ end
363
+ end