Skip to content

Commit

Permalink
Explain tests and organize them
Browse files Browse the repository at this point in the history
Library tests are now separated from "feature" tests, which explain
better what each feature of the component is and how it works. Works
better than a README if you ask me, or Respect\Doc for that matter -
which suffered an overhaul that I still haven't take the time to
understand.

Previous coverage is unchanged, although more tests were added for
clarity and better coverage of each feature usage.

Changes
-------

You can now indent INI declarations, every blank space before the start
of any declaration will be removed.

A bug happened when you manipulated the container by defining an item
entry with an instance.

The "ifs" surrounding `$this->configure()` were unnecessary.

Describes development dependencies better on `composer.json` to run the
test suite.
  • Loading branch information
augustohp committed Dec 3, 2017
1 parent ae1bae9 commit a9b68ab
Show file tree
Hide file tree
Showing 15 changed files with 1,121 additions and 636 deletions.
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
"psr/container": "^1.0"
},
"require-dev": {
"ext-PDO": "*",
"ext-pdo_sqlite": "*",
"phpunit/phpunit": "~4.4",
"respect/test": "dev-master"
},
Expand Down
25 changes: 12 additions & 13 deletions library/Respect/Config/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@ public function __isset($name)
{
return $this->has($name);
}
public function has($name)

public function has($name)
{
if ($this->configurator) {
$this->configure();
}
$this->configure();

return parent::offsetExists($name);
}
Expand Down Expand Up @@ -70,9 +68,7 @@ function ($param) use ($container) {
parent::offsetSet($name, $item);
}

if ($this->configurator) {
$this->configure();
}
$this->configure();

return $this;
}
Expand Down Expand Up @@ -107,12 +103,10 @@ protected function configure()

throw new Argument("Invalid input. Must be a valid file or array");
}

public function getItem($name, $raw = false)
{
if ($this->configurator) {
$this->configure();
}
$this->configure();

if (!isset($this[$name])) {
throw new NotFoundException("Item $name not found");
Expand All @@ -124,14 +118,15 @@ public function getItem($name, $raw = false)

return $this->lazyLoad($name);
}

public function get($name)
{
return $this->getItem($name);
}

public function loadString($configurator)
{
$configuration = preg_replace('/^[\s\t]+/', '', $configurator);
$iniData = parse_ini_string($configurator, true);
if (false === $iniData || count($iniData) == 0) {
throw new Argument("Invalid configuration string");
Expand Down Expand Up @@ -268,6 +263,10 @@ protected function hasCompleteBrackets($value)

protected function parseSingleValue($value)
{
if (is_object($value)) {
return $value;
}

$value = trim($value);
if ($this->hasCompleteBrackets($value)) {
return $this->parseBrackets($value);
Expand Down
98 changes: 98 additions & 0 deletions tests/feature/Callback.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

namespace Test\Feature;

use Respect\Config\Container;

class ItemConsuptionViaCallback extends \PHPUnit_Framework_TestCase
{
public function testLateDefinitionOfVariableExpansionThroughContainerCallbackReturnsContainer()
{
$c = new Container(<<<INI
foo = [undef]
bar = [foo]
INI
);
$definition = array('undef' => 'Hello');
$result = $c($definition);

$this->assertEquals(
'Hello',
$result->bar,
'Calling the container as a function will append the array passed as content to it.' . PHP_EOL .
'It will return the itself, as well.'
);
$this->assertSame(
$result->bar,
$c->bar,
"But it doesn't matter on which instance of the container you call."
);
}

public function testLateDefinitionOfVariableExpansionThroughItemCallbackReturnsValue()
{
$c = new Container(<<<INI
foo = [undef]
bar = [foo]
INI
);

$result = $c->bar(array('undef'=>'Hello'));
$this->assertEquals('Hello', $result);
}

public function testRetrievalOfItemThroughInstanceTypeOnContainerCallbackReturnsValue()
{
$called = false;
$c = new Container(<<<INI
[instanceof DateTime]
time = now
INI
);
$result = $c(function(\DateTime $date) use (&$called) {
$called = true;
return $date;
});

$result2 = $c['DateTime'];
$this->assertInstanceOf('DateTime', $result);
$this->assertInstanceOf('DateTime', $result2);
$this->assertTrue($called);
}

public function testRetrievalOfInstanceTypeThroughContainerCallbackReturnsValueEvenWithoutDeclaringItsType()
{
$c = new Container();
$c(new \DateTime);
$called = false;

$result = $c(function(\DateTime $date) use (&$called) {
$called = true;
return $date;
});

$result2 = $c['DateTime'];
$this->assertInstanceOf('DateTime', $result);
$this->assertInstanceOf('DateTime', $result2);
$this->assertTrue($called);
}

public function testContainerCallbackReceivingACallableCallsItAndReturnsValue()
{
$c = new Container();
$c(new \DateTime);
$result = $c(array('Test\Stub\TimePrinter', 'returnTimePassedAsArgument'));
$this->assertInstanceOf('DateTime', $result);
}
}

namespace Test\Stub;

class TimePrinter
{
public function returnTimePassedAsArgument(\DateTime $time)
{
return $time;
}
}

45 changes: 45 additions & 0 deletions tests/feature/ContainerAsArray.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace Test\Feature;

use Respect\Config\Container;

class ContainerAsArray extends \PHPUnit_Framework_TestCase
{
/**
* @TODO Fix issue where passing INI to container construction does not
* allow ArrayAccess usage. T.T
*/
public function testUsingItemsAsContainerWasAnArray()
{
$c = new Container();
$c->loadString(<<<INI
fibonacci = [1, 1, 2, 3, 5]
INI
);

$this->assertInstanceOf(
'ArrayAccess',
$c,
'The container implements the \ArrayAccess interface, so it behaves like an array.'
);
$this->assertTrue(
isset($c['fibonacci'])
);
$this->assertEquals(
array(1, 1, 2, 3, 5),
$c['fibonacci'],
'The container implements the \ArrayAccess interface, so it behaves like an array.'
);
}

public function testDefiningItemWithArrayLikeNotation()
{
$c = new Container;

$c['not'] = false;
$this->assertTrue(isset($c['not']));
$this->assertFalse($c['not']);
}
}

92 changes: 92 additions & 0 deletions tests/feature/ContainerManipulation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

namespace Test\Feature;

use Respect\Config\Container;

class ContainerManipulation extends \PHPUnit_Framework_TestCase
{
public function testDefiningNewItemOnContainer()
{
$c = new Container;

$c->name = 'John Snow';

$this->assertEquals(
'John Snow',
$c->name,
'You can define new items just like you would define a property on an instance.'
);
}

public function testDefinitionOfItemWithAnonymousFunctionExecutesItAndReturnsItsValueUponUsage()
{
$c = new Container;

$c->name = function() { return 'John Doe'; };

$this->assertEquals(
'John Doe',
$c->name,
'The function gets executed and the return value is stored in the container.'
);
}

public function testDefinitionOfItemOnContainerWithItems()
{
$c = new Container(<<<INI
respect_blah = ""
INI
);

$c->panda = function() { return 'ok'; };

$this->assertEquals(
'ok',
$c->panda,
'It works if the container has stuff or not.'
);
}

/**
* @group issue
* @ticket 14
*/
public function testItemOverwrrite()
{
$c = new Container(<<<INI
[pdo StdClass]
[db Test\Stub\DatabaseWow]
con = [pdo];
INI
);

$c->pdo = new \PDO('sqlite::memory:');

$this->assertNotInstanceOf(
'StdClass',
$c->pdo,
'Although PDO was defined with StdClass we overwritten it to a proper instance of PDO manually.'
);

$this->assertSame(
$c->pdo,
$c->db->c,
'This should overwrite every usage of that element inside the container.'
);
}
}

namespace Test\Stub;

class DatabaseWow
{
public $c;

public function __construct($con)
{
$this->c = $con;
}
}

Loading

0 comments on commit a9b68ab

Please sign in to comment.