roar 1.0.4 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +14 -6
  3. data/CHANGES.markdown +75 -58
  4. data/CONTRIBUTING.md +31 -0
  5. data/Gemfile +12 -2
  6. data/ISSUE_TEMPLATE.md +20 -0
  7. data/LICENSE +1 -1
  8. data/README.markdown +126 -250
  9. data/Rakefile +3 -1
  10. data/examples/example.rb +0 -0
  11. data/examples/example_server.rb +0 -0
  12. data/lib/roar.rb +3 -3
  13. data/lib/roar/client.rb +8 -3
  14. data/lib/roar/decorator.rb +2 -2
  15. data/lib/roar/http_verbs.rb +0 -16
  16. data/lib/roar/hypermedia.rb +30 -56
  17. data/lib/roar/json.rb +5 -5
  18. data/lib/roar/json/collection.rb +10 -2
  19. data/lib/roar/json/hal.rb +72 -82
  20. data/lib/roar/version.rb +1 -1
  21. data/lib/roar/xml.rb +1 -1
  22. data/roar.gemspec +6 -6
  23. data/test/client_test.rb +1 -1
  24. data/test/coercion_feature_test.rb +7 -2
  25. data/test/decorator_test.rb +17 -7
  26. data/test/hal_json_test.rb +98 -106
  27. data/test/hypermedia_feature_test.rb +13 -31
  28. data/test/hypermedia_test.rb +26 -92
  29. data/test/{decorator_client_test.rb → integration/decorator_client_test.rb} +5 -4
  30. data/test/{faraday_http_transport_test.rb → integration/faraday_http_transport_test.rb} +1 -0
  31. data/test/{http_verbs_test.rb → integration/http_verbs_test.rb} +3 -2
  32. data/test/integration/json_collection_test.rb +35 -0
  33. data/test/{net_http_transport_test.rb → integration/net_http_transport_test.rb} +1 -0
  34. data/test/integration/runner.rb +2 -3
  35. data/test/integration/server.rb +6 -0
  36. data/test/json_representer_test.rb +2 -29
  37. data/test/lonely_test.rb +1 -2
  38. data/test/ssl_client_certs_test.rb +1 -1
  39. data/test/test_helper.rb +21 -3
  40. data/test/xml_representer_test.rb +6 -5
  41. metadata +22 -36
  42. data/gemfiles/Gemfile.representable-1.7 +0 -6
  43. data/gemfiles/Gemfile.representable-1.8 +0 -6
  44. data/gemfiles/Gemfile.representable-2.0 +0 -5
  45. data/gemfiles/Gemfile.representable-2.1 +0 -5
  46. data/gemfiles/Gemfile.representable-head +0 -6
  47. data/lib/roar/json/collection_json.rb +0 -208
  48. data/lib/roar/json/json_api.rb +0 -233
  49. data/test/collection_json_test.rb +0 -132
  50. data/test/hal_links_test.rb +0 -31
  51. data/test/json_api_test.rb +0 -451
  52. data/test/lib/runner.rb +0 -134
@@ -1,3 +1,3 @@
1
1
  module Roar
2
- VERSION = "1.0.4"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -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
@@ -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://rubygems.org/gems/roar"
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", ">= 2.0.1", "< 2.4.0"
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 "minitest", ">= 5.4.2"
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 "json"
29
+ s.add_development_dependency "multi_json"
30
30
  end
@@ -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({:links => false})
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 ImmigrantSong
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 = ImmigrantSong.new.from_json("{\"composed_at\":\"November 18th, 1983\"}")
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
@@ -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 "rendering links works" do
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.must_equal nil
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 .links[:self].must_equal(link(:rel=>:self, :href=>"http://percolator"))
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[:self].must_equal(link(:rel=>:self, :href=>"http://percolator"))
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 (:decorator) { rpr_mod = rpr
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
- decorator.new(model_with_links).from_hash("_links"=>{"self"=>{:href=>"http://self"}})
127
- model_with_links.links[:self].must_equal(link(:rel=>"self", :href=>"http://self"))
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
@@ -2,8 +2,8 @@ require 'test_helper'
2
2
  require 'roar/json/hal'
3
3
 
4
4
  class HalJsonTest < MiniTest::Spec
5
- let(:rpr) do
6
- Module.new do
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.extend(rpr) }
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
- obj.links.must_equal "self" => [link("rel" => "self", "href" => "http://en.hit", "lang" => "en"), link("rel" => "self", "href" => "http://de.hit", "lang" => "de")]
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
- obj.links.must_equal "next" => link("rel" => "next", "href" => "http://next")
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("{\"_links\":{\"next\":{\"href\":\"http://next\"}, \"self\":[{\"lang\":\"en\",\"href\":\"http://en.hit\"},{\"lang\":\"de\",\"href\":\"http://de.hit\"}]}}")
37
- obj.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")]
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\":[]}}").links[:self].must_equal []
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\":{}}").links[:self].must_equal nil # DISCUSS: should this be []?
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
- assert_raises TypeError do
50
- subject.from_json("{\"_links\":{\"self\":{\"href\":\"http://next\"}}}")
51
- end
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
- it "renders empty link array" do
61
- rpr = Module.new do
62
- include Roar::JSON::HAL
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
- links :self do [] end
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
- # describe "#prepare_links!" do
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
- describe "#link_array_rels" do
81
- it "returns list of rels for array links" do
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 "HAL/JSON" do
88
- Bla = Module.new do
89
- include Roar::JSON::HAL
90
- property :title
91
- link :self do
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
- representer_for([Roar::JSON::HAL]) do
97
- property :id
98
- collection :songs, :class => Song, :extend => Bla, :embedded => true
99
- link :self do
100
- "http://albums/#{id}"
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
- before do
105
- @album = Album.new(:songs => [Song.new(:title => "Beer")], :id => 1).extend(rpr)
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
- assert_equal "{\"id\":1,\"_embedded\":{\"songs\":[{\"title\":\"Beer\",\"_links\":{\"self\":{\"href\":\"http://songs/Beer\"}}}]},\"_links\":{\"self\":{\"href\":\"http://albums/1\"}}}", @album.to_json
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
- @album.from_json("{\"id\":2,\"_embedded\":{\"songs\":[{\"title\":\"Coffee\",\"_links\":{\"self\":{\"href\":\"http://songs/Coffee\"}}}]},\"_links\":{\"self\":{\"href\":\"http://albums/2\"}}}")
114
- assert_equal 2, @album.id
115
- assert_equal "Coffee", @album.songs.first.title
116
- assert_equal "http://songs/Coffee", @album.songs.first.links[:self].href
117
- assert_equal "http://albums/2", @album.links[:self].href
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
- @album.from_json("{\"id\":2}")
122
- assert_equal 2, @album.id
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"], @album.songs.map(&:title)
126
- @album.links.must_equal nil
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
- representer! do
147
- property :artist, embedded: true, render_nil: false do
148
- property :name
149
- end
133
+ let(:decorator_class) do
134
+ Class.new(Roar::Decorator) do
135
+ include Roar::JSON
136
+ include Roar::JSON::HAL
150
137
 
151
- collection :songs, embedded: true, render_empty: false do
152
- property :title
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")]).extend(representer).to_hash.must_equal({"_embedded"=>{"artist"=>{"name"=>"Bare, Jr."}, "songs"=>[{"title"=>"Tobacco Spit"}]}}) }
157
- it { Album.new.extend(representer).to_hash.must_equal({}) }
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
- representer! do
162
- property :artist, as: :my_artist, class: Artist, embedded: true do
163
- property :name
164
- end
153
+ let(:decorator_class) do
154
+ Class.new(Roar::Decorator) do
155
+ include Roar::JSON
156
+ include Roar::JSON::HAL
165
157
 
166
- collection :songs, as: :my_songs, class: Song, embedded: true do
167
- property :title
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")]).extend(representer).to_hash.must_equal({"_embedded"=>{"my_artist"=>{"name"=>"Bare, Jr."}, "my_songs"=>[{"title"=>"Tobacco Spit"}]}}) }
172
- it { Album.new.extend(representer).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\">]>" }
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
- class LinkCollectionTest < MiniTest::Spec
178
- subject { Roar::JSON::HAL::LinkCollection.new([:self, "next"]) }
179
- describe "#is_array?" do
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
- class HalCurieTest < MiniTest::Spec
193
- representer!([Roar::JSON::HAL]) do
194
- link "doc:self" do
195
- "/"
196
- end
183
+ links "doc:link_collection" do
184
+ [{:name => "link_collection", :href => "/"}]
185
+ end
197
186
 
198
- curies do
199
- [{:name => :doc,
200
- :href => "//docs/{rel}",
201
- :templated => true}]
187
+ curies do
188
+ [{:name => :doc,
189
+ :href => "//docs/{rel}",
190
+ :templated => true}]
191
+ end
202
192
  end
203
193
  end
204
194
 
205
- it { Object.new.extend(rpr).to_hash.must_equal({"_links"=>{"doc:self"=>{"href"=>"/"}, :curies=>[{"name"=>:doc, "href"=>"//docs/{rel}", "templated"=>true}]}}) }
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