ndr_import 4.1.4 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +1 -32
- data/.travis.yml +16 -14
- data/code_safety.yml +38 -40
- data/gemfiles/Gemfile.rails51 +6 -0
- data/gemfiles/Gemfile.rails52 +7 -0
- data/lib/ndr_import/csv_library.rb +8 -0
- data/lib/ndr_import/file/delimited.rb +4 -4
- data/lib/ndr_import/helpers/file/delimited.rb +5 -5
- data/lib/ndr_import/helpers/file/xml.rb +5 -2
- data/lib/ndr_import/mapper.rb +6 -3
- data/lib/ndr_import/table.rb +13 -9
- data/lib/ndr_import/version.rb +1 -1
- data/ndr_import.gemspec +5 -5
- data/test/file/delimited_test.rb +1 -1
- data/test/file/pdf_test.rb +1 -1
- data/test/file/registry_test.rb +1 -1
- data/test/helpers/file/pdf_test.rb +1 -1
- data/test/mapper_test.rb +64 -4
- data/test/resources/hello_world.pdf +0 -0
- data/test/table_test.rb +69 -7
- data/test/test_helper.rb +1 -1
- metadata +18 -18
- data/gemfiles/Gemfile.rails32 +0 -5
- data/gemfiles/Gemfile.rails41 +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c3697b01f732fdef03d66858b9f699b0c95673824332a1d4f2d8fa2b845aed24
|
4
|
+
data.tar.gz: 87bb849993db749b7b9a58d2a47be6b1f4ecd5a928f9541f97529452836f7fb1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 445825462bf049b2d8ebacd391695176302924e8b12a5e08c283e9b5ed32bb9600befa48c6777ed038f8a2f6c257604d3c86b899b795fd8d13e7980f85b7911f
|
7
|
+
data.tar.gz: a9c796eb0f8d1914df8fc1dc5c943c49ab7de68f7f109e2e917637a88262d334ef1e1a47f5f23571a910e51664109851f4748988c0b8592cf3c376f8d8c5b0cd
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,32 +1 @@
|
|
1
|
-
|
2
|
-
Enabled: true
|
3
|
-
|
4
|
-
# Multi-line method chaining should be done with trailing dots.
|
5
|
-
Style/DotPosition:
|
6
|
-
EnforcedStyle: trailing
|
7
|
-
|
8
|
-
HashSyntax:
|
9
|
-
EnforcedStyle: hash_rockets
|
10
|
-
SupportedStyles:
|
11
|
-
- ruby19
|
12
|
-
- hash_rockets
|
13
|
-
|
14
|
-
# Override HoundCI's preference for double quotes:
|
15
|
-
Style/StringLiterals:
|
16
|
-
EnforcedStyle: single_quotes
|
17
|
-
|
18
|
-
# Would enforce "-> { }", which we cannot use yet.
|
19
|
-
Lambda:
|
20
|
-
Enabled: false
|
21
|
-
|
22
|
-
# ...
|
23
|
-
LineLength:
|
24
|
-
Max: 99
|
25
|
-
|
26
|
-
# Relax some of the cops for tests
|
27
|
-
Metrics/ClassLength:
|
28
|
-
Exclude:
|
29
|
-
- test/**/*.rb
|
30
|
-
Metrics/MethodLength:
|
31
|
-
Exclude:
|
32
|
-
- test/**/*.rb
|
1
|
+
inherit_from: 'https://raw.githubusercontent.com/PublicHealthEngland/ndr_dev_support/master/.rubocop.yml'
|
data/.travis.yml
CHANGED
@@ -1,19 +1,21 @@
|
|
1
1
|
language: ruby
|
2
|
-
|
3
2
|
rvm:
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
- 2.3
|
4
|
+
- 2.4
|
5
|
+
- 2.5
|
7
6
|
gemfile:
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
- gemfiles/Gemfile.rails42
|
8
|
+
- gemfiles/Gemfile.rails50
|
9
|
+
- gemfiles/Gemfile.rails51
|
10
|
+
- gemfiles/Gemfile.rails52
|
13
11
|
sudo: false
|
14
|
-
|
15
12
|
cache: bundler
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
before_script: bundle update
|
14
|
+
script: bundle exec rake test
|
15
|
+
notifications:
|
16
|
+
slack:
|
17
|
+
on_pull_requests: false
|
18
|
+
on_success: always
|
19
|
+
on_failure: always
|
20
|
+
rooms:
|
21
|
+
secure: NMd9N/jNbECT/fCUBxPDKy4IMpUnRdMhobwa+9kDRaWYbRAwIkHLd8sI1l63qx7O03SlDpsHLLckjayMKS35gO/wRmgC7T8k9ppW75Xs5D4jR/j3FdTFawnXF+wVx0ddQrpH0K8oftPX1euPEllIh7+bJUYct/Siv0UX5eP+qyHT0gKtbDlI2CMKOcOHE8Q/zwjx0mLVSj/0U+HRx5+sMEDcwPupzhCYLdIAtenHsZ2Zmo2uSqOzK9Ruf3UsIh3gVSKXWGvXQzG8bIxogIJbEbwIk/gQyMr7UXwgNzhltPz1CqOrrTmSonrd3HbLVajJvDWPMBPGDZrUyipiW/MOUKpXgd8CsL46o4icYIZIAYEWLsn/AJkrA+UQZ8S5poR06jNH8xrI0eUQsu6maWhJ/rPfzwb6x2hCCyk2iQsGtO+SPCUrWnT1T3ir8H0HStD+AZ4/yz4cdWlClchko2ZfqS0q3Yv5jF3K4iVOF4GOUo01Ft+LDU3sPC7Ngq51bejoaLTzexiOfEaF0kKvB8XNXYYjV5ATNJ8XWQR7ISJ+na4FCwt4KaKtC864TWWDTxaz6lfr0B3Wf0lZLH22+BhpzrfPWFo3YGyMsOcgPU0rPHrtAzks55rqCTQEOaKTw4rfEmuMEFJK/y80GYS2jTPu0nCnJo4NdV1fVuSSD8iUFAM=
|
data/code_safety.yml
CHANGED
@@ -3,19 +3,19 @@ file safety:
|
|
3
3
|
".gitignore":
|
4
4
|
comments: whole file re-reviewed
|
5
5
|
reviewed_by: josh.pencheon
|
6
|
-
safe_revision:
|
6
|
+
safe_revision: 3ef51291c413fd5772d61a8394359146a02ae628
|
7
7
|
".hound.yml":
|
8
8
|
comments:
|
9
9
|
reviewed_by: timgentry
|
10
10
|
safe_revision: df3c0be0e655f4fc95c86d4a57bda6eef1fb8955
|
11
11
|
".rubocop.yml":
|
12
12
|
comments:
|
13
|
-
reviewed_by:
|
14
|
-
safe_revision:
|
13
|
+
reviewed_by: josh.pencheon
|
14
|
+
safe_revision: b09e268ff9c8349b914aa1b7ba888e1d39f97e4a
|
15
15
|
".travis.yml":
|
16
16
|
comments:
|
17
17
|
reviewed_by: josh.pencheon
|
18
|
-
safe_revision:
|
18
|
+
safe_revision: 661b5b8e71572bba28aa92fb95aa218e3f8444f4
|
19
19
|
CODE_OF_CONDUCT.md:
|
20
20
|
comments:
|
21
21
|
reviewed_by: timgentry
|
@@ -40,14 +40,6 @@ file safety:
|
|
40
40
|
comments:
|
41
41
|
reviewed_by: josh.pencheon
|
42
42
|
safe_revision: 5a7f26cecaabab20f4e666776f9166dcc3fa6bfe
|
43
|
-
gemfiles/Gemfile.rails32:
|
44
|
-
comments:
|
45
|
-
reviewed_by: timgentry
|
46
|
-
safe_revision: 0c5967732100f43e7b60a97a7f0aae60d3641791
|
47
|
-
gemfiles/Gemfile.rails41:
|
48
|
-
comments:
|
49
|
-
reviewed_by: timgentry
|
50
|
-
safe_revision: 0c5967732100f43e7b60a97a7f0aae60d3641791
|
51
43
|
gemfiles/Gemfile.rails42:
|
52
44
|
comments:
|
53
45
|
reviewed_by: timgentry
|
@@ -56,6 +48,14 @@ file safety:
|
|
56
48
|
comments:
|
57
49
|
reviewed_by: josh.pencheon
|
58
50
|
safe_revision: 738577adf8eeacc7a000d08289bd7ae7bf3b5849
|
51
|
+
gemfiles/Gemfile.rails51:
|
52
|
+
comments:
|
53
|
+
reviewed_by: josh.pencheon
|
54
|
+
safe_revision: eedd8f5588edd2a9463250fcddc5602f62ab26f1
|
55
|
+
gemfiles/Gemfile.rails52:
|
56
|
+
comments:
|
57
|
+
reviewed_by: josh.pencheon
|
58
|
+
safe_revision: c158dc783b84cab31380708e76e3812544cc1c2f
|
59
59
|
lib/ndr_import.rb:
|
60
60
|
comments:
|
61
61
|
reviewed_by: timgentry
|
@@ -63,7 +63,7 @@ file safety:
|
|
63
63
|
lib/ndr_import/csv_library.rb:
|
64
64
|
comments:
|
65
65
|
reviewed_by: josh.pencheon
|
66
|
-
safe_revision:
|
66
|
+
safe_revision: be12e57519d3737e8d3901d7b01485c6995708dd
|
67
67
|
lib/ndr_import/file/all.rb:
|
68
68
|
comments:
|
69
69
|
reviewed_by: timgentry
|
@@ -75,7 +75,7 @@ file safety:
|
|
75
75
|
lib/ndr_import/file/delimited.rb:
|
76
76
|
comments:
|
77
77
|
reviewed_by: josh.pencheon
|
78
|
-
safe_revision:
|
78
|
+
safe_revision: be12e57519d3737e8d3901d7b01485c6995708dd
|
79
79
|
lib/ndr_import/file/excel.rb:
|
80
80
|
comments:
|
81
81
|
reviewed_by: joshpencheon
|
@@ -102,8 +102,8 @@ file safety:
|
|
102
102
|
safe_revision: c88000b32401b5ae9ef7f5878a9b630506ab5a94
|
103
103
|
lib/ndr_import/helpers/file/delimited.rb:
|
104
104
|
comments:
|
105
|
-
reviewed_by:
|
106
|
-
safe_revision:
|
105
|
+
reviewed_by: josh.pencheon
|
106
|
+
safe_revision: be12e57519d3737e8d3901d7b01485c6995708dd
|
107
107
|
lib/ndr_import/helpers/file/excel.rb:
|
108
108
|
comments:
|
109
109
|
reviewed_by: joshpencheon
|
@@ -119,15 +119,15 @@ file safety:
|
|
119
119
|
lib/ndr_import/helpers/file/xml.rb:
|
120
120
|
comments:
|
121
121
|
reviewed_by: josh.pencheon
|
122
|
-
safe_revision:
|
122
|
+
safe_revision: d2245268ec6a0e4f60c521d171a820f299632c4f
|
123
123
|
lib/ndr_import/helpers/file/zip.rb:
|
124
124
|
comments:
|
125
125
|
reviewed_by: timgentry
|
126
126
|
safe_revision: 6c6f204fab2f4232d81cb76aa523c26b0c490ae7
|
127
127
|
lib/ndr_import/mapper.rb:
|
128
|
-
comments:
|
128
|
+
comments:
|
129
129
|
reviewed_by: josh.pencheon
|
130
|
-
safe_revision:
|
130
|
+
safe_revision: fbd4e1bfda8acd9ae026601dc4ecdabca5be4bc7
|
131
131
|
lib/ndr_import/mapping_error.rb:
|
132
132
|
comments:
|
133
133
|
reviewed_by: timgentry
|
@@ -161,10 +161,9 @@ file safety:
|
|
161
161
|
reviewed_by: josh.pencheon
|
162
162
|
safe_revision: 3c7f827d17aacbf7b811eea67e27553f3b039070
|
163
163
|
lib/ndr_import/table.rb:
|
164
|
-
comments:
|
165
|
-
digests changed on branch'
|
164
|
+
comments: uses File.basename
|
166
165
|
reviewed_by: josh.pencheon
|
167
|
-
safe_revision:
|
166
|
+
safe_revision: 14775e7262dbec3b6d0f69930ff526f856a94214
|
168
167
|
lib/ndr_import/universal_importer_helper.rb:
|
169
168
|
comments:
|
170
169
|
reviewed_by: josh.pencheon
|
@@ -172,11 +171,11 @@ file safety:
|
|
172
171
|
lib/ndr_import/version.rb:
|
173
172
|
comments: another check?
|
174
173
|
reviewed_by: josh.pencheon
|
175
|
-
safe_revision:
|
174
|
+
safe_revision: 1df87077495c1f595023bdbbd1e0bfb220dc5da5
|
176
175
|
ndr_import.gemspec:
|
177
|
-
comments:
|
176
|
+
comments:
|
178
177
|
reviewed_by: josh.pencheon
|
179
|
-
safe_revision:
|
178
|
+
safe_revision: b3f39d7243c41a44594336c3feed3b29c2386a0e
|
180
179
|
test/file/base_test.rb:
|
181
180
|
comments:
|
182
181
|
reviewed_by: timgentry
|
@@ -184,19 +183,19 @@ file safety:
|
|
184
183
|
test/file/delimited_test.rb:
|
185
184
|
comments:
|
186
185
|
reviewed_by: josh.pencheon
|
187
|
-
safe_revision:
|
186
|
+
safe_revision: be12e57519d3737e8d3901d7b01485c6995708dd
|
188
187
|
test/file/excel_test.rb:
|
189
188
|
comments:
|
190
189
|
reviewed_by: joshpencheon
|
191
190
|
safe_revision: 334d53bb9e8698bba3d92b4dbd71b36faacae629
|
192
191
|
test/file/pdf_test.rb:
|
193
192
|
comments:
|
194
|
-
reviewed_by:
|
195
|
-
safe_revision:
|
193
|
+
reviewed_by: josh.pencheon
|
194
|
+
safe_revision: f82e6839f7e3f9932a6f92242c03d94234fc1d82
|
196
195
|
test/file/registry_test.rb:
|
197
196
|
comments:
|
198
|
-
reviewed_by:
|
199
|
-
safe_revision:
|
197
|
+
reviewed_by: josh.pencheon
|
198
|
+
safe_revision: f82e6839f7e3f9932a6f92242c03d94234fc1d82
|
200
199
|
test/file/text_test.rb:
|
201
200
|
comments:
|
202
201
|
reviewed_by: timgentry
|
@@ -219,8 +218,8 @@ file safety:
|
|
219
218
|
safe_revision: 377c060bd1e012d6e162a4ab8923a3609aacdf57
|
220
219
|
test/helpers/file/pdf_test.rb:
|
221
220
|
comments:
|
222
|
-
reviewed_by:
|
223
|
-
safe_revision:
|
221
|
+
reviewed_by: josh.pencheon
|
222
|
+
safe_revision: f82e6839f7e3f9932a6f92242c03d94234fc1d82
|
224
223
|
test/helpers/file/word_test.rb:
|
225
224
|
comments:
|
226
225
|
reviewed_by: timgentry
|
@@ -234,10 +233,9 @@ file safety:
|
|
234
233
|
reviewed_by: josh.pencheon
|
235
234
|
safe_revision: 9abdd6ced1d0c90ce8dd88abee4eb6472c7ff0d6
|
236
235
|
test/mapper_test.rb:
|
237
|
-
comments:
|
238
|
-
digests changed on branch'
|
236
|
+
comments: exposes Mapper internals to test them
|
239
237
|
reviewed_by: josh.pencheon
|
240
|
-
safe_revision:
|
238
|
+
safe_revision: 3cea78767a73fd0d0ae64a4af3f07389e45349e9
|
241
239
|
test/non_tabular/mapping_test.rb:
|
242
240
|
comments:
|
243
241
|
reviewed_by: timgentry
|
@@ -304,8 +302,8 @@ file safety:
|
|
304
302
|
safe_revision: 45da71ebd3acbc0fe53755bcd75483ba17cb6924
|
305
303
|
test/resources/hello_world.pdf:
|
306
304
|
comments:
|
307
|
-
reviewed_by:
|
308
|
-
safe_revision:
|
305
|
+
reviewed_by: josh.pencheon
|
306
|
+
safe_revision: f82e6839f7e3f9932a6f92242c03d94234fc1d82
|
309
307
|
test/resources/hello_world.txt:
|
310
308
|
comments:
|
311
309
|
reviewed_by: timgentry
|
@@ -404,12 +402,12 @@ file safety:
|
|
404
402
|
safe_revision: 3c7f827d17aacbf7b811eea67e27553f3b039070
|
405
403
|
test/table_test.rb:
|
406
404
|
comments:
|
407
|
-
reviewed_by:
|
408
|
-
safe_revision:
|
405
|
+
reviewed_by: josh.pencheon
|
406
|
+
safe_revision: 14775e7262dbec3b6d0f69930ff526f856a94214
|
409
407
|
test/test_helper.rb:
|
410
408
|
comments:
|
411
409
|
reviewed_by: josh.pencheon
|
412
|
-
safe_revision:
|
410
|
+
safe_revision: 72750275da2193cc9ed362da85b88e9b5054f2d7
|
413
411
|
test/universal_importer_helper_test.rb:
|
414
412
|
comments:
|
415
413
|
reviewed_by: josh.pencheon
|
@@ -10,6 +10,14 @@ class << CSVLibrary
|
|
10
10
|
not self.const_defined?(:Reader)
|
11
11
|
end
|
12
12
|
|
13
|
+
# Ensure that we can pass "mode" straight through the underlying IO object
|
14
|
+
def foreach(path, **options, &block)
|
15
|
+
return to_enum(__method__, path, options) unless block
|
16
|
+
open(path, options.delete(:mode) || 'r', options) do |csv|
|
17
|
+
csv.each(&block)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
13
21
|
def write_csv_to_string(data)
|
14
22
|
self.generate do |csv|
|
15
23
|
data.each { |line| csv << line }
|
@@ -46,17 +46,17 @@ module NdrImport
|
|
46
46
|
def determine_encodings!(safe_path)
|
47
47
|
# delimiter encoding => # FasterCSV encoding string
|
48
48
|
supported_encodings = {
|
49
|
-
'UTF-8' => 'bom|utf-8',
|
50
|
-
'Windows-1252' => 'windows-1252:utf-8'
|
49
|
+
'UTF-8' => 'r:bom|utf-8',
|
50
|
+
'Windows-1252' => 'r:windows-1252:utf-8'
|
51
51
|
}
|
52
52
|
|
53
53
|
successful_options = nil
|
54
|
-
supported_encodings.each do |delimiter_encoding,
|
54
|
+
supported_encodings.each do |delimiter_encoding, access_mode|
|
55
55
|
begin
|
56
56
|
col_sep = @options['col_sep']
|
57
57
|
options = {
|
58
58
|
:col_sep => (col_sep || ',').force_encoding(delimiter_encoding),
|
59
|
-
:
|
59
|
+
:mode => access_mode
|
60
60
|
}
|
61
61
|
|
62
62
|
row_num = 0
|
@@ -48,16 +48,16 @@ module NdrImport
|
|
48
48
|
def determine_encodings!(safe_path, col_sep = nil)
|
49
49
|
# delimiter encoding => # FasterCSV encoding string
|
50
50
|
supported_encodings = {
|
51
|
-
'UTF-8' => 'bom|utf-8',
|
52
|
-
'Windows-1252' => 'windows-1252:utf-8'
|
51
|
+
'UTF-8' => 'r:bom|utf-8',
|
52
|
+
'Windows-1252' => 'r:windows-1252:utf-8'
|
53
53
|
}
|
54
54
|
|
55
55
|
successful_options = nil
|
56
|
-
supported_encodings.each do |delimiter_encoding,
|
56
|
+
supported_encodings.each do |delimiter_encoding, access_mode|
|
57
57
|
begin
|
58
58
|
options = {
|
59
|
-
:col_sep
|
60
|
-
:
|
59
|
+
:col_sep => (col_sep || ',').force_encoding(delimiter_encoding),
|
60
|
+
:mode => access_mode
|
61
61
|
}
|
62
62
|
|
63
63
|
row_num = 0
|
@@ -31,13 +31,16 @@ module NdrImport
|
|
31
31
|
# We let slide any warnings about xml declared as one of our
|
32
32
|
# auto encodings, but parsed as UTF-8:
|
33
33
|
encoding_pattern = AUTO_ENCODINGS.map { |name| Regexp.escape(name) }.join('|')
|
34
|
-
encoding_warning =
|
34
|
+
encoding_warning = /Document labelled (#{encoding_pattern}) but has UTF-8 content\z/
|
35
35
|
fatal_errors = document.errors.select do |error|
|
36
36
|
error.fatal? && (encoding_warning !~ error.message)
|
37
37
|
end
|
38
38
|
|
39
39
|
return unless fatal_errors.any?
|
40
|
-
|
40
|
+
raise Nokogiri::XML::SyntaxError, <<~MSG
|
41
|
+
The file had #{fatal_errors.length} fatal error(s)!"
|
42
|
+
#{fatal_errors.join("\n")}
|
43
|
+
MSG
|
41
44
|
end
|
42
45
|
end
|
43
46
|
end
|
data/lib/ndr_import/mapper.rb
CHANGED
@@ -177,11 +177,14 @@ module NdrImport::Mapper
|
|
177
177
|
raise e2
|
178
178
|
end
|
179
179
|
elsif field_mapping.include?(Strings::CLEAN)
|
180
|
-
return
|
180
|
+
return nil if original_value.blank?
|
181
|
+
|
182
|
+
cleaners = Array(field_mapping[Strings::CLEAN])
|
183
|
+
return cleaners.inject(original_value) { |a, e| a.clean(e) }
|
181
184
|
elsif field_mapping.include?(Strings::MAP)
|
182
|
-
return field_mapping[Strings::MAP]
|
185
|
+
return field_mapping[Strings::MAP].fetch(original_value, original_value)
|
183
186
|
elsif field_mapping.include?(Strings::MATCH)
|
184
|
-
# WARNING:TVB Thu Aug 9 17:09:25 BST 2012 field_mapping[
|
187
|
+
# WARNING:TVB Thu Aug 9 17:09:25 BST 2012 field_mapping[Strings::MATCH] regexp
|
185
188
|
# may need to be escaped
|
186
189
|
matches = Regexp.new(field_mapping[Strings::MATCH]).match(original_value)
|
187
190
|
return matches[1].strip if matches && matches.size > 0
|
data/lib/ndr_import/table.rb
CHANGED
@@ -62,13 +62,16 @@ module NdrImport
|
|
62
62
|
return enum_for(:process_line, line) unless block
|
63
63
|
|
64
64
|
if @row_index < header_lines
|
65
|
-
|
65
|
+
consume_header_line(line, @columns)
|
66
66
|
else
|
67
|
-
fail_unless_header_complete(@columns)
|
68
67
|
transform_line(line, @row_index, &block)
|
69
68
|
end
|
70
69
|
|
71
70
|
@row_index += 1
|
71
|
+
|
72
|
+
# We've now seen enough lines to have consumed a valid header; is this the case?
|
73
|
+
fail_unless_header_complete(@columns) if @row_index == header_lines
|
74
|
+
|
72
75
|
@notifier.try(:processed, @row_index)
|
73
76
|
end
|
74
77
|
|
@@ -163,20 +166,21 @@ module NdrImport
|
|
163
166
|
fail ArgumentError, "Unrecognised options: #{unrecognised_options.inspect}"
|
164
167
|
end
|
165
168
|
|
166
|
-
#
|
167
|
-
|
169
|
+
# Process `line` as a candidate header row. Header validation is done
|
170
|
+
# lazily, once all expected header lines have been consumed.
|
171
|
+
def consume_header_line(line, column_mappings)
|
168
172
|
columns = column_names(column_mappings)
|
169
173
|
|
170
|
-
|
171
|
-
fail "Number of columns does not match; expected #{columns.length}, got #{line.length}!"
|
172
|
-
end
|
173
|
-
|
174
|
-
header_guess = line.map(&:downcase)
|
174
|
+
header_guess = line.map { |column| column.to_s.downcase }
|
175
175
|
|
176
|
+
# The "best guess" is only if/when the header eventually deemed to be
|
177
|
+
# invalid - in which case, it builds the informative error message.
|
176
178
|
@header_best_guess = header_guess if header_guess.any?(&:present?)
|
177
179
|
@header_valid = true if header_guess == columns
|
178
180
|
end
|
179
181
|
|
182
|
+
# Once all header lines have been consumed, blow up in a
|
183
|
+
# helpful fashion if no valid row was found:
|
180
184
|
def fail_unless_header_complete(column_mappings)
|
181
185
|
return unless header_lines > 0 && !header_valid?
|
182
186
|
|
data/lib/ndr_import/version.rb
CHANGED
data/ndr_import.gemspec
CHANGED
@@ -19,16 +19,16 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
20
|
spec.require_paths = ['lib']
|
21
21
|
|
22
|
-
spec.add_dependency 'activesupport', '>= 3.2.18', '< 5.
|
23
|
-
spec.add_dependency 'ndr_support', '>=
|
22
|
+
spec.add_dependency 'activesupport', '>= 3.2.18', '< 5.3'
|
23
|
+
spec.add_dependency 'ndr_support', '>= 5.3.2', '< 6'
|
24
24
|
|
25
25
|
spec.add_dependency 'rubyzip', '~> 1.2', '>= 1.2.1'
|
26
26
|
spec.add_dependency 'roo', '~> 2.0'
|
27
27
|
|
28
|
-
spec.add_dependency 'nokogiri', '~> 1.
|
28
|
+
spec.add_dependency 'nokogiri', '~> 1.8', '>= 1.8.2'
|
29
29
|
spec.add_dependency 'roo-xls'
|
30
30
|
spec.add_dependency 'spreadsheet', '1.0.3'
|
31
|
-
spec.add_dependency 'pdf-reader', '1.2.0'
|
31
|
+
spec.add_dependency 'pdf-reader', '1.2.0' # Raises warnings on Ruby 2.4+
|
32
32
|
spec.add_dependency 'msworddoc-extractor', '0.2.0'
|
33
33
|
|
34
34
|
spec.required_ruby_version = '>= 2.2'
|
@@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
|
|
37
37
|
spec.add_development_dependency 'rake', '~> 10.0'
|
38
38
|
spec.add_development_dependency 'minitest'
|
39
39
|
spec.add_development_dependency 'mocha'
|
40
|
-
spec.add_development_dependency 'ndr_dev_support', '~>
|
40
|
+
spec.add_development_dependency 'ndr_dev_support', '~> 3.0'
|
41
41
|
spec.add_development_dependency 'guard'
|
42
42
|
spec.add_development_dependency 'guard-rubocop'
|
43
43
|
spec.add_development_dependency 'guard-test'
|
data/test/file/delimited_test.rb
CHANGED
@@ -143,7 +143,7 @@ module NdrImport
|
|
143
143
|
file_path = @permanent_test_files.join('normal.csv')
|
144
144
|
handler = NdrImport::File::Delimited.new(file_path, 'csv', 'col_sep' => nil)
|
145
145
|
|
146
|
-
handler.expects(determine_encodings!: {
|
146
|
+
handler.expects(determine_encodings!: { mode: 'r:bom|utf-8', col_sep: ',' }).once
|
147
147
|
|
148
148
|
2.times do
|
149
149
|
handler.tables.each do |tablename, sheet|
|
data/test/file/pdf_test.rb
CHANGED
data/test/file/registry_test.rb
CHANGED
@@ -15,7 +15,7 @@ class PdfTest < ActiveSupport::TestCase
|
|
15
15
|
|
16
16
|
test 'read_pdf_file helper should read pdf file' do
|
17
17
|
file_content = @importer.send(:read_pdf_file, @permanent_test_files.join('hello_world.pdf'))
|
18
|
-
assert_equal
|
18
|
+
assert_equal ['Hello World ', 'Goodbye Universe ', ' '], file_content
|
19
19
|
end
|
20
20
|
|
21
21
|
test 'read_pdf_file helper should raise exception on invalid pdf file' do
|
data/test/mapper_test.rb
CHANGED
@@ -21,6 +21,7 @@ class MapperTest < ActiveSupport::TestCase
|
|
21
21
|
clean_ethniccategory_mapping = { 'clean' => :ethniccategory }
|
22
22
|
clean_icd_mapping = { 'clean' => :icd }
|
23
23
|
clean_opcs_mapping = { 'clean' => :code_opcs }
|
24
|
+
clean_code_and_upcase_mapping = { 'clean' => [:code, :upcase] }
|
24
25
|
map_mapping = { 'map' => { 'A' => '1' } }
|
25
26
|
replace_mapping = { 'replace' => { '.0' => '' } }
|
26
27
|
daysafter_mapping = { 'daysafter' => '2012-05-16' }
|
@@ -102,6 +103,21 @@ class MapperTest < ActiveSupport::TestCase
|
|
102
103
|
priority: 1
|
103
104
|
YML
|
104
105
|
|
106
|
+
cross_populate_map_reverse_priority_mapping = YAML.load <<-YML
|
107
|
+
- column: referringclinicianname
|
108
|
+
mappings:
|
109
|
+
- field: consultantname
|
110
|
+
- field: consultantcode
|
111
|
+
priority: 1
|
112
|
+
map:
|
113
|
+
"Bob Fossil": "C5678"
|
114
|
+
"Bolo": ""
|
115
|
+
- column: referringcliniciancode
|
116
|
+
mappings:
|
117
|
+
- field: consultantcode
|
118
|
+
priority: 2
|
119
|
+
YML
|
120
|
+
|
105
121
|
cross_populate_order_mapping = YAML.load <<-YML
|
106
122
|
- column: referringclinicianname
|
107
123
|
mappings:
|
@@ -282,7 +298,7 @@ class MapperTest < ActiveSupport::TestCase
|
|
282
298
|
end
|
283
299
|
|
284
300
|
test 'map should return nil' do
|
285
|
-
|
301
|
+
assert_equal 'B', TestMapper.new.mapped_value('B', map_mapping)
|
286
302
|
end
|
287
303
|
|
288
304
|
test 'map should return correct date format' do
|
@@ -333,11 +349,16 @@ class MapperTest < ActiveSupport::TestCase
|
|
333
349
|
assert_equal 'U212 Y973', TestMapper.new.mapped_value('U212,Y973,X1', clean_opcs_mapping)
|
334
350
|
assert_equal '', TestMapper.new.mapped_value('98', clean_opcs_mapping)
|
335
351
|
assert_equal '', TestMapper.new.mapped_value('TooLong', clean_opcs_mapping)
|
336
|
-
|
352
|
+
assert_nil TestMapper.new.mapped_value('', clean_opcs_mapping)
|
337
353
|
assert_equal 'ABCD', TestMapper.new.mapped_value('AbcD', clean_opcs_mapping)
|
338
354
|
assert_equal '1234', TestMapper.new.mapped_value('1234', clean_opcs_mapping)
|
339
355
|
end
|
340
356
|
|
357
|
+
test 'map should use multiple cleans' do
|
358
|
+
assert_equal 'U3 Y2 X1',
|
359
|
+
TestMapper.new.mapped_value('u3,y2,x1', clean_code_and_upcase_mapping)
|
360
|
+
end
|
361
|
+
|
341
362
|
test 'map should handle array original value' do
|
342
363
|
original_value = ['C9999998', %w(Addenbrookes RGT01)]
|
343
364
|
mapped_value = TestMapper.new.mapped_line(original_value, replace_array_mapping)
|
@@ -373,7 +394,7 @@ class MapperTest < ActiveSupport::TestCase
|
|
373
394
|
test 'line mapping should create valid hash with blank cleaned value' do
|
374
395
|
assert_equal '', TestMapper.new.mapped_value('98', clean_opcs_mapping)
|
375
396
|
line_hash = TestMapper.new.mapped_line(['98'], simple_mapping_with_clean_opcs)
|
376
|
-
|
397
|
+
assert_nil line_hash['primaryprocedures']
|
377
398
|
assert_equal '98', line_hash[:rawtext]['primaryprocedures']
|
378
399
|
end
|
379
400
|
|
@@ -453,13 +474,52 @@ class MapperTest < ActiveSupport::TestCase
|
|
453
474
|
assert_equal 'C5678', line_hash['consultantcode']
|
454
475
|
end
|
455
476
|
|
477
|
+
test 'should create valid hash with used cross populate with map with no p2 map' do
|
478
|
+
line_hash = TestMapper.new.mapped_line(['something', ''], cross_populate_map_mapping)
|
479
|
+
assert_equal 'something', line_hash[:rawtext]['referringclinicianname']
|
480
|
+
assert_equal '', line_hash[:rawtext]['referringcliniciancode']
|
481
|
+
|
482
|
+
assert_equal 'something', line_hash['consultantname']
|
483
|
+
assert_equal 'something', line_hash['consultantcode']
|
484
|
+
end
|
485
|
+
|
486
|
+
test 'should create valid hash with used cross populate with map with p1 mapped' do
|
487
|
+
line_hash = TestMapper.new.mapped_line(['Bob Fossil', 'P2'],
|
488
|
+
cross_populate_map_reverse_priority_mapping)
|
489
|
+
assert_equal 'Bob Fossil', line_hash[:rawtext]['referringclinicianname']
|
490
|
+
assert_equal 'P2', line_hash[:rawtext]['referringcliniciancode']
|
491
|
+
|
492
|
+
assert_equal 'Bob Fossil', line_hash['consultantname']
|
493
|
+
assert_equal 'C5678', line_hash['consultantcode']
|
494
|
+
end
|
495
|
+
|
496
|
+
test 'should create valid hash with used cross populate with map with p1 mapped out' do
|
497
|
+
line_hash = TestMapper.new.mapped_line(['Bolo', 'P2'],
|
498
|
+
cross_populate_map_reverse_priority_mapping)
|
499
|
+
assert_equal 'Bolo', line_hash[:rawtext]['referringclinicianname']
|
500
|
+
assert_equal 'P2', line_hash[:rawtext]['referringcliniciancode']
|
501
|
+
|
502
|
+
assert_equal 'Bolo', line_hash['consultantname']
|
503
|
+
assert_equal 'P2', line_hash['consultantcode']
|
504
|
+
end
|
505
|
+
|
506
|
+
test 'should create valid hash with used cross populate with map with p1 no map' do
|
507
|
+
line_hash = TestMapper.new.mapped_line(['something', 'P2'],
|
508
|
+
cross_populate_map_reverse_priority_mapping)
|
509
|
+
assert_equal 'something', line_hash[:rawtext]['referringclinicianname']
|
510
|
+
assert_equal 'P2', line_hash[:rawtext]['referringcliniciancode']
|
511
|
+
|
512
|
+
assert_equal 'something', line_hash['consultantname']
|
513
|
+
assert_equal 'something', line_hash['consultantcode']
|
514
|
+
end
|
515
|
+
|
456
516
|
test 'should create valid hash with used cross populate without map' do
|
457
517
|
line_hash = TestMapper.new.mapped_line(['Bob Smith', ''], cross_populate_map_mapping)
|
458
518
|
assert_equal 'Bob Smith', line_hash[:rawtext]['referringclinicianname']
|
459
519
|
assert_equal '', line_hash[:rawtext]['referringcliniciancode']
|
460
520
|
|
461
521
|
assert_equal 'Bob Smith', line_hash['consultantname']
|
462
|
-
|
522
|
+
assert_equal 'Bob Smith', line_hash['consultantcode']
|
463
523
|
end
|
464
524
|
|
465
525
|
test 'should create valid hash with used cross populate without map and priorities' do
|
Binary file
|
data/test/table_test.rb
CHANGED
@@ -100,11 +100,22 @@ class TableTest < ActiveSupport::TestCase
|
|
100
100
|
:columns => [{ 'column' => 'one' }, { 'column' => 'two' }])
|
101
101
|
|
102
102
|
output = []
|
103
|
-
table.process_line(%w(
|
104
|
-
|
105
|
-
end
|
103
|
+
table.process_line(%w(ONE TWO)).each { |*stuff| output << stuff }
|
104
|
+
table.process_line(%w(CARROT POTATO)).each { |*stuff| output << stuff }
|
106
105
|
|
107
|
-
|
106
|
+
expected_output = [
|
107
|
+
['SomeTestKlass', { :rawtext => { 'one' => 'CARROT', 'two' => 'POTATO' } }, 1]
|
108
|
+
]
|
109
|
+
assert_equal expected_output, output
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_process_line_with_unsatisifed_header
|
113
|
+
table = NdrImport::Table.new(:header_lines => 1, :footer_lines => 0,
|
114
|
+
:klass => 'SomeTestKlass',
|
115
|
+
:columns => [{ 'column' => 'one' }, { 'column' => 'two' }])
|
116
|
+
|
117
|
+
exception = assert_raises(RuntimeError) { table.process_line(%w(ONE THREE)).to_a }
|
118
|
+
assert_equal 'Header is not valid! missing: ["two"] unexpected: ["three"]', exception.message
|
108
119
|
end
|
109
120
|
|
110
121
|
def test_transform_line
|
@@ -243,11 +254,59 @@ class TableTest < ActiveSupport::TestCase
|
|
243
254
|
assert_equal expected_output, output
|
244
255
|
end
|
245
256
|
|
246
|
-
def
|
257
|
+
def test_varying_header_line_lengths_with_valid_header_row_including_nils
|
258
|
+
lines = [
|
259
|
+
[nil] << 'RIGHTALIGN1' << 'RIGHTALIGN2',
|
260
|
+
%w(ONE TWO),
|
261
|
+
%w(LEFTALIGN) << nil,
|
262
|
+
%w(CENTRE1) << nil << 'CENTRE2',
|
263
|
+
%w(UNO DOS)
|
264
|
+
].each
|
265
|
+
|
266
|
+
table = NdrImport::Table.new(:header_lines => 4, :footer_lines => 0,
|
267
|
+
:klass => 'SomeTestKlass',
|
268
|
+
:columns => [{ 'column' => 'one' }, { 'column' => 'two' }])
|
269
|
+
|
270
|
+
output = []
|
271
|
+
table.transform(lines).each do |klass, fields, index|
|
272
|
+
output << [klass, fields, index]
|
273
|
+
end
|
274
|
+
|
275
|
+
assert table.header_valid?
|
276
|
+
|
277
|
+
expected_output = [['SomeTestKlass', { :rawtext => { 'one' => 'UNO', 'two' => 'DOS' } }, 4]]
|
278
|
+
assert_equal expected_output, output
|
279
|
+
end
|
280
|
+
|
281
|
+
def test_varying_header_line_lengths_with_valid_header_row
|
247
282
|
lines = [
|
248
283
|
%w(NOTHEADING1 NOTHEADING2 UHOH3 UHOH4),
|
249
284
|
%w(ONE TWO),
|
250
|
-
%w(DEFINITELYNOTHEADING1 DEFINITELYNOTHEADING2)
|
285
|
+
%w(DEFINITELYNOTHEADING1 DEFINITELYNOTHEADING2),
|
286
|
+
%w(UNO DOS)
|
287
|
+
].each
|
288
|
+
|
289
|
+
table = NdrImport::Table.new(:header_lines => 3, :footer_lines => 0,
|
290
|
+
:klass => 'SomeTestKlass',
|
291
|
+
:columns => [{ 'column' => 'one' }, { 'column' => 'two' }])
|
292
|
+
|
293
|
+
output = []
|
294
|
+
table.transform(lines).each do |klass, fields, index|
|
295
|
+
output << [klass, fields, index]
|
296
|
+
end
|
297
|
+
|
298
|
+
assert table.header_valid?
|
299
|
+
|
300
|
+
expected_output = [['SomeTestKlass', { :rawtext => { 'one' => 'UNO', 'two' => 'DOS' } }, 3]]
|
301
|
+
assert_equal expected_output, output
|
302
|
+
end
|
303
|
+
|
304
|
+
def test_varying_header_line_lengths_without_valid_header_row
|
305
|
+
lines = [
|
306
|
+
%w(NOTHEADING1 NOTHEADING2 UHOH3 UHOH4),
|
307
|
+
%w(ONE TWO NOPE),
|
308
|
+
%w(NOT_HERE OR_HERE),
|
309
|
+
%w(UNO DOS)
|
251
310
|
].each
|
252
311
|
|
253
312
|
table = NdrImport::Table.new(:header_lines => 3, :footer_lines => 0,
|
@@ -255,7 +314,10 @@ class TableTest < ActiveSupport::TestCase
|
|
255
314
|
:columns => [{ 'column' => 'one' }, { 'column' => 'two' }])
|
256
315
|
|
257
316
|
exception = assert_raises(RuntimeError) { table.transform(lines).to_a }
|
258
|
-
|
317
|
+
|
318
|
+
assert_match(/Header is not valid!/, exception.message)
|
319
|
+
assert_match(/missing: \["one", "two"\]/, exception.message)
|
320
|
+
assert_match(/unexpected: \["not_here", "or_here"\]/, exception.message)
|
259
321
|
end
|
260
322
|
|
261
323
|
def test_jumbled_header
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ndr_import
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- NCRS Development Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-06-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: 3.2.18
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '5.
|
22
|
+
version: '5.3'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,14 +29,14 @@ dependencies:
|
|
29
29
|
version: 3.2.18
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '5.
|
32
|
+
version: '5.3'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: ndr_support
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
39
|
+
version: 5.3.2
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: '6'
|
@@ -46,7 +46,7 @@ dependencies:
|
|
46
46
|
requirements:
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
49
|
+
version: 5.3.2
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: '6'
|
@@ -90,14 +90,20 @@ dependencies:
|
|
90
90
|
requirements:
|
91
91
|
- - "~>"
|
92
92
|
- !ruby/object:Gem::Version
|
93
|
-
version: '1.
|
93
|
+
version: '1.8'
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.8.2
|
94
97
|
type: :runtime
|
95
98
|
prerelease: false
|
96
99
|
version_requirements: !ruby/object:Gem::Requirement
|
97
100
|
requirements:
|
98
101
|
- - "~>"
|
99
102
|
- !ruby/object:Gem::Version
|
100
|
-
version: '1.
|
103
|
+
version: '1.8'
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: 1.8.2
|
101
107
|
- !ruby/object:Gem::Dependency
|
102
108
|
name: roo-xls
|
103
109
|
requirement: !ruby/object:Gem::Requirement
|
@@ -216,20 +222,14 @@ dependencies:
|
|
216
222
|
requirements:
|
217
223
|
- - "~>"
|
218
224
|
- !ruby/object:Gem::Version
|
219
|
-
version: '
|
220
|
-
- - ">="
|
221
|
-
- !ruby/object:Gem::Version
|
222
|
-
version: 1.1.3
|
225
|
+
version: '3.0'
|
223
226
|
type: :development
|
224
227
|
prerelease: false
|
225
228
|
version_requirements: !ruby/object:Gem::Requirement
|
226
229
|
requirements:
|
227
230
|
- - "~>"
|
228
231
|
- !ruby/object:Gem::Version
|
229
|
-
version: '
|
230
|
-
- - ">="
|
231
|
-
- !ruby/object:Gem::Version
|
232
|
-
version: 1.1.3
|
232
|
+
version: '3.0'
|
233
233
|
- !ruby/object:Gem::Dependency
|
234
234
|
name: guard
|
235
235
|
requirement: !ruby/object:Gem::Requirement
|
@@ -317,10 +317,10 @@ files:
|
|
317
317
|
- README.md
|
318
318
|
- Rakefile
|
319
319
|
- code_safety.yml
|
320
|
-
- gemfiles/Gemfile.rails32
|
321
|
-
- gemfiles/Gemfile.rails41
|
322
320
|
- gemfiles/Gemfile.rails42
|
323
321
|
- gemfiles/Gemfile.rails50
|
322
|
+
- gemfiles/Gemfile.rails51
|
323
|
+
- gemfiles/Gemfile.rails52
|
324
324
|
- lib/ndr_import.rb
|
325
325
|
- lib/ndr_import/csv_library.rb
|
326
326
|
- lib/ndr_import/file/all.rb
|
data/gemfiles/Gemfile.rails32
DELETED