spec/reloading_lab_spec.rb
122 lines · ruby
Project files
# frozen_string_literal: true
require "caliber_specification"
require "cartridge_case"
require "case_classifier"
require "fact_station"
require "final_inspection"
require "foreign_object"
require "press_recovery"
require "production_line"
require "production_readiness_gate"
require "production_run"
require "progressive_press"
require_relative "support/fakes/fake_fault_once_station"
RSpec.describe "The reloading lab" do
subject(:result) do
run.call(
[ready_case, unsized, nine_millimeter, stripper_clip],
provenance: provenance
)
end
let(:charge) do
FakeFaultOnceStation.new(
name: "charge", fact: :charged, fault: :powder_hopper_empty
)
end
let(:stations) do
[
FactStation.new(name: "prime", fact: :primed),
charge,
FactStation.new(name: "seat", fact: :seated),
FactStation.new(name: "crimp", fact: :crimped)
]
end
let(:press) { ProgressivePress.new(stations: stations) }
let(:line) do
ProductionLine.new(
press: press, recovery: PressRecovery.new(stations: stations)
)
end
let(:run) do
ProductionRun.new(
classifier: CaseClassifier.new(expected_caliber: "5.56"),
gate: readiness_gate,
line: line,
final_inspection: FinalInspection.new(
required_facts: %i[primed charged seated crimped]
)
)
end
let(:readiness_gate) do
ProductionReadinessGate.new(
caliber_specification: CaliberSpecification.new(
caliber: "5.56", maximum_case_length: 1.760
)
)
end
let(:ready_case) { cartridge_case }
let(:unsized) { cartridge_case(sized: false) }
let(:nine_millimeter) { CartridgeCase.new(caliber: "9mm") }
let(:stripper_clip) { ForeignObject.new(description: "stripper clip") }
let(:provenance) do
{
load_specification: "556-2026-001 v1",
brass_lot: "LC-2026-A",
component_lots: {
primer: "P-77", powder: "H-4895-23", bullet: "B-62gr-9"
}
}
end
it "stops at the first station fault instead of silently retrying" do
result
expect(charge.attempts).to eq(1)
end
it "returns a halted result with the fault and a derived recovery plan" do
expect(result).to have_attributes(
halted?: true,
faults: contain_exactly(
have_attributes(
station: "charge", status: :faulted, fault: :powder_hopper_empty
)
),
recovery_plan: contain_exactly(
have_attributes(station: "charge", disposition: :resume, missing: [])
)
)
end
it "preserves the in-progress material and its established facts" do
expect(result).to have_attributes(
positions: include(
have_attributes(
station: have_attributes(name: "charge"),
work: have_attributes(facts: { primed: true })
)
)
)
end
it "preserves every exit decided before the production fault" do
expect(result.rejected.map { |kase, _admission| kase }).to eq([unsized])
expect(result.rejected.first.last.reasons).to eq([:unsized])
expect(result.wrong_context).to eq([nine_millimeter])
expect(result.foreign).to eq([stripper_clip])
end
def cartridge_case(overrides = {})
CartridgeCase.new(**readiness_facts.merge(overrides))
end
def readiness_facts
{
caliber: "5.56", clean: true, primer_pocket_clear: true,
primer_pocket_prepared: true, sized: true, length: 1.750, defects: []
}
end
end
Read along in the manual: The Reloading Lab · Download the project (zip)