[Agavi-Commits] r4917 - in branches/config-1.1: samples/app/config src/config/util/dom test/tests/unit/config/util/dom

0 views
Skip to first unread message

com...@lists.agavi.org

unread,
Dec 30, 2011, 3:00:16 PM12/30/11
to com...@lists.agavi.org
Author: david
Date: 2011-12-30 21:00:13 +0100 (Fri, 30 Dec 2011)
New Revision: 4917

Modified:
branches/config-1.1/samples/app/config/factories.xml
branches/config-1.1/src/config/util/dom/AgaviXmlConfigDomElement.class.php
branches/config-1.1/test/tests/unit/config/util/dom/AgaviXmlConfigDomElementTest.php
Log:
first and incomplete (as in edge cases not tested/specced) implementation of merge modes for configuration parameters as detailed in AEP-101, refs #1466

Modified: branches/config-1.1/samples/app/config/factories.xml
===================================================================
--- branches/config-1.1/samples/app/config/factories.xml 2011-12-30 19:49:52 UTC (rev 4916)
+++ branches/config-1.1/samples/app/config/factories.xml 2011-12-30 20:00:13 UTC (rev 4917)
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<ae:configurations xmlns:ae="http://agavi.org/agavi/config/global/envelope/1.1" xmlns="http://agavi.org/agavi/config/parts/factories/1.1">
+<ae:configurations xmlns:ae="http://agavi.org/agavi/config/global/envelope/1.0" xmlns="http://agavi.org/agavi/config/parts/factories/1.0">

<ae:configuration>

Modified: branches/config-1.1/src/config/util/dom/AgaviXmlConfigDomElement.class.php
===================================================================
--- branches/config-1.1/src/config/util/dom/AgaviXmlConfigDomElement.class.php 2011-12-30 19:49:52 UTC (rev 4916)
+++ branches/config-1.1/src/config/util/dom/AgaviXmlConfigDomElement.class.php 2011-12-30 20:00:13 UTC (rev 4917)
@@ -521,19 +521,52 @@
$elements = $this->get('parameters', AgaviXmlConfigParser::NAMESPACE_AGAVI_ENVELOPE_LATEST);

foreach($elements as $element) {
- $key = null;
+ if(!$element->hasAttribute('merge')) {
+ // assume "auto" as default merge mode
+ $element->setAttribute('merge', 'auto');
+ }
+
if(!$element->hasAttribute('name')) {
- $result[$key = $offset++] = null;
+ if($element->getAttribute('merge') == 'append') {
+ $key = $result ? (int)max(array_keys($result)) : -1; // if the result is empty, we start at 0
+ // if there are string keys only, or string keys and a key int(0), max() will return a string, so we need to make sure we start at 0 or 1 depending on the case
+ // since we cast to int above, we can check for this special case and set the key to -1
+ if($key === 0 && !isset($result[0])) {
+ $key = -1;
+ }
+ // finally, increment the key to the desired value
+ $key++;
+ } else {
+ $key = $offset++;
+ }
} else {
$key = $element->getAttribute('name');
}

+ if($element->getAttribute('merge') == 'remove') {
+ // remove the element and skip the rest of the loop
+ unset($result[$key]);
+ continue;
+ }
+
+ if($element->getAttribute('merge') == 'setnx' && array_key_exists($key, $result)) { // TODO: isset or array_key_exists?
+ // key already exists, we're not supposed to set our value then, skip...
+ continue;
+ }
+
if($element->hasAgaviParameters()) {
- $result[$key] = isset($result[$key]) && is_array($result[$key]) ? $result[$key] : array();
- $result[$key] = $element->getAgaviParameters($result[$key]);
+ // $value = isset($result[$key]) && is_array($result[$key]) ? $result[$key] : array();
+ // $value = $element->getAgaviParameters($element->getAttribute('merge') == 'auto' ? $value : array()); // merge or replace
+ $value = $element->getAgaviParameters(
+ $element->getAttribute('merge') == 'auto' && isset($result[$key]) && is_array($result[$key]) // only merge arrays or else we break BC
+ ? $result[$key]
+ : array()
+ );
} else {
- $result[$key] = $element->getLiteralValue();
+ $value = $element->getLiteralValue();
}
+
+ $result[$key] = $value;
}
}

Modified: branches/config-1.1/test/tests/unit/config/util/dom/AgaviXmlConfigDomElementTest.php
===================================================================
--- branches/config-1.1/test/tests/unit/config/util/dom/AgaviXmlConfigDomElementTest.php 2011-12-30 19:49:52 UTC (rev 4916)
+++ branches/config-1.1/test/tests/unit/config/util/dom/AgaviXmlConfigDomElementTest.php 2011-12-30 20:00:13 UTC (rev 4917)
@@ -204,13 +204,159 @@
public function genGetAgaviParametersMergeCases()
{
return array(
- 'simple overwrite' => array(array('<ae:parameter name="foo">bar</ae:parameter>', '<ae:parameter name="foo">baz</ae:parameter>'), array('foo' => 'baz')),
- 'singular/plural overwrite' => array(array('<ae:parameter name="foo">bar</ae:parameter>', '<ae:parameters><ae:parameter name="foo">baz</ae:parameter></ae:parameters>'), array('foo' => 'baz')),
- 'overwrite array with string' => array(array('<ae:parameter name="foo"><ae:parameter>bar</ae:parameter></ae:parameter>', '<ae:parameter name="foo">baz</ae:parameter>'), array('foo' => 'baz')),
- 'overwrite string with array' => array(array('<ae:parameter name="foo">baz</ae:parameter>', '<ae:parameter name="foo"><ae:parameter>bar</ae:parameter></ae:parameter>'), array('foo' => array('bar'))),
- 'overwrite string with array w/ key' => array(array('<ae:parameter name="foo">baz</ae:parameter>', '<ae:parameter name="foo"><ae:parameter name="1">bar</ae:parameter></ae:parameter>'), array('foo' => array(1 => 'bar'))),
- 'numeric keys are not reindexed' => array(array('<ae:parameter name="foo"><ae:parameter>bar</ae:parameter></ae:parameter>', '<ae:parameter name="foo"><ae:parameter>baz</ae:parameter></ae:parameter>'), array('foo' => array(0 => 'baz'))),
- 'empty element overwrites' => array(array('<ae:parameter name="foo">bar</ae:parameter>', '<ae:parameter name="foo"></ae:parameter>'), array('foo' => null)),
+ 'simple overwrite' => array(array(
+ '<ae:parameter name="foo">bar</ae:parameter>',
+ '<ae:parameter name="foo">baz</ae:parameter>',
+ ), array('foo' => 'baz')),
+ 'singular/plural overwrite' => array(array(
+ '<ae:parameter name="foo">bar</ae:parameter>',
+ '<ae:parameters><ae:parameter name="foo">baz</ae:parameter></ae:parameters>',
+ ), array('foo' => 'baz')),
+ 'overwrite array with string' => array(array(
+ '<ae:parameter name="foo"><ae:parameter>bar</ae:parameter></ae:parameter>',
+ '<ae:parameter name="foo">baz</ae:parameter>',
+ ), array('foo' => 'baz')),
+ 'overwrite string with array' => array(array(
+ '<ae:parameter name="foo">baz</ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter>bar</ae:parameter></ae:parameter>',
+ ), array('foo' => array('bar'))),
+ 'overwrite string with array w/ key' => array(array(
+ '<ae:parameter name="foo">baz</ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter name="1">bar</ae:parameter></ae:parameter>',
+ ), array('foo' => array(1 => 'bar'))),
+ 'numeric keys are not reindexed' => array(array(
+ '<ae:parameter name="foo"><ae:parameter>bar</ae:parameter></ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter>baz</ae:parameter></ae:parameter>',
+ ), array('foo' => array(0 => 'baz'))),
+ 'empty element overwrites' => array(array(
+ '<ae:parameter name="foo">bar</ae:parameter>',
+ '<ae:parameter name="foo"></ae:parameter>',
+ ), array('foo' => null)),
+
+ 'simple overwrite (auto)' => array(array(
+ '<ae:parameter name="foo">bar</ae:parameter>',
+ '<ae:parameter name="foo">baz</ae:parameter>',
+ ), array('foo' => 'baz')),
+ 'singular/plural overwrite (auto)' => array(array(
+ '<ae:parameter name="foo">bar</ae:parameter>',
+ '<ae:parameters><ae:parameter name="foo">baz</ae:parameter></ae:parameters>',
+ ), array('foo' => 'baz')),
+ 'overwrite array with string (auto)' => array(array(
+ '<ae:parameter name="foo"><ae:parameter>bar</ae:parameter></ae:parameter>',
+ '<ae:parameter name="foo">baz</ae:parameter>',
+ ), array('foo' => 'baz')),
+ 'overwrite string with array (auto)' => array(array(
+ '<ae:parameter name="foo">baz</ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter>bar</ae:parameter></ae:parameter>',
+ ), array('foo' => array('bar'))),
+ 'overwrite string with array w/ key (auto)' => array(array(
+ '<ae:parameter name="foo">baz</ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter name="1">bar</ae:parameter></ae:parameter>',
+ ), array('foo' => array(1 => 'bar'))),
+ 'numeric keys are not reindexed (auto)' => array(array(
+ '<ae:parameter name="foo"><ae:parameter>bar</ae:parameter></ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter>baz</ae:parameter></ae:parameter>',
+ ), array('foo' => array(0 => 'baz'))),
+ 'empty element overwrites (auto)' => array(array(
+ '<ae:parameter name="foo">bar</ae:parameter>',
+ '<ae:parameter name="foo"></ae:parameter>',
+ ), array('foo' => null)),
+
+ 'replace existing key' => array(array(
+ '<ae:parameter name="foo">bar</ae:parameter>',
+ '<ae:parameter name="foo" mode="replace">baz</ae:parameter>',
+ ), array('foo' => 'baz')),
+ 'replace non-existing key' => array(array(
+ '<ae:parameter name="foo">bar</ae:parameter>',
+ '<ae:parameter name="bar" mode="replace">baz</ae:parameter>',
+ ), array('foo' => 'bar', 'bar' => 'baz')),
+ 'replace simple item with complex item' => array(array(
+ '<ae:parameter name="foo">bar</ae:parameter>',
+ '<ae:parameter name="foo" mode="replace"><ae:parameter>baz</ae:parameter></ae:parameter>',
+ ), array('foo' => array('baz'))),
+ 'replace complex item with simple item' => array(array(
+ '<ae:parameter name="foo"><ae:parameter>bar</ae:parameter></ae:parameter>',
+ '<ae:parameter name="foo" mode="replace">baz</ae:parameter>',
+ ), array('foo' => 'baz')),
+
+ 'remove' => array(array(
+ '<ae:parameter name="foo">bar</ae:parameter>',
+ '<ae:parameter name="foo" merge="remove" />',
+ ), array()),
+ 'remove despite content' => array(array(
+ '<ae:parameter name="foo">bar</ae:parameter>',
+ '<ae:parameter name="foo" merge="remove">baz</ae:parameter>',
+ ), array()),
+ 'remove complex content' => array(array(
+ '<ae:parameter name="foo"><ae:parameter name="bar">baz</ae:parameter></ae:parameter>',
+ '<ae:parameter name="foo" merge="remove" />',
+ ), array()),
+ 'remove nested' => array(array(
+ '<ae:parameter name="foo"><ae:parameter name="bar">baz</ae:parameter></ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter name="bar" merge="remove" /></ae:parameter>',
+ ), array('foo' => array())),
+ 'remove numeric' => array(array(
+ '<ae:parameter name="foo"><ae:parameter>bar</ae:parameter></ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter merge="remove" /></ae:parameter>',
+ ), array('foo' => array())),
+ 'removal leaves gap' => array(array(
+ '<ae:parameter name="foo"><ae:parameter>foo</ae:parameter><ae:parameter>bar</ae:parameter></ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter merge="remove" /><ae:parameter>bar</ae:parameter></ae:parameter>',
+ ), array('foo' => array(1 => 'bar'))), // EDGE CASE, WHAT TO DO?
+
+ 'setnx sets if key not exists' => array(array(
+ '<ae:parameter name="foo" merge="setnx">bar</ae:parameter>',
+ ), array('foo' => 'bar')),
+ 'setnx does not set if key exists' => array(array(
+ '<ae:parameter name="foo">bar</ae:parameter>',
+ '<ae:parameter name="foo" merge="setnx">baz</ae:parameter>',
+ ), array('foo' => 'bar')),
+ 'setnx does not set if existing is null' => array(array(
+ '<ae:parameter name="foo"></ae:parameter>',
+ '<ae:parameter name="foo" merge="setnx">baz</ae:parameter>',
+ ), array('foo' => null)),
+ 'setnx can set into children' => array(array(
+ '<ae:parameter name="foo"><ae:parameter name="bar">lol</ae:parameter></ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter name="baz">ohai</ae:parameter></ae:parameter>',
+ ), array('foo' => array('bar' => 'lol', 'baz' => 'ohai'))),
+ 'setnx array casts scalar existing item' => array(array( // EDGE CASE, WHAT TO DO?
+ '<ae:parameter name="foo">lol</ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter name="baz">ohai</ae:parameter></ae:parameter>',
+ ), array('foo' => array('baz' => 'ohai'))),
+
+ 'append' => array(array(
+ '<ae:parameter name="foo"><ae:parameter>egg</ae:parameter></ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter merge="append">spam</ae:parameter></ae:parameter>',
+ ), array('foo' => array('egg', 'spam'))),
+ 'append overwrites existing scalar' => array(array( // EDGE CASE, BUT THERE REALLY IS NO OTHER WAY IMPLEMENTATION-WISE
+ '<ae:parameter name="foo">bar</ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter merge="append">spam</ae:parameter></ae:parameter>',
+ ), array('foo' => array('spam'))),
+ 'appending to map gives key 0' => array(array(
+ '<ae:parameter name="foo"><ae:parameter name="bar">baz</ae:parameter></ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter merge="append">spam</ae:parameter></ae:parameter>',
+ ), array('foo' => array('bar' => 'baz', 0 => 'spam'))),
+ 'appending to mixed array gives right key' => array(array(
+ '<ae:parameter name="foo"><ae:parameter name="bar">baz</ae:parameter><ae:parameter>lulz</ae:parameter></ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter merge="append">spam</ae:parameter></ae:parameter>',
+ ), array('foo' => array('bar' => 'baz', 0 => 'lulz', 1 => 'spam'))),
+ 'appending to array without 0 key works' => array(array(
+ '<ae:parameter name="foo"><ae:parameter name="1">lulz</ae:parameter></ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter merge="append">spam</ae:parameter></ae:parameter>',
+ ), array('foo' => array(1 => 'lulz', 2 => 'spam'))),
+ 'appending to array with key gaps works' => array(array(
+ '<ae:parameter name="foo"><ae:parameter>bar</ae:parameter><ae:parameter name="2">baz</ae:parameter></ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter merge="append">spam</ae:parameter></ae:parameter>',
+ ), array('foo' => array(0 => 'bar', 2 => 'baz', 3 => 'spam'))),
+ 'appending to array with remove gaps works' => array(array(
+ '<ae:parameter name="foo"><ae:parameter>bar</ae:parameter><ae:parameter>zomg</ae:parameter><ae:parameter>baz</ae:parameter></ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter name="1" merge="remove" /></ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter merge="append">spam</ae:parameter></ae:parameter>',
+ ), array('foo' => array(0 => 'bar', 2 => 'baz', 3 => 'spam'))),
+ 'following siblings are not reindexed' => array(array(
+ '<ae:parameter name="foo"><ae:parameter>foo</ae:parameter><ae:parameter>bar</ae:parameter></ae:parameter>',
+ '<ae:parameter name="foo"><ae:parameter merge="append">baz</ae:parameter><ae:parameter>spam</ae:parameter></ae:parameter>',
+ ), array('foo' => array(0 => 'spam', 1 => 'bar', 2 => 'baz'))),
);
}
}
\ No newline at end of file


_______________________________________________
Agavi Commits Mailing List
com...@lists.agavi.org
http://lists.agavi.org/mailman/listinfo/commits

Reply all
Reply to author
Forward
0 new messages