tdd-deciphered.com

created by @parsingphase

Chapter 10: Rotor turnover, part 1

Having handled the electrical aspects of the rotors and slots, we need to consider how the mechanical interaction works. For the rightmost rotor (slot 1), the motion of pushing down the key will also push around the rotor in slot one. If this rotor is in its turnover position, when it turns it will also push around the rotor in slot 2, and so on. At the end of its downward mechanical motion the key completes the electrical circuit and so the signal current flows after all turnovers have taken place.

In terms of functional requirements, this means:

The rightmost rotor will turn over on every keypress, but not all rotors will turn over on every keypress. The action of the remaining rotors depends on the identity and position of the adjacent rotors.

Before we consider the general case, we'll handle the simple case of the first rotor. This simply needs an "increment rotor position" function that we'll trigger manually. We just need to test that the rotor offset after calling this is one more than it was beforehand.

We can add the following test to RotorSlotTest.php:

/**
 * @dataProvider offsetIncrementDataProvider
 */
public function testRotorOffsetIncrement($originalOffset, $newOffset)
{
    $rotor = new Rotor();
    $coreMapping=[
        'A'=>'E','B'=>'K','C'=>'M','D'=>'F','E'=>'L','F'=>'G','G'=>'D','H'=>'Q','I'=>'V',
        'J'=>'Z','K'=>'N','L'=>'T','M'=>'O','N'=>'W','O'=>'Y','P'=>'H','Q'=>'X','R'=>'U',
        'S'=>'S','T'=>'P','U'=>'A','V'=>'I','W'=>'B','X'=>'R','Y'=>'C','Z'=>'J'
    ];

    $rotor->setRingOffset(1);
    $rotor->setCoreMapping($coreMapping);

    $slot=new RotorSlot();
    $slot->loadRotor($rotor);
    $slot->setRotorOffset($originalOffset);

    $this->assertSame($originalOffset,$slot->getRotorOffset());
    $slot->incrementRotorOffset();
    $this->assertSame($newOffset, $slot->getRotorOffset());
}

public function offsetIncrementDataProvider()
{
    return [
        [1, 2],
        [13, 14],
        [26, 1]
    ];
}

which satisfactorily causes our tests to fail until we add the missing methods to RotorSlot.php:

/**
 * @return int
 */
public function getRotorOffset()
{
    return $this->rotorOffset;
}

public function incrementRotorOffset()
{
    $this->rotorOffset++;
    if ($this->rotorOffset > 26) {
        $this->rotorOffset = 1;
    }
}

Having now written the required functionality for rotors, slots, and turnovers, we’ve got models for most of our core elements in place. Over the next few chapters, we’ll add the last couple of element types and give ourselves an easier way of accessing all the parts we’ve built.

The code at this point is tagged Chapter10-1-RotorTurnover