Module: RubyLLM::Contract::Concerns::StubHelpers
- Included in:
- MinitestHelpers, RSpec::Helpers
- Defined in:
- lib/ruby_llm/contract/concerns/stub_helpers.rb
Overview
Shared implementation of ‘stub_step`, `stub_steps`, and `stub_all_steps`. Included by both `RubyLLM::Contract::RSpec::Helpers` and `RubyLLM::Contract::MinitestHelpers` so the two test-framework adapters cannot drift on stub semantics (Codex DRY finding #1: the prior parallel implementations had already diverged on `normalize_test_response` — RSpec had it, Minitest didn’t).
Cleanup between examples is the responsibility of the host helper:
-
RSpec: ‘around(:each)` hook in `lib/ruby_llm/contract/rspec.rb` restores `step_adapter_overrides`.
-
Minitest: ‘teardown` in `MinitestHelpers` clears overrides and restores `default_adapter`.
Instance Method Summary collapse
-
#stub_all_steps(response: nil, responses: nil, &block) ⇒ Object
Set a global test adapter for ALL steps.
-
#stub_step(step_class, response: nil, responses: nil, &block) ⇒ Object
Stub a single step to return a canned response without API calls.
-
#stub_steps(stubs, &block) ⇒ Object
Stub multiple steps with different responses.
Instance Method Details
#stub_all_steps(response: nil, responses: nil, &block) ⇒ Object
Set a global test adapter for ALL steps. Block form restores the previous adapter on exit; non-block form persists until host cleanup.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/ruby_llm/contract/concerns/stub_helpers.rb', line 63 def stub_all_steps(response: nil, responses: nil, &block) adapter = build_test_adapter(response: response, responses: responses) if block previous = RubyLLM::Contract.configuration.default_adapter begin RubyLLM::Contract.configuration.default_adapter = adapter yield ensure RubyLLM::Contract.configuration.default_adapter = previous end else RubyLLM::Contract.configure { |c| c.default_adapter = adapter } end end |
#stub_step(step_class, response: nil, responses: nil, &block) ⇒ Object
Stub a single step to return a canned response without API calls. Block form scopes the stub to the block; non-block form lives until the host’s teardown/around hook fires.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/ruby_llm/contract/concerns/stub_helpers.rb', line 22 def stub_step(step_class, response: nil, responses: nil, &block) adapter = build_test_adapter(response: response, responses: responses) overrides = RubyLLM::Contract.step_adapter_overrides if block previous = overrides[step_class] overrides[step_class] = adapter begin yield ensure previous ? (overrides[step_class] = previous) : overrides.delete(step_class) end else overrides[step_class] = adapter end end |
#stub_steps(stubs, &block) ⇒ Object
Stub multiple steps with different responses. Requires a block.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/ruby_llm/contract/concerns/stub_helpers.rb', line 40 def stub_steps(stubs, &block) raise ArgumentError, "stub_steps requires a block" unless block overrides = RubyLLM::Contract.step_adapter_overrides previous = {} stubs.each do |step_class, opts| opts = opts.transform_keys(&:to_sym) previous[step_class] = overrides[step_class] overrides[step_class] = build_test_adapter(**opts.slice(:response, :responses)) end begin yield ensure stubs.each_key do |step_class| previous[step_class] ? (overrides[step_class] = previous[step_class]) : overrides.delete(step_class) end end end |