data_maps 0.1.0

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 (62) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +7 -0
  5. data/Gemfile +6 -0
  6. data/Gemfile.lock +48 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +264 -0
  9. data/Rakefile +9 -0
  10. data/data_maps.gemspec +27 -0
  11. data/lib/data_maps/concerns/factory.rb +31 -0
  12. data/lib/data_maps/condition.rb +81 -0
  13. data/lib/data_maps/converter/affixes.rb +35 -0
  14. data/lib/data_maps/converter/base.rb +12 -0
  15. data/lib/data_maps/converter/bool.rb +15 -0
  16. data/lib/data_maps/converter/keys.rb +23 -0
  17. data/lib/data_maps/converter/map.rb +24 -0
  18. data/lib/data_maps/converter/numeric.rb +28 -0
  19. data/lib/data_maps/converter/ruby.rb +20 -0
  20. data/lib/data_maps/converter/string.rb +15 -0
  21. data/lib/data_maps/errors/invalid_data.rb +6 -0
  22. data/lib/data_maps/executable.rb +33 -0
  23. data/lib/data_maps/filtered_value.rb +16 -0
  24. data/lib/data_maps/mapper.rb +25 -0
  25. data/lib/data_maps/mapping.rb +102 -0
  26. data/lib/data_maps/statement.rb +80 -0
  27. data/lib/data_maps/then/base.rb +12 -0
  28. data/lib/data_maps/then/convert.rb +25 -0
  29. data/lib/data_maps/then/filter.rb +16 -0
  30. data/lib/data_maps/then/set.rb +15 -0
  31. data/lib/data_maps/version.rb +3 -0
  32. data/lib/data_maps/when/base.rb +12 -0
  33. data/lib/data_maps/when/comparison.rb +99 -0
  34. data/lib/data_maps/when/empty.rb +15 -0
  35. data/lib/data_maps/when/regex.rb +23 -0
  36. data/lib/data_maps.rb +13 -0
  37. data/spec/data_maps/concerns/factory_spec.rb +54 -0
  38. data/spec/data_maps/condition_spec.rb +104 -0
  39. data/spec/data_maps/converter/affixes_spec.rb +119 -0
  40. data/spec/data_maps/converter/base_spec.rb +21 -0
  41. data/spec/data_maps/converter/bool_spec.rb +11 -0
  42. data/spec/data_maps/converter/keys_spec.rb +25 -0
  43. data/spec/data_maps/converter/map_spec.rb +45 -0
  44. data/spec/data_maps/converter/numeric_spec.rb +81 -0
  45. data/spec/data_maps/converter/ruby_spec.rb +15 -0
  46. data/spec/data_maps/converter/string_spec.rb +14 -0
  47. data/spec/data_maps/executable_spec.rb +23 -0
  48. data/spec/data_maps/filtered_value_spec.rb +12 -0
  49. data/spec/data_maps/mapper_spec.rb +38 -0
  50. data/spec/data_maps/mapping_spec.rb +192 -0
  51. data/spec/data_maps/statement_spec.rb +94 -0
  52. data/spec/data_maps/then/base_spec.rb +21 -0
  53. data/spec/data_maps/then/convert_spec.rb +28 -0
  54. data/spec/data_maps/then/filter_spec.rb +13 -0
  55. data/spec/data_maps/then/set_spec.rb +11 -0
  56. data/spec/data_maps/version_spec.rb +8 -0
  57. data/spec/data_maps/when/base_spec.rb +21 -0
  58. data/spec/data_maps/when/comparison_spec.rb +129 -0
  59. data/spec/data_maps/when/empty_spec.rb +29 -0
  60. data/spec/data_maps/when/regex_spec.rb +31 -0
  61. data/spec/spec_helper.rb +7 -0
  62. metadata +199 -0
@@ -0,0 +1,119 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMaps::Converter::Prefix do
4
+ subject { DataMaps::Converter::Prefix.new('PREFIX') }
5
+
6
+ describe '#execute' do
7
+ describe 'for Arrays' do
8
+ it 'cast all values to strings' do
9
+ data = [double(Object), double(Object)]
10
+
11
+ expect(data[0]).to receive(:to_s).and_return(String.new)
12
+ expect(data[1]).to receive(:to_s).and_return(String.new)
13
+
14
+ expect(
15
+ subject.execute(data).all?{ |x| x.is_a?(String) }
16
+ ).to be_truthy
17
+ end
18
+
19
+ it 'prefixes all values' do
20
+ expect(
21
+ subject.execute(%w[ a b c ])
22
+ ).to eq %w[ PREFIXa PREFIXb PREFIXc ]
23
+ end
24
+ end
25
+
26
+ describe 'for Hashes' do
27
+ it 'cast all values to strings' do
28
+ data = { a: double(Object), b: double(Object) }
29
+
30
+ expect(data[:a]).to receive(:to_s).and_return(String.new)
31
+ expect(data[:b]).to receive(:to_s).and_return(String.new)
32
+
33
+ expect(
34
+ subject.execute(data).all?{ |k,v| v.is_a?(String) }
35
+ ).to be_truthy
36
+ end
37
+
38
+ it 'prefixes all values' do
39
+ expect(
40
+ subject.execute({ a: 'a', b: 'b', c: 'c' })
41
+ ).to eq({ a: 'PREFIXa', b: 'PREFIXb', c: 'PREFIXc' })
42
+ end
43
+ end
44
+
45
+ describe 'for flat values' do
46
+ it 'cast value to string' do
47
+ data = double(Object)
48
+
49
+ expect(data).to receive(:to_s).and_return(String.new)
50
+ expect(subject.execute(data)).to be_a String
51
+ end
52
+
53
+ it 'prefixes the value' do
54
+ expect(
55
+ subject.execute('a')
56
+ ).to eq 'PREFIXa'
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ describe DataMaps::Converter::Postfix do
63
+ subject { DataMaps::Converter::Postfix.new('POSTFIX') }
64
+
65
+ describe '#execute' do
66
+ describe 'for Arrays' do
67
+ it 'cast all values to strings' do
68
+ data = [double(Object), double(Object)]
69
+
70
+ expect(data[0]).to receive(:to_s).and_return(String.new)
71
+ expect(data[1]).to receive(:to_s).and_return(String.new)
72
+
73
+ expect(
74
+ subject.execute(data).all?{ |x| x.is_a?(String) }
75
+ ).to be_truthy
76
+ end
77
+
78
+ it 'postfixes all values' do
79
+ expect(
80
+ subject.execute(%w[ a b c ])
81
+ ).to eq %w[ aPOSTFIX bPOSTFIX cPOSTFIX ]
82
+ end
83
+ end
84
+
85
+ describe 'for Hashes' do
86
+ it 'cast all values to strings' do
87
+ data = { a: double(Object), b: double(Object) }
88
+
89
+ expect(data[:a]).to receive(:to_s).and_return(String.new)
90
+ expect(data[:b]).to receive(:to_s).and_return(String.new)
91
+
92
+ expect(
93
+ subject.execute(data).all?{ |k,v| v.is_a?(String) }
94
+ ).to be_truthy
95
+ end
96
+
97
+ it 'postfixes all values' do
98
+ expect(
99
+ subject.execute({ a: 'a', b: 'b', c: 'c' })
100
+ ).to eq({ a: 'aPOSTFIX', b: 'bPOSTFIX', c: 'cPOSTFIX' })
101
+ end
102
+ end
103
+
104
+ describe 'for flat values' do
105
+ it 'cast value to string' do
106
+ data = double(Object)
107
+
108
+ expect(data).to receive(:to_s).and_return(String.new)
109
+ expect(subject.execute(data)).to be_a String
110
+ end
111
+
112
+ it 'postfixes the value' do
113
+ expect(
114
+ subject.execute('a')
115
+ ).to eq 'aPOSTFIX'
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMaps::Converter do
4
+ describe '::create_from_map' do
5
+ it 'creates new converter' do
6
+ mapping = { ruby: :upcase }
7
+
8
+ expect(DataMaps::Converter).to receive(:factory).with(:ruby, :upcase).and_call_original
9
+
10
+ DataMaps::Converter.create_from_map(mapping)
11
+ end
12
+ end
13
+ end
14
+
15
+ describe DataMaps::Converter::Base do
16
+ subject { DataMaps::Converter::Base.new('muh') }
17
+
18
+ it 'is an executable' do
19
+ expect(subject).to be_a DataMaps::Executable
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMaps::Converter::Bool do
4
+ describe '#execute' do
5
+ subject { DataMaps::Converter::Bool.new(true) }
6
+
7
+ it 'returns true or false' do
8
+ expect([true, false]).to include subject.execute('something')
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMaps::Converter::Keys do
4
+ describe '#execute' do
5
+ subject { DataMaps::Converter::Keys.new({ a: 'x', b: 'y', c: 'z' }) }
6
+
7
+ it 'converts the keys' do
8
+ expect(
9
+ subject.execute({ a: 1, b: 2, c: 3 })
10
+ ).to eq({ 'x' => 1, 'y' => 2, 'z' => 3 })
11
+ end
12
+
13
+ it 'does nothing with keys that doesn\'t exist in mapping' do
14
+ expect(
15
+ subject.execute({ d: 4, e: 5, f: 6 })
16
+ ).to eq({ d: 4, e: 5, f: 6 })
17
+ end
18
+
19
+ it 'does nothing with data when data isn\'t a hash' do
20
+ expect(
21
+ subject.execute('something')
22
+ ).to eq 'something'
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMaps::Converter::Map do
4
+ describe '#execute' do
5
+ subject { DataMaps::Converter::Map.new({ a: 'x', b: 'y', c: 'z' }) }
6
+
7
+ describe 'for arrays' do
8
+ it 'converts an array of data' do
9
+ expect(
10
+ subject.execute(%w[ a b c ])
11
+ ).to eq %w[ x y z ]
12
+ end
13
+
14
+ it 'returns nil when a value doesn\'t exists in map' do
15
+ expect(
16
+ subject.execute(%w[ a b c d ])
17
+ ).to eq [ 'x', 'y', 'z', nil ]
18
+ end
19
+ end
20
+
21
+ describe 'for hashes' do
22
+ it 'converts values in a data hash' do
23
+ expect(
24
+ subject.execute({ x: 'a', y: 'b', z: 'c' })
25
+ ).to eq({ x: 'x', y: 'y', z: 'z' })
26
+ end
27
+
28
+ it 'returns nil when a value doesn\'t exists in map' do
29
+ expect(
30
+ subject.execute({ x: 'a', y: 'b', z: 'c', w: 'd' })
31
+ ).to eq({ x: 'x', y: 'y', z: 'z', w: nil })
32
+ end
33
+ end
34
+
35
+ describe 'for flat values' do
36
+ it 'converts the value' do
37
+ expect(subject.execute('a')).to eq 'x'
38
+ end
39
+
40
+ it 'returns original value when value doesn\'t exists in map' do
41
+ expect(subject.execute('d')).to eq 'd'
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMaps::Converter::Numeric do
4
+ describe '#execute' do
5
+ describe 'Integer' do
6
+ subject { DataMaps::Converter::Numeric.new('Integer') }
7
+
8
+ it 'converts a float' do
9
+ expect(subject.execute(5.5)).to eq 5
10
+ end
11
+
12
+ it 'converts a float string' do
13
+ expect(subject.execute('5.5')).to eq 5
14
+ end
15
+
16
+ it 'converts a string' do
17
+ expect(subject.execute('5')).to eq 5
18
+ end
19
+
20
+ it 'raise an error if the string is not a numeric string' do
21
+ expect{ subject.execute('5,50€') }.to raise_error DataMaps::Errors::InvalidDataError
22
+ end
23
+ end
24
+
25
+ describe 'Float' do
26
+ subject { DataMaps::Converter::Numeric.new('Float') }
27
+
28
+ it 'converts an integer' do
29
+ expect(subject.execute(5)).to eq 5.0
30
+ end
31
+
32
+ it 'converts a float string' do
33
+ expect(subject.execute('5.5')).to eq 5.5
34
+ end
35
+
36
+ it 'converts a string' do
37
+ expect(subject.execute('5')).to eq 5.0
38
+ end
39
+ end
40
+
41
+ describe 'precision' do
42
+ subject { DataMaps::Converter::Numeric.new(2) }
43
+
44
+ it 'converts an integer' do
45
+ expect(subject.execute(5)).to eq 5.0
46
+ end
47
+
48
+ it 'converts a float' do
49
+ expect(subject.execute(5.128)).to eq 5.13
50
+ end
51
+
52
+ it 'converts a float string' do
53
+ expect(subject.execute('5.128')).to eq 5.13
54
+ end
55
+
56
+ it 'converts a string' do
57
+ expect(subject.execute('5')).to eq 5.0
58
+ end
59
+ end
60
+
61
+ describe 'no options' do
62
+ subject { DataMaps::Converter::Numeric.new(nil) }
63
+
64
+ it 'returns the given numeric data without any modification' do
65
+ expect(subject.execute(5)). to eq 5
66
+ end
67
+
68
+ it 'returns the given float data without any modification' do
69
+ expect(subject.execute(5.5)). to eq 5.5
70
+ end
71
+
72
+ it 'returns the given string data without any modification' do
73
+ expect(subject.execute('5')). to eq '5'
74
+ end
75
+
76
+ it 'raise an error for invalid data' do
77
+ expect{ subject.execute({ something: 'huh' }) }.to raise_error DataMaps::Errors::InvalidDataError
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMaps::Converter::Ruby do
4
+ describe '#execute' do
5
+ subject { DataMaps::Converter::Ruby.new([:my_method, 'option1', 'option2']) }
6
+
7
+ it 'applies the given method on the data' do
8
+ data = double(Object)
9
+
10
+ expect(data).to receive(:my_method).with('option1', 'option2')
11
+
12
+ subject.execute(data)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMaps::Converter::String do
4
+ describe '#execute' do
5
+ subject { DataMaps::Converter::String.new(true) }
6
+
7
+ it 'calls to_s on data' do
8
+ data = double(Object)
9
+
10
+ expect(data).to receive(:to_s).and_return(String.new)
11
+ expect(subject.execute(data)).to be_a String
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMaps::Executable do
4
+ subject { DataMaps::Executable.new('option') }
5
+
6
+ describe 'initialization' do
7
+ it 'first argument is available via option attribute reader' do
8
+ expect(subject.option).to eq 'option'
9
+ end
10
+
11
+ it 'calls the after_initialize callback' do
12
+ expect_any_instance_of(DataMaps::Executable).to receive(:after_initialize)
13
+
14
+ DataMaps::Executable.new('option')
15
+ end
16
+ end
17
+
18
+ describe '#execute' do
19
+ it 'raise an NotImplementedError' do
20
+ expect{ subject.execute('something') }.to raise_error NotImplementedError
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMaps::FilteredValue do
4
+ describe 'initialisation' do
5
+ it 'sets value' do
6
+ data = 'something'
7
+ value = DataMaps::FilteredValue.new(data)
8
+
9
+ expect(value.value).to be data
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMaps::Mapper do
4
+ it 'cant\'t be initialized without a mapping' do
5
+ expect{ DataMaps::Mapper.new }.to raise_error ArgumentError
6
+ end
7
+
8
+ it 'cant\t be initialized with an invalid mapping' do
9
+ expect{ DataMaps::Mapper.new('something') }.to raise_error ArgumentError
10
+ end
11
+
12
+ describe 'initialisation' do
13
+ it 'sets mapping' do
14
+ mapping = DataMaps::Mapping.new({})
15
+ mapper = DataMaps::Mapper.new(mapping)
16
+
17
+ expect(mapper.mapping).to be_a DataMaps::Mapping
18
+ expect(mapper.mapping).to eq mapping
19
+ end
20
+ end
21
+
22
+ describe '#convert' do
23
+ let(:mapping) { DataMaps::Mapping.new({ 'b' => 'a' }) }
24
+ let(:mapper) { DataMaps::Mapper.new(mapping) }
25
+
26
+ it 'executes mapping' do
27
+ data = { 'a' => 'x' }
28
+ expect(mapping).to receive(:execute).with(data).and_call_original
29
+ expect(mapper.convert(data)).to eq({ 'b' => 'x' })
30
+ end
31
+
32
+ it 'converts keys of the data to string keys' do
33
+ data = { a: 'x' }
34
+ expect(data).to receive(:stringify_keys).and_call_original
35
+ expect(mapper.convert(data)).to eq({ 'b' => 'x' })
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,192 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMaps::Mapping do
4
+ let(:simple_mapping_hash) do
5
+ {
6
+ 'destination1' => 'source1',
7
+ 'destination2' => 'source2'
8
+ }
9
+ end
10
+
11
+ let(:conditional_mapping_hash) do
12
+ {
13
+ 'destination1' => {
14
+ from: 'source1',
15
+ conditions: [
16
+ { when: { empty: true }, then: { filter: true } },
17
+ { when: { regex: /[a-z]/ }, then: { convert: { ruby: :upcase } } },
18
+ ]
19
+ }
20
+ }
21
+ end
22
+
23
+ let(:converter_mapping_hash) do
24
+ {
25
+ 'destination2' => {
26
+ from: %w[ source2 source3 ],
27
+ converter: {
28
+ ruby: [:join, ', '],
29
+ }
30
+ }
31
+ }
32
+ end
33
+
34
+ let(:complex_mapping_hash) do
35
+ conditional_mapping_hash.merge converter_mapping_hash
36
+ end
37
+
38
+ let(:invalid_mapping_hash) do
39
+ {
40
+ 'destination3' => {
41
+ from: 'source3',
42
+ condition: { when: 'this', then: 'that' },
43
+ converter: 'something invalid'
44
+ }
45
+ }
46
+ end
47
+
48
+ it 'cant\t be initialized without a valid mapping_hash' do
49
+ expect{ DataMaps::Mapping.new('something') }.to raise_error ArgumentError
50
+ end
51
+
52
+ describe 'compile' do
53
+ describe 'lazy compilation' do
54
+ subject{ DataMaps::Mapping.new(simple_mapping_hash) }
55
+
56
+ it 'compiles nothing if mapping is initialized' do
57
+ expect(subject.mapping).to be_empty
58
+ end
59
+
60
+ it 'compiles if calling get_statement_for' do
61
+ expect{ subject.get_statement_for('destination1') }.to change{ subject.mapping.length }.from(0).to(2)
62
+ end
63
+
64
+ it 'compiles if calling each_statement' do
65
+ expect{ subject.each_statement { |d,s| } }.to change{ subject.mapping.length }.from(0).to(2)
66
+ end
67
+ end
68
+
69
+ # Test mapping generation of a simple destination => source mapping without any conditions or converter
70
+ describe 'simple mapping hash' do
71
+ subject{ DataMaps::Mapping.new(simple_mapping_hash) }
72
+
73
+ it 'has correct destination key' do
74
+ expect{ subject.get_statement_for('destination1') }.not_to raise_error
75
+ end
76
+ it 'is a MappingStatement' do
77
+ expect(subject.get_statement_for('destination1')).to be_a DataMaps::Statement
78
+ end
79
+ it 'has the correct statement options' do
80
+ statement = subject.get_statement_for('destination1')
81
+
82
+ expect(statement.from).to eq 'source1'
83
+ expect(statement.to).to eq 'destination1'
84
+ expect(statement.conditions).to be_a Array
85
+ expect(statement.conditions).to be_empty
86
+ expect(statement.converter).to be_a Array
87
+ expect(statement.converter).to be_empty
88
+ end
89
+ end
90
+
91
+ # Test mapping generation of a mapping hash with conditions
92
+ describe 'conditional mapping hash' do
93
+ subject{ DataMaps::Mapping.new(conditional_mapping_hash) }
94
+
95
+ it 'has correct destination key' do
96
+ expect{ subject.get_statement_for('destination1') }.not_to raise_error
97
+ end
98
+ it 'is a MappingStatement' do
99
+ expect(subject.get_statement_for('destination1')).to be_a DataMaps::Statement
100
+ end
101
+ it 'has the correct statement options' do
102
+ statement = subject.get_statement_for('destination1')
103
+
104
+ expect(statement.from).to eq 'source1'
105
+ expect(statement.to).to eq 'destination1'
106
+ expect(statement.conditions).to be_a Array
107
+ expect(statement.conditions.length).to eq 2
108
+ expect(statement.conditions.all?{ |c| c.is_a?(DataMaps::Condition) }).to be_truthy
109
+ expect(statement.converter).to be_a Array
110
+ expect(statement.converter).to be_empty
111
+ end
112
+ end
113
+
114
+ # Test mapping generation of a mapping hash with converter
115
+ describe 'conditional mapping hash' do
116
+ subject{ DataMaps::Mapping.new(converter_mapping_hash) }
117
+
118
+ it 'has correct destination key' do
119
+ expect{ subject.get_statement_for('destination2') }.not_to raise_error
120
+ end
121
+ it 'is a MappingStatement' do
122
+ expect(subject.get_statement_for('destination2')).to be_a DataMaps::Statement
123
+ end
124
+ it 'has the correct statement options' do
125
+ statement = subject.get_statement_for('destination2')
126
+
127
+ expect(statement.from).to eq %w[ source2 source3 ]
128
+ expect(statement.to).to eq 'destination2'
129
+ expect(statement.conditions).to be_a Array
130
+ expect(statement.conditions).to be_empty
131
+
132
+ expect(statement.converter.length).to eq 1
133
+ expect(statement.converter.all?{ |c| c.is_a?(DataMaps::Converter::Base) }).to be_truthy
134
+ end
135
+ end
136
+ end
137
+
138
+ describe 'validation' do
139
+ it 'valid? returns true for complex_mapping_hash' do
140
+ mapping = DataMaps::Mapping.new(complex_mapping_hash)
141
+ expect(mapping.valid?).to be_truthy
142
+ end
143
+
144
+ it 'valid? returns false for invalid_mapping_hash' do
145
+ mapping = DataMaps::Mapping.new(invalid_mapping_hash)
146
+ expect(mapping.valid?).to be_falsey
147
+ end
148
+ end
149
+
150
+ describe '#each_statement' do
151
+ subject{ DataMaps::Mapping.new(simple_mapping_hash) }
152
+
153
+ it 'return an Enumerator if no block given' do
154
+ expect(subject.each_statement).to be_a Enumerator
155
+ end
156
+
157
+ it 'calls the given block with destination field name and statement' do
158
+ expect do |block|
159
+ subject.each_statement(&block)
160
+ end.to yield_successive_args(
161
+ ['destination1', DataMaps::Statement],
162
+ ['destination2', DataMaps::Statement]
163
+ )
164
+ end
165
+ end
166
+
167
+ describe '#execute' do
168
+ subject{ DataMaps::Mapping.new(complex_mapping_hash) }
169
+
170
+ it 'executes each statement' do
171
+ data = {}
172
+
173
+ subject.compile
174
+
175
+ expect(subject.mapping['destination1']).to receive(:execute).with(data).and_return(['destination1', 'value 1'])
176
+ expect(subject.mapping['destination2']).to receive(:execute).with(data).and_return(['destination2', 'value 2'])
177
+
178
+ expect(subject.execute(data)).to eq({ 'destination1' => 'value 1', 'destination2' => 'value 2' })
179
+ end
180
+
181
+ it 'filters FilteredValue from result' do
182
+ data = {}
183
+
184
+ subject.compile
185
+
186
+ expect(subject.mapping['destination1']).to receive(:execute).with(data).and_return(['destination1', 'value 1'])
187
+ expect(subject.mapping['destination2']).to receive(:execute).with(data).and_return(['destination2', DataMaps::FilteredValue.new('value 2')])
188
+
189
+ expect(subject.execute(data)).to eq({ 'destination1' => 'value 1' })
190
+ end
191
+ end
192
+ end