Follow the Brass

spec/production_run_spec.rb

75 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_run"
require "production_readiness_gate"
require "progressive_press"

RSpec.describe ProductionRun do
  subject(:run) do
    described_class.new(classifier: classifier, gate: gate, line: line,
                        final_inspection: final_inspection)
  end

  let(:classifier) { CaseClassifier.new(expected_caliber: "5.56") }
  let(:gate) do
    ProductionReadinessGate.new(
      caliber_specification: CaliberSpecification.new(caliber: "5.56",
                                                      maximum_case_length: 1.760)
    )
  end
  let(:stations) do
    [
      FactStation.new(name: "prime", fact: :primed),
      FactStation.new(name: "charge", fact: :charged),
      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(:final_inspection) do
    FinalInspection.new(required_facts: %i[primed charged seated crimped])
  end

  it "turns a mixed batch into a released, labeled, fully sorted result" do
    ready_one = ready_case
    ready_two = ready_case
    unsized = ready_case(sized: false)
    nine_millimeter = CartridgeCase.new(caliber: "9mm")
    stripper_clip = ForeignObject.new(description: "stripper clip")

    result = run.call(
      [ready_one, ready_two, unsized, nine_millimeter, stripper_clip],
      provenance: { load_specification: "556-2026-001 v1", brass_lot: "LC-2026-A",
                    component_lots: { primer: "P-77", powder: "H-4895-23",
                                      bullet: "B-62gr-9" } }
    )

    expect(result.released.map(&:cartridge_case)).to contain_exactly(ready_one, ready_two)
    expect(result.released).to all(satisfy { |work| final_inspection.assess(work).admitted? })
    expect(result.record.label).to eq("LC-2026-A / 556-2026-001 v1 / 2 rounds")
    expect(result.rejected.map { |kase, _| 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])
    expect(result.quarantined).to be_empty
  end

  def ready_case(overrides = {})
    CartridgeCase.new(**{ caliber: "5.56", clean: true, primer_pocket_clear: true,
                          primer_pocket_prepared: true, sized: true, length: 1.750,
                          defects: [] }.merge(overrides))
  end
end

Read along in the manual: The Reloading Lab · Download the project (zip)