Permalink
Browse files

Merge pull request #3 from technoweenie/rels-parsing

Rels parsing
  • Loading branch information...
2 parents 2e4865d + db2a266 commit b35f4567367df5f82f048ea86551a64ac8005639 @pengwynn pengwynn committed Nov 6, 2012
Showing with 94 additions and 15 deletions.
  1. +1 −0 lib/sawyer.rb
  2. +7 −0 lib/sawyer/agent.rb
  3. +13 −0 lib/sawyer/hal_rels_parser.rb
  4. +7 −2 lib/sawyer/relation.rb
  5. +2 −1 lib/sawyer/resource.rb
  6. +35 −0 test/agent_test.rb
  7. +8 −0 test/relation_test.rb
  8. +21 −12 test/resource_test.rb
View
@@ -12,4 +12,5 @@ class Error < StandardError; end
response
serializer
agent
+ hal_rels_parser
).each { |f| require File.expand_path("../sawyer/#{f}", __FILE__) }
View
@@ -5,6 +5,8 @@ module Sawyer
class Agent
NO_BODY = Set.new([:get, :head])
+ attr_accessor :links_parser
+
class << self
attr_writer :serializer
end
@@ -35,6 +37,7 @@ def initialize(endpoint, options = nil)
@endpoint = endpoint
@conn = (options && options[:faraday]) || Faraday.new
@serializer = (options && options[:serializer]) || self.class.serializer
+ @links_parser = (options && options[:links_parser]) || HalLinksParser.new
@conn.url_prefix = @endpoint
yield @conn if block_given?
end
@@ -116,6 +119,10 @@ def decode_body(str)
@serializer.decode(str)
end
+ def parse_links(data)
+ @links_parser.parse(data)
+ end
+
def expand_url(url, options = nil)
tpl = url.respond_to?(:expand) ? url : URITemplate.new(url.to_s)
expand = tpl.method(:expand)
@@ -0,0 +1,13 @@
+module Sawyer
+
+ class HalLinksParser
+
+ def parse(data)
+ links = data.delete(:_links)
+
+ return data, links
+ end
+
+ end
+
+end
View
@@ -13,7 +13,7 @@ def initialize
#
# Returns nothing.
def <<(rel)
- @map[rel.name] = rel
+ @map[rel.name] = rel if rel
end
# Gets the raw Relation by its name.
@@ -99,7 +99,11 @@ def self.from_link(agent, name, options)
def initialize(agent, name, href, method = nil)
@agent = agent
@name = name.to_sym
- @href_template = URITemplate.new(href.to_s)
+ @href = href
+ begin
+ @href_template = URITemplate.new(href.to_s)
+ rescue URITemplate::RFC6570::Invalid => e
+ end
methods = nil
@@ -230,6 +234,7 @@ def options(data = nil, opt = nil)
end
def href(options = nil)
+ return @href if @href_template.nil?
method = @href_template.method(:expand)
options ? method.call(options) : method.call
end
View
@@ -11,7 +11,8 @@ class Resource
# data - Hash of key/value properties.
def initialize(agent, data = {})
@_agent = agent
- @_rels = Relation.from_links(agent, data.delete(:_links))
+ data, links = agent.parse_links(data)
+ @_rels = Relation.from_links(agent, links)
@_fields = Set.new
@_metaclass = (class << self; self; end)
@attrs = {}
View
@@ -2,6 +2,16 @@
module Sawyer
class AgentTest < TestCase
+
+ class InlineRelsParser
+ def parse(data)
+ links = {}
+ data.keys.select {|k| k[/_url$/] }.each {|k| links[k.to_s.gsub(/_url$/, '')] = data.delete(k) }
+
+ return data, links
+ end
+ end
+
def setup
@stubs = Faraday::Adapter::Test::Stubs.new
@agent = Sawyer::Agent.new "http://foo.com/a/" do |conn|
@@ -25,6 +35,31 @@ def test_accesses_root_relations
assert_equal :get, @agent.rels[:users].method
end
+ def test_allows_custom_rel_parsing
+ @stubs.get '/a/' do |env|
+ assert_equal 'foo.com', env[:url].host
+
+ [200, {}, Sawyer::Agent.encode(
+ :url => '/',
+ :users_url => '/users',
+ :repos_url => '/repos')]
+ end
+
+ agent = Sawyer::Agent.new "http://foo.com/a/" do |conn|
+ conn.builder.handlers.delete(Faraday::Adapter::NetHttp)
+ conn.adapter :test, @stubs
+ end
+ agent.links_parser = InlineRelsParser.new
+
+ assert_equal 200, agent.root.status
+
+ assert_equal '/users', agent.rels[:users].href
+ assert_equal :get, agent.rels[:users].method
+ assert_equal '/repos', agent.rels[:repos].href
+ assert_equal :get, agent.rels[:repos].method
+
+ end
+
def test_saves_root_endpoint
@stubs.get '/a/' do |env|
[200, {}, '{}']
View
@@ -126,6 +126,14 @@ def test_relation_api_calls_with_uri_tempate
assert_equal 404, rel.get.status
assert_equal 200, rel.get(:uri => {'user' => 'octocat', 'repo' => 'hello', 'a' => 1, 'b' => 2}).status
end
+
+ def test_handles_invalid_uri
+ hash = {:href => '/this has spaces', :method => 'post'}
+ rel = Sawyer::Relation.from_link(nil, :self, hash)
+
+ assert_equal :self, rel.name
+ assert_equal '/this has spaces', rel.href
+ end
end
end
View
@@ -2,35 +2,44 @@
module Sawyer
class ResourceTest < TestCase
+
+ def setup
+ @stubs = Faraday::Adapter::Test::Stubs.new
+ @agent = Sawyer::Agent.new "http://foo.com/a/" do |conn|
+ conn.builder.handlers.delete(Faraday::Adapter::NetHttp)
+ conn.adapter :test, @stubs
+ end
+ end
+
def test_accessible_keys
- res = Resource.new :agent, :a => 1,
+ res = Resource.new @agent, :a => 1,
:_links => {:self => {:href => '/'}}
assert_equal 1, res.a
assert res.rels[:self]
- assert_equal :agent, res.agent
+ assert_equal @agent, res.agent
assert_equal 1, res.fields.size
assert res.fields.include?(:a)
end
def test_clashing_keys
- res = Resource.new :agent, :agent => 1, :rels => 2, :fields => 3,
+ res = Resource.new @agent, :agent => 1, :rels => 2, :fields => 3,
:_links => {:self => {:href => '/'}}
assert_equal 1, res.agent
assert_equal 2, res.rels
assert_equal 3, res.fields
assert res._rels[:self]
- assert_equal :agent, res._agent
+ assert_equal @agent, res._agent
assert_equal 3, res._fields.size
[:agent, :rels, :fields].each do |f|
assert res._fields.include?(f)
end
end
def test_nested_object
- res = Resource.new :agent,
+ res = Resource.new @agent,
:user => {:id => 1, :_links => {:self => {:href => '/users/1'}}},
:_links => {:self => {:href => '/'}}
@@ -41,7 +50,7 @@ def test_nested_object
end
def test_nested_collection
- res = Resource.new :agent,
+ res = Resource.new @agent,
:users => [{:id => 1, :_links => {:self => {:href => '/users/1'}}}],
:_links => {:self => {:href => '/'}}
@@ -55,7 +64,7 @@ def test_nested_collection
end
def test_attribute_predicates
- res = Resource.new :agent, :a => 1, :b => true, :c => nil, :d => false
+ res = Resource.new @agent, :a => 1, :b => true, :c => nil, :d => false
assert res.a?
assert res.b?
@@ -64,7 +73,7 @@ def test_attribute_predicates
end
def test_attribute_setter
- res = Resource.new :agent, :a => 1
+ res = Resource.new @agent, :a => 1
assert_equal 1, res.a
assert !res.key?(:b)
@@ -74,7 +83,7 @@ def test_attribute_setter
end
def test_dynamic_attribute_methods_from_getter
- res = Resource.new :agent, :a => 1
+ res = Resource.new @agent, :a => 1
assert res.key?(:a)
assert res.respond_to?(:a)
assert res.respond_to?(:a=)
@@ -85,7 +94,7 @@ def test_dynamic_attribute_methods_from_getter
end
def test_dynamic_attribute_methods_from_setter
- res = Resource.new :agent, :a => 1
+ res = Resource.new @agent, :a => 1
assert !res.key?(:b)
assert !res.respond_to?(:b)
assert !res.respond_to?(:b=)
@@ -97,13 +106,13 @@ def test_dynamic_attribute_methods_from_setter
end
def test_attrs
- res = Resource.new :agent, :a => 1
+ res = Resource.new @agent, :a => 1
hash = {:a => 1 }
assert_equal hash, res.attrs
end
def test_handle_hash_notation_with_string_key
- res = Resource.new :agent, :a => 1
+ res = Resource.new @agent, :a => 1
assert_equal 1, res['a']
res[:b] = 2

0 comments on commit b35f456

Please sign in to comment.