csv2hash 0.6.6 → 0.6.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|