ahora 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 62ad288812b561ef44fb7da891c744a3f703bff7
4
+ data.tar.gz: 2022328ba2e73d65a131cafa976389e3b443cd5b
5
+ SHA512:
6
+ metadata.gz: f9ab7f72fe0aceb9dad7b35e9b9da672dd11a1dd1b60e12fdc8a8e77ebae33a9bc08e509de75d10b0acde640ca6d4811eece4faf51ef079f76a48955cb15eaf4
7
+ data.tar.gz: 93f01442df08707277bf9860e91212fda599c2809b1cec67f95a287184b943a27f507e97e2cd941fab75c74a815d99325a27bf0932d82816c39a8338d444fb2a
@@ -7,6 +7,7 @@ require 'delegate'
7
7
  module Ahora
8
8
  class Representation < Nibbler
9
9
  INTEGER_PARSER = lambda { |node| Integer(node.content) if node.content.present? }
10
+ FLOAT_PARSER = lambda { |node| Float(node.content) if node.content.present? }
10
11
  DATE_PARSER = lambda { |node| Date.parse(node.content) if node.content.present? }
11
12
  TIME_PARSER = lambda { |node| Time.parse(node.content) if node.content.present? }
12
13
  BOOL_PARSER =
@@ -26,27 +27,12 @@ module Ahora
26
27
  parser = names.pop if names.last.is_a?(Proc)
27
28
  names.each do |name|
28
29
  selector = name
29
- if name.is_a? Hash
30
- selector, name = name.first
31
- end
32
- element to_selector(selector.to_s.camelcase(:lower)) => name.to_s, :with => parser
30
+ selector, name = name.first if name.is_a? Hash
31
+ selector = "./#{selector.to_s.camelcase(:lower)}"
32
+ element selector => name.to_s, :with => parser
33
33
  end
34
34
  end
35
35
 
36
- # Public: define Java style object id mapping
37
- #
38
- # *names - Array of String or Symbol ruby style names
39
- #
40
- # Examples
41
- #
42
- # objectid :id, parent_id
43
- # # is equivalent to
44
- # element 'objectId' => 'id'
45
- # element 'parentObjectId' => 'parent_id'
46
- def objectid(*names)
47
- attribute names.map { |name| { name.to_s.gsub('id', 'object_id') => name } }, INTEGER_PARSER
48
- end
49
-
50
36
  def string(*names)
51
37
  attribute(names)
52
38
  end
@@ -55,6 +41,10 @@ module Ahora
55
41
  attribute(names, INTEGER_PARSER)
56
42
  end
57
43
 
44
+ def float(*names)
45
+ attribute(names, FLOAT_PARSER)
46
+ end
47
+
58
48
  def date(*names)
59
49
  attribute(names, DATE_PARSER)
60
50
  end
@@ -69,10 +59,11 @@ module Ahora
69
59
  end
70
60
 
71
61
  private
72
- # Convert to XPATH selector for current node or
73
- # one level deep.
74
- def to_selector(name)
75
- "./*/#{name}|./#{name}"
62
+
63
+ # allows using block sub-parsers without explicitly stating they need to
64
+ # inherit from Ahora::Representation
65
+ def base_parser_class
66
+ Representation
76
67
  end
77
68
  end
78
69
 
@@ -85,7 +76,13 @@ module Ahora
85
76
  send("#{key}=", val)
86
77
  end
87
78
  else
88
- super
79
+ doc = doc_or_atts
80
+ doc = XmlParser.parse(doc) unless doc.respond_to?(:search)
81
+ if doc.node_type == Nokogiri::XML::Node::DOCUMENT_NODE
82
+ # immediately scope to root element
83
+ doc = doc.at('/*')
84
+ end
85
+ super(doc)
89
86
  end
90
87
  end
91
88
  end
@@ -96,16 +93,10 @@ module Ahora
96
93
  @instantiator = instantiator
97
94
  @document_parser = document_parser
98
95
  @response = response
99
- @cache_key = response.env[:response_headers]['X-Ahora-Cache-Key']
100
96
  super([])
101
97
  end
102
98
 
103
- def cache_key
104
- @cache_key or raise NoCacheKeyAvailable,
105
- "No caching middleware is used or resource does not support caching."
106
- end
107
-
108
- %w( to_s to_a size each first last [] inspect pretty_print ).each do |method_name|
99
+ %w( to_s to_a size each first last [] inspect pretty_print find detect map collect inject select select! delete_if ).each do |method_name|
109
100
  eval "def #{method_name}(*); kicker; super; end"
110
101
  end
111
102
 
@@ -126,4 +117,4 @@ module Ahora
126
117
  Nokogiri::XML.parse(body, nil, nil, Nokogiri::XML::ParseOptions::STRICT)
127
118
  end
128
119
  end
129
- end
120
+ end
@@ -4,43 +4,51 @@ module Ahora
4
4
  module Resource
5
5
  attr_writer :document_parser
6
6
 
7
- def get(url, params = {})
8
- connection.get do |req|
9
- set_common_headers(req)
10
- req.url url, params
7
+ def get(url, params = nil)
8
+ connection.run_request(:get, url, nil, nil) do |req|
9
+ req.params.update(params) if params
10
+ yield req if block_given?
11
11
  end
12
12
  end
13
13
 
14
14
  # FIXME test
15
- def post(url, body)
16
- connection.post do |req|
17
- set_common_headers(req)
18
- req.url url
19
- req.body = body
15
+ def post(url, body = nil)
16
+ connection.run_request(:post, url, body, nil) do |req|
17
+ yield req if block_given?
20
18
  end
21
19
  end
22
20
 
23
21
  # FIXME test
24
- def put(url, body)
25
- connection.put do |req|
26
- set_common_headers(req)
27
- req.url url
28
- req.body = body
22
+ def put(url, body = nil)
23
+ connection.run_request(:put, url, body, nil) do |req|
24
+ yield req if block_given?
29
25
  end
30
26
  end
31
27
 
32
28
  def connection
33
- conn = Faraday.new(host, :ssl => { :verify => false }) do |builder|
34
- builder.use Faraday::Response::RaiseError
35
- extend_middleware(builder)
36
- builder.adapter Faraday.default_adapter
29
+ Faraday.new(host.dup, connection_options) do |conn|
30
+ conn.use Faraday::Response::RaiseError
31
+ extend_middleware(conn.builder)
32
+ unless conn.builder.handlers.any? {|mid| mid.klass < Faraday::Adapter }
33
+ conn.adapter Faraday.default_adapter
34
+ end
37
35
  end
38
- conn.headers['User-Agent'] = 'Ahora'
39
- conn
40
36
  end
41
37
 
42
38
  # @abstract override to use custom Faraday middleware
43
- def extend_middleware(builder); end;
39
+ def extend_middleware(builder)
40
+ super if defined? super
41
+ end
42
+
43
+ # FIXME test (FakeWeb cannot test request headers)
44
+ # @abstract override to set custome headers
45
+ # returns a hash with a string for each key
46
+ def headers
47
+ (defined?(super) ? super.dup : {}).update \
48
+ :user_agent => 'Ahora',
49
+ :content_type => 'application/xml',
50
+ :accept => 'application/xml'
51
+ end
44
52
 
45
53
  def collection(*args, &block)
46
54
  if args.size == 2
@@ -60,9 +68,9 @@ module Ahora
60
68
  @document_parser ||= XmlParser.method(:parse)
61
69
  end
62
70
 
63
- def set_common_headers(req)
64
- req.headers['Content-Type'] = 'application/xml'
65
- req.headers['Accept'] = 'application/xml'
71
+ def connection_options
72
+ (defined?(super) ? super.dup : {}).update \
73
+ :headers => headers
66
74
  end
67
75
  end
68
- end
76
+ end
data/lib/ahora/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ahora
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -5,6 +5,7 @@ require_relative '../../lib/ahora/representation'
5
5
 
6
6
  class Employee < Ahora::Representation
7
7
  boolean :is_rockstar, :slacker, :fired
8
+ float :rating
8
9
  end
9
10
 
10
11
  describe "boolean elements" do
@@ -36,4 +37,13 @@ describe "boolean elements" do
36
37
  it "parsing missing value adds the correct question mark reader" do
37
38
  employee.fired?.must_equal false
38
39
  end
40
+ end
41
+
42
+ describe "float elements" do
43
+ let(:employee) { Employee.parse(fixture('employee').read) }
44
+
45
+ it "parses float elements" do
46
+ employee.rating.must_equal 7.8
47
+ end
48
+
39
49
  end
@@ -0,0 +1,79 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/pride'
3
+ require 'fakeweb'
4
+ require_relative '../test_helper'
5
+ require_relative '../../lib/ahora/resource'
6
+
7
+ FakeWeb.allow_net_connect = false
8
+
9
+ class DefaultPost
10
+ include Ahora::Resource
11
+
12
+ def host
13
+ 'http://test.net/'
14
+ end
15
+ end
16
+
17
+ class CustomPost < DefaultPost
18
+ def headers
19
+ super.update \
20
+ 'Accept' => 'text/plain',
21
+ 'X-Custom' => 'foobar'
22
+ end
23
+
24
+ def extend_middleware builder
25
+ builder.adapter :rack
26
+ end
27
+ end
28
+
29
+ describe 'default headers' do
30
+ before do
31
+ @default = DefaultPost.new.connection.headers
32
+ @custom = CustomPost.new.connection.headers
33
+ end
34
+
35
+ it 'includes the user agent, accept and content-type' do
36
+ @default['User-Agent'].must_equal 'Ahora'
37
+ @default['Accept'].must_equal 'application/xml'
38
+ @default['Content-Type'].must_equal 'application/xml'
39
+ end
40
+
41
+ it 'allows overriding and setting custom headers' do
42
+ @custom['User-Agent'].must_equal 'Ahora'
43
+ @custom['Accept'].must_equal 'text/plain'
44
+ @custom['Content-Type'].must_equal 'application/xml'
45
+ @custom['X-Custom'].must_equal 'foobar'
46
+ end
47
+ end
48
+
49
+ describe 'connection adapter' do
50
+ it 'includes the default Faraday adapter' do
51
+ faraday = DefaultPost.new.connection
52
+ adapter = faraday.builder.handlers.last
53
+ adapter.klass.ancestors.must_include Faraday::Adapter
54
+ end
55
+
56
+ it 'can configure a custom Faraday adapter' do
57
+ faraday = CustomPost.new.connection
58
+ adapter = faraday.builder.handlers.last
59
+ adapter.klass.must_equal Faraday::Adapter::Rack
60
+ end
61
+ end
62
+
63
+ describe '#put' do
64
+ before do
65
+ @post = DefaultPost.new
66
+ end
67
+
68
+ it "supports passing an url and a body" do
69
+ FakeWeb.register_uri :put, 'http://test.net/posts', :body => 'body'
70
+ @post.put("posts", "body").body.must_equal 'body'
71
+ end
72
+
73
+ it "supports passing an url and a params hash" do
74
+ FakeWeb.register_uri :put, 'http://test.net/posts?foo=bar', :body => 'param'
75
+ @post.put("posts") { |req|
76
+ req.params[:foo] = 'bar'
77
+ }.body.must_equal 'param'
78
+ end
79
+ end
data/test/ahora_test.rb CHANGED
@@ -42,14 +42,16 @@ class PostRepository
42
42
  end
43
43
 
44
44
  class Post < Ahora::Representation
45
- objectid :id, :user_id, :parent_id
45
+ element './objectId' => :id, :with => lambda {|n| n.content.to_i }
46
+ element './userObjectId' => :user_id, :with => lambda {|n| n.content.to_i }
47
+ element './parentObjectId' => :parent_id, :with => lambda {|n| n.content.to_i }
46
48
  date :created_at
47
49
  element :body
48
- element 'user', :with => Ahora::Representation do
50
+ element 'user' do
49
51
  string :first_name, :last_name
50
52
  end
51
53
  boolean :hidden
52
- elements 'replies/userPost' => :replies, :with => Post
54
+ elements 'replies/userPost' => :replies, :with => self
53
55
  end
54
56
 
55
57
  class PostDomainRepository < PostRepository
@@ -93,10 +95,6 @@ describe "requesting a collection" do
93
95
  @posts.size.must_equal 2
94
96
  end
95
97
 
96
- it "raises on #cache_key, because the backend does not has support for it" do
97
- -> { @posts.cache_key }.must_raise(Ahora::Collection::NoCacheKeyAvailable)
98
- end
99
-
100
98
  describe "a single post from the collection" do
101
99
  subject { @posts.first }
102
100
 
@@ -153,13 +151,6 @@ describe 'requesting a collection with if-modified-since support' do
153
151
 
154
152
  it "has a cache key" do
155
153
  @posts = @repository.find_by_user_id(1)
156
- @posts.cache_key.
157
- must_equal 'http://test.net/users/1/posts.xml:fragment_Mon, 02 Apr 2012 15:20:41 GMT'
158
- end
159
-
160
- it "has a cache key for cached response" do
161
- @repository.find_by_user_id(1).cache_key.
162
- must_equal @repository.find_by_user_id(1).cache_key
163
154
  end
164
155
 
165
156
  it "caches when response header includes Last-Modified" do
@@ -215,4 +206,4 @@ describe "passing a block instead of a class to collection" do
215
206
  repository = BlogPostRepository.new
216
207
  repository.all.first.id.must_equal 1
217
208
  end
218
- end
209
+ end
@@ -3,4 +3,5 @@
3
3
  <firstName>John</firstName>
4
4
  <isRockstar>true</isRockstar>
5
5
  <slacker>false</slacker>
6
+ <rating>7.8</rating>
6
7
  </employee>
metadata CHANGED
@@ -1,82 +1,99 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ahora
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
5
- prerelease:
4
+ version: 0.0.3
6
5
  platform: ruby
7
6
  authors:
8
7
  - Matthijs Langenberg
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-06-26 00:00:00.000000000 Z
11
+ date: 2013-07-02 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: nibbler
16
- requirement: &70334212827160 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: 1.3.0
22
20
  type: :runtime
23
21
  prerelease: false
24
- version_requirements: *70334212827160
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.3.0
25
27
  - !ruby/object:Gem::Dependency
26
28
  name: faraday
27
- requirement: &70334212826660 !ruby/object:Gem::Requirement
28
- none: false
29
+ requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - ! '>='
31
+ - - '>='
31
32
  - !ruby/object:Gem::Version
32
33
  version: '0.7'
33
34
  type: :runtime
34
35
  prerelease: false
35
- version_requirements: *70334212826660
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0.7'
36
41
  - !ruby/object:Gem::Dependency
37
42
  name: nokogiri
38
- requirement: &70334212826200 !ruby/object:Gem::Requirement
39
- none: false
43
+ requirement: !ruby/object:Gem::Requirement
40
44
  requirements:
41
45
  - - ~>
42
46
  - !ruby/object:Gem::Version
43
47
  version: '1.5'
44
48
  type: :runtime
45
49
  prerelease: false
46
- version_requirements: *70334212826200
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.5'
47
55
  - !ruby/object:Gem::Dependency
48
56
  name: activesupport
49
- requirement: &70334212825820 !ruby/object:Gem::Requirement
50
- none: false
57
+ requirement: !ruby/object:Gem::Requirement
51
58
  requirements:
52
- - - ! '>='
59
+ - - '>='
53
60
  - !ruby/object:Gem::Version
54
61
  version: '0'
55
62
  type: :runtime
56
63
  prerelease: false
57
- version_requirements: *70334212825820
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
58
69
  - !ruby/object:Gem::Dependency
59
70
  name: fakeweb
60
- requirement: &70334212825360 !ruby/object:Gem::Requirement
61
- none: false
71
+ requirement: !ruby/object:Gem::Requirement
62
72
  requirements:
63
- - - ! '>='
73
+ - - '>='
64
74
  - !ruby/object:Gem::Version
65
75
  version: '0'
66
76
  type: :development
67
77
  prerelease: false
68
- version_requirements: *70334212825360
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: minitest
71
- requirement: &70334212824940 !ruby/object:Gem::Requirement
72
- none: false
85
+ requirement: !ruby/object:Gem::Requirement
73
86
  requirements:
74
- - - ! '>='
87
+ - - '>='
75
88
  - !ruby/object:Gem::Version
76
89
  version: '0'
77
90
  type: :development
78
91
  prerelease: false
79
- version_requirements: *70334212824940
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
80
97
  description: Consume Java-ish XML HTTP Resources easily
81
98
  email:
82
99
  - matthijs.langenberg@nedap.com
@@ -99,32 +116,32 @@ files:
99
116
  - lib/ahora/resource.rb
100
117
  - lib/ahora/version.rb
101
118
  - test/ahora/representation_test.rb
119
+ - test/ahora/resource_test.rb
102
120
  - test/ahora_test.rb
103
121
  - test/fixtures/employee.xml
104
122
  - test/fixtures/user_posts.xml
105
123
  - test/test_helper.rb
106
124
  homepage: ''
107
125
  licenses: []
126
+ metadata: {}
108
127
  post_install_message:
109
128
  rdoc_options: []
110
129
  require_paths:
111
130
  - lib
112
131
  required_ruby_version: !ruby/object:Gem::Requirement
113
- none: false
114
132
  requirements:
115
- - - ! '>='
133
+ - - '>='
116
134
  - !ruby/object:Gem::Version
117
135
  version: '0'
118
136
  required_rubygems_version: !ruby/object:Gem::Requirement
119
- none: false
120
137
  requirements:
121
- - - ! '>='
138
+ - - '>='
122
139
  - !ruby/object:Gem::Version
123
140
  version: '0'
124
141
  requirements: []
125
142
  rubyforge_project:
126
- rubygems_version: 1.8.15
143
+ rubygems_version: 2.0.3
127
144
  signing_key:
128
- specification_version: 3
145
+ specification_version: 4
129
146
  summary: Consume Java-ish XML HTTP Resources easily
130
147
  test_files: []