mimic 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +4 -0
- data/README.md +0 -2
- data/Rakefile +1 -1
- data/lib/mimic.rb +14 -12
- data/lib/mimic/api.rb +19 -1
- data/lib/mimic/fake_host.rb +92 -2
- metadata +4 -4
data/CHANGES
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# What is Mimic?
|
2
2
|
Mimic is a testing tool that lets you set create a fake stand-in for an external web service to be used when writing integration/end-to-end tests for applications or libraries that access these services.
|
3
3
|
|
4
|
-
Note: this is still very early in its development; don't let the existence of this README fool you into thinking its ready for prime-time!
|
5
|
-
|
6
4
|
## Why not stub?
|
7
5
|
There are already some good tools, like [FakeWeb](http://fakeweb.rubyforge.org/) which let you stub requests at a low-level which is fine for unit and functional tests but when exercising our code through integration or end-to-end tests we want to exercise as much of the stack as possible.
|
8
6
|
|
data/Rakefile
CHANGED
@@ -27,7 +27,7 @@ spec = Gem::Specification.new do |s|
|
|
27
27
|
|
28
28
|
# Change these as appropriate
|
29
29
|
s.name = "mimic"
|
30
|
-
s.version = "0.4.
|
30
|
+
s.version = "0.4.2"
|
31
31
|
s.summary = "A Ruby gem for faking external web services for testing"
|
32
32
|
s.authors = "Luke Redpath"
|
33
33
|
s.email = "luke@lukeredpath.co.uk"
|
data/lib/mimic.rb
CHANGED
@@ -18,7 +18,7 @@ module Mimic
|
|
18
18
|
|
19
19
|
host = FakeHost.new(options[:hostname], options[:remote_configuration_path]).tap do |host|
|
20
20
|
host.instance_eval(&block) if block_given?
|
21
|
-
Server.instance.serve(host, options
|
21
|
+
Server.instance.serve(host, options)
|
22
22
|
end
|
23
23
|
add_host(host)
|
24
24
|
end
|
@@ -44,30 +44,32 @@ module Mimic
|
|
44
44
|
@logger ||= Logger.new(StringIO.new)
|
45
45
|
end
|
46
46
|
|
47
|
-
def serve(
|
48
|
-
if
|
47
|
+
def serve(app, options)
|
48
|
+
if options[:fork]
|
49
49
|
@thread = Thread.fork do
|
50
|
-
start_service(
|
50
|
+
start_service(app, options)
|
51
51
|
end
|
52
52
|
|
53
|
-
wait_for_service(
|
54
|
-
|
53
|
+
wait_for_service(app.hostname, options[:port])
|
54
|
+
|
55
55
|
else
|
56
|
-
start_service(
|
56
|
+
start_service(app, options)
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
def start_service(
|
61
|
-
Rack::Handler::WEBrick.run(
|
62
|
-
:Port => port,
|
60
|
+
def start_service(app, options)
|
61
|
+
Rack::Handler::WEBrick.run(app.url_map, {
|
62
|
+
:Port => options[:port],
|
63
63
|
:Logger => logger,
|
64
64
|
:AccessLog => logger,
|
65
65
|
|
66
66
|
}) do |server|
|
67
67
|
@server = server
|
68
68
|
|
69
|
-
trap(
|
70
|
-
|
69
|
+
old = trap('EXIT') do
|
70
|
+
old.call if old
|
71
|
+
@server.shutdown
|
72
|
+
end
|
71
73
|
end
|
72
74
|
end
|
73
75
|
|
data/lib/mimic/api.rb
CHANGED
@@ -31,6 +31,14 @@ module Mimic
|
|
31
31
|
[200, {}, "Cleared stubs: #{response_body}"]
|
32
32
|
end
|
33
33
|
|
34
|
+
get "/ping" do
|
35
|
+
[200, {}, "OK"]
|
36
|
+
end
|
37
|
+
|
38
|
+
get "/debug" do
|
39
|
+
[200, {}, self.host.inspect]
|
40
|
+
end
|
41
|
+
|
34
42
|
private
|
35
43
|
|
36
44
|
class APIRequest
|
@@ -68,7 +76,13 @@ module Mimic
|
|
68
76
|
end
|
69
77
|
|
70
78
|
def on(host)
|
71
|
-
host.send(@method.downcase.to_sym, path).returning(body, code, headers)
|
79
|
+
stub = host.send(@method.downcase.to_sym, path).returning(body, code, headers)
|
80
|
+
stub.with_query_parameters(params)
|
81
|
+
stub.echo_request!(echo_format)
|
82
|
+
end
|
83
|
+
|
84
|
+
def echo_format
|
85
|
+
@data['echo'].to_sym rescue nil
|
72
86
|
end
|
73
87
|
|
74
88
|
def path
|
@@ -86,6 +100,10 @@ module Mimic
|
|
86
100
|
def headers
|
87
101
|
@data['headers'] || {}
|
88
102
|
end
|
103
|
+
|
104
|
+
def params
|
105
|
+
@data['params'] || {}
|
106
|
+
end
|
89
107
|
end
|
90
108
|
end
|
91
109
|
end
|
data/lib/mimic/fake_host.rb
CHANGED
@@ -8,6 +8,7 @@ module Mimic
|
|
8
8
|
def initialize(hostname, remote_configuration_path = nil)
|
9
9
|
@hostname = hostname
|
10
10
|
@remote_configuration_path = remote_configuration_path
|
11
|
+
@imports = []
|
11
12
|
clear
|
12
13
|
build_url_map!
|
13
14
|
end
|
@@ -34,7 +35,10 @@ module Mimic
|
|
34
35
|
|
35
36
|
def import(path)
|
36
37
|
if File.exists?(path)
|
38
|
+
@imports << path unless @imports.include?(path)
|
37
39
|
instance_eval(File.read(path))
|
40
|
+
else
|
41
|
+
raise "Could not locate file for stub import: #{path}"
|
38
42
|
end
|
39
43
|
end
|
40
44
|
|
@@ -49,6 +53,10 @@ module Mimic
|
|
49
53
|
@app.not_found do
|
50
54
|
[404, {}, ""]
|
51
55
|
end
|
56
|
+
@app.helpers do
|
57
|
+
include Helpers
|
58
|
+
end
|
59
|
+
@imports.each { |file| import(file) }
|
52
60
|
end
|
53
61
|
|
54
62
|
def inspect
|
@@ -81,11 +89,59 @@ module Mimic
|
|
81
89
|
@url_map = Rack::URLMap.new(routes)
|
82
90
|
end
|
83
91
|
|
92
|
+
module Helpers
|
93
|
+
def echo_request!(format)
|
94
|
+
RequestEcho.new(request).response_as(format)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
class RequestEcho
|
99
|
+
def initialize(request)
|
100
|
+
@request = request
|
101
|
+
end
|
102
|
+
|
103
|
+
def response_as(format)
|
104
|
+
content_type = case format
|
105
|
+
when :json, :plist
|
106
|
+
"application/#{format.to_s.downcase}"
|
107
|
+
else
|
108
|
+
"text/plain"
|
109
|
+
end
|
110
|
+
[200, {"Content-Type" => content_type}, to_s(format)]
|
111
|
+
end
|
112
|
+
|
113
|
+
def to_s(format)
|
114
|
+
case format
|
115
|
+
when :json
|
116
|
+
to_hash.to_json
|
117
|
+
when :plist
|
118
|
+
to_hash.to_plist
|
119
|
+
when :text
|
120
|
+
to_hash.inspect
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def to_hash
|
125
|
+
{"echo" => {
|
126
|
+
"params" => @request.params,
|
127
|
+
"env" => env_without_rack_env,
|
128
|
+
"body" => @request.body.read
|
129
|
+
}}
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
def env_without_rack_env
|
135
|
+
Hash[*@request.env.select { |key, value| key !~ /^rack/i }.flatten]
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
84
139
|
class StubbedRequest
|
85
140
|
def initialize(app, method, path)
|
86
141
|
@method, @path = method, path
|
87
142
|
@code = 200
|
88
143
|
@headers = {}
|
144
|
+
@params = {}
|
89
145
|
@body = ""
|
90
146
|
@app = app
|
91
147
|
end
|
@@ -98,9 +154,43 @@ module Mimic
|
|
98
154
|
end
|
99
155
|
end
|
100
156
|
|
157
|
+
def with_query_parameters(params)
|
158
|
+
tap do
|
159
|
+
@params = params
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def echo_request!(format = :json)
|
164
|
+
@echo_request_format = format
|
165
|
+
end
|
166
|
+
|
167
|
+
def matches?(request)
|
168
|
+
if @params.any?
|
169
|
+
request.params == @params
|
170
|
+
else
|
171
|
+
true
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def matched_response
|
176
|
+
[@code, @headers, @body]
|
177
|
+
end
|
178
|
+
|
179
|
+
def unmatched_response
|
180
|
+
[404, "", {}]
|
181
|
+
end
|
182
|
+
|
183
|
+
def response_for_request(request)
|
184
|
+
if @echo_request_format
|
185
|
+
@body = RequestEcho.new(request).to_s(@echo_request_format)
|
186
|
+
end
|
187
|
+
|
188
|
+
matches?(request) ? matched_response : unmatched_response
|
189
|
+
end
|
190
|
+
|
101
191
|
def build
|
102
|
-
|
103
|
-
@app.send(@method.downcase, @path) {
|
192
|
+
stub = self
|
193
|
+
@app.send(@method.downcase, @path) { stub.response_for_request(request) }
|
104
194
|
end
|
105
195
|
end
|
106
196
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mimic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 4
|
9
|
-
-
|
10
|
-
version: 0.4.
|
9
|
+
- 2
|
10
|
+
version: 0.4.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Luke Redpath
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-04-20 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|