forked from hhvm/hhast
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLinterTestTrait.hack
More file actions
101 lines (90 loc) · 3 KB
/
LinterTestTrait.hack
File metadata and controls
101 lines (90 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
namespace Facebook\HHAST;
use type Facebook\HackTest\DataProvider;
use function Facebook\HHAST\TestLib\expect;
use namespace HH\Lib\{C, Str, Vec};
trait LinterTestTrait {
require extends TestCase;
abstract protected function getLinter(string $file): Linter;
abstract public function getCleanExamples(): vec<(string)>;
final public function getDirtyFixtures(): vec<(string)> {
return static::class
|> \explode('\\', $$)
|> C\lastx($$)
|> Str\strip_suffix($$, 'Test')
|> \glob(__DIR__.'/examples/'.$$.'/*.in')
|> Vec\map($$, $path ==> \basename($path, '.in'))
|> Vec\map($$, $path ==> Str\strip_suffix($path, '.php'))
|> Vec\map($$, $path ==> Str\strip_suffix($path, '.hack'))
|> Vec\map($$, $arg ==> tuple($arg));
}
final protected function getFullFixtureName(string $name): string {
$base = static::class
|> \explode('\\', $$)
|> C\lastx($$)
|> Str\strip_suffix($$, 'Test')
|> $$.'/'.$name;
if (\file_exists(__DIR__.'/examples/'.$base.'.php.in')) {
return $base.'.php';
}
return $base.'.hack';
}
<<DataProvider('getCleanExamples')>>
final public async function testCleanExample(string $code): Awaitable<void> {
$file = \sys_get_temp_dir().'/hhast-tmp-'.\bin2hex(\random_bytes(16));
if (
Str\starts_with($code, '<?') ||
Str\starts_with(Str\split($code, "\n")[1] ?? '', '<?') // #! lines
) {
$file .= '.php';
} else {
$file .= '.hack';
}
\file_put_contents($file, $code);
try {
$linter = $this->getLinter($file);
$errors = await $linter->getLintErrorsAsync();
if (C\is_empty($errors)) {
return;
}
Vec\map(
$errors,
$error ==> Str\format(
"- %s: %s at line %d:\n%s",
$error->getLintRule()->getName(),
$error->getDescription(),
$error->getRange()[0][1] ?? -1,
$error->getPrettyBlame() ?? '',
),
)
|> Str\join($$, "\n")
|> self::fail("Expected no errors, got:\n".$$);
} finally {
\unlink($file);
}
}
<<DataProvider('getDirtyFixtures')>>
final public function testDirtyFixtures(string $example): void {
$example = $this->getFullFixtureName($example);
$linter = $this->getLinter(__DIR__.'/examples/'.$example.'.in');
/*HHAST_FIXME[DontUseAsioJoin]*/
$out = \HH\Asio\join($linter->getLintErrorsAsync())
|> Vec\map($$, $error ==> self::getErrorAsShape($error))
|> \json_encode($$, \JSON_PRETTY_PRINT)."\n";
expect($out)->toMatchExpectFile($example.'.expect');
}
final protected static function getErrorAsShape(LintError $e): shape(...) {
return shape(
'blame' => $e->getBlameCode(),
'blame_pretty' => $e->getPrettyBlame(),
'description' => $e->getDescription(),
);
}
}