Module: CMDx::RSpec::Helpers
- Defined in:
- lib/cmdx/rspec/helpers.rb
Overview
RSpec helpers for stubbing and asserting Task execution. Each helper builds a frozen CMDx::Result carrying the requested Signal and wires it into a fresh Chain so callers see realistic execution output without invoking the Task’s ‘work`.
Mix into example groups via ‘config.include CMDx::RSpec::Helpers`.
Instance Method Summary collapse
-
#capture_cmdx_logs { ... } ⇒ Array<String>
Captures lines written to a temporary CMDx logger for the duration of the block.
-
#expect_no_task_execution(command, **context) ⇒ RSpec::Mocks::MessageExpectation
Sets a negative message expectation that ‘command.execute` is not invoked.
-
#expect_no_task_execution!(command, **context) ⇒ RSpec::Mocks::MessageExpectation
Sets a negative message expectation that ‘command.execute!` is not invoked.
-
#expect_task_execution(command, **context) ⇒ RSpec::Mocks::MessageExpectation
Sets a positive message expectation that ‘command.execute` is invoked.
-
#expect_task_execution!(command, **context) ⇒ RSpec::Mocks::MessageExpectation
Sets a positive message expectation that ‘command.execute!` is invoked.
-
#stub_task_deprecated(command, metadata: {}, **context) ⇒ CMDx::Result
Stubs ‘command.execute` to return a successful Result flagged as `deprecated?`.
-
#stub_task_error(command, exception, message = nil, metadata: {}, **context) ⇒ CMDx::Result
Stubs ‘command.execute` to return a frozen failed Result whose `cause` is an instance of
exception. -
#stub_task_fail(command, reason: nil, cause: nil, metadata: {}, **context) ⇒ CMDx::Result
Stubs ‘command.execute` to return a frozen failed Result.
-
#stub_task_fail!(command, reason: nil, cause: nil, metadata: {}, **context) ⇒ CMDx::Result
Stubs ‘command.execute!` (bang variant) to return a frozen failed Result.
-
#stub_task_skip(command, reason: nil, cause: nil, metadata: {}, **context) ⇒ CMDx::Result
Stubs ‘command.execute` to return a frozen skipped Result.
-
#stub_task_skip!(command, reason: nil, cause: nil, metadata: {}, **context) ⇒ CMDx::Result
Stubs ‘command.execute!` (bang variant) to return a frozen skipped Result.
-
#stub_task_success(command, metadata: {}, **context) ⇒ CMDx::Result
Stubs ‘command.execute` to return a frozen successful Result.
-
#stub_task_success!(command, metadata: {}, **context) ⇒ CMDx::Result
Stubs ‘command.execute!` (bang variant) to return a frozen successful Result.
-
#stub_task_throw(command, upstream_result, metadata: {}, **context) ⇒ CMDx::Result
Stubs ‘command.execute` to return a frozen failed Result that echoes
upstream_result. -
#stub_workflow_tasks(command) {|task| ... } ⇒ void
Yields each distinct Task class reachable from a Workflow’s pipeline, in first-seen order, so callers can stub them in a single block.
-
#subscribe_telemetry(command, *events) { ... } ⇒ Array<CMDx::Telemetry::Event>
Subscribes to telemetry events on
command‘s telemetry registry for the duration of the block. -
#unstub_task(command, **context) ⇒ void
Restores ‘command.execute` to its original implementation.
-
#unstub_task!(command, **context) ⇒ void
Restores ‘command.execute!` to its original implementation.
-
#with_cmdx_chain(command) { ... } ⇒ CMDx::Chain?
Captures the Chain produced by
command‘s execution within the block.
Instance Method Details
#capture_cmdx_logs { ... } ⇒ Array<String>
Captures lines written to a temporary CMDx logger for the duration of the block. Restores the previous logger on exit.
141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/cmdx/rspec/helpers.rb', line 141 def capture_cmdx_logs(&) raise ArgumentError, "block required" unless block_given? io = StringIO.new previous = CMDx.configuration.logger CMDx.configuration.logger = Logger.new(io, formatter: previous&.formatter || CMDx::LogFormatters::Line.new) yield io.string.lines.map(&:chomp) ensure CMDx.configuration.logger = previous if previous end |
#expect_no_task_execution(command, **context) ⇒ RSpec::Mocks::MessageExpectation
Sets a negative message expectation that ‘command.execute` is not invoked. When `context` is supplied, only the matching signature is forbidden.
278 279 280 281 282 283 284 |
# File 'lib/cmdx/rspec/helpers.rb', line 278 def expect_no_task_execution(command, **context) if context.empty? expect(command).not_to receive(:execute) else expect(command).not_to receive(:execute).with(**context) end end |
#expect_no_task_execution!(command, **context) ⇒ RSpec::Mocks::MessageExpectation
Sets a negative message expectation that ‘command.execute!` is not invoked. When `context` is supplied, only the matching signature is forbidden.
292 293 294 295 296 297 298 |
# File 'lib/cmdx/rspec/helpers.rb', line 292 def expect_no_task_execution!(command, **context) if context.empty? expect(command).not_to receive(:execute!) else expect(command).not_to receive(:execute!).with(**context) end end |
#expect_task_execution(command, **context) ⇒ RSpec::Mocks::MessageExpectation
Sets a positive message expectation that ‘command.execute` is invoked. When `context` is supplied, the expectation is constrained to that signature.
250 251 252 253 254 255 256 |
# File 'lib/cmdx/rspec/helpers.rb', line 250 def expect_task_execution(command, **context) if context.empty? expect(command).to receive(:execute) else expect(command).to receive(:execute).with(**context) end end |
#expect_task_execution!(command, **context) ⇒ RSpec::Mocks::MessageExpectation
Sets a positive message expectation that ‘command.execute!` is invoked. When `context` is supplied, the expectation is constrained to that signature.
264 265 266 267 268 269 270 |
# File 'lib/cmdx/rspec/helpers.rb', line 264 def expect_task_execution!(command, **context) if context.empty? expect(command).to receive(:execute!) else expect(command).to receive(:execute!).with(**context) end end |
#stub_task_deprecated(command, metadata: {}, **context) ⇒ CMDx::Result
Stubs ‘command.execute` to return a successful Result flagged as `deprecated?`. Useful when asserting deprecation surfaces without triggering the real `Deprecation` action.
129 130 131 |
# File 'lib/cmdx/rspec/helpers.rb', line 129 def stub_task_deprecated(command, metadata: {}, **context) build_stub(command, :execute, CMDx::Signal.success(nil, metadata:), context, deprecated: true) end |
#stub_task_error(command, exception, message = nil, metadata: {}, **context) ⇒ CMDx::Result
Stubs ‘command.execute` to return a frozen failed Result whose `cause` is an instance of exception. Models the “rescued StandardError -> failed signal” path that Runtime takes when a task’s ‘work` raises something other than a Fault.
97 98 99 100 101 |
# File 'lib/cmdx/rspec/helpers.rb', line 97 def stub_task_error(command, exception, = nil, metadata: {}, **context) ex = exception.is_a?(Class) ? exception.new( || "stubbed") : exception reason = "[#{ex.class}] #{ex.}" build_stub(command, :execute, CMDx::Signal.failed(reason, metadata:, cause: ex), context) end |
#stub_task_fail(command, reason: nil, cause: nil, metadata: {}, **context) ⇒ CMDx::Result
Stubs ‘command.execute` to return a frozen failed Result.
67 68 69 |
# File 'lib/cmdx/rspec/helpers.rb', line 67 def stub_task_fail(command, reason: nil, cause: nil, metadata: {}, **context) build_stub(command, :execute, CMDx::Signal.failed(reason, metadata:, cause:), context) end |
#stub_task_fail!(command, reason: nil, cause: nil, metadata: {}, **context) ⇒ CMDx::Result
Stubs ‘command.execute!` (bang variant) to return a frozen failed Result.
79 80 81 |
# File 'lib/cmdx/rspec/helpers.rb', line 79 def stub_task_fail!(command, reason: nil, cause: nil, metadata: {}, **context) build_stub(command, :execute!, CMDx::Signal.failed(reason, metadata:, cause:), context, strict: true) end |
#stub_task_skip(command, reason: nil, cause: nil, metadata: {}, **context) ⇒ CMDx::Result
Stubs ‘command.execute` to return a frozen skipped Result.
43 44 45 |
# File 'lib/cmdx/rspec/helpers.rb', line 43 def stub_task_skip(command, reason: nil, cause: nil, metadata: {}, **context) build_stub(command, :execute, CMDx::Signal.skipped(reason, metadata:, cause:), context) end |
#stub_task_skip!(command, reason: nil, cause: nil, metadata: {}, **context) ⇒ CMDx::Result
Stubs ‘command.execute!` (bang variant) to return a frozen skipped Result.
55 56 57 |
# File 'lib/cmdx/rspec/helpers.rb', line 55 def stub_task_skip!(command, reason: nil, cause: nil, metadata: {}, **context) build_stub(command, :execute!, CMDx::Signal.skipped(reason, metadata:, cause:), context, strict: true) end |
#stub_task_success(command, metadata: {}, **context) ⇒ CMDx::Result
Stubs ‘command.execute` to return a frozen successful Result.
21 22 23 |
# File 'lib/cmdx/rspec/helpers.rb', line 21 def stub_task_success(command, metadata: {}, **context) build_stub(command, :execute, CMDx::Signal.success(nil, metadata:), context) end |
#stub_task_success!(command, metadata: {}, **context) ⇒ CMDx::Result
Stubs ‘command.execute!` (bang variant) to return a frozen successful Result.
31 32 33 |
# File 'lib/cmdx/rspec/helpers.rb', line 31 def stub_task_success!(command, metadata: {}, **context) build_stub(command, :execute!, CMDx::Signal.success(nil, metadata:), context, strict: true) end |
#stub_task_throw(command, upstream_result, metadata: {}, **context) ⇒ CMDx::Result
Stubs ‘command.execute` to return a frozen failed Result that echoes upstream_result. Models the `throw!`-then-propagate path used by nested tasks/workflows.
112 113 114 115 116 117 118 119 |
# File 'lib/cmdx/rspec/helpers.rb', line 112 def stub_task_throw(command, upstream_result, metadata: {}, **context) unless upstream_result.is_a?(CMDx::Result) && upstream_result.failed? raise ArgumentError, "upstream_result must be a failed CMDx::Result" end build_stub(command, :execute, CMDx::Signal.echoed(upstream_result, metadata:), context) end |
#stub_workflow_tasks(command) {|task| ... } ⇒ void
This method returns an undefined value.
Yields each distinct Task class reachable from a Workflow’s pipeline, in first-seen order, so callers can stub them in a single block.
309 310 311 312 313 314 315 316 317 |
# File 'lib/cmdx/rspec/helpers.rb', line 309 def stub_workflow_tasks(command, &) if !block_given? raise ArgumentError, "block required" elsif !command.include?(Workflow) raise ArgumentError, "#{command.inspect} must be a workflow" end command.pipeline.flat_map(&:tasks).uniq.each(&) end |
#subscribe_telemetry(command, *events) { ... } ⇒ Array<CMDx::Telemetry::Event>
Subscribes to telemetry events on command‘s telemetry registry for the duration of the block. Captures every emitted event. Tasks subclassing command also fire (telemetry is cloned at class definition; the registry array is shared by reference until dup).
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/cmdx/rspec/helpers.rb', line 167 def subscribe_telemetry(command, *events, &) raise ArgumentError, "block required" unless block_given? events = CMDx::Telemetry::EVENTS if events.empty? captured = [] telemetry = command.telemetry listener = ->(event) { captured << event } events.each { |e| telemetry.subscribe(e, listener) } begin yield ensure events.each { |e| telemetry.unsubscribe(e, listener) } end captured end |
#unstub_task(command, **context) ⇒ void
This method returns an undefined value.
Restores ‘command.execute` to its original implementation. When `context` is supplied, only the matching argument signature is unstubbed.
222 223 224 225 226 227 228 |
# File 'lib/cmdx/rspec/helpers.rb', line 222 def unstub_task(command, **context) if context.empty? allow(command).to receive(:execute).and_call_original else allow(command).to receive(:execute).with(**context).and_call_original end end |
#unstub_task!(command, **context) ⇒ void
This method returns an undefined value.
Restores ‘command.execute!` to its original implementation. When `context` is supplied, only the matching argument signature is unstubbed.
236 237 238 239 240 241 242 |
# File 'lib/cmdx/rspec/helpers.rb', line 236 def unstub_task!(command, **context) if context.empty? allow(command).to receive(:execute!).and_call_original else allow(command).to receive(:execute!).with(**context).and_call_original end end |
#with_cmdx_chain(command) { ... } ⇒ CMDx::Chain?
Captures the Chain produced by command‘s execution within the block. Subscribes to command’s ‘:task_executed` telemetry to grab the chain reference before Runtime teardown clears it.
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/cmdx/rspec/helpers.rb', line 197 def with_cmdx_chain(command) raise ArgumentError, "block required" unless block_given? captured = nil telemetry = command.telemetry listener = lambda do |event| captured ||= event.payload[:result].chain if event.root end telemetry.subscribe(:task_executed, listener) begin yield ensure telemetry.unsubscribe(:task_executed, listener) end captured end |