ndr_import 8.5.0 → 8.5.1

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.
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