MonoTest.php #1

  • //
  • guest/
  • perforce_software/
  • chronicle/
  • main/
  • tests/
  • phpunit/
  • P4/
  • Spec/
  • MonoTest.php
  • View
  • Commits
  • Open Download .zip Download (16 KB)
<?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   2011 Perforce Software. All rights reserved.
 * @license     Please see LICENSE.txt in top-level folder of this distribution.
 * @version     <release>/<patch>
 */
class P4_Spec_MonoTest extends TestCase
{
    /**
     * Setup Mono test object
     */
    public function setUp()
    {
        // disable mutators by default
        P4_Spec_MonoMock::setProtectedStaticVar('_mutators',    array());
        P4_Spec_MonoMock::setProtectedStaticVar('_accessors',   array());
        P4_Spec_MonoMock::setProtectedStaticVar('_specType',    'typemap');

        parent::setUp();
    }

    /**
     * Constructor Test
     */
    public function testConstructor()
    {
        // Construct object with no passed values
        $mono = new P4_Spec_MonoMock;

        $expected = array (
            'TypeMap' => null
        );

        $this->assertSame(
            $expected,
            $mono->getValues(),
            '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 P4_Spec_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 testGetSetValues()
    {
        $mono = new P4_Spec_MonoMock;

        $expected = array (
            'TypeMap' => array('blah //...','etc //test/...','oneMore "//test with space/..."')
        );

        $mono = new P4_Spec_MonoMock;
        $mono->setValues($expected);

        $this->assertSame(
            $expected,
            $mono->getValues(),
            'Expected passed fields to take'
        );
    }

    /**
     * Exercise get/set values with combinations of mutator/accessor
     */
    public function testGetSetValuesWithMutatorAccessor()
    {
        // Enable mutator and accessor and verify fields passed are affected
        P4_Spec_MonoMock::setProtectedStaticVar('_mutators',   array('TypeMap' => 'setTypeMapRemoveA'));
        P4_Spec_MonoMock::setProtectedStaticVar('_accessors',  array('TypeMap' => 'getTypeMapAppendA'));

        $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 = new P4_Spec_MonoMock;

        $mono->setValues($mutated);

        $this->assertSame(
            $raw,
            $mono->callProtectedFunc('_getValues'),
            'Expected _getValues to match unmodified version'
        );

        $this->assertSame(
            $mutated,
            $mono->getValues(),
            'Expected getValues to match mutated version'
        );


        // Enable mutator only and verify fields passed are affected
        P4_Spec_MonoMock::setProtectedStaticVar('_mutators',   array('TypeMap' => 'setTypeMapRemoveA'));
        P4_Spec_MonoMock::setProtectedStaticVar('_accessors',  array());

        $mono = new P4_Spec_MonoMock;

        $mono->setValues($mutated);

        $this->assertSame(
            $raw,
            $mono->callProtectedFunc('_getValues'),
            'Expected _getValues to match unmodified version'
        );

        $this->assertSame(
            $raw,
            $mono->getValues(),
            'Expected getValues to match raw version'
        );
    }

    /**
     * Test that setValues ignores exceptions.
     */
    public function testSetValuesIgnoresErrors()
    {
        $mono = new P4_Spec_MonoMock;

        $values = $mono->getValues();
        $values['JunkEntry'] = 'a junk entry';

        // invalid field would normally throw; ensure it doesn't here.
        try {
            $mono->setValues($values);

            $this->assertSame(
                array('TypeMap' => $values['TypeMap']),
                $mono->getValues(),
                'Expected values to match'
            );
        } catch (Exception $e) {
            $this->fail('Unexpected Exception ('. get_class($e) .'): '. $e->getMessage());
        }
    }

    /**
     * Test set raw values
     */
    public function testSetRawValues()
    {
        // Enable mutator and accessor and verify setRawValues is unaffected
        P4_Spec_MonoMock::setProtectedStaticVar('_mutators',   array('TypeMap' => 'setTypeMapRemoveA'));
        P4_Spec_MonoMock::setProtectedStaticVar('_accessors',  array('TypeMap' => 'getTypeMapAppendA'));

        $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 = new P4_Spec_MonoMock;

        $mono->callProtectedFunc('_setValues', array($raw));

        $this->assertSame(
            $raw,
            $mono->callProtectedFunc('_getValues'),
            'Expected _getValues to match unmodified version'
        );

        $this->assertSame(
            $mutated,
            $mono->getValues(),
            'Expected getValues to match mutated version'
        );
    }

    /**
     * Test get/set Value
     */
    public function testGetSetValue()
    {
        $mono = new P4_Spec_MonoMock;

        $expected = array('blah //...','etc //test/...','oneMore "//test with space/..."');

        // Verify get value reflects setValues input
        $mono = new P4_Spec_MonoMock;
        $mono->setValues(array('TypeMap' => $expected));

        $this->assertSame(
            $expected,
            $mono->getValue('TypeMap'),
            'Expected setValues to take'
        );

        // Verify get value reflects set value input
        $mono = new P4_Spec_MonoMock;
        $mono->setValue('TypeMap', $expected);

        $this->assertSame(
            $expected,
            $mono->getValue('TypeMap'),
            'Expected setValue to take'
        );

        // Verify get values reflects set value input
        $this->assertSame(
            array('TypeMap' => $expected),
            $mono->getValues(),
            'Expected setValue to affect getValues'
        );
    }

    /**
     * Test get/set Value with mutator/accessor
     */
    public function testGetSetValueWithMutatorAccessor()
    {
        // Enable mutator and accessor and verify fields passed are affected
        P4_Spec_MonoMock::setProtectedStaticVar('_mutators',   array('TypeMap' => 'setTypeMapRemoveA'));
        P4_Spec_MonoMock::setProtectedStaticVar('_accessors',  array('TypeMap' => 'getTypeMapAppendA'));

        $raw     = array('blah //...','etc //test/...','oneMore "//test with space/..."');
        $mutated = array('blah //...A','etc //test/...A','oneMore "//test with space/..."A');


        $mono = new P4_Spec_MonoMock;

        $mono->setValue('TypeMap', $mutated);

        $this->assertSame(
            $raw,
            $mono->callProtectedFunc('_getValue', 'TypeMap'),
            'Expected _getValue to match unmodified version'
        );

        $this->assertSame(
            $mutated,
            $mono->getValue('TypeMap'),
            'Expected getValues to match mutated version'
        );


        // Enable mutator only and verify fields passed are affected
        P4_Spec_MonoMock::setProtectedStaticVar('_mutators',   array('TypeMap' => 'setTypeMapRemoveA'));
        P4_Spec_MonoMock::setProtectedStaticVar('_accessors',  array());

        $mono = new P4_Spec_MonoMock;

        $mono->setValue('TypeMap', $mutated);

        $this->assertSame(
            $raw,
            $mono->callProtectedFunc('_getValue', 'TypeMap'),
            'Expected _getValue to match unmodified version'
        );

        $this->assertSame(
            $raw,
            $mono->getValue('TypeMap'),
            'Expected getValue to match raw version'
        );
    }

    /**
     * Test getting a bad field fails
     */
    public function testGetValueBadField()
    {
        $mono = new P4_Spec_MonoMock;

        $this->assertFalse(
            $mono->hasField('BadFieldName'),
            'Expected BadFieldName field would not exist'
        );

        try {
            $mono->getValue('BadFieldName');

            $this->fail('Expected get value of BadFieldName would fail');
        } catch (P4_Spec_Exception $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 testSetValueBadField()
    {
        $mono = new P4_Spec_MonoMock;

        $this->assertFalse(
            $mono->hasField('BadFieldName'),
            'Expected BadFieldName field would not exist'
        );

        try {
            $mono->setValue('BadFieldName', 'blah');

            $this->fail('Expected set value of BadFieldName would fail');
        } catch (P4_Spec_Exception $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 P4_Spec_MonoMock;

        $this->assertNotSame(
            $values,
            $mono->getValues(),
            'Expected mono starting values to be different'
        );

        $mono->setValues($values);
        $mono->save();

        $this->assertSame(
            $values,
            $mono->getValues(),
            'Expected updated values to match'
        );

        // Get a fresh instance to verify it is also ok
        $mono = P4_Spec_MonoMock::fetch();

        $this->assertSame(
            $values,
            $mono->getValues(),
            'Expected updated values to match in new instance'
        );

        // ensure new in-memory objects are still empty.
        $mono = new P4_Spec_MonoMock;
        $this->assertSame(
            array('TypeMap' => null),
            $mono->getValues(),
            'Expected updated values to match in new instance'
        );
    }

    /**
     * Test bad _specType values cause exception
     */
    public function testSpecTypeBad()
    {
        $tests = array(
            __LINE__.' null'            => null,
            __LINE__.' empty string'    => '',
            __LINE__.' spaces'          => '  ',
            __LINE__.' tabs'            => "\t"
        );

        foreach ($tests as $title => $value) {
            P4_Spec_MonoMock::setProtectedStaticVar('_specType', $value);

            $mono = new P4_Spec_MonoMock;

            try {
                $mono->getSpecDefinition();

                $this->fail($title.': Expected Exception');
            } catch (P4_Spec_Exception $e) {
                $this->assertSame(
                    'No type is defined for this specification.',
                    $e->getMessage(),
                    $title.': Unexpected message in exception'
                );
            } catch (Exception $e) {
                $this->fail($title.': Unexpected Exception ('. get_class($e) .'): '. $e->getMessage());
            }
        }
    }

    /**
     * Test get default value when no default is present
     */
    public function testGetDefaultValueNoDefault()
    {
        $mono = new P4_Spec_MonoMock;

        $this->assertSame(
            null,
            $mono->callProtectedFunc('_getDefaultValue', 'TypeMap'),
            'Expected default typemap value to match'
        );
    }

    /**
     * Test _setValue are defensive for bad fields
     */
    public function testProtectedSetValueDefensive()
    {
        $mono = new P4_Spec_MonoMock;

        $this->assertFalse(
            $mono->hasField('BadFieldName'),
            'Expected BadFieldName field would not exist'
        );

        try {
            $mono->callProtectedFunc('_setValue', array('BadFieldName', 'blah'));

            $this->fail('Expected _setValue of BadFieldName would fail');
        } catch (P4_Spec_Exception $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 _getValue are defensive for bad fields
     */
    public function testProtectedGetValueDefensive()
    {
        $mono = new P4_Spec_MonoMock;

        $this->assertFalse(
            $mono->hasField('BadFieldName'),
            'Expected BadFieldName field would not exist'
        );

        try {
            $mono->callProtectedFunc('_getValue', array('BadFieldName', 'blah'));

            $this->fail('Expected _getValue of BadFieldName would fail');
        } catch (P4_Spec_Exception $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());
        }
    }
}
# Change User Description Committed
#1 16170 perforce_software Move Chronicle files to follow new path scheme for branching.
//guest/perforce_software/chronicle/tests/phpunit/P4/Spec/MonoTest.php
#1 8972 Matt Attaway Initial add of the Chronicle source code