csv2hash 0.5.0 → 0.6.0

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