csv_monster 0.1.1 → 0.2.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.
- data/lib/csv_monster.rb +3 -1
- data/lib/csv_monster/version.rb +1 -1
- data/spec/csv_monster_spec.rb +209 -89
- metadata +2 -2
data/lib/csv_monster.rb
CHANGED
@@ -40,7 +40,7 @@ class CSVMonster
|
|
40
40
|
content.length
|
41
41
|
end
|
42
42
|
|
43
|
-
def split
|
43
|
+
def split(split_count)
|
44
44
|
header, *entries = self.content
|
45
45
|
splits = []
|
46
46
|
|
@@ -57,6 +57,8 @@ class CSVMonster
|
|
57
57
|
splits
|
58
58
|
end
|
59
59
|
|
60
|
+
alias_method :'/', :split
|
61
|
+
|
60
62
|
def write! outfile = nil
|
61
63
|
outfile ||= default_outfile_name
|
62
64
|
CSV.open(outfile, "wb") do |csv|
|
data/lib/csv_monster/version.rb
CHANGED
data/spec/csv_monster_spec.rb
CHANGED
@@ -18,60 +18,80 @@ end
|
|
18
18
|
|
19
19
|
describe CSVMonster do
|
20
20
|
describe "#+" do
|
21
|
-
let(:csv_monster)
|
22
|
-
let(:another_csv_monster) { described_class.new
|
21
|
+
let(:csv_monster) { described_class.new(sample_csv_filepath) }
|
22
|
+
let(:another_csv_monster) { described_class.new(another_sample_csv_filepath) }
|
23
23
|
|
24
|
-
subject { csv_monster +
|
24
|
+
subject { csv_monster + another_csv_monster }
|
25
25
|
|
26
26
|
it "yields a new instance with the combination of the two's content" do
|
27
|
-
expect(csv_monster.content).to eq
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
27
|
+
expect(csv_monster.content).to eq(
|
28
|
+
[
|
29
|
+
["header_1", "header_2"],
|
30
|
+
["row_1_column_1_entry", "row_1_column_2_entry"],
|
31
|
+
["row_2_column_1_entry", "row_2_column_2_entry"]
|
32
|
+
]
|
33
|
+
)
|
34
|
+
|
35
|
+
expect(another_csv_monster.content).to eq(
|
36
|
+
[
|
37
|
+
["header_1", "header_2"],
|
38
|
+
["row_1_column_1_entry_diff_content", "row_1_column_2_entry_diff_content"],
|
39
|
+
["row_2_column_1_entry_diff_content", "row_2_column_2_entry_diff_content"]
|
40
|
+
]
|
41
|
+
)
|
34
42
|
|
35
43
|
result = subject
|
36
44
|
|
37
|
-
expect(csv_monster.content).to eq
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
expect(
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
expect(csv_monster.content).to eq(
|
46
|
+
[
|
47
|
+
["header_1", "header_2"],
|
48
|
+
["row_1_column_1_entry", "row_1_column_2_entry"],
|
49
|
+
["row_2_column_1_entry", "row_2_column_2_entry"]
|
50
|
+
]
|
51
|
+
)
|
52
|
+
|
53
|
+
expect(another_csv_monster.content).to eq(
|
54
|
+
[
|
55
|
+
["header_1", "header_2"],
|
56
|
+
["row_1_column_1_entry_diff_content", "row_1_column_2_entry_diff_content"],
|
57
|
+
["row_2_column_1_entry_diff_content", "row_2_column_2_entry_diff_content"]
|
58
|
+
]
|
59
|
+
)
|
60
|
+
|
61
|
+
expect(result.content).to eq(
|
62
|
+
[
|
63
|
+
["header_1", "header_2"],
|
64
|
+
["row_1_column_1_entry", "row_1_column_2_entry"],
|
65
|
+
["row_2_column_1_entry", "row_2_column_2_entry"],
|
66
|
+
["row_1_column_1_entry_diff_content", "row_1_column_2_entry_diff_content"],
|
67
|
+
["row_2_column_1_entry_diff_content", "row_2_column_2_entry_diff_content"]
|
68
|
+
]
|
69
|
+
)
|
50
70
|
end
|
51
71
|
end
|
52
72
|
|
53
73
|
describe "#==" do
|
54
|
-
let(:csv_monster)
|
74
|
+
let(:csv_monster) { described_class.new }
|
55
75
|
let(:another_csv_monster) { described_class.new }
|
56
76
|
|
57
77
|
context "when the content is the same" do
|
58
78
|
before do
|
59
|
-
csv_monster.filepaths
|
79
|
+
csv_monster.filepaths = sample_csv_filepath
|
60
80
|
another_csv_monster.filepaths = sample_csv_filepath
|
61
81
|
end
|
62
82
|
|
63
83
|
subject { csv_monster == another_csv_monster }
|
64
|
-
it
|
84
|
+
it { expect(subject).to be_true }
|
65
85
|
end
|
66
86
|
|
67
87
|
context "when the content is different" do
|
68
88
|
before do
|
69
|
-
csv_monster.filepaths
|
89
|
+
csv_monster.filepaths = sample_csv_filepath
|
70
90
|
another_csv_monster.filepaths = another_sample_csv_filepath
|
71
91
|
end
|
72
92
|
|
73
93
|
subject { csv_monster == another_csv_monster }
|
74
|
-
it
|
94
|
+
it { expect(subject).to be_false }
|
75
95
|
end
|
76
96
|
end
|
77
97
|
|
@@ -79,33 +99,101 @@ describe CSVMonster do
|
|
79
99
|
let(:csv_monster) { described_class.new }
|
80
100
|
|
81
101
|
context "with a single csv file" do
|
82
|
-
before
|
102
|
+
before { csv_monster.filepaths = sample_csv_filepath }
|
83
103
|
subject { csv_monster.content }
|
84
|
-
it
|
85
|
-
|
86
|
-
|
104
|
+
it {
|
105
|
+
expect(subject).to eq(
|
106
|
+
[
|
107
|
+
["header_1", "header_2"],
|
108
|
+
["row_1_column_1_entry", "row_1_column_2_entry"],
|
109
|
+
["row_2_column_1_entry", "row_2_column_2_entry"]
|
110
|
+
]
|
111
|
+
)
|
112
|
+
}
|
87
113
|
end
|
88
114
|
|
89
115
|
context "with multiple csv files" do
|
90
|
-
before
|
116
|
+
before { csv_monster.filepaths = [sample_csv_filepath, another_sample_csv_filepath] }
|
91
117
|
subject { csv_monster.content }
|
92
118
|
|
93
119
|
it "combines the content, removing headers from all but the first" do
|
94
|
-
expect(subject).to eq
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
120
|
+
expect(subject).to eq(
|
121
|
+
[
|
122
|
+
["header_1", "header_2"],
|
123
|
+
["row_1_column_1_entry", "row_1_column_2_entry"],
|
124
|
+
["row_2_column_1_entry", "row_2_column_2_entry"],
|
125
|
+
["row_1_column_1_entry_diff_content", "row_1_column_2_entry_diff_content"],
|
126
|
+
["row_2_column_1_entry_diff_content", "row_2_column_2_entry_diff_content"]
|
127
|
+
]
|
128
|
+
)
|
99
129
|
end
|
100
130
|
end
|
101
131
|
end
|
102
132
|
|
103
133
|
describe "#content_length" do
|
104
|
-
let(:csv_monster) { described_class.new
|
105
|
-
subject
|
134
|
+
let(:csv_monster) { described_class.new(sample_csv_filepath) }
|
135
|
+
subject { csv_monster.content_length }
|
106
136
|
|
107
137
|
it "equals the number of entries" do
|
108
|
-
expect(subject).to eq
|
138
|
+
expect(subject).to eq(3)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "#/" do
|
143
|
+
let(:number_of_splits) { 2 }
|
144
|
+
|
145
|
+
context "with an even number of records (excluding header)" do
|
146
|
+
let(:csv_monster) { described_class.new(sample_csv_filepath) }
|
147
|
+
|
148
|
+
subject { csv_monster / number_of_splits }
|
149
|
+
|
150
|
+
it "leaves the original instance unchanged" do
|
151
|
+
expect(csv_monster.content).to eq(
|
152
|
+
[
|
153
|
+
["header_1", "header_2"],
|
154
|
+
["row_1_column_1_entry", "row_1_column_2_entry"],
|
155
|
+
["row_2_column_1_entry", "row_2_column_2_entry"]
|
156
|
+
]
|
157
|
+
)
|
158
|
+
|
159
|
+
subject
|
160
|
+
|
161
|
+
expect(csv_monster.content).to eq(
|
162
|
+
[
|
163
|
+
["header_1", "header_2"],
|
164
|
+
["row_1_column_1_entry", "row_1_column_2_entry"],
|
165
|
+
["row_2_column_1_entry", "row_2_column_2_entry"]
|
166
|
+
]
|
167
|
+
)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "returns the specified number of objects of the same type" do
|
171
|
+
result = subject
|
172
|
+
|
173
|
+
expect(result.length).to eq(number_of_splits)
|
174
|
+
|
175
|
+
expect(result[0]).to be_an_instance_of(described_class)
|
176
|
+
expect(result[1]).to be_an_instance_of(described_class)
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
it "splits the content amongst the parts evenly" do
|
181
|
+
result = subject
|
182
|
+
|
183
|
+
expect(result[0].content).to eq(
|
184
|
+
[
|
185
|
+
["header_1", "header_2"],
|
186
|
+
["row_1_column_1_entry", "row_1_column_2_entry"]
|
187
|
+
]
|
188
|
+
)
|
189
|
+
|
190
|
+
expect(result[1].content).to eq(
|
191
|
+
[
|
192
|
+
["header_1", "header_2"],
|
193
|
+
["row_2_column_1_entry", "row_2_column_2_entry"]
|
194
|
+
]
|
195
|
+
)
|
196
|
+
end
|
109
197
|
end
|
110
198
|
end
|
111
199
|
|
@@ -113,106 +201,138 @@ describe CSVMonster do
|
|
113
201
|
let(:number_of_splits) { 2 }
|
114
202
|
|
115
203
|
context "with an even number of records (excluding header)" do
|
116
|
-
let(:csv_monster) { described_class.new
|
204
|
+
let(:csv_monster) { described_class.new(sample_csv_filepath) }
|
117
205
|
|
118
206
|
subject { csv_monster.split(number_of_splits) }
|
119
207
|
|
120
208
|
it "leaves the original instance unchanged" do
|
121
|
-
expect(csv_monster.content).to eq
|
122
|
-
|
123
|
-
|
209
|
+
expect(csv_monster.content).to eq(
|
210
|
+
[
|
211
|
+
["header_1", "header_2"],
|
212
|
+
["row_1_column_1_entry", "row_1_column_2_entry"],
|
213
|
+
["row_2_column_1_entry", "row_2_column_2_entry"]
|
214
|
+
]
|
215
|
+
)
|
124
216
|
|
125
217
|
subject
|
126
218
|
|
127
|
-
expect(csv_monster.content).to eq
|
128
|
-
|
129
|
-
|
219
|
+
expect(csv_monster.content).to eq(
|
220
|
+
[
|
221
|
+
["header_1", "header_2"],
|
222
|
+
["row_1_column_1_entry", "row_1_column_2_entry"],
|
223
|
+
["row_2_column_1_entry", "row_2_column_2_entry"]
|
224
|
+
]
|
225
|
+
)
|
130
226
|
end
|
131
227
|
|
132
228
|
it "returns the specified number of objects of the same type" do
|
133
229
|
result = subject
|
134
230
|
|
135
|
-
expect(result.length).to eq
|
231
|
+
expect(result.length).to eq(number_of_splits)
|
136
232
|
|
137
|
-
expect(result[0]).to be_an_instance_of
|
138
|
-
expect(result[1]).to be_an_instance_of
|
233
|
+
expect(result[0]).to be_an_instance_of(described_class)
|
234
|
+
expect(result[1]).to be_an_instance_of(described_class)
|
139
235
|
end
|
140
236
|
|
141
237
|
|
142
238
|
it "splits the content amongst the parts evenly" do
|
143
239
|
result = subject
|
144
240
|
|
145
|
-
expect(result[0].content).to eq
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
241
|
+
expect(result[0].content).to eq(
|
242
|
+
[
|
243
|
+
["header_1", "header_2"],
|
244
|
+
["row_1_column_1_entry", "row_1_column_2_entry"]
|
245
|
+
]
|
246
|
+
)
|
247
|
+
|
248
|
+
expect(result[1].content).to eq(
|
249
|
+
[
|
250
|
+
["header_1", "header_2"],
|
251
|
+
["row_2_column_1_entry", "row_2_column_2_entry"]
|
252
|
+
]
|
253
|
+
)
|
150
254
|
end
|
151
255
|
end
|
152
256
|
|
153
257
|
context "with an odd number of records (excluding header)" do
|
154
|
-
let(:csv_monster) { described_class.new
|
258
|
+
let(:csv_monster) { described_class.new(odd_number_of_records_csv_filepath) }
|
155
259
|
|
156
260
|
subject { csv_monster.split(number_of_splits) }
|
157
261
|
|
158
262
|
it "leaves the original instance unchanged" do
|
159
|
-
expect(csv_monster.content).to eq
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
263
|
+
expect(csv_monster.content).to eq(
|
264
|
+
[
|
265
|
+
["header_1", "header_2"],
|
266
|
+
["odd_row_1_column_1_entry", "odd_row_1_column_2_entry"],
|
267
|
+
["odd_row_2_column_1_entry", "odd_row_2_column_2_entry"],
|
268
|
+
["odd_row_3_column_1_entry", "odd_row_3_column_2_entry"],
|
269
|
+
["odd_row_4_column_1_entry", "odd_row_4_column_2_entry"],
|
270
|
+
["odd_row_5_column_1_entry", "odd_row_5_column_2_entry"]
|
271
|
+
]
|
272
|
+
)
|
165
273
|
|
166
274
|
subject
|
167
275
|
|
168
|
-
expect(csv_monster.content).to eq
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
276
|
+
expect(csv_monster.content).to eq(
|
277
|
+
[
|
278
|
+
["header_1", "header_2"],
|
279
|
+
["odd_row_1_column_1_entry", "odd_row_1_column_2_entry"],
|
280
|
+
["odd_row_2_column_1_entry", "odd_row_2_column_2_entry"],
|
281
|
+
["odd_row_3_column_1_entry", "odd_row_3_column_2_entry"],
|
282
|
+
["odd_row_4_column_1_entry", "odd_row_4_column_2_entry"],
|
283
|
+
["odd_row_5_column_1_entry", "odd_row_5_column_2_entry"]
|
284
|
+
]
|
285
|
+
)
|
174
286
|
end
|
175
287
|
|
176
288
|
it "returns the specified number of objects of the same type" do
|
177
289
|
result = subject
|
178
|
-
expect(result.length).to eq
|
179
|
-
expect(result[0]).to be_an_instance_of
|
180
|
-
expect(result[1]).to be_an_instance_of
|
290
|
+
expect(result.length).to eq(number_of_splits)
|
291
|
+
expect(result[0]).to be_an_instance_of(described_class)
|
292
|
+
expect(result[1]).to be_an_instance_of(described_class)
|
181
293
|
end
|
182
294
|
|
183
295
|
it "splits the content amongst the parts approximately evenly" do
|
184
296
|
result = subject
|
185
297
|
|
186
|
-
expect(result[0].content).to eq
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
298
|
+
expect(result[0].content).to eq(
|
299
|
+
[
|
300
|
+
["header_1", "header_2"],
|
301
|
+
["odd_row_1_column_1_entry", "odd_row_1_column_2_entry"],
|
302
|
+
["odd_row_2_column_1_entry", "odd_row_2_column_2_entry"]
|
303
|
+
]
|
304
|
+
)
|
305
|
+
|
306
|
+
expect(result[1].content).to eq(
|
307
|
+
[
|
308
|
+
["header_1", "header_2"],
|
309
|
+
["odd_row_3_column_1_entry", "odd_row_3_column_2_entry"],
|
310
|
+
["odd_row_4_column_1_entry", "odd_row_4_column_2_entry"],
|
311
|
+
["odd_row_5_column_1_entry", "odd_row_5_column_2_entry"]
|
312
|
+
]
|
313
|
+
)
|
194
314
|
end
|
195
315
|
end
|
196
316
|
end
|
197
317
|
|
198
318
|
describe "#write!" do
|
199
|
-
let(:infile)
|
200
|
-
let(:outfile)
|
201
|
-
let(:csv_monster) { described_class.new
|
319
|
+
let(:infile) { sample_csv_filepath }
|
320
|
+
let(:outfile) { File.expand_path(File.join("..", "support", "test", "write_sample.csv"), __FILE__) }
|
321
|
+
let(:csv_monster) { described_class.new(infile) }
|
202
322
|
|
203
|
-
before
|
204
|
-
after
|
323
|
+
before { safely_rm(outfile) }
|
324
|
+
after { safely_rm(outfile) }
|
205
325
|
|
206
|
-
subject { csv_monster.write!
|
326
|
+
subject { csv_monster.write!(outfile) }
|
207
327
|
|
208
328
|
it "returns the file path it wrote to" do
|
209
|
-
expect(subject).to eq
|
329
|
+
expect(subject).to eq(outfile)
|
210
330
|
end
|
211
331
|
|
212
332
|
it "writes the file to the specified location" do
|
213
|
-
expect(File.exists?
|
333
|
+
expect(File.exists?(outfile)).to be_false
|
214
334
|
subject
|
215
|
-
expect(FileUtils.identical?
|
335
|
+
expect(FileUtils.identical?(infile, outfile)).to be_true
|
216
336
|
end
|
217
337
|
end
|
218
338
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: csv_monster
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -88,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
88
|
version: '0'
|
89
89
|
requirements: []
|
90
90
|
rubyforge_project:
|
91
|
-
rubygems_version: 1.8.
|
91
|
+
rubygems_version: 1.8.21
|
92
92
|
signing_key:
|
93
93
|
specification_version: 3
|
94
94
|
summary: A monster of a CSV util
|