/** * set the context on the statemachine and provide bidirectional * association. * * change the context for a statemachine that already has a context. * When the context is changed, but it is for the same statemachine (with * the same transitions), the statemachine can be used directly with the * new context. * * The current state is reset to whatever state the machine should be in * (either the initial state or the stored state) whenever a context change * is made. * * we can change context to: * - switch builders/persistence adapters at runtime * - reuse the statemachine for a different entity so we do not * have to load the statemachine with the same transition definitions * * @param Context $context * @throws Exception */ public function setContext(Context $context) { if ($this->getContext()) { // context already exists. if ($this->getContext()->getMachine() !== $context->getMachine()) { throw new Exception(sprintf("Trying to set context for a different machine. currently '%s' and new '%s'", $this->getContext()->getMachine(), $context->getMachine()), Exception::SM_CONTEXT_DIFFERENT_MACHINE); } // reset state TODO: move outside if statement $this->state = null; } $context->setStateMachine($this); $this->context = $context; }
/** * test the factory method with all parameters provided * implicitely tests the constructor */ public function testContext() { $entity_id = "id1"; $machine = "test machine"; $identifier = new Identifier($entity_id, $machine); $builder = new EntityBuilder(); $io = new Memory(); // all parameters $o = new Context($identifier, $builder, $io); $this->assertEquals($entity_id, $o->getEntityId()); $this->assertEquals($machine, $o->getMachine()); $this->assertNull($o->getStateMachine()); $this->assertTrue(is_a($o->getPersistenceAdapter(), 'izzum\\statemachine\\persistence\\Memory')); $this->assertTrue(is_a($o->getBuilder(), 'izzum\\statemachine\\EntityBuilder')); $this->assertEquals($identifier, $o->getEntity()); $this->assertTrue(is_string($o->getEntityId())); $this->assertTrue(is_string($o->toString())); $this->assertContains($entity_id, $o->toString()); $this->assertContains($machine, $o->toString()); $this->assertContains('izzum\\statemachine\\Context', $o->toString()); // even though we have a valid reader, the state machine does not exist. $this->assertEquals(State::STATE_UNKNOWN, $o->getState()); $this->assertTrue($o->setState(State::STATE_NEW, 'this is an informational message about why we set this state: we set this state to new for a unittest'), 'added'); $this->assertFalse($o->setState(State::STATE_NEW), 'already there'); // for coverage. $statemachine = new StateMachine($o); $this->assertNull($o->setStateMachine($statemachine)); $this->assertContains('Context', $o . '', '__toString()'); }