Commit 2826a61d authored by alexpott's avatar alexpott

Issue #1696172 by fgm, tim.plunkett: Add unit tests for complex deep array merge cases.

parent 8ebee83d
......@@ -14,19 +14,28 @@
* Tests the NestedArray helper class.
*
* @group System
*
* @coversDefaultClass \Drupal\Component\Utility\NestedArray
*/
class NestedArrayTest extends UnitTestCase {
/**
* Form array to check.
*
* @var array
*/
protected $form;
/**
* Array of parents for the nested element.
*
* @var array
*/
protected $parents;
/**
* {@inheritdoc}
*/
public static function getInfo() {
return array(
'name' => 'NestedArray functionality',
......@@ -35,7 +44,10 @@ public static function getInfo() {
);
}
public function setUp() {
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Create a form structure with a nested element.
......@@ -49,34 +61,38 @@ public function setUp() {
/**
* Tests getting nested array values.
*
* @covers ::getValue
*/
public function testGetValue() {
// Verify getting a value of a nested element.
$value = NestedArray::getValue($this->form, $this->parents);
$this->assertEquals($value['#value'], 'Nested element', 'Nested element value found.');
$this->assertSame('Nested element', $value['#value'], 'Nested element value found.');
// Verify changing a value of a nested element by reference.
$value = &NestedArray::getValue($this->form, $this->parents);
$value['#value'] = 'New value';
$value = NestedArray::getValue($this->form, $this->parents);
$this->assertEquals($value['#value'], 'New value', 'Nested element value was changed by reference.');
$this->assertEquals($this->form['details']['element']['#value'], 'New value', 'Nested element value was changed by reference.');
$this->assertSame('New value', $value['#value'], 'Nested element value was changed by reference.');
$this->assertSame('New value', $this->form['details']['element']['#value'], 'Nested element value was changed by reference.');
// Verify that an existing key is reported back.
$key_exists = NULL;
NestedArray::getValue($this->form, $this->parents, $key_exists);
$this->assertSame($key_exists, TRUE, 'Existing key found.');
$this->assertTrue($key_exists, 'Existing key found.');
// Verify that a non-existing key is reported back and throws no errors.
$key_exists = NULL;
$parents = $this->parents;
$parents[] = 'foo';
NestedArray::getValue($this->form, $parents, $key_exists);
$this->assertSame($key_exists, FALSE, 'Non-existing key not found.');
$this->assertFalse($key_exists, 'Non-existing key not found.');
}
/**
* Tests setting nested array values.
*
* @covers ::setValue
*/
public function testSetValue() {
$new_value = array(
......@@ -86,12 +102,14 @@ public function testSetValue() {
// Verify setting the value of a nested element.
NestedArray::setValue($this->form, $this->parents, $new_value);
$this->assertEquals($this->form['details']['element']['#value'], 'New value', 'Changed nested element value found.');
$this->assertSame($this->form['details']['element']['#required'], TRUE, 'New nested element value found.');
$this->assertSame('New value', $this->form['details']['element']['#value'], 'Changed nested element value found.');
$this->assertTrue($this->form['details']['element']['#required'], 'New nested element value found.');
}
/**
* Tests force-setting values.
*
* @covers ::setValue
*/
public function testSetValueForce() {
$new_value = array(
......@@ -100,11 +118,13 @@ public function testSetValueForce() {
$this->form['details']['non-array-parent'] = 'string';
$parents = array('details', 'non-array-parent', 'child');
NestedArray::setValue($this->form, $parents, $new_value, TRUE);
$this->assertEquals($this->form['details']['non-array-parent']['child'], $new_value, 'The nested element was not forced to the new value.');
$this->assertSame($new_value, $this->form['details']['non-array-parent']['child'], 'The nested element was not forced to the new value.');
}
/**
* Tests unsetting nested array values.
*
* @covers ::unsetValue
*/
public function testUnsetValue() {
// Verify unsetting a non-existing nested element throws no errors and the
......@@ -114,13 +134,13 @@ public function testUnsetValue() {
$parents[] = 'foo';
NestedArray::unsetValue($this->form, $parents, $key_existed);
$this->assertTrue(isset($this->form['details']['element']['#value']), 'Outermost nested element key still exists.');
$this->assertSame($key_existed, FALSE, 'Non-existing key not found.');
$this->assertFalse($key_existed, 'Non-existing key not found.');
// Verify unsetting a nested element.
$key_existed = NULL;
NestedArray::unsetValue($this->form, $this->parents, $key_existed);
$this->assertFalse(isset($this->form['details']['element']), 'Removed nested element not found.');
$this->assertSame($key_existed, TRUE, 'Existing key was found.');
$this->assertTrue($key_existed, 'Existing key was found.');
}
/**
......@@ -128,16 +148,19 @@ public function testUnsetValue() {
*/
public function testKeyExists() {
// Verify that existing key is found.
$this->assertSame(NestedArray::keyExists($this->form, $this->parents), TRUE, 'Nested key found.');
$this->assertTrue(NestedArray::keyExists($this->form, $this->parents), 'Nested key found.');
// Verify that non-existing keys are not found.
$parents = $this->parents;
$parents[] = 'foo';
$this->assertSame(NestedArray::keyExists($this->form, $parents), FALSE, 'Non-existing nested key not found.');
$this->assertFalse(NestedArray::keyExists($this->form, $parents), 'Non-existing nested key not found.');
}
/**
* Tests NestedArray::mergeDeepArray().
*
* @covers ::mergeDeep
* @covers ::mergeDeepArray
*/
public function testMergeDeepArray() {
$link_options_1 = array(
......@@ -156,8 +179,98 @@ public function testMergeDeepArray() {
'language' => 'en',
'html' => TRUE,
);
$this->assertSame(NestedArray::mergeDeepArray(array($link_options_1, $link_options_2)), $expected, 'NestedArray::mergeDeepArray() returned a properly merged array.');
$this->assertSame($expected, NestedArray::mergeDeepArray(array($link_options_1, $link_options_2)), 'NestedArray::mergeDeepArray() returned a properly merged array.');
// Test wrapper function, NestedArray::mergeDeep().
$this->assertSame(NestedArray::mergeDeep($link_options_1, $link_options_2), $expected, 'NestedArray::mergeDeep() returned a properly merged array.');
$this->assertSame($expected, NestedArray::mergeDeep($link_options_1, $link_options_2), 'NestedArray::mergeDeep() returned a properly merged array.');
}
/**
* Tests that arrays with implicit keys are appended, not merged.
*
* @covers ::mergeDeepArray
*/
public function testMergeImplicitKeys() {
$a = array(
'subkey' => array('X', 'Y'),
);
$b = array(
'subkey' => array('X'),
);
// Drupal core behavior.
$expected = array(
'subkey' => array('X', 'Y', 'X'),
);
$actual = NestedArray::mergeDeepArray(array($a, $b));
$this->assertSame($expected, $actual, 'drupal_array_merge_deep() creates new numeric keys in the implicit sequence.');
}
/**
* Tests that even with explicit keys, values are appended, not merged.
*
* @covers ::mergeDeepArray
*/
public function testMergeExplicitKeys() {
$a = array(
'subkey' => array(
0 => 'A',
1 => 'B',
),
);
$b = array(
'subkey' => array(
0 => 'C',
1 => 'D',
),
);
// Drupal core behavior.
$expected = array(
'subkey' => array(
0 => 'A',
1 => 'B',
2 => 'C',
3 => 'D',
),
);
$actual = NestedArray::mergeDeepArray(array($a, $b));
$this->assertSame($expected, $actual, 'drupal_array_merge_deep() creates new numeric keys in the explicit sequence.');
}
/**
* Tests that array keys values on the first array are ignored when merging.
*
* Even if the initial ordering would place the data from the second array
* before those in the first one, they are still appended, and the keys on
* the first array are deleted and regenerated.
*
* @covers ::mergeDeepArray
*/
public function testMergeOutOfSequenceKeys() {
$a = array(
'subkey' => array(
10 => 'A',
30 => 'B',
),
);
$b = array(
'subkey' => array(
20 => 'C',
0 => 'D',
),
);
// Drupal core behavior.
$expected = array(
'subkey' => array(
0 => 'A',
1 => 'B',
2 => 'C',
3 => 'D',
),
);
$actual = NestedArray::mergeDeepArray(array($a, $b));
$this->assertSame($expected, $actual, 'drupal_array_merge_deep() ignores numeric key order when merging.');
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment