topographer 0.0.2 → 0.0.3

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 (33) hide show
  1. checksums.yaml +8 -8
  2. data/.gitignore +1 -0
  3. data/.travis.yml +5 -0
  4. data/README.md +1 -4
  5. data/lib/Topographer/importer/input/source_data.rb +4 -0
  6. data/lib/Topographer/importer/mapper/mapper_builder.rb +46 -0
  7. data/lib/Topographer/importer/mapper/mapping_columns.rb +46 -0
  8. data/lib/Topographer/importer/mapper/mapping_validator.rb +40 -0
  9. data/lib/Topographer/importer/mapper.rb +37 -130
  10. data/lib/Topographer/importer.rb +7 -4
  11. data/lib/Topographer/version.rb +1 -1
  12. data/spec/{Cartographer → Topographer}/importer/importer_spec.rb +14 -3
  13. data/spec/Topographer/importer/input/source_data_spec.rb +22 -0
  14. data/spec/Topographer/importer/mapper/mapper_builder_spec.rb +131 -0
  15. data/spec/Topographer/importer/mapper/mapping_columns_spec.rb +87 -0
  16. data/spec/Topographer/importer/mapper/mapping_validator_spec.rb +121 -0
  17. data/spec/{Cartographer → Topographer}/importer/mapper_spec.rb +66 -32
  18. data/spec/{Cartographer → Topographer}/importer/strategy/create_or_update_record_spec.rb +4 -2
  19. data/spec/{Cartographer → Topographer}/importer/strategy/import_new_records_spec.rb +2 -1
  20. data/spec/{Cartographer → Topographer}/importer/strategy/update_record_spec.rb +4 -2
  21. metadata +48 -36
  22. /data/spec/{Cartographer → Topographer}/importer/helpers/write_log_to_csv_spec.rb +0 -0
  23. /data/spec/{Cartographer → Topographer}/importer/helpers_spec.rb +0 -0
  24. /data/spec/{Cartographer → Topographer}/importer/importable_spec.rb +0 -0
  25. /data/spec/{Cartographer → Topographer}/importer/logger/base_spec.rb +0 -0
  26. /data/spec/{Cartographer → Topographer}/importer/logger/fatal_error_entry_spec.rb +0 -0
  27. /data/spec/{Cartographer → Topographer}/importer/logger/simple_spec.rb +0 -0
  28. /data/spec/{Cartographer → Topographer}/importer/mapper/default_field_mapping_spec.rb +0 -0
  29. /data/spec/{Cartographer → Topographer}/importer/mapper/field_mapping_spec.rb +0 -0
  30. /data/spec/{Cartographer → Topographer}/importer/mapper/validation_field_mapping_spec.rb +0 -0
  31. /data/spec/{Cartographer → Topographer}/importer/strategy/base_spec.rb +0 -0
  32. /data/spec/{Cartographer → Topographer}/importer/strategy/import_status_spec.rb +0 -0
  33. /data/spec/{Cartographer → Topographer}/importer/strategy/mapped_model.rb +0 -0
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZjI0NDZhMDEyMDhkNzA0NzA4MTczMjBjYzY3NWZkMzQxODBmYzBjNg==
4
+ NDcwNmMxNWRlMjkzMDgzMzg0MTMxNjM1YjMzODhmMDRhZmYwNzFlMg==
5
5
  data.tar.gz: !binary |-
6
- OTI1MzZhMWU2NTZhOTllOTE2Nzg4ZjMyZTVmMmU5MDQzMWU3ZmI1Ng==
6
+ Mjg4YzFlYWNiZmY0YzFkOTNlNGQ0ZDE5YWFkYmE1Zjk3YTRhOGVkYw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YzczMzllN2M3YTc3ZTc2M2E3YTY2NmJjMjU0YmNkODdhN2ViZDY5MGEzYjg3
10
- MTU1YTVkZmIwYjUwM2UyNWNhMjAzMTdiMjc2ZmIwZTZiMWE5OWU1MGU1OTk5
11
- ZDYyNWUyNTNjMjYzNzhkYzM4N2FiNjU4OWYyMWY0NzViNGMzNjM=
9
+ MDQ1YzFkYTI2MmI2ZTA2YzY3MzYyOWY1YzAyYTUwY2VhYmU1ZWVjMzllN2Y3
10
+ ODRmODMxNTc2ZmUxMzI1NWFhMDg4NGFmYTZkNWE5YmIyMTRkNTUxNjQ4N2Y3
11
+ NGRkMDlhMGNjZTM5YmQ1MDczZGVkMzM5ODNmNmEwYzQ4ZTYxZDA=
12
12
  data.tar.gz: !binary |-
13
- MjExOTg5NGM5OWYzZDhkYzM1NzBlM2RmMTY5N2JiNDRmNmJkNDUyZDhhOTll
14
- YTcwMWYyYmVkMjg5M2RkZTkwN2IwMjg5OWQ5N2I4MzhiNTEwZDQ3ZWVmNTEw
15
- ODViNDYxMjA4NDFhODIyMTI3OWY0YzAyYTFmY2I1YjE2YmVlZDI=
13
+ MGZkODRiZGI0OWY0MTlkMjFhNGM2MTQ3YjA0YjYwNDZiZGU1YmExMmVkY2Ux
14
+ Y2IxZGM1ZjIyODA0ODU4YmZmMGQxNDFjNTM2YzJmYzUzZTEyM2Q4YjFlZjcx
15
+ MDJjZWMyZjlkZmQzMDlmMTdkNTc4ZTUyNjYyODk5N2IyYzVhYTk=
data/.gitignore CHANGED
@@ -3,6 +3,7 @@
3
3
  .bundle
4
4
  .config
5
5
  .yardoc
6
+ .flooignore
6
7
  Gemfile.lock
7
8
  InstalledFiles
8
9
  _yardoc
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - "2.0.0"
5
+ script: bundle exec rspec spec
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Topographer
1
+ # Topographer [![Gem Version](https://badge.fury.io/rb/topographer.png)](http://badge.fury.io/rb/topographer) [![Build Status](https://travis-ci.org/SciMed/topographer.png?branch=master)](https://travis-ci.org/SciMed/topographer)
2
2
 
3
3
  Topographer is a gem that provides functionality to conveniently import from various data sources into
4
4
  ActiveRecord or other ORM systems. This accomplished by defining an input wrapper, a mapping from input data to
@@ -32,7 +32,4 @@ Check back soon for detailed usage instructions
32
32
  3. Commit your changes (`git commit -am 'Add some feature'`)
33
33
  4. Push to the branch (`git push origin my-new-feature`)
34
34
  5. Create new Pull Request
35
- =======
36
- Topographer
37
- ===========
38
35
 
@@ -5,4 +5,8 @@ class Topographer::Importer::Input::SourceData
5
5
  @source_identifier = source_identifier
6
6
  @data = data
7
7
  end
8
+
9
+ def empty?
10
+ @data.empty?
11
+ end
8
12
  end
@@ -0,0 +1,46 @@
1
+ class Topographer::Importer::Mapper::MapperBuilder
2
+ include Topographer::Importer::Mapper::MappingColumns
3
+ include Topographer::Importer::Mapper::MappingValidator
4
+
5
+ attr_reader :required_mappings, :optional_mappings, :ignored_mappings,
6
+ :validation_mappings, :default_values, :key_fields
7
+
8
+ def initialize
9
+ @required_mappings = {}
10
+ @optional_mappings = {}
11
+ @ignored_mappings = {}
12
+ @validation_mappings = {}
13
+ @default_values = {}
14
+ @key_fields = []
15
+ end
16
+
17
+ def required_mapping(input_columns, output_field, &mapping_behavior)
18
+ validate_unique_mapping(input_columns, output_field)
19
+ @required_mappings[output_field] = Topographer::Importer::Mapper::FieldMapping.new(true, input_columns, output_field, &mapping_behavior)
20
+ end
21
+
22
+ def optional_mapping(input_columns, output_field, &mapping_behavior)
23
+ validate_unique_mapping(input_columns, output_field)
24
+ @optional_mappings[output_field] = Topographer::Importer::Mapper::FieldMapping.new(false, input_columns, output_field, &mapping_behavior)
25
+ end
26
+
27
+ def validation_field(name, input_columns, &mapping_behavior)
28
+ validate_unique_validation_name(name)
29
+ @validation_mappings[name] = Topographer::Importer::Mapper::ValidationFieldMapping.new(name, input_columns, &mapping_behavior)
30
+ end
31
+
32
+ def default_value(output_field, &mapping_behavior)
33
+ validate_unique_mapping([], output_field)
34
+ @default_values[output_field] = Topographer::Importer::Mapper::DefaultFieldMapping.new(output_field, &mapping_behavior)
35
+ end
36
+
37
+ def key_field(output_field)
38
+ validate_key_field(output_field)
39
+ @key_fields << output_field
40
+ end
41
+
42
+ def ignored_column(input_column)
43
+ validate_unique_column_mapping_type(input_column, ignored: true)
44
+ @ignored_mappings[input_column] = Topographer::Importer::Mapper::IgnoredFieldMapping.new(input_column)
45
+ end
46
+ end
@@ -0,0 +1,46 @@
1
+ module Topographer::Importer::Mapper::MappingColumns
2
+ def output_fields
3
+ (required_mappings.merge(optional_mappings).merge(default_values)).values.map(&:output_field)
4
+ end
5
+
6
+ def required_input_columns
7
+ (required_mapping_columns + validation_mapping_columns).uniq
8
+ end
9
+
10
+ def input_columns
11
+ (required_mapping_columns + optional_mapping_columns + validation_mapping_columns).uniq
12
+ end
13
+
14
+ def default_fields
15
+ default_values.keys
16
+ end
17
+
18
+ def validation_mapping_columns
19
+ validation_mappings.values.flat_map(&:input_columns)
20
+ end
21
+
22
+ def ignored_mapping_columns
23
+ ignored_mappings.values.flat_map(&:input_columns)
24
+ end
25
+
26
+ def optional_mapping_columns
27
+ optional_mappings.values.flat_map(&:input_columns)
28
+ end
29
+
30
+ def required_mapping_columns
31
+ required_mappings.values.flat_map(&:input_columns)
32
+ end
33
+
34
+ private
35
+ def mapped_input_columns
36
+ required_mapping_columns + optional_mapping_columns + ignored_mapping_columns + validation_mapping_columns
37
+ end
38
+
39
+ def mappings
40
+ required_mappings.merge(optional_mappings).merge(ignored_mappings).merge(default_values)
41
+ end
42
+
43
+ def non_ignored_columns
44
+ required_mappings.merge(optional_mappings)
45
+ end
46
+ end
@@ -0,0 +1,40 @@
1
+ module Topographer::Importer::Mapper::MappingValidator
2
+
3
+ def validate_unique_validation_name(name)
4
+ raise Topographer::InvalidMappingError, "A validation already exists with the name `#{name}`" if validation_mappings.has_key?(name)
5
+ end
6
+
7
+ def validate_unique_output_mapping(output_field)
8
+ if output_fields.include?(output_field)
9
+ raise Topographer::InvalidMappingError, 'Output column already mapped.'
10
+ end
11
+ end
12
+
13
+ def validate_unique_column_mapping_type(mapping_input_columns, options = {})
14
+ ignored = options.fetch(:ignored, false)
15
+ mapping_input_columns = Array(mapping_input_columns)
16
+ mapping_input_columns.each do |col|
17
+ if ignored && ((input_columns + ignored_mapping_columns).include?(col))
18
+ raise Topographer::InvalidMappingError, 'Input column already mapped to an output column.'
19
+ elsif (ignored_mapping_columns.include?(col))
20
+ raise Topographer::InvalidMappingError, 'Input column already ignored.'
21
+ end
22
+ end
23
+ end
24
+
25
+ def validate_unique_mapping(mapping_input_columns, output_field)
26
+ if (output_field.is_a?(Array))
27
+ raise Topographer::InvalidMappingError, 'One to many mapping is not supported'
28
+ end
29
+ validate_unique_column_mapping_type(mapping_input_columns)
30
+ validate_unique_output_mapping(output_field)
31
+ end
32
+
33
+ def validate_key_field(field)
34
+ if field.is_a?(Array)
35
+ raise Topographer::InvalidMappingError, 'One to many mapping is not supported'
36
+ elsif key_fields.include?(field)
37
+ raise Topographer::InvalidMappingError, "Field `#{field}` has already been included as a key"
38
+ end
39
+ end
40
+ end
@@ -1,161 +1,68 @@
1
1
  class Topographer::Importer::Mapper
2
+ require_relative 'mapper/mapping_validator'
3
+ require_relative 'mapper/mapping_columns'
4
+ require_relative 'mapper/mapper_builder'
2
5
  require_relative 'mapper/field_mapping'
3
6
  require_relative 'mapper/ignored_field_mapping'
4
7
  require_relative 'mapper/validation_field_mapping'
5
8
  require_relative 'mapper/default_field_mapping'
6
9
  require_relative 'mapper/result'
7
10
 
8
- attr_reader :bad_columns, :missing_columns, :model_class, :key_fields
11
+ include Topographer::Importer::Mapper::MappingColumns
12
+
13
+ attr_reader :required_mappings, :optional_mappings, :ignored_mappings, :validation_mappings,
14
+ :default_values, :key_fields, :bad_columns, :missing_columns, :model_class, :key_fields
9
15
 
10
16
  def self.build_mapper(model_class)
11
- mapper = self.new(model_class)
12
- yield mapper
17
+ mapper_builder = MapperBuilder.new()
18
+ yield mapper_builder
13
19
 
14
- mapper
20
+ new(mapper_builder, model_class)
15
21
  end
16
22
 
17
- def initialize(model_class)
18
- @required_mappings = {}
19
- @optional_mappings = {}
20
- @ignored_mappings = {}
21
- @validation_mappings = {}
22
- @default_values = {}
23
- @key_fields = []
23
+ def initialize(mapper_builder, model_class)
24
+ @required_mappings = mapper_builder.required_mappings
25
+ @optional_mappings = mapper_builder.optional_mappings
26
+ @ignored_mappings = mapper_builder.ignored_mappings
27
+ @validation_mappings = mapper_builder.validation_mappings
28
+ @default_values = mapper_builder.default_values
29
+ @key_fields = mapper_builder.key_fields
24
30
  @model_class = model_class
25
31
  end
26
32
 
27
- def required_columns
28
- @required_mappings.values.flat_map(&:input_columns)
29
- end
30
-
31
- def optional_columns
32
- @optional_mappings.values.flat_map(&:input_columns)
33
- end
34
-
35
- def ignored_columns
36
- @ignored_mappings.values.flat_map(&:input_columns)
37
- end
38
-
39
- def validation_columns
40
- @validation_mappings.values.flat_map(&:input_columns)
41
- end
42
-
43
- def default_fields
44
- @default_values.keys
45
- end
46
-
47
- def input_columns
48
- required_columns + optional_columns + validation_columns
49
- end
50
-
51
- def required_input_columns
52
- required_columns + validation_columns
53
- end
54
-
55
- def output_fields
56
- (@required_mappings.merge(@optional_mappings).merge(@default_values)).values.map(&:output_field)
57
- end
58
-
59
- def required_mapping(input_columns, output_field, &mapping_behavior)
60
- validate_unique_mapping(input_columns, output_field)
61
- @required_mappings[output_field] = FieldMapping.new(true, input_columns, output_field, &mapping_behavior)
62
- end
63
-
64
- def optional_mapping(input_columns, output_field, &mapping_behavior)
65
- validate_unique_mapping(input_columns, output_field)
66
- @optional_mappings[output_field] = FieldMapping.new(false, input_columns, output_field, &mapping_behavior)
67
- end
68
-
69
- def validation_field(name, input_columns, &mapping_behavior)
70
- validate_unique_validation_name(name)
71
- @validation_mappings[name] = ValidationFieldMapping.new(name, input_columns, &mapping_behavior)
72
- end
73
-
74
- def default_value(output_field, &mapping_behavior)
75
- validate_unique_mapping([], output_field)
76
- @default_values[output_field] = DefaultFieldMapping.new(output_field, &mapping_behavior)
77
- end
78
-
79
- def key_field(output_field)
80
- validate_key_field(output_field)
81
- @key_fields << output_field
82
- end
83
-
84
- def ignored_column(input_column)
85
- validate_unique_column_mapping_type(input_column, ignored: true)
86
- @ignored_mappings[input_column] = IgnoredFieldMapping.new(input_column)
87
- end
88
-
89
- def input_structure_valid?(input_columns)
33
+ def input_structure_valid?(input_columns, options={})
34
+ ignore_unmapped_columns = options.fetch(:ignore_unmapped_columns, false)
90
35
  @bad_columns ||= input_columns - mapped_input_columns
91
36
  @missing_columns ||= required_input_columns - input_columns
92
- @bad_columns.empty? && @missing_columns.empty?
37
+
38
+ if ignore_unmapped_columns
39
+ @missing_columns.empty?
40
+ else
41
+ @bad_columns.empty? && @missing_columns.empty?
42
+ end
93
43
  end
94
44
 
95
45
  def map_input(source_data)
96
46
  mapping_result = Result.new(source_data.source_identifier)
97
47
 
98
- @validation_mappings.values.each do |validation_field_mapping|
99
- validation_field_mapping.process_input(source_data.data, mapping_result)
100
- end
48
+ if source_data.empty?
49
+ handle_no_data(mapping_result)
50
+ else
51
+ @validation_mappings.values.each do |validation_field_mapping|
52
+ validation_field_mapping.process_input(source_data.data, mapping_result)
53
+ end
101
54
 
102
- output_fields.each do |output_field|
103
- field_mapping = mappings[output_field]
104
- field_mapping.process_input(source_data.data, mapping_result)
55
+ output_fields.each do |output_field|
56
+ field_mapping = mappings[output_field]
57
+ field_mapping.process_input(source_data.data, mapping_result)
58
+ end
105
59
  end
106
60
 
107
61
  mapping_result
108
62
  end
109
63
 
110
64
  private
111
- def mapped_input_columns
112
- required_columns + optional_columns + ignored_columns + validation_columns
113
- end
114
-
115
- def mappings
116
- @required_mappings.merge(@optional_mappings).merge(@ignored_mappings).merge(@default_values)
117
- end
118
-
119
- def non_ignored_columns
120
- @required_mappings.merge(@optional_mappings)
121
- end
122
-
123
- def validate_key_field(field)
124
- if field.is_a?(Array)
125
- raise Topographer::InvalidMappingError, 'One to many mapping is not supported'
126
- elsif @key_fields.include?(field)
127
- raise Topographer::InvalidMappingError, "Field `#{field}` has already been included as a key"
128
- end
129
- end
130
-
131
- def validate_unique_mapping(input_columns, output_field)
132
- if(output_field.is_a?(Array))
133
- raise Topographer::InvalidMappingError, 'One to many mapping is not supported'
134
- end
135
- validate_unique_column_mapping_type(input_columns)
136
- validate_unique_output_mapping(output_field)
137
- end
138
-
139
- def validate_unique_column_mapping_type(mapping_input_columns, options = {})
140
- ignored = options.fetch(:ignored, false)
141
- mapping_input_columns = Array(mapping_input_columns)
142
- mapping_input_columns.each do |col|
143
- if ignored && ((input_columns + ignored_columns).include?(col))
144
- raise Topographer::InvalidMappingError, 'Input column already mapped to an output column.'
145
- elsif(ignored_columns.include?(col))
146
- raise Topographer::InvalidMappingError, 'Input column already ignored.'
147
- end
148
- end
65
+ def handle_no_data(mapping_result)
66
+ mapping_result.add_error('EmptyRow', 'Unable to import empty row.')
149
67
  end
150
-
151
- def validate_unique_output_mapping(output_field)
152
- if output_fields.include?(output_field)
153
- raise Topographer::InvalidMappingError, 'Output column already mapped.'
154
- end
155
- end
156
-
157
- def validate_unique_validation_name(name)
158
- raise Topographer::InvalidMappingError, "A validation already exists with the name `#{name}`" if @validation_mappings.has_key?(name)
159
- end
160
-
161
68
  end
@@ -13,15 +13,18 @@ class Topographer::Importer
13
13
  end
14
14
 
15
15
  def self.import_data(input, import_class, strategy_class, logger, options = {})
16
- dry_run = options.fetch(:dry_run, false)
17
- importer = new(input, import_class, strategy_class, logger, dry_run)
16
+ importer = new(input, import_class, strategy_class, logger, options)
18
17
  importer.logger
19
18
  end
20
19
 
21
- def initialize(input, import_class, strategy_class, logger, dry_run)
20
+ def initialize(input, import_class, strategy_class, logger, options = {})
22
21
  @logger = logger
22
+
23
+ dry_run = options.fetch(:dry_run, false)
24
+ ignore_unmapped_columns = options.fetch(:ignore_unmapped_columns, false)
25
+
23
26
  mapper = import_class.get_mapper(strategy_class)
24
- valid_header = mapper.input_structure_valid?(input.get_header)
27
+ valid_header = mapper.input_structure_valid?(input.get_header, ignore_unmapped_columns: ignore_unmapped_columns)
25
28
 
26
29
  if valid_header
27
30
  strategy = strategy_class.new(mapper)
@@ -1,3 +1,3 @@
1
1
  module Topographer
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -115,6 +115,17 @@ describe Topographer::Importer do
115
115
  expect(import_log.fatal_errors.first.message).
116
116
  to match(/Invalid Input Header.+Missing Columns:\s+Field2.+Invalid Columns:\s+BadCol1.+BadCol2/)
117
117
  end
118
+
119
+ it 'does import data with umapped columns when ignoring unmapped columns' do
120
+ extra_column_input = input
121
+ extra_column_input.stub(:get_header) { %w(Field1 Field2 Field3 UnknownField1) }
122
+
123
+ import_log = Topographer::Importer.import_data(extra_column_input, model_class, strategy_class, simple_logger, ignore_unmapped_columns: true)
124
+
125
+ expect(import_log.fatal_error?).to be_false
126
+ expect(import_log.total_imports).to be 4
127
+ expect(import_log.successful_imports).to be 3
128
+ end
118
129
  end
119
130
  describe '.build_mapper' do
120
131
  it 'returns a mapper with the defined mappings' do
@@ -124,9 +135,9 @@ describe Topographer::Importer do
124
135
  mapping.optional_mapping 'Field3', 'field_3'
125
136
  mapping.ignored_column 'IgnoredField'
126
137
  end
127
- expect(mapper.required_columns).to eql(['Field1', 'Field2'])
128
- expect(mapper.optional_columns).to eql(['Field3'])
129
- expect(mapper.ignored_columns).to eql(['IgnoredField'])
138
+ expect(mapper.required_mapping_columns).to eql(['Field1', 'Field2'])
139
+ expect(mapper.optional_mapping_columns).to eql(['Field3'])
140
+ expect(mapper.ignored_mapping_columns).to eql(['IgnoredField'])
130
141
  end
131
142
  end
132
143
  end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe Topographer::Importer::Input::SourceData do
4
+
5
+ let(:with_no_data) do
6
+ Topographer::Importer::Input::SourceData.new("foo", {})
7
+ end
8
+
9
+ let(:with_data) do
10
+ Topographer::Importer::Input::SourceData.new("foo", {bar: 'baz'})
11
+ end
12
+
13
+ describe '#empty?' do
14
+ it 'should return true if there is no data' do
15
+ expect(with_no_data.empty?).to be_true
16
+ end
17
+ it 'should return false if there is data' do
18
+ expect(with_data.empty?).to be_false
19
+ end
20
+ end
21
+
22
+ end
@@ -0,0 +1,131 @@
1
+ require 'spec_helper'
2
+
3
+ describe Topographer::Importer::Mapper::MapperBuilder do
4
+
5
+ let(:builder) { Topographer::Importer::Mapper::MapperBuilder.new }
6
+
7
+ describe '#required_mapping' do
8
+ it 'should add a new simple required mapping' do
9
+ builder.required_mapping('input_column1', 'output_field1')
10
+ expect(builder.required_mappings.count).to eql(1)
11
+ expect(builder.required_mappings['output_field1']).to be_an_instance_of(Topographer::Importer::Mapper::FieldMapping)
12
+ end
13
+ it 'should add a new complex required mapping' do
14
+ builder.required_mapping 'input_column1', 'output_field1' do |inputs|
15
+ 'foo'
16
+ end
17
+ expect(builder.required_mappings.count).to eql(1)
18
+ expect(builder.required_mappings['output_field1']).to be_an_instance_of(Topographer::Importer::Mapper::FieldMapping)
19
+ end
20
+ it 'should raise an error if the output field has already been mapped' do
21
+ builder.required_mapping('input_column1', 'output_field1')
22
+ expect{
23
+ builder.required_mapping('input_column2', 'output_field1')
24
+ }.to raise_error
25
+ end
26
+ end
27
+
28
+ describe '#optional_mapping' do
29
+ it 'should add a new simple optional mapping' do
30
+ builder.optional_mapping('input_column1', 'output_field1')
31
+ expect(builder.optional_mappings.count).to eql(1)
32
+ expect(builder.optional_mappings['output_field1']).to be_an_instance_of(Topographer::Importer::Mapper::FieldMapping)
33
+ end
34
+ it 'should add a new complex optional mapping' do
35
+ builder.optional_mapping 'input_column1', 'output_field1' do |inputs|
36
+ 'foo'
37
+ end
38
+ expect(builder.optional_mappings.count).to eql(1)
39
+ expect(builder.optional_mappings['output_field1']).to be_an_instance_of(Topographer::Importer::Mapper::FieldMapping)
40
+ end
41
+ it 'should raise an error if the output field has already been mapped' do
42
+ builder.optional_mapping('input_column1', 'output_field1')
43
+ expect{
44
+ builder.optional_mapping('input_column2', 'output_field1')
45
+ }.to raise_error
46
+ end
47
+ end
48
+
49
+ describe '#validation_field' do
50
+ it 'should add a new validation field mapping' do
51
+ builder.validation_field('validation_1', 'input_column1') do
52
+ return true
53
+ end
54
+ expect(builder.validation_mappings.count).to eql(1)
55
+ expect(builder.validation_mappings['validation_1']).to be_an_instance_of(Topographer::Importer::Mapper::ValidationFieldMapping)
56
+ end
57
+ it 'should raise an error if there is no behavior block provided' do
58
+ expect {
59
+ builder.validation_field('validation_1', 'input_column1')
60
+ }.to raise_error
61
+ end
62
+ it 'should raise an error if a validation mapping already exists with a given name' do
63
+ builder.validation_field('validation_1', 'input_column1') do
64
+ return true
65
+ end
66
+ expect {
67
+ builder.validation_field('validation_1', 'input_column1') do
68
+ return true
69
+ end
70
+ }.to raise_error
71
+ end
72
+ end
73
+
74
+ describe '#default_value' do
75
+ it 'should add a new default value mapping' do
76
+ builder.default_value('output_field1') do
77
+ return true
78
+ end
79
+ expect(builder.default_values.count).to eql(1)
80
+ expect(builder.default_values['output_field1']).to be_an_instance_of(Topographer::Importer::Mapper::DefaultFieldMapping)
81
+ end
82
+ it 'should raise an error if there is no behavior block provided' do
83
+ expect {
84
+ builder.default_value('output_field1')
85
+ }.to raise_error
86
+ end
87
+ it 'should raise an error if a default value mapping already exists for a column' do
88
+ builder.default_value('output_field1') do
89
+ return true
90
+ end
91
+ expect {
92
+ builder.default_value('output_field1') do
93
+ return true
94
+ end
95
+ }.to raise_error
96
+ end
97
+ end
98
+
99
+ describe '#key_field' do
100
+ it 'should add a new key field mapping' do
101
+ builder.key_field('output_field1')
102
+ expect(builder.key_fields.count).to eql(1)
103
+ expect(builder.key_fields.first).to eql('output_field1')
104
+ end
105
+ it 'should raise an error if a default value mapping already exists for a column' do
106
+ builder.key_field('output_field1')
107
+ expect {
108
+
109
+ builder.key_field('output_field1')
110
+ }.to raise_error
111
+ end
112
+ end
113
+
114
+ describe '#ignored_column' do
115
+ it 'should add a new ignored column' do
116
+ builder.ignored_column('column1')
117
+ expect(builder.ignored_mappings.count).to eql(1)
118
+ expect(builder.ignored_mappings['column1']).to be_an_instance_of(Topographer::Importer::Mapper::IgnoredFieldMapping)
119
+ end
120
+ it 'should raise an error if the column has already been ignored or added as an input' do
121
+ builder.ignored_column('column1')
122
+ builder.required_mapping('column2', 'field1')
123
+ expect {
124
+ builder.ignored_column('column1')
125
+ }.to raise_error
126
+ expect {
127
+ builder.ignored_column('column2')
128
+ }.to raise_error
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+ require 'ostruct'
3
+
4
+ class MockMapping
5
+ include Topographer::Importer::Mapper::MappingColumns
6
+
7
+ attr_reader :required_mappings, :optional_mappings, :ignored_mappings,
8
+ :validation_mappings, :default_values, :key_fields
9
+
10
+
11
+ def initialize
12
+ @required_mappings = {
13
+ 'field1' => OpenStruct.new(output_field: 'field1',
14
+ input_columns: ['column1', 'column2']
15
+ ),
16
+ 'field2' => OpenStruct.new(output_field: 'field2',
17
+ input_columns: ['column3']
18
+ )
19
+ }
20
+ @optional_mappings = {
21
+ 'field3' => OpenStruct.new(output_field: 'field3',
22
+ input_columns: ['column4', 'column5']
23
+ ),
24
+ 'field4' => OpenStruct.new(output_field: 'field4',
25
+ input_columns: ['column8']
26
+ )
27
+ }
28
+ @default_values = {
29
+ 'field5' => OpenStruct.new(output_field: 'field5')
30
+ }
31
+ @validation_mappings = {
32
+ 'validation1' => OpenStruct.new(input_columns: ['column1', 'column2']),
33
+ 'validation2' => OpenStruct.new(input_columns: 'column6')
34
+ }
35
+ @ignored_mappings = {
36
+ 'column4' => OpenStruct.new(input_columns: 'column4'),
37
+ 'column5' => OpenStruct.new(input_columns: 'column5')
38
+ }
39
+ end
40
+ end
41
+
42
+ describe Topographer::Importer::Mapper::MappingColumns do
43
+
44
+ let(:mapping) { MockMapping.new }
45
+
46
+ describe '#output_fields' do
47
+ it 'should return an array of all fields that are required, optional, or have default values' do
48
+ expect(mapping.output_fields).to eql(['field1', 'field2', 'field3', 'field4', 'field5'])
49
+ end
50
+ end
51
+ describe '#required_mapping_columns' do
52
+ it 'returns an array of the required input column names' do
53
+ expect(mapping.required_mapping_columns).to eql(['column1', 'column2', 'column3'])
54
+ end
55
+ end
56
+ describe '#optional_mapping_columns' do
57
+ it 'returns an array of the optional input column names' do
58
+ expect(mapping.optional_mapping_columns).to eql(['column4', 'column5', 'column8'])
59
+ end
60
+ end
61
+ describe '#ignored_mapping_columns' do
62
+ it 'returns an array of the ignored input column names' do
63
+ expect(mapping.ignored_mapping_columns).to eql(['column4', 'column5'])
64
+ end
65
+ end
66
+ describe '#validation_mapping_columns' do
67
+ it 'returns an array of the validation mapping input columns' do
68
+ expect(mapping.validation_mapping_columns).to eql(['column1', 'column2', 'column6'])
69
+ end
70
+ end
71
+ describe '#required_input_columns' do
72
+ it 'should return an array of the required and validation columns' do
73
+ expect(mapping.required_input_columns).to eql(['column1', 'column2', 'column3', 'column6'])
74
+ end
75
+ end
76
+ describe '#input_columns' do
77
+ it 'should return an array of the required, validation, and optional columns' do
78
+ expect(mapping.input_columns).to eql(['column1', 'column2', 'column3', 'column4', 'column5', 'column8', 'column6'])
79
+ end
80
+ end
81
+ describe '#default_fields' do
82
+ it 'should return all the fields given a default value' do
83
+ expect(mapping.default_fields).to eql(['field5'])
84
+ end
85
+ end
86
+
87
+ end
@@ -0,0 +1,121 @@
1
+ require 'spec_helper'
2
+
3
+ class MockValidator
4
+ include Topographer::Importer::Mapper::MappingValidator
5
+
6
+ attr_reader :required_mappings, :optional_mappings, :ignored_mappings,
7
+ :validation_mappings, :default_values, :key_fields,
8
+ :output_fields, :input_columns, :ignored_mapping_columns
9
+
10
+ def initialize
11
+ @validation_mappings = {
12
+ 'Field1' => {},
13
+ 'Field2' => {}
14
+ }
15
+ @output_fields = %w(output_field1 output_field2)
16
+ @input_columns = %w(input_column1 input_column2)
17
+ @ignored_mapping_columns = %w(ignored_column1 ignored_column2)
18
+ @key_fields = %w(key_field1)
19
+ end
20
+
21
+ end
22
+
23
+ describe Topographer::Importer::Mapper::MappingValidator do
24
+
25
+ let(:validator) do
26
+ MockValidator.new
27
+ end
28
+
29
+ describe '#validate_unique_validation_name' do
30
+ it 'should not raise an error if a name is not in the validation list' do
31
+ expect {
32
+ validator.validate_unique_validation_name('unique_field_name_37')
33
+ }.not_to raise_error
34
+ end
35
+ it 'should raise an error if a name is in the validation list' do
36
+ expect {
37
+ validator.validate_unique_validation_name('Field1')
38
+ }.to raise_error
39
+ end
40
+ end
41
+
42
+ describe '#validate_unique_output_mapping' do
43
+ it 'should not raise an error if a field is not already an output field' do
44
+ expect {
45
+ validator.validate_unique_output_mapping('unique_field_37')
46
+ }.not_to raise_error
47
+ end
48
+ it 'should raise an error if a field is already an output field' do
49
+ expect {
50
+ validator.validate_unique_output_mapping('output_field2')
51
+ }.to raise_error
52
+ end
53
+ end
54
+
55
+ describe '#validate_unique_column_mapping_type' do
56
+ it 'should not raise an error if a field is not already mapped' do
57
+ expect {
58
+ validator.validate_unique_column_mapping_type('input_column3')
59
+ }.not_to raise_error
60
+ end
61
+ it 'should not raise an error if a field is already mapped but is not ignored' do
62
+ expect {
63
+ validator.validate_unique_column_mapping_type('input_column2')
64
+ }.not_to raise_error
65
+ end
66
+ it 'should raise an error if a field is already ignored' do
67
+ expect {
68
+ validator.validate_unique_column_mapping_type('ignored_column1')
69
+ }.to raise_error
70
+ end
71
+ it 'should raise an error when validating an ignored column that has already been mapped' do
72
+ expect {
73
+ validator.validate_unique_column_mapping_type('input_column1', ignored: true)
74
+ }.to raise_error
75
+ expect {
76
+ validator.validate_unique_column_mapping_type('ignored_column1', ignored: true)
77
+ }.to raise_error
78
+ end
79
+ end
80
+
81
+ describe '#validate_unique_mapping' do
82
+ it 'should not raise an error if a new mapping has a unique output field' do
83
+ expect {
84
+ validator.validate_unique_mapping('input_column2', 'output_field3')
85
+ }.not_to raise_error
86
+ end
87
+ it 'should raise an error if a new mapping does not have a unique output field' do
88
+ expect {
89
+ validator.validate_unique_mapping('input_column2', 'output_field2')
90
+ }.to raise_error
91
+ end
92
+ it 'should raise an error if a new mapping includes an already ignored column' do
93
+ expect {
94
+ validator.validate_unique_mapping('ignored_column2', 'output_field2')
95
+ }.to raise_error
96
+ end
97
+ end
98
+ it 'should raise an error if a new mapping includes many output fields' do
99
+ expect {
100
+ validator.validate_unique_mapping('ignored_column2', %w(output_field2 output_field3))
101
+ }.to raise_error
102
+ end
103
+
104
+ describe '#validate_key_field' do
105
+ it 'should raise an error if a new key field includes multiple fields' do
106
+ expect {
107
+ validator.validate_key_field(%w(output_field2 output_field3))
108
+ }.to raise_error
109
+ end
110
+ it 'should raise an error if a key field is duplicated' do
111
+ expect {
112
+ validator.validate_key_field('key_field1')
113
+ }.to raise_error
114
+ end
115
+ it 'should not raise an error if a key field is not already mapped' do
116
+ expect {
117
+ validator.validate_key_field('key_field2')
118
+ }.not_to raise_error
119
+ end
120
+ end
121
+ end
@@ -7,14 +7,14 @@ describe Topographer::Importer::Mapper do
7
7
  mapper = Topographer::Importer::Mapper.build_mapper(Object) do |m|
8
8
  m.required_mapping 'Field1', 'field_1'
9
9
  end
10
- mapper.required_columns.should include("Field1")
10
+ mapper.required_mapping_columns.should include("Field1")
11
11
  mapper.output_fields.should include('field_1')
12
12
  end
13
13
  it 'can require a many to one field mapping' do
14
14
  mapper = Topographer::Importer::Mapper.build_mapper(Object) do |m|
15
15
  m.required_mapping ['Field1', 'Field2'], 'field_1'
16
16
  end
17
- mapper.required_columns.should include("Field1", "Field2")
17
+ mapper.required_mapping_columns.should include("Field1", "Field2")
18
18
  mapper.output_fields.should include('field_1')
19
19
  end
20
20
  it 'cannot require a one to many field mapping' do
@@ -29,14 +29,14 @@ describe Topographer::Importer::Mapper do
29
29
  mapper = Topographer::Importer::Mapper.build_mapper(Object) do |m|
30
30
  m.optional_mapping 'Field1', 'field_1'
31
31
  end
32
- mapper.optional_columns.should include("Field1")
32
+ mapper.optional_mapping_columns.should include("Field1")
33
33
  mapper.output_fields.should include('field_1')
34
34
  end
35
35
  it 'can create an optional many to one field mapping' do
36
36
  mapper = Topographer::Importer::Mapper.build_mapper(Object) do |m|
37
37
  m.optional_mapping ['Field1', 'Field2'], 'field_1'
38
38
  end
39
- mapper.optional_columns.should include("Field1", "Field2")
39
+ mapper.optional_mapping_columns.should include("Field1", "Field2")
40
40
  mapper.output_fields.should include('field_1')
41
41
  end
42
42
  it 'cannot create an optional one to many field mapping' do
@@ -51,7 +51,7 @@ describe Topographer::Importer::Mapper do
51
51
  mapper = Topographer::Importer::Mapper.build_mapper(Object) do |m|
52
52
  m.ignored_column 'Field1'
53
53
  end
54
- mapper.ignored_columns.should include('Field1')
54
+ mapper.ignored_mapping_columns.should include('Field1')
55
55
  mapper.output_fields.should be_empty
56
56
  end
57
57
 
@@ -84,7 +84,7 @@ describe Topographer::Importer::Mapper do
84
84
  raise 'No Input' unless input
85
85
  end
86
86
  end
87
- expect(mapper.validation_columns).to include('Field1')
87
+ expect(mapper.validation_mapping_columns).to include('Field1')
88
88
  expect(mapper.output_fields.empty?).to be_true
89
89
  end
90
90
  it 'can create a multicolumn validation' do
@@ -93,7 +93,7 @@ describe Topographer::Importer::Mapper do
93
93
  raise 'No Input' unless input
94
94
  end
95
95
  end
96
- expect(mapper.validation_columns).to eql(['Field1', 'Field2'])
96
+ expect(mapper.validation_mapping_columns).to eql(['Field1', 'Field2'])
97
97
  expect(mapper.output_fields.empty?).to be_true
98
98
  end
99
99
  it 'raises an error if a validation name is repeated' do
@@ -133,6 +133,32 @@ describe Topographer::Importer::Mapper do
133
133
  end
134
134
  end }.to raise_error(Topographer::InvalidMappingError)
135
135
  end
136
+
137
+
138
+ end
139
+
140
+ describe 'key field mappings' do
141
+ it 'should add a key field to the list of key fields' do
142
+ mapper = Topographer::Importer::Mapper.build_mapper(Object) do |m|
143
+ m.key_field 'Field1'
144
+ end
145
+ expect(mapper.key_fields).to eql(['Field1'])
146
+ end
147
+ it 'should not allow multiple key fields at one time' do
148
+ expect {
149
+ mapper = Topographer::Importer::Mapper.build_mapper(Object) do |m|
150
+ m.key_field ['Field1', 'Field2']
151
+ end
152
+ }.to raise_error(Topographer::InvalidMappingError)
153
+ end
154
+ it 'should not allow the same key field more than once' do
155
+ expect {
156
+ mapper = Topographer::Importer::Mapper.build_mapper(Object) do |m|
157
+ m.key_field 'Field1'
158
+ m.key_field 'Field1'
159
+ end
160
+ }.to raise_error(Topographer::InvalidMappingError)
161
+ end
136
162
  end
137
163
 
138
164
  it 'associates the model class with the mapper instance' do
@@ -144,25 +170,6 @@ describe Topographer::Importer::Mapper do
144
170
  end
145
171
  end
146
172
 
147
- describe '#key_field' do
148
- let(:mapper) { Topographer::Importer::Mapper.new(Object) }
149
- it 'should add a key field to the list of key fields' do
150
- mapper.key_field 'Field1'
151
- expect(mapper.key_fields).to eql(['Field1'])
152
- end
153
- it 'should not allow multiple key fields at one time' do
154
- expect {
155
- mapper.key_field ['Field1', 'Field2']
156
- }.to raise_error(Topographer::InvalidMappingError)
157
- end
158
- it 'should not allow the same key field more than once' do
159
- expect {
160
- mapper.key_field 'Field1'
161
- mapper.key_field 'Field1'
162
- }.to raise_error(Topographer::InvalidMappingError)
163
- end
164
- end
165
-
166
173
  describe '#input_structure_valid?' do
167
174
  let(:mapper) do
168
175
  Topographer::Importer::Mapper.build_mapper(Object) do |m|
@@ -178,7 +185,8 @@ describe Topographer::Importer::Mapper do
178
185
  let(:valid_input_structure_without_options) { ['Field1', 'Field2', 'Field4'] }
179
186
  let(:missing_required_column_structure) { ['Field1', 'Field3'] }
180
187
  let(:missing_validation_column_structure) { ['Field1', 'Field2', 'Field3'] }
181
- let(:bad_column_structure) { ['Field1', 'UnknownField', 'Field2', 'Field4'] }
188
+ let(:bad_column_structure) { ['Field1', 'UnknownField', 'Field4'] }
189
+ let(:unmapped_column_structure) {['Field1', 'Field2', 'Field3', 'Field4', 'UnmappedField'] }
182
190
 
183
191
  it 'returns false if required fields are missing' do
184
192
  expect(mapper.input_structure_valid?(missing_required_column_structure)).to be_false
@@ -196,8 +204,18 @@ describe Topographer::Importer::Mapper do
196
204
  expect(mapper.input_structure_valid?(valid_input_structure_with_options)).to be_true
197
205
  expect(mapper.input_structure_valid?(valid_input_structure_with_options+['Field5'])).to be_true
198
206
  end
199
- it 'returns false if there are any extra fields that have not been ignored' do
200
- mapper.input_structure_valid?(bad_column_structure).should be_false
207
+ context 'not ignoring unmapped columns' do
208
+ it 'returns false if there are any extra fields that have not been ignored' do
209
+ expect(mapper.input_structure_valid?(bad_column_structure)).to be_false
210
+ end
211
+ end
212
+ context 'ignoring unmapped columns' do
213
+ it 'returns false if there are any extra fields that have not been ignored and required fields are missing' do
214
+ expect(mapper.input_structure_valid?(bad_column_structure, ignore_unmapped_columns: true)).to be_false
215
+ end
216
+ it 'returns true if there are any extra fields that have not been ignored but all required fields are present' do
217
+ expect(mapper.input_structure_valid?(unmapped_column_structure, ignore_unmapped_columns: true)).to be_true
218
+ end
201
219
  end
202
220
  end
203
221
 
@@ -255,7 +273,8 @@ describe Topographer::Importer::Mapper do
255
273
  source_identifier: 'row1',
256
274
  data: {'Field1' => 'datum1',
257
275
  'Field2' => 'datum2',
258
- 'Field3' => 6}
276
+ 'Field3' => 6},
277
+ empty?: false
259
278
  end
260
279
 
261
280
  let(:invalid_data_input) do
@@ -263,14 +282,23 @@ describe Topographer::Importer::Mapper do
263
282
  source_identifier: 'row1',
264
283
  data: {'Field1' => 'datum1',
265
284
  'Field2' => 'bad_field2_data',
266
- 'Field3' => 6}
285
+ 'Field3' => 6},
286
+ empty?: false
267
287
  end
268
288
 
269
289
  let(:missing_field_input) do
270
290
  double 'SourceData',
271
291
  source_identifier: 'row1',
272
292
  data: {'Field1' => 'datum1',
273
- 'Field2' => 'datum2'}
293
+ 'Field2' => 'datum2'},
294
+ empty?: false
295
+ end
296
+
297
+ let(:empty_input) do
298
+ double 'SourceData',
299
+ source_identifier: 'row1',
300
+ data: {},
301
+ empty?: true
274
302
  end
275
303
 
276
304
  let(:result) do
@@ -314,5 +342,11 @@ describe Topographer::Importer::Mapper do
314
342
  it 'does not return an error if an optional field is missing in the input data' do
315
343
  expect(result.errors?).to be_false
316
344
  end
345
+
346
+ it 'returns a `blank row` error if an entire row is blank' do
347
+ empty_result = mapper.map_input(empty_input)
348
+ expect(empty_result.errors?).to be_true
349
+ expect(empty_result.errors['EmptyRow']).to include('empty row')
350
+ end
317
351
  end
318
352
  end
@@ -9,12 +9,14 @@ describe Topographer::Importer::Strategy::CreateOrUpdateRecord do
9
9
  double 'Data',
10
10
  source_identifier: 'record',
11
11
  data: {'Field1' => 'datum1',
12
- 'Field2' => 'datum2'}
12
+ 'Field2' => 'datum2'},
13
+ empty?: false
13
14
  end
14
15
  let(:invalid_input) do
15
16
  double 'Data',
16
17
  source_identifier: 'bad record',
17
- data: {'Field1' => 'datum1'}
18
+ data: {'Field1' => 'datum1'},
19
+ empty?: false
18
20
  end
19
21
 
20
22
 
@@ -27,7 +27,8 @@ describe Topographer::Importer::Strategy::ImportNewRecord do
27
27
  double 'Data',
28
28
  source_identifier: 'record',
29
29
  data: {'Field1' => 'datum1',
30
- 'Field2' => 'datum2'}
30
+ 'Field2' => 'datum2'},
31
+ empty?: false
31
32
  end
32
33
 
33
34
  describe '#initialize' do
@@ -9,12 +9,14 @@ describe Topographer::Importer::Strategy::UpdateRecord do
9
9
  double 'Data',
10
10
  source_identifier: 'record',
11
11
  data: {'Field1' => 'datum1',
12
- 'Field2' => 'datum2'}
12
+ 'Field2' => 'datum2'},
13
+ empty?: false
13
14
  end
14
15
  let(:invalid_input) do
15
16
  double 'Data',
16
17
  source_identifier: 'bad record',
17
- data: {'Field1' => 'datum1'}
18
+ data: {'Field1' => 'datum1'},
19
+ empty?: false
18
20
  end
19
21
 
20
22
  describe '#import_record' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: topographer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Simpson
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-02-11 00:00:00.000000000 Z
12
+ date: 2014-02-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -76,6 +76,7 @@ extensions: []
76
76
  extra_rdoc_files: []
77
77
  files:
78
78
  - .gitignore
79
+ - .travis.yml
79
80
  - Gemfile
80
81
  - LICENSE
81
82
  - LICENSE.txt
@@ -100,6 +101,9 @@ files:
100
101
  - lib/Topographer/importer/mapper/default_field_mapping.rb
101
102
  - lib/Topographer/importer/mapper/field_mapping.rb
102
103
  - lib/Topographer/importer/mapper/ignored_field_mapping.rb
104
+ - lib/Topographer/importer/mapper/mapper_builder.rb
105
+ - lib/Topographer/importer/mapper/mapping_columns.rb
106
+ - lib/Topographer/importer/mapper/mapping_validator.rb
103
107
  - lib/Topographer/importer/mapper/result.rb
104
108
  - lib/Topographer/importer/mapper/validation_field_mapping.rb
105
109
  - lib/Topographer/importer/strategy.rb
@@ -110,23 +114,27 @@ files:
110
114
  - lib/Topographer/importer/strategy/update_record.rb
111
115
  - lib/Topographer/version.rb
112
116
  - lib/topographer.rb
113
- - spec/Cartographer/importer/helpers/write_log_to_csv_spec.rb
114
- - spec/Cartographer/importer/helpers_spec.rb
115
- - spec/Cartographer/importer/importable_spec.rb
116
- - spec/Cartographer/importer/importer_spec.rb
117
- - spec/Cartographer/importer/logger/base_spec.rb
118
- - spec/Cartographer/importer/logger/fatal_error_entry_spec.rb
119
- - spec/Cartographer/importer/logger/simple_spec.rb
120
- - spec/Cartographer/importer/mapper/default_field_mapping_spec.rb
121
- - spec/Cartographer/importer/mapper/field_mapping_spec.rb
122
- - spec/Cartographer/importer/mapper/validation_field_mapping_spec.rb
123
- - spec/Cartographer/importer/mapper_spec.rb
124
- - spec/Cartographer/importer/strategy/base_spec.rb
125
- - spec/Cartographer/importer/strategy/create_or_update_record_spec.rb
126
- - spec/Cartographer/importer/strategy/import_new_records_spec.rb
127
- - spec/Cartographer/importer/strategy/import_status_spec.rb
128
- - spec/Cartographer/importer/strategy/mapped_model.rb
129
- - spec/Cartographer/importer/strategy/update_record_spec.rb
117
+ - spec/Topographer/importer/helpers/write_log_to_csv_spec.rb
118
+ - spec/Topographer/importer/helpers_spec.rb
119
+ - spec/Topographer/importer/importable_spec.rb
120
+ - spec/Topographer/importer/importer_spec.rb
121
+ - spec/Topographer/importer/input/source_data_spec.rb
122
+ - spec/Topographer/importer/logger/base_spec.rb
123
+ - spec/Topographer/importer/logger/fatal_error_entry_spec.rb
124
+ - spec/Topographer/importer/logger/simple_spec.rb
125
+ - spec/Topographer/importer/mapper/default_field_mapping_spec.rb
126
+ - spec/Topographer/importer/mapper/field_mapping_spec.rb
127
+ - spec/Topographer/importer/mapper/mapper_builder_spec.rb
128
+ - spec/Topographer/importer/mapper/mapping_columns_spec.rb
129
+ - spec/Topographer/importer/mapper/mapping_validator_spec.rb
130
+ - spec/Topographer/importer/mapper/validation_field_mapping_spec.rb
131
+ - spec/Topographer/importer/mapper_spec.rb
132
+ - spec/Topographer/importer/strategy/base_spec.rb
133
+ - spec/Topographer/importer/strategy/create_or_update_record_spec.rb
134
+ - spec/Topographer/importer/strategy/import_new_records_spec.rb
135
+ - spec/Topographer/importer/strategy/import_status_spec.rb
136
+ - spec/Topographer/importer/strategy/mapped_model.rb
137
+ - spec/Topographer/importer/strategy/update_record_spec.rb
130
138
  - spec/spec_helper.rb
131
139
  - topographer.gemspec
132
140
  homepage: ''
@@ -155,22 +163,26 @@ specification_version: 4
155
163
  summary: Topographer allows the mapping of columnar input data to fields for active
156
164
  record models. This facilitates importing from a variety of sources.
157
165
  test_files:
158
- - spec/Cartographer/importer/helpers/write_log_to_csv_spec.rb
159
- - spec/Cartographer/importer/helpers_spec.rb
160
- - spec/Cartographer/importer/importable_spec.rb
161
- - spec/Cartographer/importer/importer_spec.rb
162
- - spec/Cartographer/importer/logger/base_spec.rb
163
- - spec/Cartographer/importer/logger/fatal_error_entry_spec.rb
164
- - spec/Cartographer/importer/logger/simple_spec.rb
165
- - spec/Cartographer/importer/mapper/default_field_mapping_spec.rb
166
- - spec/Cartographer/importer/mapper/field_mapping_spec.rb
167
- - spec/Cartographer/importer/mapper/validation_field_mapping_spec.rb
168
- - spec/Cartographer/importer/mapper_spec.rb
169
- - spec/Cartographer/importer/strategy/base_spec.rb
170
- - spec/Cartographer/importer/strategy/create_or_update_record_spec.rb
171
- - spec/Cartographer/importer/strategy/import_new_records_spec.rb
172
- - spec/Cartographer/importer/strategy/import_status_spec.rb
173
- - spec/Cartographer/importer/strategy/mapped_model.rb
174
- - spec/Cartographer/importer/strategy/update_record_spec.rb
166
+ - spec/Topographer/importer/helpers/write_log_to_csv_spec.rb
167
+ - spec/Topographer/importer/helpers_spec.rb
168
+ - spec/Topographer/importer/importable_spec.rb
169
+ - spec/Topographer/importer/importer_spec.rb
170
+ - spec/Topographer/importer/input/source_data_spec.rb
171
+ - spec/Topographer/importer/logger/base_spec.rb
172
+ - spec/Topographer/importer/logger/fatal_error_entry_spec.rb
173
+ - spec/Topographer/importer/logger/simple_spec.rb
174
+ - spec/Topographer/importer/mapper/default_field_mapping_spec.rb
175
+ - spec/Topographer/importer/mapper/field_mapping_spec.rb
176
+ - spec/Topographer/importer/mapper/mapper_builder_spec.rb
177
+ - spec/Topographer/importer/mapper/mapping_columns_spec.rb
178
+ - spec/Topographer/importer/mapper/mapping_validator_spec.rb
179
+ - spec/Topographer/importer/mapper/validation_field_mapping_spec.rb
180
+ - spec/Topographer/importer/mapper_spec.rb
181
+ - spec/Topographer/importer/strategy/base_spec.rb
182
+ - spec/Topographer/importer/strategy/create_or_update_record_spec.rb
183
+ - spec/Topographer/importer/strategy/import_new_records_spec.rb
184
+ - spec/Topographer/importer/strategy/import_status_spec.rb
185
+ - spec/Topographer/importer/strategy/mapped_model.rb
186
+ - spec/Topographer/importer/strategy/update_record_spec.rb
175
187
  - spec/spec_helper.rb
176
188
  has_rdoc: