- <?php
- /**
- * Test methods for the P4 Counter class.
- *
- * @copyright 2012 Perforce Software. All rights reserved.
- * @license Please see LICENSE.txt in top-level folder of this distribution.
- * @version <release>/<patch>
- */
-
- namespace P4Test\Counter;
-
- use P4Test\TestCase;
- use P4\Counter\Counter;
- use P4\Connection\Connection;
- use P4\Connection\Exception\CommandException;
-
- class Test extends TestCase
- {
- /**
- * Test fetchAll method
- */
- public function testFetchAll()
- {
- $entries = array(
- 'test1' => 'value1',
- 'test2' => 'value2',
- 'test3' => 'value3',
- 'test4' => 'value4',
- 'test5' => 'value5',
- 'test6' => 'value6',
- );
-
- $startEntries = array_combine(
- Counter::fetchAll()->invoke('getId'),
- Counter::fetchAll()->invoke('get')
- );
-
- if (USE_UNICODE_P4D) {
- $expectedCounters = array('unicode', 'upgrade');
- } else {
- $expectedCounters = array('upgrade');
- }
-
- $this->assertSame(
- $expectedCounters,
- array_keys($startEntries),
- 'Expected list of counters to start'
- );
-
- // prime the data
- foreach ($entries as $id => $value) {
- $counter = new Counter;
- $counter->setId($id)->set($value);
- }
-
- // merge in and sort the startEntries
- $entries = array_merge($entries, $startEntries);
- ksort($entries);
-
-
- // run a fetch all and validate result
- $counters = Counter::fetchAll();
- foreach ($counters as $counter) {
- $this->assertTrue(
- array_key_exists($counter->getId(), $entries),
- 'Expected counter '.$counter->getId().' to exist in our entries array'
- );
-
- $this->assertSame(
- $entries[$counter->getId()],
- $counter->get(),
- 'Expected matching counter value for entry '.$counter->getId()
- );
- }
-
- // Verify fetchAll with made up option works
- $this->assertSame(
- count($entries),
- count(Counter::fetchAll(array('fooBar' => true))),
- 'Expected fetch all with made up option to match'
- );
-
- // Verify full FETCH_MAXIMUM works
- $this->assertSame(
- array_slice(array_keys($entries), 0, 3),
- Counter::fetchAll(array(Counter::FETCH_MAXIMUM => '3'))->invoke('getId'),
- 'Expected fetch all with Maximum to match'
- );
- }
-
- /**
- * Test fetchAll with 'after' works
- */
- public function testFetchAllAfter()
- {
- $entries = array(
- 'test1' => 'value1',
- 'test2' => 'value2',
- 'test3' => 'value3',
- 'test4' => 'value4',
- 'test5' => 'value5',
- 'test6' => 'value6',
- );
-
- $startEntries = array_combine(
- Counter::fetchAll()->invoke('getId'),
- Counter::fetchAll()->invoke('get')
- );
-
- // prime the data
- foreach ($entries as $id => $value) {
- $counter = new Counter;
- $counter->setId($id)->set($value);
- }
-
- $after = Counter::fetchAll(
- array(
- Counter::FETCH_BY_NAME => 'test*',
- Counter::FETCH_AFTER => 'test3'
- )
- );
- $this->assertSame(
- array_slice(array_keys($entries), 3),
- $after->invoke('getId'),
- 'expected results to start after test3'
- );
- }
-
- /**
- * Ensure calling fetchAll() with FETCH_BY_NAME flag works.
- */
- public function testFetchAllWithOptions()
- {
- // add counters to test
- $counters = array(
- 'testcounter1',
- 'testcounter2',
- 'testcounter3',
- 'testa',
- 'testb',
- 'testc',
- 'counter1',
- 'counter2',
- 'testcounter4'
- );
-
- foreach ($counters as $id) {
- $counter = new Counter;
- $counter->setId($id)
- ->set(1);
- }
-
- // define tests
- $tests = array(
- array(
- 'pattern' => 'testc',
- 'expected' => array(
- 'testc'
- )
- ),
- array(
- 'pattern' => 'testc*',
- 'expected' => array(
- 'testcounter1',
- 'testcounter2',
- 'testcounter3',
- 'testc',
- 'testcounter4'
- )
- ),
- array(
- 'pattern' => '*stc*',
- 'expected' => array(
- 'testcounter1',
- 'testcounter2',
- 'testcounter3',
- 'testcounter4',
- 'testc'
- )
- )
- );
-
- // run tests
- foreach ($tests as $test) {
- $options = array(
- Counter::FETCH_BY_NAME => $test['pattern']
- );
-
- $result = Counter::fetchAll($options)->invoke('getId');
-
- // sort resulting arrays as counters may come in different order
- // from the server
- sort($result);
- sort($test['expected']);
-
- $this->assertSame(
- $test['expected'],
- $result
- );
- }
- }
-
- /**
- * Test calling set without an ID
- */
- public function testSetNoId()
- {
- try {
- $counter = new Counter;
- $counter->set('test');
-
- $this->fail('unexpected success');
- } catch (\PHPUnit\Framework\AssertionFailedError $e) {
- $this->fail($e->getMessage());
- } catch (\P4\Exception $e) {
- $this->assertSame(
- "Cannot set value. No id has been set.",
- $e->getMessage(),
- 'unexpected exception message'
- );
- } catch (\Exception $e) {
- $this->fail(': unexpected exception ('. get_class($e) .') '. $e->getMessage());
- }
- }
-
- /**
- * Test the get value function
- */
- public function testGetSet()
- {
- $counter = new Counter();
- $counter->setId('test')->set('testValue');
-
- $counter = Counter::fetch('test');
-
- $this->assertSame(
- 'test',
- $counter->getId(),
- 'Expected matching Id'
- );
-
- $this->assertSame(
- 'testValue',
- $counter->get(),
- 'Expected matching value'
- );
-
- Counter::fetch('test')->set('testValue2');
-
- $this->assertSame(
- 'testValue',
- $counter->get(),
- 'Expected cached value after outside modification'
- );
-
- $this->assertSame(
- 'testValue2',
- $counter->get(true),
- 'Expected matching value after outside modification'
- );
-
- $counter = new Counter;
- $this->assertSame(
- null,
- $counter->get(),
- 'Expected no-id counter value to match'
- );
-
- $counter->setId('newCounter');
- $this->assertSame(
- null,
- $counter->get(),
- 'Expected non-existent counter value to match'
- );
- }
-
- /**
- * Test a good call to fetch
- */
- public function testFetch()
- {
- $counter = new Counter();
- $counter->setId('test')->set('testValue');
-
- $counter = Counter::fetch('test');
-
- $this->assertSame(
- 'test',
- $counter->getId(),
- 'Expected matching Id'
- );
-
- $this->assertSame(
- 'testValue',
- $counter->get(),
- 'Expected matching value'
- );
- }
-
- /**
- * Test fetch of non-existent record
- */
- public function testNonExistentFetch()
- {
- // ensure fetch fails for a non-existant counter.
- try {
- Counter::fetch('alskdfj2134');
- $this->fail("Fetch should fail for a non-existant counter.");
- } catch (\PHPUnit\Framework\AssertionFailedError $e) {
- $this->fail($e->getMessage());
- } catch (\P4\Exception $e) {
- $this->assertSame(
- "Cannot fetch entry. Id does not exist.",
- $e->getMessage(),
- 'unexpected exception message'
- );
- } catch (\Exception $e) {
- $this->fail(': unexpected exception ('. get_class($e) .') '. $e->getMessage());
- }
- }
-
- /**
- * Test fetch of bad id record
- */
- public function testBadIdFetch()
- {
- // ensure fetch fails for a bad Id.
- try {
- Counter::fetch('te/st');
- $this->fail("Fetch should fail for a il-formated counter.");
- } catch (\PHPUnit\Framework\AssertionFailedError $e) {
- $this->fail($e->getMessage());
- } catch (\InvalidArgumentException $e) {
- $this->assertSame(
- "Must supply a valid id to fetch.",
- $e->getMessage(),
- 'unexpected exception message'
- );
- } catch (\Exception $e) {
- $this->fail(': unexpected exception ('. get_class($e) .') '. $e->getMessage());
- }
- }
-
- /**
- * test bad values for setId
- */
- public function testBadSetId()
- {
- $tests = array(
- array(
- 'title' => __LINE__." leading minus",
- 'value' => '-test'
- ),
- array(
- 'title' => __LINE__." forward slash",
- 'value' => 'te/st'
- ),
- array(
- 'title' => __LINE__." all numeric",
- 'value' => '1234'
- ),
- );
-
- foreach ($tests as $test) {
- // ensure fetch fails for a non-existant counter.
- try {
- $counter = new Counter;
- $counter->setId($test['value']);
- $this->fail($test['title'].': unexpected success');
- } catch (\PHPUnit\Framework\AssertionFailedError $e) {
- $this->fail($e->getMessage());
- } catch (\InvalidArgumentException $e) {
- $this->assertSame(
- "Cannot set id. Id is invalid.",
- $e->getMessage(),
- $test['title'].': unexpected exception message'
- );
- } catch (\Exception $e) {
- $this->fail($test['title'].': : unexpected exception ('. get_class($e) .') '. $e->getMessage());
- }
- }
- }
-
- /**
- * Test exists
- */
- public function testExists()
- {
- // ensure id-exists returns false for ill formatted counter
- $this->assertFalse(Counter::exists("-alsdjf"), "Leading - counter id should not exist.");
- $this->assertFalse(Counter::exists("als/djf"), "Forward slash counter id should not exist.");
-
- // ensure id-exists returns false for non-existant counter
- $this->assertFalse(Counter::exists("alsdjf"), "Given counter id should not exist.");
-
- // create counter and ensure it exists.
- $group = new Counter;
- $group->setId('test')
- ->set('tester');
- $this->assertTrue(Counter::exists("test"), "Given counter id should exist.");
- }
-
- /**
- * Test the increment function
- */
- public function testIncrement()
- {
- $counter = new Counter;
-
- // Test counter that already exists, starting at 0
- $counter->setId('existing')->set(0);
- $this->assertSame(
- "1",
- $counter->increment(),
- 'Expected matching value when starting at 0'
- );
- $this->assertSame(
- "1",
- Counter::fetch('existing')->get(),
- 'Expected matching value when starting at 0 on independent fetch'
- );
- $this->assertSame(
- "2",
- $counter->increment(),
- 'Expected matching value after second increment'
- );
- $this->assertSame(
- "2",
- Counter::fetch('existing')->get(),
- 'Expected matching value after second increment on independent fetch'
- );
-
- // Test counter that already exists starting at 1
- $counter->set(1);
- $this->assertSame(
- "2",
- $counter->increment(),
- 'Expected matching value when starting at 2'
- );
-
- // Test increment will create a counter if it doesn't exist
- $counter = new Counter;
- $counter->setId('newCounter');
- $this->assertSame(
- "1",
- $counter->increment(),
- 'Expected matching value for new counter'
- );
- $this->assertSame(
- "1",
- Counter::fetch('newCounter')->get(),
- 'Expected matching value for new counter on independent fetch'
- );
- }
-
- /**
- * Test the increment function with bad starting value
- */
- public function testBadIncrement()
- {
- // Test counter that already exists, starting at 'bad'
- try {
- $counter = new Counter;
- $counter->setId('existing')->set('bad');
- $counter->increment();
- $this->fail("Increment should fail for a il-valued counter.");
- } catch (\PHPUnit\Framework\AssertionFailedError $e) {
- $this->fail($e->getMessage());
- } catch (\P4\Exception $e) {
- $this->assertSame(
- "Command failed: Can't increment counter 'existing' - value is not numeric.",
- $e->getMessage(),
- 'unexpected exception message'
- );
- } catch (\Exception $e) {
- $this->fail(': unexpected exception ('. get_class($e) .') '. $e->getMessage());
- }
- }
-
- /**
- * Test the delete function
- */
- public function testDelete()
- {
- $counter = new Counter;
- $counter->setId('test')->set('testValue');
-
- $this->assertTrue(Counter::exists('test'), 'expected test entry to exist');
-
- $counter->delete('test');
- $this->assertFalse(Counter::exists('test'), 'expected test entry was deleted');
-
- $counters = Counter::fetchAll();
- $this->assertFalse(
- in_array('test', $counters->invoke('getId')),
- 'expected deleted entry would not be returned by fetchall'
- );
- }
-
- /**
- * Test the delete function with non-existent id
- */
- public function testMissingIdDelete()
- {
- try {
- $counter = new Counter;
- $counter->setId('missing')->delete();
- $this->fail("Delete should fail for a missing counter.");
- } catch (\PHPUnit\Framework\AssertionFailedError $e) {
- $this->fail($e->getMessage());
- } catch (\P4\Exception $e) {
- $this->assertSame(
- "Cannot delete entry. Id does not exist.",
- $e->getMessage(),
- 'unexpected exception message'
- );
- } catch (\Exception $e) {
- $this->fail(': unexpected exception ('. get_class($e) .') '. $e->getMessage());
- }
- }
-
- /**
- * Test the delete function with no id
- */
- public function testNoIdDelete()
- {
- try {
- $counter = new Counter;
- $counter->delete();
- $this->fail("Delete should fail when no id is set.");
- } catch (\PHPUnit\Framework\AssertionFailedError $e) {
- $this->fail($e->getMessage());
- } catch (\P4\Exception $e) {
- $this->assertSame(
- "Cannot delete. No id has been set.",
- $e->getMessage(),
- 'unexpected exception message'
- );
- } catch (\Exception $e) {
- $this->fail(': unexpected exception ('. get_class($e) .') '. $e->getMessage());
- }
- }
-
- /**
- * Test the force option.
- */
- public function testForce()
- {
- // ensure 'security' counter protected.
- $counter = new Counter;
- $counter->setId('security');
- try {
- $counter->set(1);
- $this->fail("Expected exception");
- } catch (CommandException $e) {
- $this->assertTrue(true);
- }
-
- // set a protected counter.
- $counter->set(1, true);
- $this->assertSame(1, (int) $counter->get(), "Expected security level 1");
-
- // now try to delete it.
- try {
- $counter->delete();
- $this->fail("Expected exception");
- } catch (CommandException $e) {
- $this->assertTrue(true);
- }
-
- // delete with force.
- $counter->delete(true);
- $this->assertFalse(
- Counter::exists('security'),
- "Expected 'security' counter to be deleted."
- );
- }
- }