<?php /** * This is a test thoroughly exercises the SpecAbstract via the SpecMono class. * It is used to thoroughly exercise the base spec functionality so latter implementors * can focus on testing only their own additions/modifications. * * The actual spec type represented by SpecMono is of no importance and should not be considered * tested in this context. * * @copyright 2012 Perforce Software. All rights reserved. * @license Please see LICENSE.txt in top-level folder of this distribution. * @version <release>/<patch> */ namespace P4Test\Spec; use P4Test\TestCase; use P4\Spec\Exception\Exception as SpecException; class MonoTest extends TestCase { /** * Constructor Test */ public function testConstructor() { // Construct object with no passed values $mono = new MonoMock; $expected = array ( 'TypeMap' => null ); $this->assertSame( $expected, $mono->get(), 'Expected starting fields to match' ); } /** * Test retrieval of the spec definition */ public function testGetSpecDefinition() { $specDef = \P4\Spec\Definition::fetch('typemap'); $this->assertSame( $specDef->getType(), 'typemap', 'Expected spec definition type to match' ); $expected = array ( 'TypeMap' => array ( 'code' => '601', 'dataType' => 'wlist', 'displayLength' => '64', 'fieldType' => 'default', 'wordCount' => '2', ), ); $this->assertSame( $expected, $specDef->getFields(), 'Expected fields to match' ); } /** * Test the has field function. */ public function testHasField() { $tests = array ( array ( 'label' => __LINE__ . " Empty String", 'field' => '', 'error' => true ), array ( 'label' => __LINE__ . " null", 'field' => null, 'error' => true ), array ( 'label' => __LINE__ . " bool", 'field' => true, 'error' => true ), array ( 'label' => __LINE__ . " int", 'field' => 10, 'error' => true ), array ( 'label' => __LINE__ . " float", 'field' => 10.10, 'error' => true ), array ( 'label' => __LINE__ . " bad field name", 'field' => 'badField', 'error' => true ), array ( 'label' => __LINE__ . " incorrect case", 'field' => 'typeMap', 'error' => true ), array ( 'label' => __LINE__ . " known good field", 'field' => 'TypeMap', 'error' => false ), ); foreach ($tests as $test) { $mono = new MonoMock; $result = $mono->hasField($test['field']); if ($test['error']) { $this->assertFalse($result, 'Unexpected false: '. $test['label']); } else { $this->assertTrue($result, 'Unexpected true: '. $test['label']); } } } /** * Test get/setFields */ public function testGetSetMulti() { $mono = new MonoMock; $expected = array ( 'TypeMap' => array('blah //...','etc //test/...','oneMore "//test with space/..."') ); $mono = new MonoMock; $mono->set($expected); $this->assertSame( $expected, $mono->get(), 'Expected passed fields to take' ); } /** * Exercise get/set values with combinations of mutator/accessor */ public function testGetSetMultiWithMutatorAccessor() { // Enable mutator and accessor and verify fields passed are affected $mono = new MonoMock; $mono->setProtected( 'fields', array( 'TypeMap' => array( 'accessor' => 'getTypeMapAppendA', 'mutator' => 'setTypeMapRemoveA' ) ) ); $raw = array ( 'TypeMap' => array('blah //...','etc //test/...','oneMore "//test with space/..."') ); $mutated = array ( 'TypeMap' => array('blah //...A','etc //test/...A','oneMore "//test with space/..."A') ); $mono->set($mutated); $this->assertSame( $raw, $mono->callProtected('getRawValues'), 'Expected getRawValues to match unmodified version' ); $this->assertSame( $mutated, $mono->get(), 'Expected get to match mutated version' ); // Enable mutator only and verify fields passed are affected $mono = new MonoMock; $mono->setProtected( 'fields', array( 'TypeMap' => array( 'mutator' => 'setTypeMapRemoveA' ) ) ); $mono->set($mutated); $this->assertSame( $raw, $mono->callProtected('getRawValues'), 'Expected getRawValues to match unmodified version' ); $this->assertSame( $raw, $mono->get(), 'Expected get to match raw version' ); } /** * Test set raw values */ public function testSetRawValues() { // Enable mutator and accessor and verify setRawValues is unaffected $mono = new MonoMock; $mono->setProtected( 'fields', array( 'TypeMap' => array( 'accessor' => 'getTypeMapAppendA', 'mutator' => 'setTypeMapRemoveA' ) ) ); $raw = array ( 'TypeMap' => array('blah //...','etc //test/...','oneMore "//test with space/..."') ); $mutated = array ( 'TypeMap' => array('blah //...A','etc //test/...A','oneMore "//test with space/..."A') ); $mono->callProtected('setRawValues', array($raw)); $this->assertSame( $raw, $mono->callProtected('getRawValues'), 'Expected getRawValues to match unmodified version' ); $this->assertSame( $mutated, $mono->get(), 'Expected get to match mutated version' ); } /** * Test get/set Value */ public function testGetSet() { $mono = new MonoMock; $expected = array('blah //...','etc //test/...','oneMore "//test with space/..."'); // Verify get value reflects set input $mono = new MonoMock; $mono->set(array('TypeMap' => $expected)); $this->assertSame( $expected, $mono->get('TypeMap'), 'Expected set to take' ); // Verify get value reflects set value input $mono = new MonoMock; $mono->set('TypeMap', $expected); $this->assertSame( $expected, $mono->get('TypeMap'), 'Expected set to take' ); // Verify get values reflects set value input $this->assertSame( array('TypeMap' => $expected), $mono->get(), 'Expected set to affect get' ); } /** * Test get/set Value with mutator/accessor */ public function testGetSetWithMutatorAccessor() { // Enable mutator and accessor and verify fields passed are affected $mono = new MonoMock; $mono->setProtected( 'fields', array( 'TypeMap' => array( 'accessor' => 'getTypeMapAppendA', 'mutator' => 'setTypeMapRemoveA' ) ) ); $raw = array('blah //...','etc //test/...','oneMore "//test with space/..."'); $mutated = array('blah //...A','etc //test/...A','oneMore "//test with space/..."A'); $mono->set('TypeMap', $mutated); $this->assertSame( $raw, $mono->callProtected('getRawValue', 'TypeMap'), 'Expected getRawValue to match unmodified version' ); $this->assertSame( $mutated, $mono->get('TypeMap'), 'Expected get to match mutated version' ); // Enable mutator only and verify fields passed are affected $mono = new MonoMock; $mono->setProtected( 'fields', array( 'TypeMap' => array( 'mutator' => 'setTypeMapRemoveA' ) ) ); $mono->set('TypeMap', $mutated); $this->assertSame( $raw, $mono->callProtected('getRawValue', 'TypeMap'), 'Expected getRawValue to match unmodified version' ); $this->assertSame( $raw, $mono->get('TypeMap'), 'Expected get to match raw version' ); } /** * Test getting a bad field fails */ public function testGetBadField() { $mono = new MonoMock; $this->assertFalse( $mono->hasField('BadFieldName'), 'Expected BadFieldName field would not exist' ); try { $mono->get('BadFieldName'); $this->fail('Expected get value of BadFieldName would fail'); } catch (SpecException $e) { $this->assertSame( "Can't get the value of a non-existant field.", $e->getMessage(), 'Unexpected message in exception' ); } catch (\Exception $e) { $this->fail('Unexpected Exception ('. get_class($e) .'): '. $e->getMessage()); } } /** * Test setting a bad field fails */ public function testSetBadField() { $mono = new MonoMock; $this->assertFalse( $mono->hasField('BadFieldName'), 'Expected BadFieldName field would not exist' ); try { $mono->set('BadFieldName', 'blah'); $this->fail('Expected set value of BadFieldName would fail'); } catch (SpecException $e) { $this->assertSame( "Can't set the value of a non-existant field.", $e->getMessage(), 'Unexpected message in exception' ); } catch (\Exception $e) { $this->fail('Unexpected Exception ('. get_class($e) .'): '. $e->getMessage()); } } /** * Test save. */ public function testSave() { $values = array ( 'TypeMap' => array('ctext //...','xtext //test/...','xbinary "//test with space/..."') ); $mono = new MonoMock; $this->assertNotSame( $values, $mono->get(), 'Expected mono starting values to be different' ); $mono->set($values); $mono->save(); $this->assertSame( $values, $mono->get(), 'Expected updated values to match' ); // Get a fresh instance to verify it is also ok $mono = MonoMock::fetch(); $this->assertSame( $values, $mono->get(), 'Expected updated values to match in new instance' ); // ensure new in-memory objects are still empty. $mono = new MonoMock; $this->assertSame( array('TypeMap' => null), $mono->get(), 'Expected updated values to match in new instance' ); } /** * Test get default value when no default is present */ public function testGetDefaultValueNoDefault() { $mono = new MonoMock; $this->assertSame( null, $mono->callProtected('getDefaultValue', 'TypeMap'), 'Expected default typemap value to match' ); } /** * Test setRawValue are defensive for bad fields */ public function testProtectedSetDefensive() { $mono = new MonoMock; $this->assertFalse( $mono->hasField('BadFieldName'), 'Expected BadFieldName field would not exist' ); try { $mono->callProtected('setRawValue', array('BadFieldName', 'blah')); $this->fail('Expected setRawValue of BadFieldName would fail'); } catch (SpecException $e) { $this->assertSame( "Can't set the value of a non-existant field.", $e->getMessage(), 'Unexpected message in exception' ); } catch (\Exception $e) { $this->fail('Unexpected Exception ('. get_class($e) .'): '. $e->getMessage()); } } /** * Test getRawValue are defensive for bad fields */ public function testProtectedGetDefensive() { $mono = new MonoMock; $this->assertFalse( $mono->hasField('BadFieldName'), 'Expected BadFieldName field would not exist' ); try { $mono->callProtected('getRawValue', array('BadFieldName', 'blah')); $this->fail('Expected getRawValue of BadFieldName would fail'); } catch (SpecException $e) { $this->assertSame( "Can't get the value of a non-existant field.", $e->getMessage(), 'Unexpected message in exception' ); } catch (\Exception $e) { $this->fail('Unexpected Exception ('. get_class($e) .'): '. $e->getMessage()); } } }