blob: cc16010c7023a7b2492171df5b665dcbc54488fe [file] [log] [blame]
// Copyright 2014 The Flutter Authors. 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:dds/src/dap/protocol_generated.dart';
import 'package:file/file.dart';
import 'package:flutter_tools/src/cache.dart';
import '../../src/common.dart';
import '../test_data/integration_tests_project.dart';
import '../test_data/tests_project.dart';
import '../test_utils.dart';
import 'test_client.dart';
import 'test_support.dart';
void main() {
late Directory tempDir;
late DapTestSession dap;
late DapTestClient client;
late TestsProject project;
setUpAll(() {
Cache.flutterRoot = getFlutterRoot();
});
setUp(() async {
tempDir = createResolvedTempDirectorySync('flutter_test_adapter_test.');
dap = await DapTestSession.setUp(additionalArgs: <String>['--test']);
client = dap.client;
});
tearDown(() async {
await dap.tearDown();
tryToDelete(tempDir);
});
void standardTests({List<String>? toolArgs}) {
test('can run in debug mode', () async {
// Collect output and test events while running the script.
final TestEvents outputEvents = await client.collectTestOutput(
launch: () => client.launch(
program: project.testFilePath,
cwd: project.dir.path,
toolArgs: toolArgs,
),
);
// Check the printed output shows that the run finished, and it's exit
// code (which is 1 due to the failing test).
final String output = outputEvents.output.map((OutputEventBody e) => e.output).join();
expectLines(
output,
<Object>[
startsWith('Connecting to VM Service at'),
..._testsProjectExpectedOutput,
],
allowExtras: true, // Allow for printed call stack etc.
);
_expectStandardTestsProjectResults(outputEvents);
});
test('can run in noDebug mode', () async {
// Collect output and test events while running the script.
final TestEvents outputEvents = await client.collectTestOutput(
launch: () => client.launch(
program: project.testFilePath,
noDebug: true,
cwd: project.dir.path,
toolArgs: toolArgs,
),
);
// Check the printed output shows that the run finished, and it's exit
// code (which is 1 due to the failing test).
final String output = outputEvents.output.map((OutputEventBody e) => e.output).join();
expectLines(
output,
_testsProjectExpectedOutput,
allowExtras: true, // Allow for printed call stack etc.
);
_expectStandardTestsProjectResults(outputEvents);
});
test('can run a single test', () async {
// Collect output and test events while running the script.
final TestEvents outputEvents = await client.collectTestOutput(
launch: () => client.launch(
program: project.testFilePath,
noDebug: true,
cwd: project.dir.path,
// It's up to the calling IDE to pass the correct args for
// 'flutter test' if it wants to run a subset of tests.
toolArgs: <String>[
'--plain-name',
'can pass',
...?toolArgs,
],
),
);
final List<Object> testsNames = outputEvents.testNotifications
.where((Map<String, Object?> e) => e['type'] == 'testStart')
.map((Map<String, Object?> e) => (e['test']! as Map<String, Object?>)['name']!)
.toList();
expect(testsNames, contains('Flutter tests can pass'));
expect(testsNames, isNot(contains('Flutter tests can fail')));
});
}
group('widget tests', () {
setUp(() async {
project = TestsProject();
await project.setUpIn(tempDir);
});
standardTests();
});
group('integration tests', () {
const List<String> toolArgs = <String>['-d', 'flutter-tester'];
setUp(() async {
project = IntegrationTestsProject();
await project.setUpIn(tempDir);
});
standardTests(toolArgs: toolArgs);
});
}
/// Matchers for the expected console output of [TestsProject].
final List<Object> _testsProjectExpectedOutput = <Object>[
// First test
'✓ Flutter tests can pass',
// Second test
'══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════',
'The following TestFailure was thrown running a test:',
'Expected: false',
' Actual: <true>',
'',
'The test description was: can fail',
'',
'✖ Flutter tests can fail',
// Exit
'',
'Exited (1).',
];
/// A helper that verifies a full set of expected test results for the
/// [TestsProject] script.
void _expectStandardTestsProjectResults(TestEvents events) {
// Check we received all expected test events passed through from
// package:test.
final List<Object> eventNames = events.testNotifications
.map((Map<String, Object?> e) => e['type']!)
.toList();
// start/done should always be first/last.
expect(eventNames.first, equals('start'));
expect(eventNames.last, equals('done'));
// allSuites should have occurred after start.
expect(
eventNames,
containsAllInOrder(<String>['start', 'allSuites']),
);
// Expect two tests, with the failing one emitting an error.
expect(
eventNames,
containsAllInOrder(<String>[
'testStart',
'testDone',
'testStart',
'error',
'testDone',
]),
);
}