1
0
mirror of https://github.com/guzzle/guzzle.git synced 2025-02-25 02:22:57 +01:00

Replaced the old AbstractFactory classes with config loaders

Added the ability to add includes to arrays, JSON, and PHP files
This commit is contained in:
Michael Dowling 2012-09-19 23:37:26 -07:00
parent f4ea933af7
commit e052a1d584
31 changed files with 638 additions and 1032 deletions

View File

@ -0,0 +1,132 @@
<?php
namespace Guzzle\Service;
use Guzzle\Common\Exception\InvalidArgumentException;
use Guzzle\Service\Exception\JsonException;
/**
* Abstract config loader
*/
abstract class AbstractConfigLoader implements ConfigLoaderInterface
{
/**
* @var array Array of aliases for actual filenames
*/
protected $aliases = array();
/**
* {@inheritdoc}
*/
public function load($config, array $options = array())
{
if (is_string($config)) {
$config = $this->loadFile($config);
} elseif (!is_array($config)) {
throw new InvalidArgumentException('Unknown type passed to configuration loader: ' . gettype($config));
} else {
$this->mergeIncludes($config);
}
return $this->build($config, $options);
}
/**
* Add an include alias to the loader
*
* @param string $filename Filename to alias (e.g. _foo)
* @param string $alias Actual file to use (e.g. /path/to/foo.json)
*
* @return self
*/
public function addAlias($filename, $alias)
{
$this->aliases[$filename] = $alias;
return $this;
}
/**
* Perform the parsing of a config file and create the end result
*
* @param array $config Configuration data
* @param array $options Options to use when building
*
* @return mixed
*/
protected abstract function build($config, array $options);
/**
* Load a configuration file (can load JSON or PHP files that return an array when included)
*
* @param string $filename File to load
*
* @return array
* @throws InvalidArgumentException
*/
protected function loadFile($filename)
{
if (isset($this->aliases[$filename])) {
$filename = $this->aliases[$filename];
}
if (!is_readable($filename)) {
throw new InvalidArgumentException("Unable to open {$filename} for reading");
}
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if ($ext == 'js' || $ext == 'json') {
$config = json_decode(file_get_contents($filename), true);
// Throw an exception if there was an error loading the file
if ($error = json_last_error()) {
throw new JsonException("Error loading JSON data from {$filename}: {$error}");
}
} elseif ($ext == 'php') {
$config = require $filename;
if (!is_array($config)) {
throw new InvalidArgumentException('PHP files must return an array of configuration data');
}
} else {
throw new InvalidArgumentException('Unknown file extension: ' . $filename);
}
// Merge include files into the configuration array
$this->mergeIncludes($config, dirname($filename));
return $config;
}
/**
* Merges in all include files
*
* @param array $config Config data that contains includes
* @param string $basePath Base path to use when a relative path is encountered
*
* @return array Returns the merged and included data
*/
protected function mergeIncludes(&$config, $basePath = null)
{
if (!empty($config['includes'])) {
foreach ($config['includes'] as &$path) {
// Account for relative paths
if ($path[0] != DIRECTORY_SEPARATOR && !isset($this->aliases[$path]) && $basePath) {
$path = "{$basePath}/{$path}";
}
$config = $this->mergeData($this->loadFile($path), $config);
}
}
}
/**
* Default implementation for merging two arrays of data (uses array_merge_recursive)
*
* @param array $a Original data
* @param array $b Data to merge into the original and overwrite existing values
*
* @return array
*/
protected function mergeData(array $a, array $b)
{
return array_merge_recursive($a, $b);
}
}

View File

@ -1,70 +0,0 @@
<?php
namespace Guzzle\Service;
/**
* Abstract factory used to delegate class instantiation and manages caching
*/
abstract class AbstractFactory
{
/**
* {@inheritdoc}
*/
public function build($config, array $options = null)
{
$adapter = null;
$cacheTtlKey = $this->getCacheTtlKey($config);
// Check if a cache was provided
if (isset($options['cache.adapter']) && is_string($config)) {
$adapter = $options['cache.adapter'];
$ttl = isset($options[$cacheTtlKey]) ? $options[$cacheTtlKey] : 3600;
$cacheKey = 'guzzle' . crc32($config);
// Check if the instantiated data is in the cache
if ($cached = $adapter->fetch($cacheKey)) {
return $cached;
}
}
// Get the name of the class to instantiate for the type of data
$factory = $this->getFactory($config);
if (!$factory || is_string($factory)) {
return $this->throwException($factory);
}
$result = $factory->build($config, $options);
if ($adapter) {
$adapter->save($cacheKey, $result, $ttl);
}
return $result;
}
/**
* Get the string used to hold cache TTL specific information for the factory
*
* @param mixed $config Config data being loaded
*
* @return string
*/
abstract protected function getCacheTtlKey($config);
/**
* Throw an exception when the abstract factory cannot instantiate anything
*
* @param string $message Message for the exception
*
* @return string
* @throws \Exception
*/
abstract protected function throwException($message = '');
/**
* Get a concrete factory based on the data provided
*
* @param mixed $config Data to use to determine the concrete factory
*
* @return mixed|string Returning a string will throw an exception with a specific message
*/
abstract protected function getFactory($config);
}

View File

@ -1,41 +0,0 @@
<?php
namespace Guzzle\Service\Builder;
use Guzzle\Service\JsonLoader;
/**
* Creates a ServiceBuilder using a JSON configuration file
*/
class JsonServiceBuilderFactory extends JsonLoader implements ServiceBuilderFactoryInterface
{
/**
* @var ArrayServiceBuilderFactory Factory used when building off of the parsed data
*/
protected $factory;
/**
* @param ServiceBuilderAbstractFactory $factory Factory used when building off of the parsed data
*/
public function __construct(ArrayServiceBuilderFactory $factory)
{
$this->factory = $factory;
}
/**
* {@inheritdoc}
*/
public function build($config, array $options = null)
{
return $this->factory->build($this->parseJsonFile($config), $options);
}
/**
* {@inheritdoc}
* Adds special handling for JSON configuration merging
*/
protected function mergeJson(array $jsonA, array $jsonB)
{
return ServiceBuilderAbstractFactory::combineConfigs($jsonA, $jsonB);
}
}

View File

@ -4,7 +4,6 @@ namespace Guzzle\Service\Builder;
use Guzzle\Common\AbstractHasDispatcher;
use Guzzle\Http\ClientInterface;
use Guzzle\Service\Builder\ServiceBuilderAbstractFactory;
use Guzzle\Service\Exception\ServiceBuilderException;
use Guzzle\Service\Exception\ServiceNotFoundException;
@ -24,7 +23,7 @@ class ServiceBuilder extends AbstractHasDispatcher implements ServiceBuilderInte
protected $clients = array();
/**
* @var ServiceBuilderAbstractFactory Cached instance of the abstract factory
* @var ServiceBuilderLoader Cached instance of the service builder loader
*/
protected static $cachedFactory;
@ -39,15 +38,15 @@ class ServiceBuilder extends AbstractHasDispatcher implements ServiceBuilderInte
* @throws ServiceBuilderException if a file cannot be opened
* @throws ServiceNotFoundException when trying to extend a missing client
*/
public static function factory($config = null, array $globalParameters = null)
public static function factory($config = null, array $globalParameters = array())
{
// @codeCoverageIgnoreStart
if (!static::$cachedFactory) {
static::$cachedFactory = new ServiceBuilderAbstractFactory();
static::$cachedFactory = new ServiceBuilderLoader();
}
// @codeCoverageIgnoreEnd
return self::$cachedFactory->build($config, $globalParameters);
return self::$cachedFactory->load($config, $globalParameters);
}
/**

View File

@ -1,118 +0,0 @@
<?php
namespace Guzzle\Service\Builder;
use Guzzle\Service\AbstractFactory;
use Guzzle\Service\Exception\ServiceBuilderException;
/**
* Abstract factory used to build service builders
*/
class ServiceBuilderAbstractFactory extends AbstractFactory implements ServiceBuilderFactoryInterface
{
/**
* @var array Pool of instantiated factories by name
*/
protected $factories = array();
/**
* Combines service builder configuration file arrays
*
* @param array $a Original data
* @param array $b Data to merge in to the original data
*
* @return array
*/
public static function combineConfigs(array $a, array $b)
{
$result = $b + $a;
// Merge services using a recursive union of arrays
if (isset($a['services']) && $b['services']) {
// Get a union of the services of the two arrays
$result['services'] = $b['services'] + $a['services'];
// Merge each service in using a union of the two arrays
foreach ($result['services'] as $name => &$service) {
// By default, services completely override a previously defined service unless it extends itself
if (isset($a['services'][$name]['extends'])
&& isset($b['services'][$name]['extends'])
&& $b['services'][$name]['extends'] == $name
) {
$service += $a['services'][$name];
// Use the `extends` attribute of the parent
$service['extends'] = $a['services'][$name]['extends'];
// Merge parameters using a union if both have paramters
if (isset($a['services'][$name]['params'])) {
$service['params'] += $a['services'][$name]['params'];
}
}
}
}
return $result;
}
/**
* Get an array factory
*
* @return ArrayServiceBuilderFactory
*/
public function getArrayFactory()
{
if (!isset($this->factories['array'])) {
$this->factories['array'] = new ArrayServiceBuilderFactory();
}
return $this->factories['array'];
}
/**
* Get a JSON factory
*
* @return JsonServiceBuilderFactory
*/
public function getJsonFactory()
{
if (!isset($this->factories['json'])) {
$this->factories['json'] = new JsonServiceBuilderFactory($this->getArrayFactory());
}
return $this->factories['json'];
}
/**
* {@inheritdoc}
*/
protected function getFactory($config)
{
if (is_array($config)) {
return $this->getArrayFactory();
} elseif (is_string($config)) {
$ext = pathinfo($config, PATHINFO_EXTENSION);
if ($ext == 'js' || $ext == 'json') {
return $this->getJsonFactory();
}
}
return 'Must pass the name of a .js or .json file or array';
}
/**
* {@inheritdoc}
*/
protected function getCacheTtlKey($config)
{
return 'cache.builder.ttl';
}
/**
* {@inheritdoc}
*/
protected function throwException($message = '')
{
throw new ServiceBuilderException($message ?: 'Unable to build service builder');
}
}

View File

@ -1,19 +0,0 @@
<?php
namespace Guzzle\Service\Builder;
/**
* Factory used to create {@see ServiceBuilderInterface} objects
*/
interface ServiceBuilderFactoryInterface
{
/**
* Builds a new service builder object
*
* @param mixed $config File, array, or data string to build from
* @param array $options (options) Options used when building
*
* @return ServiceBuilderInterface
*/
public function build($config, array $options = null);
}

View File

@ -2,18 +2,18 @@
namespace Guzzle\Service\Builder;
use Guzzle\Common\Exception\RuntimeException;
use Guzzle\Service\AbstractConfigLoader;
use Guzzle\Service\Exception\ServiceNotFoundException;
/**
* Creates a ServiceBuilder using an array of data
* Service builder config loader
*/
class ArrayServiceBuilderFactory implements ServiceBuilderFactoryInterface
class ServiceBuilderLoader extends AbstractConfigLoader
{
/**
* {@inheritdoc}
*/
public function build($config, array $options = null)
protected function build($config, array $options)
{
// A service builder class can be specified in the class field
$class = !empty($config['class']) ? $config['class'] : __NAMESPACE__ . '\\ServiceBuilder';
@ -37,12 +37,12 @@ class ArrayServiceBuilderFactory implements ServiceBuilderFactoryInterface
}
$extended = &$services[$service['extends']];
// Use the correct class attribute
if (empty($service['class'])) {
$service['class'] = isset($extended['class']) ? $extended['class'] : '';
}
$extendsParams = isset($extended['params']) ? $extended['params'] : false;
if ($extendsParams) {
if ($extendsParams = isset($extended['params']) ? $extended['params'] : false) {
$service['params'] = $service['params'] + $extendsParams;
}
}
@ -57,4 +57,39 @@ class ArrayServiceBuilderFactory implements ServiceBuilderFactoryInterface
return new $class($services);
}
/**
* {@inheritdoc}
*/
protected function mergeData(array $a, array $b)
{
$result = $b + $a;
// Merge services using a recursive union of arrays
if (isset($a['services']) && $b['services']) {
// Get a union of the services of the two arrays
$result['services'] = $b['services'] + $a['services'];
// Merge each service in using a union of the two arrays
foreach ($result['services'] as $name => &$service) {
// By default, services completely override a previously defined service unless it extends itself
if (isset($a['services'][$name]['extends'])
&& isset($b['services'][$name]['extends'])
&& $b['services'][$name]['extends'] == $name
) {
$service += $a['services'][$name];
// Use the `extends` attribute of the parent
$service['extends'] = $a['services'][$name]['extends'];
// Merge parameters using a union if both have parameters
if (isset($a['services'][$name]['params'])) {
$service['params'] += $a['services'][$name]['params'];
}
}
}
}
return $result;
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace Guzzle\Service;
use Guzzle\Cache\CacheAdapterInterface;
/**
* Decorator that adds caching to a service description loader
*/
class CachingConfigLoader implements ConfigLoaderInterface
{
/**
* @var ConfigLoaderInterface
*/
protected $loader;
/**
* @var CacheAdapterInterface
*/
protected $cache;
/**
* Add caching to a config loader
*
* @param ConfigLoaderInterface $loader Loader used to load the config when there is a cache miss
* @param CacheAdapterInterface $cache Object used to cache the loaded result
*/
public function __construct(ConfigLoaderInterface $loader, CacheAdapterInterface $cache)
{
$this->loader = $loader;
$this->cache = $cache;
}
/**
* {@inheritdoc}
*/
public function load($config, array $options = array())
{
if (is_string($config)) {
$key = 'loader_' . crc32($config);
if ($result = $this->cache->fetch($key)) {
return $result;
}
} else {
$key = false;
}
$result = $this->loader->load($config, $options);
if ($key) {
$this->cache->save($key, $result);
}
return $result;
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace Guzzle\Service;
/**
* Interface used for loading configuration data (service descriptions, service builder configs, etc)
*
* If a loaded configuration data sets includes a top level key containing an 'includes' section, then the data in the
* file will extend the merged result of all of the included config files.
*/
interface ConfigLoaderInterface
{
/**
* Loads configuration data and returns an array of the loaded result
*
* @param mixed $config Data to load (filename or array of data)
* @param array $options Array of options to use when loading
*
* @return mixed
*/
public function load($config, array $options = array());
}

View File

@ -1,28 +0,0 @@
<?php
namespace Guzzle\Service\Description;
use Guzzle\Service\JsonLoader;
/**
* Build service descriptions using a JSON document
*/
class JsonDescriptionBuilder implements DescriptionBuilderInterface
{
/**
* @var JsonLoader
*/
protected $loader;
/**
* {@inheritdoc}
*/
public function build($config, array $options = null)
{
if (!$this->loader) {
$this->loader = new JsonLoader();
}
return ServiceDescription::factory($this->loader->parseJsonFile($config));
}
}

View File

@ -38,24 +38,24 @@ class ServiceDescription implements ServiceDescriptionInterface
protected $extraData = array();
/**
* @var ServiceDescriptionFactoryInterface Factory used in factory method
* @var ServiceDescriptionLoader Factory used in factory method
*/
protected static $descriptionFactory;
protected static $descriptionLoader;
/**
* {@inheritdoc}
* @param string|array $config File to build or array of operation information
* @param array $options Service description factory options
*/
public static function factory($config, array $options = null)
public static function factory($config, array $options = array())
{
// @codeCoverageIgnoreStart
if (!self::$descriptionFactory) {
self::$descriptionFactory = new ServiceDescriptionAbstractFactory();
if (!self::$descriptionLoader) {
self::$descriptionLoader = new ServiceDescriptionLoader();
}
// @codeCoverageIgnoreEnd
return self::$descriptionFactory->build($config, $options);
return self::$descriptionLoader->load($config, $options);
}
/**

View File

@ -1,43 +0,0 @@
<?php
namespace Guzzle\Service\Description;
use Guzzle\Service\AbstractFactory;
use Guzzle\Service\Exception\DescriptionBuilderException;
/**
* Abstract factory used to build service descriptions
*/
class ServiceDescriptionAbstractFactory extends AbstractFactory implements ServiceDescriptionFactoryInterface
{
/**
* {@inheritdoc}
*/
protected function getCacheTtlKey($config)
{
return 'cache.description.ttl';
}
/**
* {@inheritdoc}
*/
protected function throwException($message = '')
{
throw new DescriptionBuilderException($message ?: 'Unable to load service description due to unknown file extension');
}
/**
* {@inheritdoc}
*/
protected function getFactory($config)
{
if (is_array($config)) {
return new ArrayDescriptionBuilder();
} else {
$ext = pathinfo($config, PATHINFO_EXTENSION);
if ($ext == 'js' || $ext == 'json') {
return new JsonDescriptionBuilder();
}
}
}
}

View File

@ -1,23 +0,0 @@
<?php
namespace Guzzle\Service\Description;
use Guzzle\Service\Exception\DescriptionBuilderException;
/**
* A ServiceDescription factory interface
*/
interface ServiceDescriptionFactoryInterface
{
/**
* Create a {@see ServiceDescriptionInterface} object
*
* @param string|array $config File to build or array of command information
* @param array $options Factory configuration options.
* - cache.adapter: CacheAdapterInterface used for caching descriptions
* - cache.description.ttl: TTL for caching built service descriptions
*
* @throws DescriptionBuilderException when the type is not recognized
*/
public function build($config, array $options = null);
}

View File

@ -2,17 +2,18 @@
namespace Guzzle\Service\Description;
use Guzzle\Service\AbstractConfigLoader;
use Guzzle\Service\Exception\DescriptionBuilderException;
/**
* Build service descriptions using an array of configuration data
* Loader for service descriptions
*/
class ArrayDescriptionBuilder implements DescriptionBuilderInterface
class ServiceDescriptionLoader extends AbstractConfigLoader
{
/**
* {@inheritdoc}
*/
public function build($config, array $options = null)
protected function build($config, array $options)
{
$operations = array();

View File

@ -1,83 +0,0 @@
<?php
namespace Guzzle\Service;
use Guzzle\Service\Exception\JsonException;
/**
* Used to load JSON files that have an "includes" array. Each file in the array is then loaded and merged.
*/
class JsonLoader
{
/**
* @var array Aliases that will be replaces by an actual filename
*/
protected $aliases = array();
/**
* Add an include alias to the loader
*
* @param string $filename Filename to alias (e.g. _foo)
* @param string $alias Actual file to use (e.g. /path/to/foo.json)
*
* @return self
*/
public function addAlias($filename, $alias)
{
$this->aliases[$filename] = $alias;
return $this;
}
/**
* Loads a JSON file and includes any files in the "includes" array
*
* @param string $jsonFile File to load
*
* @return array
* @throws JsonException if unable to open the file or if there is a parsing error
*/
public function parseJsonFile($jsonFile)
{
// Use the registered alias if one matches the file
if (isset($this->aliases[$jsonFile])) {
$jsonFile = $this->aliases[$jsonFile];
}
// Ensure that the file can be opened for reading
if (!is_readable($jsonFile)) {
throw new JsonException("Unable to open {$jsonFile} for reading");
}
$data = json_decode(file_get_contents($jsonFile), true);
// Throw an exception if there was an error loading the file
if ($error = json_last_error()) {
throw new JsonException("Error loading JSON data from {$jsonFile}: {$error}");
}
// Handle includes
if (!empty($data['includes'])) {
foreach ($data['includes'] as $path) {
if ($path[0] != DIRECTORY_SEPARATOR && !isset($this->aliases[$path])) {
$path = dirname($jsonFile) . DIRECTORY_SEPARATOR . $path;
}
$data = $this->mergeJson($this->parseJsonFile($path), $data);
}
}
return $data;
}
/**
* Default implementation for merging two JSON files (uses array_merge_recursive)
*
* @param array $a Original JSON data
* @param array $b JSON data to merge into the original and overwrite existing values
*
* @return array
*/
protected function mergeJson(array $a, array $b)
{
return array_merge_recursive($a, $b);
}
}

View File

@ -0,0 +1,128 @@
<?php
namespace Guzzle\Tests\Service;
/**
* @covers Guzzle\Service\AbstractConfigLoader
*/
class AbstractConfigLoaderTest extends \Guzzle\Tests\GuzzleTestCase
{
/**
* @var \Guzzle\Service\AbstractConfigLoader
*/
protected $loader;
/**
* @var array Any files that need to be deleted on tear down
*/
protected $cleanup = array();
public function setUp()
{
$this->loader = $this->getMockBuilder('Guzzle\Service\AbstractConfigLoader')
->setMethods(array('build'))
->getMockForAbstractClass();
}
public function tearDown()
{
foreach ($this->cleanup as $file) {
unlink($file);
}
}
/**
* @expectedException Guzzle\Common\Exception\InvalidArgumentException
*/
public function testOnlyLoadsSupportedTypes()
{
$this->loader->load(new \stdClass());
}
/**
* @expectedException Guzzle\Common\Exception\InvalidArgumentException
* @expectedExceptionMessage Unable to open fooooooo! for reading
*/
public function testFileMustBeReadable()
{
$this->loader->load('fooooooo!');
}
/**
* @expectedException Guzzle\Common\Exception\InvalidArgumentException
* @expectedExceptionMessage Unknown file extension
*/
public function testMustBeSupportedExtension()
{
$this->loader->load(dirname(__DIR__) . '/TestData/FileBody.txt');
}
/**
* @expectedException Guzzle\Service\Exception\JsonException
* @expectedExceptionMessage Error loading JSON data from
*/
public function testJsonMustBeValue()
{
$filename = tempnam(sys_get_temp_dir(), 'json') . '.json';
file_put_contents($filename, '{/{./{}foo');
$this->cleanup[] = $filename;
$this->loader->load($filename);
}
/**
* @expectedException Guzzle\Common\Exception\InvalidArgumentException
* @expectedExceptionMessage PHP files must return an array
*/
public function testPhpFilesMustReturnAnArray()
{
$filename = tempnam(sys_get_temp_dir(), 'php') . '.php';
file_put_contents($filename, '<?php $fdr = false;');
$this->cleanup[] = $filename;
$this->loader->load($filename);
}
public function testLoadsPhpFileIncludes()
{
$filename = tempnam(sys_get_temp_dir(), 'php') . '.php';
file_put_contents($filename, '<?php return array("foo" => "bar");');
$this->cleanup[] = $filename;
$this->loader->expects($this->exactly(1))->method('build')->will($this->returnArgument(0));
$config = $this->loader->load($filename);
$this->assertEquals(array('foo' => 'bar'), $config);
}
public function testCanCreateFromJson()
{
$file = dirname(__DIR__) . '/TestData/services/json1.json';
// The build method will just return the config data
$this->loader->expects($this->exactly(1))->method('build')->will($this->returnArgument(0));
$data = $this->loader->load($file);
// Ensure that the config files were merged using the includes directives
$this->assertArrayHasKey('includes', $data);
$this->assertArrayHasKey('services', $data);
$this->assertInternalType('array', $data['services']['foo']);
$this->assertInternalType('array', $data['services']['abstract']);
$this->assertInternalType('array', $data['services']['mock']);
$this->assertEquals('bar', $data['services']['foo']['params']['baz']);
}
public function testUsesAliases()
{
$file = dirname(__DIR__) . '/TestData/services/json1.json';
$this->loader->addAlias('foo', $file);
// The build method will just return the config data
$this->loader->expects($this->exactly(1))->method('build')->will($this->returnArgument(0));
$data = $this->loader->load('foo');
$this->assertEquals('bar', $data['services']['foo']['params']['baz']);
}
public function testCanLoadArraysWithIncludes()
{
$file = dirname(__DIR__) . '/TestData/services/json1.json';
$config = array('includes' => array($file));
// The build method will just return the config data
$this->loader->expects($this->exactly(1))->method('build')->will($this->returnArgument(0));
$data = $this->loader->load($config);
$this->assertEquals('bar', $data['services']['foo']['params']['baz']);
}
}

View File

@ -1,64 +0,0 @@
<?php
namespace Guzzle\Tests\Service;
use Guzzle\Cache\DoctrineCacheAdapter;
use Guzzle\Service\AbstractFactory;
use Guzzle\Service\Builder\JsonServiceBuilderFactory;
use Guzzle\Service\Exception\ServiceBuilderException;
use Guzzle\Service\Builder\ArrayServiceBuilderFactory;
use Doctrine\Common\Cache\ArrayCache;
/**
* @covers Guzzle\Service\AbstractFactory
*/
class AbstractFactoryTest extends \Guzzle\Tests\GuzzleTestCase
{
protected function getFactory()
{
return $this->getMockBuilder('Guzzle\Service\AbstractFactory')
->setMethods(array('getCacheTtlKey', 'throwException', 'getFactory'))
->getMockForAbstractClass();
}
public function testCachesArtifacts()
{
$jsonFile = __DIR__ . '/../TestData/test_service.json';
$adapter = new DoctrineCacheAdapter(new ArrayCache());
$factory = $this->getFactory();
$factory->expects($this->once())
->method('getFactory')
->will($this->returnValue(new JsonServiceBuilderFactory(new ArrayServiceBuilderFactory())));
// Create a service and add it to the cache
$service = $factory->build($jsonFile, array(
'cache.adapter' => $adapter
));
// Ensure the cache key was set
$this->assertTrue($adapter->contains('guzzle' . crc32($jsonFile)));
// Grab the service from the cache
$this->assertEquals($service, $factory->build($jsonFile, array(
'cache.adapter' => $adapter
)));
}
/**
* @expectedException Guzzle\Service\Exception\ServiceBuilderException
*/
public function testThrowsExceptionsWhenNoFactoryResolves()
{
$factory = $this->getFactory();
$factory->expects($this->any())
->method('getFactory')
->will($this->returnValue(false));
$factory->expects($this->any())
->method('throwException')
->will($this->throwException(new ServiceBuilderException()));
$service = $factory->build('foo');
}
}

View File

@ -1,107 +0,0 @@
<?php
namespace Guzzle\Tests\Service\Builder;
use Guzzle\Service\Builder\ArrayServiceBuilderFactory;
/**
* @covers Guzzle\Service\Builder\ArrayServiceBuilderFactory
*/
class ArrayServiceBuilderFactoryTest extends \Guzzle\Tests\GuzzleTestCase
{
public function testBuildsServiceBuilders()
{
$arrayFactory = new ArrayServiceBuilderFactory();
$data = array(
'services' => array(
'abstract' => array(
'params' => array(
'access_key' => 'xyz',
'secret' => 'abc',
),
),
'foo' => array(
'extends' => 'abstract',
'params' => array(
'baz' => 'bar',
),
),
'mock' => array(
'extends' => 'abstract',
'params' => array(
'username' => 'foo',
'password' => 'baz',
'subdomain' => 'bar',
)
)
)
);
$builder = $arrayFactory->build($data);
// Ensure that services were parsed
$this->assertTrue(isset($builder['mock']));
$this->assertTrue(isset($builder['abstract']));
$this->assertTrue(isset($builder['foo']));
$this->assertFalse(isset($builder['jimmy']));
}
/**
* @expectedException Guzzle\Service\Exception\ServiceNotFoundException
* @expectedExceptionMessage foo is trying to extend a non-existent service: abstract
*/
public function testThrowsExceptionWhenExtendingNonExistentService()
{
$arrayFactory = new ArrayServiceBuilderFactory();
$data = array(
'services' => array(
'foo' => array(
'extends' => 'abstract'
)
)
);
$builder = $arrayFactory->build($data);
}
public function testAllowsGlobalParameterOverrides()
{
$arrayFactory = new ArrayServiceBuilderFactory();
$data = array(
'services' => array(
'foo' => array(
'params' => array(
'foo' => 'baz',
'bar' => 'boo'
)
)
)
);
$builder = $arrayFactory->build($data, array(
'bar' => 'jar',
'far' => 'car'
));
$compiled = json_decode($builder->serialize(), true);
$this->assertEquals(array(
'foo' => 'baz',
'bar' => 'jar',
'far' => 'car'
), $compiled['foo']['params']);
}
public function tstDoesNotErrorOnCircularReferences()
{
$arrayFactory = new ArrayServiceBuilderFactory();
$arrayFactory->build(array(
'services' => array(
'too' => array('extends' => 'ball'),
'ball' => array('extends' => 'too'),
)
));
}
}

View File

@ -1,86 +0,0 @@
<?php
namespace Guzzle\Tests\Service\Builder;
use Guzzle\Service\Builder\ArrayServiceBuilderFactory;
use Guzzle\Service\Builder\ServiceBuilder;
use Guzzle\Service\Builder\JsonServiceBuilderFactory;
/**
* @covers Guzzle\Service\Builder\JsonServiceBuilderFactory
* @covers Guzzle\Service\Builder\ArrayServiceBuilderFactory
*/
class JsonServiceBuilderFactoryTest extends \Guzzle\Tests\GuzzleTestCase
{
public function testBuildsServiceBuilders()
{
$j = new JsonServiceBuilderFactory(new ArrayServiceBuilderFactory());
$file = __DIR__ . '/../../TestData/services/json1.json';
// Initial build
$builder = $j->build($file);
// Build it again, get a similar result using the same JsonLoader
$this->assertEquals($builder, $j->build($file));
// Ensure that services were parsed
$this->assertTrue(isset($builder['mock']));
$this->assertTrue(isset($builder['abstract']));
$this->assertTrue(isset($builder['foo']));
$this->assertFalse(isset($builder['jimmy']));
}
public function testServicesCanBeExtendedWithIncludes()
{
$data = array(
'services' => array(
'foo' => array(
'class' => 'stdClass',
'params' => array('baz' => 'bar')
),
'bar' => array(
'extends' => 'foo',
'params' => array(
'test' => '123',
'ext' => 'abc'
)
)
)
);
$file1 = tempnam(sys_get_temp_dir(), 'service_1') . '.json';
file_put_contents($file1, json_encode($data));
$data = array(
'includes' => array($file1),
'services' => array(
'bar' => array(
'extends' => 'bar',
'params' => array(
'test' => '456'
)
)
)
);
$file2 = tempnam(sys_get_temp_dir(), 'service_2') . '.json';
file_put_contents($file2, json_encode($data));
$builder = ServiceBuilder::factory($file2);
unlink($file1);
unlink($file2);
$this->assertEquals(array(
'bar' => array(
'class' => 'stdClass',
'extends' => 'foo',
'params' => array(
'test' => '456',
'baz' => 'bar',
'ext' => 'abc'
)
),
'foo' => array(
'class' => 'stdClass',
'params' => array('baz' => 'bar')
)
), $this->readAttribute($builder, 'builderConfig'));
}
}

View File

@ -1,111 +0,0 @@
<?php
namespace Guzzle\Tests\Service\Builder;
use Guzzle\Service\Builder\ServiceBuilderAbstractFactory;
/**
* @covers Guzzle\Service\Builder\ServiceBuilderAbstractFactory
*/
class ServiceBuilderAbstractFactoryTest extends \Guzzle\Tests\GuzzleTestCase
{
protected $jsonFile;
public function setup()
{
$this->jsonFile = __DIR__ . '/../../TestData/services/json1.json';
}
public function testFactoryDelegatesToConcreteFactories()
{
$factory = new ServiceBuilderAbstractFactory();
$this->assertInstanceOf('Guzzle\Service\Builder\ServiceBuilder', $factory->build($this->jsonFile));
}
/**
* @expectedException Guzzle\Service\Exception\ServiceBuilderException
* @expectedExceptionMessage Must pass the name of a .js or .json file or array
*/
public function testThrowsExceptionWhenInvalidFileExtensionIsPassed()
{
$factory = new ServiceBuilderAbstractFactory();
$factory->build(__FILE__);
}
/**
* @expectedException Guzzle\Service\Exception\ServiceBuilderException
* @expectedExceptionMessage Must pass the name of a .js or .json file or array
*/
public function testThrowsExceptionWhenUnknownTypeIsPassed()
{
$factory = new ServiceBuilderAbstractFactory();
$factory->build(new \stdClass());
}
public function configProvider()
{
$foo = array(
'extends' => 'bar',
'class' => 'stdClass',
'params' => array('a' => 'test', 'b' => '456')
);
return array(
array(
// Does not extend the existing `foo` service but overwrites it
array(
'services' => array(
'foo' => $foo,
'bar' => array('params' => array('baz' => '123'))
)
),
array(
'services' => array(
'foo' => array('class' => 'Baz')
)
),
array(
'services' => array(
'foo' => array('class' => 'Baz'),
'bar' => array('params' => array('baz' => '123'))
)
)
),
array(
// Extends the existing `foo` service
array(
'services' => array(
'foo' => $foo,
'bar' => array('params' => array('baz' => '123'))
)
),
array(
'services' => array(
'foo' => array(
'extends' => 'foo',
'params' => array('b' => '123', 'c' => 'def')
)
)
),
array(
'services' => array(
'foo' => array(
'extends' => 'bar',
'class' => 'stdClass',
'params' => array('a' => 'test', 'b' => '123', 'c' => 'def')
),
'bar' => array('params' => array('baz' => '123'))
)
)
)
);
}
/**
* @dataProvider configProvider
*/
public function testCombinesConfigs($a, $b, $c)
{
$this->assertEquals($c, ServiceBuilderAbstractFactory::combineConfigs($a, $b));
}
}

View File

@ -0,0 +1,177 @@
<?php
namespace Guzzle\Tests\Service\Builder;
use Guzzle\Service\Builder\ServiceBuilderLoader;
/**
* @covers Guzzle\Service\Builder\ServiceBuilderLoader
*/
class ServiceBuilderLoaderTest extends \Guzzle\Tests\GuzzleTestCase
{
public function testBuildsServiceBuilders()
{
$arrayFactory = new ServiceBuilderLoader();
$data = array(
'services' => array(
'abstract' => array(
'params' => array(
'access_key' => 'xyz',
'secret' => 'abc',
),
),
'foo' => array(
'extends' => 'abstract',
'params' => array(
'baz' => 'bar',
),
),
'mock' => array(
'extends' => 'abstract',
'params' => array(
'username' => 'foo',
'password' => 'baz',
'subdomain' => 'bar',
)
)
)
);
$builder = $arrayFactory->load($data);
// Ensure that services were parsed
$this->assertTrue(isset($builder['mock']));
$this->assertTrue(isset($builder['abstract']));
$this->assertTrue(isset($builder['foo']));
$this->assertFalse(isset($builder['jimmy']));
}
/**
* @expectedException Guzzle\Service\Exception\ServiceNotFoundException
* @expectedExceptionMessage foo is trying to extend a non-existent service: abstract
*/
public function testThrowsExceptionWhenExtendingNonExistentService()
{
$arrayFactory = new ServiceBuilderLoader();
$data = array(
'services' => array(
'foo' => array(
'extends' => 'abstract'
)
)
);
$builder = $arrayFactory->load($data);
}
public function testAllowsGlobalParameterOverrides()
{
$arrayFactory = new ServiceBuilderLoader();
$data = array(
'services' => array(
'foo' => array(
'params' => array(
'foo' => 'baz',
'bar' => 'boo'
)
)
)
);
$builder = $arrayFactory->load($data, array(
'bar' => 'jar',
'far' => 'car'
));
$compiled = json_decode($builder->serialize(), true);
$this->assertEquals(array(
'foo' => 'baz',
'bar' => 'jar',
'far' => 'car'
), $compiled['foo']['params']);
}
public function tstDoesNotErrorOnCircularReferences()
{
$arrayFactory = new ServiceBuilderLoader();
$arrayFactory->load(array(
'services' => array(
'too' => array('extends' => 'ball'),
'ball' => array('extends' => 'too'),
)
));
}
public function configProvider()
{
$foo = array(
'extends' => 'bar',
'class' => 'stdClass',
'params' => array('a' => 'test', 'b' => '456')
);
return array(
array(
// Does not extend the existing `foo` service but overwrites it
array(
'services' => array(
'foo' => $foo,
'bar' => array('params' => array('baz' => '123'))
)
),
array(
'services' => array(
'foo' => array('class' => 'Baz')
)
),
array(
'services' => array(
'foo' => array('class' => 'Baz'),
'bar' => array('params' => array('baz' => '123'))
)
)
),
array(
// Extends the existing `foo` service
array(
'services' => array(
'foo' => $foo,
'bar' => array('params' => array('baz' => '123'))
)
),
array(
'services' => array(
'foo' => array(
'extends' => 'foo',
'params' => array('b' => '123', 'c' => 'def')
)
)
),
array(
'services' => array(
'foo' => array(
'extends' => 'bar',
'class' => 'stdClass',
'params' => array('a' => 'test', 'b' => '123', 'c' => 'def')
),
'bar' => array('params' => array('baz' => '123'))
)
)
)
);
}
/**
* @dataProvider configProvider
*/
public function testCombinesConfigs($a, $b, $c)
{
$l = new ServiceBuilderLoader();
$m = new \ReflectionMethod($l, 'mergeData');
$m->setAccessible(true);
$this->assertEquals($c, $m->invoke($l, $a, $b));
}
}

View File

@ -8,6 +8,9 @@ use Guzzle\Service\Client;
use Guzzle\Service\Exception\ServiceNotFoundException;
use Doctrine\Common\Cache\ArrayCache;
/**
* @covers Guzzle\Service\Builder\ServiceBuilder
*/
class ServiceBuilderTest extends \Guzzle\Tests\GuzzleTestCase
{
protected $arrayData = array(
@ -54,10 +57,6 @@ class ServiceBuilderTest extends \Guzzle\Tests\GuzzleTestCase
)
);
/**
* @covers Guzzle\Service\Builder\ServiceBuilder::serialize
* @covers Guzzle\Service\Builder\ServiceBuilder::unserialize
*/
public function testAllowsSerialization()
{
$builder = ServiceBuilder::factory($this->arrayData);
@ -65,9 +64,6 @@ class ServiceBuilderTest extends \Guzzle\Tests\GuzzleTestCase
$this->assertEquals($cached, $builder);
}
/**
* @covers Guzzle\Service\Builder\ServiceBuilder::factory
*/
public function testDelegatesFactoryMethodToAbstractFactory()
{
$builder = ServiceBuilder::factory($this->arrayData);
@ -76,7 +72,6 @@ class ServiceBuilderTest extends \Guzzle\Tests\GuzzleTestCase
}
/**
* @covers Guzzle\Service\Builder\ServiceBuilder::get
* @expectedException Guzzle\Service\Exception\ServiceNotFoundException
* @expectedExceptionMessage No service is registered as foobar
*/
@ -85,9 +80,6 @@ class ServiceBuilderTest extends \Guzzle\Tests\GuzzleTestCase
ServiceBuilder::factory($this->arrayData)->get('foobar');
}
/**
* @covers Guzzle\Service\Builder\ServiceBuilder::get
*/
public function testStoresClientCopy()
{
$builder = ServiceBuilder::factory($this->arrayData);
@ -114,9 +106,6 @@ class ServiceBuilderTest extends \Guzzle\Tests\GuzzleTestCase
$this->assertFalse($client2 === $builder->get('billy.mock'));
}
/**
* @covers Guzzle\Service\Builder\ServiceBuilder
*/
public function testBuildersPassOptionsThroughToClients()
{
$s = new ServiceBuilder(array(
@ -136,9 +125,6 @@ class ServiceBuilderTest extends \Guzzle\Tests\GuzzleTestCase
$this->assertEquals(8080, $c->getConfig('curl.curlopt_proxyport'));
}
/**
* @covers Guzzle\Service\Builder\ServiceBuilder
*/
public function testUsesTheDefaultBuilderWhenNoBuilderIsSpecified()
{
$s = new ServiceBuilder(array(
@ -158,13 +144,6 @@ class ServiceBuilderTest extends \Guzzle\Tests\GuzzleTestCase
$this->assertInstanceOf('Guzzle\\Tests\\Service\\Mock\\MockClient', $c);
}
/**
* @covers Guzzle\Service\Builder\ServiceBuilder::set
* @covers Guzzle\Service\Builder\ServiceBuilder::offsetSet
* @covers Guzzle\Service\Builder\ServiceBuilder::offsetGet
* @covers Guzzle\Service\Builder\ServiceBuilder::offsetUnset
* @covers Guzzle\Service\Builder\ServiceBuilder::offsetExists
*/
public function testUsedAsArray()
{
$b = ServiceBuilder::factory($this->arrayData);
@ -179,9 +158,6 @@ class ServiceBuilderTest extends \Guzzle\Tests\GuzzleTestCase
$this->assertInstanceOf('Guzzle\\Service\\Client', $b['michael.mock']);
}
/**
* @covers Guzzle\Service\Builder\ServiceBuilder::factory
*/
public function testFactoryCanCreateFromJson()
{
$tmp = sys_get_temp_dir() . '/test.js';
@ -193,9 +169,6 @@ class ServiceBuilderTest extends \Guzzle\Tests\GuzzleTestCase
$this->assertEquals('billy', $s->getConfig('username'));
}
/**
* @covers Guzzle\Service\Builder\ServiceBuilder::factory
*/
public function testFactoryCanCreateFromArray()
{
$b = ServiceBuilder::factory($this->arrayData);
@ -204,36 +177,6 @@ class ServiceBuilderTest extends \Guzzle\Tests\GuzzleTestCase
$this->assertEquals('billy', $s->getConfig('username'));
}
/**
* @covers Guzzle\Service\Builder\ServiceBuilder::factory
* @expectedException Guzzle\Service\Exception\ServiceBuilderException
* @expectedExceptionMessage Must pass the name of a .js or .json file or array
*/
public function testFactoryValidatesFileExtension()
{
$tmp = sys_get_temp_dir() . '/test.abc';
file_put_contents($tmp, 'data');
try {
ServiceBuilder::factory($tmp);
} catch (\RuntimeException $e) {
unlink($tmp);
throw $e;
}
}
/**
* @covers Guzzle\Service\Builder\ServiceBuilder::factory
* @expectedException Guzzle\Service\Exception\ServiceBuilderException
* @expectedExceptionMessage Must pass the name of a .js or .json file or array
*/
public function testFactoryValidatesObjectTypes()
{
ServiceBuilder::factory(new \stdClass());
}
/**
* @covers Guzzle\Service\Builder\ServiceBuilder::factory
*/
public function testFactoryDoesNotRequireParams()
{
$b = ServiceBuilder::factory($this->arrayData);
@ -241,9 +184,6 @@ class ServiceBuilderTest extends \Guzzle\Tests\GuzzleTestCase
$this->assertEquals('billy', $s->getConfig('username'));
}
/**
* @covers Guzzle\Service\Builder\ServiceBuilder
*/
public function testBuilderAllowsReferencesBetweenClients()
{
$builder = ServiceBuilder::factory(array(
@ -272,10 +212,6 @@ class ServiceBuilderTest extends \Guzzle\Tests\GuzzleTestCase
$this->assertEquals('1', $builder['b']->getConfig('username'));
}
/**
* @covers Guzzle\Service\Builder\ServiceBuilder::getAllEvents
* @covers Guzzle\Service\Builder\ServiceBuilder::get
*/
public function testEmitsEventsWhenClientsAreCreated()
{
// Ensure that the client signals that it emits an event
@ -307,9 +243,6 @@ class ServiceBuilderTest extends \Guzzle\Tests\GuzzleTestCase
$this->assertInstanceOf('Guzzle\Tests\Service\Mock\MockClient', $client);
}
/**
* @covers Guzzle\Service\Builder\ServiceBuilder::factory
*/
public function testCanAddGlobalParametersToServicesOnLoad()
{
$builder = ServiceBuilder::factory($this->arrayData, array(
@ -325,17 +258,6 @@ class ServiceBuilderTest extends \Guzzle\Tests\GuzzleTestCase
}
}
public function testDescriptionIsCacheable()
{
$jsonFile = __DIR__ . '/../../TestData/test_service.json';
$adapter = new DoctrineCacheAdapter(new ArrayCache());
$builder = ServiceBuilder::factory($jsonFile, array('cache.adapter' => $adapter));
// Ensure the cache key was set
$this->assertTrue($adapter->contains('guzzle' . crc32($jsonFile)));
// Grab the service from the cache
$this->assertEquals($builder, ServiceBuilder::factory($jsonFile, array('cache.adapter' => $adapter)));
}
public function testCacheServiceCanBeCreatedAndInjectedIntoOtherServices()
{
$builder = ServiceBuilder::factory($this->arrayData);

View File

@ -0,0 +1,43 @@
<?php
namespace Guzzle\Tests\Service;
use Guzzle\Cache\DoctrineCacheAdapter;
use Guzzle\Service\CachingConfigLoader;
use Doctrine\Common\Cache\ArrayCache;
/**
* @covers Guzzle\Service\CachingConfigLoader
*/
class CachingConfigLoaderTest extends \Guzzle\Tests\GuzzleTestCase
{
public function testLoadsPhpFileIncludes()
{
$cache = new DoctrineCacheAdapter(new ArrayCache());
$loader = $this->getMockBuilder('Guzzle\Service\ConfigLoaderInterface')
->setMethods(array('load'))
->getMockForAbstractClass();
$data = array('foo' => 'bar');
$loader->expects($this->once())
->method('load')
->will($this->returnValue($data));
$cache = new CachingConfigLoader($loader, $cache);
$this->assertEquals($data, $cache->load('foo'));
$this->assertEquals($data, $cache->load('foo'));
}
public function testDoesNotCacheArrays()
{
$cache = new DoctrineCacheAdapter(new ArrayCache());
$loader = $this->getMockBuilder('Guzzle\Service\ConfigLoaderInterface')
->setMethods(array('load'))
->getMockForAbstractClass();
$data = array('foo' => 'bar');
$loader->expects($this->exactly(2))
->method('load')
->will($this->returnValue($data));
$cache = new CachingConfigLoader($loader, $cache);
$this->assertEquals($data, $cache->load(array()));
$this->assertEquals($data, $cache->load(array()));
}
}

View File

@ -410,6 +410,16 @@ class CommandTest extends AbstractCommandTest
$command->prepare();
}
public function testValidatorUpdatesCommand()
{
$command = new MockCommand(array('test' => 123, 'foo' => 'bar'));
$command->setClient(new \Guzzle\Service\Client());
$command->prepare();
$this->assertEquals(123, $command->get('test'));
$this->assertEquals('abc', $command->get('_internal'));
$this->assertEquals('BAR', $command->get('foo'));
}
/**
* @expectedException Guzzle\Service\Exception\ValidationException
* @expectedExceptionMessage [Foo] Baz

View File

@ -1,31 +0,0 @@
<?php
namespace Guzzle\Tests\Service\Description;
use Guzzle\Service\Description\JsonDescriptionBuilder;
/**
* @covers Guzzle\Service\Description\JsonDescriptionBuilder
*/
class JsonDescriptionBuilderTest extends \Guzzle\Tests\GuzzleTestCase
{
/**
* @expectedException Guzzle\Service\Exception\JsonException
*/
public function testThrowsErrorsOnOpenFailure()
{
$j = new JsonDescriptionBuilder();
$b = @$j->build('/foo.does.not.exist');
}
public function testBuildsServiceDescriptions()
{
$j = new JsonDescriptionBuilder();
$description = $j->build(__DIR__ . '/../../TestData/test_service.json');
$this->assertTrue($description->hasOperation('test'));
$test = $description->getOperation('test');
$this->assertEquals('/path', $test->getUri());
$test = $description->getOperation('concrete');
$this->assertEquals('/abstract', $test->getUri());
}
}

View File

@ -260,12 +260,13 @@ class OperationTest extends \Guzzle\Tests\GuzzleTestCase
public function testHasResponseType()
{
$o = new Operation();
$this->assertEquals('primitive', $o->getResponseType());
$this->assertEquals('model', $o->setResponseType('model')->getResponseType());
// infers in the constructor
$o = new Operation(array('responseClass' => 'array'));
$this->assertEquals('primitive', $o->getResponseType());
// Infers when set
$o = new Operation();
$this->assertEquals('primitive', $o->getResponseType());
$this->assertEquals('model', $o->setResponseType('model')->getResponseType());
}
/**

View File

@ -1,29 +0,0 @@
<?php
namespace Guzzle\Tests\Service\Description;
use Guzzle\Service\Description\ServiceDescriptionAbstractFactory;
/**
* @covers Guzzle\Service\Description\ServiceDescriptionAbstractFactory
*/
class ServiceDescriptionAbstractFactoryTest extends \Guzzle\Tests\GuzzleTestCase
{
public function testFactoryDelegatesToConcreteFactories()
{
$factory = new ServiceDescriptionAbstractFactory();
$this->assertInstanceOf(
'Guzzle\Service\Description\ServiceDescription',
$factory->build(__DIR__ . '/../../TestData/test_service.json')
);
}
/**
* @expectedException Guzzle\Service\Exception\DescriptionBuilderException
*/
public function testFactoryEnsuresItCanHandleTheTypeOfFileOrArray()
{
$factory = new ServiceDescriptionAbstractFactory();
$factory->build('jarJarBinks');
}
}

View File

@ -3,17 +3,13 @@
namespace Guzzle\Tests\Service\Description;
use Guzzle\Service\Description\ServiceDescription;
use Guzzle\Service\Description\ArrayDescriptionBuilder;
use Guzzle\Service\Description\ServiceDescriptionLoader;
/**
* @covers Guzzle\Service\Description\ArrayDescriptionBuilder
* @covers Guzzle\Service\Description\ServiceDescriptionLoader
*/
class ArrayDescriptionBuilderTest extends \Guzzle\Tests\GuzzleTestCase
class ServiceDescriptionLoaderTest extends \Guzzle\Tests\GuzzleTestCase
{
/**
* @covers Guzzle\Service\Description\ServiceDescription::factory
* @covers Guzzle\Service\Description\ArrayDescriptionBuilder::build
*/
public function testAllowsDeepNestedInheritance()
{
$d = ServiceDescription::factory(array(
@ -39,8 +35,6 @@ class ArrayDescriptionBuilderTest extends \Guzzle\Tests\GuzzleTestCase
}
/**
* @covers Guzzle\Service\Description\ServiceDescription::factory
* @covers Guzzle\Service\Description\ArrayDescriptionBuilder::build
* @expectedException RuntimeException
*/
public function testThrowsExceptionWhenExtendingMissingCommand()

View File

@ -6,6 +6,9 @@ use Guzzle\Service\Description\ServiceDescription;
use Guzzle\Service\Description\Operation;
use Guzzle\Service\Client;
/**
* @covers Guzzle\Service\Description\ServiceDescription
*/
class ServiceDescriptionTest extends \Guzzle\Tests\GuzzleTestCase
{
protected $serviceData;
@ -28,7 +31,7 @@ class ServiceDescriptionTest extends \Guzzle\Tests\GuzzleTestCase
/**
* @covers Guzzle\Service\Description\ServiceDescription::factory
* @covers Guzzle\Service\Description\ArrayDescriptionBuilder::build
* @covers Guzzle\Service\Description\ServiceDescriptionLoader::build
*/
public function testFactoryDelegatesToConcreteFactories()
{
@ -36,12 +39,6 @@ class ServiceDescriptionTest extends \Guzzle\Tests\GuzzleTestCase
$this->assertInstanceOf('Guzzle\Service\Description\ServiceDescription', ServiceDescription::factory($jsonFile));
}
/**
* @covers Guzzle\Service\Description\ServiceDescription
* @covers Guzzle\Service\Description\ServiceDescription::__construct
* @covers Guzzle\Service\Description\ServiceDescription::getOperations
* @covers Guzzle\Service\Description\ServiceDescription::getOperation
*/
public function testConstructor()
{
$service = new ServiceDescription(array('operations' => $this->serviceData));
@ -50,10 +47,6 @@ class ServiceDescriptionTest extends \Guzzle\Tests\GuzzleTestCase
$this->assertTrue($service->hasOperation('test_command'));
}
/**
* @covers Guzzle\Service\Description\ServiceDescription::serialize
* @covers Guzzle\Service\Description\ServiceDescription::unserialize
*/
public function testIsSerializable()
{
$service = new ServiceDescription(array('operations' => $this->serviceData));

View File

@ -1,54 +0,0 @@
<?php
namespace Guzzle\Tests\Service;
use Guzzle\Service\JsonLoader;
/**
* @covers Guzzle\Service\JsonLoader
*/
class JsonLoaderTest extends \Guzzle\Tests\GuzzleTestCase
{
/**
* @expectedException Guzzle\Service\Exception\JsonException
* @expectedExceptionMessage Unable to open
*/
public function testFileMustBeReadable()
{
$loader = new JsonLoader();
$loader->parseJsonFile('fooooooo!');
}
/**
* @expectedException Guzzle\Service\Exception\JsonException
* @expectedExceptionMessage Error loading JSON data from
*/
public function testJsonMustBeValue()
{
$loader = new JsonLoader();
$loader->parseJsonFile(__FILE__);
}
public function testFactoryCanCreateFromJson()
{
$file = dirname(__DIR__) . '/TestData/services/json1.json';
$loader = new JsonLoader();
$data = $loader->parseJsonFile($file);
$this->assertArrayHasKey('includes', $data);
$this->assertArrayHasKey('services', $data);
$this->assertInternalType('array', $data['services']['foo']);
$this->assertInternalType('array', $data['services']['abstract']);
$this->assertInternalType('array', $data['services']['mock']);
$this->assertEquals('bar', $data['services']['foo']['params']['baz']);
}
public function testFactoryUsesAliases()
{
$file = dirname(__DIR__) . '/TestData/services/json1.json';
$loader = new JsonLoader();
$loader->addAlias('foo', $file);
$data = $loader->parseJsonFile('foo');
$this->assertEquals('bar', $data['services']['foo']['params']['baz']);
}
}

View File

@ -19,7 +19,8 @@ class MockCommand extends \Guzzle\Service\Command\AbstractCommand
),
'_internal' => array(
'default' => 'abc'
)
),
'foo' => array('filters' => array('strtoupper'))
)
));
}