From 23122964d2e67a99f763bce5971a043212474e25 Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Thu, 15 Oct 2015 22:00:09 -0400 Subject: [PATCH] Better testing for ArrayType and Config classes --- src/Aviat/AnimeClient/Config.php | 73 +++++++----------------------- src/Aviat/Ion/Type/ArrayType.php | 76 +++++++++++++++++++++++++++----- tests/AnimeClient/ConfigTest.php | 33 +++++++++----- tests/Ion/Type/ArrayTypeTest.php | 22 +++++++++ 4 files changed, 126 insertions(+), 78 deletions(-) diff --git a/src/Aviat/AnimeClient/Config.php b/src/Aviat/AnimeClient/Config.php index 4a238aed..d5a1b61e 100644 --- a/src/Aviat/AnimeClient/Config.php +++ b/src/Aviat/AnimeClient/Config.php @@ -5,6 +5,8 @@ namespace Aviat\AnimeClient; +use InvalidArgumentException; + /** * Wrapper for configuration values */ @@ -15,7 +17,7 @@ class Config { /** * Config object * - * @var array + * @var Aviat\Ion\Type\ArrayType */ protected $map = []; @@ -26,7 +28,7 @@ class Config { */ public function __construct(array $config_array = []) { - $this->map = $config_array; + $this->map = $this->arr($config_array); } /** @@ -39,50 +41,10 @@ class Config { { if (is_array($key)) { - return $this->arr($this->map)->get_deep_key($key); + return $this->map->get_deep_key($key); } - if (array_key_exists($key, $this->map)) - { - return $this->map[$key]; - } - - return NULL; - } - - /** - * Return a reference to an arbitrary key on the config map - * @param array $key - * @param bool $create Whether to create the missing array keys - * @return mixed - */ - protected function &get_deep_key(array $key, $create = TRUE) - { - $pos =& $this->map; - - // Create the start of the array if it doesn't exist - if ($create && ! is_array($pos)) - { - $pos = []; - } - elseif ( ! is_array($pos)) - { - return NULL; - } - - // Iterate through the levels of the array, - // create the levels if they don't exist - foreach($key as $level) - { - if ($create && empty($pos) && ! is_array($pos)) - { - $pos = []; - $pos[$level] = []; - } - $pos =& $pos[$level]; - } - - return $pos; + return $this->map->get($key); } /** @@ -93,39 +55,38 @@ class Config { */ public function delete($key) { - $pos =& $this->map; - if (is_array($key)) { - $pos =& $this->arr($this->map)->get_deep_key($key); + $this->map->set_deep_key($key, NULL); } else { - $pos =& $this->map[$key]; + $pos =& $this->map->get($key); + $pos = NULL; } - - $pos = NULL; } /** * Set a config value * - * @param string|array $key + * @param integer|string|array $key * @param mixed $value + * @throws InvalidArgumentException * @return Config */ public function set($key, $value) { - $pos =& $this->map; - if (is_array($key)) { - $pos =& $this->get_deep_key($key); - $pos = $value; + $this->map->set_deep_key($key, $value); + } + else if(is_scalar($key) && ! empty($key)) + { + $this->map->set($key, $value); } else { - $pos[$key] = $value; + throw new InvalidArgumentException("Key must be integer, string, or array, and cannot be empty"); } return $this; diff --git a/src/Aviat/Ion/Type/ArrayType.php b/src/Aviat/Ion/Type/ArrayType.php index b1076b1b..35a1fe8b 100644 --- a/src/Aviat/Ion/Type/ArrayType.php +++ b/src/Aviat/Ion/Type/ArrayType.php @@ -156,13 +156,39 @@ class ArrayType { } /** - * Return the array + * Return the array, or a key * - * @return array + * @param string|integer $key + * @return mixed */ - public function get() + public function &get($key = NULL) { - return $this->arr; + $value = NULL; + if (is_null($key)) + { + $value =& $this->arr; + } + else + { + if ($this->has_key($key)) + { + $value =& $this->arr[$key]; + } + } + + return $value; + } + + /** + * Set a key on the array + * + * @param mixed $key + * @param mixed $value + * @return ArrayType + */ + public function set($key, $value) + { + $this->arr[$key] = $value; } /** @@ -175,20 +201,46 @@ class ArrayType { { $pos =& $this->arr; - // Create the start of the array if it doesn't exist - if ( ! is_array($pos)) - { - return NULL; - } - - // Iterate through the levels of the array, - // create the levels if they don't exist foreach($key as $level) { + if (empty($pos) || ! is_array($pos)) + { + $pos = NULL; + return $pos; + } $pos =& $pos[$level]; } return $pos; } + + /** + * Sets the value of an arbitrarily deep key in the array + * and returns the modified array + * + * @param array $key + * @param mixed $value + * @return array + */ + public function set_deep_key(array $key, $value) + { + $pos =& $this->arr; + + // Iterate through the levels of the array, + // create the levels if they don't exist + foreach($key as $level) + { + if ( ! is_array($pos) && empty($pos)) + { + $pos = []; + $pos[$level] = []; + } + $pos =& $pos[$level]; + } + + $pos = $value; + + return $this->arr; + } } // End of ArrayType.php \ No newline at end of file diff --git a/tests/AnimeClient/ConfigTest.php b/tests/AnimeClient/ConfigTest.php index 5258a782..b3134843 100644 --- a/tests/AnimeClient/ConfigTest.php +++ b/tests/AnimeClient/ConfigTest.php @@ -18,8 +18,7 @@ class ConfigTest extends AnimeClient_TestCase { $this->assertEquals('bar', $this->config->get('foo')); $this->assertEquals('baz', $this->config->get('bar')); $this->assertNull($this->config->get('baz')); - - $this->assertNull($this->config->get(['apple','sauce'])); + $this->assertNull($this->config->get(['apple', 'sauce', 'is'])); } public function testConfigSet() @@ -28,7 +27,16 @@ class ConfigTest extends AnimeClient_TestCase { $this->assertEquals('foobar', $this->config->get('foo')); $this->config->set(['apple', 'sauce', 'is'], 'great'); - $this->assertEquals('great', $this->config->get(['apple', 'sauce', 'is'])); + $apple = $this->config->get('apple'); + $this->assertEquals('great', $apple['sauce']['is'], "Config value not set correctly"); + + $this->assertEquals('great', $this->config->get(['apple', 'sauce', 'is']), "Array argument get for config failed."); + } + + public function testConfigBadSet() + { + $this->setExpectedException('InvalidArgumentException'); + $this->config->set(NULL, FALSE); } public function dataConfigDelete() @@ -51,7 +59,7 @@ class ConfigTest extends AnimeClient_TestCase { ] ] ], - /*'mid level delete' => [ + 'mid level delete' => [ 'key' => ['apple', 'sauce'], 'assertKeys' => [ [ @@ -64,7 +72,9 @@ class ConfigTest extends AnimeClient_TestCase { ], [ 'path' => 'apple', - 'expected' => [] + 'expected' => [ + 'sauce' => NULL + ] ] ] ], @@ -77,10 +87,12 @@ class ConfigTest extends AnimeClient_TestCase { ], [ 'path' => ['apple', 'sauce'], - 'expected' => NULL + 'expected' => [ + 'is' => NULL + ] ] ] - ]*/ + ] ]; } @@ -89,12 +101,13 @@ class ConfigTest extends AnimeClient_TestCase { */ public function testConfigDelete($key, $assertKeys) { - $this->config->set(['apple', 'sauce', 'is'], 'great'); - $this->config->delete($key); + $config = new Config([]); + $config->set(['apple', 'sauce', 'is'], 'great'); + $config->delete($key); foreach($assertKeys as $pair) { - $this->assertEquals($pair['expected'], $this->config->get($pair['path'])); + $this->assertEquals($pair['expected'], $config->get($pair['path'])); } } diff --git a/tests/Ion/Type/ArrayTypeTest.php b/tests/Ion/Type/ArrayTypeTest.php index b260ac28..db2d56c6 100644 --- a/tests/Ion/Type/ArrayTypeTest.php +++ b/tests/Ion/Type/ArrayTypeTest.php @@ -79,6 +79,28 @@ class ArrayTypeTest extends AnimeClient_TestCase { $this->assertEquals($expected, $actual); } + public function testGet() + { + $array = [1, 2, 3, 4, 5]; + $obj = $this->arr($array); + $this->assertEquals($array, $obj->get()); + $this->assertEquals(1, $obj->get(0)); + $this->assertEquals(5, $obj->get(4)); + } + + public function testGetDeepKey() + { + $arr = [ + 'foo' => 'bar', + 'baz' => [ + 'bar' => 'foobar' + ] + ]; + $obj = $this->arr($arr); + $this->assertEquals('foobar', $obj->get_deep_key(['baz', 'bar'])); + $this->assertNull($obj->get_deep_key(['foo', 'bar', 'baz'])); + } + public function testMap() { $obj = $this->arr([1, 2, 3]);