df5d728e08
They already do the right thing, but this pins it down. Also added a little functionality in AbstractSingleUnit to allow ignoring expected diagnostics in the input code. I did that instead of adding another diagnostic to the blanket ignores because diag.privateNamedNonFieldParameter felt like an error we wouldn't want to always ignore. I also like tests generally being specific in what they permit. Let me know what you think of this approach. BUG: https://github.com/dart-lang/sdk/issues/62434 Change-Id: I344aa665aeed0b766d6c2d97608dc4eedf14b2f9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/473925 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Commit-Queue: Brian Wilkerson <brianwilkerson@google.com> Auto-Submit: Bob Nystrom <rnystrom@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
146 lines
4.4 KiB
Dart
146 lines
4.4 KiB
Dart
// Copyright (c) 2014, 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:analyzer/dart/analysis/results.dart';
|
|
import 'package:analyzer/dart/ast/ast.dart';
|
|
import 'package:analyzer/dart/element/element.dart';
|
|
import 'package:analyzer/error/error.dart';
|
|
import 'package:analyzer/file_system/file_system.dart';
|
|
import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag;
|
|
import 'package:analyzer/src/test_utilities/find_element2.dart';
|
|
import 'package:analyzer/src/test_utilities/find_node.dart';
|
|
import 'package:analyzer/src/test_utilities/test_code_format.dart';
|
|
import 'package:analyzer/src/utilities/extensions/analysis_session.dart';
|
|
import 'package:test/test.dart';
|
|
|
|
import 'abstract_context.dart';
|
|
|
|
class AbstractSingleUnitTest extends AbstractContextTest {
|
|
bool verifyNoTestUnitErrors = true;
|
|
|
|
/// Whether the test code should parse with position and range shorthands.
|
|
///
|
|
/// Set this to `false` when the test code contains a legitimate carret
|
|
/// or contains `[!` or `!]`.
|
|
bool allowTestCodeShorthand = true;
|
|
|
|
TestCode? _parsedTestCode;
|
|
late ParsedUnitResult testParsedResult;
|
|
late ResolvedLibraryResult? testLibraryResult;
|
|
late ResolvedUnitResult testAnalysisResult;
|
|
late CompilationUnit testUnit;
|
|
late FindNode findNode;
|
|
late FindElement2 findElement2;
|
|
late LibraryElement testLibraryElement;
|
|
TestCode get parsedTestCode => _parsedTestCode!;
|
|
set parsedTestCode(TestCode value) {
|
|
if (_parsedTestCode != null) {
|
|
throw ArgumentError(
|
|
'parsedTestCode is already set to ${_parsedTestCode!.code}',
|
|
);
|
|
}
|
|
_parsedTestCode = value;
|
|
}
|
|
|
|
String get testCode => parsedTestCode.code;
|
|
set testCode(String value) {
|
|
parsedTestCode = TestCode.parseNormalized(
|
|
value,
|
|
positionShorthand: allowTestCodeShorthand,
|
|
rangeShorthand: allowTestCodeShorthand,
|
|
);
|
|
}
|
|
|
|
void addTestSource(String code) {
|
|
testCode = code;
|
|
newFile(testFile.path, testCode);
|
|
}
|
|
|
|
int findEnd(String search) {
|
|
return findOffset(search) + search.length;
|
|
}
|
|
|
|
int findOffset(String search) {
|
|
var offset = testCode.indexOf(search);
|
|
expect(offset, isNonNegative, reason: "Not found '$search' in\n$testCode");
|
|
return offset;
|
|
}
|
|
|
|
@override
|
|
Future<ResolvedUnitResult> getResolvedUnit(
|
|
File file, {
|
|
List<DiagnosticCode>? ignore,
|
|
}) async {
|
|
var session = await this.session;
|
|
var libraryResult = await session.getResolvedContainingLibrary(file.path);
|
|
var unitResult = libraryResult?.unitWithPath(file.path);
|
|
unitResult ??= await super.getResolvedUnit(file);
|
|
|
|
if (file.path == convertPath(testFilePath)) {
|
|
testLibraryResult = libraryResult;
|
|
testAnalysisResult = unitResult;
|
|
testUnit = unitResult.unit;
|
|
testLibraryElement = testUnit.declaredFragment!.element;
|
|
findNode = FindNode(unitResult.content, testUnit);
|
|
findElement2 = FindElement2(testUnit);
|
|
}
|
|
|
|
if (verifyNoTestUnitErrors) {
|
|
var allIgnored = const <DiagnosticCode>{
|
|
diag.deadCode,
|
|
diag.unusedCatchClause,
|
|
diag.unusedCatchStack,
|
|
diag.unusedElement,
|
|
diag.unusedField,
|
|
diag.unusedImport,
|
|
diag.unusedLocalVariable,
|
|
};
|
|
|
|
if (ignore != null) {
|
|
allIgnored = {...allIgnored, ...ignore};
|
|
}
|
|
|
|
expect(
|
|
unitResult.diagnostics.where(
|
|
(d) => !allIgnored.contains(d.diagnosticCode),
|
|
),
|
|
isEmpty,
|
|
);
|
|
}
|
|
return unitResult;
|
|
}
|
|
|
|
Future<void> parseTestCode(String code) async {
|
|
addTestSource(code);
|
|
testParsedResult = await getParsedUnit(testFile);
|
|
testUnit = testParsedResult.unit;
|
|
findNode = FindNode(testCode, testUnit);
|
|
findElement2 = FindElement2(testUnit);
|
|
}
|
|
|
|
void putTestFileInTestDir() {
|
|
testFilePath = '$testPackageTestPath/test.dart';
|
|
}
|
|
|
|
Future<void> resolveTestCode(
|
|
String code, {
|
|
List<DiagnosticCode>? ignore,
|
|
}) async {
|
|
addTestSource(code);
|
|
await resolveTestFile(ignore: ignore);
|
|
}
|
|
|
|
Future<void> resolveTestFile({List<DiagnosticCode>? ignore}) async {
|
|
await getResolvedUnit(testFile, ignore: ignore);
|
|
}
|
|
|
|
void updateTestSource(String code) {
|
|
if (_parsedTestCode == null) {
|
|
throw StateError('testCode is not set');
|
|
}
|
|
_parsedTestCode = null;
|
|
addTestSource(code);
|
|
}
|
|
}
|