Class: Eco::API::UseCases::GraphQL::Compat::Parity::Comparison

Inherits:
Object
  • Object
show all
Defined in:
lib/eco/api/usecases/graphql/compat/parity/comparison.rb

Overview

The result of comparing a legacy RunResult (A) against a native RunResult (B).

Pure value object: given two RunResults it computes the KPI deltas, the set of page ids only one side touched, and the per-page payload diffs. equivalent? is the go/no-go signal the migration flips a case name on.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(run_a, run_b) ⇒ Comparison

Returns a new instance of Comparison.



11
12
13
14
# File 'lib/eco/api/usecases/graphql/compat/parity/comparison.rb', line 11

def initialize(run_a, run_b)
  @a = run_a
  @b = run_b
end

Instance Attribute Details

#aObject (readonly)

Returns the value of attribute a.



9
10
11
# File 'lib/eco/api/usecases/graphql/compat/parity/comparison.rb', line 9

def a
  @a
end

#bObject (readonly)

Returns the value of attribute b.



9
10
11
# File 'lib/eco/api/usecases/graphql/compat/parity/comparison.rb', line 9

def b
  @b
end

Instance Method Details

#equivalent?Boolean

True when the two runs are indistinguishable on the canonical KPI set and on every per-page update payload.

Returns:

  • (Boolean)


18
19
20
# File 'lib/eco/api/usecases/graphql/compat/parity/comparison.rb', line 18

def equivalent?
  kpi_diff.empty? && only_in_a.empty? && only_in_b.empty? && payload_diffs.empty?
end

#kpi_diffObject

Canonical KPI names whose values differ, => [a_value, b_value].



23
24
25
26
27
28
29
30
# File 'lib/eco/api/usecases/graphql/compat/parity/comparison.rb', line 23

def kpi_diff
  keys = a.kpis.keys | b.kpis.keys
  keys.each_with_object({}) do |key, out|
    av = a.kpis[key].to_i
    bv = b.kpis[key].to_i
    out[key] = [av, bv] if av != bv
  end
end

#only_in_aObject

Page ids only the legacy run acted on.



33
34
35
# File 'lib/eco/api/usecases/graphql/compat/parity/comparison.rb', line 33

def only_in_a
  a.page_ids - b.page_ids
end

#only_in_bObject

Page ids only the native run acted on.



38
39
40
# File 'lib/eco/api/usecases/graphql/compat/parity/comparison.rb', line 38

def only_in_b
  b.page_ids - a.page_ids
end

#payload_diffsObject

Per-page payload diffs for the ids BOTH runs touched, => [a_payload, b_payload].



43
44
45
46
47
48
49
# File 'lib/eco/api/usecases/graphql/compat/parity/comparison.rb', line 43

def payload_diffs
  (a.page_ids & b.page_ids).each_with_object({}) do |id, out|
    ap = a.updates[id]
    bp = b.updates[id]
    out[id] = [ap, bp] if ap != bp
  end
end

#reportObject

Human-readable report of the divergences (empty when equivalent).



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/eco/api/usecases/graphql/compat/parity/comparison.rb', line 52

def report # rubocop:disable Metrics/AbcSize
  return "PARITY OK — #{a.label}#{b.label}" if equivalent?

  lines = ["PARITY MISMATCH — #{a.label} vs #{b.label}:"]
  kpi_diff.each do |key, (av, bv)|
    lines << "  * KPI #{key}: #{a.label}=#{av} #{b.label}=#{bv}"
  end
  lines << "  * only in #{a.label}: #{only_in_a.join(', ')}" unless only_in_a.empty?
  lines << "  * only in #{b.label}: #{only_in_b.join(', ')}" unless only_in_b.empty?
  payload_diffs.each do |id, (ap, bp)|
    lines << "  * payload #{id}:"
    lines << "      #{a.label}: #{ap.inspect}"
    lines << "      #{b.label}: #{bp.inspect}"
  end
  lines.join("\n")
end