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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2bb7b8770886210c259064f3d2ba30d7fd3b4e50350e0a9cbd98640261ac3879
|
|
4
|
+
data.tar.gz: 664ee784de146034f31308b2207a121e0a1fbeea38ca3989fc09a1fe04016bc1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1ecad360b289f31fa0ed925369e3541cb580154c158c1f6b21dd0c0e9ebd98945fe1534292e882521ef3d6c0a24447f55a1b1267deb29282af0d7d1d0b8970c9
|
|
7
|
+
data.tar.gz: dce51b8db19df9005a598272847b55088a9f0ee91c6e4f5aed33075ac43bc28b8edac1a76a020be2e195c3358dc13b1a698ae78cb0d323ce2c3c4ede4a52c912
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -1,23 +1,30 @@
|
|
|
1
|
+
## This file is managed by Terraform.
|
|
2
|
+
## Do not modify this file directly, as it may be overwritten.
|
|
3
|
+
## Please open an issue instead.
|
|
1
4
|
name: CI
|
|
2
|
-
on:
|
|
3
|
-
push:
|
|
4
|
-
branches:
|
|
5
|
-
- master
|
|
6
|
-
pull_request:
|
|
7
|
-
branches:
|
|
8
|
-
- master
|
|
9
|
-
|
|
5
|
+
on: [push, pull_request]
|
|
10
6
|
jobs:
|
|
11
7
|
test:
|
|
12
8
|
strategy:
|
|
13
9
|
fail-fast: false
|
|
14
10
|
matrix:
|
|
15
|
-
ruby: [
|
|
11
|
+
ruby: ["3.0", "3.1", "3.2", '3.3', '3.4', '4.0']
|
|
16
12
|
runs-on: ubuntu-latest
|
|
17
13
|
steps:
|
|
18
|
-
- uses: actions/checkout@
|
|
14
|
+
- uses: actions/checkout@v7
|
|
19
15
|
- uses: ruby/setup-ruby@v1
|
|
20
16
|
with:
|
|
21
17
|
ruby-version: ${{ matrix.ruby }}
|
|
22
18
|
bundler-cache: true
|
|
23
19
|
- run: bundle exec rake
|
|
20
|
+
|
|
21
|
+
test-head:
|
|
22
|
+
continue-on-error: true
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v7
|
|
26
|
+
- uses: ruby/setup-ruby@v1
|
|
27
|
+
with:
|
|
28
|
+
ruby-version: head
|
|
29
|
+
bundler-cache: true
|
|
30
|
+
- run: bundle exec rake
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
## This file is managed by Terraform.
|
|
2
|
+
## Do not modify this file directly, as it may be overwritten.
|
|
3
|
+
## Please open an issue instead.
|
|
4
|
+
name: CI JRuby
|
|
5
|
+
on: [push, pull_request]
|
|
6
|
+
jobs:
|
|
7
|
+
test:
|
|
8
|
+
strategy:
|
|
9
|
+
fail-fast: false
|
|
10
|
+
matrix:
|
|
11
|
+
ruby: [jruby, jruby-head]
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v7
|
|
15
|
+
- uses: ruby/setup-ruby@v1
|
|
16
|
+
with:
|
|
17
|
+
ruby-version: ${{ matrix.ruby }}
|
|
18
|
+
bundler-cache: true
|
|
19
|
+
- run: bundle exec rake
|
|
20
|
+
env:
|
|
21
|
+
JRUBY_OPTS: --profile.api
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
## This file is managed by Terraform.
|
|
2
|
+
## Do not modify this file directly, as it may be overwritten.
|
|
3
|
+
## Please open an issue instead.
|
|
4
|
+
name: CI TruffleRuby
|
|
5
|
+
on: [push, pull_request]
|
|
6
|
+
jobs:
|
|
7
|
+
test:
|
|
8
|
+
strategy:
|
|
9
|
+
fail-fast: false
|
|
10
|
+
matrix:
|
|
11
|
+
ruby: [truffleruby, truffleruby-head]
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v7
|
|
15
|
+
- uses: ruby/setup-ruby@v1
|
|
16
|
+
with:
|
|
17
|
+
ruby-version: ${{ matrix.ruby }}
|
|
18
|
+
bundler-cache: true
|
|
19
|
+
- run: bundle exec rake
|
data/CHANGES.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# Representable
|
|
2
2
|
|
|
3
3
|
Representable maps Ruby objects to documents and back.
|
|
4
|
-
|
|
5
4
|

|
|
7
6
|
[](http://badge.fury.io/rb/representable)
|
data/lib/representable/json.rb
CHANGED
|
@@ -6,6 +6,18 @@ require "representable"
|
|
|
6
6
|
module Representable
|
|
7
7
|
# Brings #to_json and #from_json to your object.
|
|
8
8
|
module JSON
|
|
9
|
+
if Kernel.const_defined?(:MultiJson) # Ruby 3.0
|
|
10
|
+
module MultiJSON
|
|
11
|
+
def self.generate(*args)
|
|
12
|
+
MultiJson.dump(*args)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.parse(*args)
|
|
16
|
+
MultiJson.load(*args)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
9
21
|
autoload :Collection, "representable/json/collection"
|
|
10
22
|
|
|
11
23
|
extend Hash::ClassMethods
|
|
@@ -33,13 +45,13 @@ module Representable
|
|
|
33
45
|
|
|
34
46
|
# Parses the body as JSON and delegates to #from_hash.
|
|
35
47
|
def from_json(data, *args)
|
|
36
|
-
data =
|
|
48
|
+
data = MultiJSON.parse(data)
|
|
37
49
|
from_hash(data, *args)
|
|
38
50
|
end
|
|
39
51
|
|
|
40
52
|
# Returns a JSON string representing this object.
|
|
41
53
|
def to_json(*args)
|
|
42
|
-
|
|
54
|
+
MultiJSON.generate to_hash(*args)
|
|
43
55
|
end
|
|
44
56
|
|
|
45
57
|
alias_method :render, :to_json
|
|
@@ -2,13 +2,6 @@ require 'representable/binding'
|
|
|
2
2
|
|
|
3
3
|
module Representable
|
|
4
4
|
module XML
|
|
5
|
-
module_function def Node(document, name, attributes={})
|
|
6
|
-
node = Nokogiri::XML::Node.new(name.to_s, document) # Java::OrgW3cDom::DOMException: NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces.
|
|
7
|
-
|
|
8
|
-
attributes.each { |k, v| node[k] = v } # TODO: benchmark.
|
|
9
|
-
node
|
|
10
|
-
end
|
|
11
|
-
|
|
12
5
|
class Binding < Representable::Binding
|
|
13
6
|
def self.build_for(definition)
|
|
14
7
|
return Collection.new(definition) if definition.array?
|
data/lib/representable/xml.rb
CHANGED
|
@@ -9,6 +9,13 @@ module Representable
|
|
|
9
9
|
autoload :Collection, 'representable/xml/collection'
|
|
10
10
|
autoload :Namespace, 'representable/xml/namespace'
|
|
11
11
|
|
|
12
|
+
module_function def Node(document, name, attributes={})
|
|
13
|
+
node = document.create_element(name.to_s)
|
|
14
|
+
|
|
15
|
+
attributes.each { |k, v| node[k] = v } # TODO: benchmark.
|
|
16
|
+
node
|
|
17
|
+
end
|
|
18
|
+
|
|
12
19
|
def self.included(base)
|
|
13
20
|
base.class_eval do
|
|
14
21
|
include Representable
|
data/representable.gemspec
CHANGED
|
@@ -19,16 +19,14 @@ Gem::Specification.new do |spec|
|
|
|
19
19
|
spec.require_paths = ["lib"]
|
|
20
20
|
spec.license = "MIT"
|
|
21
21
|
|
|
22
|
-
spec.required_ruby_version = '>=
|
|
22
|
+
spec.required_ruby_version = '>= 3.0.0'
|
|
23
23
|
|
|
24
24
|
spec.add_dependency "uber", "< 0.2.0"
|
|
25
25
|
spec.add_dependency "declarative", "< 0.1.0"
|
|
26
26
|
spec.add_dependency "trailblazer-option", ">= 0.1.1", "< 0.2.0"
|
|
27
27
|
|
|
28
28
|
spec.add_development_dependency "rake"
|
|
29
|
-
spec.add_development_dependency "test_xml", ">= 0.1.6"
|
|
30
29
|
spec.add_development_dependency "minitest"
|
|
31
|
-
spec.add_development_dependency "virtus"
|
|
32
30
|
spec.add_development_dependency "dry-types"
|
|
33
31
|
spec.add_development_dependency "ruby-prof" if RUBY_ENGINE == "ruby" # mri
|
|
34
32
|
end
|
data/test/as_test.rb
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
|
-
class AsTest <
|
|
3
|
+
class AsTest < Minitest::Spec
|
|
4
4
|
for_formats(
|
|
5
|
-
:hash => [Representable::Hash, {"title" => "Wie Es Geht"}, {"title" => "Revolution"}]
|
|
5
|
+
:hash => [Representable::Hash, {"title" => "Wie Es Geht"}, {"title" => "Revolution"}]
|
|
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("Revolution")) }
|
|
11
10
|
let(:format) { format }
|
|
12
11
|
|
|
13
|
-
|
|
14
12
|
describe "as: with :symbol" do
|
|
15
13
|
representer!(:module => mod) do
|
|
16
14
|
property :name, :as => :title
|
|
@@ -20,32 +18,29 @@ class AsTest < MiniTest::Spec
|
|
|
20
18
|
it { _(parse(song, input).name).must_equal "Wie Es Geht" }
|
|
21
19
|
end
|
|
22
20
|
|
|
23
|
-
|
|
24
21
|
describe "as: with lambda" do
|
|
25
22
|
representer!(:module => mod) do
|
|
26
|
-
property :name, :as =>
|
|
23
|
+
property :name, :as => ->(*) { self.class.to_s }
|
|
27
24
|
end
|
|
28
25
|
|
|
29
26
|
it { render(song).must_equal_document({"Song" => "Revolution"}) }
|
|
30
27
|
it { _(parse(song, {"Song" => "Wie Es Geht"}).name).must_equal "Wie Es Geht" }
|
|
31
28
|
end
|
|
32
29
|
|
|
33
|
-
|
|
34
30
|
describe "lambda arguments" do
|
|
35
31
|
representer! do
|
|
36
|
-
property :name, :as =>
|
|
32
|
+
property :name, :as => ->(options) { options[:user_options].inspect }
|
|
37
33
|
end
|
|
38
34
|
|
|
39
|
-
it { render(song, user_options:{volume: 1}).must_equal_document({
|
|
40
|
-
it { _(parse(song, {
|
|
35
|
+
it { render(song, user_options: {volume: 1}).must_equal_document({{volume: 1}.inspect => "Revolution"}) }
|
|
36
|
+
it { _(parse(song, {{volume: 1}.inspect => "Wie Es Geht"}, user_options: {volume: 1}).name).must_equal "Wie Es Geht" }
|
|
41
37
|
end
|
|
42
38
|
end
|
|
43
39
|
end
|
|
44
40
|
|
|
45
|
-
|
|
46
41
|
# hash: to_hash(wrap: ) is representation_wrap
|
|
47
42
|
|
|
48
|
-
class AsXmlTest <
|
|
43
|
+
class AsXmlTest < Minitest::Spec
|
|
49
44
|
Band = Struct.new(:name, :label)
|
|
50
45
|
Album = Struct.new(:band)
|
|
51
46
|
Label = Struct.new(:name)
|
data/test/benchmarking.rb
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
|
+
require "benchmark"
|
|
3
3
|
|
|
4
4
|
SONG_PROPERTIES = 1000.times.collect do |i|
|
|
5
5
|
"property_#{i}"
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
-
|
|
9
8
|
module SongRepresenter
|
|
10
9
|
include Representable::JSON
|
|
11
10
|
|
|
@@ -26,7 +25,7 @@ module AlbumRepresenter
|
|
|
26
25
|
end
|
|
27
26
|
|
|
28
27
|
def random_song
|
|
29
|
-
attrs = Hash[SONG_PROPERTIES.collect { |n| [n,n] }]
|
|
28
|
+
attrs = Hash[SONG_PROPERTIES.collect { |n| [n, n] }]
|
|
30
29
|
OpenStruct.new(attrs)
|
|
31
30
|
end
|
|
32
31
|
|
|
@@ -49,30 +48,26 @@ puts times.join("")
|
|
|
49
48
|
## 100 songs, 1000 attrs
|
|
50
49
|
# 0.470000 0.010000 0.480000 ( 0.483708)
|
|
51
50
|
|
|
52
|
-
|
|
53
51
|
### without binding cache:
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
# 2.790000 0.030000 2.820000 ( 2.820190)
|
|
57
53
|
|
|
58
54
|
### with extend: on Song, with binding cache>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
55
|
+
# 2.490000 0.030000 2.520000 ( 2.517433) 2.4-3.0
|
|
56
|
+
### without skip?
|
|
57
|
+
# 2.030000 0.020000 2.050000 ( 2.050796) 2.1-2.3
|
|
58
|
+
|
|
59
|
+
### without :writer
|
|
60
|
+
# 2.270000 0.010000 2.280000 ( 2.284530 1.9-2.2
|
|
61
|
+
### without :render_filter
|
|
62
|
+
# 2.020000 0.000000 2.020000 ( 2.030234) 1.5-2.0
|
|
63
|
+
# ##without default_for and skipable?
|
|
64
|
+
# 1.730000 0.010000 1.740000 ( 1.735597 1.4-1.7
|
|
65
|
+
### without :serialize
|
|
66
|
+
# 1.780000 0.010000 1.790000 ( 1.786791) 1.4-1.7
|
|
67
|
+
### using decorator
|
|
68
|
+
# 1.400000 0.030000 1.430000 ( 1.434206) 1.4-1.6
|
|
69
|
+
### with prepare AFTER representable?
|
|
70
|
+
# 1.330000 0.010000 1.340000 ( 1.335900) 1.1-1.3
|
|
76
71
|
|
|
77
72
|
# representable 2.0
|
|
78
73
|
# 3.000000 0.020000 3.020000 ( 3.013031) 2.7-3.0
|
data/test/binding_test.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
|
-
class BindingTest <
|
|
3
|
+
class BindingTest < Minitest::Spec
|
|
4
4
|
Binding = Representable::Binding
|
|
5
5
|
let(:render_nil_definition) { Representable::Definition.new(:song, :render_nil => true) }
|
|
6
6
|
|
|
@@ -20,7 +20,6 @@ class BindingTest < MiniTest::Spec
|
|
|
20
20
|
it { _(Binding.new(Representable::Definition.new(:song)).skipable_empty_value?("Fatal Flu")).must_equal false }
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
|
|
24
23
|
describe "#default_for" do
|
|
25
24
|
let(:definition) { Representable::Definition.new(:song, :default => "Insider") }
|
|
26
25
|
let(:binding) { Binding.new(definition) }
|
|
@@ -38,9 +37,18 @@ class BindingTest < MiniTest::Spec
|
|
|
38
37
|
it { _(Binding.new(render_nil_definition).default_for(nil)).must_be_nil }
|
|
39
38
|
|
|
40
39
|
# return nil when value nil and render_nil: true, even when :default is set" do
|
|
41
|
-
it {
|
|
40
|
+
it {
|
|
41
|
+
_(
|
|
42
|
+
Binding.new(
|
|
43
|
+
Representable::Definition.new(
|
|
44
|
+
:song, :render_nil => true,
|
|
45
|
+
:default => "The Quest"
|
|
46
|
+
)
|
|
47
|
+
).default_for(nil)
|
|
48
|
+
).must_be_nil
|
|
49
|
+
}
|
|
42
50
|
|
|
43
51
|
# return nil if no :default
|
|
44
52
|
it { _(Binding.new(Representable::Definition.new(:song)).default_for(nil)).must_be_nil }
|
|
45
53
|
end
|
|
46
|
-
end
|
|
54
|
+
end
|
data/test/cached_test.rb
CHANGED
|
@@ -1,30 +1,36 @@
|
|
|
1
1
|
require "test_helper"
|
|
2
2
|
|
|
3
3
|
class Profiler
|
|
4
|
+
SUPPORTED_ENGINES = %w[ruby jruby].freeze
|
|
5
|
+
|
|
6
|
+
def self.available?
|
|
7
|
+
SUPPORTED_ENGINES.include?(RUBY_ENGINE)
|
|
8
|
+
end
|
|
9
|
+
|
|
4
10
|
def self.profile(&block)
|
|
5
11
|
case RUBY_ENGINE
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
12
|
+
when "ruby"
|
|
13
|
+
require "ruby-prof"
|
|
14
|
+
|
|
15
|
+
output = StringIO.new
|
|
16
|
+
profile_result = RubyProf::Profile.profile(&block)
|
|
17
|
+
printer = RubyProf::FlatPrinter.new(profile_result)
|
|
18
|
+
printer.print(output)
|
|
19
|
+
output.string
|
|
20
|
+
when "jruby"
|
|
21
|
+
require "jruby/profiler"
|
|
22
|
+
|
|
23
|
+
output_stream = java.io.ByteArrayOutputStream.new
|
|
24
|
+
print_stream = java.io.PrintStream.new(output_stream)
|
|
25
|
+
profile_result = JRuby::Profiler.profile(&block)
|
|
26
|
+
printer = JRuby::Profiler::FlatProfilePrinter.new(profile_result)
|
|
27
|
+
printer.printProfile(print_stream)
|
|
28
|
+
output_stream.toString
|
|
23
29
|
end
|
|
24
30
|
end
|
|
25
31
|
end
|
|
26
32
|
|
|
27
|
-
class CachedTest <
|
|
33
|
+
class CachedTest < Minitest::Spec
|
|
28
34
|
# TODO: also test with feature(Cached)
|
|
29
35
|
|
|
30
36
|
module Model
|
|
@@ -37,7 +43,7 @@ class CachedTest < MiniTest::Spec
|
|
|
37
43
|
include Representable::Hash
|
|
38
44
|
feature Representable::Cached
|
|
39
45
|
|
|
40
|
-
property :title, render_filter:
|
|
46
|
+
property :title, render_filter: ->(input, options) { "#{input}:#{options[:options][:user_options]}" }
|
|
41
47
|
property :composer, class: Model::Artist do
|
|
42
48
|
property :name
|
|
43
49
|
end
|
|
@@ -51,9 +57,13 @@ class CachedTest < MiniTest::Spec
|
|
|
51
57
|
collection :songs, decorator: SongRepresenter, class: Model::Song
|
|
52
58
|
end
|
|
53
59
|
|
|
54
|
-
|
|
55
60
|
describe "serialization" do
|
|
56
|
-
let(:album_hash)
|
|
61
|
+
let(:album_hash) do
|
|
62
|
+
{
|
|
63
|
+
"name" => "Louder And Even More Dangerous",
|
|
64
|
+
"songs" => [{"title" => "Southbound:#{{volume: 10}.inspect}"}, {"title" => "Jailbreak:#{{volume: 10}.inspect}"}]
|
|
65
|
+
}
|
|
66
|
+
end
|
|
57
67
|
|
|
58
68
|
let(:song) { Model::Song.new("Jailbreak") }
|
|
59
69
|
let(:song2) { Model::Song.new("Southbound") }
|
|
@@ -64,8 +74,15 @@ class CachedTest < MiniTest::Spec
|
|
|
64
74
|
# album2 = Model::Album.new("Louder And Even More Dangerous", [song2, song])
|
|
65
75
|
|
|
66
76
|
# makes sure options are passed correctly.
|
|
67
|
-
_(representer.to_hash(user_options: {volume: 9})).must_equal(
|
|
68
|
-
|
|
77
|
+
_(representer.to_hash(user_options: {volume: 9})).must_equal(
|
|
78
|
+
{
|
|
79
|
+
"name" => "Live And Dangerous",
|
|
80
|
+
"songs" => [
|
|
81
|
+
{"title" => "Jailbreak:#{{volume: 9}.inspect}"}, {"title" => "Southbound:#{{volume: 9}.inspect}"},
|
|
82
|
+
{"title" => "Emerald:#{{volume: 9}.inspect}"}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
) # called in Deserializer/Serializer
|
|
69
86
|
|
|
70
87
|
# representer becomes reusable as it is stateless.
|
|
71
88
|
# representer.update!(album2)
|
|
@@ -76,6 +93,8 @@ class CachedTest < MiniTest::Spec
|
|
|
76
93
|
|
|
77
94
|
# profiling
|
|
78
95
|
it do
|
|
96
|
+
skip "no profiler available for #{RUBY_ENGINE}" unless Profiler.available?
|
|
97
|
+
|
|
79
98
|
representer.to_hash
|
|
80
99
|
|
|
81
100
|
data = Profiler.profile { representer.to_hash }
|
|
@@ -88,30 +107,29 @@ class CachedTest < MiniTest::Spec
|
|
|
88
107
|
# - "3 Representable::Decorator.prepare" -> At JRuby
|
|
89
108
|
|
|
90
109
|
# 3 nested decorator is instantiated for 3 Songs, though.
|
|
91
|
-
_(data).must_match(/3\s*(<Class::)?Representable::Decorator
|
|
110
|
+
_(data).must_match(/3\s*(<Class::)?Representable::Decorator>?[\#.]prepare/m)
|
|
92
111
|
# no Binding is instantiated at runtime.
|
|
93
112
|
_(data).wont_match "Representable::Binding#initialize"
|
|
94
113
|
# 2 mappers for Album, Song
|
|
95
114
|
# data.must_match "2 Representable::Mapper::Methods#initialize"
|
|
96
115
|
# title, songs, 3x title, composer
|
|
97
|
-
_(data).must_match(/8\s*Representable::Binding[
|
|
116
|
+
_(data).must_match(/8\s*Representable::Binding[#.]render_pipeline/m)
|
|
98
117
|
_(data).wont_match "render_functions"
|
|
99
118
|
_(data).wont_match "Representable::Binding::Factories#render_functions"
|
|
100
119
|
end
|
|
101
120
|
end
|
|
102
121
|
|
|
103
|
-
|
|
104
122
|
describe "deserialization" do
|
|
105
|
-
let(:album_hash)
|
|
123
|
+
let(:album_hash) do
|
|
106
124
|
{
|
|
107
|
-
"name"=>"Louder And Even More Dangerous",
|
|
108
|
-
"songs"=>[
|
|
109
|
-
{"title"=>"Southbound", "composer"=>{"name"=>"Lynott"}},
|
|
110
|
-
{"title"=>"Jailbreak", "composer"=>{"name"=>"Phil Lynott"}},
|
|
125
|
+
"name" => "Louder And Even More Dangerous",
|
|
126
|
+
"songs" => [
|
|
127
|
+
{"title" => "Southbound", "composer" => {"name"=>"Lynott"}},
|
|
128
|
+
{"title" => "Jailbreak", "composer" => {"name"=>"Phil Lynott"}},
|
|
111
129
|
{"title"=>"Emerald"}
|
|
112
130
|
]
|
|
113
131
|
}
|
|
114
|
-
|
|
132
|
+
end
|
|
115
133
|
|
|
116
134
|
it do
|
|
117
135
|
album = Model::Album.new
|
|
@@ -131,6 +149,8 @@ class CachedTest < MiniTest::Spec
|
|
|
131
149
|
end
|
|
132
150
|
|
|
133
151
|
it "xxx" do
|
|
152
|
+
skip "no profiler available for #{RUBY_ENGINE}" unless Profiler.available?
|
|
153
|
+
|
|
134
154
|
representer = AlbumRepresenter.new(Model::Album.new)
|
|
135
155
|
representer.from_hash(album_hash)
|
|
136
156
|
|
|
@@ -139,12 +159,12 @@ class CachedTest < MiniTest::Spec
|
|
|
139
159
|
# only 2 nested decorators are instantiated, Song, and Artist.
|
|
140
160
|
# Didn't like the regexp?
|
|
141
161
|
# MRI and JRuby has different output formats. See note above.
|
|
142
|
-
_(data).must_match(/5\s*(<Class::)?Representable::Decorator>?[
|
|
162
|
+
_(data).must_match(/5\s*(<Class::)?Representable::Decorator>?[#.]prepare/)
|
|
143
163
|
# a total of 5 properties in the object graph.
|
|
144
164
|
_(data).wont_match "Representable::Binding#initialize"
|
|
145
165
|
|
|
146
166
|
_(data).wont_match "parse_functions" # no pipeline creation.
|
|
147
|
-
_(data).must_match(/10\s*Representable::Binding[
|
|
167
|
+
_(data).must_match(/10\s*Representable::Binding[#.]parse_pipeline/)
|
|
148
168
|
# three mappers for Album, Song, composer
|
|
149
169
|
# data.must_match "3 Representable::Mapper::Methods#initialize"
|
|
150
170
|
# # 6 deserializers as the songs collection uses 2.
|
|
@@ -154,4 +174,4 @@ class CachedTest < MiniTest::Spec
|
|
|
154
174
|
# printer.print(STDOUT)
|
|
155
175
|
end
|
|
156
176
|
end
|
|
157
|
-
end
|
|
177
|
+
end
|