csv2hash 0.5.0 → 0.6.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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +81 -37
- data/ReleaseNotes.md +9 -1
- data/bin/launch_irb +1 -0
- data/lib/csv2hash/adapters/base.rb +0 -1
- data/lib/csv2hash/cell.rb +11 -0
- data/lib/csv2hash/definition.rb +54 -25
- data/lib/csv2hash/expectation.rb +10 -0
- data/lib/csv2hash/parser/collection.rb +28 -22
- data/lib/csv2hash/parser/mapping.rb +6 -6
- data/lib/csv2hash/registry.rb +13 -0
- data/lib/csv2hash/structure_validator.rb +1 -0
- data/lib/csv2hash/validator/collection.rb +19 -13
- data/lib/csv2hash/validator/mapping.rb +13 -9
- data/lib/csv2hash/validator.rb +14 -13
- data/lib/csv2hash/version.rb +1 -1
- data/lib/csv2hash.rb +20 -0
- data/spec/csv2hash/definition_spec.rb +55 -52
- data/spec/csv2hash/parser/collection_spec.rb +49 -44
- data/spec/csv2hash/parser/mapping_spec.rb +31 -26
- data/spec/csv2hash/structure_validator_spec.rb +66 -65
- data/spec/csv2hash/validator/collection_spec.rb +63 -55
- data/spec/csv2hash/validator/mapping_spec.rb +82 -78
- data/spec/csv2hash/validator_spec.rb +25 -24
- data/spec/csv2hash_spec.rb +15 -1
- metadata +6 -1
@@ -1,103 +1,107 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
module Csv2hash
|
4
|
+
describe Validator::Mapping do
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
let(:definition) do
|
7
|
+
Main.generate_definition :foo do
|
8
|
+
set_type { Definition::MAPPING }
|
9
|
+
mapping { cell position: [0,0], key: 'name' }
|
10
|
+
end.tap { |d| d.validate! ; d.default! }
|
9
11
|
end
|
10
|
-
end
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
subject do
|
14
|
+
Main.new(definition, data_source, ignore_blank_line: false)
|
15
|
+
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
before do
|
18
|
+
allow(subject).to receive(:break_on_failure) { true }
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
context 'with valid data' do
|
22
|
+
let(:data_source) { [ [ 'John Doe' ] ]}
|
23
|
+
it { expect { subject.validate_data! }.to_not raise_error }
|
24
|
+
end
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
context 'with invalid data' do
|
27
|
+
let(:data_source) { [ [ ] ]}
|
28
|
+
it { expect { subject.validate_data! }.to raise_error('undefined name on [0, 0]') }
|
29
|
+
end
|
29
30
|
|
30
|
-
|
31
|
-
|
31
|
+
context 'wihtout exception' do
|
32
|
+
let(:data_source) { [ [ ] ] }
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
34
|
+
before do
|
35
|
+
allow(subject).to receive(:break_on_failure) { false }
|
36
|
+
end
|
36
37
|
|
37
|
-
|
38
|
+
it { expect(subject.parse.errors.to_csv).to eql ",\"undefined name on [0, 0]\"\n" }
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
context 'errors should be filled' do
|
41
|
+
before { subject.parse }
|
42
|
+
its(:errors) { should eql [{x: 0, y: 0, message: 'undefined name on [0, 0]', key: 'name'}] }
|
43
|
+
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
context 'original csv + errors should be returned' do
|
46
|
+
let(:definition) do
|
47
|
+
Main.generate_definition :foo do
|
48
|
+
set_type { Definition::MAPPING }
|
49
|
+
mapping do
|
50
|
+
cell position: [0,0], key: 'agree', values: ['yes', 'no']
|
51
|
+
cell position: [1,0], key: 'agree', values: ['yes', 'no']
|
52
|
+
cell position: [2,0], key: 'agree', values: ['yes', 'no']
|
53
|
+
end
|
54
|
+
end.tap { |d| d.validate! ; d.default! }
|
48
55
|
end
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
{ position: [0,0], key: 'agree', values: ['yes', 'no'] },
|
54
|
-
{ position: [1,0], key: 'agree', values: ['yes', 'no'] },
|
55
|
-
{ position: [2,0], key: 'agree', values: ['yes', 'no'] }
|
56
|
-
]
|
56
|
+
context 'string values' do
|
57
|
+
let(:data_source) { [ [ 'what?' ], [ 'yes', 'what?' ], [ 'yes', 'what?', 'no' ] ] }
|
58
|
+
it { expect(subject.parse.errors.to_csv).to eql(
|
59
|
+
"what?,\"agree not supported, please use one of [\"\"yes\"\", \"\"no\"\"]\"\n") }
|
57
60
|
end
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
{
|
68
|
-
|
61
|
+
context 'range values' do
|
62
|
+
let(:definition) do
|
63
|
+
Main.generate_definition :foo do
|
64
|
+
set_type { Definition::MAPPING }
|
65
|
+
mapping do
|
66
|
+
cell position: [0,0], key: 'score', values: 1..10
|
67
|
+
cell position: [1,0], key: 'score', values: 1..10
|
68
|
+
cell position: [2,0], key: 'score', values: 1..10
|
69
|
+
end
|
70
|
+
end.tap { |d| d.validate! ; d.default! }
|
71
|
+
end
|
72
|
+
let(:data_source) { [ [ 12 ], [ 2, 12 ], [ 3, 12, 1 ] ] }
|
73
|
+
it { expect(subject.parse.errors.to_csv).to eql("12,\"score not supported, please use one of 1..10\"\n") }
|
69
74
|
end
|
70
|
-
let(:data_source) { [ [ 12 ], [ 2, 12 ], [ 3, 12, 1 ] ] }
|
71
|
-
it { expect(subject.parse.errors.to_csv).to eql("12,\"score not supported, please use one of 1..10\"\n") }
|
72
75
|
end
|
73
|
-
end
|
74
76
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
{
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
77
|
+
context 'with extra_validator' do
|
78
|
+
let(:definition) do
|
79
|
+
Main.generate_definition :foo do
|
80
|
+
set_type { Definition::MAPPING }
|
81
|
+
mapping do
|
82
|
+
cell position: [0,0], key: 'name', extra_validator: DowncaseValidator.new,
|
83
|
+
message: 'your data should be writting in downcase only'
|
84
|
+
end
|
85
|
+
end.tap { |d| d.validate! ; d.default! }
|
86
|
+
end
|
87
|
+
before { subject.parse }
|
88
|
+
context 'not valid data' do
|
89
|
+
let(:data_source) { [ [ 'Foo' ] ] }
|
90
|
+
its(:errors) do
|
91
|
+
should eql [{x: 0, y: 0, message: 'your data should be writting in downcase only', key: 'name'}]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
context 'valid data' do
|
95
|
+
let(:data_source) { [ [ 'foo' ] ] }
|
96
|
+
its(:errors) { should be_empty }
|
84
97
|
end
|
85
|
-
end
|
86
|
-
before { subject.parse }
|
87
|
-
context 'not valid data' do
|
88
|
-
let(:data_source) { [ [ 'Foo' ] ] }
|
89
|
-
its(:errors) { should eql [{x: 0, y: 0, message: 'your data should be writting in downcase only', key: 'name'}]}
|
90
|
-
end
|
91
|
-
context 'valid data' do
|
92
|
-
let(:data_source) { [ [ 'foo' ] ] }
|
93
|
-
its(:errors) { should be_empty }
|
94
98
|
end
|
95
99
|
end
|
96
100
|
end
|
97
|
-
end
|
98
101
|
|
99
|
-
class DowncaseValidator <
|
100
|
-
|
101
|
-
|
102
|
+
class DowncaseValidator < ExtraValidator
|
103
|
+
def valid? rule, value
|
104
|
+
!!(value.match /^[a-z]+$/)
|
105
|
+
end
|
102
106
|
end
|
103
107
|
end
|
@@ -1,40 +1,41 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
module Csv2hash
|
4
|
+
describe 'Validator' do
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
definition.validate!
|
8
|
-
definition.default!
|
9
|
-
end
|
10
|
-
end
|
6
|
+
describe '#message' do
|
7
|
+
let(:cell) { double(:cell, rules: rules) }
|
11
8
|
|
12
|
-
|
13
|
-
|
9
|
+
subject do
|
10
|
+
Class.new do
|
11
|
+
include Validator
|
12
|
+
end.new
|
13
|
+
end
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
context 'string value' do
|
16
|
+
let(:rules) {{ foo: 'bar', message: ':foo are value of foo key' }}
|
17
17
|
|
18
|
-
|
19
|
-
|
18
|
+
it 'substitue value of key' do
|
19
|
+
expect(subject.send(:message, cell, nil, nil)).to eql 'bar are value of foo key'
|
20
|
+
end
|
20
21
|
end
|
21
|
-
end
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
context 'array value' do
|
24
|
+
let(:rules) { { foo: ['bar', 'zone'], message: ':foo are values of foo key' } }
|
25
25
|
|
26
|
-
|
27
|
-
|
26
|
+
it 'substitue value of key' do
|
27
|
+
expect(subject.send(:message, cell, nil, nil)).to eql '["bar", "zone"] are values of foo key'
|
28
|
+
end
|
28
29
|
end
|
29
|
-
end
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
context 'with position' do
|
32
|
+
let(:rules) { { message: 'value not found on :position' } }
|
33
33
|
|
34
|
-
|
35
|
-
|
34
|
+
it 'substitue value of key' do
|
35
|
+
expect(subject.send(:message, cell, 0, 2)).to eql 'value not found on [0, 2]'
|
36
|
+
end
|
36
37
|
end
|
37
38
|
end
|
38
|
-
end
|
39
39
|
|
40
|
+
end
|
40
41
|
end
|
data/spec/csv2hash_spec.rb
CHANGED
@@ -1,3 +1,17 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Csv2hash
|
3
|
+
describe Csv2hash do
|
4
|
+
let(:definition) { double('definition', type: nil) }
|
5
|
+
let(:data_source) { nil }
|
6
|
+
|
7
|
+
subject do
|
8
|
+
Csv2hash::Main.new(definition, data_source, ignore_blank_line: false)
|
9
|
+
end
|
10
|
+
|
11
|
+
context '...' do
|
12
|
+
specify do
|
13
|
+
expect(subject.options.fetch(:ignore_blank_line)).to eql(false)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
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.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel AZEMAR
|
@@ -83,6 +83,7 @@ dependencies:
|
|
83
83
|
description: DSL to map a CSV to a Ruby Hash
|
84
84
|
email: joel.azemar@gmail.com
|
85
85
|
executables:
|
86
|
+
- launch_irb
|
86
87
|
- load_rvm
|
87
88
|
extensions: []
|
88
89
|
extra_rdoc_files: []
|
@@ -97,6 +98,7 @@ files:
|
|
97
98
|
- README.md
|
98
99
|
- Rakefile
|
99
100
|
- ReleaseNotes.md
|
101
|
+
- bin/launch_irb
|
100
102
|
- bin/load_rvm
|
101
103
|
- coverage/.resultset.json.lock
|
102
104
|
- csv2hash.gemspec
|
@@ -105,14 +107,17 @@ files:
|
|
105
107
|
- lib/csv2hash/adapters/base.rb
|
106
108
|
- lib/csv2hash/adapters/csv_adapter.rb
|
107
109
|
- lib/csv2hash/adapters/memory_adapter.rb
|
110
|
+
- lib/csv2hash/cell.rb
|
108
111
|
- lib/csv2hash/csv_array.rb
|
109
112
|
- lib/csv2hash/data_wrapper.rb
|
110
113
|
- lib/csv2hash/definition.rb
|
114
|
+
- lib/csv2hash/expectation.rb
|
111
115
|
- lib/csv2hash/extra_validator.rb
|
112
116
|
- lib/csv2hash/notifier.rb
|
113
117
|
- lib/csv2hash/parser.rb
|
114
118
|
- lib/csv2hash/parser/collection.rb
|
115
119
|
- lib/csv2hash/parser/mapping.rb
|
120
|
+
- lib/csv2hash/registry.rb
|
116
121
|
- lib/csv2hash/structure_validator.rb
|
117
122
|
- lib/csv2hash/structure_validator/max_columns.rb
|
118
123
|
- lib/csv2hash/structure_validator/min_columns.rb
|