leadlight 0.0.5 → 0.0.6

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.
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