Skip to content

Commit

Permalink
Merge pull request #35 from kschroeder/develop
Browse files Browse the repository at this point in the history
A bunch o'f stuff
  • Loading branch information
kschroeder authored Feb 22, 2017
2 parents a6220b6 + 6905a57 commit 8d9e7bb
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 31 deletions.
18 changes: 16 additions & 2 deletions lib/Config/BuilderFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,30 @@

use Magium\Configuration\Config\Storage\RelationalDatabase;
use Magium\Configuration\File\Configuration\ConfigurationFileRepository;
use Magium\Configuration\File\Context\AbstractContextConfigurationFile;
use Magium\Configuration\InvalidConfigurationException;
use Magium\Configuration\Manager\CacheFactory;
use Zend\Db\Adapter\Adapter;

class BuilderFactory implements BuilderFactoryInterface
{
protected $configuration;
protected $adapter;
protected $contextFile;
protected $baseDirectory;

public function __construct(\SimpleXMLElement $configuration)
public function __construct(
\SplFileInfo $baseDirectory,
\SimpleXMLElement $configuration,
AbstractContextConfigurationFile $contextConfigurationFile
)
{
$this->configuration = $configuration;
$this->contextFile = $contextConfigurationFile;
if (!$baseDirectory->isDir()) {
throw new InvalidConfigurationException('Base directory must be a directory');
}
$this->baseDirectory = $baseDirectory;
}

protected function getCache(\SimpleXMLElement $element)
Expand All @@ -35,12 +48,13 @@ public function getAdapter()

public function getPersistence()
{
$persistence = new RelationalDatabase($this->getAdapter());
$persistence = new RelationalDatabase($this->getAdapter(), $this->contextFile);
return $persistence;
}

protected function getSecureBaseDirectories()
{
chdir($this->baseDirectory->getPath());
$config = json_encode($this->configuration->configurationDirectories);
$config = json_decode($config, true);
$baseDirs = [];
Expand Down
5 changes: 4 additions & 1 deletion lib/Config/BuilderFactoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Magium\Configuration\Config;

use Magium\Configuration\File\Context\AbstractContextConfigurationFile;
use Zend\Db\Adapter\Adapter;

interface BuilderFactoryInterface
Expand All @@ -11,10 +12,12 @@ interface BuilderFactoryInterface
* BuilderFactoryInterface constructor. If you need something that does things differently, such as adding your
* own service manager or dependency injection container, you should
* override the MagiumConfigurationFactory class and make your own getBuilder() method.
* @param \SplFileInfo $baseDirectory
* @param \SimpleXMLElement $config
* @param AbstractContextConfigurationFile $contextConfigurationFile
*/

public function __construct(\SimpleXMLElement $config);
public function __construct(\SplFileInfo $baseDirectory, \SimpleXMLElement $config, AbstractContextConfigurationFile $contextConfigurationFile);

/**
* @return Builder
Expand Down
29 changes: 10 additions & 19 deletions lib/Config/Storage/RelationalDatabase.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,17 @@ class RelationalDatabase implements StorageInterface

public function __construct(
Adapter $adapter,
AbstractContextConfigurationFile $context = null
AbstractContextConfigurationFile $context
)
{
$this->adapter = $adapter;
$this->configurationFile = $context;
if ($context instanceof AbstractContextConfigurationFile) {
$this->configurationFile = $context->toXml();
$this->configurationFile->registerXPathNamespace('s', 'http://www.magiumlib.com/ConfigurationContext');

}
}

public function getContexts()
{
$contexts = [Config::CONTEXT_DEFAULT];
if ($this->configurationFile instanceof \SimpleXMLElement) {
$configuredContexts = $this->configurationFile->xpath('//s:context');
foreach ($configuredContexts as $context) {
$contexts[] = (string)$context['id'];
}
}
return $contexts;
return $this->configurationFile->getContexts();
}

/**
Expand All @@ -58,14 +47,16 @@ public function getPathForContext($requestedContext)
{
$names = [];

if ($requestedContext !== Config::CONTEXT_DEFAULT
&& $this->configurationFile instanceof \SimpleXMLElement) {
$xpath = sprintf('//s:context[@id="%s"]', $requestedContext);
$contexts = $this->configurationFile->xpath($xpath);
if (!$contexts) {
if ($requestedContext !== Config::CONTEXT_DEFAULT) {
$contexts = $this->getContexts();
$xml = $this->configurationFile->toXml();
if (!in_array($requestedContext, $contexts)) {
throw new InvalidContextException('Unable to find context: ' . $requestedContext);
}

$xml->registerXPathNamespace('s', 'http://www.magiumlib.com/ConfigurationContext');
$contexts = $xml->xpath(sprintf('//s:context[@id="%s"]', $requestedContext));

$context = array_shift($contexts);
do {

Expand Down Expand Up @@ -135,7 +126,7 @@ protected function exists(Sql $sql, $path, $context)
$select->where(['path' => $path, 'context' => $context]);
$select = $select->getSqlString($this->adapter->getPlatform());

$result = $this->adapter->query($select)->execute();
$result = $this->adapter->query($select)->execute( );
$check = $result->current();
return $check && $check['cnt'] > 0;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Console/Command/ContextList.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
protected function formatNode($id, $name = null)
{
if ($name == null) {
$name = $id;
return $id;
}
return sprintf('%s (%s)', $id, $name);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/MagiumConfigurationFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public function getBuilderFactory()
if (!$reflection->implementsInterface(BuilderFactoryInterface::class)) {
throw new InvalidConfigurationException($class . ' must implement ' . BuilderFactoryInterface::class);
}
$this->builderFactory = $reflection->newInstance($this->xml);
$this->builderFactory = $reflection->newInstance(new \SplFileInfo($this->baseDir), $this->xml, $this->getContextFile());
}
return $this->builderFactory;
}
Expand Down
76 changes: 76 additions & 0 deletions tests/Command/ContextListTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

namespace Magium\Configuration\Tests\Command;

use Magium\Configuration\Config\Builder;
use Magium\Configuration\Config\BuilderFactory;
use Magium\Configuration\Config\BuilderFactoryInterface;
use Magium\Configuration\Config\Config;
use Magium\Configuration\Config\Storage\StorageInterface;
use Magium\Configuration\Console\Command\ConfigurationSet;
use Magium\Configuration\Console\Command\ContextList;
use Magium\Configuration\Console\Command\UnconfiguredPathException;
use Magium\Configuration\File\Context\AbstractContextConfigurationFile;
use Magium\Configuration\MagiumConfigurationFactory;
use Magium\Configuration\MagiumConfigurationFactoryInterface;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class ContextListTest extends TestCase
{

public function testConfiguration()
{
$command = new ContextList();
$name = $command->getName();
self::assertEquals(ContextList::COMMAND, $name);
}

public function testIndentationIsCorrect()
{
self::assertEquals(' ', ContextList::TAB);
}

public function testGetFormat()
{

$config = $this->createMock(AbstractContextConfigurationFile::class);
$config->expects(self::once())->method('toXml')->willReturn(
new \SimpleXMLElement(<<<XML
<?xml version="1.0" encoding="UTF-8" ?>
<defaultContext xmlns="http://www.magiumlib.com/ConfigurationContext">
<context id="test" title="Test">
<context title="SubTest" id="subtest" />
</context>
<context id="base"/>
</defaultContext>
XML
)
);
$factory = $this->createMock(MagiumConfigurationFactoryInterface::class);
$factory->expects(self::once())->method('getContextFile')->willReturn($config);
$contextList = new ContextList();
$contextList->setConfigurationFactory($factory);

$output = $this->createMock(OutputInterface::class);
$expected = [
'default (Default)',
ContextList::TAB . 'test (Test)',
ContextList::TAB . ContextList::TAB . 'subtest (SubTest)',
ContextList::TAB . 'base',
];
$output->expects(self::any())->method('writeln')->willReturnCallback(function($param) use (&$expected) {
$key = array_search($param, $expected);
if ($key !== false) {
unset($expected[$key]);
}
});

$contextList->run($this->createMock(InputInterface::class), $output);

self::assertCount(0, $expected);
}


}
11 changes: 11 additions & 0 deletions tests/Config/BuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Magium\Configuration\File\Configuration\UnsupportedFileTypeException;
use Magium\Configuration\File\InvalidFileException;
use Magium\Configuration\File\Configuration\XmlFile;
use Magium\Configuration\InvalidConfigurationException;
use PHPUnit\Framework\TestCase;
use Zend\EventManager\Exception\InvalidCallbackException;

Expand All @@ -34,6 +35,16 @@ public function testBuildConfigurationStructureMerges()
self::assertEquals('Test Value 2', (string)$paths[0]->value);
}

public function testInvalidConfigurationFileThrowsException()
{
$this->expectException(InvalidConfigurationException::class);
$builder = $this->getMockBuilder(Builder::class)->disableOriginalConstructor()->setMethods(
['getMergedStructure']
)->getMock();
$builder->expects(self::once())->method('getMergedStructure')->willReturn(null);
$builder->build();
}

public function testBuildConfigurationNewChildren()
{
/*
Expand Down
40 changes: 38 additions & 2 deletions tests/Factory/FactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
namespace Magium\Configuration\Tests\Factory;

use Magium\Configuration\Config\Builder;
use Magium\Configuration\Config\Config;
use Magium\Configuration\Config\InvalidConfigurationLocationException;
use Magium\Configuration\Config\MissingConfigurationException;
use Magium\Configuration\File\Context\AbstractContextConfigurationFile;
use Magium\Configuration\File\Context\XmlFile;
use Magium\Configuration\InvalidConfigurationException;
use Magium\Configuration\InvalidConfigurationFileException;
use Magium\Configuration\MagiumConfigurationFactory;
Expand All @@ -24,7 +26,6 @@ protected function setFile($contents = '<config />', $filename = self::CONFIG)
{
$this->configFile[$filename] = __DIR__ . '/../../' . $filename;
file_put_contents($this->configFile[$filename], $contents);
parent::setUp();
}

protected function tearDown()
Expand Down Expand Up @@ -241,13 +242,26 @@ public function testInvalidBuilderFactoryTypeThrowsException()
public function testGetManager()
{
$this->setValidFile();
$this->setContextFile();
$factory = new MagiumConfigurationFactory();
$manager = $factory->getManager();
self::assertInstanceOf(Manager::class, $manager);
}

protected function setContextFile()
{
$this->setFile(<<<XML
<?xml version="1.0" encoding="utf-8">
<defaultContext xmlns="http://www.magiumlib.com/ConfigurationContext"/>
XML
,
'contexts.xml'
);
}

public function testGetNotManagerAndMakeSureSettersAreCalled()
{
$this->setContextFile();
$this->setFile(<<<XML
<?xml version="1.0" encoding="utf-8"?>
<magium xmlns="http://www.magiumlib.com/BaseConfiguration"
Expand All @@ -261,7 +275,8 @@ public function testGetNotManagerAndMakeSureSettersAreCalled()
XML
);
$factory = new MagiumConfigurationFactory();
$factory = $this->getMockBuilder(MagiumConfigurationFactory::class)->setMethods(['getContextFile'])->getMock();
$factory->expects(self::once())->method('getContextFile')->willReturn(new XmlFile($this->configFile['contexts.xml']));
$manager = $factory->getManager();
self::assertInstanceOf(NotManagerManager::class, $manager);
/* @var $manager NotManagerManager */
Expand All @@ -270,10 +285,31 @@ public function testGetNotManagerAndMakeSureSettersAreCalled()
self::assertInstanceOf(StorageInterface::class, $manager->getRemoteCache());
}

public function testInvalidManagerThrowsException()
{
$this->setFile(<<<XML
<?xml version="1.0" encoding="utf-8"?>
<magium xmlns="http://www.magiumlib.com/BaseConfiguration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.magiumlib.com/BaseConfiguration">
<persistenceConfiguration><driver>pdo_sqlite</driver><database>:memory:</database></persistenceConfiguration>
<manager class="ArrayObject" />
<cache><adapter>filesystem</adapter></cache>
<localCache><adapter>filesystem</adapter></localCache>
</magium>
XML
);
$this->expectException(InvalidConfigurationException::class);
$factory = new MagiumConfigurationFactory();
$factory->getManager();
}

public function testInvalidBaseDirectoryThrowsException()
{
$base = $tmp = sys_get_temp_dir();
$base .= DIRECTORY_SEPARATOR . 'remove-me'; // Won't exist
$this->setContextFile();
$this->setFile(<<<XML
<?xml version="1.0" encoding="utf-8"?>
<magium xmlns="http://www.magiumlib.com/BaseConfiguration"
Expand Down
14 changes: 9 additions & 5 deletions tests/Storage/CrudTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class CrudTest extends TestCase

public function testRelationalCreate()
{
$db = $this->createDatabase();
$db = $this->createDatabase($this->createMock(XmlFile::class));
$db->setValue('path', 'value');
$value = $db->getValue('path');
self::assertEquals('value', $value);
Expand All @@ -31,7 +31,9 @@ public function testRelationalCreate()
public function testRelationalCreateOnInvalidContextWithoutConfigThrowsException()
{
$this->expectException(InvalidContextException::class);
$db = $this->createDatabase();
$mock = $this->createMock(XmlFile::class);
$mock->expects(self::once())->method('getContexts')->willReturn([Config::CONTEXT_DEFAULT]);
$db = $this->createDatabase($mock);
$db->setValue('path', 'value', 'boogers');
}

Expand Down Expand Up @@ -74,15 +76,17 @@ public function testMakeSureUpdateAndInsertAreCalledAppropriately()
}
});

$relational = new RelationalDatabase($adapter);
$relational = new RelationalDatabase($adapter, $this->createMock(XmlFile::class));
$relational->setValue('path', 'value', Config::CONTEXT_DEFAULT);
$relational->setValue('path', 'value', Config::CONTEXT_DEFAULT);
}


public function testNullReturnedForNonExistentPath()
{
$db = $this->createDatabase();
$mock = $this->createMock(XmlFile::class);
$mock->expects(self::once())->method('getContexts')->willReturn([Config::CONTEXT_DEFAULT]);
$db = $this->createDatabase($mock);
$result = $db->getValue('no-existe');
self::assertNull($result);
}
Expand Down Expand Up @@ -170,7 +174,7 @@ protected function getAdapter()
return $this->sqlite;
}

protected function createDatabase(AbstractContextConfigurationFile $contextConfigurationFile = null)
protected function createDatabase(AbstractContextConfigurationFile $contextConfigurationFile)
{
$sqlite = $this->getAdapter();
$db = new RelationalDatabase($sqlite, $contextConfigurationFile);
Expand Down

0 comments on commit 8d9e7bb

Please sign in to comment.