elevate 0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/.rvmrc +5 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +41 -0
- data/Guardfile +9 -0
- data/LICENSE +7 -0
- data/README.md +179 -0
- data/Rakefile +20 -0
- data/app/app_delegate.rb +5 -0
- data/elevate.gemspec +21 -0
- data/lib/elevate.rb +11 -0
- data/lib/elevate/api.rb +33 -0
- data/lib/elevate/callback.rb +13 -0
- data/lib/elevate/dispatcher.rb +53 -0
- data/lib/elevate/dsl.rb +18 -0
- data/lib/elevate/http/base64.rb +9 -0
- data/lib/elevate/http/http_client.rb +100 -0
- data/lib/elevate/http/request.rb +95 -0
- data/lib/elevate/http/response.rb +22 -0
- data/lib/elevate/http/uri.rb +19 -0
- data/lib/elevate/io_coordinator.rb +69 -0
- data/lib/elevate/operation.rb +74 -0
- data/lib/elevate/promise.rb +27 -0
- data/lib/elevate/version.rb +3 -0
- data/spec/api_spec.rb +23 -0
- data/spec/callback_spec.rb +12 -0
- data/spec/dispatcher_spec.rb +40 -0
- data/spec/dsl_spec.rb +21 -0
- data/spec/helpers/target.rb +23 -0
- data/spec/http/http_client_spec.rb +40 -0
- data/spec/http/http_request_spec.rb +103 -0
- data/spec/io_coordinator_spec.rb +44 -0
- data/spec/operation_spec.rb +133 -0
- metadata +157 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
describe Elevate::Dispatcher do
|
2
|
+
DELAY = 0.2
|
3
|
+
|
4
|
+
before do
|
5
|
+
@dispatcher = Elevate::Dispatcher.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "#on_started=" do
|
9
|
+
before do
|
10
|
+
@dispatcher.on_started = lambda { @thread = NSThread.currentThread }
|
11
|
+
end
|
12
|
+
|
13
|
+
after do
|
14
|
+
@thread = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "invokes the callback on the main thread" do
|
18
|
+
wait DELAY do
|
19
|
+
@thread.should == NSThread.currentThread
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "does not invoke the callback immediately" do
|
24
|
+
@thread.should.be.nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#on_finished=" do
|
29
|
+
before do
|
30
|
+
@dispatcher.on_finished = lambda { @thread = NSThread.currentThread }
|
31
|
+
@dispatcher.invoke_finished_callback()
|
32
|
+
end
|
33
|
+
|
34
|
+
it "invokes the callback on the main thread" do
|
35
|
+
wait DELAY do
|
36
|
+
@thread.should == NSThread.currentThread
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/spec/dsl_spec.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
describe Elevate::DSL do
|
2
|
+
describe "#on_started" do
|
3
|
+
it "stores the provided block" do
|
4
|
+
i = Elevate::DSL.new do
|
5
|
+
on_started { |operation| puts 'hi' }
|
6
|
+
end
|
7
|
+
|
8
|
+
i.started_callback.should.not.be.nil
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#on_completed" do
|
13
|
+
it "stores the passed block" do
|
14
|
+
i = Elevate::DSL.new do
|
15
|
+
on_completed { |o| puts 'hi' }
|
16
|
+
end
|
17
|
+
|
18
|
+
i.finished_callback.should.not.be.nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Target
|
2
|
+
attr_reader :called
|
3
|
+
attr_reader :io_coordinator
|
4
|
+
attr_accessor :exception
|
5
|
+
attr_accessor :result
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@called = 0
|
9
|
+
@result = true
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute
|
13
|
+
@io_coordinator = Thread.current[:io_coordinator]
|
14
|
+
|
15
|
+
@called += 1
|
16
|
+
|
17
|
+
if @exception
|
18
|
+
raise @exception
|
19
|
+
end
|
20
|
+
|
21
|
+
@result
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
describe Elevate::HTTP::HTTPClient do
|
2
|
+
extend WebStub::SpecHelpers
|
3
|
+
|
4
|
+
before do
|
5
|
+
disable_network_access!
|
6
|
+
|
7
|
+
@base_url = "http://www.example.com"
|
8
|
+
@path = "/resource/action"
|
9
|
+
@url = @base_url + @path
|
10
|
+
|
11
|
+
@client = Elevate::HTTP::HTTPClient.new(@base_url)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "issues requests to the complete URL" do
|
15
|
+
stub_request(:get, @url).to_return(status_code: 201)
|
16
|
+
|
17
|
+
@client.get(@path).status_code.should == 201
|
18
|
+
end
|
19
|
+
|
20
|
+
it "appends query parameters to the URL" do
|
21
|
+
stub_request(:get, @url + "?q=help&page=2").to_return(json: { result: 0 })
|
22
|
+
|
23
|
+
@client.get(@path, q: "help", page: 2).body.should == { "result" => 0 }
|
24
|
+
end
|
25
|
+
|
26
|
+
it "decodes JSON responses" do
|
27
|
+
result = { "int" => 42, "string" => "hi", "dict" => { "boolean" => true }, "array" => [1,2,3] }
|
28
|
+
stub_request(:get, @url).to_return(json: result)
|
29
|
+
|
30
|
+
@client.get(@path).body.should == result
|
31
|
+
end
|
32
|
+
|
33
|
+
it "encodes JSON bodies" do
|
34
|
+
stub_request(:post, @url).
|
35
|
+
with(json: { string: "hello", array: [1,2,3] }).
|
36
|
+
to_return(json: { result: true })
|
37
|
+
|
38
|
+
@client.post(@path, { string: "hello", array: [1,2,3] }).body.should == { "result" => true }
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
describe Elevate::HTTP::HTTPRequest do
|
2
|
+
extend WebStub::SpecHelpers
|
3
|
+
|
4
|
+
before do
|
5
|
+
disable_network_access!
|
6
|
+
end
|
7
|
+
|
8
|
+
before do
|
9
|
+
@url = "http://www.example.com/"
|
10
|
+
@body = "hello"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "requires a valid HTTP method" do
|
14
|
+
lambda { Elevate::HTTP::HTTPRequest.new(:invalid, @url) }.should.raise(ArgumentError)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "requires a URL starting with http" do
|
18
|
+
lambda { Elevate::HTTP::HTTPRequest.new(:get, "asdf") }.should.raise(ArgumentError)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "requires the body to be an instance of NSData" do
|
22
|
+
lambda { Elevate::HTTP::HTTPRequest.new(:get, @url, body: @body) }.should.raise(ArgumentError)
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "fulfilling a GET request" do
|
26
|
+
before do
|
27
|
+
stub_request(:get, @url).
|
28
|
+
to_return(body: @body, headers: {"Content-Type" => "text/plain"}, status_code: 201)
|
29
|
+
|
30
|
+
@request = Elevate::HTTP::HTTPRequest.new(:get, @url)
|
31
|
+
@response = @request.response
|
32
|
+
end
|
33
|
+
|
34
|
+
it "response has the correct status code" do
|
35
|
+
@response.status_code.should == 201
|
36
|
+
end
|
37
|
+
|
38
|
+
it "response has the right body" do
|
39
|
+
NSString.alloc.initWithData(@response.body, encoding:NSUTF8StringEncoding).should == @body
|
40
|
+
end
|
41
|
+
|
42
|
+
it "response has the correct headers" do
|
43
|
+
@response.headers.should == { "Content-Type" => "text/plain" }
|
44
|
+
end
|
45
|
+
|
46
|
+
it "response has no errors" do
|
47
|
+
@response.error.should.be.nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "fulfilling a GET request with headers" do
|
52
|
+
before do
|
53
|
+
stub_request(:get, @url).with(headers: { "API-Token" => "abc123" }).to_return(body: @body)
|
54
|
+
|
55
|
+
@request = Elevate::HTTP::HTTPRequest.new(:get, @url, headers: {})
|
56
|
+
@response = @request.response
|
57
|
+
end
|
58
|
+
|
59
|
+
it "includes the headers in the request" do
|
60
|
+
@response.body.should.not.be.nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "fulfilling a POST request with a body" do
|
65
|
+
before do
|
66
|
+
stub_request(:post, @url).with(body: @body).to_return(body: @body)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "sends the body as part of the request" do
|
70
|
+
request = Elevate::HTTP::HTTPRequest.new(:post, @url, body: @body.dataUsingEncoding(NSUTF8StringEncoding))
|
71
|
+
response = request.response
|
72
|
+
|
73
|
+
NSString.alloc.initWithData(response.body, encoding:NSUTF8StringEncoding).should == @body
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "cancelling a request" do
|
78
|
+
before do
|
79
|
+
stub_request(:get, @url).to_return(body: @body, delay: 1.0)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "aborts the request" do
|
83
|
+
start = Time.now
|
84
|
+
|
85
|
+
request = Elevate::HTTP::HTTPRequest.new(:get, @url)
|
86
|
+
request.start()
|
87
|
+
request.cancel()
|
88
|
+
|
89
|
+
response = request.response # simulate blocking
|
90
|
+
finish = Time.now
|
91
|
+
|
92
|
+
(finish - start).should < 1.0
|
93
|
+
end
|
94
|
+
|
95
|
+
it "sets the response to nil" do
|
96
|
+
request = Elevate::HTTP::HTTPRequest.new(:get, @url)
|
97
|
+
request.start()
|
98
|
+
request.cancel()
|
99
|
+
|
100
|
+
request.response.should.be.nil
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
describe Elevate::IOCoordinator do
|
2
|
+
before do
|
3
|
+
@coordinator = Elevate::IOCoordinator.new
|
4
|
+
end
|
5
|
+
|
6
|
+
it "is not cancelled" do
|
7
|
+
@coordinator.should.not.be.cancelled
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#install" do
|
11
|
+
it "stores the coordinator in a thread-local variable" do
|
12
|
+
@coordinator.install()
|
13
|
+
|
14
|
+
Thread.current[:io_coordinator].should == @coordinator
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
[:signal_blocked, :signal_unblocked].each do |method|
|
19
|
+
describe method.to_s do
|
20
|
+
describe "when IO has not been cancelled" do
|
21
|
+
it "does not raise CancelledError" do
|
22
|
+
lambda { @coordinator.send(method, 42) }.should.not.raise
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "when IO was cancelled" do
|
27
|
+
it "raises CancelledError" do
|
28
|
+
@coordinator.cancel()
|
29
|
+
|
30
|
+
lambda { @coordinator.send(method, "hello") }.should.raise(Elevate::CancelledError)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#uninstall" do
|
37
|
+
it "removes the coordinator from a thread-local variable" do
|
38
|
+
@coordinator.install()
|
39
|
+
@coordinator.uninstall()
|
40
|
+
|
41
|
+
Thread.current[:io_coordinator].should.be.nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
describe Elevate::ElevateOperation do
|
2
|
+
before do
|
3
|
+
@target = Target.new
|
4
|
+
@operation = Elevate::ElevateOperation.alloc.initWithTarget(@target)
|
5
|
+
@queue = NSOperationQueue.alloc.init
|
6
|
+
end
|
7
|
+
|
8
|
+
after do
|
9
|
+
@queue.waitUntilAllOperationsAreFinished()
|
10
|
+
end
|
11
|
+
|
12
|
+
it "subclasses NSOperation" do
|
13
|
+
@operation.class.ancestors.should.include NSOperation
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#on_finished" do
|
17
|
+
it "invokes it after #on_started" do
|
18
|
+
@lock = NSLock.alloc.init
|
19
|
+
@value = []
|
20
|
+
|
21
|
+
@operation.on_started = lambda do
|
22
|
+
@lock.lock()
|
23
|
+
if @value == []
|
24
|
+
@value << 1
|
25
|
+
end
|
26
|
+
@lock.unlock()
|
27
|
+
end
|
28
|
+
|
29
|
+
@operation.on_finished = lambda do
|
30
|
+
@lock.lock()
|
31
|
+
if @value == [1]
|
32
|
+
@value << 2
|
33
|
+
end
|
34
|
+
@lock.unlock()
|
35
|
+
|
36
|
+
resume
|
37
|
+
end
|
38
|
+
|
39
|
+
@queue.addOperation(@operation)
|
40
|
+
|
41
|
+
wait_max 1.0 do
|
42
|
+
@lock.lock()
|
43
|
+
@value.should == [1,2]
|
44
|
+
@lock.unlock()
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#exception" do
|
50
|
+
describe "when no exception is raised" do
|
51
|
+
it "returns nil" do
|
52
|
+
@queue.addOperation(@operation)
|
53
|
+
@operation.waitUntilFinished()
|
54
|
+
|
55
|
+
@operation.exception.should.be.nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "when an exception is raised" do
|
60
|
+
it "returns the exception" do
|
61
|
+
@target.exception = IndexError.new
|
62
|
+
|
63
|
+
@queue.addOperation(@operation)
|
64
|
+
@operation.waitUntilFinished()
|
65
|
+
|
66
|
+
@operation.exception.should == @target.exception
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#main" do
|
72
|
+
describe "when the operation has not been run" do
|
73
|
+
it "invokes the target" do
|
74
|
+
@queue.addOperation(@operation)
|
75
|
+
@operation.waitUntilFinished()
|
76
|
+
|
77
|
+
@target.called.should == 1
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "when the operation has been cancelled prior to starting" do
|
82
|
+
it "does not invoke the target" do
|
83
|
+
@operation.cancel()
|
84
|
+
|
85
|
+
@queue.addOperation(@operation)
|
86
|
+
@operation.waitUntilFinished()
|
87
|
+
|
88
|
+
@target.called.should == 0
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "when the operation is running" do
|
93
|
+
it "allows IO to be cancelled" do
|
94
|
+
@queue.addOperation(@operation)
|
95
|
+
@operation.waitUntilFinished()
|
96
|
+
|
97
|
+
@target.io_coordinator.should.not.be.nil
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "#result" do
|
103
|
+
before do
|
104
|
+
@target.result = 42
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "before starting the operation" do
|
108
|
+
it "returns nil" do
|
109
|
+
@operation.result.should.be.nil
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "when the operation has been cancelled" do
|
114
|
+
it "returns nil" do
|
115
|
+
@operation.cancel()
|
116
|
+
|
117
|
+
@queue.addOperation(@operation)
|
118
|
+
@operation.waitUntilFinished()
|
119
|
+
|
120
|
+
@operation.result.should.be.nil
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "when the operation has finished" do
|
125
|
+
it "returns the result of the target's #execute method" do
|
126
|
+
@queue.addOperation(@operation)
|
127
|
+
@operation.waitUntilFinished()
|
128
|
+
|
129
|
+
@operation.result.should == 42
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
metadata
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: elevate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.3'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Matt Green
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.9.0
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.9.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: guard-motion
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.1.1
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.1.1
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rb-fsevent
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.9.1
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.9.1
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: webstub
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.3.3
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.3.3
|
78
|
+
description: Distill the essence of your RubyMotion app
|
79
|
+
email:
|
80
|
+
- mattgreenrocks@gmail.com
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- .gitignore
|
86
|
+
- .rvmrc
|
87
|
+
- Gemfile
|
88
|
+
- Gemfile.lock
|
89
|
+
- Guardfile
|
90
|
+
- LICENSE
|
91
|
+
- README.md
|
92
|
+
- Rakefile
|
93
|
+
- app/app_delegate.rb
|
94
|
+
- elevate.gemspec
|
95
|
+
- lib/elevate.rb
|
96
|
+
- lib/elevate/api.rb
|
97
|
+
- lib/elevate/callback.rb
|
98
|
+
- lib/elevate/dispatcher.rb
|
99
|
+
- lib/elevate/dsl.rb
|
100
|
+
- lib/elevate/http/base64.rb
|
101
|
+
- lib/elevate/http/http_client.rb
|
102
|
+
- lib/elevate/http/request.rb
|
103
|
+
- lib/elevate/http/response.rb
|
104
|
+
- lib/elevate/http/uri.rb
|
105
|
+
- lib/elevate/io_coordinator.rb
|
106
|
+
- lib/elevate/operation.rb
|
107
|
+
- lib/elevate/promise.rb
|
108
|
+
- lib/elevate/version.rb
|
109
|
+
- spec/api_spec.rb
|
110
|
+
- spec/callback_spec.rb
|
111
|
+
- spec/dispatcher_spec.rb
|
112
|
+
- spec/dsl_spec.rb
|
113
|
+
- spec/helpers/target.rb
|
114
|
+
- spec/http/http_client_spec.rb
|
115
|
+
- spec/http/http_request_spec.rb
|
116
|
+
- spec/io_coordinator_spec.rb
|
117
|
+
- spec/operation_spec.rb
|
118
|
+
homepage: http://github.com/mattgreen/elevate
|
119
|
+
licenses: []
|
120
|
+
post_install_message:
|
121
|
+
rdoc_options: []
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
126
|
+
requirements:
|
127
|
+
- - ! '>='
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
segments:
|
131
|
+
- 0
|
132
|
+
hash: 1532692712045252370
|
133
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
|
+
none: false
|
135
|
+
requirements:
|
136
|
+
- - ! '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
segments:
|
140
|
+
- 0
|
141
|
+
hash: 1532692712045252370
|
142
|
+
requirements: []
|
143
|
+
rubyforge_project:
|
144
|
+
rubygems_version: 1.8.24
|
145
|
+
signing_key:
|
146
|
+
specification_version: 3
|
147
|
+
summary: Distill the essence of your RubyMotion app
|
148
|
+
test_files:
|
149
|
+
- spec/api_spec.rb
|
150
|
+
- spec/callback_spec.rb
|
151
|
+
- spec/dispatcher_spec.rb
|
152
|
+
- spec/dsl_spec.rb
|
153
|
+
- spec/helpers/target.rb
|
154
|
+
- spec/http/http_client_spec.rb
|
155
|
+
- spec/http/http_request_spec.rb
|
156
|
+
- spec/io_coordinator_spec.rb
|
157
|
+
- spec/operation_spec.rb
|