representable 3.0.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +17 -0
- data/CHANGES.md +25 -0
- data/Gemfile +4 -12
- data/LICENSE +1 -1
- data/README.md +6 -6
- data/Rakefile +1 -6
- data/TODO +1 -3
- data/TODO-4.0.md +72 -0
- data/lib/representable.rb +19 -25
- data/lib/representable/binding.rb +32 -12
- data/lib/representable/cached.rb +1 -1
- data/lib/representable/coercion.rb +8 -6
- data/lib/representable/config.rb +13 -3
- data/lib/representable/debug.rb +23 -15
- data/lib/representable/declarative.rb +12 -7
- data/lib/representable/decorator.rb +1 -1
- data/lib/representable/definition.rb +7 -3
- data/lib/representable/deserializer.rb +5 -4
- data/lib/representable/for_collection.rb +1 -1
- data/lib/representable/hash.rb +9 -2
- data/lib/representable/hash/allow_symbols.rb +9 -11
- data/lib/representable/hash/binding.rb +1 -0
- data/lib/representable/hash/collection.rb +4 -2
- data/lib/representable/hash_methods.rb +3 -2
- data/lib/representable/insert.rb +1 -1
- data/lib/representable/json.rb +8 -7
- data/lib/representable/json/collection.rb +3 -0
- data/lib/representable/object.rb +1 -1
- data/lib/representable/object/binding.rb +5 -1
- data/lib/representable/option.rb +19 -0
- data/lib/representable/pipeline.rb +3 -2
- data/lib/representable/pipeline_factories.rb +4 -2
- data/lib/representable/populator.rb +1 -1
- data/lib/representable/represent.rb +1 -0
- data/lib/representable/serializer.rb +3 -2
- data/lib/representable/version.rb +1 -1
- data/lib/representable/virtus_coercion.rb +38 -0
- data/lib/representable/xml.rb +12 -10
- data/lib/representable/xml/binding.rb +19 -13
- data/lib/representable/xml/namespace.rb +122 -0
- data/lib/representable/yaml.rb +6 -2
- data/lib/representable/yaml/binding.rb +1 -0
- data/representable.gemspec +8 -9
- data/test/as_test.rb +7 -7
- data/test/binding_test.rb +14 -14
- data/test/cached_test.rb +59 -49
- data/test/class_test.rb +9 -9
- data/test/coercion_test.rb +33 -22
- data/test/config/inherit_test.rb +14 -14
- data/test/config_test.rb +20 -20
- data/test/decorator_scope_test.rb +4 -4
- data/test/decorator_test.rb +33 -20
- data/test/default_test.rb +8 -8
- data/test/defaults_options_test.rb +3 -3
- data/test/definition_test.rb +38 -40
- data/test/{example.rb → examples/example.rb} +0 -1
- data/test/examples/object.rb +1 -5
- data/test/exec_context_test.rb +8 -8
- data/test/features_test.rb +6 -6
- data/test/filter_test.rb +8 -8
- data/test/for_collection_test.rb +10 -10
- data/test/generic_test.rb +13 -13
- data/test/getter_setter_test.rb +5 -5
- data/test/hash_bindings_test.rb +1 -1
- data/test/hash_test.rb +45 -23
- data/test/heritage_test.rb +16 -13
- data/test/if_test.rb +9 -9
- data/test/include_exclude_test.rb +14 -14
- data/test/inherit_test.rb +18 -18
- data/test/inline_test.rb +24 -24
- data/test/instance_test.rb +31 -31
- data/test/is_representable_test.rb +10 -10
- data/test/json_test.rb +29 -7
- data/test/lonely_test.rb +31 -31
- data/test/nested_test.rb +13 -13
- data/test/object_test.rb +9 -9
- data/test/option_test.rb +36 -0
- data/test/parse_pipeline_test.rb +3 -5
- data/test/pipeline_test.rb +50 -50
- data/test/populator_test.rb +18 -18
- data/test/prepare_test.rb +4 -4
- data/test/private_options_test.rb +2 -2
- data/test/reader_writer_test.rb +2 -2
- data/test/render_nil_test.rb +2 -2
- data/test/represent_test.rb +14 -14
- data/test/representable_test.rb +34 -36
- data/test/schema_test.rb +8 -11
- data/test/serialize_deserialize_test.rb +2 -2
- data/test/skip_test.rb +14 -14
- data/test/stringify_hash_test.rb +3 -3
- data/test/test_helper.rb +26 -14
- data/test/uncategorized_test.rb +10 -10
- data/test/user_options_test.rb +4 -4
- data/test/virtus_coercion_test.rb +52 -0
- data/test/wrap_test.rb +19 -19
- data/test/xml_bindings_test.rb +0 -4
- data/test/xml_namespace_test.rb +186 -0
- data/test/xml_test.rb +103 -43
- data/test/yaml_test.rb +51 -26
- metadata +101 -39
- data/.travis.yml +0 -7
- data/lib/representable/TODO.getting_serious +0 -11
- data/lib/representable/autoload.rb +0 -10
- data/test/mongoid_test.rb +0 -31
data/test/binding_test.rb
CHANGED
@@ -2,45 +2,45 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class BindingTest < MiniTest::Spec
|
4
4
|
Binding = Representable::Binding
|
5
|
-
let
|
5
|
+
let(:render_nil_definition) { Representable::Definition.new(:song, :render_nil => true) }
|
6
6
|
|
7
7
|
describe "#skipable_empty_value?" do
|
8
|
-
let
|
8
|
+
let(:binding) { Binding.new(render_nil_definition) }
|
9
9
|
|
10
10
|
# don't skip when present.
|
11
|
-
it { binding.skipable_empty_value?("Disconnect, Disconnect").must_equal false }
|
11
|
+
it { _(binding.skipable_empty_value?("Disconnect, Disconnect")).must_equal false }
|
12
12
|
|
13
13
|
# don't skip when it's nil and render_nil: true
|
14
|
-
it { binding.skipable_empty_value?(nil).must_equal false }
|
14
|
+
it { _(binding.skipable_empty_value?(nil)).must_equal false }
|
15
15
|
|
16
16
|
# skip when nil and :render_nil undefined.
|
17
|
-
it { Binding.new(Representable::Definition.new(:song)).skipable_empty_value?(nil).must_equal true }
|
17
|
+
it { _(Binding.new(Representable::Definition.new(:song)).skipable_empty_value?(nil)).must_equal true }
|
18
18
|
|
19
19
|
# don't skip when nil and :render_nil undefined.
|
20
|
-
it { Binding.new(Representable::Definition.new(:song)).skipable_empty_value?("Fatal Flu").must_equal false }
|
20
|
+
it { _(Binding.new(Representable::Definition.new(:song)).skipable_empty_value?("Fatal Flu")).must_equal false }
|
21
21
|
end
|
22
22
|
|
23
23
|
|
24
24
|
describe "#default_for" do
|
25
|
-
let
|
26
|
-
let
|
25
|
+
let(:definition) { Representable::Definition.new(:song, :default => "Insider") }
|
26
|
+
let(:binding) { Binding.new(definition) }
|
27
27
|
|
28
28
|
# return value when value present.
|
29
|
-
it { binding.default_for("Black And Blue").must_equal "Black And Blue" }
|
29
|
+
it { _(binding.default_for("Black And Blue")).must_equal "Black And Blue" }
|
30
30
|
|
31
31
|
# return false when value false.
|
32
|
-
it { binding.default_for(false).must_equal false }
|
32
|
+
it { _(binding.default_for(false)).must_equal false }
|
33
33
|
|
34
34
|
# return default when value nil.
|
35
|
-
it { binding.default_for(nil).must_equal "Insider" }
|
35
|
+
it { _(binding.default_for(nil)).must_equal "Insider" }
|
36
36
|
|
37
37
|
# return nil when value nil and render_nil: true.
|
38
|
-
it { Binding.new(render_nil_definition).default_for(nil).
|
38
|
+
it { _(Binding.new(render_nil_definition).default_for(nil)).must_be_nil }
|
39
39
|
|
40
40
|
# return nil when value nil and render_nil: true, even when :default is set" do
|
41
|
-
it { Binding.new(Representable::Definition.new(:song, :render_nil => true, :default => "The Quest")).default_for(nil).
|
41
|
+
it { _(Binding.new(Representable::Definition.new(:song, :render_nil => true, :default => "The Quest")).default_for(nil)).must_be_nil }
|
42
42
|
|
43
43
|
# return nil if no :default
|
44
|
-
it { Binding.new(Representable::Definition.new(:song)).default_for(nil).
|
44
|
+
it { _(Binding.new(Representable::Definition.new(:song)).default_for(nil)).must_be_nil }
|
45
45
|
end
|
46
46
|
end
|
data/test/cached_test.rb
CHANGED
@@ -1,5 +1,28 @@
|
|
1
1
|
require "test_helper"
|
2
|
-
|
2
|
+
|
3
|
+
class Profiler
|
4
|
+
def self.profile(&block)
|
5
|
+
case RUBY_ENGINE
|
6
|
+
when "ruby"
|
7
|
+
require 'ruby-prof'
|
8
|
+
|
9
|
+
output = StringIO.new
|
10
|
+
profile_result = RubyProf.profile(&block)
|
11
|
+
printer = RubyProf::FlatPrinter.new(profile_result)
|
12
|
+
printer.print(output)
|
13
|
+
output.string
|
14
|
+
when "jruby"
|
15
|
+
require 'jruby/profiler'
|
16
|
+
|
17
|
+
output_stream = java.io.ByteArrayOutputStream.new
|
18
|
+
print_stream = java.io.PrintStream.new(output_stream)
|
19
|
+
profile_result = JRuby::Profiler.profile(&block)
|
20
|
+
printer = JRuby::Profiler::FlatProfilePrinter.new(profile_result)
|
21
|
+
printer.printProfile(print_stream)
|
22
|
+
output_stream.toString
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
3
26
|
|
4
27
|
class CachedTest < MiniTest::Spec
|
5
28
|
# TODO: also test with feature(Cached)
|
@@ -30,18 +53,18 @@ class CachedTest < MiniTest::Spec
|
|
30
53
|
|
31
54
|
|
32
55
|
describe "serialization" do
|
33
|
-
let
|
56
|
+
let(:album_hash) { {"name"=>"Louder And Even More Dangerous", "songs"=>[{"title"=>"Southbound:{:volume=>10}"}, {"title"=>"Jailbreak:{:volume=>10}"}]} }
|
34
57
|
|
35
|
-
let
|
36
|
-
let
|
37
|
-
let
|
38
|
-
let
|
58
|
+
let(:song) { Model::Song.new("Jailbreak") }
|
59
|
+
let(:song2) { Model::Song.new("Southbound") }
|
60
|
+
let(:album) { Model::Album.new("Live And Dangerous", [song, song2, Model::Song.new("Emerald")]) }
|
61
|
+
let(:representer) { AlbumRepresenter.new(album) }
|
39
62
|
|
40
63
|
it do
|
41
|
-
album2 = Model::Album.new("Louder And Even More Dangerous", [song2, song])
|
64
|
+
# album2 = Model::Album.new("Louder And Even More Dangerous", [song2, song])
|
42
65
|
|
43
66
|
# makes sure options are passed correctly.
|
44
|
-
representer.to_hash(user_options: {volume: 9}).must_equal({"name"=>"Live And Dangerous",
|
67
|
+
_(representer.to_hash(user_options: {volume: 9})).must_equal({"name"=>"Live And Dangerous",
|
45
68
|
"songs"=>[{"title"=>"Jailbreak:{:volume=>9}"}, {"title"=>"Southbound:{:volume=>9}"}, {"title"=>"Emerald:{:volume=>9}"}]}) # called in Deserializer/Serializer
|
46
69
|
|
47
70
|
# representer becomes reusable as it is stateless.
|
@@ -55,36 +78,31 @@ class CachedTest < MiniTest::Spec
|
|
55
78
|
it do
|
56
79
|
representer.to_hash
|
57
80
|
|
58
|
-
|
59
|
-
representer.to_hash
|
60
|
-
res = RubyProf.stop
|
61
|
-
|
62
|
-
printer = RubyProf::FlatPrinter.new(res)
|
63
|
-
|
64
|
-
data = StringIO.new
|
65
|
-
printer.print(data)
|
66
|
-
data = data.string
|
67
|
-
|
68
|
-
printer.print(STDOUT)
|
81
|
+
data = Profiler.profile { representer.to_hash }
|
69
82
|
|
70
83
|
# 3 songs get decorated.
|
71
|
-
data.must_match
|
84
|
+
_(data).must_match(/3\s*Representable::Function::Decorate#call/m)
|
85
|
+
# These weird Regexp bellow are a quick workaround to accomodate
|
86
|
+
# the different profiler result formats.
|
87
|
+
# - "3 <Class::Representable::Decorator>#prepare" -> At MRI Ruby
|
88
|
+
# - "3 Representable::Decorator.prepare" -> At JRuby
|
89
|
+
|
72
90
|
# 3 nested decorator is instantiated for 3 Songs, though.
|
73
|
-
data.must_match
|
91
|
+
_(data).must_match(/3\s*(<Class::)?Representable::Decorator\>?[\#.]prepare/m)
|
74
92
|
# no Binding is instantiated at runtime.
|
75
|
-
data.wont_match "Representable::Binding#initialize"
|
93
|
+
_(data).wont_match "Representable::Binding#initialize"
|
76
94
|
# 2 mappers for Album, Song
|
77
95
|
# data.must_match "2 Representable::Mapper::Methods#initialize"
|
78
96
|
# title, songs, 3x title, composer
|
79
|
-
data.must_match
|
80
|
-
data.wont_match "render_functions"
|
81
|
-
data.wont_match "Representable::Binding::Factories#render_functions"
|
97
|
+
_(data).must_match(/8\s*Representable::Binding[#\.]render_pipeline/m)
|
98
|
+
_(data).wont_match "render_functions"
|
99
|
+
_(data).wont_match "Representable::Binding::Factories#render_functions"
|
82
100
|
end
|
83
101
|
end
|
84
102
|
|
85
103
|
|
86
104
|
describe "deserialization" do
|
87
|
-
let
|
105
|
+
let(:album_hash) {
|
88
106
|
{
|
89
107
|
"name"=>"Louder And Even More Dangerous",
|
90
108
|
"songs"=>[
|
@@ -100,14 +118,14 @@ class CachedTest < MiniTest::Spec
|
|
100
118
|
|
101
119
|
AlbumRepresenter.new(album).from_hash(album_hash)
|
102
120
|
|
103
|
-
album.songs.size.must_equal 3
|
104
|
-
album.name.must_equal "Louder And Even More Dangerous"
|
105
|
-
album.songs[0].title.must_equal "Southbound"
|
106
|
-
album.songs[0].composer.name.must_equal "Lynott"
|
107
|
-
album.songs[1].title.must_equal "Jailbreak"
|
108
|
-
album.songs[1].composer.name.must_equal "Phil Lynott"
|
109
|
-
album.songs[2].title.must_equal "Emerald"
|
110
|
-
album.songs[2].composer.
|
121
|
+
_(album.songs.size).must_equal 3
|
122
|
+
_(album.name).must_equal "Louder And Even More Dangerous"
|
123
|
+
_(album.songs[0].title).must_equal "Southbound"
|
124
|
+
_(album.songs[0].composer.name).must_equal "Lynott"
|
125
|
+
_(album.songs[1].title).must_equal "Jailbreak"
|
126
|
+
_(album.songs[1].composer.name).must_equal "Phil Lynott"
|
127
|
+
_(album.songs[2].title).must_equal "Emerald"
|
128
|
+
_(album.songs[2].composer).must_be_nil
|
111
129
|
|
112
130
|
# TODO: test options.
|
113
131
|
end
|
@@ -116,25 +134,17 @@ class CachedTest < MiniTest::Spec
|
|
116
134
|
representer = AlbumRepresenter.new(Model::Album.new)
|
117
135
|
representer.from_hash(album_hash)
|
118
136
|
|
119
|
-
|
120
|
-
# puts "#{representer.class.representable_attrs.get(:songs).representer_module.representable_attrs.inspect}"
|
121
|
-
representer.from_hash(album_hash)
|
122
|
-
res = RubyProf.stop
|
123
|
-
|
124
|
-
printer = RubyProf::FlatPrinter.new(res)
|
125
|
-
|
126
|
-
data = StringIO.new
|
127
|
-
printer.print(data)
|
128
|
-
data = data.string
|
137
|
+
data = Profiler.profile { representer.from_hash(album_hash) }
|
129
138
|
|
130
139
|
# only 2 nested decorators are instantiated, Song, and Artist.
|
131
|
-
|
140
|
+
# Didn't like the regexp?
|
141
|
+
# MRI and JRuby has different output formats. See note above.
|
142
|
+
_(data).must_match(/5\s*(<Class::)?Representable::Decorator>?[#\.]prepare/)
|
132
143
|
# a total of 5 properties in the object graph.
|
133
|
-
data.wont_match "Representable::Binding#initialize"
|
134
|
-
|
144
|
+
_(data).wont_match "Representable::Binding#initialize"
|
135
145
|
|
136
|
-
data.wont_match "parse_functions" # no pipeline creation.
|
137
|
-
data.must_match
|
146
|
+
_(data).wont_match "parse_functions" # no pipeline creation.
|
147
|
+
_(data).must_match(/10\s*Representable::Binding[#\.]parse_pipeline/)
|
138
148
|
# three mappers for Album, Song, composer
|
139
149
|
# data.must_match "3 Representable::Mapper::Methods#initialize"
|
140
150
|
# # 6 deserializers as the songs collection uses 2.
|
data/test/class_test.rb
CHANGED
@@ -20,8 +20,8 @@ class ClassTest < BaseTest
|
|
20
20
|
|
21
21
|
it "creates fresh instance and doesn't extend" do
|
22
22
|
song = representer.prepare(OpenStruct.new).from_hash({"song" => {"__name__" => "Captured"}}).song
|
23
|
-
song.must_be_instance_of RepresentingSong
|
24
|
-
song.name.must_equal "Captured"
|
23
|
+
_(song).must_be_instance_of RepresentingSong
|
24
|
+
_(song.name).must_equal "Captured"
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -33,8 +33,8 @@ class ClassTest < BaseTest
|
|
33
33
|
|
34
34
|
it "creates fresh instance and doesn't extend" do
|
35
35
|
song = representer.prepare(OpenStruct.new).from_hash({"song" => {"__name__" => "Captured"}}).song
|
36
|
-
song.must_be_instance_of RepresentingSong
|
37
|
-
song.name.must_equal "Captured"
|
36
|
+
_(song).must_be_instance_of RepresentingSong
|
37
|
+
_(song.name).must_equal "Captured"
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -54,7 +54,7 @@ class ClassTest < BaseTest
|
|
54
54
|
|
55
55
|
|
56
56
|
describe "lambda receiving fragment and args" do
|
57
|
-
let
|
57
|
+
let(:klass) { Class.new do
|
58
58
|
class << self
|
59
59
|
attr_accessor :args
|
60
60
|
end
|
@@ -69,13 +69,13 @@ class ClassTest < BaseTest
|
|
69
69
|
property :song, :class => lambda { |options| _klass.args=([options[:fragment],options[:user_options]]); _klass }
|
70
70
|
end
|
71
71
|
|
72
|
-
it { representer.prepare(OpenStruct.new).from_hash({"song" => {"name" => "Captured"}}, user_options: {volume: true}).song.class.args.
|
72
|
+
it { _(representer.prepare(OpenStruct.new).from_hash({"song" => {"name" => "Captured"}}, user_options: {volume: true}).song.class.args).
|
73
73
|
must_equal([{"name"=>"Captured"}, {:volume=>true}]) }
|
74
74
|
end
|
75
75
|
|
76
76
|
|
77
77
|
describe "collection: lambda receiving fragment and args" do
|
78
|
-
let
|
78
|
+
let(:klass) { Class.new do
|
79
79
|
class << self
|
80
80
|
attr_accessor :args
|
81
81
|
end
|
@@ -90,7 +90,7 @@ class ClassTest < BaseTest
|
|
90
90
|
collection :songs, :class => lambda { |options| _klass.args=([options[:fragment],options[:index],options[:user_options]]); _klass }
|
91
91
|
end
|
92
92
|
|
93
|
-
it { representer.prepare(OpenStruct.new).from_hash({"songs" => [{"name" => "Captured"}]}, user_options: {volume: true}).songs.first.class.args.
|
93
|
+
it { _(representer.prepare(OpenStruct.new).from_hash({"songs" => [{"name" => "Captured"}]}, user_options: {volume: true}).songs.first.class.args).
|
94
94
|
must_equal([{"name"=>"Captured"}, 0, {:volume=>true}]) }
|
95
95
|
end
|
96
96
|
|
@@ -109,7 +109,7 @@ class ClassTest < BaseTest
|
|
109
109
|
end
|
110
110
|
|
111
111
|
it "allows returning arbitrary objects in #from_hash" do
|
112
|
-
representer.prepare(OpenStruct.new).from_hash({"song" => 1}).song.must_equal [1,2,3,4]
|
112
|
+
_(representer.prepare(OpenStruct.new).from_hash({"song" => 1}).song).must_equal [1,2,3,4]
|
113
113
|
end
|
114
114
|
end
|
115
115
|
end
|
data/test/coercion_test.rb
CHANGED
@@ -1,52 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
require 'representable/coercion'
|
3
5
|
|
4
|
-
class
|
6
|
+
class CoercionTest < MiniTest::Spec
|
5
7
|
representer! do
|
6
8
|
include Representable::Coercion
|
7
9
|
|
8
10
|
property :title # no coercion.
|
9
|
-
property :length, :
|
11
|
+
property :length, type: Representable::Coercion::Types::Params::Float
|
10
12
|
|
11
|
-
property :band, :
|
12
|
-
property :founded, :
|
13
|
+
property :band, class: OpenStruct do
|
14
|
+
property :founded, type: Representable::Coercion::Types::Params::Integer
|
13
15
|
end
|
14
16
|
|
15
|
-
collection :songs, :
|
16
|
-
property :ok, :
|
17
|
+
collection :songs, class: OpenStruct do
|
18
|
+
property :ok, type: Representable::Coercion::Types::Params::Bool
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
20
|
-
let
|
21
|
-
|
22
|
-
|
22
|
+
let(:album) do
|
23
|
+
OpenStruct.new(title: 'Dire Straits', length: 41.34,
|
24
|
+
band: OpenStruct.new(founded: '1977'),
|
25
|
+
songs: [OpenStruct.new(ok: 1), OpenStruct.new(ok: 0)])
|
26
|
+
end
|
23
27
|
|
24
|
-
it
|
28
|
+
it do
|
29
|
+
_(album.extend(representer).to_hash).must_equal({ 'title' => 'Dire Straits',
|
30
|
+
'length' => 41.34,
|
31
|
+
'band' => { 'founded' => 1977 },
|
32
|
+
'songs' => [{ 'ok' => true }, { 'ok' => false }] })
|
33
|
+
end
|
25
34
|
|
26
35
|
it {
|
27
36
|
album = OpenStruct.new
|
28
37
|
album.extend(representer)
|
29
|
-
album.from_hash({
|
38
|
+
album.from_hash({ 'title' => 'Dire Straits',
|
39
|
+
'length' => '41.34',
|
40
|
+
'band' => { 'founded' => '1977' },
|
41
|
+
'songs' => [{ 'ok' => 1 }, { 'ok' => 0 }] })
|
30
42
|
|
31
43
|
# it
|
32
|
-
album.length.must_equal 41.34
|
33
|
-
album.band.founded.must_equal 1977
|
34
|
-
album.songs[0].ok.must_equal true
|
44
|
+
_(album.length).must_equal 41.34
|
45
|
+
_(album.band.founded).must_equal 1977
|
46
|
+
_(album.songs[0].ok).must_equal true
|
35
47
|
}
|
36
48
|
|
37
|
-
|
38
|
-
describe "with user :parse_filter and :render_filter" do
|
49
|
+
describe 'with user :parse_filter and :render_filter' do
|
39
50
|
representer! do
|
40
51
|
include Representable::Coercion
|
41
52
|
|
42
|
-
property :length, :
|
43
|
-
|
44
|
-
|
53
|
+
property :length, type: Representable::Coercion::Types::Params::Float,
|
54
|
+
parse_filter: ->(input, _options) { "#{input}.1" }, # happens BEFORE coercer.
|
55
|
+
render_filter: ->(fragment, *) { "#{fragment}.1" }
|
45
56
|
end
|
46
57
|
|
47
58
|
# user's :parse_filter(s) are run before coercion.
|
48
|
-
it { OpenStruct.new.extend(representer).from_hash(
|
59
|
+
it { _(OpenStruct.new.extend(representer).from_hash('length' => '1').length).must_equal 1.1 }
|
49
60
|
# user's :render_filter(s) are run before coercion.
|
50
|
-
it { OpenStruct.new(:
|
61
|
+
it { _(OpenStruct.new(length: 1).extend(representer).to_hash).must_equal({ 'length' => 1.1 }) }
|
51
62
|
end
|
52
|
-
end
|
63
|
+
end
|
data/test/config/inherit_test.rb
CHANGED
@@ -9,8 +9,8 @@ class ConfigInheritTest < MiniTest::Spec
|
|
9
9
|
|
10
10
|
child_def.merge!(:alias => property)
|
11
11
|
|
12
|
-
child_def[:alias].wont_equal parent_def[:alias]
|
13
|
-
child_def.object_id.wont_equal parent_def.object_id
|
12
|
+
_(child_def[:alias]).wont_equal parent_def[:alias]
|
13
|
+
_(child_def.object_id).wont_equal parent_def.object_id
|
14
14
|
end
|
15
15
|
# class Object
|
16
16
|
|
@@ -30,7 +30,7 @@ class ConfigInheritTest < MiniTest::Spec
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
it { Decorator.definitions.keys.must_equal ["title", "artist"] }
|
33
|
+
it { _(Decorator.definitions.keys).must_equal ["title", "artist"] }
|
34
34
|
|
35
35
|
# in inheriting Decorator
|
36
36
|
|
@@ -38,10 +38,10 @@ class ConfigInheritTest < MiniTest::Spec
|
|
38
38
|
property :location
|
39
39
|
end
|
40
40
|
|
41
|
-
it { InheritingDecorator.definitions.keys.must_equal ["title", "artist", "location"] }
|
41
|
+
it { _(InheritingDecorator.definitions.keys).must_equal ["title", "artist", "location"] }
|
42
42
|
it { assert_cloned(InheritingDecorator, Decorator, "title") }
|
43
43
|
it do
|
44
|
-
InheritingDecorator.representable_attrs.get(:artist).representer_module.object_id.wont_equal Decorator.representable_attrs.get(:artist).representer_module.object_id
|
44
|
+
_(InheritingDecorator.representable_attrs.get(:artist).representer_module.object_id).wont_equal Decorator.representable_attrs.get(:artist).representer_module.object_id
|
45
45
|
end
|
46
46
|
|
47
47
|
# in inheriting and including Decorator
|
@@ -51,7 +51,7 @@ class ConfigInheritTest < MiniTest::Spec
|
|
51
51
|
property :location
|
52
52
|
end
|
53
53
|
|
54
|
-
it { InheritingAndIncludingDecorator.definitions.keys.must_equal ["title", "artist", "genre", "location"] }
|
54
|
+
it { _(InheritingAndIncludingDecorator.definitions.keys).must_equal ["title", "artist", "genre", "location"] }
|
55
55
|
it { assert_cloned(InheritingAndIncludingDecorator, GenreModule, :genre) }
|
56
56
|
|
57
57
|
|
@@ -61,7 +61,7 @@ class ConfigInheritTest < MiniTest::Spec
|
|
61
61
|
property :title
|
62
62
|
end
|
63
63
|
|
64
|
-
it { Module.definitions.keys.must_equal ["title"] }
|
64
|
+
it { _(Module.definitions.keys).must_equal ["title"] }
|
65
65
|
|
66
66
|
|
67
67
|
# in module including module
|
@@ -72,7 +72,7 @@ class ConfigInheritTest < MiniTest::Spec
|
|
72
72
|
property :location
|
73
73
|
end
|
74
74
|
|
75
|
-
it { SubModule.definitions.keys.must_equal ["title", "location"] }
|
75
|
+
it { _(SubModule.definitions.keys).must_equal ["title", "location"] }
|
76
76
|
it { assert_cloned(SubModule, Module, :title) }
|
77
77
|
|
78
78
|
# including preserves order
|
@@ -84,7 +84,7 @@ class ConfigInheritTest < MiniTest::Spec
|
|
84
84
|
property :location
|
85
85
|
end
|
86
86
|
|
87
|
-
it { IncludingModule.definitions.keys.must_equal ["genre", "title", "location"] }
|
87
|
+
it { _(IncludingModule.definitions.keys).must_equal ["genre", "title", "location"] }
|
88
88
|
|
89
89
|
|
90
90
|
# included in class -------------------------------------------
|
@@ -93,7 +93,7 @@ class ConfigInheritTest < MiniTest::Spec
|
|
93
93
|
include IncludingModule
|
94
94
|
end
|
95
95
|
|
96
|
-
it { Class.definitions.keys.must_equal ["genre", "title", "location"] }
|
96
|
+
it { _(Class.definitions.keys).must_equal ["genre", "title", "location"] }
|
97
97
|
it { assert_cloned(Class, IncludingModule, :title) }
|
98
98
|
it { assert_cloned(Class, IncludingModule, :location) }
|
99
99
|
it { assert_cloned(Class, IncludingModule, :genre) }
|
@@ -105,7 +105,7 @@ class ConfigInheritTest < MiniTest::Spec
|
|
105
105
|
include IncludingModule
|
106
106
|
end
|
107
107
|
|
108
|
-
it { DefiningClass.definitions.keys.must_equal ["street_cred", "genre", "title", "location"] }
|
108
|
+
it { _(DefiningClass.definitions.keys).must_equal ["street_cred", "genre", "title", "location"] }
|
109
109
|
|
110
110
|
# in class
|
111
111
|
class RepresenterClass
|
@@ -113,7 +113,7 @@ class ConfigInheritTest < MiniTest::Spec
|
|
113
113
|
property :title
|
114
114
|
end
|
115
115
|
|
116
|
-
it { RepresenterClass.definitions.keys.must_equal ["title"] }
|
116
|
+
it { _(RepresenterClass.definitions.keys).must_equal ["title"] }
|
117
117
|
|
118
118
|
|
119
119
|
# in inheriting class
|
@@ -122,7 +122,7 @@ class ConfigInheritTest < MiniTest::Spec
|
|
122
122
|
property :location
|
123
123
|
end
|
124
124
|
|
125
|
-
it { InheritingClass.definitions.keys.must_equal ["title", "location"] }
|
125
|
+
it { _(InheritingClass.definitions.keys).must_equal ["title", "location"] }
|
126
126
|
it { assert_cloned(InheritingClass, RepresenterClass, :title) }
|
127
127
|
|
128
128
|
# in inheriting class and including
|
@@ -131,5 +131,5 @@ class ConfigInheritTest < MiniTest::Spec
|
|
131
131
|
include GenreModule
|
132
132
|
end
|
133
133
|
|
134
|
-
it { InheritingAndIncludingClass.definitions.keys.must_equal ["title", "location", "genre"] }
|
134
|
+
it { _(InheritingAndIncludingClass.definitions.keys).must_equal ["title", "location", "genre"] }
|
135
135
|
end
|