roar 0.12.0 → 0.12.1
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 +7 -0
- data/CHANGES.markdown +4 -0
- data/Gemfile +2 -1
- data/README.textile +8 -1
- data/lib/roar/representer/feature/client.rb +4 -1
- data/lib/roar/representer/feature/http_verbs.rb +3 -0
- data/lib/roar/representer/feature/hypermedia.rb +1 -1
- data/lib/roar/representer/json/hal.rb +7 -4
- data/lib/roar/representer/transport/faraday.rb +1 -1
- data/lib/roar/representer/transport/net_http.rb +10 -1
- data/lib/roar/version.rb +1 -1
- data/roar.gemspec +1 -2
- data/test/client_test.rb +6 -0
- data/test/collection_json_test.rb +3 -1
- data/test/faraday_http_transport_test.rb +3 -3
- data/test/hal_json_test.rb +41 -18
- data/test/http_verbs_feature_test.rb +9 -9
- data/test/{Gemfile → integration/Gemfile} +1 -1
- data/test/integration/band_representer.rb +8 -0
- data/test/integration/runner.rb +30 -0
- data/test/integration/server.rb +77 -0
- data/test/json_representer_test.rb +3 -2
- data/test/net_http_transport_test.rb +25 -21
- data/test/test_helper.rb +1 -6
- metadata +27 -59
- data/test/fake_server.rb +0 -81
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 29d7b45c0c70d694a009c07d504cdb64527a67dd
|
4
|
+
data.tar.gz: 3b4e5c1d025541be5de8e5b0df42cf01052f843a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b9e45c7ec240bce207c05a8165fd03d8a35c770ee60a643c5fe07a5feff5e99ab646b3873efa619e3d732cb9aec9a079d7aa843ac685de3ec75cd50c0f20dca5
|
7
|
+
data.tar.gz: cfde908ba1165bb30fa43dc8a22b8d5de7bff6092ccf38d0eb906bd4ff04ca170a44726a9a3ff597e91c8a41deea83cd29d4eac6edcc8b48c509d6cce8b7dba5
|
data/CHANGES.markdown
CHANGED
data/Gemfile
CHANGED
data/README.textile
CHANGED
@@ -4,7 +4,14 @@ _Resource-Oriented Architectures in Ruby._
|
|
4
4
|
|
5
5
|
h2. Introduction
|
6
6
|
|
7
|
-
Roar is a framework for parsing and rendering REST documents. Nothing more.
|
7
|
+
Roar is a framework for parsing and rendering REST documents. Nothing more.
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
coercion
|
12
|
+
|
13
|
+
|
14
|
+
With Roar, REST documents - also known as representations - are defined using a new concept called representers. Both syntax and semantics are declared in Ruby modules that can be mixed into your domain models, following clean OOP patterns.
|
8
15
|
|
9
16
|
Roar comes with built-in JSON, JSON::HAL and XML support. It exposes a highly modular architecture and makes it very simple to add new media types and functionality where needed. Additional features include client HTTP support, coercion, client-side caching, awesome hypermedia support and more. Representers fit pretty well in DCI environments, too.
|
10
17
|
|
@@ -27,8 +27,11 @@ module Roar
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
+
# DISCUSS: should we just override #serialize here? otherwise if you later include Hypermedia, it'll run before that method.
|
30
31
|
def before_serialize(options={})
|
31
|
-
|
32
|
+
options[:links] ||= false
|
33
|
+
|
34
|
+
super(options)
|
32
35
|
end
|
33
36
|
end
|
34
37
|
end
|
@@ -41,8 +41,8 @@ module Roar
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def before_serialize(options={})
|
44
|
+
super(options) # Representer::Base
|
44
45
|
prepare_links!(options) unless options[:links] == false # DISCUSS: doesn't work when links are already setup (e.g. from #deserialize).
|
45
|
-
super # Representer::Base
|
46
46
|
end
|
47
47
|
|
48
48
|
attr_writer :links
|
@@ -101,7 +101,7 @@ module Roar::Representer
|
|
101
101
|
return super(href, options) unless options[:array] # TODO: remove :array and use special instan
|
102
102
|
|
103
103
|
list = href.collect { |opts| Feature::Hypermedia::Hyperlink.new(opts.merge!(:rel => options[:rel])) }
|
104
|
-
LinkArray.new(list)
|
104
|
+
LinkArray.new(list, options[:rel])
|
105
105
|
end
|
106
106
|
|
107
107
|
# TODO: move to LinksDefinition.
|
@@ -126,7 +126,7 @@ module Roar::Representer
|
|
126
126
|
|
127
127
|
|
128
128
|
def from_hash(hash, options={})
|
129
|
-
hash.each { |k,v| hash[k] = LinkArray.new(v) if is_array?(k) }
|
129
|
+
hash.each { |k,v| hash[k] = LinkArray.new(v, k) if is_array?(k) }
|
130
130
|
|
131
131
|
hsh = super(hash) # this is where :class and :extend do the work.
|
132
132
|
|
@@ -135,10 +135,13 @@ module Roar::Representer
|
|
135
135
|
end
|
136
136
|
|
137
137
|
class LinkArray < Array
|
138
|
-
def rel
|
139
|
-
|
138
|
+
def initialize(elems, rel)
|
139
|
+
super(elems)
|
140
|
+
@rel = rel
|
140
141
|
end
|
141
142
|
|
143
|
+
attr_reader :rel
|
144
|
+
|
142
145
|
def rel=(rel)
|
143
146
|
each { |lnk| lnk.rel = rel }
|
144
147
|
end
|
@@ -31,14 +31,23 @@ module Roar
|
|
31
31
|
private
|
32
32
|
def do_request(what, uri, as, body="")
|
33
33
|
# DISCUSS: can this be made easier?
|
34
|
-
uri =
|
34
|
+
uri = parse_uri(uri)
|
35
35
|
http = Net::HTTP.new(uri.host, uri.port)
|
36
36
|
req = what.new(uri.request_uri)
|
37
|
+
|
38
|
+
|
37
39
|
req.content_type = as
|
38
40
|
req["accept"] = as # TODO: test me. # DISCUSS: if Accept is not set, rails treats this request as as "text/html".
|
39
41
|
req.body = body if body
|
42
|
+
|
40
43
|
http.request(req)
|
41
44
|
end
|
45
|
+
|
46
|
+
def parse_uri(url)
|
47
|
+
uri = URI(url)
|
48
|
+
raise "Incorrect URL `#{url}`. Maybe you forgot http://?" if uri.instance_of?(URI::Generic)
|
49
|
+
uri
|
50
|
+
end
|
42
51
|
end
|
43
52
|
end
|
44
53
|
end
|
data/lib/roar/version.rb
CHANGED
data/roar.gemspec
CHANGED
@@ -19,12 +19,11 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
|
-
s.add_runtime_dependency "representable", "
|
22
|
+
s.add_runtime_dependency "representable", ">= 1.6.0"
|
23
23
|
|
24
24
|
s.add_development_dependency "rake", ">= 0.10.1"
|
25
25
|
s.add_development_dependency "test_xml", ">= 0.1.6"
|
26
26
|
s.add_development_dependency "minitest", ">= 5.0.0"
|
27
|
-
s.add_development_dependency "sham_rack"
|
28
27
|
s.add_development_dependency "sinatra"
|
29
28
|
s.add_development_dependency "virtus"
|
30
29
|
s.add_development_dependency "faraday"
|
data/test/client_test.rb
CHANGED
@@ -26,5 +26,11 @@ class ClientTest < MiniTest::Spec
|
|
26
26
|
song.name = "Silenced"
|
27
27
|
song.to_json.must_equal %{{\"name\":\"Silenced\",\"links\":[]}}
|
28
28
|
end
|
29
|
+
|
30
|
+
# since this is considered dangerous, we test the mutuable options.
|
31
|
+
it "adds links: false to options" do
|
32
|
+
song.to_hash(options = {})
|
33
|
+
options.must_equal({:links => false})
|
34
|
+
end
|
29
35
|
end
|
30
36
|
end
|
@@ -4,6 +4,8 @@ require 'roar/representer/json/collection_json'
|
|
4
4
|
class CollectionJsonTest < MiniTest::Spec
|
5
5
|
let(:song) { OpenStruct.new(:title => "scarifice", :length => 43) }
|
6
6
|
|
7
|
+
# FIXME: test absence of ::items, ::template, etc.
|
8
|
+
|
7
9
|
representer_for([Roar::Representer::JSON::CollectionJSON]) do
|
8
10
|
version "1.0"
|
9
11
|
href { "//songs/" }
|
@@ -48,7 +50,7 @@ class CollectionJsonTest < MiniTest::Spec
|
|
48
50
|
},
|
49
51
|
|
50
52
|
"queries"=>[
|
51
|
-
{:rel=>:search, :href=>"//search",
|
53
|
+
{:rel=>:search, :href=>"//search",
|
52
54
|
:data=>[
|
53
55
|
{:name=>"q", :value=>""}
|
54
56
|
]
|
@@ -3,7 +3,7 @@ require 'roar/representer/transport/faraday'
|
|
3
3
|
|
4
4
|
class FaradayHttpTransportTest < MiniTest::Spec
|
5
5
|
describe 'FaradayHttpTransport' do
|
6
|
-
let(:url) { "http://
|
6
|
+
let(:url) { "http://localhost:4567/method" }
|
7
7
|
let(:body) { "booty" }
|
8
8
|
let(:as) { "application/xml" }
|
9
9
|
before do
|
@@ -32,7 +32,7 @@ class FaradayHttpTransportTest < MiniTest::Spec
|
|
32
32
|
|
33
33
|
describe 'non-existent resource' do
|
34
34
|
before do
|
35
|
-
@not_found_url = 'http://
|
35
|
+
@not_found_url = 'http://localhost:4567/missing-resource'
|
36
36
|
end
|
37
37
|
|
38
38
|
it '#get_uri raises a ResourceNotFound error' do
|
@@ -63,7 +63,7 @@ class FaradayHttpTransportTest < MiniTest::Spec
|
|
63
63
|
describe 'server errors (500 Internal Server Error)' do
|
64
64
|
it '#get_uri raises a ClientError' do
|
65
65
|
assert_raises(Faraday::Error::ClientError) do
|
66
|
-
@transport.get_uri('http://
|
66
|
+
@transport.get_uri('http://localhost:4567/deliberate-error', as).body
|
67
67
|
end
|
68
68
|
end
|
69
69
|
end
|
data/test/hal_json_test.rb
CHANGED
@@ -20,30 +20,53 @@ class HalJsonTest < MiniTest::Spec
|
|
20
20
|
|
21
21
|
subject { Object.new.extend(rpr) }
|
22
22
|
|
23
|
-
describe "
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
describe "links" do
|
24
|
+
describe "parsing" do
|
25
|
+
it "parses link array" do # TODO: remove me.
|
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)]
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
it "parses single links" do # TODO: remove me.
|
31
|
+
obj = subject.from_json("{\"_links\":{\"next\":{\"href\":\"http://next\"}}}")
|
32
|
+
obj.links.must_equal "next" => link(:rel => :next, :href => "http://next")
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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)]
|
38
|
+
end
|
39
|
+
|
40
|
+
it "parses empty link array" do
|
41
|
+
subject.from_json("{\"_links\":{\"self\":[]}}").links[:self].must_equal []
|
42
|
+
end
|
38
43
|
|
39
|
-
|
40
|
-
|
41
|
-
|
44
|
+
it "parses non-existent link array" do
|
45
|
+
subject.from_json("{\"_links\":{}}").links[:self].must_equal nil # DISCUSS: should this be []?
|
46
|
+
end
|
47
|
+
|
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
|
42
52
|
end
|
43
53
|
end
|
44
54
|
|
45
|
-
|
46
|
-
|
55
|
+
describe "rendering" do
|
56
|
+
it "renders link and link array" do
|
57
|
+
subject.to_json.must_equal "{\"_links\":{\"self\":[{\"lang\":\"en\",\"href\":\"http://en.hit\"},{\"lang\":\"de\",\"href\":\"http://de.hit\"}],\"next\":{\"href\":\"http://next\"}}}"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "renders empty link array" do
|
61
|
+
rpr = Module.new do
|
62
|
+
include Roar::Representer::JSON::HAL
|
63
|
+
|
64
|
+
links :self do [] end
|
65
|
+
end
|
66
|
+
subject = Object.new.extend(rpr)
|
67
|
+
|
68
|
+
subject.to_json.must_equal "{\"_links\":{\"self\":[]}}"
|
69
|
+
end
|
47
70
|
end
|
48
71
|
end
|
49
72
|
|
@@ -3,7 +3,7 @@ require 'roar/representer/feature/http_verbs'
|
|
3
3
|
require 'roar/representer/json'
|
4
4
|
|
5
5
|
class HttpVerbsTest < MiniTest::Spec
|
6
|
-
BandRepresenter =
|
6
|
+
BandRepresenter = Integration::BandRepresenter
|
7
7
|
|
8
8
|
# keep this class clear of Roar modules.
|
9
9
|
class Band
|
@@ -38,7 +38,7 @@ class HttpVerbsTest < MiniTest::Spec
|
|
38
38
|
|
39
39
|
describe "HttpVerbs.get" do
|
40
40
|
it "returns instance from incoming representation" do
|
41
|
-
band = @band.get("http://
|
41
|
+
band = @band.get("http://localhost:4567/bands/slayer", "application/json")
|
42
42
|
assert_equal "Slayer", band.name
|
43
43
|
assert_equal "Canadian Maple", band.label
|
44
44
|
end
|
@@ -49,14 +49,14 @@ class HttpVerbsTest < MiniTest::Spec
|
|
49
49
|
it 'handles HTTP errors and raises a ResourceNotFound error with FaradayHttpTransport' do
|
50
50
|
@band.transport_engine = Roar::Representer::Transport::Faraday
|
51
51
|
assert_raises(::Faraday::Error::ResourceNotFound) do
|
52
|
-
@band.get('http://
|
52
|
+
@band.get('http://localhost:4567/bands/anthrax', "application/json")
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
56
|
it 'performs no HTTP error handling with NetHttpTransport' do
|
57
57
|
@band.transport_engine = Roar::Representer::Transport::NetHTTP
|
58
58
|
assert_raises(MultiJson::LoadError) do
|
59
|
-
@band.get('http://
|
59
|
+
@band.get('http://localhost:4567/bands/anthrax', "application/json")
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
@@ -64,7 +64,7 @@ class HttpVerbsTest < MiniTest::Spec
|
|
64
64
|
|
65
65
|
describe "#get" do
|
66
66
|
it "updates instance with incoming representation" do
|
67
|
-
@band.get("http://
|
67
|
+
@band.get("http://localhost:4567/bands/slayer", "application/json")
|
68
68
|
assert_equal "Slayer", @band.name
|
69
69
|
assert_equal "Canadian Maple", @band.label
|
70
70
|
end
|
@@ -75,7 +75,7 @@ class HttpVerbsTest < MiniTest::Spec
|
|
75
75
|
@band.name = "Strung Out"
|
76
76
|
assert_equal nil, @band.label
|
77
77
|
|
78
|
-
@band.post("http://
|
78
|
+
@band.post("http://localhost:4567/bands", "application/xml")
|
79
79
|
assert_equal "STRUNG OUT", @band.name
|
80
80
|
assert_equal nil, @band.label
|
81
81
|
end
|
@@ -85,7 +85,7 @@ class HttpVerbsTest < MiniTest::Spec
|
|
85
85
|
it "updates instance with incoming representation" do
|
86
86
|
@band.name = "Strung Out"
|
87
87
|
@band.label = "Fat Wreck"
|
88
|
-
@band.put("http://
|
88
|
+
@band.put("http://localhost:4567/bands/strungout", "application/xml")
|
89
89
|
assert_equal "STRUNG OUT", @band.name
|
90
90
|
assert_equal "FAT WRECK", @band.label
|
91
91
|
end
|
@@ -94,14 +94,14 @@ class HttpVerbsTest < MiniTest::Spec
|
|
94
94
|
describe "#patch" do
|
95
95
|
it 'does something' do
|
96
96
|
@band.label = 'Fat Mike'
|
97
|
-
@band.patch("http://
|
97
|
+
@band.patch("http://localhost:4567/bands/strungout", "application/xml")
|
98
98
|
assert_equal 'FAT MIKE', @band.label
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
102
|
describe "#delete" do
|
103
103
|
it 'does something' do
|
104
|
-
@band.delete("http://
|
104
|
+
@band.delete("http://localhost:4567/bands/metallica", "application/xml")
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "integration/band_representer"
|
2
|
+
#require '/home/nick/projects/sinatra/test/integration_helper'
|
3
|
+
class ServerRunner# < IntegrationHelper::Server
|
4
|
+
def app_file
|
5
|
+
File.expand_path("../server.rb", __FILE__)
|
6
|
+
end
|
7
|
+
|
8
|
+
def run
|
9
|
+
puts command
|
10
|
+
puts @pipe = IO.popen(command)
|
11
|
+
sleep 2
|
12
|
+
end
|
13
|
+
|
14
|
+
def command
|
15
|
+
"cd #{File.expand_path("..", __FILE__)} && bundle exec ruby #{app_file} -p 4567 -e production"
|
16
|
+
end
|
17
|
+
|
18
|
+
def kill
|
19
|
+
puts "Killling : #{@pipe.pid.inspect}"
|
20
|
+
Process.kill("KILL", @pipe.pid)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
runner = ServerRunner.new
|
24
|
+
#at_exit { puts "killing it:"; runner.kill }
|
25
|
+
|
26
|
+
runner.run
|
27
|
+
|
28
|
+
MiniTest::Unit.after_tests do
|
29
|
+
runner.kill
|
30
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
require "sinatra"
|
3
|
+
require "ostruct"
|
4
|
+
require "roar/representer/json"
|
5
|
+
|
6
|
+
require File.expand_path("../band_representer.rb", __FILE__)
|
7
|
+
|
8
|
+
class Band
|
9
|
+
attr_reader :name, :label
|
10
|
+
|
11
|
+
def name=(value)
|
12
|
+
@name = value.upcase
|
13
|
+
end
|
14
|
+
|
15
|
+
def label=(value)
|
16
|
+
@label = value.upcase
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def consume_band
|
21
|
+
Band.new.
|
22
|
+
extend(Integration::BandRepresenter).
|
23
|
+
from_json(request.body.read)
|
24
|
+
end
|
25
|
+
|
26
|
+
get "/method" do
|
27
|
+
"<method>get</method>"
|
28
|
+
end
|
29
|
+
|
30
|
+
post "/method" do
|
31
|
+
"<method>post - #{request.body.read}</method>"
|
32
|
+
end
|
33
|
+
|
34
|
+
put "/method" do
|
35
|
+
"<method>put - #{request.body.read}</method>"
|
36
|
+
end
|
37
|
+
|
38
|
+
delete "/method" do
|
39
|
+
"<method>delete</method>"
|
40
|
+
end
|
41
|
+
|
42
|
+
patch "/method" do
|
43
|
+
"<method>patch - #{request.body.read}</method>"
|
44
|
+
end
|
45
|
+
|
46
|
+
get '/deliberate-error' do
|
47
|
+
raise 'this error was deliberate'
|
48
|
+
end
|
49
|
+
|
50
|
+
post "/bands" do
|
51
|
+
#if request.content_type =~ /xml/
|
52
|
+
body consume_band.to_json
|
53
|
+
|
54
|
+
status 201
|
55
|
+
end
|
56
|
+
|
57
|
+
put "/bands/strungout" do
|
58
|
+
# DISCUSS: as long as we don't agree on what to return in PUT/PATCH, let's return an updated document.
|
59
|
+
body consume_band.to_json
|
60
|
+
#status 204
|
61
|
+
end
|
62
|
+
|
63
|
+
patch '/bands/strungout' do
|
64
|
+
# DISCUSS: as long as we don't agree on what to return in PUT/PATCH, let's return an updated document.
|
65
|
+
body consume_band.to_json
|
66
|
+
#status 204
|
67
|
+
end
|
68
|
+
|
69
|
+
get "/bands/slayer" do
|
70
|
+
OpenStruct.new(:name => "Slayer", :label => "Canadian Maple").
|
71
|
+
extend(Integration::BandRepresenter).
|
72
|
+
to_json
|
73
|
+
end
|
74
|
+
|
75
|
+
delete '/bands/metallica' do
|
76
|
+
status 204
|
77
|
+
end
|
@@ -74,7 +74,8 @@ end
|
|
74
74
|
class JsonHyperlinkRepresenterTest
|
75
75
|
describe "API" do
|
76
76
|
before do
|
77
|
-
@link = Roar::Representer::Feature::Hypermedia::Hyperlink.new.extend(Roar::Representer::JSON::HyperlinkRepresenter).from_json(
|
77
|
+
@link = Roar::Representer::Feature::Hypermedia::Hyperlink.new.extend(Roar::Representer::JSON::HyperlinkRepresenter).from_json(
|
78
|
+
'{"rel":"self", "href":"http://roar.apotomo.de", "media":"web"}')
|
78
79
|
end
|
79
80
|
|
80
81
|
it "responds to #rel" do
|
@@ -118,7 +119,7 @@ class JsonHypermediaTest
|
|
118
119
|
end
|
119
120
|
|
120
121
|
it "extracts links from JSON" do
|
121
|
-
r = @c.from_json({:
|
122
|
+
r = @c.from_json('{"links":[{"rel":"self","href":"http://self"}]}')
|
122
123
|
|
123
124
|
assert_equal 1, r.links_array.size
|
124
125
|
link = r.links_array.first
|
@@ -2,32 +2,36 @@ require 'test_helper'
|
|
2
2
|
require 'roar/representer/transport/net_http'
|
3
3
|
|
4
4
|
class NetHTTPTransportTest < MiniTest::Spec
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
5
|
+
let(:url) { "http://localhost:4567/method" }
|
6
|
+
let(:body) { "booty" }
|
7
|
+
let(:as) { "application/xml" }
|
8
|
+
before do
|
9
|
+
@transport = Roar::Representer::Transport::NetHTTP.new
|
10
|
+
end
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
it "#get_uri returns response" do
|
13
|
+
@transport.get_uri(url, as).must_match_net_response :get, url, as
|
14
|
+
end
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
it "#post_uri returns response" do
|
17
|
+
@transport.post_uri(url, body, as).must_match_net_response :post, url, as, body
|
18
|
+
end
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
it "#put_uri returns response" do
|
21
|
+
@transport.put_uri(url, body, as).must_match_net_response :put, url, as, body
|
22
|
+
end
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
it "#delete_uri returns response" do
|
25
|
+
@transport.delete_uri(url, as).must_match_net_response :delete, url, as
|
26
|
+
end
|
27
|
+
|
28
|
+
it "#patch_uri returns response" do
|
29
|
+
@transport.patch_uri(url, body, as).must_match_net_response :patch, url, as, body
|
30
|
+
end
|
28
31
|
|
29
|
-
|
30
|
-
|
32
|
+
it "complains with invalid URL" do
|
33
|
+
assert_raises RuntimeError do
|
34
|
+
@transport.get_uri("example.com", as)
|
31
35
|
end
|
32
36
|
end
|
33
37
|
end
|
data/test/test_helper.rb
CHANGED
@@ -26,12 +26,7 @@ end
|
|
26
26
|
require "test_xml/mini_test"
|
27
27
|
require "roar/representer/xml"
|
28
28
|
|
29
|
-
require
|
30
|
-
require './test/fake_server'
|
31
|
-
|
32
|
-
ShamRack.at('roar.example.com').rackup do
|
33
|
-
run FakeServer
|
34
|
-
end
|
29
|
+
require "integration/runner"
|
35
30
|
|
36
31
|
MiniTest::Spec.class_eval do
|
37
32
|
def link(options)
|
metadata
CHANGED
@@ -1,158 +1,125 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.12.
|
5
|
-
prerelease:
|
4
|
+
version: 0.12.1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Nick Sutterer
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-11-27 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: representable
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: 1.6.0
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: 1.6.0
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rake
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: 0.10.1
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: 0.10.1
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: test_xml
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: 0.1.6
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: 0.1.6
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: minitest
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - '>='
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: 5.0.0
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - '>='
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: 5.0.0
|
78
|
-
- !ruby/object:Gem::Dependency
|
79
|
-
name: sham_rack
|
80
|
-
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
|
-
requirements:
|
83
|
-
- - ! '>='
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
version: '0'
|
86
|
-
type: :development
|
87
|
-
prerelease: false
|
88
|
-
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
|
-
requirements:
|
91
|
-
- - ! '>='
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
version: '0'
|
94
69
|
- !ruby/object:Gem::Dependency
|
95
70
|
name: sinatra
|
96
71
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
72
|
requirements:
|
99
|
-
- -
|
73
|
+
- - '>='
|
100
74
|
- !ruby/object:Gem::Version
|
101
75
|
version: '0'
|
102
76
|
type: :development
|
103
77
|
prerelease: false
|
104
78
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
79
|
requirements:
|
107
|
-
- -
|
80
|
+
- - '>='
|
108
81
|
- !ruby/object:Gem::Version
|
109
82
|
version: '0'
|
110
83
|
- !ruby/object:Gem::Dependency
|
111
84
|
name: virtus
|
112
85
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
86
|
requirements:
|
115
|
-
- -
|
87
|
+
- - '>='
|
116
88
|
- !ruby/object:Gem::Version
|
117
89
|
version: '0'
|
118
90
|
type: :development
|
119
91
|
prerelease: false
|
120
92
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
93
|
requirements:
|
123
|
-
- -
|
94
|
+
- - '>='
|
124
95
|
- !ruby/object:Gem::Version
|
125
96
|
version: '0'
|
126
97
|
- !ruby/object:Gem::Dependency
|
127
98
|
name: faraday
|
128
99
|
requirement: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
100
|
requirements:
|
131
|
-
- -
|
101
|
+
- - '>='
|
132
102
|
- !ruby/object:Gem::Version
|
133
103
|
version: '0'
|
134
104
|
type: :development
|
135
105
|
prerelease: false
|
136
106
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
none: false
|
138
107
|
requirements:
|
139
|
-
- -
|
108
|
+
- - '>='
|
140
109
|
- !ruby/object:Gem::Version
|
141
110
|
version: '0'
|
142
111
|
- !ruby/object:Gem::Dependency
|
143
112
|
name: json
|
144
113
|
requirement: !ruby/object:Gem::Requirement
|
145
|
-
none: false
|
146
114
|
requirements:
|
147
|
-
- -
|
115
|
+
- - '>='
|
148
116
|
- !ruby/object:Gem::Version
|
149
117
|
version: '0'
|
150
118
|
type: :development
|
151
119
|
prerelease: false
|
152
120
|
version_requirements: !ruby/object:Gem::Requirement
|
153
|
-
none: false
|
154
121
|
requirements:
|
155
|
-
- -
|
122
|
+
- - '>='
|
156
123
|
- !ruby/object:Gem::Version
|
157
124
|
version: '0'
|
158
125
|
description: Streamlines the development of RESTful, resource-oriented architectures
|
@@ -189,18 +156,20 @@ files:
|
|
189
156
|
- lib/roar/representer/xml.rb
|
190
157
|
- lib/roar/version.rb
|
191
158
|
- roar.gemspec
|
192
|
-
- test/Gemfile
|
193
159
|
- test/client_test.rb
|
194
160
|
- test/coercion_feature_test.rb
|
195
161
|
- test/collection_json_test.rb
|
196
162
|
- test/decorator_test.rb
|
197
|
-
- test/fake_server.rb
|
198
163
|
- test/faraday_http_transport_test.rb
|
199
164
|
- test/hal_json_test.rb
|
200
165
|
- test/hal_links_test.rb
|
201
166
|
- test/http_verbs_feature_test.rb
|
202
167
|
- test/hypermedia_feature_test.rb
|
203
168
|
- test/hypermedia_test.rb
|
169
|
+
- test/integration/Gemfile
|
170
|
+
- test/integration/band_representer.rb
|
171
|
+
- test/integration/runner.rb
|
172
|
+
- test/integration/server.rb
|
204
173
|
- test/json_representer_test.rb
|
205
174
|
- test/net_http_transport_test.rb
|
206
175
|
- test/representer_test.rb
|
@@ -209,26 +178,25 @@ files:
|
|
209
178
|
homepage: http://rubygems.org/gems/roar
|
210
179
|
licenses:
|
211
180
|
- MIT
|
181
|
+
metadata: {}
|
212
182
|
post_install_message:
|
213
183
|
rdoc_options: []
|
214
184
|
require_paths:
|
215
185
|
- lib
|
216
186
|
required_ruby_version: !ruby/object:Gem::Requirement
|
217
|
-
none: false
|
218
187
|
requirements:
|
219
|
-
- -
|
188
|
+
- - '>='
|
220
189
|
- !ruby/object:Gem::Version
|
221
190
|
version: '0'
|
222
191
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
223
|
-
none: false
|
224
192
|
requirements:
|
225
|
-
- -
|
193
|
+
- - '>='
|
226
194
|
- !ruby/object:Gem::Version
|
227
195
|
version: '0'
|
228
196
|
requirements: []
|
229
197
|
rubyforge_project: roar
|
230
|
-
rubygems_version:
|
198
|
+
rubygems_version: 2.0.3
|
231
199
|
signing_key:
|
232
|
-
specification_version:
|
200
|
+
specification_version: 4
|
233
201
|
summary: Resource-oriented architectures in Ruby.
|
234
202
|
test_files: []
|
data/test/fake_server.rb
DELETED
@@ -1,81 +0,0 @@
|
|
1
|
-
require "bundler/setup"
|
2
|
-
require "sinatra/base"
|
3
|
-
require "roar/representer/json"
|
4
|
-
|
5
|
-
class FakeServer < Sinatra::Base
|
6
|
-
set :raise_errors, false
|
7
|
-
|
8
|
-
module BandRepresenter
|
9
|
-
include Roar::Representer::JSON
|
10
|
-
|
11
|
-
property :name
|
12
|
-
property :label
|
13
|
-
end
|
14
|
-
|
15
|
-
class Band
|
16
|
-
attr_reader :name, :label
|
17
|
-
|
18
|
-
def name=(value)
|
19
|
-
@name = value.upcase
|
20
|
-
end
|
21
|
-
|
22
|
-
def label=(value)
|
23
|
-
@label = value.upcase
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def consume_band
|
28
|
-
Band.new.extend(BandRepresenter).from_json(request.body.string)
|
29
|
-
end
|
30
|
-
|
31
|
-
get "/method" do
|
32
|
-
"<method>get</method>"
|
33
|
-
end
|
34
|
-
|
35
|
-
post "/method" do
|
36
|
-
"<method>post - #{request.body.read}</method>"
|
37
|
-
end
|
38
|
-
|
39
|
-
put "/method" do
|
40
|
-
"<method>put - #{request.body.read}</method>"
|
41
|
-
end
|
42
|
-
|
43
|
-
delete "/method" do
|
44
|
-
"<method>delete</method>"
|
45
|
-
end
|
46
|
-
|
47
|
-
patch "/method" do
|
48
|
-
"<method>patch - #{request.body.read}</method>"
|
49
|
-
end
|
50
|
-
|
51
|
-
get '/deliberate-error' do
|
52
|
-
raise 'this error was deliberate'
|
53
|
-
end
|
54
|
-
|
55
|
-
post "/bands" do
|
56
|
-
#if request.content_type =~ /xml/
|
57
|
-
body consume_band.to_json
|
58
|
-
|
59
|
-
status 201
|
60
|
-
end
|
61
|
-
|
62
|
-
put "/bands/strungout" do
|
63
|
-
# DISCUSS: as long as we don't agree on what to return in PUT/PATCH, let's return an updated document.
|
64
|
-
body consume_band.to_json
|
65
|
-
#status 204
|
66
|
-
end
|
67
|
-
|
68
|
-
patch '/bands/strungout' do
|
69
|
-
# DISCUSS: as long as we don't agree on what to return in PUT/PATCH, let's return an updated document.
|
70
|
-
body consume_band.to_json
|
71
|
-
#status 204
|
72
|
-
end
|
73
|
-
|
74
|
-
get "/bands/slayer" do
|
75
|
-
{:name => "Slayer", :label => "Canadian Maple"}.to_json
|
76
|
-
end
|
77
|
-
|
78
|
-
delete '/banks/metallica' do
|
79
|
-
status 204
|
80
|
-
end
|
81
|
-
end
|