field_mapper 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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