magic-support 0.2.0 → 0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fa812d41502d5c332298c520006236fb6c6535e8403e0beb253354712f7694e8
4
- data.tar.gz: 2029e9de5202d7c451264ae71ef471d76723e89451556b3db6c511b51102f05d
3
+ metadata.gz: e3dffa896a85c7423e7b1ad3efe36699cad07cf6703c97ba6ed4c4c28d5ad388
4
+ data.tar.gz: 8897d2aad72a04861e835d5483d5a426210a284594e1da521609689399c25da4
5
5
  SHA512:
6
- metadata.gz: 987615bca255fc3fe46178003bcea2e96df7ce8b55ae07f3b73551c8631209ddb0dea1da5931bc48396b1c983538507b96c185ebde57cbbcab40e828366753fc
7
- data.tar.gz: 4cce946f3b7dc0211041516e9d9fa5ab083b6610af51fd63e9f2f062bbedd5d383bb4039d4e6c7f02a0009272f938fe826480b782f9229c6a1b22308a82e5499
6
+ metadata.gz: 3aa49f7609147b8452ed86157288b4aa5b039fee7920a94ea9c0cc967032d54a8060f1473e39d7b32e9a9d0f25f5c1f2ca4bf8967954c5e13b429547e08951e3
7
+ data.tar.gz: 34e4287e50b6354b5af181c1cea9e15fb1ebdfa9ff9e117b28fd074af1b630d5c49d4fdfe3ea01716207c1fa0f12e958580478b1df120b9404fee690817c91b9
data/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
+ ## [0.3.0] — 2025-05-18
2
+
3
+ ### RSpec
4
+
5
+ #### Method specs
6
+
7
+ ##### Changed
8
+
9
+ - Set tested method’s owner to an overridden subject if any.
10
+
11
+ ##### Added
12
+
13
+ - Support for nesting of method specs.
14
+ - Support for named overridden subjects to follow the original RSpec API.
15
+
16
+ ##### Fixed
17
+
18
+ - `receiver` should always be equal to `subject.receiver`.
19
+
20
+
21
+ ## [0.2.1] — 2025-05-13
22
+
23
+ ### RSpec
24
+
25
+ #### Method specs
26
+
27
+ ##### Fixed
28
+
29
+ - Method specs with implicit subjects got broken in v0.2.0.
30
+
31
+
1
32
  ## [0.2.0] — 2025-05-13
2
33
 
34
+ ### Core extensions
35
+
36
+ #### Fixed
37
+
38
+ - Don’t forget to `require 'pathname'` as it’s not a core class.
39
+ - Don’t load all core extensions unless required explicitly.
40
+
3
41
  ### RSpec
4
42
 
5
43
  #### Method specs
data/README.md CHANGED
@@ -219,6 +219,12 @@ RSpec.describe MyModule do
219
219
  end
220
220
  ```
221
221
 
222
+ ##### Nesting
223
+
224
+ One may nest method specs.
225
+ This could be useful when a method being tested affects other methods.
226
+ See the spec for examples.
227
+
222
228
  ## Development
223
229
 
224
230
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Magic
4
4
  module Support
5
- VERSION = '0.2.0'
5
+ VERSION = '0.3.0'
6
6
  end
7
7
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpec
4
+ module Method # :nodoc:
5
+ # Adds the `its_result` to RSpec method example groups.
6
+ # Included by default.
7
+ module Its
8
+ def its_result(*args, &) = its(args, &)
9
+ end
10
+
11
+ ExampleGroup::ClassMethods.include Its
12
+ end
13
+ end
data/lib/rspec/method.rb CHANGED
@@ -11,7 +11,7 @@ module RSpec # :nodoc:
11
11
  }
12
12
  .map { |name, pattern| "(?<#{name}>#{pattern})" }
13
13
  .join
14
- .then { /(?:^|\s)#{_1}(?:$|\s)/ } # may be surrounded by some text
14
+ .then { /(?:^|\s)#{_1}\b/ } # may be surrounded by some text
15
15
 
16
16
  # @api public
17
17
  # Container module for method specs.
@@ -21,39 +21,57 @@ module RSpec # :nodoc:
21
21
  included do
22
22
  metadata[:type] ||= :method
23
23
 
24
- description.match(REFERENCE) in { scope:, name: } or
25
- raise ArgumentError, "'#{description}' doesn't look like a method reference"
26
-
27
- subject_method = instance_method :subject
28
-
29
- while subject_method.owner.then { not _1.respond_to? :metadata or _1.metadata[:method] }
30
- subject_method = subject_method.super_method or break
31
- end
24
+ setup_method_context
25
+ end
32
26
 
33
- let :receiver do
34
- case [ scope, subject_method&.bind_call(self) || super() ]
35
- in '#', receiver
36
- receiver
37
- in '.', Module => receiver
38
- receiver
39
- in '.', receiver
40
- receiver.class
27
+ class_methods do
28
+ def subject(name = nil, &)
29
+ if name
30
+ alias_method :__subject__, let(name, &)
31
+
32
+ self::NamedSubjectPreventSuper.__send__ :define_method, name do
33
+ raise NotImplementedError, '`super` in named subjects is not supported'
34
+ end
35
+ else
36
+ let :__subject__, &
41
37
  end
42
38
  end
43
39
 
44
- let(:method_name) { name.to_sym }
45
- end
40
+ private
46
41
 
47
- class_methods do
48
- def subject(&)
49
- prepend Module.new {
50
- define_method(:subject) { super().unbind.bind instance_eval(&) }
51
- }
42
+ def setup_method_context
43
+ description.match(REFERENCE) in { scope:, name: } or
44
+ raise ArgumentError, "'#{description}' doesn't look like a method reference"
45
+
46
+ backup_subject
47
+
48
+ let :receiver do
49
+ case [ scope, __subject__ ]
50
+ in '#', receiver
51
+ receiver
52
+ in '.', Module => receiver
53
+ receiver
54
+ in '.', receiver
55
+ receiver.class
56
+ end
57
+ end
58
+
59
+ let(:method_name) { name.to_sym }
52
60
  end
53
61
 
54
- next unless defined? RSpec::Its
62
+ def backup_subject
63
+ subject_method = instance_method :subject
64
+
65
+ while subject_method.owner.then { not _1.respond_to? :metadata or _1.metadata[:method] }
66
+ subject_method = subject_method.super_method or break
67
+ end
55
68
 
56
- def its_result(*args, &) = its(args, &)
69
+ if subject_method
70
+ let(:__subject__) { subject_method.bind_call self }
71
+ else
72
+ let(:__subject__) { method(:subject).super_method[] }
73
+ end
74
+ end
57
75
  end
58
76
 
59
77
  def subject
@@ -69,6 +87,8 @@ module RSpec # :nodoc:
69
87
  end
70
88
  end
71
89
 
90
+ require_relative 'method/its' if defined? Its
91
+
72
92
  shared_context :method, description: Method::REFERENCE do
73
93
  include Method::ExampleGroup
74
94
 
@@ -88,6 +108,12 @@ module RSpec # :nodoc:
88
108
  end
89
109
  end
90
110
 
111
+ shared_context :nested_method, full_description: /(.*#{Method::REFERENCE}){2,}/ do
112
+ next unless metadata[:description].match? Method::REFERENCE
113
+
114
+ setup_method_context
115
+ end
116
+
91
117
  configure do
92
118
  _1.backtrace_exclusion_patterns << %r'/lib/rspec/method'
93
119
  end
@@ -0,0 +1,7 @@
1
+ module RSpec
2
+ module Method
3
+ module Its
4
+ def its_result: (*untyped) -> void
5
+ end
6
+ end
7
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: magic-support
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Senko
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-05-13 00:00:00.000000000 Z
10
+ date: 2025-05-18 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: activesupport
@@ -46,6 +46,7 @@ files:
46
46
  - lib/magic/support/authors.rb
47
47
  - lib/magic/support/version.rb
48
48
  - lib/rspec/method.rb
49
+ - lib/rspec/method/its.rb
49
50
  - lib/rubygems/author.rb
50
51
  - sig/lib/magic/support/author.rbs
51
52
  - sig/magic/core_ext.rbs
@@ -53,13 +54,14 @@ files:
53
54
  - sig/magic/loader.rbs
54
55
  - sig/magic/support.rbs
55
56
  - sig/rspec/method.rbs
57
+ - sig/rspec/method/its.rbs
56
58
  - sig/rubygems/author.rbs
57
59
  homepage: https://github.com/Alexander-Senko/magic-support
58
60
  licenses:
59
61
  - MIT
60
62
  metadata:
61
63
  source_code_uri: https://github.com/Alexander-Senko/magic-support
62
- changelog_uri: https://github.com/Alexander-Senko/magic-support/blob/v0.2.0/CHANGELOG.md
64
+ changelog_uri: https://github.com/Alexander-Senko/magic-support/blob/v0.3.0/CHANGELOG.md
63
65
  rdoc_options: []
64
66
  require_paths:
65
67
  - lib