ahora 0.0.2 → 0.0.3

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 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: []