leadlight 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +5 -7
- data/README.md +82 -0
- data/default.gems +1 -0
- data/leadlight.gemspec +16 -7
- data/lib/leadlight.rb +18 -62
- data/lib/leadlight/basic_converter.rb +18 -0
- data/lib/leadlight/codec.rb +2 -0
- data/lib/leadlight/entity.rb +1 -0
- data/lib/leadlight/errors.rb +10 -2
- data/lib/leadlight/header_helpers.rb +11 -0
- data/lib/leadlight/hyperlinkable.rb +1 -1
- data/lib/leadlight/representation.rb +19 -1
- data/lib/leadlight/request.rb +44 -11
- data/lib/leadlight/service.rb +4 -9
- data/lib/leadlight/service_class_methods.rb +69 -0
- data/lib/leadlight/service_middleware.rb +2 -14
- data/lib/leadlight/tint.rb +6 -2
- data/lib/leadlight/tint_helper.rb +27 -4
- data/lib/leadlight/type_map.rb +101 -0
- data/spec/cassettes/Leadlight/authorized_GitHub_example/_user/has_the_expected_content.yml +8 -8
- data/spec/cassettes/Leadlight/authorized_GitHub_example/_user/indicates_the_expected_oath_scopes.yml +8 -8
- data/spec/cassettes/Leadlight/authorized_GitHub_example/adding_and_removing_team_members.yml +273 -284
- data/spec/cassettes/Leadlight/authorized_GitHub_example/{adding_and_removing_team_members/.yml → adding_and_removing_teams.yml} +57 -84
- data/spec/cassettes/Leadlight/authorized_GitHub_example/test_team/.yml +111 -117
- data/spec/cassettes/Leadlight/basic_GitHub_example/_root/.yml +58 -25
- data/spec/cassettes/Leadlight/basic_GitHub_example/_root/__location__/.yml +58 -25
- data/spec/cassettes/Leadlight/basic_GitHub_example/_root/should_be_a_204_no_content.yml +58 -25
- data/spec/cassettes/Leadlight/tinted_GitHub_example/_root/.yml +58 -25
- data/spec/cassettes/Leadlight/tinted_GitHub_example/_root/__location__/.yml +58 -25
- data/spec/cassettes/Leadlight/tinted_GitHub_example/_root/should_be_a_204_no_content.yml +58 -25
- data/spec/cassettes/Leadlight/tinted_GitHub_example/_user/has_the_expected_content.yml +122 -50
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/.yml +190 -77
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/should_be_able_to_follow_next_link.yml +260 -104
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/should_be_enumerable.yml +616 -212
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/should_be_enumerable_over_page_boundaries.yml +331 -131
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/should_have_next_and_last_links.yml +190 -77
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_link/exists.yml +58 -25
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_link/links_to_the_expected_URL.yml +58 -25
- data/spec/leadlight/hyperlinkable_spec.rb +3 -1
- data/spec/leadlight/link_template_spec.rb +2 -1
- data/spec/leadlight/request_spec.rb +44 -21
- data/spec/leadlight/service_middleware_spec.rb +9 -46
- data/spec/leadlight/service_spec.rb +30 -24
- data/spec/leadlight/tint_helper_spec.rb +67 -1
- data/spec/leadlight/tint_spec.rb +69 -0
- data/spec/leadlight/type_map_spec.rb +127 -0
- data/spec/leadlight_spec.rb +102 -51
- data/spec/support/credentials.rb +10 -2
- data/spec/support/vcr.rb +1 -1
- metadata +61 -32
- data/lib/leadlight/type.rb +0 -71
- data/spec/leadlight/type_spec.rb +0 -137
data/Gemfile.lock
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
leadlight (0.0.
|
4
|
+
leadlight (0.0.2)
|
5
|
+
addressable
|
5
6
|
faraday
|
6
7
|
fattr
|
7
8
|
hookr
|
@@ -20,7 +21,7 @@ GEM
|
|
20
21
|
faraday (0.7.5)
|
21
22
|
addressable (~> 2.2.6)
|
22
23
|
multipart-post (~> 1.1.3)
|
23
|
-
rack (
|
24
|
+
rack (>= 1.1.0, < 2)
|
24
25
|
fattr (2.2.0)
|
25
26
|
ffi (1.0.11)
|
26
27
|
guard (0.10.0)
|
@@ -33,7 +34,6 @@ GEM
|
|
33
34
|
guard (>= 0.10.0)
|
34
35
|
hookr (1.1.1)
|
35
36
|
fail-fast (= 1.0.0)
|
36
|
-
libnotify (0.7.1)
|
37
37
|
linecache19 (0.5.12)
|
38
38
|
ruby_core_source (>= 0.1.4)
|
39
39
|
link_header (0.0.5)
|
@@ -41,8 +41,7 @@ GEM
|
|
41
41
|
multi_json (1.0.4)
|
42
42
|
multipart-post (1.1.4)
|
43
43
|
rack (1.4.0)
|
44
|
-
|
45
|
-
ffi (>= 0.5.0)
|
44
|
+
rake (0.9.2.2)
|
46
45
|
rspec (2.7.0)
|
47
46
|
rspec-core (~> 2.7.0)
|
48
47
|
rspec-expectations (~> 2.7.0)
|
@@ -72,8 +71,7 @@ DEPENDENCIES
|
|
72
71
|
guard-bundler
|
73
72
|
guard-rspec
|
74
73
|
leadlight!
|
75
|
-
|
76
|
-
rb-inotify
|
74
|
+
rake
|
77
75
|
rspec
|
78
76
|
ruby-debug19
|
79
77
|
vcr (~> 2.0.0.rc1)
|
data/README.md
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
# Leadlight [![Build Status](https://secure.travis-ci.org/avdi/leadlight.png)](http://travis-ci.org/avdi/leadlight)
|
2
|
+
|
3
|
+
Rose colored stained glass windows for HTTP.
|
4
|
+
|
5
|
+
|
6
|
+
## Goals
|
7
|
+
|
8
|
+
### Progressive enhancement for HTTP APIs
|
9
|
+
|
10
|
+
Don't cover up the web; just fill in the gaps here and there. Make it easy to
|
11
|
+
add links and other affordances API publishers might have forgotten.
|
12
|
+
|
13
|
+
### Model RESTful APIs as a web of links
|
14
|
+
|
15
|
+
Don't try to make the web look like a database.
|
16
|
+
|
17
|
+
### Representations over resources
|
18
|
+
|
19
|
+
Resources are the server's job to worry about. The things we get back from a
|
20
|
+
server are representations. Take representations at face value and interpret
|
21
|
+
them sensibly, rather than trying to fit them into a client-side model of an
|
22
|
+
imaginary server-side object graph.
|
23
|
+
|
24
|
+
### Support current and emerging standards
|
25
|
+
|
26
|
+
Such as the [Link header][], [URI templates][], [PATCH][], [ETags][], and
|
27
|
+
[JSON-schema][].
|
28
|
+
|
29
|
+
### Sensible defaults
|
30
|
+
|
31
|
+
Always try to convert representations returned by the server into a form that is
|
32
|
+
useful to the programmer--whether that is a Hash parsed from JSON data, a
|
33
|
+
Nokogiri document, or a text string.
|
34
|
+
|
35
|
+
### Backend agnostic
|
36
|
+
|
37
|
+
Using the power of [Faraday][].
|
38
|
+
|
39
|
+
### Exception-free
|
40
|
+
|
41
|
+
Only raise exceptions in API calls which explicitly request them. Provide ample
|
42
|
+
information to explain the cause of a failure.
|
43
|
+
|
44
|
+
### Async-ready
|
45
|
+
|
46
|
+
Architected from the ground up with asynchrony in mind. It's easier to build a
|
47
|
+
synchronous API on top of an async one than vice-versa.
|
48
|
+
|
49
|
+
### Controlled abstraction leakage
|
50
|
+
|
51
|
+
All abstractions are leaky. Provide ample and convenient access points into the
|
52
|
+
guts of the request lifecycle for situations when the defaults are not
|
53
|
+
sufficient.
|
54
|
+
|
55
|
+
### Quality
|
56
|
+
|
57
|
+
Code quality is important. [Code Climate][] keeps a
|
58
|
+
[close eye on Leadlight][leadlight_climate] instilling confidence and showing
|
59
|
+
how any technical debt can be paid down.
|
60
|
+
|
61
|
+
|
62
|
+
[link header]: http://tools.ietf.org/html/draft-nottingham-http-link-header
|
63
|
+
[uri templates]: http://tools.ietf.org/html/draft-gregorio-uritemplate
|
64
|
+
[patch]: http://tools.ietf.org/html/rfc5789
|
65
|
+
[etags]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.19
|
66
|
+
[json-schema]: http://tools.ietf.org/html/draft-zyp-json-schema
|
67
|
+
[faraday]: https://github.com/technoweenie/faraday
|
68
|
+
[code climate]: https://codeclimate.com
|
69
|
+
[leadlight_climate]: https://codeclimate.com/github/avdi/leadlight
|
70
|
+
|
71
|
+
|
72
|
+
## Installation
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
gem 'leadlight'
|
76
|
+
```
|
77
|
+
|
78
|
+
## Usage
|
79
|
+
|
80
|
+
_See
|
81
|
+
[leadlight_spec.rb](https://github.com/avdi/leadlight/blob/master/spec/leadlight_spec.rb)
|
82
|
+
for now._
|
data/default.gems
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
bundler -v1.0.21
|
data/leadlight.gemspec
CHANGED
@@ -13,14 +13,14 @@ 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.
|
17
|
-
s.date = '2012-
|
16
|
+
s.version = '0.0.3'
|
17
|
+
s.date = '2012-02-05'
|
18
18
|
s.rubyforge_project = 'leadlight'
|
19
19
|
|
20
20
|
## Make sure your summary is short. The description may be as long
|
21
21
|
## as you like.
|
22
|
-
s.summary = "
|
23
|
-
s.description = "
|
22
|
+
s.summary = "Rose colored stained glass windows for HTTP."
|
23
|
+
s.description = "Rose colored stained glass windows for HTTP."
|
24
24
|
|
25
25
|
## List the primary authors. If there are a bunch of authors, it's probably
|
26
26
|
## better to set the email to an email list or something. If you don't have
|
@@ -41,6 +41,7 @@ Gem::Specification.new do |s|
|
|
41
41
|
## List your runtime dependencies here. Runtime dependencies are those
|
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
|
+
s.add_dependency 'addressable'
|
44
45
|
s.add_dependency 'faraday'
|
45
46
|
s.add_dependency 'fattr'
|
46
47
|
s.add_dependency 'link_header'
|
@@ -51,6 +52,7 @@ Gem::Specification.new do |s|
|
|
51
52
|
## List your development dependencies here. Development dependencies are
|
52
53
|
## those that are only needed during development
|
53
54
|
## s.add_development_dependency('DEVDEPNAME', [">= 1.1.0", "< 2.0.0"])
|
55
|
+
s.add_development_dependency 'rake'
|
54
56
|
s.add_development_dependency 'rspec'
|
55
57
|
s.add_development_dependency 'vcr', '~> 2.0.0.rc1'
|
56
58
|
s.add_development_dependency 'guard'
|
@@ -66,27 +68,33 @@ Gem::Specification.new do |s|
|
|
66
68
|
Gemfile
|
67
69
|
Gemfile.lock
|
68
70
|
Guardfile
|
71
|
+
README.md
|
69
72
|
Rakefile
|
73
|
+
default.gems
|
70
74
|
leadlight.gemspec
|
71
75
|
lib/leadlight.rb
|
76
|
+
lib/leadlight/basic_converter.rb
|
72
77
|
lib/leadlight/blank.rb
|
73
78
|
lib/leadlight/codec.rb
|
79
|
+
lib/leadlight/entity.rb
|
74
80
|
lib/leadlight/enumerable_representation.rb
|
75
81
|
lib/leadlight/errors.rb
|
82
|
+
lib/leadlight/header_helpers.rb
|
76
83
|
lib/leadlight/hyperlinkable.rb
|
77
84
|
lib/leadlight/link.rb
|
78
85
|
lib/leadlight/link_template.rb
|
79
86
|
lib/leadlight/representation.rb
|
80
87
|
lib/leadlight/request.rb
|
81
88
|
lib/leadlight/service.rb
|
89
|
+
lib/leadlight/service_class_methods.rb
|
82
90
|
lib/leadlight/service_middleware.rb
|
83
91
|
lib/leadlight/tint.rb
|
84
92
|
lib/leadlight/tint_helper.rb
|
85
|
-
lib/leadlight/
|
93
|
+
lib/leadlight/type_map.rb
|
86
94
|
spec/cassettes/Leadlight/authorized_GitHub_example/_user/has_the_expected_content.yml
|
87
95
|
spec/cassettes/Leadlight/authorized_GitHub_example/_user/indicates_the_expected_oath_scopes.yml
|
88
96
|
spec/cassettes/Leadlight/authorized_GitHub_example/adding_and_removing_team_members.yml
|
89
|
-
spec/cassettes/Leadlight/authorized_GitHub_example/
|
97
|
+
spec/cassettes/Leadlight/authorized_GitHub_example/adding_and_removing_teams.yml
|
90
98
|
spec/cassettes/Leadlight/authorized_GitHub_example/test_team/.yml
|
91
99
|
spec/cassettes/Leadlight/basic_GitHub_example/_root/.yml
|
92
100
|
spec/cassettes/Leadlight/basic_GitHub_example/_root/__location__/.yml
|
@@ -111,7 +119,8 @@ Gem::Specification.new do |s|
|
|
111
119
|
spec/leadlight/service_middleware_spec.rb
|
112
120
|
spec/leadlight/service_spec.rb
|
113
121
|
spec/leadlight/tint_helper_spec.rb
|
114
|
-
spec/leadlight/
|
122
|
+
spec/leadlight/tint_spec.rb
|
123
|
+
spec/leadlight/type_map_spec.rb
|
115
124
|
spec/leadlight_spec.rb
|
116
125
|
spec/spec_helper_lite.rb
|
117
126
|
spec/support/credentials.rb
|
data/lib/leadlight.rb
CHANGED
@@ -1,27 +1,37 @@
|
|
1
1
|
require 'faraday'
|
2
2
|
require 'fattr'
|
3
3
|
require 'logger'
|
4
|
+
require 'hookr'
|
4
5
|
require 'leadlight/errors'
|
5
6
|
require 'leadlight/link'
|
6
7
|
require 'leadlight/hyperlinkable'
|
7
8
|
require 'leadlight/service_middleware'
|
8
9
|
require 'leadlight/representation'
|
9
10
|
require 'leadlight/tint'
|
10
|
-
require 'leadlight/type'
|
11
11
|
require 'leadlight/service'
|
12
|
+
require 'leadlight/service_class_methods'
|
12
13
|
require 'leadlight/enumerable_representation'
|
14
|
+
require 'leadlight/basic_converter'
|
13
15
|
|
14
16
|
|
15
17
|
module Leadlight
|
16
18
|
|
17
|
-
VERSION = '0.0.
|
18
|
-
|
19
|
-
def self.build_service(target, &block)
|
20
|
-
target.
|
21
|
-
|
22
|
-
|
19
|
+
VERSION = '0.0.3'
|
20
|
+
|
21
|
+
def self.build_service(target=Class.new, &block)
|
22
|
+
target.tap do
|
23
|
+
target.module_eval do
|
24
|
+
extend ServiceClassMethods
|
25
|
+
include Service
|
26
|
+
include HookR::Hooks
|
27
|
+
extend SingleForwardable
|
28
|
+
|
29
|
+
request_events = request_class.hooks.map(&:name)
|
30
|
+
def_delegators :request_class, *request_events
|
31
|
+
define_hook :on_init, :service
|
32
|
+
end
|
33
|
+
target.module_eval(&block)
|
23
34
|
end
|
24
|
-
target.module_eval(&block)
|
25
35
|
end
|
26
36
|
|
27
37
|
def self.build_connection_common(&common_connection_stack)
|
@@ -34,59 +44,5 @@ module Leadlight
|
|
34
44
|
}
|
35
45
|
end
|
36
46
|
|
37
|
-
module ServiceClassMethods
|
38
|
-
fattr(:tints) { default_tints }
|
39
|
-
fattr(:types) { [] }
|
40
|
-
|
41
|
-
def url(new_url=:none)
|
42
|
-
if new_url == :none
|
43
|
-
@url ||= Addressable::URI.parse('http://example.com')
|
44
|
-
else
|
45
|
-
@url = Addressable::URI.parse(new_url)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def session(options={})
|
50
|
-
sessions[options]
|
51
|
-
end
|
52
|
-
|
53
|
-
def sessions
|
54
|
-
@sessions ||= Hash.new{|h,k|
|
55
|
-
h[k] = new(k)
|
56
|
-
}
|
57
|
-
end
|
58
|
-
|
59
|
-
def connection_stack
|
60
|
-
@connection_stack ||= ->(builder){}
|
61
|
-
end
|
62
|
-
|
63
|
-
def default_tints
|
64
|
-
[
|
65
|
-
EnumerableRepresentation::Tint
|
66
|
-
]
|
67
|
-
end
|
68
|
-
|
69
|
-
private
|
70
|
-
|
71
|
-
def tint(name, &block)
|
72
|
-
self.tints << Tint.new(name, &block)
|
73
|
-
end
|
74
|
-
|
75
|
-
def type(name, &block)
|
76
|
-
self.types << Type.new(name, self, &block)
|
77
|
-
end
|
78
|
-
|
79
|
-
def type_for_name(name)
|
80
|
-
raise_on_missing = -> do
|
81
|
-
raise KeyError, "Type not found: #{name}"
|
82
|
-
end
|
83
|
-
types.detect(raise_on_missing){|type| type.name.to_s == name.to_s}
|
84
|
-
end
|
85
|
-
|
86
|
-
def build_connection(&block)
|
87
|
-
@connection_stack = block
|
88
|
-
end
|
89
|
-
|
90
|
-
end
|
91
47
|
|
92
48
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Leadlight
|
2
|
+
module BasicConverter
|
3
|
+
fattr(:codec) { Codec.new }
|
4
|
+
|
5
|
+
def initialize(codec)
|
6
|
+
@codec = codec
|
7
|
+
end
|
8
|
+
|
9
|
+
def decode_with_type(content_type, entity_body, options={})
|
10
|
+
codec.decode(content_type, entity_body, options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def encode_with_type(content_type, object, options={})
|
14
|
+
body = codec.encode(content_type, object, options)
|
15
|
+
Entity.new(content_type, body)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/leadlight/codec.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
Entity ||= Struct.new(:content_type, :body)
|
data/lib/leadlight/errors.rb
CHANGED
@@ -1,14 +1,22 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
1
3
|
module Leadlight
|
2
4
|
class Error < StandardError; end
|
3
5
|
class CredentialsRequiredError < Error; end
|
4
6
|
class HttpError < Error
|
7
|
+
extend Forwardable
|
8
|
+
|
5
9
|
attr_reader :response
|
6
|
-
|
10
|
+
|
11
|
+
def_delegator :response, :status
|
12
|
+
|
13
|
+
def initialize(response, message=response.status.to_s)
|
7
14
|
@response = response
|
8
|
-
super(
|
15
|
+
super(message)
|
9
16
|
end
|
10
17
|
end
|
11
18
|
class ClientError < HttpError; end
|
12
19
|
class ResourceNotFound < ClientError; end
|
13
20
|
class ServerError < HttpError; end
|
21
|
+
class TypeError < Error; end
|
14
22
|
end
|
@@ -10,7 +10,7 @@ module Leadlight
|
|
10
10
|
module Hyperlinkable
|
11
11
|
def self.extended(representation)
|
12
12
|
super(representation)
|
13
|
-
representation.add_link(representation.
|
13
|
+
representation.add_link(representation.__location__,
|
14
14
|
'self', 'self', rev: 'self')
|
15
15
|
representation.add_links_from_headers
|
16
16
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'addressable/uri'
|
2
2
|
require 'leadlight/link'
|
3
|
+
require 'leadlight/errors'
|
3
4
|
|
4
5
|
module Leadlight
|
5
6
|
module Representation
|
6
7
|
attr_accessor :__service__
|
7
8
|
attr_accessor :__location__
|
8
9
|
attr_accessor :__response__
|
9
|
-
attr_accessor :__type__
|
10
10
|
|
11
11
|
def initialize_representation(service, location, response)
|
12
12
|
self.__service__ = service
|
@@ -21,6 +21,24 @@ module Leadlight
|
|
21
21
|
self
|
22
22
|
end
|
23
23
|
|
24
|
+
def exception(message=exception_message)
|
25
|
+
return super if defined?(super)
|
26
|
+
case __response__.status.to_i
|
27
|
+
when 404 then ResourceNotFound
|
28
|
+
when (400..499) then ClientError
|
29
|
+
when (500..599) then ServerError
|
30
|
+
end.new(__response__, exception_message)
|
31
|
+
end
|
32
|
+
|
33
|
+
def exception_message
|
34
|
+
http_status_message
|
35
|
+
end
|
36
|
+
|
37
|
+
def http_status_message
|
38
|
+
__response__.env.fetch(:response_headers).fetch('status'){
|
39
|
+
status.to_s
|
40
|
+
}
|
41
|
+
end
|
24
42
|
|
25
43
|
private
|
26
44
|
|
data/lib/leadlight/request.rb
CHANGED
@@ -1,35 +1,49 @@
|
|
1
1
|
require 'monitor'
|
2
2
|
require 'fattr'
|
3
|
+
require 'forwardable'
|
3
4
|
require 'hookr'
|
4
5
|
require 'leadlight/errors'
|
6
|
+
require 'leadlight/blank'
|
7
|
+
require 'leadlight/hyperlinkable'
|
8
|
+
require 'leadlight/representation'
|
9
|
+
require 'leadlight/type_map'
|
10
|
+
require 'leadlight/header_helpers'
|
5
11
|
|
6
12
|
module Leadlight
|
7
13
|
class Request
|
8
14
|
include HookR::Hooks
|
9
15
|
include MonitorMixin
|
16
|
+
extend Forwardable
|
17
|
+
include HeaderHelpers
|
10
18
|
|
11
19
|
fattr(:http_method)
|
12
20
|
fattr(:url)
|
13
21
|
fattr(:connection)
|
14
22
|
fattr(:body)
|
15
23
|
fattr(:params)
|
24
|
+
fattr(:service)
|
25
|
+
fattr(:codec)
|
26
|
+
fattr(:type_map) { service.type_map || TypeMap.new }
|
16
27
|
|
17
28
|
attr_reader :response
|
18
29
|
|
19
30
|
define_hook :on_prepare_request, :request
|
20
31
|
define_hook :on_complete, :response
|
21
32
|
|
22
|
-
|
33
|
+
def_delegator :service, :service_options
|
34
|
+
|
35
|
+
def initialize(service, connection, url, method, params={}, body=nil)
|
23
36
|
self.connection = connection
|
24
37
|
self.url = url
|
25
38
|
self.http_method = method
|
26
39
|
self.body = body
|
27
40
|
self.params = params
|
41
|
+
self.service = service
|
28
42
|
@completed = new_cond
|
29
43
|
@state = :initialized
|
30
44
|
@env = nil
|
31
45
|
@response = nil
|
32
|
-
super
|
46
|
+
super()
|
33
47
|
end
|
34
48
|
|
35
49
|
def completed?
|
@@ -37,11 +51,16 @@ module Leadlight
|
|
37
51
|
end
|
38
52
|
|
39
53
|
def submit
|
40
|
-
|
54
|
+
entity = type_map.to_entity_body(body)
|
55
|
+
entity_body = entity.body
|
56
|
+
content_type = entity.content_type
|
57
|
+
connection.run_request(http_method, url, entity_body, {}) do |request|
|
58
|
+
request.headers['Content-Type'] = content_type if content_type
|
59
|
+
request.options[:leadlight_request] = self
|
41
60
|
execute_hook(:on_prepare_request, request)
|
42
61
|
end.on_complete do |env|
|
43
62
|
synchronize do
|
44
|
-
@response =
|
63
|
+
@response = env.fetch(:response)
|
45
64
|
execute_hook :on_complete, @response
|
46
65
|
@env = env
|
47
66
|
@state = :completed
|
@@ -66,13 +85,8 @@ module Leadlight
|
|
66
85
|
|
67
86
|
def raise_on_error
|
68
87
|
on_or_after_complete do |response|
|
69
|
-
|
70
|
-
|
71
|
-
raise ResourceNotFound, response
|
72
|
-
when (400..499)
|
73
|
-
raise ClientError, response
|
74
|
-
when (500..599)
|
75
|
-
raise ServerError, response
|
88
|
+
unless response.success?
|
89
|
+
raise response.env.fetch(:leadlight_representation)
|
76
90
|
end
|
77
91
|
end
|
78
92
|
self
|
@@ -87,5 +101,24 @@ module Leadlight
|
|
87
101
|
end
|
88
102
|
end
|
89
103
|
end
|
104
|
+
|
105
|
+
def represent(env)
|
106
|
+
content_type = env[:response_headers]['Content-Type']
|
107
|
+
content_type = clean_content_type(content_type)
|
108
|
+
representation = type_map.to_native(content_type, env[:body])
|
109
|
+
location = Addressable::URI.parse(env[:response_headers].fetch('location'){ env[:url] })
|
110
|
+
representation.
|
111
|
+
extend(Representation).
|
112
|
+
initialize_representation(env[:leadlight_service], location, env[:response]).
|
113
|
+
extend(Hyperlinkable).
|
114
|
+
apply_all_tints
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
def representation
|
120
|
+
raise "No representation until complete" unless completed?
|
121
|
+
@env.fetch(:leadlight_representation)
|
122
|
+
end
|
90
123
|
end
|
91
124
|
end
|