service_double 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/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in service_double.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 iain
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,117 @@
1
+ # Service Double
2
+
3
+ A tool for making fake versions of external (web) services. You can use fake
4
+ web services to return predicatable results for testing.
5
+
6
+ What you need to do is create a small Sinatra application, that will play the
7
+ fake version during your tests.
8
+
9
+ By convention, the application should respond to two basic urls: `GET /` and
10
+ `DELETE /`. The GET request is used to tell if the application is running. The
11
+ DELETE request should reset the application, and is called between each
12
+ test/scenario.
13
+
14
+ An example of such a fake web service:
15
+
16
+ ``` ruby
17
+ values = []
18
+
19
+ get "/" do
20
+ 200
21
+ end
22
+
23
+ delete "/" do
24
+ values.clear
25
+ 200
26
+ end
27
+
28
+ post "/remember" do
29
+ values << params[:value]
30
+ end
31
+
32
+ get "/remembered" do
33
+ { :remembered => values }.to_json
34
+ end
35
+ ```
36
+
37
+ The idea is that inside this fake app, you can cheat all you like. Your
38
+ database might be a simple hash or array, or you can choose to return simple
39
+ canned responses.
40
+
41
+ You can also add paths to your fake app that don't exist in the real app, which
42
+ you can use for easy testing and debugging.
43
+
44
+ ## Installation
45
+
46
+ Add this line to your application's Gemfile:
47
+
48
+ ``` ruby
49
+ group :test do
50
+ gem 'service_double', require: false
51
+ end
52
+ ```
53
+
54
+ And then execute:
55
+
56
+ $ bundle
57
+
58
+ Or install it yourself as:
59
+
60
+ $ gem install service_double
61
+
62
+ ## Usage
63
+
64
+ To hook it up to a test framework:
65
+
66
+ ``` ruby
67
+ require 'service_double'
68
+
69
+ ServiceDouble.hook_into(:cucumber) do |config|
70
+ config.server = "my_sinatra_server.rb"
71
+ config.url = "http://localhost:12345"
72
+ end
73
+ ```
74
+
75
+ Supported frameworks are currently `:cucumber` and `:rspec`.
76
+
77
+ The configuration options are:
78
+
79
+ * **server** where to find the fake web service app (required)
80
+ * **url** where the fake web service should be accessed (required)
81
+ * **timeout** how long you allow the fake server to take booting up (default: 2 seconds)
82
+ * **log_file** where to write the server logs to (default: "log/#{server}.log")
83
+
84
+ You can have one or multiple services doubles, and control them:
85
+
86
+ ``` ruby
87
+ $widget_service = ServiceDouble.hook_into(:rspec) do |config|
88
+ config.server = "fake_widgets.rb"
89
+ config.url = "http://localhost:12345"
90
+ end
91
+
92
+ $weather_service = ServiceDouble.hook_into(:rspec) do |config|
93
+ config.server = "fake_weather.rb"
94
+ config.url = "http://localhost:12346"
95
+ end
96
+
97
+ # later on:
98
+
99
+ $weather_service.post("/_stub_temp", :place => "New York", :temp => 22.4)
100
+ ```
101
+
102
+ Here are some methods that can be called on the service objects:
103
+
104
+ * **get** performs a GET request (maps to Faraday's `get` method)
105
+ * **post** performs a POST request (like `get`)
106
+ * **delete** etc...
107
+ * **put** etc...
108
+ * **post** etc...
109
+ * **reset** sends `DELETE` request to `/` (is done automatically between tests)
110
+
111
+ ## Contributing
112
+
113
+ 1. Fork it
114
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
115
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
116
+ 4. Push to the branch (`git push origin my-new-feature`)
117
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ require 'cucumber/rake/task'
7
+ Cucumber::Rake::Task.new(:cucumber) do |t|
8
+ t.cucumber_opts = "features --format pretty"
9
+ end
10
+
11
+ task :default => [:spec, :cucumber]
@@ -0,0 +1,9 @@
1
+ Feature: Service Double
2
+
3
+ Scenario: Remembering something
4
+ When I ask the fake server to remember "the fifth of November"
5
+ Then the fake server remembered to "the fifth of November"
6
+
7
+ Scenario: Forgetting everything between scenarios
8
+ When I am in a new scenario
9
+ Then the fake server should remember nothing from the previous scenario
@@ -0,0 +1,17 @@
1
+ When /^I ask the fake server to remember "(.*?)"$/ do |value|
2
+ $cucumber_server.post("/remember", :value => value)
3
+ end
4
+
5
+ Then /^the fake server remembered to "(.*?)"$/ do |value|
6
+ remembered = JSON.parse($cucumber_server.get("/remembered").body)
7
+ remembered.should eq "remembered" => [value]
8
+ end
9
+
10
+ When /^I am in a new scenario$/ do
11
+ # noop
12
+ end
13
+
14
+ Then /^the fake server should remember nothing from the previous scenario$/ do
15
+ remembered = JSON.parse($cucumber_server.get("/remembered").body)
16
+ remembered.should eq "remembered" => []
17
+ end
@@ -0,0 +1,10 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require 'service_double'
5
+ require 'json'
6
+
7
+ $cucumber_server = ServiceDouble.hook_into :cucumber do |config|
8
+ config.server = File.expand_path("../../../spec/support/rspec_server.rb", __FILE__)
9
+ config.url = "http://localhost:8083"
10
+ end
@@ -0,0 +1,38 @@
1
+ require "service_double/version"
2
+
3
+ module ServiceDouble
4
+
5
+ Error = Class.new(StandardError)
6
+ UnknownFramework = Class.new(Error)
7
+
8
+ require "service_double/manager"
9
+ require "service_double/configuration"
10
+
11
+ def self.hook_into(framework, &block)
12
+ require_relative "service_double/frameworks/#{framework}"
13
+ config = Configuration.new
14
+ yield config
15
+ manager = Manager.new(config)
16
+ managers << manager
17
+ manager
18
+ rescue LoadError
19
+ raise UnknownFramework, "No hooks provided for #{framework.inspect}."
20
+ end
21
+
22
+ def self.managers
23
+ @managers ||= []
24
+ end
25
+
26
+ def self.start
27
+ managers.each(&:start)
28
+ end
29
+
30
+ def self.stop
31
+ managers.each(&:stop)
32
+ end
33
+
34
+ def self.reset
35
+ managers.each(&:reset)
36
+ end
37
+
38
+ end
@@ -0,0 +1,52 @@
1
+ module ServiceDouble
2
+
3
+ NoURLSet = Class.new(Error)
4
+ NoServerSet = Class.new(Error)
5
+ ServerNotFound = Class.new(Error)
6
+
7
+ class Configuration
8
+
9
+ attr_accessor :url, :log_file, :timeout, :server
10
+
11
+ def initialize
12
+ @url = nil
13
+ @server = nil
14
+ @log_file = nil
15
+ @timeout = 2
16
+ end
17
+
18
+ def url
19
+ @url || no_url_set!
20
+ end
21
+
22
+ def server=(path)
23
+ full = File.expand_path(path)
24
+ if File.exist?(full)
25
+ @server = full
26
+ else
27
+ raise ServerNotFound, "Cannot find server to run at #{full}"
28
+ end
29
+ end
30
+
31
+ def server
32
+ @server || no_server_set!
33
+ end
34
+
35
+ def log_file
36
+ @log_file || "log/#{name}.log"
37
+ end
38
+
39
+ def name
40
+ File.basename(server, ".rb")
41
+ end
42
+
43
+ def no_url_set!
44
+ raise NoURLSet, "No URL set for the fake shop."
45
+ end
46
+
47
+ def no_server_set!
48
+ raise NoServerSet, "No server option set."
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,11 @@
1
+ AfterConfiguration do |config|
2
+ ServiceDouble.start
3
+ end
4
+
5
+ Before do
6
+ ServiceDouble.reset
7
+ end
8
+
9
+ at_exit do
10
+ ServiceDouble.stop
11
+ end
@@ -0,0 +1,15 @@
1
+ RSpec.configure do |config|
2
+
3
+ config.before(:suite) do
4
+ ServiceDouble.start
5
+ end
6
+
7
+ config.before(:each) do
8
+ ServiceDouble.reset
9
+ end
10
+
11
+ config.after(:suite) do
12
+ ServiceDouble.stop
13
+ end
14
+
15
+ end
@@ -0,0 +1,93 @@
1
+ require 'faraday'
2
+ require 'uri'
3
+ require 'verbose_hash_fetch'
4
+ require 'yaml'
5
+ require 'json'
6
+ require 'forwardable'
7
+ require 'fileutils'
8
+
9
+ module ServiceDouble
10
+
11
+ NotRunning = Class.new(Error)
12
+ NotStarted = Class.new(Error)
13
+ Timeout = Class.new(Error)
14
+
15
+ class Manager
16
+
17
+ extend Forwardable
18
+
19
+ def_delegators :connection, :get, :post, :head, :delete, :put, :patch
20
+
21
+ attr_reader :root_url, :log_file, :started_at, :timeout, :server, :name
22
+
23
+ def initialize(config)
24
+ @root_url = config.url
25
+ @log_file = config.log_file
26
+ @timeout = config.timeout
27
+ @server = config.server
28
+ @name = config.name
29
+ end
30
+
31
+ def start
32
+ FileUtils.mkdir_p(File.dirname(log_file)) if log_file.is_a?(String)
33
+ args = %w(ruby -r sinatra -r json) << server << "-p" << port
34
+ args << { :out => log_file, :err => log_file }
35
+ @pid = Process.spawn(*args)
36
+ @started_at = Time.now
37
+ wait until up?
38
+ end
39
+
40
+ def reset
41
+ delete("/")
42
+ end
43
+
44
+ def stop
45
+ if started?
46
+ Process.kill("TERM", @pid)
47
+ Process.waitpid(@pid)
48
+ end
49
+ end
50
+
51
+ def port
52
+ URI(root_url).port.to_s
53
+ end
54
+
55
+ def wait
56
+ unless timed_out?
57
+ sleep 0.01
58
+ else
59
+ raise Timeout, "It took more than #{timeout} seconds to start #{name}. Check the logs at #{log_file} to see why."
60
+ end
61
+ end
62
+
63
+ def up?
64
+ started? and running?
65
+ end
66
+
67
+ def started?
68
+ if @pid
69
+ Process.getpgid(@pid) rescue false
70
+ else
71
+ raise NotStarted, "The fake #{name} hasn't been started yet."
72
+ end
73
+ end
74
+
75
+ def running?
76
+ get("/").status == 200 rescue false
77
+ end
78
+
79
+ def timed_out?
80
+ Time.now - timeout > started_at
81
+ end
82
+
83
+ def connection
84
+ @connection ||= Faraday.new(url: root_url) { |faraday|
85
+ faraday.request :multipart
86
+ faraday.request :url_encoded
87
+ faraday.adapter Faraday.default_adapter
88
+ }
89
+ end
90
+
91
+ end
92
+
93
+ end
@@ -0,0 +1,3 @@
1
+ module ServiceDouble
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,26 @@
1
+ [2013-03-05 15:36:55] INFO WEBrick 1.3.1
2
+ [2013-03-05 15:36:55] INFO ruby 1.9.3 (2013-02-22) [x86_64-darwin12.2.0]
3
+ == Sinatra/1.3.5 has taken the stage on 8083 for development with backup from WEBrick
4
+ [2013-03-05 15:36:55] INFO WEBrick::HTTPServer#start: pid=51710 port=8083
5
+ 127.0.0.1 - - [05/Mar/2013 15:36:55] "GET / HTTP/1.1" 200 - 0.0022
6
+ localhost - - [05/Mar/2013:15:36:55 CET] "GET / HTTP/1.1" 200 0
7
+ - -> /
8
+ 127.0.0.1 - - [05/Mar/2013 15:36:55] "DELETE / HTTP/1.1" 200 - 0.0003
9
+ localhost - - [05/Mar/2013:15:36:55 CET] "DELETE / HTTP/1.1" 200 0
10
+ - -> /
11
+ 127.0.0.1 - - [05/Mar/2013 15:36:55] "POST /remember HTTP/1.1" 200 21 0.0003
12
+ localhost - - [05/Mar/2013:15:36:55 CET] "POST /remember HTTP/1.1" 200 21
13
+ - -> /remember
14
+ 127.0.0.1 - - [05/Mar/2013 15:36:55] "GET /remembered HTTP/1.1" 200 40 0.0003
15
+ localhost - - [05/Mar/2013:15:36:55 CET] "GET /remembered HTTP/1.1" 200 40
16
+ - -> /remembered
17
+ 127.0.0.1 - - [05/Mar/2013 15:36:55] "DELETE / HTTP/1.1" 200 - 0.0002
18
+ localhost - - [05/Mar/2013:15:36:55 CET] "DELETE / HTTP/1.1" 200 0
19
+ - -> /
20
+ 127.0.0.1 - - [05/Mar/2013 15:36:55] "GET /remembered HTTP/1.1" 200 17 0.0002
21
+ localhost - - [05/Mar/2013:15:36:55 CET] "GET /remembered HTTP/1.1" 200 17
22
+ - -> /remembered
23
+
24
+ == Sinatra has ended his set (crowd applauds)
25
+ [2013-03-05 15:36:57] INFO going to shutdown ...
26
+ [2013-03-05 15:36:57] INFO WEBrick::HTTPServer#start done.
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'service_double/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "service_double"
8
+ spec.version = ServiceDouble::VERSION
9
+ spec.authors = ["iain"]
10
+ spec.email = ["iain@iain.nl"]
11
+ spec.description = %q{A tool for making fake versions of external (web) services.}
12
+ spec.summary = %q{A tool for making fake versions of external (web) services.}
13
+ spec.homepage = "https://github.com/yourkarma/service_double"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "faraday"
22
+ spec.add_dependency "sinatra"
23
+ spec.add_dependency "verbose_hash_fetch"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.3"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "rspec"
28
+ spec.add_development_dependency "cucumber"
29
+ end
@@ -0,0 +1,27 @@
1
+ require 'service_double'
2
+ require 'json'
3
+
4
+ $rspec_server = ServiceDouble.hook_into :rspec do |config|
5
+ config.server = File.expand_path("../support/rspec_server.rb", __FILE__)
6
+ config.url = "http://localhost:8082"
7
+ end
8
+
9
+ describe ServiceDouble do
10
+
11
+ it "should be running" do
12
+ $rspec_server.should be_running
13
+ end
14
+
15
+ it "should receive requests" do
16
+ value = rand(10**26).to_s(26)
17
+ $rspec_server.post("/remember", value: value)
18
+ values = JSON.parse($rspec_server.get("/remembered").body)
19
+ values.should eq "remembered" => [value]
20
+ end
21
+
22
+ it "should not remember request from the previous test" do
23
+ values = JSON.parse($rspec_server.get("/remembered").body)
24
+ values.should eq "remembered" => []
25
+ end
26
+
27
+ end
@@ -0,0 +1,18 @@
1
+ values = []
2
+
3
+ get "/" do
4
+ 200
5
+ end
6
+
7
+ delete "/" do
8
+ values.clear
9
+ 200
10
+ end
11
+
12
+ post "/remember" do
13
+ values << params[:value]
14
+ end
15
+
16
+ get "/remembered" do
17
+ { :remembered => values }.to_json
18
+ end
metadata ADDED
@@ -0,0 +1,182 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: service_double
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - iain
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: faraday
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: sinatra
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: verbose_hash_fetch
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: bundler
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '1.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: '1.3'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rake
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: cucumber
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ description: A tool for making fake versions of external (web) services.
127
+ email:
128
+ - iain@iain.nl
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - .gitignore
134
+ - .rspec
135
+ - Gemfile
136
+ - LICENSE.txt
137
+ - README.md
138
+ - Rakefile
139
+ - features/service_double.feature
140
+ - features/step_definitions/service_double_steps.rb
141
+ - features/support/env.rb
142
+ - lib/service_double.rb
143
+ - lib/service_double/configuration.rb
144
+ - lib/service_double/frameworks/cucumber.rb
145
+ - lib/service_double/frameworks/rspec.rb
146
+ - lib/service_double/manager.rb
147
+ - lib/service_double/version.rb
148
+ - log/rspec_server.log
149
+ - service_double.gemspec
150
+ - spec/service_double_spec.rb
151
+ - spec/support/rspec_server.rb
152
+ homepage: https://github.com/yourkarma/service_double
153
+ licenses:
154
+ - MIT
155
+ post_install_message:
156
+ rdoc_options: []
157
+ require_paths:
158
+ - lib
159
+ required_ruby_version: !ruby/object:Gem::Requirement
160
+ none: false
161
+ requirements:
162
+ - - ! '>='
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ required_rubygems_version: !ruby/object:Gem::Requirement
166
+ none: false
167
+ requirements:
168
+ - - ! '>='
169
+ - !ruby/object:Gem::Version
170
+ version: '0'
171
+ requirements: []
172
+ rubyforge_project:
173
+ rubygems_version: 1.8.23
174
+ signing_key:
175
+ specification_version: 3
176
+ summary: A tool for making fake versions of external (web) services.
177
+ test_files:
178
+ - features/service_double.feature
179
+ - features/step_definitions/service_double_steps.rb
180
+ - features/support/env.rb
181
+ - spec/service_double_spec.rb
182
+ - spec/support/rspec_server.rb