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,102 @@
1
+ require_relative "../test_helper"
2
+ require_relative "plat_example"
3
+
4
+ module Custom
5
+ class PlatTest < MicroTest::Test
6
+
7
+ before do
8
+ @class = Custom::PlatExample
9
+ @instance = Custom::PlatExample.new
10
+ end
11
+
12
+ test "set_standard" do
13
+ assert @class.standard_plat == Standard::PlatExample
14
+ end
15
+
16
+ test "field mapping" do
17
+ assert @class.find_field(:name).standard_field == @class.standard_plat.find_field(:name)
18
+ end
19
+
20
+ test "field mapping with value mappings" do
21
+ custom_field = @class.find_field(:color)
22
+ standard_field = @class.standard_plat.find_field(:color)
23
+ assert custom_field.standard_field == standard_field
24
+ assert custom_field.find_value("blue").standard_value == standard_field.find_value("aliceblue")
25
+ assert custom_field.find_value("green").standard_value == standard_field.find_value("lawngreen")
26
+ assert custom_field.find_value("red").standard_value == standard_field.find_value("orangered")
27
+ end
28
+
29
+ test "field mapping with value mappings (diff names)" do
30
+ custom_field = @class.find_field(:painter)
31
+ standard_field = @class.standard_plat.find_field(:artist)
32
+ assert custom_field.standard_field == standard_field
33
+ assert custom_field.find_value("Leonardo").standard_value == standard_field.find_value("Leonardo Da Vinci")
34
+ end
35
+
36
+ test "field mapping with value mappings (diff types)" do
37
+ custom_field = @class.find_field(:rating)
38
+ standard_field = @class.standard_plat.find_field(:score)
39
+ assert custom_field.standard_field == standard_field
40
+ assert custom_field.find_value("A").standard_value == standard_field.find_value(1)
41
+ assert custom_field.find_value("B").standard_value == standard_field.find_value(2)
42
+ assert custom_field.find_value("C").standard_value == standard_field.find_value(3)
43
+ end
44
+
45
+ test "find_mapped_fields" do
46
+ standard_field = @class.standard_plat.find_field(:artist)
47
+ custom_field = @class.find_field(:painter)
48
+ assert @class.find_mapped_fields(standard_field).include?(custom_field)
49
+ end
50
+
51
+ test "to_hash" do
52
+ @instance.parent_plat = Custom::PlatExample.new
53
+ @instance.child_plats << Custom::PlatExampleAlt.new
54
+ @instance.child_plats << Custom::PlatExampleAlt.new
55
+ assert @instance.to_hash == {
56
+ "_node_id" => @instance.object_id,
57
+ "_flat" => false,
58
+ "name" => nil,
59
+ "desc" => nil,
60
+ "rating" => nil,
61
+ "color" => nil,
62
+ "painter" => nil,
63
+ "characters" => nil,
64
+ "parent_plat" => {
65
+ "_node_id" => @instance.parent_plat.object_id,
66
+ "_flat" => false,
67
+ "name" => nil,
68
+ "desc" => nil,
69
+ "rating" => nil,
70
+ "color" => nil,
71
+ "painter" => nil,
72
+ "characters" => nil,
73
+ "parent_plat" => nil,
74
+ "child_plats" => []
75
+ },
76
+ "child_plats" => [
77
+ {
78
+ "_node_id" => @instance.child_plats.first.object_id,
79
+ "_flat" => false,
80
+ "name" => nil,
81
+ "gender" => nil,
82
+ "day" => nil,
83
+ "fonzie" => nil,
84
+ "rbg" => nil,
85
+ "colour" => nil
86
+ },
87
+ {
88
+ "_node_id" => @instance.child_plats.last.object_id,
89
+ "_flat" => false,
90
+ "name" => nil,
91
+ "gender" => nil,
92
+ "day" => nil,
93
+ "fonzie" => nil,
94
+ "rbg" => nil,
95
+ "colour" => nil
96
+ }
97
+ ]
98
+ }
99
+ end
100
+
101
+ end
102
+ end
@@ -0,0 +1,43 @@
1
+ require_relative "../test_helper"
2
+
3
+ module Custom
4
+ class ValueTest < MicroTest::Test
5
+
6
+ before do
7
+ standard_field = FieldMapper::Standard::Field.new(:foo, type: String)
8
+ @custom_field = FieldMapper::Custom::Field.new(:bar, standard_field: standard_field)
9
+ end
10
+
11
+ test "constructor requires standar_field when standard_value is set" do
12
+ begin
13
+ custom_field = FieldMapper::Custom::Field.new(:bar, type: Integer)
14
+ FieldMapper::Custom::Value.new(1, field: custom_field, standard_value: 1)
15
+ rescue StandardFieldNotFound => e
16
+ error = e
17
+ end
18
+ assert error.present?
19
+ end
20
+
21
+ test "constructor ensures standard_value exists" do
22
+ begin
23
+ FieldMapper::Custom::Value.new("a", field: @custom_field, standard_value: "a")
24
+ rescue StandardValueNotFound => e
25
+ error = e
26
+ end
27
+ assert error.present?
28
+ end
29
+
30
+ test "constructor maps values" do
31
+ @custom_field.standard_field.value("a")
32
+ value = FieldMapper::Custom::Value.new("a", field: @custom_field, standard_value: "a")
33
+ assert value.value == value.standard_value.value
34
+ end
35
+
36
+ test "constructor sets priority" do
37
+ @custom_field.standard_field.value("a")
38
+ value = FieldMapper::Custom::Value.new("a", field: @custom_field, standard_value: "a", priority: true)
39
+ assert value.priority
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,119 @@
1
+ require_relative "test_helper"
2
+
3
+ class ReadmeTest < MicroTest::Test
4
+
5
+ test "readme examples" do
6
+
7
+ class StandardUser < FieldMapper::Standard::Plat
8
+ field :name, type: String
9
+ field :screen_name, type: String
10
+ field :info, type: String
11
+ field :website, type: String
12
+
13
+ # field with allowed values
14
+ field :gender, type: String do
15
+ value "F"
16
+ value "M"
17
+ end
18
+
19
+ field :age, type: Integer
20
+
21
+ # field with a default value
22
+ field :net_worth, type: Money, default: 0
23
+
24
+ # field that holds a list of plats
25
+ field :friends, type: FieldMapper::Types::List[StandardUser], default: []
26
+ end
27
+
28
+ class FacebookUser < FieldMapper::Custom::Plat
29
+ # note that we set the standard
30
+ set_standard StandardUser
31
+
32
+ # fields are mapped to the standard
33
+ field :name, standard: :name
34
+
35
+ # field with complex transformation rules
36
+ field :username, standard: :screen_name,
37
+ custom_to_standard: -> (value, standard_instance: nil) {
38
+ # value passed is the custom value
39
+ # value returned is the standard value
40
+ "Facebook:#{value.to_s.strip}"
41
+ },
42
+ standard_to_custom: -> (value, standard_instance: nil) {
43
+ # value passed is the standard value
44
+ # value returned is the custom value
45
+ value.to_s.split(/:/).last
46
+ }
47
+
48
+ field :bio, standard: :info
49
+ field :website, standard: :website
50
+
51
+ # field with mapped values
52
+ field :gender, standard: :gender do
53
+ value "female", standard: "F"
54
+ value "male", standard: "M"
55
+ end
56
+
57
+ field :net_worth, standard: :net_worth
58
+ field :friends, standard: :friends, type: FieldMapper::Types::List[FacebookUser], default: []
59
+
60
+ # not all custom fields are required to map to a standard
61
+ field :birthday, type: Time
62
+ end
63
+
64
+ class TwitterUser < FieldMapper::Custom::Plat
65
+ set_standard StandardUser
66
+
67
+ field :name, standard: :name
68
+ field :screen_name, standard: :screen_name,
69
+ custom_to_standard: -> (value, standard_instance: nil) {
70
+ "Twitter:#{value.to_s.strip}"
71
+ },
72
+ standard_to_custom: -> (value, standard_instance: nil) {
73
+ value.to_s.split(/:/).last
74
+ }
75
+ field :description, standard: :info
76
+ field :url, standard: :website
77
+ field :followers_count, type: Integer
78
+
79
+ # callback method that runs after tranformation
80
+ def after_convert(from: nil, to: nil)
81
+ if from.respond_to? :friends
82
+ self.followers_count = from.friends.length
83
+ end
84
+ end
85
+ end
86
+
87
+ zuck = FacebookUser.new(
88
+ name: "Mark Zuckerberg",
89
+ username: "zuck",
90
+ bio: "Creator of Facebook",
91
+ website: "http://www.facebook.com/zuck",
92
+ gender: "male",
93
+ age: 29,
94
+ net_worth: "$29,000,000,000 USD", # value will be cast to a Money
95
+ birthday: "1984-05-14" # value will be cast to a Time
96
+ )
97
+
98
+ zuck.friends << FacebookUser.new(name: "Priscilla Chan")
99
+
100
+ converter = FieldMapper::Custom::Converter.new(zuck)
101
+ standard_zuck = converter.convert_to_standard
102
+
103
+ converter = FieldMapper::Custom::Converter.new(zuck)
104
+ twitter_zuck = converter.convert_to(TwitterUser)
105
+
106
+ converter = FieldMapper::Standard::Converter.new(standard_zuck)
107
+ zuck2 = converter.convert_to(FacebookUser)
108
+ twitter_zuck2 = converter.convert_to(TwitterUser)
109
+
110
+ zuck_hash = zuck.to_hash
111
+ zuck_flat_hash = zuck.to_hash(flatten: true)
112
+ zuck_from_hash = FacebookUser.new(zuck_hash)
113
+ zuck_from_flat_hash = FacebookUser.new(zuck_flat_hash)
114
+
115
+ # TODO: break tests up & add some asserts
116
+ #assert false
117
+ end
118
+
119
+ end
@@ -0,0 +1,88 @@
1
+ require_relative "../test_helper"
2
+ require_relative "plat_example"
3
+ require_relative "../custom/plat_example"
4
+ require_relative "../custom/plat_example_alt"
5
+
6
+ module Standard
7
+ class ConverterTest < MicroTest::Test
8
+
9
+ before do
10
+ @standard = Standard::PlatExample.new
11
+ @converter = FieldMapper::Standard::Converter.new(@standard)
12
+ end
13
+
14
+ test "convert_to (basic)" do
15
+ @standard.name = "foobar"
16
+ custom = @converter.convert_to(Custom::PlatExample)
17
+ assert custom.name == "foobar"
18
+ end
19
+
20
+ test "convert_to (find strategy)" do
21
+ @standard.score = 3
22
+ custom = @converter.convert_to(Custom::PlatExample)
23
+ assert custom.rating == "C"
24
+ end
25
+
26
+ test "convert_to (compute strategy)" do
27
+ @standard.name = "Nathan"
28
+ @standard.desc = "This is a test."
29
+ custom = @converter.convert_to(Custom::PlatExample)
30
+ assert custom.desc == "'This is a test.' --Nathan"
31
+ end
32
+
33
+ test "convert_to (custom has values but standard does not MATCH)" do
34
+ @standard.desc = "Male"
35
+ custom = @converter.convert_to(Custom::PlatExampleAlt)
36
+ assert custom.gender == "Male"
37
+ end
38
+
39
+ test "convert_to (custom has values but standard does not NO MATCH)" do
40
+ @standard.desc = "Bunk"
41
+ custom = @converter.convert_to(Custom::PlatExampleAlt)
42
+ assert custom.gender.nil?
43
+ end
44
+
45
+ test "convert_to (standard has values but custom does not)" do
46
+ @standard.day = "Tuesday"
47
+ custom = @converter.convert_to(Custom::PlatExampleAlt)
48
+ assert custom.day == "Tuesday"
49
+ end
50
+
51
+ test "convert_to (multiple selected list values)" do
52
+ @standard.letters = ["a", "c"]
53
+ custom = @converter.convert_to(Custom::PlatExample)
54
+ assert custom.characters = ["X", "Z"]
55
+ end
56
+
57
+ test "convert_to (with PlatList values)" do
58
+ a = Standard::PlatExample.new(name: "a", score: 1)
59
+ b = Standard::PlatExample.new(name: "b", score: 2)
60
+ @standard.children = [a, b]
61
+ converter = FieldMapper::Standard::Converter.new(@standard)
62
+ custom = converter.convert_to(Custom::PlatExample)
63
+
64
+ assert custom.child_plats.first.name == "a"
65
+ assert custom.child_plats.first.rating == "A"
66
+ custom_a = FieldMapper::Standard::Converter.new(a).convert_to(Custom::PlatExample)
67
+ assert custom.child_plats.first.to_hash.merge(_node_id: nil) == custom_a.to_hash.merge(_node_id: nil)
68
+
69
+ assert custom.child_plats.last.name == "b"
70
+ assert custom.child_plats.last.rating == "B"
71
+ custom_b = FieldMapper::Standard::Converter.new(b).convert_to(Custom::PlatExample)
72
+ assert custom.child_plats.last.to_hash.merge(_node_id: nil) == custom_b.to_hash.merge(_node_id: nil)
73
+ end
74
+
75
+ test "convert_to (with PlatList value)" do
76
+ parent = Standard::PlatExample.new(name: "parent", score: 1)
77
+ @standard.parent = parent
78
+ converter = FieldMapper::Standard::Converter.new(@standard)
79
+ custom = converter.convert_to(Custom::PlatExample)
80
+
81
+ assert custom.parent_plat.name == "parent"
82
+ assert custom.parent_plat.rating == "A"
83
+ custom_parent = FieldMapper::Standard::Converter.new(parent).convert_to(Custom::PlatExample)
84
+ assert custom.parent_plat.to_hash.merge(_node_id: nil) == custom_parent.to_hash.merge(_node_id: nil)
85
+ end
86
+
87
+ end
88
+ end
@@ -0,0 +1,156 @@
1
+ require_relative "../test_helper"
2
+ require_relative "plat_example"
3
+
4
+ module Standard
5
+ class FieldTest < MicroTest::Test
6
+
7
+ test "constructor requires type" do
8
+ begin
9
+ FieldMapper::Standard::Field.new(:foo)
10
+ rescue TypeNotSpecified => e
11
+ error = e
12
+ end
13
+ assert error.present?
14
+ end
15
+
16
+ test "constructor sets name" do
17
+ field = FieldMapper::Standard::Field.new(:foo, type: String)
18
+ assert field.name == :foo
19
+ end
20
+
21
+ test "constructor sets type" do
22
+ field = FieldMapper::Standard::Field.new(:foo, type: String)
23
+ assert field.type == String
24
+ end
25
+
26
+ test "constructor sets desc" do
27
+ field = FieldMapper::Standard::Field.new(:foo, type: String, desc: "A description")
28
+ assert field.desc == "A description"
29
+ end
30
+
31
+ test "constructor sets default" do
32
+ field = FieldMapper::Standard::Field.new(:foo, type: String, default: "bar")
33
+ assert field.default == "bar"
34
+ end
35
+
36
+ test "add value" do
37
+ field = FieldMapper::Standard::Field.new(:foo, type: String)
38
+ field.value("bar")
39
+ assert field.values.first.value == "bar"
40
+ end
41
+
42
+ test "load values" do
43
+ field = FieldMapper::Standard::Field.new(:color, type: String)
44
+ field.load_values(File.expand_path("../assets/colors.csv", __FILE__))
45
+ assert field.has_values?
46
+ assert field.values.first.value == "aliceblue"
47
+ assert field.values.last.value == "yellowgreen"
48
+ end
49
+
50
+ test "has_values? (false)" do
51
+ field = FieldMapper::Standard::Field.new(:foo, type: String)
52
+ assert !field.has_values?
53
+ end
54
+
55
+ test "has_values? (true)" do
56
+ field = FieldMapper::Standard::Field.new(:foo, type: String)
57
+ field.value("bar")
58
+ assert field.has_values?
59
+ end
60
+
61
+ test "values (nil)" do
62
+ field = FieldMapper::Standard::Field.new(:foo, type: Integer)
63
+ assert field.values.nil?
64
+ end
65
+
66
+ test "values (present)" do
67
+ field = FieldMapper::Standard::Field.new(:foo, type: Integer)
68
+ (1..3).each { |i| field.value(i) }
69
+ assert field.values.present?
70
+ assert field.values.length == 3
71
+ end
72
+
73
+ test "find_value (base value)" do
74
+ field = FieldMapper::Standard::Field.new(:foo, type: Integer)
75
+ (1..3).each { |i| field.value(i) }
76
+ assert field.find_value(2) == field.values[1]
77
+ end
78
+
79
+ test "find_value (value type)" do
80
+ field = FieldMapper::Standard::Field.new(:foo, type: Integer)
81
+ (1..3).each { |i| field.value(i) }
82
+ assert field.find_value(field.values[1]) == field.values[1]
83
+ end
84
+
85
+ test "add value performs type cast" do
86
+ field = FieldMapper::Standard::Field.new(:foo, type: String)
87
+ field.value(:bar)
88
+ assert field.values.first.value == "bar"
89
+ end
90
+
91
+ test "cast (String)" do
92
+ field = FieldMapper::Standard::Field.new(:foo, type: String)
93
+ assert field.cast(1) == "1"
94
+ end
95
+
96
+ test "cast (Integer)" do
97
+ field = FieldMapper::Standard::Field.new(:foo, type: Integer)
98
+ assert field.cast("1") == 1
99
+ end
100
+
101
+ test "cast (Float)" do
102
+ field = FieldMapper::Standard::Field.new(:foo, type: Float)
103
+ assert field.cast("0.1") == 0.1
104
+ end
105
+
106
+ test "cast (Time)" do
107
+ field = FieldMapper::Standard::Field.new(:foo, type: Time)
108
+ expected = Time.parse("2000-01-15")
109
+ assert field.cast("01/15/2000") == expected
110
+ end
111
+
112
+ test "cast (Boolean true)" do
113
+ field = FieldMapper::Standard::Field.new(:foo, type: FieldMapper::Types::Boolean)
114
+ assert field.cast(:true) == true
115
+ assert field.cast(:t) == true
116
+ assert field.cast(1) == true
117
+ assert field.cast(:foo) == true
118
+ end
119
+
120
+ test "cast (Boolean false)" do
121
+ field = FieldMapper::Standard::Field.new(:foo, type: FieldMapper::Types::Boolean)
122
+ assert field.cast(:false) == false
123
+ assert field.cast(:f) == false
124
+ assert field.cast(:n) == false
125
+ assert field.cast(0) == false
126
+ end
127
+
128
+ test "cast (Money USD)" do
129
+ field = FieldMapper::Standard::Field.new(:foo, type: Money)
130
+ assert field.cast("$100.00 USD") == Money.new(100_00, "USD")
131
+ end
132
+
133
+ test "cast (Money EUR)" do
134
+ field = FieldMapper::Standard::Field.new(:foo, type: Money)
135
+ assert field.cast("€100.00 EUR") == Money.new(100_00, "EUR")
136
+ end
137
+
138
+ test "cast (Money MXN)" do
139
+ field = FieldMapper::Standard::Field.new(:foo, type: Money)
140
+ assert field.cast("$100.00 MXN") == Money.new(100_00, "MXN")
141
+ end
142
+
143
+ test "cast (List)" do
144
+ field = FieldMapper::Standard::Field.new(:foo, type: FieldMapper::Types::List[Standard::PlatExample])
145
+ list = []
146
+ list << Standard::PlatExample.new(name: :foo)
147
+ list << Standard::PlatExample.new(name: :bar)
148
+ assert field.cast(list) == list
149
+ end
150
+
151
+ test "to_s" do
152
+ field = FieldMapper::Standard::Field.new(:foo, type: String)
153
+ assert field.to_s == field.name
154
+ end
155
+ end
156
+ end