Class: Eco::API::UseCases::GraphQL::Compat::Parity::Harness
- Defined in:
- lib/eco/api/usecases/graphql/compat/parity/harness.rb
Overview
A/B parity harness for the ooze -> native GraphQL strangler-fig migration.
Runs the SAME logical register-processing case through the two code paths — A: legacy (v2 / OozeRedirect shim), B: native GraphQL — and asserts that the observable outcome (KPI counters + per-page update payloads) is equivalent.
The comparison logic (RunResult / Comparison) is PURE and offline-runnable.
The harness itself is a thin orchestrator: you hand it two callables, each of
which runs its side and returns a RunResult. In a live run each callable would
execute the case in -simulate mode against the same test org, using a
Recorder to capture what each side WOULD write (no data is mutated). Wiring the
two live runs needs credentials + a test org; the structural machinery here is
verified offline.
== Usage (live)
harness = Parity::Harness.new( legacy: -> { Parity::Harness.record('legacy') { |rec| run_legacy_case(rec) } }, native: -> { Parity::Harness.record('native') { |rec| run_native_case(rec) } } ) comparison = harness.run raise comparison.report unless comparison.equivalent?
== Usage (offline / spec)
a = Parity::RunResult.new(label: 'legacy', kpis: ..., updates: ...) b = Parity::RunResult.new(label: 'native', kpis: ..., updates: ...) Parity::Harness.new(legacy: -> { a }, native: -> { b }).run.equivalent?
Defined Under Namespace
Classes: Recorder
Class Method Summary collapse
-
.record(label) {|recorder| ... } ⇒ RunResult
Capture the observable outcome of a case run into a RunResult.
Instance Method Summary collapse
-
#initialize(legacy:, native:) ⇒ Harness
constructor
A new instance of Harness.
-
#run ⇒ Object
Execute both sides and compare.
Constructor Details
#initialize(legacy:, native:) ⇒ Harness
Returns a new instance of Harness.
34 35 36 37 |
# File 'lib/eco/api/usecases/graphql/compat/parity/harness.rb', line 34 def initialize(legacy:, native:) @legacy = legacy @native = native end |
Class Method Details
.record(label) {|recorder| ... } ⇒ RunResult
Capture the observable outcome of a case run into a RunResult.
Yields a Recorder. The caller runs the case, feeding each page's would-be
update payload to recorder.record_update(page_id, payload) (typically wired
by stubbing the case's update_page to call graphql.pages.get_body(page)
instead of persisting). After the run, pass the case's KPI hash to
recorder.kpis = case.kpis_hash (or set counters individually).
59 60 61 62 63 |
# File 'lib/eco/api/usecases/graphql/compat/parity/harness.rb', line 59 def self.record(label) recorder = Recorder.new(label) yield(recorder) if block_given? recorder.to_run_result end |
Instance Method Details
#run ⇒ Object
Execute both sides and compare. Returns a Parity::Comparison.
40 41 42 43 44 45 46 |
# File 'lib/eco/api/usecases/graphql/compat/parity/harness.rb', line 40 def run a = @legacy.call b = @native.call assert_run_result!(a, 'legacy') assert_run_result!(b, 'native') a.compare_to(b) end |