leadlight 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/Gemfile.lock +20 -18
  2. data/default.gems +1 -1
  3. data/leadlight.gemspec +24 -4
  4. data/lib/leadlight.rb +4 -5
  5. data/lib/leadlight/connection_builder.rb +29 -0
  6. data/lib/leadlight/errors.rb +11 -5
  7. data/lib/leadlight/hyperlinkable.rb +31 -10
  8. data/lib/leadlight/lib_ext.rb +3 -0
  9. data/lib/leadlight/lib_ext/faraday/README +6 -0
  10. data/lib/leadlight/lib_ext/faraday/adapter.rb +7 -0
  11. data/lib/leadlight/lib_ext/faraday/builder.rb +47 -0
  12. data/lib/leadlight/lib_ext/faraday/connection.rb +40 -0
  13. data/lib/leadlight/lib_ext/faraday/middleware.rb +7 -0
  14. data/lib/leadlight/link.rb +91 -4
  15. data/lib/leadlight/link_template.rb +13 -5
  16. data/lib/leadlight/null_link.rb +21 -0
  17. data/lib/leadlight/param_hash.rb +42 -0
  18. data/lib/leadlight/representation.rb +23 -3
  19. data/lib/leadlight/request.rb +42 -10
  20. data/lib/leadlight/service.rb +11 -9
  21. data/lib/leadlight/service_class_methods.rb +11 -3
  22. data/lib/leadlight/tint_helper.rb +32 -2
  23. data/spec/cassettes/Leadlight/authorized_GitHub_example/_user/has_the_expected_content.yml +72 -54
  24. data/spec/cassettes/Leadlight/authorized_GitHub_example/_user/indicates_the_expected_oath_scopes.yml +73 -55
  25. data/spec/cassettes/Leadlight/authorized_GitHub_example/adding_and_removing_team_members.yml +353 -265
  26. data/spec/cassettes/Leadlight/authorized_GitHub_example/adding_and_removing_teams.yml +75 -175
  27. data/spec/cassettes/Leadlight/authorized_GitHub_example/team_list/should_have_a_link_back_to_the_org.yml +196 -0
  28. data/spec/cassettes/Leadlight/authorized_GitHub_example/test_team/.yml +152 -108
  29. data/spec/cassettes/Leadlight/authorized_GitHub_example/test_team/has_a_root_link.yml +197 -0
  30. data/spec/cassettes/Leadlight/basic_GitHub_example/_root/.yml +15 -43
  31. data/spec/cassettes/Leadlight/basic_GitHub_example/_root/__location__/.yml +15 -43
  32. data/spec/cassettes/Leadlight/basic_GitHub_example/_root/should_be_a_204_no_content.yml +15 -43
  33. data/spec/cassettes/Leadlight/tinted_GitHub_example/_root/.yml +15 -43
  34. data/spec/cassettes/Leadlight/tinted_GitHub_example/_root/__location__/.yml +15 -43
  35. data/spec/cassettes/Leadlight/tinted_GitHub_example/_root/should_be_a_204_no_content.yml +15 -43
  36. data/spec/cassettes/Leadlight/tinted_GitHub_example/_user/has_the_expected_content.yml +35 -90
  37. data/spec/cassettes/Leadlight/tinted_GitHub_example/bad_links/enables_custom_error_matching.yml +25 -17
  38. data/spec/cassettes/Leadlight/tinted_GitHub_example/bad_links/should_raise_ResourceNotFound.yml +26 -90
  39. data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/.yml +57 -140
  40. data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/should_be_able_to_follow_next_link.yml +79 -192
  41. data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/should_be_enumerable.yml +279 -350
  42. data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/should_be_enumerable_over_page_boundaries.yml +98 -243
  43. data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/should_have_next_and_last_links.yml +59 -142
  44. data/spec/cassettes/Leadlight/tinted_GitHub_example/user_link/exists.yml +15 -43
  45. data/spec/cassettes/Leadlight/tinted_GitHub_example/user_link/links_to_the_expected_URL.yml +15 -43
  46. data/spec/leadlight/hyperlinkable_spec.rb +50 -4
  47. data/spec/leadlight/link_spec.rb +70 -10
  48. data/spec/leadlight/link_template_spec.rb +20 -4
  49. data/spec/leadlight/null_link_spec.rb +14 -0
  50. data/spec/leadlight/param_hash_spec.rb +26 -0
  51. data/spec/leadlight/representation_spec.rb +36 -4
  52. data/spec/leadlight/request_spec.rb +39 -22
  53. data/spec/leadlight/service_spec.rb +14 -13
  54. data/spec/leadlight/tint_helper_spec.rb +36 -2
  55. data/spec/leadlight_spec.rb +31 -17
  56. data/spec/support/link_matchers.rb +59 -0
  57. data/spec/support/misc.rb +9 -0
  58. metadata +49 -34
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- leadlight (0.0.5)
4
+ leadlight (0.0.6)
5
5
  addressable
6
- faraday
6
+ faraday (= 0.8.1)
7
7
  fattr
8
8
  hookr
9
9
  link_header
@@ -13,15 +13,13 @@ PATH
13
13
  GEM
14
14
  remote: http://rubygems.org/
15
15
  specs:
16
- addressable (2.2.6)
16
+ addressable (2.3.2)
17
17
  archive-tar-minitar (0.5.2)
18
18
  columnize (0.3.6)
19
19
  diff-lcs (1.1.3)
20
20
  fail-fast (1.0.0)
21
- faraday (0.7.6)
22
- addressable (~> 2.2)
21
+ faraday (0.8.1)
23
22
  multipart-post (~> 1.1)
24
- rack (~> 1.1)
25
23
  fattr (2.2.1)
26
24
  ffi (1.0.11)
27
25
  guard (1.0.0)
@@ -34,22 +32,24 @@ GEM
34
32
  guard (>= 0.10.0)
35
33
  hookr (1.1.1)
36
34
  fail-fast (= 1.0.0)
35
+ libnotify (0.7.2)
37
36
  linecache19 (0.5.12)
38
37
  ruby_core_source (>= 0.1.4)
39
38
  link_header (0.0.5)
40
- mime-types (1.17.2)
39
+ mime-types (1.19)
41
40
  multi_json (1.0.4)
42
41
  multipart-post (1.1.5)
43
- rack (1.4.1)
44
42
  rake (0.9.2.2)
45
- rspec (2.8.0)
46
- rspec-core (~> 2.8.0)
47
- rspec-expectations (~> 2.8.0)
48
- rspec-mocks (~> 2.8.0)
49
- rspec-core (2.8.0)
50
- rspec-expectations (2.8.0)
51
- diff-lcs (~> 1.1.2)
52
- rspec-mocks (2.8.0)
43
+ rb-inotify (0.8.8)
44
+ ffi (>= 0.5.0)
45
+ rspec (2.11.0)
46
+ rspec-core (~> 2.11.0)
47
+ rspec-expectations (~> 2.11.0)
48
+ rspec-mocks (~> 2.11.0)
49
+ rspec-core (2.11.1)
50
+ rspec-expectations (2.11.2)
51
+ diff-lcs (~> 1.1.3)
52
+ rspec-mocks (2.11.1)
53
53
  ruby-debug-base19 (0.11.25)
54
54
  columnize (>= 0.3.1)
55
55
  linecache19 (>= 0.5.11)
@@ -61,7 +61,7 @@ GEM
61
61
  ruby_core_source (0.1.5)
62
62
  archive-tar-minitar (>= 0.5.2)
63
63
  thor (0.14.6)
64
- vcr (2.0.0.rc1)
64
+ vcr (2.2.4)
65
65
 
66
66
  PLATFORMS
67
67
  ruby
@@ -71,7 +71,9 @@ DEPENDENCIES
71
71
  guard-bundler
72
72
  guard-rspec
73
73
  leadlight!
74
+ libnotify
74
75
  rake
76
+ rb-inotify
75
77
  rspec
76
78
  ruby-debug19
77
- vcr (~> 2.0.0.rc1)
79
+ vcr (~> 2.0)
@@ -1 +1 @@
1
- bundler -v1.0.21
1
+ bundler -v1.1.3
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
13
13
  ## If your rubyforge_project name is different, then edit it and comment out
14
14
  ## the sub! line in the Rakefile
15
15
  s.name = 'leadlight'
16
- s.version = '0.0.5'
17
- s.date = '2012-02-15'
16
+ s.version = '0.0.6'
17
+ s.date = '2012-08-01'
18
18
  s.rubyforge_project = 'leadlight'
19
19
 
20
20
  ## Make sure your summary is short. The description may be as long
@@ -42,7 +42,12 @@ Gem::Specification.new do |s|
42
42
  ## that are needed for an end user to actually USE your code.
43
43
  ## s.add_dependency('DEPNAME', [">= 1.1.0", "< 2.0.0"])
44
44
  s.add_dependency 'addressable'
45
- s.add_dependency 'faraday'
45
+
46
+ # This dependency will have to stay fixed until the adapter API
47
+ # changes in lib_ext (or something like them) get rolled into
48
+ # Faraday
49
+ s.add_dependency 'faraday', '= 0.8.1'
50
+
46
51
  s.add_dependency 'fattr'
47
52
  s.add_dependency 'link_header'
48
53
  s.add_dependency 'multi_json', '~> 1.0.4'
@@ -54,7 +59,7 @@ Gem::Specification.new do |s|
54
59
  ## s.add_development_dependency('DEVDEPNAME', [">= 1.1.0", "< 2.0.0"])
55
60
  s.add_development_dependency 'rake'
56
61
  s.add_development_dependency 'rspec'
57
- s.add_development_dependency 'vcr', '~> 2.0.0.rc1'
62
+ s.add_development_dependency 'vcr', '~> 2.0'
58
63
  s.add_development_dependency 'guard'
59
64
  s.add_development_dependency 'guard-rspec'
60
65
  s.add_development_dependency 'guard-bundler'
@@ -76,13 +81,22 @@ Gem::Specification.new do |s|
76
81
  lib/leadlight/basic_converter.rb
77
82
  lib/leadlight/blank.rb
78
83
  lib/leadlight/codec.rb
84
+ lib/leadlight/connection_builder.rb
79
85
  lib/leadlight/entity.rb
80
86
  lib/leadlight/enumerable_representation.rb
81
87
  lib/leadlight/errors.rb
82
88
  lib/leadlight/header_helpers.rb
83
89
  lib/leadlight/hyperlinkable.rb
90
+ lib/leadlight/lib_ext.rb
91
+ lib/leadlight/lib_ext/faraday/README
92
+ lib/leadlight/lib_ext/faraday/adapter.rb
93
+ lib/leadlight/lib_ext/faraday/builder.rb
94
+ lib/leadlight/lib_ext/faraday/connection.rb
95
+ lib/leadlight/lib_ext/faraday/middleware.rb
84
96
  lib/leadlight/link.rb
85
97
  lib/leadlight/link_template.rb
98
+ lib/leadlight/null_link.rb
99
+ lib/leadlight/param_hash.rb
86
100
  lib/leadlight/representation.rb
87
101
  lib/leadlight/request.rb
88
102
  lib/leadlight/service.rb
@@ -95,7 +109,9 @@ Gem::Specification.new do |s|
95
109
  spec/cassettes/Leadlight/authorized_GitHub_example/_user/indicates_the_expected_oath_scopes.yml
96
110
  spec/cassettes/Leadlight/authorized_GitHub_example/adding_and_removing_team_members.yml
97
111
  spec/cassettes/Leadlight/authorized_GitHub_example/adding_and_removing_teams.yml
112
+ spec/cassettes/Leadlight/authorized_GitHub_example/team_list/should_have_a_link_back_to_the_org.yml
98
113
  spec/cassettes/Leadlight/authorized_GitHub_example/test_team/.yml
114
+ spec/cassettes/Leadlight/authorized_GitHub_example/test_team/has_a_root_link.yml
99
115
  spec/cassettes/Leadlight/basic_GitHub_example/_root/.yml
100
116
  spec/cassettes/Leadlight/basic_GitHub_example/_root/__location__/.yml
101
117
  spec/cassettes/Leadlight/basic_GitHub_example/_root/should_be_a_204_no_content.yml
@@ -116,6 +132,8 @@ Gem::Specification.new do |s|
116
132
  spec/leadlight/hyperlinkable_spec.rb
117
133
  spec/leadlight/link_spec.rb
118
134
  spec/leadlight/link_template_spec.rb
135
+ spec/leadlight/null_link_spec.rb
136
+ spec/leadlight/param_hash_spec.rb
119
137
  spec/leadlight/representation_spec.rb
120
138
  spec/leadlight/request_spec.rb
121
139
  spec/leadlight/service_middleware_spec.rb
@@ -126,6 +144,8 @@ Gem::Specification.new do |s|
126
144
  spec/leadlight_spec.rb
127
145
  spec/spec_helper_lite.rb
128
146
  spec/support/credentials.rb
147
+ spec/support/link_matchers.rb
148
+ spec/support/misc.rb
129
149
  spec/support/vcr.rb
130
150
  ]
131
151
  # = MANIFEST =
@@ -2,6 +2,7 @@ require 'faraday'
2
2
  require 'fattr'
3
3
  require 'logger'
4
4
  require 'hookr'
5
+ require 'leadlight/lib_ext'
5
6
  require 'leadlight/errors'
6
7
  require 'leadlight/link'
7
8
  require 'leadlight/hyperlinkable'
@@ -16,7 +17,7 @@ require 'leadlight/basic_converter'
16
17
 
17
18
  module Leadlight
18
19
 
19
- VERSION = '0.0.5'
20
+ VERSION = '0.0.6'
20
21
 
21
22
  def self.build_service(target=Class.new, &block)
22
23
  target.tap do
@@ -25,7 +26,7 @@ module Leadlight
25
26
  include Service
26
27
  include HookR::Hooks
27
28
  extend SingleForwardable
28
-
29
+
29
30
  request_events = request_class.hooks.map(&:name)
30
31
  def_delegators :request_class, *request_events
31
32
  define_hook :on_init, :service
@@ -39,9 +40,7 @@ module Leadlight
39
40
  end
40
41
 
41
42
  def self.common_connection_stack
42
- @common_connection_stack ||= ->(builder) {
43
- builder.adapter :net_http
44
- }
43
+ @common_connection_stack ||= ->(builder) {}
45
44
  end
46
45
 
47
46
 
@@ -0,0 +1,29 @@
1
+ require 'fattr'
2
+ require 'forwardable'
3
+
4
+ module Leadlight
5
+ class ConnectionBuilder
6
+ extend Forwardable
7
+
8
+ fattr(:url)
9
+ fattr(:service)
10
+ fattr(:common_stack)
11
+ fattr(:adapter)
12
+
13
+ def_delegators :service, :connection_stack, :logger
14
+
15
+ def initialize
16
+ yield self if block_given?
17
+ end
18
+
19
+ def call
20
+ Faraday.new(url: url.to_s) do |connection|
21
+ connection.use Leadlight::ServiceMiddleware, service: service
22
+ connection.use Faraday::Response::Logger, logger
23
+ service.instance_exec(connection, &connection_stack)
24
+ service.instance_exec(connection, &common_stack)
25
+ connection.adapter = adapter
26
+ end
27
+ end
28
+ end
29
+ end
@@ -6,13 +6,19 @@ module Leadlight
6
6
  class HttpError < Error
7
7
  extend Forwardable
8
8
 
9
- attr_reader :response
9
+ attr_reader :request
10
10
 
11
- def_delegator :response, :status
11
+ def_delegators :response, :status, :response
12
12
 
13
- def initialize(response, message=response.status.to_s)
14
- @response = response
15
- super(message)
13
+ def initialize(request, message=response.status.to_s)
14
+ @request = request
15
+ super(amplify_message(message))
16
+ end
17
+
18
+ private
19
+
20
+ def amplify_message(message)
21
+ "#{message} (#{request.http_method.upcase} #{request.location})"
16
22
  end
17
23
  end
18
24
  class ClientError < HttpError; end
@@ -23,18 +23,25 @@ module Leadlight
23
23
  end
24
24
  end
25
25
 
26
- def link(key, &fallback)
27
- result = links.at(key, &fallback)
26
+ def link(key, *expand_args, &fallback)
27
+ link = links.at(key, &fallback)
28
+ link && link.expand(*expand_args)
28
29
  end
29
30
 
30
31
  def add_link(url, rel=nil, title=rel, options={})
31
- link = Link.new(__service__, url, rel, title, options)
32
+ absolute_url = base_url + url
33
+ template = LinkTemplate.new(__service__, absolute_url, rel,
34
+ title, options)
35
+ link = template.expand(captures_for_variables(__captures__,
36
+ template.variables))
32
37
  define_link_helper(rel) if rel
33
38
  links << link
34
39
  end
35
40
 
36
41
  def add_link_template(template, rel=nil, title=rel, options={})
37
- link = LinkTemplate.new(__service__, template, rel, title, options)
42
+ absolute_url = base_url + template
43
+ link = LinkTemplate.new(__service__, absolute_url.to_s, rel,
44
+ title, options)
38
45
  define_link_helper(rel) if rel
39
46
  links << link
40
47
  end
@@ -46,10 +53,10 @@ module Leadlight
46
53
  yield.each do |link_attributes|
47
54
  attributes = default_link_attributes.merge(link_attributes)
48
55
  define_link_set_helper(rel, helper_name) if helper_name
49
- links << Link.new(__service__,
50
- attributes[:href],
51
- attributes[:rel],
52
- attributes[:title],
56
+ links << Link.new(__service__,
57
+ attributes[:href],
58
+ attributes[:rel],
59
+ attributes[:title],
53
60
  attributes)
54
61
  end
55
62
  end
@@ -69,7 +76,7 @@ module Leadlight
69
76
  include Enumerable
70
77
  fattr(:links) { Set.new }
71
78
 
72
- def_delegators :links, :<<, :push, :size, :length, :empty?, :each,
79
+ def_delegators :links, :<<, :push, :size, :length, :empty?, :each,
73
80
  :initialize
74
81
 
75
82
  # Match links on rel or title
@@ -87,7 +94,7 @@ module Leadlight
87
94
 
88
95
  def link_matcher(key)
89
96
  ->(link) {
90
- key === link.rel ||
97
+ key === link.rel ||
91
98
  key === link.title ||
92
99
  link.aliases.any?{|a| key === a}
93
100
  }
@@ -122,5 +129,19 @@ module Leadlight
122
129
  end
123
130
  end
124
131
  end
132
+
133
+ def captures_for_variables(captures, variables)
134
+ variables.each_with_object({}) do |key, h|
135
+ h[key] = captures[key] if captures[key]
136
+ end
137
+ end
138
+
139
+ def base_url
140
+ loc = __location__.to_s
141
+ unless loc[-1] == "/"
142
+ loc = loc + "/"
143
+ end
144
+ Addressable::URI.parse(loc)
145
+ end
125
146
  end
126
147
  end
@@ -0,0 +1,3 @@
1
+ Dir.glob(File.expand_path("../lib_ext/**/*.rb", __FILE__)).each do |file|
2
+ require file
3
+ end
@@ -0,0 +1,6 @@
1
+ This directory contains monkeypatches to the Faraday library, on which
2
+ Leadlight is based.
3
+
4
+ I feel really bad for doing this, and I fully intend to work with
5
+ Mislav to come up with some mutually-agreeable changes to the Faraday
6
+ API which will eliminate the need for this directory to exist. This is strictly an interim measure.
@@ -0,0 +1,7 @@
1
+ module Faraday
2
+ class Adapter < Middleware
3
+ def self.adapter?
4
+ true
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,47 @@
1
+ module Faraday
2
+ class Builder
3
+ class Handler
4
+ attr_reader :args
5
+
6
+ def adapter?
7
+ klass.respond_to?(:adapter?) && klass.adapter?
8
+ end
9
+
10
+ end
11
+
12
+ def build(options = {})
13
+ raise_if_locked
14
+ clear unless options[:keep]
15
+ yield self if block_given?
16
+ end
17
+
18
+ def clear
19
+ @handlers.clear
20
+ end
21
+
22
+ def adapter(key=nil, *args, &block)
23
+ if [key, *args, block].none?
24
+ find_adapter
25
+ else
26
+ use_symbol(Faraday::Adapter, key, *args, &block)
27
+ end
28
+ end
29
+
30
+ def has_adapter?
31
+ !!find_adapter
32
+ end
33
+
34
+ def adapter=(adapter_args)
35
+ clear_adapters
36
+ adapter(*adapter_args)
37
+ end
38
+
39
+ def find_adapter
40
+ @handlers.detect{|h| h.adapter?}
41
+ end
42
+
43
+ def clear_adapters
44
+ @handlers.delete_if{|h| h.adapter?}
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,40 @@
1
+ module Faraday
2
+ class Connection
3
+ def initialize(url = nil, options = {})
4
+ if url.is_a?(Hash)
5
+ options = url
6
+ url = options[:url]
7
+ end
8
+ @headers = Utils::Headers.new
9
+ @params = Utils::ParamsHash.new
10
+ @options = options[:request] || {}
11
+ @ssl = options[:ssl] || {}
12
+ adapter = options[:adapter]
13
+
14
+ @parallel_manager = nil
15
+ @default_parallel_manager = options[:parallel_manager]
16
+
17
+ @builder = options[:builder] || begin
18
+ # pass an empty block to Builder so it doesn't assume default middleware
19
+ block = block_given?? Proc.new {|b| } : nil
20
+ Builder.new(&block)
21
+ end
22
+
23
+ self.url_prefix = url || 'http:/'
24
+
25
+ @params.update options[:params] if options[:params]
26
+ @headers.update options[:headers] if options[:headers]
27
+
28
+ @proxy = nil
29
+ proxy(options.fetch(:proxy) { ENV['http_proxy'] })
30
+
31
+ yield self if block_given?
32
+
33
+ if adapter
34
+ self.adapter = adapter
35
+ end
36
+ end
37
+
38
+ def_delegators :builder, :adapter=
39
+ end
40
+ end