representable 2.4.1 → 3.0.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/.travis.yml +7 -12
- data/CHANGES.md +6 -27
- data/README.md +28 -1326
- data/lib/representable.rb +4 -14
- data/lib/representable/binding.rb +3 -7
- data/lib/representable/definition.rb +1 -2
- data/lib/representable/populator.rb +35 -0
- data/lib/representable/version.rb +1 -1
- data/test/definition_test.rb +0 -7
- data/test/exec_context_test.rb +2 -2
- data/test/instance_test.rb +0 -19
- data/test/realistic_benchmark.rb +0 -13
- data/test/representable_test.rb +0 -16
- data/test/skip_test.rb +1 -1
- data/test/test_helper.rb +0 -2
- metadata +3 -65
- data/lib/representable/deprecations.rb +0 -127
- data/lib/representable/parse_strategies.rb +0 -93
- data/test-with-deprecations/as_test.rb +0 -65
- data/test-with-deprecations/benchmarking.rb +0 -83
- data/test-with-deprecations/binding_test.rb +0 -46
- data/test-with-deprecations/blaaaaaaaa_test.rb +0 -69
- data/test-with-deprecations/cached_test.rb +0 -147
- data/test-with-deprecations/class_test.rb +0 -119
- data/test-with-deprecations/coercion_test.rb +0 -52
- data/test-with-deprecations/config/inherit_test.rb +0 -135
- data/test-with-deprecations/config_test.rb +0 -122
- data/test-with-deprecations/decorator_scope_test.rb +0 -28
- data/test-with-deprecations/decorator_test.rb +0 -96
- data/test-with-deprecations/default_test.rb +0 -34
- data/test-with-deprecations/defaults_options_test.rb +0 -93
- data/test-with-deprecations/definition_test.rb +0 -264
- data/test-with-deprecations/example.rb +0 -310
- data/test-with-deprecations/examples/object.rb +0 -31
- data/test-with-deprecations/exec_context_test.rb +0 -93
- data/test-with-deprecations/features_test.rb +0 -70
- data/test-with-deprecations/filter_test.rb +0 -57
- data/test-with-deprecations/for_collection_test.rb +0 -74
- data/test-with-deprecations/generic_test.rb +0 -116
- data/test-with-deprecations/getter_setter_test.rb +0 -21
- data/test-with-deprecations/hash_bindings_test.rb +0 -87
- data/test-with-deprecations/hash_test.rb +0 -160
- data/test-with-deprecations/heritage_test.rb +0 -62
- data/test-with-deprecations/if_test.rb +0 -79
- data/test-with-deprecations/include_exclude_test.rb +0 -88
- data/test-with-deprecations/inherit_test.rb +0 -159
- data/test-with-deprecations/inline_test.rb +0 -272
- data/test-with-deprecations/instance_test.rb +0 -266
- data/test-with-deprecations/is_representable_test.rb +0 -77
- data/test-with-deprecations/json_test.rb +0 -355
- data/test-with-deprecations/lonely_test.rb +0 -239
- data/test-with-deprecations/mongoid_test.rb +0 -31
- data/test-with-deprecations/nested_test.rb +0 -115
- data/test-with-deprecations/object_test.rb +0 -60
- data/test-with-deprecations/parse_pipeline_test.rb +0 -64
- data/test-with-deprecations/parse_strategy_test.rb +0 -279
- data/test-with-deprecations/pass_options_test.rb +0 -27
- data/test-with-deprecations/pipeline_test.rb +0 -277
- data/test-with-deprecations/populator_test.rb +0 -105
- data/test-with-deprecations/prepare_test.rb +0 -67
- data/test-with-deprecations/private_options_test.rb +0 -18
- data/test-with-deprecations/reader_writer_test.rb +0 -19
- data/test-with-deprecations/realistic_benchmark.rb +0 -115
- data/test-with-deprecations/render_nil_test.rb +0 -21
- data/test-with-deprecations/represent_test.rb +0 -88
- data/test-with-deprecations/representable_test.rb +0 -511
- data/test-with-deprecations/schema_test.rb +0 -148
- data/test-with-deprecations/serialize_deserialize_test.rb +0 -33
- data/test-with-deprecations/skip_test.rb +0 -81
- data/test-with-deprecations/stringify_hash_test.rb +0 -41
- data/test-with-deprecations/test_helper.rb +0 -135
- data/test-with-deprecations/test_helper_test.rb +0 -25
- data/test-with-deprecations/uncategorized_test.rb +0 -67
- data/test-with-deprecations/user_options_test.rb +0 -15
- data/test-with-deprecations/wrap_test.rb +0 -152
- data/test-with-deprecations/xml_bindings_test.rb +0 -62
- data/test-with-deprecations/xml_test.rb +0 -503
- data/test-with-deprecations/yaml_test.rb +0 -162
- data/test/parse_strategy_test.rb +0 -279
@@ -1,93 +0,0 @@
|
|
1
|
-
module Representable
|
2
|
-
class Populator
|
3
|
-
FindOrInstantiate = ->(input, options) {
|
4
|
-
binding = options[:binding]
|
5
|
-
|
6
|
-
object_class = binding[:class].(input, options)
|
7
|
-
object = object_class.find_by(id: input["id"]) || object_class.new
|
8
|
-
if options[:binding].array?
|
9
|
-
# represented.songs[i] = model
|
10
|
-
options[:represented].send(binding.getter)[options[:index]] = object
|
11
|
-
else
|
12
|
-
# represented.song = model
|
13
|
-
options[:represented].send(binding.setter, object)
|
14
|
-
end
|
15
|
-
|
16
|
-
object
|
17
|
-
}
|
18
|
-
|
19
|
-
# pipeline: [StopOnExcluded, AssignName, ReadFragment, StopOnNotFound, OverwriteOnNil, AssignFragment, #<Representable::Function::CreateObject:0x9805a44>, #<Representable::Function::Decorate:0x9805a1c>, Deserialize, Set]
|
20
|
-
|
21
|
-
def self.apply!(options)
|
22
|
-
return unless populator = options[:populator]
|
23
|
-
|
24
|
-
options[:parse_pipeline] = ->(input, options) do
|
25
|
-
pipeline = Pipeline[*parse_functions] # TODO: AssignFragment
|
26
|
-
pipeline = Pipeline::Insert.(pipeline, SetValue, delete: true) # remove the setter function.
|
27
|
-
pipeline = Pipeline::Insert.(pipeline, populator, replace: CreateObject::Populator) # let the actual populator do the job.
|
28
|
-
# puts pipeline.extend(Representable::Pipeline::Debug).inspect
|
29
|
-
pipeline
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
FindOrInstantiate = Populator::FindOrInstantiate
|
35
|
-
|
36
|
-
# Parse strategies are just a combination of representable's options. They save you from memoizing the
|
37
|
-
# necessary parameters.
|
38
|
-
#
|
39
|
-
# Feel free to contribute your strategy if you think it's worth sharing!
|
40
|
-
class ParseStrategy
|
41
|
-
def self.apply!(options)
|
42
|
-
return unless strategy = options[:parse_strategy]
|
43
|
-
|
44
|
-
warn "[Representable] :parse_strategy is deprecated. Please use a populator."
|
45
|
-
|
46
|
-
strategy = :proc if strategy.is_a?(::Proc)
|
47
|
-
|
48
|
-
parse_strategies[strategy].apply!(name, options)
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.parse_strategies
|
52
|
-
{
|
53
|
-
:sync => Sync,
|
54
|
-
:find_or_instantiate => FindOrInstantiate,
|
55
|
-
:proc => Proc
|
56
|
-
}
|
57
|
-
end
|
58
|
-
|
59
|
-
|
60
|
-
# Using a lambda as parse_strategy does not set the parsed property for you.
|
61
|
-
class Proc
|
62
|
-
def self.apply!(name, options)
|
63
|
-
options[:setter] = lambda { |*| }
|
64
|
-
options[:pass_options] = true
|
65
|
-
options[:instance] = options[:parse_strategy]
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
|
70
|
-
class Sync
|
71
|
-
def self.apply!(name, options)
|
72
|
-
options[:setter] = lambda { |*args| }
|
73
|
-
options[:pass_options] = true
|
74
|
-
options[:instance] = options[:collection] ?
|
75
|
-
lambda { |options| options[:binding].get(options)[options[:index]] } :
|
76
|
-
lambda { |options| options[:binding].get(options) }
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
|
81
|
-
# replaces current collection.
|
82
|
-
class FindOrInstantiate
|
83
|
-
def self.apply!(name, options)
|
84
|
-
options[:pass_options] = true
|
85
|
-
options[:instance] = lambda { |options|
|
86
|
-
object_class = options[:binding][:class].evaluate(self, options)
|
87
|
-
|
88
|
-
object_class.find_by({id: options[:fragment]["id"]}) or object_class.new
|
89
|
-
}
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class AsTest < MiniTest::Spec
|
4
|
-
for_formats(
|
5
|
-
:hash => [Representable::Hash, {"title" => "Wie Es Geht"}, {"title" => "Revolution"}],
|
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
|
-
# :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"],
|
8
|
-
) do |format, mod, input, output|
|
9
|
-
|
10
|
-
let (:song) { representer.prepare(Song.new("Revolution")) }
|
11
|
-
let (:format) { format }
|
12
|
-
|
13
|
-
|
14
|
-
describe "as: with :symbol" do
|
15
|
-
representer!(:module => mod) do
|
16
|
-
property :name, :as => :title
|
17
|
-
end
|
18
|
-
|
19
|
-
it { render(song).must_equal_document output }
|
20
|
-
it { parse(song, input).name.must_equal "Wie Es Geht" }
|
21
|
-
end
|
22
|
-
|
23
|
-
|
24
|
-
describe "as: with lambda" do
|
25
|
-
representer!(:module => mod) do
|
26
|
-
property :name, :as => lambda { |*| "#{self.class}" }
|
27
|
-
end
|
28
|
-
|
29
|
-
it { render(song).must_equal_document({"Song" => "Revolution"}) }
|
30
|
-
it { parse(song, {"Song" => "Wie Es Geht"}).name.must_equal "Wie Es Geht" }
|
31
|
-
end
|
32
|
-
|
33
|
-
|
34
|
-
describe "lambda arguments" do
|
35
|
-
representer! do
|
36
|
-
property :name, :as => lambda { |*args| args.inspect }
|
37
|
-
end
|
38
|
-
|
39
|
-
it { render(song, :volume => 1).must_equal_document({"[{:volume=>1}]" => "Revolution"}) }
|
40
|
-
it { parse(song, {"[{:volume=>1}]" => "Wie Es Geht"}, :volume => 1).name.must_equal "Wie Es Geht" }
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
|
46
|
-
# hash: to_hash(wrap: ) is representation_wrap
|
47
|
-
|
48
|
-
class AsXmlTest < MiniTest::Spec
|
49
|
-
Band = Struct.new(:name, :label)
|
50
|
-
Album = Struct.new(:band)
|
51
|
-
Label = Struct.new(:name)
|
52
|
-
|
53
|
-
representer!(module: Representable::XML, decorator: true) do
|
54
|
-
self.representation_wrap = :album
|
55
|
-
property :band, as: :combo do
|
56
|
-
self.representation_wrap = :band
|
57
|
-
property :name
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
it do
|
62
|
-
skip
|
63
|
-
representer.new(Album.new(Band.new("Offspring"))).to_xml.must_equal ""
|
64
|
-
end
|
65
|
-
end
|
@@ -1,83 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'benchmark'
|
3
|
-
|
4
|
-
SONG_PROPERTIES = 1000.times.collect do |i|
|
5
|
-
"property_#{i}"
|
6
|
-
end
|
7
|
-
|
8
|
-
|
9
|
-
module SongRepresenter
|
10
|
-
include Representable::JSON
|
11
|
-
|
12
|
-
SONG_PROPERTIES.each { |p| property p }
|
13
|
-
end
|
14
|
-
|
15
|
-
class SongDecorator < Representable::Decorator
|
16
|
-
include Representable::JSON
|
17
|
-
|
18
|
-
SONG_PROPERTIES.each { |p| property p }
|
19
|
-
end
|
20
|
-
|
21
|
-
module AlbumRepresenter
|
22
|
-
include Representable::JSON
|
23
|
-
|
24
|
-
# collection :songs, extend: SongRepresenter
|
25
|
-
collection :songs, extend: SongDecorator
|
26
|
-
end
|
27
|
-
|
28
|
-
def random_song
|
29
|
-
attrs = Hash[SONG_PROPERTIES.collect { |n| [n,n] }]
|
30
|
-
OpenStruct.new(attrs)
|
31
|
-
end
|
32
|
-
|
33
|
-
times = []
|
34
|
-
|
35
|
-
3.times.each do
|
36
|
-
album = OpenStruct.new(songs: 100.times.collect { random_song })
|
37
|
-
|
38
|
-
times << Benchmark.measure do
|
39
|
-
puts "================ next!"
|
40
|
-
album.extend(AlbumRepresenter).to_json
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
puts times.join("")
|
45
|
-
|
46
|
-
# 100 songs, 100 attrs
|
47
|
-
# 0.050000 0.000000 0.050000 ( 0.093157)
|
48
|
-
|
49
|
-
## 100 songs, 1000 attrs
|
50
|
-
# 0.470000 0.010000 0.480000 ( 0.483708)
|
51
|
-
|
52
|
-
|
53
|
-
### without binding cache:
|
54
|
-
# 2.790000 0.030000 2.820000 ( 2.820190)
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
### with extend: on Song, with binding cache>
|
59
|
-
# 2.490000 0.030000 2.520000 ( 2.517433) 2.4-3.0
|
60
|
-
### without skip?
|
61
|
-
# 2.030000 0.020000 2.050000 ( 2.050796) 2.1-2.3
|
62
|
-
|
63
|
-
### without :writer
|
64
|
-
# 2.270000 0.010000 2.280000 ( 2.284530 1.9-2.2
|
65
|
-
### without :render_filter
|
66
|
-
# 2.020000 0.000000 2.020000 ( 2.030234) 1.5-2.0
|
67
|
-
###without default_for and skipable?
|
68
|
-
# 1.730000 0.010000 1.740000 ( 1.735597 1.4-1.7
|
69
|
-
### without :serialize
|
70
|
-
# 1.780000 0.010000 1.790000 ( 1.786791) 1.4-1.7
|
71
|
-
### using decorator
|
72
|
-
# 1.400000 0.030000 1.430000 ( 1.434206) 1.4-1.6
|
73
|
-
### with prepare AFTER representable?
|
74
|
-
# 1.330000 0.010000 1.340000 ( 1.335900) 1.1-1.3
|
75
|
-
|
76
|
-
|
77
|
-
# representable 2.0
|
78
|
-
# 3.000000 0.020000 3.020000 ( 3.013031) 2.7-3.0
|
79
|
-
|
80
|
-
# no method missing
|
81
|
-
# 2.280000 0.030000 2.310000 ( 2.313522) 2.2-2.5
|
82
|
-
# no def_delegator in Definition
|
83
|
-
# 2.130000 0.010000 2.140000 ( 2.136115) 1.7-2.1
|
@@ -1,46 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class BindingTest < MiniTest::Spec
|
4
|
-
Binding = Representable::Binding
|
5
|
-
let (:render_nil_definition) { Representable::Definition.new(:song, :render_nil => true) }
|
6
|
-
|
7
|
-
describe "#skipable_empty_value?" do
|
8
|
-
let (:binding) { Binding.new(render_nil_definition) }
|
9
|
-
|
10
|
-
# don't skip when present.
|
11
|
-
it { binding.skipable_empty_value?("Disconnect, Disconnect").must_equal false }
|
12
|
-
|
13
|
-
# don't skip when it's nil and render_nil: true
|
14
|
-
it { binding.skipable_empty_value?(nil).must_equal false }
|
15
|
-
|
16
|
-
# skip when nil and :render_nil undefined.
|
17
|
-
it { Binding.new(Representable::Definition.new(:song)).skipable_empty_value?(nil).must_equal true }
|
18
|
-
|
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 }
|
21
|
-
end
|
22
|
-
|
23
|
-
|
24
|
-
describe "#default_for" do
|
25
|
-
let (:definition) { Representable::Definition.new(:song, :default => "Insider") }
|
26
|
-
let (:binding) { Binding.new(definition) }
|
27
|
-
|
28
|
-
# return value when value present.
|
29
|
-
it { binding.default_for("Black And Blue").must_equal "Black And Blue" }
|
30
|
-
|
31
|
-
# return false when value false.
|
32
|
-
it { binding.default_for(false).must_equal false }
|
33
|
-
|
34
|
-
# return default when value nil.
|
35
|
-
it { binding.default_for(nil).must_equal "Insider" }
|
36
|
-
|
37
|
-
# return nil when value nil and render_nil: true.
|
38
|
-
it { Binding.new(render_nil_definition).default_for(nil).must_equal nil }
|
39
|
-
|
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 }
|
42
|
-
|
43
|
-
# return nil if no :default
|
44
|
-
it { Binding.new(Representable::Definition.new(:song)).default_for(nil).must_equal nil }
|
45
|
-
end
|
46
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
# Include Inherit Module And Decorator Test
|
7
|
-
class SchemaTest < MiniTest::Spec
|
8
|
-
module Genre
|
9
|
-
include Representable
|
10
|
-
property :genre
|
11
|
-
end
|
12
|
-
|
13
|
-
module LinkFeature
|
14
|
-
def self.included(base)
|
15
|
-
base.extend(Link)
|
16
|
-
end
|
17
|
-
|
18
|
-
module Link
|
19
|
-
def link
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
|
25
|
-
module Module
|
26
|
-
include Representable::Hash
|
27
|
-
feature LinkFeature
|
28
|
-
|
29
|
-
property :title
|
30
|
-
property :label do # extend: LabelModule
|
31
|
-
property :name
|
32
|
-
link # feature
|
33
|
-
|
34
|
-
property :location do
|
35
|
-
property :city
|
36
|
-
link # feature.
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
property :album, :extend => lambda { raise "don't manifest me!" } # this is not an inline decorator, don't manifest it.
|
41
|
-
|
42
|
-
|
43
|
-
include Genre # Schema::Included::included is called!
|
44
|
-
end
|
45
|
-
|
46
|
-
|
47
|
-
class InheritDecorator < Representable::Decorator
|
48
|
-
include Representable::Hash
|
49
|
-
|
50
|
-
include Module
|
51
|
-
|
52
|
-
property :label, inherit: true do # decorator.rb:27:in `initialize': superclass must be a Class (Module given)
|
53
|
-
property :city
|
54
|
-
|
55
|
-
property :location, :inherit => true do
|
56
|
-
property :city
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
|
62
|
-
class InheritFromDecorator < InheritDecorator
|
63
|
-
property :label, inherit: true do
|
64
|
-
collection :employees do
|
65
|
-
property :name
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
@@ -1,147 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
require 'ruby-prof'
|
3
|
-
|
4
|
-
class CachedTest < MiniTest::Spec
|
5
|
-
# TODO: also test with feature(Cached)
|
6
|
-
|
7
|
-
module Model
|
8
|
-
Song = Struct.new(:title, :composer)
|
9
|
-
Album = Struct.new(:name, :songs, :artist)
|
10
|
-
Artist = Struct.new(:name, :hidden_taste)
|
11
|
-
end
|
12
|
-
|
13
|
-
class SongRepresenter < Representable::Decorator
|
14
|
-
include Representable::Hash
|
15
|
-
feature Representable::Cached
|
16
|
-
|
17
|
-
property :title, render_filter: lambda { |input, options| "#{input}:#{options[:options][:user_options]}" }
|
18
|
-
property :composer, class: Model::Artist do
|
19
|
-
property :name
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
class AlbumRepresenter < Representable::Decorator
|
24
|
-
include Representable::Hash
|
25
|
-
include Representable::Cached
|
26
|
-
|
27
|
-
property :name
|
28
|
-
collection :songs, decorator: SongRepresenter, class: Model::Song
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
|
-
describe "serialization" do
|
33
|
-
let (:album_hash) { {"name"=>"Louder And Even More Dangerous", "songs"=>[{"title"=>"Southbound:{:volume=>10}"}, {"title"=>"Jailbreak:{:volume=>10}"}]} }
|
34
|
-
|
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) }
|
39
|
-
|
40
|
-
it do
|
41
|
-
album2 = Model::Album.new("Louder And Even More Dangerous", [song2, song])
|
42
|
-
|
43
|
-
# makes sure options are passed correctly.
|
44
|
-
representer.to_hash(volume: 9).must_equal({"name"=>"Live And Dangerous",
|
45
|
-
"songs"=>[{"title"=>"Jailbreak:{:volume=>9}"}, {"title"=>"Southbound:{:volume=>9}"}, {"title"=>"Emerald:{:volume=>9}"}]}) # called in Deserializer/Serializer
|
46
|
-
|
47
|
-
# representer becomes reusable as it is stateless.
|
48
|
-
# representer.update!(album2)
|
49
|
-
|
50
|
-
# makes sure options are passed correctly.
|
51
|
-
# representer.to_hash(volume:10).must_equal(album_hash)
|
52
|
-
end
|
53
|
-
|
54
|
-
# profiling
|
55
|
-
it do
|
56
|
-
representer.to_hash
|
57
|
-
|
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)
|
69
|
-
|
70
|
-
# 3 songs get decorated.
|
71
|
-
data.must_match "3 Representable::Function::Decorate#call"
|
72
|
-
# 3 nested decorator is instantiated for 3 Songs, though.
|
73
|
-
data.must_match "3 <Class::Representable::Decorator>#prepare"
|
74
|
-
# no Binding is instantiated at runtime.
|
75
|
-
data.wont_match "Representable::Binding#initialize"
|
76
|
-
# 2 mappers for Album, Song
|
77
|
-
# data.must_match "2 Representable::Mapper::Methods#initialize"
|
78
|
-
# 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"
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
|
86
|
-
describe "deserialization" do
|
87
|
-
let (:album_hash) {
|
88
|
-
{
|
89
|
-
"name"=>"Louder And Even More Dangerous",
|
90
|
-
"songs"=>[
|
91
|
-
{"title"=>"Southbound", "composer"=>{"name"=>"Lynott"}},
|
92
|
-
{"title"=>"Jailbreak", "composer"=>{"name"=>"Phil Lynott"}},
|
93
|
-
{"title"=>"Emerald"}
|
94
|
-
]
|
95
|
-
}
|
96
|
-
}
|
97
|
-
|
98
|
-
it do
|
99
|
-
album = Model::Album.new
|
100
|
-
|
101
|
-
AlbumRepresenter.new(album).from_hash(album_hash)
|
102
|
-
|
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
|
111
|
-
|
112
|
-
# TODO: test options.
|
113
|
-
end
|
114
|
-
|
115
|
-
it "xxx" do
|
116
|
-
representer = AlbumRepresenter.new(Model::Album.new)
|
117
|
-
representer.from_hash(album_hash)
|
118
|
-
|
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
|
129
|
-
|
130
|
-
# only 2 nested decorators are instantiated, Song, and Artist.
|
131
|
-
data.must_match "5 <Class::Representable::Decorator>#prepare"
|
132
|
-
# a total of 5 properties in the object graph.
|
133
|
-
data.wont_match "Representable::Binding#initialize"
|
134
|
-
|
135
|
-
|
136
|
-
data.wont_match "parse_functions" # no pipeline creation.
|
137
|
-
data.must_match "10 Representable::Binding#parse_pipeline"
|
138
|
-
# three mappers for Album, Song, composer
|
139
|
-
# data.must_match "3 Representable::Mapper::Methods#initialize"
|
140
|
-
# # 6 deserializers as the songs collection uses 2.
|
141
|
-
# data.must_match "6 Representable::Deserializer#initialize"
|
142
|
-
# # one populater for every property.
|
143
|
-
# data.must_match "5 Representable::Populator#initialize"
|
144
|
-
# printer.print(STDOUT)
|
145
|
-
end
|
146
|
-
end
|
147
|
-
end
|