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')); }
/** * 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); }; }