| // 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<String, int>')); |
| }); |
| |
| 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<int>.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<String>.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<String>.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)')); |
| }); |
| }); |
| } |