representable 3.2.0 → 3.3.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +17 -10
  3. data/.github/workflows/ci_jruby.yml +21 -0
  4. data/.github/workflows/ci_truffleruby.yml +19 -0
  5. data/CHANGES.md +5 -0
  6. data/Gemfile +1 -1
  7. data/README.md +0 -1
  8. data/lib/representable/hash/binding.rb +1 -0
  9. data/lib/representable/json.rb +14 -2
  10. data/lib/representable/version.rb +1 -1
  11. data/lib/representable/xml/binding.rb +0 -7
  12. data/lib/representable/xml.rb +7 -0
  13. data/representable.gemspec +1 -3
  14. data/test/as_test.rb +8 -13
  15. data/test/benchmarking.rb +20 -25
  16. data/test/binding_test.rb +13 -5
  17. data/test/cached_test.rb +55 -35
  18. data/test/class_test.rb +46 -33
  19. data/test/coercion_test.rb +29 -19
  20. data/test/config/inherit_test.rb +12 -17
  21. data/test/config_test.rb +5 -7
  22. data/test/decorator_scope_test.rb +13 -11
  23. data/test/decorator_test.rb +11 -11
  24. data/test/default_test.rb +2 -2
  25. data/test/defaults_options_test.rb +37 -9
  26. data/test/definition_test.rb +10 -12
  27. data/test/examples/example.rb +43 -38
  28. data/test/examples/object.rb +7 -6
  29. data/test/exec_context_test.rb +18 -23
  30. data/test/features_test.rb +29 -10
  31. data/test/filter_test.rb +29 -20
  32. data/test/for_collection_test.rb +12 -15
  33. data/test/generic_test.rb +15 -22
  34. data/test/getter_setter_test.rb +11 -6
  35. data/test/hash_bindings_test.rb +21 -12
  36. data/test/hash_test.rb +53 -38
  37. data/test/heritage_test.rb +0 -1
  38. data/test/if_test.rb +25 -21
  39. data/test/include_exclude_test.rb +24 -16
  40. data/test/inherit_test.rb +114 -27
  41. data/test/inline_test.rb +42 -33
  42. data/test/instance_test.rb +151 -109
  43. data/test/is_representable_test.rb +19 -17
  44. data/test/json_test.rb +48 -46
  45. data/test/lonely_test.rb +35 -33
  46. data/test/nested_test.rb +16 -19
  47. data/test/object_test.rb +6 -6
  48. data/test/option_test.rb +10 -8
  49. data/test/parse_pipeline_test.rb +21 -15
  50. data/test/pipeline_test.rb +144 -108
  51. data/test/populator_test.rb +18 -15
  52. data/test/prepare_test.rb +15 -17
  53. data/test/private_options_test.rb +3 -2
  54. data/test/reader_writer_test.rb +4 -4
  55. data/test/realistic_benchmark.rb +21 -27
  56. data/test/render_nil_test.rb +1 -1
  57. data/test/represent_test.rb +14 -18
  58. data/test/representable_test.rb +86 -53
  59. data/test/schema_test.rb +51 -21
  60. data/test/serialize_deserialize_test.rb +14 -14
  61. data/test/skip_test.rb +39 -28
  62. data/test/stringify_hash_test.rb +29 -31
  63. data/test/test_helper.rb +31 -25
  64. data/test/test_helper_test.rb +7 -7
  65. data/test/uncategorized_test.rb +20 -15
  66. data/test/user_options_test.rb +12 -3
  67. data/test/wrap_test.rb +27 -17
  68. data/test/xml_assertions.rb +29 -0
  69. data/test/xml_bindings_test.rb +5 -8
  70. data/test/xml_namespace_test.rb +46 -39
  71. data/test/xml_test.rb +109 -88
  72. data/test/yaml_test.rb +73 -51
  73. metadata +7 -32
data/test/inherit_test.rb CHANGED
@@ -1,7 +1,8 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
- class InheritTest < MiniTest::Spec
4
- module SongRepresenter # it's important to have a global module so we can test if stuff gets overridden in the original module.
3
+ class InheritTest < Minitest::Spec
4
+ # it's important to have a global module so we can test if stuff gets overridden in the original module.
5
+ module SongRepresenter
5
6
  include Representable::Hash
6
7
  property :name, :as => :title do
7
8
  property :string, :as => :str
@@ -16,11 +17,11 @@ class InheritTest < MiniTest::Spec
16
17
  representer! do
17
18
  include SongRepresenter
18
19
 
19
- property :track, :inherit => true, :getter => lambda { |*| "n/a" }
20
+ property :track, :inherit => true, :getter => ->(*) { "n/a" }
20
21
  end
21
22
 
22
- it { _(SongRepresenter.prepare(song).to_hash).must_equal({"title"=>{"str"=>"Roxanne"}, "no"=>1}) }
23
- it { _(representer.prepare(song).to_hash).must_equal({"title"=>{"str"=>"Roxanne"}, "no"=>"n/a"}) } # as: inherited.
23
+ it { _(SongRepresenter.prepare(song).to_hash).must_equal({"title" => {"str"=>"Roxanne"}, "no" => 1}) }
24
+ it { _(representer.prepare(song).to_hash).must_equal({"title" => {"str"=>"Roxanne"}, "no" => "n/a"}) } # as: inherited.
24
25
  end
25
26
 
26
27
  describe ":inherit with empty inline representer" do
@@ -32,9 +33,27 @@ class InheritTest < MiniTest::Spec
32
33
  end
33
34
  end
34
35
 
35
- it { _(SongRepresenter.prepare(Song.new(Struct.new(:string).new("Believe It"), 1)).to_hash).must_equal({"title"=>{"str"=>"Believe It"}, "no"=>1}) }
36
+ it {
37
+ _(
38
+ SongRepresenter.prepare(
39
+ Song.new(
40
+ Struct.new(:string).new("Believe It"),
41
+ 1
42
+ )
43
+ ).to_hash
44
+ ).must_equal({"title" => {"str"=>"Believe It"}, "no" => 1})
45
+ }
36
46
  # the block doesn't override the inline representer.
37
- it { _(representer.prepare( Song.new(Struct.new(:string).new("Believe It"), 1)).to_hash).must_equal({"title"=>{"str"=>"Believe It"}, "no"=>1}) }
47
+ it {
48
+ _(
49
+ representer.prepare(
50
+ Song.new(
51
+ Struct.new(:string).new("Believe It"),
52
+ 1
53
+ )
54
+ ).to_hash
55
+ ).must_equal({"title" => {"str"=>"Believe It"}, "no" => 1})
56
+ }
38
57
  end
39
58
 
40
59
  describe ":inherit with overriding inline representer" do
@@ -48,7 +67,16 @@ class InheritTest < MiniTest::Spec
48
67
  end
49
68
  end
50
69
 
51
- it { _(representer.prepare( Song.new(Struct.new(:string, :length).new("Believe It", 10), 1)).to_hash).must_equal({"title"=>{"s"=>"Believe It","length"=>10}, "no"=>1}) }
70
+ it {
71
+ _(
72
+ representer.prepare(
73
+ Song.new(
74
+ Struct.new(:string, :length).new("Believe It", 10),
75
+ 1
76
+ )
77
+ ).to_hash
78
+ ).must_equal({"title" => {"s" => "Believe It", "length" => 10}, "no" => 1})
79
+ }
52
80
  end
53
81
 
54
82
  describe ":inherit with empty inline and options" do
@@ -60,8 +88,26 @@ class InheritTest < MiniTest::Spec
60
88
  end
61
89
  end
62
90
 
63
- it { _(SongRepresenter.prepare(Song.new(Struct.new(:string).new("Believe It"), 1)).to_hash).must_equal({"title"=>{"str"=>"Believe It"}, "no"=>1}) }
64
- it { _(representer.prepare( Song.new(Struct.new(:string).new("Believe It"), 1)).to_hash).must_equal({"name"=>{"str"=>"Believe It"}, "no"=>1}) }
91
+ it {
92
+ _(
93
+ SongRepresenter.prepare(
94
+ Song.new(
95
+ Struct.new(:string).new("Believe It"),
96
+ 1
97
+ )
98
+ ).to_hash
99
+ ).must_equal({"title" => {"str"=>"Believe It"}, "no" => 1})
100
+ }
101
+ it {
102
+ _(
103
+ representer.prepare(
104
+ Song.new(
105
+ Struct.new(:string).new("Believe It"),
106
+ 1
107
+ )
108
+ ).to_hash
109
+ ).must_equal({"name" => {"str"=>"Believe It"}, "no" => 1})
110
+ }
65
111
  end
66
112
 
67
113
  describe ":inherit with inline without block but options" do
@@ -71,12 +117,28 @@ class InheritTest < MiniTest::Spec
71
117
  property :name, :inherit => true, :as => :name # FIXME: add :getter or something else dynamic since this is double-wrapped.
72
118
  end
73
119
 
74
- it { _(SongRepresenter.prepare(Song.new(Struct.new(:string).new("Believe It"), 1)).to_hash).must_equal({"title"=>{"str"=>"Believe It"}, "no"=>1}) }
75
- it { _(representer.prepare( Song.new(Struct.new(:string).new("Believe It"), 1)).to_hash).must_equal({"name"=>{"str"=>"Believe It"}, "no"=>1}) }
120
+ it {
121
+ _(
122
+ SongRepresenter.prepare(
123
+ Song.new(
124
+ Struct.new(:string).new("Believe It"),
125
+ 1
126
+ )
127
+ ).to_hash
128
+ ).must_equal({"title" => {"str"=>"Believe It"}, "no" => 1})
129
+ }
130
+ it {
131
+ _(
132
+ representer.prepare(
133
+ Song.new(
134
+ Struct.new(:string).new("Believe It"),
135
+ 1
136
+ )
137
+ ).to_hash
138
+ ).must_equal({"name" => {"str"=>"Believe It"}, "no" => 1})
139
+ }
76
140
  end
77
141
 
78
-
79
-
80
142
  # no :inherit
81
143
  describe "overwriting without :inherit" do
82
144
  representer! do
@@ -90,12 +152,11 @@ class InheritTest < MiniTest::Spec
90
152
 
91
153
  definition = representer.representable_attrs.get(:track) # TODO: find a better way to assert Definition identity.
92
154
  # definition.keys.size.must_equal 2
93
- _(definition[:representable]). must_equal true
155
+ _(definition[:representable]).must_equal true
94
156
  _(definition.name).must_equal "track" # was "no".
95
157
  end
96
158
  end
97
159
 
98
-
99
160
  # decorator
100
161
  describe ":inherit with decorator" do
101
162
  representer!(:decorator => true) do
@@ -108,7 +169,7 @@ class InheritTest < MiniTest::Spec
108
169
  end
109
170
  end
110
171
 
111
- let(:inheriting) {
172
+ let(:inheriting) do
112
173
  class InheritingDecorator < representer
113
174
  include Representable::Debug
114
175
  property :hit, :inherit => true do
@@ -117,30 +178,56 @@ class InheritTest < MiniTest::Spec
117
178
  end
118
179
  self
119
180
  end
120
- }
181
+ end
121
182
 
122
- it { _(representer.new(OpenStruct.new(hit: OpenStruct.new(title: "I WILL BE OVERRIDDEN", :length => "2:59"))).to_hash).must_equal(
123
- {"hit"=>{"title"=>"Cheap Transistor Radio"}}) }
183
+ it {
184
+ _(
185
+ representer.new(
186
+ OpenStruct.new(
187
+ hit: OpenStruct.new(
188
+ title: "I WILL BE OVERRIDDEN",
189
+ :length => "2:59"
190
+ )
191
+ )
192
+ ).to_hash
193
+ ).must_equal(
194
+ {"hit"=>{"title"=>"Cheap Transistor Radio"}}
195
+ )
196
+ }
124
197
 
125
198
  # inheriting decorator inherits inline representer class (InlineRepresenter#title).
126
199
  # inheriting decorator adds :length.
127
- it { _(inheriting.new(OpenStruct.new(:hit => OpenStruct.new(:title => "Hole In Your Soul", :length => "2:59"))).to_hash).must_equal(
128
- {"hit"=>{"title"=>"Cheap Transistor Radio", "length"=>"2:59"}}) }
200
+ it {
201
+ _(
202
+ inheriting.new(
203
+ OpenStruct.new(
204
+ :hit => OpenStruct.new(
205
+ :title => "Hole In Your Soul",
206
+ :length => "2:59"
207
+ )
208
+ )
209
+ ).to_hash
210
+ ).must_equal(
211
+ {
212
+ "hit" => {
213
+ "title" => "Cheap Transistor Radio", "length" => "2:59"
214
+ }
215
+ }
216
+ )
217
+ }
129
218
  end
130
219
 
131
-
132
220
  # :inherit when property doesn't exist, yet.
133
221
  describe ":inherit without inheritable property" do
134
222
  representer! do
135
223
  property :name, :inherit => true
136
224
  end
137
225
 
138
- it { _(representer.prepare(Song.new("The Beginning")).to_hash).must_equal({"name"=>"The Beginning"})}
226
+ it { _(representer.prepare(Song.new("The Beginning")).to_hash).must_equal({"name"=>"The Beginning"}) }
139
227
  end
140
228
  end
141
229
 
142
-
143
- # class InheritancingTest < MiniTest::Spec
230
+ # class InheritancingTest < Minitest::Spec
144
231
  # class SongDecorator < Representable::Decorator
145
232
  # include Representable::Hash
146
233
  # property :album do
data/test/inline_test.rb CHANGED
@@ -1,14 +1,17 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
- class InlineTest < MiniTest::Spec
3
+ class InlineTest < Minitest::Spec
4
4
  let(:song) { Song.new("Alive") }
5
5
  let(:request) { representer.prepare(OpenStruct.new(:song => song)) }
6
6
 
7
7
  {
8
8
  :hash => [Representable::Hash, {"song"=>{"name"=>"Alive"}}, {"song"=>{"name"=>"You've Taken Everything"}}],
9
9
  :json => [Representable::JSON, "{\"song\":{\"name\":\"Alive\"}}", "{\"song\":{\"name\":\"You've Taken Everything\"}}"],
10
- :xml => [Representable::XML, "<open_struct>\n <song>\n <name>Alive</name>\n </song>\n</open_struct>", "<open_struct><song><name>You've Taken Everything</name></song>/open_struct>"],
11
- :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"],
10
+ :xml => [
11
+ Representable::XML, "<open_struct>\n <song>\n <name>Alive</name>\n </song>\n</open_struct>",
12
+ "<open_struct><song><name>You've Taken Everything</name></song>/open_struct>"
13
+ ],
14
+ :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"]
12
15
  }.each do |format, cfg|
13
16
  mod, output, input = cfg
14
17
 
@@ -22,15 +25,18 @@ class InlineTest < MiniTest::Spec
22
25
  let(:format) { format }
23
26
 
24
27
  it { render(request).must_equal_document output }
25
- it { _(parse(request, input).song.name).must_equal "You've Taken Everything"}
28
+ it { _(parse(request, input).song.name).must_equal "You've Taken Everything" }
26
29
  end
27
30
  end
28
31
 
29
32
  {
30
33
  :hash => [Representable::Hash, {"songs"=>[{"name"=>"Alive"}]}, {"songs"=>[{"name"=>"You've Taken Everything"}]}],
31
34
  :json => [Representable::JSON, "{\"songs\":[{\"name\":\"Alive\"}]}", "{\"songs\":[{\"name\":\"You've Taken Everything\"}]}"],
32
- :xml => [Representable::XML, "<open_struct>\n <song>\n <name>Alive</name>\n </song>\n</open_struct>", "<open_struct><song><name>You've Taken Everything</name></song></open_struct>", { :as => :song }],
33
- :yaml => [Representable::YAML, "---\nsongs:\n- name: Alive\n", "---\nsongs:\n- name: You've Taken Everything\n"],
35
+ :xml => [
36
+ Representable::XML, "<open_struct>\n <song>\n <name>Alive</name>\n </song>\n</open_struct>",
37
+ "<open_struct><song><name>You've Taken Everything</name></song></open_struct>", {:as => :song}
38
+ ],
39
+ :yaml => [Representable::YAML, "---\nsongs:\n- name: Alive\n", "---\nsongs:\n- name: You've Taken Everything\n"]
34
40
  }.each do |format, cfg|
35
41
  mod, output, input, collection_options = cfg
36
42
  collection_options ||= {}
@@ -47,7 +53,7 @@ class InlineTest < MiniTest::Spec
47
53
  let(:format) { format } # FIXME: why do we have to define this?
48
54
 
49
55
  it { render(request).must_equal_document output }
50
- it { _(parse(request, input).songs.first.name).must_equal "You've Taken Everything"}
56
+ it { _(parse(request, input).songs.first.name).must_equal "You've Taken Everything" }
51
57
  end
52
58
  end
53
59
 
@@ -61,13 +67,11 @@ class InlineTest < MiniTest::Spec
61
67
  it { _(request.to_hash).must_equal({"song"=>{"name"=>"Alive"}}) }
62
68
  end
63
69
 
64
-
65
70
  for_formats(
66
- :hash => [Representable::Hash, {}],
71
+ :hash => [Representable::Hash, {}]
67
72
  # :xml => [Representable::XML, "<open_struct>\n <song>\n <name>Alive</name>\n </song>\n</open_struct>", "<open_struct><song><name>You've Taken Everything</name></song>/open_struct>"],
68
73
  # :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"],
69
74
  ) do |format, mod, input|
70
-
71
75
  describe "parsing [#{format}] where nested property missing" do
72
76
  representer!(:module => mod) do
73
77
  property :song do
@@ -81,7 +85,6 @@ class InlineTest < MiniTest::Spec
81
85
  end
82
86
  end
83
87
 
84
-
85
88
  describe "inheriting from outer representer" do
86
89
  let(:request) { Struct.new(:song, :requester).new(song, "Josephine") }
87
90
 
@@ -96,8 +99,8 @@ class InlineTest < MiniTest::Spec
96
99
 
97
100
  let(:decorator) { representer.prepare(request) }
98
101
 
99
- it { _(decorator.to_hash).must_equal({"requester"=>"Josephine", "song"=>{"name"=>"Alive"}}) }
100
- it { _(decorator.from_hash({"song"=>{"name"=>"You've Taken Everything"}}).song.name).must_equal "You've Taken Everything"}
102
+ it { _(decorator.to_hash).must_equal({"requester" => "Josephine", "song" => {"name"=>"Alive"}}) }
103
+ it { _(decorator.from_hash({"song"=>{"name"=>"You've Taken Everything"}}).song.name).must_equal "You've Taken Everything" }
101
104
  end
102
105
  end
103
106
 
@@ -144,13 +147,13 @@ class InlineTest < MiniTest::Spec
144
147
  # end
145
148
  # end
146
149
 
147
-
148
- for_formats({
149
- :hash => [Representable::Hash, {"album" => {"artist" => {"label"=>"Epitaph"}}}],
150
+ for_formats(
151
+ {
152
+ :hash => [Representable::Hash, {"album" => {"artist" => {"label"=>"Epitaph"}}}]
150
153
  # :xml => [Representable::XML, "<open_struct></open_struct>"],
151
- #:yaml => [Representable::YAML, "---\nlabel:\n label: Epitaph\n owner: Brett Gurewitz\n"]
152
- }) do |format, mod, output, input|
153
-
154
+ # :yaml => [Representable::YAML, "---\nlabel:\n label: Epitaph\n owner: Brett Gurewitz\n"]
155
+ }
156
+ ) do |format, mod, output, _input|
154
157
  class ArtistDecorator < Representable::Decorator
155
158
  include Representable::JSON
156
159
  property :label
@@ -162,7 +165,7 @@ class InlineTest < MiniTest::Spec
162
165
  representer!(:module => mod) do
163
166
  self.representation_wrap = "album"
164
167
 
165
- property :artist, :getter => lambda { |args| represented }, :decorator => ArtistDecorator
168
+ property :artist, :getter => ->(_args) { represented }, :decorator => ArtistDecorator
166
169
  end
167
170
 
168
171
  let(:album) { OpenStruct.new(:label => "Epitaph").extend(representer) }
@@ -173,14 +176,14 @@ class InlineTest < MiniTest::Spec
173
176
  end
174
177
  end
175
178
 
176
-
177
179
  # test helper methods within inline representer
178
- for_formats({
179
- :hash => [Representable::Hash, {"song"=>{"name"=>"ALIVE"}}],
180
- :xml => [Representable::XML, "<request>\n <song>\n <name>ALIVE</name>\n </song>\n</request>"],
181
- :yaml => [Representable::YAML, "---\nsong:\n name: ALIVE\n"],
182
- }) do |format, mod, output|
183
-
180
+ for_formats(
181
+ {
182
+ :hash => [Representable::Hash, {"song"=>{"name"=>"ALIVE"}}],
183
+ :xml => [Representable::XML, "<request>\n <song>\n <name>ALIVE</name>\n </song>\n</request>"],
184
+ :yaml => [Representable::YAML, "---\nsong:\n name: ALIVE\n"]
185
+ }
186
+ ) do |format, mod, output|
184
187
  describe "helper method within inline representer [#{format}]" do
185
188
  let(:format) { format }
186
189
 
@@ -207,7 +210,6 @@ class InlineTest < MiniTest::Spec
207
210
  end
208
211
  end
209
212
 
210
-
211
213
  describe "include module in inline representers" do
212
214
  representer! do
213
215
  extension = Module.new do
@@ -221,13 +223,20 @@ class InlineTest < MiniTest::Spec
221
223
  end
222
224
  end
223
225
 
224
- it do _(OpenStruct.new(:song => OpenStruct.new(:title => "The Fever And The Sound", :artist => "Strung Out")).extend(representer).
225
- to_hash).
226
- must_equal({"song"=>{"artist"=>"Strung Out", "title"=>"The Fever And The Sound"}})
226
+ it do
227
+ _(
228
+ OpenStruct.new(
229
+ :song => OpenStruct.new(
230
+ :title => "The Fever And The Sound",
231
+ :artist => "Strung Out"
232
+ )
233
+ ).extend(representer)
234
+ .to_hash
235
+ )
236
+ .must_equal({"song"=>{"artist" => "Strung Out", "title" => "The Fever And The Sound"}})
227
237
  end
228
238
  end
229
239
 
230
-
231
240
  # define method in inline representer
232
241
  describe "define method in inline representer" do
233
242
  Mod = Module.new do