representable 2.4.0.rc2 → 2.4.0.rc3
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/CHANGES.md +6 -1
- data/Gemfile +1 -1
- data/lib/representable/deprecations.rb +1 -1
- data/lib/representable/deserializer.rb +3 -5
- data/lib/representable/hash_methods.rb +1 -1
- data/lib/representable/insert.rb +10 -3
- data/lib/representable/parse_strategies.rb +5 -3
- data/lib/representable/pipeline_factories.rb +3 -3
- data/lib/representable/serializer.rb +1 -1
- data/lib/representable/version.rb +1 -1
- data/test/pipeline_test.rb +37 -19
- data/test/populator_test.rb +31 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f9cc279171577dec367b7910ae42b4d4f8b6240
|
4
|
+
data.tar.gz: 193116e06652a35c3fa5bd5124a401d51c8d5c7e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 14296a6fb55202f2c747cbe0a77e97a3bef8f82673eae9467cd290243dd0ed438f3ffe5fbbf7ec53728818b91459774f18e7141117d9788bd497218ad4899325
|
7
|
+
data.tar.gz: 35a26662c16e844cb9944cdf06cb9a5014c266f53568e714d0f37e49922076cc200e1126fb554dc13a2a0115a97479ea5ddce300bf3d6663148f9adf9ef108c8
|
data/CHANGES.md
CHANGED
@@ -44,8 +44,13 @@ and it suddenly is super simple to understand
|
|
44
44
|
* Removed `Binding@represented` (which was never public anyway). Use `Binding#represented`.
|
45
45
|
* Changed signature: `Binding#get(represented:)`. In now needs a hash `{represented: ..}`.
|
46
46
|
|
47
|
-
# 2.4.0.
|
47
|
+
# 2.4.0.rc3
|
48
48
|
|
49
|
+
* `CreateObject` no longer invokes `AssignFragment`. This is now part of the official parse pipeline.
|
50
|
+
|
51
|
+
# 2.4.0.rc4
|
52
|
+
|
53
|
+
* `Set` is `SetValue`. `Get` is `GetValue`.
|
49
54
|
* Use Declarative's `::build_definition` interface instead of overwriting `::property`.
|
50
55
|
|
51
56
|
# 2.3.0
|
data/Gemfile
CHANGED
@@ -84,7 +84,7 @@ module Representable::Binding::Deprecation
|
|
84
84
|
|
85
85
|
def get(options={}) # DISCUSS: evluate if we really need this.
|
86
86
|
warn "[Representable] Binding#get is deprecated."
|
87
|
-
self[:getter] ? Representable::Getter.(nil, options.merge(binding: self)) : Representable::
|
87
|
+
self[:getter] ? Representable::Getter.(nil, options.merge(binding: self)) : Representable::GetValue.(nil, options.merge(binding: self))
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|
@@ -20,7 +20,7 @@ module Representable
|
|
20
20
|
end
|
21
21
|
|
22
22
|
OverwriteOnNil = ->(input, options) do
|
23
|
-
input.nil? ? (
|
23
|
+
input.nil? ? (SetValue.(input, options); Pipeline::Stop) : input
|
24
24
|
end
|
25
25
|
|
26
26
|
Default = ->(input, options) do
|
@@ -38,8 +38,6 @@ module Representable
|
|
38
38
|
module Function
|
39
39
|
class CreateObject
|
40
40
|
def call(input, options)
|
41
|
-
AssignFragment.(input, options)
|
42
|
-
|
43
41
|
instance_for(input, options) || class_for(input, options)
|
44
42
|
end
|
45
43
|
|
@@ -99,8 +97,8 @@ module Representable
|
|
99
97
|
options[:binding][:parse_filter].(input, options)
|
100
98
|
end
|
101
99
|
|
102
|
-
Setter
|
103
|
-
|
100
|
+
Setter = ->(input, options) { options[:binding].evaluate_option(:setter, input, options) }
|
101
|
+
SetValue = ->(input, options) { options[:binding].send(:exec_context, options).send(options[:binding].setter, input) }
|
104
102
|
|
105
103
|
|
106
104
|
Stop = ->(*) { Pipeline::Stop }
|
@@ -4,7 +4,7 @@ module Representable
|
|
4
4
|
hash = filter_keys_for!(represented, options) # FIXME: this modifies options and replicates logic from Representable.
|
5
5
|
bin = representable_map(options, format).first
|
6
6
|
|
7
|
-
Collect::Hash[*bin.default_render_fragment_functions].
|
7
|
+
Collect::Hash[*bin.default_render_fragment_functions].(hash, {doc: doc, user_options: options, binding: bin, represented: represented, decorator: self})
|
8
8
|
end
|
9
9
|
|
10
10
|
def update_properties_from(doc, options, format)
|
data/lib/representable/insert.rb
CHANGED
@@ -16,12 +16,19 @@ module Representable
|
|
16
16
|
arr[index] = Collect[*Pipeline::Insert.(func, new_func, replace: old_func)]
|
17
17
|
end
|
18
18
|
|
19
|
-
arr[index] = new_func if
|
19
|
+
arr[index] = new_func if func==old_func
|
20
20
|
}
|
21
21
|
end
|
22
22
|
|
23
|
-
def delete!(arr,
|
24
|
-
arr.delete(
|
23
|
+
def delete!(arr, removed_func)
|
24
|
+
arr.delete(removed_func)
|
25
|
+
|
26
|
+
# TODO: make nice.
|
27
|
+
arr.each_with_index { |func, index|
|
28
|
+
if func.is_a?(Collect)
|
29
|
+
arr[index] = Collect[*Pipeline::Insert.(func, removed_func, delete: true)]
|
30
|
+
end
|
31
|
+
}
|
25
32
|
end
|
26
33
|
end
|
27
34
|
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
module Representable
|
2
2
|
class Populator
|
3
3
|
FindOrInstantiate = ->(input, options) {
|
4
|
-
AssignFragment.(input, options)
|
5
|
-
|
6
4
|
binding = options[:binding]
|
7
5
|
|
8
6
|
object_class = binding[:class].(input, options)
|
@@ -18,13 +16,17 @@ module Representable
|
|
18
16
|
object
|
19
17
|
}
|
20
18
|
|
19
|
+
# pipeline: [StopOnExcluded, AssignName, ReadFragment, StopOnNotFound, OverwriteOnNil, AssignFragment, #<Representable::Function::CreateObject:0x9805a44>, #<Representable::Function::Decorate:0x9805a1c>, Deserialize, Set]
|
20
|
+
|
21
21
|
def self.apply!(options)
|
22
22
|
return unless populator = options[:populator]
|
23
23
|
|
24
24
|
options[:parse_pipeline] = ->(input, options) do
|
25
25
|
pipeline = Pipeline[*parse_functions] # TODO: AssignFragment
|
26
|
-
pipeline = Pipeline::Insert.(pipeline,
|
26
|
+
pipeline = Pipeline::Insert.(pipeline, SetValue, delete: true) # remove the setter function.
|
27
27
|
pipeline = Pipeline::Insert.(pipeline, populator, replace: CreateObject) # let the populator do CreateObject's job.
|
28
|
+
# puts pipeline.extend(Representable::Pipeline::Debug).inspect
|
29
|
+
pipeline
|
28
30
|
end
|
29
31
|
end
|
30
32
|
end
|
@@ -44,7 +44,7 @@ module Representable
|
|
44
44
|
functions << Stop if self[:readable]==false
|
45
45
|
functions << StopOnExcluded
|
46
46
|
functions << If if self[:if]
|
47
|
-
functions << (self[:getter] ? Getter :
|
47
|
+
functions << (self[:getter] ? Getter : GetValue)
|
48
48
|
functions << Writer if self[:writer]
|
49
49
|
functions << RenderFilter if self[:render_filter].any?
|
50
50
|
functions << RenderDefault if has_default?
|
@@ -64,7 +64,7 @@ module Representable
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def default_parse_fragment_functions
|
67
|
-
functions = []
|
67
|
+
functions = [AssignFragment]
|
68
68
|
functions << SkipParse if self[:skip_parse]
|
69
69
|
|
70
70
|
if typed?
|
@@ -82,7 +82,7 @@ module Representable
|
|
82
82
|
def default_post_functions
|
83
83
|
funcs = []
|
84
84
|
funcs << ParseFilter if self[:parse_filter].any?
|
85
|
-
funcs << (self[:setter] ? Setter :
|
85
|
+
funcs << (self[:setter] ? Setter : SetValue)
|
86
86
|
end
|
87
87
|
end
|
88
88
|
end
|
@@ -3,7 +3,7 @@ module Representable
|
|
3
3
|
options[:binding].evaluate_option(:getter, input, options)
|
4
4
|
end
|
5
5
|
|
6
|
-
|
6
|
+
GetValue = ->(input, options) { options[:binding].send(:exec_context, options).send(options[:binding].getter) }
|
7
7
|
|
8
8
|
Writer = ->(input, options) do
|
9
9
|
options[:binding].evaluate_option(:writer, input, options)
|
data/test/pipeline_test.rb
CHANGED
@@ -77,7 +77,7 @@ class PipelineTest < MiniTest::Spec
|
|
77
77
|
it "rendering scalar property" do
|
78
78
|
doc = {}
|
79
79
|
P[
|
80
|
-
R::
|
80
|
+
R::GetValue,
|
81
81
|
R::StopOnSkipable,
|
82
82
|
R::AssignName,
|
83
83
|
R::WriteFragment
|
@@ -93,7 +93,7 @@ class PipelineTest < MiniTest::Spec
|
|
93
93
|
R::StopOnNotFound,
|
94
94
|
R::OverwriteOnNil,
|
95
95
|
# R::SkipParse,
|
96
|
-
R::
|
96
|
+
R::SetValue,
|
97
97
|
].extend(P::Debug).(doc={"title"=>"Eruption"}, {represented: song=Song.new("Lime Green"), binding: title, doc: doc}).must_equal "Eruption"
|
98
98
|
song.title.must_equal "Eruption"
|
99
99
|
end
|
@@ -116,7 +116,7 @@ class PipelineTest < MiniTest::Spec
|
|
116
116
|
it "rendering typed property" do
|
117
117
|
doc = {}
|
118
118
|
P[
|
119
|
-
R::
|
119
|
+
R::GetValue,
|
120
120
|
R::StopOnSkipable,
|
121
121
|
R::StopOnNil,
|
122
122
|
R::SkipRender,
|
@@ -136,10 +136,11 @@ class PipelineTest < MiniTest::Spec
|
|
136
136
|
R::StopOnNotFound,
|
137
137
|
R::OverwriteOnNil,
|
138
138
|
# R::SkipParse,
|
139
|
+
R::AssignFragment,
|
139
140
|
R::CreateObject,
|
140
141
|
R::Decorate,
|
141
142
|
R::Deserialize,
|
142
|
-
R::
|
143
|
+
R::SetValue,
|
143
144
|
].extend(P::Debug).(doc={"artist"=>{"name"=>"Doobie Brothers"}}, {represented: song_model, binding: artist, doc: doc, user_options: {}}).must_equal model=Artist.new("Doobie Brothers")
|
144
145
|
song_model.artist.must_equal model
|
145
146
|
end
|
@@ -155,7 +156,7 @@ class PipelineTest < MiniTest::Spec
|
|
155
156
|
it "render scalar collection" do
|
156
157
|
doc = {}
|
157
158
|
P[
|
158
|
-
R::
|
159
|
+
R::GetValue,
|
159
160
|
R::StopOnSkipable,
|
160
161
|
R::Collect[
|
161
162
|
R::SkipRender,
|
@@ -176,7 +177,7 @@ class PipelineTest < MiniTest::Spec
|
|
176
177
|
it "render typed collection" do
|
177
178
|
doc = {}
|
178
179
|
P[
|
179
|
-
R::
|
180
|
+
R::GetValue,
|
180
181
|
R::StopOnSkipable,
|
181
182
|
R::Collect[
|
182
183
|
R::SkipRender,
|
@@ -201,12 +202,13 @@ let (:album_model) { Album.new(nil, [Artist.new("Diesel Boy"), Artist.new("Van H
|
|
201
202
|
R::OverwriteOnNil,
|
202
203
|
# R::SkipParse,
|
203
204
|
R::Collect[
|
205
|
+
R::AssignFragment,
|
204
206
|
R::SkipRender,
|
205
207
|
R::CreateObject,
|
206
208
|
R::Decorate,
|
207
209
|
R::Deserialize,
|
208
210
|
],
|
209
|
-
R::
|
211
|
+
R::SetValue,
|
210
212
|
].extend(P::Debug).(doc, {represented: album_model, binding: artists, doc: doc, user_options: {}}).must_equal([Artist.new("Diesel Boy"), Artist.new("Van Halen")])
|
211
213
|
|
212
214
|
album_model.artists.must_equal([Artist.new("Diesel Boy"), Artist.new("Van Halen")])
|
@@ -214,7 +216,7 @@ let (:album_model) { Album.new(nil, [Artist.new("Diesel Boy"), Artist.new("Van H
|
|
214
216
|
|
215
217
|
# TODO: test with arrays, too, not "only" Pipeline instances.
|
216
218
|
describe "#Insert Pipeline[], Function, replace: OldFunction" do
|
217
|
-
let (:pipeline) { P[R::
|
219
|
+
let (:pipeline) { P[R::GetValue, R::StopOnSkipable, R::StopOnNil] }
|
218
220
|
|
219
221
|
it "returns Pipeline instance when passing in Pipeline instance" do
|
220
222
|
P::Insert.(pipeline, R::Default, replace: R::StopOnSkipable).must_be_instance_of(R::Pipeline)
|
@@ -222,8 +224,8 @@ let (:album_model) { Album.new(nil, [Artist.new("Diesel Boy"), Artist.new("Van H
|
|
222
224
|
|
223
225
|
it "replaces if exists" do
|
224
226
|
# pipeline.insert!(R::Default, replace: R::StopOnSkipable)
|
225
|
-
P::Insert.(pipeline, R::Default, replace: R::StopOnSkipable).must_equal P[R::
|
226
|
-
pipeline.must_equal P[R::
|
227
|
+
P::Insert.(pipeline, R::Default, replace: R::StopOnSkipable).must_equal P[R::GetValue, R::Default, R::StopOnNil]
|
228
|
+
pipeline.must_equal P[R::GetValue, R::StopOnSkipable, R::StopOnNil]
|
227
229
|
end
|
228
230
|
|
229
231
|
it "replaces Function instance" do
|
@@ -234,26 +236,42 @@ let (:album_model) { Album.new(nil, [Artist.new("Diesel Boy"), Artist.new("Van H
|
|
234
236
|
|
235
237
|
it "does not replace when not existing" do
|
236
238
|
P::Insert.(pipeline, R::Default, replace: R::Prepare)
|
237
|
-
pipeline.must_equal P[R::
|
239
|
+
pipeline.must_equal P[R::GetValue, R::StopOnSkipable, R::StopOnNil]
|
238
240
|
end
|
239
241
|
|
240
242
|
it "applies on nested Collect" do
|
241
|
-
pipeline = P[R::
|
243
|
+
pipeline = P[R::GetValue, R::Collect[R::GetValue, R::StopOnSkipable], R::StopOnNil]
|
242
244
|
|
243
|
-
P::Insert.(pipeline, R::Default, replace: R::StopOnSkipable).extend(P::Debug).inspect.must_equal "Pipeline[
|
244
|
-
pipeline.must_equal P[R::
|
245
|
+
P::Insert.(pipeline, R::Default, replace: R::StopOnSkipable).extend(P::Debug).inspect.must_equal "Pipeline[GetValue, Collect[GetValue, Default], StopOnNil]"
|
246
|
+
pipeline.must_equal P[R::GetValue, R::Collect[R::GetValue, R::StopOnSkipable], R::StopOnNil]
|
245
247
|
|
246
248
|
|
247
|
-
P::Insert.(pipeline, R::Default, replace: R::StopOnNil).extend(P::Debug).inspect.must_equal "Pipeline[
|
249
|
+
P::Insert.(pipeline, R::Default, replace: R::StopOnNil).extend(P::Debug).inspect.must_equal "Pipeline[GetValue, Collect[GetValue, StopOnSkipable], Default]"
|
250
|
+
end
|
251
|
+
|
252
|
+
it "applies on nested Collect with Function::CreateObject" do
|
253
|
+
pipeline = P[R::GetValue, R::Collect[R::GetValue, R::CreateObject], R::StopOnNil]
|
254
|
+
|
255
|
+
P::Insert.(pipeline, R::Default, replace: R::CreateObject).extend(P::Debug).inspect.must_equal "Pipeline[GetValue, Collect[GetValue, Default], StopOnNil]"
|
256
|
+
pipeline.must_equal P[R::GetValue, R::Collect[R::GetValue, R::CreateObject], R::StopOnNil]
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
describe "Insert.(delete: true)" do
|
261
|
+
let(:pipeline) { P[R::GetValue, R::StopOnNil] }
|
262
|
+
|
263
|
+
it do
|
264
|
+
P::Insert.(pipeline, R::GetValue, delete: true).extend(P::Debug).inspect.must_equal "Pipeline[StopOnNil]"
|
265
|
+
pipeline.extend(P::Debug).inspect.must_equal "Pipeline[GetValue, StopOnNil]"
|
248
266
|
end
|
249
267
|
end
|
250
268
|
|
251
|
-
describe "Insert
|
252
|
-
let(:pipeline) { P[R::
|
269
|
+
describe "Insert.(delete: true) with Collect" do
|
270
|
+
let(:pipeline) { P[R::GetValue, R::Collect[R::GetValue, R::StopOnSkipable], R::StopOnNil] }
|
253
271
|
|
254
272
|
it do
|
255
|
-
P::Insert.(pipeline, R::
|
256
|
-
pipeline.extend(P::Debug).inspect.must_equal "Pipeline[
|
273
|
+
P::Insert.(pipeline, R::GetValue, delete: true).extend(P::Debug).inspect.must_equal "Pipeline[Collect[StopOnSkipable], StopOnNil]"
|
274
|
+
pipeline.extend(P::Debug).inspect.must_equal "Pipeline[GetValue, Collect[GetValue, StopOnSkipable], StopOnNil]"
|
257
275
|
end
|
258
276
|
end
|
259
277
|
end
|
data/test/populator_test.rb
CHANGED
@@ -1,6 +1,35 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
|
3
|
-
class
|
3
|
+
class PopulatorTest < Minitest::Spec
|
4
|
+
Song = Struct.new(:id)
|
5
|
+
Artist = Struct.new(:name)
|
6
|
+
Album = Struct.new(:songs, :artist)
|
7
|
+
|
8
|
+
describe "populator: ->{}" do
|
9
|
+
representer! do
|
10
|
+
collection :songs, populator: ->(input, options) { options[:represented].songs << song = Song.new; song } do
|
11
|
+
property :id
|
12
|
+
end
|
13
|
+
|
14
|
+
property :artist, populator: ->(input, options) { options[:represented].artist = Artist.new } do
|
15
|
+
property :name
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
let (:album) { Album.new([]) }
|
20
|
+
|
21
|
+
it do
|
22
|
+
album.extend(representer).from_hash("songs"=>[{"id"=>1}, {"id"=>2}], "artist"=>{"name"=>"Waste"})
|
23
|
+
album.inspect.must_equal "#<struct PopulatorTest::Album songs=[#<struct PopulatorTest::Song id=1>, #<struct PopulatorTest::Song id=2>], artist=#<struct PopulatorTest::Artist name=\"Waste\">>"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "populator: ->{}, " do
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class PopulatorFindOrInstantiateTest < Minitest::Spec
|
4
33
|
Song = Struct.new(:id, :title, :uid) do
|
5
34
|
def self.find_by(attributes={})
|
6
35
|
return new(1, "Resist Stan", "abcd") if attributes[:id]==1# we should return the same object here
|
@@ -26,7 +55,7 @@ class PopulatorFindOrInstantiateTest < MiniTest::Spec
|
|
26
55
|
end
|
27
56
|
end
|
28
57
|
|
29
|
-
let (:album) { Composer.new.extend(representer) }
|
58
|
+
let (:album) { Composer.new.extend(representer).extend(Representable::Debug) }
|
30
59
|
|
31
60
|
it "finds by :id and creates new without :id" do
|
32
61
|
album.from_hash({"song"=>{"id" => 1, "title"=>"Resist Stance"}})
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: representable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.4.0.
|
4
|
+
version: 2.4.0.rc3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
11
|
+
date: 2015-11-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: uber
|