ahora 0.0.4 → 0.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f0985b57a670034c7945f5e36a9cc90101bf8f83
4
- data.tar.gz: d0092b586366a543d87a11cec7b739c325fb7f50
3
+ metadata.gz: 1cb06d2658dbbeb7b3ef608c0a075f6bf231a841
4
+ data.tar.gz: 70f9af7383998d3f989e2403d4576a1a087cb92d
5
5
  SHA512:
6
- metadata.gz: 51b4dfac648230d1fd5e0e1623045e38ead1401db50509e6b982b1cd4a6b59b93e240c0dd9ce95329a139104745267db76307b0569258bfb64313cc21033b3e6
7
- data.tar.gz: 1e388b5863a1f2a9808c3b1a59040464a1b35386296ad0d81afb53f578320da1b9b4745cf21b604430c695bf7b194551737e965d608d189f2a552ac98010af80
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"
@@ -1,3 +1,5 @@
1
+ require 'time'
2
+
1
3
  module Ahora
2
4
  module Middleware
3
5
  class LastModifiedCaching < Faraday::Middleware
@@ -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
- INTEGER_PARSER = lambda { |node| Integer(node.content) if node.content.present? }
10
- FLOAT_PARSER = lambda { |node| Float(node.content) if node.content.present? }
11
- DATE_PARSER = lambda { |node| Date.parse(node.content) if node.content.present? }
12
- TIME_PARSER = lambda { |node| Time.parse(node.content) if node.content.present? }
13
- BOOL_PARSER =
14
- lambda { |node| node.content.to_s.downcase == 'true' if node.content.present? }
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
- selector = name
30
- selector, name = name.first if name.is_a? Hash
31
- selector = "./#{selector.to_s.camelcase(:lower)}"
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 Collection < DelegateClass(Array)
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
- %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|
100
- eval "def #{method_name}(*); kicker; super; end"
107
+ def target
108
+ @instantiator.call @document_parser.call(@response.body)
101
109
  end
102
110
 
103
- private
104
- def kicker
105
- @_collection ||= __setobj__ doc.search("/*[@type='array']/*").map { |element|
106
- @instantiator.call element
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
- def doc
111
- @document_parser.call(@response.body)
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
 
@@ -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
- Collection.new instantiator, document_parser, response
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.4"
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
+
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0"?>
2
2
  <employee>
3
- <firstName>John</firstName>
4
- <isRockstar>true</isRockstar>
3
+ <first_name>John</first_name>
4
+ <is_rockstar>true</is_rockstar>
5
5
  <slacker>false</slacker>
6
6
  <rating>7.8</rating>
7
- </employee>
7
+ </employee>
@@ -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
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-12 00:00:00.000000000 Z
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: []