csv2hash 0.6.6 → 0.6.7
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 +4 -4
- data/CHANGELOG.md +11 -1
- data/Gemfile.lock +13 -13
- data/README.md +139 -126
- data/UPGRADE.md +4 -0
- data/config/{rules.extra_validator.erb.yml → rules.extra_validator.yml.erb} +0 -0
- data/config/{rules.erb.yml → rules.yml.erb} +0 -0
- data/lib/csv2hash/validator.rb +46 -26
- data/lib/csv2hash/version.rb +1 -1
- data/lib/csv2hash/yaml_loader.rb +1 -1
- data/lib/csv2hash.rb +9 -3
- data/spec/csv2hash/structure_validator_spec.rb +3 -1
- data/spec/csv2hash/yaml_loader_spec.rb +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 332e1760a8872c909fea63cc52a8701580ab1c50
|
4
|
+
data.tar.gz: 5c40139eef7283dbb3505b2557c539a4a9fb16c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d468a06d1114d8b16f283ea2f06ce08774cfa769eb761e4bb8c6a1f2f78431461c59f31d2ab4c79900ab500546c7c2666bc11a9ea0597ad8550a76c31bf01e8e
|
7
|
+
data.tar.gz: c6e8e3297d875cd2fda25ae025282df0a233170c3543c3d110280e30c8e4d7aedda4e0008941a258473aa5bc844547383b171169205b691ee65008f685a6a1fd
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,19 @@
|
|
1
|
+
### VERSION 0.6.7
|
2
|
+
|
3
|
+
* enhancements
|
4
|
+
* initializer can be take block or value
|
5
|
+
|
6
|
+
* refactoring
|
7
|
+
* following rails way for naming file
|
8
|
+
|
9
|
+
* [fullchanges](https://github.com/FinalCAD/csv2hash/pull/17)
|
10
|
+
|
1
11
|
### VERSION 0.6.6
|
2
12
|
|
3
13
|
* refactoring
|
4
14
|
* little trick on YamlLoader
|
5
15
|
|
6
|
-
* [fullchanges](https://github.com/FinalCAD/csv2hash/
|
16
|
+
* [fullchanges](https://github.com/FinalCAD/csv2hash/commit/a4b3fb5b6cdb3ed41b039f68391b30054fab3668)
|
7
17
|
|
8
18
|
### VERSION 0.6.5
|
9
19
|
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
csv2hash (0.6.
|
4
|
+
csv2hash (0.6.7)
|
5
5
|
activesupport (~> 4.1)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: http://rubygems.org/
|
9
9
|
specs:
|
10
|
-
activesupport (4.1.
|
10
|
+
activesupport (4.1.6)
|
11
11
|
i18n (~> 0.6, >= 0.6.9)
|
12
12
|
json (~> 1.7, >= 1.7.7)
|
13
13
|
minitest (~> 5.1)
|
@@ -44,18 +44,18 @@ GEM
|
|
44
44
|
rest-client (1.7.2)
|
45
45
|
mime-types (>= 1.16, < 3.0)
|
46
46
|
netrc (~> 0.7)
|
47
|
-
rspec (3.
|
48
|
-
rspec-core (~> 3.
|
49
|
-
rspec-expectations (~> 3.
|
50
|
-
rspec-mocks (~> 3.
|
51
|
-
rspec-core (3.
|
52
|
-
rspec-support (~> 3.
|
53
|
-
rspec-expectations (3.
|
47
|
+
rspec (3.1.0)
|
48
|
+
rspec-core (~> 3.1.0)
|
49
|
+
rspec-expectations (~> 3.1.0)
|
50
|
+
rspec-mocks (~> 3.1.0)
|
51
|
+
rspec-core (3.1.3)
|
52
|
+
rspec-support (~> 3.1.0)
|
53
|
+
rspec-expectations (3.1.1)
|
54
54
|
diff-lcs (>= 1.2.0, < 2.0)
|
55
|
-
rspec-support (~> 3.
|
56
|
-
rspec-mocks (3.0
|
57
|
-
rspec-support (~> 3.
|
58
|
-
rspec-support (3.0
|
55
|
+
rspec-support (~> 3.1.0)
|
56
|
+
rspec-mocks (3.1.0)
|
57
|
+
rspec-support (~> 3.1.0)
|
58
|
+
rspec-support (3.1.0)
|
59
59
|
simplecov (0.9.0)
|
60
60
|
docile (~> 1.1.0)
|
61
61
|
multi_json
|
data/README.md
CHANGED
@@ -31,16 +31,16 @@ Parsing is based on rules, you should defined rule for each cells
|
|
31
31
|
### DSL
|
32
32
|
|
33
33
|
```
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
34
|
+
Csv2hash::Main.generate_definition :name do
|
35
|
+
set_type { Definition::MAPPING }
|
36
|
+
set_header_size { 2 } # 0 by default
|
37
|
+
set_structure_rules {{ max_columns: 2 }}
|
38
|
+
mapping do
|
39
|
+
cell position: [0,0], key: 'gender'
|
40
|
+
cell position: [1,0], key: 'name'
|
42
41
|
end
|
43
|
-
|
42
|
+
end
|
43
|
+
Csv2hash::Main[:name] # Access anywhere
|
44
44
|
```
|
45
45
|
|
46
46
|
### Rules
|
@@ -52,37 +52,37 @@ Example :
|
|
52
52
|
If you want the very first cell, located on the first line and on the first column to be a string with values are either 'yes' either 'no', you can write the following validation rule:
|
53
53
|
|
54
54
|
```
|
55
|
-
|
55
|
+
cell name: 'aswering', type: 'string', values: ['yes', 'no'], position: [0,0]
|
56
56
|
```
|
57
57
|
|
58
58
|
`:type` attribute has `String` for default value, therefore you can just write this:
|
59
59
|
|
60
60
|
```
|
61
|
-
|
61
|
+
cell name: 'aswering', values: ['yes', 'no'], position: [0,0]
|
62
62
|
```
|
63
63
|
|
64
64
|
You can define you own message but default message is 'undefined :key on :position'
|
65
65
|
|
66
66
|
```
|
67
|
-
|
67
|
+
cell name: 'aswering', values: ['yes', 'no'], position: [0,0], message: 'this value is not supported'
|
68
68
|
```
|
69
69
|
|
70
70
|
You can also define Range of values
|
71
71
|
|
72
72
|
```
|
73
|
-
|
73
|
+
cell name: 'score', values: 0..5, position: [0,0]
|
74
74
|
```
|
75
75
|
|
76
76
|
The message is parsed:
|
77
77
|
|
78
78
|
```
|
79
|
-
|
79
|
+
cell ..., message: 'value of :name is not supported, please you one of :values'
|
80
80
|
```
|
81
81
|
|
82
82
|
It produces :
|
83
83
|
|
84
84
|
```
|
85
|
-
|
85
|
+
value of answering is not supported, please use one of [yes, no]
|
86
86
|
```
|
87
87
|
|
88
88
|
### Default values
|
@@ -109,6 +109,24 @@ A definition should be provided. There are 2 types of definitions:
|
|
109
109
|
* search for data at a precise position in the table: `y,x`
|
110
110
|
* or search for data in a column of rows, where all the rows are the same: `x` (column index)
|
111
111
|
|
112
|
+
## Invoke
|
113
|
+
|
114
|
+
```
|
115
|
+
Csv2hash::Main.new(:<definition_name>, file_path_or_data, options).parse
|
116
|
+
```
|
117
|
+
|
118
|
+
```
|
119
|
+
Csv2hash::Main.new(:<definition_name>, options) do
|
120
|
+
file_path_or_data
|
121
|
+
end.parse
|
122
|
+
```
|
123
|
+
|
124
|
+
### Options
|
125
|
+
|
126
|
+
List of options :
|
127
|
+
|
128
|
+
* ignore_blank_line: :boolean # i think is pretty straightforward to understand
|
129
|
+
|
112
130
|
## Samples
|
113
131
|
|
114
132
|
### [MAPPING] Validation of cells with defined precision
|
@@ -126,33 +144,31 @@ Consider the following CSV:
|
|
126
144
|
Precise position validation sample:
|
127
145
|
|
128
146
|
```
|
129
|
-
|
147
|
+
class MyParser
|
130
148
|
|
131
|
-
|
149
|
+
attr_accessor :file_path_or_data
|
132
150
|
|
133
|
-
|
134
|
-
|
135
|
-
|
151
|
+
def initialize file_path_or_data
|
152
|
+
@file_path_or_data = file_path_or_data
|
153
|
+
end
|
136
154
|
|
137
|
-
|
138
|
-
|
139
|
-
|
155
|
+
def data
|
156
|
+
@data_wrapper ||= Csv2hash::Main.new(:<definition_name>, file_path_or_data).parse
|
157
|
+
end
|
140
158
|
|
141
|
-
|
142
|
-
|
143
|
-
def definition
|
144
|
-
Main.generate_definition :my_defintion do
|
145
|
-
set_type { Definition::MAPPING }
|
146
|
-
set_header_size { 1 }
|
147
|
-
mapping do
|
148
|
-
cell position: [2,1], key: 'first_name'
|
149
|
-
cell position: [3,1], key: 'last_name'
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
159
|
+
private
|
154
160
|
|
161
|
+
def definition
|
162
|
+
Main.generate_definition :my_defintion do
|
163
|
+
set_type { Definition::MAPPING }
|
164
|
+
set_header_size { 1 }
|
165
|
+
mapping do
|
166
|
+
cell position: [2,1], key: 'first_name'
|
167
|
+
cell position: [3,1], key: 'last_name'
|
168
|
+
end
|
169
|
+
end
|
155
170
|
end
|
171
|
+
end
|
156
172
|
```
|
157
173
|
|
158
174
|
### Auto discover position
|
@@ -177,14 +193,14 @@ You want extract `Employment` information and `Personal info` but we do not know
|
|
177
193
|
|
178
194
|
You must change Y position (rows) by the column index and regex, the parser will search on this column the index row of this regex, here our rule :
|
179
195
|
|
180
|
-
```
|
181
|
-
|
196
|
+
```
|
197
|
+
cell position: [4,1], key: 'employment'
|
182
198
|
```
|
183
199
|
|
184
200
|
became
|
185
201
|
|
186
202
|
```
|
187
|
-
|
203
|
+
cell position: [[0, /Employment/],1], key: 'employment'
|
188
204
|
```
|
189
205
|
|
190
206
|
### [COLLECTION] Validation of a collection (Regular CSV)
|
@@ -201,38 +217,36 @@ Consider the following CSV:
|
|
201
217
|
Collection validation sample:
|
202
218
|
|
203
219
|
```
|
204
|
-
|
205
|
-
|
206
|
-
attr_accessor :file_path_or_data
|
220
|
+
class MyParser
|
207
221
|
|
208
|
-
|
209
|
-
@file_path_or_data = file_path_or_data
|
210
|
-
end
|
211
|
-
|
212
|
-
def data
|
213
|
-
@data_wrapper ||= Csv2hash::Main.new(:<definition_name>, file_path_or_data).parse
|
214
|
-
end
|
222
|
+
attr_accessor :file_path_or_data
|
215
223
|
|
216
|
-
|
224
|
+
def initialize file_path_or_data
|
225
|
+
@file_path_or_data = file_path_or_data
|
226
|
+
end
|
217
227
|
|
218
|
-
|
219
|
-
|
220
|
-
|
228
|
+
def data
|
229
|
+
@data_wrapper ||= Csv2hash::Main.new(:<definition_name>, file_path_or_data).parse
|
230
|
+
end
|
221
231
|
|
222
|
-
|
223
|
-
Main.generate_definition :my_defintion do
|
224
|
-
set_type { Definition::COLLECTION }
|
225
|
-
set_header_size { 1 }
|
226
|
-
mapping do
|
227
|
-
cell position: 0, key: 'nickname'
|
228
|
-
cell position: 1, key: 'first_name'
|
229
|
-
cell position: 2, key: 'last_name'
|
230
|
-
end
|
231
|
-
end
|
232
|
-
end
|
233
|
-
end
|
232
|
+
private
|
234
233
|
|
234
|
+
def definition
|
235
|
+
Csv2Hash::Definition.new(rules, type = Csv2Hash::Definition::COLLECTION, header_size: 1)
|
235
236
|
end
|
237
|
+
|
238
|
+
def definition
|
239
|
+
Main.generate_definition :my_defintion do
|
240
|
+
set_type { Definition::COLLECTION }
|
241
|
+
set_header_size { 1 }
|
242
|
+
mapping do
|
243
|
+
cell position: 0, key: 'nickname'
|
244
|
+
cell position: 1, key: 'first_name'
|
245
|
+
cell position: 2, key: 'last_name'
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
236
250
|
```
|
237
251
|
|
238
252
|
### Structure validation rules
|
@@ -241,34 +255,33 @@ You may want to validate some structure, like min or max number of columns, defi
|
|
241
255
|
Current validations are: :min_columns, :max_columns
|
242
256
|
|
243
257
|
```
|
244
|
-
|
258
|
+
class MyParser
|
245
259
|
|
246
|
-
|
260
|
+
attr_accessor :file_path_or_data
|
247
261
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
def data
|
253
|
-
@data_wrapper ||= Csv2hash::Main.new(:<definition_name>, file_path_or_data).parse
|
254
|
-
end
|
262
|
+
def initialize file_path_or_data
|
263
|
+
@file_path_or_data = file_path_or_data
|
264
|
+
end
|
255
265
|
|
256
|
-
|
266
|
+
def data
|
267
|
+
@data_wrapper ||= Csv2hash::Main.new(:<definition_name>, file_path_or_data).parse
|
268
|
+
end
|
257
269
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
270
|
+
private
|
271
|
+
|
272
|
+
def definition
|
273
|
+
Main.generate_definition :my_defintion do
|
274
|
+
set_type { Definition::COLLECTION }
|
275
|
+
set_header_size { 1 }
|
276
|
+
set_structure_rules {{ min_columns: 2, max_columns: 3 }}
|
277
|
+
mapping do
|
278
|
+
cell position: 0, key: 'nickname'
|
279
|
+
cell position: 1, key: 'first_name'
|
280
|
+
cell position: 2, key: 'last_name'
|
269
281
|
end
|
270
282
|
end
|
271
283
|
end
|
284
|
+
end
|
272
285
|
```
|
273
286
|
|
274
287
|
### CSV Headers
|
@@ -276,7 +289,7 @@ Current validations are: :min_columns, :max_columns
|
|
276
289
|
You can define the number of rows to skip in the header of the CSV.
|
277
290
|
|
278
291
|
```
|
279
|
-
|
292
|
+
set_header_size { 1 }
|
280
293
|
```
|
281
294
|
|
282
295
|
### Parser and configuration
|
@@ -284,7 +297,7 @@ You can define the number of rows to skip in the header of the CSV.
|
|
284
297
|
Pasrer can take several parameters like that:
|
285
298
|
|
286
299
|
```
|
287
|
-
|
300
|
+
definition, file_path_or_data, ignore_blank_line: false
|
288
301
|
```
|
289
302
|
|
290
303
|
in `file_path_or_data` attribute you can pass directly an `Array` of data (`Array` with 2 dimensions) really useful for testing, if you don't care about blank lines in your CSV you can ignore them.
|
@@ -294,18 +307,18 @@ in `file_path_or_data` attribute you can pass directly an `Array` of data (`Arra
|
|
294
307
|
The parser return values wrapper into `DataWrapper Object`, you can call ```.valid?``` method on this Object and grab either data or errors like that :
|
295
308
|
|
296
309
|
```
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
310
|
+
response = parser.parse
|
311
|
+
if response.valid?
|
312
|
+
response.data
|
313
|
+
else
|
314
|
+
response.errors
|
315
|
+
end
|
303
316
|
```
|
304
317
|
|
305
318
|
data or errors are Array, but errors can be formatted on csv format with .to_csv call
|
306
319
|
|
307
320
|
```
|
308
|
-
|
321
|
+
response.errors.to_csv
|
309
322
|
```
|
310
323
|
|
311
324
|
## Exception or Not !
|
@@ -323,34 +336,34 @@ You need call `.parse()` return `data_wrapper` if `.parse()` is invalid, you can
|
|
323
336
|
in your code
|
324
337
|
|
325
338
|
```
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
339
|
+
parser = Csv2hash::Main.new(definition, file_path_or_data, ignore_blank_line: false).new
|
340
|
+
response = parser.parse
|
341
|
+
return response if response.valid?
|
342
|
+
# Whatever
|
330
343
|
```
|
331
344
|
|
332
345
|
In the same time Csv2hash call **notify(response)** method when CSV parsing fail, you can add your own Notifier:
|
333
346
|
|
334
347
|
```
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
348
|
+
module Csv2hash
|
349
|
+
module Plugins
|
350
|
+
class Notifier
|
351
|
+
def initialize csv2hash
|
352
|
+
csv2hash.notifier.extend NotifierWithEmail
|
353
|
+
end
|
341
354
|
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
end
|
355
|
+
module NotifierWithEmail
|
356
|
+
def notify response
|
357
|
+
filename = 'issues_errors.csv'
|
358
|
+
tempfile = Tempfile.new [filename, File.extname(filename)]
|
359
|
+
File.open(tempfile.path, 'wb') { |file| file.write response.errors.to_csv }
|
360
|
+
# Send mail with csv file + errors and free resource
|
361
|
+
tempfile.unlink
|
350
362
|
end
|
351
363
|
end
|
352
364
|
end
|
353
365
|
end
|
366
|
+
end
|
354
367
|
```
|
355
368
|
|
356
369
|
Or other implementation
|
@@ -360,7 +373,7 @@ Or other implementation
|
|
360
373
|
errors is a Array of Hash
|
361
374
|
|
362
375
|
```
|
363
|
-
|
376
|
+
{ y: 1, x: 0, message: 'message', key: 'key', value: '' }
|
364
377
|
```
|
365
378
|
|
366
379
|
## Sample
|
@@ -376,13 +389,13 @@ errors is a Array of Hash
|
|
376
389
|
### Rule
|
377
390
|
|
378
391
|
```
|
379
|
-
|
392
|
+
cell position: [1,1], key: 'nickname', allow_blank: false
|
380
393
|
```
|
381
394
|
|
382
395
|
### Error
|
383
396
|
|
384
397
|
```
|
385
|
-
|
398
|
+
{ y: 1, x: 1, message: 'undefined nikcname on [0, 0]', key: 'nickname', value: nil }
|
386
399
|
```
|
387
400
|
|
388
401
|
## Personal Validator Rule
|
@@ -392,24 +405,24 @@ You can define your own Validator
|
|
392
405
|
For downcase validation
|
393
406
|
|
394
407
|
```
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
end
|
408
|
+
class DowncaseValidator < Csv2hash::ExtraValidator
|
409
|
+
def valid? value
|
410
|
+
!!(value.match /^[a-z]+$/)
|
399
411
|
end
|
412
|
+
end
|
400
413
|
```
|
401
414
|
|
402
415
|
in your rule
|
403
416
|
|
404
417
|
```
|
405
|
-
|
406
|
-
|
418
|
+
cell position: [0,0], key: 'name', extra_validator: DowncaseValidator.new,
|
419
|
+
message: 'your data should be written in lowercase only.'
|
407
420
|
```
|
408
421
|
|
409
422
|
Csv data
|
410
423
|
|
411
424
|
```
|
412
|
-
|
425
|
+
[ [ 'Foo' ] ]
|
413
426
|
```
|
414
427
|
|
415
428
|
# Config file
|
@@ -468,19 +481,19 @@ position: [[0,'LastName'],1]
|
|
468
481
|
|
469
482
|
this change is due to Yaml conversion
|
470
483
|
|
471
|
-
You can write ERB file, should be named with following convention ```<file name>.erb
|
484
|
+
You can write ERB file, should be named with following convention ```<file name>.yml.erb```
|
472
485
|
|
473
486
|
## YamlLoader
|
474
487
|
|
475
488
|
You can load your definition with YamlLoader llike that :
|
476
489
|
|
477
490
|
```
|
478
|
-
loader = Csv2hash::YamlLoader.load!('config/rules.erb
|
491
|
+
loader = Csv2hash::YamlLoader.load!('config/rules.yml.erb')
|
479
492
|
loader.definition
|
480
493
|
```
|
481
494
|
or
|
482
495
|
```
|
483
|
-
loader = Csv2hash::YamlLoader.new('config/rules.erb
|
496
|
+
loader = Csv2hash::YamlLoader.new('config/rules.yml.erb')
|
484
497
|
loader.load!
|
485
498
|
loader.definition
|
486
499
|
```
|
data/UPGRADE.md
CHANGED
File without changes
|
File without changes
|
data/lib/csv2hash/validator.rb
CHANGED
@@ -25,16 +25,13 @@ module Csv2hash
|
|
25
25
|
def validate_cell y, x, cell
|
26
26
|
value = data_source[y][x] rescue nil
|
27
27
|
begin
|
28
|
-
|
29
|
-
if
|
30
|
-
|
28
|
+
verify_blank! cell, value
|
29
|
+
if extra_validator?(cell)
|
30
|
+
verify_extra_validator! cell, value
|
31
31
|
else
|
32
|
-
if
|
33
|
-
|
34
|
-
|
35
|
-
else
|
36
|
-
raise unless values.include?(value)
|
37
|
-
end
|
32
|
+
if rang? cell, value
|
33
|
+
values = cell.rules.fetch(:values)
|
34
|
+
verify_rang! values, value
|
38
35
|
end
|
39
36
|
end
|
40
37
|
rescue => e
|
@@ -54,27 +51,50 @@ module Csv2hash
|
|
54
51
|
|
55
52
|
private
|
56
53
|
|
54
|
+
def extra_validator? cell
|
55
|
+
(extra_validator = cell.rules.fetch(:extra_validator)) && extra_validator.kind_of?(ExtraValidator)
|
56
|
+
end
|
57
|
+
|
58
|
+
def verify_extra_validator! cell, value
|
59
|
+
raise unless cell.rules.fetch(:extra_validator).valid? cell.rules, value
|
60
|
+
end
|
61
|
+
|
62
|
+
def verify_blank! cell, value
|
63
|
+
raise unless value unless cell.rules.fetch :allow_blank
|
64
|
+
end
|
65
|
+
|
66
|
+
def rang? cell, value
|
67
|
+
value && (values = cell.rules.fetch(:values))
|
68
|
+
end
|
69
|
+
|
70
|
+
def verify_rang! values, value
|
71
|
+
if values.class == Range
|
72
|
+
raise unless values.include?(value.to_f)
|
73
|
+
else
|
74
|
+
raise unless values.include?(value)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
57
78
|
def find_or_remove_dynamic_fields!
|
58
79
|
cells = definition.cells.dup
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
80
|
+
# cells without optional and not found dynamic field
|
81
|
+
definition.cells = [].tap do |_cells|
|
82
|
+
while(!cells.empty?) do
|
83
|
+
cell = cells.pop
|
84
|
+
_y, x = cell.rules.fetch(:position)
|
85
|
+
if dynamic_field?(_y)
|
86
|
+
begin
|
87
|
+
_cell = find_dynamic_position cell
|
88
|
+
_cells << _cell
|
89
|
+
rescue => e
|
90
|
+
self.errors << { y: (_y||y), x: x, message: e.message, key: cell.rules.fetch(:key) }
|
91
|
+
raise if break_on_failure
|
92
|
+
end
|
93
|
+
else
|
94
|
+
_cells << cell
|
71
95
|
end
|
72
|
-
else
|
73
|
-
_cells << cell
|
74
96
|
end
|
75
|
-
end
|
76
|
-
|
77
|
-
definition.cells = _cells # cells without optional and not found dynamic field
|
97
|
+
end.compact
|
78
98
|
nil
|
79
99
|
end
|
80
100
|
|
data/lib/csv2hash/version.rb
CHANGED
data/lib/csv2hash/yaml_loader.rb
CHANGED
data/lib/csv2hash.rb
CHANGED
@@ -70,10 +70,16 @@ module Csv2hash
|
|
70
70
|
|
71
71
|
attr_accessor :definition, :file_path_or_data, :data, :notifier, :break_on_failure, :errors, :options
|
72
72
|
|
73
|
-
def initialize
|
74
|
-
self.options
|
73
|
+
def initialize *args
|
74
|
+
self.options = args.extract_options!
|
75
|
+
definition_file_or_symbol, file_path_or_data = args
|
76
|
+
|
77
|
+
unless block_given? ^ file_path_or_data
|
78
|
+
raise ArgumentError, 'Either value or block must be given, but not both'
|
79
|
+
end
|
80
|
+
|
81
|
+
self.file_path_or_data = file_path_or_data || yield
|
75
82
|
self.definition = load_definition(definition_file_or_symbol)
|
76
|
-
self.file_path_or_data = file_path_or_data
|
77
83
|
self.break_on_failure = false
|
78
84
|
self.errors = []
|
79
85
|
self.notifier = Notifier.new
|
@@ -6,7 +6,7 @@ module Csv2hash
|
|
6
6
|
before { subject.load! }
|
7
7
|
|
8
8
|
context 'yml' do
|
9
|
-
let(:config_file) { 'config/rules.erb
|
9
|
+
let(:config_file) { 'config/rules.yml.erb' }
|
10
10
|
|
11
11
|
specify do
|
12
12
|
expect(subject.definition.name).to eql('example')
|
@@ -25,7 +25,7 @@ module Csv2hash
|
|
25
25
|
end
|
26
26
|
|
27
27
|
context 'extra validator' do
|
28
|
-
let(:config_file) { 'config/rules.extra_validator.erb
|
28
|
+
let(:config_file) { 'config/rules.extra_validator.yml.erb' }
|
29
29
|
|
30
30
|
specify do
|
31
31
|
expect(subject.definition.name).to eql('example')
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: csv2hash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel AZEMAR
|
@@ -108,9 +108,9 @@ files:
|
|
108
108
|
- bin/launch_irb
|
109
109
|
- bin/load_rvm
|
110
110
|
- config/example.csv
|
111
|
-
- config/rules.
|
112
|
-
- config/rules.extra_validator.erb.yml
|
111
|
+
- config/rules.extra_validator.yml.erb
|
113
112
|
- config/rules.yml
|
113
|
+
- config/rules.yml.erb
|
114
114
|
- coverage/.resultset.json.lock
|
115
115
|
- csv2hash.gemspec
|
116
116
|
- lib/csv2hash.rb
|