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.
@@ -1,70 +1,73 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Csv2hash::Definition do
3
+ module Csv2hash
4
+ describe Definition do
5
+ let(:valid_rules) { [ { position: [0,0], key: 'name' } ] }
4
6
 
5
- let(:valid_rules) { [ { position: [0,0], key: 'name' } ] }
6
- context 'regular context' do
7
- subject do
8
- Csv2hash::Definition.new(
9
- valid_rules,
10
- Csv2hash::Definition::MAPPING
11
- )
12
- end
13
-
14
- it 'variable should be assigned' do
15
- expect(subject.type).to eql Csv2hash::Definition::MAPPING
16
- expect(subject.rules).to eql [ { position: [0,0], key: 'name' } ]
17
- end
18
- end
19
-
20
- describe '#validate!' do
21
- context 'rules failling validation' do
7
+ context 'regular context' do
22
8
  subject do
23
- Csv2hash::Definition.new nil, 'unsuitable_type'
9
+ Main.generate_definition :foo do
10
+ set_type { Definition::MAPPING }
11
+ mapping { cell position: [0,0], key: 'name' }
12
+ end
24
13
  end
25
- it 'should throw exception' do
26
- expect {
27
- subject.validate!
28
- }.to raise_error("not suitable type, please use '#{Csv2hash::Definition::MAPPING}' " \
29
- "or '#{Csv2hash::Definition::COLLECTION}'")
14
+
15
+ it 'variable should be assigned' do
16
+ expect(subject.type).to eql Definition::MAPPING
17
+ expect(subject.cells.first.rules).to eql({ position: [0,0], key: 'name' })
30
18
  end
31
19
  end
32
- context 'rules failling validation' do
33
- subject do
34
- Csv2hash::Definition.new 'rules',Csv2hash::Definition::MAPPING
20
+
21
+ describe '#validate!' do
22
+ context 'rules failling validation' do
23
+ subject do
24
+ Main.generate_definition :foo do
25
+ set_type { :unsuitable_type }
26
+ end
27
+ end
28
+ it 'should throw exception' do
29
+ expect {
30
+ subject.validate!
31
+ }.to raise_error("not suitable type, please use '#{Definition::MAPPING}' " \
32
+ "or '#{Definition::COLLECTION}'")
33
+ end
35
34
  end
36
- it 'should throw exception' do
37
- expect { subject.validate! }.to raise_error 'rules must be an Array of rules'
35
+
36
+ context 'structure rules failling validation' do
37
+ subject do
38
+ Main.generate_definition :foo do
39
+ set_type { Definition::MAPPING }
40
+ set_structure_rules { :unsuitable_structure_rule }
41
+ end
42
+ end
43
+
44
+ it 'should throw exception' do
45
+ expect { subject.validate! }.to raise_error 'structure rules must be a Hash of rules'
46
+ end
38
47
  end
39
48
  end
40
49
 
41
- context 'structure rules failling validation' do
50
+ describe '#default!' do
42
51
  subject do
43
- Csv2hash::Definition.new valid_rules, Csv2hash::Definition::MAPPING, { structure_rules: 'invalid structure rule' }
52
+ Main.generate_definition :foo do
53
+ set_type { Definition::MAPPING }
54
+ mapping { cell position: [0,0], key: 'name' }
55
+ end
44
56
  end
45
- it 'should throw exception' do
46
- expect { subject.validate! }.to raise_error 'structure rules must be a Hash of rules'
47
- end
48
- end
49
- end
50
-
51
- describe '#default!' do
52
- subject do
53
- Csv2hash::Definition.new [ { position: [0,0], key: 'name' } ], Csv2hash::Definition::MAPPING
54
- end
55
57
 
56
- before { subject.default! }
58
+ before { subject.default! }
57
59
 
58
- it 'missing key must be filled' do
59
- expect(subject.rules).to eql([{ position: [0, 0],
60
- key: 'name',
61
- message: 'undefined :key on :position',
62
- mappable: true,
63
- type: 'string',
64
- values: nil,
65
- nested: nil,
66
- allow_blank: false,
67
- extra_validator: nil }])
60
+ it 'missing key must be filled' do
61
+ expect(subject.cells.first.rules).to eql({ position: [0, 0],
62
+ key: 'name',
63
+ message: 'undefined :key on :position',
64
+ mappable: true,
65
+ type: 'string',
66
+ values: nil,
67
+ nested: nil,
68
+ allow_blank: false,
69
+ extra_validator: nil })
70
+ end
68
71
  end
69
72
  end
70
73
  end
@@ -1,58 +1,63 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Csv2hash::Parser::Collection do
3
+ module Csv2hash
4
+ describe Parser::Collection do
4
5
 
5
- let(:definition) do
6
- Csv2hash::Definition.new [ { position: 0, key: 'name' } ], Csv2hash::Definition::COLLECTION
7
- end
6
+ let(:definition) do
7
+ Main.generate_definition :foo do
8
+ set_type { Definition::COLLECTION }
9
+ mapping { cell position: 0, key: 'name' }
10
+ end
11
+ end
8
12
 
9
- let(:data_source) { [ [ 'John Doe' ], [ 'Jane Doe' ] ] }
10
- let(:ignore_blank_line) { false }
13
+ let(:data_source) { [ [ 'John Doe' ], [ 'Jane Doe' ] ] }
14
+ let(:ignore_blank_line) { false }
11
15
 
12
- subject do
13
- Csv2hash::Main.new(definition, data_source, ignore_blank_line: ignore_blank_line)
14
- end
16
+ subject do
17
+ Main.new(definition, data_source, ignore_blank_line: ignore_blank_line)
18
+ end
15
19
 
16
- context 'regular way' do
17
- it { expect { subject.parse }.to_not raise_error }
18
- it {
19
- expect(subject.tap do |parser|
20
- parser.parse
21
- end.data).to eql({ data: [ { 'name' => 'John Doe' }, { 'name' => 'Jane Doe' } ] })
22
- }
23
- context 'with header' do
24
- before { subject.definition.header_size = 1 }
25
- let(:data_source) { [ [ 'Name' ], [ 'John Doe' ], [ 'Jane Doe' ] ] }
20
+ context 'regular way' do
21
+ it { expect { subject.parse! }.to_not raise_error }
26
22
  it {
27
- expect(subject.tap { |c| c.parse }.data).to eql(
28
- { data: [ { 'name' => 'John Doe' }, { 'name' => 'Jane Doe' } ] })
23
+ expect(subject.tap do |parser|
24
+ parser.parse!
25
+ end.data).to eql({ data: [ { 'name' => 'John Doe' }, { 'name' => 'Jane Doe' } ] })
29
26
  }
27
+ context 'with header' do
28
+ before { subject.definition.header_size = 1 }
29
+ let(:data_source) { [ [ 'Name' ], [ 'John Doe' ], [ 'Jane Doe' ] ] }
30
+ it {
31
+ expect(subject.tap { |c| c.parse }.data).to eql(
32
+ { data: [ { 'name' => 'John Doe' }, { 'name' => 'Jane Doe' } ] })
33
+ }
34
+ end
30
35
  end
31
- end
32
36
 
33
- context 'with nested' do
34
- let(:data_source) { [ [ 'John Doe', 22 ], [ 'Jane Doe', 19 ] ] }
35
- before do
36
- definition.rules << { position: 1, key: 'age', nested: 'infos' }
37
+ context 'with nested' do
38
+ let(:data_source) { [ [ 'John Doe', 22 ], [ 'Jane Doe', 19 ] ] }
39
+ before do
40
+ definition.cells << Cell.new({ position: 1, key: 'age', nested: 'infos' })
41
+ end
42
+ it {
43
+ expect(subject.tap { |c| c.parse! }.data).to eql(
44
+ { data: [
45
+ { 'name' => 'John Doe', 'infos' => { 'age' => 22 } },
46
+ { 'name' => 'Jane Doe', 'infos' => { 'age' => 19 } }
47
+ ]
48
+ }
49
+ )
50
+ }
37
51
  end
38
- it {
39
- expect(subject.tap { |c| c.parse }.data).to eql(
40
- { data: [
41
- { 'name' => 'John Doe', 'infos' => { 'age' => 22 } },
42
- { 'name' => 'Jane Doe', 'infos' => { 'age' => 19 } }
43
- ]
44
- }
45
- )
46
- }
47
- end
48
52
 
49
- context '#ignore_blank_line' do
50
- let(:data_source) { [ [ 'John Doe' ], [ 'Jane Doe' ], [ nil ] ] }
51
- let(:ignore_blank_line) { true }
52
- it {
53
- expect(subject.tap do |parser|
54
- parser.parse
55
- end.data).to eql({ data: [ { 'name' => 'John Doe' }, { 'name' => 'Jane Doe' } ] })
56
- }
53
+ context '#ignore_blank_line' do
54
+ let(:data_source) { [ [ 'John Doe' ], [ 'Jane Doe' ], [ nil ] ] }
55
+ let(:ignore_blank_line) { true }
56
+ it {
57
+ expect(subject.tap do |parser|
58
+ parser.parse!
59
+ end.data).to eql({ data: [ { 'name' => 'John Doe' }, { 'name' => 'Jane Doe' } ] })
60
+ }
61
+ end
57
62
  end
58
63
  end
@@ -1,36 +1,41 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Csv2hash::Parser::Mapping do
3
+ module Csv2hash
4
+ describe Parser::Mapping do
4
5
 
5
- let(:definition) do
6
- Csv2hash::Definition.new [ { position: [0,0], key: 'name' } ], Csv2hash::Definition::MAPPING
7
- end
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
11
+ end
8
12
 
9
- let(:data_source) { [ [ 'John Doe' ] ] }
13
+ let(:data_source) { [ [ 'John Doe' ] ] }
10
14
 
11
- subject do
12
- Csv2hash::Main.new(definition, data_source, ignore_blank_line: false)
13
- end
15
+ subject do
16
+ Main.new(definition, data_source, ignore_blank_line: false)
17
+ end
14
18
 
15
- context 'regular way' do
16
- it { expect { subject.parse }.to_not raise_error }
17
- it {
18
- expect(subject.tap do |csv2hash|
19
- csv2hash.parse
20
- end.data).to eql({ data: [ { 'name' => 'John Doe' } ] })
21
- }
22
- end
19
+ context 'regular way' do
20
+ it { expect { subject.parse! }.to_not raise_error }
21
+ it {
22
+ expect(subject.tap do |csv2hash|
23
+ csv2hash.parse!
24
+ end.data).to eql({ data: [ { 'name' => 'John Doe' } ] })
25
+ }
26
+ end
23
27
 
24
- context 'with nested' do
25
- let(:data_source) { [ [ 'John Doe', 22 ] ] }
26
- before do
27
- definition.rules << { position: [0,1], key: 'age', nested: 'infos' }
28
+ context 'with nested' do
29
+ let(:data_source) { [ [ 'John Doe', 22 ] ] }
30
+ before do
31
+ definition.cells << Cell.new({ position: [0,1], key: 'age', nested: 'infos' })
32
+ end
33
+ it {
34
+ expect(subject.tap { |c| c.parse! }.data).to eql(
35
+ { data: [ { 'name' => 'John Doe', 'infos' => { 'age' => 22 } } ] }
36
+ )
37
+ }
28
38
  end
29
- it {
30
- expect(subject.tap { |c| c.parse }.data).to eql(
31
- { data: [ { 'name' => 'John Doe', 'infos' => { 'age' => 22 } } ] }
32
- )
33
- }
34
- end
35
39
 
40
+ end
36
41
  end
@@ -1,89 +1,90 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Csv2hash::StructureValidator do
4
-
5
- let(:rules) { [ { position: [0,0], key: 'name' } ] }
6
- let(:options) { {} }
7
- let(:definition) do
8
- Csv2hash::Definition.new(rules, Csv2hash::Definition::MAPPING, options).tap do |definition|
9
- definition.validate!
10
- definition.default!
11
- end
12
- end
13
-
14
- subject do
15
- Csv2hash::Main.new(definition, data_source, ignore_blank_line: false)
16
- end
17
-
18
- context 'the csv with errors' do
19
- let(:options){ { structure_rules: { 'MaxColumns' => 2 } } }
20
- before { subject.parse }
21
- let(:data_source) do
22
- [
23
- [ 'John', 'Doe' ],
24
- [ 'Jane', 'Doe', 'extra field' ]
25
- ]
26
- end
27
-
28
- its(:csv_with_errors) { should be_kind_of CsvArray }
29
- it "adds structure error in first cell" do
30
- expect(subject.csv_with_errors.first[:message]).to eq 'Too many columns (max. 2) on line 1'
3
+ module Csv2hash
4
+ describe StructureValidator do
5
+ let(:definition) do
6
+ Main.generate_definition :foo do
7
+ set_type { Definition::MAPPING }
8
+ mapping { cell position: [0,0], key: 'name' }
9
+ end.tap do |definition|
10
+ definition.validate!
11
+ definition.default!
12
+ end
31
13
  end
32
- end
33
-
34
-
35
- context '#MaxColumns' do
36
- let(:options){ { structure_rules: { 'MaxColumns' => 2 } } }
37
14
 
38
- before do
39
- allow(subject).to receive(:break_on_failure) { true }
15
+ subject do
16
+ Main.new(definition, data_source, ignore_blank_line: false)
40
17
  end
41
18
 
42
- context 'valid data' do
43
- let(:data_source) do
44
- [
45
- [ 'John', 'Doe' ]
46
- ]
19
+ context 'the csv with errors' do
20
+ before do
21
+ allow(definition).to receive(:structure_rules) {{ 'MaxColumns' => 2 }}
22
+ subject.parse
47
23
  end
48
- it { expect { subject.validate_structure! }.to_not raise_error }
49
- end
50
-
51
- context 'invalid data' do
52
24
  let(:data_source) do
53
25
  [
54
26
  [ 'John', 'Doe' ],
55
27
  [ 'Jane', 'Doe', 'extra field' ]
56
28
  ]
57
29
  end
58
- it { expect { subject.validate_structure! }.to raise_error 'Too many columns (max. 2) on line 1' }
30
+
31
+ its(:csv_with_errors) { should be_kind_of CsvArray }
32
+ it "adds structure error in first cell" do
33
+ expect(subject.csv_with_errors.first[:message]).to eq 'Too many columns (max. 2) on line 1'
34
+ end
59
35
  end
60
- end
61
36
 
62
- context '#MinColumns' do
63
- let(:options){ { structure_rules: { 'MinColumns' => 2 } } }
37
+ context '#MaxColumns' do
38
+ before do
39
+ allow(definition).to receive(:structure_rules) {{ 'MaxColumns' => 2 }}
40
+ allow(subject).to receive(:break_on_failure) { true }
41
+ end
64
42
 
65
- before do
66
- allow(subject).to receive(:break_on_failure) { true }
67
- end
43
+ context 'valid data' do
44
+ let(:data_source) do
45
+ [
46
+ [ 'John', 'Doe' ]
47
+ ]
48
+ end
49
+ it { expect { subject.validate_structure! }.to_not raise_error }
50
+ end
68
51
 
69
- context 'valid data' do
70
- let(:data_source) do
71
- [
72
- [ 'John', 'Doe', 'foo' ]
73
- ]
52
+ context 'invalid data' do
53
+ let(:data_source) do
54
+ [
55
+ [ 'John', 'Doe' ],
56
+ [ 'Jane', 'Doe', 'extra field' ]
57
+ ]
58
+ end
59
+ it { expect { subject.validate_structure! }.to raise_error 'Too many columns (max. 2) on line 1' }
74
60
  end
75
- it { expect { subject.validate_structure! }.to_not raise_error }
76
61
  end
77
62
 
78
- context 'invalid data' do
79
- let(:data_source) do
80
- [
81
- [ 'John' ],
82
- [ 'Jane', 'Doe' ]
83
- ]
63
+ context '#MinColumns' do
64
+ before do
65
+ allow(definition).to receive(:structure_rules) {{ 'MinColumns' => 2 }}
66
+ allow(subject).to receive(:break_on_failure) { true }
67
+ end
68
+
69
+ context 'valid data' do
70
+ let(:data_source) do
71
+ [
72
+ [ 'John', 'Doe', 'foo' ]
73
+ ]
74
+ end
75
+ it { expect { subject.validate_structure! }.to_not raise_error }
76
+ end
77
+
78
+ context 'invalid data' do
79
+ let(:data_source) do
80
+ [
81
+ [ 'John' ],
82
+ [ 'Jane', 'Doe' ]
83
+ ]
84
+ end
85
+ it { expect { subject.validate_structure! }.to raise_error 'Not enough columns (min. 2) on line 0' }
84
86
  end
85
- it { expect { subject.validate_structure! }.to raise_error 'Not enough columns (min. 2) on line 0' }
86
87
  end
87
- end
88
88
 
89
+ end
89
90
  end
@@ -1,78 +1,86 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Csv2hash::Validator::Collection do
4
- let(:options) { {} }
5
- let(:definition) do
6
- Csv2hash::Definition.new([ { position: 0, key: 'name' } ], Csv2hash::Definition::COLLECTION, options).tap do |definition|
7
- definition.validate!
8
- definition.default!
3
+ module Csv2hash
4
+ describe Validator::Collection do
5
+ let(:options) { {} }
6
+ let(:definition) do
7
+ Main.generate_definition :foo do
8
+ set_type { Definition::COLLECTION }
9
+ mapping { cell position: 0, key: 'name' }
10
+ end.tap do |definition|
11
+ definition.validate!
12
+ definition.default!
13
+ end
9
14
  end
10
- end
11
- let(:ignore_blank_line) { false }
15
+ let(:ignore_blank_line) { false }
12
16
 
13
- subject do
14
- Csv2hash::Main.new(definition, data_source, ignore_blank_line: ignore_blank_line)
15
- end
17
+ subject do
18
+ Main.new(definition, data_source, ignore_blank_line: ignore_blank_line)
19
+ end
16
20
 
17
- before do
18
- allow(subject).to receive(:break_on_failure) { true }
19
- end
21
+ before do
22
+ allow(subject).to receive(:break_on_failure) { true }
23
+ end
20
24
 
21
- context 'with valid data' do
22
- let(:data_source) { [ [ 'John Doe' ] ]}
25
+ context 'with valid data' do
26
+ let(:data_source) { [ [ 'John Doe' ] ]}
23
27
 
24
- it { expect { subject.validate_data! }.to_not raise_error }
25
- context 'with header' do
26
- let(:options) { { header_size: 1 } }
27
- let(:data_source) { [ [ 'Name' ], [ 'John Doe' ] ]}
28
28
  it { expect { subject.validate_data! }.to_not raise_error }
29
+ context 'with header' do
30
+ let(:options) { { header_size: 1 } }
31
+ let(:data_source) { [ [ 'Name' ], [ 'John Doe' ] ]}
32
+ it { expect { subject.validate_data! }.to_not raise_error }
33
+ end
29
34
  end
30
- end
31
35
 
32
- context '#ignore_blank_line' do
33
- let(:data_source) { [ [ ] ] }
34
- let(:ignore_blank_line) { true }
35
- it { expect { subject.validate_data! }.to_not raise_error }
36
- context 'csv mode' do
37
- before { subject.break_on_failure = false }
38
- its(:errors) { should be_empty }
36
+ context '#ignore_blank_line' do
37
+ let(:data_source) { [ [ ] ] }
38
+ let(:ignore_blank_line) { true }
39
+ it { expect { subject.validate_data! }.to_not raise_error }
40
+ context 'csv mode' do
41
+ before { subject.break_on_failure = false }
42
+ its(:errors) { should be_empty }
43
+ end
39
44
  end
40
- end
41
45
 
42
- context 'with invalid data' do
43
- let(:data_source) { [ [ ] ] }
44
- it { expect { subject.validate_data! }.to raise_error('undefined name on [0, 0]') }
45
- context 'with header' do
46
- let(:options) { { header_size: 1 } }
47
- let(:data_source) { [ [ 'Name' ], [ ] ]}
48
- it { expect { subject.validate_data! }.to raise_error('undefined name on [1, 0]') }
46
+ context 'with invalid data' do
47
+ let(:data_source) { [ [ ] ] }
48
+ it { expect { subject.validate_data! }.to raise_error('undefined name on [0, 0]') }
49
+ context 'with header' do
50
+ let(:options) { { header_size: 1 } }
51
+ let(:data_source) { [ [ 'Name' ], [ ] ]}
52
+ it { expect { subject.validate_data! }.to raise_error('undefined name on [1, 0]') }
53
+ end
49
54
  end
50
- end
51
55
 
52
- context 'wihtout exception' do
53
- let(:data_source) { [ [ ] ]}
56
+ context 'wihtout exception' do
57
+ let(:data_source) { [ [ ] ]}
54
58
 
55
- before do
56
- allow(subject).to receive(:break_on_failure) { false }
57
- end
59
+ before do
60
+ allow(subject).to receive(:break_on_failure) { false }
61
+ end
58
62
 
59
- it { expect(subject.parse.errors.to_csv).to eql ",\"undefined name on [0, 0]\"\n" }
63
+ it { expect(subject.parse.errors.to_csv).to eql ",\"undefined name on [0, 0]\"\n" }
60
64
 
61
- context 'errors should be filled' do
62
- before { subject.parse }
63
- its(:errors) { should eql [{x: 0, y: 0, message: 'undefined name on [0, 0]', key: 'name'}] }
64
- end
65
+ context 'errors should be filled' do
66
+ before { subject.parse }
67
+ its(:errors) { should eql [{x: 0, y: 0, message: 'undefined name on [0, 0]', key: 'name'}] }
68
+ end
65
69
 
66
- context 'original csv + errors should returned' do
67
- let(:definition) do
68
- Csv2hash::Definition.new(
69
- [{ position: 0, key: 'agree', values: ['yes', 'no'] }], Csv2hash::Definition::COLLECTION).tap do |d|
70
- d.validate!; d.default!
70
+ context 'original csv + errors should returned' do
71
+ let(:definition) do
72
+ Main.generate_definition :foo do
73
+ set_type { Definition::COLLECTION }
74
+ mapping { cell position: 0, key: 'agree', values: ['yes', 'no'] }
75
+ end.tap do |definition|
76
+ definition.validate!
77
+ definition.default!
78
+ end
71
79
  end
80
+ let(:data_source) { [ [ 'what?' ], [ 'yes' ], [ 'no' ] ] }
81
+ it { expect(subject.parse.errors.to_csv).to eql "what?,\"agree not supported, please use one of [\"\"yes\"\", \"\"no\"\"]\"\n" }
72
82
  end
73
- let(:data_source) { [ [ 'what?' ], [ 'yes' ], [ 'no' ] ] }
74
- it { expect(subject.parse.errors.to_csv).to eql "what?,\"agree not supported, please use one of [\"\"yes\"\", \"\"no\"\"]\"\n" }
75
83
  end
76
- end
77
84
 
85
+ end
78
86
  end