r_spec 1.0.0.beta6 → 1.0.0.beta7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6facf7764beddac81425ab44d80ed3b306f6c63c3532401bb658240654b06845
4
- data.tar.gz: 944d53b22a1ffeeca3afe990aa99a613493f9ff1b3aad3ceaa43ae0b9a8ec019
3
+ metadata.gz: 46557ee64f6cc554942399aa9219e9102879b2b7b113e53dc4ba63d2c0c5c0af
4
+ data.tar.gz: a83b773e20cf2db46b28586be6836d7913a4c3b8f9bf2ce747110f2556737374
5
5
  SHA512:
6
- metadata.gz: c28b4fbd53cf2a368022418c2ccbbf31cf4a35abce141f0999285bff90b4c84d7f36209894dafcf5362464d01fad3dcb724d942ae5db5c1095387997b087964f
7
- data.tar.gz: 4c7a23212c2ce90a67b04e9fe25dda7812c37902eba8f6febdb9e4e2dcd33633fa43642d6905f9bfffa6215b467eb88cbb921d596f0276fb788cc876bc63e291
6
+ metadata.gz: b7c89ce9b933e7adcfc26e03c2f4417ed44c423ca56932f173b2161572877967df37d99c9a560e8cf64c58458777842cb0db7eb1396c89a7f052d981b45f9864
7
+ data.tar.gz: 51c4b747116d8f1bb3bb2e593b00aa940ec463d1b9a03506984f2b445f3607febd455884051279f73cef2fc2edac7cfe6d9b4de210c1f1cef6402bd501729f6c
data/README.md CHANGED
@@ -11,11 +11,12 @@ A minimalist __[RSpec](https://github.com/rspec/rspec) clone__ with all the esse
11
11
  [![Inline Docs](https://inch-ci.org/github/cyril/r_spec.rb.svg)](https://inch-ci.org/github/cyril/r_spec.rb)
12
12
  [![Documentation](https://img.shields.io/:yard-docs-38c800.svg)](https://rubydoc.info/gems/r_spec/frames)
13
13
 
14
- ## Goal
14
+ ## Project Goals
15
15
 
16
- This clone attempts to provide most of RSpec's DSL to express expected outcomes of a code example without magic power.
16
+ * Enforce the guidelines and best practices outlined in the community [RSpec style guide](https://rspec.rubystyle.guide/).
17
+ * Provide most of RSpec's DSL to express expected outcomes of a code example without magic power.
17
18
 
18
- ## Some differences
19
+ ## Some Differences
19
20
 
20
21
  * Less features and an implementation with much less code complexity.
21
22
  * Spec files can also be executed directly with the `ruby` executable.
@@ -28,6 +29,10 @@ This clone attempts to provide most of RSpec's DSL to express expected outcomes
28
29
  * [Arbitrary helper methods](https://relishapp.com/rspec/rspec-core/v/3-10/docs/helper-methods/arbitrary-helper-methods) are not exposed to examples.
29
30
  * The `let` method defines a helper method rather than a memoized helper method.
30
31
  * The one-liner `is_expected` syntax also works with block expectations.
32
+ * All `subject` definitions must come _before_ examples.
33
+ * All `before` definitions must come _before_ examples.
34
+ * All `after` definitions must come _before_ examples.
35
+ * All `let` definitions must come _before_ examples.
31
36
 
32
37
  ## Important ⚠️
33
38
 
@@ -46,7 +51,7 @@ Following [RubyGems naming conventions](https://guides.rubygems.org/name-your-ge
46
51
  Add this line to your application's Gemfile:
47
52
 
48
53
  ```ruby
49
- gem "r_spec", ">= 1.0.0.beta6"
54
+ gem "r_spec", ">= 1.0.0.beta7"
50
55
  ```
51
56
 
52
57
  And then execute:
@@ -215,15 +220,18 @@ task default: :test
215
220
 
216
221
  ## Performance
217
222
 
218
- Benchmark against an single expectation executed 100 times from the console.
223
+ ### Runtime
224
+
225
+ Benchmark against [100 executions of a file containing one expectation](https://github.com/cyril/r_spec.rb/blob/main/benchmark/) (lower is better).
219
226
 
220
227
  | Framework | Seconds to complete |
221
228
  |-------------|---------------------|
222
- | RSpec clone | [13.2](https://github.com/cyril/r_spec.rb/blob/main/benchmark/r_spec.rb) |
223
- | RSpec | [32.7](https://github.com/cyril/r_spec.rb/blob/main/benchmark/rspec.rb) |
224
- | minitest | [17.6](https://github.com/cyril/r_spec.rb/blob/main/benchmark/minitest.rb) |
229
+ | `r_spec` | 13.0 |
230
+ | `rspec` | 32.2 |
231
+ | `minitest` | 17.5 |
232
+ | `test-unit` | 20.5 |
225
233
 
226
- ## Test suite
234
+ ## Test Suite
227
235
 
228
236
  __RSpec clone__'s specifications are self-described here: [spec/](https://github.com/cyril/r_spec.rb/blob/main/spec/)
229
237
 
@@ -233,14 +241,14 @@ __RSpec clone__'s specifications are self-described here: [spec/](https://github
233
241
  * Source code: https://github.com/cyril/r_spec.rb
234
242
  * Twitter: [https://twitter.com/cyri\_](https://twitter.com/cyri\_)
235
243
 
236
- ## Special thanks ❤️
244
+ ## Special Thanks ❤️
237
245
 
238
246
  I would like to thank the whole [RSpec team](https://rspec.info/about/) for all their work.
239
247
  It's a great framework and it's a pleasure to work with every day.
240
248
 
241
249
  Without RSpec, this clone would not have been possible.
242
250
 
243
- ## Buy me a coffee
251
+ ## Buy me a Coffee
244
252
 
245
253
  If you like this project please consider making a small donation.
246
254
 
data/lib/r_spec.rb CHANGED
@@ -7,7 +7,7 @@ require_relative File.join("r_spec", "dsl")
7
7
  # @example The true from the false
8
8
  # require "r_spec"
9
9
  #
10
- # RSpec.describe do
10
+ # RSpec.describe "The true from the false" do
11
11
  # it { expect(false).not_to be true }
12
12
  # end
13
13
  #
@@ -71,7 +71,7 @@ module RSpec
71
71
  # @param block [Proc] The block to define the specs.
72
72
  #
73
73
  # @api public
74
- def self.describe(const = nil, &block)
74
+ def self.describe(const, &block)
75
75
  Dsl.describe(const, &block)
76
76
  end
77
77
  end
data/lib/r_spec/dsl.rb CHANGED
@@ -1,15 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "securerandom"
4
-
5
3
  require_relative "console"
6
4
  require_relative "error"
7
5
  require_relative "expectation_helper"
8
- require_relative "sandbox"
9
6
 
10
7
  module RSpec
11
8
  # Abstract class for handling the domain-specific language.
12
9
  class Dsl
10
+ BEFORE_METHOD = :initialize
11
+ AFTER_METHOD = :terminate
12
+
13
+ private_constant :BEFORE_METHOD, :AFTER_METHOD
14
+
13
15
  # Executes the given block before each spec in the current context runs.
14
16
  #
15
17
  # @example
@@ -40,12 +42,12 @@ module RSpec
40
42
  #
41
43
  # @param block [Proc] The content to execute at the class initialization.
42
44
  def self.before(&block)
43
- define_method(:initialize) do
45
+ define_method(BEFORE_METHOD) do
44
46
  super()
45
47
  instance_eval(&block)
46
48
  end
47
49
 
48
- private :initialize
50
+ private BEFORE_METHOD
49
51
  end
50
52
 
51
53
  # Executes the given block after each spec in the current context runs.
@@ -67,12 +69,12 @@ module RSpec
67
69
  #
68
70
  # @param block [Proc] The content to execute at the class initialization.
69
71
  def self.after(&block)
70
- define_method(:terminate) do
72
+ define_method(AFTER_METHOD) do
71
73
  instance_exec(&block)
72
74
  super()
73
75
  end
74
76
 
75
- private :terminate
77
+ private AFTER_METHOD
76
78
  end
77
79
 
78
80
  # Sets a user-defined property.
@@ -80,7 +82,7 @@ module RSpec
80
82
  # @example
81
83
  # require "r_spec"
82
84
  #
83
- # RSpec.describe do
85
+ # RSpec.describe "Name stories" do
84
86
  # let(:name) { "Bob" }
85
87
  #
86
88
  # it { expect(name).to eq "Bob" }
@@ -99,9 +101,11 @@ module RSpec
99
101
  # @param name [String, Symbol] The name of the property.
100
102
  # @param block [Proc] The content of the method to define.
101
103
  #
102
- # @return [Symbol] A protected method that define the block content.
104
+ # @return [Symbol] A private method that define the block content.
103
105
  def self.let(name, *args, **kwargs, &block)
104
- protected define_method(name.to_sym, *args, **kwargs, &block)
106
+ raise Error::ReservedMethod if [BEFORE_METHOD, AFTER_METHOD].include?(name.to_sym)
107
+
108
+ private define_method(name, *args, **kwargs, &block)
105
109
  end
106
110
 
107
111
  # Sets a user-defined property named {#subject}.
@@ -140,16 +144,11 @@ module RSpec
140
144
  # # Output to the console
141
145
  # # Success: expected to eq "foobar".
142
146
  #
143
- # @param const [Module, #object_id] A module to include in block context.
147
+ # @param const [Module, String] A module to include in block context.
144
148
  # @param block [Proc] The block to define the specs.
145
- def self.describe(const = nil, &block)
146
- desc = Sandbox.const_set(random_context_const_name, ::Class.new(self))
147
-
148
- if const.is_a?(::Module)
149
- desc.define_method(:described_class) { const }
150
- desc.send(:protected, :described_class)
151
- end
152
-
149
+ def self.describe(const, &block)
150
+ desc = ::Class.new(self)
151
+ desc.let(:described_class) { const } if const.is_a?(::Module)
153
152
  desc.instance_eval(&block)
154
153
  end
155
154
 
@@ -161,7 +160,7 @@ module RSpec
161
160
  # @example
162
161
  # require "r_spec"
163
162
  #
164
- # RSpec.describe do
163
+ # RSpec.describe "web resource" do
165
164
  # context "when resource is not found" do
166
165
  # pending "responds with 404"
167
166
  # end
@@ -179,7 +178,7 @@ module RSpec
179
178
  # "when", "with" or "without".
180
179
  # @param block [Proc] The block to define the specs.
181
180
  def self.context(_description = nil, &block)
182
- desc = Sandbox.const_set(random_context_const_name, ::Class.new(self))
181
+ desc = ::Class.new(self)
183
182
  desc.instance_eval(&block)
184
183
  end
185
184
 
@@ -224,14 +223,14 @@ module RSpec
224
223
  def self.it(_name = nil, &block)
225
224
  raise ::ArgumentError, "Missing example block" unless block
226
225
 
227
- i = it_example.new
228
- i.instance_eval(&block)
226
+ example = ::Class.new(self) { include ExpectationHelper::It }.new
227
+ example.instance_eval(&block)
229
228
  rescue ::SystemExit
230
229
  Console.source(*block.source_location)
231
230
 
232
231
  exit false
233
232
  ensure
234
- i.send(:terminate)
233
+ example.send(AFTER_METHOD)
235
234
  end
236
235
 
237
236
  # Use the {.its} method to define a single spec that specifies the actual
@@ -282,19 +281,21 @@ module RSpec
282
281
  def self.its(attribute, *args, **kwargs, &block)
283
282
  raise ::ArgumentError, "Missing example block" unless block
284
283
 
285
- i = its_example.new
284
+ example = ::Class.new(self) do
285
+ include ExpectationHelper::Its
286
286
 
287
- i.define_singleton_method(:actual) do
288
- subject.public_send(attribute, *args, **kwargs)
289
- end
287
+ define_method(:actual) do
288
+ subject.public_send(attribute, *args, **kwargs)
289
+ end
290
+ end.new
290
291
 
291
- i.instance_eval(&block)
292
+ example.instance_eval(&block)
292
293
  rescue ::SystemExit
293
294
  Console.source(*block.source_location)
294
295
 
295
296
  exit false
296
297
  ensure
297
- i.send(:terminate)
298
+ example.send(AFTER_METHOD)
298
299
  end
299
300
 
300
301
  # Defines a pending test case.
@@ -305,23 +306,16 @@ module RSpec
305
306
  # @example
306
307
  # require "r_spec"
307
308
  #
308
- # RSpec.describe do
309
+ # RSpec.describe "an example" do
309
310
  # pending "is implemented but waiting" do
310
- # expect("something").to eq("getting finished")
311
+ # expect something to be finished
311
312
  # end
312
- # end
313
313
  #
314
- # # Output to the console
315
- # # Warning: is implemented but waiting.
316
- #
317
- # @example
318
- # require "r_spec"
319
- #
320
- # RSpec.describe do
321
314
  # pending "is not yet implemented and waiting"
322
315
  # end
323
316
  #
324
317
  # # Output to the console
318
+ # # Warning: is implemented but waiting.
325
319
  # # Warning: is not yet implemented and waiting.
326
320
  #
327
321
  # @param message [String] The reason why the example is pending.
@@ -333,30 +327,7 @@ module RSpec
333
327
  Console.passed_spec Error::PendingExpectation.result(message)
334
328
  end
335
329
 
336
- # @private
337
- #
338
- # @return [Class<Dsl>] The class of the example to be tested.
339
- def self.it_example
340
- ::Class.new(self) { include ExpectationHelper::It }
341
- end
342
-
343
- # @private
344
- #
345
- # @return [Class<Dsl>] The class of the example to be tested.
346
- def self.its_example
347
- ::Class.new(self) { include ExpectationHelper::Its }
348
- end
349
-
350
- # @private
351
- #
352
- # @return [String] A random constant name for a test class.
353
- def self.random_context_const_name
354
- "Context#{::SecureRandom.hex(4).to_i(16)}"
355
- end
356
-
357
- private_class_method :it_example, :its_example, :random_context_const_name
358
-
359
- protected
330
+ private
360
331
 
361
332
  def described_class
362
333
  raise Error::UndefinedDescribedClass,
@@ -367,6 +338,8 @@ module RSpec
367
338
  raise Error::UndefinedSubject, "subject not explicitly defined"
368
339
  end
369
340
 
370
- def terminate; end
341
+ define_method(AFTER_METHOD) do
342
+ # do nothing by default
343
+ end
371
344
  end
372
345
  end
data/lib/r_spec/error.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative File.join("error", "pending_expectation")
4
+ require_relative File.join("error", "reserved_method")
4
5
  require_relative File.join("error", "undefined_described_class")
5
6
  require_relative File.join("error", "undefined_subject")
6
7
 
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpec
4
+ module Error
5
+ # Exception for reserved methods.
6
+ #
7
+ # @api private
8
+ class ReservedMethod < ::RuntimeError
9
+ end
10
+ end
11
+ end
@@ -4,7 +4,7 @@ require_relative File.join("expectation_helper", "it")
4
4
  require_relative File.join("expectation_helper", "its")
5
5
 
6
6
  module RSpec
7
- # Namespace for `it` and `its` helper modules.
7
+ # Namespace for {Dsl.it} and {Dsl.its}'s helper modules.
8
8
  module ExpectationHelper
9
9
  end
10
10
  end
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "base"
3
+ require_relative "shared"
4
4
  require_relative File.join("..", "expectation_target")
5
5
 
6
6
  module RSpec
7
7
  module ExpectationHelper
8
- # {RSpec::DSL#it}'s expectation helper module.
8
+ # {RSpec::Dsl.it}'s expectation helper module.
9
9
  module It
10
- include Base
10
+ include Shared
11
11
 
12
12
  # Create an expectation for a spec.
13
13
  #
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "base"
3
+ require_relative "shared"
4
4
  require_relative File.join("..", "expectation_target", "block")
5
5
 
6
6
  module RSpec
7
7
  module ExpectationHelper
8
- # {RSpec::DSL#its}'s expectation helper module.
8
+ # {RSpec::Dsl.its}'s expectation helper module.
9
9
  module Its
10
- include Base
10
+ include Shared
11
11
 
12
12
  # Wraps the target of an expectation with the actual value.
13
13
  #
@@ -75,7 +75,7 @@ module RSpec
75
75
  #
76
76
  # @see https://github.com/fixrb/matchi
77
77
  # @see https://github.com/fixrb/matchi-rspec
78
- module Base
78
+ module Shared
79
79
  include ::Matchi::Helper
80
80
  end
81
81
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: r_spec
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta6
4
+ version: 1.0.0.beta7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyril Kato
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-13 00:00:00.000000000 Z
11
+ date: 2021-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: expresenter
@@ -30,28 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.1.1
33
+ version: 1.1.2
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 1.1.1
40
+ version: 1.1.2
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: spectus
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 3.3.3
47
+ version: 3.3.4
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 3.3.3
54
+ version: 3.3.4
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -191,17 +191,17 @@ files:
191
191
  - lib/r_spec/dsl.rb
192
192
  - lib/r_spec/error.rb
193
193
  - lib/r_spec/error/pending_expectation.rb
194
+ - lib/r_spec/error/reserved_method.rb
194
195
  - lib/r_spec/error/undefined_described_class.rb
195
196
  - lib/r_spec/error/undefined_subject.rb
196
197
  - lib/r_spec/expectation_helper.rb
197
- - lib/r_spec/expectation_helper/base.rb
198
198
  - lib/r_spec/expectation_helper/it.rb
199
199
  - lib/r_spec/expectation_helper/its.rb
200
+ - lib/r_spec/expectation_helper/shared.rb
200
201
  - lib/r_spec/expectation_target.rb
201
202
  - lib/r_spec/expectation_target/base.rb
202
203
  - lib/r_spec/expectation_target/block.rb
203
204
  - lib/r_spec/expectation_target/value.rb
204
- - lib/r_spec/sandbox.rb
205
205
  homepage: https://r-spec.dev/
206
206
  licenses:
207
207
  - MIT
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RSpec
4
- # Namespace to collect test classes.
5
- #
6
- # @api private
7
- module Sandbox
8
- end
9
- end