View source
<?php
state_machine_load_class_file();
class StateMachine_Test extends StateMachine {
public function init() {
$this
->create_state('step1', array(
'on_exit' => array(
$this,
'log_on_exit',
),
));
$this
->create_state('step2', array(
'on_enter' => array(
$this,
'log_on_enter',
),
));
$this
->create_state('step3', array());
$this
->create_event('goto2', array(
'origin' => 'step1',
'target' => 'step2',
));
$this
->create_event('goto2_with_logs', array(
'origin' => 'step1',
'target' => 'step2',
'guard' => array(
$this,
'log_on_guard',
),
'before_transition' => array(
$this,
'log_before_transition',
),
'after_transition' => array(
$this,
'log_after_transition',
),
));
$this
->create_event('goto3', array(
'origin' => array(
'step1',
'step2',
),
'target' => 'step3',
'guard' => FALSE,
'onTransition' => FALSE,
));
$this
->create_event('reset', array(
'origin' => array(
'step2',
'step3',
),
'target' => 'step1',
));
$this
->create_event('dont_do_it', array(
'origin' => array(
'step1',
'step2',
'step3',
),
'target' => 'step1',
'guard' => array(
$this,
'guard_with_your_life',
),
));
}
public $logs = array();
public function reset_logs() {
$this->logs = array();
}
public function log_callback($callback) {
$this->logs[] = $callback;
}
public function log_on_guard() {
$this
->log_callback('guard');
}
public function log_before_transition() {
$this
->log_callback('before_transition');
}
public function log_after_transition() {
$this
->log_callback('after_transition');
}
public function log_on_enter() {
$this
->log_callback('on_enter');
}
public function log_on_exit() {
$this
->log_callback('on_exit');
}
public function guard_with_your_life() {
return FALSE;
}
}
class StateMachineUnitTest extends DrupalUnitTestCase {
public static function getInfo() {
return array(
'name' => 'Base class unit tests',
'description' => 'Perform unit tests on the State Machine base classes function.',
'group' => 'State Machine',
);
}
function setup() {
parent::setup('state_machine');
$machine = new StateMachine_Test();
$this->machine = $machine;
}
function testStateMachine() {
$this
->assertEqual($this->machine
->get_current_state(), 'step1', t('Initial state should be the first defined state.'));
$this->machine
->fire_event('goto2');
$this
->assertEqual($this->machine
->get_current_state(), 'step2', t('Current state should change when a valid event is fired.'));
$this->machine
->fire_event('goto2');
$this
->assertEqual($this->machine
->get_current_state(), 'step2', t('Event should not execute if current state is not valid for the specified event.'));
$this->machine
->fire_event('reset');
$this
->assertEqual($this->machine
->get_current_state(), 'step1', t('Event should allow transitions from multiple origins.'));
$current = $this->machine
->get_current_state();
$this->machine
->fire_event('dont_do_it');
$this
->assertEqual($current, $this->machine
->get_current_state(), t('State should not change when guard function returns FALSE.'));
$this->machine
->fire_event('reset');
$this->machine
->reset_logs();
$this->machine
->fire_event('goto2_with_logs');
$this
->assertEqual($this->machine->logs[0], 'guard', t('The guard condition should be the first callback executed.'));
$this
->assertEqual($this->machine->logs[1], 'before_transition', t('The before_transition callback should be the second callback executed.'));
$this
->assertEqual($this->machine->logs[2], 'on_exit', t('The on_exit callback should be the third callback executed.'));
$this
->assertEqual($this->machine->logs[3], 'on_enter', t('The on_enter callback should be the fourth callback executed.'));
$this
->assertEqual($this->machine->logs[4], 'after_transition', t('The after_transition callback should be the fifth callback executed.'));
$this->machine
->fire_event('reset');
$events = $this->machine
->get_available_events();
$this
->assertTrue(in_array('goto2', $events), t('The machine should return a list of available events.'));
$this
->assertTrue(in_array('goto3', $events), t('The machine should return a list of available events.'));
}
}