faraday_simulation 0.0.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.
- data/Gemfile +4 -0
- data/Gemfile.lock +20 -0
- data/MIT-LICENSE +20 -0
- data/README.md +49 -0
- data/Rakefile +12 -0
- data/faraday_simulation.gemspec +19 -0
- data/lib/faraday_simulation/adapter.rb +8 -0
- data/lib/faraday_simulation/stub.rb +68 -0
- data/lib/faraday_simulation/stubs.rb +8 -0
- data/lib/faraday_simulation/version.rb +5 -0
- data/lib/faraday_simulation.rb +8 -0
- data/test/test_helper.rb +2 -0
- data/test/unit/test_adapter.rb +96 -0
- data/test/unit/test_readme.rb +39 -0
- metadata +101 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
faraday_simulation (0.0.1)
|
5
|
+
faraday
|
6
|
+
rake
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
faraday (0.8.1)
|
12
|
+
multipart-post (~> 1.1)
|
13
|
+
multipart-post (1.1.5)
|
14
|
+
rake (0.9.2.2)
|
15
|
+
|
16
|
+
PLATFORMS
|
17
|
+
ruby
|
18
|
+
|
19
|
+
DEPENDENCIES
|
20
|
+
faraday_simulation!
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Joseph Pearson
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# FaradaySimulation
|
2
|
+
|
3
|
+
A [Faraday]() extension to provide dynamic stubbing. This makes it possible
|
4
|
+
to simulate more of the behavior of the target service in your tests and when
|
5
|
+
your app is running in development mode.
|
6
|
+
|
7
|
+
|
8
|
+
## Usage
|
9
|
+
|
10
|
+
The `FaradaySimulation::Adapter` class is the equivalent of Faraday's own
|
11
|
+
test adapter, but you can do a bit more with the stubs:
|
12
|
+
|
13
|
+
conn = Faraday::Connection.new { |builder|
|
14
|
+
builder.use(FaradaySimulation::Adapter) { |stub|
|
15
|
+
stub.get('/drink/:name.json') { |env|
|
16
|
+
[200, {}, "Drinking #{env[:params]['name']}"]
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
resp = conn.get('/drink/sake.json')
|
22
|
+
# resp.body => 'Drinking sake'
|
23
|
+
|
24
|
+
resp = conn.get('/drink/ale.json')
|
25
|
+
# resp.body => 'Drinking ale'
|
26
|
+
|
27
|
+
Put simply, any stub path you define that includes `:foo` will match to
|
28
|
+
any string, and that string will be the value of `env[:params]['foo']` in
|
29
|
+
your stub block.
|
30
|
+
|
31
|
+
For more complex routes, you can define the stub with a regular expression.
|
32
|
+
Any regex group (you know, parenthesized pattern) in the matching regex will
|
33
|
+
be placed in env[:segments]. For example:
|
34
|
+
|
35
|
+
stub.get(/\/foo\/([A-Z]+)\//) { |env|
|
36
|
+
[200, {}, "Segment is #{env[:segments][0]}"]
|
37
|
+
}
|
38
|
+
|
39
|
+
resp = conn.get('/foo/BAR')
|
40
|
+
# resp.body => 'Segment is BAR'
|
41
|
+
|
42
|
+
resp = conn.get('/foo/bar')
|
43
|
+
# => Stubs::NotFound error
|
44
|
+
|
45
|
+
|
46
|
+
## Copyright
|
47
|
+
|
48
|
+
Copyright (c) 2012 Joseph Pearson, released under the MIT License.
|
49
|
+
See MIT-LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/faraday_simulation/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ['Joseph Pearson']
|
6
|
+
gem.email = ['joseph@booki.sh']
|
7
|
+
gem.description = 'A Faraday extension to provide dynamic stubbing.'
|
8
|
+
gem.summary = 'Dynamic stubbing in Faraday'
|
9
|
+
gem.homepage = ''
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = 'faraday_simulation'
|
15
|
+
gem.require_paths = ['lib']
|
16
|
+
gem.version = FaradaySimulation::VERSION
|
17
|
+
gem.add_dependency('rake')
|
18
|
+
gem.add_dependency('faraday')
|
19
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
class FaradaySimulation::Stub < Faraday::Adapter::Test::Stub
|
2
|
+
|
3
|
+
attr_accessor(:segments, :segment_names)
|
4
|
+
|
5
|
+
|
6
|
+
def initialize(full, body, block)
|
7
|
+
self.segment_names = []
|
8
|
+
query = nil
|
9
|
+
if full.kind_of?(String)
|
10
|
+
self.path, query = full.split('?')
|
11
|
+
process_path
|
12
|
+
else
|
13
|
+
self.path = full
|
14
|
+
end
|
15
|
+
self.params = query ? Faraday::Utils.parse_nested_query(query) : {}
|
16
|
+
self.body = body
|
17
|
+
self.block = Proc.new { |env|
|
18
|
+
env[:params].update(body_params(env))
|
19
|
+
segment_names.each { |name|
|
20
|
+
env[:params][name] = self.segments.shift
|
21
|
+
}
|
22
|
+
env[:segments] = self.segments
|
23
|
+
block.call(env)
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def matches?(request_uri, request_body)
|
29
|
+
request_path, request_query = request_uri.split('?')
|
30
|
+
request_params = request_query ?
|
31
|
+
Faraday::Utils.parse_nested_query(request_query) :
|
32
|
+
{}
|
33
|
+
md = request_path.match(self.path)
|
34
|
+
if (
|
35
|
+
(md && md[0] == request_path) &&
|
36
|
+
params_match?(request_params) &&
|
37
|
+
(body.to_s.size.zero? || request_body == body)
|
38
|
+
)
|
39
|
+
self.segments = md.to_a.slice(1, md.size)
|
40
|
+
true
|
41
|
+
else
|
42
|
+
false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def process_path
|
48
|
+
self.path += '/' unless path.match(/\/$/)
|
49
|
+
self.path.gsub!(/:([^\/\.]+)/) {
|
50
|
+
self.segment_names << $1
|
51
|
+
'([^\/\.]+)'
|
52
|
+
}
|
53
|
+
self.path = Regexp.new(self.path) if segment_names.any?
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
protected
|
58
|
+
|
59
|
+
def body_params(env)
|
60
|
+
case env[:request_headers]["Content-Type"]
|
61
|
+
when /\bjson$/
|
62
|
+
JSON.load(env[:body])
|
63
|
+
else
|
64
|
+
Faraday::Utils.send(:parse_nested_query, env[:body])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class FaradaySimulation::TestAdapter < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@stubs = FaradaySimulation::Stubs.new
|
7
|
+
@conn = Faraday::Connection.new { |builder|
|
8
|
+
builder.use(FaradaySimulation::Adapter, @stubs)
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
def test_simplest_case_of_stubbed_routing
|
14
|
+
conn = Faraday::Connection.new { |builder|
|
15
|
+
builder.use(FaradaySimulation::Adapter) { |stub|
|
16
|
+
stub.get('/nigiri/sake.json') {
|
17
|
+
[200, {}, 'hi world']
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
resp = conn.get('/nigiri/sake.json')
|
23
|
+
assert_equal('hi world', resp.body)
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def test_body_params
|
28
|
+
@stubs.post('/endpoint') { |env|
|
29
|
+
assert_equal('bar', env[:params]['foo'])
|
30
|
+
}
|
31
|
+
@conn.post('/endpoint', 'foo=bar')
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def test_query_params
|
36
|
+
@stubs.get('/endpoint') { |env|
|
37
|
+
assert_equal('garply', env[:params]['foo'])
|
38
|
+
}
|
39
|
+
@conn.get('/endpoint?foo=garply')
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def test_query_params_when_defined_do_not_match
|
44
|
+
@stubs.get('/endpoint?foo=baz') { |env| }
|
45
|
+
assert_raises(Faraday::Adapter::Test::Stubs::NotFound) {
|
46
|
+
@conn.get('/endpoint?foo=woz')
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
def test_segment_params
|
52
|
+
@stubs.get(/\/endpoint\/([^\/]+)\//) { |env|
|
53
|
+
assert_equal('slug', env[:segments][0])
|
54
|
+
}
|
55
|
+
@conn.get('/endpoint/slug')
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
def test_multiple_segment_params
|
60
|
+
@stubs.get(/\/endpoint\/([^\/]+)\/junk\/(.*)/) { |env|
|
61
|
+
assert_equal('slug', env[:segments][0])
|
62
|
+
assert_equal('wildcard/string/', env[:segments][1])
|
63
|
+
}
|
64
|
+
@conn.get('/endpoint/slug/junk/wildcard/string/')
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def test_segment_params_with_query_params
|
69
|
+
@stubs.get(/\/endpoint\/([^\/]+)\//) { |env|
|
70
|
+
assert_equal('bar', env[:params]['foo'])
|
71
|
+
}
|
72
|
+
@conn.get('/endpoint/slug?foo=bar')
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
def test_routed_params
|
77
|
+
@stubs.get('/endpoint/:slug') { |env|
|
78
|
+
assert_equal('faraday_simulation', env[:params]['slug'])
|
79
|
+
}
|
80
|
+
assert_nothing_raised {
|
81
|
+
@conn.get('/endpoint/faraday_simulation')
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
def test_routed_params_with_extension
|
87
|
+
@stubs.get('/endpoint/:slug.:format') { |env|
|
88
|
+
assert_equal('faraday_simulation', env[:params]['slug'])
|
89
|
+
assert_equal('json', env[:params]['format'])
|
90
|
+
}
|
91
|
+
assert_nothing_raised {
|
92
|
+
@conn.get('/endpoint/faraday_simulation.json')
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class FaradaySimulation::TestReadme < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_routed_example
|
6
|
+
conn = Faraday::Connection.new { |builder|
|
7
|
+
builder.use(FaradaySimulation::Adapter) { |stub|
|
8
|
+
stub.get('/drink/:name.json') { |env|
|
9
|
+
[200, {}, "Drinking #{env[:params]['name']}"]
|
10
|
+
}
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
resp = conn.get('/drink/sake.json')
|
15
|
+
assert_equal('Drinking sake', resp.body)
|
16
|
+
|
17
|
+
resp = conn.get('/drink/ale.json')
|
18
|
+
assert_equal('Drinking ale', resp.body)
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def test_segmented_example
|
23
|
+
conn = Faraday::Connection.new { |builder|
|
24
|
+
builder.use(FaradaySimulation::Adapter) { |stub|
|
25
|
+
stub.get(/\/foo\/([A-Z]+)\//) { |env|
|
26
|
+
[200, {}, "Segment is #{env[:segments][0]}"]
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
resp = conn.get('/foo/BAR')
|
32
|
+
assert_equal('Segment is BAR', resp.body)
|
33
|
+
|
34
|
+
assert_raises(Faraday::Adapter::Test::Stubs::NotFound) {
|
35
|
+
resp = conn.get('/foo/bar')
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: faraday_simulation
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Joseph Pearson
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2012-07-09 00:00:00 +10:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rake
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: faraday
|
34
|
+
prerelease: false
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
segments:
|
40
|
+
- 0
|
41
|
+
version: "0"
|
42
|
+
type: :runtime
|
43
|
+
version_requirements: *id002
|
44
|
+
description: A Faraday extension to provide dynamic stubbing.
|
45
|
+
email:
|
46
|
+
- joseph@booki.sh
|
47
|
+
executables: []
|
48
|
+
|
49
|
+
extensions: []
|
50
|
+
|
51
|
+
extra_rdoc_files: []
|
52
|
+
|
53
|
+
files:
|
54
|
+
- Gemfile
|
55
|
+
- Gemfile.lock
|
56
|
+
- MIT-LICENSE
|
57
|
+
- README.md
|
58
|
+
- Rakefile
|
59
|
+
- faraday_simulation.gemspec
|
60
|
+
- lib/faraday_simulation.rb
|
61
|
+
- lib/faraday_simulation/adapter.rb
|
62
|
+
- lib/faraday_simulation/stub.rb
|
63
|
+
- lib/faraday_simulation/stubs.rb
|
64
|
+
- lib/faraday_simulation/version.rb
|
65
|
+
- test/test_helper.rb
|
66
|
+
- test/unit/test_adapter.rb
|
67
|
+
- test/unit/test_readme.rb
|
68
|
+
has_rdoc: true
|
69
|
+
homepage: ""
|
70
|
+
licenses: []
|
71
|
+
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
segments:
|
82
|
+
- 0
|
83
|
+
version: "0"
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
requirements: []
|
92
|
+
|
93
|
+
rubyforge_project:
|
94
|
+
rubygems_version: 1.3.6
|
95
|
+
signing_key:
|
96
|
+
specification_version: 3
|
97
|
+
summary: Dynamic stubbing in Faraday
|
98
|
+
test_files:
|
99
|
+
- test/test_helper.rb
|
100
|
+
- test/unit/test_adapter.rb
|
101
|
+
- test/unit/test_readme.rb
|