CQ. Switch analysis options tests to inline expected diagnostics.
Change-Id: I2c33dbd645bd8611836cbcbab597a23165d1fb9e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/511060 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
6de2588d56
commit
649a56d6e4
@@ -176,6 +176,36 @@ class NodeTextExpectationsCollector {
|
||||
methodName: 'parseTestCodeWithDiagnostics',
|
||||
argument: _ArgumentIndex(0),
|
||||
),
|
||||
_AssertMethod(
|
||||
className: 'AbstractAnalysisOptionsTest',
|
||||
methodName: 'assertDiagnosticsInCode',
|
||||
argument: _ArgumentIndex(0),
|
||||
),
|
||||
_AssertMethod(
|
||||
className: 'AbstractAnalysisOptionsTest',
|
||||
methodName: 'assertDiagnosticsInFiles',
|
||||
argument: _ArgumentMapEntryValue(mapArgument: _ArgumentIndex(0)),
|
||||
),
|
||||
_AssertMethod(
|
||||
className: 'OptionsFileValidatorTest',
|
||||
methodName: 'validate',
|
||||
argument: _ArgumentIndex(0),
|
||||
),
|
||||
_AssertMethod(
|
||||
className: 'OptionsProviderTest',
|
||||
methodName: 'assertDiagnosticsInOptionsFile',
|
||||
argument: _ArgumentIndex(1),
|
||||
),
|
||||
_AssertMethod(
|
||||
className: 'OptionsRuleValidatorTestMixin',
|
||||
methodName: 'assertDiagnostics',
|
||||
argument: _ArgumentIndex(0),
|
||||
),
|
||||
_AssertMethod(
|
||||
className: 'OptionsRuleValidatorTestMixin',
|
||||
methodName: 'assertRuleDiagnosticsInFiles',
|
||||
argument: _ArgumentMapEntryValue(mapArgument: _ArgumentIndex(0)),
|
||||
),
|
||||
_AssertMethod(
|
||||
className: 'ResolutionTest',
|
||||
methodName: 'assertDartObjectText',
|
||||
|
||||
+99
-36
@@ -2,7 +2,7 @@
|
||||
// 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:_fe_analyzer_shared/src/base/errors.dart';
|
||||
import 'package:analyzer/diagnostic/diagnostic.dart';
|
||||
import 'package:analyzer/file_system/file_system.dart';
|
||||
import 'package:analyzer/source/file_source.dart';
|
||||
import 'package:analyzer/src/analysis_options/options_file_validator.dart';
|
||||
@@ -12,59 +12,46 @@ import 'package:analyzer/src/generated/source.dart';
|
||||
import 'package:analyzer/src/source/package_map_resolver.dart';
|
||||
import 'package:analyzer/src/test_utilities/lint_registration_mixin.dart';
|
||||
import 'package:analyzer_testing/resource_provider_mixin.dart';
|
||||
import 'package:analyzer_testing/src/analysis_rule/pub_package_resolution.dart';
|
||||
import 'package:analyzer_testing/src/expected_diagnostics.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:pub_semver/pub_semver.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../../generated/test_support.dart';
|
||||
import '../../../util/diff.dart';
|
||||
import '../../dart/resolution/node_text_expectations.dart';
|
||||
|
||||
abstract class AbstractAnalysisOptionsTest
|
||||
with ResourceProviderMixin, LintRegistrationMixin {
|
||||
with
|
||||
ResourceProviderMixin,
|
||||
LintRegistrationMixin,
|
||||
AnalysisOptionsDiagnosticExpectationMixin {
|
||||
late SourceFactory sourceFactory;
|
||||
Map<String, String>? dependencies;
|
||||
|
||||
late File analysisOptionsFile = newFile(analysisOptionsPath, '');
|
||||
late String analysisOptionsPath = convertPath('/analysis_options.yaml');
|
||||
late File analysisOptionsFile = getFile('/analysis_options.yaml');
|
||||
VersionConstraint? get sdkVersionConstraint => null;
|
||||
|
||||
Future<void> assertErrorsInCode(
|
||||
String code,
|
||||
List<ExpectedDiagnostic> expectedDiagnostics,
|
||||
) async {
|
||||
analysisOptionsFile.writeAsStringSync(code);
|
||||
Future<void> assertDiagnosticsInCode(String code) async {
|
||||
await assertDiagnosticsInFiles({analysisOptionsFile: code});
|
||||
}
|
||||
|
||||
Future<void> assertDiagnosticsInFiles(Map<File, String> codeByFile) async {
|
||||
var cleanCodeByFile = writeFilesWithoutDiagnosticExpectations(codeByFile);
|
||||
|
||||
var diagnostics = AnalysisOptionsAnalyzer(
|
||||
initialSource: FileSource(analysisOptionsFile),
|
||||
sourceFactory: sourceFactory,
|
||||
contextRoot: '/',
|
||||
sdkVersionConstraint: sdkVersionConstraint,
|
||||
resourceProvider: resourceProvider,
|
||||
).walkIncludes(content: code);
|
||||
var diagnosticListener = GatheringDiagnosticListener();
|
||||
diagnosticListener.addAll(diagnostics);
|
||||
diagnosticListener.assertErrors(expectedDiagnostics);
|
||||
).walkIncludes(content: cleanCodeByFile[analysisOptionsFile]!);
|
||||
|
||||
assertDiagnosticMarkersInFiles(
|
||||
codeByFile: codeByFile,
|
||||
diagnostics: diagnostics,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> assertNoErrorsInCode(String code) async =>
|
||||
await assertErrorsInCode(code, const []);
|
||||
|
||||
ExpectedError error(
|
||||
DiagnosticCode code,
|
||||
int offset,
|
||||
int length, {
|
||||
Pattern? correctionContains,
|
||||
String? text,
|
||||
List<Pattern> messageContains = const [],
|
||||
List<ExpectedContextMessage> contextMessages =
|
||||
const <ExpectedContextMessage>[],
|
||||
}) => ExpectedError(
|
||||
code,
|
||||
offset,
|
||||
length,
|
||||
correctionContains: correctionContains,
|
||||
messageContainsAll: messageContains,
|
||||
contextMessages: contextMessages,
|
||||
);
|
||||
|
||||
void setUp() {
|
||||
var resolvers = [
|
||||
ResourceUriResolver(resourceProvider),
|
||||
@@ -82,3 +69,79 @@ abstract class AbstractAnalysisOptionsTest
|
||||
unregisterLintRules();
|
||||
}
|
||||
}
|
||||
|
||||
/// Shared inline diagnostic expectation checks for analysis-options tests.
|
||||
///
|
||||
/// These helpers only compare diagnostics with inline markers. Test-specific
|
||||
/// helpers remain responsible for choosing which analyzer or validator entry
|
||||
/// point produces the diagnostics.
|
||||
mixin AnalysisOptionsDiagnosticExpectationMixin {
|
||||
void assertDiagnosticMarkersInFiles({
|
||||
required Map<File, String> codeByFile,
|
||||
required List<Diagnostic> diagnostics,
|
||||
}) {
|
||||
var cleanCodeByFile = {
|
||||
for (var entry in codeByFile.entries)
|
||||
entry.key: removeDiagnosticExpectations(entry.value),
|
||||
};
|
||||
var actualCodeByFile = updateExpectedDiagnosticsForFiles(
|
||||
contentByFile: cleanCodeByFile,
|
||||
actualDiagnosticsByFile: _diagnosticsByFile(
|
||||
files: codeByFile.keys,
|
||||
diagnostics: diagnostics,
|
||||
),
|
||||
);
|
||||
|
||||
var hasMismatch = false;
|
||||
var index = 0;
|
||||
for (var entry in codeByFile.entries) {
|
||||
var actual = actualCodeByFile[entry.key]!;
|
||||
if (actual != entry.value) {
|
||||
NodeTextExpectationsCollector.add(actual, intraInvocationId: '$index');
|
||||
print('-------- ${entry.key.path} --------');
|
||||
printPrettyDiff(entry.value, actual);
|
||||
hasMismatch = true;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
if (hasMismatch) {
|
||||
fail('See the difference above.');
|
||||
}
|
||||
}
|
||||
|
||||
Map<File, String> writeFilesWithoutDiagnosticExpectations(
|
||||
Map<File, String> codeByFile,
|
||||
) {
|
||||
var cleanCodeByFile = {
|
||||
for (var entry in codeByFile.entries)
|
||||
entry.key: removeDiagnosticExpectations(entry.value),
|
||||
};
|
||||
for (var entry in cleanCodeByFile.entries) {
|
||||
entry.key.writeAsStringSync(entry.value);
|
||||
}
|
||||
return cleanCodeByFile;
|
||||
}
|
||||
|
||||
Map<File, List<Diagnostic>> _diagnosticsByFile({
|
||||
required Iterable<File> files,
|
||||
required List<Diagnostic> diagnostics,
|
||||
}) {
|
||||
var fileByPath = {for (var file in files) file.path: file};
|
||||
var diagnosticsByFile = {for (var file in files) file: <Diagnostic>[]};
|
||||
|
||||
for (var diagnostic in diagnostics) {
|
||||
var filePath = diagnostic.problemMessage.filePath;
|
||||
var file = fileByPath[filePath];
|
||||
if (file == null) {
|
||||
fail(
|
||||
'Cannot generate diagnostic expectations for $filePath: '
|
||||
'no content was provided.',
|
||||
);
|
||||
}
|
||||
diagnosticsByFile[file]!.add(diagnostic);
|
||||
}
|
||||
|
||||
return diagnosticsByFile;
|
||||
}
|
||||
}
|
||||
|
||||
+48
-101
@@ -2,7 +2,6 @@
|
||||
// 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/src/diagnostic/diagnostic.dart' as diag;
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import 'analysis_options_test_support.dart';
|
||||
@@ -16,159 +15,107 @@ main() {
|
||||
@reflectiveTest
|
||||
class IncludeFileNotFoundTest extends AbstractAnalysisOptionsTest {
|
||||
Future<void> test_notFound_existent_doubleQuoted() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
await assertDiagnosticsInCode('''
|
||||
include: "./analysis_options.yaml"
|
||||
''',
|
||||
[error(diag.recursiveIncludeFile, 9, 25)],
|
||||
);
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
// [diag.recursiveIncludeFile] The URI './analysis_options.yaml' included in '/analysis_options.yaml' includes '/analysis_options.yaml', creating a circular reference.
|
||||
''');
|
||||
}
|
||||
|
||||
Future<void> test_notFound_existent_list_first() async {
|
||||
newFile('/included1.yaml', '');
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
await assertDiagnosticsInFiles({
|
||||
analysisOptionsFile: '''
|
||||
include:
|
||||
- ./analysis_options.yaml
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
// [diag.recursiveIncludeFile] The URI './analysis_options.yaml' included in '/analysis_options.yaml' includes '/analysis_options.yaml', creating a circular reference.
|
||||
- included1.yaml
|
||||
''',
|
||||
[error(diag.recursiveIncludeFile, 13, 23)],
|
||||
);
|
||||
getFile('/included1.yaml'): '',
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> test_notFound_existent_list_second() async {
|
||||
newFile('/included1.yaml', '');
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
await assertDiagnosticsInFiles({
|
||||
analysisOptionsFile: '''
|
||||
include:
|
||||
- included1.yaml
|
||||
- ./analysis_options.yaml
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
// [diag.recursiveIncludeFile] The URI './analysis_options.yaml' included in '/analysis_options.yaml' includes '/analysis_options.yaml', creating a circular reference.
|
||||
''',
|
||||
[error(diag.recursiveIncludeFile, 32, 23)],
|
||||
);
|
||||
getFile('/included1.yaml'): '',
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> test_notFound_existent_notQuoted() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
await assertDiagnosticsInCode('''
|
||||
include: ./analysis_options.yaml
|
||||
''',
|
||||
[error(diag.recursiveIncludeFile, 9, 23)],
|
||||
);
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
// [diag.recursiveIncludeFile] The URI './analysis_options.yaml' included in '/analysis_options.yaml' includes '/analysis_options.yaml', creating a circular reference.
|
||||
''');
|
||||
}
|
||||
|
||||
Future<void> test_notFound_existent_singleQuoted() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
await assertDiagnosticsInCode('''
|
||||
include: './analysis_options.yaml'
|
||||
''',
|
||||
[error(diag.recursiveIncludeFile, 9, 25)],
|
||||
);
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
// [diag.recursiveIncludeFile] The URI './analysis_options.yaml' included in '/analysis_options.yaml' includes '/analysis_options.yaml', creating a circular reference.
|
||||
''');
|
||||
}
|
||||
|
||||
Future<void> test_notFound_nonexistent_doubleQuoted() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
await assertDiagnosticsInCode('''
|
||||
# We don't depend on pedantic, but we should consider adding it.
|
||||
include: "package:pedantic/analysis_options.yaml"
|
||||
''',
|
||||
[
|
||||
error(
|
||||
diag.includeFileNotFound,
|
||||
74,
|
||||
40,
|
||||
text:
|
||||
"The URI 'package:pedantic/analysis_options.yaml' included in "
|
||||
"'${convertPath('/analysis_options.yaml')}' can't be found "
|
||||
"when analyzing '/'.",
|
||||
),
|
||||
],
|
||||
);
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
// [diag.includeFileNotFound] The URI 'package:pedantic/analysis_options.yaml' included in '/analysis_options.yaml' can't be found when analyzing '/'.
|
||||
''');
|
||||
}
|
||||
|
||||
Future<void> test_notFound_nonexistent_list_first() async {
|
||||
newFile('/included1.yaml', '');
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
await assertDiagnosticsInFiles({
|
||||
analysisOptionsFile: '''
|
||||
# We don't depend on pedantic, but we should consider adding it.
|
||||
include:
|
||||
- package:pedantic/analysis_options.yaml
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
// [diag.includeFileNotFound] The URI 'package:pedantic/analysis_options.yaml' included in '/analysis_options.yaml' can't be found when analyzing '/'.
|
||||
- included1.yaml
|
||||
''',
|
||||
[
|
||||
error(
|
||||
diag.includeFileNotFound,
|
||||
78,
|
||||
38,
|
||||
text:
|
||||
"The URI 'package:pedantic/analysis_options.yaml' included in "
|
||||
"'${convertPath('/analysis_options.yaml')}' can't be found "
|
||||
"when analyzing '/'.",
|
||||
),
|
||||
],
|
||||
);
|
||||
getFile('/included1.yaml'): '',
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> test_notFound_nonexistent_list_second() async {
|
||||
newFile('/included1.yaml', '');
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
await assertDiagnosticsInFiles({
|
||||
analysisOptionsFile: '''
|
||||
# We don't depend on pedantic, but we should consider adding it.
|
||||
include:
|
||||
- included1.yaml
|
||||
- package:pedantic/analysis_options.yaml
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
// [diag.includeFileNotFound] The URI 'package:pedantic/analysis_options.yaml' included in '/analysis_options.yaml' can't be found when analyzing '/'.
|
||||
''',
|
||||
[
|
||||
error(
|
||||
diag.includeFileNotFound,
|
||||
97,
|
||||
38,
|
||||
text:
|
||||
"The URI 'package:pedantic/analysis_options.yaml' included in "
|
||||
"'${convertPath('/analysis_options.yaml')}' can't be found "
|
||||
"when analyzing '/'.",
|
||||
),
|
||||
],
|
||||
);
|
||||
getFile('/included1.yaml'): '',
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> test_notFound_nonexistent_notQuoted() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
await assertDiagnosticsInCode('''
|
||||
# We don't depend on pedantic, but we should consider adding it.
|
||||
include: package:pedantic/analysis_options.yaml
|
||||
''',
|
||||
[
|
||||
error(
|
||||
diag.includeFileNotFound,
|
||||
74,
|
||||
38,
|
||||
text:
|
||||
"The URI 'package:pedantic/analysis_options.yaml' included in "
|
||||
"'${convertPath('/analysis_options.yaml')}' can't be found "
|
||||
"when analyzing '/'.",
|
||||
),
|
||||
],
|
||||
);
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
// [diag.includeFileNotFound] The URI 'package:pedantic/analysis_options.yaml' included in '/analysis_options.yaml' can't be found when analyzing '/'.
|
||||
''');
|
||||
}
|
||||
|
||||
Future<void> test_notFound_nonexistent_singleQuoted() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
await assertDiagnosticsInCode('''
|
||||
# We don't depend on pedantic, but we should consider adding it.
|
||||
include: 'package:pedantic/analysis_options.yaml'
|
||||
''',
|
||||
[
|
||||
error(
|
||||
diag.includeFileNotFound,
|
||||
74,
|
||||
40,
|
||||
text:
|
||||
"The URI 'package:pedantic/analysis_options.yaml' included in "
|
||||
"'${convertPath('/analysis_options.yaml')}' can't be found "
|
||||
"when analyzing '/'.",
|
||||
),
|
||||
],
|
||||
);
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
// [diag.includeFileNotFound] The URI 'package:pedantic/analysis_options.yaml' included in '/analysis_options.yaml' can't be found when analyzing '/'.
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// 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/src/diagnostic/diagnostic.dart' as diag;
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import 'analysis_options_test_support.dart';
|
||||
@@ -16,25 +15,16 @@ main() {
|
||||
@reflectiveTest
|
||||
class IncludeFileWarningTest extends AbstractAnalysisOptionsTest {
|
||||
Future<void> test_fileWarning() async {
|
||||
newFile('/a.yaml', '''
|
||||
await assertDiagnosticsInFiles({
|
||||
analysisOptionsFile: '''
|
||||
include: a.yaml
|
||||
// ^^^^^^
|
||||
// [diag.includedFileWarning] Warning in the included options file /a.yaml(12..20): The option 'something' isn't supported by 'analyzer'.
|
||||
''',
|
||||
getFile('/a.yaml'): '''
|
||||
analyzer:
|
||||
something: bad
|
||||
''');
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
include: a.yaml
|
||||
''',
|
||||
[
|
||||
error(
|
||||
diag.includedFileWarning,
|
||||
9,
|
||||
6,
|
||||
messageContains: [
|
||||
'Warning in the included options file ${convertPath('/a.yaml')}',
|
||||
": The option 'something' isn't supported by 'analyzer'.",
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+80
-149
@@ -2,7 +2,6 @@
|
||||
// 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/src/diagnostic/diagnostic.dart' as diag;
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import 'analysis_options_test_support.dart';
|
||||
@@ -16,203 +15,135 @@ main() {
|
||||
@reflectiveTest
|
||||
class RecursiveIncludeFileTest extends AbstractAnalysisOptionsTest {
|
||||
Future<void> test_itself() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
await assertDiagnosticsInCode('''
|
||||
include: analysis_options.yaml
|
||||
''',
|
||||
[
|
||||
error(
|
||||
diag.recursiveIncludeFile,
|
||||
9,
|
||||
21,
|
||||
text:
|
||||
"The URI 'analysis_options.yaml' included in "
|
||||
"'${convertPath('/analysis_options.yaml')}' includes "
|
||||
"'${convertPath('/analysis_options.yaml')}', "
|
||||
"creating a circular reference.",
|
||||
),
|
||||
],
|
||||
);
|
||||
// ^^^^^^^^^^^^^^^^^^^^^
|
||||
// [diag.recursiveIncludeFile] The URI 'analysis_options.yaml' included in '/analysis_options.yaml' includes '/analysis_options.yaml', creating a circular reference.
|
||||
''');
|
||||
}
|
||||
|
||||
Future<void> test_itself_inList() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
await assertDiagnosticsInCode('''
|
||||
include:
|
||||
- analysis_options.yaml
|
||||
''',
|
||||
[
|
||||
error(
|
||||
diag.recursiveIncludeFile,
|
||||
13,
|
||||
21,
|
||||
text:
|
||||
"The URI 'analysis_options.yaml' included in "
|
||||
"'${convertPath('/analysis_options.yaml')}' includes "
|
||||
"'${convertPath('/analysis_options.yaml')}', "
|
||||
"creating a circular reference.",
|
||||
),
|
||||
],
|
||||
);
|
||||
// ^^^^^^^^^^^^^^^^^^^^^
|
||||
// [diag.recursiveIncludeFile] The URI 'analysis_options.yaml' included in '/analysis_options.yaml' includes '/analysis_options.yaml', creating a circular reference.
|
||||
''');
|
||||
}
|
||||
|
||||
Future<void> test_notRecursive() async {
|
||||
newFile('/a.yaml', '''
|
||||
include: b.yaml
|
||||
''');
|
||||
newFile('/b.yaml', '');
|
||||
await assertNoErrorsInCode('''
|
||||
await assertDiagnosticsInFiles({
|
||||
analysisOptionsFile: '''
|
||||
include:
|
||||
- a.yaml
|
||||
- b.yaml
|
||||
''');
|
||||
''',
|
||||
getFile('/a.yaml'): '''
|
||||
include: b.yaml
|
||||
''',
|
||||
getFile('/b.yaml'): '',
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> test_notRecursive_included() async {
|
||||
newFile('/a.yaml', '''
|
||||
await assertDiagnosticsInFiles({
|
||||
analysisOptionsFile: '''
|
||||
include: c.yaml
|
||||
''',
|
||||
getFile('/a.yaml'): '''
|
||||
include: b.yaml
|
||||
''');
|
||||
newFile('/b.yaml', '');
|
||||
newFile('/c.yaml', '''
|
||||
''',
|
||||
getFile('/b.yaml'): '',
|
||||
getFile('/c.yaml'): '''
|
||||
include:
|
||||
- a.yaml
|
||||
- b.yaml
|
||||
''');
|
||||
await assertNoErrorsInCode('''
|
||||
include: c.yaml
|
||||
''');
|
||||
''',
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> test_recursive() async {
|
||||
newFile('/a.yaml', '''
|
||||
include: b.yaml
|
||||
''');
|
||||
newFile('/b.yaml', '''
|
||||
include: analysis_options.yaml
|
||||
''');
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
await assertDiagnosticsInFiles({
|
||||
analysisOptionsFile: '''
|
||||
include: a.yaml
|
||||
// ^^^^^^
|
||||
// [diag.recursiveIncludeFile] The URI 'analysis_options.yaml' included in '/b.yaml' includes '/b.yaml', creating a circular reference.
|
||||
''',
|
||||
[
|
||||
error(
|
||||
diag.recursiveIncludeFile,
|
||||
9,
|
||||
6,
|
||||
text:
|
||||
"The URI 'analysis_options.yaml' included in "
|
||||
"'${convertPath('/b.yaml')}' includes "
|
||||
"'${convertPath('/b.yaml')}', "
|
||||
"creating a circular reference.",
|
||||
),
|
||||
],
|
||||
);
|
||||
getFile('/a.yaml'): '''
|
||||
include: b.yaml
|
||||
''',
|
||||
getFile('/b.yaml'): '''
|
||||
include: analysis_options.yaml
|
||||
''',
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> test_recursive_itself() async {
|
||||
newFile('/a.yaml', '''
|
||||
await assertDiagnosticsInFiles({
|
||||
analysisOptionsFile: '''
|
||||
include: a.yaml
|
||||
''');
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
// ^^^^^^
|
||||
// [diag.includedFileWarning] Warning in the included options file /a.yaml(9..14): The file includes itself recursively.
|
||||
''',
|
||||
getFile('/a.yaml'): '''
|
||||
include: a.yaml
|
||||
''',
|
||||
[
|
||||
error(
|
||||
diag.includedFileWarning,
|
||||
9,
|
||||
6,
|
||||
messageContains: [
|
||||
"Warning in the included options file ${convertPath('/a.yaml')}",
|
||||
": The file includes itself recursively.",
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> test_recursive_listAtTop() async {
|
||||
newFile('/a.yaml', '''
|
||||
include: b.yaml
|
||||
''');
|
||||
newFile('/b.yaml', '''
|
||||
include: analysis_options.yaml
|
||||
''');
|
||||
newFile('/empty.yaml', '''
|
||||
''');
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
await assertDiagnosticsInFiles({
|
||||
analysisOptionsFile: '''
|
||||
include:
|
||||
- empty.yaml
|
||||
- a.yaml
|
||||
// ^^^^^^
|
||||
// [diag.recursiveIncludeFile] The URI 'analysis_options.yaml' included in '/b.yaml' includes '/b.yaml', creating a circular reference.
|
||||
''',
|
||||
[
|
||||
error(
|
||||
diag.recursiveIncludeFile,
|
||||
28,
|
||||
6,
|
||||
text:
|
||||
"The URI 'analysis_options.yaml' included in "
|
||||
"'${convertPath('/b.yaml')}' includes "
|
||||
"'${convertPath('/b.yaml')}', "
|
||||
"creating a circular reference.",
|
||||
),
|
||||
],
|
||||
);
|
||||
getFile('/a.yaml'): '''
|
||||
include: b.yaml
|
||||
''',
|
||||
getFile('/b.yaml'): '''
|
||||
include: analysis_options.yaml
|
||||
''',
|
||||
getFile('/empty.yaml'): '''
|
||||
''',
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> test_recursive_listIncluded() async {
|
||||
newFile('/a.yaml', '''
|
||||
await assertDiagnosticsInFiles({
|
||||
analysisOptionsFile: '''
|
||||
include: a.yaml
|
||||
// ^^^^^^
|
||||
// [diag.recursiveIncludeFile] The URI 'analysis_options.yaml' included in '/b.yaml' includes '/b.yaml', creating a circular reference.
|
||||
''',
|
||||
getFile('/a.yaml'): '''
|
||||
include:
|
||||
- empty.yaml
|
||||
- b.yaml
|
||||
''');
|
||||
newFile('/b.yaml', '''
|
||||
include: analysis_options.yaml
|
||||
''');
|
||||
newFile('/empty.yaml', '''
|
||||
''');
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
include: a.yaml
|
||||
''',
|
||||
[
|
||||
error(
|
||||
diag.recursiveIncludeFile,
|
||||
9,
|
||||
6,
|
||||
text:
|
||||
"The URI 'analysis_options.yaml' included in "
|
||||
"'${convertPath('/b.yaml')}' includes "
|
||||
"'${convertPath('/b.yaml')}', "
|
||||
"creating a circular reference.",
|
||||
),
|
||||
],
|
||||
);
|
||||
getFile('/b.yaml'): '''
|
||||
include: analysis_options.yaml
|
||||
''',
|
||||
getFile('/empty.yaml'): '''
|
||||
''',
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> test_recursive_notInBeginning() async {
|
||||
newFile('/a.yaml', '''
|
||||
include: b.yaml
|
||||
''');
|
||||
newFile('/b.yaml', '''
|
||||
await assertDiagnosticsInFiles({
|
||||
analysisOptionsFile: '''
|
||||
include: a.yaml
|
||||
''');
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
// ^^^^^^
|
||||
// [diag.includedFileWarning] Warning in the included options file /a.yaml(9..14): The file includes itself recursively.
|
||||
''',
|
||||
getFile('/a.yaml'): '''
|
||||
include: b.yaml
|
||||
''',
|
||||
getFile('/b.yaml'): '''
|
||||
include: a.yaml
|
||||
''',
|
||||
[
|
||||
error(
|
||||
diag.includedFileWarning,
|
||||
9,
|
||||
6,
|
||||
messageContains: [
|
||||
"Warning in the included options file ${convertPath('/a.yaml')}",
|
||||
": The file includes itself recursively.",
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../../dart/resolution/node_text_expectations.dart';
|
||||
import 'include_file_not_found_test.dart' as include_file_not_found;
|
||||
import 'include_file_warning_test.dart' as include_file_warning;
|
||||
import 'recursive_include_file_test.dart' as recursive_include_file;
|
||||
@@ -13,5 +14,6 @@ main() {
|
||||
include_file_not_found.main();
|
||||
include_file_warning.main();
|
||||
recursive_include_file.main();
|
||||
defineReflectiveTests(UpdateNodeTextExpectations);
|
||||
});
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user