representable 3.0.0 → 3.2.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 (103) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +23 -0
  3. data/CHANGES.md +33 -0
  4. data/Gemfile +4 -12
  5. data/LICENSE +1 -1
  6. data/README.md +12 -13
  7. data/Rakefile +1 -6
  8. data/TODO +1 -3
  9. data/TODO-4.0.md +72 -0
  10. data/lib/representable/binding.rb +32 -12
  11. data/lib/representable/cached.rb +1 -1
  12. data/lib/representable/coercion.rb +8 -6
  13. data/lib/representable/config.rb +13 -3
  14. data/lib/representable/debug.rb +23 -15
  15. data/lib/representable/declarative.rb +12 -7
  16. data/lib/representable/decorator.rb +1 -1
  17. data/lib/representable/definition.rb +7 -3
  18. data/lib/representable/deserializer.rb +5 -4
  19. data/lib/representable/for_collection.rb +1 -1
  20. data/lib/representable/hash/allow_symbols.rb +9 -11
  21. data/lib/representable/hash/binding.rb +1 -0
  22. data/lib/representable/hash/collection.rb +4 -2
  23. data/lib/representable/hash.rb +9 -2
  24. data/lib/representable/hash_methods.rb +3 -2
  25. data/lib/representable/insert.rb +1 -1
  26. data/lib/representable/json/collection.rb +3 -0
  27. data/lib/representable/json.rb +8 -7
  28. data/lib/representable/object/binding.rb +5 -1
  29. data/lib/representable/object.rb +1 -1
  30. data/lib/representable/option.rb +19 -0
  31. data/lib/representable/pipeline.rb +3 -2
  32. data/lib/representable/pipeline_factories.rb +4 -2
  33. data/lib/representable/populator.rb +1 -1
  34. data/lib/representable/represent.rb +1 -0
  35. data/lib/representable/serializer.rb +3 -2
  36. data/lib/representable/version.rb +1 -1
  37. data/lib/representable/xml/binding.rb +19 -13
  38. data/lib/representable/xml/namespace.rb +122 -0
  39. data/lib/representable/xml.rb +12 -10
  40. data/lib/representable/yaml/binding.rb +1 -0
  41. data/lib/representable/yaml.rb +6 -2
  42. data/lib/representable.rb +19 -25
  43. data/representable.gemspec +8 -9
  44. data/test/as_test.rb +7 -7
  45. data/test/binding_test.rb +14 -14
  46. data/test/cached_test.rb +59 -49
  47. data/test/class_test.rb +9 -9
  48. data/test/coercion_test.rb +33 -22
  49. data/test/config/inherit_test.rb +14 -14
  50. data/test/config_test.rb +20 -20
  51. data/test/decorator_scope_test.rb +4 -4
  52. data/test/decorator_test.rb +33 -20
  53. data/test/default_test.rb +8 -8
  54. data/test/defaults_options_test.rb +3 -3
  55. data/test/definition_test.rb +38 -40
  56. data/test/{example.rb → examples/example.rb} +0 -1
  57. data/test/examples/object.rb +1 -5
  58. data/test/exec_context_test.rb +8 -8
  59. data/test/features_test.rb +6 -6
  60. data/test/filter_test.rb +8 -8
  61. data/test/for_collection_test.rb +10 -10
  62. data/test/generic_test.rb +13 -13
  63. data/test/getter_setter_test.rb +5 -5
  64. data/test/hash_bindings_test.rb +1 -1
  65. data/test/hash_test.rb +45 -23
  66. data/test/heritage_test.rb +16 -13
  67. data/test/if_test.rb +9 -9
  68. data/test/include_exclude_test.rb +14 -14
  69. data/test/inherit_test.rb +18 -18
  70. data/test/inline_test.rb +24 -24
  71. data/test/instance_test.rb +31 -31
  72. data/test/is_representable_test.rb +10 -10
  73. data/test/json_test.rb +29 -7
  74. data/test/lonely_test.rb +31 -31
  75. data/test/nested_test.rb +13 -13
  76. data/test/object_test.rb +9 -9
  77. data/test/option_test.rb +36 -0
  78. data/test/parse_pipeline_test.rb +3 -5
  79. data/test/pipeline_test.rb +50 -50
  80. data/test/populator_test.rb +18 -18
  81. data/test/prepare_test.rb +4 -4
  82. data/test/private_options_test.rb +2 -2
  83. data/test/reader_writer_test.rb +2 -2
  84. data/test/render_nil_test.rb +2 -2
  85. data/test/represent_test.rb +14 -14
  86. data/test/representable_test.rb +34 -36
  87. data/test/schema_test.rb +8 -11
  88. data/test/serialize_deserialize_test.rb +2 -2
  89. data/test/skip_test.rb +14 -14
  90. data/test/stringify_hash_test.rb +3 -3
  91. data/test/test_helper.rb +26 -14
  92. data/test/uncategorized_test.rb +10 -10
  93. data/test/user_options_test.rb +4 -4
  94. data/test/wrap_test.rb +19 -19
  95. data/test/xml_bindings_test.rb +0 -4
  96. data/test/xml_namespace_test.rb +186 -0
  97. data/test/xml_test.rb +103 -43
  98. data/test/yaml_test.rb +51 -26
  99. metadata +42 -35
  100. data/.travis.yml +0 -7
  101. data/lib/representable/TODO.getting_serious +0 -11
  102. data/lib/representable/autoload.rb +0 -10
  103. data/test/mongoid_test.rb +0 -31
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.platform = Gem::Platform::RUBY
10
10
  spec.authors = ["Nick Sutterer"]
11
11
  spec.email = ["apotonick@gmail.com"]
12
- spec.homepage = "https://github.com/apotonick/representable/"
12
+ spec.homepage = "https://github.com/trailblazer/representable/"
13
13
  spec.summary = %q{Renders and parses JSON/XML/YAML documents from and to Ruby objects. Includes plain properties, collections, nesting, coercion and more.}
14
14
  spec.description = spec.summary
15
15
 
@@ -19,17 +19,16 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
  spec.license = "MIT"
21
21
 
22
- spec.required_ruby_version = '>= 1.9.3'
22
+ spec.required_ruby_version = '>= 2.4.0'
23
23
 
24
- spec.add_dependency "uber", "~> 0.0.15"
25
- spec.add_dependency "declarative", "~> 0.0.5"
24
+ spec.add_dependency "uber", "< 0.2.0"
25
+ spec.add_dependency "declarative", "< 0.1.0"
26
+ spec.add_dependency "trailblazer-option", ">= 0.1.1", "< 0.2.0"
26
27
 
27
28
  spec.add_development_dependency "rake"
28
- spec.add_development_dependency "test_xml", "0.1.6"
29
+ spec.add_development_dependency "test_xml", ">= 0.1.6"
29
30
  spec.add_development_dependency "minitest"
30
- spec.add_development_dependency "mongoid"
31
31
  spec.add_development_dependency "virtus"
32
- spec.add_development_dependency "json", '>= 1.7.7'
33
-
34
- spec.add_development_dependency "ruby-prof"
32
+ spec.add_development_dependency "dry-types"
33
+ spec.add_development_dependency "ruby-prof" if RUBY_ENGINE == "ruby" # mri
35
34
  end
data/test/as_test.rb CHANGED
@@ -7,8 +7,8 @@ class AsTest < MiniTest::Spec
7
7
  # :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"],
8
8
  ) do |format, mod, input, output|
9
9
 
10
- let (:song) { representer.prepare(Song.new("Revolution")) }
11
- let (:format) { format }
10
+ let(:song) { representer.prepare(Song.new("Revolution")) }
11
+ let(:format) { format }
12
12
 
13
13
 
14
14
  describe "as: with :symbol" do
@@ -17,7 +17,7 @@ class AsTest < MiniTest::Spec
17
17
  end
18
18
 
19
19
  it { render(song).must_equal_document output }
20
- it { parse(song, input).name.must_equal "Wie Es Geht" }
20
+ it { _(parse(song, input).name).must_equal "Wie Es Geht" }
21
21
  end
22
22
 
23
23
 
@@ -27,7 +27,7 @@ class AsTest < MiniTest::Spec
27
27
  end
28
28
 
29
29
  it { render(song).must_equal_document({"Song" => "Revolution"}) }
30
- it { parse(song, {"Song" => "Wie Es Geht"}).name.must_equal "Wie Es Geht" }
30
+ it { _(parse(song, {"Song" => "Wie Es Geht"}).name).must_equal "Wie Es Geht" }
31
31
  end
32
32
 
33
33
 
@@ -37,7 +37,7 @@ class AsTest < MiniTest::Spec
37
37
  end
38
38
 
39
39
  it { render(song, user_options:{volume: 1}).must_equal_document({"{:volume=>1}" => "Revolution"}) }
40
- it { parse(song, {"{:volume=>1}" => "Wie Es Geht"}, user_options: {volume: 1}).name.must_equal "Wie Es Geht" }
40
+ it { _(parse(song, {"{:volume=>1}" => "Wie Es Geht"}, user_options: {volume: 1}).name).must_equal "Wie Es Geht" }
41
41
  end
42
42
  end
43
43
  end
@@ -60,6 +60,6 @@ class AsXmlTest < MiniTest::Spec
60
60
 
61
61
  it do
62
62
  skip
63
- representer.new(Album.new(Band.new("Offspring"))).to_xml.must_equal ""
63
+ _(representer.new(Album.new(Band.new("Offspring"))).to_xml).must_equal ""
64
64
  end
65
- end
65
+ end
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 (:render_nil_definition) { Representable::Definition.new(:song, :render_nil => true) }
5
+ let(:render_nil_definition) { Representable::Definition.new(:song, :render_nil => true) }
6
6
 
7
7
  describe "#skipable_empty_value?" do
8
- let (:binding) { Binding.new(render_nil_definition) }
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 (:definition) { Representable::Definition.new(:song, :default => "Insider") }
26
- let (:binding) { Binding.new(definition) }
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).must_equal 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).must_equal 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).must_equal 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
- require 'ruby-prof'
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 (:album_hash) { {"name"=>"Louder And Even More Dangerous", "songs"=>[{"title"=>"Southbound:{:volume=>10}"}, {"title"=>"Jailbreak:{:volume=>10}"}]} }
56
+ let(:album_hash) { {"name"=>"Louder And Even More Dangerous", "songs"=>[{"title"=>"Southbound:{:volume=>10}"}, {"title"=>"Jailbreak:{:volume=>10}"}]} }
34
57
 
35
- let (:song) { Model::Song.new("Jailbreak") }
36
- let (:song2) { Model::Song.new("Southbound") }
37
- let (:album) { Model::Album.new("Live And Dangerous", [song, song2, Model::Song.new("Emerald")]) }
38
- let (:representer) { AlbumRepresenter.new(album) }
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
- RubyProf.start
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 "3 Representable::Function::Decorate#call"
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 "3 <Class::Representable::Decorator>#prepare"
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 "8 Representable::Binding#render_pipeline"
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 (:album_hash) {
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.must_equal nil
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
- RubyProf.start
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
- data.must_match "5 <Class::Representable::Decorator>#prepare"
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 "10 Representable::Binding#parse_pipeline"
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 (:klass) { Class.new do
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 (:klass) { Class.new do
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
@@ -1,52 +1,63 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
  require 'representable/coercion'
3
5
 
4
- class VirtusCoercionTest < MiniTest::Spec
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, :type => Float
11
+ property :length, type: Representable::Coercion::Types::Params::Float
10
12
 
11
- property :band, :class => OpenStruct do
12
- property :founded, :type => Integer
13
+ property :band, class: OpenStruct do
14
+ property :founded, type: Representable::Coercion::Types::Params::Integer
13
15
  end
14
16
 
15
- collection :songs, :class => OpenStruct do
16
- property :ok, :type => Virtus::Attribute::Boolean
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 (:album) { OpenStruct.new(:title => "Dire Straits", :length => 41.34,
21
- :band => OpenStruct.new(:founded => "1977"),
22
- :songs => [OpenStruct.new(:ok => 1), OpenStruct.new(:ok => 0)]) }
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 { album.extend(representer).to_hash.must_equal({"title"=>"Dire Straits", "length"=>41.34, "band"=>{"founded"=>1977}, "songs"=>[{"ok"=>true}, {"ok"=>false}]}) }
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({"title"=>"Dire Straits", "length"=>"41.34", "band"=>{"founded"=>"1977"}, "songs"=>[{"ok"=>1}, {"ok"=>0}]})
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, :type => Float,
43
- :parse_filter => lambda { |input, options| "#{input}.1" }, # happens BEFORE coercer.
44
- :render_filter => lambda { |fragment,*| "#{fragment}.1" }
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("length"=>"1").length.must_equal 1.1 }
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(:length=>1).extend(representer).to_hash.must_equal({"length" => 1.1}) }
61
+ it { _(OpenStruct.new(length: 1).extend(representer).to_hash).must_equal({ 'length' => 1.1 }) }
51
62
  end
52
- end
63
+ end
@@ -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