summaryrefslogtreecommitdiff
path: root/Zend/tests/traits
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2013-03-14 05:42:27 +0000
committer <>2013-04-03 16:25:08 +0000
commitc4dd7a1a684490673e25aaf4fabec5df138854c4 (patch)
tree4d57c44caae4480efff02b90b9be86f44bf25409 /Zend/tests/traits
downloadphp2-master.tar.gz
Imported from /home/lorry/working-area/delta_php2/php-5.4.13.tar.bz2.HEADphp-5.4.13master
Diffstat (limited to 'Zend/tests/traits')
-rw-r--r--Zend/tests/traits/bug54441.phpt19
-rw-r--r--Zend/tests/traits/bug55137.phpt26
-rw-r--r--Zend/tests/traits/bug55214.phpt71
-rw-r--r--Zend/tests/traits/bug55355.phpt46
-rw-r--r--Zend/tests/traits/bug55372.phpt28
-rw-r--r--Zend/tests/traits/bug55424.phpt35
-rw-r--r--Zend/tests/traits/bug55524.phpt15
-rw-r--r--Zend/tests/traits/bug55554a.phpt34
-rw-r--r--Zend/tests/traits/bug55554b.phpt56
-rw-r--r--Zend/tests/traits/bug55554c.phpt46
-rw-r--r--Zend/tests/traits/bug55554d.phpt32
-rw-r--r--Zend/tests/traits/bug55554e.phpt30
-rw-r--r--Zend/tests/traits/bug55554f.phpt29
-rw-r--r--Zend/tests/traits/bug55554g.phpt29
-rw-r--r--Zend/tests/traits/bug60145.phpt17
-rw-r--r--Zend/tests/traits/bug60153.phpt19
-rw-r--r--Zend/tests/traits/bug60165a.phpt17
-rw-r--r--Zend/tests/traits/bug60165b.phpt17
-rw-r--r--Zend/tests/traits/bug60165c.phpt22
-rw-r--r--Zend/tests/traits/bug60165d.phpt21
-rw-r--r--Zend/tests/traits/bug60173.phpt12
-rw-r--r--Zend/tests/traits/bug60217a.phpt26
-rw-r--r--Zend/tests/traits/bug60217b.phpt26
-rw-r--r--Zend/tests/traits/bug60217c.phpt26
-rw-r--r--Zend/tests/traits/bug60369.phpt17
-rw-r--r--Zend/tests/traits/bug60717.phpt73
-rw-r--r--Zend/tests/traits/bug60809.phpt36
-rw-r--r--Zend/tests/traits/bug61052.phpt18
-rw-r--r--Zend/tests/traits/bug61998.phpt68
-rw-r--r--Zend/tests/traits/bug64070.phpt36
-rw-r--r--Zend/tests/traits/bug64235.phpt34
-rw-r--r--Zend/tests/traits/bug64235b.phpt35
-rw-r--r--Zend/tests/traits/bugs/abstract-methods01.phpt19
-rw-r--r--Zend/tests/traits/bugs/abstract-methods02.phpt26
-rw-r--r--Zend/tests/traits/bugs/abstract-methods03.phpt22
-rw-r--r--Zend/tests/traits/bugs/abstract-methods04.phpt36
-rw-r--r--Zend/tests/traits/bugs/abstract-methods05.phpt25
-rw-r--r--Zend/tests/traits/bugs/abstract-methods06.phpt26
-rw-r--r--Zend/tests/traits/bugs/alias-semantics.phpt23
-rw-r--r--Zend/tests/traits/bugs/alias-semantics02.phpt25
-rw-r--r--Zend/tests/traits/bugs/alias01.phpt26
-rw-r--r--Zend/tests/traits/bugs/case-sensitive.phpt23
-rw-r--r--Zend/tests/traits/bugs/interfaces.phpt19
-rw-r--r--Zend/tests/traits/bugs/missing-trait.phpt15
-rw-r--r--Zend/tests/traits/bugs/overridding-conflicting-methods.phpt31
-rw-r--r--Zend/tests/traits/bugs/overridding-conflicting-property-initializer.phpt23
-rw-r--r--Zend/tests/traits/conflict001.phpt25
-rw-r--r--Zend/tests/traits/conflict002.phpt32
-rw-r--r--Zend/tests/traits/conflict003.phpt31
-rw-r--r--Zend/tests/traits/error_001.phpt28
-rw-r--r--Zend/tests/traits/error_002.phpt12
-rw-r--r--Zend/tests/traits/error_003.phpt15
-rw-r--r--Zend/tests/traits/error_004.phpt15
-rw-r--r--Zend/tests/traits/error_005.phpt15
-rw-r--r--Zend/tests/traits/error_006.phpt15
-rw-r--r--Zend/tests/traits/error_007.phpt13
-rw-r--r--Zend/tests/traits/error_008.phpt12
-rw-r--r--Zend/tests/traits/error_009.phpt12
-rw-r--r--Zend/tests/traits/error_010.phpt23
-rw-r--r--Zend/tests/traits/error_011.phpt26
-rw-r--r--Zend/tests/traits/error_012.phpt19
-rw-r--r--Zend/tests/traits/error_013.phpt19
-rw-r--r--Zend/tests/traits/error_014.phpt23
-rw-r--r--Zend/tests/traits/error_015.phpt26
-rw-r--r--Zend/tests/traits/error_016.phpt12
-rw-r--r--Zend/tests/traits/flattening001.phpt42
-rw-r--r--Zend/tests/traits/flattening002.phpt28
-rw-r--r--Zend/tests/traits/flattening003.phpt32
-rw-r--r--Zend/tests/traits/get_declared_traits_001.phpt19
-rw-r--r--Zend/tests/traits/get_declared_traits_002.phpt20
-rw-r--r--Zend/tests/traits/get_declared_traits_003.phpt25
-rw-r--r--Zend/tests/traits/inheritance001.phpt24
-rw-r--r--Zend/tests/traits/inheritance002.phpt27
-rw-r--r--Zend/tests/traits/inheritance003.phpt38
-rw-r--r--Zend/tests/traits/interface_001.phpt25
-rw-r--r--Zend/tests/traits/interface_002.phpt24
-rw-r--r--Zend/tests/traits/interface_003.phpt27
-rw-r--r--Zend/tests/traits/language001.phpt21
-rw-r--r--Zend/tests/traits/language002.phpt32
-rw-r--r--Zend/tests/traits/language003.phpt29
-rw-r--r--Zend/tests/traits/language004.phpt31
-rw-r--r--Zend/tests/traits/language005.phpt40
-rw-r--r--Zend/tests/traits/language006.phpt31
-rw-r--r--Zend/tests/traits/language007.phpt30
-rw-r--r--Zend/tests/traits/language008a.phpt23
-rw-r--r--Zend/tests/traits/language008b.phpt30
-rw-r--r--Zend/tests/traits/language009.phpt36
-rw-r--r--Zend/tests/traits/language010.phpt30
-rw-r--r--Zend/tests/traits/language011.phpt30
-rw-r--r--Zend/tests/traits/language012.phpt27
-rw-r--r--Zend/tests/traits/language013.phpt37
-rw-r--r--Zend/tests/traits/language014.phpt30
-rw-r--r--Zend/tests/traits/language015.phpt17
-rw-r--r--Zend/tests/traits/language016.phpt17
-rw-r--r--Zend/tests/traits/language017.phpt17
-rw-r--r--Zend/tests/traits/language018.phpt15
-rw-r--r--Zend/tests/traits/language019.phpt15
-rw-r--r--Zend/tests/traits/methods_001.phpt39
-rw-r--r--Zend/tests/traits/methods_002.phpt28
-rw-r--r--Zend/tests/traits/methods_003.phpt24
-rw-r--r--Zend/tests/traits/noctor001.phpt28
-rw-r--r--Zend/tests/traits/property001.phpt41
-rw-r--r--Zend/tests/traits/property002.phpt32
-rw-r--r--Zend/tests/traits/property003.phpt30
-rw-r--r--Zend/tests/traits/property004.phpt30
-rw-r--r--Zend/tests/traits/property005.phpt40
-rw-r--r--Zend/tests/traits/property006.phpt37
-rw-r--r--Zend/tests/traits/property007.phpt38
-rw-r--r--Zend/tests/traits/property008.phpt62
-rw-r--r--Zend/tests/traits/property009.phpt59
-rw-r--r--Zend/tests/traits/static_001.phpt22
-rw-r--r--Zend/tests/traits/static_002.phpt23
-rw-r--r--Zend/tests/traits/static_003.phpt27
-rw-r--r--Zend/tests/traits/static_004.phpt22
-rw-r--r--Zend/tests/traits/static_forward_static_call.phpt28
-rw-r--r--Zend/tests/traits/static_get_called_class.phpt24
-rw-r--r--Zend/tests/traits/trait_constant_001.phpt36
-rw-r--r--Zend/tests/traits/trait_constant_002.phpt27
118 files changed, 3294 insertions, 0 deletions
diff --git a/Zend/tests/traits/bug54441.phpt b/Zend/tests/traits/bug54441.phpt
new file mode 100644
index 0000000..84139f3
--- /dev/null
+++ b/Zend/tests/traits/bug54441.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Bug #54441 (Changing trait static method visibility)
+--FILE--
+<?php
+
+trait Foo {
+ public function bar() {}
+}
+
+class Boo {
+ use Foo {
+ bar as dontKnow;
+ dontKnow as protected;
+ }
+}
+
+?>
+--EXPECTF--
+Fatal error: The modifiers for the trait alias dontKnow() need to be changed in the same statment in which the alias is defined. Error in %s on line %d
diff --git a/Zend/tests/traits/bug55137.phpt b/Zend/tests/traits/bug55137.phpt
new file mode 100644
index 0000000..4a4e6e6
--- /dev/null
+++ b/Zend/tests/traits/bug55137.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Bug #55137 (Changing trait static method visibility)
+--FILE--
+<?php
+
+trait A {
+ protected static function foo() { echo "abc\n"; }
+ private static function bar() { echo "def\n"; }
+}
+
+
+class B {
+ use A {
+ A::foo as public;
+ A::bar as public baz;
+ }
+}
+
+B::foo();
+B::baz();
+
+
+?>
+--EXPECT--
+abc
+def
diff --git a/Zend/tests/traits/bug55214.phpt b/Zend/tests/traits/bug55214.phpt
new file mode 100644
index 0000000..890fc37
--- /dev/null
+++ b/Zend/tests/traits/bug55214.phpt
@@ -0,0 +1,71 @@
+--TEST--
+Bug #55214 (Use of __CLASS__ within trait returns trait name not class name)
+--FILE--
+<?php
+
+trait ATrait {
+ public static $static_var = __CLASS__;
+ public $var = __CLASS__;
+
+ public static function get_class_name() {
+ return __CLASS__;
+ }
+
+ public function get_class_name_obj() {
+ return __CLASS__;
+ }
+
+ public static function get_class_name2() {
+ return self::$static_var;
+ }
+
+ public function get_class_name_obj2() {
+ return $this->var;
+ }
+}
+
+trait Indirect {
+ use ATrait;
+}
+
+class SomeClass {
+ use ATrait;
+}
+
+class UsingIndirect {
+ use Indirect;
+}
+
+$r = SomeClass::get_class_name();
+var_dump($r);
+$r = SomeClass::get_class_name2();
+var_dump($r);
+
+$o = new SomeClass();
+$r = $o->get_class_name_obj();
+var_dump($r);
+$r = $o->get_class_name_obj2();
+var_dump($r);
+
+$r = UsingIndirect::get_class_name();
+var_dump($r);
+$r = UsingIndirect::get_class_name2();
+var_dump($r);
+
+$o = new UsingIndirect();
+$r = $o->get_class_name_obj();
+var_dump($r);
+$r = $o->get_class_name_obj2();
+var_dump($r);
+
+
+?>
+--EXPECT--
+string(9) "SomeClass"
+string(9) "SomeClass"
+string(9) "SomeClass"
+string(9) "SomeClass"
+string(13) "UsingIndirect"
+string(13) "UsingIndirect"
+string(13) "UsingIndirect"
+string(13) "UsingIndirect"
diff --git a/Zend/tests/traits/bug55355.phpt b/Zend/tests/traits/bug55355.phpt
new file mode 100644
index 0000000..301ceee
--- /dev/null
+++ b/Zend/tests/traits/bug55355.phpt
@@ -0,0 +1,46 @@
+--TEST--
+Bug #55355 (Abstract functions required by a trait are not correctly found when implemented in an ancestor class)
+--FILE--
+<?php
+
+// A trait that has a abstract function
+trait ATrait {
+ function bar() {
+ $this->foo();
+ }
+ abstract function foo();
+}
+
+// A class on the second level in the
+// inheritance chain
+class Level2Impl {
+ function foo() {}
+}
+
+class Level1Indirect extends Level2Impl {}
+
+// A class on the first level in the
+// inheritance chain
+class Level1Direct {
+ function foo() {}
+}
+
+// Trait Uses
+
+class Direct {
+ use ATrait;
+ function foo() {}
+}
+
+class BaseL2 extends Level1Indirect {
+ use ATrait;
+}
+
+class BaseL1 extends Level1Direct {
+ use ATrait;
+}
+
+echo 'DONE';
+?>
+--EXPECT--
+DONE
diff --git a/Zend/tests/traits/bug55372.phpt b/Zend/tests/traits/bug55372.phpt
new file mode 100644
index 0000000..e215d96
--- /dev/null
+++ b/Zend/tests/traits/bug55372.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Bug #55372 (Literal handling in methods is inconsistent, causing memory corruption)
+--FILE--
+<?php
+
+trait testTrait {
+ public function testMethod() {
+ if (1) {
+ $letters1 = range('a', 'z', 1);
+ $letters2 = range('A', 'Z', 1);
+ $letters1 = 'foo';
+ $letters2 = 'baarr';
+ var_dump($letters1);
+ var_dump($letters2);
+ }
+ }
+}
+
+class foo {
+ use testTrait;
+}
+
+$x = new foo;
+$x->testMethod();
+?>
+--EXPECT--
+string(3) "foo"
+string(5) "baarr"
diff --git a/Zend/tests/traits/bug55424.phpt b/Zend/tests/traits/bug55424.phpt
new file mode 100644
index 0000000..b6c3b54
--- /dev/null
+++ b/Zend/tests/traits/bug55424.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Bug #55424 (Method got missing from class when a trait defined an abstract method to express a requirement)
+--FILE--
+<?php
+
+ trait ATrait
+ {
+ function setRequired()
+ {
+ $this->setAttribute();
+ }
+
+ abstract function setAttribute();
+ }
+
+ class Base
+ {
+ function setAttribute() { }
+ }
+
+ class MyClass extends Base
+ {
+ use ATrait;
+ }
+
+ $i = new Base();
+ $i->setAttribute();
+
+ $t = new MyClass();
+ /* setAttribute used to disappear for no good reason. */
+ $t->setRequired();
+ echo 'DONE';
+?>
+--EXPECT--
+DONE
diff --git a/Zend/tests/traits/bug55524.phpt b/Zend/tests/traits/bug55524.phpt
new file mode 100644
index 0000000..1379759
--- /dev/null
+++ b/Zend/tests/traits/bug55524.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Bug #55524 Traits should not be able to extend a class
+--FILE--
+<?php
+
+class Base {}
+
+trait Foo extends Base {
+ function bar() {}
+}
+
+echo 'DONE';
+?>
+--EXPECTF--
+Fatal error: A trait (Foo) cannot extend a class. Traits can only be composed from other traits with the 'use' keyword. Error in %s on line %d
diff --git a/Zend/tests/traits/bug55554a.phpt b/Zend/tests/traits/bug55554a.phpt
new file mode 100644
index 0000000..b92a81f
--- /dev/null
+++ b/Zend/tests/traits/bug55554a.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Bug #55137 (Legacy constructor not registered for class)
+--FILE--
+<?php
+
+// All constructors should be registered as such
+
+trait TConstructor {
+ public function constructor() {
+ echo "ctor executed\n";
+ }
+}
+
+class NewConstructor {
+ use TConstructor {
+ constructor as __construct;
+ }
+}
+
+class LegacyConstructor {
+ use TConstructor {
+ constructor as LegacyConstructor;
+ }
+}
+
+echo "New constructor: ";
+$o = new NewConstructor;
+
+echo "Legacy constructor: ";
+$o = new LegacyConstructor;
+
+--EXPECT--
+New constructor: ctor executed
+Legacy constructor: ctor executed
diff --git a/Zend/tests/traits/bug55554b.phpt b/Zend/tests/traits/bug55554b.phpt
new file mode 100644
index 0000000..bf40e89
--- /dev/null
+++ b/Zend/tests/traits/bug55554b.phpt
@@ -0,0 +1,56 @@
+--TEST--
+Bug #55137 (Legacy constructor not registered for class)
+--FILE--
+<?php
+
+trait TConstructor {
+ public function foo() {
+ echo "foo executed\n";
+ }
+ public function bar() {
+ echo "bar executed\n";
+ }
+}
+
+class OverridingIsSilent1 {
+ use TConstructor {
+ foo as __construct;
+ }
+
+ public function __construct() {
+ echo "OverridingIsSilent1 __construct\n";
+ }
+}
+
+$o = new OverridingIsSilent1;
+
+class OverridingIsSilent2 {
+ use TConstructor {
+ foo as OverridingIsSilent2;
+ }
+
+ public function OverridingIsSilent2() {
+ echo "OverridingIsSilent2 OverridingIsSilent2\n";
+ }
+}
+
+$o = new OverridingIsSilent2;
+
+class ReportCollision {
+ use TConstructor {
+ bar as ReportCollision;
+ foo as __construct;
+ }
+}
+
+
+echo "ReportCollision: ";
+$o = new ReportCollision;
+
+
+--EXPECTF--
+OverridingIsSilent1 __construct
+OverridingIsSilent2 OverridingIsSilent2
+
+Fatal error: ReportCollision has colliding constructor definitions coming from traits in %s on line %d
+
diff --git a/Zend/tests/traits/bug55554c.phpt b/Zend/tests/traits/bug55554c.phpt
new file mode 100644
index 0000000..466b3f1
--- /dev/null
+++ b/Zend/tests/traits/bug55554c.phpt
@@ -0,0 +1,46 @@
+--TEST--
+Bug #55137 (Legacy constructor not registered for class)
+--FILE--
+<?php
+
+// Test that the behavior is consistent with the existing handling of new
+// and legacy constructors.
+// Here, the traits conflicts are overridden by local definitions,
+// and the two constructor definitions do not directly collide in that case.
+
+trait TC1 {
+ public function __construct() {
+ echo "TC1 executed\n";
+ }
+ public function ReportCollision() {
+ echo "TC1 executed\n";
+ }
+}
+
+trait TC2 {
+ public function __construct() {
+ echo "TC2 executed\n";
+ }
+ public function ReportCollision() {
+ echo "TC1 executed\n";
+ }
+}
+
+class ReportCollision {
+ use TC1, TC2;
+
+ public function __construct() {
+ echo "New constructor executed\n";
+ }
+ public function ReportCollision() {
+ echo "Legacy constructor executed\n";
+ }
+}
+
+
+echo "ReportCollision: ";
+$o = new ReportCollision;
+
+
+--EXPECTF--
+ReportCollision: New constructor executed
diff --git a/Zend/tests/traits/bug55554d.phpt b/Zend/tests/traits/bug55554d.phpt
new file mode 100644
index 0000000..10f2e29
--- /dev/null
+++ b/Zend/tests/traits/bug55554d.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Bug #55137 (Legacy constructor not registered for class)
+--FILE--
+<?php
+
+// Test mixed constructors from different traits, we are more strict about
+// these cases, since that can lead to un-expected behavior.
+// It is not consistent with the normal constructor handling, but
+// here we have a chance to be more strict for the new traits.
+
+trait TNew {
+ public function __construct() {
+ echo "TNew executed\n";
+ }
+}
+
+trait TLegacy {
+ public function ReportCollision() {
+ echo "ReportCollision executed\n";
+ }
+}
+
+class ReportCollision {
+ use TNew, TLegacy;
+}
+
+$o = new ReportCollision;
+
+--EXPECTF--
+
+Fatal error: ReportCollision has colliding constructor definitions coming from traits in %s on line %d
+
diff --git a/Zend/tests/traits/bug55554e.phpt b/Zend/tests/traits/bug55554e.phpt
new file mode 100644
index 0000000..5db508f
--- /dev/null
+++ b/Zend/tests/traits/bug55554e.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Bug #55137 (Legacy constructor not registered for class)
+--FILE--
+<?php
+
+// Ensuring that the collision still occurs as expected.
+
+trait TC1 {
+ public function ReportCollision() {
+ echo "TC1 executed\n";
+ }
+}
+
+trait TC2 {
+ public function ReportCollision() {
+ echo "TC1 executed\n";
+ }
+}
+
+class ReportCollision {
+ use TC1, TC2;
+}
+
+
+echo "ReportCollision: ";
+$o = new ReportCollision;
+
+
+--EXPECTF--
+Fatal error: Trait method ReportCollision has not been applied, because there are collisions with other trait methods on ReportCollision in %s on line %d \ No newline at end of file
diff --git a/Zend/tests/traits/bug55554f.phpt b/Zend/tests/traits/bug55554f.phpt
new file mode 100644
index 0000000..34b327d
--- /dev/null
+++ b/Zend/tests/traits/bug55554f.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Bug #55137 (Legacy constructor not registered for class)
+--FILE--
+<?php
+
+// Ensuring that inconsistent constructor use results in an error to avoid
+// problems creeping in.
+
+trait TNew {
+ public function __construct() {
+ echo "TNew executed\n";
+ }
+}
+
+class ReportCollision {
+ use TNew;
+
+ public function ReportCollision() {
+ echo "ReportCollision executed\n";
+ }
+}
+
+
+echo "ReportCollision: ";
+$o = new ReportCollision;
+
+
+--EXPECTF--
+Fatal error: ReportCollision has colliding constructor definitions coming from traits in %s on line %d \ No newline at end of file
diff --git a/Zend/tests/traits/bug55554g.phpt b/Zend/tests/traits/bug55554g.phpt
new file mode 100644
index 0000000..22d2696
--- /dev/null
+++ b/Zend/tests/traits/bug55554g.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Bug #55137 (Legacy constructor not registered for class)
+--FILE--
+<?php
+
+// Ensuring that inconsistent constructor use results in an error to avoid
+// problems creeping in.
+
+trait TLegacy {
+ public function ReportCollision() {
+ echo "TLegacy executed\n";
+ }
+}
+
+class ReportCollision {
+ use TLegacy;
+
+ public function __construct() {
+ echo "ReportCollision executed\n";
+ }
+}
+
+
+echo "ReportCollision: ";
+$o = new ReportCollision;
+
+
+--EXPECTF--
+Fatal error: ReportCollision has colliding constructor definitions coming from traits in %s on line %d \ No newline at end of file
diff --git a/Zend/tests/traits/bug60145.phpt b/Zend/tests/traits/bug60145.phpt
new file mode 100644
index 0000000..fcd0cfa
--- /dev/null
+++ b/Zend/tests/traits/bug60145.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #60145 (Usage of trait's use statement inside interfaces not properly checked.)
+--FILE--
+<?php
+
+trait foo {
+
+}
+
+interface MyInterface {
+ use foo;
+
+ public function b();
+
+}
+--EXPECTF--
+Fatal error: Cannot use traits inside of interfaces. foo is used in MyInterface in %s on line %d
diff --git a/Zend/tests/traits/bug60153.phpt b/Zend/tests/traits/bug60153.phpt
new file mode 100644
index 0000000..979eced
--- /dev/null
+++ b/Zend/tests/traits/bug60153.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Bug #60153 (Interface method prototypes not enforced when implementd via traits.)
+--FILE--
+<?php
+
+interface IFoo {
+ public function oneArgument($a);
+}
+
+trait TFoo {
+ public function oneArgument() {}
+}
+
+class C implements IFoo {
+ use TFoo;
+}
+
+--EXPECTF--
+Fatal error: Declaration of TFoo::oneArgument() must be compatible with IFoo::oneArgument($a) in %s on line %d
diff --git a/Zend/tests/traits/bug60165a.phpt b/Zend/tests/traits/bug60165a.phpt
new file mode 100644
index 0000000..245bb94
--- /dev/null
+++ b/Zend/tests/traits/bug60165a.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #60165 (Aliasing unexisting trait should throw/trigger the exception/error)
+--FILE--
+<?php
+
+trait A {
+ public function bar() {}
+}
+
+class MyClass {
+ use A {
+ nonExistent as barA;
+ }
+}
+
+--EXPECTF--
+Fatal error: An alias (barA) was defined for method nonExistent(), but this method does not exist in %s on line %d
diff --git a/Zend/tests/traits/bug60165b.phpt b/Zend/tests/traits/bug60165b.phpt
new file mode 100644
index 0000000..7b4855a
--- /dev/null
+++ b/Zend/tests/traits/bug60165b.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #60165 (Aliasing unexisting trait should throw/trigger the exception/error)
+--FILE--
+<?php
+
+trait A {
+ public function bar() {}
+}
+
+class MyClass {
+ use A {
+ A::nonExistent as barA;
+ }
+}
+
+--EXPECTF--
+Fatal error: An alias was defined for A::nonExistent but this method does not exist in %s on line %d
diff --git a/Zend/tests/traits/bug60165c.phpt b/Zend/tests/traits/bug60165c.phpt
new file mode 100644
index 0000000..d72491f
--- /dev/null
+++ b/Zend/tests/traits/bug60165c.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Bug #60165 (Aliasing unexisting trait should throw/trigger the exception/error)
+--FILE--
+<?php
+
+trait A {
+ public function bar() {}
+}
+
+trait B {
+ public function foo() {}
+}
+
+class MyClass {
+ use A, B {
+ foo as fooB;
+ baz as foobar;
+ }
+}
+
+--EXPECTF--
+Fatal error: An alias (foobar) was defined for method baz(), but this method does not exist in %s on line %d
diff --git a/Zend/tests/traits/bug60165d.phpt b/Zend/tests/traits/bug60165d.phpt
new file mode 100644
index 0000000..26ac927
--- /dev/null
+++ b/Zend/tests/traits/bug60165d.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug #60165 (Aliasing unexisting trait should throw/trigger the exception/error)
+--FILE--
+<?php
+
+// The same is true for the insteadof operator to resolve conflicts
+
+trait A {}
+
+trait B {
+ public function bar() {}
+}
+
+class MyClass {
+ use A, B {
+ A::bar insteadof B;
+ }
+}
+
+--EXPECTF--
+Fatal error: A precedence rule was defined for A::bar but this method does not exist in %s on line %d
diff --git a/Zend/tests/traits/bug60173.phpt b/Zend/tests/traits/bug60173.phpt
new file mode 100644
index 0000000..a28a103
--- /dev/null
+++ b/Zend/tests/traits/bug60173.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Bug #60173 (Wrong error message on reflective trait instantiation)
+--FILE--
+<?php
+
+trait foo { }
+
+$rc = new ReflectionClass('foo');
+$rc->newInstance();
+
+--EXPECTF--
+Fatal error: Cannot instantiate trait foo in %s on line %d
diff --git a/Zend/tests/traits/bug60217a.phpt b/Zend/tests/traits/bug60217a.phpt
new file mode 100644
index 0000000..62a3515
--- /dev/null
+++ b/Zend/tests/traits/bug60217a.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Bug #60217 (Requiring the same method from different traits.)
+--FILE--
+<?php
+
+trait T1 {
+ public abstract function foo();
+}
+
+trait T2 {
+ public abstract function foo();
+}
+
+class C {
+ use T1, T2;
+
+ public function foo() {
+ echo "C::foo() works.\n";
+ }
+}
+
+$o = new C;
+$o->foo();
+
+--EXPECTF--
+C::foo() works.
diff --git a/Zend/tests/traits/bug60217b.phpt b/Zend/tests/traits/bug60217b.phpt
new file mode 100644
index 0000000..eb852a4
--- /dev/null
+++ b/Zend/tests/traits/bug60217b.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Bug #60217 (Requiring the same method from different traits and abstract methods have to be compatible)
+--FILE--
+<?php
+
+trait TBroken1 {
+ public abstract function foo($a);
+}
+
+trait TBroken2 {
+ public abstract function foo($a, $b = 0);
+}
+
+class CBroken {
+ use TBroken1, TBroken2;
+
+ public function foo($a) {
+ echo 'FOO';
+ }
+}
+
+$o = new CBroken;
+$o->foo(1);
+
+--EXPECTF--
+Fatal error: Declaration of TBroken2::foo($a, $b = 0) must be compatible with TBroken1::foo($a) in %s on line %d
diff --git a/Zend/tests/traits/bug60217c.phpt b/Zend/tests/traits/bug60217c.phpt
new file mode 100644
index 0000000..baa4314
--- /dev/null
+++ b/Zend/tests/traits/bug60217c.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Bug #60217 (Requiring the same method from different traits and abstract methods have to be compatible, in both directions.)
+--FILE--
+<?php
+
+trait TBroken1 {
+ public abstract function foo($a, $b = 0);
+}
+
+trait TBroken2 {
+ public abstract function foo($a);
+}
+
+class CBroken {
+ use TBroken1, TBroken2;
+
+ public function foo($a) {
+ echo 'FOO';
+ }
+}
+
+$o = new CBroken;
+$o->foo(1);
+
+--EXPECTF--
+Fatal error: Declaration of TBroken2::foo($a) must be compatible with TBroken1::foo($a, $b = 0) in %s on line %d
diff --git a/Zend/tests/traits/bug60369.phpt b/Zend/tests/traits/bug60369.phpt
new file mode 100644
index 0000000..bfc1ee3
--- /dev/null
+++ b/Zend/tests/traits/bug60369.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #60369 (Crash with static property in trait)
+--FILE--
+<?php
+
+trait PropertiesTrait {
+ static $same = true;
+}
+
+class Properties {
+ use PropertiesTrait;
+ public $same = true;
+}
+
+?>
+--EXPECTF--
+Fatal error: Properties and PropertiesTrait define the same property ($same) in the composition of Properties. However, the definition differs and is considered incompatible. Class was composed in %s on line %d \ No newline at end of file
diff --git a/Zend/tests/traits/bug60717.phpt b/Zend/tests/traits/bug60717.phpt
new file mode 100644
index 0000000..bf3adb1
--- /dev/null
+++ b/Zend/tests/traits/bug60717.phpt
@@ -0,0 +1,73 @@
+--TEST--
+Bug #60717 (Order of traits in use statement can cause unexpected unresolved abstract method)
+--FILE--
+<?php
+
+namespace HTML
+{
+ interface Helper
+ {
+ function text($text);
+ function attributes(array $attributes = null);
+ function textArea(array $attributes = null, $value);
+ }
+
+ trait TextUTF8
+ {
+ function text($text) {}
+ }
+
+ trait TextArea
+ {
+ function textArea(array $attributes = null, $value) {}
+ abstract function attributes(array $attributes = null);
+ abstract function text($text);
+ }
+
+ trait HTMLAttributes
+ {
+ function attributes(array $attributes = null) { }
+ abstract function text($text);
+ }
+
+ class HTMLHelper implements Helper
+ {
+ use TextArea, HTMLAttributes, TextUTF8;
+ }
+
+ class HTMLHelper2 implements Helper
+ {
+ use TextArea, TextUTF8, HTMLAttributes;
+ }
+
+ class HTMLHelper3 implements Helper
+ {
+ use HTMLAttributes, TextArea, TextUTF8;
+ }
+
+ class HTMLHelper4 implements Helper
+ {
+ use HTMLAttributes, TextUTF8, TextArea;
+ }
+
+ class HTMLHelper5 implements Helper
+ {
+ use TextUTF8, TextArea, HTMLAttributes;
+ }
+
+ class HTMLHelper6 implements Helper
+ {
+ use TextUTF8, HTMLAttributes, TextArea;
+ }
+
+ $o = new HTMLHelper;
+ $o = new HTMLHelper2;
+ $o = new HTMLHelper3;
+ $o = new HTMLHelper4;
+ $o = new HTMLHelper5;
+ $o = new HTMLHelper6;
+ echo 'Done';
+}
+
+--EXPECT--
+Done
diff --git a/Zend/tests/traits/bug60809.phpt b/Zend/tests/traits/bug60809.phpt
new file mode 100644
index 0000000..78e7898
--- /dev/null
+++ b/Zend/tests/traits/bug60809.phpt
@@ -0,0 +1,36 @@
+--TEST--
+Bug #60809 (TRAITS - PHPDoc Comment Style Bug)
+--FILE--
+<?php
+class ExampleParent {
+ private $hello_world = "hello foo\n";
+ public function foo() {
+ echo $this->hello_world;
+ }
+}
+
+class Example extends ExampleParent {
+ use ExampleTrait;
+}
+
+trait ExampleTrait {
+ /**
+ *
+ */
+ private $hello_world = "hello bar\n";
+ /**
+ *
+ */
+ public $prop = "ops";
+ public function bar() {
+ echo $this->hello_world;
+ }
+}
+
+$x = new Example();
+$x->foo();
+$x->bar();
+?>
+--EXPECT--
+hello foo
+hello bar
diff --git a/Zend/tests/traits/bug61052.phpt b/Zend/tests/traits/bug61052.phpt
new file mode 100644
index 0000000..421e907
--- /dev/null
+++ b/Zend/tests/traits/bug61052.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Bug #61052 (missing error check in trait 'insteadof' clause)
+--FILE--
+<?php
+trait T1 {
+ function foo(){ echo "T1\n"; }
+}
+trait T2 {
+ function foo(){ echo "T2\n"; }
+}
+class C {
+ use T1, T2 {
+ T1::foo insteadof T1;
+ }
+}
+C::foo();
+--EXPECTF--
+Fatal error: Inconsistent insteadof definition. The method foo is to be used from T1, but T1 is also on the exclude list in %s on line %d
diff --git a/Zend/tests/traits/bug61998.phpt b/Zend/tests/traits/bug61998.phpt
new file mode 100644
index 0000000..612caa0
--- /dev/null
+++ b/Zend/tests/traits/bug61998.phpt
@@ -0,0 +1,68 @@
+--TEST--
+Bug #61998 (Using traits with method aliases appears to result in crash during execution)
+--FILE--
+<?php
+class Foo {
+ use T1 {
+ func as newFunc;
+ }
+
+ public function func() {
+ echo "From Foo\n";
+ }
+}
+
+trait T1 {
+ public function func() {
+ echo "From T1\n";
+ }
+}
+
+class Bar {
+ public function func() {
+ echo "From Bar\n";
+ }
+ public function func2() {
+ echo "From Bar\n";
+ }
+ public function func3() {
+ echo "From Bar\n";
+ }
+ use T1 {
+ func as newFunc;
+ func as func2;
+ }
+ use T2 {
+ func2 as newFunc2;
+ func2 as newFunc3;
+ func2 as func3;
+ }
+}
+
+trait T2 {
+ public function func2() {
+ echo "From T2\n";
+ }
+}
+
+$f = new Foo();
+
+$f->newFunc(); //from T1
+$f->func(); //from Foo
+
+$b = new Bar();
+$b->newFunc(); //from T1
+$b->func(); //from Bar
+$b->func2(); //from Bar
+$b->newFunc2(); //from T2
+$b->newFunc3(); //from T2
+$b->func3(); //from Bar
+--EXPECTF--
+From T1
+From Foo
+From T1
+From Bar
+From Bar
+From T2
+From T2
+From Bar
diff --git a/Zend/tests/traits/bug64070.phpt b/Zend/tests/traits/bug64070.phpt
new file mode 100644
index 0000000..a5ee3b6
--- /dev/null
+++ b/Zend/tests/traits/bug64070.phpt
@@ -0,0 +1,36 @@
+--TEST--
+Bug #64070 (Inheritance with Traits failed with error)
+--FILE--
+<?php
+trait first_trait
+{
+ function first_function()
+ {
+ echo "From First Trait\n";
+ }
+}
+
+trait second_trait
+{
+ use first_trait {
+ first_trait::first_function as second_function;
+ }
+
+ function first_function()
+ {
+ echo "From Second Trait\n";
+ }
+}
+
+class first_class
+{
+ use second_trait;
+}
+
+$obj = new first_class();
+$obj->first_function();
+$obj->second_function();
+?>
+--EXPECT--
+From Second Trait
+From First Trait
diff --git a/Zend/tests/traits/bug64235.phpt b/Zend/tests/traits/bug64235.phpt
new file mode 100644
index 0000000..d0a2a98
--- /dev/null
+++ b/Zend/tests/traits/bug64235.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Bug #64235 (Insteadof not work for class method in 5.4.11)
+--FILE--
+<?php
+
+class TestParentClass
+{
+ public function method()
+ {
+ print_r('Parent method');
+ print "\n";
+ }
+}
+
+trait TestTrait
+{
+ public function method()
+ {
+ print_r('Trait method');
+ print "\n";
+ }
+}
+
+class TestChildClass extends TestParentClass
+{
+ use TestTrait
+ {
+ TestTrait::method as methodAlias;
+ TestParentClass::method insteadof TestTrait;
+ }
+}
+?>
+--EXPECTF--
+Fatal error: Class TestParentClass is not a trait, Only traits may be used in 'as' and 'insteadof' statements in %sbug64235.php on line %d
diff --git a/Zend/tests/traits/bug64235b.phpt b/Zend/tests/traits/bug64235b.phpt
new file mode 100644
index 0000000..a326ec0
--- /dev/null
+++ b/Zend/tests/traits/bug64235b.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Bug #64235 (Insteadof not work for class method in 5.4.11)
+--FILE--
+<?php
+
+class TestParentClass
+{
+ public function method()
+ {
+ print_r('Parent method');
+ print "\n";
+ }
+}
+
+trait TestTrait
+{
+ public function method()
+ {
+ print_r('Trait method');
+ print "\n";
+ }
+}
+
+class TestChildClass extends TestParentClass
+{
+ use TestTrait
+ {
+ TestTrait::method as methodAlias;
+ TestParentClass::method as TestParent;
+ }
+}
+
+?>
+--EXPECTF--
+Fatal error: Class TestParentClass is not a trait, Only traits may be used in 'as' and 'insteadof' statements in %sbug64235b.php on line %d
diff --git a/Zend/tests/traits/bugs/abstract-methods01.phpt b/Zend/tests/traits/bugs/abstract-methods01.phpt
new file mode 100644
index 0000000..6275caa
--- /dev/null
+++ b/Zend/tests/traits/bugs/abstract-methods01.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Abstract Trait Methods should behave like common abstract methods.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait THello {
+ public abstract function hello();
+}
+
+class TraitsTest {
+ use THello;
+}
+
+$test = new TraitsTest();
+$test->hello();
+?>
+--EXPECTF--
+Fatal error: Class %s contains %d abstract method and must therefore be declared abstract or implement the remaining methods (%s) in %s on line %d \ No newline at end of file
diff --git a/Zend/tests/traits/bugs/abstract-methods02.phpt b/Zend/tests/traits/bugs/abstract-methods02.phpt
new file mode 100644
index 0000000..78abe7d
--- /dev/null
+++ b/Zend/tests/traits/bugs/abstract-methods02.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Abstract Trait Methods should behave like common abstract methods.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait THello {
+ public abstract function hello();
+}
+
+trait THelloImpl {
+ public function hello() {
+ echo 'Hello';
+ }
+}
+
+class TraitsTest {
+ use THello;
+ use THelloImpl;
+}
+
+$test = new TraitsTest();
+$test->hello();
+?>
+--EXPECTF--
+Hello \ No newline at end of file
diff --git a/Zend/tests/traits/bugs/abstract-methods03.phpt b/Zend/tests/traits/bugs/abstract-methods03.phpt
new file mode 100644
index 0000000..605b1d8
--- /dev/null
+++ b/Zend/tests/traits/bugs/abstract-methods03.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Abstract Trait Methods should behave like common abstract methods.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait THello {
+ public abstract function hello();
+}
+
+class TraitsTest {
+ use THello;
+ public function hello() {
+ echo 'Hello';
+ }
+}
+
+$test = new TraitsTest();
+$test->hello();
+?>
+--EXPECTF--
+Hello \ No newline at end of file
diff --git a/Zend/tests/traits/bugs/abstract-methods04.phpt b/Zend/tests/traits/bugs/abstract-methods04.phpt
new file mode 100644
index 0000000..56a3464
--- /dev/null
+++ b/Zend/tests/traits/bugs/abstract-methods04.phpt
@@ -0,0 +1,36 @@
+--TEST--
+Abstract Trait Methods should behave like common abstract methods and
+implementstion may be provided by other traits. Sorting order shouldn't influence result.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait THello {
+ public abstract function hello();
+}
+
+trait THelloImpl {
+ public function hello() {
+ echo 'Hello';
+ }
+}
+
+class TraitsTest1 {
+ use THello;
+ use THelloImpl;
+}
+
+$test = new TraitsTest1();
+$test->hello();
+
+class TraitsTest2 {
+ use THelloImpl;
+ use THello;
+}
+
+$test = new TraitsTest2();
+$test->hello();
+
+?>
+--EXPECTF--
+HelloHello \ No newline at end of file
diff --git a/Zend/tests/traits/bugs/abstract-methods05.phpt b/Zend/tests/traits/bugs/abstract-methods05.phpt
new file mode 100644
index 0000000..9a1315f
--- /dev/null
+++ b/Zend/tests/traits/bugs/abstract-methods05.phpt
@@ -0,0 +1,25 @@
+--TEST--
+The compatibility with the signature of abstract methods should be checked.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait THelloB {
+ public function hello() {
+ echo 'Hello';
+ }
+}
+
+trait THelloA {
+ public abstract function hello($a);
+}
+
+class TraitsTest1 {
+ use THelloB;
+ use THelloA;
+}
+
+
+?>
+--EXPECTF--
+Fatal error: Declaration of THelloA::hello($a) must be compatible with THelloB::hello() in %s on line %d
diff --git a/Zend/tests/traits/bugs/abstract-methods06.phpt b/Zend/tests/traits/bugs/abstract-methods06.phpt
new file mode 100644
index 0000000..8569aef
--- /dev/null
+++ b/Zend/tests/traits/bugs/abstract-methods06.phpt
@@ -0,0 +1,26 @@
+--TEST--
+The compatibility with the signature of abstract methods should be checked. (also checking the second possible implementation branch)
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait THelloB {
+ public function hello() {
+ echo 'Hello';
+ }
+}
+
+trait THelloA {
+ public abstract function hello($a);
+}
+
+class TraitsTest1 {
+ use THelloA;
+ use THelloB;
+}
+
+
+
+?>
+--EXPECTF--
+Fatal error: Declaration of THelloB::hello() must be compatible with THelloA::hello($a) in %s on line %d
diff --git a/Zend/tests/traits/bugs/alias-semantics.phpt b/Zend/tests/traits/bugs/alias-semantics.phpt
new file mode 100644
index 0000000..ac86692
--- /dev/null
+++ b/Zend/tests/traits/bugs/alias-semantics.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Semantic of alias operation is to provide an additional identifier for the method body of the original method.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait THello {
+ public function a() {
+ echo 'A';
+ }
+}
+
+class TraitsTest {
+ use THello { a as b; }
+}
+
+$test = new TraitsTest();
+$test->a();
+$test->b();
+
+?>
+--EXPECTF--
+AA \ No newline at end of file
diff --git a/Zend/tests/traits/bugs/alias-semantics02.phpt b/Zend/tests/traits/bugs/alias-semantics02.phpt
new file mode 100644
index 0000000..e0b5286
--- /dev/null
+++ b/Zend/tests/traits/bugs/alias-semantics02.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Semantic of alias operation is to provide an additional identifier for the
+method body of the original method.
+It should also work incase the method is fully qualified.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait THello {
+ public function a() {
+ echo 'A';
+ }
+}
+
+class TraitsTest {
+ use THello { THello::a as b; }
+}
+
+$test = new TraitsTest();
+$test->a();
+$test->b();
+
+?>
+--EXPECTF--
+AA \ No newline at end of file
diff --git a/Zend/tests/traits/bugs/alias01.phpt b/Zend/tests/traits/bugs/alias01.phpt
new file mode 100644
index 0000000..b60261e
--- /dev/null
+++ b/Zend/tests/traits/bugs/alias01.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Aliases are applied to the correct methods, and only to them.
+--FILE--
+<?php
+trait T1 {
+ function m1() { echo "T:m1\n"; }
+ function m2() { echo "T:m2\n"; }
+}
+
+class C1 {
+ use T1 { m1 as a1; }
+}
+
+$o = new C1;
+$o->m1();
+$o->a1();
+$o->m2();
+$o->a2();
+
+?>
+--EXPECTF--
+T:m1
+T:m1
+T:m2
+
+Fatal error: Call to undefined method C1::a2() in %s on line %d
diff --git a/Zend/tests/traits/bugs/case-sensitive.phpt b/Zend/tests/traits/bugs/case-sensitive.phpt
new file mode 100644
index 0000000..13d4188
--- /dev/null
+++ b/Zend/tests/traits/bugs/case-sensitive.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Check for problems with case sensitivity in compositions
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait A {
+ public function M1() {}
+ public function M2() {}
+}
+
+trait B {
+ public function M1() {}
+ public function M2() {}
+}
+
+class MyClass {
+ use A;
+ use B;
+}
+?>
+--EXPECTF--
+Fatal error: Trait method M1 has not been applied, because there are collisions with other trait methods on MyClass in %s on line %d
diff --git a/Zend/tests/traits/bugs/interfaces.phpt b/Zend/tests/traits/bugs/interfaces.phpt
new file mode 100644
index 0000000..486bda7
--- /dev/null
+++ b/Zend/tests/traits/bugs/interfaces.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Make sure trait does not implement an interface.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+interface MyInterface {
+ public function a();
+}
+
+trait THello implements MyInterface {
+ public function a() {
+ echo 'A';
+ }
+}
+
+?>
+--EXPECTF--
+Fatal error: Cannot use 'MyInterface' as interface on 'THello' since it is a Trait in %s on line %d \ No newline at end of file
diff --git a/Zend/tests/traits/bugs/missing-trait.phpt b/Zend/tests/traits/bugs/missing-trait.phpt
new file mode 100644
index 0000000..ce4fa5c
--- /dev/null
+++ b/Zend/tests/traits/bugs/missing-trait.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Check error message for missing traits
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+class TraitsTest {
+ use THello;
+}
+
+$test = new TraitsTest();
+
+?>
+--EXPECTF--
+Fatal error: Trait 'THello' not found in %s on line %d \ No newline at end of file
diff --git a/Zend/tests/traits/bugs/overridding-conflicting-methods.phpt b/Zend/tests/traits/bugs/overridding-conflicting-methods.phpt
new file mode 100644
index 0000000..fc09a36
--- /dev/null
+++ b/Zend/tests/traits/bugs/overridding-conflicting-methods.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Overridding Conflicting Methods should not result in a notice/warning about collisions
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait THello1 {
+ public function hello() {
+ echo 'Hello';
+ }
+}
+
+trait THello2 {
+ public function hello() {
+ echo 'Hello';
+ }
+}
+
+class TraitsTest {
+ use THello1;
+ use THello2;
+ public function hello() {
+ echo 'Hello';
+ }
+}
+
+$test = new TraitsTest();
+$test->hello();
+?>
+--EXPECTF--
+Hello \ No newline at end of file
diff --git a/Zend/tests/traits/bugs/overridding-conflicting-property-initializer.phpt b/Zend/tests/traits/bugs/overridding-conflicting-property-initializer.phpt
new file mode 100644
index 0000000..1b9d98d
--- /dev/null
+++ b/Zend/tests/traits/bugs/overridding-conflicting-property-initializer.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Properties are considered incompatible if they are different in any of their
+defined characteristics. Thus, initialization values have to be equal, too.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait foo
+{
+ public $zoo = 'foo::zoo';
+}
+
+class baz
+{
+ use foo;
+ public $zoo = 'baz::zoo';
+}
+
+$obj = new baz();
+echo $obj->zoo, "\n";
+?>
+--EXPECTF--
+Fatal error: baz and foo define the same property ($zoo) in the composition of baz. However, the definition differs and is considered incompatible. Class was composed in %s on line %d \ No newline at end of file
diff --git a/Zend/tests/traits/conflict001.phpt b/Zend/tests/traits/conflict001.phpt
new file mode 100644
index 0000000..32346b3
--- /dev/null
+++ b/Zend/tests/traits/conflict001.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Method conflict in traits
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait THello1 {
+ private function hello() {
+ echo 'Hello';
+ }
+}
+
+trait THello2 {
+ private function hello() {
+ echo 'Hello';
+ }
+}
+
+class TraitsTest {
+ use THello1;
+ use THello2;
+}
+?>
+--EXPECTF--
+Fatal error: Trait method hello has not been applied, because there are collisions with other trait methods on TraitsTest in %s on line %d \ No newline at end of file
diff --git a/Zend/tests/traits/conflict002.phpt b/Zend/tests/traits/conflict002.phpt
new file mode 100644
index 0000000..64712d4
--- /dev/null
+++ b/Zend/tests/traits/conflict002.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Overwridden methods do not cause a conflict.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait HelloWorld {
+ public function sayHello() {
+ echo 'Hello World!';
+ }
+}
+
+trait HelloWorld2 {
+ public function sayHello() {
+ echo 'Hello World2!';
+ }
+}
+
+
+class TheWorldIsNotEnough {
+ use HelloWorld;
+ use HelloWorld2;
+ public function sayHello() {
+ echo 'Hello Universe!';
+ }
+}
+
+$o = new TheWorldIsNotEnough();
+$o->sayHello(); // echos Hello Universe!
+?>
+--EXPECTF--
+Hello Universe! \ No newline at end of file
diff --git a/Zend/tests/traits/conflict003.phpt b/Zend/tests/traits/conflict003.phpt
new file mode 100644
index 0000000..0e71063
--- /dev/null
+++ b/Zend/tests/traits/conflict003.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Two methods resulting in a conflict, should be reported both.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait A {
+ public function smallTalk() {
+ echo 'a';
+ }
+ public function bigTalk() {
+ echo 'A';
+ }
+}
+
+trait B {
+ public function smallTalk() {
+ echo 'b';
+ }
+ public function bigTalk() {
+ echo 'B';
+ }
+}
+
+class Talker {
+ use A, B;
+}
+
+?>
+--EXPECTF--
+Fatal error: Trait method smallTalk has not been applied, because there are collisions with other trait methods on Talker in %s on line %d \ No newline at end of file
diff --git a/Zend/tests/traits/error_001.phpt b/Zend/tests/traits/error_001.phpt
new file mode 100644
index 0000000..307e5c1
--- /dev/null
+++ b/Zend/tests/traits/error_001.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Trying to use instanceof for a method twice
+--FILE--
+<?php
+
+trait foo {
+ public function foo() {
+ return 1;
+ }
+}
+
+trait foo2 {
+ public function foo() {
+ return 2;
+ }
+}
+
+
+class A extends foo {
+ use foo {
+ foo2::foo insteadof foo;
+ foo2::foo insteadof foo;
+ }
+}
+
+?>
+--EXPECTF--
+Fatal error: Class A cannot extend from trait foo in %s on line %d
diff --git a/Zend/tests/traits/error_002.phpt b/Zend/tests/traits/error_002.phpt
new file mode 100644
index 0000000..ac98769
--- /dev/null
+++ b/Zend/tests/traits/error_002.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Trying to use an undefined trait
+--FILE--
+<?php
+
+class A {
+ use abc;
+}
+
+?>
+--EXPECTF--
+Fatal error: Trait 'abc' not found in %s on line %d
diff --git a/Zend/tests/traits/error_003.phpt b/Zend/tests/traits/error_003.phpt
new file mode 100644
index 0000000..5122155
--- /dev/null
+++ b/Zend/tests/traits/error_003.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Trying to use an interface as trait
+--FILE--
+<?php
+
+interface abc {
+}
+
+class A {
+ use abc;
+}
+
+?>
+--EXPECTF--
+Fatal error: A cannot use abc - it is not a trait in %s on line %d
diff --git a/Zend/tests/traits/error_004.phpt b/Zend/tests/traits/error_004.phpt
new file mode 100644
index 0000000..c7ac916
--- /dev/null
+++ b/Zend/tests/traits/error_004.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Trying to use a class as trait
+--FILE--
+<?php
+
+class abc {
+}
+
+class A {
+ use abc;
+}
+
+?>
+--EXPECTF--
+Fatal error: A cannot use abc - it is not a trait in %s on line %d
diff --git a/Zend/tests/traits/error_005.phpt b/Zend/tests/traits/error_005.phpt
new file mode 100644
index 0000000..5aa5e10
--- /dev/null
+++ b/Zend/tests/traits/error_005.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Trying to use a final class as trait
+--FILE--
+<?php
+
+final class abc {
+}
+
+class A {
+ use abc;
+}
+
+?>
+--EXPECTF--
+Fatal error: A cannot use abc - it is not a trait in %s on line %d
diff --git a/Zend/tests/traits/error_006.phpt b/Zend/tests/traits/error_006.phpt
new file mode 100644
index 0000000..0169321
--- /dev/null
+++ b/Zend/tests/traits/error_006.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Trying to use an abstract class as trait
+--FILE--
+<?php
+
+abstract class abc {
+}
+
+class A {
+ use abc;
+}
+
+?>
+--EXPECTF--
+Fatal error: A cannot use abc - it is not a trait in %s on line %d
diff --git a/Zend/tests/traits/error_007.phpt b/Zend/tests/traits/error_007.phpt
new file mode 100644
index 0000000..82a6a2e
--- /dev/null
+++ b/Zend/tests/traits/error_007.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Trying to instantiate a trait
+--FILE--
+<?php
+
+trait abc {
+}
+
+new abc;
+
+?>
+--EXPECTF--
+Fatal error: Cannot instantiate trait abc in %s on line %d
diff --git a/Zend/tests/traits/error_008.phpt b/Zend/tests/traits/error_008.phpt
new file mode 100644
index 0000000..ee97d75
--- /dev/null
+++ b/Zend/tests/traits/error_008.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Trying to implement a trait
+--FILE--
+<?php
+
+trait abc { }
+
+class foo implements abc { }
+
+?>
+--EXPECTF--
+Fatal error: foo cannot implement abc - it is not an interface in %s on line %d
diff --git a/Zend/tests/traits/error_009.phpt b/Zend/tests/traits/error_009.phpt
new file mode 100644
index 0000000..a1eb6b4
--- /dev/null
+++ b/Zend/tests/traits/error_009.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Trying to extend a trait
+--FILE--
+<?php
+
+trait abc { }
+
+class foo extends abc { }
+
+?>
+--EXPECTF--
+Fatal error: Class foo cannot extend from trait abc in %s on line %d
diff --git a/Zend/tests/traits/error_010.phpt b/Zend/tests/traits/error_010.phpt
new file mode 100644
index 0000000..de3741e
--- /dev/null
+++ b/Zend/tests/traits/error_010.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Trying to exclude trait method multiple times
+--FILE--
+<?php
+
+trait foo {
+ public function test() { return 3; }
+}
+trait c {
+ public function test() { return 2; }
+}
+
+class bar {
+ use foo, c { c::test insteadof foo; }
+ use foo, c { c::test insteadof foo; }
+}
+
+$x = new bar;
+var_dump($x->test());
+
+?>
+--EXPECTF--
+Fatal error: Failed to evaluate a trait precedence (test). Method of trait foo was defined to be excluded multiple times in %s on line %d
diff --git a/Zend/tests/traits/error_011.phpt b/Zend/tests/traits/error_011.phpt
new file mode 100644
index 0000000..2d266dd
--- /dev/null
+++ b/Zend/tests/traits/error_011.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Testing trait collisions
+--FILE--
+<?php
+
+trait foo {
+ public function test() { return 3; }
+}
+trait c {
+ public function test() { return 2; }
+}
+
+trait b {
+ public function test() { return 1; }
+}
+
+class bar {
+ use foo, c, b;
+}
+
+$x = new bar;
+var_dump($x->test());
+
+?>
+--EXPECTF--
+Fatal error: Trait method test has not been applied, because there are collisions with other trait methods on bar in %s on line %d
diff --git a/Zend/tests/traits/error_012.phpt b/Zend/tests/traits/error_012.phpt
new file mode 100644
index 0000000..b90e32a
--- /dev/null
+++ b/Zend/tests/traits/error_012.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Trying to access a protected trait method
+--FILE--
+<?php
+
+trait foo {
+ public function test() { return 3; }
+}
+
+class bar {
+ use foo { test as protected; }
+}
+
+$x = new bar;
+var_dump($x->test());
+
+?>
+--EXPECTF--
+Fatal error: Call to protected method bar::test() from context '' in %s on line %d
diff --git a/Zend/tests/traits/error_013.phpt b/Zend/tests/traits/error_013.phpt
new file mode 100644
index 0000000..d9fda2d
--- /dev/null
+++ b/Zend/tests/traits/error_013.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Trying to use static as method modifier
+--FILE--
+<?php
+
+trait foo {
+ public function test() { return 3; }
+}
+
+class bar {
+ use foo { test as static; }
+}
+
+$x = new bar;
+var_dump($x->test());
+
+?>
+--EXPECTF--
+Fatal error: Cannot use 'static' as method modifier in %s on line %d
diff --git a/Zend/tests/traits/error_014.phpt b/Zend/tests/traits/error_014.phpt
new file mode 100644
index 0000000..be1c919
--- /dev/null
+++ b/Zend/tests/traits/error_014.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Trying to override final method
+--FILE--
+<?php
+
+trait foo {
+ public function test() { return 3; }
+}
+
+class baz {
+ final public function test() { return 4; }
+}
+
+class bar extends baz {
+ use foo { test as public; }
+}
+
+$x = new bar;
+var_dump($x->test());
+
+?>
+--EXPECTF--
+Fatal error: Cannot override final method baz::test() in %s on line %d
diff --git a/Zend/tests/traits/error_015.phpt b/Zend/tests/traits/error_015.phpt
new file mode 100644
index 0000000..efcffea
--- /dev/null
+++ b/Zend/tests/traits/error_015.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Trying to add an alias to a trait method where there is another with same name.
+Should warn about the conflict.
+--FILE--
+<?php
+
+trait foo {
+ public function test() { return 3; }
+}
+
+trait baz {
+ public function test() { return 4; }
+}
+
+class bar {
+ use foo, baz {
+ baz::test as zzz;
+ }
+}
+
+$x = new bar;
+var_dump($x->test());
+
+?>
+--EXPECTF--
+Fatal error: Trait method test has not been applied, because there are collisions with other trait methods on bar in %s on line %d
diff --git a/Zend/tests/traits/error_016.phpt b/Zend/tests/traits/error_016.phpt
new file mode 100644
index 0000000..65a3a83
--- /dev/null
+++ b/Zend/tests/traits/error_016.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Trying to create a constant on Trait
+--FILE--
+<?php
+
+trait foo {
+ const a = 1;
+}
+
+?>
+--EXPECTF--
+Fatal error: Traits cannot have constants in %s on line %d
diff --git a/Zend/tests/traits/flattening001.phpt b/Zend/tests/traits/flattening001.phpt
new file mode 100644
index 0000000..aa7f03d
--- /dev/null
+++ b/Zend/tests/traits/flattening001.phpt
@@ -0,0 +1,42 @@
+--TEST--
+Methods using object properties
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait T1 {
+ public function getText() {
+ return $this->text;
+ }
+}
+
+trait T2 {
+ public function setTextT2($val) {
+ $this->text = $val;
+ }
+}
+
+class TraitsTest {
+ use T1;
+ use T2;
+ private $text = 'test';
+ public function setText($val) {
+ $this->text = $val;
+ }
+}
+
+$o = new TraitsTest();
+var_dump($o->getText());
+
+$o->setText('foo');
+
+var_dump($o->getText());
+
+$o->setText('bar');
+
+var_dump($o->getText());
+?>
+--EXPECTF--
+string(4) "test"
+string(3) "foo"
+string(3) "bar" \ No newline at end of file
diff --git a/Zend/tests/traits/flattening002.phpt b/Zend/tests/traits/flattening002.phpt
new file mode 100644
index 0000000..251af29
--- /dev/null
+++ b/Zend/tests/traits/flattening002.phpt
@@ -0,0 +1,28 @@
+--TEST--
+parent:: works like in a method defined without traits.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+class Base {
+ public function sayHello() {
+ echo 'Hello ';
+ }
+}
+
+trait SayWorld {
+ public function sayHello() {
+ parent::sayHello();
+ echo 'World!';
+ }
+}
+
+class MyHelloWorld extends Base {
+ use SayWorld;
+}
+
+$o = new MyHelloWorld();
+$o->sayHello();
+?>
+--EXPECTF--
+Hello World! \ No newline at end of file
diff --git a/Zend/tests/traits/flattening003.phpt b/Zend/tests/traits/flattening003.phpt
new file mode 100644
index 0000000..d189ca7
--- /dev/null
+++ b/Zend/tests/traits/flattening003.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Traits are flattened recurivly.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait Hello {
+ public function sayHello() {
+ echo 'Hello ';
+ }
+}
+
+trait World {
+ public function sayWorld() {
+ echo 'World!';
+ }
+}
+
+trait HelloWorld {
+ use Hello, World;
+}
+
+class MyHelloWorld {
+ use HelloWorld;
+}
+
+$o = new MyHelloWorld();
+$o->sayHello();
+$o->sayWorld();
+?>
+--EXPECTF--
+Hello World! \ No newline at end of file
diff --git a/Zend/tests/traits/get_declared_traits_001.phpt b/Zend/tests/traits/get_declared_traits_001.phpt
new file mode 100644
index 0000000..91f6b3d
--- /dev/null
+++ b/Zend/tests/traits/get_declared_traits_001.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Testing get_declared_traits()
+--FILE--
+<?php
+
+class a { }
+interface b { }
+trait c { }
+abstract class d { }
+final class e { }
+
+var_dump(get_declared_traits());
+
+?>
+--EXPECT--
+array(1) {
+ [0]=>
+ string(1) "c"
+}
diff --git a/Zend/tests/traits/get_declared_traits_002.phpt b/Zend/tests/traits/get_declared_traits_002.phpt
new file mode 100644
index 0000000..74fdcc4
--- /dev/null
+++ b/Zend/tests/traits/get_declared_traits_002.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Testing get_declared_traits() inside namespace
+--FILE--
+<?php
+
+namespace test {
+ class a { }
+ interface b { }
+ trait c { }
+ abstract class d { }
+ final class e { }
+ var_dump(get_declared_traits());
+}
+
+?>
+--EXPECT--
+array(1) {
+ [0]=>
+ string(6) "test\c"
+}
diff --git a/Zend/tests/traits/get_declared_traits_003.phpt b/Zend/tests/traits/get_declared_traits_003.phpt
new file mode 100644
index 0000000..4a68746
--- /dev/null
+++ b/Zend/tests/traits/get_declared_traits_003.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Testing get_declared_classes() and get_declared_traits()
+--FILE--
+<?php
+
+class a { }
+interface b { }
+trait c { }
+abstract class d { }
+final class e { }
+var_dump(get_declared_classes());
+var_dump(get_declared_traits());
+
+?>
+--EXPECTF--
+%astring(1) "a"
+ [%d]=>
+ string(1) "d"
+ [%d]=>
+ string(1) "e"
+}
+array(1) {
+ [0]=>
+ string(1) "c"
+}
diff --git a/Zend/tests/traits/inheritance001.phpt b/Zend/tests/traits/inheritance001.phpt
new file mode 100644
index 0000000..e8195c4
--- /dev/null
+++ b/Zend/tests/traits/inheritance001.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Trait method overwridden by a method defined in the class.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait HelloWorld {
+ public function sayHello() {
+ echo 'Hello World!';
+ }
+}
+
+class TheWorldIsNotEnough {
+ use HelloWorld;
+ public function sayHello() {
+ echo 'Hello Universe!';
+ }
+}
+
+$o = new TheWorldIsNotEnough();
+$o->sayHello(); // echos Hello Universe!
+?>
+--EXPECTF--
+Hello Universe! \ No newline at end of file
diff --git a/Zend/tests/traits/inheritance002.phpt b/Zend/tests/traits/inheritance002.phpt
new file mode 100644
index 0000000..51badc5
--- /dev/null
+++ b/Zend/tests/traits/inheritance002.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Trait method overriddes base class method
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+class Base {
+ public function sayHello() {
+ echo 'Hello ';
+ }
+}
+
+trait SayWorld {
+ public function sayHello() {
+ echo 'World!';
+ }
+}
+
+class MyHelloWorld extends Base {
+ use SayWorld;
+}
+
+$o = new MyHelloWorld();
+$o->sayHello();
+?>
+--EXPECTF--
+World! \ No newline at end of file
diff --git a/Zend/tests/traits/inheritance003.phpt b/Zend/tests/traits/inheritance003.phpt
new file mode 100644
index 0000000..22ff6e2
--- /dev/null
+++ b/Zend/tests/traits/inheritance003.phpt
@@ -0,0 +1,38 @@
+--TEST--
+Trait method overrides base class method and satisfies prototype
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+abstract class Base {
+ public abstract function sayHello(array $a);
+}
+
+class SubClass extends Base {
+ public function sayHello(array $a) {
+ echo "World!\n";
+ }
+}
+
+$s = new SubClass();
+$s->sayHello(array());
+
+
+trait SayWorld {
+ public function sayHello(Base $d) {
+ echo 'World!';
+ }
+}
+
+class MyHelloWorld extends Base {
+ use SayWorld;
+}
+
+$o = new MyHelloWorld();
+$o->sayHello(array());
+
+?>
+--EXPECTF--
+World!
+
+Fatal error: Declaration of SayWorld::sayHello(Base $d) must be compatible with Base::sayHello(array $a) in %s on line %d
diff --git a/Zend/tests/traits/interface_001.phpt b/Zend/tests/traits/interface_001.phpt
new file mode 100644
index 0000000..a14f78e
--- /dev/null
+++ b/Zend/tests/traits/interface_001.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Using traits to implement interface
+--FILE--
+<?php
+
+trait foo {
+ public function abc() {
+ }
+}
+
+interface baz {
+ public function abc();
+}
+
+class bar implements baz {
+ use foo;
+
+}
+
+new bar;
+print "OK\n";
+
+?>
+--EXPECT--
+OK
diff --git a/Zend/tests/traits/interface_002.phpt b/Zend/tests/traits/interface_002.phpt
new file mode 100644
index 0000000..462d73f
--- /dev/null
+++ b/Zend/tests/traits/interface_002.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Checking error message when the trait doesn't implements the interface
+--FILE--
+<?php
+
+trait foo {
+ public function a() {
+ }
+}
+
+interface baz {
+ public function abc();
+}
+
+class bar implements baz {
+ use foo;
+
+}
+
+new bar;
+
+?>
+--EXPECTF--
+Fatal error: Class bar contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (baz::abc) in %s on line %d
diff --git a/Zend/tests/traits/interface_003.phpt b/Zend/tests/traits/interface_003.phpt
new file mode 100644
index 0000000..aa13bd8
--- /dev/null
+++ b/Zend/tests/traits/interface_003.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Testing to implement Serializable interface by traits
+--FILE--
+<?php
+
+trait foo {
+ public function serialize() {
+ return 'foobar';
+ }
+ public function unserialize($x) {
+ var_dump($x);
+ }
+}
+
+class bar implements Serializable {
+ use foo;
+}
+
+var_dump($o = serialize(new bar));
+var_dump(unserialize($o));
+
+?>
+--EXPECTF--
+string(20) "C:3:"bar":6:{foobar}"
+string(6) "foobar"
+object(bar)#%d (0) {
+}
diff --git a/Zend/tests/traits/language001.phpt b/Zend/tests/traits/language001.phpt
new file mode 100644
index 0000000..d892112
--- /dev/null
+++ b/Zend/tests/traits/language001.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Single Trait with simple trait method
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait THello {
+ public function hello() {
+ echo 'Hello';
+ }
+}
+
+class TraitsTest {
+ use THello;
+}
+
+$test = new TraitsTest();
+$test->hello();
+?>
+--EXPECTF--
+Hello
diff --git a/Zend/tests/traits/language002.phpt b/Zend/tests/traits/language002.phpt
new file mode 100644
index 0000000..d093f29
--- /dev/null
+++ b/Zend/tests/traits/language002.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Use multiple traits.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait Hello {
+ public function sayHello() {
+ echo 'Hello ';
+ }
+}
+
+trait World {
+ public function sayWorld() {
+ echo 'World';
+ }
+}
+
+class MyHelloWorld {
+ use Hello, World;
+ public function sayExclamationMark() {
+ echo '!';
+ }
+}
+
+$o = new MyHelloWorld();
+$o->sayHello();
+$o->sayWorld();
+$o->sayExclamationMark();
+?>
+--EXPECTF--
+Hello World! \ No newline at end of file
diff --git a/Zend/tests/traits/language003.phpt b/Zend/tests/traits/language003.phpt
new file mode 100644
index 0000000..77d4429
--- /dev/null
+++ b/Zend/tests/traits/language003.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Use instead to solve a conflict.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait Hello {
+ public function saySomething() {
+ echo 'Hello';
+ }
+}
+
+trait World {
+ public function saySomething() {
+ echo 'World';
+ }
+}
+
+class MyHelloWorld {
+ use Hello, World {
+ Hello::saySomething insteadof World;
+ }
+}
+
+$o = new MyHelloWorld();
+$o->saySomething();
+?>
+--EXPECTF--
+Hello \ No newline at end of file
diff --git a/Zend/tests/traits/language004.phpt b/Zend/tests/traits/language004.phpt
new file mode 100644
index 0000000..4df307a
--- /dev/null
+++ b/Zend/tests/traits/language004.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Use instead to solve a conflict and as to access the method.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait Hello {
+ public function saySomething() {
+ echo 'Hello';
+ }
+}
+
+trait World {
+ public function saySomething() {
+ echo ' World';
+ }
+}
+
+class MyHelloWorld {
+ use Hello, World {
+ Hello::saySomething insteadof World;
+ World::saySomething as sayWorld;
+ }
+}
+
+$o = new MyHelloWorld();
+$o->saySomething();
+$o->sayWorld();
+?>
+--EXPECTF--
+Hello World \ No newline at end of file
diff --git a/Zend/tests/traits/language005.phpt b/Zend/tests/traits/language005.phpt
new file mode 100644
index 0000000..20eaeb3
--- /dev/null
+++ b/Zend/tests/traits/language005.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Use instead to solve a conflict and as to access the method.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait A {
+ public function smallTalk() {
+ echo 'a';
+ }
+ public function bigTalk() {
+ echo 'A';
+ }
+}
+
+trait B {
+ public function smallTalk() {
+ echo 'b';
+ }
+ public function bigTalk() {
+ echo 'B';
+ }
+}
+
+class Talker {
+ use A, B {
+ B::smallTalk insteadof A;
+ A::bigTalk insteadof B;
+ B::bigTalk as talk;
+ }
+}
+
+$t = new Talker;
+$t->smallTalk();
+$t->bigTalk();
+$t->talk();
+
+?>
+--EXPECTF--
+bAB \ No newline at end of file
diff --git a/Zend/tests/traits/language006.phpt b/Zend/tests/traits/language006.phpt
new file mode 100644
index 0000000..5a32359
--- /dev/null
+++ b/Zend/tests/traits/language006.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Express requirements of a trait by abstract methods.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait Hello {
+ public function sayHelloWorld() {
+ echo 'Hello'.$this->getWorld();
+ }
+ abstract public function getWorld();
+ }
+
+class MyHelloWorld {
+ private $world;
+ use Hello;
+ public function getWorld() {
+ return $this->world;
+ }
+ public function setWorld($val) {
+ $this->world = $val;
+ }
+}
+
+$o = new MyHelloWorld();
+$o->setWorld(' World!');
+$o->sayHelloWorld();
+
+?>
+--EXPECTF--
+Hello World! \ No newline at end of file
diff --git a/Zend/tests/traits/language007.phpt b/Zend/tests/traits/language007.phpt
new file mode 100644
index 0000000..3b65d01
--- /dev/null
+++ b/Zend/tests/traits/language007.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Traits can fulfill the requirements of abstract base classes.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+abstract class Base {
+ abstract function sayWorld();
+}
+
+trait Hello {
+ public function sayHello() {
+ echo 'Hello';
+ }
+ public function sayWorld() {
+ echo ' World!';
+ }
+ }
+
+class MyHelloWorld extends Base {
+ use Hello;
+}
+
+$o = new MyHelloWorld();
+$o->sayHello();
+$o->sayWorld();
+
+?>
+--EXPECTF--
+Hello World! \ No newline at end of file
diff --git a/Zend/tests/traits/language008a.phpt b/Zend/tests/traits/language008a.phpt
new file mode 100644
index 0000000..5a12a4e
--- /dev/null
+++ b/Zend/tests/traits/language008a.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Visibility can be changed with the as aliasing construct as well.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait HelloWorld {
+ public function sayHello() {
+ echo 'Hello World!';
+ }
+}
+
+class MyClass {
+ use HelloWorld { sayHello as protected; }
+}
+
+
+$o = new MyClass;
+$o->sayHello();
+
+?>
+--EXPECTF--
+Fatal error: Call to protected method MyClass::sayHello() from context '' in %s on line %d \ No newline at end of file
diff --git a/Zend/tests/traits/language008b.phpt b/Zend/tests/traits/language008b.phpt
new file mode 100644
index 0000000..9abbdbe
--- /dev/null
+++ b/Zend/tests/traits/language008b.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Visibility can be changed with the as aliasing construct as well.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait HelloWorld {
+ public function sayHello() {
+ echo 'Hello World!';
+ }
+}
+
+class MyClass {
+ use HelloWorld { sayHello as private sayHelloWorld; }
+
+ public function callPrivateAlias() {
+ $this->sayHelloWorld();
+ }
+}
+
+$o = new MyClass();
+$o->sayHello();
+$o->callPrivateAlias();
+$o->sayHelloWorld();
+
+
+?>
+--EXPECTF--
+Hello World!Hello World!
+Fatal error: Call to private method MyClass::sayHelloWorld() from context '' in %s on line %d \ No newline at end of file
diff --git a/Zend/tests/traits/language009.phpt b/Zend/tests/traits/language009.phpt
new file mode 100644
index 0000000..e55c8d8
--- /dev/null
+++ b/Zend/tests/traits/language009.phpt
@@ -0,0 +1,36 @@
+--TEST--
+In instead definitions all trait whose methods are meant to be hidden can be listed.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait A {
+ public function foo() {
+ echo 'a';
+ }
+}
+
+trait B {
+ public function foo() {
+ echo 'b';
+ }
+}
+
+trait C {
+ public function foo() {
+ echo 'c';
+ }
+}
+
+class MyClass {
+ use C, A, B {
+ B::foo insteadof A, C;
+ }
+}
+
+$t = new MyClass;
+$t->foo();
+
+?>
+--EXPECTF--
+b \ No newline at end of file
diff --git a/Zend/tests/traits/language010.phpt b/Zend/tests/traits/language010.phpt
new file mode 100644
index 0000000..e550abb
--- /dev/null
+++ b/Zend/tests/traits/language010.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Aliasing leading to conflict should result in error message
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait Hello {
+ public function hello() {
+ echo 'Hello';
+ }
+}
+
+trait World {
+ public function world() {
+ echo ' World!';
+ }
+}
+
+
+class MyClass {
+ use Hello, World { hello as world; }
+}
+
+$o = new MyClass();
+$o->hello();
+$o->world();
+
+?>
+--EXPECTF--
+Fatal error: Trait method world has not been applied, because there are collisions with other trait methods on MyClass in %s on line %d \ No newline at end of file
diff --git a/Zend/tests/traits/language011.phpt b/Zend/tests/traits/language011.phpt
new file mode 100644
index 0000000..585699d
--- /dev/null
+++ b/Zend/tests/traits/language011.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Aliasing on conflicting method should not cover up conflict.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait Hello {
+ public function sayHello() {
+ echo 'Hello';
+ }
+}
+
+trait World {
+ public function sayHello() {
+ echo ' World!';
+ }
+}
+
+
+class MyClass {
+ use Hello, World { sayHello as sayWorld; }
+}
+
+$o = new MyClass();
+$o->sayHello();
+$o->sayWorld();
+
+?>
+--EXPECTF--
+Fatal error: Trait method sayHello has not been applied, because there are collisions with other trait methods on MyClass in %s on line %d
diff --git a/Zend/tests/traits/language012.phpt b/Zend/tests/traits/language012.phpt
new file mode 100644
index 0000000..481dd64
--- /dev/null
+++ b/Zend/tests/traits/language012.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Statics should work in traits, too.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait Counter {
+ public function inc() {
+ static $c = 0;
+ $c = $c + 1;
+ echo "$c\n";
+ }
+}
+
+
+class C1 {
+ use Counter;
+}
+
+$o = new C1();
+$o->inc();
+$o->inc();
+
+?>
+--EXPECTF--
+1
+2
diff --git a/Zend/tests/traits/language013.phpt b/Zend/tests/traits/language013.phpt
new file mode 100644
index 0000000..a55cbbe
--- /dev/null
+++ b/Zend/tests/traits/language013.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Statics work like expected for language-based copy'n'paste. No link between methods from the same trait.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait Counter {
+ public function inc() {
+ static $c = 0;
+ $c = $c + 1;
+ echo "$c\n";
+ }
+}
+
+
+class C1 {
+ use Counter;
+}
+
+class C2 {
+ use Counter;
+}
+
+$o = new C1();
+$o->inc();
+$o->inc();
+
+$p = new C2();
+$p->inc();
+$p->inc();
+
+?>
+--EXPECTF--
+1
+2
+1
+2
diff --git a/Zend/tests/traits/language014.phpt b/Zend/tests/traits/language014.phpt
new file mode 100644
index 0000000..102b9ae
--- /dev/null
+++ b/Zend/tests/traits/language014.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Aliasing leading to conflict should result in error message
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait Hello {
+ public function hello() {
+ echo 'Hello';
+ }
+}
+
+trait World {
+ public function world() {
+ echo ' World!';
+ }
+}
+
+
+class MyClass {
+ use Hello, World { world as hello; }
+}
+
+$o = new MyClass();
+$o->hello();
+$o->world();
+
+?>
+--EXPECTF--
+Fatal error: Trait method hello has not been applied, because there are collisions with other trait methods on MyClass in %s on line %d
diff --git a/Zend/tests/traits/language015.phpt b/Zend/tests/traits/language015.phpt
new file mode 100644
index 0000000..0c9fb4a
--- /dev/null
+++ b/Zend/tests/traits/language015.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Invalid conflict resolution (unused trait as lhs of "insteadof")
+--FILE--
+<?php
+trait T1 {
+ function foo() {echo "T1\n";}
+}
+trait T2 {
+ function foo() {echo "T2\n";}
+}
+class C {
+ use T1 {
+ T2::foo insteadof T1;
+ }
+}
+--EXPECTF--
+Fatal error: Required Trait T2 wasn't added to C in %slanguage015.php on line %d
diff --git a/Zend/tests/traits/language016.phpt b/Zend/tests/traits/language016.phpt
new file mode 100644
index 0000000..1c6bbea
--- /dev/null
+++ b/Zend/tests/traits/language016.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Invalid conflict resolution (unused trait as rhs of "insteadof")
+--FILE--
+<?php
+trait T1 {
+ function foo() {echo "T1\n";}
+}
+trait T2 {
+ function foo() {echo "T2\n";}
+}
+class C {
+ use T1 {
+ T1::foo insteadof T2;
+ }
+}
+--EXPECTF--
+Fatal error: Required Trait T2 wasn't added to C in %slanguage016.php on line %d
diff --git a/Zend/tests/traits/language017.phpt b/Zend/tests/traits/language017.phpt
new file mode 100644
index 0000000..539a05d
--- /dev/null
+++ b/Zend/tests/traits/language017.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Invalid conflict resolution (unused trait as lhs of "as")
+--FILE--
+<?php
+trait T1 {
+ function foo() {echo "T1\n";}
+}
+trait T2 {
+ function foo() {echo "T2\n";}
+}
+class C {
+ use T1 {
+ T2::foo as private;
+ }
+}
+--EXPECTF--
+Fatal error: Required Trait T2 wasn't added to C in %slanguage017.php on line %d
diff --git a/Zend/tests/traits/language018.phpt b/Zend/tests/traits/language018.phpt
new file mode 100644
index 0000000..169cb50
--- /dev/null
+++ b/Zend/tests/traits/language018.phpt
@@ -0,0 +1,15 @@
+--TEST--
+abstract alias
+--FILE--
+<?php
+trait T1 {
+ function foo() {}
+}
+class C1 {
+ use T1 {
+ T1::foo as abstract;
+ }
+}
+?>
+--EXPECTF--
+Fatal error: Cannot use 'abstract' as method modifier in %s on line %d
diff --git a/Zend/tests/traits/language019.phpt b/Zend/tests/traits/language019.phpt
new file mode 100644
index 0000000..83318c5
--- /dev/null
+++ b/Zend/tests/traits/language019.phpt
@@ -0,0 +1,15 @@
+--TEST--
+final alias
+--FILE--
+<?php
+trait T1 {
+ function foo() {}
+}
+class C1 {
+ use T1 {
+ T1::foo as final;
+ }
+}
+?>
+--EXPECTF--
+Fatal error: Cannot use 'final' as method modifier in %s on line %d
diff --git a/Zend/tests/traits/methods_001.phpt b/Zend/tests/traits/methods_001.phpt
new file mode 100644
index 0000000..e1ee815
--- /dev/null
+++ b/Zend/tests/traits/methods_001.phpt
@@ -0,0 +1,39 @@
+--TEST--
+Testing magic method on trait
+--FILE--
+<?php
+
+trait foo {
+ public function __toString() {
+ return '123';
+ }
+
+ public function __get($x) {
+ var_dump($x);
+ }
+
+ public function __set($attr, $val) {
+ var_dump($attr .'==='. $val);
+ }
+
+ public function __clone() {
+ var_dump(__FUNCTION__);
+ }
+}
+
+class bar {
+ use foo;
+}
+
+$o = new bar;
+echo $o, PHP_EOL;
+$o->xyz;
+$o->xyz = 2;
+clone $o;
+
+?>
+--EXPECT--
+123
+string(3) "xyz"
+string(7) "xyz===2"
+string(7) "__clone"
diff --git a/Zend/tests/traits/methods_002.phpt b/Zend/tests/traits/methods_002.phpt
new file mode 100644
index 0000000..4ed64c1
--- /dev/null
+++ b/Zend/tests/traits/methods_002.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Testing collision with magic methods
+--FILE--
+<?php
+
+trait foo {
+ public function __clone() {
+ var_dump(__FUNCTION__);
+ }
+}
+
+trait baz {
+ public function __clone() {
+ var_dump(__FUNCTION__);
+ }
+}
+
+class bar {
+ use foo;
+ use baz;
+}
+
+$o = new bar;
+var_dump(clone $o);
+
+?>
+--EXPECTF--
+Fatal error: Trait method __clone has not been applied, because there are collisions with other trait methods on bar in %s on line %d
diff --git a/Zend/tests/traits/methods_003.phpt b/Zend/tests/traits/methods_003.phpt
new file mode 100644
index 0000000..1c1218a
--- /dev/null
+++ b/Zend/tests/traits/methods_003.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Testing __construct and __destruct with Trait
+--FILE--
+<?php
+
+trait foo {
+ public function __construct() {
+ var_dump(__FUNCTION__);
+ }
+ public function __destruct() {
+ var_dump(__FUNCTION__);
+ }
+}
+
+class bar {
+ use foo;
+}
+
+new bar;
+
+?>
+--EXPECT--
+string(11) "__construct"
+string(10) "__destruct"
diff --git a/Zend/tests/traits/noctor001.phpt b/Zend/tests/traits/noctor001.phpt
new file mode 100644
index 0000000..d15acff
--- /dev/null
+++ b/Zend/tests/traits/noctor001.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Don't mark trait methods as constructor
+--FILE--
+<?php
+trait Foo {
+ public function Foo() {
+ }
+}
+
+class Bar {
+ use Foo;
+ public function Bar() {
+ }
+}
+
+$rfoofoo = new ReflectionMethod('Foo::Foo');
+var_dump($rfoofoo->isConstructor());
+
+$rbarfoo = new ReflectionMethod('Bar::Foo');
+var_dump($rbarfoo->isConstructor());
+
+$rbarbar = new ReflectionMethod('Bar::Bar');
+var_dump($rbarbar->isConstructor());
+?>
+--EXPECT--
+bool(false)
+bool(false)
+bool(true)
diff --git a/Zend/tests/traits/property001.phpt b/Zend/tests/traits/property001.phpt
new file mode 100644
index 0000000..d5e4ddc
--- /dev/null
+++ b/Zend/tests/traits/property001.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Potentially conflicting properties should result in a strict notice. Property use is discorage for traits that are supposed to enable maintainable code reuse. Accessor methods are the language supported idiom for this.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait THello1 {
+ private $foo;
+}
+
+trait THello2 {
+ private $foo;
+}
+
+echo "PRE-CLASS-GUARD-TraitsTest\n";
+error_reporting(E_ALL & ~E_STRICT); // ensuring that it is only for E_STRICT
+
+class TraitsTest {
+ use THello1;
+ use THello2;
+}
+
+error_reporting(E_ALL | E_STRICT);
+
+echo "PRE-CLASS-GUARD-TraitsTest2\n";
+
+class TraitsTest2 {
+ use THello1;
+ use THello2;
+}
+
+var_dump(property_exists('TraitsTest', 'foo'));
+var_dump(property_exists('TraitsTest2', 'foo'));
+?>
+--EXPECTF--
+PRE-CLASS-GUARD-TraitsTest
+PRE-CLASS-GUARD-TraitsTest2
+
+Strict Standards: THello1 and THello2 define the same property ($foo) in the composition of TraitsTest2. This might be incompatible, to improve maintainability consider using accessor methods in traits instead. Class was composed in %s on line %d
+bool(true)
+bool(true) \ No newline at end of file
diff --git a/Zend/tests/traits/property002.phpt b/Zend/tests/traits/property002.phpt
new file mode 100644
index 0000000..27361e0
--- /dev/null
+++ b/Zend/tests/traits/property002.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Non-conflicting properties should work just fine.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait THello1 {
+ public $hello = "hello";
+}
+
+trait THello2 {
+ private $world = "World!";
+}
+
+class TraitsTest {
+ use THello1;
+ use THello2;
+ function test() {
+ echo $this->hello . ' ' . $this->world;
+ }
+}
+
+var_dump(property_exists('TraitsTest', 'hello'));
+var_dump(property_exists('TraitsTest', 'world'));
+
+$t = new TraitsTest;
+$t->test();
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+hello World! \ No newline at end of file
diff --git a/Zend/tests/traits/property003.phpt b/Zend/tests/traits/property003.phpt
new file mode 100644
index 0000000..b4f0105
--- /dev/null
+++ b/Zend/tests/traits/property003.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Conflicting properties with different visibility modifiers should result in a fatal error, since this indicates that the code is incompatible.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait THello1 {
+ public $hello;
+}
+
+trait THello2 {
+ private $hello;
+}
+
+echo "PRE-CLASS-GUARD\n";
+
+class TraitsTest {
+ use THello1;
+ use THello2;
+}
+
+echo "POST-CLASS-GUARD\n";
+
+$t = new TraitsTest;
+$t->hello = "foo";
+?>
+--EXPECTF--
+PRE-CLASS-GUARD
+
+Fatal error: THello1 and THello2 define the same property ($hello) in the composition of TraitsTest. However, the definition differs and is considered incompatible. Class was composed in %s on line %d \ No newline at end of file
diff --git a/Zend/tests/traits/property004.phpt b/Zend/tests/traits/property004.phpt
new file mode 100644
index 0000000..393b492
--- /dev/null
+++ b/Zend/tests/traits/property004.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Conflicting properties with different initial values are considered incompatible.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait THello1 {
+ public $hello = "foo";
+}
+
+trait THello2 {
+ private $hello = "bar";
+}
+
+echo "PRE-CLASS-GUARD\n";
+
+class TraitsTest {
+ use THello1;
+ use THello2;
+ public function getHello() {
+ return $this->hello;
+ }
+}
+
+$t = new TraitsTest;
+?>
+--EXPECTF--
+PRE-CLASS-GUARD
+
+Fatal error: THello1 and THello2 define the same property ($hello) in the composition of TraitsTest. However, the definition differs and is considered incompatible. Class was composed in %s on line %d \ No newline at end of file
diff --git a/Zend/tests/traits/property005.phpt b/Zend/tests/traits/property005.phpt
new file mode 100644
index 0000000..899a332
--- /dev/null
+++ b/Zend/tests/traits/property005.phpt
@@ -0,0 +1,40 @@
+--TEST--
+The same rules are applied for properties that are defined in the class hierarchy. Thus, if the properties are compatible, a notice is issued, if not a fatal error occures.
+--FILE--
+<?php
+error_reporting(E_ALL | E_STRICT);
+
+class Base {
+ private $hello;
+}
+
+trait THello1 {
+ private $hello;
+}
+
+echo "PRE-CLASS-GUARD\n";
+class Notice extends Base {
+ use THello1;
+ private $hello;
+}
+echo "POST-CLASS-GUARD\n";
+
+// now we do the test for a fatal error
+
+class TraitsTest {
+ use THello1;
+ public $hello;
+}
+
+echo "POST-CLASS-GUARD2\n";
+
+$t = new TraitsTest;
+$t->hello = "foo";
+?>
+--EXPECTF--
+PRE-CLASS-GUARD
+
+Strict Standards: Notice and THello1 define the same property ($hello) in the composition of Notice. This might be incompatible, to improve maintainability consider using accessor methods in traits instead. Class was composed in %s on line %d
+POST-CLASS-GUARD
+
+Fatal error: TraitsTest and THello1 define the same property ($hello) in the composition of TraitsTest. However, the definition differs and is considered incompatible. Class was composed in %s on line %d
diff --git a/Zend/tests/traits/property006.phpt b/Zend/tests/traits/property006.phpt
new file mode 100644
index 0000000..1a70919
--- /dev/null
+++ b/Zend/tests/traits/property006.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Introducing new private variables of the same name in a subclass is ok, and does not lead to any output. That is consitent with normal inheritance handling.
+--FILE--
+<?php
+error_reporting(E_ALL | E_STRICT);
+
+class Base {
+ private $hello;
+}
+
+trait THello1 {
+ private $hello;
+}
+
+// Now we use the trait, which happens to introduce another private variable
+// but they are distinct, and not related to each other, so no warning.
+echo "PRE-CLASS-GUARD\n";
+class SameNameInSubClassNoNotice extends Base {
+ use THello1;
+}
+echo "POST-CLASS-GUARD\n";
+
+// now the same with a class that defines the property itself,
+// that should give the expected strict warning.
+
+class Notice extends Base {
+ use THello1;
+ private $hello;
+}
+echo "POST-CLASS-GUARD2\n";
+?>
+--EXPECTF--
+PRE-CLASS-GUARD
+POST-CLASS-GUARD
+
+Strict Standards: Notice and THello1 define the same property ($hello) in the composition of Notice. This might be incompatible, to improve maintainability consider using accessor methods in traits instead. Class was composed in %s on line %d
+POST-CLASS-GUARD2
diff --git a/Zend/tests/traits/property007.phpt b/Zend/tests/traits/property007.phpt
new file mode 100644
index 0000000..0f7c3b3
--- /dev/null
+++ b/Zend/tests/traits/property007.phpt
@@ -0,0 +1,38 @@
+--TEST--
+Introducing new private variables of the same name in a subclass is ok, and does not lead to any output. That is consitent with normal inheritance handling.
+--FILE--
+<?php
+error_reporting(E_ALL | E_STRICT);
+
+class Base {
+ protected $hello;
+}
+
+trait THello1 {
+ protected $hello;
+}
+
+// Protected and public are handle more strict with a warning then what is
+// expected from normal inheritance since they can have easier coliding semantics
+echo "PRE-CLASS-GUARD\n";
+class SameNameInSubClassProducesNotice extends Base {
+ use THello1;
+}
+echo "POST-CLASS-GUARD\n";
+
+// now the same with a class that defines the property itself, too.
+
+class Notice extends Base {
+ use THello1;
+ protected $hello;
+}
+echo "POST-CLASS-GUARD2\n";
+?>
+--EXPECTF--
+PRE-CLASS-GUARD
+
+Strict Standards: Base and THello1 define the same property ($hello) in the composition of SameNameInSubClassProducesNotice. This might be incompatible, to improve maintainability consider using accessor methods in traits instead. Class was composed in %s on line %d
+POST-CLASS-GUARD
+
+Strict Standards: Notice and THello1 define the same property ($hello) in the composition of Notice. This might be incompatible, to improve maintainability consider using accessor methods in traits instead. Class was composed in %s on line %d
+POST-CLASS-GUARD2
diff --git a/Zend/tests/traits/property008.phpt b/Zend/tests/traits/property008.phpt
new file mode 100644
index 0000000..e263692
--- /dev/null
+++ b/Zend/tests/traits/property008.phpt
@@ -0,0 +1,62 @@
+--TEST--
+Handling of private fields with traits needs to have same semantics as with normal inheritance.
+--FILE--
+<?php
+error_reporting(E_ALL | E_STRICT);
+
+class BaseWithPropA {
+ private $hello = 0;
+}
+
+// This is how privates are handled in normal inheritance
+class SubclassClassicInheritance extends BaseWithPropA {
+ private $hello = 0;
+}
+
+// And here, we need to make sure, that the traits behave the same
+
+trait AHelloProperty {
+ private $hello = 0;
+}
+
+class BaseWithTPropB {
+ use AHelloProperty;
+}
+
+class SubclassA extends BaseWithPropA {
+ use AHelloProperty;
+}
+
+class SubclassB extends BaseWithTPropB {
+ use AHelloProperty;
+}
+
+$classic = new SubclassClassicInheritance;
+var_dump($classic);
+
+$a = new SubclassA;
+var_dump($a);
+
+$b = new SubclassB;
+var_dump($b);
+
+?>
+--EXPECTF--
+object(SubclassClassicInheritance)#1 (2) {
+ ["hello":"SubclassClassicInheritance":private]=>
+ int(0)
+ ["hello":"BaseWithPropA":private]=>
+ int(0)
+}
+object(SubclassA)#2 (2) {
+ ["hello":"SubclassA":private]=>
+ int(0)
+ ["hello":"BaseWithPropA":private]=>
+ int(0)
+}
+object(SubclassB)#3 (2) {
+ ["hello":"SubclassB":private]=>
+ int(0)
+ ["hello":"BaseWithTPropB":private]=>
+ int(0)
+} \ No newline at end of file
diff --git a/Zend/tests/traits/property009.phpt b/Zend/tests/traits/property009.phpt
new file mode 100644
index 0000000..135129d
--- /dev/null
+++ b/Zend/tests/traits/property009.phpt
@@ -0,0 +1,59 @@
+--TEST--
+Handling of public fields with traits needs to have same semantics as with normal inheritance, however, we do add strict warnings since it is easier to run into something unexpeted with changing traits.
+--FILE--
+<?php
+error_reporting(E_ALL | E_STRICT);
+
+class BaseWithPropA {
+ public $hello = 0;
+}
+
+// This is how publics are handled in normal inheritance
+class SubclassClassicInheritance extends BaseWithPropA {
+ public $hello = 0;
+}
+
+// And here, we need to make sure, that the traits behave the same
+
+trait AHelloProperty {
+ public $hello = 0;
+}
+
+class BaseWithTPropB {
+ use AHelloProperty;
+}
+
+class SubclassA extends BaseWithPropA {
+ use AHelloProperty;
+}
+
+class SubclassB extends BaseWithTPropB {
+ use AHelloProperty;
+}
+
+$classic = new SubclassClassicInheritance;
+var_dump($classic);
+
+$a = new SubclassA;
+var_dump($a);
+
+$b = new SubclassB;
+var_dump($b);
+
+?>
+--EXPECTF--
+Strict Standards: BaseWithPropA and AHelloProperty define the same property ($hello) in the composition of SubclassA. This might be incompatible, to improve maintainability consider using accessor methods in traits instead. Class was composed in %s on line %d
+
+Strict Standards: BaseWithTPropB and AHelloProperty define the same property ($hello) in the composition of SubclassB. This might be incompatible, to improve maintainability consider using accessor methods in traits instead. Class was composed in %s on line %d
+object(SubclassClassicInheritance)#1 (1) {
+ ["hello"]=>
+ int(0)
+}
+object(SubclassA)#2 (1) {
+ ["hello"]=>
+ int(0)
+}
+object(SubclassB)#3 (1) {
+ ["hello"]=>
+ int(0)
+} \ No newline at end of file
diff --git a/Zend/tests/traits/static_001.phpt b/Zend/tests/traits/static_001.phpt
new file mode 100644
index 0000000..d86cb85
--- /dev/null
+++ b/Zend/tests/traits/static_001.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Traits with static methods.
+--CREDITS--
+Simas Toleikis simast@gmail.com
+--FILE--
+<?php
+
+ trait TestTrait {
+ public static function test() {
+ return 'Test';
+ }
+ }
+
+ class A {
+ use TestTrait;
+ }
+
+ echo A::test();
+
+?>
+--EXPECT--
+Test \ No newline at end of file
diff --git a/Zend/tests/traits/static_002.phpt b/Zend/tests/traits/static_002.phpt
new file mode 100644
index 0000000..c076085
--- /dev/null
+++ b/Zend/tests/traits/static_002.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Traits with static methods referenced using variable.
+--CREDITS--
+Simas Toleikis simast@gmail.com
+--FILE--
+<?php
+
+ trait TestTrait {
+ public static function test() {
+ return 'Test';
+ }
+ }
+
+ class A {
+ use TestTrait;
+ }
+
+ $class = "A";
+ echo $class::test();
+
+?>
+--EXPECT--
+Test \ No newline at end of file
diff --git a/Zend/tests/traits/static_003.phpt b/Zend/tests/traits/static_003.phpt
new file mode 100644
index 0000000..fbe5421
--- /dev/null
+++ b/Zend/tests/traits/static_003.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Traits with late static bindings.
+--CREDITS--
+Simas Toleikis simast@gmail.com
+--FILE--
+<?php
+
+ trait TestTrait {
+ public static function test() {
+ return static::$test;
+ }
+ }
+
+ class A {
+ use TestTrait;
+ protected static $test = "Test A";
+ }
+
+ class B extends A {
+ protected static $test = "Test B";
+ }
+
+ echo B::test();
+
+?>
+--EXPECT--
+Test B \ No newline at end of file
diff --git a/Zend/tests/traits/static_004.phpt b/Zend/tests/traits/static_004.phpt
new file mode 100644
index 0000000..c360f45
--- /dev/null
+++ b/Zend/tests/traits/static_004.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Traits with __callStatic magic method.
+--CREDITS--
+Simas Toleikis simast@gmail.com
+--FILE--
+<?php
+
+ trait TestTrait {
+ public static function __callStatic($name, $arguments) {
+ return $name;
+ }
+ }
+
+ class A {
+ use TestTrait;
+ }
+
+ echo A::Test();
+
+?>
+--EXPECT--
+Test \ No newline at end of file
diff --git a/Zend/tests/traits/static_forward_static_call.phpt b/Zend/tests/traits/static_forward_static_call.phpt
new file mode 100644
index 0000000..878cf1f
--- /dev/null
+++ b/Zend/tests/traits/static_forward_static_call.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Traits and forward_static_call().
+--CREDITS--
+Simas Toleikis simast@gmail.com
+--FILE--
+<?php
+
+ trait TestTrait {
+ public static function test() {
+ return 'Forwarded '.forward_static_call(array('A', 'test'));
+ }
+ }
+
+ class A {
+ public static function test() {
+ return "Test A";
+ }
+ }
+
+ class B extends A {
+ use TestTrait;
+ }
+
+ echo B::test();
+
+?>
+--EXPECT--
+Forwarded Test A \ No newline at end of file
diff --git a/Zend/tests/traits/static_get_called_class.phpt b/Zend/tests/traits/static_get_called_class.phpt
new file mode 100644
index 0000000..dc29ece
--- /dev/null
+++ b/Zend/tests/traits/static_get_called_class.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Traits and get_called_class().
+--CREDITS--
+Simas Toleikis simast@gmail.com
+--FILE--
+<?php
+
+ trait TestTrait {
+ public static function test() {
+ return get_called_class();
+ }
+ }
+
+ class A {
+ use TestTrait;
+ }
+
+ class B extends A { }
+
+ echo B::test();
+
+?>
+--EXPECT--
+B \ No newline at end of file
diff --git a/Zend/tests/traits/trait_constant_001.phpt b/Zend/tests/traits/trait_constant_001.phpt
new file mode 100644
index 0000000..0fd8ff9
--- /dev/null
+++ b/Zend/tests/traits/trait_constant_001.phpt
@@ -0,0 +1,36 @@
+--TEST--
+__TRAIT__: Basics, a constant denoiting the trait of definition.
+--FILE--
+<?php
+
+trait TestTrait {
+ public static function test() {
+ return __TRAIT__;
+ }
+}
+
+class Direct {
+ use TestTrait;
+}
+
+class IndirectInheritance extends Direct {
+
+}
+
+trait TestTraitIndirect {
+ use TestTrait;
+}
+
+class Indirect {
+ use TestTraitIndirect;
+}
+
+echo Direct::test()."\n";
+echo IndirectInheritance::test()."\n";
+echo Indirect::test()."\n";
+
+?>
+--EXPECT--
+TestTrait
+TestTrait
+TestTrait
diff --git a/Zend/tests/traits/trait_constant_002.phpt b/Zend/tests/traits/trait_constant_002.phpt
new file mode 100644
index 0000000..327dd44
--- /dev/null
+++ b/Zend/tests/traits/trait_constant_002.phpt
@@ -0,0 +1,27 @@
+--TEST--
+__TRAIT__: Use outside of traits.
+--FILE--
+<?php
+
+ class MyClass {
+ static function test() {
+ return __TRAIT__;
+ }
+ }
+
+ function someFun() {
+ return __TRAIT__;
+ }
+
+
+ $t = __TRAIT__;
+ var_dump($t);
+ $t = MyClass::test();
+ var_dump($t);
+ $t = someFun();
+ var_dump($t);
+?>
+--EXPECT--
+string(0) ""
+string(0) ""
+string(0) "" \ No newline at end of file