blob: 9821f064d64eccd21c4a0056f045567e37d7914f [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:analyzer/file_system/memory_file_system.dart';
import 'package:dartdoc/src/model/model.dart';
import 'package:dartdoc/src/package_config_provider.dart';
import 'package:dartdoc/src/package_meta.dart';
import 'package:test/test.dart';
import 'src/test_descriptor_utils.dart' as d;
import 'src/utils.dart';
void main() {
const libraryName = 'constant_values';
late PackageMetaProvider packageMetaProvider;
late MemoryResourceProvider resourceProvider;
late FakePackageConfigProvider packageConfigProvider;
late String packagePath;
Future<void> setUpPackage(
String name, {
String? pubspec,
String? analysisOptions,
}) async {
packagePath = await d.createPackage(
name,
pubspec: pubspec,
analysisOptions: analysisOptions,
resourceProvider: resourceProvider,
);
packageConfigProvider =
getTestPackageConfigProvider(packageMetaProvider.defaultSdkDir.path);
packageConfigProvider.addPackageToConfigFor(
packagePath, name, Uri.file('$packagePath/'));
}
Future<Library> bootPackageWithLibrary(String libraryContent) async {
await d.dir('lib', [
d.file('lib.dart', '''
library $libraryName;
$libraryContent
'''),
]).createInMemory(resourceProvider, packagePath);
var packageGraph = await bootBasicPackage(
packagePath,
packageMetaProvider,
packageConfigProvider,
);
return packageGraph.libraries.named(libraryName);
}
group('constructor-tearoffs', () {
const libraryName = 'constructor_tearoffs';
setUp(() async {
packageMetaProvider = testPackageMetaProvider;
resourceProvider =
packageMetaProvider.resourceProvider as MemoryResourceProvider;
await setUpPackage(
libraryName,
pubspec: '''
name: constructor_tearoffs
version: 0.0.1
environment:
sdk: '>=2.15.0-0 <3.0.0'
''',
analysisOptions: '''
analyzer:
enable-experiment:
- constructor-tearoffs
''',
);
});
test('non-generic function reference', () async {
var library = await bootPackageWithLibrary('''
void func() {}
const aFunc = func;
''');
var aFuncConstant = library.constants.named('aFunc');
expect(aFuncConstant.constantValue, equals('func'));
});
test('generic function reference', () async {
var library = await bootPackageWithLibrary('''
void funcTypeParams<T extends String, U extends num>(
T something, U different) {}
const aFuncParams = funcTypeParams;
''');
var aFuncParamsConstant = library.constants.named('aFuncParams');
expect(aFuncParamsConstant.constantValue, equals('funcTypeParams'));
});
test('generic function reference w/ type args', () async {
var library = await bootPackageWithLibrary('''
void funcTypeParams<T extends String, U extends num>(
T something, U different) {}
const aFuncWithArgs = funcTypeParams<String, int>;
''');
var aFuncWithArgs = library.constants.named('aFuncWithArgs');
expect(aFuncWithArgs.constantValue,
equals('funcTypeParams&lt;String, int&gt;'));
});
test('named constructor reference', () async {
var library = await bootPackageWithLibrary('''
class F<T> {
F.alternative();
}
const aTearOffNamedConstructor = F.alternative;
''');
var aTearOffNamedConstructor =
library.constants.named('aTearOffNamedConstructor');
expect(aTearOffNamedConstructor.constantValue, equals('F.alternative'));
});
test('named constructor reference w/ type args', () async {
var library = await bootPackageWithLibrary('''
class F<T> {
F.alternative();
}
const aTearOffNamedConstructorArgs = F<int>.alternative;
''');
var aTearOffNamedConstructorArgs =
library.constants.named('aTearOffNamedConstructorArgs');
expect(aTearOffNamedConstructorArgs.constantValue,
equals('F&lt;int&gt;.alternative'));
});
test('unnamed constructor reference', () async {
var library = await bootPackageWithLibrary('''
class F<T> {
F();
}
const aTearOffUnnamedConstructor = F.new;
''');
var aTearOffUnnamedConstructor =
library.constants.named('aTearOffUnnamedConstructor');
expect(aTearOffUnnamedConstructor.constantValue, equals('F.new'));
});
test('unnamed constructor reference w/ type args', () async {
var library = await bootPackageWithLibrary('''
class F<T> {
F();
}
const aTearOffUnnamedConstructorArgs = F<String>.new;
''');
var aTearOffUnnamedConstructorArgs =
library.constants.named('aTearOffUnnamedConstructorArgs');
expect(aTearOffUnnamedConstructorArgs.constantValue,
equals('F&lt;String&gt;.new'));
});
test('unnamed typedef constructor reference', () async {
var library = await bootPackageWithLibrary('''
class F<T> {
F();
}
const aTearOffUnnamedConstructorTypedef = Fstring.new;
''');
var aTearOffUnnamedConstructorTypedef =
library.constants.named('aTearOffUnnamedConstructorTypedef');
expect(aTearOffUnnamedConstructorTypedef.constantValue,
equals('Fstring.new'));
});
test('unnamed typedef constructor reference w/ type args', () async {
var library = await bootPackageWithLibrary('''
class F<T> {
F();
}
const aTearOffUnnamedConstructorArgsTypedef = Ft<String>.new;
''');
var aTearOffUnnamedConstructorArgsTypedef =
library.constants.named('aTearOffUnnamedConstructorArgsTypedef');
expect(aTearOffUnnamedConstructorArgsTypedef.constantValue,
equals('Ft&lt;String&gt;.new'));
});
});
group('named-arguments-anywhere', skip: !namedArgumentsAnywhereAllowed, () {
const placeholder = '%%__HTMLBASE_dartdoc_internal__%%';
const libraryName = 'constant_values';
const linkPrefix = '$placeholder$libraryName';
setUp(() async {
packageMetaProvider = testPackageMetaProvider;
resourceProvider =
packageMetaProvider.resourceProvider as MemoryResourceProvider;
await setUpPackage(
libraryName,
pubspec: '''
name: named_arguments_anywhere
version: 0.0.1
environment:
sdk: '>=2.17.0-0 <3.0.0'
''',
analysisOptions: '''
analyzer:
enable-experiment:
- named-arguments-anywhere
''',
);
});
test('named parameters in a const invocation value can be specified last',
() async {
var library = await bootPackageWithLibrary('''
class C {
const C(int a, int b, {required int c, required int d});
}
const p = C(1, 2, c: 3, d: 4);
''');
var pConst = library.constants.named('p');
expect(pConst.constantValue,
equals('<a href="$linkPrefix/C/C.html">C</a>(1, 2, c: 3, d: 4)'));
});
test(
'named parameters in a const invocation value can be specified anywhere',
() async {
var library = await bootPackageWithLibrary('''
class C {
const C(int a, int b, {required int c, required int d});
}
const q = C(1, c: 2, 3, d: 4);
''');
var qConst = library.constants.named('q');
expect(qConst.constantValue,
equals('<a href="$linkPrefix/C/C.html">C</a>(1, c: 2, 3, d: 4)'));
});
test('named parameters in a const invocation value can be specified first',
() async {
var library = await bootPackageWithLibrary('''
class C {
const C(int a, int b, {required int c, required int d});
}
const r = C(c: 1, d: 2, 3, 4);
''');
var rConst = library.constants.named('r');
expect(rConst.constantValue,
equals('<a href="$linkPrefix/C/C.html">C</a>(c: 1, d: 2, 3, 4)'));
});
});
}