]> granicus.if.org Git - php/commitdiff
Committing for Robin Fernandes
authorZoe Slattery <zoe@php.net>
Fri, 17 Oct 2008 14:40:13 +0000 (14:40 +0000)
committerZoe Slattery <zoe@php.net>
Fri, 17 Oct 2008 14:40:13 +0000 (14:40 +0000)
42 files changed:
ext/spl/tests/arrayObject___construct_basic1.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject___construct_basic2.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject___construct_basic3.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject___construct_basic4.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject___construct_basic5.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject___construct_basic6.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject___construct_error1.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject___construct_error2.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_asort_basic1.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_asort_basic2.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_clone_basic1.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_clone_basic2.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_clone_basic3.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_count_basic1.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_exchangeArray_basic3.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_getFlags_basic1.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_getFlags_basic2.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_getIteratorClass_basic1.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_ksort_basic1.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_ksort_basic2.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_magicMethods1.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_magicMethods2.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_magicMethods3.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_magicMethods4.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_magicMethods5.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_magicMethods6.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_natcasesort_basic1.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_natsort_basic1.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_setFlags_basic1.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_setFlags_basic2.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_setIteratorClass_error1.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_uasort_basic1.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_uasort_error1.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_uksort_basic1.phpt [new file with mode: 0644]
ext/spl/tests/arrayObject_uksort_error1.phpt [new file with mode: 0644]
ext/spl/tests/class_implements_basic.phpt [new file with mode: 0644]
ext/spl/tests/class_implements_basic2.phpt [new file with mode: 0644]
ext/spl/tests/class_implements_variation.phpt [new file with mode: 0644]
ext/spl/tests/class_implements_variation1.phpt [new file with mode: 0644]
ext/spl/tests/class_implements_variation2.phpt [new file with mode: 0644]
ext/spl/tests/countable_class_basic1.phpt [new file with mode: 0644]
ext/spl/tests/countable_count_variation1.phpt [new file with mode: 0644]

diff --git a/ext/spl/tests/arrayObject___construct_basic1.phpt b/ext/spl/tests/arrayObject___construct_basic1.phpt
new file mode 100644 (file)
index 0000000..264e963
--- /dev/null
@@ -0,0 +1,52 @@
+--TEST--
+SPL: ArrayObject::__construct basic usage.
+--FILE--
+<?php
+echo "--> No arguments:\n";
+var_dump(new ArrayObject());
+
+echo "--> Object argument:\n";
+$a = new stdClass;
+$a->p = 'hello';
+var_dump(new ArrayObject($a));
+
+echo "--> Array argument:\n";
+var_dump(new ArrayObject(array('key1' => 'val1')));
+
+echo "--> Nested ArrayObject argument:\n";
+var_dump(new ArrayObject(new ArrayObject($a)));
+?>
+--EXPECTF--
+--> No arguments:
+object(ArrayObject)#1 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  array(0) {
+  }
+}
+--> Object argument:
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(stdClass)#1 (1) {
+    [u"p"]=>
+    unicode(5) "hello"
+  }
+}
+--> Array argument:
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  array(1) {
+    [u"key1"]=>
+    unicode(4) "val1"
+  }
+}
+--> Nested ArrayObject argument:
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(ArrayObject)#3 (1) {
+    [u"storage":u"ArrayObject":private]=>
+    object(stdClass)#1 (1) {
+      [u"p"]=>
+      unicode(5) "hello"
+    }
+  }
+}
diff --git a/ext/spl/tests/arrayObject___construct_basic2.phpt b/ext/spl/tests/arrayObject___construct_basic2.phpt
new file mode 100644 (file)
index 0000000..790e497
--- /dev/null
@@ -0,0 +1,104 @@
+--TEST--
+SPL: ArrayObject::__construct basic usage.
+--FILE--
+<?php
+class C {
+       public $prop = 'C::prop.orig';
+}
+
+class MyArrayObject extends ArrayObject {
+       public $prop = 'MyArrayObject::prop.orig';
+}      
+
+echo "--> Access prop on instance of ArrayObject:\n";
+$c = new C;
+$ao = new ArrayObject($c);
+testAccess($c, $ao);
+
+echo "\n--> Access prop on instance of MyArrayObject:\n";
+$c = new C;
+$ao = new MyArrayObject($c);
+testAccess($c, $ao);
+
+function testAccess($c, $ao) {
+       echo "  - Iteration:\n";
+       foreach ($ao as $key=>$value) {
+               echo "      $key=>$value\n";
+       }
+
+       echo "  - Read:\n";
+       @var_dump($ao->prop, $ao['prop']);
+       
+       echo "  - Write:\n";
+       $ao->prop = 'changed1';
+       $ao['prop'] = 'changed2';
+       var_dump($ao->prop, $ao['prop']);
+       
+       echo "  - Isset:\n";
+       var_dump(isset($ao->prop), isset($ao['prop']));
+       
+       echo "  - Unset:\n";
+       unset($ao->prop);
+       unset($ao['prop']);
+       var_dump($ao->prop, $ao['prop']);
+       
+       echo "  - After:\n";
+       var_dump($ao, $c);
+}
+?>
+--EXPECTF--
+--> Access prop on instance of ArrayObject:
+  - Iteration:
+      prop=>C::prop.orig
+  - Read:
+NULL
+unicode(12) "C::prop.orig"
+  - Write:
+unicode(8) "changed1"
+unicode(8) "changed2"
+  - Isset:
+bool(true)
+bool(true)
+  - Unset:
+
+Notice: Undefined property: ArrayObject::$prop in %s on line 40
+
+Notice: Undefined index:  prop in %s on line 40
+NULL
+NULL
+  - After:
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (0) {
+  }
+}
+object(C)#1 (0) {
+}
+
+--> Access prop on instance of MyArrayObject:
+  - Iteration:
+      prop=>C::prop.orig
+  - Read:
+unicode(24) "MyArrayObject::prop.orig"
+unicode(12) "C::prop.orig"
+  - Write:
+unicode(8) "changed1"
+unicode(8) "changed2"
+  - Isset:
+bool(true)
+bool(true)
+  - Unset:
+
+Notice: Undefined property: MyArrayObject::$prop in %s on line 40
+
+Notice: Undefined index:  prop in %s on line 40
+NULL
+NULL
+  - After:
+object(MyArrayObject)#3 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#4 (0) {
+  }
+}
+object(C)#4 (0) {
+}
diff --git a/ext/spl/tests/arrayObject___construct_basic3.phpt b/ext/spl/tests/arrayObject___construct_basic3.phpt
new file mode 100644 (file)
index 0000000..4ca03f5
--- /dev/null
@@ -0,0 +1,104 @@
+--TEST--
+SPL: ArrayObject::__construct basic usage with ArrayObject::STD_PROP_LIST.
+--FILE--
+<?php
+class C {
+       public $prop = 'C::prop.orig';
+}
+
+class MyArrayObject extends ArrayObject {
+       public $prop = 'MyArrayObject::prop.orig';
+}      
+
+echo "\n--> Access prop on instance of ArrayObject with ArrayObject::STD_PROP_LIST:\n";
+$c = new C;
+$ao = new ArrayObject($c, ArrayObject::STD_PROP_LIST);
+testAccess($c, $ao);
+
+echo "\n--> Access prop on instance of MyArrayObject with ArrayObject::STD_PROP_LIST:\n";
+$c = new C;
+$ao = new MyArrayObject($c, ArrayObject::STD_PROP_LIST);
+testAccess($c, $ao);
+
+function testAccess($c, $ao) {
+       echo "  - Iteration:\n";
+       foreach ($ao as $key=>$value) {
+               echo "      $key=>$value\n";
+       }
+
+       echo "  - Read:\n";
+       @var_dump($ao->prop, $ao['prop']);
+       
+       echo "  - Write:\n";
+       $ao->prop = 'changed1';
+       $ao['prop'] = 'changed2';
+       var_dump($ao->prop, $ao['prop']);
+       
+       echo "  - Isset:\n";
+       var_dump(isset($ao->prop), isset($ao['prop']));
+       
+       echo "  - Unset:\n";
+       unset($ao->prop);
+       unset($ao['prop']);
+       var_dump($ao->prop, $ao['prop']);
+       
+       echo "  - After:\n";
+       var_dump($ao, $c);
+}
+?>
+--EXPECTF--
+--> Access prop on instance of ArrayObject with ArrayObject::STD_PROP_LIST:
+  - Iteration:
+      prop=>C::prop.orig
+  - Read:
+NULL
+unicode(12) "C::prop.orig"
+  - Write:
+unicode(8) "changed1"
+unicode(8) "changed2"
+  - Isset:
+bool(true)
+bool(true)
+  - Unset:
+
+Notice: Undefined property: ArrayObject::$prop in %s on line 40
+
+Notice: Undefined index:  prop in %s on line 40
+NULL
+NULL
+  - After:
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (0) {
+  }
+}
+object(C)#1 (0) {
+}
+
+--> Access prop on instance of MyArrayObject with ArrayObject::STD_PROP_LIST:
+  - Iteration:
+      prop=>C::prop.orig
+  - Read:
+unicode(24) "MyArrayObject::prop.orig"
+unicode(12) "C::prop.orig"
+  - Write:
+unicode(8) "changed1"
+unicode(8) "changed2"
+  - Isset:
+bool(true)
+bool(true)
+  - Unset:
+
+Notice: Undefined property: MyArrayObject::$prop in %s on line 40
+
+Notice: Undefined index:  prop in %s on line 40
+NULL
+NULL
+  - After:
+object(MyArrayObject)#3 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#4 (0) {
+  }
+}
+object(C)#4 (0) {
+}
diff --git a/ext/spl/tests/arrayObject___construct_basic4.phpt b/ext/spl/tests/arrayObject___construct_basic4.phpt
new file mode 100644 (file)
index 0000000..79bed48
--- /dev/null
@@ -0,0 +1,106 @@
+--TEST--
+SPL: ArrayObject::__construct basic usage with ArrayObject::ARRAY_AS_PROPS. Currently fails on php.net due to bug 45622.
+--FILE--
+<?php
+class C {
+       public $prop = 'C::prop.orig';
+}
+
+class MyArrayObject extends ArrayObject {
+       public $prop = 'MyArrayObject::prop.orig';
+}      
+
+echo "\n--> Access prop on instance of ArrayObject with ArrayObject::ARRAY_AS_PROPS:\n";
+$c = new C;
+$ao = new ArrayObject($c, ArrayObject::ARRAY_AS_PROPS);
+testAccess($c, $ao);
+
+echo "\n--> Access prop on instance of MyArrayObject with ArrayObject::ARRAY_AS_PROPS:\n";
+$c = new C;
+$ao = new MyArrayObject($c, ArrayObject::ARRAY_AS_PROPS);
+testAccess($c, $ao);
+
+function testAccess($c, $ao) {
+       echo "  - Iteration:\n";
+       foreach ($ao as $key=>$value) {
+               echo "      $key=>$value\n";
+       }
+
+       echo "  - Read:\n";
+       @var_dump($ao->prop, $ao['prop']);
+       
+       echo "  - Write:\n";
+       $ao->prop = 'changed1';
+       $ao['prop'] = 'changed2';
+       var_dump($ao->prop, $ao['prop']);
+       
+       echo "  - Isset:\n";
+       var_dump(isset($ao->prop), isset($ao['prop']));
+       
+       echo "  - Unset:\n";
+       unset($ao->prop);
+       unset($ao['prop']);
+       var_dump($ao->prop, $ao['prop']);
+       
+       echo "  - After:\n";
+       var_dump($ao, $c);
+}
+?>
+--EXPECTF--
+--> Access prop on instance of ArrayObject with ArrayObject::ARRAY_AS_PROPS:
+  - Iteration:
+      prop=>C::prop.orig
+  - Read:
+unicode(12) "C::prop.orig"
+unicode(12) "C::prop.orig"
+  - Write:
+unicode(8) "changed2"
+unicode(8) "changed2"
+  - Isset:
+bool(true)
+bool(true)
+  - Unset:
+
+Notice: Undefined index:  prop in %s on line 39
+
+Notice: Undefined index:  prop in %s on line 40
+
+Notice: Undefined index:  prop in %s on line 40
+NULL
+NULL
+  - After:
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (0) {
+  }
+}
+object(C)#1 (0) {
+}
+
+--> Access prop on instance of MyArrayObject with ArrayObject::ARRAY_AS_PROPS:
+  - Iteration:
+      prop=>C::prop.orig
+  - Read:
+unicode(24) "MyArrayObject::prop.orig"
+unicode(12) "C::prop.orig"
+  - Write:
+unicode(8) "changed1"
+unicode(8) "changed2"
+  - Isset:
+bool(true)
+bool(true)
+  - Unset:
+
+Notice: Undefined index:  prop in %s on line 40
+
+Notice: Undefined index:  prop in %s on line 40
+NULL
+NULL
+  - After:
+object(MyArrayObject)#3 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#4 (0) {
+  }
+}
+object(C)#4 (0) {
+}
diff --git a/ext/spl/tests/arrayObject___construct_basic5.phpt b/ext/spl/tests/arrayObject___construct_basic5.phpt
new file mode 100644 (file)
index 0000000..4ae2b03
--- /dev/null
@@ -0,0 +1,106 @@
+--TEST--
+SPL: ArrayObject::__construct basic usage with ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS. Currently fails on php.net due to bug 45622.
+--FILE--
+<?php
+class C {
+       public $prop = 'C::prop.orig';
+}
+
+class MyArrayObject extends ArrayObject {
+       public $prop = 'MyArrayObject::prop.orig';
+}      
+
+echo "\n--> Access prop on instance of ArrayObject with ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS:\n";
+$c = new C;
+$ao = new ArrayObject($c, ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS);
+testAccess($c, $ao);
+
+echo "\n--> Access prop on instance of MyArrayObject with ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS:\n";
+$c = new C;
+$ao = new MyArrayObject($c, ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS);
+testAccess($c, $ao);
+
+function testAccess($c, $ao) {
+       echo "  - Iteration:\n";
+       foreach ($ao as $key=>$value) {
+               echo "      $key=>$value\n";
+       }
+
+       echo "  - Read:\n";
+       @var_dump($ao->prop, $ao['prop']);
+       
+       echo "  - Write:\n";
+       $ao->prop = 'changed1';
+       $ao['prop'] = 'changed2';
+       var_dump($ao->prop, $ao['prop']);
+       
+       echo "  - Isset:\n";
+       var_dump(isset($ao->prop), isset($ao['prop']));
+       
+       echo "  - Unset:\n";
+       unset($ao->prop);
+       unset($ao['prop']);
+       var_dump($ao->prop, $ao['prop']);
+       
+       echo "  - After:\n";
+       var_dump($ao, $c);
+}
+?>
+--EXPECTF--
+--> Access prop on instance of ArrayObject with ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS:
+  - Iteration:
+      prop=>C::prop.orig
+  - Read:
+unicode(12) "C::prop.orig"
+unicode(12) "C::prop.orig"
+  - Write:
+unicode(8) "changed2"
+unicode(8) "changed2"
+  - Isset:
+bool(true)
+bool(true)
+  - Unset:
+
+Notice: Undefined index:  prop in %s on line 39
+
+Notice: Undefined index:  prop in %s on line 40
+
+Notice: Undefined index:  prop in %s on line 40
+NULL
+NULL
+  - After:
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (0) {
+  }
+}
+object(C)#1 (0) {
+}
+
+--> Access prop on instance of MyArrayObject with ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS:
+  - Iteration:
+      prop=>C::prop.orig
+  - Read:
+unicode(24) "MyArrayObject::prop.orig"
+unicode(12) "C::prop.orig"
+  - Write:
+unicode(8) "changed1"
+unicode(8) "changed2"
+  - Isset:
+bool(true)
+bool(true)
+  - Unset:
+
+Notice: Undefined index:  prop in %s on line 40
+
+Notice: Undefined index:  prop in %s on line 40
+NULL
+NULL
+  - After:
+object(MyArrayObject)#3 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#4 (0) {
+  }
+}
+object(C)#4 (0) {
+}
diff --git a/ext/spl/tests/arrayObject___construct_basic6.phpt b/ext/spl/tests/arrayObject___construct_basic6.phpt
new file mode 100644 (file)
index 0000000..f36ebce
--- /dev/null
@@ -0,0 +1,80 @@
+--TEST--
+SPL: ArrayObject::__construct: check impact of ArrayObject::STD_PROP_LIST on var_dump.
+--FILE--
+<?php
+class MyArrayObject extends ArrayObject {
+       private $priv1 = 'secret1';
+       public $pub1 = 'public1';
+} 
+
+$ao = new ArrayObject(array(1,2,3));
+$ao->p = 1;
+var_dump($ao);
+
+$ao = new ArrayObject(array(1,2,3), ArrayObject::STD_PROP_LIST);
+$ao->p = 1;
+var_dump($ao);
+
+$ao = new MyArrayObject(array(1,2,3));
+var_dump($ao);
+
+$ao = new MyArrayObject(array(1,2,3), ArrayObject::STD_PROP_LIST);
+var_dump($ao);
+?>
+--EXPECTF--
+object(ArrayObject)#1 (2) {
+  [u"p"]=>
+  int(1)
+  [u"storage":u"ArrayObject":private]=>
+  array(3) {
+    [0]=>
+    int(1)
+    [1]=>
+    int(2)
+    [2]=>
+    int(3)
+  }
+}
+object(ArrayObject)#2 (2) {
+  [u"p"]=>
+  int(1)
+  [u"storage":u"ArrayObject":private]=>
+  array(3) {
+    [0]=>
+    int(1)
+    [1]=>
+    int(2)
+    [2]=>
+    int(3)
+  }
+}
+object(MyArrayObject)#1 (3) {
+  [u"priv1":u"MyArrayObject":private]=>
+  unicode(7) "secret1"
+  [u"pub1"]=>
+  unicode(7) "public1"
+  [u"storage":u"ArrayObject":private]=>
+  array(3) {
+    [0]=>
+    int(1)
+    [1]=>
+    int(2)
+    [2]=>
+    int(3)
+  }
+}
+object(MyArrayObject)#2 (3) {
+  [u"priv1":u"MyArrayObject":private]=>
+  unicode(7) "secret1"
+  [u"pub1"]=>
+  unicode(7) "public1"
+  [u"storage":u"ArrayObject":private]=>
+  array(3) {
+    [0]=>
+    int(1)
+    [1]=>
+    int(2)
+    [2]=>
+    int(3)
+  }
+}
diff --git a/ext/spl/tests/arrayObject___construct_error1.phpt b/ext/spl/tests/arrayObject___construct_error1.phpt
new file mode 100644 (file)
index 0000000..21c312d
--- /dev/null
@@ -0,0 +1,25 @@
+--TEST--
+SPL: ArrayObject::__construct with bad iterator.
+--FILE--
+<?php
+echo "Bad iterator type:\n";
+$a = new stdClass;
+$a->p = 1;
+try {
+  var_dump(new ArrayObject($a, 0, "Exception"));
+} catch (InvalidArgumentException $e) {
+  echo $e->getMessage() . "(" . $e->getLine() .  ")\n";
+}
+
+echo "Non-existent class:\n";
+try {
+  var_dump(new ArrayObject(new stdClass, 0, "nonExistentClassName"));
+} catch (InvalidArgumentException $e) {
+  echo $e->getMessage() . "(" . $e->getLine() .  ")\n";
+}
+?>
+--EXPECTF--
+Bad iterator type:
+ArrayObject::__construct() expects parameter 3 to be a class name derived from Iterator, 'Exception' given(6)
+Non-existent class:
+ArrayObject::__construct() expects parameter 3 to be a class name derived from Iterator, 'nonExistentClassName' given(13)
diff --git a/ext/spl/tests/arrayObject___construct_error2.phpt b/ext/spl/tests/arrayObject___construct_error2.phpt
new file mode 100644 (file)
index 0000000..850a2cb
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--
+SPL: ArrayObject::__construct with too many arguments.
+--FILE--
+<?php
+echo "Too many arguments:\n";
+Class C implements Iterator {
+       function current() {}
+       function next() {}
+       function key() {}
+       function valid() {}
+       function rewind() {}
+}
+
+try {
+  var_dump(new ArrayObject(new stdClass, 0, "C", "extra"));
+} catch (InvalidArgumentException $e) {
+  echo $e->getMessage() . "(" . $e->getLine() .  ")\n";
+}
+?>
+--EXPECTF--
+Too many arguments:
+ArrayObject::__construct() expects at most 3 parameters, 4 given(12)
\ No newline at end of file
diff --git a/ext/spl/tests/arrayObject_asort_basic1.phpt b/ext/spl/tests/arrayObject_asort_basic1.phpt
new file mode 100644 (file)
index 0000000..5a27acd
--- /dev/null
@@ -0,0 +1,48 @@
+--TEST--
+SPL: Test ArrayObject::asort() function : basic functionality with array based store
+--FILE--
+<?php
+/* Prototype  : int ArrayObject::asort()
+ * Description: proto int ArrayIterator::asort()
+ * Sort the entries by values. 
+ * Source code: ext/spl/spl_array.c
+ * Alias to functions: 
+ */
+
+echo "*** Testing ArrayObject::asort() : basic functionality ***\n";
+
+$ao1 = new ArrayObject(array(4,2,3));
+$ao2 = new ArrayObject(array('a'=>4,'b'=>2,'c'=>3));
+var_dump($ao1->asort());
+var_dump($ao1);
+var_dump($ao2->asort('blah'));
+var_dump($ao2);
+?>
+===DONE===
+--EXPECTF--
+*** Testing ArrayObject::asort() : basic functionality ***
+bool(true)
+object(ArrayObject)#1 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  array(3) {
+    [1]=>
+    int(2)
+    [2]=>
+    int(3)
+    [0]=>
+    int(4)
+  }
+}
+bool(true)
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  array(3) {
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"a"]=>
+    int(4)
+  }
+}
+===DONE===
diff --git a/ext/spl/tests/arrayObject_asort_basic2.phpt b/ext/spl/tests/arrayObject_asort_basic2.phpt
new file mode 100644 (file)
index 0000000..47b707d
--- /dev/null
@@ -0,0 +1,52 @@
+--TEST--
+SPL: Test ArrayObject::asort() function : basic functionality with object based store
+--FILE--
+<?php
+/* Prototype  : int ArrayObject::asort()
+ * Description: proto int ArrayIterator::asort()
+ * Sort the entries by values. 
+ * Source code: ext/spl/spl_array.c
+ * Alias to functions: 
+ */
+
+echo "*** Testing ArrayObject::asort() : basic functionality ***\n";
+Class C {
+       public $prop1 = 'x';
+       public $prop2 = 'z';
+       private $prop3 = 'a';
+       public $prop4 = 'x';
+}
+
+$c = new C;
+$ao1 = new ArrayObject($c);
+var_dump($ao1->asort());
+var_dump($ao1, $c);
+?>
+===DONE===
+--EXPECTF--
+*** Testing ArrayObject::asort() : basic functionality ***
+bool(true)
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (4) {
+    [u"prop3":u"C":private]=>
+    unicode(1) "a"
+    [u"prop1"]=>
+    unicode(1) "x"
+    [u"prop4"]=>
+    unicode(1) "x"
+    [u"prop2"]=>
+    unicode(1) "z"
+  }
+}
+object(C)#1 (4) {
+  [u"prop3":u"C":private]=>
+  unicode(1) "a"
+  [u"prop1"]=>
+  unicode(1) "x"
+  [u"prop4"]=>
+  unicode(1) "x"
+  [u"prop2"]=>
+  unicode(1) "z"
+}
+===DONE===
diff --git a/ext/spl/tests/arrayObject_clone_basic1.phpt b/ext/spl/tests/arrayObject_clone_basic1.phpt
new file mode 100644 (file)
index 0000000..b9edc68
--- /dev/null
@@ -0,0 +1,49 @@
+--TEST--
+SPL: Cloning an instance of ArrayObject which wraps an array. 
+--FILE--
+<?php
+$a = array(1,2);
+$aa1 =  new ArrayObject($a);
+$a['p1'] = 'new element added to a before clone';
+
+$aa2 = clone $aa1;
+
+$a['p2'] = 'new element added to a after clone';
+$aa1['new.aa1'] = 'new element added to aa1';
+$aa2['new.aa2'] = 'new element added to aa2';
+var_dump($a, $aa1, $aa2);
+?>
+--EXPECTF--
+array(4) {
+  [0]=>
+  int(1)
+  [1]=>
+  int(2)
+  [u"p1"]=>
+  unicode(35) "new element added to a before clone"
+  [u"p2"]=>
+  unicode(34) "new element added to a after clone"
+}
+object(ArrayObject)#1 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  array(3) {
+    [0]=>
+    int(1)
+    [1]=>
+    int(2)
+    [u"new.aa1"]=>
+    unicode(24) "new element added to aa1"
+  }
+}
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  array(3) {
+    [0]=>
+    int(1)
+    [1]=>
+    int(2)
+    [u"new.aa2"]=>
+    unicode(24) "new element added to aa2"
+  }
+}
+
diff --git a/ext/spl/tests/arrayObject_clone_basic2.phpt b/ext/spl/tests/arrayObject_clone_basic2.phpt
new file mode 100644 (file)
index 0000000..062d8d5
--- /dev/null
@@ -0,0 +1,46 @@
+--TEST--
+SPL: Cloning an instance of ArrayObject which wraps an object. 
+--FILE--
+<?php
+class C { }
+
+$c = new C;
+$ao1 =  new ArrayObject($c);
+$c->p1 = 'new prop added to c before clone';
+
+$ao2 = clone $ao1;
+
+$c->p2 = 'new prop added to c after clone';
+$ao1['new.ao1'] = 'new element added to ao1';
+$ao2['new.ao2'] = 'new element added to ao2';
+var_dump($c, $ao1, $ao2);
+?>
+--EXPECTF--
+object(C)#1 (3) {
+  [u"p1"]=>
+  unicode(32) "new prop added to c before clone"
+  [u"p2"]=>
+  unicode(31) "new prop added to c after clone"
+  [u"new.ao1"]=>
+  unicode(24) "new element added to ao1"
+}
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (3) {
+    [u"p1"]=>
+    unicode(32) "new prop added to c before clone"
+    [u"p2"]=>
+    unicode(31) "new prop added to c after clone"
+    [u"new.ao1"]=>
+    unicode(24) "new element added to ao1"
+  }
+}
+object(ArrayObject)#3 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  array(2) {
+    [u"p1"]=>
+    unicode(32) "new prop added to c before clone"
+    [u"new.ao2"]=>
+    unicode(24) "new element added to ao2"
+  }
+}
diff --git a/ext/spl/tests/arrayObject_clone_basic3.phpt b/ext/spl/tests/arrayObject_clone_basic3.phpt
new file mode 100644 (file)
index 0000000..9e64d0b
--- /dev/null
@@ -0,0 +1,80 @@
+--TEST--
+SPL: Cloning nested ArrayObjects. 
+--FILE--
+<?php
+class C {
+       public $p = 'C::p.orig';
+}
+
+$wrappedObject = new C;
+$innerArrayObject = new ArrayObject($wrappedObject);
+
+$outerArrayObject =  new ArrayObject($innerArrayObject);
+
+$wrappedObject->dynamic1 = 'new prop added to $wrappedObject before clone';
+$clonedOuterArrayObject = clone $outerArrayObject;
+$wrappedObject->dynamic2 = 'new prop added to $wrappedObject after clone';
+
+$innerArrayObject['new.iAO'] = 'new element added $innerArrayObject';
+$outerArrayObject['new.oAO'] = 'new element added to $outerArrayObject';
+$clonedOuterArrayObject['new.coAO'] = 'new element added to $clonedOuterArrayObject';
+
+var_dump($wrappedObject, $innerArrayObject, $outerArrayObject, $clonedOuterArrayObject);
+?>
+--EXPECTF--
+object(C)#1 (5) {
+  [u"p"]=>
+  unicode(9) "C::p.orig"
+  [u"dynamic1"]=>
+  unicode(45) "new prop added to $wrappedObject before clone"
+  [u"dynamic2"]=>
+  unicode(44) "new prop added to $wrappedObject after clone"
+  [u"new.iAO"]=>
+  unicode(35) "new element added $innerArrayObject"
+  [u"new.oAO"]=>
+  unicode(38) "new element added to $outerArrayObject"
+}
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (5) {
+    [u"p"]=>
+    unicode(9) "C::p.orig"
+    [u"dynamic1"]=>
+    unicode(45) "new prop added to $wrappedObject before clone"
+    [u"dynamic2"]=>
+    unicode(44) "new prop added to $wrappedObject after clone"
+    [u"new.iAO"]=>
+    unicode(35) "new element added $innerArrayObject"
+    [u"new.oAO"]=>
+    unicode(38) "new element added to $outerArrayObject"
+  }
+}
+object(ArrayObject)#3 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(ArrayObject)#2 (1) {
+    [u"storage":u"ArrayObject":private]=>
+    object(C)#1 (5) {
+      [u"p"]=>
+      unicode(9) "C::p.orig"
+      [u"dynamic1"]=>
+      unicode(45) "new prop added to $wrappedObject before clone"
+      [u"dynamic2"]=>
+      unicode(44) "new prop added to $wrappedObject after clone"
+      [u"new.iAO"]=>
+      unicode(35) "new element added $innerArrayObject"
+      [u"new.oAO"]=>
+      unicode(38) "new element added to $outerArrayObject"
+    }
+  }
+}
+object(ArrayObject)#4 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  array(3) {
+    [u"p"]=>
+    unicode(9) "C::p.orig"
+    [u"dynamic1"]=>
+    unicode(45) "new prop added to $wrappedObject before clone"
+    [u"new.coAO"]=>
+    unicode(44) "new element added to $clonedOuterArrayObject"
+  }
+}
diff --git a/ext/spl/tests/arrayObject_count_basic1.phpt b/ext/spl/tests/arrayObject_count_basic1.phpt
new file mode 100644 (file)
index 0000000..1a3b84d
--- /dev/null
@@ -0,0 +1,80 @@
+--TEST--
+SPL: ArrayObject::count() and ArrayIterator::count() basic functionality. 
+--FILE--
+==ArrayObject==
+<?php
+class C extends ArrayObject {
+  function count() {
+    return 99;
+  }
+}
+
+$c = new C;
+$ao = new ArrayObject;
+
+var_dump(count($c), count($ao));
+
+$c[] = 'a';
+$ao[] = 'a';
+var_dump(count($c), count($ao));
+
+$c[] = 'b';
+$ao[] = 'b';
+var_dump(count($c), count($ao));
+
+unset($c[0]);
+unset($ao[0]);
+var_dump($c->count(), $ao->count());
+
+//Extra args are ignored.
+var_dump($ao->count('blah'));
+?>
+==ArrayIterator==
+<?php
+class D extends ArrayIterator {
+  function count() {
+    return 99;
+  }
+}
+
+$c = new D;
+$ao = new ArrayIterator;
+
+var_dump(count($c), count($ao));
+
+$c[] = 'a';
+$ao[] = 'a';
+var_dump(count($c), count($ao));
+
+$c[] = 'b';
+$ao[] = 'b';
+var_dump(count($c), count($ao));
+
+unset($c[0]);
+unset($ao[0]);
+var_dump($c->count(), $ao->count());
+
+//Extra args are ignored.
+var_dump($ao->count('blah'));
+?>
+--EXPECTF--
+==ArrayObject==
+int(99)
+int(0)
+int(99)
+int(1)
+int(99)
+int(2)
+int(99)
+int(1)
+int(1)
+==ArrayIterator==
+int(99)
+int(0)
+int(99)
+int(1)
+int(99)
+int(2)
+int(99)
+int(1)
+int(1)
\ No newline at end of file
diff --git a/ext/spl/tests/arrayObject_exchangeArray_basic3.phpt b/ext/spl/tests/arrayObject_exchangeArray_basic3.phpt
new file mode 100644 (file)
index 0000000..88a2fb4
--- /dev/null
@@ -0,0 +1,128 @@
+--TEST--
+SPL: ArrayObject::exchangeArray() basic usage with object as underlying data store.
+--FILE--
+<?php
+
+class C {
+       public $pub1 = 'public1';
+} 
+
+echo "--> exchangeArray() with objects:\n";
+$original = new C;
+$ao = new ArrayObject($original);
+$swapIn = new C;
+try {
+       $copy = $ao->exchangeArray($swapIn);
+       $copy['addedToCopy'] = 'added To Copy';
+} catch (Exception $e) {
+       echo "Exception:" . $e->getMessage() . "\n";
+}
+$swapIn->addedToSwapIn = 'added To Swap-In';
+$original->addedToOriginal = 'added To Original';
+var_dump($ao, $original, $swapIn, $copy);
+
+
+echo "\n\n--> exchangeArray() with no arg:\n";
+unset($original, $ao, $swapIn, $copy);
+$original = new C;
+$ao = new ArrayObject($original);
+try {
+       $copy = $ao->exchangeArray();
+       $copy['addedToCopy'] = 'added To Copy';
+} catch (Exception $e) {
+       echo "Exception:" . $e->getMessage() . "\n";
+}
+$original->addedToOriginal = 'added To Original';
+var_dump($ao, $original, $copy);
+
+echo "\n\n--> exchangeArray() with bad arg type:\n";
+unset($original, $ao, $swapIn, $copy);
+$original = new C;
+$ao = new ArrayObject($original);
+try {
+       $copy = $ao->exchangeArray(null);
+       $copy['addedToCopy'] = 'added To Copy';
+} catch (Exception $e) {
+       echo "Exception:" . $e->getMessage() . "\n";
+}
+$original->addedToOriginal = 'added To Original';
+var_dump($ao, $original, $copy);
+
+?>
+--EXPECTF--
+--> exchangeArray() with objects:
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#3 (2) {
+    [u"pub1"]=>
+    unicode(7) "public1"
+    [u"addedToSwapIn"]=>
+    unicode(16) "added To Swap-In"
+  }
+}
+object(C)#1 (2) {
+  [u"pub1"]=>
+  unicode(7) "public1"
+  [u"addedToOriginal"]=>
+  unicode(17) "added To Original"
+}
+object(C)#3 (2) {
+  [u"pub1"]=>
+  unicode(7) "public1"
+  [u"addedToSwapIn"]=>
+  unicode(16) "added To Swap-In"
+}
+array(2) {
+  [u"pub1"]=>
+  unicode(7) "public1"
+  [u"addedToCopy"]=>
+  unicode(13) "added To Copy"
+}
+
+
+--> exchangeArray() with no arg:
+
+Warning: ArrayObject::exchangeArray() expects exactly 1 parameter, 0 given in %s on line 27
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#3 (2) {
+    [u"pub1"]=>
+    unicode(7) "public1"
+    [u"addedToOriginal"]=>
+    unicode(17) "added To Original"
+  }
+}
+object(C)#3 (2) {
+  [u"pub1"]=>
+  unicode(7) "public1"
+  [u"addedToOriginal"]=>
+  unicode(17) "added To Original"
+}
+array(2) {
+  [u"pub1"]=>
+  unicode(7) "public1"
+  [u"addedToCopy"]=>
+  unicode(13) "added To Copy"
+}
+
+
+--> exchangeArray() with bad arg type:
+Exception:Passed variable is not an array or object, using empty array instead
+
+Notice: Undefined variable: copy in %s on line 46
+object(ArrayObject)#3 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#2 (2) {
+    [u"pub1"]=>
+    unicode(7) "public1"
+    [u"addedToOriginal"]=>
+    unicode(17) "added To Original"
+  }
+}
+object(C)#2 (2) {
+  [u"pub1"]=>
+  unicode(7) "public1"
+  [u"addedToOriginal"]=>
+  unicode(17) "added To Original"
+}
+NULL
diff --git a/ext/spl/tests/arrayObject_getFlags_basic1.phpt b/ext/spl/tests/arrayObject_getFlags_basic1.phpt
new file mode 100644 (file)
index 0000000..b078c51
--- /dev/null
@@ -0,0 +1,25 @@
+--TEST--
+SPL: ArrayObject::getFlags() basic usage
+--FILE--
+<?php
+$ao = new ArrayObject(new ArrayObject(new stdClass));
+var_dump($ao->getFlags());
+
+$ao = new ArrayObject(new ArrayObject(array(1,2,3)), ArrayObject::STD_PROP_LIST);
+var_dump($ao->getFlags());
+
+$ao = new ArrayObject(new ArrayIterator(new ArrayObject()), ArrayObject::ARRAY_AS_PROPS);
+var_dump($ao->getFlags());
+
+$ao = new ArrayObject(new ArrayObject(), ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS);
+var_dump($ao->getFlags());
+
+$cao = clone $ao;
+var_dump($cao->getFlags());
+?>
+--EXPECTF--
+int(0)
+int(1)
+int(2)
+int(3)
+int(3)
\ No newline at end of file
diff --git a/ext/spl/tests/arrayObject_getFlags_basic2.phpt b/ext/spl/tests/arrayObject_getFlags_basic2.phpt
new file mode 100644 (file)
index 0000000..f7d56ea
--- /dev/null
@@ -0,0 +1,24 @@
+--TEST--
+SPL: ArrayObject::getFlags() - ensure flags are passed on to nested array objects and iterators.
+--FILE--
+<?php
+$ao = new ArrayObject(array(), ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS);
+var_dump($ao->getFlags());
+
+$ao2 = new ArrayObject($ao);
+var_dump($ao2->getFlags());
+var_dump($ao2->getIterator()->getFlags());
+
+$ai = new ArrayIterator($ao);
+var_dump($ai->getFlags());
+
+$ao2 = new ArrayObject($ao, 0);
+var_dump($ao2->getFlags());
+
+?>
+--EXPECTF--
+int(3)
+int(3)
+int(3)
+int(3)
+int(0)
\ No newline at end of file
diff --git a/ext/spl/tests/arrayObject_getIteratorClass_basic1.phpt b/ext/spl/tests/arrayObject_getIteratorClass_basic1.phpt
new file mode 100644 (file)
index 0000000..3a988e2
--- /dev/null
@@ -0,0 +1,116 @@
+--TEST--
+SPL: ArrayObject::getIteratorClass and ArrayObject::setIteratorClass basic functionality 
+--FILE--
+<?php
+class MyIterator extends ArrayIterator {
+
+       function __construct() {
+               $args = func_get_args();
+               echo "   In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+
+       function rewind() { 
+               $args = func_get_args();
+               echo "   In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+               return parent::rewind();
+       }
+
+       function valid() { 
+               $args = func_get_args();
+               echo "   In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+               return parent::valid();
+       }
+       
+       function current() { 
+               $args = func_get_args();
+               echo "   In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+               return parent::current();
+       }
+
+       function next() { 
+               $args = func_get_args();
+               echo "   In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+               return parent::next();
+       }
+       
+       function key() { 
+               $args = func_get_args();
+               echo "   In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+               return parent::key();
+       }
+}
+
+$ao = new ArrayObject(array('a'=>1,'b'=>2,'c'=>3), 0, "MyIterator");
+
+echo "--> Access using MyIterator:\n";
+var_dump($ao->getIteratorClass());
+var_dump($ao->getIterator());
+foreach($ao as $key=>$value) {
+       echo "  $key=>$value\n";
+}
+
+echo "\n\n--> Access using ArrayIterator:\n";
+var_dump($ao->setIteratorClass("ArrayIterator"));
+var_dump($ao->getIteratorClass());
+var_dump($ao->getIterator());
+foreach($ao as $key=>$value) {
+       echo "$key=>$value\n";
+}
+
+?>
+--EXPECTF--
+--> Access using MyIterator:
+unicode(10) "MyIterator"
+object(MyIterator)#2 (1) {
+  [u"storage":u"ArrayIterator":private]=>
+  object(ArrayObject)#1 (1) {
+    [u"storage":u"ArrayObject":private]=>
+    array(3) {
+      [u"a"]=>
+      int(1)
+      [u"b"]=>
+      int(2)
+      [u"c"]=>
+      int(3)
+    }
+  }
+}
+   In MyIterator::rewind()
+   In MyIterator::valid()
+   In MyIterator::current()
+   In MyIterator::key()
+  a=>1
+   In MyIterator::next()
+   In MyIterator::valid()
+   In MyIterator::current()
+   In MyIterator::key()
+  b=>2
+   In MyIterator::next()
+   In MyIterator::valid()
+   In MyIterator::current()
+   In MyIterator::key()
+  c=>3
+   In MyIterator::next()
+   In MyIterator::valid()
+
+
+--> Access using ArrayIterator:
+NULL
+unicode(13) "ArrayIterator"
+object(ArrayIterator)#3 (1) {
+  [u"storage":u"ArrayIterator":private]=>
+  object(ArrayObject)#1 (1) {
+    [u"storage":u"ArrayObject":private]=>
+    array(3) {
+      [u"a"]=>
+      int(1)
+      [u"b"]=>
+      int(2)
+      [u"c"]=>
+      int(3)
+    }
+  }
+}
+a=>1
+b=>2
+c=>3
diff --git a/ext/spl/tests/arrayObject_ksort_basic1.phpt b/ext/spl/tests/arrayObject_ksort_basic1.phpt
new file mode 100644 (file)
index 0000000..bd62cc1
--- /dev/null
@@ -0,0 +1,49 @@
+--TEST--
+SPL: Test ArrayObject::ksort() function : basic functionality with array based store 
+--FILE--
+<?php
+/* Prototype  : int ArrayObject::ksort()
+ * Description: proto int ArrayIterator::ksort()
+ * Sort the entries by key. 
+ * Source code: ext/spl/spl_array.c
+ * Alias to functions: 
+ */
+
+echo "*** Testing ArrayObject::ksort() : basic functionality ***\n";
+$ao1 = new ArrayObject(array(4,2,3));
+$ao2 = new ArrayObject(array('b'=>4,'a'=>2,'q'=>3, 99=>'x'));
+var_dump($ao1->ksort());
+var_dump($ao1);
+var_dump($ao2->ksort('blah'));
+var_dump($ao2);
+?>
+===DONE===
+--EXPECTF--
+*** Testing ArrayObject::ksort() : basic functionality ***
+bool(true)
+object(ArrayObject)#1 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  array(3) {
+    [0]=>
+    int(4)
+    [1]=>
+    int(2)
+    [2]=>
+    int(3)
+  }
+}
+bool(true)
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  array(4) {
+    [u"a"]=>
+    int(2)
+    [u"b"]=>
+    int(4)
+    [u"q"]=>
+    int(3)
+    [99]=>
+    unicode(1) "x"
+  }
+}
+===DONE===
diff --git a/ext/spl/tests/arrayObject_ksort_basic2.phpt b/ext/spl/tests/arrayObject_ksort_basic2.phpt
new file mode 100644 (file)
index 0000000..3f170a5
--- /dev/null
@@ -0,0 +1,52 @@
+--TEST--
+SPL: Test ArrayObject::ksort() function : basic functionality with object base store 
+--FILE--
+<?php
+/* Prototype  : int ArrayObject::ksort()
+ * Description: proto int ArrayIterator::ksort()
+ * Sort the entries by key. 
+ * Source code: ext/spl/spl_array.c
+ * Alias to functions: 
+ */
+
+echo "*** Testing ArrayObject::ksort() : basic functionality ***\n";
+Class C {
+       public $x = 'prop1';
+       public $z = 'prop2';
+       public $a = 'prop3';
+       private $b = 'prop4';
+}
+
+$c = new C;
+$ao1 = new ArrayObject($c);
+var_dump($ao1->ksort());
+var_dump($ao1, $c);
+?>
+===DONE===
+--EXPECTF--
+*** Testing ArrayObject::ksort() : basic functionality ***
+bool(true)
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (4) {
+    [u"b":u"C":private]=>
+    unicode(5) "prop4"
+    [u"a"]=>
+    unicode(5) "prop3"
+    [u"x"]=>
+    unicode(5) "prop1"
+    [u"z"]=>
+    unicode(5) "prop2"
+  }
+}
+object(C)#1 (4) {
+  [u"b":u"C":private]=>
+  unicode(5) "prop4"
+  [u"a"]=>
+  unicode(5) "prop3"
+  [u"x"]=>
+  unicode(5) "prop1"
+  [u"z"]=>
+  unicode(5) "prop2"
+}
+===DONE===
diff --git a/ext/spl/tests/arrayObject_magicMethods1.phpt b/ext/spl/tests/arrayObject_magicMethods1.phpt
new file mode 100644 (file)
index 0000000..e4492ee
--- /dev/null
@@ -0,0 +1,195 @@
+--TEST--
+SPL: ArrayObject: ensure a wrapped object's magic methods for property access are not invoked when manipulating the ArrayObject's elements using [].
+--FILE--
+<?php
+class UsesMagic {
+       public $a = 1;
+       public $b = 2;
+       public $c = 3;
+
+       private $priv = 'secret';
+       
+       function __get($name) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       function __set($name, $value) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       function __isset($name) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       function __unset($name) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       
+}
+
+$obj = new UsesMagic;
+
+$ao = new ArrayObject($obj);
+echo "\n--> Write existent, non-existent and dynamic:\n";
+$ao['a'] = 'changed';
+$ao['dynamic'] = 'new';
+$ao['dynamic'] = 'new.changed';
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+
+echo "\n--> Read existent, non-existent and dynamic:\n";
+var_dump($ao['a']);
+var_dump($ao['nonexistent']);
+var_dump($ao['dynamic']);
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+
+echo "\n--> isset existent, non-existent and dynamic:\n";
+var_dump(isset($ao['a']));
+var_dump(isset($ao['nonexistent']));
+var_dump(isset($ao['dynamic']));
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+
+echo "\n--> Unset existent, non-existent and dynamic:\n";
+unset($ao['a']);
+unset($ao['nonexistent']);
+unset($ao['dynamic']);
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+?>
+--EXPECTF--
+--> Write existent, non-existent and dynamic:
+  Original wrapped object:
+object(UsesMagic)#1 (5) {
+  [u"a"]=>
+  unicode(7) "changed"
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"UsesMagic":private]=>
+  unicode(6) "secret"
+  [u"dynamic"]=>
+  unicode(11) "new.changed"
+}
+  Wrapping ArrayObject:
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(UsesMagic)#1 (5) {
+    [u"a"]=>
+    unicode(7) "changed"
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"UsesMagic":private]=>
+    unicode(6) "secret"
+    [u"dynamic"]=>
+    unicode(11) "new.changed"
+  }
+}
+
+--> Read existent, non-existent and dynamic:
+unicode(7) "changed"
+
+Notice: Undefined index:  nonexistent in %s on line 42
+NULL
+unicode(11) "new.changed"
+  Original wrapped object:
+object(UsesMagic)#1 (5) {
+  [u"a"]=>
+  unicode(7) "changed"
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"UsesMagic":private]=>
+  unicode(6) "secret"
+  [u"dynamic"]=>
+  unicode(11) "new.changed"
+}
+  Wrapping ArrayObject:
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(UsesMagic)#1 (5) {
+    [u"a"]=>
+    unicode(7) "changed"
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"UsesMagic":private]=>
+    unicode(6) "secret"
+    [u"dynamic"]=>
+    unicode(11) "new.changed"
+  }
+}
+
+--> isset existent, non-existent and dynamic:
+bool(true)
+bool(false)
+bool(true)
+  Original wrapped object:
+object(UsesMagic)#1 (5) {
+  [u"a"]=>
+  unicode(7) "changed"
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"UsesMagic":private]=>
+  unicode(6) "secret"
+  [u"dynamic"]=>
+  unicode(11) "new.changed"
+}
+  Wrapping ArrayObject:
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(UsesMagic)#1 (5) {
+    [u"a"]=>
+    unicode(7) "changed"
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"UsesMagic":private]=>
+    unicode(6) "secret"
+    [u"dynamic"]=>
+    unicode(11) "new.changed"
+  }
+}
+
+--> Unset existent, non-existent and dynamic:
+
+Notice: Undefined index:  nonexistent in %s on line 60
+  Original wrapped object:
+object(UsesMagic)#1 (3) {
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"UsesMagic":private]=>
+  unicode(6) "secret"
+}
+  Wrapping ArrayObject:
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(UsesMagic)#1 (3) {
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"UsesMagic":private]=>
+    unicode(6) "secret"
+  }
+}
diff --git a/ext/spl/tests/arrayObject_magicMethods2.phpt b/ext/spl/tests/arrayObject_magicMethods2.phpt
new file mode 100644 (file)
index 0000000..946e0ad
--- /dev/null
@@ -0,0 +1,197 @@
+--TEST--
+SPL: ArrayObject: ensure a wrapped object's magic methods for property access are not invoked when manipulating the ArrayObject's elements using ->.
+--FILE--
+<?php
+class UsesMagic {
+       public $a = 1;
+       public $b = 2;
+       public $c = 3;
+
+       private $priv = 'secret';
+       
+       function __get($name) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       function __set($name, $value) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       function __isset($name) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       function __unset($name) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       
+}
+
+$obj = new UsesMagic;
+
+$ao = new ArrayObject($obj);
+echo "\n--> Write existent, non-existent and dynamic:\n";
+$ao->a = 'changed';
+$ao->dynamic = 'new';
+$ao->dynamic = 'new.changed';
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+
+echo "\n--> Read existent, non-existent and dynamic:\n";
+var_dump($ao->a);
+var_dump($ao->nonexistent);
+var_dump($ao->dynamic);
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+
+echo "\n--> isset existent, non-existent and dynamic:\n";
+var_dump(isset($ao->a));
+var_dump(isset($ao->nonexistent));
+var_dump(isset($ao->dynamic));
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+
+echo "\n--> Unset existent, non-existent and dynamic:\n";
+unset($ao->a);
+unset($ao->nonexistent);
+unset($ao->dynamic);
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+?>
+--EXPECTF--
+--> Write existent, non-existent and dynamic:
+  Original wrapped object:
+object(UsesMagic)#1 (4) {
+  [u"a"]=>
+  int(1)
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"UsesMagic":private]=>
+  unicode(6) "secret"
+}
+  Wrapping ArrayObject:
+object(ArrayObject)#2 (3) {
+  [u"a"]=>
+  unicode(7) "changed"
+  [u"dynamic"]=>
+  unicode(11) "new.changed"
+  [u"storage":u"ArrayObject":private]=>
+  object(UsesMagic)#1 (4) {
+    [u"a"]=>
+    int(1)
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"UsesMagic":private]=>
+    unicode(6) "secret"
+  }
+}
+
+--> Read existent, non-existent and dynamic:
+unicode(7) "changed"
+
+Notice: Undefined property: ArrayObject::$nonexistent in %s on line 42
+NULL
+unicode(11) "new.changed"
+  Original wrapped object:
+object(UsesMagic)#1 (4) {
+  [u"a"]=>
+  int(1)
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"UsesMagic":private]=>
+  unicode(6) "secret"
+}
+  Wrapping ArrayObject:
+object(ArrayObject)#2 (3) {
+  [u"a"]=>
+  unicode(7) "changed"
+  [u"dynamic"]=>
+  unicode(11) "new.changed"
+  [u"storage":u"ArrayObject":private]=>
+  object(UsesMagic)#1 (4) {
+    [u"a"]=>
+    int(1)
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"UsesMagic":private]=>
+    unicode(6) "secret"
+  }
+}
+
+--> isset existent, non-existent and dynamic:
+bool(true)
+bool(false)
+bool(true)
+  Original wrapped object:
+object(UsesMagic)#1 (4) {
+  [u"a"]=>
+  int(1)
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"UsesMagic":private]=>
+  unicode(6) "secret"
+}
+  Wrapping ArrayObject:
+object(ArrayObject)#2 (3) {
+  [u"a"]=>
+  unicode(7) "changed"
+  [u"dynamic"]=>
+  unicode(11) "new.changed"
+  [u"storage":u"ArrayObject":private]=>
+  object(UsesMagic)#1 (4) {
+    [u"a"]=>
+    int(1)
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"UsesMagic":private]=>
+    unicode(6) "secret"
+  }
+}
+
+--> Unset existent, non-existent and dynamic:
+  Original wrapped object:
+object(UsesMagic)#1 (4) {
+  [u"a"]=>
+  int(1)
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"UsesMagic":private]=>
+  unicode(6) "secret"
+}
+  Wrapping ArrayObject:
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(UsesMagic)#1 (4) {
+    [u"a"]=>
+    int(1)
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"UsesMagic":private]=>
+    unicode(6) "secret"
+  }
+}
diff --git a/ext/spl/tests/arrayObject_magicMethods3.phpt b/ext/spl/tests/arrayObject_magicMethods3.phpt
new file mode 100644 (file)
index 0000000..b4ae21a
--- /dev/null
@@ -0,0 +1,195 @@
+--TEST--
+SPL: ArrayObject: ensure a wrapped object's magic methods for property access are not invoked when manipulating the ArrayObject's elements using -> and ArrayObject::ARRAY_AS_PROPS.
+--FILE--
+<?php
+class UsesMagic {
+       public $a = 1;
+       public $b = 2;
+       public $c = 3;
+
+       private $priv = 'secret';
+       
+       function __get($name) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       function __set($name, $value) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       function __isset($name) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       function __unset($name) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       
+}
+
+$obj = new UsesMagic;
+
+$ao = new ArrayObject($obj, ArrayObject::ARRAY_AS_PROPS);
+echo "\n--> Write existent, non-existent and dynamic:\n";
+$ao->a = 'changed';
+$ao->dynamic = 'new';
+$ao->dynamic = 'new.changed';
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+
+echo "\n--> Read existent, non-existent and dynamic:\n";
+var_dump($ao->a);
+var_dump($ao->nonexistent);
+var_dump($ao->dynamic);
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+
+echo "\n--> isset existent, non-existent and dynamic:\n";
+var_dump(isset($ao->a));
+var_dump(isset($ao->nonexistent));
+var_dump(isset($ao->dynamic));
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+
+echo "\n--> Unset existent, non-existent and dynamic:\n";
+unset($ao->a);
+unset($ao->nonexistent);
+unset($ao->dynamic);
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+?>
+--EXPECTF--
+--> Write existent, non-existent and dynamic:
+  Original wrapped object:
+object(UsesMagic)#1 (5) {
+  [u"a"]=>
+  unicode(7) "changed"
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"UsesMagic":private]=>
+  unicode(6) "secret"
+  [u"dynamic"]=>
+  unicode(11) "new.changed"
+}
+  Wrapping ArrayObject:
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(UsesMagic)#1 (5) {
+    [u"a"]=>
+    unicode(7) "changed"
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"UsesMagic":private]=>
+    unicode(6) "secret"
+    [u"dynamic"]=>
+    unicode(11) "new.changed"
+  }
+}
+
+--> Read existent, non-existent and dynamic:
+unicode(7) "changed"
+
+Notice: Undefined index:  nonexistent in %s on line 42
+NULL
+unicode(11) "new.changed"
+  Original wrapped object:
+object(UsesMagic)#1 (5) {
+  [u"a"]=>
+  unicode(7) "changed"
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"UsesMagic":private]=>
+  unicode(6) "secret"
+  [u"dynamic"]=>
+  unicode(11) "new.changed"
+}
+  Wrapping ArrayObject:
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(UsesMagic)#1 (5) {
+    [u"a"]=>
+    unicode(7) "changed"
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"UsesMagic":private]=>
+    unicode(6) "secret"
+    [u"dynamic"]=>
+    unicode(11) "new.changed"
+  }
+}
+
+--> isset existent, non-existent and dynamic:
+bool(true)
+bool(false)
+bool(true)
+  Original wrapped object:
+object(UsesMagic)#1 (5) {
+  [u"a"]=>
+  unicode(7) "changed"
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"UsesMagic":private]=>
+  unicode(6) "secret"
+  [u"dynamic"]=>
+  unicode(11) "new.changed"
+}
+  Wrapping ArrayObject:
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(UsesMagic)#1 (5) {
+    [u"a"]=>
+    unicode(7) "changed"
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"UsesMagic":private]=>
+    unicode(6) "secret"
+    [u"dynamic"]=>
+    unicode(11) "new.changed"
+  }
+}
+
+--> Unset existent, non-existent and dynamic:
+
+Notice: Undefined index:  nonexistent in %s on line 60
+  Original wrapped object:
+object(UsesMagic)#1 (3) {
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"UsesMagic":private]=>
+  unicode(6) "secret"
+}
+  Wrapping ArrayObject:
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  object(UsesMagic)#1 (3) {
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"UsesMagic":private]=>
+    unicode(6) "secret"
+  }
+}
diff --git a/ext/spl/tests/arrayObject_magicMethods4.phpt b/ext/spl/tests/arrayObject_magicMethods4.phpt
new file mode 100644 (file)
index 0000000..85f2d99
--- /dev/null
@@ -0,0 +1,206 @@
+--TEST--
+SPL: ArrayObject: ensure the magic methods for property access of a subclass of ArrayObject are not invoked when manipulating its elements using [].
+--FILE--
+<?php
+class C {
+       public $a = 1;
+       public $b = 2;
+       public $c = 3;
+
+       private $priv = 'secret';
+}
+
+class UsesMagic extends ArrayObject {
+       
+       public $b = "This should not be in the storage";
+
+       function __get($name) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       function __set($name, $value) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       function __isset($name) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       function __unset($name) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       
+}
+$obj = new C;
+$ao = new UsesMagic($obj);
+echo "\n--> Write existent, non-existent and dynamic:\n";
+$ao['a'] = 'changed';
+$ao['dynamic'] = 'new';
+$ao['dynamic'] = 'new.changed';
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+
+echo "\n--> Read existent, non-existent and dynamic:\n";
+var_dump($ao['a']);
+var_dump($ao['nonexistent']);
+var_dump($ao['dynamic']);
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+
+echo "\n--> isset existent, non-existent and dynamic:\n";
+var_dump(isset($ao['a']));
+var_dump(isset($ao['nonexistent']));
+var_dump(isset($ao['dynamic']));
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+
+echo "\n--> Unset existent, non-existent and dynamic:\n";
+unset($ao['a']);
+unset($ao['nonexistent']);
+unset($ao['dynamic']);
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+?>
+--EXPECTF--
+--> Write existent, non-existent and dynamic:
+  Original wrapped object:
+object(C)#1 (5) {
+  [u"a"]=>
+  unicode(7) "changed"
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"C":private]=>
+  unicode(6) "secret"
+  [u"dynamic"]=>
+  unicode(11) "new.changed"
+}
+  Wrapping ArrayObject:
+object(UsesMagic)#2 (2) {
+  [u"b"]=>
+  unicode(33) "This should not be in the storage"
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (5) {
+    [u"a"]=>
+    unicode(7) "changed"
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"C":private]=>
+    unicode(6) "secret"
+    [u"dynamic"]=>
+    unicode(11) "new.changed"
+  }
+}
+
+--> Read existent, non-existent and dynamic:
+unicode(7) "changed"
+
+Notice: Undefined index:  nonexistent in %s on line 45
+NULL
+unicode(11) "new.changed"
+  Original wrapped object:
+object(C)#1 (5) {
+  [u"a"]=>
+  unicode(7) "changed"
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"C":private]=>
+  unicode(6) "secret"
+  [u"dynamic"]=>
+  unicode(11) "new.changed"
+}
+  Wrapping ArrayObject:
+object(UsesMagic)#2 (2) {
+  [u"b"]=>
+  unicode(33) "This should not be in the storage"
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (5) {
+    [u"a"]=>
+    unicode(7) "changed"
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"C":private]=>
+    unicode(6) "secret"
+    [u"dynamic"]=>
+    unicode(11) "new.changed"
+  }
+}
+
+--> isset existent, non-existent and dynamic:
+bool(true)
+bool(false)
+bool(true)
+  Original wrapped object:
+object(C)#1 (5) {
+  [u"a"]=>
+  unicode(7) "changed"
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"C":private]=>
+  unicode(6) "secret"
+  [u"dynamic"]=>
+  unicode(11) "new.changed"
+}
+  Wrapping ArrayObject:
+object(UsesMagic)#2 (2) {
+  [u"b"]=>
+  unicode(33) "This should not be in the storage"
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (5) {
+    [u"a"]=>
+    unicode(7) "changed"
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"C":private]=>
+    unicode(6) "secret"
+    [u"dynamic"]=>
+    unicode(11) "new.changed"
+  }
+}
+
+--> Unset existent, non-existent and dynamic:
+
+Notice: Undefined index:  nonexistent in %s on line 63
+  Original wrapped object:
+object(C)#1 (3) {
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"C":private]=>
+  unicode(6) "secret"
+}
+  Wrapping ArrayObject:
+object(UsesMagic)#2 (2) {
+  [u"b"]=>
+  unicode(33) "This should not be in the storage"
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (3) {
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"C":private]=>
+    unicode(6) "secret"
+  }
+}
diff --git a/ext/spl/tests/arrayObject_magicMethods5.phpt b/ext/spl/tests/arrayObject_magicMethods5.phpt
new file mode 100644 (file)
index 0000000..67dbd7b
--- /dev/null
@@ -0,0 +1,206 @@
+--TEST--
+SPL: ArrayObject: ensure the magic methods for property access of a subclass of ArrayObject ARE invoked when manipulating its elements using ->.
+--FILE--
+<?php
+class C {
+       public $a = 1;
+       public $b = 2;
+       public $c = 3;
+
+       private $priv = 'secret';
+}
+
+class UsesMagic extends ArrayObject {
+       
+       public $b = "This should appear in storage";
+
+       function __get($name) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       function __set($name, $value) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       function __isset($name) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       function __unset($name) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       
+}
+$obj = new C;
+$ao = new UsesMagic($obj);
+echo "\n--> Write existent, non-existent and dynamic:\n";
+$ao->a = 'changed';
+$ao->dynamic = 'new';
+$ao->dynamic = 'new.changed';
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+
+echo "\n--> Read existent, non-existent and dynamic:\n";
+var_dump($ao->a);
+var_dump($ao->nonexistent);
+var_dump($ao->dynamic);
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+
+echo "\n--> isset existent, non-existent and dynamic:\n";
+var_dump(isset($ao->a));
+var_dump(isset($ao->nonexistent));
+var_dump(isset($ao->dynamic));
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+
+echo "\n--> Unset existent, non-existent and dynamic:\n";
+unset($ao->a);
+unset($ao->nonexistent);
+unset($ao->dynamic);
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+?>
+--EXPECTF--
+--> Write existent, non-existent and dynamic:
+In UsesMagic::__set(a,changed)
+In UsesMagic::__set(dynamic,new)
+In UsesMagic::__set(dynamic,new.changed)
+  Original wrapped object:
+object(C)#1 (4) {
+  [u"a"]=>
+  int(1)
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"C":private]=>
+  unicode(6) "secret"
+}
+  Wrapping ArrayObject:
+object(UsesMagic)#2 (2) {
+  [u"b"]=>
+  unicode(29) "This should appear in storage"
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (4) {
+    [u"a"]=>
+    int(1)
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"C":private]=>
+    unicode(6) "secret"
+  }
+}
+
+--> Read existent, non-existent and dynamic:
+In UsesMagic::__get(a)
+NULL
+In UsesMagic::__get(nonexistent)
+NULL
+In UsesMagic::__get(dynamic)
+NULL
+  Original wrapped object:
+object(C)#1 (4) {
+  [u"a"]=>
+  int(1)
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"C":private]=>
+  unicode(6) "secret"
+}
+  Wrapping ArrayObject:
+object(UsesMagic)#2 (2) {
+  [u"b"]=>
+  unicode(29) "This should appear in storage"
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (4) {
+    [u"a"]=>
+    int(1)
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"C":private]=>
+    unicode(6) "secret"
+  }
+}
+
+--> isset existent, non-existent and dynamic:
+In UsesMagic::__isset(a)
+bool(false)
+In UsesMagic::__isset(nonexistent)
+bool(false)
+In UsesMagic::__isset(dynamic)
+bool(false)
+  Original wrapped object:
+object(C)#1 (4) {
+  [u"a"]=>
+  int(1)
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"C":private]=>
+  unicode(6) "secret"
+}
+  Wrapping ArrayObject:
+object(UsesMagic)#2 (2) {
+  [u"b"]=>
+  unicode(29) "This should appear in storage"
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (4) {
+    [u"a"]=>
+    int(1)
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"C":private]=>
+    unicode(6) "secret"
+  }
+}
+
+--> Unset existent, non-existent and dynamic:
+In UsesMagic::__unset(a)
+In UsesMagic::__unset(nonexistent)
+In UsesMagic::__unset(dynamic)
+  Original wrapped object:
+object(C)#1 (4) {
+  [u"a"]=>
+  int(1)
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"C":private]=>
+  unicode(6) "secret"
+}
+  Wrapping ArrayObject:
+object(UsesMagic)#2 (2) {
+  [u"b"]=>
+  unicode(29) "This should appear in storage"
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (4) {
+    [u"a"]=>
+    int(1)
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"C":private]=>
+    unicode(6) "secret"
+  }
+}
diff --git a/ext/spl/tests/arrayObject_magicMethods6.phpt b/ext/spl/tests/arrayObject_magicMethods6.phpt
new file mode 100644 (file)
index 0000000..c916a5c
--- /dev/null
@@ -0,0 +1,209 @@
+--TEST--
+SPL: ArrayObject: ensure the magic methods for property access of a subclass of ArrayObject are not invoked when manipulating its elements using -> ArrayObject::ARRAY_AS_PROPS.
+--FILE--
+<?php
+class C {
+       public $a = 1;
+       public $b = 2;
+       public $c = 3;
+
+       private $priv = 'secret';
+}
+
+class UsesMagic extends ArrayObject {
+       
+       public $b = "This should never appear in storage";
+
+       function __get($name) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       function __set($name, $value) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       function __isset($name) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       function __unset($name) { 
+               $args = func_get_args();
+               echo "In " . __METHOD__ . "(" . implode($args, ',') . ")\n";
+       }
+       
+}
+$obj = new C;
+$ao = new UsesMagic($obj, ArrayObject::ARRAY_AS_PROPS);
+echo "\n--> Write existent, non-existent and dynamic:\n";
+$ao->a = 'changed';
+$ao->dynamic = 'new';
+$ao->dynamic = 'new.changed';
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+
+echo "\n--> Read existent, non-existent and dynamic:\n";
+var_dump($ao->a);
+var_dump($ao->nonexistent);
+var_dump($ao->dynamic);
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+
+echo "\n--> isset existent, non-existent and dynamic:\n";
+var_dump(isset($ao->a));
+var_dump(isset($ao->nonexistent));
+var_dump(isset($ao->dynamic));
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+
+echo "\n--> Unset existent, non-existent and dynamic:\n";
+unset($ao->a);
+unset($ao->nonexistent);
+unset($ao->dynamic);
+echo "  Original wrapped object:\n";
+var_dump($obj);
+echo "  Wrapping ArrayObject:\n";
+var_dump($ao);
+?>
+--EXPECTF--
+--> Write existent, non-existent and dynamic:
+  Original wrapped object:
+object(C)#1 (5) {
+  [u"a"]=>
+  unicode(7) "changed"
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"C":private]=>
+  unicode(6) "secret"
+  [u"dynamic"]=>
+  unicode(11) "new.changed"
+}
+  Wrapping ArrayObject:
+object(UsesMagic)#2 (2) {
+  [u"b"]=>
+  unicode(35) "This should never appear in storage"
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (5) {
+    [u"a"]=>
+    unicode(7) "changed"
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"C":private]=>
+    unicode(6) "secret"
+    [u"dynamic"]=>
+    unicode(11) "new.changed"
+  }
+}
+
+--> Read existent, non-existent and dynamic:
+unicode(7) "changed"
+
+Notice: Undefined index:  nonexistent in %s on line 45
+NULL
+unicode(11) "new.changed"
+  Original wrapped object:
+object(C)#1 (5) {
+  [u"a"]=>
+  unicode(7) "changed"
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"C":private]=>
+  unicode(6) "secret"
+  [u"dynamic"]=>
+  unicode(11) "new.changed"
+}
+  Wrapping ArrayObject:
+object(UsesMagic)#2 (2) {
+  [u"b"]=>
+  unicode(35) "This should never appear in storage"
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (5) {
+    [u"a"]=>
+    unicode(7) "changed"
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"C":private]=>
+    unicode(6) "secret"
+    [u"dynamic"]=>
+    unicode(11) "new.changed"
+  }
+}
+
+--> isset existent, non-existent and dynamic:
+In UsesMagic::__isset(a)
+bool(true)
+In UsesMagic::__isset(nonexistent)
+bool(false)
+In UsesMagic::__isset(dynamic)
+bool(true)
+  Original wrapped object:
+object(C)#1 (5) {
+  [u"a"]=>
+  unicode(7) "changed"
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"C":private]=>
+  unicode(6) "secret"
+  [u"dynamic"]=>
+  unicode(11) "new.changed"
+}
+  Wrapping ArrayObject:
+object(UsesMagic)#2 (2) {
+  [u"b"]=>
+  unicode(35) "This should never appear in storage"
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (5) {
+    [u"a"]=>
+    unicode(7) "changed"
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"C":private]=>
+    unicode(6) "secret"
+    [u"dynamic"]=>
+    unicode(11) "new.changed"
+  }
+}
+
+--> Unset existent, non-existent and dynamic:
+
+Notice: Undefined index:  nonexistent in %s on line 63
+  Original wrapped object:
+object(C)#1 (3) {
+  [u"b"]=>
+  int(2)
+  [u"c"]=>
+  int(3)
+  [u"priv":u"C":private]=>
+  unicode(6) "secret"
+}
+  Wrapping ArrayObject:
+object(UsesMagic)#2 (2) {
+  [u"b"]=>
+  unicode(35) "This should never appear in storage"
+  [u"storage":u"ArrayObject":private]=>
+  object(C)#1 (3) {
+    [u"b"]=>
+    int(2)
+    [u"c"]=>
+    int(3)
+    [u"priv":u"C":private]=>
+    unicode(6) "secret"
+  }
+}
diff --git a/ext/spl/tests/arrayObject_natcasesort_basic1.phpt b/ext/spl/tests/arrayObject_natcasesort_basic1.phpt
new file mode 100644 (file)
index 0000000..c5ee452
--- /dev/null
@@ -0,0 +1,56 @@
+--TEST--
+SPL: Test ArrayObject::natcasesort() function : basic functionality 
+--FILE--
+<?php
+/* Prototype  : int ArrayObject::natcasesort()
+ * Description: proto int ArrayIterator::natcasesort()
+ Sort the entries by values using case insensitive "natural order" algorithm. 
+ * Source code: ext/spl/spl_array.c
+ * Alias to functions: 
+ */
+
+echo "*** Testing ArrayObject::natcasesort() : basic functionality ***\n";
+
+$ao1 = new ArrayObject(array('boo10','boo1','boo2','boo22','BOO5'));
+$ao2 = new ArrayObject(array('a'=>'boo10','b'=>'boo1','c'=>'boo2','d'=>'boo22','e'=>'BOO5'));
+var_dump($ao1->natcasesort());
+var_dump($ao1);
+var_dump($ao2->natcasesort('blah'));
+var_dump($ao2);
+?>
+===DONE===
+--EXPECTF--
+*** Testing ArrayObject::natcasesort() : basic functionality ***
+bool(true)
+object(ArrayObject)#1 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  array(5) {
+    [1]=>
+    unicode(4) "boo1"
+    [2]=>
+    unicode(4) "boo2"
+    [4]=>
+    unicode(4) "BOO5"
+    [0]=>
+    unicode(5) "boo10"
+    [3]=>
+    unicode(5) "boo22"
+  }
+}
+bool(true)
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  array(5) {
+    [u"b"]=>
+    unicode(4) "boo1"
+    [u"c"]=>
+    unicode(4) "boo2"
+    [u"e"]=>
+    unicode(4) "BOO5"
+    [u"a"]=>
+    unicode(5) "boo10"
+    [u"d"]=>
+    unicode(5) "boo22"
+  }
+}
+===DONE===
diff --git a/ext/spl/tests/arrayObject_natsort_basic1.phpt b/ext/spl/tests/arrayObject_natsort_basic1.phpt
new file mode 100644 (file)
index 0000000..44723f2
--- /dev/null
@@ -0,0 +1,56 @@
+--TEST--
+SPL: Test ArrayObject::natsort() function : basic functionality 
+--FILE--
+<?php
+/* Prototype  : int ArrayObject::natsort()
+ * Description: proto int ArrayIterator::natsort()
+ Sort the entries by values using "natural order" algorithm. 
+ * Source code: ext/spl/spl_array.c
+ * Alias to functions: 
+ */
+
+echo "*** Testing ArrayObject::natsort() : basic functionality ***\n";
+
+$ao1 = new ArrayObject(array('boo10','boo1','boo2','boo22','BOO5'));
+$ao2 = new ArrayObject(array('a'=>'boo10','b'=>'boo1','c'=>'boo2','d'=>'boo22','e'=>'BOO5'));
+var_dump($ao1->natsort());
+var_dump($ao1);
+var_dump($ao2->natsort('blah'));
+var_dump($ao2);
+?>
+===DONE===
+--EXPECTF--
+*** Testing ArrayObject::natsort() : basic functionality ***
+bool(true)
+object(ArrayObject)#1 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  array(5) {
+    [4]=>
+    unicode(4) "BOO5"
+    [1]=>
+    unicode(4) "boo1"
+    [2]=>
+    unicode(4) "boo2"
+    [0]=>
+    unicode(5) "boo10"
+    [3]=>
+    unicode(5) "boo22"
+  }
+}
+bool(true)
+object(ArrayObject)#2 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  array(5) {
+    [u"e"]=>
+    unicode(4) "BOO5"
+    [u"b"]=>
+    unicode(4) "boo1"
+    [u"c"]=>
+    unicode(4) "boo2"
+    [u"a"]=>
+    unicode(5) "boo10"
+    [u"d"]=>
+    unicode(5) "boo22"
+  }
+}
+===DONE===
diff --git a/ext/spl/tests/arrayObject_setFlags_basic1.phpt b/ext/spl/tests/arrayObject_setFlags_basic1.phpt
new file mode 100644 (file)
index 0000000..465e162
--- /dev/null
@@ -0,0 +1,51 @@
+--TEST--
+SPL: ArrayObject::setFlags basic usage with ArrayObject::ARRAY_AS_PROPS. Currently fails on php.net due to bug 45622. 
+--FILE--
+<?php
+class C extends ArrayObject {
+       public $p = 'object property';
+}      
+
+function access_p($ao) {
+  // isset
+  var_dump(isset($ao->p));
+  // read
+  var_dump($ao->p);
+  // write  
+  $ao->p = $ao->p . '.changed';
+  var_dump($ao->p);
+}
+
+$ao = new C(array('p'=>'array element'));
+$ao->setFlags(ArrayObject::ARRAY_AS_PROPS);
+
+echo "\n--> Access the real property:\n";
+access_p($ao);
+
+echo "\n--> Remove the real property and access the array element:\n";
+unset($ao->p);
+access_p($ao);
+
+echo "\n--> Remove the array element and try access again:\n";
+unset($ao->p);
+access_p($ao);
+?>
+--EXPECTF--
+--> Access the real property:
+bool(true)
+unicode(15) "object property"
+unicode(23) "object property.changed"
+
+--> Remove the real property and access the array element:
+bool(true)
+unicode(13) "array element"
+unicode(21) "array element.changed"
+
+--> Remove the array element and try access again:
+bool(false)
+
+Notice: Undefined index:  p in %s on line 10
+NULL
+
+Notice: Undefined index:  p in %s on line 12
+unicode(8) ".changed"
diff --git a/ext/spl/tests/arrayObject_setFlags_basic2.phpt b/ext/spl/tests/arrayObject_setFlags_basic2.phpt
new file mode 100644 (file)
index 0000000..42b550d
--- /dev/null
@@ -0,0 +1,29 @@
+--TEST--
+SPL: Ensure access to non-visible properties falls back to dimension access with ArrayObject::ARRAY_AS_PROPS.
+--FILE--
+<?php
+class C extends ArrayObject {
+       private $x = 'secret';
+       
+       static function go($c) {
+         var_dump($c->x);
+       }
+}      
+
+$c = new C(array('x'=>'public'));
+
+$c->setFlags(ArrayObject::ARRAY_AS_PROPS);
+C::go($c);
+var_dump($c->x);
+
+
+$c->setFlags(0);
+C::go($c);
+var_dump($c->x);
+?>
+--EXPECTF--
+unicode(6) "secret"
+unicode(6) "public"
+unicode(6) "secret"
+
+Fatal error: Cannot access private property C::$x in %s on line 19
diff --git a/ext/spl/tests/arrayObject_setIteratorClass_error1.phpt b/ext/spl/tests/arrayObject_setIteratorClass_error1.phpt
new file mode 100644 (file)
index 0000000..0436d4c
--- /dev/null
@@ -0,0 +1,56 @@
+--TEST--
+SPL: ArrayObject with bad iterator class.
+--FILE--
+<?php
+try {
+  $ao = new ArrayObject(array('a'=>1,'b'=>2,'c'=>3));
+  $ao->setIteratorClass("nonExistentClass");
+  foreach($ao as $key=>$value) {
+    echo "  $key=>$value\n";
+  }
+} catch (Exception $e) {
+       var_dump($e->getMessage());
+}
+
+try {
+  $ao = new ArrayObject(array('a'=>1,'b'=>2,'c'=>3));
+  $ao->setIteratorClass("stdClass");
+  foreach($ao as $key=>$value) {
+    echo "  $key=>$value\n";
+  }
+} catch (Exception $e) {
+       var_dump($e->getMessage());
+}
+
+
+try {
+  $ao = new ArrayObject(array('a'=>1,'b'=>2,'c'=>3), 0, "nonExistentClass");
+  foreach($ao as $key=>$value) {
+    echo "  $key=>$value\n";
+  }
+} catch (Exception $e) {
+       var_dump($e->getMessage());
+}
+
+try {
+  $ao = new ArrayObject(array('a'=>1,'b'=>2,'c'=>3), 0, "stdClass");
+  foreach($ao as $key=>$value) {
+    echo "  $key=>$value\n";
+  }
+} catch (Exception $e) {
+       var_dump($e->getMessage());
+}
+
+?>
+--EXPECTF--
+Warning: ArrayObject::setIteratorClass() expects parameter 1 to be a class name derived from Iterator, 'nonExistentClass' given in %s on line 4
+  a=>1
+  b=>2
+  c=>3
+
+Warning: ArrayObject::setIteratorClass() expects parameter 1 to be a class name derived from Iterator, 'stdClass' given in %s on line 14
+  a=>1
+  b=>2
+  c=>3
+unicode(113) "ArrayObject::__construct() expects parameter 3 to be a class name derived from Iterator, 'nonExistentClass' given"
+unicode(105) "ArrayObject::__construct() expects parameter 3 to be a class name derived from Iterator, 'stdClass' given"
diff --git a/ext/spl/tests/arrayObject_uasort_basic1.phpt b/ext/spl/tests/arrayObject_uasort_basic1.phpt
new file mode 100644 (file)
index 0000000..291f0de
--- /dev/null
@@ -0,0 +1,44 @@
+--TEST--
+SPL: Test ArrayObject::uasort() function : basic functionality 
+--FILE--
+<?php
+/* Prototype  : int ArrayObject::uasort(callback cmp_function)
+ * Description: proto int ArrayIterator::uasort(callback cmp_function)
+ Sort the entries by values user defined function. 
+ * Source code: ext/spl/spl_array.c
+ * Alias to functions: 
+ */
+
+echo "*** Testing ArrayObject::uasort() : basic functionality ***\n";
+
+// Reverse sorter
+function cmp($value1, $value2) {
+  if($value1 == $value2) {
+    return 0;
+  }
+  else if($value1 < $value2) {
+    return 1;
+  }
+  else
+    return -1;
+}
+$ao = new ArrayObject(array(2,3,1));
+
+$ao->uasort('cmp');
+var_dump($ao);
+?>
+===DONE===
+--EXPECTF--
+*** Testing ArrayObject::uasort() : basic functionality ***
+object(ArrayObject)#1 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  array(3) {
+    [1]=>
+    int(3)
+    [0]=>
+    int(2)
+    [2]=>
+    int(1)
+  }
+}
+===DONE===
diff --git a/ext/spl/tests/arrayObject_uasort_error1.phpt b/ext/spl/tests/arrayObject_uasort_error1.phpt
new file mode 100644 (file)
index 0000000..d7306c9
--- /dev/null
@@ -0,0 +1,30 @@
+--TEST--
+Test ArrayObject::uasort() function : wrong arg count 
+--FILE--
+<?php
+/* Prototype  : int ArrayObject::uasort(callback cmp_function)
+ * Description: proto int ArrayIterator::uasort(callback cmp_function)
+ Sort the entries by values user defined function. 
+ * Source code: ext/spl/spl_array.c
+ * Alias to functions: 
+ */
+
+$ao = new ArrayObject();
+
+try {
+       $ao->uasort();
+} catch (BadMethodCallException $e) {
+       echo $e->getMessage() . "\n";
+}
+
+try {
+       $ao->uasort(1,2);
+} catch (BadMethodCallException $e) {
+       echo $e->getMessage() . "\n";
+}
+?>
+===DONE===
+--EXPECTF--
+Function expects exactly one argument
+Function expects exactly one argument
+===DONE===
diff --git a/ext/spl/tests/arrayObject_uksort_basic1.phpt b/ext/spl/tests/arrayObject_uksort_basic1.phpt
new file mode 100644 (file)
index 0000000..9ea6ccb
--- /dev/null
@@ -0,0 +1,47 @@
+--TEST--
+Test ArrayObject::uksort() function : basic functionality 
+--FILE--
+<?php
+/* Prototype  : int ArrayObject::uksort(callback cmp_function)
+ * Description: proto int ArrayIterator::uksort(callback cmp_function)
+ * Sort the entries by key using user defined function. 
+ * Source code: ext/spl/spl_array.c
+ * Alias to functions: 
+ */
+
+echo "*** Testing ArrayObject::uksort() : basic functionality ***\n";
+// Reverse sorter
+function cmp($value1, $value2) {
+  if($value1 == $value2) {
+    return 0;
+  }
+  else if($value1 < $value2) {
+    return 1;
+  }
+  else
+    return -1;
+}
+$ao = new ArrayObject(array(3=>0, 2=>1, 5=>2, 6=>3, 1=>4));
+
+$ao->uksort('cmp');
+var_dump($ao);
+?>
+===DONE===
+--EXPECTF--
+*** Testing ArrayObject::uksort() : basic functionality ***
+object(ArrayObject)#1 (1) {
+  [u"storage":u"ArrayObject":private]=>
+  array(5) {
+    [6]=>
+    int(3)
+    [5]=>
+    int(2)
+    [3]=>
+    int(0)
+    [2]=>
+    int(1)
+    [1]=>
+    int(4)
+  }
+}
+===DONE===
diff --git a/ext/spl/tests/arrayObject_uksort_error1.phpt b/ext/spl/tests/arrayObject_uksort_error1.phpt
new file mode 100644 (file)
index 0000000..d019fc4
--- /dev/null
@@ -0,0 +1,30 @@
+--TEST--
+Test ArrayObject::uksort() function : wrong arg count 
+--FILE--
+<?php
+/* Prototype  : int ArrayObject::uksort(callback cmp_function)
+ * Description: proto int ArrayIterator::uksort(callback cmp_function)
+ Sort the entries by key using user defined function.
+ * Source code: ext/spl/spl_array.c
+ * Alias to functions: 
+ */
+
+$ao = new ArrayObject();
+
+try {
+       $ao->uksort();
+} catch (BadMethodCallException $e) {
+       echo $e->getMessage() . "\n";
+}
+
+try {
+       $ao->uksort(1,2);
+} catch (BadMethodCallException $e) {
+       echo $e->getMessage() . "\n";
+}
+?>
+===DONE===
+--EXPECTF--
+Function expects exactly one argument
+Function expects exactly one argument
+===DONE===
diff --git a/ext/spl/tests/class_implements_basic.phpt b/ext/spl/tests/class_implements_basic.phpt
new file mode 100644 (file)
index 0000000..6ba8f3f
--- /dev/null
@@ -0,0 +1,33 @@
+--TEST--
+SPL: Test class_implements() function : basic 
+--FILE--
+<?php
+/* Prototype  : array class_implements(mixed what [, bool autoload ])
+ * Description: Return all classes and interfaces implemented by SPL 
+ * Source code: ext/spl/php_spl.c
+ * Alias to functions: 
+ */
+
+echo "*** Testing class_implements() : basic ***\n";
+
+
+interface foo { }
+class bar implements foo {}
+
+var_dump(class_implements(new bar));
+var_dump(class_implements('bar'));
+
+
+?>
+===DONE===
+--EXPECT--
+*** Testing class_implements() : basic ***
+array(1) {
+  [u"foo"]=>
+  unicode(3) "foo"
+}
+array(1) {
+  [u"foo"]=>
+  unicode(3) "foo"
+}
+===DONE===
diff --git a/ext/spl/tests/class_implements_basic2.phpt b/ext/spl/tests/class_implements_basic2.phpt
new file mode 100644 (file)
index 0000000..1e7b588
--- /dev/null
@@ -0,0 +1,74 @@
+--TEST--
+SPL: Test class_implements() function : basic 
+--FILE--
+<?php
+/* Prototype  : array class_implements(mixed what [, bool autoload ])
+ * Description: Return all classes and interfaces implemented by SPL 
+ * Source code: ext/spl/php_spl.c
+ * Alias to functions: 
+ */
+
+echo "*** Testing class_implements() : basic ***\n";
+
+
+interface foo { }
+class fooImpl implements foo {}
+
+interface bar { }
+class barImpl implements bar {}
+
+class foobarImpl implements foo, bar {}
+
+class fooViaBarImpl extends barImpl implements foo {}
+
+class fooExtended extends fooImpl {}
+
+s_var_dump(class_implements(new foobarImpl));
+s_var_dump(class_implements('foobarImpl'));
+s_var_dump(class_implements(new fooViaBarImpl));
+s_var_dump(class_implements('fooViaBarImpl'));
+s_var_dump(class_implements(new fooExtended));
+s_var_dump(class_implements('fooExtended'));
+
+
+function s_var_dump($arr) {
+   krsort($arr);
+   var_dump($arr);
+}
+?>
+===DONE===
+--EXPECT--
+*** Testing class_implements() : basic ***
+array(2) {
+  [u"foo"]=>
+  unicode(3) "foo"
+  [u"bar"]=>
+  unicode(3) "bar"
+}
+array(2) {
+  [u"foo"]=>
+  unicode(3) "foo"
+  [u"bar"]=>
+  unicode(3) "bar"
+}
+array(2) {
+  [u"foo"]=>
+  unicode(3) "foo"
+  [u"bar"]=>
+  unicode(3) "bar"
+}
+array(2) {
+  [u"foo"]=>
+  unicode(3) "foo"
+  [u"bar"]=>
+  unicode(3) "bar"
+}
+array(1) {
+  [u"foo"]=>
+  unicode(3) "foo"
+}
+array(1) {
+  [u"foo"]=>
+  unicode(3) "foo"
+}
+===DONE===
diff --git a/ext/spl/tests/class_implements_variation.phpt b/ext/spl/tests/class_implements_variation.phpt
new file mode 100644 (file)
index 0000000..52fdbca
--- /dev/null
@@ -0,0 +1,45 @@
+--TEST--
+SPL: Test class_implements() function : variation - no interfaces and autoload
+--FILE--
+<?php
+/* Prototype  : array class_implements(mixed what [, bool autoload ])
+ * Description: Return all classes and interfaces implemented by SPL 
+ * Source code: ext/spl/php_spl.c
+ * Alias to functions: 
+ */
+
+echo "*** Testing class_implements() : variation ***\n";
+
+echo "--- testing no interfaces ---\n";
+class fs {}
+var_dump(class_implements(new fs));
+var_dump(class_implements('fs'));
+
+echo "\n--- testing autoload ---\n";
+var_dump(class_implements('non-existent'));
+var_dump(class_implements('non-existent2', false));
+
+
+function __autoload($classname) {
+   echo "attempting to autoload $classname\n";
+}
+
+?>
+===DONE===
+--EXPECTF--
+*** Testing class_implements() : variation ***
+--- testing no interfaces ---
+array(0) {
+}
+array(0) {
+}
+
+--- testing autoload ---
+attempting to autoload non-existent
+
+Warning: class_implements(): Class non-existent does not exist and could not be loaded in %s on line %d
+bool(false)
+
+Warning: class_implements(): Class non-existent2 does not exist in %s on line %d
+bool(false)
+===DONE===
diff --git a/ext/spl/tests/class_implements_variation1.phpt b/ext/spl/tests/class_implements_variation1.phpt
new file mode 100644 (file)
index 0000000..d8a45ce
--- /dev/null
@@ -0,0 +1,221 @@
+--TEST--
+SPL: Test class_implements() function : variation 
+--FILE--
+<?php
+/* Prototype  : array class_implements(mixed what [, bool autoload ])
+ * Description: Return all classes and interfaces implemented by SPL 
+ * Source code: ext/spl/php_spl.c
+ * Alias to functions: 
+ */
+
+echo "*** Testing class_implements() : variation ***\n";
+
+
+// Define error handler
+function test_error_handler($err_no, $err_msg, $filename, $linenum, $vars) {
+       if (error_reporting() != 0) {
+               // report non-silenced errors
+               echo "Error: $err_no - $err_msg, $filename($linenum)\n";
+       }
+}
+set_error_handler('test_error_handler');
+
+// Initialise function arguments not being substituted (if any)
+$autoload = true;
+
+//resource
+$res = fopen(__FILE__,'r');
+
+//get an unset variable
+$unset_var = 10;
+unset ($unset_var);
+
+// define some classes
+class classWithToString
+{
+       public function __toString() {
+               return "Class A object";
+       }
+}
+
+class classWithoutToString
+{
+}
+
+// heredoc string
+$heredoc = <<<EOT
+hello world
+EOT;
+
+// add arrays
+$index_array = array (1, 2, 3);
+$assoc_array = array ('one' => 1, 'two' => 2);
+
+//array of values to iterate over
+$inputs = array(
+
+      // int data
+      'int 0' => 0,
+      'int 1' => 1,
+      'int 12345' => 12345,
+      'int -12345' => -2345,
+
+      // float data
+      'float 10.5' => 10.5,
+      'float -10.5' => -10.5,
+      'float 12.3456789000e10' => 12.3456789000e10,
+      'float -12.3456789000e10' => -12.3456789000e10,
+      'float .5' => .5,
+
+      // array data
+      'empty array' => array(),
+      'int indexed array' => $index_array,
+      'associative array' => $assoc_array,
+      'nested arrays' => array('foo', $index_array, $assoc_array),
+
+      // null data
+      'uppercase NULL' => NULL,
+      'lowercase null' => null,
+
+      // boolean data
+      'lowercase true' => true,
+      'lowercase false' =>false,
+      'uppercase TRUE' =>TRUE,
+      'uppercase FALSE' =>FALSE,
+
+      // empty data
+      'empty string DQ' => "",
+      'empty string SQ' => '',
+
+      // object data
+      'instance of classWithToString' => new classWithToString(),
+      'instance of classWithoutToString' => new classWithoutToString(),
+
+      // undefined data
+      'undefined var' => @$undefined_var,
+
+      // unset data
+      'unset var' => @$unset_var,
+      
+      //resource
+      'resource' => $res,
+);
+
+// loop through each element of the array for pattern
+
+foreach($inputs as $key =>$value) {
+      echo "\n--$key--\n";
+      var_dump( class_implements($value, $autoload) );
+};
+
+fclose($res);
+
+?>
+===DONE===
+--EXPECTF--
+*** Testing class_implements() : variation ***
+
+--int 0--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--int 1--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--int 12345--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--int -12345--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--float 10.5--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--float -10.5--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--float 12.3456789000e10--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--float -12.3456789000e10--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--float .5--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--empty array--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--int indexed array--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--associative array--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--nested arrays--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--uppercase NULL--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--lowercase null--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--lowercase true--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--lowercase false--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--uppercase TRUE--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--uppercase FALSE--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--empty string DQ--
+Error: 2 - class_implements(): Class  does not exist and could not be loaded, %s(%d)
+bool(false)
+
+--empty string SQ--
+Error: 2 - class_implements(): Class  does not exist and could not be loaded, %s(%d)
+bool(false)
+
+--instance of classWithToString--
+array(0) {
+}
+
+--instance of classWithoutToString--
+array(0) {
+}
+
+--undefined var--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--unset var--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+
+--resource--
+Error: 2 - class_implements(): object or string expected, %s(%d)
+bool(false)
+===DONE===
diff --git a/ext/spl/tests/class_implements_variation2.phpt b/ext/spl/tests/class_implements_variation2.phpt
new file mode 100644 (file)
index 0000000..2a64bed
--- /dev/null
@@ -0,0 +1,259 @@
+--TEST--
+SPL: Test class_implements() function : variation 
+--FILE--
+<?php
+/* Prototype  : array class_implements(mixed what [, bool autoload ])
+ * Description: Return all classes and interfaces implemented by SPL 
+ * Source code: ext/spl/php_spl.c
+ * Alias to functions: 
+ */
+
+echo "*** Testing class_implements() : variation ***\n";
+
+
+// Define error handler
+function test_error_handler($err_no, $err_msg, $filename, $linenum, $vars) {
+       if (error_reporting() != 0) {
+               // report non-silenced errors
+               echo "Error: $err_no - $err_msg, $filename($linenum)\n";
+       }
+}
+set_error_handler('test_error_handler');
+
+// Initialise function arguments not being substituted (if any)
+$class = 'Iterator';
+
+//resource
+$res = fopen(__FILE__,'r');
+
+//get an unset variable
+$unset_var = 10;
+unset ($unset_var);
+
+// define some classes
+class classWithToString
+{
+       public function __toString() {
+               return "Class A object";
+       }
+}
+
+class classWithoutToString
+{
+}
+
+// heredoc string
+$heredoc = <<<EOT
+hello world
+EOT;
+
+// add arrays
+$index_array = array (1, 2, 3);
+$assoc_array = array ('one' => 1, 'two' => 2);
+
+//array of values to iterate over
+$inputs = array(
+
+      // int data
+      'int 0' => 0,
+      'int 1' => 1,
+      'int 12345' => 12345,
+      'int -12345' => -2345,
+
+      // float data
+      'float 10.5' => 10.5,
+      'float -10.5' => -10.5,
+      'float 12.3456789000e10' => 12.3456789000e10,
+      'float -12.3456789000e10' => -12.3456789000e10,
+      'float .5' => .5,
+
+      // array data
+      'empty array' => array(),
+      'int indexed array' => $index_array,
+      'associative array' => $assoc_array,
+      'nested arrays' => array('foo', $index_array, $assoc_array),
+
+      // null data
+      'uppercase NULL' => NULL,
+      'lowercase null' => null,
+
+      // boolean data
+      'lowercase true' => true,
+      'lowercase false' =>false,
+      'uppercase TRUE' =>TRUE,
+      'uppercase FALSE' =>FALSE,
+
+      // empty data
+      'empty string DQ' => "",
+      'empty string SQ' => '',
+
+      // object data
+      'instance of classWithToString' => new classWithToString(),
+      'instance of classWithoutToString' => new classWithoutToString(),
+
+      // undefined data
+      'undefined var' => @$undefined_var,
+
+      // unset data
+      'unset var' => @$unset_var,
+      
+      //resource
+      'resource' => $res,
+);
+
+// loop through each element of the array for pattern
+
+foreach($inputs as $key =>$value) {
+      echo "\n--$key--\n";
+      var_dump( class_implements($class, $value) );
+};
+
+fclose($res);
+
+?>
+===DONE===
+--EXPECTF--
+*** Testing class_implements() : variation ***
+
+--int 0--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--int 1--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--int 12345--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--int -12345--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--float 10.5--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--float -10.5--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--float 12.3456789000e10--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--float -12.3456789000e10--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--float .5--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--empty array--
+Error: 2 - class_implements() expects parameter 2 to be boolean, array given, %s(%d)
+bool(false)
+
+--int indexed array--
+Error: 2 - class_implements() expects parameter 2 to be boolean, array given, %s(%d)
+bool(false)
+
+--associative array--
+Error: 2 - class_implements() expects parameter 2 to be boolean, array given, %s(%d)
+bool(false)
+
+--nested arrays--
+Error: 2 - class_implements() expects parameter 2 to be boolean, array given, %s(%d)
+bool(false)
+
+--uppercase NULL--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--lowercase null--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--lowercase true--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--lowercase false--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--uppercase TRUE--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--uppercase FALSE--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--empty string DQ--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--empty string SQ--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--instance of classWithToString--
+Error: 2 - class_implements() expects parameter 2 to be boolean, object given, %s(%d)
+bool(false)
+
+--instance of classWithoutToString--
+Error: 2 - class_implements() expects parameter 2 to be boolean, object given, %s(%d)
+bool(false)
+
+--undefined var--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--unset var--
+array(1) {
+  [u"Traversable"]=>
+  unicode(11) "Traversable"
+}
+
+--resource--
+Error: 2 - class_implements() expects parameter 2 to be boolean, resource given, %s(%d)
+bool(false)
+===DONE===
diff --git a/ext/spl/tests/countable_class_basic1.phpt b/ext/spl/tests/countable_class_basic1.phpt
new file mode 100644 (file)
index 0000000..0f712cb
--- /dev/null
@@ -0,0 +1,34 @@
+--TEST--
+SPL: Test shape of interface Countable.
+--SKIPIF--
+<?php 
+// Skip the test case if Standard PHP Library(spl) is not installed
+  if( !extension_loaded('spl'))
+  {
+     die('skip spl is not installed');
+  }
+?>
+--FILE--
+<?php
+ReflectionClass::export('Countable');
+?>
+--EXPECTF--
+Interface [ <internal%s> interface Countable ] {
+
+  - Constants [0] {
+  }
+
+  - Static properties [0] {
+  }
+
+  - Static methods [0] {
+  }
+
+  - Properties [0] {
+  }
+
+  - Methods [1] {
+    Method [ <internal%s> abstract public method count ] {
+    }
+  }
+}
diff --git a/ext/spl/tests/countable_count_variation1.phpt b/ext/spl/tests/countable_count_variation1.phpt
new file mode 100644 (file)
index 0000000..642887d
--- /dev/null
@@ -0,0 +1,68 @@
+--TEST--
+SPL: Countable::count() with wrong return types and exception.
+--FILE--
+<?php
+
+Class returnNull implements Countable {
+       function count() {
+       }
+}
+
+Class returnString implements Countable {
+       function count() {
+               return "hello";
+       }
+}
+
+Class returnObject implements Countable {
+       function count() {
+               return new returnObject;
+       }
+}
+
+Class returnArray implements Countable {
+       function count() {
+               return array(1,2,3);
+       }
+}
+
+Class throwException implements Countable {
+       function count() {
+               throw new Exception('Thrown from count');
+       }
+}
+
+
+echo "Count returns null:\n";
+var_dump(count(new returnNull));
+
+echo "Count returns a string:\n";
+var_dump(count(new returnString));
+
+echo "Count returns an object:\n";
+var_dump(count(new returnObject));
+
+echo "Count returns an array:\n";
+var_dump(count(new returnArray));
+
+echo "Count throws an exception:\n";
+try {
+       echo count(new throwException);
+} catch (Exception $e) {
+       echo $e->getMessage();
+}
+
+?>
+--EXPECTF--
+Count returns null:
+int(0)
+Count returns a string:
+int(0)
+Count returns an object:
+
+Notice: Object of class returnObject could not be converted to int in %s on line 40
+int(1)
+Count returns an array:
+int(1)
+Count throws an exception:
+Thrown from count
\ No newline at end of file