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,70 +1,73 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
module Csv2hash
|
4
|
+
describe Definition do
|
5
|
+
let(:valid_rules) { [ { position: [0,0], key: 'name' } ] }
|
4
6
|
|
5
|
-
|
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
|
-
|
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
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
33
|
-
|
34
|
-
|
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
|
-
|
37
|
-
|
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
|
-
|
50
|
+
describe '#default!' do
|
42
51
|
subject do
|
43
|
-
|
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
|
-
|
58
|
+
before { subject.default! }
|
57
59
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
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
|
-
|
3
|
+
module Csv2hash
|
4
|
+
describe Parser::Collection do
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
10
|
-
|
13
|
+
let(:data_source) { [ [ 'John Doe' ], [ 'Jane Doe' ] ] }
|
14
|
+
let(:ignore_blank_line) { false }
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
|
16
|
+
subject do
|
17
|
+
Main.new(definition, data_source, ignore_blank_line: ignore_blank_line)
|
18
|
+
end
|
15
19
|
|
16
|
-
|
17
|
-
|
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
|
28
|
-
|
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
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
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
|
-
|
3
|
+
module Csv2hash
|
4
|
+
describe Parser::Mapping do
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
13
|
+
let(:data_source) { [ [ 'John Doe' ] ] }
|
10
14
|
|
11
|
-
|
12
|
-
|
13
|
-
|
15
|
+
subject do
|
16
|
+
Main.new(definition, data_source, ignore_blank_line: false)
|
17
|
+
end
|
14
18
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
definition
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
39
|
-
|
15
|
+
subject do
|
16
|
+
Main.new(definition, data_source, ignore_blank_line: false)
|
40
17
|
end
|
41
18
|
|
42
|
-
context '
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
-
|
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
|
-
|
63
|
-
|
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
|
-
|
66
|
-
|
67
|
-
|
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
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
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 '
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
11
|
-
let(:ignore_blank_line) { false }
|
15
|
+
let(:ignore_blank_line) { false }
|
12
16
|
|
13
|
-
|
14
|
-
|
15
|
-
|
17
|
+
subject do
|
18
|
+
Main.new(definition, data_source, ignore_blank_line: ignore_blank_line)
|
19
|
+
end
|
16
20
|
|
17
|
-
|
18
|
-
|
19
|
-
|
21
|
+
before do
|
22
|
+
allow(subject).to receive(:break_on_failure) { true }
|
23
|
+
end
|
20
24
|
|
21
|
-
|
22
|
-
|
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
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
-
|
53
|
-
|
56
|
+
context 'wihtout exception' do
|
57
|
+
let(:data_source) { [ [ ] ]}
|
54
58
|
|
55
|
-
|
56
|
-
|
57
|
-
|
59
|
+
before do
|
60
|
+
allow(subject).to receive(:break_on_failure) { false }
|
61
|
+
end
|
58
62
|
|
59
|
-
|
63
|
+
it { expect(subject.parse.errors.to_csv).to eql ",\"undefined name on [0, 0]\"\n" }
|
60
64
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
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
|