diff --git a/tests/AlgebraTest.php b/tests/AlgebraTest.php new file mode 100644 index 000000000..8eaaf21da --- /dev/null +++ b/tests/AlgebraTest.php @@ -0,0 +1,151 @@ + ['!falsy']]), + ]; + + $negated_formula = Algebra::negateFormula($formula); + + $this->assertCount(1, $negated_formula); + $this->assertSame(['$a' => ['falsy']], $negated_formula[0]->possibilities); + + $formula = [ + new Clause(['$a' => ['!falsy'], '$b' => ['!falsy']]), + ]; + + $negated_formula = Algebra::negateFormula($formula); + + $this->assertCount(2, $negated_formula); + $this->assertSame(['$a' => ['falsy']], $negated_formula[0]->possibilities); + $this->assertSame(['$b' => ['falsy']], $negated_formula[1]->possibilities); + + $formula = [ + new Clause(['$a' => ['!falsy']]), + new Clause(['$b' => ['!falsy']]), + ]; + + $negated_formula = Algebra::negateFormula($formula); + + $this->assertCount(1, $negated_formula); + $this->assertSame(['$a' => ['falsy'], '$b' => ['falsy']], $negated_formula[0]->possibilities); + + $formula = [ + new Clause(['$a' => ['int', 'string'], '$b' => ['!falsy']]), + ]; + + $negated_formula = Algebra::negateFormula($formula); + + $this->assertCount(3, $negated_formula); + $this->assertSame(['$a' => ['!int']], $negated_formula[0]->possibilities); + $this->assertSame(['$a' => ['!string']], $negated_formula[1]->possibilities); + $this->assertSame(['$b' => ['falsy']], $negated_formula[2]->possibilities); + } + + /** + * @return void + */ + public function testCombinatorialExpansion() + { + $dnf = 'assertInstanceOf(PhpParser\Node\Stmt\Expression::class, $dnf_stmt); + + $file_analyzer = new FileAnalyzer($this->project_analyzer, 'somefile.php', 'somefile.php'); + $file_analyzer->context = new Context(); + $statements_analyzer = new StatementsAnalyzer($file_analyzer); + + $dnf_clauses = Algebra::getFormula( + $dnf_stmt->expr, + null, + $statements_analyzer + ); + + $this->assertCount(6561, $dnf_clauses); + + $simplified_dnf_clauses = Algebra::simplifyCNF($dnf_clauses); + + $this->assertCount(23, $simplified_dnf_clauses); + } + + /** + * @return void + */ + public function testContainsClause() + { + $this->assertTrue( + (new Clause( + [ + '$a' => ['!falsy'], + '$b' => ['!falsy'], + ] + ))->contains( + new Clause( + [ + '$a' => ['!falsy'], + ] + ) + ) + ); + + $this->assertFalse( + (new Clause( + [ + '$a' => ['!falsy'], + ] + ))->contains( + new Clause( + [ + '$a' => ['!falsy'], + '$b' => ['!falsy'], + ] + ) + ) + ); + } + + /** + * @return void + */ + public function testSimplifyCNF() + { + $formula = [ + new Clause(['$a' => ['!falsy']]), + new Clause(['$a' => ['falsy'], '$b' => ['falsy']]), + ]; + + $simplified_formula = Algebra::simplifyCNF($formula); + + $this->assertCount(2, $simplified_formula); + $this->assertSame(['$a' => ['!falsy']], $simplified_formula[0]->possibilities); + $this->assertSame(['$b' => ['falsy']], $simplified_formula[1]->possibilities); + } +} diff --git a/tests/TypeReconciliationTest.php b/tests/TypeReconciliationTest.php index 0d75422b2..cca554661 100644 --- a/tests/TypeReconciliationTest.php +++ b/tests/TypeReconciliationTest.php @@ -83,105 +83,6 @@ class TypeReconciliationTest extends TestCase ); } - /** - * @return void - */ - public function testNegateFormula() - { - $formula = [ - new Clause(['$a' => ['!falsy']]), - ]; - - $negated_formula = Algebra::negateFormula($formula); - - $this->assertCount(1, $negated_formula); - $this->assertSame(['$a' => ['falsy']], $negated_formula[0]->possibilities); - - $formula = [ - new Clause(['$a' => ['!falsy'], '$b' => ['!falsy']]), - ]; - - $negated_formula = Algebra::negateFormula($formula); - - $this->assertCount(2, $negated_formula); - $this->assertSame(['$a' => ['falsy']], $negated_formula[0]->possibilities); - $this->assertSame(['$b' => ['falsy']], $negated_formula[1]->possibilities); - - $formula = [ - new Clause(['$a' => ['!falsy']]), - new Clause(['$b' => ['!falsy']]), - ]; - - $negated_formula = Algebra::negateFormula($formula); - - $this->assertCount(1, $negated_formula); - $this->assertSame(['$a' => ['falsy'], '$b' => ['falsy']], $negated_formula[0]->possibilities); - - $formula = [ - new Clause(['$a' => ['int', 'string'], '$b' => ['!falsy']]), - ]; - - $negated_formula = Algebra::negateFormula($formula); - - $this->assertCount(3, $negated_formula); - $this->assertSame(['$a' => ['!int']], $negated_formula[0]->possibilities); - $this->assertSame(['$a' => ['!string']], $negated_formula[1]->possibilities); - $this->assertSame(['$b' => ['falsy']], $negated_formula[2]->possibilities); - } - - /** - * @return void - */ - public function testContainsClause() - { - $this->assertTrue( - (new Clause( - [ - '$a' => ['!falsy'], - '$b' => ['!falsy'], - ] - ))->contains( - new Clause( - [ - '$a' => ['!falsy'], - ] - ) - ) - ); - - $this->assertFalse( - (new Clause( - [ - '$a' => ['!falsy'], - ] - ))->contains( - new Clause( - [ - '$a' => ['!falsy'], - '$b' => ['!falsy'], - ] - ) - ) - ); - } - - /** - * @return void - */ - public function testSimplifyCNF() - { - $formula = [ - new Clause(['$a' => ['!falsy']]), - new Clause(['$a' => ['falsy'], '$b' => ['falsy']]), - ]; - - $simplified_formula = Algebra::simplifyCNF($formula); - - $this->assertCount(2, $simplified_formula); - $this->assertSame(['$a' => ['!falsy']], $simplified_formula[0]->possibilities); - $this->assertSame(['$b' => ['falsy']], $simplified_formula[1]->possibilities); - } - /** * @return array */ @@ -1454,6 +1355,29 @@ class TypeReconciliationTest extends TestCase if ($a === $b) {} }', ], + 'preventCombinatorialExpansion' => [ + '