ahora 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +20 -0
- data/ahora.gemspec +1 -1
- data/lib/ahora/middleware/last_modified_caching.rb +2 -0
- data/lib/ahora/representation.rb +33 -22
- data/lib/ahora/resource.rb +13 -3
- data/lib/ahora/version.rb +2 -2
- data/test/ahora_test.rb +36 -0
- data/test/fixtures/employee.xml +3 -3
- data/test/fixtures/user_post.xml +12 -0
- metadata +6 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1cb06d2658dbbeb7b3ef608c0a075f6bf231a841
|
4
|
+
data.tar.gz: 70f9af7383998d3f989e2403d4576a1a087cb92d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 790ee4e933c2fa58e003f4ab6cf982680da6df0f6ba8861fa9749158cda98a7d10b0b1c51b07748601969c9f2efda1b85baaef154ca7685c9093033a8b388bbd
|
7
|
+
data.tar.gz: 3348a8dc3dc622b57521061cfbb219c8a2559b27f9456dd477297390df787a9c51ad59339cad49b732fd3386b8b5e1fe0531169115779d1f204ab684b5f4c6d3
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 Matthijs Langenberg and other contributors
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/ahora.gemspec
CHANGED
@@ -11,6 +11,7 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.homepage = ""
|
12
12
|
s.summary = %q{Consume Java-ish XML HTTP Resources easily}
|
13
13
|
s.description = %q{Consume Java-ish XML HTTP Resources easily}
|
14
|
+
s.license = 'MIT'
|
14
15
|
|
15
16
|
s.files = `git ls-files`.split("\n")
|
16
17
|
s.test_files = `git ls-files -- {test}/*`.split("\n")
|
@@ -20,7 +21,6 @@ Gem::Specification.new do |s|
|
|
20
21
|
s.add_dependency "nibbler", '>= 1.3.0'
|
21
22
|
s.add_dependency "faraday", '>= 0.7'
|
22
23
|
s.add_dependency "nokogiri", "~> 1.5"
|
23
|
-
s.add_dependency "activesupport"
|
24
24
|
|
25
25
|
s.add_development_dependency "fakeweb"
|
26
26
|
s.add_development_dependency "minitest"
|
data/lib/ahora/representation.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
require 'nibbler'
|
2
2
|
require 'nokogiri'
|
3
|
+
require 'time'
|
3
4
|
require 'date'
|
4
|
-
require 'active_support/core_ext/string'
|
5
5
|
require 'delegate'
|
6
|
+
require 'digest/sha1'
|
6
7
|
|
7
8
|
module Ahora
|
8
9
|
class Representation < Nibbler
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
present = lambda { |obj| obj && !obj.empty? }
|
11
|
+
|
12
|
+
INTEGER_PARSER = lambda { |node| Integer(node.content) if present.call(node.content) }
|
13
|
+
FLOAT_PARSER = lambda { |node| Float(node.content) if present.call(node.content) }
|
14
|
+
DATE_PARSER = lambda { |node| Date.parse(node.content) if present.call(node.content) }
|
15
|
+
TIME_PARSER = lambda { |node| Time.parse(node.content) if present.call(node.content) }
|
16
|
+
BOOL_PARSER = lambda { |node| node.content.to_s.downcase == 'true' }
|
15
17
|
|
16
18
|
module Definition
|
17
19
|
def element(*)
|
@@ -26,13 +28,20 @@ module Ahora
|
|
26
28
|
names = names.flatten
|
27
29
|
parser = names.pop if names.last.is_a?(Proc)
|
28
30
|
names.each do |name|
|
29
|
-
|
30
|
-
|
31
|
-
|
31
|
+
if Hash === name
|
32
|
+
selector, name = name.first
|
33
|
+
else
|
34
|
+
selector = attribute_selector(name)
|
35
|
+
end
|
32
36
|
element selector => name.to_s, :with => parser
|
33
37
|
end
|
34
38
|
end
|
35
39
|
|
40
|
+
# override in subclasses for e.g. camelCase support
|
41
|
+
def attribute_selector(name)
|
42
|
+
name.to_s
|
43
|
+
end
|
44
|
+
|
36
45
|
def string(*names)
|
37
46
|
attribute(names)
|
38
47
|
end
|
@@ -87,28 +96,30 @@ module Ahora
|
|
87
96
|
end
|
88
97
|
end
|
89
98
|
|
90
|
-
class
|
91
|
-
NoCacheKeyAvailable = Class.new(StandardError)
|
99
|
+
class Response < DelegateClass(Ahora::Representation)
|
92
100
|
def initialize(instantiator, document_parser, response)
|
93
101
|
@instantiator = instantiator
|
94
102
|
@document_parser = document_parser
|
95
103
|
@response = response
|
96
|
-
super(
|
104
|
+
super(target)
|
97
105
|
end
|
98
106
|
|
99
|
-
|
100
|
-
|
107
|
+
def target
|
108
|
+
@instantiator.call @document_parser.call(@response.body)
|
101
109
|
end
|
102
110
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
}.to_a.compact
|
111
|
+
def cache_key
|
112
|
+
uri = @response.env[:url].dup
|
113
|
+
uri.host = @response.env['HTTP_HOST'] if @response.env['HTTP_HOST']
|
114
|
+
"#{Digest::SHA1.hexdigest(uri.normalize.to_s)}/#{Digest::SHA1.hexdigest(@response.body)}"
|
108
115
|
end
|
116
|
+
end
|
109
117
|
|
110
|
-
|
111
|
-
|
118
|
+
class Collection < Response
|
119
|
+
def target
|
120
|
+
@document_parser.call(@response.body).search("/*[@type='array']/*").map { |element|
|
121
|
+
@instantiator.call element
|
122
|
+
}.to_a.compact
|
112
123
|
end
|
113
124
|
end
|
114
125
|
|
data/lib/ahora/resource.rb
CHANGED
@@ -63,6 +63,18 @@ module Ahora
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def collection(*args, &block)
|
66
|
+
instantiator, response = extract_parser_from_args(*args, &block)
|
67
|
+
Collection.new instantiator, document_parser, response
|
68
|
+
end
|
69
|
+
|
70
|
+
def single(*args, &block)
|
71
|
+
instantiator, response = extract_parser_from_args(*args, &block)
|
72
|
+
Response.new instantiator, document_parser, response
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def extract_parser_from_args(*args, &block)
|
66
78
|
if args.size == 2
|
67
79
|
klass, response = args
|
68
80
|
instantiator = lambda do |doc|
|
@@ -72,11 +84,9 @@ module Ahora
|
|
72
84
|
response = args.first
|
73
85
|
instantiator = block
|
74
86
|
end
|
75
|
-
|
87
|
+
[instantiator, response]
|
76
88
|
end
|
77
89
|
|
78
|
-
private
|
79
|
-
|
80
90
|
def document_parser
|
81
91
|
@document_parser ||= XmlParser.method(:parse)
|
82
92
|
end
|
data/lib/ahora/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Ahora
|
2
|
-
VERSION = "0.0
|
3
|
-
end
|
2
|
+
VERSION = "0.1.0"
|
3
|
+
end
|
data/test/ahora_test.rb
CHANGED
@@ -31,6 +31,10 @@ class PostRepository
|
|
31
31
|
collection Post, get("/users/#{id}/posts.xml")
|
32
32
|
end
|
33
33
|
|
34
|
+
def find_by_user_id_and_post_id(user_id, id)
|
35
|
+
single PostDomain, get("/users/#{user_id}/posts/#{id}.xml")
|
36
|
+
end
|
37
|
+
|
34
38
|
def extend_middleware(builder)
|
35
39
|
builder.use Faraday::Request::BasicAuthentication, USERNAME, PASSWORD
|
36
40
|
builder.use Ahora::Middleware::LastModifiedCaching, MemCache.instance
|
@@ -42,6 +46,14 @@ class PostRepository
|
|
42
46
|
end
|
43
47
|
|
44
48
|
class Post < Ahora::Representation
|
49
|
+
def self.attribute_selector(name)
|
50
|
+
"./#{name.to_s.gsub(/_([a-z])/){ $1.upcase }}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.base_parser_class
|
54
|
+
Post
|
55
|
+
end
|
56
|
+
|
45
57
|
element './objectId' => :id, :with => lambda {|n| n.content.to_i }
|
46
58
|
element './userObjectId' => :user_id, :with => lambda {|n| n.content.to_i }
|
47
59
|
element './parentObjectId' => :parent_id, :with => lambda {|n| n.content.to_i }
|
@@ -95,6 +107,10 @@ describe "requesting a collection" do
|
|
95
107
|
@posts.size.must_equal 2
|
96
108
|
end
|
97
109
|
|
110
|
+
it "has a cache key" do
|
111
|
+
@posts.cache_key.must_equal 'd630281e7b240892745b975d6b3ff9abe4fb3064/c7244914c7109201527c1b59930b64d242eca842'
|
112
|
+
end
|
113
|
+
|
98
114
|
describe "a single post from the collection" do
|
99
115
|
subject { @posts.first }
|
100
116
|
|
@@ -140,6 +156,24 @@ describe "requesting a collection" do
|
|
140
156
|
end
|
141
157
|
end
|
142
158
|
|
159
|
+
describe 'requesting a single resource' do
|
160
|
+
before do
|
161
|
+
fake_http '/users/1/posts/2.xml', fixture('user_post')
|
162
|
+
@post = PostRepository.new.find_by_user_id_and_post_id(1, 2)
|
163
|
+
end
|
164
|
+
|
165
|
+
subject { @post }
|
166
|
+
|
167
|
+
it "has the right body" do
|
168
|
+
subject.body.must_equal "When will world see Baby Cambridge?"
|
169
|
+
end
|
170
|
+
|
171
|
+
it "has a cache key" do
|
172
|
+
subject.cache_key.must_equal 'd2c6c472195a1f74b8271c5e7ced007cf9b2821e/c9e3c5a555a38cc7f99c3cdada0e5ec02341c674'
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
|
143
177
|
describe 'requesting a collection with if-modified-since support' do
|
144
178
|
before do
|
145
179
|
FakeWeb.register_uri :get, uri('/users/1/posts.xml'), [
|
@@ -207,3 +241,5 @@ describe "passing a block instead of a class to collection" do
|
|
207
241
|
repository.all.first.id.must_equal 1
|
208
242
|
end
|
209
243
|
end
|
244
|
+
|
245
|
+
|
data/test/fixtures/employee.xml
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<userPost>
|
3
|
+
<hidden>false</hidden>
|
4
|
+
<objectId>1</objectId>
|
5
|
+
<userObjectId>1</userObjectId>
|
6
|
+
<user>
|
7
|
+
<firstName>John</firstName>
|
8
|
+
<lastName>Doe</lastName>
|
9
|
+
</user>
|
10
|
+
<body>When will world see Baby Cambridge?</body>
|
11
|
+
<createdAt>2011-10-26T17:01:52+02:00</createdAt>
|
12
|
+
</userPost>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ahora
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthijs Langenberg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-07-
|
11
|
+
date: 2013-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nibbler
|
@@ -52,20 +52,6 @@ dependencies:
|
|
52
52
|
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.5'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: activesupport
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - '>='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :runtime
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - '>='
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: fakeweb
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -105,6 +91,7 @@ files:
|
|
105
91
|
- .travis.yml
|
106
92
|
- AUTHORS
|
107
93
|
- Gemfile
|
94
|
+
- LICENSE
|
108
95
|
- README.md
|
109
96
|
- Rakefile
|
110
97
|
- ahora.gemspec
|
@@ -120,10 +107,12 @@ files:
|
|
120
107
|
- test/ahora/resource_test.rb
|
121
108
|
- test/ahora_test.rb
|
122
109
|
- test/fixtures/employee.xml
|
110
|
+
- test/fixtures/user_post.xml
|
123
111
|
- test/fixtures/user_posts.xml
|
124
112
|
- test/test_helper.rb
|
125
113
|
homepage: ''
|
126
|
-
licenses:
|
114
|
+
licenses:
|
115
|
+
- MIT
|
127
116
|
metadata: {}
|
128
117
|
post_install_message:
|
129
118
|
rdoc_options: []
|