Unverified Commit f92ba2d2 authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Replace MockUsage with Usage.test in build tests (#67670)

parent 41325b56
...@@ -198,6 +198,7 @@ class _DefaultUsage implements Usage { ...@@ -198,6 +198,7 @@ class _DefaultUsage implements Usage {
final bool usingLogFile = logFilePath != null && logFilePath.isNotEmpty; final bool usingLogFile = logFilePath != null && logFilePath.isNotEmpty;
analyticsIOFactory ??= _defaultAnalyticsIOFactory; analyticsIOFactory ??= _defaultAnalyticsIOFactory;
_clock = globals.systemClock;
if (// To support testing, only allow other signals to supress analytics if (// To support testing, only allow other signals to supress analytics
// when analytics are not being shunted to a file. // when analytics are not being shunted to a file.
...@@ -272,13 +273,15 @@ class _DefaultUsage implements Usage { ...@@ -272,13 +273,15 @@ class _DefaultUsage implements Usage {
} }
_DefaultUsage.test() : _DefaultUsage.test() :
_suppressAnalytics = true, _suppressAnalytics = false,
_analytics = AnalyticsMock(); _analytics = AnalyticsMock(true),
_clock = SystemClock.fixed(DateTime(2020, 10, 8));
Analytics _analytics; Analytics _analytics;
bool _printedWelcome = false; bool _printedWelcome = false;
bool _suppressAnalytics = false; bool _suppressAnalytics = false;
SystemClock _clock;
@override @override
bool get isFirstRun => _analytics.firstRun; bool get isFirstRun => _analytics.firstRun;
...@@ -310,7 +313,7 @@ class _DefaultUsage implements Usage { ...@@ -310,7 +313,7 @@ class _DefaultUsage implements Usage {
final Map<String, String> paramsWithLocalTime = <String, String>{ final Map<String, String> paramsWithLocalTime = <String, String>{
...?parameters, ...?parameters,
cdKey(CustomDimensions.localTime): formatDateTime(globals.systemClock.now()), cdKey(CustomDimensions.localTime): formatDateTime(_clock.now()),
}; };
_analytics.sendScreenView(command, parameters: paramsWithLocalTime); _analytics.sendScreenView(command, parameters: paramsWithLocalTime);
} }
...@@ -329,7 +332,7 @@ class _DefaultUsage implements Usage { ...@@ -329,7 +332,7 @@ class _DefaultUsage implements Usage {
final Map<String, String> paramsWithLocalTime = <String, String>{ final Map<String, String> paramsWithLocalTime = <String, String>{
...?parameters, ...?parameters,
cdKey(CustomDimensions.localTime): formatDateTime(globals.systemClock.now()), cdKey(CustomDimensions.localTime): formatDateTime(_clock.now()),
}; };
_analytics.sendEvent( _analytics.sendEvent(
......
...@@ -15,7 +15,6 @@ import 'package:flutter_tools/src/commands/build_linux.dart'; ...@@ -15,7 +15,6 @@ import 'package:flutter_tools/src/commands/build_linux.dart';
import 'package:flutter_tools/src/features.dart'; import 'package:flutter_tools/src/features.dart';
import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/reporting.dart'; import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:mockito/mockito.dart';
import 'package:process/process.dart'; import 'package:process/process.dart';
import '../../src/common.dart'; import '../../src/common.dart';
...@@ -45,12 +44,12 @@ void main() { ...@@ -45,12 +44,12 @@ void main() {
FileSystem fileSystem; FileSystem fileSystem;
ProcessManager processManager; ProcessManager processManager;
MockUsage usage; Usage usage;
setUp(() { setUp(() {
fileSystem = MemoryFileSystem.test(); fileSystem = MemoryFileSystem.test();
Cache.flutterRoot = _kTestFlutterRoot; Cache.flutterRoot = _kTestFlutterRoot;
usage = MockUsage(); usage = Usage.test();
}); });
// Creates the mock files necessary to look like a Flutter project. // Creates the mock files necessary to look like a Flutter project.
...@@ -399,11 +398,15 @@ set(BINARY_NAME "fizz_bar") ...@@ -399,11 +398,15 @@ set(BINARY_NAME "fizz_bar")
..createSync(recursive: true) ..createSync(recursive: true)
..writeAsBytesSync(List<int>.filled(10000, 0)); ..writeAsBytesSync(List<int>.filled(10000, 0));
await createTestCommandRunner(command).run( // Capture Usage.test() events.
final StringBuffer buffer = await capturedConsolePrint(() =>
createTestCommandRunner(command).run(
const <String>['build', 'linux', '--no-pub', '--analyze-size'] const <String>['build', 'linux', '--no-pub', '--analyze-size']
)
); );
expect(testLogger.statusText, contains('A summary of your Linux bundle analysis can be found at')); expect(testLogger.statusText, contains('A summary of your Linux bundle analysis can be found at'));
verify(usage.sendEvent('code-size-analysis', 'linux')).called(1); expect(buffer.toString(), contains('event {category: code-size-analysis, action: linux, label: null, value: null, cd33:'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
ProcessManager: () => processManager, ProcessManager: () => processManager,
...@@ -412,5 +415,3 @@ set(BINARY_NAME "fizz_bar") ...@@ -412,5 +415,3 @@ set(BINARY_NAME "fizz_bar")
Usage: () => usage, Usage: () => usage,
}); });
} }
class MockUsage extends Mock implements Usage {}
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
...@@ -15,7 +17,6 @@ import 'package:flutter_tools/src/features.dart'; ...@@ -15,7 +17,6 @@ import 'package:flutter_tools/src/features.dart';
import 'package:flutter_tools/src/ios/xcodeproj.dart'; import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/reporting.dart'; import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:mockito/mockito.dart';
import 'package:process/process.dart'; import 'package:process/process.dart';
import '../../src/common.dart'; import '../../src/common.dart';
...@@ -49,7 +50,7 @@ final Platform notMacosPlatform = FakePlatform( ...@@ -49,7 +50,7 @@ final Platform notMacosPlatform = FakePlatform(
void main() { void main() {
FileSystem fileSystem; FileSystem fileSystem;
MockUsage usage; Usage usage;
setUpAll(() { setUpAll(() {
Cache.disableLocking(); Cache.disableLocking();
...@@ -57,7 +58,7 @@ void main() { ...@@ -57,7 +58,7 @@ void main() {
setUp(() { setUp(() {
fileSystem = MemoryFileSystem.test(); fileSystem = MemoryFileSystem.test();
usage = MockUsage(); usage = Usage.test();
}); });
// Sets up the minimal mock project files necessary to look like a Flutter project. // Sets up the minimal mock project files necessary to look like a Flutter project.
...@@ -329,12 +330,15 @@ void main() { ...@@ -329,12 +330,15 @@ void main() {
..createSync(recursive: true) ..createSync(recursive: true)
..writeAsBytesSync(List<int>.generate(10000, (int index) => 0)); ..writeAsBytesSync(List<int>.generate(10000, (int index) => 0));
await createTestCommandRunner(command).run( // Capture Usage.test() events.
final StringBuffer buffer = await capturedConsolePrint(() =>
createTestCommandRunner(command).run(
const <String>['build', 'macos', '--no-pub', '--analyze-size'] const <String>['build', 'macos', '--no-pub', '--analyze-size']
)
); );
expect(testLogger.statusText, contains('A summary of your macOS bundle analysis can be found at')); expect(testLogger.statusText, contains('A summary of your macOS bundle analysis can be found at'));
verify(usage.sendEvent('code-size-analysis', 'macos')).called(1); expect(buffer.toString(), contains('event {category: code-size-analysis, action: macos, label: null, value: null, cd33:'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[ ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
...@@ -360,5 +364,3 @@ void main() { ...@@ -360,5 +364,3 @@ void main() {
Usage: () => usage, Usage: () => usage,
}); });
} }
class MockUsage extends Mock implements Usage {}
...@@ -43,7 +43,7 @@ void main() { ...@@ -43,7 +43,7 @@ void main() {
ProcessManager processManager; ProcessManager processManager;
MockVisualStudio mockVisualStudio; MockVisualStudio mockVisualStudio;
MockUsage usage; Usage usage;
setUpAll(() { setUpAll(() {
Cache.disableLocking(); Cache.disableLocking();
...@@ -53,7 +53,7 @@ void main() { ...@@ -53,7 +53,7 @@ void main() {
fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows); fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
Cache.flutterRoot = flutterRoot; Cache.flutterRoot = flutterRoot;
mockVisualStudio = MockVisualStudio(); mockVisualStudio = MockVisualStudio();
usage = MockUsage(); usage = Usage.test();
}); });
// Creates the mock files necessary to look like a Flutter project. // Creates the mock files necessary to look like a Flutter project.
...@@ -403,12 +403,15 @@ C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier ...@@ -403,12 +403,15 @@ C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier
}), }),
]); ]);
await createTestCommandRunner(command).run( // Capture Usage.test() events.
final StringBuffer buffer = await capturedConsolePrint(() =>
createTestCommandRunner(command).run(
const <String>['windows', '--no-pub', '--analyze-size'] const <String>['windows', '--no-pub', '--analyze-size']
)
); );
expect(testLogger.statusText, contains('A summary of your Windows bundle analysis can be found at')); expect(testLogger.statusText, contains('A summary of your Windows bundle analysis can be found at'));
verify(usage.sendEvent('code-size-analysis', 'windows')).called(1); expect(buffer.toString(), contains('event {category: code-size-analysis, action: windows, label: null, value: null, cd33:'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true), FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
...@@ -420,4 +423,3 @@ C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier ...@@ -420,4 +423,3 @@ C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier
} }
class MockVisualStudio extends Mock implements VisualStudio {} class MockVisualStudio extends Mock implements VisualStudio {}
class MockUsage extends Mock implements Usage {}
...@@ -81,9 +81,7 @@ void main() { ...@@ -81,9 +81,7 @@ void main() {
}); });
testUsingContext('printStatus should log to stdout when logToStdout is enabled', () async { testUsingContext('printStatus should log to stdout when logToStdout is enabled', () async {
final StringBuffer buffer = StringBuffer(); final StringBuffer buffer = await capturedConsolePrint(() {
await runZoned<Future<void>>(() async {
final StreamController<Map<String, dynamic>> commands = StreamController<Map<String, dynamic>>(); final StreamController<Map<String, dynamic>> commands = StreamController<Map<String, dynamic>>();
final StreamController<Map<String, dynamic>> responses = StreamController<Map<String, dynamic>>(); final StreamController<Map<String, dynamic>> responses = StreamController<Map<String, dynamic>>();
daemon = Daemon( daemon = Daemon(
...@@ -93,11 +91,8 @@ void main() { ...@@ -93,11 +91,8 @@ void main() {
logToStdout: true, logToStdout: true,
); );
globals.printStatus('daemon.logMessage test'); globals.printStatus('daemon.logMessage test');
// Service the event loop. return Future<void>.value();
await Future<void>.value(); });
}, zoneSpecification: ZoneSpecification(print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
buffer.writeln(line);
}));
expect(buffer.toString().trim(), 'daemon.logMessage test'); expect(buffer.toString().trim(), 'daemon.logMessage test');
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async';
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter_tools/src/application_package.dart'; import 'package:flutter_tools/src/application_package.dart';
...@@ -143,13 +145,13 @@ void main() { ...@@ -143,13 +145,13 @@ void main() {
Artifacts artifacts; Artifacts artifacts;
MockCache mockCache; MockCache mockCache;
MockProcessManager mockProcessManager; MockProcessManager mockProcessManager;
MockUsage mockUsage; Usage usage;
Directory tempDir; Directory tempDir;
setUp(() { setUp(() {
artifacts = Artifacts.test(); artifacts = Artifacts.test();
mockCache = MockCache(); mockCache = MockCache();
mockUsage = MockUsage(); usage = Usage.test();
fs = MemoryFileSystem.test(); fs = MemoryFileSystem.test();
mockProcessManager = MockProcessManager(); mockProcessManager = MockProcessManager();
...@@ -374,33 +376,19 @@ void main() { ...@@ -374,33 +376,19 @@ void main() {
..writeAsStringSync('# Hello, World'); ..writeAsStringSync('# Hello, World');
globals.fs.currentDirectory = tempDir; globals.fs.currentDirectory = tempDir;
try { // Capture Usage.test() events.
await createTestCommandRunner(command).run(<String>[ final StringBuffer buffer = await capturedConsolePrint(() =>
expectToolExitLater(createTestCommandRunner(command).run(<String>[
'run', 'run',
'--no-pub', '--no-pub',
'--no-hot', '--no-hot',
]); ]), isNull)
fail('Exception expected'); );
} on ToolExit catch (e) { // Allow any CustomDimensions.localTime (cd33) timestamp.
// We expect a ToolExit because app does not start final RegExp usageRegexp = RegExp(
expect(e.message, null); 'screenView {cd3: false, cd4: ios, cd22: iOS 13, cd23: debug, cd18: false, cd15: swift, cd31: false, cd47: false, cd33: .*, viewName: run'
} on Exception catch (e) { );
fail('ToolExit expected, got $e'); expect(buffer.toString(), matches(usageRegexp));
}
final List<dynamic> captures = verify(mockUsage.sendCommand(
captureAny,
parameters: captureAnyNamed('parameters'),
)).captured;
expect(captures[0], 'run');
final Map<String, String> parameters = captures[1] as Map<String, String>;
expect(parameters[cdKey(CustomDimensions.commandRunIsEmulator)], 'false');
expect(parameters[cdKey(CustomDimensions.commandRunTargetName)], 'ios');
expect(parameters[cdKey(CustomDimensions.commandRunProjectHostLanguage)], 'swift');
expect(parameters[cdKey(CustomDimensions.commandRunTargetOsVersion)], 'iOS 13');
expect(parameters[cdKey(CustomDimensions.commandRunModeName)], 'debug');
expect(parameters[cdKey(CustomDimensions.commandRunProjectModule)], 'false');
expect(parameters.containsKey(cdKey(CustomDimensions.commandRunAndroidEmbeddingVersion)), false);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ApplicationPackageFactory: () => mockApplicationPackageFactory, ApplicationPackageFactory: () => mockApplicationPackageFactory,
Artifacts: () => artifacts, Artifacts: () => artifacts,
...@@ -408,7 +396,7 @@ void main() { ...@@ -408,7 +396,7 @@ void main() {
DeviceManager: () => mockDeviceManager, DeviceManager: () => mockDeviceManager,
FileSystem: () => fs, FileSystem: () => fs,
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
Usage: () => mockUsage, Usage: () => usage,
}); });
}); });
......
...@@ -92,6 +92,18 @@ CommandRunner<void> createTestCommandRunner([ FlutterCommand command ]) { ...@@ -92,6 +92,18 @@ CommandRunner<void> createTestCommandRunner([ FlutterCommand command ]) {
return runner; return runner;
} }
/// Capture console print events into a string buffer.
Future<StringBuffer> capturedConsolePrint(Future<void> Function() body) async {
final StringBuffer buffer = StringBuffer();
await runZoned<Future<void>>(() async {
// Service the event loop.
await body();
}, zoneSpecification: ZoneSpecification(print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
buffer.writeln(line);
}));
return buffer;
}
/// Matcher for functions that throw [AssertionError]. /// Matcher for functions that throw [AssertionError].
final Matcher throwsAssertionError = throwsA(isA<AssertionError>()); final Matcher throwsAssertionError = throwsA(isA<AssertionError>());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment