r_spec 0.3.2 → 1.0.0.beta4
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 +4 -4
- data/LICENSE.md +1 -1
- data/README.md +187 -79
- data/lib/r_spec.rb +54 -22
- data/lib/r_spec/dsl.rb +135 -0
- data/lib/r_spec/expectation_helper.rb +10 -0
- data/lib/r_spec/expectation_helper/base.rb +96 -0
- data/lib/r_spec/expectation_helper/it.rb +41 -0
- data/lib/r_spec/expectation_helper/its.rb +25 -0
- data/lib/r_spec/expectation_target.rb +30 -0
- data/lib/r_spec/expectation_target/base.rb +73 -0
- data/lib/r_spec/expectation_target/block.rb +60 -0
- data/lib/r_spec/expectation_target/value.rb +53 -0
- data/lib/r_spec/pending.rb +26 -0
- data/lib/r_spec/sandbox.rb +9 -0
- metadata +104 -68
- data/.gitignore +0 -11
- data/.rubocop.yml +0 -1
- data/.rubocop_todo.yml +0 -28
- data/.travis.yml +0 -26
- data/.yardopts +0 -1
- data/CODE_OF_CONDUCT.md +0 -13
- data/Gemfile +0 -5
- data/Rakefile +0 -22
- data/VERSION.semver +0 -1
- data/bin/console +0 -8
- data/bin/setup +0 -5
- data/checksum/r_spec-0.1.0.gem.sha512 +0 -1
- data/checksum/r_spec-0.1.1.gem.sha512 +0 -1
- data/checksum/r_spec-0.2.0.gem.sha512 +0 -1
- data/checksum/r_spec-0.3.0.gem.sha512 +0 -1
- data/checksum/r_spec-0.3.1.gem.sha512 +0 -1
- data/lib/fix/it.rb +0 -12
- data/lib/fix/on.rb +0 -45
- data/pkg_checksum +0 -12
- data/r_spec.gemspec +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d94ad6d7ba01dc04c4bcbe727543524f6a3d83cf69549a34453c1eefc5282e9
|
4
|
+
data.tar.gz: 61b3ebe1299e69d7ef1f2c180325e85e1bda05e2347176ae507fc7430cf311ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d44ce99f58c17711be4b3f76cdfaf3c9923d031aa9a7d214db50b990825673b9bb485ce095195594fbeb45977763dc5a0be31770f089cd17dcb1e3ef1d6885b
|
7
|
+
data.tar.gz: ca64a27f7cf4032b6b073b9fc2eb05aa37654c02a58289c41094e9afa000deccc3886d03d2043642a02e38cf10b6cc0fbd775e7ef9bc1c29cb592b813dcf5d04
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -1,131 +1,239 @@
|
|
1
|
-
#
|
1
|
+
# RSpec clone
|
2
2
|
|
3
|
-
[
|
4
|
-
[][codeclimate]
|
5
|
-
[][gemnasium]
|
6
|
-
[][gem]
|
7
|
-
[][inchpages]
|
8
|
-
[][rubydoc]
|
3
|
+
A minimalist __[RSpec](https://github.com/rspec/rspec) clone__ with all the essentials.
|
9
4
|
|
10
|
-
|
5
|
+

|
11
6
|
|
12
|
-
|
7
|
+
## Status
|
13
8
|
|
14
|
-
|
9
|
+
[](https://badge.fury.io/rb/r_spec)
|
10
|
+
[](https://travis-ci.org/cyril/r_spec.rb)
|
11
|
+
[](https://inch-ci.org/github/cyril/r_spec.rb)
|
12
|
+
[](https://rubydoc.info/gems/r_spec/frames)
|
15
13
|
|
16
|
-
|
14
|
+
## Goal
|
17
15
|
|
18
|
-
This
|
16
|
+
This clone attempts to provide most of RSpec's DSL to express expected outcomes of a code example without magic power.
|
19
17
|
|
20
|
-
|
18
|
+
## Some differences
|
21
19
|
|
22
|
-
|
20
|
+
* Less features and an implementation with much less code complexity.
|
21
|
+
* Spec files can also be executed directly with the `ruby` executable.
|
22
|
+
* There is no option to activate monkey-patching.
|
23
|
+
* It does not rely on hacks such as `at_exit` hook to trigger the tests.
|
24
|
+
* Built-in matchers do not trust _actual_ and do not send it messages.
|
25
|
+
* The `subject` must be explicitly defined, otherwise it is not implemented.
|
26
|
+
* Expectations cannot be added inside a `before` block.
|
27
|
+
* [Arbitrary helper methods](https://relishapp.com/rspec/rspec-core/v/3-10/docs/helper-methods/arbitrary-helper-methods) are not exposed to examples.
|
28
|
+
* The `let` method defines a helper method rather than a memoized helper method.
|
29
|
+
* The one-liner `is_expected` syntax also works with block expectations.
|
23
30
|
|
24
|
-
##
|
31
|
+
## Important ⚠️
|
25
32
|
|
26
|
-
|
27
|
-
* Bugs/issues: https://github.com/cyril/r_spec/issues
|
33
|
+
To avoid confusion in the community, please note that:
|
28
34
|
|
29
|
-
|
35
|
+
- the gem of this project is **not [`rspec`](https://rubygems.org/gems/rspec)**,
|
36
|
+
it is **[`r_spec`](https://rubygems.org/gems/r_spec)**;
|
37
|
+
- this project is totally independent of [rspec.info](https://rspec.info/).
|
30
38
|
|
31
|
-
|
32
|
-
* [Rubinius](http://rubini.us/)
|
33
|
-
* [JRuby](http://jruby.org/)
|
39
|
+
### Note
|
34
40
|
|
35
|
-
|
41
|
+
Following [RubyGems naming conventions](https://guides.rubygems.org/name-your-gem/#use-underscores-for-multiple-words), the module name for this project is `RSpec`.
|
36
42
|
|
37
|
-
|
43
|
+
## Installation
|
38
44
|
|
39
|
-
|
45
|
+
Add this line to your application's Gemfile:
|
40
46
|
|
41
|
-
|
47
|
+
```ruby
|
48
|
+
gem "r_spec", ">= 1.0.0.beta4"
|
49
|
+
```
|
42
50
|
|
43
|
-
|
51
|
+
And then execute:
|
44
52
|
|
45
|
-
|
53
|
+
```sh
|
54
|
+
bundle
|
55
|
+
```
|
46
56
|
|
47
|
-
|
57
|
+
Or install it yourself as:
|
48
58
|
|
49
|
-
|
59
|
+
```sh
|
60
|
+
gem install r_spec --pre
|
61
|
+
```
|
50
62
|
|
51
|
-
##
|
63
|
+
## Overview
|
52
64
|
|
53
|
-
|
65
|
+
__RSpec clone__ provides a structure for writing executable examples of how your code should behave.
|
66
|
+
|
67
|
+
Inspired by [RSpec](https://rspec.info/), it includes a domain specific language (DSL) that allows you to write examples in a way similar to plain english.
|
68
|
+
|
69
|
+
A basic spec looks something like this:
|
70
|
+
|
71
|
+
[](https://asciinema.org/a/418672?autoplay=1)
|
72
|
+
|
73
|
+
## Usage
|
74
|
+
|
75
|
+
### Anatomy of a spec file
|
76
|
+
|
77
|
+
To use the `RSpec` module and its DSL, you need to add `require "r_spec"` to your spec files.
|
78
|
+
Many projects use a custom spec helper which organizes these includes.
|
79
|
+
|
80
|
+
Concrete test cases are defined in `it` blocks.
|
81
|
+
An optional descriptive string states it's purpose and a block contains the main logic performing the test.
|
82
|
+
|
83
|
+
An `it` block contains an example that should invoke the code to be tested and define what is expected of it.
|
84
|
+
Each example can contain multiple expectations, but it should test only one specific behaviour.
|
85
|
+
|
86
|
+
To express an expectation, wrap an object or block in `expect`, call `to` or `not_to` and pass it a matcher object.
|
87
|
+
|
88
|
+
If the expectation is met, code execution continues.
|
89
|
+
Otherwise the example has _failed_ and other code will not be executed.
|
90
|
+
|
91
|
+
Test cases that have been defined or outlined but are not yet expected to work can be defined using `pending` instead of `expect`. They will not be run but show up in the spec report as pending.
|
92
|
+
|
93
|
+
In test files, specs are structured by example groups which are defined by `describe` and `context` sections.
|
94
|
+
Typically a top level `describe` defines the outer unit (such as a class) to be tested by the spec.
|
95
|
+
Further `describe` sections can be nested within the outer unit to specify smaller units under test (such as individual methods).
|
96
|
+
|
97
|
+
For unit tests, it is recommended to follow the conventions for method names:
|
98
|
+
|
99
|
+
* outer `describe` is the name of the class, inner `describe` targets methods;
|
100
|
+
* instance methods are prefixed with `#`, class methods with `.`.
|
101
|
+
|
102
|
+
To establish certain contexts - think _empty array_ versus _array with elements_ - the `context` method may be used to communicate this to the reader.
|
103
|
+
It has a different name, but behaves exactly like `describe`.
|
104
|
+
|
105
|
+
`describe` and `context` take an optional description as argument and a block containing the individual specs or nested groupings.
|
106
|
+
|
107
|
+
### Expectations
|
108
|
+
|
109
|
+
Expectations define if the value being tested (_actual_) matches a certain value or specific criteria.
|
110
|
+
|
111
|
+
#### Equivalence
|
54
112
|
|
55
113
|
```ruby
|
56
|
-
|
114
|
+
expect(actual).to eql(expected) # passes if expected.eql?(actual)
|
115
|
+
expect(actual).to eq(expected) # passes if expected.eql?(actual)
|
57
116
|
```
|
58
117
|
|
59
|
-
|
118
|
+
#### Identity
|
60
119
|
|
61
|
-
|
120
|
+
```ruby
|
121
|
+
expect(actual).to equal(expected) # passes if expected.equal?(actual)
|
122
|
+
expect(actual).to be(expected) # passes if expected.equal?(actual)
|
123
|
+
```
|
62
124
|
|
63
|
-
|
125
|
+
#### Regular expressions
|
64
126
|
|
65
|
-
|
127
|
+
```ruby
|
128
|
+
expect(actual).to match(expected) # passes if expected.match?(actual)
|
129
|
+
```
|
66
130
|
|
67
|
-
|
131
|
+
#### Expecting errors
|
68
132
|
|
69
|
-
|
133
|
+
```ruby
|
134
|
+
expect { actual }.to raise_exception(expected) # passes if expected exception is raised
|
135
|
+
```
|
136
|
+
|
137
|
+
#### Truth
|
70
138
|
|
71
139
|
```ruby
|
72
|
-
|
140
|
+
expect(actual).to be_true # passes if true.equal?(actual)
|
141
|
+
```
|
142
|
+
|
143
|
+
#### Untruth
|
73
144
|
|
74
|
-
|
145
|
+
```ruby
|
146
|
+
expect(actual).to be_false # passes if false.equal?(actual)
|
147
|
+
```
|
75
148
|
|
76
|
-
|
77
|
-
context 'Alice' do
|
78
|
-
before { greeting.gsub!('world', 'Alice') }
|
79
|
-
it { expect(greeting).to eql 'Hello, Alice!' }
|
80
|
-
end
|
149
|
+
#### Nil
|
81
150
|
|
82
|
-
|
83
|
-
|
84
|
-
it { expect(greeting).to eql 'Hello, Bob!' }
|
85
|
-
end
|
86
|
-
end
|
151
|
+
```ruby
|
152
|
+
expect(actual).to be_nil # passes if nil.equal?(actual)
|
87
153
|
```
|
88
154
|
|
89
|
-
|
155
|
+
#### Type/class
|
90
156
|
|
91
|
-
|
92
|
-
|
157
|
+
```ruby
|
158
|
+
expect(actual).to be_instance_of(expected) # passes if expected.equal?(actual.class)
|
159
|
+
expect(actual).to be_an_instance_of(expected) # passes if expected.equal?(actual.class)
|
160
|
+
```
|
161
|
+
|
162
|
+
### Running specs
|
163
|
+
|
164
|
+
By convention, specs live in the `spec/` directory of a project. Spec files should end with `_spec.rb` to be recognizable as such.
|
93
165
|
|
94
|
-
|
95
|
-
|
166
|
+
Depending of the project settings, you may run the specs of a project by running `rake spec` (see [`rake` integration example](#rake-integration-example) below).
|
167
|
+
A single file can also be executed directly with the Ruby interpreter.
|
96
168
|
|
97
|
-
|
169
|
+
#### Examples
|
98
170
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
171
|
+
Run all specs in files matching `spec/**/*_spec.rb`:
|
172
|
+
|
173
|
+
```sh
|
174
|
+
bundle exec rake spec
|
175
|
+
```
|
103
176
|
|
104
|
-
|
105
|
-
example:
|
177
|
+
Run a single file:
|
106
178
|
|
107
|
-
|
108
|
-
|
179
|
+
```sh
|
180
|
+
ruby spec/my/test/file_spec.rb
|
181
|
+
```
|
182
|
+
|
183
|
+
I know that sounds weird, but the [`rspec` command line](https://relishapp.com/rspec/rspec-core/docs/command-line) is also working pretty well:
|
184
|
+
|
185
|
+
```sh
|
186
|
+
rspec spec/my/test/file_spec.rb
|
187
|
+
rspec spec/my/test/file_spec.rb:42
|
188
|
+
rspec spec/my/test/
|
189
|
+
rspec
|
190
|
+
```
|
191
|
+
|
192
|
+
### Spec helper
|
193
|
+
|
194
|
+
Many projects use a custom spec helper file, usually named `spec/spec_helper.rb`.
|
195
|
+
|
196
|
+
This file is used to require `r_spec` and other includes, like the code from the project needed for every spec file.
|
197
|
+
|
198
|
+
### `rake` integration example
|
199
|
+
|
200
|
+
The following `Rakefile` settings should be enough:
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
require "bundler/gem_tasks"
|
204
|
+
require "rake/testtask"
|
205
|
+
|
206
|
+
Rake::TestTask.new do |t|
|
207
|
+
t.pattern = "spec/**/*_spec.rb"
|
208
|
+
t.verbose = true
|
209
|
+
t.warning = true
|
210
|
+
end
|
211
|
+
|
212
|
+
task spec: :test
|
213
|
+
task default: :test
|
214
|
+
```
|
215
|
+
|
216
|
+
## Test suite
|
217
|
+
|
218
|
+
__RSpec clone__'s specifications are self-described here: [spec/](https://github.com/cyril/r_spec.rb/blob/main/spec/)
|
219
|
+
|
220
|
+
## Contact
|
221
|
+
|
222
|
+
* Home page: https://r-spec.dev
|
223
|
+
* Source code: https://github.com/cyril/r_spec.rb
|
224
|
+
* Twitter: [https://twitter.com/cyri\_](https://twitter.com/cyri\_)
|
109
225
|
|
110
226
|
## Versioning
|
111
227
|
|
112
|
-
|
228
|
+
__RSpec clone__ follows [Semantic Versioning 2.0](https://semver.org/).
|
113
229
|
|
114
|
-
##
|
230
|
+
## Special thanks
|
115
231
|
|
116
|
-
|
117
|
-
|
118
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
119
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
120
|
-
5. Create a new Pull Request
|
232
|
+
I would like to thank the whole [RSpec team](https://rspec.info/about/) for all their work.
|
233
|
+
It's a great framework and it's a pleasure to work with every day.
|
121
234
|
|
122
|
-
|
235
|
+
Without RSpec, this clone would not have been possible. ❤️
|
123
236
|
|
124
|
-
|
237
|
+
## License
|
125
238
|
|
126
|
-
[gem]
|
127
|
-
[travis]: https://travis-ci.org/cyril/r_spec
|
128
|
-
[codeclimate]: https://codeclimate.com/github/cyril/r_spec
|
129
|
-
[gemnasium]: https://gemnasium.com/cyril/r_spec
|
130
|
-
[inchpages]: http://inch-ci.org/github/cyril/r_spec
|
131
|
-
[rubydoc]: http://rubydoc.info/gems/r_spec/frames
|
239
|
+
The [gem](https://rubygems.org/gems/r_spec) is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/lib/r_spec.rb
CHANGED
@@ -1,33 +1,65 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require 'fix/expect'
|
5
|
-
require 'fix/its'
|
6
|
-
|
7
|
-
# Namespace for the R Spec framework.
|
3
|
+
# Top level namespace for the RSpec clone.
|
8
4
|
#
|
9
|
-
# @
|
5
|
+
# @example The true from the false
|
6
|
+
# require "r_spec"
|
7
|
+
#
|
8
|
+
# RSpec.describe do
|
9
|
+
# it { expect(false).not_to be true }
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# @example The basic behavior of arrays
|
13
|
+
# require "r_spec"
|
14
|
+
#
|
15
|
+
# RSpec.describe Array do
|
16
|
+
# describe "#size" do
|
17
|
+
# it "correctly reports the number of elements in the Array" do
|
18
|
+
# expect([1, 2, 3].size).to eq 3
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# describe "#empty?" do
|
23
|
+
# it "is empty when no elements are in the array" do
|
24
|
+
# expect([].empty?).to be_true
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# it "is not empty if there are elements in the array" do
|
28
|
+
# expect([1].empty?).to be_false
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# @example An inherited definition of let
|
34
|
+
# require "r_spec"
|
10
35
|
#
|
36
|
+
# RSpec.describe Integer do
|
37
|
+
# let(:answer) { 42 }
|
38
|
+
#
|
39
|
+
# it "returns the value" do
|
40
|
+
# expect(answer).to be(42)
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# context "when the number is incremented" do
|
44
|
+
# let(:answer) { super().next }
|
45
|
+
#
|
46
|
+
# it "returns the next value" do
|
47
|
+
# expect(answer).to be(43)
|
48
|
+
# end
|
49
|
+
# end
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# @api public
|
11
53
|
module RSpec
|
12
54
|
# Specs are built with this method.
|
13
55
|
#
|
14
|
-
# @
|
15
|
-
#
|
16
|
-
# it { expect(42).to be 42 }
|
17
|
-
# end
|
18
|
-
#
|
19
|
-
# @param front_object [#object_id] The front object.
|
20
|
-
# @param options [Hash] Some options.
|
21
|
-
# @param specs [Proc] The set of specs.
|
56
|
+
# @param const [Module, String] A module to include in block context.
|
57
|
+
# @param block [Proc] The block to define the specs.
|
22
58
|
#
|
23
|
-
# @
|
24
|
-
def self.describe(
|
25
|
-
|
26
|
-
|
27
|
-
print t.report.to_s if options.fetch(:verbose, true)
|
28
|
-
exit t.pass?
|
59
|
+
# @api public
|
60
|
+
def self.describe(const = nil, &block)
|
61
|
+
Dsl.describe(const, &block)
|
29
62
|
end
|
30
63
|
end
|
31
64
|
|
32
|
-
require_relative File.join
|
33
|
-
require_relative File.join 'fix', 'on'
|
65
|
+
require_relative File.join("r_spec", "dsl")
|
data/lib/r_spec/dsl.rb
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "securerandom"
|
4
|
+
|
5
|
+
module RSpec
|
6
|
+
# Abstract class for handling the domain-specific language.
|
7
|
+
class Dsl
|
8
|
+
# Instructs the spec runner to execute the given block before each spec in
|
9
|
+
# the spec suite.
|
10
|
+
#
|
11
|
+
# @param block [Proc] The content to execute at the class initialization.
|
12
|
+
def self.before(&block)
|
13
|
+
define_method(:initialize) do |*args, **kwargs|
|
14
|
+
super()
|
15
|
+
instance_exec(*args, **kwargs, &block)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Sets a user-defined property.
|
20
|
+
#
|
21
|
+
# @param name [String, Symbol] The name of the property.
|
22
|
+
# @param block [Proc] The content of the method to define.
|
23
|
+
#
|
24
|
+
# @return [Symbol] A protected method that define the block content.
|
25
|
+
def self.let(name, *args, **kwargs, &block)
|
26
|
+
protected define_method(name.to_sym, *args, **kwargs, &block)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Sets a user-defined property named `subject`.
|
30
|
+
#
|
31
|
+
# @param block [Proc] The subject to set.
|
32
|
+
# @return [Symbol] A `subject` method that define the block content.
|
33
|
+
def self.subject(&block)
|
34
|
+
let(__method__, &block)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Create a group of specs.
|
38
|
+
#
|
39
|
+
# @param const [Module, #object_id] A module to include in block context.
|
40
|
+
# @param block [Proc] The block to define the specs.
|
41
|
+
def self.describe(const = nil, &block)
|
42
|
+
desc = Sandbox.const_set(random_test_const_name, ::Class.new(self))
|
43
|
+
|
44
|
+
if const.is_a?(::Module)
|
45
|
+
desc.define_method(:described_class) { const }
|
46
|
+
desc.send(:protected, :described_class)
|
47
|
+
end
|
48
|
+
|
49
|
+
desc.instance_eval(&block)
|
50
|
+
desc
|
51
|
+
end
|
52
|
+
|
53
|
+
# Add `context` to the DSL.
|
54
|
+
singleton_class.send(:alias_method, :context, :describe)
|
55
|
+
|
56
|
+
# Define a single spec. A spec should contain one or more expectations that
|
57
|
+
# test the state of the code.
|
58
|
+
#
|
59
|
+
# @param block [Proc] An expectation to evaluate.
|
60
|
+
#
|
61
|
+
# @raise (see ExpectationTarget::Base#result)
|
62
|
+
# @return (see ExpectationTarget::Base#result)
|
63
|
+
def self.it(_name = nil, &block)
|
64
|
+
raise ::ArgumentError, "Missing block" unless block
|
65
|
+
|
66
|
+
puts "\e[37m#{block.source_location.join(':')}\e[0m"
|
67
|
+
|
68
|
+
i = it_example.new
|
69
|
+
i.instance_eval(&block)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Define a single spec. A spec should contain one or more expectations that
|
73
|
+
# test the state of the code.
|
74
|
+
#
|
75
|
+
# @example The value after 41
|
76
|
+
# require "r_spec"
|
77
|
+
#
|
78
|
+
# RSpec.describe Integer do
|
79
|
+
# subject { 41 }
|
80
|
+
#
|
81
|
+
# its(:next) { is_expected.to be 42 }
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# @example Without defining a subject
|
85
|
+
# require "r_spec"
|
86
|
+
#
|
87
|
+
# RSpec.describe Integer do
|
88
|
+
# its(:next) { is_expected.to raise_exception NameError }
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# @param attribute [String, Symbol] The property to call to subject.
|
92
|
+
#
|
93
|
+
# @raise (see ExpectationTarget::Base#result)
|
94
|
+
# @return (see ExpectationTarget::Base#result)
|
95
|
+
def self.its(attribute, *args, **kwargs, &block)
|
96
|
+
raise ::ArgumentError, "Missing block" unless block
|
97
|
+
|
98
|
+
puts "\e[37m#{block.source_location.join(':')}\e[0m"
|
99
|
+
|
100
|
+
i = its_example.new
|
101
|
+
|
102
|
+
i.define_singleton_method(:actual) do
|
103
|
+
subject.public_send(attribute, *args, **kwargs)
|
104
|
+
end
|
105
|
+
|
106
|
+
i.instance_eval(&block)
|
107
|
+
end
|
108
|
+
|
109
|
+
# @private
|
110
|
+
#
|
111
|
+
# @return [Class<Dsl>] The class of the example to be tested.
|
112
|
+
def self.it_example
|
113
|
+
::Class.new(self) { include ExpectationHelper::It }
|
114
|
+
end
|
115
|
+
|
116
|
+
# @private
|
117
|
+
#
|
118
|
+
# @return [Class<Dsl>] The class of the example to be tested.
|
119
|
+
def self.its_example
|
120
|
+
::Class.new(self) { include ExpectationHelper::Its }
|
121
|
+
end
|
122
|
+
|
123
|
+
# @private
|
124
|
+
#
|
125
|
+
# @return [String] A random constant name for a test class.
|
126
|
+
def self.random_test_const_name
|
127
|
+
"Test#{::SecureRandom.hex(4).to_i(16)}"
|
128
|
+
end
|
129
|
+
|
130
|
+
private_class_method :it_example, :its_example, :random_test_const_name
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
require_relative "expectation_helper"
|
135
|
+
require_relative "sandbox"
|