/**
* @test
*/
public function shouldBeAbleToStoreAndRetrieveData()
{
$redis = new Redis();
$redis->setDatabase(15);
//clear the redis database for testing
$redis->flushdb();
$machine = new StateMachine(new Context(new Identifier('1', 'test-machine'), null, $redis));
//create the loader
//get the configuration from the json file
$configuration = file_get_contents(__DIR__ . '/../loader/fixture-example.json');
//set it. normally, this would be done by a seperate process that has already loaded the configuration
$redis->set(Redis::KEY_CONFIGURATION, $configuration);
//load the machine
$count = $redis->load($machine);
//add the machine to the backend system
$this->assertTrue($machine->add('this is the first addition'));
$this->assertFalse($machine->add(), 'returns false, already added');
$this->assertTrue($machine->run('this is a test run message'), 'succesful transitions so it returns true');
$this->assertEquals('b', $machine->getCurrentState());
$this->assertContains('1', $redis->getEntityIds('test-machine'));
$this->assertTrue($machine->hasEvent('goToC'));
try {
$machine->goToC();
$this->fail('should not come here');
} catch (Exception $e) {
$this->assertEquals(Exception::RULE_APPLY_FAILURE, $e->getCode());
}
$this->assertEquals('b', $machine->getCurrentState());
//create new instance of same machine
$machine2 = new StateMachine(new Context(new Identifier('1', 'test-machine'), null, $redis));
$this->assertNotSame($machine2, $machine);
$redis->load($machine2);
$this->assertEquals('b', $machine2->getCurrentState(), 'should retrieve the same value');
//create new instance of other machine
$machine3 = new StateMachine(new Context(new Identifier('2', 'test-machine'), null, $redis));
$this->assertNotSame($machine2, $machine3);
$redis->load($machine3);
$this->assertTrue($machine3->add());
$this->assertNotEquals('b', $machine3->getCurrentState()->getName(), 'should not retrieve the same value as the other machine');
$this->assertEquals('a', $machine3->getCurrentState()->getName(), 'initial state');
//echo $machine3->toString(true);
$this->assertEquals(2, $machine3->runToCompletion("go to the final state"));
$this->assertEquals('done', $machine3->getCurrentState()->getName(), 'final state');
$machine4 = new StateMachine(new Context(new Identifier('3', 'another-machine'), null, $redis));
$a = new State('begin', State::TYPE_INITIAL);
$b = new State('enter', State::TYPE_NORMAL);
$c = new State('leave', State::TYPE_FINAL);
$machine4->addTransition(new Transition($a, $b));
$machine4->addTransition(new Transition($b, $c));
$machine4->add('creating another machine to see that all goes well storing the data for multiple machines in redis');
$this->assertEquals(2, $machine4->runToCompletion('running the machine to completion'));
$ids = $redis->getEntityIds('test-machine');
$this->assertEquals(array('1', '2'), $ids);
$ids = $redis->getEntityIds('another-machine');
$this->assertEquals(array('3'), $ids);
$ids = $redis->getEntityIds('test-machine', 'done');
$this->assertEquals(array('2'), $ids, 'only 2 was run to completion and in state done');
$ids = $redis->getEntityIds('another-machine', 'leave');
$this->assertEquals(array('3'), $ids, 'only 3 was run to completion and in state leave');
//$redis->hmset("key" , array("name1" => "value1", "name2" => "value2"));
}