add new Horde_Constraint package for building up constraint sets
authorChuck Hagenbuch <chuck@horde.org>
Sat, 26 Sep 2009 03:15:35 +0000 (23:15 -0400)
committerChuck Hagenbuch <chuck@horde.org>
Sat, 26 Sep 2009 03:40:40 +0000 (23:40 -0400)
21 files changed:
framework/Constraint/lib/Horde/Constraint.php [new file with mode: 0644]
framework/Constraint/lib/Horde/Constraint/AlwaysFalse.php [new file with mode: 0644]
framework/Constraint/lib/Horde/Constraint/AlwaysTrue.php [new file with mode: 0644]
framework/Constraint/lib/Horde/Constraint/And.php [new file with mode: 0644]
framework/Constraint/lib/Horde/Constraint/Compound.php [new file with mode: 0644]
framework/Constraint/lib/Horde/Constraint/IsEqual.php [new file with mode: 0644]
framework/Constraint/lib/Horde/Constraint/IsInstanceOf.php [new file with mode: 0644]
framework/Constraint/lib/Horde/Constraint/Not.php [new file with mode: 0644]
framework/Constraint/lib/Horde/Constraint/Null.php [new file with mode: 0644]
framework/Constraint/lib/Horde/Constraint/Or.php [new file with mode: 0644]
framework/Constraint/lib/Horde/Constraint/PregMatch.php [new file with mode: 0644]
framework/Constraint/package.xml [new file with mode: 0644]
framework/Constraint/test/Horde/Constraint/AllTests.php [new file with mode: 0644]
framework/Constraint/test/Horde/Constraint/AlwaysFalseTest.php [new file with mode: 0644]
framework/Constraint/test/Horde/Constraint/AlwaysTrueTest.php [new file with mode: 0644]
framework/Constraint/test/Horde/Constraint/AndTest.php [new file with mode: 0644]
framework/Constraint/test/Horde/Constraint/IsInstanceOfTest.php [new file with mode: 0644]
framework/Constraint/test/Horde/Constraint/NotTest.php [new file with mode: 0644]
framework/Constraint/test/Horde/Constraint/NullTest.php [new file with mode: 0644]
framework/Constraint/test/Horde/Constraint/OrTest.php [new file with mode: 0644]
framework/Constraint/test/Horde/Constraint/PregMatchTest.php [new file with mode: 0644]

diff --git a/framework/Constraint/lib/Horde/Constraint.php b/framework/Constraint/lib/Horde/Constraint.php
new file mode 100644 (file)
index 0000000..359856a
--- /dev/null
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Interface for constraints.
+ *
+ * @author James Pepin <james@jamespepin.com>
+ */
+interface Horde_Constraint
+{
+    public function evaluate($value);
+}
diff --git a/framework/Constraint/lib/Horde/Constraint/AlwaysFalse.php b/framework/Constraint/lib/Horde/Constraint/AlwaysFalse.php
new file mode 100644 (file)
index 0000000..2dcc0e1
--- /dev/null
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Always returns false
+ *
+ * @author James Pepin <james@jamespepin.com>
+ */
+class Horde_Constraint_AlwaysFalse implements Horde_Constraint
+{
+    public function evaluate($value)
+    {
+        return false;
+    }
+}
diff --git a/framework/Constraint/lib/Horde/Constraint/AlwaysTrue.php b/framework/Constraint/lib/Horde/Constraint/AlwaysTrue.php
new file mode 100644 (file)
index 0000000..d4848e5
--- /dev/null
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Always returns true
+ *
+ * @author James Pepin <james@jamespepin.com>
+ */
+class Horde_Constraint_AlwaysTrue implements Horde_Constraint
+{
+    public function evaluate($value)
+    {
+        return true;
+    }
+}
diff --git a/framework/Constraint/lib/Horde/Constraint/And.php b/framework/Constraint/lib/Horde/Constraint/And.php
new file mode 100644 (file)
index 0000000..2f199a4
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Represents a collection of constraints, if one is false, this collection will
+ * evaluate to false
+ *
+ * Based on PHPUnit_Framework_Constraint_And
+ *
+ * @author James Pepin <james@jamespepin.com>
+ */
+class Horde_Constraint_And extends Horde_Constraint_Compound
+{
+    public function evaluate($value)
+    {
+        foreach ($this->_constraints as $c) {
+            if (!$c->evaluate($value)) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/framework/Constraint/lib/Horde/Constraint/Compound.php b/framework/Constraint/lib/Horde/Constraint/Compound.php
new file mode 100644 (file)
index 0000000..48d8027
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Interface for compound constraints.
+ *
+ * @author James Pepin <james@jamespepin.com>
+ */
+abstract class Horde_Constraint_Compound implements Horde_Constraint
+{
+    protected $_constraints = array();
+
+    public function __construct()
+    {
+        $constraints = func_get_args();
+        foreach ($constraints as $c) {
+            if (! $c instanceof Horde_Constraint) {
+                throw new IllegalArgumentException("$c does not implement Horde_Constraint");
+            }
+        }
+        $this->_constraints = $constraints;
+    }
+
+    public function addConstraint(Horde_Constraint $constraint)
+    {
+        $this->_constraints[] = $constraint;
+        return $this;
+    }
+
+    abstract public function evaluate($value);
+}
diff --git a/framework/Constraint/lib/Horde/Constraint/IsEqual.php b/framework/Constraint/lib/Horde/Constraint/IsEqual.php
new file mode 100644 (file)
index 0000000..3c06dc7
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Checks for equality
+ *
+ * Based on PHPUnit_Framework_Constraint_IsEqual
+ *
+ * @author James Pepin <james@jamespepin.com>
+ */
+class Horde_Constraint_IsEqual implements Horde_Constraint
+{
+    private $_value;
+
+    public function __construct($value)
+    {
+        $this->_value = $value;
+    }
+
+    public function evaluate($value)
+    {
+        return $this->_value == $value;
+    }
+}
diff --git a/framework/Constraint/lib/Horde/Constraint/IsInstanceOf.php b/framework/Constraint/lib/Horde/Constraint/IsInstanceOf.php
new file mode 100644 (file)
index 0000000..43d43e7
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Checks for an instance of a class
+ *
+ * Based on PHPUnit_Framework_Constraint_IsInstanceOf
+ *
+ * @author James Pepin <james@jamespepin.com>
+ */
+class Horde_Constraint_IsInstanceOf implements Horde_Constraint
+{
+    private $_type;
+
+    public function __construct($type)
+    {
+        $this->_type = $type;
+    }
+
+    public function evaluate($value)
+    {
+        return $value instanceof $this->_type;
+    }
+}
diff --git a/framework/Constraint/lib/Horde/Constraint/Not.php b/framework/Constraint/lib/Horde/Constraint/Not.php
new file mode 100644 (file)
index 0000000..69addc4
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Negates another constraint
+ *
+ * Based on PHPUnit_Framework_Constraint_Not
+ *
+ * @author James Pepin <james@jamespepin.com>
+ */
+class Horde_Constraint_Not implements Horde_Constraint
+{
+    private $_constraint;
+
+    public function __construct(Horde_Constraint $constraint)
+    {
+        $this->_constraint = $constraint;
+    }
+
+    public function evaluate($value)
+    {
+        return !$this->_constraint->evaluate($value);
+    }
+}
diff --git a/framework/Constraint/lib/Horde/Constraint/Null.php b/framework/Constraint/lib/Horde/Constraint/Null.php
new file mode 100644 (file)
index 0000000..c385900
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Checks if the value is null
+ *
+ * Based on PHPUnit_Framework_Constraint_Null
+ *
+ * @author James Pepin <james@jamespepin.com>
+ */
+class Horde_Constraint_Null implements Horde_Constraint
+{
+    public function evaluate($value)
+    {
+        return is_null($value);
+    }
+}
diff --git a/framework/Constraint/lib/Horde/Constraint/Or.php b/framework/Constraint/lib/Horde/Constraint/Or.php
new file mode 100644 (file)
index 0000000..0882fed
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Represents a collection of constraints, if any are true, the collection will evaluate to true.
+ *
+ * @author James Pepin <james@jamespepin.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ */
+class Horde_Constraint_Or extends Horde_Constraint_Compound
+{
+    public function evaluate($value)
+    {
+        foreach ($this->_constraints as $c) {
+            if ($c->evaluate($value)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/framework/Constraint/lib/Horde/Constraint/PregMatch.php b/framework/Constraint/lib/Horde/Constraint/PregMatch.php
new file mode 100644 (file)
index 0000000..cc148e2
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Matches against a PCRE regex
+ *
+ * Based on PHPUnit_Framework_Constraint_PCREMatch
+ *
+ * @author James Pepin <james@jamespepin.com>
+ */
+class Horde_Constraint_PregMatch implements Horde_Constraint
+{
+    private $_regex;
+
+    public function __construct($regex)
+    {
+        $this->_regex = $regex;
+    }
+
+    public function evaluate($value)
+    {
+        return preg_match($this->_regex, $value) > 0;
+    }
+}
diff --git a/framework/Constraint/package.xml b/framework/Constraint/package.xml
new file mode 100644 (file)
index 0000000..f070797
--- /dev/null
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.4.9" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+http://pear.php.net/dtd/tasks-1.0.xsd
+http://pear.php.net/dtd/package-2.0
+http://pear.php.net/dtd/package-2.0.xsd">
+ <name>Constraint</name>
+ <channel>pear.horde.org</channel>
+ <summary>Horde Constraint library</summary>
+ <description>This package provides a programmatic way of building constraints that evaluate to true or false
+ </description>
+ <lead>
+  <name>Chuck Hagenbuch</name>
+  <user>chuck</user>
+  <email>chuck@horde.org</email>
+  <active>yes</active>
+ </lead>
+ <lead>
+  <name>James Pepin</name>
+  <user>james</user>
+  <email>james@jamespepin</email>
+  <active>yes</active>
+ </lead>
+ <date>2009-09-25</date>
+ <version>
+  <release>0.1.0</release>
+  <api>0.1.0</api>
+ </version>
+ <stability>
+  <release>beta</release>
+  <api>beta</api>
+ </stability>
+ <license uri="http://opensource.org/licenses/bsd-license.php">BSD</license>
+ <notes>* Initial release.
+ </notes>
+ <contents>
+  <dir name="/">
+   <dir name="lib">
+    <dir name="Horde">
+     <dir name="Constraint">
+      <file name="AlwaysFalse.php" role="php" />
+      <file name="AlwaysTrue.php" role="php" />
+      <file name="And.php" role="php" />
+      <file name="Compound.php" role="php" />
+      <file name="IsEqual.php" role="php" />
+      <file name="IsInstanceOf.php" role="php" />
+      <file name="Not.php" role="php" />
+      <file name="Null.php" role="php" />
+      <file name="Or.php" role="php" />
+      <file name="PregMatch.php" role="php" />
+     </dir> <!-- /lib/Horde/Constraint -->
+     <file name="Constraint.php" role="php" />
+    </dir> <!-- /lib/Horde -->
+   </dir> <!-- /lib -->
+  </dir> <!-- / -->
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>5.2.0</min>
+   </php>
+   <pearinstaller>
+    <min>1.7.0</min>
+   </pearinstaller>
+  </required>
+ </dependencies>
+ <phprelease>
+  <filelist>
+   <install name="lib/Horde/Constraint/AlwaysFalse.php" as="Horde/Constraint/AlwaysFalse.php" />
+   <install name="lib/Horde/Constraint/AlwaysTrue.php" as="Horde/Constraint/AlwaysTrue.php" />
+   <install name="lib/Horde/Constraint/And.php" as="Horde/Constraint/And.php" />
+   <install name="lib/Horde/Constraint/Compound.php" as="Horde/Constraint/Compound.php" />
+   <install name="lib/Horde/Constraint/IsEqual.php" as="Horde/Constraint/IsEqual.php" />
+   <install name="lib/Horde/Constraint/IsInstanceOf.php" as="Horde/Constraint/IsInstanceOf.php" />
+   <install name="lib/Horde/Constraint/Not.php" as="Horde/Constraint/Not.php" />
+   <install name="lib/Horde/Constraint/Null.php" as="Horde/Constraint/Null.php" />
+   <install name="lib/Horde/Constraint/Or.php" as="Horde/Constraint/Or.php" />
+   <install name="lib/Horde/Constraint/PregMatch.php" as="Horde/Constraint/PregMatch.php" />
+   <install name="lib/Horde/Constraint.php" as="Horde/Constraint.php" />
+  </filelist>
+ </phprelease>
+</package>
diff --git a/framework/Constraint/test/Horde/Constraint/AllTests.php b/framework/Constraint/test/Horde/Constraint/AllTests.php
new file mode 100644 (file)
index 0000000..c196808
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+/**
+ * @package    Horde_Constraint
+ * @subpackage UnitTests
+ */
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'Horde_Constraint_AllTests::main');
+}
+
+if (!spl_autoload_functions()) {
+    spl_autoload_register(create_function('$class', '$filename = str_replace(array(\'::\', \'_\'), \'/\', $class); @include_once "$filename.php";'));
+}
+
+class Horde_Constraint_AllTests
+{
+    public static function main()
+    {
+        PHPUnit_TextUI_TestRunner::run(self::suite());
+    }
+
+    public static function suite()
+    {
+        set_include_path(dirname(__FILE__) . '/../../../lib' . PATH_SEPARATOR . get_include_path());
+        $suite = new PHPUnit_Framework_TestSuite('Horde Framework - Horde_Constraint');
+
+        $basedir = dirname(__FILE__);
+        $baseregexp = preg_quote($basedir . DIRECTORY_SEPARATOR, '/');
+
+        foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($basedir)) as $file) {
+            if ($file->isFile() && preg_match('/Test.php$/', $file->getFilename())) {
+                $pathname = $file->getPathname();
+                require $pathname;
+
+                $class = str_replace(DIRECTORY_SEPARATOR, '_',
+                                     preg_replace("/^$baseregexp(.*)\.php/", '\\1', $pathname));
+                $suite->addTestSuite('Horde_Constraint_' . $class);
+            }
+        }
+
+        return $suite;
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'Horde_Constraint_AllTests::main') {
+    Horde_Constraint_AllTests::main();
+}
diff --git a/framework/Constraint/test/Horde/Constraint/AlwaysFalseTest.php b/framework/Constraint/test/Horde/Constraint/AlwaysFalseTest.php
new file mode 100644 (file)
index 0000000..cd6af31
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+class Horde_Constraint_AlwaysFalseTest extends Horde_Test_Case
+{
+    public static function randomObjectProvider()
+    {
+        return array(
+            array('teststring'),
+            array(''),
+            array(true),
+            array(false),
+        );
+    }
+
+    /**
+     * @dataProvider randomObjectProvider
+     */
+    public function testEvaluateIsAlwaysFalse($value)
+    {
+        $const = new Horde_Constraint_AlwaysFalse();
+        $this->assertFalse($const->evaluate($value));
+    }
+}
diff --git a/framework/Constraint/test/Horde/Constraint/AlwaysTrueTest.php b/framework/Constraint/test/Horde/Constraint/AlwaysTrueTest.php
new file mode 100644 (file)
index 0000000..aa69e65
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+class Horde_Constraint_AlwaysTrueTest extends Horde_Test_Case
+{
+    public static function randomObjectProvider()
+    {
+        return array(
+            array('teststring'),
+            array(''),
+            array(true),
+            array(false),
+        );
+    }
+
+    /**
+     * @dataProvider randomObjectProvider
+     */
+    public function testEvaluateIsAlwaysTrue($value)
+    {
+        $const = new Horde_Constraint_AlwaysTrue();
+        $this->assertTrue($const->evaluate($value));
+    }
+}
diff --git a/framework/Constraint/test/Horde/Constraint/AndTest.php b/framework/Constraint/test/Horde/Constraint/AndTest.php
new file mode 100644 (file)
index 0000000..6be9f03
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+class Horde_Constraint_AndTest extends Horde_Test_Case
+{
+    public function testAndEvaluatesFalseWhenOneConstraintIsFalse()
+    {
+        $c1  = new Horde_Constraint_AlwaysTrue();
+        $c2  = new Horde_Constraint_AlwaysFalse();
+        $and = new Horde_Constraint_And($c1, $c2);
+
+        $this->assertFalse($and->evaluate('test_string'));
+    }
+
+    public function testAndEvaluatesFalseWhenBothConstraintsAreFalse()
+    {
+        $c1  = new Horde_Constraint_AlwaysFalse();
+        $c2  = new Horde_Constraint_AlwaysFalse();
+        $and = new Horde_Constraint_And($c1, $c2);
+
+        $this->assertFalse($and->evaluate('test_string'));
+    }
+
+    public function testAndEvaluatesTrueWhenBothConstraintsAreTrue()
+    {
+        $c1  = new Horde_Constraint_AlwaysTrue();
+        $c2  = new Horde_Constraint_AlwaysTrue();
+        $and = new Horde_Constraint_And($c1, $c2);
+
+        $this->assertTrue($and->evaluate('test_string'));
+    }
+
+    public function testAndEvaluatesFalseWhenFalseConstraintIsAddedViaSetter()
+    {
+        $c1  = new Horde_Constraint_AlwaysTrue();
+        $c2  = new Horde_Constraint_AlwaysTrue();
+        $and = new Horde_Constraint_And($c1, $c2);
+
+        $and->addConstraint(new Horde_Constraint_AlwaysFalse());
+
+        $this->assertFalse($and->evaluate('test_string'));
+    }
+
+    public function testAndaddConstraintReturnsAndConstraint()
+    {
+        $c1  = new Horde_Constraint_AlwaysTrue();
+        $c2  = new Horde_Constraint_AlwaysTrue();
+        $and = new Horde_Constraint_And($c1, $c2);
+
+        $returnConst = $and->addConstraint(new Horde_Constraint_AlwaysFalse());
+
+        $this->assertType('Horde_Constraint_And', $returnConst);
+    }
+
+    public function testReturnedAndEvaluatesFalseWhenFalseConstraintIsAddedViaSetter()
+    {
+        $c1  = new Horde_Constraint_AlwaysTrue();
+        $c2  = new Horde_Constraint_AlwaysTrue();
+        $and = new Horde_Constraint_And($c1, $c2);
+
+        $and = $and->addConstraint(new Horde_Constraint_AlwaysFalse());
+
+        $this->assertFalse($and->evaluate('test_string'));
+    }
+}
diff --git a/framework/Constraint/test/Horde/Constraint/IsInstanceOfTest.php b/framework/Constraint/test/Horde/Constraint/IsInstanceOfTest.php
new file mode 100644 (file)
index 0000000..66a21f4
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+class Horde_Constraint_IsInstanceOfTest extends Horde_Test_Case
+{
+    public function testConstraintReturnsFalseWhenInstanceIsWrongClass()
+    {
+        $foo = new StdClass();
+        $const = new Horde_Constraint_IsInstanceOf('FakeClassName');
+
+        $this->assertFalse($const->evaluate($foo));
+    }
+
+    public function testConstraintReturnsTrueWhenInstanceIsCorrectClass()
+    {
+        $foo = new StdClass();
+        $const = new Horde_Constraint_IsInstanceOf('StdClass');
+
+        $this->assertTrue($const->evaluate($foo));
+    }
+}
diff --git a/framework/Constraint/test/Horde/Constraint/NotTest.php b/framework/Constraint/test/Horde/Constraint/NotTest.php
new file mode 100644 (file)
index 0000000..919cb8c
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+class Horde_Constraint_NotTest extends Horde_Test_Case
+{
+    public function testNotMakesFalseConstraintTrue()
+    {
+        $not = new Horde_Constraint_Not(new Horde_Constraint_AlwaysFalse());
+        $this->assertTrue($not->evaluate('foo'));
+    }
+
+    public function testNotMakesTrueConstraintFalse()
+    {
+        $not = new Horde_Constraint_Not(new Horde_Constraint_AlwaysTrue());
+        $this->assertFalse($not->evaluate('foo'));
+    }
+}
diff --git a/framework/Constraint/test/Horde/Constraint/NullTest.php b/framework/Constraint/test/Horde/Constraint/NullTest.php
new file mode 100644 (file)
index 0000000..22efcab
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+class Horde_Constraint_NullTest extends Horde_Test_Case
+{
+    public function testNullReturnsTrueWhenValueisNull()
+    {
+        $const = new Horde_Constraint_Null();
+        $this->assertTrue($const->evaluate(null));
+    }
+
+    public function testNullReturnsFalseWhenValue_IsNot_Null()
+    {
+        $const = new Horde_Constraint_Null();
+        $this->assertFalse($const->evaluate('not null value'));
+    }
+}
diff --git a/framework/Constraint/test/Horde/Constraint/OrTest.php b/framework/Constraint/test/Horde/Constraint/OrTest.php
new file mode 100644 (file)
index 0000000..2b3ce61
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+class Horde_Constraint_OrTest extends Horde_Test_Case
+{
+    public function testOrEvaluatesTrueWhenOneConstraintIsTrue()
+    {
+        $c1 = new Horde_Constraint_AlwaysTrue();
+        $c2 = new Horde_Constraint_AlwaysFalse();
+        $or = new Horde_Constraint_Or($c1, $c2);
+
+        $this->assertTrue($or->evaluate('test_string'));
+    }
+
+    public function testOrEvaluatesFalseWhenBothConstraintsAreFalse()
+    {
+        $c1 = new Horde_Constraint_AlwaysFalse();
+        $c2 = new Horde_Constraint_AlwaysFalse();
+        $or = new Horde_Constraint_Or($c1, $c2);
+
+        $this->assertFalse($or->evaluate('test_string'));
+    }
+
+    public function testOrEvaluatesTrueWhenBothConstraintsAreTrue()
+    {
+        $c1 = new Horde_Constraint_AlwaysTrue();
+        $c2 = new Horde_Constraint_AlwaysTrue();
+        $or = new Horde_Constraint_Or($c1, $c2);
+
+        $this->assertTrue($or->evaluate('test_string'));
+    }
+
+    public function testOrEvaluatesTrueWhenTrueConstraintIsAddedViaSetter()
+    {
+        $c1 = new Horde_Constraint_AlwaysFalse();
+        $c2 = new Horde_Constraint_AlwaysFalse();
+        $or = new Horde_Constraint_Or($c1, $c2);
+
+        $or->addConstraint(new Horde_Constraint_AlwaysTrue());
+
+        $this->assertTrue($or->evaluate('test_string'));
+    }
+
+    public function testOraddConstraintReturnsOrConstraint()
+    {
+        $c1 = new Horde_Constraint_AlwaysTrue();
+        $c2 = new Horde_Constraint_AlwaysTrue();
+        $or = new Horde_Constraint_Or($c1, $c2);
+
+        $returnConst = $or->addConstraint(new Horde_Constraint_AlwaysFalse());
+
+        $this->assertType('Horde_Constraint_Or', $returnConst);
+    }
+
+    public function testReturnedOrEvaluatesTrueWhenTrueConstraintIsAddedViaSetter()
+    {
+        $c1 = new Horde_Constraint_AlwaysFalse();
+        $c2 = new Horde_Constraint_AlwaysFalse();
+        $or = new Horde_Constraint_Or($c1, $c2);
+
+        $or = $or->addConstraint(new Horde_Constraint_AlwaysTrue());
+
+        $this->assertTrue($or->evaluate('test_string'));
+    }
+}
diff --git a/framework/Constraint/test/Horde/Constraint/PregMatchTest.php b/framework/Constraint/test/Horde/Constraint/PregMatchTest.php
new file mode 100644 (file)
index 0000000..8168365
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+class Horde_Constraint_PregMatchTest extends Horde_Test_Case
+{
+    public function testPregReturnsTrueWhenRegexMatches()
+    {
+        $preg = new Horde_Constraint_PregMatch('/somestring/');
+        $this->assertTrue($preg->evaluate('somestring'));
+    }
+
+    public function testPregReturnsFalseWhenRegex_DoesNot_Match()
+    {
+        $preg = new Horde_Constraint_PregMatch('/somestring/');
+        $this->assertFalse($preg->evaluate('some other string'));
+    }
+}