spyke 5.0.0 → 5.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 +4 -4
- data/README.md +6 -6
- data/lib/spyke/attribute_assignment.rb +5 -1
- data/lib/spyke/path.rb +18 -14
- data/lib/spyke/rfc_converter.rb +28 -0
- data/lib/spyke/version.rb +1 -1
- data/spyke.gemspec +1 -1
- data/test/attributes_test.rb +7 -7
- data/test/fallbacks_test.rb +1 -1
- data/test/path_test.rb +20 -4
- metadata +7 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5862d16d060c727c750f6ef6fa7f785d729747f5
|
4
|
+
data.tar.gz: '09585cb44ae03a6fda4c919d04ec24175dc55392'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3fba59829a12e29b2b8290f8aaa6a75fff77ecd274c11a32a46e60797d61f4fcfd08ff24cb9b36083f6c248367778e8668613e69289b7d89b22b98c32d19b3eb
|
7
|
+
data.tar.gz: b4ff64f835373b9bb7eaeda69d3d67e29ead1926dbf4fecbdd745f0a2409164d1d5ebb3778ac9d9dee6bf907ea2981a1863bf7d0aa1841ff13cf99cb54747f76
|
data/README.md
CHANGED
@@ -91,7 +91,7 @@ user = User.find(3)
|
|
91
91
|
# => GET http://api.com/users/3
|
92
92
|
|
93
93
|
user.posts
|
94
|
-
# => find embedded in returned
|
94
|
+
# => find embedded in returned data or GET http://api.com/users/3/posts
|
95
95
|
|
96
96
|
user.update(name: 'Alice')
|
97
97
|
# => PUT http://api.com/users/3 - { user: { name: 'Alice' } }
|
@@ -106,22 +106,22 @@ User.create(name: 'Bob')
|
|
106
106
|
### Custom URIs
|
107
107
|
|
108
108
|
You can specify custom URIs on both the class and association level.
|
109
|
-
Set uri to `nil` for associations you only want to use embedded
|
110
|
-
and never call out to the API.
|
109
|
+
Set uri to `nil` for associations you only want to use data embedded
|
110
|
+
in the response and never call out to the API.
|
111
111
|
|
112
112
|
```ruby
|
113
113
|
class User < Spyke::Base
|
114
|
-
uri 'people
|
114
|
+
uri 'people(/:id)' # id optional, both /people and /people/4 are valid
|
115
115
|
|
116
116
|
has_many :posts, uri: 'posts/for_user/:user_id' # user_id is required
|
117
|
-
has_one :image, uri: nil # only use embedded
|
117
|
+
has_one :image, uri: nil # only use embedded data
|
118
118
|
end
|
119
119
|
|
120
120
|
class Post < Spyke::Base
|
121
121
|
end
|
122
122
|
|
123
123
|
user = User.find(3) # => GET http://api.com/people/3
|
124
|
-
user.image # Will only use embedded
|
124
|
+
user.image # Will only use embedded data and never call out to api
|
125
125
|
user.posts # => GET http://api.com/posts/for_user/3
|
126
126
|
Post.find(4) # => GET http://api.com/posts/4
|
127
127
|
```
|
@@ -15,7 +15,7 @@ module Spyke
|
|
15
15
|
# they become overridable with "super".
|
16
16
|
# http://thepugautomatic.com/2013/07/dsom/
|
17
17
|
def attributes(*names)
|
18
|
-
unless
|
18
|
+
unless instance_variable_defined?(:@spyke_instance_method_container)
|
19
19
|
@spyke_instance_method_container = Module.new
|
20
20
|
include @spyke_instance_method_container
|
21
21
|
end
|
@@ -25,6 +25,10 @@ module Spyke
|
|
25
25
|
define_method(name) do
|
26
26
|
attribute(name)
|
27
27
|
end
|
28
|
+
|
29
|
+
define_method(:"#{name}=") do |value|
|
30
|
+
set_attribute(name, value)
|
31
|
+
end
|
28
32
|
end
|
29
33
|
end
|
30
34
|
end
|
data/lib/spyke/path.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
require '
|
1
|
+
require 'addressable/template'
|
2
|
+
require 'spyke/rfc_converter'
|
2
3
|
|
3
4
|
module Spyke
|
4
5
|
class InvalidPathError < StandardError; end
|
5
6
|
class Path
|
6
|
-
|
7
7
|
def initialize(pattern, params = {})
|
8
8
|
@pattern = pattern
|
9
9
|
@params = params.symbolize_keys
|
@@ -24,36 +24,40 @@ module Spyke
|
|
24
24
|
private
|
25
25
|
|
26
26
|
def uri_template
|
27
|
-
@uri_template ||=
|
27
|
+
@uri_template ||= Addressable::Template.new(pattern_with_rfc_style_parens)
|
28
28
|
end
|
29
29
|
|
30
30
|
def pattern_with_rfc_style_parens
|
31
|
-
@pattern
|
31
|
+
RfcConverter.new(@pattern).convert
|
32
32
|
end
|
33
33
|
|
34
34
|
def path
|
35
|
-
|
36
|
-
uri_template.expand(@params).chomp('/')
|
35
|
+
validate_required_variables!
|
36
|
+
uri_template.expand(@params).to_s.chomp('/')
|
37
37
|
end
|
38
38
|
|
39
|
-
def
|
40
|
-
if
|
41
|
-
raise Spyke::InvalidPathError, "Missing required
|
39
|
+
def validate_required_variables!
|
40
|
+
if missing_required_variables.any?
|
41
|
+
raise Spyke::InvalidPathError, "Missing required variables: #{missing_required_variables.join(', ')} in #{@pattern}. Mark optional variables with parens eg: (:param)"
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
def
|
46
|
-
|
45
|
+
def missing_required_variables
|
46
|
+
required_variables - variables_with_values
|
47
47
|
end
|
48
48
|
|
49
|
-
def
|
49
|
+
def variables_with_values
|
50
50
|
@params.map do |key, value|
|
51
51
|
key if value.present?
|
52
52
|
end.compact
|
53
53
|
end
|
54
54
|
|
55
|
-
def
|
56
|
-
|
55
|
+
def required_variables
|
56
|
+
variables - optional_variables
|
57
|
+
end
|
58
|
+
|
59
|
+
def optional_variables
|
60
|
+
@pattern.scan(/\(\/?:(\w+)\)/).flatten.map(&:to_sym)
|
57
61
|
end
|
58
62
|
end
|
59
63
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Spyke
|
2
|
+
class RfcConverter
|
3
|
+
def initialize(input)
|
4
|
+
@input = input
|
5
|
+
end
|
6
|
+
|
7
|
+
def convert
|
8
|
+
output = @input.dup
|
9
|
+
output = wrap_required_variables_in_curly_braces(output)
|
10
|
+
output = convert_parens_to_curly_braces(output)
|
11
|
+
output = remove_colons(output)
|
12
|
+
output
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def wrap_required_variables_in_curly_braces(text)
|
17
|
+
text.gsub(/(:\w+(?!\)))\b/, '{\1}')
|
18
|
+
end
|
19
|
+
|
20
|
+
def convert_parens_to_curly_braces(text)
|
21
|
+
text.gsub('(', '{').gsub(')', '}')
|
22
|
+
end
|
23
|
+
|
24
|
+
def remove_colons(text)
|
25
|
+
text.gsub(':', '')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/spyke/version.rb
CHANGED
data/spyke.gemspec
CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_dependency 'activemodel', '>= 4.0.0', '< 6.0'
|
23
23
|
spec.add_dependency 'faraday', '>= 0.9.0', '< 2.0'
|
24
24
|
spec.add_dependency 'faraday_middleware', '>= 0.9.1', '< 2.0'
|
25
|
-
spec.add_dependency '
|
25
|
+
spec.add_dependency 'addressable', '>= 2.5.2'
|
26
26
|
|
27
27
|
spec.add_development_dependency 'bundler', '~> 1.6'
|
28
28
|
spec.add_development_dependency 'coveralls', '~> 0.7'
|
data/test/attributes_test.rb
CHANGED
@@ -92,7 +92,7 @@ module Spyke
|
|
92
92
|
|
93
93
|
def test_explicit_attributes
|
94
94
|
recipe = Recipe.new
|
95
|
-
|
95
|
+
assert_nil recipe.title
|
96
96
|
assert_raises NoMethodError do
|
97
97
|
recipe.not_set
|
98
98
|
end
|
@@ -102,18 +102,18 @@ module Spyke
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def test_super_with_explicit_attributes
|
105
|
-
|
105
|
+
assert_nil Recipe.new.description
|
106
106
|
end
|
107
107
|
|
108
108
|
def test_inheriting_explicit_attributes
|
109
|
-
|
110
|
-
|
109
|
+
assert_nil Image.new.description
|
110
|
+
assert_nil Image.new.caption
|
111
111
|
assert_raises NoMethodError do
|
112
112
|
Image.new.note
|
113
113
|
end
|
114
|
-
|
115
|
-
|
116
|
-
|
114
|
+
assert_nil StepImage.new.description
|
115
|
+
assert_nil StepImage.new.caption
|
116
|
+
assert_nil StepImage.new.note
|
117
117
|
end
|
118
118
|
|
119
119
|
def test_converting_files_to_faraday_io
|
data/test/fallbacks_test.rb
CHANGED
data/test/path_test.rb
CHANGED
@@ -20,16 +20,32 @@ module Spyke
|
|
20
20
|
assert_equal '/users/1/recipes/2', Path.new('/users/:user_id/recipes/:id', user_id: 1, id: 2).to_s
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
24
|
-
assert_raises Spyke::InvalidPathError, 'Missing required
|
23
|
+
def test_required_variables
|
24
|
+
assert_raises Spyke::InvalidPathError, 'Missing required variables: user_id in /users/:user_id/recipes/(:id)' do
|
25
25
|
Path.new('/users/:user_id/recipes/(:id)', id: 2).to_s
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
30
|
-
|
29
|
+
def test_mix_of_required_and_unrequired_variables
|
30
|
+
assert_raises Spyke::InvalidPathError, 'Missing required variables: part2, part4' do
|
31
|
+
Path.new('/1/profiles(/:part1)/:part2(/:part3)/:part4.xml').to_s
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_present_optional_param_with_extension
|
31
36
|
assert_equal '/1/profiles/2.json', Path.new('/1/profiles(/:id).json', id: 2).to_s
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_missing_optional_variables_with_extension
|
32
40
|
assert_equal '/1/profiles.json', Path.new('/1/profiles(/:id).json').to_s
|
33
41
|
end
|
42
|
+
|
43
|
+
def test_multiple_missing_optional_variables_with_extension
|
44
|
+
assert_equal '/1/profiles.xml', Path.new('/1/profiles(/:id1)(/:id2)(/:id3)(/:id4).xml').to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_mixture_of_optional_variables_and_required_variables_with_extension
|
48
|
+
assert_equal '/1/profiles/other/2.xml', Path.new('/1/profiles(/:part1)/:part2(/:part3)/:id.xml', part2: 'other', id: 2).to_s
|
49
|
+
end
|
34
50
|
end
|
35
51
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spyke
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jens Balvig
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -91,25 +91,19 @@ dependencies:
|
|
91
91
|
- !ruby/object:Gem::Version
|
92
92
|
version: '2.0'
|
93
93
|
- !ruby/object:Gem::Dependency
|
94
|
-
name:
|
94
|
+
name: addressable
|
95
95
|
requirement: !ruby/object:Gem::Requirement
|
96
96
|
requirements:
|
97
97
|
- - ">="
|
98
98
|
- !ruby/object:Gem::Version
|
99
|
-
version:
|
100
|
-
- - "<"
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: '2.0'
|
99
|
+
version: 2.5.2
|
103
100
|
type: :runtime
|
104
101
|
prerelease: false
|
105
102
|
version_requirements: !ruby/object:Gem::Requirement
|
106
103
|
requirements:
|
107
104
|
- - ">="
|
108
105
|
- !ruby/object:Gem::Version
|
109
|
-
version:
|
110
|
-
- - "<"
|
111
|
-
- !ruby/object:Gem::Version
|
112
|
-
version: '2.0'
|
106
|
+
version: 2.5.2
|
113
107
|
- !ruby/object:Gem::Dependency
|
114
108
|
name: bundler
|
115
109
|
requirement: !ruby/object:Gem::Requirement
|
@@ -285,6 +279,7 @@ files:
|
|
285
279
|
- lib/spyke/path.rb
|
286
280
|
- lib/spyke/relation.rb
|
287
281
|
- lib/spyke/result.rb
|
282
|
+
- lib/spyke/rfc_converter.rb
|
288
283
|
- lib/spyke/scope_registry.rb
|
289
284
|
- lib/spyke/scoping.rb
|
290
285
|
- lib/spyke/version.rb
|
@@ -320,7 +315,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
320
315
|
version: '0'
|
321
316
|
requirements: []
|
322
317
|
rubyforge_project:
|
323
|
-
rubygems_version: 2.
|
318
|
+
rubygems_version: 2.6.13
|
324
319
|
signing_key:
|
325
320
|
specification_version: 4
|
326
321
|
summary: Interact with REST services in an ActiveRecord-like manner
|