roar 1.0.4 → 1.1.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 +14 -6
- data/CHANGES.markdown +75 -58
- data/CONTRIBUTING.md +31 -0
- data/Gemfile +12 -2
- data/ISSUE_TEMPLATE.md +20 -0
- data/LICENSE +1 -1
- data/README.markdown +126 -250
- data/Rakefile +3 -1
- data/examples/example.rb +0 -0
- data/examples/example_server.rb +0 -0
- data/lib/roar.rb +3 -3
- data/lib/roar/client.rb +8 -3
- data/lib/roar/decorator.rb +2 -2
- data/lib/roar/http_verbs.rb +0 -16
- data/lib/roar/hypermedia.rb +30 -56
- data/lib/roar/json.rb +5 -5
- data/lib/roar/json/collection.rb +10 -2
- data/lib/roar/json/hal.rb +72 -82
- data/lib/roar/version.rb +1 -1
- data/lib/roar/xml.rb +1 -1
- data/roar.gemspec +6 -6
- data/test/client_test.rb +1 -1
- data/test/coercion_feature_test.rb +7 -2
- data/test/decorator_test.rb +17 -7
- data/test/hal_json_test.rb +98 -106
- data/test/hypermedia_feature_test.rb +13 -31
- data/test/hypermedia_test.rb +26 -92
- data/test/{decorator_client_test.rb → integration/decorator_client_test.rb} +5 -4
- data/test/{faraday_http_transport_test.rb → integration/faraday_http_transport_test.rb} +1 -0
- data/test/{http_verbs_test.rb → integration/http_verbs_test.rb} +3 -2
- data/test/integration/json_collection_test.rb +35 -0
- data/test/{net_http_transport_test.rb → integration/net_http_transport_test.rb} +1 -0
- data/test/integration/runner.rb +2 -3
- data/test/integration/server.rb +6 -0
- data/test/json_representer_test.rb +2 -29
- data/test/lonely_test.rb +1 -2
- data/test/ssl_client_certs_test.rb +1 -1
- data/test/test_helper.rb +21 -3
- data/test/xml_representer_test.rb +6 -5
- metadata +22 -36
- data/gemfiles/Gemfile.representable-1.7 +0 -6
- data/gemfiles/Gemfile.representable-1.8 +0 -6
- data/gemfiles/Gemfile.representable-2.0 +0 -5
- data/gemfiles/Gemfile.representable-2.1 +0 -5
- data/gemfiles/Gemfile.representable-head +0 -6
- data/lib/roar/json/collection_json.rb +0 -208
- data/lib/roar/json/json_api.rb +0 -233
- data/test/collection_json_test.rb +0 -132
- data/test/hal_links_test.rb +0 -31
- data/test/json_api_test.rb +0 -451
- data/test/lib/runner.rb +0 -134
data/lib/roar/version.rb
CHANGED
data/lib/roar/xml.rb
CHANGED
@@ -35,10 +35,10 @@ module Roar
|
|
35
35
|
# FIXME: this doesn't belong into the generic XML representer.
|
36
36
|
{
|
37
37
|
:as => :link,
|
38
|
-
:collection => true,
|
39
38
|
:class => Hypermedia::Hyperlink,
|
40
39
|
:extend => XML::HyperlinkRepresenter,
|
41
40
|
:exec_context => :decorator,
|
41
|
+
collection: true
|
42
42
|
} # TODO: merge with JSON.
|
43
43
|
end
|
44
44
|
end
|
data/roar.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.authors = ["Nick Sutterer"]
|
9
9
|
s.email = ["apotonick@gmail.com"]
|
10
|
-
s.homepage = "http://
|
10
|
+
s.homepage = "http://trailblazer.to/gems/roar"
|
11
11
|
s.summary = %q{Parse and render REST API documents using representers.}
|
12
12
|
s.description = %q{Object-oriented representers help you defining nested REST API documents which can then be rendered and parsed using one and the same concept.}
|
13
13
|
s.license = 'MIT'
|
@@ -17,14 +17,14 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
18
|
s.require_paths = ["lib"]
|
19
19
|
|
20
|
-
s.add_runtime_dependency "representable", "
|
20
|
+
s.add_runtime_dependency "representable", "~> 3.0.0"
|
21
21
|
|
22
22
|
s.add_development_dependency "rake", ">= 0.10.1"
|
23
23
|
s.add_development_dependency "test_xml", "0.1.6"
|
24
|
-
s.add_development_dependency
|
25
|
-
s.add_development_dependency "sinatra"
|
26
|
-
s.add_development_dependency "sinatra-contrib"
|
24
|
+
s.add_development_dependency 'minitest', '>= 5.10'
|
25
|
+
s.add_development_dependency "sinatra", '>= 2.0.0'
|
26
|
+
s.add_development_dependency "sinatra-contrib", '>= 2.0.0'
|
27
27
|
s.add_development_dependency "virtus", ">= 1.0.0"
|
28
28
|
s.add_development_dependency "faraday"
|
29
|
-
s.add_development_dependency "
|
29
|
+
s.add_development_dependency "multi_json"
|
30
30
|
end
|
data/test/client_test.rb
CHANGED
@@ -30,7 +30,7 @@ class ClientTest < MiniTest::Spec
|
|
30
30
|
# since this is considered dangerous, we test the mutuable options.
|
31
31
|
it "adds links: false to options" do
|
32
32
|
song.to_hash(options = {})
|
33
|
-
options.must_equal({:
|
33
|
+
options.must_equal(user_options: {links: false})
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
@@ -1,14 +1,17 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
require 'roar/coercion'
|
3
|
+
require 'roar/decorator'
|
3
4
|
|
4
5
|
class CoercionFeatureTest < MiniTest::Spec
|
5
6
|
describe "Coercion" do
|
6
|
-
class
|
7
|
+
class SongDecorator < Roar::Decorator
|
7
8
|
include Roar::JSON
|
8
9
|
include Roar::Coercion
|
9
10
|
|
10
11
|
property :composed_at, :type => DateTime, :default => "May 12th, 2012"
|
12
|
+
end
|
11
13
|
|
14
|
+
class ImmigrantSong
|
12
15
|
attr_accessor :composed_at
|
13
16
|
def composed_at=(v) # in ruby 2.2, #label= is not there, all at sudden. what *is* that?
|
14
17
|
@composed_at = v
|
@@ -16,7 +19,9 @@ class CoercionFeatureTest < MiniTest::Spec
|
|
16
19
|
end
|
17
20
|
|
18
21
|
it "coerces into the provided type" do
|
19
|
-
song
|
22
|
+
song = ImmigrantSong.new
|
23
|
+
decorator = SongDecorator.new(song)
|
24
|
+
decorator.from_json("{\"composed_at\":\"November 18th, 1983\"}")
|
20
25
|
assert_equal DateTime.parse("Fri, 18 Nov 1983 00:00:00 +0000"), song.composed_at
|
21
26
|
end
|
22
27
|
end
|
data/test/decorator_test.rb
CHANGED
@@ -27,11 +27,15 @@ class DecoratorTest < MiniTest::Spec
|
|
27
27
|
describe "JSON" do
|
28
28
|
let (:decorator_class) { rpr_mod = rpr
|
29
29
|
Class.new(Roar::Decorator) do
|
30
|
+
include Roar::JSON
|
31
|
+
include Roar::Hypermedia
|
32
|
+
|
30
33
|
include rpr_mod
|
31
34
|
end }
|
32
35
|
let (:decorator) { decorator_class.new(model) }
|
33
36
|
|
34
|
-
it "
|
37
|
+
it "xxxrendering links works" do
|
38
|
+
pp decorator.send(:representable_attrs)
|
35
39
|
decorator.to_hash.must_equal({"links"=>[{"rel"=>"self", "href"=>"http://self"}]})
|
36
40
|
end
|
37
41
|
|
@@ -42,7 +46,7 @@ class DecoratorTest < MiniTest::Spec
|
|
42
46
|
|
43
47
|
it "does not set links on represented" do
|
44
48
|
decorator_class.new(model_with_links).from_hash("links"=>[{:rel=>:self, :href=>"http://self"}])
|
45
|
-
model_with_links.links.
|
49
|
+
model_with_links.links.must_be_nil
|
46
50
|
end
|
47
51
|
|
48
52
|
class ConsumingDecorator < Roar::Decorator
|
@@ -63,10 +67,10 @@ class DecoratorTest < MiniTest::Spec
|
|
63
67
|
decorator.from_hash("links"=>[{:rel=>:self, :href=>"http://percolator"}])
|
64
68
|
|
65
69
|
# links are always set on decorator instance.
|
66
|
-
decorator
|
70
|
+
decorator.links["self"].must_equal(link(:rel=>:self, :href=>"http://percolator"))
|
67
71
|
|
68
72
|
# and propagated to represented with HypermediaConsumer.
|
69
|
-
model_with_links.links[
|
73
|
+
model_with_links.links["self"].must_equal(link(:rel=>:self, :href=>"http://percolator"))
|
70
74
|
end
|
71
75
|
end
|
72
76
|
end
|
@@ -78,6 +82,8 @@ class DecoratorTest < MiniTest::Spec
|
|
78
82
|
end
|
79
83
|
let (:decorator_class) { rpr_mod = rpr
|
80
84
|
Class.new(Roar::Decorator) do
|
85
|
+
include Roar::XML
|
86
|
+
include Roar::Hypermedia
|
81
87
|
include rpr_mod
|
82
88
|
self.representation_wrap = :song
|
83
89
|
end
|
@@ -97,10 +103,13 @@ class DecoratorTest < MiniTest::Spec
|
|
97
103
|
|
98
104
|
describe "JSON::HAL" do
|
99
105
|
representer_for([Roar::JSON::HAL]) do
|
106
|
+
# feature Roar::JSON::HAL
|
100
107
|
link(:self) { "http://self" }
|
101
108
|
end
|
102
109
|
let (:decorator_class) { rpr_mod = rpr
|
103
110
|
Class.new(Roar::Decorator) do
|
111
|
+
include Roar::JSON::HAL
|
112
|
+
|
104
113
|
include rpr_mod
|
105
114
|
end
|
106
115
|
}
|
@@ -116,15 +125,16 @@ class DecoratorTest < MiniTest::Spec
|
|
116
125
|
end
|
117
126
|
|
118
127
|
describe "Decorator::HypermediaClient" do
|
119
|
-
let (:
|
128
|
+
let (:decorator_class) { rpr_mod = rpr
|
120
129
|
Class.new(Roar::Decorator) do
|
130
|
+
include Roar::JSON::HAL
|
121
131
|
include rpr_mod
|
122
132
|
include Roar::Decorator::HypermediaConsumer
|
123
133
|
end }
|
124
134
|
|
125
135
|
it "propagates links to represented" do
|
126
|
-
|
127
|
-
model_with_links.links[
|
136
|
+
decorator_class.new(model_with_links).from_hash("_links"=>{"self"=>{:href=>"http://self"}})
|
137
|
+
model_with_links.links["self"].must_equal(link(:rel=>"self", :href=>"http://self"))
|
128
138
|
end
|
129
139
|
end
|
130
140
|
end
|
data/test/hal_json_test.rb
CHANGED
@@ -2,8 +2,8 @@ require 'test_helper'
|
|
2
2
|
require 'roar/json/hal'
|
3
3
|
|
4
4
|
class HalJsonTest < MiniTest::Spec
|
5
|
-
let(:
|
6
|
-
|
5
|
+
let(:decorator_class) do
|
6
|
+
Class.new(Roar::Decorator) do
|
7
7
|
include Roar::JSON
|
8
8
|
include Roar::JSON::HAL
|
9
9
|
|
@@ -18,112 +18,107 @@ class HalJsonTest < MiniTest::Spec
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
subject { Object.new
|
21
|
+
subject { decorator_class.new(Object.new) }
|
22
22
|
|
23
23
|
describe "links" do
|
24
24
|
describe "parsing" do
|
25
25
|
it "parses link array" do # TODO: remove me.
|
26
26
|
obj = subject.from_json("{\"_links\":{\"self\":[{\"lang\":\"en\",\"href\":\"http://en.hit\"},{\"lang\":\"de\",\"href\":\"http://de.hit\"}]}}")
|
27
|
-
|
27
|
+
subject.links.must_equal "self" => [link("rel" => "self", "href" => "http://en.hit", "lang" => "en"), link("rel" => "self", "href" => "http://de.hit", "lang" => "de")]
|
28
28
|
end
|
29
29
|
|
30
30
|
it "parses single links" do # TODO: remove me.
|
31
31
|
obj = subject.from_json("{\"_links\":{\"next\":{\"href\":\"http://next\"}}}")
|
32
|
-
|
32
|
+
subject.links.must_equal "next" => link("rel" => "next", "href" => "http://next")
|
33
33
|
end
|
34
34
|
|
35
35
|
it "parses link and link array" do
|
36
|
-
obj = subject.from_json(
|
37
|
-
|
36
|
+
obj = subject.from_json(%@{"_links":{"next":{"href":"http://next"}, "self":[{"lang":"en","href":"http://en.hit"},{"lang":"de","href":"http://de.hit"}]}}@)
|
37
|
+
subject._links.must_equal "next"=>link("rel" => "next", "href" => "http://next"), "self"=>[link("rel" => "self", "href" => "http://en.hit", "lang" => "en"), link("rel" => "self", "href" => "http://de.hit", "lang" => "de")]
|
38
38
|
end
|
39
39
|
|
40
40
|
it "parses empty link array" do
|
41
|
-
subject.from_json("{\"_links\":{\"self\":[]}}")
|
41
|
+
subject.from_json("{\"_links\":{\"self\":[]}}")
|
42
|
+
subject.links[:self].must_be_nil
|
42
43
|
end
|
43
44
|
|
44
45
|
it "parses non-existent link array" do
|
45
|
-
subject.from_json("{\"_links\":{}}")
|
46
|
+
subject.from_json("{\"_links\":{}}")
|
47
|
+
subject.links[:self].must_be_nil # DISCUSS: should this be []?
|
46
48
|
end
|
47
49
|
|
48
|
-
it "rejects single links declared as array" do
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
50
|
+
# it "rejects single links declared as array" do
|
51
|
+
# assert_raises TypeError do
|
52
|
+
# subject.from_json("{\"_links\":{\"self\":{\"href\":\"http://next\"}}}")
|
53
|
+
# end
|
54
|
+
# end
|
53
55
|
end
|
54
56
|
|
55
57
|
describe "rendering" do
|
56
58
|
it "renders link and link array" do
|
57
59
|
subject.to_json.must_equal "{\"_links\":{\"self\":[{\"lang\":\"en\",\"href\":\"http://en.hit\"},{\"lang\":\"de\",\"href\":\"http://de.hit\"}],\"next\":{\"href\":\"http://next\"}}}"
|
58
60
|
end
|
61
|
+
end
|
62
|
+
end
|
59
63
|
|
60
|
-
|
61
|
-
|
62
|
-
|
64
|
+
describe "empty link array" do
|
65
|
+
let(:decorator_class) do
|
66
|
+
Class.new(Roar::Decorator) do
|
67
|
+
include Roar::JSON
|
68
|
+
include Roar::JSON::HAL
|
63
69
|
|
64
|
-
|
65
|
-
end
|
66
|
-
subject = Object.new.extend(rpr)
|
67
|
-
|
68
|
-
subject.to_json.must_equal "{\"_links\":{\"self\":[]}}"
|
70
|
+
links(:self) { [] }
|
69
71
|
end
|
70
72
|
end
|
71
|
-
end
|
72
73
|
|
73
|
-
|
74
|
-
# it "should map link arrays correctly" do
|
75
|
-
# subject.send :prepare_links!, {}
|
76
|
-
# subject.links.must_equal :self => [link("rel" => "self", "href" => "http://en.hit", "lang" => "en"),link("rel" => :self, "href" => "http://de.hit", "lang" => "de")], "next" => link("href" => "http://next", "rel" => "next")
|
77
|
-
# end
|
78
|
-
# end
|
74
|
+
subject { decorator_class.new(Object.new) }
|
79
75
|
|
80
|
-
|
81
|
-
|
82
|
-
subject.send(:link_array_rels).must_equal [:self]
|
76
|
+
it "gets render" do
|
77
|
+
subject.to_json.must_equal %@{"_links":{"self":[]}}@
|
83
78
|
end
|
84
79
|
end
|
85
80
|
|
86
81
|
|
87
|
-
describe "
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
"http://songs/#{title}"
|
93
|
-
end
|
94
|
-
end
|
82
|
+
describe "_links and _embedded" do
|
83
|
+
let(:decorator_class) do
|
84
|
+
Class.new(Roar::Decorator) do
|
85
|
+
include Roar::JSON
|
86
|
+
include Roar::JSON::HAL
|
95
87
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
88
|
+
property :id
|
89
|
+
collection :songs, class: Song, embedded: true do
|
90
|
+
include Roar::JSON::HAL
|
91
|
+
|
92
|
+
property :title
|
93
|
+
link(:self) { "http://songs/#{represented.title}" }
|
94
|
+
end
|
95
|
+
|
96
|
+
link(:self) { "http://albums/#{represented.id}" }
|
101
97
|
end
|
102
98
|
end
|
103
99
|
|
104
|
-
|
105
|
-
|
106
|
-
end
|
100
|
+
let(:album) { Album.new(:songs => [Song.new(:title => "Beer")], :id => 1) }
|
101
|
+
subject { decorator_class.new(album) }
|
107
102
|
|
108
103
|
it "render links and embedded resources according to HAL" do
|
109
|
-
|
104
|
+
subject.to_json.must_equal "{\"id\":1,\"_embedded\":{\"songs\":[{\"title\":\"Beer\",\"_links\":{\"self\":{\"href\":\"http://songs/Beer\"}}}]},\"_links\":{\"self\":{\"href\":\"http://albums/1\"}}}"
|
110
105
|
end
|
111
106
|
|
112
107
|
it "parses links and resources following the mighty HAL" do
|
113
|
-
|
114
|
-
assert_equal 2,
|
115
|
-
assert_equal "Coffee",
|
116
|
-
assert_equal "http://songs/Coffee",
|
117
|
-
assert_equal "http://albums/2",
|
108
|
+
subject.from_json("{\"id\":2,\"_embedded\":{\"songs\":[{\"title\":\"Coffee\",\"_links\":{\"self\":{\"href\":\"http://songs/Coffee\"}}}]},\"_links\":{\"self\":{\"href\":\"http://albums/2\"}}}")
|
109
|
+
assert_equal 2, album.id
|
110
|
+
assert_equal "Coffee", album.songs.first.title
|
111
|
+
# FIXME assert_equal "http://songs/Coffee", subject.songs.first.links["self"].href
|
112
|
+
assert_equal "http://albums/2", subject.links["self"].href
|
118
113
|
end
|
119
114
|
|
120
115
|
it "doesn't require _links and _embedded to be present" do
|
121
|
-
|
122
|
-
assert_equal 2,
|
116
|
+
subject.from_json("{\"id\":2}")
|
117
|
+
assert_equal 2, album.id
|
123
118
|
|
124
119
|
# in newer representables, this is not overwritten to an empty [] anymore.
|
125
|
-
assert_equal ["Beer"],
|
126
|
-
|
120
|
+
assert_equal ["Beer"], album.songs.map(&:title)
|
121
|
+
album.links.must_be_nil
|
127
122
|
end
|
128
123
|
end
|
129
124
|
|
@@ -134,73 +129,70 @@ class JsonHalTest < MiniTest::Spec
|
|
134
129
|
Artist = Struct.new(:name)
|
135
130
|
Song = Struct.new(:title)
|
136
131
|
|
137
|
-
def self.representer!
|
138
|
-
super([Roar::JSON::HAL])
|
139
|
-
end
|
140
|
-
|
141
|
-
def representer
|
142
|
-
rpr
|
143
|
-
end
|
144
|
-
|
145
132
|
describe "render_nil: false" do
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
133
|
+
let(:decorator_class) do
|
134
|
+
Class.new(Roar::Decorator) do
|
135
|
+
include Roar::JSON
|
136
|
+
include Roar::JSON::HAL
|
150
137
|
|
151
|
-
|
152
|
-
|
138
|
+
property :artist, embedded: true, render_nil: false do
|
139
|
+
property :name
|
140
|
+
end
|
141
|
+
|
142
|
+
collection :songs, embedded: true, render_empty: false do
|
143
|
+
property :title
|
144
|
+
end
|
153
145
|
end
|
154
146
|
end
|
155
147
|
|
156
|
-
it { Album.new(Artist.new("Bare, Jr."), [Song.new("Tobacco Spit")])
|
157
|
-
it { Album.new
|
148
|
+
it { decorator_class.new(Album.new(Artist.new("Bare, Jr."), [Song.new("Tobacco Spit")])).to_hash.must_equal({"_embedded"=>{"artist"=>{"name"=>"Bare, Jr."}, "songs"=>[{"title"=>"Tobacco Spit"}]}}) }
|
149
|
+
it { decorator_class.new(Album.new).to_hash.must_equal({}) }
|
158
150
|
end
|
159
151
|
|
160
152
|
describe "as: alias" do
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
153
|
+
let(:decorator_class) do
|
154
|
+
Class.new(Roar::Decorator) do
|
155
|
+
include Roar::JSON
|
156
|
+
include Roar::JSON::HAL
|
165
157
|
|
166
|
-
|
167
|
-
|
158
|
+
property :artist, as: :my_artist, class: Artist, embedded: true do
|
159
|
+
property :name
|
160
|
+
end
|
161
|
+
|
162
|
+
collection :songs, as: :my_songs, class: Song, embedded: true do
|
163
|
+
property :title
|
164
|
+
end
|
168
165
|
end
|
169
166
|
end
|
170
167
|
|
171
|
-
it { Album.new(Artist.new("Bare, Jr."), [Song.new("Tobacco Spit")])
|
172
|
-
it { Album.new
|
168
|
+
it { decorator_class.new(Album.new(Artist.new("Bare, Jr."), [Song.new("Tobacco Spit")])).to_hash.must_equal({"_embedded"=>{"my_artist"=>{"name"=>"Bare, Jr."}, "my_songs"=>[{"title"=>"Tobacco Spit"}]}}) }
|
169
|
+
it { decorator_class.new(Album.new).from_hash({"_embedded"=>{"my_artist"=>{"name"=>"Bare, Jr."}, "my_songs"=>[{"title"=>"Tobacco Spit"}]}}).inspect.must_equal "#<struct JsonHalTest::Album artist=#<struct JsonHalTest::Artist name=\"Bare, Jr.\">, songs=[#<struct JsonHalTest::Song title=\"Tobacco Spit\">]>" }
|
173
170
|
end
|
174
171
|
end
|
175
172
|
|
173
|
+
class HalCurieTest < MiniTest::Spec
|
174
|
+
let(:decorator_class) do
|
175
|
+
Class.new(Roar::Decorator) do
|
176
|
+
include Roar::JSON
|
177
|
+
include Roar::JSON::HAL
|
176
178
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
it "returns true for array link" do
|
181
|
-
subject.is_array?(:self).must_equal true
|
182
|
-
subject.is_array?("self").must_equal true
|
183
|
-
end
|
184
|
-
|
185
|
-
it "returns false otherwise" do
|
186
|
-
subject.is_array?("prev").must_equal false
|
187
|
-
end
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
179
|
+
link "doc:self" do
|
180
|
+
"/"
|
181
|
+
end
|
191
182
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
"/"
|
196
|
-
end
|
183
|
+
links "doc:link_collection" do
|
184
|
+
[{:name => "link_collection", :href => "/"}]
|
185
|
+
end
|
197
186
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
187
|
+
curies do
|
188
|
+
[{:name => :doc,
|
189
|
+
:href => "//docs/{rel}",
|
190
|
+
:templated => true}]
|
191
|
+
end
|
202
192
|
end
|
203
193
|
end
|
204
194
|
|
205
|
-
|
195
|
+
subject { decorator_class.new(Object.new) }
|
196
|
+
|
197
|
+
it { subject.to_hash.must_equal({"_links"=>{"doc:self"=>{"href"=>"/"}, "doc:link_collection"=>[{"name"=>"link_collection", "href"=>"/"}], "curies"=>[{"name"=>:doc, "href"=>"//docs/{rel}", "templated"=>true}]}}) }
|
206
198
|
end
|