smartest 0.3.3.alpha2 → 0.3.3.alpha3

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: 396af151370001b4762c6c1a71426fef7c2e0773626080af62496bc068afdc02
4
- data.tar.gz: 0b5b6e9e76582dfd91df63fe7e2928fbbd6d0a90101e8f3d9834a91d7b94c109
3
+ metadata.gz: 46365bf842594d74023e6c47da5b98f28e2f8ad765a035de09a54f5d127db2ee
4
+ data.tar.gz: 53134bcd0052d5cd8b495b36a9ba8bb1344c6dcb0626d0547dfa49bf6eff005e
5
5
  SHA512:
6
- metadata.gz: 320397233b8b2e0c46b5d44d6a8bc892d44bfccfc9b63a1db31f868fdc3ac7da7c500902f93b36124f61119dc23b05a3238d3032d7e814defed8c7f5b57f9ef1
7
- data.tar.gz: 0b507415bf8e31472e4117371474226fbec62802be8a41d002cc38403967d2a877e60d2a7fb0d0695490e416e1fcf208928f3a6882620208c4d694f425138b37
6
+ metadata.gz: a5ffe755697e79babe4e54e52d9a2e2a13aee1ade7306dfa7adffd7d9ea6ca75b7b96825b05c713261f420f35b28e980a85b068a94823109bffc0a54774d864a
7
+ data.tar.gz: c030cd6bfcfb44f8273348f99a36a6213c237c9bd580cd49287351b4bf9b70a04af3b6b7889287f12ffbda747dfd7d6a450b9954bf51f8c2bdf5fb71768027ba
data/README.md CHANGED
@@ -613,6 +613,18 @@ class PaymentFixture < Smartest::Fixture
613
613
  end
614
614
  ```
615
615
 
616
+ Register the fixture class from `around_suite` before tests request the fixture:
617
+
618
+ ```ruby
619
+ around_suite do |suite|
620
+ use_fixture PaymentFixture
621
+ suite.run
622
+ end
623
+ ```
624
+
625
+ `use_fixture` is available inside `around_suite` or `around_test` blocks, not as
626
+ a top-level method in a test file.
627
+
616
628
  The stub affects existing instances and new instances of the target class in
617
629
  the current Fiber until it is reset. Other Fibers and Threads continue to see
618
630
  the original method unless they apply their own stub. Tests can request the
@@ -625,10 +637,16 @@ end
625
637
  ```
626
638
 
627
639
  Use `simple_stub(Time, :now) { fixed_time }` for singleton methods such as class
628
- methods. Both helpers call `Smartest::SimpleStub` internally, apply the stub,
629
- register `cleanup { stub.reset }`, and return the stub object. They are
630
- available inside `Smartest::Fixture` fixture blocks because they need cleanup to
631
- tie the stub lifetime to the fixture scope.
640
+ methods. Use `simple_stub_const("AppConfig::PAYMENT_PROVIDER", "fake")` for
641
+ constants. Constant stubs are process-global; avoid concurrent tests that stub
642
+ the same constant.
643
+
644
+ The method stub helpers call `Smartest::SimpleStub` internally, apply the stub,
645
+ register `cleanup { stub.reset }`, and return the stub object.
646
+ `simple_stub_const` records the previous constant value, replaces it, and
647
+ restores or removes it during cleanup. These helpers are available inside
648
+ `Smartest::Fixture` fixture blocks because they need cleanup to tie the stub
649
+ lifetime to the fixture scope.
632
650
 
633
651
  `Smartest::SimpleStub#apply` and `#reset` are idempotent in the current Fiber.
634
652
  `apply!` raises
@@ -862,7 +880,7 @@ Smartest currently focuses on a small runner API:
862
880
  - fixture dependencies through keyword arguments
863
881
  - fixture cleanup
864
882
  - suite-scoped fixtures through `suite_fixture`
865
- - fixture-scoped method stubs through `simple_stub_any_instance_of` and `simple_stub`
883
+ - fixture-scoped method and constant stubs
866
884
  - suite hooks with `around_suite`
867
885
  - test hooks with `around_test`
868
886
  - skipped and pending tests through `skip` and `pending`
@@ -73,12 +73,48 @@ module Smartest
73
73
  apply_simple_stub(SimpleStub.new(object.singleton_class, method_name, &block))
74
74
  end
75
75
 
76
+ def simple_stub_const(constant_path, value)
77
+ owner, constant_name = resolve_simple_stub_constant(constant_path)
78
+ original_defined = owner.const_defined?(constant_name, false)
79
+ original_value = owner.const_get(constant_name, false) if original_defined
80
+
81
+ owner.__send__(:remove_const, constant_name) if original_defined
82
+ owner.const_set(constant_name, value)
83
+
84
+ cleanup do
85
+ owner.__send__(:remove_const, constant_name) if owner.const_defined?(constant_name, false)
86
+ owner.const_set(constant_name, original_value) if original_defined
87
+ end
88
+
89
+ value
90
+ end
91
+
76
92
  def apply_simple_stub(stub)
77
93
  stub.apply!
78
94
  cleanup { stub.reset }
79
95
  stub
80
96
  end
81
97
 
98
+ def resolve_simple_stub_constant(constant_path)
99
+ unless constant_path.is_a?(String) || constant_path.is_a?(Symbol)
100
+ raise ArgumentError, "constant path must be a String or Symbol"
101
+ end
102
+
103
+ names = constant_path.to_s.split("::")
104
+ names.shift if names.first == ""
105
+ raise ArgumentError, "constant path must not be empty" if names.empty?
106
+
107
+ names.each do |name|
108
+ raise ArgumentError, "invalid constant path: #{constant_path}" unless name.match?(/\A[A-Z]\w*\z/)
109
+ end
110
+
111
+ constant_name = names.pop.to_sym
112
+ owner = names.reduce(Object) { |namespace, name| namespace.const_get(name, false) }
113
+ raise ArgumentError, "constant owner must be a Module or Class" unless owner.is_a?(Module)
114
+
115
+ [owner, constant_name]
116
+ end
117
+
82
118
  def method_missing(method_name, *args, &block)
83
119
  return super if RESERVED_CONTEXT_METHODS.include?(method_name)
84
120
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Smartest
4
- VERSION = "0.3.3.alpha2"
4
+ VERSION = "0.3.3.alpha3"
5
5
  end
@@ -63,6 +63,10 @@ class SimpleStubSelfTestClock
63
63
  end
64
64
  end
65
65
 
66
+ module SimpleStubSelfTestConfig
67
+ PROVIDER = :original_provider
68
+ end
69
+
66
70
  test("simple stub stubs instance methods until reset") do
67
71
  existing = SimpleStubSelfTestSubject.new("Alice")
68
72
  stub = Smartest::SimpleStub.new(SimpleStubSelfTestSubject, :name) { "stubbed" }
@@ -154,6 +158,66 @@ test("simple_stub applies and resets singleton methods from fixture cleanup") do
154
158
  expect(status).to eq(0)
155
159
  end
156
160
 
161
+ test("simple_stub_const applies and resets existing constants from fixture cleanup") do
162
+ fixture_class = Class.new(Smartest::Fixture) do
163
+ fixture :stubbed_provider do
164
+ simple_stub_const("SimpleStubSelfTestConfig::PROVIDER", :stubbed_provider)
165
+ end
166
+ end
167
+
168
+ suite = Smartest::Suite.new
169
+ suite.fixture_classes.add(fixture_class)
170
+ suite.tests.add(
171
+ SimpleStubSelfTest.test_case(
172
+ "uses constant stub fixture",
173
+ proc do |stubbed_provider:|
174
+ expect(stubbed_provider).to eq(:stubbed_provider)
175
+ expect(SimpleStubSelfTestConfig::PROVIDER).to eq(:stubbed_provider)
176
+ end
177
+ )
178
+ )
179
+ suite.tests.add(
180
+ SimpleStubSelfTest.test_case(
181
+ "sees restored constant",
182
+ proc { expect(SimpleStubSelfTestConfig::PROVIDER).to eq(:original_provider) }
183
+ )
184
+ )
185
+
186
+ status, = SimpleStubSelfTest.run_suite(suite)
187
+
188
+ expect(status).to eq(0)
189
+ end
190
+
191
+ test("simple_stub_const removes newly defined constants from fixture cleanup") do
192
+ fixture_class = Class.new(Smartest::Fixture) do
193
+ fixture :stubbed_missing_provider do
194
+ simple_stub_const("SimpleStubSelfTestConfig::MISSING_PROVIDER", :stubbed_missing_provider)
195
+ end
196
+ end
197
+
198
+ suite = Smartest::Suite.new
199
+ suite.fixture_classes.add(fixture_class)
200
+ suite.tests.add(
201
+ SimpleStubSelfTest.test_case(
202
+ "uses new constant stub fixture",
203
+ proc do |stubbed_missing_provider:|
204
+ expect(stubbed_missing_provider).to eq(:stubbed_missing_provider)
205
+ expect(SimpleStubSelfTestConfig::MISSING_PROVIDER).to eq(:stubbed_missing_provider)
206
+ end
207
+ )
208
+ )
209
+ suite.tests.add(
210
+ SimpleStubSelfTest.test_case(
211
+ "sees removed constant",
212
+ proc { expect(SimpleStubSelfTestConfig.const_defined?(:MISSING_PROVIDER, false)).to eq(false) }
213
+ )
214
+ )
215
+
216
+ status, = SimpleStubSelfTest.run_suite(suite)
217
+
218
+ expect(status).to eq(0)
219
+ end
220
+
157
221
  test("simple stub preserves receiver self and method blocks") do
158
222
  subject = SimpleStubSelfTestSubject.new("Alice")
159
223
  stub = Smartest::SimpleStub.new(SimpleStubSelfTestSubject, :yielding_greeting) do |prefix, &block|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smartest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3.alpha2
4
+ version: 0.3.3.alpha3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yusuke Iwaki