├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── composer.json ├── phpunit.xml.dist ├── src └── Dflydev │ └── PlaceholderResolver │ ├── AbstractPlaceholderResolver.php │ ├── Cache │ ├── Cache.php │ └── CacheInterface.php │ ├── DataSource │ ├── ArrayDataSource.php │ └── DataSourceInterface.php │ ├── PlaceholderResolverInterface.php │ ├── RegexPlaceholderResolver.php │ └── RegexPlaceholderResolverCallback.php └── tests ├── Dflydev └── PlaceholderResolver │ ├── Cache │ └── CacheTest.php │ ├── DataSource │ └── ArrayDataSourceTest.php │ ├── RegexPlaceholderResolverCallbackTest.php │ └── RegexPlaceholderResolverTest.php └── bootstrap.php /.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | vendor 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.3.3 5 | - 5.3 6 | - 5.4 7 | 8 | before_script: 9 | - wget -nc http://getcomposer.org/composer.phar 10 | - php composer.phar install --dev 11 | 12 | script: phpunit --coverage-text --verbose 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Dragonfly Development Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Placeholder Resolver 2 | 3 | Given a data source representing key => value pairs, resolve placeholders 4 | like `${foo.bar}` to the value associated with the `foo.bar` key in 5 | the data source. 6 | 7 | Placeholder Resolver is intended to be used at a relatively low level. 8 | For example, a configuration library could use Placeholder Resolver 9 | behind the scenes to allow for configuration values to reference 10 | other configuration values. 11 | 12 | ## Example 13 | 14 | ```yml 15 | conn.driver: mysql 16 | conn.db_name: example 17 | conn.hostname: 127.0.0.1 18 | conn.username: root 19 | conn.password: pa$$word 20 | ``` 21 | 22 | Given the appropriate `DataSourceInterface` implementation to provide 23 | the above data as a set of key => value pairs, the Placeholder Resolver 24 | would resolve the value of `$dsnPattern` to `mysql:dbname=example;host=127.0.0.1`. 25 | 26 | ```php 27 | $dsnPattern = '${conn.driver}:dbname=${conn.db_name};host=${conn.hostname}'; 28 | $dsn = $placeholderResolver->resolveValue($dsnPattern); 29 | // mysql:dbname=example;host=127.0.0.1 30 | ``` 31 | 32 | ## Requirements 33 | 34 | * PHP 5.3+ 35 | 36 | ## Usage 37 | 38 | ```php 39 | use Dflydev\PlaceholderResolver\RegexPlaceholderResolver; 40 | 41 | // YourDataSource implements Dflydev\PlaceholderResolver\DataSource\DataSourceInterface 42 | $dataSource = new YourDataSource; 43 | 44 | // Create the placeholder resolver 45 | $placeholderResolver = new RegexPlaceholderResolver($dataSource); 46 | 47 | // Start resolving placeholders 48 | $value = $placeholderResolver->resolvePlaceholder('${foo}'); 49 | ``` 50 | 51 | The `RegexPlaceholderResolver` constructor accepts two additional arguments, 52 | a placeholder prefix and a placeholder suffix. The default placeholder 53 | prefix is `${` and the default placeholder suffix is `}`. 54 | 55 | To handle placeholders that look like `` instead of `${foo.bar}`, 56 | one would instantiate the class like this: 57 | 58 | ```php 59 | $placeholderResolver = new RegexPlaceholderResolver($dataSource, '<', '>'); 60 | ``` 61 | 62 | Placeholders can recursively resolve placeholders. For example, given a 63 | data source with the following: 64 | 65 | ```php 66 | array( 67 | 'foo' => 'FOO', 68 | 'bar' => 'BAR', 69 | 'FOO.BAR' => 'BAZ!', 70 | ); 71 | ``` 72 | 73 | The placeholder `${${foo}.${bar}}` would internally be resolved to 74 | `${FOO.BAR}` before being further resolved to `BAZ!`. 75 | 76 | Resolved placeholders are cached using the `CacheInterface`. The default 77 | `Cache` implementation is used unless it is explicitly set on the 78 | Placeholder Resolver. 79 | 80 | ```php 81 | // YourCache implements Dflydev\PlaceholderResolver\Cache\CacheInterface 82 | $cache = new YourCache; 83 | 84 | $placeholderResolver->setCache($cache); 85 | ``` 86 | 87 | ## License 88 | 89 | This library is licensed under the New BSD License - see the LICENSE file 90 | for details. 91 | 92 | ## Community 93 | 94 | If you have questions or want to help out, join us in the 95 | [#dflydev](irc://irc.freenode.net/#dflydev) channel on irc.freenode.net. 96 | 97 | ## Not Invented Here 98 | 99 | Much of the ideas behind this library came from Spring's Property 100 | Placeholder Configurer implementation. 101 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dflydev/placeholder-resolver", 3 | "type": "library", 4 | "description": "Given a data source representing key => value pairs, resolve placeholders like ${foo.bar} to the value associated with the 'foo.bar' key in the data source.", 5 | "homepage": "https://github.com/dflydev/dflydev-placeholder-resolver", 6 | "keywords": ["placeholder", "resolver"], 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Dragonfly Development Inc.", 11 | "email": "info@dflydev.com", 12 | "homepage": "http://dflydev.com" 13 | }, 14 | { 15 | "name": "Beau Simensen", 16 | "email": "beau@dflydev.com", 17 | "homepage": "http://beausimensen.com" 18 | } 19 | ], 20 | "require": { 21 | "php": ">=5.3.2" 22 | }, 23 | "autoload": { 24 | "psr-0": { 25 | "Dflydev\\PlaceholderResolver": "src" 26 | } 27 | }, 28 | "extra": { 29 | "branch-alias": { 30 | "dev-master": "1.0-dev" 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ./tests/Dflydev/PlaceholderResolver 6 | 7 | 8 | 9 | 10 | 11 | ./src/Dflydev/PlaceholderResolver/ 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/Dflydev/PlaceholderResolver/AbstractPlaceholderResolver.php: -------------------------------------------------------------------------------- 1 | maxReplacementDepth = $maxReplacementDepth; 32 | 33 | return $this; 34 | } 35 | 36 | /** 37 | * Get cache 38 | * 39 | * @return CacheInterface 40 | */ 41 | public function getCache() 42 | { 43 | if (null === $this->cache) { 44 | $this->cache = new Cache; 45 | } 46 | 47 | return $this->cache; 48 | } 49 | 50 | /** 51 | * Set cache 52 | * 53 | * @param CacheInterface $cache 54 | */ 55 | public function setCache(CacheInterface $cache) 56 | { 57 | $this->cache = $cache; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Dflydev/PlaceholderResolver/Cache/Cache.php: -------------------------------------------------------------------------------- 1 | cache); 28 | } 29 | 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public function get($placeholder) 34 | { 35 | if (is_array($placeholder)) { 36 | throw new \RuntimeException('Placeholder is an array'); 37 | } 38 | 39 | return array_key_exists((string) $placeholder, $this->cache) 40 | ? $this->cache[(string) $placeholder] 41 | : null; 42 | } 43 | 44 | /** 45 | * {@inheritdoc} 46 | */ 47 | public function set($placeholder, $value = null) 48 | { 49 | if (is_array($placeholder)) { 50 | throw new \RuntimeException('Placeholder is an array'); 51 | } 52 | $this->cache[(string) $placeholder] = $value; 53 | } 54 | 55 | /** 56 | * {@inheritdoc} 57 | */ 58 | public function flush() 59 | { 60 | $this->cache = array(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Dflydev/PlaceholderResolver/Cache/CacheInterface.php: -------------------------------------------------------------------------------- 1 | 20 | */ 21 | class ArrayDataSource implements DataSourceInterface 22 | { 23 | /** 24 | * @var array 25 | */ 26 | protected $array; 27 | 28 | /** 29 | * Constructor 30 | * 31 | * @param array $array 32 | */ 33 | public function __construct(array $array = array()) 34 | { 35 | $this->array = $array; 36 | } 37 | 38 | /** 39 | * {@inheritdoc} 40 | */ 41 | public function exists($key, $system = false) 42 | { 43 | if ($system) { 44 | return false; 45 | } 46 | 47 | return isset($this->array[$key]); 48 | } 49 | 50 | /** 51 | * {@inheritdoc} 52 | */ 53 | public function get($key, $system = false) 54 | { 55 | if ($system) { 56 | return null; 57 | } 58 | 59 | return isset($this->array[$key]) ? $this->array[$key] : null; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Dflydev/PlaceholderResolver/DataSource/DataSourceInterface.php: -------------------------------------------------------------------------------- 1 | placeholderResolverCallback = new RegexPlaceholderResolverCallback($dataSource); 38 | $placeholderPrefix = preg_quote($placeholderPrefix); 39 | $placeholderSuffix = preg_quote($placeholderSuffix); 40 | $this->pattern = "/{$placeholderPrefix}([a-zA-Z0-9\.\(\)_\:]+?){$placeholderSuffix}/"; 41 | } 42 | 43 | /** 44 | * {@inheritdoc} 45 | */ 46 | public function resolvePlaceholder($placeholder) 47 | { 48 | if (!is_string($placeholder)) { 49 | return $placeholder; 50 | } 51 | 52 | if ($this->getCache()->exists($placeholder)) { 53 | return $this->getCache()->get($placeholder); 54 | } 55 | 56 | $value = $placeholder; 57 | $counter = 0; 58 | 59 | while ($counter++ < $this->maxReplacementDepth) { 60 | $newValue = preg_replace_callback( 61 | $this->pattern, 62 | array($this->placeholderResolverCallback, 'callback'), 63 | (string)$value 64 | ); 65 | if ($newValue === $value) { break; } 66 | $value = $newValue; 67 | } 68 | 69 | $this->getCache()->set($placeholder, $value); 70 | 71 | return $value; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Dflydev/PlaceholderResolver/RegexPlaceholderResolverCallback.php: -------------------------------------------------------------------------------- 1 | dataSource = $dataSource; 31 | } 32 | 33 | /** 34 | * Callback for preg_replace_callback() generally called in PlaceholderResolver 35 | * 36 | * The expected input will be array($fullMatch, $potentialKey) and the 37 | * expected output will be either a value from the data source, a special 38 | * value from SERVER or CONSTANT, or the contents of $fullMatch (the key 39 | * itself with its wrapped prefix and suffix). 40 | * 41 | * @param array $matches 42 | * 43 | * @return string|null 44 | */ 45 | public function callback($matches) 46 | { 47 | list ($fullMatch, $potentialKey) = $matches; 48 | if (preg_match('/^(SYSTEM|SERVER|CONSTANT):(\w+)$/', $potentialKey, $specialMatches)) { 49 | list ($dummy, $which, $specialKey) = $specialMatches; 50 | switch ($which) { 51 | case 'SERVER': 52 | case 'SYSTEM': 53 | if ($this->dataSource->exists($specialKey, true)) { 54 | return $this->dataSource->get($specialKey, true); 55 | } 56 | break; 57 | case 'CONSTANT': 58 | if (defined($specialKey)) { 59 | return constant($specialKey); 60 | } 61 | break; 62 | } 63 | } 64 | 65 | if ($this->dataSource->exists($potentialKey)) { 66 | return $this->dataSource->get($potentialKey); 67 | } 68 | 69 | return $fullMatch; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /tests/Dflydev/PlaceholderResolver/Cache/CacheTest.php: -------------------------------------------------------------------------------- 1 | set(1, "one as integer"); 22 | $cache->set("2", "two as string '2'"); 23 | $cache->set("three", "three as string"); 24 | $cache->set($object, "object"); 25 | 26 | $this->assertEquals("one as integer", $cache->get(1)); 27 | $this->assertEquals("two as string '2'", $cache->get('2')); 28 | $this->assertEquals("three as string", $cache->get('three')); 29 | $this->assertEquals("object", $cache->get($object)); 30 | 31 | $this->assertNull($cache->get(11)); 32 | $this->assertNull($cache->get('12')); 33 | $this->assertNull($cache->get('thirteen')); 34 | } 35 | 36 | public function testExists() 37 | { 38 | $object = new CacheTestToSTring; 39 | 40 | $cache = new Cache; 41 | 42 | $this->assertFalse($cache->exists(1)); 43 | $this->assertFalse($cache->exists("2")); 44 | $this->assertFalse($cache->exists("three")); 45 | $this->assertFalse($cache->exists($object)); 46 | } 47 | 48 | public function testExistsArray() 49 | { 50 | $array = array(); 51 | 52 | $cache = new Cache; 53 | 54 | $this->setExpectedException('RuntimeException'); 55 | 56 | $cache->exists($array); 57 | } 58 | 59 | public function testGetArray() 60 | { 61 | $array = array(); 62 | 63 | $cache = new Cache; 64 | 65 | $this->setExpectedException('RuntimeException'); 66 | 67 | $cache->get($array); 68 | } 69 | 70 | public function testSetArray() 71 | { 72 | $array = array(); 73 | 74 | $cache = new Cache; 75 | 76 | $this->setExpectedException('RuntimeException'); 77 | 78 | $cache->set($array, 'broken'); 79 | } 80 | 81 | public function testExistsNoToString() 82 | { 83 | $object = new CacheTestNoToSTring; 84 | 85 | $cache = new Cache; 86 | 87 | $this->setExpectedException('PHPUnit_Framework_Error'); 88 | 89 | $cache->exists($object); 90 | } 91 | 92 | public function testGetNoToString() 93 | { 94 | $object = new CacheTestNoToSTring; 95 | 96 | $cache = new Cache; 97 | 98 | $this->setExpectedException('PHPUnit_Framework_Error'); 99 | 100 | $cache->get($object); 101 | } 102 | 103 | public function testSetNoToString() 104 | { 105 | $object = new CacheTestNoToSTring; 106 | 107 | $cache = new Cache; 108 | 109 | $this->setExpectedException('PHPUnit_Framework_Error'); 110 | 111 | $cache->set($object, 'broken'); 112 | } 113 | } 114 | 115 | class CacheTestNoToSTring 116 | { 117 | } 118 | 119 | class CacheTestToSTring 120 | { 121 | public function __toString() 122 | { 123 | return 'any string'; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /tests/Dflydev/PlaceholderResolver/DataSource/ArrayDataSourceTest.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class ArrayDataSourceTest extends \PHPUnit_Framework_TestCase 20 | { 21 | /** 22 | * Test basic functionality 23 | */ 24 | public function testBasic() 25 | { 26 | $dataSource = new ArrayDataSource(array( 27 | 'a' => 'A', 28 | 'b' => 'B', 29 | 'c' => 'C', 30 | )); 31 | 32 | $this->assertTrue($dataSource->exists('a')); 33 | $this->assertTrue($dataSource->exists('b')); 34 | $this->assertTrue($dataSource->exists('c')); 35 | $this->assertFalse($dataSource->exists('d')); 36 | 37 | $this->assertFalse($dataSource->exists('a', true)); 38 | $this->assertFalse($dataSource->exists('d', true)); 39 | 40 | $this->assertEquals('A', $dataSource->get('a')); 41 | $this->assertEquals('B', $dataSource->get('b')); 42 | $this->assertEquals('C', $dataSource->get('c')); 43 | $this->assertNull($dataSource->get('d')); 44 | 45 | $this->assertNull($dataSource->get('a', true)); 46 | $this->assertNull($dataSource->get('d', true)); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tests/Dflydev/PlaceholderResolver/RegexPlaceholderResolverCallbackTest.php: -------------------------------------------------------------------------------- 1 | getMock('Dflydev\PlaceholderResolver\DataSource\DataSourceInterface'); 19 | $dataSource 20 | ->expects($this->any()) 21 | ->method('exists') 22 | ->will($this->returnValueMap(array( 23 | array('foo', false, true), 24 | array('bar', false, true), 25 | array('baz', false, true), 26 | array('bat', false, false), 27 | array('foo', true, true), 28 | array('bar', true, false), 29 | ))) 30 | ; 31 | $dataSource 32 | ->expects($this->any()) 33 | ->method('get') 34 | ->will($this->returnValueMap(array( 35 | array('foo', false, 'FOO'), 36 | array('bar', false, 'BAR'), 37 | array('baz', false, 'BAZ'), 38 | array('foo', true, 'SYSTEM FOO'), 39 | ))) 40 | ; 41 | 42 | $placeholderResolverCallback = new RegexPlaceholderResolverCallback($dataSource); 43 | 44 | define('TEST_CONSTANT_RESOLVE', 'abc123'); 45 | 46 | $this->assertEquals('FOO', $placeholderResolverCallback->callback(array('${foo}', 'foo'))); 47 | $this->assertEquals('BAR', $placeholderResolverCallback->callback(array('${bar}', 'bar'))); 48 | $this->assertEquals('BAZ', $placeholderResolverCallback->callback(array('${baz}', 'baz'))); 49 | $this->assertEquals('${bat}', $placeholderResolverCallback->callback(array('${bat}', 'bat'))); 50 | $this->assertEquals('SYSTEM FOO', $placeholderResolverCallback->callback(array('${SYSTEM:foo}', 'SYSTEM:foo'))); 51 | $this->assertEquals('${SYSTEM:bar}', $placeholderResolverCallback->callback(array('${SYSTEM:bar}', 'SYSTEM:bar'))); 52 | $this->assertEquals('SYSTEM FOO', $placeholderResolverCallback->callback(array('${SERVER:foo}', 'SERVER:foo'))); 53 | $this->assertEquals('${SERVER:bar}', $placeholderResolverCallback->callback(array('${SERVER:bar}', 'SERVER:bar'))); 54 | $this->assertEquals('abc123', $placeholderResolverCallback->callback(array('${CONSTANT:TEST_CONSTANT_RESOLVE}', 'CONSTANT:TEST_CONSTANT_RESOLVE'))); 55 | $this->assertEquals('${CONSTANT:MISSING_TEST_CONSTANT_RESOLVE}', $placeholderResolverCallback->callback(array('${CONSTANT:MISSING_TEST_CONSTANT_RESOLVE}', 'CONSTANT:MISSING_TEST_CONSTANT_RESOLVE'))); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tests/Dflydev/PlaceholderResolver/RegexPlaceholderResolverTest.php: -------------------------------------------------------------------------------- 1 | getMock('Dflydev\PlaceholderResolver\DataSource\DataSourceInterface'); 19 | $dataSource 20 | ->expects($this->any()) 21 | ->method('exists') 22 | ->will($this->returnValueMap(array( 23 | array('foo', false, true), 24 | array('bar', false, true), 25 | array('baz', false, true), 26 | array('bat', false, false), 27 | array('composite', false, true), 28 | array('FOO.BAR', false, true), 29 | array('FOO.BAR.BAZ', false, false), 30 | ))) 31 | ; 32 | $dataSource 33 | ->expects($this->any()) 34 | ->method('get') 35 | ->will($this->returnValueMap(array( 36 | array('foo', false, 'FOO'), 37 | array('bar', false, 'BAR'), 38 | array('baz', false, 'BAZ'), 39 | array('composite', false, '${foo}-${bar}'), 40 | array('FOO.BAR', false, 'Foo Dot Bar'), 41 | ))) 42 | ; 43 | 44 | $placeholderResolver = new RegexPlaceholderResolver($dataSource); 45 | 46 | $this->assertEquals("FOO", $placeholderResolver->resolvePlaceholder('${foo}')); 47 | $this->assertEquals("BAR", $placeholderResolver->resolvePlaceholder('${bar}')); 48 | $this->assertEquals("BAZ", $placeholderResolver->resolvePlaceholder('${baz}')); 49 | $this->assertEquals("FOO-BAR", $placeholderResolver->resolvePlaceholder('${composite}')); 50 | $this->assertEquals("FOO-BAR-BAZ", $placeholderResolver->resolvePlaceholder('${composite}-${baz}')); 51 | $this->assertEquals("Foo Dot Bar", $placeholderResolver->resolvePlaceholder('${${foo}.${bar}}')); 52 | $this->assertEquals('${FOO.BAR.BAZ}', $placeholderResolver->resolvePlaceholder('${FOO.BAR.BAZ}')); 53 | } 54 | 55 | /** 56 | * @dataProvider resolvePlaceholderPrefixAndSuffixProvider 57 | */ 58 | public function testResolvePlaceholderPrefixAndSuffix($prefix, $suffix) 59 | { 60 | $dataSource = $this->getMock('Dflydev\PlaceholderResolver\DataSource\DataSourceInterface'); 61 | $dataSource 62 | ->expects($this->any()) 63 | ->method('exists') 64 | ->will($this->returnValueMap(array( 65 | array('foo', false, true), 66 | array('bar', false, true), 67 | array('baz', false, true), 68 | array('bat', false, false), 69 | array('composite', false, true), 70 | array('FOO.BAR', false, true), 71 | ))) 72 | ; 73 | $dataSource 74 | ->expects($this->any()) 75 | ->method('get') 76 | ->will($this->returnValueMap(array( 77 | array('foo', false, 'FOO'), 78 | array('bar', false, 'BAR'), 79 | array('baz', false, 'BAZ'), 80 | array('composite', false, $prefix.'foo'.$suffix.'-'.$prefix.'bar'.$suffix), 81 | array('FOO.BAR', false, 'Foo Dot Bar'), 82 | ))) 83 | ; 84 | 85 | $placeholderResolver = new RegexPlaceholderResolver($dataSource, $prefix, $suffix); 86 | $this->assertEquals("FOO", $placeholderResolver->resolvePlaceholder($prefix.'foo'.$suffix)); 87 | $this->assertEquals($prefix.'bat'.$suffix, $placeholderResolver->resolvePlaceholder($prefix.'bat'.$suffix)); 88 | $this->assertEquals("FOO-BAR", $placeholderResolver->resolvePlaceholder($prefix.'composite'.$suffix)); 89 | $this->assertEquals("FOO-BAR-BAZ", $placeholderResolver->resolvePlaceholder($prefix.'composite'.$suffix.'-'.$prefix.'baz'.$suffix)); 90 | $this->assertEquals("Foo Dot Bar", $placeholderResolver->resolvePlaceholder($prefix.$prefix.'foo'.$suffix.'.'.$prefix.'bar'.$suffix.$suffix)); 91 | } 92 | 93 | public function resolvePlaceholderPrefixAndSuffixProvider() 94 | { 95 | return array( 96 | array('%', '%'), 97 | array('<', '>'), 98 | array('(<)', '(>)'), 99 | ); 100 | } 101 | 102 | public function testResolvePlaceholderReturnType() 103 | { 104 | $dataSource = $this->getMock('Dflydev\PlaceholderResolver\DataSource\DataSourceInterface'); 105 | $dataSource 106 | ->expects($this->any()) 107 | ->method('exists') 108 | ->will($this->returnValueMap(array( 109 | array('true', false, true), 110 | array('int', false, true), 111 | array('composite', false, true), 112 | ))) 113 | ; 114 | $dataSource 115 | ->expects($this->any()) 116 | ->method('get') 117 | ->will($this->returnValueMap(array( 118 | array('true', false, true), 119 | array('int', false, 2015), 120 | array('composite', false, '${int}'), 121 | ))) 122 | ; 123 | 124 | $placeholderResolver = new RegexPlaceholderResolver($dataSource); 125 | 126 | $this->assertSame(true, $placeholderResolver->resolvePlaceholder(true)); 127 | $this->assertSame(false, $placeholderResolver->resolvePlaceholder(false)); 128 | $this->assertSame(2015, $placeholderResolver->resolvePlaceholder(2015)); 129 | $this->assertSame(2015.0914, $placeholderResolver->resolvePlaceholder(2015.0914)); 130 | $this->assertSame('2015', $placeholderResolver->resolvePlaceholder('2015')); 131 | $this->assertSame('2015', $placeholderResolver->resolvePlaceholder('${int}')); 132 | $this->assertSame('1', $placeholderResolver->resolvePlaceholder('${true}')); 133 | $this->assertSame('2015', $placeholderResolver->resolvePlaceholder('${composite}')); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 |