public function testSizeIncreasesEvenIfEvaluationsAreSkippedDueToAntecedentsNotBeingSatisfied() { $this->forAll(Generator\seq(Generator\elements(1, 2, 3)))->when(function ($seq) { return count($seq) > 0; })->then(function ($seq) { $this->assertGreaterThan(0, count($seq)); }); }
public function testConcatenationMaintainsLength() { $this->forAll(Generator\tuple(Generator\elements("A", "B", "C"), Generator\choose(0, 9)))->then(function ($tuple) { $letter = $tuple[0]; $cipher = $tuple[1]; $this->assertEquals(2, strlen($letter . $cipher), "{$letter}{$cipher} is not a 2-char string"); }); }
public function testCreatingABrandNewGeneratorFromAGeneratedValue() { $this->forAll(Generator\bind(Generator\vector(4, Generator\nat()), function ($vector) { return Generator\tuple(Generator\elements($vector), Generator\constant($vector)); }))->then(function ($tuple) { list($element, $vector) = $tuple; $this->assertContains($element, $vector); }); }
public function testVectorOfElementsGenerators() { $this->forAll(Generator\vector(4, Generator\elements([2, 4, 6, 8, 10, 12])))->then(function ($vector) { $sum = array_sum($vector); $isEven = function ($number) { return $number % 2 == 0; }; $this->assertTrue($isEven($sum), "{$sum} is not even, but it's the sum of the vector " . var_export($vector, true)); }); }
public function testAssociativeArraysGeneratedOnStandardKeys() { $this->forAll(Generator\associative(['letter' => Generator\elements("A", "B", "C"), 'cipher' => Generator\choose(0, 9)]))->then(function ($array) { $this->assertEquals(2, count($array)); $letter = $array['letter']; $this->assertInternalType('string', $letter); $cipher = $array['cipher']; $this->assertInternalType('integer', $cipher); }); }
/** * @test */ public function a_type_is_different_than_another_one() { $allTypes = [Type::A(), Type::B(), Type::C()]; $remove = function ($array, $whatToRemove) { return array_values(array_filter($array, function ($candidate) use($whatToRemove) { return $candidate != $whatToRemove; })); }; $this->forAll(Generator\bind(call_user_func_array('Eris\\Generator\\elements', $allTypes), function ($first) use($allTypes, $remove) { return Generator\tuple(Generator\constant($first), Generator\elements($remove($allTypes, $first))); }))->then(function ($differentElements) { $this->assertNotEquals($differentElements[0], $differentElements[1], "Several discussion types are equals"); }); }
public function testNotWithstandingCrashesJobsAreEventuallyPerformed() { $this->limitTo(100)->forAll(Generator\bind(Generator\choose(1, 4), function ($workers) { return Generator\tuple(Generator\constant($workers), Generator\seq(Generator\oneOf(Generator\map(function ($durationAndTag) { list($duration, $tag) = $durationAndTag; return ['enqueueJob', $duration, $tag]; }, Generator\tuple(Generator\nat(), Generator\elements(['generic', 'fast-lane']))), Generator\map(function ($workerIndex) { return ['restartWorkerGracefully', $workerIndex]; }, Generator\choose(0, $workers - 1)), Generator\map(function ($workerIndex) { return ['restartWorkerByKilling', $workerIndex]; }, Generator\choose(0, $workers - 1)), Generator\constant('restartRecruiterGracefully'), Generator\constant('restartRecruiterByKilling'), Generator\map(function ($milliseconds) { return ['sleep', $milliseconds]; }, Generator\choose(1, 1000))))); }))->hook(Listener\log('/tmp/recruiter-test-iterations.log'))->hook(Listener\collectFrequencies())->disableShrinking()->then(function ($tuple) { list($workers, $actions) = $tuple; $this->clean(); $this->start($workers); foreach ($actions as $action) { $this->logAction($action); if (is_array($action)) { $arguments = $action; $method = array_shift($arguments); call_user_func_array([$this, $method], $arguments); } else { $this->{$action}(); } } $estimatedTime = max(count($actions) * 4, 60); Timeout::inSeconds($estimatedTime, function () { return "all {$this->jobs} jobs to be performed. Now is " . date('c') . " Logs: " . $this->files(); })->until(function () { return $this->jobRepository->countArchived() === $this->jobs; }); $at = T\now(); $statistics = $this->recruiter->statistics($tag = null, $at); $this->assertInvariantsOnStatistics($statistics); // TODO: remove duplication $statisticsByTag = []; $cumulativeThroughput = 0; foreach (['generic', 'fast-lane'] as $tag) { $statisticsByTag[$tag] = $this->recruiter->statistics($tag, $at); $this->assertInvariantsOnStatistics($statisticsByTag[$tag]); $cumulativeThroughput += $statisticsByTag[$tag]['throughput']['value']; } var_dump($statistics, $statisticsByTag); // TODO: add tolerance $this->assertEquals($statistics['throughput']['value'], $cumulativeThroughput); }); }
public function testFailsNoMatterWhatIsTheInput() { $this->forAll(Generator\elements(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']))->then(function ($someChar) { $this->fail("This test fails by design. '{$someChar}' was passed in"); }); }
/** * @group long */ public function testPropertyBased() { $this->iteration = 0; $this->forAll(Generator\vector(2, Generator\seq(Generator\elements(['acquire', 'release']))))->when(function ($sequencesOfSteps) { foreach ($sequencesOfSteps as $sequence) { if (!$sequence) { return false; } } return true; })->then(function ($sequencesOfSteps) { $this->lockCollection->drop(); $log = "/tmp/mongolock_{$this->iteration}.log"; if (file_exists($log)) { unlink($log); } $processes = []; foreach ($sequencesOfSteps as $i => $sequence) { $processName = "p{$i}"; $steps = implode(',', $sequence); $process = new Process("exec php " . __DIR__ . "/mongolock.php {$processName} {$steps} >> {$log}"); $process->start(); $processes[] = $process; } foreach ($processes as $process) { $process->wait(); $this->assertExitedCorrectly($process, "Error in MongoLock run"); } $process = new Process("exec java -jar " . __DIR__ . "/knossos-onebip.jar mongo-lock {$log}"); $process->run(); $this->assertExitedCorrectly($process, "Non-linearizable history in {$log}"); $this->iteration++; }); }