Move to setup-dart for CI Also enable and fix some good lints
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 2ac7525..71fdee6 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml
@@ -1,32 +1,51 @@ -name: Dart +name: CI on: - pull_request: + # Run on PRs and pushes to the default branch. push: - branches: - - master + branches: [ master ] + pull_request: + branches: [ master ] schedule: - # “At 00:00 (UTC) on Sunday.” - - cron: '0 0 * * 0' + - cron: "0 0 * * 0" + +env: + PUB_ENVIRONMENT: bot.github jobs: - build: + # Check code formatting and static analysis on a single OS (linux) + # against Dart dev and stable. + analyze: runs-on: ubuntu-latest - - container: - image: google/dart:beta - + strategy: + matrix: + sdk: [dev] steps: - uses: actions/checkout@v2 + - uses: dart-lang/setup-dart@v1.1 + with: + sdk: ${{ matrix.sdk }} + - id: install + run: dart pub get + - run: dart format --output=none --set-exit-if-changed . + if: always() && steps.install.outcome == 'success' + - run: dart analyze --fatal-infos + if: always() && steps.install.outcome == 'success' - - name: pub get - run: pub get - - - name: dart format - run: dart format --output=none --set-exit-if-changed . - - - name: dart analyze - run: dart analyze - - - name: dart test - run: dart test + test: + needs: analyze + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + sdk: [2.12.0, dev] + steps: + - uses: actions/checkout@v2 + - uses: dart-lang/setup-dart@v1.1 + with: + sdk: ${{ matrix.sdk }} + - id: install + run: dart pub get + - run: dart test --platform vm + if: always() && steps.install.outcome == 'success'
diff --git a/analysis_options.yaml b/analysis_options.yaml index 180004e..adb30b1 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml
@@ -1,7 +1,15 @@ +include: package:lints/recommended.yaml + analyzer: + strong-mode: + implicit-casts: false linter: rules: - always_declare_return_types - directives_ordering + - lines_longer_than_80_chars - public_member_api_docs + - slash_for_doc_comments + - unnecessary_const + - unnecessary_new
diff --git a/lib/test_reflective_loader.dart b/lib/test_reflective_loader.dart index 3528a43..db87681 100644 --- a/lib/test_reflective_loader.dart +++ b/lib/test_reflective_loader.dart
@@ -9,40 +9,29 @@ import 'package:test/test.dart' as test_package; -/** - * A marker annotation used to annotate test methods which are expected to fail - * when asserts are enabled. - */ -const _AssertFailingTest assertFailingTest = const _AssertFailingTest(); +/// A marker annotation used to annotate test methods which are expected to fail +/// when asserts are enabled. +const _AssertFailingTest assertFailingTest = _AssertFailingTest(); -/** - * A marker annotation used to annotate test methods which are expected to fail. - */ -const FailingTest failingTest = const FailingTest(); +/// A marker annotation used to annotate test methods which are expected to +/// fail. +const FailingTest failingTest = FailingTest(); -/** - * A marker annotation used to instruct dart2js to keep reflection information - * for the annotated classes. - */ -const _ReflectiveTest reflectiveTest = const _ReflectiveTest(); +/// A marker annotation used to instruct dart2js to keep reflection information +/// for the annotated classes. +const _ReflectiveTest reflectiveTest = _ReflectiveTest(); -/** - * A marker annotation used to annotate test methods that should be skipped. - */ -const SkippedTest skippedTest = const SkippedTest(); +/// A marker annotation used to annotate test methods that should be skipped. +const SkippedTest skippedTest = SkippedTest(); -/** - * A marker annotation used to annotate "solo" groups and tests. - */ -const _SoloTest soloTest = const _SoloTest(); +/// A marker annotation used to annotate "solo" groups and tests. +const _SoloTest soloTest = _SoloTest(); final List<_Group> _currentGroups = <_Group>[]; int _currentSuiteLevel = 0; String _currentSuiteName = ''; -/** - * Is `true` the application is running in the checked mode. - */ +/// Is `true` the application is running in the checked mode. final bool _isCheckedMode = () { try { assert(false); @@ -52,13 +41,11 @@ } }(); -/** - * Run the [define] function parameter that calls [defineReflectiveTests] to - * add normal and "solo" tests, and also calls [defineReflectiveSuite] to - * create embedded suites. If the current suite is the top-level one, perform - * check for "solo" groups and tests, and run all or only "solo" items. - */ -void defineReflectiveSuite(void define(), {String name = ''}) { +/// Run the [define] function parameter that calls [defineReflectiveTests] to +/// add normal and "solo" tests, and also calls [defineReflectiveSuite] to +/// create embedded suites. If the current suite is the top-level one, perform +/// check for "solo" groups and tests, and run all or only "solo" items. +void defineReflectiveSuite(void Function() define, {String name = ''}) { String groupName = _currentSuiteName; _currentSuiteLevel++; try { @@ -71,32 +58,30 @@ _addTestsIfTopLevelSuite(); } -/** - * Runs test methods existing in the given [type]. - * - * If there is a "solo" test method in the top-level suite, only "solo" methods - * are run. - * - * If there is a "solo" test type, only its test methods are run. - * - * Otherwise all tests methods of all test types are run. - * - * Each method is run with a new instance of [type]. - * So, [type] should have a default constructor. - * - * If [type] declares method `setUp`, it methods will be invoked before any test - * method invocation. - * - * If [type] declares method `tearDown`, it will be invoked after any test - * method invocation. If method returns [Future] to test some asynchronous - * behavior, then `tearDown` will be invoked in `Future.complete`. - */ +/// Runs test methods existing in the given [type]. +/// +/// If there is a "solo" test method in the top-level suite, only "solo" methods +/// are run. +/// +/// If there is a "solo" test type, only its test methods are run. +/// +/// Otherwise all tests methods of all test types are run. +/// +/// Each method is run with a new instance of [type]. +/// So, [type] should have a default constructor. +/// +/// If [type] declares method `setUp`, it methods will be invoked before any +/// test method invocation. +/// +/// If [type] declares method `tearDown`, it will be invoked after any test +/// method invocation. If method returns [Future] to test some asynchronous +/// behavior, then `tearDown` will be invoked in `Future.complete`. void defineReflectiveTests(Type type) { ClassMirror classMirror = reflectClass(type); if (!classMirror.metadata.any((InstanceMirror annotation) => annotation.type.reflectedType == _ReflectiveTest)) { String name = MirrorSystem.getName(classMirror.qualifiedName); - throw new Exception('Class $name must have annotation "@reflectiveTest" ' + throw Exception('Class $name must have annotation "@reflectiveTest" ' 'in order to be run by runReflectiveTests.'); } @@ -104,7 +89,7 @@ { bool isSolo = _hasAnnotationInstance(classMirror, soloTest); String className = MirrorSystem.getName(classMirror.simpleName); - group = new _Group(isSolo, _combineNames(_currentSuiteName, className)); + group = _Group(isSolo, _combineNames(_currentSuiteName, className)); _currentGroups.add(group); } @@ -162,9 +147,7 @@ _addTestsIfTopLevelSuite(); } -/** - * If the current suite is the top-level one, add tests to the `test` package. - */ +/// If the current suite is the top-level one, add tests to the `test` package. void _addTestsIfTopLevelSuite() { if (_currentSuiteLevel == 0) { void runTests({required bool allGroups, required bool allTests}) { @@ -191,10 +174,8 @@ } } -/** - * Return the combination of the [base] and [addition] names. - * If any other two is `null`, then the other one is returned. - */ +/// Return the combination of the [base] and [addition] names. +/// If any other two is `null`, then the other one is returned. String _combineNames(String base, String addition) { if (base.isEmpty) { return addition; @@ -229,33 +210,33 @@ Future<Object?> _invokeSymbolIfExists( InstanceMirror instanceMirror, Symbol symbol) { - Object? invocationResult = null; + Object? invocationResult; InstanceMirror? closure; try { closure = instanceMirror.getField(symbol); - } on NoSuchMethodError {} + } on NoSuchMethodError { + // noop + } if (closure is ClosureMirror) { invocationResult = closure.apply([]).reflectee; } - return new Future.value(invocationResult); + return Future.value(invocationResult); } -/** - * Run a test that is expected to fail, and confirm that it fails. - * - * This properly handles the following cases: - * - The test fails by throwing an exception - * - The test returns a future which completes with an error. - * - An exception is thrown to the zone handler from a timer task. - */ +/// Run a test that is expected to fail, and confirm that it fails. +/// +/// This properly handles the following cases: +/// - The test fails by throwing an exception +/// - The test returns a future which completes with an error. +/// - An exception is thrown to the zone handler from a timer task. Future<Object?>? _runFailingTest(ClassMirror classMirror, Symbol symbol) { bool passed = false; return runZonedGuarded(() { - return new Future.sync(() => _runTest(classMirror, symbol)).then<void>((_) { + return Future.sync(() => _runTest(classMirror, symbol)).then((_) { passed = true; test_package.fail('Test passed - expected to fail.'); - }).catchError((e) { + }).catchError((Object e) { // if passed, and we call fail(), rethrow this exception if (passed) { throw e; @@ -272,64 +253,49 @@ } Future<Object?> _runTest(ClassMirror classMirror, Symbol symbol) { - InstanceMirror instanceMirror = classMirror.newInstance(new Symbol(''), []); + InstanceMirror instanceMirror = classMirror.newInstance(Symbol(''), []); return _invokeSymbolIfExists(instanceMirror, #setUp) .then((_) => instanceMirror.invoke(symbol, []).reflectee) .whenComplete(() => _invokeSymbolIfExists(instanceMirror, #tearDown)); } -typedef dynamic _TestFunction(); +typedef _TestFunction = dynamic Function(); -/** - * A marker annotation used to annotate test methods which are expected to fail. - */ +/// A marker annotation used to annotate test methods which are expected to +/// fail. class FailingTest { - /** - * Initialize this annotation with the given arguments. - * - * [issue] is a full URI describing the failure and used for tracking. - * [reason] is a free form textual description. - */ + /// Initialize this annotation with the given arguments. + /// + /// [issue] is a full URI describing the failure and used for tracking. + /// [reason] is a free form textual description. const FailingTest({String? issue, String? reason}); } -/** - * A marker annotation used to annotate test methods which are skipped. - */ +/// A marker annotation used to annotate test methods which are skipped. class SkippedTest { - /** - * Initialize this annotation with the given arguments. - * - * [issue] is a full URI describing the failure and used for tracking. - * [reason] is a free form textual description. - */ + /// Initialize this annotation with the given arguments. + /// + /// [issue] is a full URI describing the failure and used for tracking. + /// [reason] is a free form textual description. const SkippedTest({String? issue, String? reason}); } -/** - * A marker annotation used to annotate test methods with additional timeout - * information. - */ +/// A marker annotation used to annotate test methods with additional timeout +/// information. class TestTimeout { final test_package.Timeout _timeout; - /** - * Initialize this annotation with the given timeout. - */ + /// Initialize this annotation with the given timeout. const TestTimeout(test_package.Timeout timeout) : _timeout = timeout; } -/** - * A marker annotation used to annotate test methods which are expected to fail - * when asserts are enabled. - */ +/// A marker annotation used to annotate test methods which are expected to fail +/// when asserts are enabled. class _AssertFailingTest { const _AssertFailingTest(); } -/** - * Information about a type based test group. - */ +/// Information about a type based test group. class _Group { final bool isSolo; final String name; @@ -341,7 +307,7 @@ void addSkippedTest(String name) { var fullName = _combineNames(this.name, name); - tests.add(new _Test.skipped(isSolo, fullName)); + tests.add(_Test.skipped(isSolo, fullName)); } void addTest(bool isSolo, String name, MethodMirror memberMirror, @@ -349,28 +315,22 @@ var fullName = _combineNames(this.name, name); var timeout = _getAnnotationInstance(memberMirror, TestTimeout) as TestTimeout?; - tests.add(new _Test(isSolo, fullName, function, timeout?._timeout)); + tests.add(_Test(isSolo, fullName, function, timeout?._timeout)); } } -/** - * A marker annotation used to instruct dart2js to keep reflection information - * for the annotated classes. - */ +/// A marker annotation used to instruct dart2js to keep reflection information +/// for the annotated classes. class _ReflectiveTest { const _ReflectiveTest(); } -/** - * A marker annotation used to annotate "solo" groups and tests. - */ +/// A marker annotation used to annotate "solo" groups and tests. class _SoloTest { const _SoloTest(); } -/** - * Information about a test. - */ +/// Information about a test. class _Test { final bool isSolo; final String name;
diff --git a/pubspec.yaml b/pubspec.yaml index 1a72733..b374f1d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml
@@ -1,11 +1,12 @@ name: test_reflective_loader -version: 0.2.0 +version: 0.2.1-dev description: Support for discovering tests and test suites using reflection. homepage: https://github.com/dart-lang/test_reflective_loader environment: - sdk: '>=2.12.0-0 <3.0.0' + sdk: '>=2.12.0 <3.0.0' dependencies: - test: '>=1.16.0 <2.0.0' + lints: ^1.0.1 + test: ^1.16.0
diff --git a/test/test_reflective_loader_test.dart b/test/test_reflective_loader_test.dart index 2c69cce..ea7911f 100644 --- a/test/test_reflective_loader_test.dart +++ b/test/test_reflective_loader_test.dart
@@ -2,6 +2,8 @@ // 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. +// ignore_for_file: non_constant_identifier_names + import 'dart:async'; import 'package:test/test.dart'; @@ -31,7 +33,7 @@ @failingTest Future test_fails_throws_async() { - return new Future.error('foo'); + return Future.error('foo'); } @skippedTest