mimic 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/README.md +20 -11
  2. data/Rakefile +4 -3
  3. data/lib/mimic.rb +7 -34
  4. data/lib/mimic/fake_host.rb +25 -35
  5. metadata +26 -16
data/README.md CHANGED
@@ -8,17 +8,13 @@ There are already some good tools, like [FakeWeb](http://fakeweb.rubyforge.org/)
8
8
 
9
9
  Mimic aims to make it possible to test your networking code without actually hitting the real services by starting up a real web server and responding to HTTP requests. This lets you test your application against canned responses in an as-close-to-the-real-thing-as-possible way.
10
10
 
11
- Also, because Mimic starts responds to real HTTP requests, it can be used when testing non-Ruby applications too (like an iPhone application).
12
-
13
- ## How does it work?
14
-
15
- Mimic's API is designed to be simple yet expressive. You simply register the host that you want to fake and then register any number of requests and responses. Mimic will then start an HTTP server (using Rack and WEBRick) on the specified port and add an entry to your hosts file (OSX and Linux only) for that host.
11
+ Also, because Mimic responds to real HTTP requests, it can be used when testing non-Ruby applications too.
16
12
 
17
13
  ## Examples
18
14
 
19
15
  Registering to a single request stub:
20
16
 
21
- Mimic.mimic("www.example.com", 10090).get("/some/path").returning("hello world")
17
+ Mimic.mimic.get("/some/path").returning("hello world")
22
18
 
23
19
  And the result, using RestClient:
24
20
 
@@ -26,18 +22,31 @@ And the result, using RestClient:
26
22
 
27
23
  Registering multiple request stubs; note that you can stub the same path with different HTTP methods separately.
28
24
 
29
- Mimic.mimic("www.example.com", 10090) do
25
+ Mimic.mimic do
30
26
  get("/some/path").returning("Hello World", 200)
31
27
  get("/some/other/path").returning("Redirecting...", 301, {"Location" => "somewhere else"})
32
28
  post("/some/path").returning("Created!", 201)
33
29
  end
34
30
 
35
- ## Caveats
36
-
37
- * Because the server is not started on port 80, you need a way of configuring your application under test to use a different port at runtime.
31
+ You can even use Rack middlewares, e.g. to handle common testing scenarios such as authentication:
32
+
33
+ Mimic.mimic do
34
+ use Rack::Auth::Basic do |user, pass|
35
+ user == 'theuser' and pass == 'thepass'
36
+ end
37
+
38
+ get("/some/path")
39
+ end
40
+
41
+ Finally, because Mimic is built on top of Sinatra for the core request handling, you can create your stubbed requests like you would in any Sinatra app:
38
42
 
39
- * Mimic uses the Ghost gem to modify the hosts file and is therefore dependent on support for this gem. In addition, Ghost currently requires sudo privileges to run which means entering your password. I'm happy to hear any suggestions for working around this.
43
+ Mimic.mimic do
44
+ get "/some/path" do
45
+ [200, {}, "hello world"]
46
+ end
47
+ end
40
48
 
41
49
  ## License
42
50
 
43
51
  As usual, the code is released under the MIT license which is included in the repository.
52
+
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.1.0"
30
+ s.version = "0.2.0"
31
31
  s.summary = "A Ruby gem for faking external web services for testing"
32
32
  s.author = "Luke Redpath"
33
33
  s.email = "luke@lukeredpath.co.uk"
@@ -43,12 +43,13 @@ spec = Gem::Specification.new do |s|
43
43
 
44
44
  # If you want to depend on other gems, add them here, along with any
45
45
  # relevant versions
46
- s.add_dependency("ghost", "~> 0.2.5")
47
- s.add_dependency("rack", "~> 1.2.1")
46
+ s.add_dependency("rack")
47
+ s.add_dependency("sinatra")
48
48
 
49
49
  # If your tests use any gems, include them here
50
50
  s.add_development_dependency("rspec")
51
51
  s.add_development_dependency("cucumber")
52
+ s.add_development_dependency("mocha")
52
53
  end
53
54
 
54
55
  # This task actually builds the gem. We also regenerate a static
data/lib/mimic.rb CHANGED
@@ -7,23 +7,17 @@ require 'logger'
7
7
  module Mimic
8
8
  MIMIC_DEFAULT_PORT = 11988
9
9
 
10
- def self.mimic(hostname, port = MIMIC_DEFAULT_PORT, &block)
11
- FakeHost.new(hostname).tap do |host|
12
- registry.register_host(host)
10
+ def self.mimic(options = {}, &block)
11
+ options = {:hostname => 'localhost', :port => MIMIC_DEFAULT_PORT}.merge(options)
12
+
13
+ FakeHost.new(options[:hostname]).tap do |host|
13
14
  host.instance_eval(&block) if block_given?
14
- Server.instance.serve(host, port)
15
+ Server.instance.serve(host, options[:port])
15
16
  end
16
17
  end
17
18
 
18
19
  def self.cleanup!
19
20
  Mimic::Server.instance.shutdown
20
- registry.unregister_all_hosts
21
- end
22
-
23
- private
24
-
25
- def self.registry
26
- @registry ||= Registry.new
27
21
  end
28
22
 
29
23
  class Server
@@ -34,12 +28,11 @@ module Mimic
34
28
  end
35
29
 
36
30
  def serve(host_app, port)
37
- webrick_logger = logger
38
31
  @thread = Thread.fork do
39
32
  Rack::Handler::WEBrick.run(host_app,
40
33
  :Port => port,
41
- :Logger => webrick_logger,
42
- :AccessLog => webrick_logger
34
+ :Logger => logger,
35
+ :AccessLog => logger
43
36
 
44
37
  ) { |server| @server = server }
45
38
  end
@@ -52,24 +45,4 @@ module Mimic
52
45
  end
53
46
  end
54
47
  end
55
-
56
- class Registry
57
- def initialize
58
- @hosts = []
59
- end
60
-
61
- def register_host(host)
62
- @hosts << host
63
- Host.add(host.hostname)
64
- end
65
-
66
- def unregister_host(host)
67
- @hosts.delete(host)
68
- Host.delete(host.hostname)
69
- end
70
-
71
- def unregister_all_hosts
72
- @hosts.each { |host| unregister_host(host) }
73
- end
74
- end
75
48
  end
@@ -1,11 +1,17 @@
1
+ require 'sinatra/base'
2
+
1
3
  module Mimic
2
4
  class FakeHost
3
5
  attr_reader :hostname
4
6
 
5
- def initialize(hostname, unhandled_response_strategy = NotFoundResponseStrategy.new)
7
+ def initialize(hostname)
6
8
  @hostname = hostname
7
- @stubs = {}
8
- @unhandled_response_strategy = unhandled_response_strategy
9
+ @stubs = []
10
+ @app = Class.new(Sinatra::Base)
11
+
12
+ @app.not_found do
13
+ [404, {}, ""]
14
+ end
9
15
  end
10
16
 
11
17
  def get(path)
@@ -29,35 +35,32 @@ module Mimic
29
35
  end
30
36
 
31
37
  def call(env)
32
- handler_for_call(env).call(env)
38
+ @stubs.each(&:build)
39
+ @app.call(env)
33
40
  end
34
41
 
35
- def terminate
36
- Mimic.terminate(@hostname)
42
+ def method_missing(method, *args, &block)
43
+ @app.send(method, *args, &block)
37
44
  end
38
45
 
39
46
  private
40
47
 
41
- def request(method, path)
42
- stubbed_request = StubbedRequest.new(method, path)
43
- @stubs[stubbed_request.key] = stubbed_request
44
- end
45
-
46
- def handler_for_call(env)
47
- (@stubs[request_key(env)] || @unhandled_response_strategy)
48
- end
49
-
50
- def request_key(env)
51
- request = Rack::Request.new(env)
52
- StubbedRequest.key(request.request_method, request.path)
48
+ def request(method, path, &block)
49
+ if block_given?
50
+ @app.send(method.downcase, path, &block)
51
+ else
52
+ @stubs << StubbedRequest.new(@app, method, path)
53
+ @stubs.last
54
+ end
53
55
  end
54
56
 
55
57
  class StubbedRequest
56
- def initialize(method, path)
58
+ def initialize(app, method, path)
57
59
  @method, @path = method, path
58
60
  @code = 200
59
61
  @headers = {}
60
62
  @body = ""
63
+ @app = app
61
64
  end
62
65
 
63
66
  def returning(body, code = 200, headers = {})
@@ -68,22 +71,9 @@ module Mimic
68
71
  end
69
72
  end
70
73
 
71
- def call(env)
72
- [@code, @headers, @body]
73
- end
74
-
75
- def key
76
- self.class.key(@method, @path)
77
- end
78
-
79
- def self.key(method, path)
80
- "#{method} #{path}"
81
- end
82
- end
83
-
84
- class NotFoundResponseStrategy
85
- def call(env)
86
- [404, {}, ""]
74
+ def build
75
+ response = [@code, @headers, @body]
76
+ @app.send(@method.downcase, @path) { response }
87
77
  end
88
78
  end
89
79
  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: 27
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 0.1.0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Luke Redpath
@@ -19,35 +19,31 @@ date: 2010-08-19 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- name: ghost
22
+ name: rack
23
23
  prerelease: false
24
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - ~>
27
+ - - ">="
28
28
  - !ruby/object:Gem::Version
29
- hash: 29
29
+ hash: 3
30
30
  segments:
31
31
  - 0
32
- - 2
33
- - 5
34
- version: 0.2.5
32
+ version: "0"
35
33
  type: :runtime
36
34
  version_requirements: *id001
37
35
  - !ruby/object:Gem::Dependency
38
- name: rack
36
+ name: sinatra
39
37
  prerelease: false
40
38
  requirement: &id002 !ruby/object:Gem::Requirement
41
39
  none: false
42
40
  requirements:
43
- - - ~>
41
+ - - ">="
44
42
  - !ruby/object:Gem::Version
45
- hash: 29
43
+ hash: 3
46
44
  segments:
47
- - 1
48
- - 2
49
- - 1
50
- version: 1.2.1
45
+ - 0
46
+ version: "0"
51
47
  type: :runtime
52
48
  version_requirements: *id002
53
49
  - !ruby/object:Gem::Dependency
@@ -78,6 +74,20 @@ dependencies:
78
74
  version: "0"
79
75
  type: :development
80
76
  version_requirements: *id004
77
+ - !ruby/object:Gem::Dependency
78
+ name: mocha
79
+ prerelease: false
80
+ requirement: &id005 !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ type: :development
90
+ version_requirements: *id005
81
91
  description:
82
92
  email: luke@lukeredpath.co.uk
83
93
  executables: []