blob: f07be1c17c8aea5f19be3b02cfc29a2e3a6cb469 [file]
// 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:analyzer/src/dart/element/element.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'context_collection_resolution.dart';
import 'node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(PartDirectiveResolutionTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@reflectiveTest
class PartDirectiveResolutionTest extends PubPackageResolutionTest {
test_enclosingUnit() async {
newFile('$testPackageLibPath/a.dart', r'''
part of 'test.dart';
''');
var result = await resolveTestCodeWithDiagnostics(r'''
part 'a.dart';
''');
expect(
(result.findNode.part('part').partInclude! as PartIncludeImpl)
.libraryFragment,
same(result.findNode.unit.declaredFragment),
);
}
test_inLibrary_fileDoesNotExist() async {
var result = await resolveTestCodeWithDiagnostics(r'''
part 'a.dart';
// ^^^^^^^^
// [diag.uriDoesNotExist] Target of URI doesn't exist: 'package:test/a.dart'.
''');
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: SimpleStringLiteral
literal: 'a.dart'
semicolon: ;
partInclude: PartInclude
uri: DirectiveUriWithSource
source: package:test/a.dart
''');
}
test_inLibrary_fileDoesNotExist_generated() async {
await resolveTestCodeWithDiagnostics('''
part 'part.g.dart';
// ^^^^^^^^^^^^^
// [diag.uriHasNotBeenGenerated] Target of URI hasn't been generated: 'package:test/part.g.dart'.
''');
}
test_inLibrary_noRelativeUri() async {
var result = await resolveTestCodeWithDiagnostics(r'''
part ':net';
// ^^^^^^
// [diag.invalidUri] Invalid URI syntax: ':net'.
''');
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: SimpleStringLiteral
literal: ':net'
semicolon: ;
partInclude: PartInclude
uri: DirectiveUriWithRelativeUriString
relativeUriString: :net
''');
}
test_inLibrary_noRelativeUriStr() async {
var result = await resolveTestCodeWithDiagnostics(r'''
part '${'foo'}.dart';
// ^^^^^^^^^^^^^^^
// [diag.uriWithInterpolation] URIs can't use string interpolation.
''');
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: StringInterpolation
elements
InterpolationString
contents: '
InterpolationExpression
leftBracket: ${
expression: SimpleStringLiteral
literal: 'foo'
rightBracket: }
InterpolationString
contents: .dart'
staticType: String
stringValue: null
semicolon: ;
partInclude: PartInclude
uri: DirectiveUri
''');
}
test_inLibrary_noSource() async {
var result = await resolveTestCodeWithDiagnostics(r'''
part 'foo:bar';
// ^^^^^^^^^
// [diag.uriDoesNotExist] Target of URI doesn't exist: 'foo:bar'.
''');
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: SimpleStringLiteral
literal: 'foo:bar'
semicolon: ;
partInclude: PartInclude
uri: DirectiveUriWithRelativeUri
relativeUri: foo:bar
''');
}
test_inLibrary_withPart_partOfName() async {
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var results = await resolveFilesWithDiagnostics({
a: r'''
// @dart = 3.4
library my.lib;
part 'b.dart';
''',
b: r'''
// @dart = 3.4
part of my.lib;
''',
});
var result = results[a]!;
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: SimpleStringLiteral
literal: 'b.dart'
semicolon: ;
partInclude: PartInclude
uri: DirectiveUriWithUnit
uri: package:test/b.dart
''');
}
test_inLibrary_withPart_partOfName_preEnhancedParts() async {
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var results = await resolveFilesWithDiagnostics({
a: r'''
// @dart = 3.4
library my.lib;
part 'b.dart';
''',
b: r'''
// @dart = 3.4
part of my.lib;
''',
});
var result = results[a]!;
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: SimpleStringLiteral
literal: 'b.dart'
semicolon: ;
partInclude: PartInclude
uri: DirectiveUriWithUnit
uri: package:test/b.dart
''');
}
test_inLibrary_withPart_partOfName_preEnhancedParts_different() async {
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var results = await resolveFilesWithDiagnostics({
a: r'''
// @dart = 3.4
library foo;
part 'b.dart';
// ^^^^^^^^
// [diag.partOfDifferentLibrary] Expected this library to be part of 'foo', not 'bar'.
''',
b: r'''
// @dart = 3.4
part of bar;
''',
});
var result = results[a]!;
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: SimpleStringLiteral
literal: 'b.dart'
semicolon: ;
partInclude: PartInclude
uri: DirectiveUriWithSource
source: package:test/b.dart
''');
}
test_inLibrary_withPart_partOfUri() async {
newFile('$testPackageLibPath/a.dart', r'''
part of 'test.dart';
''');
var result = await resolveTestCodeWithDiagnostics(r'''
part 'a.dart';
''');
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: SimpleStringLiteral
literal: 'a.dart'
semicolon: ;
partInclude: PartInclude
uri: DirectiveUriWithUnit
uri: package:test/a.dart
''');
}
test_inLibrary_withPart_partOfUri_different() async {
newFile('$testPackageLibPath/a.dart', r'''
part of 'x.dart';
''');
var result = await resolveTestCodeWithDiagnostics(r'''
part 'a.dart';
// ^^^^^^^^
// [diag.partOfDifferentLibrary] Expected this library to be part of 'package:test/test.dart', not 'package:test/a.dart'.
''');
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: SimpleStringLiteral
literal: 'a.dart'
semicolon: ;
partInclude: PartInclude
uri: DirectiveUriWithSource
source: package:test/a.dart
''');
}
test_inLibrary_withPart_partOfUri_packageBuild_generated() async {
var packageName = 'test';
newPubspecYamlFile(testPackageRootPath, 'name: $packageName');
var testPackageGeneratedPath =
'$testPackageRootPath/.dart_tool/build/generated';
newFile('$testPackageGeneratedPath/$packageName/lib/foo.g.dart', '''
part of 'foo.dart';
''');
var foo = getFile('$testPackageRootPath/lib/foo.dart');
var result = await resolveFileWithDiagnostics(foo, '''
part 'foo.g.dart';
''');
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: SimpleStringLiteral
literal: 'foo.g.dart'
semicolon: ;
partInclude: PartInclude
uri: DirectiveUriWithUnit
uri: package:test/foo.g.dart
''');
}
test_inLibrary_withSource_notPart_library() async {
newFile('$testPackageLibPath/a.dart', '');
var result = await resolveTestCodeWithDiagnostics(r'''
part 'a.dart';
// ^^^^^^^^
// [diag.partOfNonPart] The included part 'package:test/a.dart' must have a part-of directive.
''');
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: SimpleStringLiteral
literal: 'a.dart'
semicolon: ;
partInclude: PartInclude
uri: DirectiveUriWithSource
source: package:test/a.dart
''');
}
test_inPart_fileDoesNotExist() async {
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var results = await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
part 'c.dart';
// ^^^^^^^^
// [diag.uriDoesNotExist] Target of URI doesn't exist: 'package:test/c.dart'.
''',
});
var result = results[b]!;
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: SimpleStringLiteral
literal: 'c.dart'
semicolon: ;
partInclude: PartInclude
uri: DirectiveUriWithSource
source: package:test/c.dart
''');
}
test_inPart_noRelativeUri() async {
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var results = await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
part ':net';
// ^^^^^^
// [diag.invalidUri] Invalid URI syntax: ':net'.
''',
});
var result = results[b]!;
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: SimpleStringLiteral
literal: ':net'
semicolon: ;
partInclude: PartInclude
uri: DirectiveUriWithRelativeUriString
relativeUriString: :net
''');
}
test_inPart_noRelativeUriStr() async {
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var results = await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
part '${'foo'}.dart';
// ^^^^^^^^^^^^^^^
// [diag.uriWithInterpolation] URIs can't use string interpolation.
''',
});
var result = results[b]!;
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: StringInterpolation
elements
InterpolationString
contents: '
InterpolationExpression
leftBracket: ${
expression: SimpleStringLiteral
literal: 'foo'
rightBracket: }
InterpolationString
contents: .dart'
staticType: String
stringValue: null
semicolon: ;
partInclude: PartInclude
uri: DirectiveUri
''');
}
test_inPart_noSource() async {
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var results = await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
part 'foo:bar';
// ^^^^^^^^^
// [diag.uriDoesNotExist] Target of URI doesn't exist: 'foo:bar'.
''',
});
var result = results[b]!;
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: SimpleStringLiteral
literal: 'foo:bar'
semicolon: ;
partInclude: PartInclude
uri: DirectiveUriWithRelativeUri
relativeUri: foo:bar
''');
}
test_inPart_withPart_partOfName() async {
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var c = getFile('$testPackageLibPath/c.dart');
var results = await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
part 'c.dart';
''',
c: r'''
part of my.lib;
// ^^^^^^
// [diag.partOfName] The 'part of' directive can't use a name with the enhanced-parts feature.
''',
});
// We already reported an error above.
var result = results[b]!;
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: SimpleStringLiteral
literal: 'c.dart'
semicolon: ;
partInclude: PartInclude
uri: DirectiveUriWithSource
source: package:test/c.dart
''');
}
test_inPart_withPart_partOfUri() async {
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var c = getFile('$testPackageLibPath/c.dart');
var results = await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
part 'c.dart';
''',
c: r'''
part of 'b.dart';
''',
});
var result = results[b]!;
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: SimpleStringLiteral
literal: 'c.dart'
semicolon: ;
partInclude: PartInclude
uri: DirectiveUriWithUnit
uri: package:test/c.dart
''');
}
test_inPart_withPart_partOfUri_different() async {
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var c = getFile('$testPackageLibPath/c.dart');
var results = await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
part 'c.dart';
// ^^^^^^^^
// [diag.partOfDifferentLibrary] Expected this library to be part of 'package:test/b.dart', not 'package:test/c.dart'.
''',
c: r'''
part of 'a.dart';
''',
});
var result = results[b]!;
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: SimpleStringLiteral
literal: 'c.dart'
semicolon: ;
partInclude: PartInclude
uri: DirectiveUriWithSource
source: package:test/c.dart
''');
}
test_inPart_withSource_notPart_library() async {
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var c = getFile('$testPackageLibPath/c.dart');
var results = await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
part 'c.dart';
// ^^^^^^^^
// [diag.partOfNonPart] The included part 'package:test/c.dart' must have a part-of directive.
''',
c: '',
});
var result = results[b]!;
var node = result.findNode.singlePartDirective;
assertResolvedNodeText(node, r'''
PartDirective
partKeyword: part
uri: SimpleStringLiteral
literal: 'c.dart'
semicolon: ;
partInclude: PartInclude
uri: DirectiveUriWithSource
source: package:test/c.dart
''');
}
}