|
3 | 3 | // BSD-style license that can be found in the LICENSE file.
|
4 | 4 |
|
5 | 5 | import 'dart:async';
|
| 6 | +import 'dart:convert'; |
6 | 7 |
|
7 | 8 | import 'package:dart_mcp/server.dart';
|
8 | 9 | import 'package:path/path.dart' as p;
|
@@ -66,9 +67,18 @@ base mixin DashCliSupport on ToolsSupport, LoggingSupport, RootsTrackingSupport
|
66 | 67 |
|
67 | 68 | /// Implementation of the [runTestsTool].
|
68 | 69 | Future<CallToolResult> _runTests(CallToolRequest request) async {
|
| 70 | + final testRunnerArguments = |
| 71 | + request.arguments?[ParameterNames.testRunnerArgs] |
| 72 | + as Map<String, Object?>?; |
| 73 | + final hasReporterArg = |
| 74 | + testRunnerArguments?.containsKey('reporter') ?? false; |
69 | 75 | return runCommandInRoots(
|
70 | 76 | request,
|
71 |
| - arguments: ['test', '--reporter=failures-only'], |
| 77 | + arguments: [ |
| 78 | + 'test', |
| 79 | + if (!hasReporterArg) '--reporter=failures-only', |
| 80 | + ...?testRunnerArguments?.asCliArgs(), |
| 81 | + ], |
72 | 82 | commandDescription: 'dart|flutter test',
|
73 | 83 | processManager: processManager,
|
74 | 84 | knownRoots: await roots,
|
@@ -187,14 +197,26 @@ base mixin DashCliSupport on ToolsSupport, LoggingSupport, RootsTrackingSupport
|
187 | 197 | ),
|
188 | 198 | );
|
189 | 199 |
|
190 |
| - static final runTestsTool = Tool( |
191 |
| - name: 'run_tests', |
192 |
| - description: 'Runs Dart or Flutter tests for the given project roots.', |
193 |
| - annotations: ToolAnnotations(title: 'Run tests', readOnlyHint: true), |
194 |
| - inputSchema: Schema.object( |
195 |
| - properties: {ParameterNames.roots: rootsSchema(supportsPaths: true)}, |
196 |
| - ), |
197 |
| - ); |
| 200 | + static final Tool runTestsTool = () { |
| 201 | + final cliSchemaJson = |
| 202 | + jsonDecode(_dartTestCliSchema) as Map<String, Object?>; |
| 203 | + const blocklist = {'color', 'debug', 'help', 'pause-after-load', 'version'}; |
| 204 | + cliSchemaJson.removeWhere((argument, _) => blocklist.contains(argument)); |
| 205 | + final cliSchema = Schema.fromMap(cliSchemaJson); |
| 206 | + return Tool( |
| 207 | + name: 'run_tests', |
| 208 | + description: |
| 209 | + 'Run Dart or Flutter tests with an agent centric UX. ' |
| 210 | + 'ALWAYS use instead of `dart test` or `flutter test` shell commands.', |
| 211 | + annotations: ToolAnnotations(title: 'Run tests', readOnlyHint: true), |
| 212 | + inputSchema: Schema.object( |
| 213 | + properties: { |
| 214 | + ParameterNames.roots: rootsSchema(supportsPaths: true), |
| 215 | + ParameterNames.testRunnerArgs: cliSchema, |
| 216 | + }, |
| 217 | + ), |
| 218 | + ); |
| 219 | + }(); |
198 | 220 |
|
199 | 221 | static final createProjectTool = Tool(
|
200 | 222 | name: 'create_project',
|
@@ -245,3 +267,29 @@ base mixin DashCliSupport on ToolsSupport, LoggingSupport, RootsTrackingSupport
|
245 | 267 | 'ios',
|
246 | 268 | };
|
247 | 269 | }
|
| 270 | + |
| 271 | +extension on Map<String, Object?> { |
| 272 | + Iterable<String> asCliArgs() sync* { |
| 273 | + for (final MapEntry(:key, :value) in entries) { |
| 274 | + if (value is List) { |
| 275 | + for (final element in value) { |
| 276 | + yield '--$key'; |
| 277 | + yield element as String; |
| 278 | + } |
| 279 | + continue; |
| 280 | + } |
| 281 | + yield '--$key'; |
| 282 | + if (value is bool) continue; |
| 283 | + yield value as String; |
| 284 | + } |
| 285 | + } |
| 286 | +} |
| 287 | + |
| 288 | +// Generated by the test runner using an un-merged commit. |
| 289 | +// To update merge the latest argument changes to the `json-schema` branch and |
| 290 | +// run with the `--json-help` argument. Pipe to `sed 's/\\/\\\\/g'` to escape |
| 291 | +// as a Dart source string. |
| 292 | +// https://github.com/dart-lang/test/pull/2508 |
| 293 | +const _dartTestCliSchema = ''' |
| 294 | +{"type":"object","properties":{"help":{"type":"boolean","description":"Show this usage information.\\ndefaults to \\"false\\""},"version":{"type":"boolean","description":"Show the package:test version.\\ndefaults to \\"false\\""},"name":{"type":"array","description":"A substring of the name of the test to run.\\nRegular expression syntax is supported.\\nIf passed multiple times, tests must match all substrings.\\ndefaults to \\"[]\\"","items":{"type":"string"}},"plain-name":{"type":"array","description":"A plain-text substring of the name of the test to run.\\nIf passed multiple times, tests must match all substrings.\\ndefaults to \\"[]\\"","items":{"type":"string"}},"tags":{"type":"array","description":"Run only tests with all of the specified tags.\\nSupports boolean selector syntax.\\ndefaults to \\"[]\\"","items":{"type":"string"}},"exclude-tags":{"type":"array","description":"Don't run tests with any of the specified tags.\\nSupports boolean selector syntax.\\ndefaults to \\"[]\\"","items":{"type":"string"}},"run-skipped":{"type":"boolean","description":"Run skipped tests instead of skipping them.\\ndefaults to \\"false\\""},"platform":{"type":"array","description":"The platform(s) on which to run the tests.\\n[vm (default), chrome, firefox, edge, node].\\nEach platform supports the following compilers:\\n[vm]: kernel (default), source, exe\\n[chrome]: dart2js (default), dart2wasm\\n[firefox]: dart2js (default), dart2wasm\\n[edge]: dart2js (default)\\n[node]: dart2js (default), dart2wasm\\ndefaults to \\"[]\\"","items":{"type":"string"}},"compiler":{"type":"array","description":"The compiler(s) to use to run tests, supported compilers are [dart2js, dart2wasm, exe, kernel, source].\\nEach platform has a default compiler but may support other compilers.\\nYou can target a compiler to a specific platform using arguments of the following form [<platform-selector>:]<compiler>.\\nIf a platform is specified but no given compiler is supported for that platform, then it will use its default compiler.\\ndefaults to \\"[]\\"","items":{"type":"string"}},"preset":{"type":"array","description":"The configuration preset(s) to use.\\ndefaults to \\"[]\\"","items":{"type":"string"}},"concurrency":{"type":"string","description":"The number of concurrent test suites run.\\ndefaults to \\"8\\""},"total-shards":{"type":"string","description":"The total number of invocations of the test runner being run."},"shard-index":{"type":"string","description":"The index of this test runner invocation (of --total-shards)."},"timeout":{"type":"string","description":"The default test timeout. For example: 15s, 2x, none\\ndefaults to \\"30s\\""},"ignore-timeouts":{"type":"boolean","description":"Ignore all timeouts (useful if debugging)\\ndefaults to \\"false\\""},"pause-after-load":{"type":"boolean","description":"Pause for debugging before any tests execute.\\nImplies --concurrency=1, --debug, and --ignore-timeouts.\\nCurrently only supported for browser tests.\\ndefaults to \\"false\\""},"debug":{"type":"boolean","description":"Run the VM and Chrome tests in debug mode.\\ndefaults to \\"false\\""},"coverage":{"type":"string","description":"Gather coverage and output it to the specified directory.\\nImplies --debug."},"chain-stack-traces":{"type":"boolean","description":"Use chained stack traces to provide greater exception details\\nespecially for asynchronous code. It may be useful to disable\\nto provide improved test performance but at the cost of\\ndebuggability.\\ndefaults to \\"false\\""},"no-retry":{"type":"boolean","description":"Don't rerun tests that have retry set.\\ndefaults to \\"false\\""},"test-randomize-ordering-seed":{"type":"string","description":"Use the specified seed to randomize the execution order of test cases.\\nMust be a 32bit unsigned integer or \\"random\\".\\nIf \\"random\\", pick a random seed to use.\\nIf not passed, do not randomize test case execution order."},"fail-fast":{"type":"boolean","description":"Stop running tests after the first failure.\\n\\ndefaults to \\"false\\""},"reporter":{"type":"string","description":"Set how to print test results.\\ndefaults to \\"compact\\"\\nallowed values: compact, expanded, failures-only, github, json, silent"},"file-reporter":{"type":"string","description":"Enable an additional reporter writing test results to a file.\\nShould be in the form <reporter>:<filepath>, Example: \\"json:reports/tests.json\\""},"verbose-trace":{"type":"boolean","description":"Emit stack traces with core library frames.\\ndefaults to \\"false\\""},"js-trace":{"type":"boolean","description":"Emit raw JavaScript stack traces for browser tests.\\ndefaults to \\"false\\""},"color":{"type":"boolean","description":"Use terminal colors.\\n(auto-detected by default)\\ndefaults to \\"false\\""}},"required":[]} |
| 295 | +'''; |
0 commit comments