Follow the Brass

spec/progressive_press_spec.rb

86 lines · ruby

Project files
# frozen_string_literal: true

require "cartridge_case"
require "fact_station"
require "progressive_press"
require "work_in_progress"

FaultStation = Data.define(:name, :fault_reason) do
  def apply(work)
    StationResult.new(work: work, fault: fault_reason)
  end
end

RSpec.describe ProgressivePress do
  subject(:press) { described_class.new(stations: stations) }

  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

  it "advances every occupied position on one clean cycle" do
    press.feed(work)

    result = press.cycle

    expect(result).to be_advanced
    expect(result.outcomes.map(&:status)).to eq(%i[completed empty empty empty])
  end

  it "carries staggered pieces through different stations on one stroke" do
    press.feed(work)
    press.cycle
    press.feed(work)

    result = press.cycle

    expect(result.outcomes.map(&:status)).to eq(%i[completed completed empty empty])
  end

  it "ejects a finished round only after the final station" do
    press.feed(work)
    results = 4.times.map { press.cycle }

    finished = results.last.ejected

    expect(results[0..2].map(&:ejected)).to all(be_nil)
    expect(%i[primed charged seated crimped].all? { |fact| finished.fact?(fact) }).to be(true)
    expect(press.completed).to eq([finished])
  end

  it "refuses a feed while the first position is occupied" do
    press.feed(work)

    placement = press.feed(work)

    expect(placement).to be_refused
    expect(placement.reason).to eq(:position_occupied)
  end

  it "holds the plate when any station faults mid-stroke" do
    faulty = described_class.new(stations: [
      stations[0],
      FaultStation.new(name: "charge", fault_reason: :powder_hopper_empty),
      stations[2],
      stations[3]
    ])
    faulty.feed(work)
    faulty.cycle
    faulty.feed(work)

    result = faulty.cycle

    expect(result).not_to be_advanced
    expect(result.outcomes.map(&:status)).to eq(%i[completed faulted empty empty])
    expect(result.outcomes[1].fault).to eq(:powder_hopper_empty)
  end

  def work
    WorkInProgress.new(cartridge_case: CartridgeCase.new(caliber: "5.56"))
  end
end

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