Tester.php
<?php
namespace Tlf\Lexer\Test;
class Tester extends \Tlf\Tester {
/**
* See the PhpGrammar test
*
* @return an array of test results where key is test name & value is true/false for pass/fail
*/
protected function runDirectiveTests($grammars, $thingies){
$skipped = [];
/** test descriptions that failed to pass*/
$failures = [];
$test_results = [];
foreach ($thingies as $description=>$test){
$startingAst = $test['ast']??null;
if ($startingAst==null
&&isset($test['ast.type'])
){
$startingAst = ['type'=>$test['ast.type']];
}
$startingDirectives=$test['start'];
if (!is_array($startingDirectives))$startingDirectives = [$startingDirectives];
$inputString=$test['input']??file_get_contents($test['file']);
// a sloppy way to add alternate expectations based upon 'previous'
$expect=$test['expect'] ?? $test['expect.previous'];
$compareTo = isset($test['expect']) ? 'tree' : 'previous';
$run = $this->options['run']??null;
if ($run===null||$run==$description
|| substr($run,-1)=='*'
&& substr($description, 0, (strlen($run) - 1) )
== substr($run,0,-1)
){
$this->test($description);
$lexer = new \Tlf\Lexer();
if (isset($this->options['stop_loop'])){
$lexer->stop_loop = $this->options['stop_loop'];
}
foreach ($grammars as $g){
$lexer->addGrammar($g, null, false);
}
$lexer->addGrammar($grammars[0], 'this', false);
if (isset($this->options['run']) && substr($run,-1)!='*')$lexer->debug = true;
$tree = $this->parse($lexer, $inputString, $startingDirectives, $startingAst);
if (($test['expect_failure']??false)===true){
$this->invert();
echo "\n # This grammar feature isn't implemented yet";
}
// more of the sloppy way to add alternate expectations
if ($compareTo=='tree'){
$succeeded = $this->compare($expect, $tree);
if (!$succeeded){
$failures[] = $description;
}
} else if ($compareTo=='previous'){
foreach ($expect as $key=>$target){
$previous = $lexer->previous($key);
if ($previous instanceof \Tlf\Lexer\Ast){
$tree = $previous->getTree();
} else $tree = $previous;
$succeeded = $this->compare($target, $tree);
if (!$succeeded){
$failures[] = $description;
}
// $this->compare(var_export($target,true), var_export($tree, true));
}
}
if (($test['expect_failure']??false)===true){
$this->invert();
}
if (($test['is_bad_test']??false)!==false){
echo " \033[4;31m"."# BAD SUBTEST"."\033[0m\n";
echo ' '.$test['is_bad_test'];
echo "\n";
// echo "\n\n---------badd test -------------\n\n";
}
$test_results[$description] = $succeeded;
} else {
$skipped[] = $description;
}
}
echo "\n\n";
$skipCount = count($skipped);
if ($skipCount>0){
echo "$skipCount sub tests were skipped: ". implode(", ", $skipped)."\n";
}
$failedCount = count($failures);
if ($failedCount>0){
echo "\n$failedCount sub tests failed: ". implode(", ", $failures)."\n";
}
echo "Specify `-run \"Test Description\"` to only run what you need";
return $test_results;
}
protected function parse(\Tlf\Lexer $lexer, string $toLex, array $startingDirectives, ?array $startingAst){
foreach ($startingDirectives as $name){
$parts = explode(':',$name);
$namespace = count($parts)===2 ? $parts[0] : 'this';
$grammar = $lexer->getGrammar($namespace);
foreach ($grammar->getDirectives(':'.$name) as $directive){
$lexer->addDirective($directive);
}
}
if ($startingAst!=null){
$startingAst = new \Tlf\Lexer\Ast($startingAst['type'], $startingAst);
}
$ast = $lexer->lex($toLex,$startingAst);
$tree = $ast->getTree();
unset($tree['type'], $tree['src']);
return $tree;
}
}