r_spec-clone 1.6.0 → 1.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d2e7a16588ed11ac0ab9cd7eebcb01c3d6e914d351c5041cfbed6015c88128ea
4
- data.tar.gz: 96dfc31819a59b319c06c777a63aa09daf5630a3db7cf5860c59474b1809f94c
3
+ metadata.gz: 6014d4cd0ffe271d71ff599cdba7ce291b5329c062aeea611c292dcb9d24d822
4
+ data.tar.gz: 96e14ce3c34c9d5d6e9a6c49769c94db2562e2a14eaeae94e6415884f2f5c7eb
5
5
  SHA512:
6
- metadata.gz: f34d7820173f21ffdafe71d206314aee90904ab7b9a46c29511aed5e4191742e87a14ef2e9da512e48917c080c97d52b5618ce545519f49955fb3edc6b20022d
7
- data.tar.gz: d2ad326e9150e95b19f9f62994568e5a44474b6567727e15c38020ede970f1c20b4bd0ddc1d1ab450f968fedfd109ed795accda5724b0424ef666fe09e31e92c
6
+ metadata.gz: c7bd806d2a1a220c86320a6a8fa93bf9b19f60ac2a0b4f03f510f727d6d0132995c0dde783659923c2031d7f0864b63f5137976c136d3c1c90a62ecd8996ef25
7
+ data.tar.gz: 4eda5fc59e05cb4a2a20e18cc403a89985552737b551d2f343fedf3b9f98f6dd572ef977c0164926b5b0703a9b91b2901189bcad6823618558c908df6a869c4a
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- The MIT License (MIT)
1
+ # The MIT License
2
2
 
3
3
  Copyright (c) 2015-2022 Cyril Kato
4
4
 
data/README.md CHANGED
@@ -15,14 +15,14 @@ A minimalist __RSpec clone__ with all the essentials.
15
15
 
16
16
  ## Project goals
17
17
 
18
- 1. Keep a low level of code complexity, avoid false negatives and false positives.
19
- 2. Translate specification documents into atomic and thread safe Ruby objects.
18
+ 1. Keep code complexity low, avoid false negatives and false positives.
19
+ 2. Load specifications in simple, atomic and thread safe Ruby primitives.
20
20
  3. Avoid overloading the interface with additional alternative syntaxes.
21
- 4. Provide most of RSpec's DSL to express expected outcomes of a code example.
21
+ 4. Provide the basics of DSL RSpec to write tests.
22
22
 
23
23
  ## Some differences
24
24
 
25
- * There is no option to activate monkey-patching.
25
+ * There is no option to enable monkey-patching.
26
26
  * It does not rely on [hacks such as `at_exit` hook](https://blog.arkency.com/2013/06/are-we-abusing-at-exit/) to trigger the tests.
27
27
  * Malicious _actual values_ cannot [hack results](https://asciinema.org/a/423547?autoplay=1&speed=2).
28
28
  * If no `subject` has been explicitly determined, none is defined.
@@ -31,9 +31,9 @@ A minimalist __RSpec clone__ with all the essentials.
31
31
  * [Arbitrary helper methods](https://relishapp.com/rspec/rspec-core/v/3-10/docs/helper-methods/arbitrary-helper-methods) are not exposed to examples.
32
32
  * The `let` method defines a helper method rather than a memoized helper method.
33
33
  * The one-liner `is_expected` syntax also works with block expectations.
34
- * `subject`, `before`, `after` and `let` definitions must come before examples.
34
+ * `subject`, `before` and `let` definitions must come before examples.
35
35
  * The execution of the test suite stops as soon as an error is detected.
36
- * The order of the unit tests does not matter because they are executed in isolation.
36
+ * Each `context` block isolates its tests and possible side effects.
37
37
 
38
38
  ## Installation
39
39
 
@@ -87,7 +87,7 @@ To express an expectation, wrap an object or block in `expect`, call `to` (or `n
87
87
  If the expectation is met, code execution continues.
88
88
  Otherwise the example has _failed_ and other code will not be executed.
89
89
 
90
- In test files, specs are structured by example groups which are defined by `describe` and `context` sections.
90
+ In test files, specs can be structured by example groups which are defined by `describe` and `context` sections.
91
91
  Typically a top level `describe` defines the outer unit (such as a class) to be tested by the spec.
92
92
  Further `describe` sections can be nested within the outer unit to specify smaller units under test (such as individual methods).
93
93
 
@@ -98,6 +98,9 @@ For unit tests, it is recommended to follow the conventions for method names:
98
98
 
99
99
  To establish certain contexts — think _empty array_ versus _array with elements_ — the `context` method may be used to communicate this to the reader.
100
100
 
101
+ Unlike a `describe` block, all specifications executed within a `context` are isolated in a subprocess.
102
+ This prevents possible side effects on the Ruby object environment from being propagated outside their context, which could alter the result of the unit test suite.
103
+
101
104
  Note: if you are wondering what kind of code might be generated by the DSL, an article that shows the dynamic transcription of the main methods with simple examples is available in [Chinese](https://ruby-china.org/topics/41441), in [English](https://dev.to/cyri_/what-ruby-code-to-expect-from-a-testing-dsl-4oe1) and in [Japanese](https://qiita.com/cyril/items/17ee758e162bae144a07).
102
105
 
103
106
  ### Expectations
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "console"
3
+ require_relative "logger"
4
4
  require_relative "error"
5
5
  require_relative "expectation_helper"
6
6
 
@@ -9,9 +9,8 @@ module RSpec
9
9
  # Abstract class for handling the domain-specific language.
10
10
  class Dsl
11
11
  BEFORE_METHOD = :initialize
12
- AFTER_METHOD = :terminate
13
12
 
14
- private_constant :BEFORE_METHOD, :AFTER_METHOD
13
+ private_constant :BEFORE_METHOD
15
14
 
16
15
  # Executes the given block before each spec in the current context runs.
17
16
  #
@@ -53,35 +52,6 @@ module RSpec
53
52
  private BEFORE_METHOD
54
53
  end
55
54
 
56
- # Executes the given block after each spec in the current context runs.
57
- #
58
- # @example
59
- # require "r_spec"
60
- #
61
- # RSpec.describe Integer do
62
- # after do
63
- # puts "That is the answer to everything."
64
- # end
65
- #
66
- # it { expect(42).to be 42 }
67
- # end
68
- #
69
- # # Output to the console
70
- # # Success: expected to be 42.
71
- # # That is the answer to everything.
72
- #
73
- # @param block [Proc] The content to execute at the class initialization.
74
- #
75
- # @api public
76
- def self.after(&block)
77
- define_method(AFTER_METHOD) do
78
- instance_exec(&block)
79
- super()
80
- end
81
-
82
- private AFTER_METHOD
83
- end
84
-
85
55
  # Sets a user-defined property.
86
56
  #
87
57
  # @example
@@ -110,7 +80,7 @@ module RSpec
110
80
  #
111
81
  # @api public
112
82
  def self.let(name, *args, **kwargs, &block)
113
- raise Error::ReservedMethod if [BEFORE_METHOD, AFTER_METHOD].include?(name.to_sym)
83
+ raise Error::ReservedMethod if BEFORE_METHOD.equal?(name.to_sym)
114
84
 
115
85
  private define_method(name, *args, **kwargs, &block)
116
86
  end
@@ -176,6 +146,11 @@ module RSpec
176
146
  # Defines an example group that establishes a specific context, like
177
147
  # _empty array_ versus _array with elements_.
178
148
  #
149
+ # Unlike a `describe` block, all specifications executed within a
150
+ # `context` are isolated in a subprocess. This prevents possible side
151
+ # effects on the Ruby object environment from being propagated outside
152
+ # their context, which could alter the result of the unit test suite.
153
+ #
179
154
  # @example
180
155
  # require "r_spec"
181
156
  #
@@ -199,8 +174,8 @@ module RSpec
199
174
  #
200
175
  # @api public
201
176
  def self.context(_description, &block)
202
- desc = ::Class.new(self)
203
- desc.instance_eval(&block)
177
+ pid = ::Process.fork { ::Class.new(self).instance_eval(&block) }
178
+ exit false unless ::Process::Status.wait(pid).exitstatus.zero?
204
179
  end
205
180
 
206
181
  # :nocov:
@@ -246,7 +221,8 @@ module RSpec
246
221
  #
247
222
  # @api public
248
223
  def self.it(_name = nil, &block)
249
- exit false unless ::Aw.fork? { run(example_without_attribute.new, &block) }
224
+ Logger.source(*block.source_location)
225
+ example_without_attribute.new.instance_eval(&block)
250
226
  end
251
227
 
252
228
  # :nocov:
@@ -298,7 +274,9 @@ module RSpec
298
274
  #
299
275
  # @api public
300
276
  def self.its(attribute, *args, **kwargs, &block)
301
- exit false unless ::Aw.fork? { run(example_with_attribute(attribute, *args, **kwargs).new, &block) }
277
+ Logger.source(*block.source_location)
278
+ example_with_attribute(attribute, *args, **kwargs).new
279
+ .instance_eval(&block)
302
280
  end
303
281
 
304
282
  # :nocov:
@@ -329,7 +307,7 @@ module RSpec
329
307
  #
330
308
  # @api public
331
309
  def self.pending(message)
332
- Console.passed_spec Error::PendingExpectation.result(message)
310
+ Logger.passed_spec Error::PendingExpectation.result(message)
333
311
  end
334
312
 
335
313
  # Example class for concrete test case.
@@ -351,15 +329,7 @@ module RSpec
351
329
  end
352
330
  end
353
331
 
354
- # Execution of specifications.
355
- def self.run(example, &block)
356
- Console.source(*block.source_location)
357
- exit false unless ::Aw.fork? { example.instance_eval(&block) }
358
- ensure
359
- example&.send(AFTER_METHOD)
360
- end
361
-
362
- private_class_method :example_without_attribute, :example_with_attribute, :run
332
+ private_class_method :example_without_attribute, :example_with_attribute
363
333
 
364
334
  private
365
335
 
@@ -374,10 +344,6 @@ module RSpec
374
344
  def subject
375
345
  raise Error::UndefinedSubject, "subject not explicitly defined"
376
346
  end
377
-
378
- define_method(AFTER_METHOD) do
379
- # do nothing by default
380
- end
381
347
  end
382
348
  end
383
349
  end
@@ -3,7 +3,7 @@
3
3
  require "expresenter"
4
4
  require "test_tube"
5
5
 
6
- require_relative File.join("..", "console")
6
+ require_relative File.join("..", "logger")
7
7
 
8
8
  module RSpec
9
9
  module Clone
@@ -82,6 +82,8 @@ module RSpec
82
82
  test.got.equal?(true)
83
83
  end
84
84
 
85
+ # :nocov:
86
+
85
87
  # @param passed [Boolean] The high expectation passed or failed.
86
88
  # @param actual [#object_id] The actual value.
87
89
  # @param error [Exception, nil] Any raised exception.
@@ -94,7 +96,7 @@ module RSpec
94
96
  # @raise [SystemExit] Terminate execution immediately by calling
95
97
  # `Kernel.exit(false)` with a failure message written to STDERR.
96
98
  def result(passed, actual:, error:, got:, matcher:, negate:)
97
- Console.passed_spec ::Expresenter.call(passed).with(
99
+ Logger.passed_spec ::Expresenter.call(passed).with(
98
100
  actual: actual,
99
101
  definition: matcher.to_s,
100
102
  error: error,
@@ -104,8 +106,10 @@ module RSpec
104
106
  level: :MUST
105
107
  )
106
108
  rescue ::Expresenter::Fail => e
107
- Console.failed_spec(e)
109
+ Logger.failed_spec(e)
108
110
  end
111
+
112
+ # :nocov:
109
113
  end
110
114
  end
111
115
  end
@@ -3,7 +3,7 @@
3
3
  module RSpec
4
4
  module Clone
5
5
  # Send log messages to the console.
6
- module Console
6
+ module Logger
7
7
  # @param report [::Expresenter::Pass] Passed expectation result presenter.
8
8
  #
9
9
  # @see https://github.com/fixrb/expresenter
@@ -13,17 +13,21 @@ module RSpec
13
13
  puts report.colored_string
14
14
  end
15
15
 
16
+ # :nocov:
17
+
16
18
  # @param report [::Expresenter::Fail] Failed expectation result presenter.
17
19
  #
18
20
  # @see https://github.com/fixrb/expresenter
19
21
  #
20
- # @raise [SystemExit] Terminate execution immediately with colored message.
22
+ # @raise [SystemExit] Terminate execution immediately with message.
21
23
  def self.failed_spec(report)
22
24
  abort report.colored_string
23
25
  end
24
26
 
25
- # The Ruby source filename and line number containing this method or nil if
26
- # this method was not defined in Ruby (i.e. native).
27
+ # :nocov:
28
+
29
+ # The Ruby source filename and line number containing this method or nil
30
+ # if this method was not defined in Ruby (i.e. native).
27
31
  #
28
32
  # @param filename [String, nil] The Ruby source filename.
29
33
  # @param line [Integer, nil] The Ruby source line number.
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: r_spec-clone
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyril Kato
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-02 00:00:00.000000000 Z
11
+ date: 2022-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: aw
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: 0.2.0
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: 0.2.0
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: expresenter
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -44,14 +30,14 @@ dependencies:
44
30
  requirements:
45
31
  - - "~>"
46
32
  - !ruby/object:Gem::Version
47
- version: 3.3.0
33
+ version: 3.3.1
48
34
  type: :runtime
49
35
  prerelease: false
50
36
  version_requirements: !ruby/object:Gem::Requirement
51
37
  requirements:
52
38
  - - "~>"
53
39
  - !ruby/object:Gem::Version
54
- version: 3.3.0
40
+ version: 3.3.1
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: test_tube
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -202,7 +188,6 @@ files:
202
188
  - README.md
203
189
  - lib/r_spec.rb
204
190
  - lib/r_spec/clone.rb
205
- - lib/r_spec/clone/console.rb
206
191
  - lib/r_spec/clone/dsl.rb
207
192
  - lib/r_spec/clone/error.rb
208
193
  - lib/r_spec/clone/error/pending_expectation.rb
@@ -217,6 +202,7 @@ files:
217
202
  - lib/r_spec/clone/expectation_target/base.rb
218
203
  - lib/r_spec/clone/expectation_target/block.rb
219
204
  - lib/r_spec/clone/expectation_target/value.rb
205
+ - lib/r_spec/clone/logger.rb
220
206
  homepage: https://r-spec.dev/
221
207
  licenses:
222
208
  - MIT
@@ -234,14 +220,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
234
220
  requirements:
235
221
  - - ">="
236
222
  - !ruby/object:Gem::Version
237
- version: 2.7.5
223
+ version: 3.0.4
238
224
  required_rubygems_version: !ruby/object:Gem::Requirement
239
225
  requirements:
240
226
  - - ">="
241
227
  - !ruby/object:Gem::Version
242
228
  version: '0'
243
229
  requirements: []
244
- rubygems_version: 3.1.6
230
+ rubygems_version: 3.2.33
245
231
  signing_key:
246
232
  specification_version: 4
247
233
  summary: A minimalist RSpec clone