From cb40f1b8fd8fe16935bddfc6cc9a7e80f523a338 Mon Sep 17 00:00:00 2001 From: Andrew Kolos Date: Fri, 28 Mar 2025 06:41:28 -0700 Subject: [PATCH] Get analytics welcome message under test (#162627) Fixes https://github.com/flutter/flutter/issues/160374 For this I resorted to a unit test directly against `exitWithHooks` (which is called when the tool is shutting down). An integration test against a "fresh" tool checkout would probably be more resilient, but I'm not sure if a more heavyweight test is worth it.
Pre-launch checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing.
[Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md --- .../lib/src/runner/flutter_command.dart | 2 - .../test/general.shard/base/process_test.dart | 50 ++++++++++++++++++- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart index 09425d25ec..17ab07e321 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart @@ -1541,8 +1541,6 @@ abstract class FlutterCommand extends Command { if (_usesFatalWarnings) { globals.logger.fatalWarnings = boolArg(FlutterOptions.kFatalWarnings); } - // Prints the welcome message if needed. - globals.flutterUsage.printWelcome(); _printDeprecationWarning(); final String? commandPath = await usagePath; if (commandPath != null) { diff --git a/packages/flutter_tools/test/general.shard/base/process_test.dart b/packages/flutter_tools/test/general.shard/base/process_test.dart index 20f5a019d9..34337b3cc0 100644 --- a/packages/flutter_tools/test/general.shard/base/process_test.dart +++ b/packages/flutter_tools/test/general.shard/base/process_test.dart @@ -4,14 +4,17 @@ import 'dart:async'; +import 'package:file/memory.dart'; +import 'package:flutter_tools/src/base/io.dart' as io; import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/base/process.dart'; import 'package:flutter_tools/src/base/terminal.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import '../../src/common.dart'; -import '../../src/fake_process_manager.dart'; +import '../../src/context.dart'; import '../../src/fakes.dart'; void main() { @@ -393,6 +396,51 @@ void main() { expect(errorPassedToCallback, const TypeMatcher()); }); }); + + group('exitWithHooks', () { + late MemoryFileSystem fileSystem; + late BufferLogger logger; + late Analytics analytics; + + setUp(() { + fileSystem = MemoryFileSystem.test(); + logger = BufferLogger.test(); + final FakeFlutterVersion fakeFlutterVersion = FakeFlutterVersion(); + analytics = Analytics.fake( + tool: DashTool.flutterTool, + homeDirectory: fileSystem.currentDirectory, + dartVersion: fakeFlutterVersion.dartSdkVersion, + fs: fileSystem, + flutterChannel: fakeFlutterVersion.channel, + flutterVersion: fakeFlutterVersion.getVersionString(), + ); + }); + + testUsingContext( + 'prints analytics welcome message', + () async { + io.setExitFunctionForTests((int exitCode) {}); + final ShutdownHooks shutdownHooks = ShutdownHooks(); + await exitWithHooks(0, shutdownHooks: shutdownHooks); + expect(logger.statusText, contains(analytics.getConsentMessage)); + }, + overrides: {Analytics: () => analytics, Logger: () => logger}, + ); + + testUsingContext( + 'does not print analytics welcome message if Analytics instance indicates it should not be printed', + () async { + io.setExitFunctionForTests((int exitCode) {}); + + analytics.clientShowedMessage(); + + final ShutdownHooks shutdownHooks = ShutdownHooks(); + await exitWithHooks(0, shutdownHooks: shutdownHooks); + expect(logger.statusText, isNot(contains(analytics.getConsentMessage))); + }, + overrides: {Analytics: () => analytics, Logger: () => logger}, + ); + }); } class _ThrowsOnFlushIOSink extends MemoryIOSink {