endpoint_stub 1.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.idea/.name +1 -0
- data/.idea/.rakeTasks +7 -0
- data/.idea/dictionaries/devmini.xml +3 -0
- data/.idea/encodings.xml +5 -0
- data/.idea/endpoint_stub.iml +42 -0
- data/.idea/misc.xml +48 -0
- data/.idea/modules.xml +9 -0
- data/.idea/scopes/scope_settings.xml +5 -0
- data/.idea/vcs.xml +7 -0
- data/.rspec +4 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +98 -0
- data/Rakefile +1 -0
- data/endpoint_stub.gemspec +30 -0
- data/lib/endpoint/stub.rb +307 -0
- data/lib/endpoint_stub/version.rb +3 -0
- data/lib/endpoint_stub.rb +87 -0
- data/spec/endpoint/stub_spec.rb +146 -0
- data/spec/endpoint_stub_spec.rb +19 -0
- data/spec/spec_helper.rb +67 -0
- metadata +129 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: b16dff51967c4be2433bd1743c9fcd182775613e
|
|
4
|
+
data.tar.gz: f2b80f0274615d21885838acf3ce83a7b5e405d9
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 3f1f45d0961b3c4ad738d76789b5a49a8ef3170f0f64f390a07f139dd14035c85231d2599d063127941999b17013f4f903e6dcb6a144939285421739d4f04a94
|
|
7
|
+
data.tar.gz: ac4bf26b1026758711958739f75bbdcbb984454e63fdb32f8c1e7cf0829530bb7f4ec10d8aceaa667a73dbbc89d2158f4910fe5fae87a80993cf4670c33dfaa0
|
data/.gitignore
ADDED
data/.idea/.name
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
endpoint_stub
|
data/.idea/.rakeTasks
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<Settings><!--This file was automatically generated by Ruby plugin.
|
|
3
|
+
You are allowed to:
|
|
4
|
+
1. Remove rake task
|
|
5
|
+
2. Add existing rake tasks
|
|
6
|
+
To add existing rake tasks automatically delete this file and reload the project.
|
|
7
|
+
--><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Build endpoint_stub-0.0.1.gem into the pkg directory" fullCmd="build" taksId="build" /><RakeTask description="Build and install endpoint_stub-0.0.1.gem into system gems" fullCmd="install" taksId="install" /><RakeTask description="Create tag v0.0.1 and build and push endpoint_stub-0.0.1.gem to Rubygems" fullCmd="release" taksId="release" /></RakeGroup></Settings>
|
data/.idea/encodings.xml
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="RUBY_MODULE" version="4">
|
|
3
|
+
<component name="CompassSettings">
|
|
4
|
+
<option name="compassSupportEnabled" value="true" />
|
|
5
|
+
</component>
|
|
6
|
+
<component name="FacetManager">
|
|
7
|
+
<facet type="gem" name="Ruby Gem">
|
|
8
|
+
<configuration>
|
|
9
|
+
<option name="GEM_APP_ROOT_PATH" value="$MODULE_DIR$" />
|
|
10
|
+
<option name="GEM_APP_TEST_PATH" value="" />
|
|
11
|
+
<option name="GEM_APP_LIB_PATH" value="$MODULE_DIR$/lib" />
|
|
12
|
+
</configuration>
|
|
13
|
+
</facet>
|
|
14
|
+
</component>
|
|
15
|
+
<component name="NewModuleRootManager">
|
|
16
|
+
<content url="file://$MODULE_DIR$" />
|
|
17
|
+
<orderEntry type="inheritedJdk" />
|
|
18
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
19
|
+
<orderEntry type="library" scope="PROVIDED" name="activemodel (v4.0.8, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
20
|
+
<orderEntry type="library" scope="PROVIDED" name="activeresource (v4.0.0, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
21
|
+
<orderEntry type="library" scope="PROVIDED" name="activesupport (v4.0.8, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
22
|
+
<orderEntry type="library" scope="PROVIDED" name="addressable (v2.3.6, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
23
|
+
<orderEntry type="library" scope="PROVIDED" name="builder (v3.1.4, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
24
|
+
<orderEntry type="library" scope="PROVIDED" name="bundler (v1.5.3, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
25
|
+
<orderEntry type="library" scope="PROVIDED" name="crack (v0.4.2, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
26
|
+
<orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.2.5, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
27
|
+
<orderEntry type="library" scope="PROVIDED" name="i18n (v0.6.11, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
28
|
+
<orderEntry type="library" scope="PROVIDED" name="multi_json (v1.10.1, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
29
|
+
<orderEntry type="library" scope="PROVIDED" name="rails-observers (v0.1.2, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
30
|
+
<orderEntry type="library" scope="PROVIDED" name="rake (v10.3.2, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
31
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec (v3.0.0, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
32
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.0.2, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
33
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.0.2, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
34
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.0.2, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
35
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.0.2, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
36
|
+
<orderEntry type="library" scope="PROVIDED" name="safe_yaml (v1.0.3, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
37
|
+
<orderEntry type="library" scope="PROVIDED" name="thread_safe (v0.3.4, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
38
|
+
<orderEntry type="library" scope="PROVIDED" name="tzinfo (v0.3.40, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
39
|
+
<orderEntry type="library" scope="PROVIDED" name="webmock (v1.18.0, RVM: ruby-2.1.1) [gem]" level="application" />
|
|
40
|
+
</component>
|
|
41
|
+
</module>
|
|
42
|
+
|
data/.idea/misc.xml
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="ProjectInspectionProfilesVisibleTreeState">
|
|
4
|
+
<entry key="Project Default">
|
|
5
|
+
<profile-state>
|
|
6
|
+
<expanded-state>
|
|
7
|
+
<State>
|
|
8
|
+
<id />
|
|
9
|
+
</State>
|
|
10
|
+
<State>
|
|
11
|
+
<id>Cucumber</id>
|
|
12
|
+
</State>
|
|
13
|
+
<State>
|
|
14
|
+
<id>Naming ConventionsRuby</id>
|
|
15
|
+
</State>
|
|
16
|
+
<State>
|
|
17
|
+
<id>Rails</id>
|
|
18
|
+
</State>
|
|
19
|
+
<State>
|
|
20
|
+
<id>Ruby</id>
|
|
21
|
+
</State>
|
|
22
|
+
</expanded-state>
|
|
23
|
+
<selected-state>
|
|
24
|
+
<State>
|
|
25
|
+
<id>CoffeeScript</id>
|
|
26
|
+
</State>
|
|
27
|
+
</selected-state>
|
|
28
|
+
</profile-state>
|
|
29
|
+
</entry>
|
|
30
|
+
</component>
|
|
31
|
+
<component name="ProjectRootManager" version="2" project-jdk-name="RVM: ruby-2.1.1" project-jdk-type="RUBY_SDK" />
|
|
32
|
+
<component name="masterDetails">
|
|
33
|
+
<states>
|
|
34
|
+
<state key="ScopeChooserConfigurable.UI">
|
|
35
|
+
<settings>
|
|
36
|
+
<splitter-proportions>
|
|
37
|
+
<option name="proportions">
|
|
38
|
+
<list>
|
|
39
|
+
<option value="0.2" />
|
|
40
|
+
</list>
|
|
41
|
+
</option>
|
|
42
|
+
</splitter-proportions>
|
|
43
|
+
</settings>
|
|
44
|
+
</state>
|
|
45
|
+
</states>
|
|
46
|
+
</component>
|
|
47
|
+
</project>
|
|
48
|
+
|
data/.idea/modules.xml
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="ProjectModuleManager">
|
|
4
|
+
<modules>
|
|
5
|
+
<module fileurl="file://$PROJECT_DIR$/.idea/endpoint_stub.iml" filepath="$PROJECT_DIR$/.idea/endpoint_stub.iml" />
|
|
6
|
+
</modules>
|
|
7
|
+
</component>
|
|
8
|
+
</project>
|
|
9
|
+
|
data/.idea/vcs.xml
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2014 Resonious
|
|
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,98 @@
|
|
|
1
|
+
# EndpointStub
|
|
2
|
+
|
|
3
|
+
I found that testing solutions for ActiveResource were either sub-optimal or
|
|
4
|
+
outdated, so I decided to make my own using WebMock.
|
|
5
|
+
|
|
6
|
+
EndpointStub is kind of like the built in ActiveResource HTTPMock, except
|
|
7
|
+
you can bind logic and dynamic routes to it, so it's like a mini controller
|
|
8
|
+
almost. EndpointStub comes with the default RESTful CRUD actions supported
|
|
9
|
+
by ActiveResource build in (currently JSON format only). It also comes with
|
|
10
|
+
an interface for defining your own routes and logic.
|
|
11
|
+
|
|
12
|
+
Nested resources are currently pending, but definitely implementable via custom
|
|
13
|
+
response mocking.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
Add this line to your application's Gemfile:
|
|
18
|
+
|
|
19
|
+
gem 'endpoint_stub'
|
|
20
|
+
|
|
21
|
+
And then execute:
|
|
22
|
+
|
|
23
|
+
$ bundle
|
|
24
|
+
|
|
25
|
+
Or install it yourself as:
|
|
26
|
+
|
|
27
|
+
$ gem install endpoint_stub
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
Add
|
|
32
|
+
|
|
33
|
+
require 'endpoint_stub'
|
|
34
|
+
|
|
35
|
+
to your spec_helper / test_helper.
|
|
36
|
+
Then, in your tests, you can call
|
|
37
|
+
|
|
38
|
+
Endpoint::Stub.create_for(MyActiveResourceModel)
|
|
39
|
+
|
|
40
|
+
which will bring MyActiveResourceModel to life!
|
|
41
|
+
Here is a more in-depth example.
|
|
42
|
+
|
|
43
|
+
class Greeter < ActiveResource::Base
|
|
44
|
+
def say_hi_to(someone)
|
|
45
|
+
"#{self.greeting}, someone"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
self.site = "http://example.com/api/greeter"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
Endpoint::Stub.create_for(Greeter)
|
|
52
|
+
record = Greeter.create(greeting: 'hello')
|
|
53
|
+
record.say_hi_to('sir') # ===> "hello, sir"
|
|
54
|
+
|
|
55
|
+
record.greeting = 'hey...'
|
|
56
|
+
record.save # ===> true
|
|
57
|
+
record.greeting # ===> 'hey...'
|
|
58
|
+
|
|
59
|
+
record.destroy
|
|
60
|
+
record.destroyed? # ===> true
|
|
61
|
+
|
|
62
|
+
Greeter.create(greeting: 'hi')
|
|
63
|
+
Greeter.create(greeting: 'ahoy')
|
|
64
|
+
|
|
65
|
+
Greeter.all # ===> [{id: 1, greeting: 'hi'}, {id: 2, greeting: 'ahoy'}]
|
|
66
|
+
|
|
67
|
+
Also, custom responses and default attributes:
|
|
68
|
+
|
|
69
|
+
class Test < ActiveResource::Base
|
|
70
|
+
self.site = "http://example.com/api/whatever"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
Endpoint::Stub.create_for(Test) do
|
|
74
|
+
add_default test_attr: 'nice'
|
|
75
|
+
|
|
76
|
+
mock_response(:put, '/:id/change') do |response, params, stub|
|
|
77
|
+
stub.update_record params[:id], test_attr: '*changed*'
|
|
78
|
+
{ body: "did it" }
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
record = Test.create
|
|
83
|
+
record.test_attr # ===> 'nice'
|
|
84
|
+
record.put(:change).body # ===> 'did it'
|
|
85
|
+
record.reload
|
|
86
|
+
record.test_attr # ===> '*changed*'
|
|
87
|
+
|
|
88
|
+
Afterwards, custom responses can be un-mocked:
|
|
89
|
+
|
|
90
|
+
Endpoint::Stub[Test].unmock_response(:put, '/:id/change') # ===> true
|
|
91
|
+
|
|
92
|
+
## Contributing
|
|
93
|
+
|
|
94
|
+
1. Fork it ( http://github.com/<my-github-username>/endpoint_stub/fork )
|
|
95
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
96
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
97
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
98
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'endpoint_stub/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "endpoint_stub"
|
|
8
|
+
spec.version = EndpointStub::VERSION
|
|
9
|
+
spec.authors = ["Nigel Baillie"]
|
|
10
|
+
spec.email = ["metreckk@gmail.com"]
|
|
11
|
+
spec.summary = %q{Uses WebMock to intercept http requests to perform basic CRUD operations with ActiveResource.}
|
|
12
|
+
spec.description = %q{
|
|
13
|
+
Kind of like the built-in HttpMock that ActiveResource comes with, except EntpointStub
|
|
14
|
+
actually creates and destroys records, and also allows you to bind custom logic to a
|
|
15
|
+
particular path. Kind of like a controller.
|
|
16
|
+
}
|
|
17
|
+
spec.homepage = ""
|
|
18
|
+
spec.license = "MIT"
|
|
19
|
+
|
|
20
|
+
spec.files = `git ls-files -z`.split("\x0")
|
|
21
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
22
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
23
|
+
spec.require_paths = ["lib"]
|
|
24
|
+
|
|
25
|
+
spec.add_development_dependency "activeresource"
|
|
26
|
+
spec.add_development_dependency "webmock"
|
|
27
|
+
|
|
28
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
|
29
|
+
spec.add_development_dependency "rake"
|
|
30
|
+
end
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
require 'endpoint_stub'
|
|
2
|
+
require 'webmock'
|
|
3
|
+
|
|
4
|
+
module Endpoint
|
|
5
|
+
##
|
|
6
|
+
# Represents a stubbed endpoint that creates, updates,
|
|
7
|
+
# destroys, and stores data based on http requests.
|
|
8
|
+
class Stub
|
|
9
|
+
@stubs = {}
|
|
10
|
+
class << self
|
|
11
|
+
attr_reader :stubs
|
|
12
|
+
##
|
|
13
|
+
# Creates a fake endpoint for the given ActiveResource model.
|
|
14
|
+
#
|
|
15
|
+
# The options hash currently only accepts :defaults, which allows
|
|
16
|
+
# you to define default attribute values for the endpoint to
|
|
17
|
+
# consider on record creation.
|
|
18
|
+
#
|
|
19
|
+
# If a block is supplied, it will be executed in the context
|
|
20
|
+
# of the new Endpoint::Stub, allowing you to elegantly mock
|
|
21
|
+
# custom responses if needed.
|
|
22
|
+
def create_for(model, options={}, &block)
|
|
23
|
+
model = assure_model model
|
|
24
|
+
return if stubs.keys.include? model
|
|
25
|
+
new_stub = Stub.new(model, options)
|
|
26
|
+
|
|
27
|
+
EndpointStub::Config.default_responses.each do |response|
|
|
28
|
+
new_stub.mock_response(*response)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
@stubs[model] = new_stub
|
|
32
|
+
|
|
33
|
+
new_stub.instance_eval(&block) if block_given?
|
|
34
|
+
new_stub
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
##
|
|
38
|
+
# Removes fake endpoint for the given model, meaning any
|
|
39
|
+
# ActiveResource activity on the model will raise errors
|
|
40
|
+
# once again.
|
|
41
|
+
def clear_for(model)
|
|
42
|
+
stubs.delete assure_model model
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def get_for(model)
|
|
46
|
+
@stubs[assure_model(model)]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
##
|
|
50
|
+
# Clears all endpoint stubs.
|
|
51
|
+
def clear!
|
|
52
|
+
@stubs = {}
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
##
|
|
56
|
+
# Gets or creates a stub for the given model.
|
|
57
|
+
# i.e. Endpoint::Stub[Post]
|
|
58
|
+
def [](model)
|
|
59
|
+
create_for model or get_for model
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
def assure_model(model)
|
|
64
|
+
if model.ancestors.include? ActiveResource::Base
|
|
65
|
+
model
|
|
66
|
+
else
|
|
67
|
+
Kernel.const_get model
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
attr_reader :defaults
|
|
73
|
+
attr_reader :model
|
|
74
|
+
attr_accessor :records
|
|
75
|
+
def initialize(model, options)
|
|
76
|
+
@defaults = options[:defaults] || {}
|
|
77
|
+
|
|
78
|
+
@model = model
|
|
79
|
+
@site = URI "#{model.site}/#{model.name.underscore.pluralize}"
|
|
80
|
+
|
|
81
|
+
@responses = {}
|
|
82
|
+
|
|
83
|
+
@records = []
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
##
|
|
87
|
+
# Adds a record to the stub, automatically assigning an id as though
|
|
88
|
+
# it were in a database.
|
|
89
|
+
def add_record(attrs)
|
|
90
|
+
unless attrs.is_a? Hash
|
|
91
|
+
raise "Endpoint::Stub#add_record expects a Hash. Got #{attrs.class.name}."
|
|
92
|
+
end
|
|
93
|
+
attrs[:id] = current_id
|
|
94
|
+
attrs.merge!(@defaults) { |k,a,b| a }
|
|
95
|
+
@records << attrs
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
##
|
|
99
|
+
# Updates the record with the given id with the given attributes.
|
|
100
|
+
def update_record(id, attrs)
|
|
101
|
+
unless attrs.is_a? Hash
|
|
102
|
+
raise "Endpoint::Stub#update_record expects a Hash. Got #{attrs.class.name}."
|
|
103
|
+
end
|
|
104
|
+
id = id.to_i
|
|
105
|
+
if @records[id]
|
|
106
|
+
@records[id].merge! attrs
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
##
|
|
111
|
+
# Removes the record with the given id from the fake database.
|
|
112
|
+
def remove_record(id)
|
|
113
|
+
id = id.to_i
|
|
114
|
+
if @records[id]
|
|
115
|
+
@records[id] = nil
|
|
116
|
+
true
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def record(id)
|
|
121
|
+
@records[id.to_i]
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
##
|
|
125
|
+
# The last assigned id.
|
|
126
|
+
def last_id
|
|
127
|
+
@records.count-1
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
##
|
|
131
|
+
# The next id for a record to be assigned to.
|
|
132
|
+
def current_id
|
|
133
|
+
@records.count
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
##
|
|
137
|
+
# The name of the represented model in underscore notation.
|
|
138
|
+
def model_name
|
|
139
|
+
@model.name.underscore
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
##
|
|
143
|
+
# Gets the url location for the given id, as used by RESTful
|
|
144
|
+
# record creation.
|
|
145
|
+
def location(id)
|
|
146
|
+
site = @site.to_s[-1] == '/' ? @site.to_s[0...-1] : @site
|
|
147
|
+
"#{site}/#{id}"
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
##
|
|
151
|
+
# Adds default attributes for record creation.
|
|
152
|
+
def add_default(attrs)
|
|
153
|
+
@defaults.merge!(attrs)
|
|
154
|
+
end
|
|
155
|
+
alias_method :add_defaults, :add_default
|
|
156
|
+
|
|
157
|
+
##
|
|
158
|
+
# Mock a custom response. Requires a type (http mthod), and route.
|
|
159
|
+
# This method will override any previous responses assigned to the
|
|
160
|
+
# given type and route.
|
|
161
|
+
#
|
|
162
|
+
# The route is the uri relative to the record's assigned site and
|
|
163
|
+
# can be formatted similarly to rails routes. Such as:
|
|
164
|
+
# '/test/:some_param.json'
|
|
165
|
+
# or
|
|
166
|
+
# '.xml' to simply imply the model's site with '.xml' appended.
|
|
167
|
+
#
|
|
168
|
+
# Lastly, a proc or block is needed to actually handle requests.
|
|
169
|
+
# The proc will be called with the request object, the extracted
|
|
170
|
+
# parameters from the uri, and the stub object so that you can
|
|
171
|
+
# interact with the stubbed records.
|
|
172
|
+
def mock_response(type, route='', proc=nil, &block)
|
|
173
|
+
proc = block if block_given?
|
|
174
|
+
|
|
175
|
+
route = clean_route route
|
|
176
|
+
|
|
177
|
+
site = "#{@site.scheme}://#{@site.host}"
|
|
178
|
+
path = @site.path.split(/\/+/).reject(&:empty?)
|
|
179
|
+
if route[0] == '.' && !route.include?('/')
|
|
180
|
+
# This allows passing '.json', etc as the route
|
|
181
|
+
if path.last
|
|
182
|
+
path = path[0...-1] + [path.last+route]
|
|
183
|
+
else
|
|
184
|
+
site += route
|
|
185
|
+
end
|
|
186
|
+
else
|
|
187
|
+
path += route.split('/')
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
@responses[type] ||= {}
|
|
191
|
+
@responses[type][route] = Response.new(type, URI.parse(site+'/'+path.join('/')), self, &proc)
|
|
192
|
+
@responses[type][route].activate!
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
##
|
|
196
|
+
# Remove a mocked response with the given type and route.
|
|
197
|
+
def unmock_response(type, route)
|
|
198
|
+
route = clean_route route
|
|
199
|
+
if @responses[type] && @responses[type][route]
|
|
200
|
+
@responses[type][route].deactivate!
|
|
201
|
+
@responses[type][route] = nil
|
|
202
|
+
true
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
private
|
|
207
|
+
def clean_route(route)
|
|
208
|
+
route = route[1..-1] if route[0] == '/'
|
|
209
|
+
route = route[0...-1] if route[-1] == '/'
|
|
210
|
+
route
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
class Response
|
|
214
|
+
include WebMock::API
|
|
215
|
+
|
|
216
|
+
# For remembering where a uri-based parameter is located.
|
|
217
|
+
ParamIndices = Struct.new(:slash, :dot)
|
|
218
|
+
# Allows more comfortable use of Symbol keys when accessing
|
|
219
|
+
# params (which are string keys).
|
|
220
|
+
class Params < Hash
|
|
221
|
+
def [](key)
|
|
222
|
+
super(key.to_s)
|
|
223
|
+
end
|
|
224
|
+
def []=(key, value)
|
|
225
|
+
super(key.to_s, value)
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def initialize(type, url, stub, &proc)
|
|
230
|
+
@param_indices = {}
|
|
231
|
+
|
|
232
|
+
@url_regex = build_url_regex!(url)
|
|
233
|
+
|
|
234
|
+
@type = type
|
|
235
|
+
@proc = proc
|
|
236
|
+
@stub = stub
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# Should be called only once, internally to perform the actual WebMock stubbing.
|
|
240
|
+
def activate!
|
|
241
|
+
@stubbed_request = stub_request(@type, @url_regex).to_return do |request|
|
|
242
|
+
params = extract_params(request)
|
|
243
|
+
|
|
244
|
+
results = @proc.call(request, params, @stub)
|
|
245
|
+
results[:body] = results[:body].to_json unless results[:body].is_a? String
|
|
246
|
+
results
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# This should remove the request stubbed by #activate!
|
|
251
|
+
def deactivate!
|
|
252
|
+
remove_request_stub @stubbed_request
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
private
|
|
256
|
+
# Bang is there because this method populates @param_indices.
|
|
257
|
+
def build_url_regex!(url)
|
|
258
|
+
regex = ""
|
|
259
|
+
separate(url).each_with_index do |x, slash_index|
|
|
260
|
+
regex += '/' unless slash_index == 0
|
|
261
|
+
# If there is a colon, it's a parameter. i.e. /resource/:id.json
|
|
262
|
+
if x.include? ':' and !(x[1..-1] =~ /^\d$/) # If it's just numbers, it's probably a port number
|
|
263
|
+
# We split by dot at this point to separate the parameter from any
|
|
264
|
+
# format/domain related suffix.
|
|
265
|
+
dot_split = x.split('.')
|
|
266
|
+
inner_regex = []
|
|
267
|
+
|
|
268
|
+
dot_split.each_with_index do |name, dot_index|
|
|
269
|
+
# A parameter can show up after a dot as well. i.e. /resource/:id.:format
|
|
270
|
+
inner_regex << if name.include? ':'
|
|
271
|
+
param_name = name[1..-1]
|
|
272
|
+
@param_indices[param_name] = ParamIndices.new(slash_index, dot_index)
|
|
273
|
+
# Add .+ regex to capture any data at this point in the url.
|
|
274
|
+
".+"
|
|
275
|
+
else
|
|
276
|
+
# If there's no colon, it's a static part of the target url.
|
|
277
|
+
Regexp.escape(name)
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# "inner_regex" was built by splitting on dots, so we put the dots back.
|
|
282
|
+
regex += inner_regex.join('\.')
|
|
283
|
+
else
|
|
284
|
+
# No colon, so this segment is static.
|
|
285
|
+
regex += Regexp.escape(x)
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
Regexp.new regex
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def extract_params(request)
|
|
292
|
+
url = separate request.uri
|
|
293
|
+
params = Params.new
|
|
294
|
+
@param_indices.each do |param_name, index|
|
|
295
|
+
value = url[index.slash].split('.')[index.dot]
|
|
296
|
+
|
|
297
|
+
params[param_name] = value
|
|
298
|
+
end
|
|
299
|
+
params
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def separate(url)
|
|
303
|
+
url.to_s[url.to_s.index('://')+3..-1].split '/'
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
require "endpoint_stub/version"
|
|
2
|
+
require 'endpoint/stub'
|
|
3
|
+
require 'webmock'
|
|
4
|
+
|
|
5
|
+
module EndpointStub
|
|
6
|
+
class Config
|
|
7
|
+
class << self
|
|
8
|
+
attr_accessor :activated
|
|
9
|
+
attr_accessor :default_responses
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Enable endpoint stubbing.
|
|
14
|
+
# This will cause all HTTP requests to raise an error,
|
|
15
|
+
# as per WebMock, unless relating to an ActiveResource
|
|
16
|
+
# model.
|
|
17
|
+
def self.activate!
|
|
18
|
+
return if Config.activated
|
|
19
|
+
WebMock.enable!
|
|
20
|
+
Config.activated = true
|
|
21
|
+
end
|
|
22
|
+
# Disable endpoint stubbing.
|
|
23
|
+
# This allows real HTTP requests again.
|
|
24
|
+
def self.deactivate!
|
|
25
|
+
return unless Config.activated
|
|
26
|
+
WebMock.disable!
|
|
27
|
+
Config.activated = false
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Calls deactivate, clears all stubs, then re-activates.
|
|
31
|
+
def self.refresh!
|
|
32
|
+
deactivate!
|
|
33
|
+
Endpoint::Stub.clear!
|
|
34
|
+
activate!
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Feel free to add to these, and they will be applied to every
|
|
38
|
+
# stubbed endpoint thereafter.
|
|
39
|
+
Config.default_responses = [
|
|
40
|
+
### Index ###
|
|
41
|
+
[:get, '.json', ->(request, params, stub) {
|
|
42
|
+
{ body: stub.records }
|
|
43
|
+
}],
|
|
44
|
+
|
|
45
|
+
### Show ###
|
|
46
|
+
[:get, '/:id.json', ->(request, params, stub) {
|
|
47
|
+
{ body: stub.records[params[:id].to_i] }
|
|
48
|
+
}],
|
|
49
|
+
|
|
50
|
+
### Create ###
|
|
51
|
+
[:post, '.json', ->(request, params, stub) {
|
|
52
|
+
stub.add_record(JSON.parse(request.body))
|
|
53
|
+
{ body: '',
|
|
54
|
+
status: 201,
|
|
55
|
+
headers: { 'Location' => stub.location(stub.last_id) }
|
|
56
|
+
}
|
|
57
|
+
}],
|
|
58
|
+
|
|
59
|
+
### Update ###
|
|
60
|
+
[:put, '/:id.json', ->(request, params, stub) {
|
|
61
|
+
if stub.update_record(params[:id], JSON.parse(request.body))
|
|
62
|
+
{ body: '', status: 204}
|
|
63
|
+
else
|
|
64
|
+
{ body: "Failed to find #{stub.model_name} with id #{params[:id]}",
|
|
65
|
+
status: 404 }
|
|
66
|
+
end
|
|
67
|
+
}],
|
|
68
|
+
|
|
69
|
+
### Destroy ###
|
|
70
|
+
[:delete, '/:id.json', ->(request, params, stub) {
|
|
71
|
+
if stub.remove_record(params[:id])
|
|
72
|
+
{ body: '', status: 200}
|
|
73
|
+
else
|
|
74
|
+
{ body: "Failed to find #{stub.model_name} with id #{params[:id]}",
|
|
75
|
+
status: 404 }
|
|
76
|
+
end
|
|
77
|
+
}]
|
|
78
|
+
]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
class Array
|
|
82
|
+
def to_json
|
|
83
|
+
'['+map do |e|
|
|
84
|
+
e.respond_to?(:to_json) ? e.to_json : e.to_s
|
|
85
|
+
end.join(', ')+']'
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
class TestModel < ActiveResource::Base
|
|
4
|
+
self.site = "http://www.not-a-site.com/api"
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
describe Endpoint::Stub, stub_spec: true do
|
|
8
|
+
before(:each) { EndpointStub.refresh! }
|
|
9
|
+
|
|
10
|
+
describe '.stubs' do
|
|
11
|
+
it 'should be a global hash of endpoint stubs, {modle => endpoint_stub}' do
|
|
12
|
+
expect(Endpoint::Stub.stubs).to be_a Hash
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
context 'http requests' do
|
|
17
|
+
it 'should fail when nothing is stubbed' do
|
|
18
|
+
expect{Net::HTTP.get "whocares.com", '/'}.to raise_error WebMock::NetConnectNotAllowedError
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe '.create_for' do
|
|
23
|
+
it 'should create a new Endpoint::Stub for the given ActiveResource model' do
|
|
24
|
+
Endpoint::Stub.create_for TestModel
|
|
25
|
+
expect(Endpoint::Stub.stubs.keys).to include TestModel
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'should be able to set default attributes' do
|
|
29
|
+
Endpoint::Stub.create_for(TestModel, {defaults: { test_attr: 'hey' }})
|
|
30
|
+
expect(Endpoint::Stub[TestModel].defaults.keys).to include :test_attr
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe '.clear_for' do
|
|
35
|
+
it 'should remove the Endpoint::Stub entry for the given ActiveResource model' do
|
|
36
|
+
Endpoint::Stub.create_for TestModel
|
|
37
|
+
Endpoint::Stub.clear_for TestModel
|
|
38
|
+
expect(Endpoint::Stub.stubs.keys).to_not include TestModel
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
context 'With a stubbed model' do
|
|
44
|
+
let!(:test_model_stub) { Endpoint::Stub.create_for(TestModel) }
|
|
45
|
+
after(:each) do
|
|
46
|
+
Endpoint::Stub.clear_for TestModel
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
describe '.find' do
|
|
50
|
+
it 'retrieves the model' do
|
|
51
|
+
test_model_stub.records << { id: 0, test_attr: 'hey' }
|
|
52
|
+
test_model_stub.records << { id: 1, test_attr: 'nice!' }
|
|
53
|
+
|
|
54
|
+
subject = TestModel.find 1
|
|
55
|
+
expect(subject.test_attr).to eq 'nice!'
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe '.all' do
|
|
60
|
+
it 'retrieves all of the models' do
|
|
61
|
+
test_model_stub.records << { id: 0, test_attr: 'first!' }
|
|
62
|
+
test_model_stub.records << { id: 1, test_attr: 'even better' }
|
|
63
|
+
|
|
64
|
+
subjects = TestModel.all
|
|
65
|
+
expect(subjects.count).to eq 2
|
|
66
|
+
expect(subjects.first.test_attr).to eq 'first!'
|
|
67
|
+
expect(subjects.last.test_attr).to eq 'even better'
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
describe 'setting record attributes' do
|
|
72
|
+
it 'should work' do
|
|
73
|
+
subject = TestModel.new
|
|
74
|
+
subject.test_attr = "heyyyyyyy"
|
|
75
|
+
subject.save
|
|
76
|
+
expect(subject.test_attr).to eq "heyyyyyyy"
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
describe 'creating a new record' do
|
|
81
|
+
it 'should work' do
|
|
82
|
+
subject = TestModel.new
|
|
83
|
+
subject.test_attr = "alright...."
|
|
84
|
+
subject.save
|
|
85
|
+
expect(subject.test_attr).to eq 'alright....'
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it 'should work with .create method' do
|
|
89
|
+
subject = TestModel.create(test_attr: 'wow')
|
|
90
|
+
expect(subject.id).to eq '0'
|
|
91
|
+
expect(subject.test_attr).to eq 'wow'
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
describe 'destroying a record' do
|
|
96
|
+
it 'should work' do
|
|
97
|
+
test_model_stub.records << { id: 0, test_attr: 'first!' }
|
|
98
|
+
test_model_stub.records << { id: 1, test_attr: 'even better' }
|
|
99
|
+
|
|
100
|
+
TestModel.find(0).destroy
|
|
101
|
+
|
|
102
|
+
expect{TestModel.find(0)}.to raise_error
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
describe 'the mocked responses' do
|
|
107
|
+
it 'should be removable' do
|
|
108
|
+
test_model_stub.records << { id: 0, test_attr: 'hey' }
|
|
109
|
+
|
|
110
|
+
expect{TestModel.find(0).test_attr}.to_not raise_error
|
|
111
|
+
|
|
112
|
+
expect(
|
|
113
|
+
test_model_stub.unmock_response(:get, '/:id.json')
|
|
114
|
+
).to be_truthy
|
|
115
|
+
|
|
116
|
+
expect{TestModel.find(0).test_attr}.to raise_error
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
describe 'custom response' do
|
|
121
|
+
it 'should be addable to existing stubs' do
|
|
122
|
+
test_model_stub.records << { id: 0, test_attr: 'hey' }
|
|
123
|
+
|
|
124
|
+
test_model_stub.mock_response(:put, '/:id/change') do |response, params, stub|
|
|
125
|
+
stub.update_record params[:id], test_attr: '*changed*'
|
|
126
|
+
{ body: "did it" }
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
subject = TestModel.find(0)
|
|
130
|
+
expect(subject.test_attr).to_not eq '*changed*'
|
|
131
|
+
expect(subject.put(:change).body).to eq 'did it'
|
|
132
|
+
subject.reload
|
|
133
|
+
expect(subject.test_attr).to eq '*changed*'
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it 'should be removable' do
|
|
137
|
+
test_model_stub.mock_response(:put, '/test') do |r,p,s|
|
|
138
|
+
{ body: 'test' }
|
|
139
|
+
end
|
|
140
|
+
expect{TestModel.put(:test)}.to_not raise_error
|
|
141
|
+
test_model_stub.unmock_response(:put, '/test')
|
|
142
|
+
expect{TestModel.put(:test)}.to raise_error
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe EndpointStub, endpoint_stub_spec: true do
|
|
4
|
+
describe '.activate!' do
|
|
5
|
+
it 'should make http requests raise WebMock::NetConnectNotAllowedError' do
|
|
6
|
+
EndpointStub.activate!
|
|
7
|
+
expect{Net::HTTP.get "test.com", "/nothing"}.to raise_error WebMock::NetConnectNotAllowedError
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe '.deactivate!' do
|
|
12
|
+
it 'should allow http requests once again' do
|
|
13
|
+
# TODO make this account for not being connected to the internet.
|
|
14
|
+
EndpointStub.activate!
|
|
15
|
+
EndpointStub.deactivate!
|
|
16
|
+
expect{Net::HTTP.get "example.com", "/foo"}.to_not raise_error
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'endpoint_stub'
|
|
2
|
+
require 'endpoint/stub'
|
|
3
|
+
require 'net/http'
|
|
4
|
+
require 'active_resource'
|
|
5
|
+
|
|
6
|
+
RSpec.configure do |config|
|
|
7
|
+
# The settings below are suggested to provide a good initial experience
|
|
8
|
+
# with RSpec, but feel free to customize to your heart's content.
|
|
9
|
+
=begin
|
|
10
|
+
# These two settings work together to allow you to limit a spec run
|
|
11
|
+
# to individual examples or groups you care about by tagging them with
|
|
12
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
|
13
|
+
# get run.
|
|
14
|
+
config.filter_run :focus
|
|
15
|
+
config.run_all_when_everything_filtered = true
|
|
16
|
+
|
|
17
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
|
18
|
+
# file, and it's useful to allow more verbose output when running an
|
|
19
|
+
# individual spec file.
|
|
20
|
+
if config.files_to_run.one?
|
|
21
|
+
# Use the documentation formatter for detailed output,
|
|
22
|
+
# unless a formatter has already been configured
|
|
23
|
+
# (e.g. via a command-line flag).
|
|
24
|
+
config.default_formatter = 'doc'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Print the 10 slowest examples and example groups at the
|
|
28
|
+
# end of the spec run, to help surface which specs are running
|
|
29
|
+
# particularly slow.
|
|
30
|
+
config.profile_examples = 10
|
|
31
|
+
|
|
32
|
+
# Run specs in random order to surface order dependencies. If you find an
|
|
33
|
+
# order dependency and want to debug it, you can fix the order by providing
|
|
34
|
+
# the seed, which is printed after each run.
|
|
35
|
+
# --seed 1234
|
|
36
|
+
config.order = :random
|
|
37
|
+
|
|
38
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
|
39
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
|
40
|
+
# test failures related to randomization by passing the same `--seed` value
|
|
41
|
+
# as the one that triggered the failure.
|
|
42
|
+
Kernel.srand config.seed
|
|
43
|
+
|
|
44
|
+
# rspec-expectations config goes here. You can use an alternate
|
|
45
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
|
46
|
+
# assertions if you prefer.
|
|
47
|
+
config.expect_with :rspec do |expectations|
|
|
48
|
+
# Enable only the newer, non-monkey-patching expect syntax.
|
|
49
|
+
# For more details, see:
|
|
50
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
|
51
|
+
expectations.syntax = :expect
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
|
55
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
|
56
|
+
config.mock_with :rspec do |mocks|
|
|
57
|
+
# Enable only the newer, non-monkey-patching expect syntax.
|
|
58
|
+
# For more details, see:
|
|
59
|
+
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
|
60
|
+
mocks.syntax = :expect
|
|
61
|
+
|
|
62
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
|
63
|
+
# a real object. This is generally recommended.
|
|
64
|
+
mocks.verify_partial_doubles = true
|
|
65
|
+
end
|
|
66
|
+
=end
|
|
67
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: endpoint_stub
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Nigel Baillie
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-07-17 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: activeresource
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: webmock
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: bundler
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '1.5'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '1.5'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rake
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
description: "\n Kind of like the built-in HttpMock that ActiveResource comes with,
|
|
70
|
+
except EntpointStub\n actually creates and destroys records, and also allows
|
|
71
|
+
you to bind custom logic to a\n particular path. Kind of like a controller.\n
|
|
72
|
+
\ "
|
|
73
|
+
email:
|
|
74
|
+
- metreckk@gmail.com
|
|
75
|
+
executables: []
|
|
76
|
+
extensions: []
|
|
77
|
+
extra_rdoc_files: []
|
|
78
|
+
files:
|
|
79
|
+
- ".gitignore"
|
|
80
|
+
- ".idea/.name"
|
|
81
|
+
- ".idea/.rakeTasks"
|
|
82
|
+
- ".idea/dictionaries/devmini.xml"
|
|
83
|
+
- ".idea/encodings.xml"
|
|
84
|
+
- ".idea/endpoint_stub.iml"
|
|
85
|
+
- ".idea/misc.xml"
|
|
86
|
+
- ".idea/modules.xml"
|
|
87
|
+
- ".idea/scopes/scope_settings.xml"
|
|
88
|
+
- ".idea/vcs.xml"
|
|
89
|
+
- ".rspec"
|
|
90
|
+
- Gemfile
|
|
91
|
+
- LICENSE.txt
|
|
92
|
+
- README.md
|
|
93
|
+
- Rakefile
|
|
94
|
+
- endpoint_stub.gemspec
|
|
95
|
+
- lib/endpoint/stub.rb
|
|
96
|
+
- lib/endpoint_stub.rb
|
|
97
|
+
- lib/endpoint_stub/version.rb
|
|
98
|
+
- spec/endpoint/stub_spec.rb
|
|
99
|
+
- spec/endpoint_stub_spec.rb
|
|
100
|
+
- spec/spec_helper.rb
|
|
101
|
+
homepage: ''
|
|
102
|
+
licenses:
|
|
103
|
+
- MIT
|
|
104
|
+
metadata: {}
|
|
105
|
+
post_install_message:
|
|
106
|
+
rdoc_options: []
|
|
107
|
+
require_paths:
|
|
108
|
+
- lib
|
|
109
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
110
|
+
requirements:
|
|
111
|
+
- - ">="
|
|
112
|
+
- !ruby/object:Gem::Version
|
|
113
|
+
version: '0'
|
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
115
|
+
requirements:
|
|
116
|
+
- - ">="
|
|
117
|
+
- !ruby/object:Gem::Version
|
|
118
|
+
version: '0'
|
|
119
|
+
requirements: []
|
|
120
|
+
rubyforge_project:
|
|
121
|
+
rubygems_version: 2.2.2
|
|
122
|
+
signing_key:
|
|
123
|
+
specification_version: 4
|
|
124
|
+
summary: Uses WebMock to intercept http requests to perform basic CRUD operations
|
|
125
|
+
with ActiveResource.
|
|
126
|
+
test_files:
|
|
127
|
+
- spec/endpoint/stub_spec.rb
|
|
128
|
+
- spec/endpoint_stub_spec.rb
|
|
129
|
+
- spec/spec_helper.rb
|