libis-tools 0.9.39 → 0.9.40
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/lib/libis/tools/csv.rb +38 -0
- data/lib/libis/tools/version.rb +1 -1
- data/spec/csv_spec.rb +159 -0
- data/spec/data/test-headers.csv +2 -0
- data/spec/data/test-noheaders.csv +1 -0
- metadata +9 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a5148788cf3b8e6f14ab072a09ccaaec0d6698cd
|
|
4
|
+
data.tar.gz: f69d737f7c8cbd7af69c949feffd7074acc4cb91
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d4d53232d21d1ea99ab69b6d0302e735787c61d09c977b986f46870baa5bf4c2aa7937e47f496cb9250bcf520f3343d025d50c4369b08caaab74dccdba174987
|
|
7
|
+
data.tar.gz: 6ff44a80101faa634c66a12d54aaae86055218e96eca8a9b739a97aca1edd5d3bdd54f82f41228e8a5fb070352f9ae2c624c3170223c4f602056ca209f6e4cb5
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'csv'
|
|
2
|
+
|
|
3
|
+
module Libis
|
|
4
|
+
module Tools
|
|
5
|
+
module Csv
|
|
6
|
+
|
|
7
|
+
# @param [String] file_name
|
|
8
|
+
# @param [Hash] options
|
|
9
|
+
# @return [CSV] Open CSV object
|
|
10
|
+
def self.open(file_name, options = {})
|
|
11
|
+
options = {
|
|
12
|
+
mode: 'rb:UTF-8',
|
|
13
|
+
required: %w'',
|
|
14
|
+
optional: %w'',
|
|
15
|
+
col_sep: ',',
|
|
16
|
+
quote_char: '"'
|
|
17
|
+
}.merge options
|
|
18
|
+
mode = options.delete(:mode)
|
|
19
|
+
required_headers = options.delete(:required)
|
|
20
|
+
optional_headers = options.delete(:optional)
|
|
21
|
+
options[:headers] = true
|
|
22
|
+
options[:return_headers] = true
|
|
23
|
+
csv = CSV.open(file_name, mode, options)
|
|
24
|
+
line = csv.shift
|
|
25
|
+
found_headers = required_headers & line.headers
|
|
26
|
+
return csv if found_headers.size == required_headers.size
|
|
27
|
+
raise RuntimeError, "CSV headers not found: #{required_headers - found_headers}" unless found_headers.empty?
|
|
28
|
+
csv.close
|
|
29
|
+
options[:headers] = (required_headers + optional_headers)[0...line.size]
|
|
30
|
+
raise RuntimeError, 'CSV does not contain enough columns' if required_headers.size > line.size
|
|
31
|
+
options[:return_headers] = true
|
|
32
|
+
csv = CSV.open(file_name, mode, options)
|
|
33
|
+
csv.shift
|
|
34
|
+
csv
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
data/lib/libis/tools/version.rb
CHANGED
data/spec/csv_spec.rb
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require_relative 'spec_helper'
|
|
3
|
+
require 'rspec/matchers'
|
|
4
|
+
require 'libis/tools/csv'
|
|
5
|
+
|
|
6
|
+
describe 'CSV File' do
|
|
7
|
+
|
|
8
|
+
let(:path) { File.absolute_path('data', File.dirname(__FILE__)) }
|
|
9
|
+
let(:csv) {
|
|
10
|
+
Libis::Tools::Csv.open(
|
|
11
|
+
File.join(path, csv_file),
|
|
12
|
+
required: required_headers,
|
|
13
|
+
optional: optional_headers
|
|
14
|
+
)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let(:optional_headers) { [] }
|
|
18
|
+
|
|
19
|
+
after(:example) { csv.close rescue nil }
|
|
20
|
+
|
|
21
|
+
context 'with headers' do
|
|
22
|
+
let(:csv_file) { 'test-headers.csv' }
|
|
23
|
+
|
|
24
|
+
context 'well-formed' do
|
|
25
|
+
|
|
26
|
+
let(:required_headers) { %w'FirstName LastName' }
|
|
27
|
+
|
|
28
|
+
it 'opens correctly' do
|
|
29
|
+
expect{ csv }.not_to raise_error
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'contains expected headers' do
|
|
33
|
+
required_headers.each do |header|
|
|
34
|
+
expect(csv.headers).to include header
|
|
35
|
+
end
|
|
36
|
+
expect(csv.headers).to eq %w'FirstName LastName address'
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it '#shift returns Row object' do
|
|
40
|
+
row = csv.shift
|
|
41
|
+
expect(row).to be_a CSV::Row
|
|
42
|
+
expect(row['FirstName']).to eq 'John'
|
|
43
|
+
expect(row['LastName']).to eq 'Smith'
|
|
44
|
+
expect(row['address']).to eq 'mystreet 1, myplace'
|
|
45
|
+
expect(row['phone']).to be_nil
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context 'not well-formed' do
|
|
51
|
+
|
|
52
|
+
let(:required_headers) { %w'FirstName LastName address phone'}
|
|
53
|
+
|
|
54
|
+
it 'throws error when opened' do
|
|
55
|
+
expect { csv }.to raise_error(RuntimeError, 'CSV headers not found: ["phone"]')
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
context 'without headers' do
|
|
62
|
+
let(:csv_file) { 'test-noheaders.csv' }
|
|
63
|
+
|
|
64
|
+
context 'well-formed and strict' do
|
|
65
|
+
let(:required_headers) { %w'FirstName LastName' }
|
|
66
|
+
|
|
67
|
+
it 'opens correctly' do
|
|
68
|
+
expect { csv }.not_to raise_error
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it 'contains only required headers' do
|
|
72
|
+
required_headers.each do |header|
|
|
73
|
+
expect(csv.headers).to include header
|
|
74
|
+
end
|
|
75
|
+
expect(csv.headers).to eq %w'FirstName LastName'
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it '#shift returns Row object' do
|
|
79
|
+
row = csv.shift
|
|
80
|
+
expect(row).to be_a CSV::Row
|
|
81
|
+
expect(row['FirstName']).to eq 'John'
|
|
82
|
+
expect(row['LastName']).to eq 'Smith'
|
|
83
|
+
expect(row['address']).to be_nil
|
|
84
|
+
expect(row['phone']).to be_nil
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
context 'well-formed with optional headers' do
|
|
90
|
+
let(:required_headers) { %w'FirstName LastName' }
|
|
91
|
+
let(:optional_headers) { %w'address' }
|
|
92
|
+
|
|
93
|
+
it 'opens correctly' do
|
|
94
|
+
expect { csv }.not_to raise_error
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it 'contains required and optional headers' do
|
|
98
|
+
required_headers.each do |header|
|
|
99
|
+
expect(csv.headers).to include header
|
|
100
|
+
end
|
|
101
|
+
optional_headers.each do |header|
|
|
102
|
+
expect(csv.headers).to include header
|
|
103
|
+
end
|
|
104
|
+
expect(csv.headers).to eq %w'FirstName LastName address'
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it '#shift returns Row object' do
|
|
108
|
+
row = csv.shift
|
|
109
|
+
expect(row).to be_a CSV::Row
|
|
110
|
+
expect(row['FirstName']).to eq 'John'
|
|
111
|
+
expect(row['LastName']).to eq 'Smith'
|
|
112
|
+
expect(row['address']).to eq 'mystreet 1, myplace'
|
|
113
|
+
expect(row['phone']).to be_nil
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
context 'missing optional headers' do
|
|
119
|
+
|
|
120
|
+
let(:required_headers) { %w'FirstName LastName address' }
|
|
121
|
+
let(:optional_headers) { %w'phone' }
|
|
122
|
+
|
|
123
|
+
it 'opens correctly' do
|
|
124
|
+
expect { csv }.not_to raise_error
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it 'contains only required headers' do
|
|
128
|
+
required_headers.each do |header|
|
|
129
|
+
expect(csv.headers).to include header
|
|
130
|
+
end
|
|
131
|
+
optional_headers.each do |header|
|
|
132
|
+
expect(csv.headers).not_to include header
|
|
133
|
+
end
|
|
134
|
+
expect(csv.headers).to eq %w'FirstName LastName address'
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it '#shift returns Row object' do
|
|
138
|
+
row = csv.shift
|
|
139
|
+
expect(row).to be_a CSV::Row
|
|
140
|
+
expect(row['FirstName']).to eq 'John'
|
|
141
|
+
expect(row['LastName']).to eq 'Smith'
|
|
142
|
+
expect(row['address']).to eq 'mystreet 1, myplace'
|
|
143
|
+
expect(row['phone']).to be_nil
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
context 'missing required header' do
|
|
149
|
+
let(:required_headers) { %w'FirstName LastName address phone'}
|
|
150
|
+
|
|
151
|
+
it 'throws error when opened' do
|
|
152
|
+
expect { csv }.to raise_error(RuntimeError, 'CSV does not contain enough columns')
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
John,Smith,"mystreet 1, myplace"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: libis-tools
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.40
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kris Dekeyser
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2016-
|
|
11
|
+
date: 2016-07-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -255,6 +255,7 @@ files:
|
|
|
255
255
|
- lib/libis/tools/command.rb
|
|
256
256
|
- lib/libis/tools/config.rb
|
|
257
257
|
- lib/libis/tools/config_file.rb
|
|
258
|
+
- lib/libis/tools/csv.rb
|
|
258
259
|
- lib/libis/tools/deep_struct.rb
|
|
259
260
|
- lib/libis/tools/extend/empty.rb
|
|
260
261
|
- lib/libis/tools/extend/hash.rb
|
|
@@ -297,7 +298,10 @@ files:
|
|
|
297
298
|
- spec/command_spec.rb
|
|
298
299
|
- spec/config_file_spec.rb
|
|
299
300
|
- spec/config_spec.rb
|
|
301
|
+
- spec/csv_spec.rb
|
|
300
302
|
- spec/data/MetadataMapping.xlsx
|
|
303
|
+
- spec/data/test-headers.csv
|
|
304
|
+
- spec/data/test-noheaders.csv
|
|
301
305
|
- spec/data/test.data
|
|
302
306
|
- spec/data/test.xml
|
|
303
307
|
- spec/data/test.yml
|
|
@@ -351,7 +355,10 @@ test_files:
|
|
|
351
355
|
- spec/command_spec.rb
|
|
352
356
|
- spec/config_file_spec.rb
|
|
353
357
|
- spec/config_spec.rb
|
|
358
|
+
- spec/csv_spec.rb
|
|
354
359
|
- spec/data/MetadataMapping.xlsx
|
|
360
|
+
- spec/data/test-headers.csv
|
|
361
|
+
- spec/data/test-noheaders.csv
|
|
355
362
|
- spec/data/test.data
|
|
356
363
|
- spec/data/test.xml
|
|
357
364
|
- spec/data/test.yml
|