cbfc0784de
Change-Id: I880e53634c570cc25f4ff22dd01397b088b9bd07 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/447441 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Samuel Rawlins <srawlins@google.com>
179 lines
5.8 KiB
Dart
179 lines
5.8 KiB
Dart
// Copyright (c) 2024, 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/analysis/session.dart';
|
|
import 'package:analyzer/file_system/file_system.dart';
|
|
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
|
|
import 'package:analyzer/src/dart/analysis/byte_store.dart';
|
|
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
|
|
import 'package:analyzer/src/error/codes.dart';
|
|
import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
|
|
import 'package:analyzer/src/test_utilities/find_node.dart';
|
|
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
|
|
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
|
|
import 'package:analyzer_testing/resource_provider_mixin.dart';
|
|
import 'package:meta/meta.dart';
|
|
import 'package:test/test.dart';
|
|
|
|
/// A base test framework for writing tests that resolve a String as Dart source
|
|
/// code.
|
|
// TODO(srawlins): This is all copied from the `AbstractSingleUnitTest` and
|
|
// `AbstractContextTest` classes in the analysis_server package. It is pared
|
|
// down as the minimum amount of code needed to run the tests in this package.
|
|
class SingleUnitTest with ResourceProviderMixin {
|
|
static final ByteStore _byteStore = MemoryByteStore();
|
|
|
|
late String testCode;
|
|
late ParsedUnitResult testParsedResult;
|
|
late ResolvedUnitResult testAnalysisResult;
|
|
late FindNode findNode;
|
|
|
|
final Map<String, String> _declaredVariables = {};
|
|
AnalysisContextCollectionImpl? _analysisContextCollection;
|
|
|
|
File get testFile => getFile(_testFilePath);
|
|
|
|
List<String> get _collectionIncludedPaths => [_workspaceRootPath];
|
|
|
|
Folder get _sdkRoot => newFolder('/sdk');
|
|
|
|
String get _testFilePath => '$_testPackageLibPath/test.dart';
|
|
|
|
String get _testPackageLibPath => '$_testPackageRootPath/lib';
|
|
|
|
String get _testPackageRootPath => '$_workspaceRootPath/test';
|
|
|
|
String get _workspaceRootPath => '/home';
|
|
|
|
void addTestSource(String code) {
|
|
testCode = code;
|
|
newFile(testFile.path, code);
|
|
}
|
|
|
|
void changeFile(File file) {
|
|
_contextFor(file).driver.changeFile(file.path);
|
|
}
|
|
|
|
Future<ParsedUnitResult> getParsedUnit(File file) async {
|
|
var path = file.path;
|
|
var session = await _sessionFor(file);
|
|
var result = session.getParsedUnit(path) as ParsedUnitResult;
|
|
|
|
testParsedResult = result;
|
|
testCode = result.content;
|
|
var testUnit = result.unit;
|
|
findNode = FindNode(testCode, testUnit);
|
|
return result;
|
|
}
|
|
|
|
Future<ResolvedUnitResult> getResolvedUnit(File file) async {
|
|
var path = file.path;
|
|
var session = await _sessionFor(file);
|
|
var result = await session.getResolvedUnit(path) as ResolvedUnitResult;
|
|
|
|
testAnalysisResult = result;
|
|
testCode = result.content;
|
|
var testUnit = result.unit;
|
|
|
|
expect(
|
|
result.diagnostics.where((d) {
|
|
return d.diagnosticCode != WarningCode.deadCode &&
|
|
d.diagnosticCode != WarningCode.unusedCatchClause &&
|
|
d.diagnosticCode != WarningCode.unusedCatchStack &&
|
|
d.diagnosticCode != WarningCode.unusedElement &&
|
|
d.diagnosticCode != WarningCode.unusedField &&
|
|
d.diagnosticCode != WarningCode.unusedImport &&
|
|
d.diagnosticCode != WarningCode.unusedLocalVariable;
|
|
}),
|
|
isEmpty,
|
|
);
|
|
|
|
findNode = FindNode(testCode, testUnit);
|
|
return result;
|
|
}
|
|
|
|
@override
|
|
File newFile(String path, String content) {
|
|
if (_analysisContextCollection != null && !path.endsWith('.dart')) {
|
|
throw StateError('Only dart files can be changed after analysis.');
|
|
}
|
|
|
|
var file = super.newFile(path, content);
|
|
_addAnalyzedFileToDrivers(file);
|
|
return file;
|
|
}
|
|
|
|
Future<void> parseTestCode(String code) async {
|
|
addTestSource(code);
|
|
await getParsedUnit(testFile);
|
|
}
|
|
|
|
Future<void> resolveTestCode(String code) async {
|
|
addTestSource(code);
|
|
await getResolvedUnit(testFile);
|
|
}
|
|
|
|
@mustCallSuper
|
|
void setUp() {
|
|
createMockSdk(resourceProvider: resourceProvider, root: _sdkRoot);
|
|
}
|
|
|
|
@mustCallSuper
|
|
Future<void> tearDown() async {
|
|
AnalysisEngine.instance.clearCaches();
|
|
await _analysisContextCollection?.dispose();
|
|
}
|
|
|
|
void _addAnalyzedFilesToDrivers() {
|
|
for (var analysisContext in _analysisContextCollection!.contexts) {
|
|
for (var path in analysisContext.contextRoot.analyzedFiles()) {
|
|
if (file_paths.isDart(resourceProvider.pathContext, path)) {
|
|
analysisContext.driver.addFile(path);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void _addAnalyzedFileToDrivers(File file) {
|
|
var collection = _analysisContextCollection;
|
|
if (collection != null) {
|
|
for (var analysisContext in collection.contexts) {
|
|
if (analysisContext.contextRoot.isAnalyzed(file.path)) {
|
|
analysisContext.driver.addFile(file.path);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
DriverBasedAnalysisContext _contextFor(File file) {
|
|
_createAnalysisContexts();
|
|
return _analysisContextCollection!.contextFor(file.path);
|
|
}
|
|
|
|
/// Creates all analysis contexts in [_collectionIncludedPaths].
|
|
void _createAnalysisContexts() {
|
|
if (_analysisContextCollection != null) {
|
|
return;
|
|
}
|
|
|
|
_analysisContextCollection = AnalysisContextCollectionImpl(
|
|
byteStore: _byteStore,
|
|
declaredVariables: _declaredVariables,
|
|
enableIndex: true,
|
|
includedPaths: _collectionIncludedPaths.map(convertPath).toList(),
|
|
resourceProvider: resourceProvider,
|
|
sdkPath: _sdkRoot.path,
|
|
);
|
|
|
|
_addAnalyzedFilesToDrivers();
|
|
}
|
|
|
|
Future<AnalysisSession> _sessionFor(File file) async {
|
|
var analysisContext = _contextFor(file);
|
|
await analysisContext.applyPendingFileChanges();
|
|
return analysisContext.currentSession;
|
|
}
|
|
}
|