ndr_import 8.5.0 → 8.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/Gemfile +0 -3
  4. data/README.md +6 -0
  5. data/bin/console +14 -0
  6. data/bin/setup +8 -0
  7. data/code_safety.yml +27 -11
  8. data/exe/pdf_acro_form_to_yaml +23 -0
  9. data/exe/pdf_to_text +28 -0
  10. data/exe/word_to_text +26 -0
  11. data/gemfiles/Gemfile.rails52 +0 -3
  12. data/gemfiles/Gemfile.rails60 +5 -0
  13. data/lib/ndr_import/version.rb +1 -1
  14. data/ndr_import.gemspec +9 -7
  15. metadata +23 -164
  16. data/gemfiles/Gemfile.rails50 +0 -8
  17. data/gemfiles/Gemfile.rails51 +0 -9
  18. data/test/file/acro_form_test.rb +0 -39
  19. data/test/file/base_test.rb +0 -54
  20. data/test/file/delimited_test.rb +0 -233
  21. data/test/file/docx_test.rb +0 -53
  22. data/test/file/excel_test.rb +0 -124
  23. data/test/file/pdf_test.rb +0 -36
  24. data/test/file/registry_test.rb +0 -62
  25. data/test/file/seven_zip_test.rb +0 -59
  26. data/test/file/text_test.rb +0 -92
  27. data/test/file/word_test.rb +0 -35
  28. data/test/file/xml_test.rb +0 -21
  29. data/test/file/zip_test.rb +0 -47
  30. data/test/fixed_width/table_test.rb +0 -35
  31. data/test/helpers/file/delimited_test.rb +0 -105
  32. data/test/helpers/file/excel_test.rb +0 -82
  33. data/test/helpers/file/pdf_test.rb +0 -27
  34. data/test/helpers/file/word_test.rb +0 -26
  35. data/test/helpers/file/xml_test.rb +0 -131
  36. data/test/helpers/file/zip_test.rb +0 -75
  37. data/test/mapper_test.rb +0 -676
  38. data/test/non_tabular/mapping_test.rb +0 -36
  39. data/test/non_tabular/table_test.rb +0 -590
  40. data/test/non_tabular_file_helper_test.rb +0 -501
  41. data/test/pdf_form/table_test.rb +0 -119
  42. data/test/readme_test.rb +0 -53
  43. data/test/resources/acro_form.pdf +0 -0
  44. data/test/resources/blank_tab_test.xlsx +0 -0
  45. data/test/resources/bomd.csv +0 -3
  46. data/test/resources/broken.csv +0 -3
  47. data/test/resources/filesystem_paths.yml +0 -26
  48. data/test/resources/flat_file.pdf +0 -0
  49. data/test/resources/flat_file.txt +0 -27
  50. data/test/resources/flat_file.yml +0 -20
  51. data/test/resources/hello_utf16be.txt +0 -0
  52. data/test/resources/hello_utf16le.txt +0 -0
  53. data/test/resources/hello_utf8.txt +0 -2
  54. data/test/resources/hello_windows.txt +0 -2
  55. data/test/resources/hello_world.doc +0 -0
  56. data/test/resources/hello_world.docx +0 -0
  57. data/test/resources/hello_world.pdf +0 -0
  58. data/test/resources/hello_world.txt +0 -2
  59. data/test/resources/high_ascii_delimited.txt +0 -2
  60. data/test/resources/high_ascii_delimited_example_two.txt +0 -3
  61. data/test/resources/malformed.csv +0 -3
  62. data/test/resources/malformed.xml +0 -6
  63. data/test/resources/malformed_pipe.csv +0 -3
  64. data/test/resources/normal.7z +0 -0
  65. data/test/resources/normal.csv +0 -3
  66. data/test/resources/normal.csv.zip +0 -0
  67. data/test/resources/normal_pipe.csv +0 -3
  68. data/test/resources/normal_thorn.csv +0 -3
  69. data/test/resources/not_a_pdf.pdf +0 -0
  70. data/test/resources/not_a_word_file.doc +0 -0
  71. data/test/resources/not_a_word_file.docx +0 -0
  72. data/test/resources/not_sign_delimited.txt +0 -3
  73. data/test/resources/password_protected_hello_world.docx +0 -0
  74. data/test/resources/password_protected_sample_xlsx.xlsx +0 -0
  75. data/test/resources/sample.xml +0 -34
  76. data/test/resources/sample_xls.xls +0 -0
  77. data/test/resources/sample_xlsx.xlsx +0 -0
  78. data/test/resources/sheet_streaming.xls +0 -0
  79. data/test/resources/sheet_streaming.xlsx +0 -0
  80. data/test/resources/standard_mappings.yml +0 -39
  81. data/test/resources/txt_file_xls_extension.xls +0 -1
  82. data/test/resources/txt_file_xlsx_extension.xlsx +0 -1
  83. data/test/resources/utf-16be_xml.xml +0 -0
  84. data/test/resources/utf-16be_xml_with_declaration.xml +0 -0
  85. data/test/resources/utf-16le_xml.xml +0 -0
  86. data/test/resources/utf-8_xml.xml +0 -9
  87. data/test/resources/windows-1252_xml.xml +0 -9
  88. data/test/resources/windows.csv +0 -5
  89. data/test/resources/xlsx_file_xls_extension.xls +0 -0
  90. data/test/standard_mappings_test.rb +0 -22
  91. data/test/table_test.rb +0 -545
  92. data/test/test_helper.rb +0 -35
  93. data/test/universal_importer_helper_test.rb +0 -86
  94. data/test/xml/table_test.rb +0 -90
@@ -1,82 +0,0 @@
1
- require 'test_helper'
2
- require 'ndr_import/helpers/file/excel'
3
-
4
- # Excel file helper tests
5
- class ExcelTest < ActiveSupport::TestCase
6
- # This is a test importer class to test the excel file helper mixin
7
- class TestImporter
8
- include NdrImport::Helpers::File::Excel
9
- end
10
-
11
- def setup
12
- @permanenttestfiles = SafePath.new('permanent_test_files')
13
- @importer = TestImporter.new
14
- end
15
-
16
- test 'read_excel_file helper should read xls file' do
17
- file_content = @importer.send(:read_excel_file, @permanenttestfiles.join('sample_xls.xls'))
18
- assert_equal file_content.count, 2
19
- assert_equal file_content.first, %w(1A 1B)
20
- end
21
-
22
- test 'read_excel_file helper should read xlsx file' do
23
- file_content = @importer.send(:read_excel_file, @permanenttestfiles.join('sample_xlsx.xlsx'))
24
- assert_equal file_content.count, 2
25
- assert_equal file_content.first, %w(1A 1B)
26
- end
27
-
28
- test 'should read xlsx file with null sheet' do
29
- file = @permanenttestfiles.join('blank_tab_test.xlsx')
30
- content = @importer.send(:read_excel_file, file, 'Sheet3')
31
-
32
- assert content.is_a?(Array)
33
- end
34
-
35
- test 'read_excel_file helper should read xlsx file with the incorrect xls extension' do
36
- file_path = @permanenttestfiles.join('xlsx_file_xls_extension.xls')
37
- file_content = @importer.send(:read_excel_file, file_path)
38
- assert_equal file_content.count, 2
39
- assert_equal file_content.first, %w(1A 1B)
40
-
41
- SafeFile.delete @permanenttestfiles.join('xlsx_file_xls_extension_amend.xlsx')
42
- end
43
-
44
- test 'read_excel_file helper should handle exceptions' do
45
- # txt file
46
- SafeFile.open(@permanenttestfiles.join('temp.txt'), 'w') { |f| f.write 'dummy line' }
47
- assert_raises RuntimeError do
48
- @importer.send(:read_excel_file, @permanenttestfiles.join('temp.txt'))
49
- end
50
-
51
- # .txt file in .xls extension
52
- File.rename @permanenttestfiles.join('temp.txt'), @permanenttestfiles.join('temp.xls')
53
- assert_raises RuntimeError do
54
- @importer.send(:read_excel_file, @permanenttestfiles.join('temp.xls'))
55
- end
56
-
57
- # .txt file in .xlsx extension
58
- File.rename @permanenttestfiles.join('temp.xls'), @permanenttestfiles.join('temp.xlsx')
59
- assert_raises RuntimeError do
60
- @importer.send(:read_excel_file, @permanenttestfiles.join('temp.xlsx'))
61
- end
62
-
63
- SafeFile.delete @permanenttestfiles.join('temp.xlsx')
64
- SafeFile.delete @permanenttestfiles.join('temp_amend.xlsx')
65
- end
66
-
67
- test 'excel_tables helper should read xls table correctly' do
68
- table = @importer.send(:excel_tables, @permanenttestfiles.join('sample_xls.xls'))
69
- table.each do |tablename, sheet|
70
- assert_equal 'Sheet1', tablename
71
- assert_equal %w(1A 1B), sheet.first
72
- end
73
- end
74
-
75
- test 'excel_tables helper should read xlsx table correctly' do
76
- table = @importer.send(:excel_tables, @permanenttestfiles.join('sample_xlsx.xlsx'))
77
- table.each do |tablename, sheet|
78
- assert_equal 'Sheet1', tablename
79
- assert_equal %w(1A 1B), sheet.first
80
- end
81
- end
82
- end
@@ -1,27 +0,0 @@
1
- require 'test_helper'
2
- require 'ndr_import/helpers/file/pdf'
3
-
4
- # PDF file helper tests
5
- class PdfTest < ActiveSupport::TestCase
6
- # This is a test importer class to test the PDF file helper mixin
7
- class TestImporter
8
- include NdrImport::Helpers::File::Pdf
9
- end
10
-
11
- def setup
12
- @permanent_test_files = SafePath.new('permanent_test_files')
13
- @importer = TestImporter.new
14
- end
15
-
16
- test 'read_pdf_file helper should read pdf file' do
17
- file_content = @importer.send(:read_pdf_file, @permanent_test_files.join('hello_world.pdf'))
18
- assert_equal ['Hello World', '',
19
- 'Goodbye Universe'], file_content
20
- end
21
-
22
- test 'read_pdf_file helper should raise exception on invalid pdf file' do
23
- assert_raises RuntimeError do
24
- @importer.send(:read_pdf_file, @permanent_test_files.join('not_a_pdf.pdf'))
25
- end
26
- end
27
- end
@@ -1,26 +0,0 @@
1
- require 'test_helper'
2
- require 'ndr_import/helpers/file/word'
3
-
4
- # Word file helper tests
5
- class WordTest < ActiveSupport::TestCase
6
- # This is a test importer class to test the Word file helper mixin
7
- class TestImporter
8
- include NdrImport::Helpers::File::Word
9
- end
10
-
11
- def setup
12
- @permanent_test_files = SafePath.new('permanent_test_files')
13
- @importer = TestImporter.new
14
- end
15
-
16
- test 'read_word_file helper should read word file' do
17
- file_content = @importer.send(:read_word_file, @permanent_test_files.join('hello_world.doc'))
18
- assert_equal file_content, ['Hello world, this is a word document']
19
- end
20
-
21
- test 'read_word_file helper should raise exception on invalid word file' do
22
- assert_raises RuntimeError do
23
- @importer.send(:read_word_file, @permanent_test_files.join('not_a_word_file.doc'))
24
- end
25
- end
26
- end
@@ -1,131 +0,0 @@
1
- require 'test_helper'
2
- require 'ndr_import/helpers/file/xml'
3
- require 'nokogiri'
4
-
5
- # XML file helper tests
6
- class XmlTest < ActiveSupport::TestCase
7
- # This is a test importer class to test the XML file helper mixin
8
- class TestImporter
9
- include NdrImport::Helpers::File::Xml
10
- end
11
-
12
- def setup
13
- @home = SafePath.new('test_space_rw')
14
- @permanent_test_files = SafePath.new('permanent_test_files')
15
- @importer = TestImporter.new
16
- end
17
-
18
- test 'import_xml_file should handle incoming UTF-8' do
19
- doc = @importer.send(:read_xml_file, @permanent_test_files.join('utf-8_xml.xml'))
20
- greek = doc.xpath('//letter').map(&:text).join
21
-
22
- assert_equal 'UTF-8', doc.encoding
23
-
24
- assert greek.valid_encoding?
25
- assert_equal Encoding.find('UTF-8'), greek.encoding
26
- assert_equal 2, greek.chars.to_a.length
27
- assert_equal [206, 177, 206, 178], greek.bytes.to_a # 2-bytes each for alpha and beta
28
- end
29
-
30
- test 'import_xml_file should handle incoming UTF-16 (big endian)' do
31
- doc = @importer.send(:read_xml_file, @permanent_test_files.join('utf-16be_xml.xml'))
32
- greek = doc.xpath('//letter').map(&:text).join
33
-
34
- assert_equal 'UTF-8', doc.encoding
35
-
36
- assert greek.valid_encoding?
37
- assert_equal Encoding.find('UTF-8'), greek.encoding
38
- assert_equal 2, greek.chars.to_a.length
39
- assert_equal [206, 177, 206, 178], greek.bytes.to_a # 2-bytes each for alpha and beta
40
- end
41
-
42
- test 'import_xml_file should handle incoming UTF-16 (little endian)' do
43
- doc = @importer.send(:read_xml_file, @permanent_test_files.join('utf-16le_xml.xml'))
44
- greek = doc.xpath('//letter').map(&:text).join
45
-
46
- assert_equal 'UTF-8', doc.encoding
47
-
48
- assert greek.valid_encoding?
49
- assert_equal Encoding.find('UTF-8'), greek.encoding
50
- assert_equal 2, greek.chars.to_a.length
51
- assert_equal [206, 177, 206, 178], greek.bytes.to_a # 2 bytes each for alpha and beta
52
- end
53
-
54
- test 'import_xml_file should handle incoming UTF-16 with declaration' do
55
- doc = @importer.send(:read_xml_file,
56
- @permanent_test_files.join('utf-16be_xml_with_declaration.xml'))
57
- greek = doc.xpath('//letter').map(&:text).join
58
-
59
- assert greek.valid_encoding?
60
- assert_equal Encoding.find('UTF-8'), greek.encoding
61
- assert_equal 2, greek.chars.to_a.length
62
- assert_equal [206, 177, 206, 178], greek.bytes.to_a # 2 bytes each for alpha and beta
63
-
64
- # The document should be UTF-8, and we shouldn't
65
- # get encoding mismatches when interrogating it:
66
- assert_equal 'UTF-8', doc.encoding
67
- assert_equal 1, doc.css('note[id=alpha]').length
68
- end
69
-
70
- test 'import_xml_file should handle incoming Windows-1252' do
71
- doc = @importer.send(:read_xml_file, @permanent_test_files.join('windows-1252_xml.xml'))
72
- punct = doc.xpath('//letter').map(&:text).join
73
-
74
- assert_equal 'UTF-8', doc.encoding
75
-
76
- assert punct.valid_encoding?
77
- assert_equal Encoding.find('UTF-8'), punct.encoding
78
- assert_equal 2, punct.chars.to_a.length
79
- assert_equal [226, 128, 153, 226, 128, 147], punct.bytes.to_a # 3 bytes each for apostrophe and dash
80
- end
81
-
82
- test 'import_xml_file with malformed XML file' do
83
- assert_raises Nokogiri::XML::SyntaxError do
84
- @importer.send(:read_xml_file, @permanent_test_files.join('malformed.xml'))
85
- end
86
- end
87
-
88
- test '.import_xml_file should reject non safe path arguments' do
89
- assert_raises ArgumentError do
90
- @importer.send(:read_xml_file, @home.join('simple.xml').to_s)
91
- end
92
- end
93
-
94
- test '.import_xml_file should accept safepath' do
95
- builder = Nokogiri::XML::Builder.new do |xml|
96
- xml.root do
97
- xml.note(:id => 1) do
98
- xml.time 'Thu Dec 13 13:12:00 UTC 2012'
99
- xml.title 'Note 1'
100
- xml.body 'Note 1 body blabla bla'
101
- end
102
- xml.note(:id => 2) do
103
- xml.time 'Thu Dec 14 12:11:00 UTC 2012'
104
- xml.title 'note 2'
105
- xml.body 'note 2 body blablabala'
106
- end
107
- end
108
- end
109
- SafeFile.open(@home.join('simple.xml'), 'w') { |f| f.write builder.to_xml }
110
-
111
- doc = @importer.send(:read_xml_file, @home.join('simple.xml'))
112
-
113
- assert_equal 1, doc.children.reject { |c| c.text =~ /\A\n *\Z/ }.length
114
- assert_equal 'root', doc.children.reject { |c| c.text =~ /\A\n *\Z/ }[0].name
115
- assert_equal 2, doc.
116
- children.reject { |c| c.text =~ /\A\n *\Z/ }[0].
117
- children.reject { |c| c.text =~ /\A\n *\Z/ }.length
118
- assert_equal 'note', doc.children.reject { |c| c.text =~ /\A\n *\Z/ }[0].
119
- children.reject { |c| c.text =~ /\A\n *\Z/ }[0].name
120
- assert_equal 3, doc.
121
- children.reject { |c| c.text =~ /\A\n *\Z/ }[0].
122
- children.reject { |c| c.text =~ /\A\n *\Z/ }[0].
123
- children.reject { |c| c.text =~ /\A\n *\Z/ }.length
124
- assert_equal 'Thu Dec 13 13:12:00 UTC 2012', doc.
125
- children.reject { |c| c.text =~ /\A\n *\Z/ }[0].
126
- children.reject { |c| c.text =~ /\A\n *\Z/ }[0].
127
- children.reject { |c| c.text =~ /\A\n *\Z/ }[0].text
128
-
129
- SafeFile.delete @home.join('simple.xml')
130
- end
131
- end
@@ -1,75 +0,0 @@
1
- require 'test_helper'
2
- require 'ndr_import/helpers/file/zip'
3
- require 'zip'
4
-
5
- # Zip file helper tests
6
- class ZipTest < ActiveSupport::TestCase
7
- # This is a test importer class to test the Zip file helper mixin
8
- class TestImporter
9
- include NdrImport::Helpers::File::Zip
10
- end
11
-
12
- def setup
13
- @home = SafePath.new('test_space_rw')
14
- @permanent_test_files = SafePath.new('permanent_test_files')
15
- @importer = TestImporter.new
16
- end
17
-
18
- test '.unzip should reject non SafePath arguments' do
19
- zip = @home.join('imaginary.zip')
20
-
21
- assert_raises ArgumentError do
22
- @importer.send(:unzip_file, zip.to_s, @home.to_s)
23
- end
24
-
25
- assert_raises ArgumentError do
26
- @importer.send(:unzip_file, zip.to_s, @home)
27
- end
28
-
29
- assert_raises ArgumentError do
30
- @importer.send(:unzip_file, zip, @home.to_s)
31
- end
32
- end
33
-
34
- test '.unzip unzip zip file' do
35
- zip_name = @home.join('test.zip')
36
-
37
- files = [
38
- @home.join('f1'),
39
- @home.join('f2'),
40
- @home.join('f3')
41
- ]
42
-
43
- files.each do |fname|
44
- File.open(fname, 'w') { |f| f.write "test #{fname}" }
45
- end
46
-
47
- ::Zip::File.open(zip_name, Zip::File::CREATE) do |zipfile|
48
- files.each do |fname|
49
- zipfile.add(File.basename(fname.to_s), fname.to_s)
50
- end
51
- end
52
-
53
- File.delete(*files)
54
-
55
- files.each do |fname|
56
- assert !File.exist?(fname)
57
- end
58
-
59
- assert File.exist?(zip_name)
60
- dest = @home.join('unziped')
61
-
62
- @importer.send(:unzip_file, zip_name, dest)
63
-
64
- files.each do |fname|
65
- assert File.exist?(dest.join(File.basename(fname)))
66
- end
67
-
68
- files.each do |fname|
69
- File.delete(dest.join(File.basename(fname)))
70
- end
71
-
72
- File.delete(zip_name)
73
- FileUtils.rm_r(dest)
74
- end
75
- end
@@ -1,676 +0,0 @@
1
- require 'test_helper'
2
-
3
- # expose private methods
4
- class TestMapper
5
- include NdrImport::Mapper
6
-
7
- public :fixed_width_columns, :mapped_line, :mapped_value, :replace_before_mapping
8
-
9
- # TODO: test fixed_width_columns
10
- end
11
-
12
- # This tests the NdrImport::Mapper class
13
- class MapperTest < ActiveSupport::TestCase
14
- def setup
15
- @permanent_test_files = SafePath.new('permanent_test_files')
16
- end
17
-
18
- format_mapping = { 'format' => 'dd/mm/yyyy' }
19
- format_mapping_yyyymmdd = { 'format' => 'yyyymmdd' }
20
- clean_name_mapping = { 'clean' => :name }
21
- clean_ethniccategory_mapping = { 'clean' => :ethniccategory }
22
- clean_icd_mapping = { 'clean' => :icd }
23
- clean_opcs_mapping = { 'clean' => :code_opcs }
24
- clean_code_and_upcase_mapping = { 'clean' => [:code, :upcase] }
25
- map_mapping = { 'map' => { 'A' => '1' } }
26
- replace_mapping = { 'replace' => { '.0' => '' } }
27
- daysafter_mapping = { 'daysafter' => '2012-05-16' }
28
- # TODO: match_mapping = {}
29
-
30
- simple_mapping = [{ 'column' => 'patient address', 'mappings' => ['field' => 'address'] }]
31
-
32
- simple_mapping_with_clean_opcs = YAML.load <<-YML
33
- - column: primaryprocedures
34
- mappings:
35
- - field: primaryprocedures
36
- clean: :code_opcs
37
- YML
38
-
39
- join_mapping = YAML.load <<-YML
40
- - column: forename1
41
- mappings:
42
- - field: forenames
43
- order: 1
44
- join: " "
45
- - column: forename2
46
- mappings:
47
- - field: forenames
48
- order: 2
49
- YML
50
-
51
- join_compact_mapping = YAML.load <<-YML
52
- - column: forename1
53
- mappings:
54
- - field: forenames
55
- order: 1
56
- join: " "
57
- compact: false
58
- - column: forename2
59
- mappings:
60
- - field: forenames
61
- order: 2
62
- YML
63
-
64
- unused_mapping = [{ 'column' => 'extra', 'rawtext_name' => 'extra' }]
65
-
66
- cross_populate_mapping = YAML.load <<-YML
67
- - column: referringclinicianname
68
- mappings:
69
- - field: consultantname
70
- - field: consultantcode
71
- priority: 2
72
- - column: referringcliniciancode
73
- mappings:
74
- - field: consultantcode
75
- YML
76
-
77
- cross_populate_replace_mapping = YAML.load <<-YML
78
- - column: referringclinicianname
79
- mappings:
80
- - field: consultantname
81
- - field: consultantcode
82
- priority: 2
83
- replace:
84
- ? !ruby/regexp /^BOB FOSSIL$/i
85
- : "ROBERT FOSSIL"
86
- - column: referringcliniciancode
87
- mappings:
88
- - field: consultantcode
89
- priority: 1
90
- YML
91
-
92
- cross_populate_map_mapping = YAML.load <<-YML
93
- - column: referringclinicianname
94
- mappings:
95
- - field: consultantname
96
- - field: consultantcode
97
- priority: 2
98
- map:
99
- "Bob Fossil": "C5678"
100
- - column: referringcliniciancode
101
- mappings:
102
- - field: consultantcode
103
- priority: 1
104
- YML
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
-
121
- cross_populate_order_mapping = YAML.load <<-YML
122
- - column: referringclinicianname
123
- mappings:
124
- - field: consultantname
125
- - field: consultantcode
126
- priority: 2
127
- - column: referringcliniciancode
128
- mappings:
129
- - field: consultantcode
130
- priority: 1
131
- - column: somecolumn
132
- mappings:
133
- - field: consultantcode
134
- priority: 5
135
- - column: anothercolumn
136
- mappings:
137
- - field: consultantcode
138
- priority: 10
139
- YML
140
-
141
- cross_populate_no_priority = YAML.load <<-YML
142
- - column: columnoneraw
143
- mappings:
144
- - field: columnone
145
- - field: columntwo
146
- - column: columntworaw
147
- mappings:
148
- - field: columntwo
149
- priority: 5
150
- YML
151
-
152
- standard_mapping_without = YAML.load <<-YML
153
- - column: surname
154
- rawtext_name: surname
155
- mappings:
156
- - field: surname
157
- clean: :name
158
- - column: forename
159
- rawtext_name: forenames
160
- mappings:
161
- - field: forenames
162
- clean: :name
163
- - column: sex
164
- rawtext_name: sex
165
- mappings:
166
- - field: sex
167
- clean: :sex
168
- - column: nhs_no
169
- rawtext_name: nhsnumber
170
- mappings:
171
- - field: nhsnumber
172
- clean: :nhsnumber
173
- YML
174
-
175
- standard_mapping_with = YAML.load <<-YML
176
- - standard_mapping: surname
177
- - column: forename
178
- standard_mapping: forenames
179
- - standard_mapping: sex
180
- - column: nhs_no
181
- standard_mapping: nhsnumber
182
- YML
183
-
184
- standard_mapping_merge = YAML.load <<-YML
185
- - column: surname
186
- standard_mapping: surname
187
- mappings:
188
- - field: surname2
189
- YML
190
-
191
- standard_mapping_column = YAML.load <<-YML
192
- - column: overriding_column_name
193
- standard_mapping: test
194
- YML
195
-
196
- invalid_priorities = YAML.load <<-YML
197
- - column: columnoneraw
198
- mappings:
199
- - field: columnone
200
- - field: columntwo
201
- priority: 5
202
- - column: columntworaw
203
- mappings:
204
- - field: columntwo
205
- priority: 5
206
- YML
207
-
208
- invalid_standard_mapping = YAML.load <<-YML
209
- - column: surname
210
- standard_mapping: surnames
211
- YML
212
-
213
- joined_mapping_blank_start = YAML.load <<-YML
214
- - column: addressoneraw
215
- mappings:
216
- - field: address
217
- join: ","
218
- order: 1
219
- - column: postcode
220
- mappings:
221
- - field: address
222
- order: 2
223
- YML
224
-
225
- joined_mapping_blank_start_uncompacted = YAML.load <<-YML
226
- - column: addressoneraw
227
- mappings:
228
- - field: address
229
- join: ","
230
- order: 1
231
- compact: false
232
- - column: postcode
233
- mappings:
234
- - field: address
235
- order: 2
236
- YML
237
-
238
- date_mapping = YAML.load <<-YML
239
- - column: birth_date
240
- rawtext_name: dateofbirth
241
- mappings:
242
- - field: dateofbirth
243
- format: dd/mm/yyyy
244
- - column: received_date
245
- rawtext_name: receiveddate
246
- mappings:
247
- - field: receiveddate
248
- format: yyyymmdd
249
- - column: american_date
250
- rawtext_name: americandate
251
- mappings:
252
- - field: americandate
253
- format: mm/dd/yyyy
254
- - column: short_date
255
- rawtext_name: shortdate
256
- mappings:
257
- - field: shortdate
258
- format: dd/mm/yy
259
- - column: funky_date
260
- rawtext_name: funkydate
261
- mappings:
262
- - field: funkydate
263
- format: dd/mmm/yy
264
- YML
265
-
266
- do_not_capture_column = YAML.load <<-YML
267
- - column: ignore_me
268
- do_not_capture: true
269
- YML
270
-
271
- base64_mapping = YAML.load <<-YML
272
- - column: base64
273
- decode:
274
- - :base64
275
- - :word_doc
276
- YML
277
-
278
- invalid_decode_mapping = YAML.load <<-YML
279
- - column: column_name
280
- decode:
281
- - :invalid_encoding
282
- YML
283
-
284
- replace_array_mapping = YAML.load <<-YML
285
- - column: consultantcode
286
- mappings:
287
- - field: consultantcode
288
- - column: hospital
289
- mappings:
290
- - field: hospital
291
- replace:
292
- - ? !ruby/regexp /Addenbrookes/
293
- : 'RGT01'
294
- YML
295
-
296
- validates_presence_mapping = YAML.safe_load <<-YML
297
- - column: column_one
298
- mappings:
299
- - field: field_one
300
- validates:
301
- presence: true
302
- - column: column_two
303
- mappings:
304
- - field: field_two
305
- YML
306
-
307
- test 'map should return a number' do
308
- assert_equal '1', TestMapper.new.mapped_value('A', map_mapping)
309
- end
310
-
311
- test 'map should return nil' do
312
- assert_equal 'B', TestMapper.new.mapped_value('B', map_mapping)
313
- end
314
-
315
- test 'map should return correct date format' do
316
- assert_equal Date.new(2011, 1, 25), TestMapper.new.mapped_value('25/01/2011', format_mapping)
317
- assert_equal Date.new(2011, 1, 25),
318
- TestMapper.new.mapped_value('20110125', format_mapping_yyyymmdd)
319
- end
320
-
321
- test 'map should return incorrect date format' do
322
- assert_not_equal Date.new(2011, 3, 4),
323
- TestMapper.new.mapped_value('03/04/2011', format_mapping)
324
- end
325
-
326
- test 'map should return nil date format' do
327
- assert_nil TestMapper.new.mapped_value('03/25/2011', format_mapping)
328
- end
329
-
330
- test 'map should replace value' do
331
- value = '2.0'
332
- TestMapper.new.replace_before_mapping(value, replace_mapping)
333
- assert_equal '2', value
334
- end
335
-
336
- test 'map should not alter value' do
337
- value = '2.1'
338
- TestMapper.new.replace_before_mapping(value, replace_mapping)
339
- assert_equal '2.1', value
340
- end
341
-
342
- test 'map should clean name' do
343
- assert_equal 'ANNABELLE SMITH',
344
- TestMapper.new.mapped_value('anna.belle,smith', clean_name_mapping)
345
- end
346
-
347
- test 'map should clean ethenic category' do
348
- assert_equal 'M', TestMapper.new.mapped_value('1', clean_ethniccategory_mapping)
349
- assert_equal 'X', TestMapper.new.mapped_value('99', clean_ethniccategory_mapping)
350
- assert_equal 'A', TestMapper.new.mapped_value('A', clean_ethniccategory_mapping)
351
- assert_equal 'INVALID', TestMapper.new.mapped_value('InValiD', clean_ethniccategory_mapping)
352
- end
353
-
354
- test 'map should clean icd code' do
355
- assert_equal 'C343 R932 Z515',
356
- TestMapper.new.mapped_value('C34.3,R93.2,Z51.5', clean_icd_mapping)
357
- end
358
-
359
- test 'map should clean opcs code' do
360
- assert_equal 'U212 Y973', TestMapper.new.mapped_value('U212,Y973,X1', clean_opcs_mapping)
361
- assert_equal '', TestMapper.new.mapped_value('98', clean_opcs_mapping)
362
- assert_equal '', TestMapper.new.mapped_value('TooLong', clean_opcs_mapping)
363
- assert_nil TestMapper.new.mapped_value('', clean_opcs_mapping)
364
- assert_equal 'ABCD', TestMapper.new.mapped_value('AbcD', clean_opcs_mapping)
365
- assert_equal '1234', TestMapper.new.mapped_value('1234', clean_opcs_mapping)
366
- end
367
-
368
- test 'map should use multiple cleans' do
369
- assert_equal 'U3 Y2 X1',
370
- TestMapper.new.mapped_value('u3,y2,x1', clean_code_and_upcase_mapping)
371
- end
372
-
373
- test 'map should handle array original value' do
374
- original_value = ['C9999998', %w(Addenbrookes RGT01)]
375
- mapped_value = TestMapper.new.mapped_line(original_value, replace_array_mapping)
376
- assert_equal %w(RGT01 RGT01), mapped_value['hospital']
377
- end
378
-
379
- test 'should raise an error on blank mandatory field' do
380
- exception = assert_raise(NdrImport::MissingFieldError) do
381
- TestMapper.new.mapped_line(['', 'RGT01'], validates_presence_mapping)
382
- end
383
- assert_equal "field_one can't be blank", exception.message
384
- end
385
-
386
- test 'should return correct date format for date fields with daysafter' do
387
- assert_equal Date.new(2012, 5, 18), TestMapper.new.mapped_value(2, daysafter_mapping)
388
- assert_equal Date.new(2012, 5, 18), TestMapper.new.mapped_value('2', daysafter_mapping)
389
- assert_equal Date.new(2012, 5, 14), TestMapper.new.mapped_value(-2, daysafter_mapping)
390
- assert_equal Date.new(2012, 5, 14), TestMapper.new.mapped_value('-2', daysafter_mapping)
391
- assert_equal Date.new(2012, 5, 16), TestMapper.new.mapped_value(0, daysafter_mapping)
392
- assert_equal 'String', TestMapper.new.mapped_value('String', daysafter_mapping)
393
- assert_equal '', TestMapper.new.mapped_value('', daysafter_mapping)
394
- assert_nil TestMapper.new.mapped_value(nil, daysafter_mapping)
395
- assert_equal Date.new(2057, 8, 23), TestMapper.new.mapped_value(16_535, daysafter_mapping)
396
- # Answer independently checked http://www.wolframalpha.com/input/?i=2012-05-16+%2B+9379+days
397
- assert_equal Date.new(2038, 1, 19), TestMapper.new.mapped_value(9379, daysafter_mapping)
398
- assert_equal Date.new(1946, 5, 11),
399
- TestMapper.new.mapped_value(16_900, 'daysafter' => '1900-02-01')
400
- assert_equal Date.new(2014, 4, 8),
401
- TestMapper.new.mapped_value(16_900, 'daysafter' => '1967-12-31')
402
- assert_equal Date.new(2046, 4, 9),
403
- TestMapper.new.mapped_value(16_900, 'daysafter' => '2000-01-01')
404
- end
405
-
406
- test 'line mapping should create valid hash' do
407
- line_hash = TestMapper.new.mapped_line(['1 test road, testtown'], simple_mapping)
408
- assert_equal '1 test road, testtown', line_hash['address']
409
- assert_equal '1 test road, testtown', line_hash[:rawtext]['patient address']
410
- end
411
-
412
- test 'line mapping should create valid hash with blank cleaned value' do
413
- assert_equal '', TestMapper.new.mapped_value('98', clean_opcs_mapping)
414
- line_hash = TestMapper.new.mapped_line(['98'], simple_mapping_with_clean_opcs)
415
- assert_nil line_hash['primaryprocedures']
416
- assert_equal '98', line_hash[:rawtext]['primaryprocedures']
417
- end
418
-
419
- test 'line mapping should create valid hash with join' do
420
- line_hash = TestMapper.new.mapped_line(%w(Catherine Elizabeth), join_mapping)
421
- assert_equal 'Catherine Elizabeth', line_hash['forenames']
422
- assert_equal 'Catherine', line_hash[:rawtext]['forename1']
423
- assert_equal 'Elizabeth', line_hash[:rawtext]['forename2']
424
- end
425
-
426
- test 'line mapping should create valid hash with rawtext only' do
427
- line_hash = TestMapper.new.mapped_line(['otherinfo'], unused_mapping)
428
- assert_equal 1, line_hash.length
429
- assert_equal 'otherinfo', line_hash[:rawtext]['extra']
430
- end
431
-
432
- test 'should create valid hash with unused cross populate' do
433
- line_hash = TestMapper.new.mapped_line(['Bob Fossil', 'C1234'], cross_populate_mapping)
434
- assert_equal 'Bob Fossil', line_hash[:rawtext]['referringclinicianname']
435
- assert_equal 'C1234', line_hash[:rawtext]['referringcliniciancode']
436
-
437
- assert_equal 'Bob Fossil', line_hash['consultantname']
438
- assert_equal 'C1234', line_hash['consultantcode']
439
- end
440
-
441
- test 'should create valid hash with used cross populate' do
442
- line_hash = TestMapper.new.mapped_line(['Bob Fossil', ''], cross_populate_mapping)
443
- assert_equal 'Bob Fossil', line_hash[:rawtext]['referringclinicianname']
444
- assert_equal '', line_hash[:rawtext]['referringcliniciancode']
445
-
446
- assert_equal 'Bob Fossil', line_hash['consultantname']
447
- assert_equal 'Bob Fossil', line_hash['consultantcode']
448
- end
449
-
450
- test 'should create valid hash with unused cross populate replace' do
451
- line_hash = TestMapper.new.mapped_line(['Bob Fossil', 'C1234'], cross_populate_replace_mapping)
452
- assert_equal 'Bob Fossil', line_hash[:rawtext]['referringclinicianname']
453
- assert_equal 'C1234', line_hash[:rawtext]['referringcliniciancode']
454
-
455
- assert_equal 'Bob Fossil', line_hash['consultantname']
456
- assert_equal 'C1234', line_hash['consultantcode']
457
- end
458
-
459
- test 'should create valid hash with used cross populate with replace' do
460
- line_hash = TestMapper.new.mapped_line(['Bob Fossil', ''], cross_populate_replace_mapping)
461
- assert_equal 'Bob Fossil', line_hash[:rawtext]['referringclinicianname']
462
- assert_equal '', line_hash[:rawtext]['referringcliniciancode']
463
-
464
- assert_equal 'Bob Fossil', line_hash['consultantname']
465
- assert_equal 'ROBERT FOSSIL', line_hash['consultantcode']
466
- end
467
-
468
- test 'should create valid hash with used cross populate without replace' do
469
- line_hash = TestMapper.new.mapped_line(['Bob Smith', ''], cross_populate_replace_mapping)
470
- assert_equal 'Bob Smith', line_hash[:rawtext]['referringclinicianname']
471
- assert_equal '', line_hash[:rawtext]['referringcliniciancode']
472
-
473
- assert_equal 'Bob Smith', line_hash['consultantname']
474
- assert_equal 'Bob Smith', line_hash['consultantcode']
475
- end
476
-
477
- test 'should create valid hash with unused cross populate map' do
478
- line_hash = TestMapper.new.mapped_line(['Bob Fossil', 'C1234'], cross_populate_map_mapping)
479
- assert_equal 'Bob Fossil', line_hash[:rawtext]['referringclinicianname']
480
- assert_equal 'C1234', line_hash[:rawtext]['referringcliniciancode']
481
-
482
- assert_equal 'Bob Fossil', line_hash['consultantname']
483
- assert_equal 'C1234', line_hash['consultantcode']
484
- end
485
-
486
- test 'should create valid hash with used cross populate with map' do
487
- line_hash = TestMapper.new.mapped_line(['Bob Fossil', ''], cross_populate_map_mapping)
488
- assert_equal 'Bob Fossil', line_hash[:rawtext]['referringclinicianname']
489
- assert_equal '', line_hash[:rawtext]['referringcliniciancode']
490
-
491
- assert_equal 'Bob Fossil', line_hash['consultantname']
492
- assert_equal 'C5678', line_hash['consultantcode']
493
- end
494
-
495
- test 'should create valid hash with used cross populate with map with no p2 map' do
496
- line_hash = TestMapper.new.mapped_line(['something', ''], cross_populate_map_mapping)
497
- assert_equal 'something', line_hash[:rawtext]['referringclinicianname']
498
- assert_equal '', line_hash[:rawtext]['referringcliniciancode']
499
-
500
- assert_equal 'something', line_hash['consultantname']
501
- assert_equal 'something', line_hash['consultantcode']
502
- end
503
-
504
- test 'should create valid hash with used cross populate with map with p1 mapped' do
505
- line_hash = TestMapper.new.mapped_line(['Bob Fossil', 'P2'],
506
- cross_populate_map_reverse_priority_mapping)
507
- assert_equal 'Bob Fossil', line_hash[:rawtext]['referringclinicianname']
508
- assert_equal 'P2', line_hash[:rawtext]['referringcliniciancode']
509
-
510
- assert_equal 'Bob Fossil', line_hash['consultantname']
511
- assert_equal 'C5678', line_hash['consultantcode']
512
- end
513
-
514
- test 'should create valid hash with used cross populate with map with p1 mapped out' do
515
- line_hash = TestMapper.new.mapped_line(['Bolo', 'P2'],
516
- cross_populate_map_reverse_priority_mapping)
517
- assert_equal 'Bolo', line_hash[:rawtext]['referringclinicianname']
518
- assert_equal 'P2', line_hash[:rawtext]['referringcliniciancode']
519
-
520
- assert_equal 'Bolo', line_hash['consultantname']
521
- assert_equal 'P2', line_hash['consultantcode']
522
- end
523
-
524
- test 'should create valid hash with used cross populate with map with p1 no map' do
525
- line_hash = TestMapper.new.mapped_line(['something', 'P2'],
526
- cross_populate_map_reverse_priority_mapping)
527
- assert_equal 'something', line_hash[:rawtext]['referringclinicianname']
528
- assert_equal 'P2', line_hash[:rawtext]['referringcliniciancode']
529
-
530
- assert_equal 'something', line_hash['consultantname']
531
- assert_equal 'something', line_hash['consultantcode']
532
- end
533
-
534
- test 'should create valid hash with used cross populate without map' do
535
- line_hash = TestMapper.new.mapped_line(['Bob Smith', ''], cross_populate_map_mapping)
536
- assert_equal 'Bob Smith', line_hash[:rawtext]['referringclinicianname']
537
- assert_equal '', line_hash[:rawtext]['referringcliniciancode']
538
-
539
- assert_equal 'Bob Smith', line_hash['consultantname']
540
- assert_equal 'Bob Smith', line_hash['consultantcode']
541
- end
542
-
543
- test 'should create valid hash with used cross populate without map and priorities' do
544
- line_hash = TestMapper.new.mapped_line(['Pass', '', 'Fail', 'Large Fail'],
545
- cross_populate_order_mapping)
546
- assert_equal 'Pass', line_hash[:rawtext]['referringclinicianname']
547
- assert_equal '', line_hash[:rawtext]['referringcliniciancode']
548
-
549
- assert_equal 'Pass', line_hash['consultantname']
550
- assert_equal 'Pass', line_hash['consultantcode']
551
- end
552
-
553
- test 'should create valid hash with used cross populate without priority' do
554
- line_hash = TestMapper.new.mapped_line(%w(Exists Not), cross_populate_no_priority)
555
- assert_equal 'Exists', line_hash[:rawtext]['columnoneraw']
556
- assert_equal 'Not', line_hash[:rawtext]['columntworaw']
557
-
558
- assert_equal 'Exists', line_hash['columnone']
559
- assert_equal 'Exists', line_hash['columntwo']
560
- end
561
-
562
- test 'should create equal hashes with standard mapping' do
563
- line_hash_without = TestMapper.new.mapped_line(
564
- ['Smith', 'John F', 'male', '01234567'], standard_mapping_without
565
- )
566
- line_hash_with = TestMapper.new.mapped_line(
567
- ['Smith', 'John F', 'male', '01234567'], standard_mapping_with
568
- )
569
- assert_equal line_hash_without, line_hash_with
570
- end
571
-
572
- test 'should merge standard mapping and normal mapping' do
573
- line_hash = TestMapper.new.mapped_line(['Smith'], standard_mapping_merge)
574
- assert_equal 'SMITH', line_hash['surname']
575
- assert_equal 'Smith', line_hash['surname2']
576
- end
577
-
578
- test 'should merge standard mapping in correct order' do
579
- line_hash = TestMapper.new.mapped_line(['Smith'], standard_mapping_column)
580
- assert_equal 'Smith', line_hash[:rawtext]['overriding_column_name']
581
- refute line_hash[:rawtext].include?('standard_mapping_column_name')
582
- end
583
-
584
- test 'should raise duplicate priority exception' do
585
- assert_raise(RuntimeError) do
586
- TestMapper.new.mapped_line(%w(A B), invalid_priorities)
587
- end
588
- end
589
-
590
- test 'should raise nonexistent standard mapping exception' do
591
- assert_raise(RuntimeError) do
592
- TestMapper.new.mapped_line(['A'], invalid_standard_mapping)
593
- end
594
- end
595
-
596
- test 'should not modify the standard mapping when using it' do
597
- # Take a deep copy of the original, using YAML serialization:
598
- standard_mappings = YAML.load(NdrImport::StandardMappings.mappings.to_yaml)
599
-
600
- TestMapper.new.mapped_line(['Smith'], YAML.load(<<-YML.strip_heredoc))
601
- - column: surname
602
- standard_mapping: surname
603
- mappings:
604
- - field: overwrite_surname
605
- YML
606
-
607
- assert_equal standard_mappings, NdrImport::StandardMappings.mappings
608
- end
609
-
610
- test 'should join blank first field with compacting' do
611
- line_hash = TestMapper.new.mapped_line(['', 'CB3 0DS'], joined_mapping_blank_start)
612
- assert_equal 'CB3 0DS', line_hash['address']
613
- end
614
-
615
- test 'should join blank first field without compacting' do
616
- line_hash = TestMapper.new.mapped_line(['', 'CB3 0DS'], joined_mapping_blank_start_uncompacted)
617
- assert_equal ',CB3 0DS', line_hash['address']
618
- end
619
-
620
- test 'line mapping should map date formats correctly' do
621
- real_date = Date.new(1927, 7, 6)
622
- incomings = %w( 06/07/1927 19270706 07/06/1927 06/07/27 06/JUL/27 )
623
- columns = %w( dateofbirth receiveddate americandate shortdate funkydate )
624
- line_hash = TestMapper.new.mapped_line(incomings, date_mapping)
625
-
626
- columns.each do |column_name|
627
- assert_equal real_date, line_hash[column_name].to_date
628
- end
629
- end
630
-
631
- test 'should ignore columns marked do not capture' do
632
- line_hash = TestMapper.new.mapped_line(['rubbish'], do_not_capture_column)
633
- refute line_hash[:rawtext].include?('ignore_me')
634
- end
635
-
636
- test 'should decode base64 encoded word document' do
637
- test_file = @permanent_test_files.join('hello_world.doc')
638
- encoded_content = Base64.encode64(File.binread(test_file))
639
- line_hash = TestMapper.new.mapped_line([encoded_content], base64_mapping)
640
- assert_equal 'Hello world, this is a word document', line_hash[:rawtext]['base64']
641
- end
642
-
643
- test 'should decode base64 encoded docx document' do
644
- test_file = @permanent_test_files.join('hello_world.docx')
645
- encoded_content = Base64.encode64(File.binread(test_file))
646
- line_hash = TestMapper.new.mapped_line([encoded_content], base64_mapping)
647
- expected_content = "Hello world, this is a modern word document\n" \
648
- "With more than one line of text\nThree in fact"
649
-
650
- assert_equal expected_content, line_hash[:rawtext]['base64']
651
- end
652
-
653
- test 'should decode word.doc' do
654
- test_file = @permanent_test_files.join('hello_world.doc')
655
- file_content = File.binread(test_file)
656
- text_content = TestMapper.new.send(:decode_raw_value, file_content, :word_doc)
657
- assert_equal 'Hello world, this is a word document', text_content
658
- end
659
-
660
- test 'should read word.doc stream' do
661
- test_file = @permanent_test_files.join('hello_world.doc')
662
- file_content = TestMapper.new.send(:read_word_stream, File.open(test_file, 'r'))
663
- assert_equal 'Hello world, this is a word document', file_content
664
- end
665
-
666
- test 'should handle blank values when attempting to decode_raw_value' do
667
- text_content = TestMapper.new.send(:decode_raw_value, '', :word_doc)
668
- assert_equal '', text_content
669
- end
670
-
671
- test 'should raise unknown encoding exception' do
672
- assert_raise(RuntimeError) do
673
- TestMapper.new.mapped_line(['A'], invalid_decode_mapping)
674
- end
675
- end
676
- end