r_spec-clone 1.6.0 → 1.7.0

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: 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