Page Menu
Home
Sealhub
Search
Configure Global Search
Log In
Files
F9583257
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
40 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index fdb205d5..5b597ce1 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1,322 +1,325 @@
<?php
/**
* This file is automatically generated. Use 'arc liberate' to rebuild it.
* @generated
* @phutil-library-version 2
*/
phutil_register_library_map(array(
'__library_version__' => 2,
'class' =>
array(
'ArcanistAliasWorkflow' => 'workflow/ArcanistAliasWorkflow.php',
'ArcanistAmendWorkflow' => 'workflow/ArcanistAmendWorkflow.php',
'ArcanistAnoidWorkflow' => 'workflow/ArcanistAnoidWorkflow.php',
'ArcanistApacheLicenseLinter' => 'lint/linter/ArcanistApacheLicenseLinter.php',
'ArcanistArcanistLinterTestCase' => 'lint/linter/__tests__/ArcanistArcanistLinterTestCase.php',
'ArcanistBackoutWorkflow' => 'workflow/ArcanistBackoutWorkflow.php',
'ArcanistBaseCommitParser' => 'parser/ArcanistBaseCommitParser.php',
'ArcanistBaseCommitParserTestCase' => 'parser/__tests__/ArcanistBaseCommitParserTestCase.php',
'ArcanistBaseTestResultParser' => 'unit/engine/ArcanistBaseTestResultParser.php',
'ArcanistBaseUnitTestEngine' => 'unit/engine/ArcanistBaseUnitTestEngine.php',
'ArcanistBaseWorkflow' => 'workflow/ArcanistBaseWorkflow.php',
'ArcanistBaseXHPASTLinter' => 'lint/linter/ArcanistBaseXHPASTLinter.php',
'ArcanistBookmarkWorkflow' => 'workflow/ArcanistBookmarkWorkflow.php',
'ArcanistBranchWorkflow' => 'workflow/ArcanistBranchWorkflow.php',
'ArcanistBritishTestCase' => 'configuration/__tests__/ArcanistBritishTestCase.php',
'ArcanistBrowseWorkflow' => 'workflow/ArcanistBrowseWorkflow.php',
'ArcanistBundle' => 'parser/ArcanistBundle.php',
'ArcanistBundleTestCase' => 'parser/__tests__/ArcanistBundleTestCase.php',
'ArcanistCSSLintLinter' => 'lint/linter/ArcanistCSSLintLinter.php',
'ArcanistCSSLintLinterTestCase' => 'lint/linter/__tests__/ArcanistCSSLintLinterTestCase.php',
'ArcanistCallConduitWorkflow' => 'workflow/ArcanistCallConduitWorkflow.php',
'ArcanistCapabilityNotSupportedException' => 'workflow/exception/ArcanistCapabilityNotSupportedException.php',
'ArcanistChooseInvalidRevisionException' => 'exception/ArcanistChooseInvalidRevisionException.php',
'ArcanistChooseNoRevisionsException' => 'exception/ArcanistChooseNoRevisionsException.php',
'ArcanistCloseRevisionWorkflow' => 'workflow/ArcanistCloseRevisionWorkflow.php',
'ArcanistCloseWorkflow' => 'workflow/ArcanistCloseWorkflow.php',
'ArcanistCommentRemover' => 'parser/ArcanistCommentRemover.php',
'ArcanistCommentRemoverTestCase' => 'parser/__tests__/ArcanistCommentRemoverTestCase.php',
'ArcanistCommitWorkflow' => 'workflow/ArcanistCommitWorkflow.php',
'ArcanistConduitLinter' => 'lint/linter/ArcanistConduitLinter.php',
'ArcanistConfiguration' => 'configuration/ArcanistConfiguration.php',
'ArcanistConfigurationDrivenLintEngine' => 'lint/engine/ArcanistConfigurationDrivenLintEngine.php',
'ArcanistCoverWorkflow' => 'workflow/ArcanistCoverWorkflow.php',
'ArcanistCppcheckLinter' => 'lint/linter/ArcanistCppcheckLinter.php',
'ArcanistCpplintLinter' => 'lint/linter/ArcanistCpplintLinter.php',
'ArcanistCpplintLinterTestCase' => 'lint/linter/__tests__/ArcanistCpplintLinterTestCase.php',
'ArcanistDiffChange' => 'parser/diff/ArcanistDiffChange.php',
'ArcanistDiffChangeType' => 'parser/diff/ArcanistDiffChangeType.php',
'ArcanistDiffHunk' => 'parser/diff/ArcanistDiffHunk.php',
'ArcanistDiffParser' => 'parser/ArcanistDiffParser.php',
'ArcanistDiffParserTestCase' => 'parser/__tests__/ArcanistDiffParserTestCase.php',
'ArcanistDiffUtils' => 'difference/ArcanistDiffUtils.php',
'ArcanistDiffUtilsTestCase' => 'difference/__tests__/ArcanistDiffUtilsTestCase.php',
'ArcanistDiffWorkflow' => 'workflow/ArcanistDiffWorkflow.php',
'ArcanistDifferentialCommitMessage' => 'differential/ArcanistDifferentialCommitMessage.php',
'ArcanistDifferentialCommitMessageParserException' => 'differential/ArcanistDifferentialCommitMessageParserException.php',
'ArcanistDifferentialRevisionHash' => 'differential/constants/ArcanistDifferentialRevisionHash.php',
'ArcanistDifferentialRevisionStatus' => 'differential/constants/ArcanistDifferentialRevisionStatus.php',
'ArcanistDownloadWorkflow' => 'workflow/ArcanistDownloadWorkflow.php',
'ArcanistEventType' => 'events/constant/ArcanistEventType.php',
'ArcanistExportWorkflow' => 'workflow/ArcanistExportWorkflow.php',
'ArcanistExternalLinter' => 'lint/linter/ArcanistExternalLinter.php',
'ArcanistFeatureWorkflow' => 'workflow/ArcanistFeatureWorkflow.php',
'ArcanistFilenameLinter' => 'lint/linter/ArcanistFilenameLinter.php',
'ArcanistFlagWorkflow' => 'workflow/ArcanistFlagWorkflow.php',
'ArcanistFlake8Linter' => 'lint/linter/ArcanistFlake8Linter.php',
'ArcanistFlake8LinterTestCase' => 'lint/linter/__tests__/ArcanistFlake8LinterTestCase.php',
'ArcanistFutureLinter' => 'lint/linter/ArcanistFutureLinter.php',
'ArcanistGeneratedLinter' => 'lint/linter/ArcanistGeneratedLinter.php',
'ArcanistGetConfigWorkflow' => 'workflow/ArcanistGetConfigWorkflow.php',
'ArcanistGitAPI' => 'repository/api/ArcanistGitAPI.php',
'ArcanistGitHookPreReceiveWorkflow' => 'workflow/ArcanistGitHookPreReceiveWorkflow.php',
'ArcanistHelpWorkflow' => 'workflow/ArcanistHelpWorkflow.php',
'ArcanistHgClientChannel' => 'hgdaemon/ArcanistHgClientChannel.php',
'ArcanistHgProxyClient' => 'hgdaemon/ArcanistHgProxyClient.php',
'ArcanistHgProxyServer' => 'hgdaemon/ArcanistHgProxyServer.php',
'ArcanistHgServerChannel' => 'hgdaemon/ArcanistHgServerChannel.php',
'ArcanistHookAPI' => 'repository/hookapi/ArcanistHookAPI.php',
'ArcanistInlinesWorkflow' => 'workflow/ArcanistInlinesWorkflow.php',
'ArcanistInstallCertificateWorkflow' => 'workflow/ArcanistInstallCertificateWorkflow.php',
'ArcanistJSHintLinter' => 'lint/linter/ArcanistJSHintLinter.php',
'ArcanistLandWorkflow' => 'workflow/ArcanistLandWorkflow.php',
'ArcanistLiberateWorkflow' => 'workflow/ArcanistLiberateWorkflow.php',
'ArcanistLicenseLinter' => 'lint/linter/ArcanistLicenseLinter.php',
'ArcanistLintConsoleRenderer' => 'lint/renderer/ArcanistLintConsoleRenderer.php',
'ArcanistLintEngine' => 'lint/engine/ArcanistLintEngine.php',
'ArcanistLintJSONRenderer' => 'lint/renderer/ArcanistLintJSONRenderer.php',
'ArcanistLintLikeCompilerRenderer' => 'lint/renderer/ArcanistLintLikeCompilerRenderer.php',
'ArcanistLintMessage' => 'lint/ArcanistLintMessage.php',
'ArcanistLintNoneRenderer' => 'lint/renderer/ArcanistLintNoneRenderer.php',
'ArcanistLintPatcher' => 'lint/ArcanistLintPatcher.php',
'ArcanistLintRenderer' => 'lint/renderer/ArcanistLintRenderer.php',
'ArcanistLintResult' => 'lint/ArcanistLintResult.php',
'ArcanistLintSeverity' => 'lint/ArcanistLintSeverity.php',
'ArcanistLintSummaryRenderer' => 'lint/renderer/ArcanistLintSummaryRenderer.php',
'ArcanistLintWorkflow' => 'workflow/ArcanistLintWorkflow.php',
'ArcanistLinter' => 'lint/linter/ArcanistLinter.php',
'ArcanistLinterTestCase' => 'lint/linter/__tests__/ArcanistLinterTestCase.php',
'ArcanistListWorkflow' => 'workflow/ArcanistListWorkflow.php',
'ArcanistMarkCommittedWorkflow' => 'workflow/ArcanistMarkCommittedWorkflow.php',
'ArcanistMercurialAPI' => 'repository/api/ArcanistMercurialAPI.php',
'ArcanistMercurialParser' => 'repository/parser/ArcanistMercurialParser.php',
'ArcanistMercurialParserTestCase' => 'repository/parser/__tests__/ArcanistMercurialParserTestCase.php',
'ArcanistMergeConflictLinter' => 'lint/linter/ArcanistMergeConflictLinter.php',
'ArcanistNoEffectException' => 'exception/usage/ArcanistNoEffectException.php',
'ArcanistNoEngineException' => 'exception/usage/ArcanistNoEngineException.php',
'ArcanistNoLintLinter' => 'lint/linter/ArcanistNoLintLinter.php',
'ArcanistNoLintTestCaseMisnamed' => 'lint/linter/__tests__/ArcanistNoLintTestCase.php',
'ArcanistPEP8Linter' => 'lint/linter/ArcanistPEP8Linter.php',
'ArcanistPEP8LinterTestCase' => 'lint/linter/__tests__/ArcanistPEP8LinterTestCase.php',
'ArcanistPHPCSLinterTestCase' => 'lint/linter/__tests__/ArcanistPHPCSLinterTestCase.php',
'ArcanistPasteWorkflow' => 'workflow/ArcanistPasteWorkflow.php',
'ArcanistPatchWorkflow' => 'workflow/ArcanistPatchWorkflow.php',
'ArcanistPhpcsLinter' => 'lint/linter/ArcanistPhpcsLinter.php',
'ArcanistPhutilLibraryLinter' => 'lint/linter/ArcanistPhutilLibraryLinter.php',
'ArcanistPhutilTestCase' => 'unit/engine/phutil/ArcanistPhutilTestCase.php',
'ArcanistPhutilTestCaseTestCase' => 'unit/engine/phutil/testcase/ArcanistPhutilTestCaseTestCase.php',
'ArcanistPhutilTestSkippedException' => 'unit/engine/phutil/testcase/ArcanistPhutilTestSkippedException.php',
'ArcanistPhutilTestTerminatedException' => 'unit/engine/phutil/testcase/ArcanistPhutilTestTerminatedException.php',
'ArcanistPhutilXHPASTLinter' => 'lint/linter/ArcanistPhutilXHPASTLinter.php',
'ArcanistPhutilXHPASTLinterTestCase' => 'lint/linter/__tests__/ArcanistPhutilXHPASTLinterTestCase.php',
'ArcanistPyFlakesLinter' => 'lint/linter/ArcanistPyFlakesLinter.php',
'ArcanistPyLintLinter' => 'lint/linter/ArcanistPyLintLinter.php',
'ArcanistRepositoryAPI' => 'repository/api/ArcanistRepositoryAPI.php',
'ArcanistRepositoryAPIMiscTestCase' => 'repository/api/__tests__/ArcanistRepositoryAPIMiscTestCase.php',
'ArcanistRepositoryAPIStateTestCase' => 'repository/api/__tests__/ArcanistRepositoryAPIStateTestCase.php',
'ArcanistRevertWorkflow' => 'workflow/ArcanistRevertWorkflow.php',
'ArcanistRubyLinter' => 'lint/linter/ArcanistRubyLinter.php',
'ArcanistRubyLinterTestCase' => 'lint/linter/__tests__/ArcanistRubyLinterTestCase.php',
'ArcanistScalaSBTLinter' => 'lint/linter/ArcanistScalaSBTLinter.php',
'ArcanistScriptAndRegexLinter' => 'lint/linter/ArcanistScriptAndRegexLinter.php',
'ArcanistSetConfigWorkflow' => 'workflow/ArcanistSetConfigWorkflow.php',
'ArcanistSettings' => 'configuration/ArcanistSettings.php',
'ArcanistShellCompleteWorkflow' => 'workflow/ArcanistShellCompleteWorkflow.php',
'ArcanistSingleLintEngine' => 'lint/engine/ArcanistSingleLintEngine.php',
'ArcanistSpellingDefaultData' => 'lint/linter/spelling/ArcanistSpellingDefaultData.php',
'ArcanistSpellingLinter' => 'lint/linter/ArcanistSpellingLinter.php',
'ArcanistSpellingLinterTestCase' => 'lint/linter/__tests__/ArcanistSpellingLinterTestCase.php',
'ArcanistSubversionAPI' => 'repository/api/ArcanistSubversionAPI.php',
'ArcanistSubversionHookAPI' => 'repository/hookapi/ArcanistSubversionHookAPI.php',
'ArcanistSvnHookPreCommitWorkflow' => 'workflow/ArcanistSvnHookPreCommitWorkflow.php',
'ArcanistTasksWorkflow' => 'workflow/ArcanistTasksWorkflow.php',
'ArcanistTestCase' => 'infrastructure/testing/ArcanistTestCase.php',
'ArcanistTextLinter' => 'lint/linter/ArcanistTextLinter.php',
'ArcanistTextLinterTestCase' => 'lint/linter/__tests__/ArcanistTextLinterTestCase.php',
'ArcanistTodoWorkflow' => 'workflow/ArcanistTodoWorkflow.php',
'ArcanistUncommittedChangesException' => 'exception/usage/ArcanistUncommittedChangesException.php',
'ArcanistUnitConsoleRenderer' => 'unit/renderer/ArcanistUnitConsoleRenderer.php',
'ArcanistUnitRenderer' => 'unit/renderer/ArcanistUnitRenderer.php',
'ArcanistUnitTestResult' => 'unit/ArcanistUnitTestResult.php',
'ArcanistUnitWorkflow' => 'workflow/ArcanistUnitWorkflow.php',
'ArcanistUpgradeWorkflow' => 'workflow/ArcanistUpgradeWorkflow.php',
'ArcanistUploadWorkflow' => 'workflow/ArcanistUploadWorkflow.php',
'ArcanistUsageException' => 'exception/ArcanistUsageException.php',
'ArcanistUserAbortException' => 'exception/usage/ArcanistUserAbortException.php',
'ArcanistWhichWorkflow' => 'workflow/ArcanistWhichWorkflow.php',
'ArcanistWorkingCopyIdentity' => 'workingcopyidentity/ArcanistWorkingCopyIdentity.php',
'ArcanistXHPASTLintNamingHook' => 'lint/linter/xhpast/ArcanistXHPASTLintNamingHook.php',
'ArcanistXHPASTLintNamingHookTestCase' => 'lint/linter/xhpast/__tests__/ArcanistXHPASTLintNamingHookTestCase.php',
'ArcanistXHPASTLintSwitchHook' => 'lint/linter/xhpast/ArcanistXHPASTLintSwitchHook.php',
'ArcanistXHPASTLintTestSwitchHook' => 'lint/linter/__tests__/ArcanistXHPASTLintTestSwitchHook.php',
'ArcanistXHPASTLinter' => 'lint/linter/ArcanistXHPASTLinter.php',
'ArcanistXHPASTLinterTestCase' => 'lint/linter/__tests__/ArcanistXHPASTLinterTestCase.php',
+ 'ArcanistXUnitTestResultParser' => 'unit/engine/ArcanistXUnitTestResultParser.php',
'CSharpToolsTestEngine' => 'unit/engine/CSharpToolsTestEngine.php',
'ComprehensiveLintEngine' => 'lint/engine/ComprehensiveLintEngine.php',
'ExampleLintEngine' => 'lint/engine/ExampleLintEngine.php',
'GoTestResultParser' => 'unit/engine/GoTestResultParser.php',
'GoTestResultParserTestCase' => 'unit/engine/__tests__/GoTestResultParserTestCase.php',
'NoseTestEngine' => 'unit/engine/NoseTestEngine.php',
'PHPUnitTestEngineTestCase' => 'unit/engine/__tests__/PHPUnitTestEngineTestCase.php',
'PhpunitResultParser' => 'unit/engine/PhpunitResultParser.php',
'PhpunitTestEngine' => 'unit/engine/PhpunitTestEngine.php',
'PhutilLintEngine' => 'lint/engine/PhutilLintEngine.php',
'PhutilUnitTestEngine' => 'unit/engine/PhutilUnitTestEngine.php',
'PhutilUnitTestEngineTestCase' => 'unit/engine/__tests__/PhutilUnitTestEngineTestCase.php',
'PytestTestEngine' => 'unit/engine/PytestTestEngine.php',
'UnitTestableArcanistLintEngine' => 'lint/engine/UnitTestableArcanistLintEngine.php',
'XUnitTestEngine' => 'unit/engine/XUnitTestEngine.php',
+ 'XUnitTestResultParserTestCase' => 'unit/engine/__tests__/XUnitTestResultParserTestCase.php',
),
'function' =>
array(
),
'xmap' =>
array(
'ArcanistAliasWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistAmendWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistAnoidWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistApacheLicenseLinter' => 'ArcanistLicenseLinter',
'ArcanistArcanistLinterTestCase' => 'ArcanistLinterTestCase',
'ArcanistBackoutWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistBaseCommitParserTestCase' => 'ArcanistTestCase',
'ArcanistBaseWorkflow' => 'Phobject',
'ArcanistBaseXHPASTLinter' => 'ArcanistFutureLinter',
'ArcanistBookmarkWorkflow' => 'ArcanistFeatureWorkflow',
'ArcanistBranchWorkflow' => 'ArcanistFeatureWorkflow',
'ArcanistBritishTestCase' => 'ArcanistTestCase',
'ArcanistBrowseWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistBundleTestCase' => 'ArcanistTestCase',
'ArcanistCSSLintLinter' => 'ArcanistExternalLinter',
'ArcanistCSSLintLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistCallConduitWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistCapabilityNotSupportedException' => 'Exception',
'ArcanistChooseInvalidRevisionException' => 'Exception',
'ArcanistChooseNoRevisionsException' => 'Exception',
'ArcanistCloseRevisionWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistCloseWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistCommentRemoverTestCase' => 'ArcanistTestCase',
'ArcanistCommitWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistConduitLinter' => 'ArcanistLinter',
'ArcanistConfigurationDrivenLintEngine' => 'ArcanistLintEngine',
'ArcanistCoverWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistCppcheckLinter' => 'ArcanistLinter',
'ArcanistCpplintLinter' => 'ArcanistLinter',
'ArcanistCpplintLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistDiffParserTestCase' => 'ArcanistTestCase',
'ArcanistDiffUtilsTestCase' => 'ArcanistTestCase',
'ArcanistDiffWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistDifferentialCommitMessageParserException' => 'Exception',
'ArcanistDownloadWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistEventType' => 'PhutilEventType',
'ArcanistExportWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistExternalLinter' => 'ArcanistFutureLinter',
'ArcanistFeatureWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistFilenameLinter' => 'ArcanistLinter',
'ArcanistFlagWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistFlake8Linter' => 'ArcanistExternalLinter',
'ArcanistFlake8LinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistFutureLinter' => 'ArcanistLinter',
'ArcanistGeneratedLinter' => 'ArcanistLinter',
'ArcanistGetConfigWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistGitAPI' => 'ArcanistRepositoryAPI',
'ArcanistGitHookPreReceiveWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistHelpWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistHgClientChannel' => 'PhutilProtocolChannel',
'ArcanistHgServerChannel' => 'PhutilProtocolChannel',
'ArcanistInlinesWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistInstallCertificateWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistJSHintLinter' => 'ArcanistLinter',
'ArcanistLandWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistLiberateWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistLicenseLinter' => 'ArcanistLinter',
'ArcanistLintConsoleRenderer' => 'ArcanistLintRenderer',
'ArcanistLintJSONRenderer' => 'ArcanistLintRenderer',
'ArcanistLintLikeCompilerRenderer' => 'ArcanistLintRenderer',
'ArcanistLintNoneRenderer' => 'ArcanistLintRenderer',
'ArcanistLintSummaryRenderer' => 'ArcanistLintRenderer',
'ArcanistLintWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistLinterTestCase' => 'ArcanistPhutilTestCase',
'ArcanistListWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistMarkCommittedWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistMercurialAPI' => 'ArcanistRepositoryAPI',
'ArcanistMercurialParserTestCase' => 'ArcanistTestCase',
'ArcanistMergeConflictLinter' => 'ArcanistLinter',
'ArcanistNoEffectException' => 'ArcanistUsageException',
'ArcanistNoEngineException' => 'ArcanistUsageException',
'ArcanistNoLintLinter' => 'ArcanistLinter',
'ArcanistNoLintTestCaseMisnamed' => 'ArcanistLinterTestCase',
'ArcanistPEP8Linter' => 'ArcanistExternalLinter',
'ArcanistPEP8LinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistPHPCSLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistPasteWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistPatchWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistPhpcsLinter' => 'ArcanistExternalLinter',
'ArcanistPhutilLibraryLinter' => 'ArcanistLinter',
'ArcanistPhutilTestCaseTestCase' => 'ArcanistPhutilTestCase',
'ArcanistPhutilTestSkippedException' => 'Exception',
'ArcanistPhutilTestTerminatedException' => 'Exception',
'ArcanistPhutilXHPASTLinter' => 'ArcanistBaseXHPASTLinter',
'ArcanistPhutilXHPASTLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistPyFlakesLinter' => 'ArcanistLinter',
'ArcanistPyLintLinter' => 'ArcanistLinter',
'ArcanistRepositoryAPIMiscTestCase' => 'ArcanistTestCase',
'ArcanistRepositoryAPIStateTestCase' => 'ArcanistTestCase',
'ArcanistRevertWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistRubyLinter' => 'ArcanistExternalLinter',
'ArcanistRubyLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistScalaSBTLinter' => 'ArcanistLinter',
'ArcanistScriptAndRegexLinter' => 'ArcanistLinter',
'ArcanistSetConfigWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistShellCompleteWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistSingleLintEngine' => 'ArcanistLintEngine',
'ArcanistSpellingLinter' => 'ArcanistLinter',
'ArcanistSpellingLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistSubversionAPI' => 'ArcanistRepositoryAPI',
'ArcanistSubversionHookAPI' => 'ArcanistHookAPI',
'ArcanistSvnHookPreCommitWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistTasksWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistTestCase' => 'ArcanistPhutilTestCase',
'ArcanistTextLinter' => 'ArcanistLinter',
'ArcanistTextLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistTodoWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistUncommittedChangesException' => 'ArcanistUsageException',
'ArcanistUnitConsoleRenderer' => 'ArcanistUnitRenderer',
'ArcanistUnitWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistUpgradeWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistUploadWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistUsageException' => 'Exception',
'ArcanistUserAbortException' => 'ArcanistUsageException',
'ArcanistWhichWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistXHPASTLintNamingHookTestCase' => 'ArcanistTestCase',
'ArcanistXHPASTLintTestSwitchHook' => 'ArcanistXHPASTLintSwitchHook',
'ArcanistXHPASTLinter' => 'ArcanistBaseXHPASTLinter',
'ArcanistXHPASTLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'CSharpToolsTestEngine' => 'XUnitTestEngine',
'ComprehensiveLintEngine' => 'ArcanistLintEngine',
'ExampleLintEngine' => 'ArcanistLintEngine',
'GoTestResultParser' => 'ArcanistBaseTestResultParser',
'GoTestResultParserTestCase' => 'ArcanistTestCase',
'NoseTestEngine' => 'ArcanistBaseUnitTestEngine',
'PHPUnitTestEngineTestCase' => 'ArcanistTestCase',
'PhpunitResultParser' => 'ArcanistBaseTestResultParser',
'PhpunitTestEngine' => 'ArcanistBaseUnitTestEngine',
'PhutilLintEngine' => 'ArcanistLintEngine',
'PhutilUnitTestEngine' => 'ArcanistBaseUnitTestEngine',
'PhutilUnitTestEngineTestCase' => 'ArcanistTestCase',
'PytestTestEngine' => 'ArcanistBaseUnitTestEngine',
'UnitTestableArcanistLintEngine' => 'ArcanistLintEngine',
'XUnitTestEngine' => 'ArcanistBaseUnitTestEngine',
+ 'XUnitTestResultParserTestCase' => 'ArcanistTestCase',
),
));
diff --git a/src/unit/engine/PytestTestEngine.php b/src/unit/engine/ArcanistXUnitTestResultParser.php
similarity index 73%
copy from src/unit/engine/PytestTestEngine.php
copy to src/unit/engine/ArcanistXUnitTestResultParser.php
index 37a43b72..a3fdacf8 100644
--- a/src/unit/engine/PytestTestEngine.php
+++ b/src/unit/engine/ArcanistXUnitTestResultParser.php
@@ -1,89 +1,97 @@
<?php
/**
- * Very basic 'py.test' unit test engine wrapper.
+ * Parser for JUnit, NUnit, etc results format - https://gist.github.com/959290
*
* @group unitrun
*/
-final class PytestTestEngine extends ArcanistBaseUnitTestEngine {
-
- public function run() {
- $junit_tmp = new TempFile();
-
- $cmd_line = csprintf('py.test --junitxml=%s',
- $junit_tmp);
-
- $future = new ExecFuture('%C', $cmd_line);
- list($stdout, $stderr) = $future->resolvex();
-
- return $this->parseTestResults($junit_tmp);
- }
+final class ArcanistXUnitTestResultParser {
+
+ /**
+ * Parse test results from provided input and return an array
+ * of ArcanistUnitTestResult
+ *
+ * @param string $path Path to test (Ignored)
+ * @param string $test_results String containing test results
+ *
+ * @return array ArcanistUnitTestResult
+ */
+ public function parseTestResults($test_results) {
+ if (!strlen($test_results)) {
+ throw new Exception(
+ 'test_results argument to parseTestResults must not be empty');
+ }
- public function parseTestResults($junit_tmp) {
// xunit xsd: https://gist.github.com/959290
$xunit_dom = new DOMDocument();
- $xunit_dom->loadXML(Filesystem::readFile($junit_tmp));
+ $load_success = @$xunit_dom->loadXML($test_results);
+
+ if (!$load_success) {
+ $input_start = phutil_utf8_shorten($test_results, 150);
+ throw new Exception(
+ "Failed to load XUnit report; Input starts with:\n\n {$input_start}");
+ }
$results = array();
$testcases = $xunit_dom->getElementsByTagName("testcase");
foreach ($testcases as $testcase) {
$classname = $testcase->getAttribute("classname");
$name = $testcase->getAttribute("name");
$time = $testcase->getAttribute("time");
$status = ArcanistUnitTestResult::RESULT_PASS;
$user_data = "";
// A skipped test is a test which was ignored using framework
// mechanizms (e.g. @skip decorator)
$skipped = $testcase->getElementsByTagName("skipped");
if ($skipped->length > 0) {
$status = ArcanistUnitTestResult::RESULT_SKIP;
$messages = array();
for ($ii = 0; $ii < $skipped->length; $ii++) {
$messages[] = trim($skipped->item($ii)->nodeValue, " \n");
}
$user_data .= implode("\n", $messages);
}
// Failure is a test which the code has explicitly failed by using
// the mechanizms for that purpose. e.g., via an assertEquals
$failures = $testcase->getElementsByTagName("failure");
if ($failures->length > 0) {
$status = ArcanistUnitTestResult::RESULT_FAIL;
$messages = array();
for ($ii = 0; $ii < $failures->length; $ii++) {
$messages[] = trim($failures->item($ii)->nodeValue, " \n");
}
$user_data .= implode("\n", $messages)."\n";
}
// An errored test is one that had an unanticipated problem. e.g., an
// unchecked throwable, or a problem with an implementation of the
// test.
$errors = $testcase->getElementsByTagName("error");
if ($errors->length > 0) {
$status = ArcanistUnitTestResult::RESULT_BROKEN;
$messages = array();
for ($ii = 0; $ii < $errors->length; $ii++) {
$messages[] = trim($errors->item($ii)->nodeValue, " \n");
}
$user_data .= implode("\n", $messages)."\n";
}
$result = new ArcanistUnitTestResult();
$result->setName($classname.".".$name);
$result->setResult($status);
$result->setDuration($time);
$result->setUserData($user_data);
$results[] = $result;
}
return $results;
}
}
diff --git a/src/unit/engine/NoseTestEngine.php b/src/unit/engine/NoseTestEngine.php
index 49f03994..00296a08 100644
--- a/src/unit/engine/NoseTestEngine.php
+++ b/src/unit/engine/NoseTestEngine.php
@@ -1,244 +1,186 @@
<?php
/**
* Very basic 'nose' unit test engine wrapper.
*
* Requires nose 1.1.3 for code coverage.
*
* @group unitrun
*/
final class NoseTestEngine extends ArcanistBaseUnitTestEngine {
public function run() {
$paths = $this->getPaths();
$affected_tests = array();
foreach ($paths as $path) {
$absolute_path = Filesystem::resolvePath($path);
if (is_dir($absolute_path)) {
$absolute_test_path = Filesystem::resolvePath("tests/".$path);
if (is_readable($absolute_test_path)) {
$affected_tests[] = $absolute_test_path;
}
}
if (is_readable($absolute_path)) {
$filename = basename($path);
$directory = dirname($path);
// assumes directory layout: tests/<package>/test_<module>.py
$relative_test_path = "tests/".$directory."/test_".$filename;
$absolute_test_path = Filesystem::resolvePath($relative_test_path);
if (is_readable($absolute_test_path)) {
$affected_tests[] = $absolute_test_path;
}
}
}
return $this->runTests($affected_tests, './');
}
public function runTests($test_paths, $source_path) {
if (empty($test_paths)) {
return array();
}
$futures = array();
$tmpfiles = array();
foreach ($test_paths as $test_path) {
$xunit_tmp = new TempFile();
$cover_tmp = new TempFile();
$future = $this->buildTestFuture($test_path,
$xunit_tmp,
$cover_tmp);
$futures[$test_path] = $future;
$tmpfiles[$test_path] = array(
'xunit' => $xunit_tmp,
'cover' => $cover_tmp,
);
}
$results = array();
foreach (Futures($futures)->limit(4) as $test_path => $future) {
try {
list($stdout, $stderr) = $future->resolvex();
} catch(CommandException $exc) {
if ($exc->getError() > 1) {
// 'nose' returns 1 when tests are failing/broken.
throw $exc;
}
}
$xunit_tmp = $tmpfiles[$test_path]['xunit'];
$cover_tmp = $tmpfiles[$test_path]['cover'];
+ $this->parser = new ArcanistXUnitTestResultParser();
$results[] = $this->parseTestResults($source_path,
$xunit_tmp,
$cover_tmp);
}
return array_mergev($results);
}
public function buildTestFuture($path, $xunit_tmp, $cover_tmp) {
$cmd_line = csprintf("nosetests --with-xunit --xunit-file=%s",
$xunit_tmp);
if ($this->getEnableCoverage() !== false) {
$cmd_line .= csprintf(" --with-coverage --cover-xml " .
"--cover-xml-file=%s",
$cover_tmp);
}
return new ExecFuture("%C %s", $cmd_line, $path);
}
public function parseTestResults($source_path, $xunit_tmp, $cover_tmp) {
- // xunit xsd: https://gist.github.com/959290
- $xunit_dom = new DOMDocument();
- $xunit_dom->loadXML(Filesystem::readFile($xunit_tmp));
+ $results = $this->parser->parseTestResults(
+ Filesystem::readFile($xunit_tmp));
// coverage is for all testcases in the executed $path
- $coverage = array();
if ($this->getEnableCoverage() !== false) {
$coverage = $this->readCoverage($cover_tmp, $source_path);
- }
-
- $results = array();
- $testcases = $xunit_dom->getElementsByTagName("testcase");
- foreach ($testcases as $testcase) {
- $classname = $testcase->getAttribute("classname");
- $name = $testcase->getAttribute("name");
- $time = $testcase->getAttribute("time");
-
- $status = ArcanistUnitTestResult::RESULT_PASS;
- $user_data = "";
-
- // A skipped test is a test which was ignored using framework
- // mechanizms (e.g. @skip decorator)
- $skipped = $testcase->getElementsByTagName("skipped");
- if ($skipped->length > 0) {
- $status = ArcanistUnitTestResult::RESULT_SKIP;
- $messages = array();
- for ($ii = 0; $ii < $skipped->length; $ii++) {
- $messages[] = trim($skipped->item($ii)->nodeValue, " \n");
- }
-
- $user_data .= implode("\n", $messages);
+ foreach ($results as $result) {
+ $result->setCoverage($coverage);
}
-
- // Failure is a test which the code has explicitly failed by using
- // the mechanizms for that purpose. e.g., via an assertEquals
- $failures = $testcase->getElementsByTagName("failure");
- if ($failures->length > 0) {
- $status = ArcanistUnitTestResult::RESULT_FAIL;
- $messages = array();
- for ($ii = 0; $ii < $failures->length; $ii++) {
- $messages[] = trim($failures->item($ii)->nodeValue, " \n");
- }
-
- $user_data .= implode("\n", $messages)."\n";
- }
-
- // An errored test is one that had an unanticipated problem. e.g., an
- // unchecked throwable, or a problem with an implementation of the
- // test.
- $errors = $testcase->getElementsByTagName("error");
- if ($errors->length > 0) {
- $status = ArcanistUnitTestResult::RESULT_BROKEN;
- $messages = array();
- for ($ii = 0; $ii < $errors->length; $ii++) {
- $messages[] = trim($errors->item($ii)->nodeValue, " \n");
- }
-
- $user_data .= implode("\n", $messages)."\n";
- }
-
- $result = new ArcanistUnitTestResult();
- $result->setName($classname.".".$name);
- $result->setResult($status);
- $result->setDuration($time);
- $result->setCoverage($coverage);
- $result->setUserData($user_data);
-
- $results[] = $result;
}
return $results;
}
public function readCoverage($cover_file, $source_path) {
$coverage_dom = new DOMDocument();
$coverage_dom->loadXML(Filesystem::readFile($cover_file));
$reports = array();
$classes = $coverage_dom->getElementsByTagName("class");
foreach ($classes as $class) {
// filename is actually python module path with ".py" at the end,
// e.g.: tornado.web.py
$relative_path = explode(".", $class->getAttribute("filename"));
array_pop($relative_path);
$relative_path = $source_path .'/'. implode("/", $relative_path);
// first we check if the path is a directory (a Python package), if it is
// set relative and absolute paths to have __init__.py at the end.
$absolute_path = Filesystem::resolvePath($relative_path);
if (is_dir($absolute_path)) {
$relative_path .= "/__init__.py";
$absolute_path .= "/__init__.py";
}
// then we check if the path with ".py" at the end is file (a Python
// submodule), if it is - set relative and absolute paths to have
// ".py" at the end.
if (is_file($absolute_path.".py")) {
$relative_path .= ".py";
$absolute_path .= ".py";
}
if (!file_exists($absolute_path)) {
continue;
}
// get total line count in file
$line_count = count(file($absolute_path));
$coverage = "";
$start_line = 1;
$lines = $class->getElementsByTagName("line");
for ($ii = 0; $ii < $lines->length; $ii++) {
$line = $lines->item($ii);
$next_line = intval($line->getAttribute("number"));
for ($start_line; $start_line < $next_line; $start_line++) {
$coverage .= "N";
}
if (intval($line->getAttribute("hits")) == 0) {
$coverage .= "U";
} else if (intval($line->getAttribute("hits")) > 0) {
$coverage .= "C";
}
$start_line++;
}
if ($start_line < $line_count) {
foreach (range($start_line, $line_count) as $line_num) {
$coverage .= "N";
}
}
$reports[$relative_path] = $coverage;
}
return $reports;
}
}
diff --git a/src/unit/engine/PytestTestEngine.php b/src/unit/engine/PytestTestEngine.php
index 37a43b72..ca2da944 100644
--- a/src/unit/engine/PytestTestEngine.php
+++ b/src/unit/engine/PytestTestEngine.php
@@ -1,89 +1,23 @@
<?php
/**
* Very basic 'py.test' unit test engine wrapper.
*
* @group unitrun
*/
final class PytestTestEngine extends ArcanistBaseUnitTestEngine {
public function run() {
$junit_tmp = new TempFile();
$cmd_line = csprintf('py.test --junitxml=%s',
$junit_tmp);
-
$future = new ExecFuture('%C', $cmd_line);
list($stdout, $stderr) = $future->resolvex();
- return $this->parseTestResults($junit_tmp);
- }
-
- public function parseTestResults($junit_tmp) {
- // xunit xsd: https://gist.github.com/959290
- $xunit_dom = new DOMDocument();
- $xunit_dom->loadXML(Filesystem::readFile($junit_tmp));
-
- $results = array();
- $testcases = $xunit_dom->getElementsByTagName("testcase");
- foreach ($testcases as $testcase) {
- $classname = $testcase->getAttribute("classname");
- $name = $testcase->getAttribute("name");
- $time = $testcase->getAttribute("time");
-
- $status = ArcanistUnitTestResult::RESULT_PASS;
- $user_data = "";
-
- // A skipped test is a test which was ignored using framework
- // mechanizms (e.g. @skip decorator)
- $skipped = $testcase->getElementsByTagName("skipped");
- if ($skipped->length > 0) {
- $status = ArcanistUnitTestResult::RESULT_SKIP;
- $messages = array();
- for ($ii = 0; $ii < $skipped->length; $ii++) {
- $messages[] = trim($skipped->item($ii)->nodeValue, " \n");
- }
-
- $user_data .= implode("\n", $messages);
- }
-
- // Failure is a test which the code has explicitly failed by using
- // the mechanizms for that purpose. e.g., via an assertEquals
- $failures = $testcase->getElementsByTagName("failure");
- if ($failures->length > 0) {
- $status = ArcanistUnitTestResult::RESULT_FAIL;
- $messages = array();
- for ($ii = 0; $ii < $failures->length; $ii++) {
- $messages[] = trim($failures->item($ii)->nodeValue, " \n");
- }
-
- $user_data .= implode("\n", $messages)."\n";
- }
-
- // An errored test is one that had an unanticipated problem. e.g., an
- // unchecked throwable, or a problem with an implementation of the
- // test.
- $errors = $testcase->getElementsByTagName("error");
- if ($errors->length > 0) {
- $status = ArcanistUnitTestResult::RESULT_BROKEN;
- $messages = array();
- for ($ii = 0; $ii < $errors->length; $ii++) {
- $messages[] = trim($errors->item($ii)->nodeValue, " \n");
- }
-
- $user_data .= implode("\n", $messages)."\n";
- }
-
- $result = new ArcanistUnitTestResult();
- $result->setName($classname.".".$name);
- $result->setResult($status);
- $result->setDuration($time);
- $result->setUserData($user_data);
-
- $results[] = $result;
- }
+ $parser = new ArcanistXUnitTestResultParser();
- return $results;
+ return $parser->parseTestResults(Filesystem::readFile($junit_tmp));
}
}
diff --git a/src/unit/engine/__tests__/XUnitTestResultParserTestCase.php b/src/unit/engine/__tests__/XUnitTestResultParserTestCase.php
new file mode 100755
index 00000000..e752cfbe
--- /dev/null
+++ b/src/unit/engine/__tests__/XUnitTestResultParserTestCase.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * Test for @{class:ArcanistXUnitTestResultParser}.
+ *
+ * (putting tests in your tests so you can test
+ * while you test)
+ *
+ * @group testcase
+ */
+final class XUnitTestResultParserTestCase extends ArcanistTestCase {
+
+ public function testAcceptsNoTestsInput() {
+ $stubbed_results = Filesystem::readFile(
+ dirname(__FILE__).'/testresults/xunit.no-tests');
+ $parsed_results = id(new ArcanistXUnitTestResultParser())
+ ->parseTestResults($stubbed_results);
+
+ $this->assertEqual(0, count($parsed_results));
+ }
+
+ public function testAcceptsSimpleInput() {
+ $stubbed_results = Filesystem::readFile(
+ dirname(__FILE__).'/testresults/xunit.simple');
+ $parsed_results = id(new ArcanistXUnitTestResultParser())
+ ->parseTestResults($stubbed_results);
+
+ $this->assertEqual(3, count($parsed_results));
+ }
+
+ public function testEmptyInputFailure() {
+ try {
+ $parsed_results = id(new ArcanistXUnitTestResultParser())
+ ->parseTestResults('');
+
+ $this->failTest('Should throw on empty input');
+ } catch (Exception $e) {
+ // OK
+ }
+ }
+
+ public function testInvalidXmlInputFailure() {
+ $stubbed_results = Filesystem::readFile(
+ dirname(__FILE__).'/testresults/xunit.invallid-xml');
+ try {
+ $parsed_results = id(new ArcanistXUnitTestResultParser())
+ ->parseTestResults($stubbed_results);
+
+ $this->failTest('Should throw on non-xml input');
+ } catch (Exception $e) {
+ // OK
+ }
+ }
+
+}
diff --git a/src/unit/engine/__tests__/testresults/xunit.invallid-xml b/src/unit/engine/__tests__/testresults/xunit.invallid-xml
new file mode 100755
index 00000000..3dfdc59b
--- /dev/null
+++ b/src/unit/engine/__tests__/testresults/xunit.invallid-xml
@@ -0,0 +1 @@
+something else
diff --git a/src/unit/engine/__tests__/testresults/xunit.no-tests b/src/unit/engine/__tests__/testresults/xunit.no-tests
new file mode 100755
index 00000000..11aa5365
--- /dev/null
+++ b/src/unit/engine/__tests__/testresults/xunit.no-tests
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><testsuite name="" errors="0" failures="0" skips="0" tests="0" time="0.001" ></testsuite>
\ No newline at end of file
diff --git a/src/unit/engine/__tests__/testresults/xunit.simple b/src/unit/engine/__tests__/testresults/xunit.simple
new file mode 100755
index 00000000..ca3559fd
--- /dev/null
+++ b/src/unit/engine/__tests__/testresults/xunit.simple
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<testsuite name="" errors="0" failures="1" skips="0" tests="3" time="0.019">
+ <testcase classname="forpytest.tests" name="test_answer" time="0.0110499858856">
+ <failure message="test failure">def test_answer():
+> assert func(3) == 5
+E assert 4 == 5
+E + where 4 = func(3)
+
+tests.py:5: AssertionError</failure>
+ </testcase>
+ <testcase classname="forpytest.tests" name="test_something" time="6.29425048828e-05"/>
+ <testcase classname="forpytest.tests" name="test_nothing" time="5.91278076172e-05"/>
+</testsuite>
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Oct 11, 09:16 (8 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
984093
Default Alt Text
(40 KB)
Attached To
Mode
R118 Arcanist - fork
Attached
Detach File
Event Timeline
Log In to Comment