ソースを参照

Make function work as expected

euromark 12 年 前
コミット
a5c31ca8c5
2 ファイル変更99 行追加15 行削除
  1. 28 6
      Lib/Utility/Utility.php
  2. 71 9
      Test/Case/Lib/Utility/UtilityTest.php

+ 28 - 6
Lib/Utility/Utility.php

@@ -407,26 +407,39 @@ class Utility {
 	 * Expands the values of an array of strings into a deep array.
 	 * Opposite of flatten().
 	 *
+	 * It needs at least a single separator to be present in all values
+	 * as the key would otherwise be undefined. If data can contain such key-less
+	 * rows, use $undefinedKey to avoid an exception being thrown. But it will
+	 * effectivly collide with other values in that same key then.
+	 *
+	 * So `Some.Deep.Value` becomes `array('Some' => array('Deep' => array('Value')))`.
+	 *
 	 * @param array $data
+	 * @param string $separator
+	 * @param string $undefinedKey
 	 * @return array
 	 */
-	public function expandList(array $data, $separator = '.') {
+	public function expandList(array $data, $separator = '.', $undefinedKey = null) {
 		$result = array();
 		foreach ($data as $value) {
 			$keys = explode($separator, $value);
 			$value = array_pop($keys);
 
 			$keys = array_reverse($keys);
-			$child = array(
-				$keys[0] => $value
-			);
+			if (!isset($keys[0])) {
+				if ($undefinedKey === null) {
+					throw new RuntimeException('Key-less values are not supported without $undefinedKey.');
+				}
+				$keys[0] = $undefinedKey;
+			}
+			$child = array($keys[0] => array($value));
 			array_shift($keys);
 			foreach ($keys as $k) {
 				$child = array(
 					$k => $child
 				);
 			}
-			$result = Hash::merge($result, $child);
+			$result = Set::merge($result, $child);
 		}
 		return $result;
 	}
@@ -435,6 +448,12 @@ class Utility {
 	 * Flattens a deep array into an array of strings.
 	 * Opposite of expand().
 	 *
+	 * So `array('Some' => array('Deep' => array('Value')))` becomes `Some.Deep.Value`.
+	 *
+	 * Note that primarily only string should be used.
+	 * However, boolean values are casted to int and thus
+	 * both boolean and integer values also supported.
+	 *
 	 * @param array $data
 	 * @return array
 	 */
@@ -457,7 +476,10 @@ class Utility {
 				reset($data);
 				$path .= $key . $separator;
 			} else {
-				$result[] = $path . $key . $separator . $element;
+				if (is_bool($element)) {
+					$element = (int)$element;
+				}
+				$result[] = $path . $element;
 			}
 
 			if (empty($data) && !empty($stack)) {

+ 71 - 9
Test/Case/Lib/Utility/UtilityTest.php

@@ -298,19 +298,56 @@ class UtilityTest extends MyCakeTestCase {
 	 */
 	public function testExpandList() {
 		$is = array(
-			'Some.Deep.Value',
+			'Some.Deep.Value1',
+			'Some.Deep.Value2',
 			'Some.Even.Deeper.Nested.Value',
 			'Empty.',
-			//'RootElementValue'
+			'0.1.2',
+			'.EmptyString'
 		);
 		$result = Utility::expandList($is);
 
 		$expected = array(
 			'Some' => array(
-				'Deep' => 'Value',
-				'Even' => array('Deeper' => array('Nested' => 'Value'))
+				'Deep' => array('Value1', 'Value2'),
+				'Even' => array('Deeper' => array('Nested' => array('Value')))
 			),
-			'Empty' => '',
+			'Empty' => array(''),
+			'0' => array('1' => array('2')),
+			'' => array('EmptyString')
+		);
+		$this->assertSame($expected, $result);
+	}
+
+	/**
+	 * UtilityTest::testExpandListWithKeyLessListInvalid()
+	 *
+	 * @expectedException RuntimeException
+	 * @return void
+	 */
+	public function testExpandListWithKeyLessListInvalid() {
+		$is = array(
+			'Some',
+			'ValueOnly',
+		);
+		Utility::expandList($is);
+	}
+
+	/**
+	 * UtilityTest::testExpandListWithKeyLessList()
+	 *
+	 * @return void
+	 */
+	public function testExpandListWithKeyLessList() {
+		$is = array(
+			'Some',
+			'Thing',
+			'.EmptyString'
+		);
+		$result = Utility::expandList($is, '.', '');
+
+		$expected = array(
+			'' => array('Some', 'Thing', 'EmptyString'),
 		);
 		$this->assertSame($expected, $result);
 	}
@@ -323,17 +360,42 @@ class UtilityTest extends MyCakeTestCase {
 	public function testFlatten() {
 		$is = array(
 			'Some' => array(
-				'Deep' => 'Value',
-				'Even' => array('Deeper' => array('Nested' => 'Value'))
+				'Deep' => array('Value1', 'Value2'),
+				'Even' => array('Deeper' => array('Nested' => array('Value')))
 			),
-			'Empty' => '',
+			'Empty' => array(''),
+			'0' => array('1' => array('2')),
+			//'ValueOnly',
+			'' => array('EmptyString')
 		);
 		$result = Utility::flattenList($is);
 
 		$expected = array(
-			'Some.Deep.Value',
+			'Some.Deep.Value1',
+			'Some.Deep.Value2',
 			'Some.Even.Deeper.Nested.Value',
 			'Empty.',
+			'0.1.2',
+			//'1.ValueOnly'
+			'.EmptyString'
+		);
+		$this->assertSame($expected, $result);
+
+		// Test integers als booleans
+		$is = array(
+			'Some' => array(
+				'Deep' => array(true),
+				'Even' => array('Deeper' => array('Nested' => array(false, true)))
+			),
+			'Integer' => array('Value' => array(-3)),
+		);
+		$result = Utility::flattenList($is);
+
+		$expected = array(
+			'Some.Deep.1',
+			'Some.Even.Deeper.Nested.0',
+			'Some.Even.Deeper.Nested.1',
+			'Integer.Value.-3',
 		);
 		$this->assertSame($expected, $result);
 	}