Module: Reeve::Testing::Checks

Defined in:
lib/reeve/testing/checks.rb,
lib/reeve/testing/checks/base.rb,
lib/reeve/testing/checks/rule_present.rb,
lib/reeve/testing/checks/audit_coverage.rb,
lib/reeve/testing/checks/guard_declared.rb,
lib/reeve/testing/checks/redaction_holds.rb,
lib/reeve/testing/checks/contract_version.rb,
lib/reeve/testing/checks/principal_required.rb,
lib/reeve/testing/checks/cross_principal_leak.rb

Overview

The seven guarantees, as objects.

This is the whole of the testing kit's logic. The RSpec matchers and the Minitest assertions are adapters over it and contain no assertions of their own, which is why the same violation reads identically from either — and from neither:

report = Reeve::Checks.run_all(principals: [alice, bob])
abort report.to_s unless report.passed?

Nothing here loads a test framework (FR-026).

Defined Under Namespace

Classes: AuditCoverage, Base, ContractVersion, CrossPrincipalLeak, GuardDeclared, PrincipalRequired, RedactionHolds, RulePresent

Constant Summary collapse

ALL =
[
  GuardDeclared,
  CrossPrincipalLeak,
  AuditCoverage,
  RulePresent,
  RedactionHolds,
  PrincipalRequired,
  ContractVersion
].freeze
GLOBAL =

The checks that are asked once about the ledger rather than once per tool.

[ContractVersion].freeze

Class Method Summary collapse

Class Method Details

.build(check, tool:, principals:, arguments: {}, invoke: nil, ledger: nil) ⇒ Object

The one place that knows what each check's constructor wants. Front-ends and hosts ask for a check by class and get a configured one back.



77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/reeve/testing/checks.rb', line 77

def self.build(check, tool:, principals:, arguments: {}, invoke: nil, ledger: nil)
  common = { tool: tool, arguments: arguments, invoke: invoke, ledger: ledger }

  case check.check_name
  when "GuardDeclared"      then GuardDeclared.new(tool: tool, ledger: ledger)
  when "ContractVersion"    then ContractVersion.new(ledger: ledger)
  when "PrincipalRequired"  then PrincipalRequired.new(**common)
  when "CrossPrincipalLeak" then CrossPrincipalLeak.new(principals: Array(principals),
                                                        **common)
  else check.new(principal: Array(principals).first, **common)
  end
end

.for_tool(tool, principals:, arguments: {}, invoke: nil, ledger: nil) ⇒ Object

Every per-tool check for one tool, instantiated but not run.



68
69
70
71
72
73
# File 'lib/reeve/testing/checks.rb', line 68

def self.for_tool(tool, principals:, arguments: {}, invoke: nil, ledger: nil)
  (ALL - GLOBAL).map do |check|
    build(check, tool: tool, principals: principals, arguments: arguments,
                 invoke: invoke, ledger: ledger)
  end
end

.run(check, principals:, tools: nil, arguments: {}, invoke: nil, ledger: nil) ⇒ Object

One check, across every tool it applies to. This is what both front-ends build a test method out of, so that a failing suite names the guarantee that broke rather than reporting "compliance" as one undifferentiated red.



55
56
57
58
59
60
61
62
63
64
65
# File 'lib/reeve/testing/checks.rb', line 55

def self.run(check, principals:, tools: nil, arguments: {}, invoke: nil, ledger: nil)
  return Report.new([check.new(ledger: ledger).call]) if GLOBAL.include?(check)

  subjects = tools || Reeve.registry.map(&:tool_class)
  Report.new(
    subjects.map do |tool|
      build(check, tool: tool, principals: principals, arguments: arguments,
                   invoke: invoke, ledger: ledger).call
    end
  )
end

.run_all(principals:, tools: nil, arguments: {}, invoke: nil, ledger: nil) ⇒ Object

The compliance suite's engine (FR-018): every check, against every registered guarded tool, in one Report.

principals must be two fixture principals with disjoint records — that disjointness is what makes a shared identifier proof of a leak.



43
44
45
46
47
48
49
50
# File 'lib/reeve/testing/checks.rb', line 43

def self.run_all(principals:, tools: nil, arguments: {}, invoke: nil, ledger: nil)
  reports = ALL.map do |check|
    run(check, principals: principals, tools: tools, arguments: arguments,
               invoke: invoke, ledger: ledger)
  end

  Report.new(reports.flat_map(&:results))
end