rspec-eventually 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 992247ed8e9a18a6a7e7f9f29c7a280f85a47661
4
+ data.tar.gz: e953bbb93dacf3c94e34b094c193323a44b49c82
5
+ SHA512:
6
+ metadata.gz: a71003af10bfc2782af1320b628c4bf3ed81af1ff9d2edf032b52fbcbbb9ab60f5e73522ceb25332748ea948e6bdf05a2cc7669291c3a81dd47c7f4ff555c1dc
7
+ data.tar.gz: 91de91764868bbbca2ccf45e2bd19c508d06ea0f6c1a54dcc8a304a50179720ca264cdba092920a4e7e5b19723bb307b131cf7a672e351accf45ba73518596fa
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format doc
data/.rubocop.yml ADDED
@@ -0,0 +1,15 @@
1
+ # This configuration was generated by `rubocop --auto-gen-config`
2
+ # on 2015-01-08 10:47:58 -0800 using RuboCop version 0.27.1.
3
+ # The point is for the user to remove these configuration records
4
+ # one by one as the offenses are removed from the code base.
5
+ # Note that changes in the inspected code, or installation of new
6
+ #
7
+ Metrics/LineLength:
8
+ Max: 100
9
+
10
+ Style/Documentation:
11
+ Enabled: false
12
+
13
+ Style/DotPosition:
14
+ Enabled: true
15
+ EnforcedStyle: trailing
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
4
+ before_install: gem install bundler -v 1.9.4
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rspec-eventually.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Hawk Newton
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,52 @@
1
+ [![Build Status](https://travis-ci.org/hawknewton/rspec-eventually.svg?branch=master)](https://travis-ci.org/hawknewton/rspec-eventually)
2
+ # Rspec::Eventually
3
+
4
+ I want to be able to do something like this:
5
+
6
+ ```ruby
7
+ it 'eventually matches' do
8
+ value = 0
9
+ Thread.new do
10
+ sleep 1
11
+ value = 1
12
+ end
13
+
14
+ expect { value }.to eventually eq 1
15
+ expect { value }.to eventually_not eq 0
16
+
17
+ # Ignore errors raised by the block and retry
18
+ expect { client.get 'ABC' }.to eventually(eq 1).by_suppressing_errors
19
+
20
+ # Change the timeout
21
+ expect { client.get 'ZYX' }.to eventually(eq 1).within 5
22
+
23
+ end
24
+ ```
25
+
26
+ ## Installation
27
+
28
+ Add this line to your application's Gemfile:
29
+
30
+ ```ruby
31
+ gem 'rspec-eventually'
32
+ ```
33
+
34
+ And then execute:
35
+
36
+ $ bundle
37
+
38
+ Or install it yourself as:
39
+
40
+ $ gem install rspec-eventually
41
+
42
+ ## Usage
43
+
44
+ TODO: Write usage instructions here
45
+
46
+ ## Contributing
47
+
48
+ 1. Fork it ( https://github.com/[my-github-username]/rspec-eventually/fork )
49
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
50
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
51
+ 4. Push to the branch (`git push origin my-new-feature`)
52
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rubocop/rake_task'
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ RuboCop::RakeTask.new
7
+
8
+ task default: [:spec, :rubocop]
@@ -0,0 +1,5 @@
1
+ module Rspec
2
+ module Eventually
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
@@ -0,0 +1,90 @@
1
+ require 'rspec/eventually/version'
2
+ require 'rspec'
3
+
4
+ module Rspec
5
+ module Eventually
6
+ class << self
7
+ attr_accessor :timeout
8
+ end
9
+ self.timeout = 5
10
+
11
+ class FailedMatcherError < StandardError; end
12
+
13
+ class Eventually
14
+ def by_suppressing_errors
15
+ tap { @suppress_errors = true }
16
+ end
17
+
18
+ def initialize(target)
19
+ @target = target
20
+ @tries = 0
21
+ @negative = false
22
+ end
23
+
24
+ def matches?(expected_block)
25
+ Timeout.timeout(timeout) { eventually_matches? expected_block }
26
+ rescue Timeout::Error
27
+ @tries == 0 && raise('Timeout before first evaluation, use a longer `eventually` timeout')
28
+ end
29
+
30
+ def does_not_match?
31
+ fail 'Use eventually_not instead of expect(...).to_not'
32
+ end
33
+
34
+ def failure_message
35
+ "After #{@tries} tries, the last failure message was:\n#{@target.failure_message}"
36
+ end
37
+
38
+ def not
39
+ tap { @negative = true }
40
+ end
41
+
42
+ def supports_block_expectations?
43
+ true
44
+ end
45
+
46
+ def suppress_errors
47
+ @suppress_errors || false
48
+ end
49
+
50
+ def within(timeout)
51
+ tap { @timeout = timeout }
52
+ end
53
+
54
+ private
55
+
56
+ def eventually_matches?(expected_block)
57
+ target_matches?(expected_block) || fail(FailedMatcherError)
58
+ rescue => e
59
+ if suppress_errors || e.is_a?(FailedMatcherError)
60
+ sleep 0.1
61
+ @tries += 1
62
+ retry
63
+ else
64
+ raise
65
+ end
66
+ end
67
+
68
+ def target_matches?(expected_block)
69
+ result = @target.matches? expected_block.call
70
+ @negative ? !result : result
71
+ end
72
+
73
+ def timeout
74
+ @timeout || Rspec::Eventually.timeout
75
+ end
76
+ end
77
+
78
+ def eventually(target)
79
+ Eventually.new target
80
+ end
81
+
82
+ def eventually_not(target)
83
+ Eventually.new(target).not
84
+ end
85
+
86
+ RSpec.configure do |config|
87
+ config.include ::Rspec::Eventually
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rspec/eventually/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'rspec-eventually'
8
+ spec.version = Rspec::Eventually::VERSION
9
+ spec.authors = ['Hawk Newton']
10
+ spec.email = ['hawk.newton@gmail.com']
11
+ spec.summary = 'Make your matchers match eventually'
12
+ spec.description = 'Enhances rspec DSL to include `eventually` and `eventually_not`'
13
+ spec.homepage = 'https://github.com/hawknewton/rspec-eventually'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(/^(test|spec|features)\//)
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.7'
22
+ spec.add_development_dependency 'rake', '~> 10.0'
23
+ spec.add_development_dependency 'rspec', '~> 3.2'
24
+ spec.add_development_dependency 'rubocop', '~> 0.27.1'
25
+ end
@@ -0,0 +1,102 @@
1
+ module Rspec
2
+ module Eventually
3
+ describe Eventually do
4
+
5
+ it 'eventually matches' do
6
+ value = 0
7
+ Thread.new do
8
+ sleep 0.5
9
+ value = 1
10
+ end
11
+
12
+ expect(Eventually.new(eq 1).matches? -> { value }).to be true
13
+ end
14
+
15
+ it 'eventually_not matches' do
16
+ value = 0
17
+ Thread.new do
18
+ sleep 0.5
19
+ value = 1
20
+ end
21
+
22
+ expect(Eventually.new(eq 0).not.matches? -> { value }).to be true
23
+ end
24
+
25
+ it 'eventually fails' do
26
+ expect(Eventually.new(eq 1).matches? -> { 0 }).to be false
27
+ end
28
+
29
+ it 'eventually_not fails' do
30
+ expect(Eventually.new(eq 1).not.matches? -> { 1 }).to be false
31
+ end
32
+
33
+ it 'has a configurable default timeout' do
34
+ begin
35
+ ::Rspec::Eventually.timeout = 1
36
+ expect(::Rspec::Eventually.timeout).to eq 1
37
+
38
+ before = Time.now
39
+ Eventually.new(eq 1).matches? -> { 0 }
40
+ took = Time.now - before
41
+ expect(took).to be_within(0.5).of 1
42
+ ensure
43
+ ::Rspec::Eventually.timeout = 5
44
+ end
45
+ end
46
+
47
+ it 'can have a specific timeout' do
48
+ before = Time.now
49
+ Eventually.new(eq 1).within(0.5).matches? -> { 0 }
50
+ took = Time.now - before
51
+ expect(took).to be_within(0.1).of 0.5
52
+ end
53
+
54
+ it 'raises errors by default' do
55
+ block = lambda do
56
+ Eventually.new(eq 1).matches? -> { fail 'I am throwing an error' }
57
+ end
58
+
59
+ expect { block.call }.to raise_error(/I am throwing an error/)
60
+ end
61
+
62
+ it 'can suppress errors' do
63
+ first = false
64
+ block = lambda do
65
+
66
+ one_eventually = lambda do
67
+ if first
68
+ first = false
69
+ fail 'I am throwing an error'
70
+ end
71
+ 1
72
+ end
73
+
74
+ Eventually.new(eq 1).by_suppressing_errors.matches? one_eventually
75
+ end
76
+
77
+ expect { block.call }.to_not raise_error
78
+ expect(block.call).to be true
79
+ end
80
+
81
+ it 'produces a coherent failure message' do
82
+ (matcher = Eventually.new(eq 1).within(0.5)).matches? -> { 0 }
83
+ message = matcher.failure_message
84
+ expect(message).to match(/After [0-9]+ tries, the last failure message was/)
85
+ expect(message).to match(/expected: 1/)
86
+ expect(message).to match(/got: 0/)
87
+ end
88
+
89
+ it 'raises an error when negated' do
90
+ expect { Eventually.new(eq 1).does_not_match? }.to raise_error(/Use eventually_not/)
91
+ end
92
+
93
+ it 'raises an error when timeout occurs before the first evaluation' do
94
+ block = lambda do
95
+ Eventually.new(eq 1).within(0.5).matches? -> { sleep 5 }
96
+ end
97
+
98
+ expect { block.call }.to raise_error(/Timeout before first evaluation/)
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,43 @@
1
+ require 'rspec/eventually'
2
+ # This file was generated by the `rspec --init` command. Conventionally, all
3
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
4
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
5
+ # this file to always be loaded, without a need to explicitly require it in any
6
+ # files.
7
+ #
8
+ # Given that it is always loaded, you are encouraged to keep this file as
9
+ # light-weight as possible. Requiring heavyweight dependencies from this file
10
+ # will add to the boot time of your test suite on EVERY test run, even for an
11
+ # individual file that may not need all of that loaded. Instead, consider making
12
+ # a separate helper file that requires the additional dependencies and performs
13
+ # the additional setup, and require it from the spec files that actually need
14
+ # it.
15
+ #
16
+ # The `.rspec` file also contains a few flags that are not defaults but that
17
+ # users commonly want.
18
+ #
19
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
20
+ RSpec.configure do |config|
21
+ # rspec-expectations config goes here. You can use an alternate
22
+ # assertion/expectation library such as wrong or the stdlib/minitest
23
+ # assertions if you prefer.
24
+ config.expect_with :rspec do |expectations|
25
+ # This option will default to `true` in RSpec 4. It makes the `description`
26
+ # and `failure_message` of custom matchers include text for helper methods
27
+ # defined using `chain`, e.g.:
28
+ # be_bigger_than(2).and_smaller_than(4).description
29
+ # # => "be bigger than 2 and smaller than 4"
30
+ # ...rather than:
31
+ # # => "be bigger than 2"
32
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
33
+ end
34
+
35
+ # rspec-mocks config goes here. You can use an alternate test double
36
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
37
+ config.mock_with :rspec do |mocks|
38
+ # Prevents you from mocking or stubbing a method that does not exist on
39
+ # a real object. This is generally recommended, and will default to
40
+ # `true` in RSpec 4.
41
+ mocks.verify_partial_doubles = true
42
+ end
43
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspec-eventually
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Hawk Newton
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.2'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.27.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.27.1
69
+ description: Enhances rspec DSL to include `eventually` and `eventually_not`
70
+ email:
71
+ - hawk.newton@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".rspec"
78
+ - ".rubocop.yml"
79
+ - ".travis.yml"
80
+ - Gemfile
81
+ - LICENSE.txt
82
+ - README.md
83
+ - Rakefile
84
+ - lib/rspec/eventually.rb
85
+ - lib/rspec/eventually/version.rb
86
+ - rspec-eventually.gemspec
87
+ - spec/eventually_spec.rb
88
+ - spec/spec_helper.rb
89
+ homepage: https://github.com/hawknewton/rspec-eventually
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.4.5
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: Make your matchers match eventually
113
+ test_files:
114
+ - spec/eventually_spec.rb
115
+ - spec/spec_helper.rb