frenetic 0.0.20.alpha.6 → 1.0.0.alpha.1
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 +7 -0
- data/.ruby-version +1 -1
- data/Appraisals +9 -0
- data/Gemfile +1 -1
- data/README.md +2 -2
- data/frenetic.gemspec +8 -5
- data/gemfiles/faraday_08.gemfile +10 -0
- data/gemfiles/faraday_08.gemfile.lock +77 -0
- data/gemfiles/faraday_09.gemfile +10 -0
- data/gemfiles/faraday_09.gemfile.lock +77 -0
- data/lib/frenetic.rb +57 -30
- data/lib/frenetic/briefly_memoizable.rb +34 -0
- data/lib/frenetic/concerns/collection_rest_methods.rb +1 -1
- data/lib/frenetic/concerns/hal_linked.rb +5 -35
- data/lib/frenetic/concerns/member_rest_methods.rb +0 -2
- data/lib/frenetic/concerns/structured.rb +0 -5
- data/lib/frenetic/connection.rb +110 -0
- data/lib/frenetic/errors.rb +112 -0
- data/lib/frenetic/hypermedia_link.rb +74 -0
- data/lib/frenetic/hypermedia_link_set.rb +43 -0
- data/lib/frenetic/middleware/hal_json.rb +9 -12
- data/lib/frenetic/resource.rb +22 -6
- data/lib/frenetic/resource_collection.rb +0 -1
- data/lib/frenetic/resource_mockery.rb +55 -1
- data/lib/frenetic/version.rb +1 -1
- data/spec/{concerns/breifly_memoizable_spec.rb → briefly_memoizable_spec.rb} +10 -18
- data/spec/concerns/hal_linked_spec.rb +49 -62
- data/spec/concerns/member_rest_methods_spec.rb +8 -10
- data/spec/concerns/structured_spec.rb +70 -75
- data/spec/connection_spec.rb +137 -0
- data/spec/fixtures/test_api_requests.rb +8 -2
- data/spec/frenetic_spec.rb +221 -133
- data/spec/hypermedia_link_set_spec.rb +155 -0
- data/spec/hypermedia_link_spec.rb +153 -0
- data/spec/middleware/hal_json_spec.rb +13 -15
- data/spec/resource_collection_spec.rb +17 -16
- data/spec/resource_mockery_spec.rb +69 -0
- data/spec/resource_spec.rb +110 -63
- data/spec/support/rspec.rb +0 -1
- metadata +88 -75
- data/lib/frenetic/concerns/briefly_memoizable.rb +0 -34
- data/lib/frenetic/concerns/configurable.rb +0 -59
- data/lib/frenetic/concerns/resource_mockery.rb +0 -48
- data/lib/frenetic/configuration.rb +0 -88
- data/spec/concerns/configurable_spec.rb +0 -50
- data/spec/concerns/resource_mockery_spec.rb +0 -56
- data/spec/configuration_spec.rb +0 -134
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: cc9d5efbe7083a07d49bc6d57da6a9ad2125e37d
|
4
|
+
data.tar.gz: 1d08f15fa29717b07f6bf43d6e46e8acc0832244
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ce6cdbdf561f06c6b4b9120b0222e69f031ea316f634e97f70df742a9c4015344ad551b6b60d072e149014ddd537def35ab6bbe7fbbd11367116fe7482527522
|
7
|
+
data.tar.gz: d70ca28073717ee35679abca5ef8107372ee7f3acf138070cdc40f91ef6a2b00481ddf49c5c76b9c6e6fcc86104e258c2f5407588d7b6c4b78abc1cb7e25a0de
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
2.1.2
|
data/Appraisals
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -176,7 +176,7 @@ end
|
|
176
176
|
|
177
177
|
#### Authentication
|
178
178
|
|
179
|
-
Frenetic supports both Basic Auth and
|
179
|
+
Frenetic supports both Basic Auth and Token Auth via the appropriate Faraday
|
180
180
|
middleware.
|
181
181
|
|
182
182
|
##### Basic Auth
|
@@ -457,4 +457,4 @@ ideas on how to support other Hypermedia formats like [Collection+JSON][coll_jso
|
|
457
457
|
[root_cache]: #default-root-cache-age
|
458
458
|
[adapters]: https://github.com/lostisland/faraday/blob/c26a060acdd9eae356409c2ca79f1c22f8263de9/lib/faraday/adapter.rb#L7-L17
|
459
459
|
[rack_cache]: https://github.com/rtomayko/rack-cache
|
460
|
-
[coll_json]: http://amundsen.com/media-types/collection/
|
460
|
+
[coll_json]: http://amundsen.com/media-types/collection/
|
data/frenetic.gemspec
CHANGED
@@ -14,15 +14,18 @@ Gem::Specification.new do |gem|
|
|
14
14
|
gem.name = "frenetic"
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = Frenetic::VERSION
|
17
|
+
gem.required_ruby_version = '>= 1.9.3'
|
17
18
|
|
18
|
-
gem.add_dependency 'faraday', '
|
19
|
-
gem.add_dependency 'faraday_middleware', '
|
19
|
+
gem.add_dependency 'faraday', '>= 0.8'
|
20
|
+
gem.add_dependency 'faraday_middleware', '>= 0.8'
|
20
21
|
gem.add_dependency 'activesupport', '>= 3'
|
21
22
|
gem.add_dependency 'addressable', '~> 2.3.4'
|
22
23
|
|
23
24
|
gem.add_development_dependency 'awesome_print'
|
24
|
-
gem.add_development_dependency 'rspec', '~>
|
25
|
+
gem.add_development_dependency 'rspec', '~> 3.0.0'
|
25
26
|
gem.add_development_dependency 'rack-cache', '~> 1.2'
|
26
|
-
gem.add_development_dependency '
|
27
|
-
gem.add_development_dependency '
|
27
|
+
gem.add_development_dependency 'faraday-http-cache', '~> 0.4.2'
|
28
|
+
gem.add_development_dependency 'webmock', '~> 1.18.0'
|
29
|
+
gem.add_development_dependency 'timecop', '~> 0.7.1'
|
30
|
+
gem.add_development_dependency 'appraisal', '~> 1.0.2'
|
28
31
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../
|
3
|
+
specs:
|
4
|
+
frenetic (0.0.20.alpha.6)
|
5
|
+
activesupport (>= 3)
|
6
|
+
addressable (~> 2.3.4)
|
7
|
+
faraday (>= 0.8)
|
8
|
+
faraday_middleware (>= 0.8)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
activesupport (4.1.5)
|
14
|
+
i18n (~> 0.6, >= 0.6.9)
|
15
|
+
json (~> 1.7, >= 1.7.7)
|
16
|
+
minitest (~> 5.1)
|
17
|
+
thread_safe (~> 0.1)
|
18
|
+
tzinfo (~> 1.1)
|
19
|
+
addressable (2.3.6)
|
20
|
+
appraisal (1.0.2)
|
21
|
+
bundler
|
22
|
+
rake
|
23
|
+
thor (>= 0.14.0)
|
24
|
+
awesome_print (1.2.0)
|
25
|
+
crack (0.4.2)
|
26
|
+
safe_yaml (~> 1.0.0)
|
27
|
+
diff-lcs (1.2.5)
|
28
|
+
faraday (0.8.9)
|
29
|
+
multipart-post (~> 1.2.0)
|
30
|
+
faraday-http-cache (0.4.2)
|
31
|
+
faraday (~> 0.8)
|
32
|
+
faraday_middleware (0.8.8)
|
33
|
+
faraday (>= 0.7.4, < 0.9)
|
34
|
+
i18n (0.6.11)
|
35
|
+
json (1.8.1)
|
36
|
+
minitest (5.4.1)
|
37
|
+
multipart-post (1.2.0)
|
38
|
+
rack (1.5.2)
|
39
|
+
rack-cache (1.2)
|
40
|
+
rack (>= 0.4)
|
41
|
+
rake (10.3.2)
|
42
|
+
rspec (3.0.0)
|
43
|
+
rspec-core (~> 3.0.0)
|
44
|
+
rspec-expectations (~> 3.0.0)
|
45
|
+
rspec-mocks (~> 3.0.0)
|
46
|
+
rspec-core (3.0.4)
|
47
|
+
rspec-support (~> 3.0.0)
|
48
|
+
rspec-expectations (3.0.4)
|
49
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
50
|
+
rspec-support (~> 3.0.0)
|
51
|
+
rspec-mocks (3.0.4)
|
52
|
+
rspec-support (~> 3.0.0)
|
53
|
+
rspec-support (3.0.4)
|
54
|
+
safe_yaml (1.0.3)
|
55
|
+
thor (0.19.1)
|
56
|
+
thread_safe (0.3.4)
|
57
|
+
timecop (0.7.1)
|
58
|
+
tzinfo (1.2.2)
|
59
|
+
thread_safe (~> 0.1)
|
60
|
+
webmock (1.18.0)
|
61
|
+
addressable (>= 2.3.6)
|
62
|
+
crack (>= 0.3.2)
|
63
|
+
|
64
|
+
PLATFORMS
|
65
|
+
ruby
|
66
|
+
|
67
|
+
DEPENDENCIES
|
68
|
+
appraisal (~> 1.0.2)
|
69
|
+
awesome_print
|
70
|
+
faraday (~> 0.8.0)
|
71
|
+
faraday-http-cache (~> 0.4.2)
|
72
|
+
faraday_middleware (~> 0.8.0)
|
73
|
+
frenetic!
|
74
|
+
rack-cache (~> 1.2)
|
75
|
+
rspec (~> 3.0.0)
|
76
|
+
timecop (~> 0.7.1)
|
77
|
+
webmock (~> 1.18.0)
|
@@ -0,0 +1,77 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../
|
3
|
+
specs:
|
4
|
+
frenetic (0.0.20.alpha.6)
|
5
|
+
activesupport (>= 3)
|
6
|
+
addressable (~> 2.3.4)
|
7
|
+
faraday (>= 0.8)
|
8
|
+
faraday_middleware (>= 0.8)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
activesupport (4.1.5)
|
14
|
+
i18n (~> 0.6, >= 0.6.9)
|
15
|
+
json (~> 1.7, >= 1.7.7)
|
16
|
+
minitest (~> 5.1)
|
17
|
+
thread_safe (~> 0.1)
|
18
|
+
tzinfo (~> 1.1)
|
19
|
+
addressable (2.3.6)
|
20
|
+
appraisal (1.0.2)
|
21
|
+
bundler
|
22
|
+
rake
|
23
|
+
thor (>= 0.14.0)
|
24
|
+
awesome_print (1.2.0)
|
25
|
+
crack (0.4.2)
|
26
|
+
safe_yaml (~> 1.0.0)
|
27
|
+
diff-lcs (1.2.5)
|
28
|
+
faraday (0.9.0)
|
29
|
+
multipart-post (>= 1.2, < 3)
|
30
|
+
faraday-http-cache (0.4.2)
|
31
|
+
faraday (~> 0.8)
|
32
|
+
faraday_middleware (0.9.1)
|
33
|
+
faraday (>= 0.7.4, < 0.10)
|
34
|
+
i18n (0.6.11)
|
35
|
+
json (1.8.1)
|
36
|
+
minitest (5.4.1)
|
37
|
+
multipart-post (2.0.0)
|
38
|
+
rack (1.5.2)
|
39
|
+
rack-cache (1.2)
|
40
|
+
rack (>= 0.4)
|
41
|
+
rake (10.3.2)
|
42
|
+
rspec (3.0.0)
|
43
|
+
rspec-core (~> 3.0.0)
|
44
|
+
rspec-expectations (~> 3.0.0)
|
45
|
+
rspec-mocks (~> 3.0.0)
|
46
|
+
rspec-core (3.0.4)
|
47
|
+
rspec-support (~> 3.0.0)
|
48
|
+
rspec-expectations (3.0.4)
|
49
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
50
|
+
rspec-support (~> 3.0.0)
|
51
|
+
rspec-mocks (3.0.4)
|
52
|
+
rspec-support (~> 3.0.0)
|
53
|
+
rspec-support (3.0.4)
|
54
|
+
safe_yaml (1.0.3)
|
55
|
+
thor (0.19.1)
|
56
|
+
thread_safe (0.3.4)
|
57
|
+
timecop (0.7.1)
|
58
|
+
tzinfo (1.2.2)
|
59
|
+
thread_safe (~> 0.1)
|
60
|
+
webmock (1.18.0)
|
61
|
+
addressable (>= 2.3.6)
|
62
|
+
crack (>= 0.3.2)
|
63
|
+
|
64
|
+
PLATFORMS
|
65
|
+
ruby
|
66
|
+
|
67
|
+
DEPENDENCIES
|
68
|
+
appraisal (~> 1.0.2)
|
69
|
+
awesome_print
|
70
|
+
faraday (~> 0.9.0)
|
71
|
+
faraday-http-cache (~> 0.4.2)
|
72
|
+
faraday_middleware (~> 0.9.0)
|
73
|
+
frenetic!
|
74
|
+
rack-cache (~> 1.2)
|
75
|
+
rspec (~> 3.0.0)
|
76
|
+
timecop (~> 0.7.1)
|
77
|
+
webmock (~> 1.18.0)
|
data/lib/frenetic.rb
CHANGED
@@ -1,44 +1,69 @@
|
|
1
1
|
require 'socket'
|
2
2
|
require 'faraday'
|
3
3
|
require 'faraday_middleware'
|
4
|
+
require 'active_support/configurable'
|
5
|
+
require 'active_support/core_ext/hash/reverse_merge'
|
4
6
|
|
5
7
|
require 'frenetic/version'
|
6
|
-
require 'frenetic/
|
7
|
-
require 'frenetic/
|
8
|
+
require 'frenetic/errors'
|
9
|
+
require 'frenetic/briefly_memoizable'
|
10
|
+
require 'frenetic/connection'
|
8
11
|
require 'frenetic/middleware/hal_json'
|
9
12
|
require 'frenetic/resource'
|
10
13
|
require 'frenetic/resource_collection'
|
11
14
|
|
12
15
|
class Frenetic
|
13
16
|
extend Forwardable
|
14
|
-
include Configurable
|
17
|
+
include ActiveSupport::Configurable
|
15
18
|
include BrieflyMemoizable
|
16
19
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
config_accessor :adapter
|
21
|
+
config_accessor :api_token
|
22
|
+
config_accessor :cache
|
23
|
+
config_accessor :default_root_cache_age
|
24
|
+
config_accessor :headers
|
25
|
+
config_accessor :middleware
|
26
|
+
config_accessor :password
|
27
|
+
config_accessor :ssl
|
28
|
+
config_accessor :test_mode
|
29
|
+
config_accessor :url
|
30
|
+
config_accessor :username
|
31
|
+
|
32
|
+
def_delegators :connection, :delete, :get, :head, :options, :patch, :post, :put
|
33
|
+
|
34
|
+
# Can't explicitly use config_accessor because we need defaults and
|
35
|
+
# ActiveSupport < 4 does not support them
|
36
|
+
@@defaults = {
|
37
|
+
adapter: Faraday.default_adapter,
|
38
|
+
api_token: nil,
|
39
|
+
cache: false,
|
40
|
+
default_root_cache_age: nil,
|
41
|
+
headers: {
|
42
|
+
accept: 'application/hal+json',
|
43
|
+
user_agent: "Frenetic v#{Frenetic::VERSION}; #{Socket.gethostname}"
|
44
|
+
},
|
45
|
+
middleware: [],
|
46
|
+
password: nil,
|
47
|
+
ssl: { verify:true },
|
48
|
+
test_mode: false,
|
49
|
+
url: nil,
|
50
|
+
username: nil
|
51
|
+
}
|
52
|
+
self.config.merge!(@@defaults)
|
53
|
+
|
54
|
+
# PENDING: [ActiveSupport4] Remove merge with class defaults
|
55
|
+
def initialize(cfg = {})
|
56
|
+
self.config.merge!(cfg.reverse_merge(self.class.config))
|
57
|
+
yield self.config if block_given?
|
58
|
+
end
|
25
59
|
|
26
60
|
def connection
|
27
|
-
@connection ||=
|
28
|
-
|
29
|
-
|
30
|
-
Faraday.new( config ) do |builder|
|
31
|
-
configure_authentication builder
|
32
|
-
|
33
|
-
builder.response :hal_json
|
34
|
-
|
35
|
-
configure_caching builder
|
36
|
-
|
37
|
-
@builder_config.call( builder ) if @builder_config
|
61
|
+
@connection ||= Connection.new(config)
|
62
|
+
end
|
38
63
|
|
39
|
-
|
40
|
-
|
41
|
-
|
64
|
+
# PENDING: [ActiveSupport4] Use super.
|
65
|
+
def configure
|
66
|
+
yield(config).tap { reset_connection! }
|
42
67
|
end
|
43
68
|
|
44
69
|
# Since Frenetic needs to frequently refer to the API design, the result of
|
@@ -49,9 +74,8 @@ class Frenetic
|
|
49
74
|
#
|
50
75
|
# If no Cache-Control header is returned, then the results are not memoized.
|
51
76
|
def description
|
52
|
-
if response = get(
|
53
|
-
@description_age = cache_control_age(
|
54
|
-
|
77
|
+
if response = get(config.url.to_s) and response.success?
|
78
|
+
@description_age = cache_control_age(response.headers)
|
55
79
|
response.body
|
56
80
|
end
|
57
81
|
end
|
@@ -61,12 +85,15 @@ class Frenetic
|
|
61
85
|
description['_embedded']['schema']
|
62
86
|
end
|
63
87
|
|
88
|
+
def reset_connection!
|
89
|
+
@connection = nil
|
90
|
+
end
|
91
|
+
|
64
92
|
private
|
65
93
|
|
66
|
-
def cache_control_age(
|
94
|
+
def cache_control_age(headers)
|
67
95
|
if cache_age = headers['Cache-Control']
|
68
96
|
age = cache_age.match(%r{max-age=(?<max_age>\d+)})[:max_age]
|
69
|
-
|
70
97
|
Time.now + age.to_i
|
71
98
|
else
|
72
99
|
config.default_root_cache_age
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
# Memoizes method calls, but only for a specific period of time.
|
4
|
+
# Useful for supporting HTTP Cache-Control without an external caching layer
|
5
|
+
# like Rack::Cache
|
6
|
+
class Frenetic
|
7
|
+
module BrieflyMemoizable
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def briefly_memoize( symbol )
|
12
|
+
original_method = "_unmemoized_#{symbol}".to_sym
|
13
|
+
memoized_ivar = "@#{symbol}"
|
14
|
+
age_ivar = "@#{symbol}_age"
|
15
|
+
|
16
|
+
class_eval <<-EOS
|
17
|
+
if method_defined?(:#{original_method}) # if method_defined?(:_unmemoized_mime_type)
|
18
|
+
raise "Already memoized #{symbol}" # raise "Already memoized mime_type"
|
19
|
+
end # end
|
20
|
+
alias #{original_method} #{symbol} # alias _unmemoized_mime_type mime_type
|
21
|
+
|
22
|
+
def #{symbol}(*args) # def mime_type(*args)
|
23
|
+
#{memoized_ivar} = nil if #{age_ivar} && Time.now > #{age_ivar} # @mime_type = nil if @mime_type_age && Time.now > @mime_type_age
|
24
|
+
#{memoized_ivar} ||= #{original_method}(*args) # @mime_type ||= _unmemoized_mime_type(*args)
|
25
|
+
end # end
|
26
|
+
|
27
|
+
def reload_#{symbol}! # def reload_mime_type!
|
28
|
+
#{memoized_ivar} = nil # @mime_type = nil
|
29
|
+
end # end
|
30
|
+
EOS
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'active_support/concern'
|
2
|
-
|
2
|
+
|
3
|
+
require 'frenetic/hypermedia_link_set'
|
3
4
|
|
4
5
|
class Frenetic
|
5
6
|
module HalLinked
|
@@ -11,10 +12,8 @@ class Frenetic
|
|
11
12
|
|
12
13
|
def member_url( params = {} )
|
13
14
|
resource = @resource_type || self.class.to_s.demodulize.underscore
|
14
|
-
|
15
15
|
link = links[resource] || links['self'] or raise HypermediaError, %Q{No Hypermedia GET Url found for the resource "#{resource}"}
|
16
|
-
|
17
|
-
self.class.parse_link link, params
|
16
|
+
HypermediaLinkSet.new( link ).href params
|
18
17
|
end
|
19
18
|
|
20
19
|
module ClassMethods
|
@@ -24,42 +23,13 @@ class Frenetic
|
|
24
23
|
|
25
24
|
def member_url( params = {} )
|
26
25
|
link = links[namespace] or raise HypermediaError, %Q{No Hypermedia GET Url found for the resource "#{namespace}"}
|
27
|
-
|
28
|
-
parse_link link, params
|
26
|
+
HypermediaLinkSet.new( link ).href params
|
29
27
|
end
|
30
28
|
|
31
29
|
def collection_url
|
32
30
|
link = links[namespace.pluralize] or raise HypermediaError, %Q{No Hypermedia GET Url found for the resource "#{namespace.pluralize}"}
|
33
|
-
|
34
|
-
link['href']
|
35
|
-
end
|
36
|
-
|
37
|
-
def parse_link( link, params = {} )
|
38
|
-
if link['templated']
|
39
|
-
expand_link link, params
|
40
|
-
else
|
41
|
-
link['href']
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
def expand_link( link, params )
|
48
|
-
tmpl = Addressable::Template.new link['href']
|
49
|
-
|
50
|
-
if params && !params.is_a?(Hash)
|
51
|
-
params = infer_url_template_values tmpl, params
|
52
|
-
end
|
53
|
-
|
54
|
-
tmpl.expand( params ).to_s
|
31
|
+
HypermediaLinkSet.new( link ).href
|
55
32
|
end
|
56
|
-
|
57
|
-
def infer_url_template_values( tmpl, params )
|
58
|
-
key = tmpl.variables.first
|
59
|
-
|
60
|
-
{ key => params }
|
61
|
-
end
|
62
|
-
|
63
33
|
end
|
64
34
|
end
|
65
35
|
end
|