Class: SpecGuard::RSpec::Schema
- Inherits:
-
Object
- Object
- SpecGuard::RSpec::Schema
- Defined in:
- lib/specguard/rspec/schema.rb
Overview
The OpenTestIntent v1 schema, loaded and applied.
Why loading failure is exit 2 and not exit 1
The exit contract (SPGD-12 §1) spends 1 on "an annotation is
malformed". If a packaging accident leaves the vendored schema out of the
gem, the obvious Ruby implementation lets the exception escape and Ruby
exits 1 — so CI reports a malformed annotation and a developer goes
hunting for a bad annotation that does not exist. The reference tool
already ruled on this:
except (OSError, json.JSONDecodeError) as exc:
print("error: could not load schema %s: %s" % (SCHEMA_PATH, exc), file=sys.stderr)
return 2
# open-test-intent, bin/validate-intent:858-862
Hence SchemaError: every way loading can fail is caught here and retyped, so the CLI can map the whole class of them to 2 without inspecting exception classes from three different libraries.
The CLI loads this before it scans anything, so a broken schema can never produce a run that reports "0 malformed" having validated nothing.
Instance Attribute Summary collapse
-
#document ⇒ Object
readonly
Returns the value of attribute document.
-
#path ⇒ Object
readonly
Returns the value of attribute path.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(document:, path: SCHEMA_PATH, renderer: ViolationRenderer.new) ⇒ Schema
constructor
A new instance of Schema.
-
#violations(intent) ⇒ Array<String>
The validator decides the verdict; the renderer only decides the wording.
Constructor Details
#initialize(document:, path: SCHEMA_PATH, renderer: ViolationRenderer.new) ⇒ Schema
Returns a new instance of Schema.
59 60 61 62 63 64 65 |
# File 'lib/specguard/rspec/schema.rb', line 59 def initialize(document:, path: SCHEMA_PATH, renderer: ViolationRenderer.new) @document = document @path = path @renderer = renderer @schemer = JSONSchemer.schema(document) reject_unusable_schema! end |
Instance Attribute Details
#document ⇒ Object (readonly)
Returns the value of attribute document.
57 58 59 |
# File 'lib/specguard/rspec/schema.rb', line 57 def document @document end |
#path ⇒ Object (readonly)
Returns the value of attribute path.
57 58 59 |
# File 'lib/specguard/rspec/schema.rb', line 57 def path @path end |
Class Method Details
.load(path = SCHEMA_PATH) ⇒ Schema
45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/specguard/rspec/schema.rb', line 45 def self.load(path = SCHEMA_PATH) document = ::JSON.parse(File.read(path, encoding: "UTF-8")) new(document: document, path: path) rescue StandardError => e # Intentionally broad. Reading can raise SystemCallError/IOError, # parsing JSON::ParserError, and compiling or meta-validating whatever # json_schemer decides an unusable schema document deserves. All of # them mean the same thing to the caller, and all of them must be 2 # rather than an uncaught exception's 1. raise SchemaError, "could not load schema #{path}: #{e.}" end |
Instance Method Details
#violations(intent) ⇒ Array<String>
The validator decides the verdict; the renderer only decides the
wording. Deriving "is this annotation valid?" from "could we phrase a
sentence about it?" would make an unphrasable violation and a clean
annotation the same state — and under Linter that state is a green
run, which is this project's signature vacuous green (KB SPGD-78)
arriving through the one door the whole rendering strategy exists to
close. The gemspec pins ~> 2.5, which admits 2.6 and beyond; the
renderer is built from structured fields precisely so a bump degrades
to wrong-looking text rather than to silence, and this is what keeps
that promise true for error shapes it has never seen.
81 82 83 84 85 86 87 |
# File 'lib/specguard/rspec/schema.rb', line 81 def violations(intent) errors = @schemer.validate(intent).to_a return [] if errors.empty? rendered = @renderer.render(errors, intent) rendered.empty? ? errors.map { |error| unrenderable_reason(error) } : rendered end |