commit
d64a982582
22 changed files with 460 additions and 198 deletions
14
.github/workflows/phpstan.yml
vendored
Normal file
14
.github/workflows/phpstan.yml
vendored
Normal file
|
@ -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
|
11
.github/workflows/phpunit.yml
vendored
Normal file
11
.github/workflows/phpunit.yml
vendored
Normal file
|
@ -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
|
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -1,2 +1,4 @@
|
||||||
/vendor/
|
/vendor
|
||||||
composer.lock
|
/composer.lock
|
||||||
|
/.phpunit.result.cache
|
||||||
|
/coverage
|
|
@ -1,6 +1,7 @@
|
||||||
# Flatrr
|
# 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)
|
[![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)
|
[![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)
|
[![Latest Unstable Version](http://poser.pugx.org/byjoby/flatrr/v/unstable)](https://packagist.org/packages/byjoby/flatrr)
|
||||||
|
|
|
@ -3,12 +3,16 @@
|
||||||
"description": "A library for working with multi-dimensional arrays through flattened keys",
|
"description": "A library for working with multi-dimensional arrays through flattened keys",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"authors": [{
|
"authors": [
|
||||||
"name": "Joby Elliott",
|
{
|
||||||
"email": "joby@byjoby.com"
|
"name": "Joby Elliott",
|
||||||
}],
|
"email": "joby@byjoby.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^7.3"
|
"phpunit/phpunit": "^9.5",
|
||||||
|
"phpstan/phpstan": "^1.9",
|
||||||
|
"squizlabs/php_codesniffer": "^3.7"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
@ -21,12 +25,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": [
|
"test": "phpunit",
|
||||||
"phpunit"
|
"stan": "phpstan",
|
||||||
]
|
"sniff": "phpcs"
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=7.1",
|
"php": ">=8.1",
|
||||||
"mustangostang/spyc": "^0.6.3"
|
"mustangostang/spyc": "^0.6.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
19
phpcs.xml
Normal file
19
phpcs.xml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="PHP_CodeSniffer"
|
||||||
|
xsi:noNamespaceSchemaLocation="./vendor/squizlabs/php_codesniffer/phpcs.xsd">
|
||||||
|
<description>Coding Standard</description>
|
||||||
|
|
||||||
|
<file>src</file>
|
||||||
|
|
||||||
|
<arg name="basepath" value="." />
|
||||||
|
<arg name="colors" />
|
||||||
|
<arg name="parallel" value="75" />
|
||||||
|
<arg value="np" />
|
||||||
|
|
||||||
|
<rule ref="PSR12">
|
||||||
|
<exclude name="Generic.Files.LineEndings" />
|
||||||
|
<exclude name="Generic.NamingConventions.CamelCapsFunctionName" />
|
||||||
|
<exclude name="PSR1.Methods.CamelCapsMethodName" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
</ruleset>
|
4
phpstan.neon
Normal file
4
phpstan.neon
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
parameters:
|
||||||
|
level: 7
|
||||||
|
paths:
|
||||||
|
- src
|
32
phpunit.xml
32
phpunit.xml
|
@ -1,7 +1,31 @@
|
||||||
<phpunit bootstrap="vendor/autoload.php">
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<phpunit
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||||
|
colors="true"
|
||||||
|
executionOrder="random"
|
||||||
|
failOnWarning="true"
|
||||||
|
failOnRisky="true"
|
||||||
|
failOnEmptyTestSuite="true"
|
||||||
|
beStrictAboutOutputDuringTests="true"
|
||||||
|
verbose="true"
|
||||||
|
bootstrap="vendor/autoload.php">
|
||||||
|
<php>
|
||||||
|
<ini name="display_errors" value="On" />
|
||||||
|
<ini name="error_reporting" value="-1" />
|
||||||
|
<ini name="xdebug.mode" value="coverage" />
|
||||||
|
</php>
|
||||||
<testsuites>
|
<testsuites>
|
||||||
<testsuite name="All">
|
<testsuite name="Tests">
|
||||||
<directory>tests</directory>
|
<directory>tests/</directory>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
</testsuites>
|
</testsuites>
|
||||||
</phpunit>
|
<coverage>
|
||||||
|
<include>
|
||||||
|
<directory suffix=".php">src</directory>
|
||||||
|
</include>
|
||||||
|
<report>
|
||||||
|
<html outputDirectory="coverage" lowUpperBound="50" highLowerBound="90" />
|
||||||
|
</report>
|
||||||
|
</coverage>
|
||||||
|
</phpunit>
|
|
@ -1,5 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
/* Flatrr | https://gitlab.com/byjoby/flatrr | MIT License */
|
|
||||||
|
/* Flatrr | https://github.com/jobyone/flatrr | MIT License */
|
||||||
|
|
||||||
namespace Flatrr\Config;
|
namespace Flatrr\Config;
|
||||||
|
|
||||||
|
@ -8,98 +9,68 @@ use Spyc;
|
||||||
|
|
||||||
class Config extends SelfReferencingFlatArray implements ConfigInterface
|
class Config extends SelfReferencingFlatArray implements ConfigInterface
|
||||||
{
|
{
|
||||||
public $strict = false;
|
public function readDir(string $dir, string $name = null, bool $overwrite = false): static
|
||||||
|
|
||||||
public function readDir($dir, string $name = null, bool $overwrite = false)
|
|
||||||
{
|
{
|
||||||
$dir = realpath($dir);
|
$dir = realpath($dir);
|
||||||
if (!$dir || !is_dir($dir)) {
|
if ($dir && is_dir($dir)) {
|
||||||
return;
|
$glob = glob("$dir/*");
|
||||||
}
|
if ($glob) {
|
||||||
foreach (glob("$dir/*") as $f) {
|
foreach ($glob as $f) {
|
||||||
if (is_file($f)) {
|
if (is_file($f)) {
|
||||||
$this->readFile($f, $name, $overwrite);
|
$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;
|
return json_encode($this->get(null, $raw), JSON_PRETTY_PRINT); // @phpstan-ignore-line
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function parse_yaml($input)
|
public function yaml(bool $raw = false): string
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
return Spyc::YAMLDump($this->get(null, $raw), 2);
|
return Spyc::YAMLDump($this->get(null, $raw), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function read_ini($filename)
|
/** @return array<mixed|mixed> */
|
||||||
|
protected function read_ini(string $filename): false|array
|
||||||
{
|
{
|
||||||
return parse_ini_file($filename, true);
|
return parse_ini_file($filename, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function read_json($filename)
|
/** @return array<mixed|mixed> */
|
||||||
|
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<mixed|mixed> */
|
||||||
|
protected function read_yaml(string $filename): array
|
||||||
{
|
{
|
||||||
return Spyc::YAMLLoad($filename);
|
return Spyc::YAMLLoad($filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function read_yml($filename)
|
/** @return array<mixed|mixed> */
|
||||||
|
protected function read_yml(string $filename): array
|
||||||
{
|
{
|
||||||
return $this->read_yaml($filename);
|
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));
|
$format = strtolower(preg_replace('/.+\./', '', $filename));
|
||||||
$fn = 'read_' . $format;
|
$fn = 'read_' . $format;
|
||||||
if (!method_exists($this, $fn)) {
|
if (is_file($filename) && is_readable($filename) && method_exists($this, $fn)) {
|
||||||
if ($this->strict) {
|
$data = $this->$fn($filename);
|
||||||
throw new \Exception("Don't know how to read the format \"$format\"");
|
if ($data !== null) {
|
||||||
} else {
|
$this->merge($data, $name, $overwrite);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$data = $this->$fn($filename);
|
return $this;
|
||||||
if (!$data) {
|
|
||||||
if ($this->strict) {
|
|
||||||
throw new \Exception("Error reading \"" . $filename . "\"");
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->merge($data, $name, $overwrite);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
<?php
|
<?php
|
||||||
/* Flatrr | https://gitlab.com/byjoby/flatrr | MIT License */
|
|
||||||
|
/* Flatrr | https://github.com/jobyone/flatrr | MIT License */
|
||||||
|
|
||||||
namespace Flatrr\Config;
|
namespace Flatrr\Config;
|
||||||
|
|
||||||
interface ConfigInterface extends \ArrayAccess
|
use Flatrr\FlatArrayInterface;
|
||||||
|
|
||||||
|
interface ConfigInterface extends FlatArrayInterface
|
||||||
{
|
{
|
||||||
public function readFile($filename, string $name = null, bool $overwrite = false);
|
public function readDir(string $dir, string $name = null, bool $overwrite = false): static;
|
||||||
public function json($raw = false) : string;
|
public function readFile(string $filename, string $name = null, bool $overwrite = false): static;
|
||||||
public function yaml($raw = false) : string;
|
public function json(bool $raw = false): string;
|
||||||
public function get(string $name = null, bool $raw = false);
|
public function yaml(bool $raw = false): string;
|
||||||
public function merge($value, string $name = null, bool $overwrite = false);
|
public function get(null|string $name = null, bool $raw = false): mixed;
|
||||||
|
public function merge(mixed $value, string $name = null, bool $overwrite = false): static;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
<?php
|
<?php
|
||||||
/* Flatrr | https://gitlab.com/byjoby/flatrr | MIT License */
|
|
||||||
|
/* Flatrr | https://github.com/jobyone/flatrr | MIT License */
|
||||||
|
|
||||||
namespace Flatrr;
|
namespace Flatrr;
|
||||||
|
|
||||||
class FlatArray implements FlatArrayInterface
|
class FlatArray implements FlatArrayInterface
|
||||||
{
|
{
|
||||||
use FlatArrayTrait;
|
use FlatArrayTrait;
|
||||||
|
|
||||||
public function __construct(array $data = null)
|
/**
|
||||||
|
* @param null|array<string|mixed> $data
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(null|array $data = null)
|
||||||
{
|
{
|
||||||
$this->merge($data);
|
$this->merge($data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
/* Flatrr | https://gitlab.com/byjoby/flatrr | MIT License */
|
|
||||||
|
/* Flatrr | https://github.com/jobyone/flatrr | MIT License */
|
||||||
|
|
||||||
namespace Flatrr;
|
namespace Flatrr;
|
||||||
|
|
||||||
interface FlatArrayInterface extends \ArrayAccess, \Iterator
|
use ArrayAccess;
|
||||||
{
|
use Iterator;
|
||||||
public function set(?string $name, $value);
|
|
||||||
public function get(?string $name = null);
|
|
||||||
public function unset(?string $name);
|
|
||||||
public function merge($value, string $name = null, bool $overwrite = false);
|
|
||||||
|
|
||||||
public function push(?string $name, $value);
|
/**
|
||||||
public function pop(?string $name);
|
* @extends ArrayAccess<string,mixed>
|
||||||
public function unshift(?string $name, $value);
|
* @extends Iterator<string,mixed>
|
||||||
public function shift(?string $name);
|
*/
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,117 +1,126 @@
|
||||||
<?php
|
<?php
|
||||||
/* Flatrr | https://gitlab.com/byjoby/flatrr | MIT License */
|
|
||||||
|
/* Flatrr | https://github.com/jobyone/flatrr | MIT License */
|
||||||
|
|
||||||
namespace Flatrr;
|
namespace Flatrr;
|
||||||
|
|
||||||
trait FlatArrayTrait
|
trait FlatArrayTrait
|
||||||
{
|
{
|
||||||
private $_arrayData = array();
|
/** @var array<string|mixed> */
|
||||||
private $_flattenCache = array();
|
protected $_arrayData = [];
|
||||||
|
/** @var array<string|mixed> */
|
||||||
|
protected $_flattenCache = [];
|
||||||
|
|
||||||
public function push(?string $name, $value)
|
public function push(null|string $name, mixed $value): static
|
||||||
{
|
{
|
||||||
$arr = $this->flattenSearch($name);
|
$arr = $this->flattenSearch($name);
|
||||||
if ($arr !== null && !is_array($arr)) {
|
if ($arr !== null && !is_array($arr)) {
|
||||||
return;
|
return $this;
|
||||||
}
|
}
|
||||||
if ($arr === null) {
|
if ($arr === null) {
|
||||||
$arr = [];
|
$arr = [];
|
||||||
}
|
}
|
||||||
$arr[] = $value;
|
$arr[] = $value;
|
||||||
$this->set($name, $arr);
|
$this->set($name, $arr);
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function pop(?string $name)
|
public function pop(null|string $name): mixed
|
||||||
{
|
{
|
||||||
$arr = $this->flattenSearch($name);
|
$arr = $this->flattenSearch($name);
|
||||||
if ($arr !== null && !is_array($arr)) {
|
if ($arr !== null && !is_array($arr)) {
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
$out = array_pop($arr);
|
$out = array_pop($arr);
|
||||||
|
$this->unset($name);
|
||||||
$this->set($name, $arr);
|
$this->set($name, $arr);
|
||||||
return $out;
|
return $out;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function unshift(?string $name, $value)
|
public function unshift(null|string $name, mixed $value): static
|
||||||
{
|
{
|
||||||
$arr = $this->flattenSearch($name);
|
$arr = $this->flattenSearch($name);
|
||||||
if ($arr !== null && !is_array($arr)) {
|
if ($arr !== null && !is_array($arr)) {
|
||||||
return;
|
return $this;
|
||||||
}
|
}
|
||||||
if ($arr === null) {
|
if ($arr === null) {
|
||||||
$arr = [];
|
$arr = [];
|
||||||
}
|
}
|
||||||
array_unshift($arr, $value);
|
array_unshift($arr, $value);
|
||||||
$this->set($name, $arr);
|
$this->set($name, $arr);
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function shift(?string $name)
|
public function shift(null|string $name): mixed
|
||||||
{
|
{
|
||||||
$arr = $this->flattenSearch($name);
|
$arr = $this->flattenSearch($name);
|
||||||
if ($arr !== null && !is_array($arr)) {
|
if ($arr !== null && !is_array($arr)) {
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
$out = array_shift($arr);
|
$out = array_shift($arr);
|
||||||
|
$this->unset($name);
|
||||||
$this->set($name, $arr);
|
$this->set($name, $arr);
|
||||||
return $out;
|
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);
|
return $this->flattenSearch($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
function unset(?string $name)
|
public function unset(null|string $name): static
|
||||||
{
|
{
|
||||||
$this->flattenSearch($name, null, true);
|
$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);
|
return $this->get($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function offsetExists($name)
|
public function offsetExists($name): bool
|
||||||
{
|
{
|
||||||
return $this->flattenSearch($name) !== null;
|
return $this->flattenSearch($name) !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function offsetUnset($name)
|
public function offsetUnset($name): void
|
||||||
{
|
{
|
||||||
$this->unset($name);
|
$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);
|
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);
|
return key($this->_arrayData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function valid()
|
public function valid(): bool
|
||||||
{
|
{
|
||||||
return isset($this->_arrayData[$this->key()]);
|
return isset($this->_arrayData[$this->key()]);
|
||||||
}
|
}
|
||||||
|
@ -120,12 +129,11 @@ trait FlatArrayTrait
|
||||||
* Recursively set a value, with control over whether existing values or new
|
* Recursively set a value, with control over whether existing values or new
|
||||||
* values take precedence
|
* 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])) {
|
if (!isset($this[$name])) {
|
||||||
//easiest possible outcome, old value doesn't exist, so we can just write the value
|
//easiest possible outcome, old value doesn't exist, so we can just write the value
|
||||||
$this->set($name, $value);
|
$this->set($name, $value);
|
||||||
return;
|
|
||||||
} elseif (is_array($value) && is_array($this->flattenSearch($name))) {
|
} elseif (is_array($value) && is_array($this->flattenSearch($name))) {
|
||||||
//both new and old values are arrays
|
//both new and old values are arrays
|
||||||
foreach ($value as $k => $v) {
|
foreach ($value as $k => $v) {
|
||||||
|
@ -134,14 +142,13 @@ trait FlatArrayTrait
|
||||||
}
|
}
|
||||||
$this->merge($v, $k, $overwrite);
|
$this->merge($v, $k, $overwrite);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
//old and new values exist, and one or both are not arrays, $overwrite rules the day
|
//old and new values exist, and one or both are not arrays, $overwrite rules the day
|
||||||
if ($overwrite) {
|
if ($overwrite) {
|
||||||
$this->set($name, $value);
|
$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
|
* string. It sets it if $value exists, otherwise it returns the value if it
|
||||||
* exists.
|
* 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) {
|
if ($value !== null || $unset) {
|
||||||
$this->_flattenCache = array();
|
$this->_flattenCache = [];
|
||||||
}
|
}
|
||||||
if (!isset($this->_flattenCache[$name])) {
|
if (!isset($this->_flattenCache[$name])) {
|
||||||
$this->_flattenCache[$name] = $this->doFlattenSearch($name, $value, $unset);
|
$this->_flattenCache[$name] = $this->doFlattenSearch($name, $value, $unset);
|
||||||
|
@ -160,7 +167,7 @@ trait FlatArrayTrait
|
||||||
return $this->_flattenCache[$name];
|
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
|
//check for home strings
|
||||||
if ($name == '' || $name === null) {
|
if ($name == '' || $name === null) {
|
||||||
|
@ -178,7 +185,7 @@ trait FlatArrayTrait
|
||||||
if ($value !== null) {
|
if ($value !== null) {
|
||||||
foreach ($name as $part) {
|
foreach ($name as $part) {
|
||||||
if (!isset($parent[$part])) {
|
if (!isset($parent[$part])) {
|
||||||
$parent[$part] = array();
|
$parent[$part] = [];
|
||||||
}
|
}
|
||||||
$parent = &$parent[$part];
|
$parent = &$parent[$part];
|
||||||
}
|
}
|
||||||
|
@ -199,9 +206,9 @@ trait FlatArrayTrait
|
||||||
//both value and destination are arrays, merge them
|
//both value and destination are arrays, merge them
|
||||||
$parent[$key] = array_replace_recursive($parent[$key], $value);
|
$parent[$key] = array_replace_recursive($parent[$key], $value);
|
||||||
} else {
|
} else {
|
||||||
//set the hard way
|
//destination is not an array, to set this we must overwrite it with an empty array
|
||||||
if (!is_array($parent)) {
|
if (!is_array(@$parent[$key])) {
|
||||||
$parent = array();
|
$parent[$key] = [];
|
||||||
}
|
}
|
||||||
$parent[$key] = $value;
|
$parent[$key] = $value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
/* Flatrr | https://gitlab.com/byjoby/flatrr | MIT License */
|
|
||||||
|
/* Flatrr | https://github.com/jobyone/flatrr | MIT License */
|
||||||
|
|
||||||
namespace Flatrr;
|
namespace Flatrr;
|
||||||
|
|
||||||
class SelfReferencingFlatArray extends FlatArray
|
class SelfReferencingFlatArray extends FlatArray
|
||||||
{
|
{
|
||||||
|
/** @var array<string,string> */
|
||||||
protected $cache = [];
|
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);
|
$out = parent::get($name);
|
||||||
if ($raw) {
|
if ($raw) {
|
||||||
|
@ -20,48 +22,29 @@ class SelfReferencingFlatArray extends FlatArray
|
||||||
return $out;
|
return $out;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function set(?string $name, $value)
|
public function set(null|string $name, mixed $value): static
|
||||||
{
|
{
|
||||||
$this->cache = [];
|
$this->cache = [];
|
||||||
return $this->filter(parent::set($name, $value));
|
$this->filter(parent::set($name, $value));
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function push(?string $name, $value)
|
public function pop(null|string $name): mixed
|
||||||
{
|
|
||||||
return $this->filter(parent::push($name, $value));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function pop(?string $name)
|
|
||||||
{
|
{
|
||||||
return $this->filter(parent::pop($name));
|
return $this->filter(parent::pop($name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function unshift(?string $name, $value)
|
public function shift(null|string $name): mixed
|
||||||
{
|
|
||||||
return $this->filter(parent::unshift($name, $value));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function shift(?string $name)
|
|
||||||
{
|
{
|
||||||
return $this->filter(parent::shift($name));
|
return $this->filter(parent::shift($name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rewind()
|
public function current(): mixed
|
||||||
{
|
|
||||||
return $this->filter(parent::rewind());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function next()
|
|
||||||
{
|
|
||||||
return $this->filter(parent::next());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function current()
|
|
||||||
{
|
{
|
||||||
return $this->filter(parent::current());
|
return $this->filter(parent::current());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function unescape($value)
|
protected function unescape(mixed $value): mixed
|
||||||
{
|
{
|
||||||
//map this function onto array values
|
//map this function onto array values
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
|
@ -88,7 +71,7 @@ class SelfReferencingFlatArray extends FlatArray
|
||||||
/**
|
/**
|
||||||
* Recursively replace ${var/name} type strings in string values with
|
* 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
|
//map this function onto array values
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
|
@ -114,9 +97,14 @@ class SelfReferencingFlatArray extends FlatArray
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function filter_regex($matches)
|
/**
|
||||||
|
* @param array<int,null|string> $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)) {
|
if (!is_array($value)) {
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
/* Flatrr | https://gitlab.com/byjoby/flatrr | MIT License */
|
/* Flatrr | https://github.com/jobyone/flatrr | MIT License */
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Flatrr\Config;
|
namespace Flatrr\Config;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
@ -30,12 +32,17 @@ class ConfigTest extends TestCase
|
||||||
];
|
];
|
||||||
//json
|
//json
|
||||||
$a = new Config();
|
$a = new Config();
|
||||||
$a->readFile(__DIR__.'/configtest.json');
|
$a->readFile(__DIR__ . '/configtest.json');
|
||||||
$this->assertEquals($data, $a->get());
|
$this->assertEquals($data, $a->get());
|
||||||
//yaml
|
//yaml
|
||||||
$a = new Config();
|
$a = new Config();
|
||||||
$a->readFile(__DIR__.'/configtest.yaml');
|
$a->readFile(__DIR__ . '/configtest.yaml');
|
||||||
$this->assertEquals($data, $a->get());
|
$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()
|
public function testSerializing()
|
||||||
|
@ -52,4 +59,16 @@ class ConfigTest extends TestCase
|
||||||
//yaml
|
//yaml
|
||||||
$this->assertEquals($data, Spyc::YAMLLoad($c->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']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
2
tests/Config/configtestdir/inifile.ini
Normal file
2
tests/Config/configtestdir/inifile.ini
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[ini_file]
|
||||||
|
a = b
|
3
tests/Config/configtestdir/jsonfile.json
Normal file
3
tests/Config/configtestdir/jsonfile.json
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"json_file": "a"
|
||||||
|
}
|
1
tests/Config/configtestdir/yamlfile.yaml
Normal file
1
tests/Config/configtestdir/yamlfile.yaml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
yaml_file: a
|
1
tests/Config/configtestdir/ymlfile.yml
Normal file
1
tests/Config/configtestdir/ymlfile.yml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
yml_file: a
|
|
@ -1,6 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
/* Flatrr | https://gitlab.com/byjoby/flatrr | MIT License */
|
/* Flatrr | https://github.com/jobyone/flatrr | MIT License */
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Flatrr;
|
namespace Flatrr;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
@ -12,11 +14,27 @@ class FlatArrayPushPopTest extends TestCase
|
||||||
$f = new FlatArray();
|
$f = new FlatArray();
|
||||||
$f->push(null, 'foo');
|
$f->push(null, 'foo');
|
||||||
$f->push(null, 'bar');
|
$f->push(null, 'bar');
|
||||||
$this->assertEquals(['foo','bar'], $f->get());
|
$this->assertEquals(['foo', 'bar'], $f->get());
|
||||||
$this->assertEquals('bar', $f->pop(null));
|
$this->assertEquals('bar', $f->pop(null));
|
||||||
$this->assertEquals(['foo'], $f->get());
|
$this->assertEquals(['foo'], $f->get());
|
||||||
$this->assertEquals('foo', $f->pop(null));
|
$this->assertEquals('foo', $f->pop(null));
|
||||||
$this->assertEquals([], $f->get());
|
$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()
|
public function testShiftUnshift()
|
||||||
|
@ -24,10 +42,25 @@ class FlatArrayPushPopTest extends TestCase
|
||||||
$f = new FlatArray();
|
$f = new FlatArray();
|
||||||
$f->unshift(null, 'foo');
|
$f->unshift(null, 'foo');
|
||||||
$f->unshift(null, 'bar');
|
$f->unshift(null, 'bar');
|
||||||
$this->assertEquals(['bar','foo'], $f->get());
|
$this->assertEquals(['bar', 'foo'], $f->get());
|
||||||
$this->assertEquals('bar', $f->shift(null));
|
$this->assertEquals('bar', $f->shift(null));
|
||||||
$this->assertEquals(['foo'], $f->get());
|
$this->assertEquals(['foo'], $f->get());
|
||||||
$this->assertEquals('foo', $f->shift(null));
|
$this->assertEquals('foo', $f->shift(null));
|
||||||
$this->assertEquals([], $f->get());
|
$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'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
/* Flatrr | https://gitlab.com/byjoby/flatrr | MIT License */
|
/* Flatrr | https://github.com/jobyone/flatrr | MIT License */
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Flatrr;
|
namespace Flatrr;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
@ -11,7 +13,7 @@ class FlatArrayTest extends TestCase
|
||||||
{
|
{
|
||||||
$data = [
|
$data = [
|
||||||
'a' => 'A',
|
'a' => 'A',
|
||||||
'b' => ['c'=>'C']
|
'b' => ['c' => 'C']
|
||||||
];
|
];
|
||||||
$a = new FlatArray($data);
|
$a = new FlatArray($data);
|
||||||
//first level
|
//first level
|
||||||
|
@ -21,8 +23,8 @@ class FlatArrayTest extends TestCase
|
||||||
$this->assertEquals('C', $a['b.c']);
|
$this->assertEquals('C', $a['b.c']);
|
||||||
$this->assertEquals('C', $a->get('b.c'));
|
$this->assertEquals('C', $a->get('b.c'));
|
||||||
//returning array
|
//returning array
|
||||||
$this->assertEquals(['c'=>'C'], $a['b']);
|
$this->assertEquals(['c' => 'C'], $a['b']);
|
||||||
$this->assertEquals(['c'=>'C'], $a->get('b'));
|
$this->assertEquals(['c' => 'C'], $a->get('b'));
|
||||||
//returning entire array by requesting null or empty string
|
//returning entire array by requesting null or empty string
|
||||||
$this->assertEquals($data, $a[null]);
|
$this->assertEquals($data, $a[null]);
|
||||||
$this->assertEquals($data, $a->get());
|
$this->assertEquals($data, $a->get());
|
||||||
|
@ -62,7 +64,7 @@ class FlatArrayTest extends TestCase
|
||||||
{
|
{
|
||||||
$data = [
|
$data = [
|
||||||
'a' => 'A',
|
'a' => 'A',
|
||||||
'b' => ['c'=>'C']
|
'b' => ['c' => 'C']
|
||||||
];
|
];
|
||||||
$a = new FlatArray($data);
|
$a = new FlatArray($data);
|
||||||
//setting on first layer
|
//setting on first layer
|
||||||
|
@ -91,7 +93,7 @@ class FlatArrayTest extends TestCase
|
||||||
|
|
||||||
public function testSettingFalseyValues()
|
public function testSettingFalseyValues()
|
||||||
{
|
{
|
||||||
$a = new FlatArray(['foo'=>['bar'=>'baz']]);
|
$a = new FlatArray(['foo' => ['bar' => 'baz']]);
|
||||||
$a['foo.bar'] = false;
|
$a['foo.bar'] = false;
|
||||||
$this->assertFalse($a['foo.bar']);
|
$this->assertFalse($a['foo.bar']);
|
||||||
$a['foo.bar'] = 0;
|
$a['foo.bar'] = 0;
|
||||||
|
@ -104,21 +106,21 @@ class FlatArrayTest extends TestCase
|
||||||
|
|
||||||
public function testMerginFalseyValues()
|
public function testMerginFalseyValues()
|
||||||
{
|
{
|
||||||
$a = new FlatArray(['foo'=>['bar'=>'baz']]);
|
$a = new FlatArray(['foo' => ['bar' => 'baz']]);
|
||||||
$a->merge(['foo'=>['bar'=>false]], null, true);
|
$a->merge(['foo' => ['bar' => false]], null, true);
|
||||||
$this->assertFalse($a['foo.bar']);
|
$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']);
|
$this->assertSame(0, $a['foo.bar']);
|
||||||
$a->merge(['foo'=>['bar'=>'']], null, true);
|
$a->merge(['foo' => ['bar' => '']], null, true);
|
||||||
$this->assertSame('', $a['foo.bar']);
|
$this->assertSame('', $a['foo.bar']);
|
||||||
$a->merge(['foo'=>['bar'=>[]]], null, true);
|
$a->merge(['foo' => ['bar' => []]], null, true);
|
||||||
$this->assertSame([], $a['foo.bar']);
|
$this->assertSame([], $a['foo.bar']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCaseSensitivity()
|
public function testCaseSensitivity()
|
||||||
{
|
{
|
||||||
$h = new FlatArray([
|
$h = new FlatArray([
|
||||||
'ABC'=>['ABC'=>'ABC']
|
'ABC' => ['ABC' => 'ABC']
|
||||||
]);
|
]);
|
||||||
$this->assertNull($h['abc.abc']);
|
$this->assertNull($h['abc.abc']);
|
||||||
$this->assertNull($h['Abc.aBC']);
|
$this->assertNull($h['Abc.aBC']);
|
||||||
|
@ -126,7 +128,7 @@ class FlatArrayTest extends TestCase
|
||||||
|
|
||||||
public function testAccidentalSubstrings()
|
public function testAccidentalSubstrings()
|
||||||
{
|
{
|
||||||
$h = new FlatArray(['foo'=>'bar']);
|
$h = new FlatArray(['foo' => 'bar']);
|
||||||
$this->assertNull($h['foo.baz']);
|
$this->assertNull($h['foo.baz']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +171,7 @@ class FlatArrayTest extends TestCase
|
||||||
//overwrite false with mismatched array-ness
|
//overwrite false with mismatched array-ness
|
||||||
$c = new FlatArray($data);
|
$c = new FlatArray($data);
|
||||||
$c->merge([
|
$c->merge([
|
||||||
'a' => ['b'=>'c'],
|
'a' => ['b' => 'c'],
|
||||||
'c' => 'd'
|
'c' => 'd'
|
||||||
]);
|
]);
|
||||||
$this->assertEquals('b', $c['a']);
|
$this->assertEquals('b', $c['a']);
|
||||||
|
@ -177,21 +179,116 @@ class FlatArrayTest extends TestCase
|
||||||
//overwrite true with mismatched array-ness
|
//overwrite true with mismatched array-ness
|
||||||
$c = new FlatArray($data);
|
$c = new FlatArray($data);
|
||||||
$c->merge([
|
$c->merge([
|
||||||
'a' => ['b'=>'c'],
|
'a' => ['b' => 'c'],
|
||||||
'c' => 'd'
|
'c' => 'd'
|
||||||
], null, true);
|
], null, true);
|
||||||
$this->assertEquals('c', $c['a.b']);
|
$this->assertEquals('c', $c['a.b']);
|
||||||
$this->assertEquals('d', $c['c']);
|
$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()
|
public function testConstructionUnflattening()
|
||||||
{
|
{
|
||||||
$arr = new FlatArray([
|
$arr = new FlatArray([
|
||||||
'foo.bar' => 'baz'
|
'foo.bar' => 'baz'
|
||||||
]);
|
]);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
['foo'=>['bar'=>'baz']],
|
['foo' => ['bar' => 'baz']],
|
||||||
$arr->get()
|
$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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
/* Flatrr | https://gitlab.com/byjoby/flatrr | MIT License */
|
/* Flatrr | https://github.com/jobyone/flatrr | MIT License */
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Flatrr;
|
namespace Flatrr;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
@ -11,7 +13,7 @@ class SelfReferencingFlatArrayTest extends TestCase
|
||||||
{
|
{
|
||||||
$f = new SelfReferencingFlatArray([
|
$f = new SelfReferencingFlatArray([
|
||||||
'foo' => 'bar',
|
'foo' => 'bar',
|
||||||
'bar' => ['baz'=>'qux'],
|
'bar' => ['baz' => 'qux'],
|
||||||
'test' => [
|
'test' => [
|
||||||
'foo' => '${foo}',
|
'foo' => '${foo}',
|
||||||
'bar' => '${bar.baz}',
|
'bar' => '${bar.baz}',
|
||||||
|
@ -49,11 +51,13 @@ class SelfReferencingFlatArrayTest extends TestCase
|
||||||
$this->assertEquals('${foo}', $f['nested.escaped.full']);
|
$this->assertEquals('${foo}', $f['nested.escaped.full']);
|
||||||
$this->assertEquals('${foo}', $f['nested.escaped.left']);
|
$this->assertEquals('${foo}', $f['nested.escaped.left']);
|
||||||
$this->assertEquals('${foo}', $f['nested.escaped.right']);
|
$this->assertEquals('${foo}', $f['nested.escaped.right']);
|
||||||
|
//raw
|
||||||
|
$this->assertEquals('${foo}', $f->get('test.foo', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSettingFalseyValues()
|
public function testSettingFalseyValues()
|
||||||
{
|
{
|
||||||
$a = new SelfReferencingFlatArray(['foo'=>['bar'=>'baz']]);
|
$a = new SelfReferencingFlatArray(['foo' => ['bar' => 'baz']]);
|
||||||
$a['foo.bar'] = false;
|
$a['foo.bar'] = false;
|
||||||
$this->assertFalse($a['foo.bar']);
|
$this->assertFalse($a['foo.bar']);
|
||||||
$a['foo.bar'] = 0;
|
$a['foo.bar'] = 0;
|
||||||
|
@ -64,16 +68,53 @@ class SelfReferencingFlatArrayTest extends TestCase
|
||||||
$this->assertSame([], $a['foo.bar']);
|
$this->assertSame([], $a['foo.bar']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMerginFalseyValues()
|
public function testMergingFalseyValues()
|
||||||
{
|
{
|
||||||
$a = new SelfReferencingFlatArray(['foo'=>['bar'=>'baz']]);
|
$a = new SelfReferencingFlatArray(['foo' => ['bar' => 'baz']]);
|
||||||
$a->merge(['foo'=>['bar'=>false]], null, true);
|
$a->merge(['foo' => ['bar' => false]], null, true);
|
||||||
$this->assertFalse($a['foo.bar']);
|
$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']);
|
$this->assertSame(0, $a['foo.bar']);
|
||||||
$a->merge(['foo'=>['bar'=>'']], null, true);
|
$a->merge(['foo' => ['bar' => '']], null, true);
|
||||||
$this->assertSame('', $a['foo.bar']);
|
$this->assertSame('', $a['foo.bar']);
|
||||||
$a->merge(['foo'=>['bar'=>[]]], null, true);
|
$a->merge(['foo' => ['bar' => []]], null, true);
|
||||||
$this->assertSame([], $a['foo.bar']);
|
$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'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue