Page MenuHomePhabricator

D8025.diff
No OneTemporary

D8025.diff

Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -69,6 +69,7 @@
'LinesOfALargeFile' => 'filesystem/linesofalarge/LinesOfALargeFile.php',
'LinesOfALargeFileTestCase' => 'filesystem/linesofalarge/__tests__/LinesOfALargeFileTestCase.php',
'MFilterTestHelper' => 'utils/__tests__/MFilterTestHelper.php',
+ 'PHPASTParserTestCase' => 'parser/xhpast/__tests__/PHPASTParserTestCase.php',
'PhageAgentBootloader' => 'phage/bootloader/PhageAgentBootloader.php',
'PhageAgentTestCase' => 'phage/__tests__/PhageAgentTestCase.php',
'PhagePHPAgent' => 'phage/agent/PhagePHPAgent.php',
@@ -476,6 +477,7 @@
'LinesOfALargeExecFutureTestCase' => 'PhutilTestCase',
'LinesOfALargeFile' => 'LinesOfALarge',
'LinesOfALargeFileTestCase' => 'PhutilTestCase',
+ 'PHPASTParserTestCase' => 'PhutilTestCase',
'PhageAgentTestCase' => 'PhutilTestCase',
'PhagePHPAgentBootloader' => 'PhageAgentBootloader',
'PhutilAWSEC2Future' => 'PhutilAWSFuture',
Index: src/parser/xhpast/__tests__/PHPASTParserTestCase.php
===================================================================
--- /dev/null
+++ src/parser/xhpast/__tests__/PHPASTParserTestCase.php
@@ -0,0 +1,131 @@
+<?php
+
+final class PHPASTParserTestCase extends PhutilTestCase {
+
+ public function testParser() {
+ if (!xhpast_is_available()) {
+ $this->assertSkipped(pht('xhpast is not built or not up to date.'));
+ }
+
+ $dir = dirname(__FILE__).'/data/';
+ foreach (Filesystem::listDirectory($dir) as $file) {
+ if (preg_match('/\.test$/', $file)) {
+ $this->executeParserTest($file, Filesystem::readFile($dir.$file));
+ }
+ }
+ }
+
+ private function executeParserTest($name, $data) {
+ $data = explode("\n", $data, 2);
+ if (count($data) !== 2) {
+ throw new Exception(
+ pht('Expected multiple lines in parser test file "%s".', $name));
+ }
+
+ $head = head($data);
+ $body = last($data);
+
+ if (!preg_match('/^#/', $head)) {
+ throw new Exception(
+ pht(
+ 'Expected first line of parser test file "%s" to begin with "#" '.
+ 'and specify test options.',
+ $name));
+ }
+
+ $head = preg_replace('/^#\s*/', '', $head);
+
+ $options_parser = new PhutilSimpleOptions();
+ $options = $options_parser->parse($head);
+
+ $type = null;
+ foreach ($options as $key => $value) {
+ switch ($key) {
+ case 'pass':
+ case 'fail-syntax':
+ case 'fail-parse':
+ if ($type !== null) {
+ throw new Exception(
+ pht(
+ 'Test file "%s" unexpectedly specifies multiple expected ',
+ 'test outcomes.',
+ $name));
+ }
+ $type = $key;
+ break;
+ default:
+ throw new Exception(
+ pht(
+ 'Test file "%s" has unknown option "%s" in its options '.
+ 'string.',
+ $name,
+ $key));
+ }
+ }
+
+ if ($type === null) {
+ throw new Exception(
+ pht(
+ 'Test file "%s" does not specify a test result (like "pass") in '.
+ 'its options string.',
+ $name));
+ }
+
+ $future = xhpast_get_parser_future($body);
+ list($err, $stdout, $stderr) = $future->resolve();
+
+ switch ($type) {
+ case 'pass':
+ case 'fail-parse':
+ $this->assertEqual(0, $err, pht('Exit code for "%s".', $name));
+
+ $expect_name = preg_replace('/\.test$/', '.expect', $name);
+
+ $dir = dirname(__FILE__).'/data/';
+ $expect = Filesystem::readFile($dir.$expect_name);
+
+ $expect = json_decode($expect, true);
+ if (!is_array($expect)) {
+ throw new Exception(
+ pht(
+ 'Test ".expect" file "%s" for test "%s" is not valid JSON.',
+ $expect_name,
+ $name));
+ }
+
+ $stdout = json_decode($stdout, true);
+ if (!is_array($stdout)) {
+ throw new Exception(
+ pht(
+ 'Output for test file "%s" is not valid JSON.',
+ $name));
+ }
+
+ $json = new PhutilJSON();
+
+ $expect_nice = $json->encodeFormatted($expect);
+ $stdout_nice = $json->encodeFormatted($stdout);
+
+ if ($type == 'pass') {
+ $this->assertEqual(
+ $expect_nice,
+ $stdout_nice,
+ pht('Parser output for "%s".', $name));
+ } else {
+ $this->assertEqual(
+ false,
+ ($expect_nice == $stdout_nice),
+ pht('Expected parser to parse "%s" incorrectly.', $name));
+ }
+ break;
+ case 'fail-syntax':
+ $this->assertEqual(1, $err, pht('Exit code for "%s".', $name));
+ $this->assertEqual(
+ true,
+ (bool)preg_match('/syntax error/', $stderr),
+ pht('Expect "syntax error" in stderr or "%s".', $name));
+ break;
+ }
+ }
+
+}
Index: src/parser/xhpast/__tests__/data/base-fail-parse.php.expect
===================================================================
--- /dev/null
+++ src/parser/xhpast/__tests__/data/base-fail-parse.php.expect
@@ -0,0 +1,4 @@
+{
+ "tree" : [],
+ "stream" : []
+}
Index: src/parser/xhpast/__tests__/data/base-fail-parse.php.test
===================================================================
--- /dev/null
+++ src/parser/xhpast/__tests__/data/base-fail-parse.php.test
@@ -0,0 +1,2 @@
+# fail-parse
+<?php
Index: src/parser/xhpast/__tests__/data/base-fail-syntax.php.test
===================================================================
--- /dev/null
+++ src/parser/xhpast/__tests__/data/base-fail-syntax.php.test
@@ -0,0 +1,2 @@
+# fail-syntax
+<?php )
Index: src/parser/xhpast/__tests__/data/base-pass.php.expect
===================================================================
--- /dev/null
+++ src/parser/xhpast/__tests__/data/base-pass.php.expect
@@ -0,0 +1,27 @@
+{
+ "tree" : [
+ 9000,
+ 0,
+ 0,
+ [
+ [
+ 9006,
+ 0,
+ 0,
+ [
+ [
+ 9007,
+ 0,
+ 0
+ ]
+ ]
+ ]
+ ]
+ ],
+ "stream" : [
+ [
+ 371,
+ 6
+ ]
+ ]
+}
Index: src/parser/xhpast/__tests__/data/base-pass.php.test
===================================================================
--- /dev/null
+++ src/parser/xhpast/__tests__/data/base-pass.php.test
@@ -0,0 +1,2 @@
+# pass
+<?php

File Metadata

Mime Type
text/plain
Expires
Sun, Sep 14, 8:13 AM (2 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
8453368
Default Alt Text
D8025.diff (6 KB)

Event Timeline