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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +17 -10
- data/.github/workflows/ci_jruby.yml +21 -0
- data/.github/workflows/ci_truffleruby.yml +19 -0
- data/CHANGES.md +5 -0
- data/Gemfile +1 -1
- data/README.md +0 -1
- data/lib/representable/hash/binding.rb +1 -0
- data/lib/representable/json.rb +14 -2
- data/lib/representable/version.rb +1 -1
- data/lib/representable/xml/binding.rb +0 -7
- data/lib/representable/xml.rb +7 -0
- data/representable.gemspec +1 -3
- data/test/as_test.rb +8 -13
- data/test/benchmarking.rb +20 -25
- data/test/binding_test.rb +13 -5
- data/test/cached_test.rb +55 -35
- data/test/class_test.rb +46 -33
- data/test/coercion_test.rb +29 -19
- data/test/config/inherit_test.rb +12 -17
- data/test/config_test.rb +5 -7
- data/test/decorator_scope_test.rb +13 -11
- data/test/decorator_test.rb +11 -11
- data/test/default_test.rb +2 -2
- data/test/defaults_options_test.rb +37 -9
- data/test/definition_test.rb +10 -12
- data/test/examples/example.rb +43 -38
- data/test/examples/object.rb +7 -6
- data/test/exec_context_test.rb +18 -23
- data/test/features_test.rb +29 -10
- data/test/filter_test.rb +29 -20
- data/test/for_collection_test.rb +12 -15
- data/test/generic_test.rb +15 -22
- data/test/getter_setter_test.rb +11 -6
- data/test/hash_bindings_test.rb +21 -12
- data/test/hash_test.rb +53 -38
- data/test/heritage_test.rb +0 -1
- data/test/if_test.rb +25 -21
- data/test/include_exclude_test.rb +24 -16
- data/test/inherit_test.rb +114 -27
- data/test/inline_test.rb +42 -33
- data/test/instance_test.rb +151 -109
- data/test/is_representable_test.rb +19 -17
- data/test/json_test.rb +48 -46
- data/test/lonely_test.rb +35 -33
- data/test/nested_test.rb +16 -19
- data/test/object_test.rb +6 -6
- data/test/option_test.rb +10 -8
- data/test/parse_pipeline_test.rb +21 -15
- data/test/pipeline_test.rb +144 -108
- data/test/populator_test.rb +18 -15
- data/test/prepare_test.rb +15 -17
- data/test/private_options_test.rb +3 -2
- data/test/reader_writer_test.rb +4 -4
- data/test/realistic_benchmark.rb +21 -27
- data/test/render_nil_test.rb +1 -1
- data/test/represent_test.rb +14 -18
- data/test/representable_test.rb +86 -53
- data/test/schema_test.rb +51 -21
- data/test/serialize_deserialize_test.rb +14 -14
- data/test/skip_test.rb +39 -28
- data/test/stringify_hash_test.rb +29 -31
- data/test/test_helper.rb +31 -25
- data/test/test_helper_test.rb +7 -7
- data/test/uncategorized_test.rb +20 -15
- data/test/user_options_test.rb +12 -3
- data/test/wrap_test.rb +27 -17
- data/test/xml_assertions.rb +29 -0
- data/test/xml_bindings_test.rb +5 -8
- data/test/xml_namespace_test.rb +46 -39
- data/test/xml_test.rb +109 -88
- data/test/yaml_test.rb +73 -51
- metadata +7 -32
data/test/definition_test.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
|
-
class DefinitionTest <
|
|
3
|
+
class DefinitionTest < Minitest::Spec
|
|
4
4
|
Definition = Representable::Definition
|
|
5
5
|
|
|
6
6
|
# TODO: test that we DON'T clone options, that must happen in
|
|
@@ -17,7 +17,6 @@ class DefinitionTest < MiniTest::Spec
|
|
|
17
17
|
end
|
|
18
18
|
_(definition.name).must_equal "song"
|
|
19
19
|
|
|
20
|
-
#
|
|
21
20
|
_(definition[:awesome]).must_equal true
|
|
22
21
|
_(definition[:parse_filter]).must_equal Representable::Pipeline[1]
|
|
23
22
|
_(definition[:render_filter]).must_equal Representable::Pipeline[]
|
|
@@ -80,7 +79,6 @@ class DefinitionTest < MiniTest::Spec
|
|
|
80
79
|
end
|
|
81
80
|
end
|
|
82
81
|
|
|
83
|
-
|
|
84
82
|
# delete!
|
|
85
83
|
describe "#delete!" do
|
|
86
84
|
let(:definition) { Definition.new(:song, serialize: "remove me!") }
|
|
@@ -92,10 +90,11 @@ class DefinitionTest < MiniTest::Spec
|
|
|
92
90
|
|
|
93
91
|
# #inspect
|
|
94
92
|
describe "#inspect" do
|
|
95
|
-
it {
|
|
93
|
+
it {
|
|
94
|
+
_(Definition.new(:songs).inspect).must_equal "#<Representable::Definition ==>songs @options=#{{name: "songs", parse_filter: [], render_filter: []}.inspect}>"
|
|
95
|
+
}
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
-
|
|
99
98
|
describe "generic API" do
|
|
100
99
|
before do
|
|
101
100
|
@def = Representable::Definition.new(:songs)
|
|
@@ -124,7 +123,6 @@ class DefinitionTest < MiniTest::Spec
|
|
|
124
123
|
end
|
|
125
124
|
end
|
|
126
125
|
|
|
127
|
-
|
|
128
126
|
describe "#representable?" do
|
|
129
127
|
it { assert Definition.new(:song, :representable => true).representable? }
|
|
130
128
|
it { _(Definition.new(:song, :representable => true, :extend => Object).representable?).must_equal true }
|
|
@@ -133,7 +131,6 @@ class DefinitionTest < MiniTest::Spec
|
|
|
133
131
|
it { refute Definition.new(:song).representable? }
|
|
134
132
|
end
|
|
135
133
|
|
|
136
|
-
|
|
137
134
|
it "responds to #getter and returns string" do
|
|
138
135
|
assert_equal "songs", @def.getter
|
|
139
136
|
end
|
|
@@ -154,7 +151,6 @@ class DefinitionTest < MiniTest::Spec
|
|
|
154
151
|
end
|
|
155
152
|
end
|
|
156
153
|
|
|
157
|
-
|
|
158
154
|
describe "#clone" do
|
|
159
155
|
subject { Representable::Definition.new(:title, :volume => 9, :clonable => ::Representable::Option(1)) }
|
|
160
156
|
|
|
@@ -183,7 +179,6 @@ class DefinitionTest < MiniTest::Spec
|
|
|
183
179
|
end
|
|
184
180
|
end
|
|
185
181
|
|
|
186
|
-
|
|
187
182
|
describe "#binding" do
|
|
188
183
|
it "returns true when :binding is set" do
|
|
189
184
|
assert Representable::Definition.new(:songs, :binding => Object)[:binding]
|
|
@@ -196,7 +191,11 @@ class DefinitionTest < MiniTest::Spec
|
|
|
196
191
|
|
|
197
192
|
describe "#create_binding" do
|
|
198
193
|
it "executes the block (without special context)" do
|
|
199
|
-
definition = Representable::Definition.new(
|
|
194
|
+
definition = Representable::Definition.new(
|
|
195
|
+
:title, :binding => ->(*args) {
|
|
196
|
+
@binding = Representable::Binding.new(*args)
|
|
197
|
+
}
|
|
198
|
+
)
|
|
200
199
|
_(definition.create_binding).must_equal @binding
|
|
201
200
|
end
|
|
202
201
|
end
|
|
@@ -211,7 +210,6 @@ class DefinitionTest < MiniTest::Spec
|
|
|
211
210
|
end
|
|
212
211
|
end
|
|
213
212
|
|
|
214
|
-
|
|
215
213
|
describe ":default => value" do
|
|
216
214
|
it "responds to #default" do
|
|
217
215
|
@def = Representable::Definition.new(:song)
|
data/test/examples/example.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "bundler"
|
|
2
2
|
Bundler.setup
|
|
3
3
|
|
|
4
|
-
require
|
|
5
|
-
require
|
|
4
|
+
require "representable/yaml"
|
|
5
|
+
require "ostruct"
|
|
6
6
|
|
|
7
7
|
def reset_representer(*module_name)
|
|
8
8
|
module_name.each do |mod|
|
|
@@ -32,7 +32,7 @@ puts rox.inspect
|
|
|
32
32
|
module SongRepresenter
|
|
33
33
|
include Representable::JSON
|
|
34
34
|
|
|
35
|
-
self.representation_wrap= :hit
|
|
35
|
+
self.representation_wrap = :hit
|
|
36
36
|
|
|
37
37
|
property :title
|
|
38
38
|
property :track
|
|
@@ -40,8 +40,6 @@ end
|
|
|
40
40
|
|
|
41
41
|
puts song.extend(SongRepresenter).to_json
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
43
|
######### collections
|
|
46
44
|
|
|
47
45
|
reset_representer(SongRepresenter)
|
|
@@ -54,17 +52,15 @@ module SongRepresenter
|
|
|
54
52
|
collection :composers
|
|
55
53
|
end
|
|
56
54
|
|
|
57
|
-
|
|
58
55
|
song = Song.new(:title => "Fallout", :composers => ["Stewart Copeland", "Sting"])
|
|
59
56
|
puts song.extend(SongRepresenter).to_json
|
|
60
57
|
|
|
61
|
-
|
|
62
58
|
######### nesting types
|
|
63
59
|
|
|
64
60
|
class Album < OpenStruct
|
|
65
61
|
def name
|
|
66
62
|
puts @table.inspect
|
|
67
|
-
|
|
63
|
+
# @attributes
|
|
68
64
|
@table[:name]
|
|
69
65
|
end
|
|
70
66
|
end
|
|
@@ -91,14 +87,15 @@ end
|
|
|
91
87
|
album = Album.new(:name => "The Police", :songs => [song, Song.new(:title => "Synchronicity")])
|
|
92
88
|
puts album.extend(AlbumRepresenter).to_json
|
|
93
89
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
90
|
+
album = Album.new.extend(AlbumRepresenter).from_json(
|
|
91
|
+
%{{"name":"Offspring","songs":[{"title":"Genocide"},{"title":"Nitro","composers":["Offspring"]}]}
|
|
92
|
+
}
|
|
93
|
+
)
|
|
97
94
|
puts album.inspect
|
|
98
95
|
|
|
99
96
|
reset_representer(SongRepresenter)
|
|
100
97
|
|
|
101
|
-
######### using helpers (customizing the rendering/parsing)
|
|
98
|
+
######### using helpers (customizing the rendering/parsing)
|
|
102
99
|
module AlbumRepresenter
|
|
103
100
|
include Representable::JSON
|
|
104
101
|
|
|
@@ -107,12 +104,11 @@ module AlbumRepresenter
|
|
|
107
104
|
end
|
|
108
105
|
end
|
|
109
106
|
|
|
110
|
-
puts Album.new(:name => "The Police")
|
|
111
|
-
|
|
107
|
+
puts Album.new(:name => "The Police")
|
|
108
|
+
.extend(AlbumRepresenter).to_json
|
|
112
109
|
|
|
113
110
|
reset_representer(SongRepresenter)
|
|
114
111
|
|
|
115
|
-
|
|
116
112
|
######### inheritance
|
|
117
113
|
module SongRepresenter
|
|
118
114
|
include Representable::JSON
|
|
@@ -128,13 +124,11 @@ module CoverSongRepresenter
|
|
|
128
124
|
property :covered_by
|
|
129
125
|
end
|
|
130
126
|
|
|
131
|
-
|
|
132
127
|
song = Song.new(:title => "Truth Hits Everybody", :covered_by => "No Use For A Name")
|
|
133
128
|
puts song.extend(CoverSongRepresenter).to_json
|
|
134
129
|
|
|
135
|
-
|
|
136
130
|
### XML
|
|
137
|
-
require
|
|
131
|
+
require "representable/xml"
|
|
138
132
|
module SongRepresenter
|
|
139
133
|
include Representable::XML
|
|
140
134
|
|
|
@@ -147,9 +141,8 @@ puts song.extend(SongRepresenter).to_xml
|
|
|
147
141
|
|
|
148
142
|
reset_representer(SongRepresenter)
|
|
149
143
|
|
|
150
|
-
|
|
151
144
|
### YAML
|
|
152
|
-
require
|
|
145
|
+
require "representable/yaml"
|
|
153
146
|
module SongRepresenter
|
|
154
147
|
include Representable::YAML
|
|
155
148
|
|
|
@@ -159,12 +152,10 @@ module SongRepresenter
|
|
|
159
152
|
end
|
|
160
153
|
puts song.extend(SongRepresenter).to_yaml
|
|
161
154
|
|
|
162
|
-
|
|
163
155
|
SongRepresenter.module_eval do
|
|
164
156
|
@representable_attrs = nil
|
|
165
157
|
end
|
|
166
158
|
|
|
167
|
-
|
|
168
159
|
### YAML
|
|
169
160
|
module SongRepresenter
|
|
170
161
|
include Representable::YAML
|
|
@@ -214,7 +205,6 @@ end
|
|
|
214
205
|
songs = [Song.new(title: "Weirdo", track: 5), CoverSong.new(title: "Truth Hits Everybody", track: 6, copyright: "The Police")]
|
|
215
206
|
album = Album.new(name: "Incognito", songs: songs)
|
|
216
207
|
|
|
217
|
-
|
|
218
208
|
reset_representer(SongRepresenter, AlbumRepresenter)
|
|
219
209
|
|
|
220
210
|
module SongRepresenter
|
|
@@ -235,7 +225,7 @@ module AlbumRepresenter
|
|
|
235
225
|
include Representable::Hash
|
|
236
226
|
|
|
237
227
|
property :name
|
|
238
|
-
collection :songs, :extend =>
|
|
228
|
+
collection :songs, :extend => ->(song) { song.is_a?(CoverSong) ? CoverSongRepresenter : SongRepresenter }
|
|
239
229
|
end
|
|
240
230
|
|
|
241
231
|
puts album.extend(AlbumRepresenter).to_hash
|
|
@@ -246,12 +236,20 @@ module AlbumRepresenter
|
|
|
246
236
|
include Representable::Hash
|
|
247
237
|
|
|
248
238
|
property :name
|
|
249
|
-
collection :songs,
|
|
250
|
-
|
|
251
|
-
|
|
239
|
+
collection :songs,
|
|
240
|
+
:extend => ->(song) { song.is_a?(CoverSong) ? CoverSongRepresenter : SongRepresenter },
|
|
241
|
+
:class => ->(hsh) { hsh.key?("copyright") ? CoverSong : Song } #=> {"title"=>"Weirdo", "track"=>5}
|
|
252
242
|
end
|
|
253
243
|
|
|
254
|
-
album = Album.new.extend(AlbumRepresenter).from_hash(
|
|
244
|
+
album = Album.new.extend(AlbumRepresenter).from_hash(
|
|
245
|
+
{
|
|
246
|
+
"name" => "Incognito",
|
|
247
|
+
"songs" => [
|
|
248
|
+
{"title" => "Weirdo", "track" => 5},
|
|
249
|
+
{"title" => "Truth Hits Everybody", "track" => 6, "copyright" => "The Police"}
|
|
250
|
+
]
|
|
251
|
+
}
|
|
252
|
+
)
|
|
255
253
|
puts album.inspect
|
|
256
254
|
|
|
257
255
|
reset_representer(AlbumRepresenter)
|
|
@@ -260,12 +258,20 @@ module AlbumRepresenter
|
|
|
260
258
|
include Representable::Hash
|
|
261
259
|
|
|
262
260
|
property :name
|
|
263
|
-
collection :songs,
|
|
264
|
-
|
|
265
|
-
|
|
261
|
+
collection :songs,
|
|
262
|
+
:extend => ->(song) { song.is_a?(CoverSong) ? CoverSongRepresenter : SongRepresenter },
|
|
263
|
+
:instance => ->(hsh) { hsh.key?("copyright") ? CoverSong.new : Song.new(original: true) }
|
|
266
264
|
end
|
|
267
265
|
|
|
268
|
-
album = Album.new.extend(AlbumRepresenter).from_hash(
|
|
266
|
+
album = Album.new.extend(AlbumRepresenter).from_hash(
|
|
267
|
+
{
|
|
268
|
+
"name" => "Incognito",
|
|
269
|
+
"songs" => [
|
|
270
|
+
{"title" => "Weirdo", "track" => 5},
|
|
271
|
+
{"title" => "Truth Hits Everybody", "track" => 6, "copyright" => "The Police"}
|
|
272
|
+
]
|
|
273
|
+
}
|
|
274
|
+
)
|
|
269
275
|
puts album.inspect
|
|
270
276
|
|
|
271
277
|
######### #hash
|
|
@@ -287,19 +293,18 @@ module FavoriteSongsRepresenter
|
|
|
287
293
|
include Representable::JSON::Hash
|
|
288
294
|
end
|
|
289
295
|
|
|
290
|
-
puts(
|
|
296
|
+
puts({"Nick" => "Hyper Music", "El" => "Blown In The Wind"}.extend(FavoriteSongsRepresenter).to_json)
|
|
291
297
|
|
|
292
|
-
require
|
|
298
|
+
require "representable/json/hash"
|
|
293
299
|
module FavoriteSongsRepresenter
|
|
294
300
|
include Representable::JSON::Hash
|
|
295
301
|
|
|
296
302
|
values extend: SongRepresenter, class: Song
|
|
297
303
|
end
|
|
298
304
|
|
|
299
|
-
puts(
|
|
300
|
-
|
|
305
|
+
puts({"Nick" => Song.new(title: "Hyper Music")}.extend(FavoriteSongsRepresenter).to_json)
|
|
301
306
|
|
|
302
|
-
require
|
|
307
|
+
require "representable/json/collection"
|
|
303
308
|
module SongsRepresenter
|
|
304
309
|
include Representable::JSON::Collection
|
|
305
310
|
|
data/test/examples/object.rb
CHANGED
|
@@ -3,9 +3,11 @@ require "test_helper"
|
|
|
3
3
|
require "ostruct"
|
|
4
4
|
require "pp"
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
source = OpenStruct.new(
|
|
7
|
+
name: "30 Years Live", songs: [
|
|
8
|
+
OpenStruct.new(id: 1, title: "Dear Beloved"), OpenStruct.new(id: 2, title: "Fuck Armageddon")
|
|
9
|
+
]
|
|
10
|
+
)
|
|
9
11
|
|
|
10
12
|
require "representable/object"
|
|
11
13
|
|
|
@@ -13,15 +15,14 @@ class AlbumRepresenter < Representable::Decorator
|
|
|
13
15
|
include Representable::Object
|
|
14
16
|
|
|
15
17
|
property :name
|
|
16
|
-
collection :songs, instance: ->(
|
|
18
|
+
collection :songs, instance: ->(_fragment, *) { Song.new } do
|
|
17
19
|
property :title
|
|
18
20
|
end
|
|
19
21
|
end
|
|
20
22
|
|
|
21
|
-
|
|
22
23
|
Album = Struct.new(:name, :songs)
|
|
23
24
|
Song = Struct.new(:title)
|
|
24
25
|
|
|
25
26
|
target = Album.new
|
|
26
27
|
|
|
27
|
-
AlbumRepresenter.new(target).from_object(source)
|
|
28
|
+
AlbumRepresenter.new(target).from_object(source)
|
data/test/exec_context_test.rb
CHANGED
|
@@ -1,65 +1,60 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
|
-
class ExecContextTest <
|
|
3
|
+
class ExecContextTest < Minitest::Spec
|
|
4
4
|
for_formats(
|
|
5
|
-
:hash => [Representable::Hash, {Song => "Rebel Fate"}, {Song=>"Timing"}]
|
|
5
|
+
:hash => [Representable::Hash, {Song => "Rebel Fate"}, {Song=>"Timing"}]
|
|
6
6
|
# :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>"],
|
|
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
|
-
|
|
10
9
|
let(:song) { representer.prepare(Song.new("Timing")) }
|
|
11
10
|
let(:format) { format }
|
|
12
11
|
|
|
13
|
-
|
|
14
12
|
describe "exec_context: nil" do
|
|
15
13
|
representer!(:module => mod) do
|
|
16
|
-
property :name, :as =>
|
|
14
|
+
property :name, :as => ->(*) { self.class }
|
|
17
15
|
end
|
|
18
16
|
|
|
19
17
|
it { render(song).must_equal_document output }
|
|
20
18
|
it { _(parse(song, input).name).must_equal "Rebel Fate" }
|
|
21
19
|
end
|
|
22
20
|
|
|
23
|
-
|
|
24
21
|
describe "exec_context: :decorator" do
|
|
25
22
|
representer!(:module => mod) do
|
|
26
|
-
property :name, :as =>
|
|
23
|
+
property :name, :as => ->(*) { self.class }, :exec_context => :decorator
|
|
27
24
|
end
|
|
28
25
|
|
|
29
26
|
it { render(song).must_equal_document output }
|
|
30
27
|
it { _(parse(song, input).name).must_equal "Rebel Fate" }
|
|
31
28
|
end
|
|
32
29
|
|
|
33
|
-
|
|
34
30
|
describe "exec_context: :binding" do
|
|
35
31
|
representer!(:module => mod) do
|
|
36
32
|
property :name,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
:as => ->(*) { self.class }, # to actually test
|
|
34
|
+
:exec_context => :binding,
|
|
35
|
+
:setter => ->(options) {
|
|
36
|
+
options[:represented].name = options[:fragment] # to make parsing work.
|
|
37
|
+
}
|
|
41
38
|
end
|
|
42
39
|
|
|
43
40
|
it { render(song).must_equal_document({Representable::Hash::Binding => "name"}) }
|
|
44
41
|
it { _(parse(song, {Representable::Hash::Binding => "Rebel Fate"}).name).must_equal "Rebel Fate" }
|
|
45
42
|
end
|
|
46
43
|
|
|
47
|
-
|
|
48
44
|
describe "Decorator" do
|
|
49
45
|
# DISCUSS: do we need this test?
|
|
50
46
|
describe "exec_context: nil" do
|
|
51
47
|
representer!(:module => mod, :decorator => true) do
|
|
52
|
-
property :name, :as =>
|
|
48
|
+
property :name, :as => ->(*) { self.class }
|
|
53
49
|
end
|
|
54
50
|
|
|
55
51
|
it { render(song).must_equal_document output }
|
|
56
52
|
it { _(parse(song, input).name).must_equal "Rebel Fate" }
|
|
57
53
|
end
|
|
58
54
|
|
|
59
|
-
|
|
60
55
|
describe "exec_context: :decorator" do # this tests if lambdas are run in the right context, if methods are called in the right context and if we can access the represented object.
|
|
61
56
|
representer!(:module => mod, :decorator => true) do
|
|
62
|
-
property :name, :as =>
|
|
57
|
+
property :name, :as => ->(*) { self.class.superclass }, :exec_context => :decorator
|
|
63
58
|
|
|
64
59
|
define_method :name do # def in Decorator class.
|
|
65
60
|
"Timebomb"
|
|
@@ -74,15 +69,15 @@ class ExecContextTest < MiniTest::Spec
|
|
|
74
69
|
it { _(parse(song, {Representable::Decorator=>"Listless"}).name).must_equal "Listless" }
|
|
75
70
|
end
|
|
76
71
|
|
|
77
|
-
|
|
78
72
|
# DISCUSS: do we need this test?
|
|
79
73
|
describe "exec_context: :binding" do
|
|
80
74
|
representer!(:module => mod, :decorator => true) do
|
|
81
75
|
property :name,
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
76
|
+
:as => ->(*) { self.class }, # to actually test
|
|
77
|
+
:exec_context => :binding,
|
|
78
|
+
:setter => ->(options) {
|
|
79
|
+
options[:represented].name = options[:fragment] # to make parsing work.
|
|
80
|
+
}
|
|
86
81
|
end
|
|
87
82
|
|
|
88
83
|
it { render(song).must_equal_document({Representable::Hash::Binding => "name"}) }
|
|
@@ -90,4 +85,4 @@ class ExecContextTest < MiniTest::Spec
|
|
|
90
85
|
end
|
|
91
86
|
end
|
|
92
87
|
end
|
|
93
|
-
end
|
|
88
|
+
end
|
data/test/features_test.rb
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
|
-
class FeaturesTest <
|
|
3
|
+
class FeaturesTest < Minitest::Spec
|
|
4
4
|
module Title
|
|
5
5
|
def title; "Is It A Lie"; end
|
|
6
6
|
end
|
|
7
|
+
|
|
7
8
|
module Length
|
|
8
9
|
def length; "2:31"; end
|
|
9
10
|
end
|
|
10
11
|
|
|
11
|
-
definition =
|
|
12
|
+
definition = -> {
|
|
12
13
|
feature Title
|
|
13
14
|
feature Length
|
|
14
15
|
|
|
@@ -27,20 +28,33 @@ class FeaturesTest < MiniTest::Spec
|
|
|
27
28
|
instance_exec(&definition)
|
|
28
29
|
end
|
|
29
30
|
|
|
30
|
-
it {
|
|
31
|
+
it {
|
|
32
|
+
_(song.extend(representer).to_hash).must_equal(
|
|
33
|
+
{
|
|
34
|
+
"title" => "Is It A Lie", "length" => "2:31",
|
|
35
|
+
"details" => {"title"=>"Is It A Lie"}
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
}
|
|
31
39
|
end
|
|
32
40
|
|
|
33
|
-
|
|
34
41
|
describe "Decorator" do
|
|
35
42
|
representer!(:decorator => true) do
|
|
36
43
|
instance_exec(&definition)
|
|
37
44
|
end
|
|
38
45
|
|
|
39
|
-
it {
|
|
46
|
+
it {
|
|
47
|
+
_(representer.new(song).to_hash).must_equal(
|
|
48
|
+
{
|
|
49
|
+
"title" => "Is It A Lie", "length" => "2:31",
|
|
50
|
+
"details" => {"title"=>"Is It A Lie"}
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
}
|
|
40
54
|
end
|
|
41
55
|
end
|
|
42
56
|
|
|
43
|
-
class FeatureInclusionOrderTest <
|
|
57
|
+
class FeatureInclusionOrderTest < Minitest::Spec
|
|
44
58
|
module Title
|
|
45
59
|
def title
|
|
46
60
|
"I was first!"
|
|
@@ -49,7 +63,7 @@ class FeatureInclusionOrderTest < MiniTest::Spec
|
|
|
49
63
|
|
|
50
64
|
module OverridingTitle
|
|
51
65
|
def title
|
|
52
|
-
"I am number two, "
|
|
66
|
+
"I am number two, #{super}"
|
|
53
67
|
end
|
|
54
68
|
end
|
|
55
69
|
|
|
@@ -65,6 +79,11 @@ class FeatureInclusionOrderTest < MiniTest::Spec
|
|
|
65
79
|
end
|
|
66
80
|
|
|
67
81
|
it do
|
|
68
|
-
_(representer.new(OpenStruct.new(song: Object)).to_hash).must_equal(
|
|
82
|
+
_(representer.new(OpenStruct.new(song: Object)).to_hash).must_equal(
|
|
83
|
+
{
|
|
84
|
+
"title" => "I am number two, I was first!",
|
|
85
|
+
"song" => {"title"=>"I am number two, I was first!"}
|
|
86
|
+
}
|
|
87
|
+
)
|
|
69
88
|
end
|
|
70
|
-
end
|
|
89
|
+
end
|
data/test/filter_test.rb
CHANGED
|
@@ -1,43 +1,53 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
|
-
class FilterPipelineTest <
|
|
4
|
-
let(:block1) {
|
|
5
|
-
let(:block2) {
|
|
3
|
+
class FilterPipelineTest < Minitest::Spec
|
|
4
|
+
let(:block1) { ->(input, _options) { "1: #{input}" } }
|
|
5
|
+
let(:block2) { ->(input, _options) { "2: #{input}" } }
|
|
6
6
|
|
|
7
7
|
subject { Representable::Pipeline[block1, block2] }
|
|
8
8
|
|
|
9
9
|
it { _(subject.call("Horowitz", {})).must_equal "2: 1: Horowitz" }
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
class FilterTest < MiniTest::Spec
|
|
12
|
+
class FilterTest < Minitest::Spec
|
|
14
13
|
representer! do
|
|
15
14
|
property :title
|
|
16
15
|
|
|
17
16
|
property :track,
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
:parse_filter => ->(input, options) { "#{input.downcase},#{options[:doc]}" },
|
|
18
|
+
:render_filter => ->(val, options) { "#{val.upcase},#{options[:doc]},#{options[:options][:user_options]}" }
|
|
20
19
|
end
|
|
21
20
|
|
|
22
21
|
# gets doc and options.
|
|
23
22
|
it {
|
|
24
23
|
song = OpenStruct.new.extend(representer).from_hash("title" => "VULCAN EARS", "track" => "Nine")
|
|
25
24
|
_(song.title).must_equal "VULCAN EARS"
|
|
26
|
-
_(song.track).must_equal "nine
|
|
25
|
+
_(song.track).must_equal "nine,#{{"title" => "VULCAN EARS", "track" => "Nine"}.inspect}"
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
it {
|
|
30
|
-
|
|
28
|
+
it {
|
|
29
|
+
_(
|
|
30
|
+
OpenStruct.new(
|
|
31
|
+
"title" => "vulcan ears",
|
|
32
|
+
"track" => "Nine"
|
|
33
|
+
).extend(representer).to_hash
|
|
34
|
+
).must_equal({
|
|
35
|
+
"title" => "vulcan ears",
|
|
36
|
+
"track" => "NINE,#{{"title" => "vulcan ears"}.inspect},#{{}.inspect}"
|
|
37
|
+
})
|
|
38
|
+
}
|
|
31
39
|
|
|
32
40
|
describe "#parse_filter" do
|
|
33
41
|
representer! do
|
|
34
42
|
property :track,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
:parse_filter => [
|
|
44
|
+
->(input, _options) { "#{input}-1" },
|
|
45
|
+
->(input, _options) { "#{input}-2" }
|
|
46
|
+
],
|
|
47
|
+
:render_filter => [
|
|
48
|
+
->(val, _options) { "#{val}-1" },
|
|
49
|
+
->(val, _options) { "#{val}-2" }
|
|
50
|
+
]
|
|
41
51
|
end
|
|
42
52
|
|
|
43
53
|
# order matters.
|
|
@@ -46,12 +56,11 @@ class FilterTest < MiniTest::Spec
|
|
|
46
56
|
end
|
|
47
57
|
end
|
|
48
58
|
|
|
49
|
-
|
|
50
|
-
# class RenderFilterTest < MiniTest::Spec
|
|
59
|
+
# class RenderFilterTest < Minitest::Spec
|
|
51
60
|
# representer! do
|
|
52
61
|
# property :track, :render_filter => [lambda { |val, options| "#{val}-1" } ]
|
|
53
62
|
# property :track, :render_filter => [lambda { |val, options| "#{val}-2" } ], :inherit => true
|
|
54
63
|
# end
|
|
55
64
|
|
|
56
65
|
# it { OpenStruct.new("track" => "Nine").extend(representer).to_hash.must_equal({"track"=>"Nine-1-2"}) }
|
|
57
|
-
# end
|
|
66
|
+
# end
|