public function test_compare()
 {
     $this->assertTrue(\Sledgehammer\compare('asd', '==', 'asd'));
     $this->assertTrue(\Sledgehammer\compare(2, '==', 2));
     $this->assertFalse(\Sledgehammer\compare('asd', '==', 'AsD'));
     // But MySQL will evalutate this to true, depending on the collation
     $this->assertTrue(\Sledgehammer\compare('1', '==', 1));
     $this->assertTrue(\Sledgehammer\compare(null, '==', null));
     $this->assertTrue(\Sledgehammer\compare(1, '>', null));
     $this->assertTrue(\Sledgehammer\compare(0, '>=', null));
     $this->assertFalse(\Sledgehammer\compare('', '==', 0));
     $this->assertFalse(\Sledgehammer\compare(0, '>', null));
     $this->assertTrue(\Sledgehammer\compare(2, 'IN', array(1, 2, 3)));
     $this->assertFalse(\Sledgehammer\compare(4, 'IN', array(1, 2, 3)));
     $this->assertTrue(\Sledgehammer\compare(4, 'NOT IN', array(1, 2, 3)));
     $this->assertFalse(\Sledgehammer\compare(2, 'NOT IN', array(1, 2, 3)));
     $this->assertTrue(\Sledgehammer\compare(1, '==', true));
     $this->assertTrue(\Sledgehammer\compare('1', '==', true));
     $this->assertTrue(\Sledgehammer\compare(0, '==', false));
     $this->assertTrue(\Sledgehammer\compare('0', '==', false));
     // compare uses the stricter equals() rules.
     $this->assertFalse(\Sledgehammer\compare('true', '==', true), '"true" != true');
     $this->assertFalse(\Sledgehammer\compare('true', '==', false), '"true" != false either');
     $this->assertFalse(\Sledgehammer\compare(2, '==', false));
     $this->assertFalse(\Sledgehammer\compare(2, '==', true));
     $this->assertTrue(\Sledgehammer\compare('car', 'LIKE', 'car'));
     $this->assertTrue(\Sledgehammer\compare('cartoon', 'LIKE', 'ca%'));
     $this->assertFalse(\Sledgehammer\compare('cartoon', 'LIKE', 'ca%pet'));
     $this->assertTrue(\Sledgehammer\compare('car', 'LIKE', 'c_r'));
     $this->assertTrue(\Sledgehammer\compare('cartoon', 'LIKE', 'ca%'));
     $this->assertTrue(\Sledgehammer\compare('\\a%b_c\\', 'LIKE', '\\a\\%b\\_c\\'), 'escape %, _ with \\ ');
     $this->assertTrue(\Sledgehammer\compare('car', 'NOT LIKE', 'bar'));
     $this->assertFalse(\Sledgehammer\compare('car', 'NOT LIKE', 'car'));
 }
Beispiel #2
0
 /**
  * Build a closure which validates an item with the gives $conditions.
  *
  * @param mixed $conditions array|Closure|expression  See Collection::where() for condition options
  *
  * @return callable
  */
 protected function buildFilter($conditions)
 {
     if (\Sledgehammer\is_closure($conditions)) {
         return $conditions;
     }
     if (is_array($conditions)) {
         // Create filter that checks all conditions
         $logicalOperator = \Sledgehammer\extract_logical_operator($conditions);
         if ($logicalOperator === false) {
             if (count($conditions) > 1) {
                 \Sledgehammer\notice('Conditions with multiple conditions require a logical operator.', "Example: array('AND', 'x' => 1, 'y' => 5)");
             }
             $logicalOperator = 'AND';
         } else {
             unset($conditions[0]);
         }
         $operators = [];
         foreach ($conditions as $path => $expectation) {
             if (preg_match('/^(.*) (' . \Sledgehammer\COMPARE_OPERATORS . ')$/', $path, $matches)) {
                 unset($conditions[$path]);
                 $conditions[$matches[1]] = $expectation;
                 $operators[$matches[1]] = $matches[2];
             } else {
                 $operators[$path] = false;
             }
         }
         // @todo Build an optimized closure for when a single conditions is given.
         if ($logicalOperator === 'AND') {
             return function ($item) use($conditions, $operators) {
                 foreach ($conditions as $path => $expectation) {
                     $actual = PropertyPath::get($path, $item);
                     $operator = $operators[$path];
                     if ($operator) {
                         if (\Sledgehammer\compare($actual, $operator, $expectation) === false) {
                             return false;
                         }
                     } elseif (\Sledgehammer\equals($actual, $expectation) === false) {
                         return false;
                     }
                 }
                 return true;
                 // All conditions are met.
             };
         } elseif ($logicalOperator === 'OR') {
             return function ($item) use($conditions, $operators) {
                 foreach ($conditions as $path => $expectation) {
                     $actual = PropertyPath::get($path, $item);
                     $operator = $operators[$path];
                     if ($operator) {
                         if (\Sledgehammer\compare($actual, $operator, $expectation) !== false) {
                             return true;
                         }
                     } elseif (\Sledgehammer\equals($actual, $expectation) !== false) {
                         return true;
                     }
                 }
                 return false;
                 // None of conditions are met.
             };
         } else {
             throw new Exception('Unsupported logical operator "' . $logicalOperator . '", expecting "AND" or "OR"');
         }
     }
     //'<= 5' or '10'
     // Compare the item directly with value given as $condition.
     if (is_string($conditions) && preg_match('/^(' . \Sledgehammer\COMPARE_OPERATORS . ') (.*)$/', $conditions, $matches)) {
         $operator = $matches[1];
         $expectation = $matches[2];
     } else {
         $expectation = $conditions;
         $operator = '==';
     }
     return function ($value) use($expectation, $operator) {
         return \Sledgehammer\compare($value, $operator, $expectation);
     };
 }