From 504a8493bbc618fc146c470565dcf42c800d317d Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Tue, 11 Jan 2022 21:58:25 -0800 Subject: [PATCH 1/5] Add tests for named arguments anywhere in constant --- test/end2end/model_special_cases_test.dart | 49 +++++++++++++++++++ .../analysis_options.yaml | 1 + .../lib/named_arguments_anywhere.dart | 15 ++++++ 3 files changed, 65 insertions(+) create mode 100644 testing/test_package_experiments/lib/named_arguments_anywhere.dart diff --git a/test/end2end/model_special_cases_test.dart b/test/end2end/model_special_cases_test.dart index 766e8a171b..007defdb42 100644 --- a/test/end2end/model_special_cases_test.dart +++ b/test/end2end/model_special_cases_test.dart @@ -273,6 +273,55 @@ void main() { // equals('Ft<String>.new')); }); }, skip: !_constructorTearoffsAllowed.allows(utils.platformVersion)); + + group('named-arguments-anywhere', () { + Library namedArgumentsAnywhere; + + setUpAll(() async { + namedArgumentsAnywhere = (await _testPackageGraphExperiments) + .libraries + .firstWhere((l) => l.name == 'named_arguments_anywhere'); + }); + + test( + 'named parameters in a const invocation value can be specified ' + 'last', () { + var p = + namedArgumentsAnywhere.constants.firstWhere((c) => c.name == 'p'); + + expect( + p.constantValue, + equals( + 'C' + '(1, 2, c: 3, d: 4)')); + }); + + test( + 'named parameters in a const invocation value can be specified ' + 'anywhere', () { + var q = + namedArgumentsAnywhere.constants.firstWhere((c) => c.name == 'q'); + + expect( + q.constantValue, + equals( + 'C' + '(1, c: 2, 3, d: 4)')); + }); + + test( + 'named parameters in a const invocation value can be specified ' + 'first', () { + var r = + namedArgumentsAnywhere.constants.firstWhere((c) => c.name == 'r'); + + expect( + r.constantValue, + equals( + 'C' + '(c: 1, d: 2, 3, 4)')); + }); + }, skip: !_constructorTearoffsAllowed.allows(utils.platformVersion)); }); group('HTML is sanitized when enabled', () { diff --git a/testing/test_package_experiments/analysis_options.yaml b/testing/test_package_experiments/analysis_options.yaml index 8f22a4573b..eb1d65a5c5 100644 --- a/testing/test_package_experiments/analysis_options.yaml +++ b/testing/test_package_experiments/analysis_options.yaml @@ -6,3 +6,4 @@ analyzer: - triple-shift - generic-metadata - constructor-tearoffs + - named-arguments-anywhere diff --git a/testing/test_package_experiments/lib/named_arguments_anywhere.dart b/testing/test_package_experiments/lib/named_arguments_anywhere.dart new file mode 100644 index 0000000000..ee4b66221d --- /dev/null +++ b/testing/test_package_experiments/lib/named_arguments_anywhere.dart @@ -0,0 +1,15 @@ +// 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. + +library named_arguments_anywhere; + +class C { + const C(int a, int b, {required int c, required int d}); +} + +const p = C(1, 2, c: 3, d: 4); + +const q = C(1, c: 2, 3, d: 4); + +const r = C(c: 1, d: 2, 3, 4); From 5dc2d7ca592276840e3ce4a09ebe6ad724996b75 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Tue, 11 Jan 2022 22:17:24 -0800 Subject: [PATCH 2/5] Prevent bad testing --- test/end2end/model_special_cases_test.dart | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/end2end/model_special_cases_test.dart b/test/end2end/model_special_cases_test.dart index 007defdb42..fb646f7638 100644 --- a/test/end2end/model_special_cases_test.dart +++ b/test/end2end/model_special_cases_test.dart @@ -76,6 +76,12 @@ void main() { final _constructorTearoffsAllowed = VersionRange(min: Version.parse('2.15.0-0'), includeMin: true); + // We can not use ExperimentalFeature.releaseVersion or even + // ExperimentalFeature.experimentalReleaseVersion as these are set to null + // even when partial analyzer implementations are available. + final _namedArgumentsAnywhereAllowed = + VersionRange(min: Version.parse('2.17.0-0'), includeMin: true); + // Experimental features not yet enabled by default. Move tests out of this // block when the feature is enabled by default. group('Experiments', () { @@ -321,7 +327,7 @@ void main() { 'C' '(c: 1, d: 2, 3, 4)')); }); - }, skip: !_constructorTearoffsAllowed.allows(utils.platformVersion)); + }, skip: !_namedArgumentsAnywhereAllowed.allows(utils.platformVersion)); }); group('HTML is sanitized when enabled', () { From ac721bcb27d38f937ae6fdbdf682553c8c192ae3 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Sat, 15 Jan 2022 12:08:07 -0800 Subject: [PATCH 3/5] 2.17 --- testing/test_package_experiments/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/test_package_experiments/pubspec.yaml b/testing/test_package_experiments/pubspec.yaml index fc0fc1ed86..5224b9cac3 100644 --- a/testing/test_package_experiments/pubspec.yaml +++ b/testing/test_package_experiments/pubspec.yaml @@ -1,5 +1,5 @@ name: test_package_experiments version: 0.0.1 environment: - sdk: '>=2.15.0-0 <3.0.0' + sdk: '>=2.17.0-0 <3.0.0' description: Experimental flags are tested here. From b3535eba7cc1acb47eeffd5c58b6f0b75d7a807e Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Sat, 15 Jan 2022 12:14:16 -0800 Subject: [PATCH 4/5] fix test --- test/end2end/model_special_cases_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/end2end/model_special_cases_test.dart b/test/end2end/model_special_cases_test.dart index 1028d0869c..0c21721965 100644 --- a/test/end2end/model_special_cases_test.dart +++ b/test/end2end/model_special_cases_test.dart @@ -276,7 +276,7 @@ void main() { }, skip: !_constructorTearoffsAllowed.allows(utils.platformVersion)); group('named-arguments-anywhere', () { - Library namedArgumentsAnywhere; + late Library namedArgumentsAnywhere; setUpAll(() async { namedArgumentsAnywhere = (await _testPackageGraphExperiments) From c03d4c241e5c684931eea2463f8f2cea51ee4d46 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Sun, 16 Jan 2022 08:11:40 -0800 Subject: [PATCH 5/5] Use test_descriptor for constant tests of experiments --- pubspec.yaml | 1 + test/constant_values_test.dart | 224 ++++++++++++++++++ test/end2end/model_special_cases_test.dart | 102 -------- .../analysis_options.yaml | 1 - .../lib/constructor_tearoffs.dart | 17 -- .../lib/named_arguments_anywhere.dart | 15 -- testing/test_package_experiments/pubspec.yaml | 2 +- 7 files changed, 226 insertions(+), 136 deletions(-) create mode 100644 test/constant_values_test.dart delete mode 100644 testing/test_package_experiments/lib/named_arguments_anywhere.dart diff --git a/pubspec.yaml b/pubspec.yaml index b38570a663..8808dc7434 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -37,6 +37,7 @@ dev_dependencies: http: ^0.13.3 lints: ^1.0.1 test: ^1.19.0 + test_descriptor: ^2.0.0 executables: dartdoc: null diff --git a/test/constant_values_test.dart b/test/constant_values_test.dart new file mode 100644 index 0000000000..9ab6800e2c --- /dev/null +++ b/test/constant_values_test.dart @@ -0,0 +1,224 @@ +// 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:async/async.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:pub_semver/pub_semver.dart'; +import 'package:test/test.dart'; +import 'package:test_descriptor/test_descriptor.dart' as d; + +import 'src/utils.dart' as utils; + +void main() { + // We can not use ExperimentalFeature.releaseVersion or even + // ExperimentalFeature.experimentalReleaseVersion as these are set to null + // even when partial analyzer implementations are available, and are often + // set too high after release. + final constructorTearoffsAllowed = + VersionRange(min: Version.parse('2.15.0-0'), includeMin: true); + + // We can not use ExperimentalFeature.releaseVersion or even + // ExperimentalFeature.experimentalReleaseVersion as these are set to null + // even when partial analyzer implementations are available. + final namedArgumentsAnywhereAllowed = + VersionRange(min: Version.parse('2.17.0-0'), includeMin: true); + + group('constructor-tearoffs', () { + late Library library; + const libraryName = 'constructor_tearoffs'; + + final packageGraphMemo = AsyncMemoizer(); + Future bootstrapPackageGraph() => + packageGraphMemo.runOnce(() => utils.bootBasicPackage( + d.dir(libraryName).io.path, + pubPackageMetaProvider, + PhysicalPackageConfigProvider(), + additionalArguments: ['--no-link-to-remote'])); + + setUp(() async { + await d.dir(libraryName, [ + d.file('pubspec.yaml', ''' +name: constructor_tearoffs +version: 0.0.1 +environment: + sdk: '>=2.15.0-0 <3.0.0' +'''), + d.file('analysis_options.yaml', ''' +analyzer: + enable-experiment: + - constructor-tearoffs +'''), + d.dir('lib', [ + d.file('lib.dart', ''' +library $libraryName; + +class F { + F(); + + F.alternative(); +} + +typedef Ft = F; + +void func() {} +void funcTypeParams( + T something, U different) {} + +const aFunc = func; +const aFuncParams = funcTypeParams; +const aFuncWithArgs = funcTypeParams; +const aTearOffUnnamedConstructor = F.new; +const aTearOffUnnamedConstructorArgs = F.new; +const aTearOffUnnamedConstructorTypedef = Fstring.new; +const aTearOffUnnamedConstructorArgsTypedef = Ft.new; +const aTearOffNamedConstructor = F.alternative; +const aTearOffNamedConstructorArgs = F.alternative; +'''), + ]), + ]).create(); + + library = (await bootstrapPackageGraph()) + .libraries + .firstWhere((l) => l.name == libraryName); + }); + + test('non-generic function reference', () { + var aFuncConstant = + library.constants.firstWhere((c) => c.name == 'aFunc'); + expect(aFuncConstant.constantValue, equals('func')); + }); + + test('generic function reference', () { + var aFuncParamsConstant = + library.constants.firstWhere((c) => c.name == 'aFuncParams'); + expect(aFuncParamsConstant.constantValue, equals('funcTypeParams')); + }); + + test('generic function reference w/ type args', () { + var aFuncWithArgs = + library.constants.firstWhere((c) => c.name == 'aFuncWithArgs'); + expect(aFuncWithArgs.constantValue, + equals('funcTypeParams<String, int>')); + }); + + test('named constructor reference', () { + var aTearOffNamedConstructor = library.constants + .firstWhere((c) => c.name == 'aTearOffNamedConstructor'); + expect(aTearOffNamedConstructor.constantValue, equals('F.alternative')); + }); + + test('named constructor reference w/ type args', () { + var aTearOffNamedConstructorArgs = library.constants + .firstWhere((c) => c.name == 'aTearOffNamedConstructorArgs'); + expect(aTearOffNamedConstructorArgs.constantValue, + equals('F<int>.alternative')); + }); + + test('unnamed constructor reference', () { + var aTearOffUnnamedConstructor = library.constants + .firstWhere((c) => c.name == 'aTearOffUnnamedConstructor'); + expect(aTearOffUnnamedConstructor.constantValue, equals('F.new')); + }); + + test('unnamed constructor reference w/ type args', () { + var aTearOffUnnamedConstructorArgs = library.constants + .firstWhere((c) => c.name == 'aTearOffUnnamedConstructorArgs'); + expect(aTearOffUnnamedConstructorArgs.constantValue, + equals('F<String>.new')); + }); + + test('unnamed typedef constructor reference', () { + var aTearOffUnnamedConstructorTypedef = library.constants + .firstWhere((c) => c.name == 'aTearOffUnnamedConstructorTypedef'); + expect(aTearOffUnnamedConstructorTypedef.constantValue, + equals('Fstring.new')); + }); + + test('unnamed typedef constructor reference w/ type args', () { + var aTearOffUnnamedConstructorArgsTypedef = library.constants + .firstWhere((c) => c.name == 'aTearOffUnnamedConstructorArgsTypedef'); + expect(aTearOffUnnamedConstructorArgsTypedef.constantValue, + equals('Ft<String>.new')); + }); + + test('constant rendering', () {}, skip: true); + }, skip: !constructorTearoffsAllowed.allows(utils.platformVersion)); + + group('named-arguments-anywhere', () { + late Library library; + const placeholder = '%%__HTMLBASE_dartdoc_internal__%%'; + const libraryName = 'named_arguments_anywhere'; + const linkPrefix = '$placeholder$libraryName'; + + final _testPackageGraphExperimentsMemo = AsyncMemoizer(); + Future bootstrapPackageGraph() => + _testPackageGraphExperimentsMemo.runOnce(() => utils.bootBasicPackage( + d.dir(libraryName).io.path, + pubPackageMetaProvider, + PhysicalPackageConfigProvider(), + additionalArguments: ['--no-link-to-remote'])); + + setUp(() async { + await d.dir(libraryName, [ + d.file('pubspec.yaml', ''' +name: named_arguments_anywhere +version: 0.0.1 +environment: + sdk: '>=2.17.0-0 <3.0.0' +'''), + d.file('analysis_options.yaml', ''' +analyzer: + enable-experiment: + - named-arguments-anywhere +'''), + d.dir('lib', [ + d.file('lib.dart', ''' +library $libraryName; + +class C { + const C(int a, int b, {required int c, required int d}); +} + +const p = C(1, 2, c: 3, d: 4); + +const q = C(1, c: 2, 3, d: 4); + +const r = C(c: 1, d: 2, 3, 4); +'''), + ]), + ]).create(); + + library = (await bootstrapPackageGraph()) + .libraries + .firstWhere((l) => l.name == libraryName); + }); + + test('named parameters in a const invocation value can be specified last', + () async { + var pConst = library.constants.firstWhere((c) => c.name == 'p'); + + expect(pConst.constantValue, + equals('C(1, 2, c: 3, d: 4)')); + }); + + test( + 'named parameters in a const invocation value can be specified anywhere', + () async { + var qConst = library.constants.firstWhere((c) => c.name == 'q'); + + expect(qConst.constantValue, + equals('C(1, c: 2, 3, d: 4)')); + }); + + test('named parameters in a const invocation value can be specified first', + () async { + var rConst = library.constants.firstWhere((c) => c.name == 'r'); + + expect(rConst.constantValue, + equals('C(c: 1, d: 2, 3, 4)')); + }); + }, skip: !namedArgumentsAnywhereAllowed.allows(utils.platformVersion)); +} diff --git a/test/end2end/model_special_cases_test.dart b/test/end2end/model_special_cases_test.dart index 0c21721965..71c8273d03 100644 --- a/test/end2end/model_special_cases_test.dart +++ b/test/end2end/model_special_cases_test.dart @@ -67,12 +67,6 @@ void main() { final _constructorTearoffsAllowed = VersionRange(min: Version.parse('2.15.0-0'), includeMin: true); - // We can not use ExperimentalFeature.releaseVersion or even - // ExperimentalFeature.experimentalReleaseVersion as these are set to null - // even when partial analyzer implementations are available. - final _namedArgumentsAnywhereAllowed = - VersionRange(min: Version.parse('2.17.0-0'), includeMin: true); - // Experimental features not yet enabled by default. Move tests out of this // block when the feature is enabled by default. group('Experiments', () { @@ -226,103 +220,7 @@ void main() { expect(referenceLookup(A, 'new'), equals(MatchingLinkResult(null))); expect(referenceLookup(At, 'new'), equals(MatchingLinkResult(null))); }); - - test('constant rendering', () { - TopLevelVariable aFunc, - aFuncParams, - aTearOffDefaultConstructor, - aTearOffNonDefaultConstructor, - aTearOffNonDefaultConstructorInt, - aTearOffDefaultConstructorArgs; - TopLevelVariable aTearOffDefaultConstructorTypedef; - aFunc = - constructorTearoffs.constants.firstWhere((c) => c.name == 'aFunc'); - aFuncParams = constructorTearoffs.constants - .firstWhere((c) => c.name == 'aFuncParams'); - aTearOffDefaultConstructor = constructorTearoffs.constants - .firstWhere((c) => c.name == 'aTearOffDefaultConstructor'); - aTearOffNonDefaultConstructor = constructorTearoffs.constants - .firstWhere((c) => c.name == 'aTearOffNonDefaultConstructor'); - aTearOffNonDefaultConstructorInt = constructorTearoffs.constants - .firstWhere((c) => c.name == 'aTearOffNonDefaultConstructorInt'); - aTearOffDefaultConstructorArgs = constructorTearoffs.constants - .firstWhere((c) => c.name == 'aTearOffDefaultConstructorArgs'); - aTearOffDefaultConstructorTypedef = constructorTearoffs.constants - .firstWhere((c) => c.name == 'aTearOffDefaultConstructorTypedef'); - - expect(aFunc.constantValue, equals('func')); - expect(aFuncParams.constantValue, equals('funcTypeParams')); - var aFuncWithArgs = constructorTearoffs.constants - .firstWhere((c) => c.name == 'aFuncWithArgs'); - expect(aFuncWithArgs.constantValue, - equals('funcTypeParams<String, int>')); - - expect(aTearOffDefaultConstructor.constantValue, equals('F.new')); - expect(aTearOffNonDefaultConstructor.constantValue, - equals('F.alternative')); - expect(aTearOffNonDefaultConstructorInt.constantValue, - equals('F<int>.alternative')); - expect(aTearOffDefaultConstructorArgs.constantValue, - equals('F<String>.new')); - - expect(aTearOffDefaultConstructorTypedef.constantValue, - equals('Fstring.new')); - var aTearOffDefaultConstructorArgsTypedef = - constructorTearoffs.constants.firstWhere( - (c) => c.name == 'aTearOffDefaultConstructorArgsTypedef'); - expect(aTearOffDefaultConstructorArgsTypedef.constantValue, - equals('Ft<String>.new')); - }); }, skip: !_constructorTearoffsAllowed.allows(utils.platformVersion)); - - group('named-arguments-anywhere', () { - late Library namedArgumentsAnywhere; - - setUpAll(() async { - namedArgumentsAnywhere = (await _testPackageGraphExperiments) - .libraries - .firstWhere((l) => l.name == 'named_arguments_anywhere'); - }); - - test( - 'named parameters in a const invocation value can be specified ' - 'last', () { - var p = - namedArgumentsAnywhere.constants.firstWhere((c) => c.name == 'p'); - - expect( - p.constantValue, - equals( - 'C' - '(1, 2, c: 3, d: 4)')); - }); - - test( - 'named parameters in a const invocation value can be specified ' - 'anywhere', () { - var q = - namedArgumentsAnywhere.constants.firstWhere((c) => c.name == 'q'); - - expect( - q.constantValue, - equals( - 'C' - '(1, c: 2, 3, d: 4)')); - }); - - test( - 'named parameters in a const invocation value can be specified ' - 'first', () { - var r = - namedArgumentsAnywhere.constants.firstWhere((c) => c.name == 'r'); - - expect( - r.constantValue, - equals( - 'C' - '(c: 1, d: 2, 3, 4)')); - }); - }, skip: !_namedArgumentsAnywhereAllowed.allows(utils.platformVersion)); }); group('HTML is sanitized when enabled', () { diff --git a/testing/test_package_experiments/analysis_options.yaml b/testing/test_package_experiments/analysis_options.yaml index eb1d65a5c5..8f22a4573b 100644 --- a/testing/test_package_experiments/analysis_options.yaml +++ b/testing/test_package_experiments/analysis_options.yaml @@ -6,4 +6,3 @@ analyzer: - triple-shift - generic-metadata - constructor-tearoffs - - named-arguments-anywhere diff --git a/testing/test_package_experiments/lib/constructor_tearoffs.dart b/testing/test_package_experiments/lib/constructor_tearoffs.dart index eba4ef2280..a76476a1af 100644 --- a/testing/test_package_experiments/lib/constructor_tearoffs.dart +++ b/testing/test_package_experiments/lib/constructor_tearoffs.dart @@ -61,20 +61,3 @@ typedef NotAClass = Function; /// Mixins don't have constructors either, so disallow `M.new`. mixin M on C {} - -void func() {} -void funcTypeParams( - T something, U different) {} - -const aFunc = func; -const aFuncParams = funcTypeParams; -const aFuncWithArgs = funcTypeParams; - -const aTearOffDefaultConstructor = F.new; -const aTearOffNonDefaultConstructor = F.alternative; -const aTearOffNonDefaultConstructorInt = F.alternative; -const aTearOffDefaultConstructorArgs = F.new; - -const aTearOffDefaultConstructorTypedef = Fstring.new; - -const aTearOffDefaultConstructorArgsTypedef = Ft.new; diff --git a/testing/test_package_experiments/lib/named_arguments_anywhere.dart b/testing/test_package_experiments/lib/named_arguments_anywhere.dart deleted file mode 100644 index ee4b66221d..0000000000 --- a/testing/test_package_experiments/lib/named_arguments_anywhere.dart +++ /dev/null @@ -1,15 +0,0 @@ -// 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. - -library named_arguments_anywhere; - -class C { - const C(int a, int b, {required int c, required int d}); -} - -const p = C(1, 2, c: 3, d: 4); - -const q = C(1, c: 2, 3, d: 4); - -const r = C(c: 1, d: 2, 3, 4); diff --git a/testing/test_package_experiments/pubspec.yaml b/testing/test_package_experiments/pubspec.yaml index 5224b9cac3..fc0fc1ed86 100644 --- a/testing/test_package_experiments/pubspec.yaml +++ b/testing/test_package_experiments/pubspec.yaml @@ -1,5 +1,5 @@ name: test_package_experiments version: 0.0.1 environment: - sdk: '>=2.17.0-0 <3.0.0' + sdk: '>=2.15.0-0 <3.0.0' description: Experimental flags are tested here.