roar 0.12.9 → 1.0.0.beta1

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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +8 -10
  4. data/CHANGES.markdown +24 -2
  5. data/Gemfile +5 -2
  6. data/README.markdown +132 -28
  7. data/TODO.markdown +9 -7
  8. data/examples/example.rb +2 -0
  9. data/examples/example_server.rb +19 -3
  10. data/gemfiles/Gemfile.representable-2.0 +5 -0
  11. data/gemfiles/Gemfile.representable-2.1 +5 -0
  12. data/lib/roar.rb +1 -1
  13. data/lib/roar/client.rb +38 -0
  14. data/lib/roar/{representer/feature/coercion.rb → coercion.rb} +2 -1
  15. data/lib/roar/decorator.rb +3 -11
  16. data/lib/roar/http_verbs.rb +88 -0
  17. data/lib/roar/hypermedia.rb +174 -0
  18. data/lib/roar/json.rb +55 -0
  19. data/lib/roar/json/collection.rb +3 -0
  20. data/lib/roar/{representer/json → json}/collection_json.rb +20 -20
  21. data/lib/roar/{representer/json → json}/hal.rb +33 -31
  22. data/lib/roar/json/hash.rb +3 -0
  23. data/lib/roar/json/json_api.rb +208 -0
  24. data/lib/roar/representer.rb +3 -36
  25. data/lib/roar/transport/faraday.rb +49 -0
  26. data/lib/roar/transport/net_http.rb +57 -0
  27. data/lib/roar/transport/net_http/request.rb +72 -0
  28. data/lib/roar/version.rb +1 -1
  29. data/lib/roar/xml.rb +54 -0
  30. data/roar.gemspec +5 -4
  31. data/test/client_test.rb +3 -3
  32. data/test/coercion_feature_test.rb +6 -3
  33. data/test/collection_json_test.rb +8 -10
  34. data/test/decorator_test.rb +27 -15
  35. data/test/faraday_http_transport_test.rb +13 -15
  36. data/test/hal_json_test.rb +16 -16
  37. data/test/hal_links_test.rb +3 -3
  38. data/test/http_verbs_test.rb +17 -22
  39. data/test/hypermedia_feature_test.rb +23 -45
  40. data/test/hypermedia_test.rb +11 -23
  41. data/test/integration/band_representer.rb +2 -2
  42. data/test/integration/runner.rb +4 -3
  43. data/test/integration/server.rb +13 -2
  44. data/test/integration/ssl_server.rb +1 -1
  45. data/test/json_api_test.rb +336 -0
  46. data/test/json_representer_test.rb +16 -12
  47. data/test/lib/runner.rb +134 -0
  48. data/test/lonely_test.rb +9 -0
  49. data/test/net_http_transport_test.rb +4 -4
  50. data/test/representer_test.rb +2 -2
  51. data/test/{lib/roar/representer/transport/net_http/request_test.rb → ssl_client_certs_test.rb} +43 -5
  52. data/test/test_helper.rb +12 -5
  53. data/test/xml_representer_test.rb +26 -166
  54. metadata +49 -29
  55. data/gemfiles/Gemfile.representable-1.7 +0 -6
  56. data/gemfiles/Gemfile.representable-1.8 +0 -6
  57. data/lib/roar/representer/feature/client.rb +0 -39
  58. data/lib/roar/representer/feature/http_verbs.rb +0 -95
  59. data/lib/roar/representer/feature/hypermedia.rb +0 -175
  60. data/lib/roar/representer/json.rb +0 -67
  61. data/lib/roar/representer/transport/faraday.rb +0 -50
  62. data/lib/roar/representer/transport/net_http.rb +0 -59
  63. data/lib/roar/representer/transport/net_http/request.rb +0 -75
  64. data/lib/roar/representer/xml.rb +0 -61
@@ -1,11 +1,11 @@
1
1
  require 'test_helper'
2
- require 'roar/representer/json/hal'
2
+ require 'roar/json/hal'
3
3
 
4
4
  class HalJsonTest < MiniTest::Spec
5
5
  let(:rpr) do
6
6
  Module.new do
7
- include Roar::Representer::JSON
8
- include Roar::Representer::JSON::HAL
7
+ include Roar::JSON
8
+ include Roar::JSON::HAL
9
9
 
10
10
  links :self do
11
11
  [{:lang => "en", :href => "http://en.hit"},
@@ -59,7 +59,7 @@ class HalJsonTest < MiniTest::Spec
59
59
 
60
60
  it "renders empty link array" do
61
61
  rpr = Module.new do
62
- include Roar::Representer::JSON::HAL
62
+ include Roar::JSON::HAL
63
63
 
64
64
  links :self do [] end
65
65
  end
@@ -70,12 +70,12 @@ class HalJsonTest < MiniTest::Spec
70
70
  end
71
71
  end
72
72
 
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
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
79
79
 
80
80
  describe "#link_array_rels" do
81
81
  it "returns list of rels for array links" do
@@ -86,14 +86,14 @@ class HalJsonTest < MiniTest::Spec
86
86
 
87
87
  describe "HAL/JSON" do
88
88
  Bla = Module.new do
89
- include Roar::Representer::JSON::HAL
89
+ include Roar::JSON::HAL
90
90
  property :title
91
91
  link :self do
92
92
  "http://songs/#{title}"
93
93
  end
94
94
  end
95
95
 
96
- representer_for([Roar::Representer::JSON::HAL]) do
96
+ representer_for([Roar::JSON::HAL]) do
97
97
  property :id
98
98
  collection :songs, :class => Song, :extend => Bla, :embedded => true
99
99
  link :self do
@@ -123,13 +123,13 @@ class HalJsonTest < MiniTest::Spec
123
123
 
124
124
  # in newer representables, this is not overwritten to an empty [] anymore.
125
125
  assert_equal ["Beer"], @album.songs.map(&:title)
126
- @album.links.must_equal({})
126
+ @album.links.must_equal nil
127
127
  end
128
128
  end
129
129
  end
130
130
 
131
131
  class LinkCollectionTest < MiniTest::Spec
132
- subject { Roar::Representer::JSON::HAL::LinkCollection.new([:self, "next"]) }
132
+ subject { Roar::JSON::HAL::LinkCollection.new([:self, "next"]) }
133
133
  describe "#is_array?" do
134
134
  it "returns true for array link" do
135
135
  subject.is_array?(:self).must_equal true
@@ -144,7 +144,7 @@ end
144
144
 
145
145
 
146
146
  class HalCurieTest < MiniTest::Spec
147
- representer!([Roar::Representer::JSON::HAL]) do
147
+ representer!([Roar::JSON::HAL]) do
148
148
  link "doc:self" do
149
149
  "/"
150
150
  end
@@ -156,5 +156,5 @@ class HalCurieTest < MiniTest::Spec
156
156
  end
157
157
  end
158
158
 
159
- it { Object.new.extend(rpr).to_hash.must_equal({"_links"=>{"doc:self"=>{:href=>"/"}, "curies"=>[{:name=>:doc, :href=>"//docs/{rel}", :templated=>true}]}}) }
159
+ it { Object.new.extend(rpr).to_hash.must_equal({"_links"=>{"doc:self"=>{"href"=>"/"}, :curies=>[{"name"=>:doc, "href"=>"//docs/{rel}", "templated"=>true}]}}) }
160
160
  end
@@ -1,13 +1,13 @@
1
1
  require 'ostruct'
2
2
  require 'test_helper'
3
- require 'roar/representer/json/hal'
3
+ require 'roar/json/hal'
4
4
 
5
5
 
6
6
  class HalLinkTest < MiniTest::Spec
7
7
  let(:rpr) do
8
8
  Module.new do
9
- include Roar::Representer::JSON
10
- include Roar::Representer::JSON::HAL::Links
9
+ include Roar::JSON
10
+ include Roar::JSON::HAL::Links
11
11
  link :self do
12
12
  "//songs"
13
13
  end
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
- require 'roar/representer/feature/http_verbs'
3
- require 'roar/representer/json'
2
+ require 'roar/http_verbs'
3
+ require 'roar/json'
4
4
 
5
5
  class HttpVerbsTest < MiniTest::Spec
6
6
  BandRepresenter = Integration::BandRepresenter
@@ -8,22 +8,26 @@ class HttpVerbsTest < MiniTest::Spec
8
8
  # keep this class clear of Roar modules.
9
9
  class Band
10
10
  attr_accessor :name, :label
11
+
12
+ def label=(v) # in ruby 2.2, #label= is not there, all at sudden. what *is* that?
13
+ @label = v
14
+ end
11
15
  end
12
16
 
13
- let (:band) { OpenStruct.new(:name => "bodyjar").extend(Roar::Representer::Feature::HttpVerbs, BandRepresenter) }
17
+ let (:band) { OpenStruct.new(:name => "bodyjar").extend(Roar::HttpVerbs, BandRepresenter) }
14
18
 
15
19
 
16
20
  describe "HttpVerbs" do
17
21
  before do
18
22
  @band = Band.new
19
23
  @band.extend(BandRepresenter)
20
- @band.extend(Roar::Representer::Feature::HttpVerbs)
24
+ @band.extend(Roar::HttpVerbs)
21
25
  end
22
26
 
23
27
  describe "transport_engine" do
24
28
  before do
25
- @http_verbs = Roar::Representer::Feature::HttpVerbs
26
- @net_http = Roar::Representer::Transport::NetHTTP
29
+ @http_verbs = Roar::HttpVerbs
30
+ @net_http = Roar::Transport::NetHTTP
27
31
  end
28
32
 
29
33
  it "has a default set in the transport module level" do
@@ -37,36 +41,27 @@ class HttpVerbsTest < MiniTest::Spec
37
41
  end
38
42
  end
39
43
 
40
-
41
- describe "deprecations" do
42
- it "old #get API still works" do
43
- @band.get("http://localhost:4567/bands/slayer", "application/json")
44
- assert_equal ["Slayer", "Canadian Maple"], [@band.name, @band.label]
45
- end
46
- end
47
-
48
-
49
44
  describe "HttpVerbs.get" do
50
45
  it "returns instance from incoming representation" do
51
- band = @band.get("http://localhost:4567/bands/slayer", "application/json")
46
+ band = @band.get(uri: "http://localhost:4567/bands/slayer", as: "application/json")
52
47
  assert_equal "Slayer", band.name
53
48
  assert_equal "Canadian Maple", band.label
54
49
  end
55
50
 
56
51
  # FIXME: move to faraday test.
57
- require 'roar/representer/transport/faraday'
52
+ require 'roar/transport/faraday'
58
53
  describe 'a non-existent resource' do
59
54
  it 'handles HTTP errors and raises a ResourceNotFound error with FaradayHttpTransport' do
60
- @band.transport_engine = Roar::Representer::Transport::Faraday
55
+ @band.transport_engine = Roar::Transport::Faraday
61
56
  assert_raises(::Faraday::Error::ResourceNotFound) do
62
- @band.get('http://localhost:4567/bands/anthrax', "application/json")
57
+ @band.get(uri: 'http://localhost:4567/bands/anthrax', as: "application/json")
63
58
  end
64
59
  end
65
60
 
66
61
  it 'performs no HTTP error handling with NetHttpTransport' do
67
- @band.transport_engine = Roar::Representer::Transport::NetHTTP
62
+ @band.transport_engine = Roar::Transport::NetHTTP
68
63
  assert_raises(MultiJson::LoadError) do
69
- @band.get('http://localhost:4567/bands/anthrax', "application/json")
64
+ @band.get(uri: 'http://localhost:4567/bands/anthrax', as: "application/json")
70
65
  end
71
66
  end
72
67
  end
@@ -116,7 +111,7 @@ class HttpVerbsTest < MiniTest::Spec
116
111
 
117
112
 
118
113
  describe "HTTPS and Authentication" do
119
- let (:song) { OpenStruct.new(:name => "bodyjar").extend(Roar::Representer::Feature::HttpVerbs, BandRepresenter) }
114
+ let (:song) { OpenStruct.new(:name => "bodyjar").extend(Roar::HttpVerbs, BandRepresenter) }
120
115
 
121
116
  describe "Basic Auth: passing manually" do
122
117
 
@@ -1,6 +1,7 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class HypermediaTest < MiniTest::Spec
4
+
4
5
  describe "Hypermedia Feature" do
5
6
 
6
7
  let (:song) { Song.new(:title => "Brandy Wine") }
@@ -8,8 +9,8 @@ class HypermediaTest < MiniTest::Spec
8
9
  before do
9
10
  @bookmarks = Class.new do
10
11
  include AttributesConstructor
11
- include Roar::Representer::XML
12
- include Roar::Representer::Feature::Hypermedia
12
+ include Roar::XML
13
+ include Roar::Hypermedia
13
14
 
14
15
  self.representation_wrap = "bookmarks"
15
16
  end
@@ -30,8 +31,8 @@ class HypermediaTest < MiniTest::Spec
30
31
  describe "#to_xml" do
31
32
  it "works when no links defined" do
32
33
  repr = Module.new do
33
- include Roar::Representer::XML
34
- include Roar::Representer::Feature::Hypermedia
34
+ include Roar::XML
35
+ include Roar::Hypermedia
35
36
 
36
37
  self.representation_wrap = "song"
37
38
  property :title
@@ -41,8 +42,8 @@ class HypermediaTest < MiniTest::Spec
41
42
  end
42
43
 
43
44
  let (:rpr) { Module.new do
44
- include Roar::Representer::XML
45
- include Roar::Representer::Feature::Hypermedia
45
+ include Roar::XML
46
+ include Roar::Hypermedia
46
47
 
47
48
  self.representation_wrap = "song"
48
49
  property :title
@@ -68,8 +69,8 @@ class HypermediaTest < MiniTest::Spec
68
69
  song_rpr = rpr
69
70
 
70
71
  album_rpr = Module.new do
71
- include Roar::Representer::XML
72
- include Roar::Representer::Feature::Hypermedia
72
+ include Roar::XML
73
+ include Roar::Hypermedia
73
74
 
74
75
  self.representation_wrap = "album"
75
76
  collection :songs, :extend => song_rpr
@@ -92,8 +93,8 @@ class HypermediaTest < MiniTest::Spec
92
93
 
93
94
  describe "#to_json" do
94
95
  class Note
95
- include Roar::Representer::JSON
96
- include Roar::Representer::Feature::Hypermedia
96
+ include Roar::JSON
97
+ include Roar::Hypermedia
97
98
  link(:self) { "http://me" }
98
99
  end
99
100
 
@@ -105,7 +106,7 @@ class HypermediaTest < MiniTest::Spec
105
106
  it "sets up links even when nested" do
106
107
  class Page
107
108
  include AttributesConstructor
108
- include Roar::Representer::JSON
109
+ include Roar::JSON
109
110
  property :note, :class => Note
110
111
  attr_accessor :note
111
112
  end
@@ -118,43 +119,20 @@ class HypermediaTest < MiniTest::Spec
118
119
 
119
120
  describe "#from_xml" do
120
121
  it "extracts links from document" do
121
- doc = @bookmarks_with_links.from_xml(%{
122
+ doc = @bookmarks_with_links.new.from_xml(%{
122
123
  <bookmarks>
123
124
  <link rel="self" href="http://bookmarks">
124
125
  </bookmarks>
125
126
  })
126
127
 
127
- assert_kind_of Roar::Representer::Feature::Hypermedia::LinkCollection, doc.links
128
+ assert_kind_of Roar::Hypermedia::LinkCollection, doc.links
128
129
  assert_equal 1, doc.links.size
129
- assert_equal(["self", "http://bookmarks"], [doc.links_array.first.rel, doc.links_array.first.href])
130
+ assert_equal(["self", "http://bookmarks"], [doc.links["self"].rel, doc.links["self"].href])
130
131
  end
131
132
 
132
133
  it "sets up an empty link list if no links found in the document" do
133
- assert_equal [], @bookmarks_with_links.from_xml(%{<bookmarks/>}).links_array
134
- end
135
- end
136
-
137
-
138
- describe "#links" do
139
- subject { Object.new.extend(rpr).tap do |obj|
140
- obj.send :prepare_links!
141
- end }
142
-
143
- representer_for do
144
- link(:self) { "//self" }
145
- link(:next) { "//next" }
134
+ @bookmarks_with_links.new.from_xml(%{<bookmarks/>}).links.must_equal nil
146
135
  end
147
-
148
- it "returns link object" do
149
- subject.links["self"].href.must_equal "//self"
150
- subject.links[:self].href.must_equal "//self"
151
- subject.links[:next].href.must_equal "//next"
152
- subject.links["unknown"].must_equal nil
153
- end
154
-
155
- # it "returns an empty list when no links present" do
156
- # assert_equal Roar::Representer::Feature::Hypermedia::LinkCollection.new, @bookmarks.new.links
157
- # end
158
136
  end
159
137
  end
160
138
  end
@@ -162,15 +140,15 @@ end
162
140
 
163
141
  class LinkCollectionTest < MiniTest::Spec
164
142
  describe "LinkCollection" do
165
- subject { Roar::Representer::Feature::Hypermedia::LinkCollection.new }
143
+ subject {
144
+ Roar::Hypermedia::LinkCollection[
145
+ @self_link = link(:rel => :self), @next_link = link(:rel => :next)
146
+ ]
147
+ }
166
148
 
167
- describe "#add" do
149
+ describe "::[]" do
168
150
  it "keys by using rel string" do
169
- subject.size.must_equal 0
170
- subject.add(link = link(:rel => :self))
171
- subject.values.must_equal [link]
172
- subject.add(link = link(:rel => "self"))
173
- subject.values.must_equal [link]
151
+ subject.values.must_equal [@self_link, @next_link]
174
152
  end
175
153
  end
176
154
  end
@@ -4,22 +4,22 @@ class HypermediaTest < MiniTest::Spec
4
4
  describe "inheritance" do
5
5
  before do
6
6
  module BaseRepresenter
7
- include Roar::Representer::JSON
8
- include Roar::Representer::Feature::Hypermedia
7
+ include Roar::JSON
8
+ include Roar::Hypermedia
9
9
 
10
10
  link(:base) { "http://base" }
11
11
  end
12
12
 
13
13
  module Bar
14
- include Roar::Representer::JSON
15
- include Roar::Representer::Feature::Hypermedia
14
+ include Roar::JSON
15
+ include Roar::Hypermedia
16
16
 
17
17
  link(:bar) { "http://bar" }
18
18
  end
19
19
 
20
20
  module Foo
21
- include Roar::Representer::JSON
22
- include Roar::Representer::Feature::Hypermedia
21
+ include Roar::JSON
22
+ include Roar::Hypermedia
23
23
  include BaseRepresenter
24
24
  include Bar
25
25
 
@@ -132,18 +132,6 @@ class HypermediaTest < MiniTest::Spec
132
132
  end
133
133
  end
134
134
  end
135
-
136
- # private tests:
137
-
138
- it "returns array of links for rendering" do
139
- subject.send :prepare_links!
140
- subject.links_array.must_equal [link(:rel => :self, :href => "//self")]
141
- end
142
-
143
- it "#links_array maps array to LinkCollection hash" do
144
- subject.links_array= [link(:rel => :self, :href => "//self")]
145
- subject.links.must_equal({"self" => link(:rel => :self, :href => "//self")})
146
- end
147
135
  end
148
136
  end
149
137
 
@@ -177,10 +165,10 @@ class HyperlinkTest < MiniTest::Spec
177
165
  describe "Config inheritance" do
178
166
  it "doesn't mess up with inheritable_array" do # FIXME: remove this test when uber is out.
179
167
  OpenStruct.new.extend( Module.new do
180
- include Roar::Representer::JSON
168
+ include Roar::JSON
181
169
  include(Module.new do
182
- include Roar::Representer::JSON
183
- include Roar::Representer::Feature::Hypermedia
170
+ include Roar::JSON
171
+ include Roar::Hypermedia
184
172
 
185
173
  property :bla
186
174
 
@@ -194,9 +182,9 @@ class HyperlinkTest < MiniTest::Spec
194
182
  #puts representable_attrs.inheritable_array(:links).inspect
195
183
 
196
184
  property :blow
197
- include Roar::Representer::Feature::Hypermedia
185
+ include Roar::Hypermedia
198
186
  link(:bla) { "boo" }
199
- end).to_hash.must_equal({"links"=>[{:rel=>:self, :href=>"bo"}, {:rel=>:bla, :href=>"boo"}]})
187
+ end).to_hash.must_equal({"links"=>[{"rel"=>"self", "href"=>"bo"}, {"rel"=>"bla", "href"=>"boo"}]})
200
188
  end
201
189
  end
202
190
  end
@@ -1,8 +1,8 @@
1
1
  module Integration
2
2
  module BandRepresenter
3
- include Roar::Representer::JSON
3
+ include Roar::JSON
4
4
 
5
5
  property :name
6
6
  property :label
7
7
  end
8
- end
8
+ end
@@ -1,5 +1,6 @@
1
1
  require "integration/band_representer"
2
- require 'sinatra/runner'
2
+ # require 'sinatra/runner' # TODO: merge that into sinatra-contrib.
3
+ require 'lib/runner'
3
4
 
4
5
  class ServerRunner < Sinatra::Runner
5
6
  def app_file
@@ -35,7 +36,7 @@ runner.run
35
36
  ssl_runner = SslServerRunner.new
36
37
  ssl_runner.run
37
38
 
38
- MiniTest::Unit.after_tests do
39
+ Minitest.after_run do
39
40
  runner.kill
40
41
  ssl_runner.kill
41
- end
42
+ end
@@ -1,7 +1,7 @@
1
1
  require "bundler/setup"
2
2
  require "sinatra"
3
3
  require "ostruct"
4
- require "roar/representer/json"
4
+ require "roar/json"
5
5
  require "sinatra/multi_route"
6
6
 
7
7
  require File.expand_path("../band_representer.rb", __FILE__)
@@ -77,6 +77,17 @@ delete '/bands/metallica' do
77
77
  status 204
78
78
  end
79
79
 
80
+ route :get, :delete, :patch, :post, :put, %r{/bands/nirvana/status([\d]*)_and_data} do
81
+ status params[:captures]
82
+ OpenStruct.new(:name => "Nirvana", :label => "Sub Pop").
83
+ extend(Integration::BandRepresenter).
84
+ to_json
85
+ end
86
+
87
+ route :get, :delete, :patch, :post, :put, %r{/bands/nirvana/status([\d]*)_no_data} do
88
+ status params[:captures]
89
+ end
90
+
80
91
 
81
92
  helpers do
82
93
  def protected!
@@ -106,4 +117,4 @@ end
106
117
 
107
118
  get "/ping" do
108
119
  "1"
109
- end
120
+ end