Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ jobs:
# E2E tests for the `packages check licenses` command
- test/commands/packages/check/licenses/licenses_allowed_test.dart
- test/commands/packages/check/licenses/licenses_forbidden_test.dart
- test/commands/packages/check/licenses/unknown_licenses_test.dart

steps:
- name: 📚 Git Checkout
Expand Down
9 changes: 8 additions & 1 deletion e2e/helpers/command_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ void Function() withRunner(
Logger logger,
PubUpdater pubUpdater,
List<String> printLogs,
List<String> progressLogs,
)
runnerFn,
) {
Expand Down Expand Up @@ -61,6 +62,12 @@ void Function() withRunner(
() => pubUpdater.getLatestVersion(any()),
).thenAnswer((_) => Future.value('1.0.0'));

await runnerFn(commandRunner, logger, pubUpdater, printLogs);
await runnerFn(
commandRunner,
logger,
pubUpdater,
printLogs,
progressLogs,
);
});
}
2 changes: 1 addition & 1 deletion e2e/test/commands/create/dart_cli/dart_cli_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ void main() {
test(
'create dart_cli',
timeout: const Timeout(Duration(minutes: 2)),
withRunner((commandRunner, logger, updater, logs) async {
withRunner((commandRunner, logger, updater, logs, progressLogs) async {
final tempDirectory = Directory.systemTemp.createTempSync();
addTearDown(() => tempDirectory.deleteSync(recursive: true));

Expand Down
2 changes: 1 addition & 1 deletion e2e/test/commands/create/dart_package/dart_pkg_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ void main() {
test(
'create dart_package',
timeout: const Timeout(Duration(minutes: 2)),
withRunner((commandRunner, logger, updater, logs) async {
withRunner((commandRunner, logger, updater, logs, progressLogs) async {
final tempDirectory = Directory.systemTemp.createTempSync();
addTearDown(() => tempDirectory.deleteSync(recursive: true));

Expand Down
2 changes: 1 addition & 1 deletion e2e/test/commands/create/docs_site/docs_site_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ void main() {
test(
'create docs_site',
timeout: const Timeout(Duration(minutes: 2)),
withRunner((commandRunner, logger, updater, logs) async {
withRunner((commandRunner, logger, updater, logs, progressLogs) async {
final tempDirectory = Directory.systemTemp.createTempSync();
addTearDown(() => tempDirectory.deleteSync(recursive: true));

Expand Down
2 changes: 1 addition & 1 deletion e2e/test/commands/create/flame_game/flame_game_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ void main() {
test(
'create flame_game',
timeout: const Timeout(Duration(minutes: 5)),
withRunner((commandRunner, logger, updater, logs) async {
withRunner((commandRunner, logger, updater, logs, progressLogs) async {
final tempDirectory = Directory.systemTemp.createTempSync();
addTearDown(() => tempDirectory.deleteSync(recursive: true));

Expand Down
2 changes: 1 addition & 1 deletion e2e/test/commands/create/flutter_app/core_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ void main() {
test(
'create flutter_app',
timeout: const Timeout(Duration(minutes: 2)),
withRunner((commandRunner, logger, updater, logs) async {
withRunner((commandRunner, logger, updater, logs, progressLogs) async {
final tempDirectory = Directory.systemTemp.createTempSync();
addTearDown(() => tempDirectory.deleteSync(recursive: true));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ void main() {
test(
'create flutter_package',
timeout: const Timeout(Duration(minutes: 2)),
withRunner((commandRunner, logger, updater, logs) async {
withRunner((commandRunner, logger, updater, logs, progressLogs) async {
final tempDirectory = Directory.systemTemp.createTempSync();
addTearDown(() => tempDirectory.deleteSync(recursive: true));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ void main() {
test(
'create flutter_plugin',
timeout: const Timeout(Duration(minutes: 8)),
withRunner((commandRunner, logger, updater, logs) async {
withRunner((commandRunner, logger, updater, logs, progressLogs) async {
final tempDirectory = Directory.systemTemp.createTempSync();
addTearDown(() => tempDirectory.deleteSync(recursive: true));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ void main() {
test(
'packages check licenses --allowed="MIT,BSD-3-Clause"',
timeout: const Timeout(Duration(minutes: 2)),
withRunner((commandRunner, logger, updater, logs) async {
withRunner((commandRunner, logger, updater, logs, progressLogs) async {
final tempDirectory = Directory.systemTemp.createTempSync();
addTearDown(() => tempDirectory.deleteSync(recursive: true));

Expand Down Expand Up @@ -52,6 +52,13 @@ void main() {
equals(ExitCode.success.code),
reason: 'Should succeed when allowed licenses are used',
);

expect(
progressLogs,
contains(
'''Retrieved 2 licenses from 2 packages of type: MIT (1) and BSD-3-Clause (1).''',
),
);
}),
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:io';

import 'package:mason/mason.dart';
import 'package:mocktail/mocktail.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';

Expand All @@ -16,7 +17,7 @@ void main() {
test(
'packages check licenses --forbidden="MIT"',
timeout: const Timeout(Duration(minutes: 2)),
withRunner((commandRunner, logger, updater, logs) async {
withRunner((commandRunner, logger, updater, logs, progressLogs) async {
final tempDirectory = Directory.systemTemp.createTempSync();
addTearDown(() => tempDirectory.deleteSync(recursive: true));

Expand Down Expand Up @@ -54,6 +55,12 @@ void main() {
equals(ExitCode.config.code),
reason: 'Should fail when forbidden licenses are used',
);

verify(
() => logger.err(
'1 dependency has a banned license: formz ([MIT](https://pub.dev/packages/formz/license)).',
),
).called(1);
}),
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import 'dart:io';

import 'package:mason/mason.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';

import '../../../../../helpers/helpers.dart';

/// Objectives:
///
/// * Generate a new Dart project using (`dart create`)
/// * Add dependencies to `pubspec.yaml` with an unknown license
/// * Run `very_good packages check licenses` and expect it to
/// report 1 unknown license
void main() {
test(
'packages check licenses (unknown license)',
timeout: const Timeout(Duration(minutes: 2)),
withRunner((commandRunner, logger, updater, logs, progressLogs) async {
final tempDirectory = Directory.systemTemp.createTempSync();
addTearDown(() => tempDirectory.deleteSync(recursive: true));

const projectName = 'my_dart_project';
await expectSuccessfulProcessResult('dart', [
'create',
'my_dart_project',
'--no-pub',
], workingDirectory: tempDirectory.path);
final projectPath = path.join(tempDirectory.path, projectName);
await expectSuccessfulProcessResult('dart', [
'pub',
'add',
'rxdart:0.27.7',
], workingDirectory: projectPath);
await expectSuccessfulProcessResult('dart', [
'pub',
'get',
], workingDirectory: projectPath);

final relativeProjectPath = path.relative(
projectPath,
from: Directory.current.path,
);

final result = await commandRunner.run([
'packages',
'check',
'licenses',
relativeProjectPath,
]);

expect(
result,
equals(ExitCode.success.code),
);

expect(
progressLogs,
contains(
'Retrieved 2 licenses from 2 packages of type: BSD-3-Clause (1) '
'and unknown (1).',
),
);
}),
);
}
2 changes: 1 addition & 1 deletion e2e/test/commands/test/async_main/async_main_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ void main() {
test(
'supports async main methods',
timeout: const Timeout(Duration(minutes: 2)),
withRunner((commandRunner, logger, updater, logs) async {
withRunner((commandRunner, logger, updater, logs, progressLogs) async {
final tempDirectory = Directory.systemTemp.createTempSync('async_main');
addTearDown(() => tempDirectory.deleteSync(recursive: true));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ void main() {
test(
'fails when there is a compilation error, but does not crash',
timeout: const Timeout(Duration(minutes: 2)),
withRunner((commandRunner, logger, updater, logs) async {
withRunner((commandRunner, logger, updater, logs, progressLogs) async {
final tempDirectory = Directory.systemTemp.createTempSync(
'compilation_error',
);
Expand Down
2 changes: 1 addition & 1 deletion e2e/test/commands/test/no_project/no_project_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import '../../../../helpers/helpers.dart';
void main() {
test(
'fails if the project does not exist',
withRunner((commandRunner, logger, updater, logs) async {
withRunner((commandRunner, logger, updater, logs, progressLogs) async {
final tempDirectory = Directory.systemTemp.createTempSync('no_project');
addTearDown(() => tempDirectory.deleteSync(recursive: true));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ void main() {
test(
'allows golden files with spaces in the name',
timeout: const Timeout(Duration(minutes: 2)),
withRunner((commandRunner, logger, updater, logs) async {
withRunner((commandRunner, logger, updater, logs, progressLogs) async {
final tempDirectory = Directory.systemTemp.createTempSync('async_main');
addTearDown(() => tempDirectory.deleteSync(recursive: true));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,11 @@ class PackagesCheckLicensesCommand extends Command<int> {
// ignore: invalid_use_of_visible_for_testing_member
.map((match) => match.license.identifier)
.toSet();
licenses[dependencyName] = rawLicense;
licenses[dependencyName] = {
...rawLicense,
// If there are no matches, we add the unknown license
if (rawLicense.isEmpty) SpdxLicense.$unknown.value,
};
}

late final _BannedDependencyLicenseMap? bannedDependencies;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,97 @@ void main() {
expect(result, equals(ExitCode.success.code));
}),
);

test(
'unknown when non-standard license file is found',
withRunner((commandRunner, logger, pubUpdater, printLogs) async {
File(
path.join(tempDirectory.path, pubspecLockBasename),
).writeAsStringSync(_validPubspecLockContent);

when(
() => packageConfig.packages,
).thenReturn([veryGoodTestRunnerConfigPackage]);
final licenseFilePath = path.join(
tempDirectory.path,
veryGoodTestRunnerConfigPackage.name,
'LICENSE',
);
File(licenseFilePath).writeAsStringSync('''
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.''');

when(() => logger.progress(any())).thenReturn(progress);
when(() => detectorResult.matches).thenReturn([]);

final result = await commandRunner.run(
[...commandArguments, tempDirectory.path],
);

verify(
() => progress.update(
'Collecting licenses from 1 out of 1 package',
),
).called(1);
verify(
() => progress.complete(
'''Retrieved 1 license from 1 package of type: unknown (1).''',
),
).called(1);

expect(result, equals(ExitCode.success.code));
}),
);

test(
'unknown when invalid license file is found',
withRunner((commandRunner, logger, pubUpdater, printLogs) async {
File(
path.join(tempDirectory.path, pubspecLockBasename),
).writeAsStringSync(_validPubspecLockContent);

when(
() => packageConfig.packages,
).thenReturn([veryGoodTestRunnerConfigPackage]);
final licenseFilePath = path.join(
tempDirectory.path,
veryGoodTestRunnerConfigPackage.name,
'LICENSE',
);
File(
licenseFilePath,
).writeAsStringSync('This is an invalid license file.');

when(() => logger.progress(any())).thenReturn(progress);
when(() => detectorResult.matches).thenReturn([]);

final result = await commandRunner.run(
[...commandArguments, tempDirectory.path],
);

verify(
() => progress.update(
'Collecting licenses from 1 out of 1 package',
),
).called(1);
verify(
() => progress.complete(
'''Retrieved 1 license from 1 package of type: unknown (1).''',
),
).called(1);

expect(result, equals(ExitCode.success.code));
}),
);
},
);

Expand Down