blob: c0721f805aff219c634635d4e7d83d7bce924f0f [file] [log] [blame]
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/services/snippets/snippet.dart';
import 'package:analysis_server/src/services/snippets/snippet_producer.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/src/dart/analysis/session_helper.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
/// Produces a [Snippet] that creates a `test()` block.
class TestDefinition extends DartSnippetProducer with TestSnippetMixin {
static const prefix = 'test';
static const label = 'test';
TestDefinition(super.request, {required super.elementImportCache});
@override
String get snippetPrefix => prefix;
@override
Future<Snippet> compute() async {
var builder = ChangeBuilder(session: request.analysisSession);
var indent = utils.getLinePrefix(request.offset);
await builder.addDartFileEdit(request.filePath, (builder) async {
await addRequiredImports(builder);
builder.addReplacement(request.replacementRange, (builder) {
void writeIndented(String string) => builder.write('$indent$string');
builder.write("test('");
builder.addSimpleLinkedEdit('testName', 'test name');
builder.writeln("', () {");
writeIndented(' ');
builder.selectHere();
builder.writeln();
writeIndented('});');
});
});
return Snippet(prefix, label, 'Insert a test block.', builder.sourceChange);
}
@override
Future<bool> isValid() async {
if (!await super.isValid()) {
return false;
}
return isInTestDirectory;
}
}
mixin TestSnippetMixin {
final _flutterTestUri = Uri.parse('package:flutter_test/flutter_test.dart');
final _dartTestUri = Uri.parse('package:test/test.dart');
AnalysisSessionHelper get sessionHelper;
/// Adds imports for `test`/`group` if required.
///
/// Both 'package:test' and 'package:flutter_test' are checked because Flutter
/// projects can use either and we don't want to add the other.
Future<void> addRequiredImports(DartFileEditBuilder builder) async {
if (builder.importsLibrary(_dartTestUri) ||
builder.importsLibrary(_flutterTestUri)) {
return;
}
var testUri = await getTestLibraryUri();
builder.importLibrary(testUri);
}
/// Gets the URI for the test library to import depending on whether
/// flutter_test is available or not.
Future<Uri> getTestLibraryUri() async {
var flutterTest = await sessionHelper.session.getLibraryByUri(
_flutterTestUri.toString(),
);
return flutterTest is LibraryElementResult ? _flutterTestUri : _dartTestUri;
}
}