field_mapper 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.
@@ -0,0 +1,15 @@
1
+ module FieldMapper
2
+ module Types
3
+
4
+ class Boolean
5
+
6
+ def self.parse(value)
7
+ return false if value.nil?
8
+ return false if value.blank? || value.to_s =~ /\A(0|f(alse)?|no?)\z/i
9
+ true
10
+ end
11
+
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,58 @@
1
+ require_relative "../standard/plat"
2
+ require_relative "../marshaller"
3
+
4
+ module FieldMapper
5
+ module Types
6
+
7
+ class List
8
+ extend Forwardable
9
+
10
+ ALLOWED_TYPES = [
11
+ String,
12
+ Integer,
13
+ Float,
14
+ FieldMapper::Standard::Plat
15
+ ]
16
+
17
+ attr_reader :type
18
+
19
+ class << self
20
+
21
+ def [](type)
22
+ List.new(type)
23
+ end
24
+
25
+ end
26
+
27
+ def initialize(type, values=[])
28
+ raise InvalidListType unless valid_type?(type)
29
+ @type = type
30
+ end
31
+
32
+ def name
33
+ self.class.name
34
+ end
35
+
36
+ def plat_list?
37
+ type.ancestors.include?(FieldMapper::Standard::Plat)
38
+ end
39
+
40
+ def valid?(list)
41
+ return true if list.empty?
42
+ types = list.map{ |v| v.class }.uniq
43
+ return false if types.length > 1
44
+ types.first.ancestors.include? type
45
+ end
46
+
47
+ private
48
+
49
+ def valid_type?(type)
50
+ return false if type.class != Class
51
+ !(type.ancestors & ALLOWED_TYPES).empty?
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+ end
58
+
@@ -0,0 +1,35 @@
1
+ require_relative "../standard/plat"
2
+
3
+ module FieldMapper
4
+ module Types
5
+
6
+ class Plat
7
+ extend Forwardable
8
+
9
+ attr_reader :type
10
+
11
+ class << self
12
+
13
+ def [](type)
14
+ Plat.new(type)
15
+ end
16
+
17
+ end
18
+
19
+ def initialize(type, values=[])
20
+ if type.class != Class || !type.ancestors.include?(FieldMapper::Standard::Plat)
21
+ raise InvalidPlatType
22
+ end
23
+
24
+ @type = type
25
+ end
26
+
27
+ def name
28
+ self.class.name
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+ end
35
+
@@ -0,0 +1,3 @@
1
+ module FieldMapper
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,123 @@
1
+ require_relative "../test_helper"
2
+ require_relative "plat_example"
3
+ require_relative "plat_example_alt"
4
+
5
+ module Custom
6
+ class ConverterTest < MicroTest::Test
7
+
8
+ before do
9
+ @custom = Custom::PlatExample.new
10
+ @converter = FieldMapper::Custom::Converter.new(@custom)
11
+ end
12
+
13
+ test "convert_to_standard (basic)" do
14
+ @custom.name = "foobar"
15
+ standard = @converter.convert_to_standard
16
+ assert standard.name == "foobar"
17
+ end
18
+
19
+ test "convert_to_standard (find strategy)" do
20
+ @custom.rating = "C"
21
+ standard = @converter.convert_to_standard
22
+ assert standard.score == 3
23
+ end
24
+
25
+ test "convert_to_standard (compute strategy)" do
26
+ @custom.name = "Nathan"
27
+ @custom.desc = "This is a test."
28
+ standard = @converter.convert_to_standard
29
+ assert standard.desc == "Nathan says, 'This is a test.'"
30
+ end
31
+
32
+ test "convert_to_standard (compute strategy with values)" do
33
+ @custom.name = "Nathan"
34
+ @custom.color = "red"
35
+ standard = @converter.convert_to_standard
36
+ assert standard.color == "blue"
37
+ end
38
+
39
+ test "convert_to_standard (compute strategy with values alt)" do
40
+ @custom.color = "red"
41
+ standard = @converter.convert_to_standard
42
+ assert standard.color == "orangered"
43
+ end
44
+
45
+ test "convert_to_standard (custom has values but standard does not)" do
46
+ custom = Custom::PlatExampleAlt.new
47
+ converter = FieldMapper::Custom::Converter.new(custom)
48
+ custom.gender = "Male"
49
+ standard = converter.convert_to_standard
50
+ assert standard.desc == "Male"
51
+ end
52
+
53
+ test "convert_to_standard (standard has values but custom does not MATCH)" do
54
+ custom = Custom::PlatExampleAlt.new
55
+ converter = FieldMapper::Custom::Converter.new(custom)
56
+ custom.day = "Tuesday"
57
+ standard = converter.convert_to_standard
58
+ assert standard.day == "Tuesday"
59
+ end
60
+
61
+ test "convert_to_standard (standard has values but custom does not NO MATCH)" do
62
+ custom = Custom::PlatExampleAlt.new
63
+ converter = FieldMapper::Custom::Converter.new(custom)
64
+ custom.day = "Bunk"
65
+ standard = converter.convert_to_standard
66
+ assert standard.day.nil?
67
+ end
68
+
69
+ test "convert_to" do
70
+ @custom.name = "foo"
71
+ @custom.rating = "C"
72
+ @custom.color = "green"
73
+ custom = @converter.convert_to(Custom::PlatExampleAlt)
74
+ assert custom.name == "foo"
75
+ assert custom.fonzie == "AAA"
76
+ assert custom.rbg == "G"
77
+ end
78
+
79
+ test "convert_to (loaded values)" do
80
+ @custom.color = "realblue"
81
+ custom = @converter.convert_to(Custom::PlatExampleAlt)
82
+ assert custom.colour == "blue"
83
+ end
84
+
85
+ test "convert_to_standard (with PlatList values)" do
86
+ a = Custom::PlatExample.new(name: "a", rating: "A")
87
+ b = Custom::PlatExample.new(name: "b", rating: "B")
88
+ @custom.child_plats = [a, b]
89
+ converter = FieldMapper::Custom::Converter.new(@custom)
90
+ standard = converter.convert_to_standard
91
+
92
+ assert standard.children.first.name == "a"
93
+ assert standard.children.first.score == 1
94
+ standard_a = FieldMapper::Custom::Converter.new(a).convert_to_standard
95
+ assert standard.children.first.to_hash.merge(_node_id: nil) == standard_a.to_hash.merge(_node_id: nil)
96
+
97
+ assert standard.children.last.name == "b"
98
+ assert standard.children.last.score == 2
99
+ standard_b = FieldMapper::Custom::Converter.new(b).convert_to_standard
100
+ assert standard.children.last.to_hash.merge(_node_id: nil) == standard_b.to_hash.merge(_node_id: nil)
101
+ end
102
+
103
+ test "convert_to_standard (with PlatList value)" do
104
+ parent = Custom::PlatExample.new(name: "parent", rating: "A")
105
+ @custom.parent_plat = parent
106
+ converter = FieldMapper::Custom::Converter.new(@custom)
107
+ standard = converter.convert_to_standard
108
+
109
+ assert standard.parent.name == "parent"
110
+ assert standard.parent.score == 1
111
+ standard_parent = FieldMapper::Custom::Converter.new(parent).convert_to_standard
112
+ assert standard.parent.to_hash.merge(_node_id: nil) == standard_parent.to_hash.merge(_node_id: nil)
113
+ end
114
+
115
+ test "convert_to (multiple selected list values)" do
116
+ @custom.characters = ["X", "Z"]
117
+ converter = FieldMapper::Custom::Converter.new(@custom)
118
+ standard = converter.convert_to_standard
119
+ assert standard.letters = ["a", "c"]
120
+ end
121
+
122
+ end
123
+ end
@@ -0,0 +1,137 @@
1
+ require_relative "../test_helper"
2
+
3
+ module Custom
4
+ class FieldTest < MicroTest::Test
5
+
6
+ test "constructor requires type" do
7
+ begin
8
+ FieldMapper::Custom::Field.new(:foo)
9
+ rescue TypeNotSpecified => e
10
+ error = e
11
+ end
12
+ assert error.present?
13
+ end
14
+
15
+ test "constructor sets standard field" do
16
+ standard_field = FieldMapper::Standard::Field.new(:foo, type: String)
17
+ custom_field = FieldMapper::Custom::Field.new(:bar, standard_field: standard_field)
18
+ assert custom_field.standard_field == standard_field
19
+ end
20
+
21
+ test "constructor sets default flippers" do
22
+ standard_field = FieldMapper::Standard::Field.new(:foo, type: String)
23
+ custom_field = FieldMapper::Custom::Field.new(:bar, standard_field: standard_field)
24
+ assert custom_field.respond_to?(:custom_to_standard)
25
+ assert custom_field.respond_to?(:standard_to_custom)
26
+ end
27
+
28
+ test "inherits standard_field's type" do
29
+ standard_field = FieldMapper::Standard::Field.new(:foo, type: FieldMapper::Types::Boolean)
30
+ custom_field = FieldMapper::Custom::Field.new(:bar, standard_field: standard_field)
31
+ assert custom_field.type == FieldMapper::Types::Boolean
32
+ end
33
+
34
+ test "custom_to_standard (default)" do
35
+ standard_field = FieldMapper::Standard::Field.new(:foo, type: String)
36
+ custom_field = FieldMapper::Custom::Field.new(:bar, standard_field: standard_field)
37
+ assert custom_field.custom_to_standard.call("foobar") == "foobar"
38
+ end
39
+
40
+ test "custom_to_standard (override)" do
41
+ standard_field = FieldMapper::Standard::Field.new(:foo, type: String)
42
+ custom_field = FieldMapper::Custom::Field.new(
43
+ :bar,
44
+ standard_field: standard_field,
45
+ custom_to_standard: -> (value, params: {}) { "override" }
46
+ )
47
+ assert custom_field.custom_to_standard.call("foobar") == "override"
48
+ end
49
+
50
+ test "standard_to_custom (default)" do
51
+ standard_field = FieldMapper::Standard::Field.new(:foo, type: String)
52
+ custom_field = FieldMapper::Custom::Field.new(:bar, standard_field: standard_field)
53
+ assert custom_field.standard_to_custom.call("foobar") == "foobar"
54
+ end
55
+
56
+ test "standard_to_custom (override)" do
57
+ standard_field = FieldMapper::Standard::Field.new(:foo, type: String)
58
+ custom_field = FieldMapper::Custom::Field.new(
59
+ :bar,
60
+ standard_field: standard_field,
61
+ standard_to_custom: -> (value, **) { "override" }
62
+ )
63
+ assert custom_field.standard_to_custom.call("foobar") == "override"
64
+ end
65
+
66
+ test "add value" do
67
+ standard_field = FieldMapper::Standard::Field.new(:foo, type: String)
68
+ standard_field.value("a")
69
+ custom_field = FieldMapper::Custom::Field.new(:bar, standard_field: standard_field)
70
+ custom_field.value("A", standard: "a")
71
+ assert custom_field.values.first.value == "A"
72
+ assert custom_field.values.first.standard_value.value == "a"
73
+ end
74
+
75
+ test "add value with priority" do
76
+ standard_field = FieldMapper::Standard::Field.new(:foo, type: String)
77
+ standard_field.value("a")
78
+ custom_field = FieldMapper::Custom::Field.new(:bar, standard_field: standard_field)
79
+ custom_field.value("A", standard: "a", priority: true)
80
+ assert custom_field.values.first.priority
81
+ end
82
+
83
+ test "find_values_mapped_to_standard" do
84
+ standard_field = FieldMapper::Standard::Field.new(:foo, type: String)
85
+ standard_field.value("a")
86
+ standard_field.value("b")
87
+ custom_field = FieldMapper::Custom::Field.new(:bar, standard_field: standard_field)
88
+ custom_field.value("A", standard: "a")
89
+ custom_field.value("B", standard: "b")
90
+ assert custom_field.find_values_mapped_to_standard(standard_field.values.first).include?(custom_field.values.first)
91
+ assert custom_field.find_values_mapped_to_standard("a").include?(custom_field.values.first)
92
+ assert custom_field.find_values_mapped_to_standard(standard_field.values.last).include?(custom_field.values.last)
93
+ assert custom_field.find_values_mapped_to_standard("b").include?(custom_field.values.last)
94
+ end
95
+
96
+ test "find_priority_value_mapped_to_standard" do
97
+ standard_field = FieldMapper::Standard::Field.new(:foo, type: String)
98
+ standard_field.value("a")
99
+ standard_field.value("b")
100
+ custom_field = FieldMapper::Custom::Field.new(:bar, standard_field: standard_field)
101
+ custom_field.value("A", standard: "a")
102
+ custom_field.value("AA", standard: "a", priority: true)
103
+ custom_field.value("B", standard: "b")
104
+ assert custom_field.find_priority_value_mapped_to_standard("a") == custom_field.values[1]
105
+ end
106
+
107
+ test "flip_strategy (default is :compute)" do
108
+ standard_field = FieldMapper::Standard::Field.new(:foo, type: String)
109
+ custom_field = FieldMapper::Custom::Field.new(:bar, standard_field: standard_field)
110
+ assert custom_field.flip_strategy(:custom_to_standard) == :compute
111
+ assert custom_field.flip_strategy(:standard_to_custom) == :compute
112
+ end
113
+
114
+ test "flip_strategy (default with allowed values is :find)" do
115
+ standard_field = FieldMapper::Standard::Field.new(:foo, type: String)
116
+ standard_field.value("a")
117
+ custom_field = FieldMapper::Custom::Field.new(:bar, standard_field: standard_field)
118
+ custom_field.value("A", standard: "a")
119
+ assert custom_field.flip_strategy(:custom_to_standard) == :find
120
+ assert custom_field.flip_strategy(:standard_to_custom) == :find
121
+ end
122
+
123
+ test "flip_strategy (with allowed values and flipper overrides is :compute)" do
124
+ standard_field = FieldMapper::Standard::Field.new(:foo, type: String)
125
+ standard_field.value("a")
126
+ custom_field = FieldMapper::Custom::Field.new(
127
+ :bar,
128
+ standard_field: standard_field,
129
+ custom_to_standard: -> (value, params: {}) { "override" },
130
+ standard_to_custom: -> (value, params: {}) { "override" },
131
+ )
132
+ custom_field.value("A", standard: "a")
133
+ assert custom_field.flip_strategy(:custom_to_standard) == :compute
134
+ assert custom_field.flip_strategy(:standard_to_custom) == :compute
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,58 @@
1
+ require_relative "../test_helper"
2
+ require_relative "../standard/plat_example"
3
+
4
+ module Custom
5
+ class PlatExample < FieldMapper::Custom::Plat
6
+ set_standard Standard::PlatExample
7
+
8
+ field :name, standard: :name
9
+ field :desc, standard: :desc,
10
+ custom_to_standard: -> (value, standard_instance: nil) {
11
+ "#{name} says, '#{value}'"
12
+ },
13
+ standard_to_custom: -> (value, standard_instance: nil) {
14
+ "'#{value}' --#{name}"
15
+ }
16
+
17
+ field :rating, type: String, standard: :score do
18
+ value "A", standard: 1
19
+ value "B", standard: 2
20
+ value "C", standard: 3
21
+ end
22
+
23
+ field :color, standard: :color,
24
+ # NOTE: as a best practice, do not define flippers on fields with allowed values
25
+ # only doing it here for testing purposes
26
+ custom_to_standard: -> (value, standard_instance: nil) {
27
+ return "blue" if name == "Nathan"
28
+ case value
29
+ when "blue" then "aliceblue"
30
+ when "realblue" then "blue"
31
+ when "green" then "lawngreen"
32
+ when "red" then "orangered"
33
+ end
34
+ } do
35
+ value "blue", standard: "aliceblue"
36
+ value "realblue", standard: "blue"
37
+ value "green", standard: "lawngreen"
38
+ value "red", standard: "orangered"
39
+ end
40
+
41
+ field :painter, standard: :artist do
42
+ value "Leonardo", standard: "Leonardo Da Vinci", priority: true
43
+ value "Leo", standard: "Leonardo Da Vinci"
44
+ value "Michelangelo", standard: "Michelangelo Buonarroti"
45
+ value "Raphael", standard: "Raphael Sanzio"
46
+ end
47
+
48
+ field :characters, standard: :letters do
49
+ value "X", standard: "a"
50
+ value "Y", standard: "b"
51
+ value "Z", standard: "c"
52
+ end
53
+
54
+ field :parent_plat, type: FieldMapper::Types::Plat[Custom::PlatExample], standard: :parent
55
+ field :child_plats, type: FieldMapper::Types::List[Custom::PlatExample], standard: :children, default: []
56
+
57
+ end
58
+ end
@@ -0,0 +1,34 @@
1
+ require_relative "../test_helper"
2
+ require_relative "../standard/plat_example"
3
+
4
+ module Custom
5
+ class PlatExampleAlt < FieldMapper::Custom::Plat
6
+ set_standard Standard::PlatExample
7
+
8
+ field :name, standard: :name
9
+
10
+ field :gender, standard: :desc do
11
+ value "Male"
12
+ value "Female"
13
+ end
14
+
15
+ field :day, standard: :day
16
+
17
+ field :fonzie, type: String, standard: :score do
18
+ value "A", standard: 1
19
+ value "AA", standard: 2
20
+ value "AAA", standard: 3
21
+ end
22
+
23
+ field :rbg, standard: :color do
24
+ value "R", standard: "orangered"
25
+ value "G", standard: "lawngreen"
26
+ value "B", standard: "aliceblue"
27
+ end
28
+
29
+ field :colour, standard: :color do
30
+ load_values File.expand_path("../assets/colors.csv", __FILE__)
31
+ end
32
+
33
+ end
34
+ end