rest_easy 1.0.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.
- data/.gitignore +14 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +70 -0
- data/Rakefile +2 -0
- data/lib/rest_easy.rb +28 -0
- data/lib/rest_easy/version.rb +3 -0
- data/rest_easy.gemspec +26 -0
- data/spec/rest_easy_spec.rb +74 -0
- metadata +121 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Johnson Denen
|
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,70 @@
|
|
1
|
+
# RestEasy
|
2
|
+
|
3
|
+
The `rest_easy` gem allows you to call an API until its response passes validation (a block) or times out. It's inspired by the `wait_until` functionality common to webdrivers, and I've found it useful in my acceptance testing.
|
4
|
+
|
5
|
+
## Example
|
6
|
+
|
7
|
+
I've had tests that may have looked like this:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
it "saves my edit" do
|
11
|
+
page_object.field = "Something"
|
12
|
+
page_object.save
|
13
|
+
sleep 5
|
14
|
+
expect(JSON.load(RestClient.get "/call/to/my/API")['data']['field']).to eq('Something')
|
15
|
+
end
|
16
|
+
```
|
17
|
+
|
18
|
+
We waited 5 seconds because it could take 1-5 seconds for us to see our edit reflected in the API response (for whatever reason). That's kind of annyoing, especially if it would have only taken 1 second to see the correct response. So, with rest_reasy, the test can look like this:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
it "saves my edit" do
|
22
|
+
page_object.field = "Something"
|
23
|
+
page_object.save
|
24
|
+
expect(RestEasy.get_until("/call/to/my/API", 5){|data| JSON.load(data)['data']['field'] == 'Something'}).to be_truthy
|
25
|
+
end
|
26
|
+
```
|
27
|
+
|
28
|
+
Our test now only waits until it gets the response it needs. If that takes 1 second, then our test is 4 seconds faster! If we've broken some functionality, the test will fail after 5 seconds.
|
29
|
+
|
30
|
+
## Installation
|
31
|
+
|
32
|
+
Add this line to your application's Gemfile:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
gem 'rest_easy'
|
36
|
+
```
|
37
|
+
|
38
|
+
And then execute:
|
39
|
+
|
40
|
+
$ bundle
|
41
|
+
|
42
|
+
Or install it yourself as:
|
43
|
+
|
44
|
+
$ gem install rest_easy
|
45
|
+
|
46
|
+
## Usage
|
47
|
+
|
48
|
+
Use `RestEasy.get_until` if you're testing the truthiness of a validation. Use `RestEasy.get_while` if you're testing falseness of a validation. Both methods require a valid URI and a validation block. Optionally, you can pass a timeout in seconds (defaults to 10) and an options hash that will be passed to RestClient.
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
# fails after 10 seconds
|
52
|
+
RestEasy.get_until('http://twitter.com'){ 1 == 0 }
|
53
|
+
|
54
|
+
# fails after 3 seconds
|
55
|
+
RestEasy.get_while('http://twitter.com', 3){ 1 == 1 }
|
56
|
+
|
57
|
+
# pass the GET response to your validation block
|
58
|
+
RestEasy.get_until('http://twitter.com'){ |response| response.code == 200 }
|
59
|
+
|
60
|
+
# add cookies to your GET request with the options hash
|
61
|
+
RestEasy.get_while('http://twitter.com', 10, cookies: {auth_token: 'blah'}){ |response| response.code == 403 }
|
62
|
+
```
|
63
|
+
|
64
|
+
## Contributing
|
65
|
+
|
66
|
+
1. Fork it ( https://github.com/[my-github-username]/rest_easy/fork )
|
67
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
68
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
69
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
70
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/lib/rest_easy.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require "rest-client"
|
2
|
+
require "rest_easy/version"
|
3
|
+
|
4
|
+
module RestEasy
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def get_until uri, timeout = 10, opts = {}, &block
|
8
|
+
iterate timeout do
|
9
|
+
result = RestClient.get(uri, opts){ |resp| yield resp }
|
10
|
+
return result if result
|
11
|
+
sleep 0.5
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_while uri, timeout = 10, opts = {}, &block
|
16
|
+
iterate timeout do
|
17
|
+
result = RestClient.get(uri, opts){ |resp| yield resp }
|
18
|
+
return !result unless result
|
19
|
+
sleep 0.5
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def iterate timeout, &block
|
24
|
+
end_time = Time.now + timeout
|
25
|
+
yield block until Time.now > end_time
|
26
|
+
false
|
27
|
+
end
|
28
|
+
end
|
data/rest_easy.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rest_easy/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rest_easy"
|
8
|
+
spec.version = RestEasy::VERSION
|
9
|
+
spec.authors = ["Johnson Denen"]
|
10
|
+
spec.email = ["jdenen@manta.com"]
|
11
|
+
spec.summary = %q{Test an API call until its response passes validation or times out.}
|
12
|
+
spec.description = %q{Test an API call until its response passes validation or times out.}
|
13
|
+
spec.homepage = "http://github.com/jdenen/rest_easy"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
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_runtime_dependency "rest-client"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
+
spec.add_development_dependency "rspec"
|
26
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'rest_easy'
|
3
|
+
|
4
|
+
describe RestEasy do
|
5
|
+
describe ".get_until" do
|
6
|
+
context "with passing validation" do
|
7
|
+
it "passes uri and options to RestClient" do
|
8
|
+
expect(RestClient).to receive(:get).with('url', header: 'header').once.and_return(true)
|
9
|
+
RestEasy.get_until('url', 1, header: 'header'){ |r| r }
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns true after one iteration" do
|
13
|
+
expect(RestClient).to receive(:get).once.and_return(true)
|
14
|
+
expect(RestEasy.get_until('url'){ |r| r }).to be_truthy
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "with failing validation" do
|
19
|
+
it "returns false" do
|
20
|
+
expect(RestClient).to receive(:get).twice.and_return(false)
|
21
|
+
expect(RestEasy.get_until('url', 1){ |r| r }).to be_falsey
|
22
|
+
end
|
23
|
+
|
24
|
+
it "times out after 10 seconds default" do
|
25
|
+
start_time = Time.now
|
26
|
+
expect(RestClient).to receive(:get).exactly(20).times.and_return(false)
|
27
|
+
RestEasy.get_until('url'){ |r| r }
|
28
|
+
expect(Time.now - start_time).to be > 10
|
29
|
+
end
|
30
|
+
|
31
|
+
it "times out after n seconds" do
|
32
|
+
start_time = Time.now
|
33
|
+
expect(RestClient).to receive(:get).exactly(6).times.and_return(false)
|
34
|
+
RestEasy.get_until('url', 3){ |r| r }
|
35
|
+
expect(Time.now - start_time).to be_within(1).of(3).and be > 3
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe ".get_while" do
|
41
|
+
context "with passing validation" do
|
42
|
+
it "passes uri and options to RestClient" do
|
43
|
+
expect(RestClient).to receive(:get).with('url', header: 'header').once.and_return(false)
|
44
|
+
RestEasy.get_while('url', 1, header: 'header'){ |r| r }
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns true after one iteration" do
|
48
|
+
expect(RestClient).to receive(:get).once.and_return(false)
|
49
|
+
expect(RestEasy.get_while('url'){ |r| r }).to be_truthy
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "with failing validation" do
|
54
|
+
it "returns false" do
|
55
|
+
expect(RestClient).to receive(:get).twice.and_return(true)
|
56
|
+
expect(RestEasy.get_while('url', 1){ |r| r }).to be_falsey
|
57
|
+
end
|
58
|
+
|
59
|
+
it "times out after 10 seconds by default" do
|
60
|
+
start_time = Time.now
|
61
|
+
expect(RestClient).to receive(:get).exactly(20).times.and_return(true)
|
62
|
+
RestEasy.get_while('url'){ |r| r }
|
63
|
+
expect(Time.now - start_time).to be > 10
|
64
|
+
end
|
65
|
+
|
66
|
+
it "times out after n seconds" do
|
67
|
+
start_time = Time.now
|
68
|
+
expect(RestClient).to receive(:get).exactly(6).times.and_return(true)
|
69
|
+
RestEasy.get_while('url', 3){ |r| r }
|
70
|
+
expect(Time.now - start_time).to be_within(1).of(3).and be > 3
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rest_easy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Johnson Denen
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-11-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rest-client
|
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: bundler
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.7'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.7'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '10.0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
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: '0'
|
78
|
+
description: Test an API call until its response passes validation or times out.
|
79
|
+
email:
|
80
|
+
- jdenen@manta.com
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- .gitignore
|
86
|
+
- Gemfile
|
87
|
+
- LICENSE.txt
|
88
|
+
- README.md
|
89
|
+
- Rakefile
|
90
|
+
- lib/rest_easy.rb
|
91
|
+
- lib/rest_easy/version.rb
|
92
|
+
- rest_easy.gemspec
|
93
|
+
- spec/rest_easy_spec.rb
|
94
|
+
homepage: http://github.com/jdenen/rest_easy
|
95
|
+
licenses:
|
96
|
+
- MIT
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
none: false
|
103
|
+
requirements:
|
104
|
+
- - ! '>='
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ! '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
requirements: []
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 1.8.23.2
|
116
|
+
signing_key:
|
117
|
+
specification_version: 3
|
118
|
+
summary: Test an API call until its response passes validation or times out.
|
119
|
+
test_files:
|
120
|
+
- spec/rest_easy_spec.rb
|
121
|
+
has_rdoc:
|