ergomentum_rspec 1.3.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/Gemfile +5 -0
- data/README.md +62 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/ergomentum_rspec.gemspec +32 -0
- data/lib/ergomentum_rspec.rb +16 -0
- data/lib/ergomentum_rspec/helpers/environment.rb +15 -0
- data/lib/ergomentum_rspec/helpers/fixture.rb +27 -0
- data/lib/ergomentum_rspec/matchers/active_model.rb +15 -0
- data/lib/ergomentum_rspec/matchers/active_model/be_invalid_for.rb +57 -0
- data/lib/ergomentum_rspec/matchers/active_model/be_valid_for.rb +43 -0
- data/lib/ergomentum_rspec/matchers/array.rb +18 -0
- data/lib/ergomentum_rspec/matchers/array/be_monotonically_decreasing.rb +31 -0
- data/lib/ergomentum_rspec/matchers/array/be_monotonically_increasing.rb +31 -0
- data/lib/ergomentum_rspec/matchers/array/be_strictly_decreasing.rb +31 -0
- data/lib/ergomentum_rspec/matchers/array/be_strictly_increasing.rb +31 -0
- data/lib/ergomentum_rspec/matchers/array/be_unique.rb +30 -0
- data/lib/ergomentum_rspec/matchers/performance.rb +14 -0
- data/lib/ergomentum_rspec/matchers/performance/allocate_objects.rb +94 -0
- data/lib/ergomentum_rspec/matchers/yield.rb +14 -0
- data/lib/ergomentum_rspec/matchers/yield/yield_all.rb +64 -0
- data/lib/ergomentum_rspec/version.rb +5 -0
- metadata +233 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1be2f4dbd6207d59937bb9e9428f969f50060d452d72ee13930be52c77114f73
|
4
|
+
data.tar.gz: c6ad0baad96d8334730fad66c79b9f35935d6a59c8dda165d5898392a5c1712d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6298b845ca13d986ba8ba4288d4a3131559065bf3fbe54ca839b0c185a7ec66b314ea0f7c15841cb034a04d94335d0adc9d82012d37b5ecca5f8fb23e30c7c50
|
7
|
+
data.tar.gz: d10d3053bf0e4b11d6606ba7eca2b2bb81de29d0283d3d845c16076f9693850387eeeb51ef3e4182dc09e6f8f6c7b633888ab1515eff0e35f270ef4dca5d939c
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# Ergomentum Rspec Matcher
|
2
|
+
|
3
|
+
[](
|
4
|
+
https://depfu.com/repos/github/ergomentum/ergomentum_rspec?project_id=17277)
|
5
|
+
[](
|
6
|
+
https://codeclimate.com/repos/5f9734dfabc428018c0022a0/maintainability)
|
7
|
+
[](
|
8
|
+
https://codeclimate.com/repos/5f9734dfabc428018c0022a0/test_coverage)
|
9
|
+
[](
|
10
|
+
https://circleci.com/gh/ergomentum/ergomentum_rspec)
|
11
|
+
|
12
|
+
The missing [rspec matchers](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/custom-matchers) and helpers not
|
13
|
+
found somewhere else.
|
14
|
+
|
15
|
+
## Array matchers
|
16
|
+
|
17
|
+
See specs for examples.
|
18
|
+
|
19
|
+
[Credits](https://rcode5.wordpress.com/2013/06/07/custom-rspec-matchers-for-arrays/)
|
20
|
+
|
21
|
+
## yield matchers
|
22
|
+
|
23
|
+
See specs for examples.
|
24
|
+
|
25
|
+
## Performance matchers
|
26
|
+
|
27
|
+
Utilize the [allocation_stats](https://github.com/srawlins/allocation_stats) Gem. This allows to assure memory
|
28
|
+
consumption. It might be useful after fixing memory holes.
|
29
|
+
|
30
|
+
See specs for examples.
|
31
|
+
|
32
|
+
[Credits](https://www.honeybadger.io/blog/testing-object-allocations/)
|
33
|
+
|
34
|
+
## Development
|
35
|
+
|
36
|
+
Create a PR to make changes. If your change is intended to release a new gem version increment the gem version in
|
37
|
+
`lib/ergomentum_rspec/version.rb` ([semantic versioning](https://semver.org/)).
|
38
|
+
|
39
|
+
After your PR is merged into `main` the gem is build by GitHub actions and deployed to
|
40
|
+
[https://github.com/ergomentum/ergomentum_rspec/packages](https://github.com/ergomentum/ergomentum_rspec/packages).
|
41
|
+
|
42
|
+
Build locally:
|
43
|
+
|
44
|
+
```bash
|
45
|
+
gem build ergomentum_rspec
|
46
|
+
```
|
47
|
+
|
48
|
+
## Resources
|
49
|
+
|
50
|
+
RSpec documentation for [Custom Matchers](
|
51
|
+
https://relishapp.com/rspec/rspec-expectations/v/3-9/docs/custom-matchers/define-a-custom-matcher).
|
52
|
+
|
53
|
+
To inspect Rspec details look into the [built in matcher implementations](
|
54
|
+
https://github.com/rspec/rspec-expectations/tree/master/lib/rspec/matchers/built_in). As well as into the
|
55
|
+
[`RSpec::Matchers::Composable`](
|
56
|
+
https://github.com/rspec/rspec-expectations/blob/master/lib/rspec/matchers/composable.rb) class.
|
57
|
+
|
58
|
+
Or have a look into the the [`shoulda-matchers`](https://github.com/thoughtbot/shoulda-matchers) implementation [work](
|
59
|
+
https://thoughtbot.com/blog/shoulda-matchers).
|
60
|
+
|
61
|
+
Blog article about the [different ways to write custom matchers](
|
62
|
+
https://makandracards.com/makandra/662-write-custom-rspec-matchers).
|
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "ergomentum_rspec"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative "lib/ergomentum_rspec/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
|
5
|
+
spec.name = "ergomentum_rspec"
|
6
|
+
spec.version = ErgomentumRspec::VERSION
|
7
|
+
spec.authors = ["Ergomentum"]
|
8
|
+
spec.email = ["info@ergomentum.de"]
|
9
|
+
spec.summary = "Provides regular used rspec custom matchers"
|
10
|
+
spec.description = "Regular used rspec matchers not found somewhere else."
|
11
|
+
spec.homepage = "https://www.ergomentum.de/"
|
12
|
+
spec.licenses = "Nonstandard"
|
13
|
+
|
14
|
+
spec.files = Dir.glob("{bin,lib}/**/*") + %w[README.md Gemfile ergomentum_rspec.gemspec]
|
15
|
+
spec.bindir = "exe"
|
16
|
+
spec.executables = spec.files.grep(%r{^exe/}, &:basename)
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
spec.required_ruby_version = ">= 3.0.1"
|
19
|
+
|
20
|
+
spec.add_development_dependency "byebug", "~> 11.1.3"
|
21
|
+
spec.add_development_dependency "rake", "~> 13.0.1"
|
22
|
+
spec.add_development_dependency "rspec_junit_formatter", "~> 0.4.1"
|
23
|
+
spec.add_development_dependency "rubocop", "~> 1.8"
|
24
|
+
spec.add_development_dependency "rubocop-performance", "~> 1.9"
|
25
|
+
spec.add_development_dependency "rubocop-rake"
|
26
|
+
spec.add_development_dependency "simplecov", "~> 0.21.2"
|
27
|
+
spec.add_development_dependency "test-prof", "~> 1.0.2"
|
28
|
+
spec.add_dependency "activemodel", "~> 6.0"
|
29
|
+
spec.add_dependency "activesupport", "~> 6.0"
|
30
|
+
spec.add_dependency "allocation_stats", "~> 0.1.5"
|
31
|
+
spec.add_dependency "rspec", "~> 3.9"
|
32
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "allocation_stats"
|
4
|
+
require "active_support/inflector"
|
5
|
+
# It's important to load Rspec before calling RSpec.configure:
|
6
|
+
require "rspec"
|
7
|
+
require "active_model"
|
8
|
+
require_relative "ergomentum_rspec/version"
|
9
|
+
require_relative "ergomentum_rspec/helpers/environment"
|
10
|
+
require_relative "ergomentum_rspec/helpers/fixture"
|
11
|
+
require_relative "ergomentum_rspec/matchers/active_model"
|
12
|
+
require_relative "ergomentum_rspec/matchers/array"
|
13
|
+
require_relative "ergomentum_rspec/matchers/performance"
|
14
|
+
require_relative "ergomentum_rspec/matchers/yield"
|
15
|
+
|
16
|
+
module ErgomentumRspec; end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErgomentumRspec
|
4
|
+
module Helpers
|
5
|
+
module Environment
|
6
|
+
def mock_environment_variables(options)
|
7
|
+
stub_const("ENV", ENV.to_h.merge(options))
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
config.include Environment
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErgomentumRspec
|
4
|
+
module Helpers
|
5
|
+
module Fixture
|
6
|
+
def load_fixture(relative_path)
|
7
|
+
File.read(fixture(relative_path))
|
8
|
+
end
|
9
|
+
|
10
|
+
def fixture(relative_path)
|
11
|
+
fixtures_directory / relative_path
|
12
|
+
end
|
13
|
+
|
14
|
+
def fixtures_directory
|
15
|
+
spec_directory / "fixtures"
|
16
|
+
end
|
17
|
+
|
18
|
+
def spec_directory
|
19
|
+
Pathname.getwd / "spec"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
RSpec.configure do |config|
|
24
|
+
config.include Fixture
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "active_model/be_invalid_for"
|
4
|
+
require_relative "active_model/be_valid_for"
|
5
|
+
|
6
|
+
module ErgomentumRspec
|
7
|
+
module Matchers
|
8
|
+
module ActiveModel
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.include ErgomentumRspec::Matchers::ActiveModel
|
15
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErgomentumRspec
|
4
|
+
module Matchers
|
5
|
+
module ActiveModel
|
6
|
+
def be_invalid_for(value)
|
7
|
+
BeInvalidFor.new(value)
|
8
|
+
end
|
9
|
+
|
10
|
+
class BeInvalidFor
|
11
|
+
def initialize(value)
|
12
|
+
@value = value
|
13
|
+
end
|
14
|
+
|
15
|
+
def matches?(validator)
|
16
|
+
model = Class.new do
|
17
|
+
include ::ActiveModel::Model
|
18
|
+
include ::ActiveModel::Attributes
|
19
|
+
|
20
|
+
# ActiveModel sometimes needs a non nil class name.
|
21
|
+
# Because we are using an anonymous class, which have no name by default, we have to override the name
|
22
|
+
# method.
|
23
|
+
def self.name
|
24
|
+
"SomeClass"
|
25
|
+
end
|
26
|
+
|
27
|
+
attribute :some_attribute
|
28
|
+
validates :some_attribute, validator
|
29
|
+
end.new(some_attribute: @value)
|
30
|
+
if model.valid?
|
31
|
+
@message = "expecting '#{@value}' to be invalid"
|
32
|
+
false
|
33
|
+
elsif model.errors.messages[:some_attribute].include?(@expected_error_message)
|
34
|
+
true
|
35
|
+
else
|
36
|
+
@message = "expecting error message '#{@expected_error_message}' for invalid value '#{@value}' but got "\
|
37
|
+
"'#{model.errors.messages[:some_attribute].join(', ')}'"
|
38
|
+
false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def and_add_error(expected_error_message)
|
43
|
+
@expected_error_message = expected_error_message
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
def failure_message
|
48
|
+
@message
|
49
|
+
end
|
50
|
+
|
51
|
+
def description
|
52
|
+
"'#{@value}' be a invalid value"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErgomentumRspec
|
4
|
+
module Matchers
|
5
|
+
module ActiveModel
|
6
|
+
def be_valid_for(value)
|
7
|
+
BeValidFor.new(value)
|
8
|
+
end
|
9
|
+
|
10
|
+
class BeValidFor
|
11
|
+
def initialize(value)
|
12
|
+
@value = value
|
13
|
+
end
|
14
|
+
|
15
|
+
def matches?(validator)
|
16
|
+
model = Class.new do
|
17
|
+
include ::ActiveModel::Model
|
18
|
+
include ::ActiveModel::Attributes
|
19
|
+
|
20
|
+
# ActiveModel sometimes needs a non nil class name.
|
21
|
+
# Because we are using an anonymous class, which have no name by default, we have to override the name
|
22
|
+
# method.
|
23
|
+
def self.name
|
24
|
+
"SomeClass"
|
25
|
+
end
|
26
|
+
|
27
|
+
attribute :some_attribute
|
28
|
+
validates :some_attribute, validator
|
29
|
+
end.new(some_attribute: @value)
|
30
|
+
model.valid? && model.errors.empty?
|
31
|
+
end
|
32
|
+
|
33
|
+
def failure_message
|
34
|
+
"expect '#{@value}' to be valid"
|
35
|
+
end
|
36
|
+
|
37
|
+
def description
|
38
|
+
"'#{@value}' be an valid value"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "array/be_unique"
|
4
|
+
require_relative "array/be_monotonically_decreasing"
|
5
|
+
require_relative "array/be_monotonically_increasing"
|
6
|
+
require_relative "array/be_strictly_decreasing"
|
7
|
+
require_relative "array/be_strictly_increasing"
|
8
|
+
|
9
|
+
module ErgomentumRspec
|
10
|
+
module Matchers
|
11
|
+
module Array
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
RSpec.configure do |config|
|
17
|
+
config.include ErgomentumRspec::Matchers::Array
|
18
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErgomentumRspec
|
4
|
+
module Matchers
|
5
|
+
module Array
|
6
|
+
def be_monotonically_decreasing
|
7
|
+
MonotonicallyDecreasing.new
|
8
|
+
end
|
9
|
+
|
10
|
+
class MonotonicallyDecreasing
|
11
|
+
def matches?(actual)
|
12
|
+
@actual = actual
|
13
|
+
derivative = actual.each_cons(2).map { |x, y| y <=> x }
|
14
|
+
derivative.all? { |v| v <= 0 }
|
15
|
+
end
|
16
|
+
|
17
|
+
def failure_message
|
18
|
+
"expected array #{@actual.inspect} to be monotonically decreasing"
|
19
|
+
end
|
20
|
+
|
21
|
+
def failure_message_when_negated
|
22
|
+
"expected array #{@actual.inspect} to not be monotonically decreasing"
|
23
|
+
end
|
24
|
+
|
25
|
+
def description
|
26
|
+
"be monotonically decreasing"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErgomentumRspec
|
4
|
+
module Matchers
|
5
|
+
module Array
|
6
|
+
def be_monotonically_increasing
|
7
|
+
MonotonicallyIncreasing.new
|
8
|
+
end
|
9
|
+
|
10
|
+
class MonotonicallyIncreasing
|
11
|
+
def matches?(actual)
|
12
|
+
@actual = actual
|
13
|
+
derivative = actual.each_cons(2).map { |x, y| y <=> x }
|
14
|
+
derivative.all? { |v| v >= 0 }
|
15
|
+
end
|
16
|
+
|
17
|
+
def failure_message
|
18
|
+
"expected array #{@actual.inspect} to be monotonically increasing"
|
19
|
+
end
|
20
|
+
|
21
|
+
def failure_message_when_negated
|
22
|
+
"expected array #{@actual.inspect} to not be monotonically increasing"
|
23
|
+
end
|
24
|
+
|
25
|
+
def description
|
26
|
+
"be monotonically increasing"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErgomentumRspec
|
4
|
+
module Matchers
|
5
|
+
module Array
|
6
|
+
def be_strictly_decreasing
|
7
|
+
StrictlyDecreasing.new
|
8
|
+
end
|
9
|
+
|
10
|
+
class StrictlyDecreasing
|
11
|
+
def matches?(actual)
|
12
|
+
@actual = actual
|
13
|
+
derivative = actual.each_cons(2).map { |x, y| y <=> x }
|
14
|
+
derivative.all?(&:negative?)
|
15
|
+
end
|
16
|
+
|
17
|
+
def failure_message
|
18
|
+
"expected array #{@actual.inspect} to be strictly decreasing"
|
19
|
+
end
|
20
|
+
|
21
|
+
def failure_message_when_negated
|
22
|
+
"expected array #{@actual.inspect} to not be strictly decreasing"
|
23
|
+
end
|
24
|
+
|
25
|
+
def description
|
26
|
+
"be strictly decreasing"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErgomentumRspec
|
4
|
+
module Matchers
|
5
|
+
module Array
|
6
|
+
def be_strictly_increasing
|
7
|
+
StrictlyIncreasing.new
|
8
|
+
end
|
9
|
+
|
10
|
+
class StrictlyIncreasing
|
11
|
+
def matches?(actual)
|
12
|
+
@actual = actual
|
13
|
+
derivative = actual.each_cons(2).map { |x, y| y <=> x }
|
14
|
+
derivative.all?(&:positive?)
|
15
|
+
end
|
16
|
+
|
17
|
+
def failure_message
|
18
|
+
"expected array #{@actual.inspect} to be strictly increasing"
|
19
|
+
end
|
20
|
+
|
21
|
+
def failure_message_when_negated
|
22
|
+
"expected array #{@actual.inspect} to not be strictly increasing"
|
23
|
+
end
|
24
|
+
|
25
|
+
def description
|
26
|
+
"be strictly increasing"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErgomentumRspec
|
4
|
+
module Matchers
|
5
|
+
module Array
|
6
|
+
def be_unique
|
7
|
+
BeUnique.new
|
8
|
+
end
|
9
|
+
|
10
|
+
class BeUnique
|
11
|
+
def matches?(actual)
|
12
|
+
@actual = actual
|
13
|
+
actual.detect { |e| actual.count(e) == 1 }
|
14
|
+
end
|
15
|
+
|
16
|
+
def failure_message
|
17
|
+
"expected array #{@actual.inspect} to be unique"
|
18
|
+
end
|
19
|
+
|
20
|
+
def failure_message_when_negated
|
21
|
+
"expected array #{@actual.inspect} to be not unique"
|
22
|
+
end
|
23
|
+
|
24
|
+
def description
|
25
|
+
"be unique"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "performance/allocate_objects"
|
4
|
+
|
5
|
+
module ErgomentumRspec
|
6
|
+
module Matchers
|
7
|
+
module Performance
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.include ErgomentumRspec::Matchers::Performance
|
14
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErgomentumRspec
|
4
|
+
module Matchers
|
5
|
+
module Performance
|
6
|
+
def allocates
|
7
|
+
AllocateObjects.new
|
8
|
+
end
|
9
|
+
|
10
|
+
class IncompleteExpectationError < StandardError
|
11
|
+
def initialize
|
12
|
+
super("Comparision operator required. E. g. allocates.exactly(1)")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class AllocateObjects
|
17
|
+
def supports_block_expectations?
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
def matches?(*actual, &block)
|
22
|
+
@trace = if block
|
23
|
+
AllocationStats.trace(&block)
|
24
|
+
elsif actual.first.is_a?(Proc)
|
25
|
+
AllocationStats.trace(&actual.first)
|
26
|
+
else
|
27
|
+
actual.first
|
28
|
+
end
|
29
|
+
@compare || raise(IncompleteExpectationError)
|
30
|
+
@compare.call
|
31
|
+
end
|
32
|
+
|
33
|
+
def exactly(expected)
|
34
|
+
@expected = expected
|
35
|
+
@compare = Proc.new { @trace.new_allocations.size == @expected }
|
36
|
+
@message = ""
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def less_than(expected)
|
41
|
+
@expected = expected
|
42
|
+
@compare = Proc.new { @trace.new_allocations.size < @expected }
|
43
|
+
@message = "less than "
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
def more_than(expected)
|
48
|
+
@expected = expected
|
49
|
+
@compare = Proc.new { @trace.new_allocations.size > @expected }
|
50
|
+
@message = "more than "
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def max(expected)
|
55
|
+
@expected = expected
|
56
|
+
@compare = Proc.new { @trace.new_allocations.size <= @expected }
|
57
|
+
@message = "max "
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
def min(expected)
|
62
|
+
@expected = expected
|
63
|
+
@compare = Proc.new { @trace.new_allocations.size >= @expected }
|
64
|
+
@message = "min "
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
def object
|
69
|
+
self
|
70
|
+
end
|
71
|
+
|
72
|
+
def objects
|
73
|
+
self
|
74
|
+
end
|
75
|
+
|
76
|
+
def failure_message
|
77
|
+
"expected #{@message}#{@expected} objects to be allocated; "\
|
78
|
+
"got #{@trace.new_allocations.size}:\n\n"\
|
79
|
+
"#{@trace.allocations(alias_paths: true).group_by(:sourcefile, :sourceline, :class).to_text}"
|
80
|
+
end
|
81
|
+
|
82
|
+
def failure_message_when_negated
|
83
|
+
"expected not #{@message}#{@expected} objects to be allocated; "\
|
84
|
+
"got #{@trace.new_allocations.size}:\n\n"\
|
85
|
+
"#{@trace.allocations(alias_paths: true).group_by(:sourcefile, :sourceline, :class).to_text}"
|
86
|
+
end
|
87
|
+
|
88
|
+
def description
|
89
|
+
"allocates number of objects"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErgomentumRspec
|
4
|
+
module Matchers
|
5
|
+
module Yield
|
6
|
+
def yield_all(expected)
|
7
|
+
YieldAll.new(expected)
|
8
|
+
end
|
9
|
+
|
10
|
+
class NoBlockGivenError < StandardError
|
11
|
+
def initialize
|
12
|
+
super("Block required. E.g. expect { |b| [0].each(&b) }.to yield_all(0)")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class YieldAll
|
17
|
+
include RSpec::Matchers::Composable
|
18
|
+
|
19
|
+
def initialize(expected)
|
20
|
+
@expected = expected
|
21
|
+
end
|
22
|
+
|
23
|
+
def supports_block_expectations?
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
def matches?(*block)
|
28
|
+
@count = 0
|
29
|
+
@result = true
|
30
|
+
if block_given?
|
31
|
+
yield(method(:match))
|
32
|
+
elsif block.first.is_a?(Proc)
|
33
|
+
block.first.call(method(:match))
|
34
|
+
else
|
35
|
+
raise NoBlockGivenError
|
36
|
+
end
|
37
|
+
@result
|
38
|
+
end
|
39
|
+
|
40
|
+
def match(actual)
|
41
|
+
@count += 1
|
42
|
+
@last = actual
|
43
|
+
@result &&= if @expected.respond_to?(:matches?)
|
44
|
+
@expected.matches?(actual)
|
45
|
+
else
|
46
|
+
values_match?(@expected, actual)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def failure_message
|
51
|
+
if @expected.respond_to?(:failure_message)
|
52
|
+
"Failed for #{ActiveSupport::Inflector.ordinalize(@count)} yield with:\n#{@expected.failure_message}"
|
53
|
+
else
|
54
|
+
"Expecting #{@expected} got #{@last} for #{ActiveSupport::Inflector.ordinalize(@count)} yield"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def description
|
59
|
+
"yields all"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
metadata
ADDED
@@ -0,0 +1,233 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ergomentum_rspec
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ergomentum
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-06-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: byebug
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 11.1.3
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 11.1.3
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 13.0.1
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 13.0.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec_junit_formatter
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.4.1
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.4.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.8'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.8'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop-performance
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.9'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.9'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.21.2
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.21.2
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: test-prof
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.0.2
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 1.0.2
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: activemodel
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '6.0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '6.0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: activesupport
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '6.0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '6.0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: allocation_stats
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 0.1.5
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 0.1.5
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: rspec
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '3.9'
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '3.9'
|
181
|
+
description: Regular used rspec matchers not found somewhere else.
|
182
|
+
email:
|
183
|
+
- info@ergomentum.de
|
184
|
+
executables: []
|
185
|
+
extensions: []
|
186
|
+
extra_rdoc_files: []
|
187
|
+
files:
|
188
|
+
- Gemfile
|
189
|
+
- README.md
|
190
|
+
- bin/console
|
191
|
+
- bin/setup
|
192
|
+
- ergomentum_rspec.gemspec
|
193
|
+
- lib/ergomentum_rspec.rb
|
194
|
+
- lib/ergomentum_rspec/helpers/environment.rb
|
195
|
+
- lib/ergomentum_rspec/helpers/fixture.rb
|
196
|
+
- lib/ergomentum_rspec/matchers/active_model.rb
|
197
|
+
- lib/ergomentum_rspec/matchers/active_model/be_invalid_for.rb
|
198
|
+
- lib/ergomentum_rspec/matchers/active_model/be_valid_for.rb
|
199
|
+
- lib/ergomentum_rspec/matchers/array.rb
|
200
|
+
- lib/ergomentum_rspec/matchers/array/be_monotonically_decreasing.rb
|
201
|
+
- lib/ergomentum_rspec/matchers/array/be_monotonically_increasing.rb
|
202
|
+
- lib/ergomentum_rspec/matchers/array/be_strictly_decreasing.rb
|
203
|
+
- lib/ergomentum_rspec/matchers/array/be_strictly_increasing.rb
|
204
|
+
- lib/ergomentum_rspec/matchers/array/be_unique.rb
|
205
|
+
- lib/ergomentum_rspec/matchers/performance.rb
|
206
|
+
- lib/ergomentum_rspec/matchers/performance/allocate_objects.rb
|
207
|
+
- lib/ergomentum_rspec/matchers/yield.rb
|
208
|
+
- lib/ergomentum_rspec/matchers/yield/yield_all.rb
|
209
|
+
- lib/ergomentum_rspec/version.rb
|
210
|
+
homepage: https://www.ergomentum.de/
|
211
|
+
licenses:
|
212
|
+
- Nonstandard
|
213
|
+
metadata: {}
|
214
|
+
post_install_message:
|
215
|
+
rdoc_options: []
|
216
|
+
require_paths:
|
217
|
+
- lib
|
218
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - ">="
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: 3.0.1
|
223
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
224
|
+
requirements:
|
225
|
+
- - ">="
|
226
|
+
- !ruby/object:Gem::Version
|
227
|
+
version: '0'
|
228
|
+
requirements: []
|
229
|
+
rubygems_version: 3.2.15
|
230
|
+
signing_key:
|
231
|
+
specification_version: 4
|
232
|
+
summary: Provides regular used rspec custom matchers
|
233
|
+
test_files: []
|