diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml
new file mode 100644
index 0000000..45f5e23
--- /dev/null
+++ b/.github/workflows/phpstan.yml
@@ -0,0 +1,14 @@
+name: phpstan
+on: push
+jobs:
+ phpstan:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: php-actions/composer@v6
+ with:
+ dev: yes
+ - uses: php-actions/phpstan@v3
+ with:
+ memory_limit: 1G
+ args: --memory-limit 1G
diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml
new file mode 100644
index 0000000..c5a182c
--- /dev/null
+++ b/.github/workflows/phpunit.yml
@@ -0,0 +1,11 @@
+name: phpunit
+on: push
+jobs:
+ phpunit:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: php-actions/composer@v6
+ with:
+ dev: yes
+ - uses: php-actions/phpunit@v3
diff --git a/.gitignore b/.gitignore
index 3a9875b..82dac7f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
-/vendor/
-composer.lock
+/vendor
+/composer.lock
+/.phpunit.result.cache
+/coverage
\ No newline at end of file
diff --git a/README.md b/README.md
index bd6e223..44bbf39 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
# Flatrr
-[![Build Status](https://travis-ci.org/jobyone/flatrr.svg?branch=main)](https://travis-ci.org/jobyone/flatrr)
+[![phpstan](https://github.com/jobyone/flatrr/actions/workflows/phpstan.yml/badge.svg?branch=v1.5)](https://github.com/jobyone/flatrr/actions/workflows/phpstan.yml)
+[![phpunit](https://github.com/jobyone/flatrr/actions/workflows/phpunit.yml/badge.svg?branch=v1.5)](https://github.com/jobyone/flatrr/actions/workflows/phpunit.yml)
[![Latest Stable Version](http://poser.pugx.org/byjoby/flatrr/v)](https://packagist.org/packages/byjoby/flatrr)
[![Total Downloads](http://poser.pugx.org/byjoby/flatrr/downloads)](https://packagist.org/packages/byjoby/flatrr)
[![Latest Unstable Version](http://poser.pugx.org/byjoby/flatrr/v/unstable)](https://packagist.org/packages/byjoby/flatrr)
diff --git a/composer.json b/composer.json
index 66585af..d37415c 100644
--- a/composer.json
+++ b/composer.json
@@ -3,12 +3,16 @@
"description": "A library for working with multi-dimensional arrays through flattened keys",
"type": "library",
"license": "MIT",
- "authors": [{
- "name": "Joby Elliott",
- "email": "joby@byjoby.com"
- }],
+ "authors": [
+ {
+ "name": "Joby Elliott",
+ "email": "joby@byjoby.com"
+ }
+ ],
"require-dev": {
- "phpunit/phpunit": "^7.3"
+ "phpunit/phpunit": "^9.5",
+ "phpstan/phpstan": "^1.9",
+ "squizlabs/php_codesniffer": "^3.7"
},
"autoload": {
"psr-4": {
@@ -21,12 +25,12 @@
}
},
"scripts": {
- "test": [
- "phpunit"
- ]
+ "test": "phpunit",
+ "stan": "phpstan",
+ "sniff": "phpcs"
},
"require": {
- "php": ">=7.1",
+ "php": ">=8.1",
"mustangostang/spyc": "^0.6.3"
}
-}
+}
\ No newline at end of file
diff --git a/phpcs.xml b/phpcs.xml
new file mode 100644
index 0000000..32ec211
--- /dev/null
+++ b/phpcs.xml
@@ -0,0 +1,19 @@
+
+
+ Coding Standard
+
+ src
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/phpstan.neon b/phpstan.neon
new file mode 100644
index 0000000..3ff6fa8
--- /dev/null
+++ b/phpstan.neon
@@ -0,0 +1,4 @@
+parameters:
+ level: 7
+ paths:
+ - src
\ No newline at end of file
diff --git a/phpunit.xml b/phpunit.xml
index 89c010e..bc2f7c1 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -1,7 +1,31 @@
-
+
+
+
+
+
+
+
-
- tests
+
+ tests/
-
+
+
+ src
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Config/Config.php b/src/Config/Config.php
index 33c5987..7d951ff 100644
--- a/src/Config/Config.php
+++ b/src/Config/Config.php
@@ -1,5 +1,6 @@
readFile($f, $name, $overwrite);
+ if ($dir && is_dir($dir)) {
+ $glob = glob("$dir/*");
+ if ($glob) {
+ foreach ($glob as $f) {
+ if (is_file($f)) {
+ $this->readFile($f, $name, $overwrite);
+ }
+ }
}
}
+ return $this;
}
- protected function parse(string $input, string $format): array
+ public function json(bool $raw = false): string
{
- $fn = 'parse_' . $format;
- if (!method_exists($this, $fn)) {
- if ($this->strict) {
- throw new \Exception("Don't know how to parse the format \"$format\"");
- } else {
- return null;
- }
- }
- if ($out = $this->$fn($input)) {
- return $out;
- }
- return array();
+ return json_encode($this->get(null, $raw), JSON_PRETTY_PRINT); // @phpstan-ignore-line
}
- protected function parse_yaml($input)
- {
- return Spyc::YAMLLoadString($input);
- }
-
- public function json($raw = false): string
- {
- return json_encode($this->get(null, $raw), JSON_PRETTY_PRINT);
- }
-
- public function yaml($raw = false): string
+ public function yaml(bool $raw = false): string
{
return Spyc::YAMLDump($this->get(null, $raw), 2);
}
- protected function read_ini($filename)
+ /** @return array */
+ protected function read_ini(string $filename): false|array
{
return parse_ini_file($filename, true);
}
- protected function read_json($filename)
+ /** @return array */
+ protected function read_json(string $filename): null|array
{
- return json_decode(file_get_contents($filename), true);
+ /** @var string */
+ $data = file_get_contents($filename);
+ return json_decode($data, true);
}
- protected function read_yaml($filename)
+ /** @return array */
+ protected function read_yaml(string $filename): array
{
return Spyc::YAMLLoad($filename);
}
- protected function read_yml($filename)
+ /** @return array */
+ protected function read_yml(string $filename): array
{
return $this->read_yaml($filename);
}
- public function readFile($filename, string $name = null, bool $overwrite = false)
+ public function readFile(string $filename, string $name = null, bool $overwrite = false): static
{
- if (!is_file($filename) || !is_readable($filename)) {
- if ($this->strict) {
- throw new \Exception("Couldn't read config file \"$filename\"");
- } else {
- return null;
- }
- }
$format = strtolower(preg_replace('/.+\./', '', $filename));
$fn = 'read_' . $format;
- if (!method_exists($this, $fn)) {
- if ($this->strict) {
- throw new \Exception("Don't know how to read the format \"$format\"");
- } else {
- return null;
+ if (is_file($filename) && is_readable($filename) && method_exists($this, $fn)) {
+ $data = $this->$fn($filename);
+ if ($data !== null) {
+ $this->merge($data, $name, $overwrite);
}
}
- $data = $this->$fn($filename);
- if (!$data) {
- if ($this->strict) {
- throw new \Exception("Error reading \"" . $filename . "\"");
- } else {
- return null;
- }
- }
- $this->merge($data, $name, $overwrite);
+ return $this;
}
}
diff --git a/src/Config/ConfigInterface.php b/src/Config/ConfigInterface.php
index 5fff574..5975f9a 100644
--- a/src/Config/ConfigInterface.php
+++ b/src/Config/ConfigInterface.php
@@ -1,12 +1,17 @@
$data
+ * @return void
+ */
+ public function __construct(null|array $data = null)
{
$this->merge($data);
}
diff --git a/src/FlatArrayInterface.php b/src/FlatArrayInterface.php
index f4da1ef..ac4a23c 100644
--- a/src/FlatArrayInterface.php
+++ b/src/FlatArrayInterface.php
@@ -1,16 +1,25 @@
+ * @extends Iterator
+ */
+interface FlatArrayInterface extends ArrayAccess, Iterator
+{
+ public function set(null|string $name, mixed $value): mixed;
+ public function get(null|string $name = null): mixed;
+ public function unset(null|string $name): static;
+ public function merge(mixed $value, string $name = null, bool $overwrite = false): static;
+
+ public function push(null|string $name, mixed $value): static;
+ public function pop(null|string $name): mixed;
+ public function unshift(null|string $name, mixed $value): static;
+ public function shift(null|string $name): mixed;
}
diff --git a/src/FlatArrayTrait.php b/src/FlatArrayTrait.php
index 3225986..b79be8e 100644
--- a/src/FlatArrayTrait.php
+++ b/src/FlatArrayTrait.php
@@ -1,117 +1,126 @@
*/
+ protected $_arrayData = [];
+ /** @var array */
+ protected $_flattenCache = [];
- public function push(?string $name, $value)
+ public function push(null|string $name, mixed $value): static
{
$arr = $this->flattenSearch($name);
if ($arr !== null && !is_array($arr)) {
- return;
+ return $this;
}
if ($arr === null) {
$arr = [];
}
$arr[] = $value;
$this->set($name, $arr);
+ return $this;
}
- public function pop(?string $name)
+ public function pop(null|string $name): mixed
{
$arr = $this->flattenSearch($name);
if ($arr !== null && !is_array($arr)) {
- return;
+ return null;
}
$out = array_pop($arr);
+ $this->unset($name);
$this->set($name, $arr);
return $out;
}
- public function unshift(?string $name, $value)
+ public function unshift(null|string $name, mixed $value): static
{
$arr = $this->flattenSearch($name);
if ($arr !== null && !is_array($arr)) {
- return;
+ return $this;
}
if ($arr === null) {
$arr = [];
}
array_unshift($arr, $value);
$this->set($name, $arr);
+ return $this;
}
- public function shift(?string $name)
+ public function shift(null|string $name): mixed
{
$arr = $this->flattenSearch($name);
if ($arr !== null && !is_array($arr)) {
- return;
+ return null;
}
$out = array_shift($arr);
+ $this->unset($name);
$this->set($name, $arr);
return $out;
}
- public function set(?string $name, $value)
+ public function set(null|string $name, mixed $value): static
{
- return $this->flattenSearch($name, $value);
+ $this->flattenSearch($name, $value);
+ return $this;
}
- public function get(?string $name = null)
+ public function get(null|string $name = null): mixed
{
return $this->flattenSearch($name);
}
- function unset(?string $name)
+ public function unset(null|string $name): static
{
$this->flattenSearch($name, null, true);
+ return $this;
}
- public function offsetSet($name, $value)
+ public function offsetSet($name, $value): void
{
- return $this->set($name, $value);
+ $this->set($name, $value);
}
- public function offsetGet($name)
+ public function offsetGet($name): mixed
{
return $this->get($name);
}
- public function offsetExists($name)
+ public function offsetExists($name): bool
{
return $this->flattenSearch($name) !== null;
}
- public function offsetUnset($name)
+ public function offsetUnset($name): void
{
$this->unset($name);
}
- public function rewind()
+ public function rewind(): void
{
- return reset($this->_arrayData);
+ reset($this->_arrayData);
}
- public function current()
+ public function current(): mixed
{
return current($this->_arrayData);
}
- public function next()
+ public function next(): void
{
- return next($this->_arrayData);
+ next($this->_arrayData);
}
- public function key()
+ public function key(): null|string|int
{
return key($this->_arrayData);
}
- public function valid()
+ public function valid(): bool
{
return isset($this->_arrayData[$this->key()]);
}
@@ -120,12 +129,11 @@ trait FlatArrayTrait
* Recursively set a value, with control over whether existing values or new
* values take precedence
*/
- public function merge($value, string $name = null, bool $overwrite = false)
+ public function merge(mixed $value, string $name = null, bool $overwrite = false): static
{
if (!isset($this[$name])) {
//easiest possible outcome, old value doesn't exist, so we can just write the value
$this->set($name, $value);
- return;
} elseif (is_array($value) && is_array($this->flattenSearch($name))) {
//both new and old values are arrays
foreach ($value as $k => $v) {
@@ -134,14 +142,13 @@ trait FlatArrayTrait
}
$this->merge($v, $k, $overwrite);
}
- return;
} else {
//old and new values exist, and one or both are not arrays, $overwrite rules the day
if ($overwrite) {
$this->set($name, $value);
}
- return;
}
+ return $this;
}
/**
@@ -149,10 +156,10 @@ trait FlatArrayTrait
* string. It sets it if $value exists, otherwise it returns the value if it
* exists.
*/
- protected function flattenSearch(?string $name, $value = null, $unset = false)
+ protected function flattenSearch(null|string $name, mixed $value = null, bool $unset = false): mixed
{
if ($value !== null || $unset) {
- $this->_flattenCache = array();
+ $this->_flattenCache = [];
}
if (!isset($this->_flattenCache[$name])) {
$this->_flattenCache[$name] = $this->doFlattenSearch($name, $value, $unset);
@@ -160,7 +167,7 @@ trait FlatArrayTrait
return $this->_flattenCache[$name];
}
- protected function doFlattenSearch(?string $name, $value = null, $unset = false)
+ protected function doFlattenSearch(null|string $name, mixed $value = null, bool $unset = false): mixed
{
//check for home strings
if ($name == '' || $name === null) {
@@ -178,7 +185,7 @@ trait FlatArrayTrait
if ($value !== null) {
foreach ($name as $part) {
if (!isset($parent[$part])) {
- $parent[$part] = array();
+ $parent[$part] = [];
}
$parent = &$parent[$part];
}
@@ -199,9 +206,9 @@ trait FlatArrayTrait
//both value and destination are arrays, merge them
$parent[$key] = array_replace_recursive($parent[$key], $value);
} else {
- //set the hard way
- if (!is_array($parent)) {
- $parent = array();
+ //destination is not an array, to set this we must overwrite it with an empty array
+ if (!is_array(@$parent[$key])) {
+ $parent[$key] = [];
}
$parent[$key] = $value;
}
diff --git a/src/SelfReferencingFlatArray.php b/src/SelfReferencingFlatArray.php
index be12251..ecbe8c4 100644
--- a/src/SelfReferencingFlatArray.php
+++ b/src/SelfReferencingFlatArray.php
@@ -1,13 +1,15 @@
*/
protected $cache = [];
- public function get(string $name = null, bool $raw = false, $unescape = true)
+ public function get(string $name = null, bool $raw = false, bool $unescape = true): mixed
{
$out = parent::get($name);
if ($raw) {
@@ -20,48 +22,29 @@ class SelfReferencingFlatArray extends FlatArray
return $out;
}
- public function set(?string $name, $value)
+ public function set(null|string $name, mixed $value): static
{
$this->cache = [];
- return $this->filter(parent::set($name, $value));
+ $this->filter(parent::set($name, $value));
+ return $this;
}
- public function push(?string $name, $value)
- {
- return $this->filter(parent::push($name, $value));
- }
-
- public function pop(?string $name)
+ public function pop(null|string $name): mixed
{
return $this->filter(parent::pop($name));
}
- public function unshift(?string $name, $value)
- {
- return $this->filter(parent::unshift($name, $value));
- }
-
- public function shift(?string $name)
+ public function shift(null|string $name): mixed
{
return $this->filter(parent::shift($name));
}
- public function rewind()
- {
- return $this->filter(parent::rewind());
- }
-
- public function next()
- {
- return $this->filter(parent::next());
- }
-
- public function current()
+ public function current(): mixed
{
return $this->filter(parent::current());
}
- protected function unescape($value)
+ protected function unescape(mixed $value): mixed
{
//map this function onto array values
if (is_array($value)) {
@@ -88,7 +71,7 @@ class SelfReferencingFlatArray extends FlatArray
/**
* Recursively replace ${var/name} type strings in string values with
*/
- protected function filter($value)
+ protected function filter(mixed $value): mixed
{
//map this function onto array values
if (is_array($value)) {
@@ -114,9 +97,14 @@ class SelfReferencingFlatArray extends FlatArray
return $value;
}
- protected function filter_regex($matches)
+ /**
+ * @param array $matches
+ * @return string
+ */
+ protected function filter_regex(array $matches): string
{
- if (null !== $value = $this->get($matches[1], false, false)) {
+ $value = $this->get($matches[1], false, false);
+ if ($value !== null) {
if (!is_array($value)) {
return $value;
}
diff --git a/tests/Config/ConfigTest.php b/tests/Config/ConfigTest.php
index 54edc70..f12abde 100644
--- a/tests/Config/ConfigTest.php
+++ b/tests/Config/ConfigTest.php
@@ -1,6 +1,8 @@
readFile(__DIR__.'/configtest.json');
+ $a->readFile(__DIR__ . '/configtest.json');
$this->assertEquals($data, $a->get());
//yaml
$a = new Config();
- $a->readFile(__DIR__.'/configtest.yaml');
+ $a->readFile(__DIR__ . '/configtest.yaml');
$this->assertEquals($data, $a->get());
+ //nonexistant files
+ $a = new Config();
+ $a->readFile(__DIR__ . '/does-not-exist.json');
+ $a->readFile(__DIR__ . '/does-not-exist.yaml');
+ $this->assertEquals([], $a->get());
}
public function testSerializing()
@@ -52,4 +59,16 @@ class ConfigTest extends TestCase
//yaml
$this->assertEquals($data, Spyc::YAMLLoad($c->yaml()));
}
+
+ public function testReadingDirectory()
+ {
+ $config = new Config;
+ $config->readDir(__DIR__ . '/nonexistantdir');
+ $this->assertEquals([], $config->get());
+ $config->readDir(__DIR__ . '/configtestdir');
+ $this->assertEquals('b', $config['ini_file.a']);
+ $this->assertEquals('a', $config['yaml_file']);
+ $this->assertEquals('a', $config['json_file']);
+ $this->assertEquals('a', $config['yml_file']);
+ }
}
diff --git a/tests/Config/configtestdir/inifile.ini b/tests/Config/configtestdir/inifile.ini
new file mode 100644
index 0000000..2aca6aa
--- /dev/null
+++ b/tests/Config/configtestdir/inifile.ini
@@ -0,0 +1,2 @@
+[ini_file]
+a = b
\ No newline at end of file
diff --git a/tests/Config/configtestdir/jsonfile.json b/tests/Config/configtestdir/jsonfile.json
new file mode 100644
index 0000000..f5a5513
--- /dev/null
+++ b/tests/Config/configtestdir/jsonfile.json
@@ -0,0 +1,3 @@
+{
+ "json_file": "a"
+}
\ No newline at end of file
diff --git a/tests/Config/configtestdir/yamlfile.yaml b/tests/Config/configtestdir/yamlfile.yaml
new file mode 100644
index 0000000..089ce12
--- /dev/null
+++ b/tests/Config/configtestdir/yamlfile.yaml
@@ -0,0 +1 @@
+yaml_file: a
\ No newline at end of file
diff --git a/tests/Config/configtestdir/ymlfile.yml b/tests/Config/configtestdir/ymlfile.yml
new file mode 100644
index 0000000..788a785
--- /dev/null
+++ b/tests/Config/configtestdir/ymlfile.yml
@@ -0,0 +1 @@
+yml_file: a
diff --git a/tests/FlatArrayPushPopTest.php b/tests/FlatArrayPushPopTest.php
index 5acdaf2..1afd689 100644
--- a/tests/FlatArrayPushPopTest.php
+++ b/tests/FlatArrayPushPopTest.php
@@ -1,6 +1,8 @@
push(null, 'foo');
$f->push(null, 'bar');
- $this->assertEquals(['foo','bar'], $f->get());
+ $this->assertEquals(['foo', 'bar'], $f->get());
$this->assertEquals('bar', $f->pop(null));
$this->assertEquals(['foo'], $f->get());
$this->assertEquals('foo', $f->pop(null));
$this->assertEquals([], $f->get());
+ $this->assertNull($f->pop(null));
+ }
+
+ public function testPushIndexCreation()
+ {
+ // pushing to a nonexistent index creates it as an array
+ $f = new FlatArray();
+ $f->push('a.b', 'c');
+ $this->assertEquals(['c'], $f['a.b']);
+ $this->assertEquals(['a' => ['b' => ['c']]], $f->get());
+ // pushing to an existing non-array index does nothing
+ $f = new FlatArray(['a' => 'b']);
+ $f->push('a', 'c');
+ $this->assertEquals(['a' => 'b'], $f->get());
+ // poping off a non-array does nothing
+ $this->assertNull($f->pop('a'));
}
public function testShiftUnshift()
@@ -24,10 +42,25 @@ class FlatArrayPushPopTest extends TestCase
$f = new FlatArray();
$f->unshift(null, 'foo');
$f->unshift(null, 'bar');
- $this->assertEquals(['bar','foo'], $f->get());
+ $this->assertEquals(['bar', 'foo'], $f->get());
$this->assertEquals('bar', $f->shift(null));
$this->assertEquals(['foo'], $f->get());
$this->assertEquals('foo', $f->shift(null));
$this->assertEquals([], $f->get());
}
+
+ public function testUnshiftIndexCreation()
+ {
+ // unshifting to a nonexistent index creates it as an array
+ $f = new FlatArray();
+ $f->unshift('a.b', 'c');
+ $this->assertEquals(['c'], $f['a.b']);
+ $this->assertEquals(['a' => ['b' => ['c']]], $f->get());
+ // unshifting to an existing non-array index does nothing
+ $f = new FlatArray(['a' => 'b']);
+ $f->unshift('a', 'c');
+ $this->assertEquals(['a' => 'b'], $f->get());
+ // shifting off a non-array does nothing
+ $this->assertNull($f->shift('a'));
+ }
}
diff --git a/tests/FlatArrayTest.php b/tests/FlatArrayTest.php
index 81b42db..7268e9c 100644
--- a/tests/FlatArrayTest.php
+++ b/tests/FlatArrayTest.php
@@ -1,6 +1,8 @@
'A',
- 'b' => ['c'=>'C']
+ 'b' => ['c' => 'C']
];
$a = new FlatArray($data);
//first level
@@ -21,8 +23,8 @@ class FlatArrayTest extends TestCase
$this->assertEquals('C', $a['b.c']);
$this->assertEquals('C', $a->get('b.c'));
//returning array
- $this->assertEquals(['c'=>'C'], $a['b']);
- $this->assertEquals(['c'=>'C'], $a->get('b'));
+ $this->assertEquals(['c' => 'C'], $a['b']);
+ $this->assertEquals(['c' => 'C'], $a->get('b'));
//returning entire array by requesting null or empty string
$this->assertEquals($data, $a[null]);
$this->assertEquals($data, $a->get());
@@ -62,7 +64,7 @@ class FlatArrayTest extends TestCase
{
$data = [
'a' => 'A',
- 'b' => ['c'=>'C']
+ 'b' => ['c' => 'C']
];
$a = new FlatArray($data);
//setting on first layer
@@ -91,7 +93,7 @@ class FlatArrayTest extends TestCase
public function testSettingFalseyValues()
{
- $a = new FlatArray(['foo'=>['bar'=>'baz']]);
+ $a = new FlatArray(['foo' => ['bar' => 'baz']]);
$a['foo.bar'] = false;
$this->assertFalse($a['foo.bar']);
$a['foo.bar'] = 0;
@@ -104,21 +106,21 @@ class FlatArrayTest extends TestCase
public function testMerginFalseyValues()
{
- $a = new FlatArray(['foo'=>['bar'=>'baz']]);
- $a->merge(['foo'=>['bar'=>false]], null, true);
+ $a = new FlatArray(['foo' => ['bar' => 'baz']]);
+ $a->merge(['foo' => ['bar' => false]], null, true);
$this->assertFalse($a['foo.bar']);
- $a->merge(['foo'=>['bar'=>0]], null, true);
+ $a->merge(['foo' => ['bar' => 0]], null, true);
$this->assertSame(0, $a['foo.bar']);
- $a->merge(['foo'=>['bar'=>'']], null, true);
+ $a->merge(['foo' => ['bar' => '']], null, true);
$this->assertSame('', $a['foo.bar']);
- $a->merge(['foo'=>['bar'=>[]]], null, true);
+ $a->merge(['foo' => ['bar' => []]], null, true);
$this->assertSame([], $a['foo.bar']);
}
public function testCaseSensitivity()
{
$h = new FlatArray([
- 'ABC'=>['ABC'=>'ABC']
+ 'ABC' => ['ABC' => 'ABC']
]);
$this->assertNull($h['abc.abc']);
$this->assertNull($h['Abc.aBC']);
@@ -126,7 +128,7 @@ class FlatArrayTest extends TestCase
public function testAccidentalSubstrings()
{
- $h = new FlatArray(['foo'=>'bar']);
+ $h = new FlatArray(['foo' => 'bar']);
$this->assertNull($h['foo.baz']);
}
@@ -169,7 +171,7 @@ class FlatArrayTest extends TestCase
//overwrite false with mismatched array-ness
$c = new FlatArray($data);
$c->merge([
- 'a' => ['b'=>'c'],
+ 'a' => ['b' => 'c'],
'c' => 'd'
]);
$this->assertEquals('b', $c['a']);
@@ -177,21 +179,116 @@ class FlatArrayTest extends TestCase
//overwrite true with mismatched array-ness
$c = new FlatArray($data);
$c->merge([
- 'a' => ['b'=>'c'],
+ 'a' => ['b' => 'c'],
'c' => 'd'
], null, true);
$this->assertEquals('c', $c['a.b']);
$this->assertEquals('d', $c['c']);
}
+ public function testMergeViaSet()
+ {
+ $arr = new FlatArray([
+ 'a' => [
+ 'a' => 'b',
+ 'c' => 'd'
+ ]
+ ]);
+ $arr->set('a', [
+ 'e' => 'f',
+ 'g' => 'h'
+ ]);
+ $this->assertEquals(
+ [
+ 'a' => [
+ 'a' => 'b',
+ 'c' => 'd',
+ 'e' => 'f',
+ 'g' => 'h'
+ ]
+ ],
+ $arr->get()
+ );
+ }
+
+ public function testNoMergeRootViaSet()
+ {
+ $arr = new FlatArray([
+ 'a' => 'b',
+ 'c' => 'd'
+ ]);
+ $arr->set(null, [
+ 'e' => 'f',
+ 'g' => 'h'
+ ]);
+ $this->assertEquals(
+ [
+ 'e' => 'f',
+ 'g' => 'h'
+ ],
+ $arr->get()
+ );
+ }
+
+ public function testMergeViaSetOverNonArray()
+ {
+ $arr = new FlatArray([
+ 'a' => 'b'
+ ]);
+ $arr->set('a', [
+ 'e' => 'f',
+ 'g' => 'h'
+ ]);
+ $this->assertEquals(
+ [
+ 'a' => [
+ 'e' => 'f',
+ 'g' => 'h'
+ ]
+ ],
+ $arr->get()
+ );
+ }
+
public function testConstructionUnflattening()
{
$arr = new FlatArray([
'foo.bar' => 'baz'
]);
$this->assertEquals(
- ['foo'=>['bar'=>'baz']],
+ ['foo' => ['bar' => 'baz']],
$arr->get()
);
}
+
+ public function testUnset()
+ {
+ $arr = new FlatArray([
+ 'a' => [
+ 'b' => 'c',
+ 'd' => 'e'
+ ]
+ ]);
+ unset($arr['a.b']);
+ $this->assertEquals([
+ 'a' => [
+ 'd' => 'e'
+ ]
+ ], $arr->get());
+ // unset root
+ $arr->unset(null);
+ $this->assertEquals([], $arr->get());
+ }
+
+ public function testForeach()
+ {
+ $reference = [
+ 'b' => 'c',
+ 'd' => 'e'
+ ];
+ $arr = new FlatArray($reference);
+ foreach ($arr as $key => $value) {
+ $this->assertEquals($reference[$key], $value);
+ }
+ }
}
diff --git a/tests/SelfReferencingFlatArrayTest.php b/tests/SelfReferencingFlatArrayTest.php
index 7e3b35c..da99489 100644
--- a/tests/SelfReferencingFlatArrayTest.php
+++ b/tests/SelfReferencingFlatArrayTest.php
@@ -1,6 +1,8 @@
'bar',
- 'bar' => ['baz'=>'qux'],
+ 'bar' => ['baz' => 'qux'],
'test' => [
'foo' => '${foo}',
'bar' => '${bar.baz}',
@@ -49,11 +51,13 @@ class SelfReferencingFlatArrayTest extends TestCase
$this->assertEquals('${foo}', $f['nested.escaped.full']);
$this->assertEquals('${foo}', $f['nested.escaped.left']);
$this->assertEquals('${foo}', $f['nested.escaped.right']);
+ //raw
+ $this->assertEquals('${foo}', $f->get('test.foo', true));
}
public function testSettingFalseyValues()
{
- $a = new SelfReferencingFlatArray(['foo'=>['bar'=>'baz']]);
+ $a = new SelfReferencingFlatArray(['foo' => ['bar' => 'baz']]);
$a['foo.bar'] = false;
$this->assertFalse($a['foo.bar']);
$a['foo.bar'] = 0;
@@ -64,16 +68,53 @@ class SelfReferencingFlatArrayTest extends TestCase
$this->assertSame([], $a['foo.bar']);
}
- public function testMerginFalseyValues()
+ public function testMergingFalseyValues()
{
- $a = new SelfReferencingFlatArray(['foo'=>['bar'=>'baz']]);
- $a->merge(['foo'=>['bar'=>false]], null, true);
+ $a = new SelfReferencingFlatArray(['foo' => ['bar' => 'baz']]);
+ $a->merge(['foo' => ['bar' => false]], null, true);
$this->assertFalse($a['foo.bar']);
- $a->merge(['foo'=>['bar'=>0]], null, true);
+ $a->merge(['foo' => ['bar' => 0]], null, true);
$this->assertSame(0, $a['foo.bar']);
- $a->merge(['foo'=>['bar'=>'']], null, true);
+ $a->merge(['foo' => ['bar' => '']], null, true);
$this->assertSame('', $a['foo.bar']);
- $a->merge(['foo'=>['bar'=>[]]], null, true);
+ $a->merge(['foo' => ['bar' => []]], null, true);
$this->assertSame([], $a['foo.bar']);
}
+
+ public function testForeach()
+ {
+ $reference = [
+ 'a' => 'b',
+ 'b' => '${a}',
+ 'd' => '${b}'
+ ];
+ $arr = new SelfReferencingFlatArray($reference);
+ foreach ($arr as $key => $value) {
+ $this->assertEquals('b', $value);
+ }
+ }
+
+ public function testPop()
+ {
+ $f = new SelfReferencingFlatArray([
+ 'a' => 'b',
+ 'c' => [
+ '${a}'
+ ]
+ ]);
+ $this->assertEquals('b', $f->pop('c'));
+ $this->assertNull($f->pop('c'));
+ }
+
+ public function testShift()
+ {
+ $f = new SelfReferencingFlatArray([
+ 'a' => 'b',
+ 'c' => [
+ '${a}'
+ ]
+ ]);
+ $this->assertEquals('b', $f->shift('c'));
+ $this->assertNull($f->shift('c'));
+ }
}