[Reland] Migration for the sendTiming
events for package:unified_analytics
(#139299)
Relanding based on this comment: - https://github.com/flutter/flutter/pull/139278#issuecomment-1832951108 Related to tracker issue: - https://github.com/flutter/flutter/issues/128251 <img width="278" alt="image" src="https://github.com/flutter/flutter/assets/42216813/cee7b9be-48d6-48e5-8c39-de28d0a1f0de"> The image above shows all of the instances where we have `sendTiming`. All of the call sites have been updated to use the new `Event.timing` event from `package:unified_analytics`.
This commit is contained in:
parent
7be25c8953
commit
2d60241d61
@ -490,7 +490,13 @@ class AndroidGradleBuilder implements AndroidBuilder {
|
|||||||
status.stop();
|
status.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
_usage.sendTiming('build', 'gradle', sw.elapsed);
|
final Duration elapsedDuration = sw.elapsed;
|
||||||
|
_usage.sendTiming('build', 'gradle', elapsedDuration);
|
||||||
|
_analytics.send(Event.timing(
|
||||||
|
workflow: 'build',
|
||||||
|
variableName: 'gradle',
|
||||||
|
elapsedMilliseconds: elapsedDuration.inMilliseconds,
|
||||||
|
));
|
||||||
|
|
||||||
if (exitCode != 0) {
|
if (exitCode != 0) {
|
||||||
if (detectedGradleError == null) {
|
if (detectedGradleError == null) {
|
||||||
@ -757,7 +763,13 @@ class AndroidGradleBuilder implements AndroidBuilder {
|
|||||||
} finally {
|
} finally {
|
||||||
status.stop();
|
status.stop();
|
||||||
}
|
}
|
||||||
_usage.sendTiming('build', 'gradle-aar', sw.elapsed);
|
final Duration elapsedDuration = sw.elapsed;
|
||||||
|
_usage.sendTiming('build', 'gradle-aar', elapsedDuration);
|
||||||
|
_analytics.send(Event.timing(
|
||||||
|
workflow: 'build',
|
||||||
|
variableName: 'gradle-aar',
|
||||||
|
elapsedMilliseconds: elapsedDuration.inMilliseconds,
|
||||||
|
));
|
||||||
|
|
||||||
if (result.exitCode != 0) {
|
if (result.exitCode != 0) {
|
||||||
_logger.printStatus(result.stdout, wrap: false);
|
_logger.printStatus(result.stdout, wrap: false);
|
||||||
@ -792,7 +804,13 @@ class AndroidGradleBuilder implements AndroidBuilder {
|
|||||||
project: project,
|
project: project,
|
||||||
);
|
);
|
||||||
|
|
||||||
_usage.sendTiming('print', 'android build variants', sw.elapsed);
|
final Duration elapsedDuration = sw.elapsed;
|
||||||
|
_usage.sendTiming('print', 'android build variants', elapsedDuration);
|
||||||
|
_analytics.send(Event.timing(
|
||||||
|
workflow: 'print',
|
||||||
|
variableName: 'android build variants',
|
||||||
|
elapsedMilliseconds: elapsedDuration.inMilliseconds,
|
||||||
|
));
|
||||||
|
|
||||||
if (result.exitCode != 0) {
|
if (result.exitCode != 0) {
|
||||||
_logger.printStatus(result.stdout, wrap: false);
|
_logger.printStatus(result.stdout, wrap: false);
|
||||||
@ -828,7 +846,13 @@ class AndroidGradleBuilder implements AndroidBuilder {
|
|||||||
options: <String>['-q', '-PoutputPath=$outputPath'],
|
options: <String>['-q', '-PoutputPath=$outputPath'],
|
||||||
project: project,
|
project: project,
|
||||||
);
|
);
|
||||||
_usage.sendTiming('outputs', 'app link settings', sw.elapsed);
|
final Duration elapsedDuration = sw.elapsed;
|
||||||
|
_usage.sendTiming('outputs', 'app link settings', elapsedDuration);
|
||||||
|
_analytics.send(Event.timing(
|
||||||
|
workflow: 'outputs',
|
||||||
|
variableName: 'app link settings',
|
||||||
|
elapsedMilliseconds: elapsedDuration.inMilliseconds,
|
||||||
|
));
|
||||||
|
|
||||||
if (result.exitCode != 0) {
|
if (result.exitCode != 0) {
|
||||||
_logger.printStatus(result.stdout, wrap: false);
|
_logger.printStatus(result.stdout, wrap: false);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:args/args.dart';
|
import 'package:args/args.dart';
|
||||||
|
import 'package:unified_analytics/unified_analytics.dart';
|
||||||
|
|
||||||
import '../base/common.dart';
|
import '../base/common.dart';
|
||||||
import '../base/os.dart';
|
import '../base/os.dart';
|
||||||
@ -298,7 +299,7 @@ class PackagesGetCommand extends FlutterCommand {
|
|||||||
processManager: globals.processManager,
|
processManager: globals.processManager,
|
||||||
platform: globals.platform,
|
platform: globals.platform,
|
||||||
usage: globals.flutterUsage,
|
usage: globals.flutterUsage,
|
||||||
analytics: globals.analytics,
|
analytics: analytics,
|
||||||
projectDir: rootProject.directory,
|
projectDir: rootProject.directory,
|
||||||
generateDartPluginRegistry: true,
|
generateDartPluginRegistry: true,
|
||||||
);
|
);
|
||||||
@ -319,7 +320,7 @@ class PackagesGetCommand extends FlutterCommand {
|
|||||||
processManager: globals.processManager,
|
processManager: globals.processManager,
|
||||||
platform: globals.platform,
|
platform: globals.platform,
|
||||||
usage: globals.flutterUsage,
|
usage: globals.flutterUsage,
|
||||||
analytics: globals.analytics,
|
analytics: analytics,
|
||||||
projectDir: rootProject.directory,
|
projectDir: rootProject.directory,
|
||||||
generateDartPluginRegistry: true,
|
generateDartPluginRegistry: true,
|
||||||
);
|
);
|
||||||
@ -354,10 +355,24 @@ class PackagesGetCommand extends FlutterCommand {
|
|||||||
command: name,
|
command: name,
|
||||||
touchesPackageConfig: !(isHelp || dryRun),
|
touchesPackageConfig: !(isHelp || dryRun),
|
||||||
);
|
);
|
||||||
globals.flutterUsage.sendTiming('pub', 'get', timer.elapsed, label: 'success');
|
final Duration elapsedDuration = timer.elapsed;
|
||||||
|
globals.flutterUsage.sendTiming('pub', 'get', elapsedDuration, label: 'success');
|
||||||
|
analytics.send(Event.timing(
|
||||||
|
workflow: 'pub',
|
||||||
|
variableName: 'get',
|
||||||
|
elapsedMilliseconds: elapsedDuration.inMilliseconds,
|
||||||
|
label: 'success'
|
||||||
|
));
|
||||||
// Not limiting to catching Exception because the exception is rethrown.
|
// Not limiting to catching Exception because the exception is rethrown.
|
||||||
} catch (_) { // ignore: avoid_catches_without_on_clauses
|
} catch (_) { // ignore: avoid_catches_without_on_clauses
|
||||||
globals.flutterUsage.sendTiming('pub', 'get', timer.elapsed, label: 'failure');
|
final Duration elapsedDuration = timer.elapsed;
|
||||||
|
globals.flutterUsage.sendTiming('pub', 'get', elapsedDuration, label: 'failure');
|
||||||
|
analytics.send(Event.timing(
|
||||||
|
workflow: 'pub',
|
||||||
|
variableName: 'get',
|
||||||
|
elapsedMilliseconds: elapsedDuration.inMilliseconds,
|
||||||
|
label: 'failure'
|
||||||
|
));
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,7 +419,13 @@ Future<XcodeBuildResult> buildXcodeProject({
|
|||||||
'Xcode ${xcodeBuildActionToString(buildAction)} done.'.padRight(kDefaultStatusPadding + 1)
|
'Xcode ${xcodeBuildActionToString(buildAction)} done.'.padRight(kDefaultStatusPadding + 1)
|
||||||
+ getElapsedAsSeconds(sw.elapsed).padLeft(5),
|
+ getElapsedAsSeconds(sw.elapsed).padLeft(5),
|
||||||
);
|
);
|
||||||
globals.flutterUsage.sendTiming(xcodeBuildActionToString(buildAction), 'xcode-ios', Duration(milliseconds: sw.elapsedMilliseconds));
|
final Duration elapsedDuration = sw.elapsed;
|
||||||
|
globals.flutterUsage.sendTiming(xcodeBuildActionToString(buildAction), 'xcode-ios', elapsedDuration);
|
||||||
|
globals.analytics.send(Event.timing(
|
||||||
|
workflow: xcodeBuildActionToString(buildAction),
|
||||||
|
variableName: 'xcode-ios',
|
||||||
|
elapsedMilliseconds: elapsedDuration.inMilliseconds,
|
||||||
|
));
|
||||||
|
|
||||||
if (tempDir.existsSync()) {
|
if (tempDir.existsSync()) {
|
||||||
// Display additional warning and error message from xcresult bundle.
|
// Display additional warning and error message from xcresult bundle.
|
||||||
|
@ -452,6 +452,11 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
|
|||||||
// Don't track restart times for dart2js builds or web-server devices.
|
// Don't track restart times for dart2js builds or web-server devices.
|
||||||
if (debuggingOptions.buildInfo.isDebug && deviceIsDebuggable) {
|
if (debuggingOptions.buildInfo.isDebug && deviceIsDebuggable) {
|
||||||
_usage.sendTiming('hot', 'web-incremental-restart', elapsed);
|
_usage.sendTiming('hot', 'web-incremental-restart', elapsed);
|
||||||
|
_analytics.send(Event.timing(
|
||||||
|
workflow: 'hot',
|
||||||
|
variableName: 'web-incremental-restart',
|
||||||
|
elapsedMilliseconds: elapsed.inMilliseconds,
|
||||||
|
));
|
||||||
final String sdkName = await device!.device!.sdkNameAndVersion;
|
final String sdkName = await device!.device!.sdkNameAndVersion;
|
||||||
HotEvent(
|
HotEvent(
|
||||||
'restart',
|
'restart',
|
||||||
|
@ -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 'package:unified_analytics/unified_analytics.dart';
|
||||||
|
|
||||||
import '../artifacts.dart';
|
import '../artifacts.dart';
|
||||||
import '../base/analyze_size.dart';
|
import '../base/analyze_size.dart';
|
||||||
import '../base/common.dart';
|
import '../base/common.dart';
|
||||||
@ -155,7 +157,13 @@ Future<void> _runCmake(String buildModeName, Directory sourceDir, Directory buil
|
|||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
throwToolExit('Unable to generate build files');
|
throwToolExit('Unable to generate build files');
|
||||||
}
|
}
|
||||||
globals.flutterUsage.sendTiming('build', 'cmake-linux', Duration(milliseconds: sw.elapsedMilliseconds));
|
final Duration elapsedDuration = sw.elapsed;
|
||||||
|
globals.flutterUsage.sendTiming('build', 'cmake-linux', elapsedDuration);
|
||||||
|
globals.analytics.send(Event.timing(
|
||||||
|
workflow: 'build',
|
||||||
|
variableName: 'cmake-linux',
|
||||||
|
elapsedMilliseconds: elapsedDuration.inMilliseconds,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _runBuild(Directory buildDir) async {
|
Future<void> _runBuild(Directory buildDir) async {
|
||||||
@ -185,5 +193,11 @@ Future<void> _runBuild(Directory buildDir) async {
|
|||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
throwToolExit('Build process failed');
|
throwToolExit('Build process failed');
|
||||||
}
|
}
|
||||||
globals.flutterUsage.sendTiming('build', 'linux-ninja', Duration(milliseconds: sw.elapsedMilliseconds));
|
final Duration elapsedDuration = sw.elapsed;
|
||||||
|
globals.flutterUsage.sendTiming('build', 'linux-ninja', elapsedDuration);
|
||||||
|
globals.analytics.send(Event.timing(
|
||||||
|
workflow: 'build',
|
||||||
|
variableName: 'linux-ninja',
|
||||||
|
elapsedMilliseconds: elapsedDuration.inMilliseconds,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
@ -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 'package:unified_analytics/unified_analytics.dart';
|
||||||
|
|
||||||
import '../base/analyze_size.dart';
|
import '../base/analyze_size.dart';
|
||||||
import '../base/common.dart';
|
import '../base/common.dart';
|
||||||
import '../base/file_system.dart';
|
import '../base/file_system.dart';
|
||||||
@ -160,7 +162,13 @@ Future<void> buildMacOS({
|
|||||||
throwToolExit('Build process failed');
|
throwToolExit('Build process failed');
|
||||||
}
|
}
|
||||||
await _writeCodeSizeAnalysis(buildInfo, sizeAnalyzer);
|
await _writeCodeSizeAnalysis(buildInfo, sizeAnalyzer);
|
||||||
globals.flutterUsage.sendTiming('build', 'xcode-macos', Duration(milliseconds: sw.elapsedMilliseconds));
|
final Duration elapsedDuration = sw.elapsed;
|
||||||
|
globals.flutterUsage.sendTiming('build', 'xcode-macos', elapsedDuration);
|
||||||
|
globals.analytics.send(Event.timing(
|
||||||
|
workflow: 'build',
|
||||||
|
variableName: 'xcode-macos',
|
||||||
|
elapsedMilliseconds: elapsedDuration.inMilliseconds,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Performs a size analysis of the AOT snapshot and writes to an analysis file, if configured.
|
/// Performs a size analysis of the AOT snapshot and writes to an analysis file, if configured.
|
||||||
|
@ -713,7 +713,13 @@ class HotRunner extends ResidentRunner {
|
|||||||
restartTimer.elapsed.inMilliseconds);
|
restartTimer.elapsed.inMilliseconds);
|
||||||
|
|
||||||
// Send timing analytics.
|
// Send timing analytics.
|
||||||
globals.flutterUsage.sendTiming('hot', 'restart', restartTimer.elapsed);
|
final Duration elapsedDuration = restartTimer.elapsed;
|
||||||
|
globals.flutterUsage.sendTiming('hot', 'restart', elapsedDuration);
|
||||||
|
_analytics.send(Event.timing(
|
||||||
|
workflow: 'hot',
|
||||||
|
variableName: 'restart',
|
||||||
|
elapsedMilliseconds: elapsedDuration.inMilliseconds,
|
||||||
|
));
|
||||||
|
|
||||||
// Toggle the main dill name after successfully uploading.
|
// Toggle the main dill name after successfully uploading.
|
||||||
_swap =! _swap;
|
_swap =! _swap;
|
||||||
@ -1112,6 +1118,11 @@ class HotRunner extends ResidentRunner {
|
|||||||
// Only report timings if we reloaded a single view without any errors.
|
// Only report timings if we reloaded a single view without any errors.
|
||||||
if ((reassembleResult.reassembleViews.length == 1) && !reassembleResult.failedReassemble && shouldReportReloadTime) {
|
if ((reassembleResult.reassembleViews.length == 1) && !reassembleResult.failedReassemble && shouldReportReloadTime) {
|
||||||
globals.flutterUsage.sendTiming('hot', 'reload', reloadDuration);
|
globals.flutterUsage.sendTiming('hot', 'reload', reloadDuration);
|
||||||
|
_analytics.send(Event.timing(
|
||||||
|
workflow: 'hot',
|
||||||
|
variableName: 'reload',
|
||||||
|
elapsedMilliseconds: reloadDuration.inMilliseconds,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
return OperationResult(
|
return OperationResult(
|
||||||
reassembleResult.failedReassemble ? 1 : OperationResult.ok.code,
|
reassembleResult.failedReassemble ? 1 : OperationResult.ok.code,
|
||||||
|
@ -1634,16 +1634,26 @@ abstract class FlutterCommand extends Command<void> {
|
|||||||
final String label = labels
|
final String label = labels
|
||||||
.where((String? label) => label != null && !_isBlank(label))
|
.where((String? label) => label != null && !_isBlank(label))
|
||||||
.join('-');
|
.join('-');
|
||||||
|
|
||||||
|
// If the command provides its own end time, use it. Otherwise report
|
||||||
|
// the duration of the entire execution.
|
||||||
|
final Duration elapsedDuration = (commandResult.endTimeOverride ?? endTime).difference(startTime);
|
||||||
globals.flutterUsage.sendTiming(
|
globals.flutterUsage.sendTiming(
|
||||||
'flutter',
|
'flutter',
|
||||||
name,
|
name,
|
||||||
// If the command provides its own end time, use it. Otherwise report
|
elapsedDuration,
|
||||||
// the duration of the entire execution.
|
|
||||||
(commandResult.endTimeOverride ?? endTime).difference(startTime),
|
|
||||||
// Report in the form of `success-[parameter1-parameter2]`, all of which
|
// Report in the form of `success-[parameter1-parameter2]`, all of which
|
||||||
// can be null if the command doesn't provide a FlutterCommandResult.
|
// can be null if the command doesn't provide a FlutterCommandResult.
|
||||||
label: label == '' ? null : label,
|
label: label == '' ? null : label,
|
||||||
);
|
);
|
||||||
|
analytics.send(Event.timing(
|
||||||
|
workflow: 'flutter',
|
||||||
|
variableName: name,
|
||||||
|
elapsedMilliseconds: elapsedDuration.inMilliseconds,
|
||||||
|
// Report in the form of `success-[parameter1-parameter2]`, all of which
|
||||||
|
// can be null if the command doesn't provide a FlutterCommandResult.
|
||||||
|
label: label == '' ? null : label,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform validation then call [runCommand] to execute the command.
|
/// Perform validation then call [runCommand] to execute the command.
|
||||||
@ -1707,7 +1717,7 @@ Run 'flutter -h' (or 'flutter <command> -h') for available flutter commands and
|
|||||||
processManager: globals.processManager,
|
processManager: globals.processManager,
|
||||||
platform: globals.platform,
|
platform: globals.platform,
|
||||||
usage: globals.flutterUsage,
|
usage: globals.flutterUsage,
|
||||||
analytics: globals.analytics,
|
analytics: analytics,
|
||||||
projectDir: project.directory,
|
projectDir: project.directory,
|
||||||
generateDartPluginRegistry: true,
|
generateDartPluginRegistry: true,
|
||||||
);
|
);
|
||||||
|
@ -6,6 +6,7 @@ import 'package:args/args.dart';
|
|||||||
import 'package:args/command_runner.dart';
|
import 'package:args/command_runner.dart';
|
||||||
import 'package:completion/completion.dart';
|
import 'package:completion/completion.dart';
|
||||||
import 'package:file/file.dart';
|
import 'package:file/file.dart';
|
||||||
|
import 'package:unified_analytics/unified_analytics.dart';
|
||||||
|
|
||||||
import '../artifacts.dart';
|
import '../artifacts.dart';
|
||||||
import '../base/common.dart';
|
import '../base/common.dart';
|
||||||
@ -329,6 +330,11 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
|||||||
|
|
||||||
if ((topLevelResults[FlutterGlobalOptions.kVersionFlag] as bool?) ?? false) {
|
if ((topLevelResults[FlutterGlobalOptions.kVersionFlag] as bool?) ?? false) {
|
||||||
globals.flutterUsage.sendCommand(FlutterGlobalOptions.kVersionFlag);
|
globals.flutterUsage.sendCommand(FlutterGlobalOptions.kVersionFlag);
|
||||||
|
globals.analytics.send(Event.flutterCommandResult(
|
||||||
|
commandPath: 'version',
|
||||||
|
result: 'success',
|
||||||
|
commandHasTerminal: globals.stdio.hasTerminal,
|
||||||
|
));
|
||||||
final FlutterVersion version = globals.flutterVersion.fetchTagsAndGetVersion(
|
final FlutterVersion version = globals.flutterVersion.fetchTagsAndGetVersion(
|
||||||
clock: globals.systemClock,
|
clock: globals.systemClock,
|
||||||
);
|
);
|
||||||
|
@ -150,11 +150,17 @@ class WebBuilder {
|
|||||||
settings: buildSettingsString,
|
settings: buildSettingsString,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
final Duration elapsedDuration = sw.elapsed;
|
||||||
_flutterUsage.sendTiming(
|
_flutterUsage.sendTiming(
|
||||||
'build',
|
'build',
|
||||||
compilerConfig.isWasm ? 'dart2wasm' : 'dart2js',
|
compilerConfig.isWasm ? 'dart2wasm' : 'dart2js',
|
||||||
Duration(milliseconds: sw.elapsedMilliseconds),
|
elapsedDuration,
|
||||||
);
|
);
|
||||||
|
_analytics.send(Event.timing(
|
||||||
|
workflow: 'build',
|
||||||
|
variableName: compilerConfig.isWasm ? 'dart2wasm' : 'dart2js',
|
||||||
|
elapsedMilliseconds: elapsedDuration.inMilliseconds,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 'package:unified_analytics/unified_analytics.dart';
|
||||||
|
|
||||||
import '../artifacts.dart';
|
import '../artifacts.dart';
|
||||||
import '../base/analyze_size.dart';
|
import '../base/analyze_size.dart';
|
||||||
import '../base/common.dart';
|
import '../base/common.dart';
|
||||||
@ -202,7 +204,13 @@ Future<void> _runCmakeGeneration({
|
|||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
throwToolExit('Unable to generate build files');
|
throwToolExit('Unable to generate build files');
|
||||||
}
|
}
|
||||||
globals.flutterUsage.sendTiming('build', 'windows-cmake-generation', Duration(milliseconds: sw.elapsedMilliseconds));
|
final Duration elapsedDuration = sw.elapsed;
|
||||||
|
globals.flutterUsage.sendTiming('build', 'windows-cmake-generation', elapsedDuration);
|
||||||
|
globals.analytics.send(Event.timing(
|
||||||
|
workflow: 'build',
|
||||||
|
variableName: 'windows-cmake-generation',
|
||||||
|
elapsedMilliseconds: elapsedDuration.inMilliseconds,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _runBuild(
|
Future<void> _runBuild(
|
||||||
@ -253,7 +261,13 @@ Future<void> _runBuild(
|
|||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
throwToolExit('Build process failed.');
|
throwToolExit('Build process failed.');
|
||||||
}
|
}
|
||||||
globals.flutterUsage.sendTiming('build', 'windows-cmake-build', Duration(milliseconds: sw.elapsedMilliseconds));
|
final Duration elapsedDuration = sw.elapsed;
|
||||||
|
globals.flutterUsage.sendTiming('build', 'windows-cmake-build', elapsedDuration);
|
||||||
|
globals.analytics.send(Event.timing(
|
||||||
|
workflow: 'build',
|
||||||
|
variableName: 'windows-cmake-build',
|
||||||
|
elapsedMilliseconds: elapsedDuration.inMilliseconds,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes the generated CMake file with the configuration for the given build.
|
/// Writes the generated CMake file with the configuration for the given build.
|
||||||
|
@ -48,7 +48,7 @@ dependencies:
|
|||||||
http_multi_server: 3.2.1
|
http_multi_server: 3.2.1
|
||||||
convert: 3.1.1
|
convert: 3.1.1
|
||||||
async: 2.11.0
|
async: 2.11.0
|
||||||
unified_analytics: 5.5.0
|
unified_analytics: 5.6.0
|
||||||
|
|
||||||
cli_config: 0.1.2
|
cli_config: 0.1.2
|
||||||
graphs: 2.3.1
|
graphs: 2.3.1
|
||||||
@ -69,7 +69,7 @@ dependencies:
|
|||||||
analyzer: 6.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
analyzer: 6.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||||
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||||
built_collection: 5.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
built_collection: 5.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||||
built_value: 8.7.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
built_value: 8.8.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||||
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||||
csslib: 1.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
csslib: 1.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||||
dap: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
dap: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||||
@ -91,7 +91,7 @@ dependencies:
|
|||||||
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||||
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||||
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||||
sse: 4.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
sse: 4.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||||
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||||
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||||
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||||
@ -115,4 +115,4 @@ dartdoc:
|
|||||||
# Exclude this package from the hosted API docs.
|
# Exclude this package from the hosted API docs.
|
||||||
nodoc: true
|
nodoc: true
|
||||||
|
|
||||||
# PUBSPEC CHECKSUM: e59e
|
# PUBSPEC CHECKSUM: b1a1
|
||||||
|
@ -19,6 +19,7 @@ import 'package:flutter_tools/src/ios/plist_parser.dart';
|
|||||||
import 'package:flutter_tools/src/ios/xcodeproj.dart';
|
import 'package:flutter_tools/src/ios/xcodeproj.dart';
|
||||||
import 'package:flutter_tools/src/reporting/reporting.dart';
|
import 'package:flutter_tools/src/reporting/reporting.dart';
|
||||||
import 'package:test/fake.dart';
|
import 'package:test/fake.dart';
|
||||||
|
import 'package:unified_analytics/unified_analytics.dart';
|
||||||
|
|
||||||
import '../../general.shard/ios/xcresult_test_data.dart';
|
import '../../general.shard/ios/xcresult_test_data.dart';
|
||||||
import '../../src/common.dart';
|
import '../../src/common.dart';
|
||||||
@ -78,6 +79,7 @@ void main() {
|
|||||||
late FakePlistUtils plistUtils;
|
late FakePlistUtils plistUtils;
|
||||||
late BufferLogger logger;
|
late BufferLogger logger;
|
||||||
late Artifacts artifacts;
|
late Artifacts artifacts;
|
||||||
|
late FakeAnalytics fakeAnalytics;
|
||||||
|
|
||||||
setUpAll(() {
|
setUpAll(() {
|
||||||
Cache.disableLocking();
|
Cache.disableLocking();
|
||||||
@ -94,6 +96,10 @@ void main() {
|
|||||||
processManager: fakeProcessManager,
|
processManager: fakeProcessManager,
|
||||||
);
|
);
|
||||||
plistUtils = FakePlistUtils();
|
plistUtils = FakePlistUtils();
|
||||||
|
fakeAnalytics = getInitializedFakeAnalyticsInstance(
|
||||||
|
fs: fileSystem,
|
||||||
|
fakeFlutterVersion: FakeFlutterVersion(),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 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.
|
||||||
@ -794,6 +800,9 @@ void main() {
|
|||||||
const TestUsageEvent('code-size-analysis', 'ios'),
|
const TestUsageEvent('code-size-analysis', 'ios'),
|
||||||
));
|
));
|
||||||
expect(fakeProcessManager, hasNoRemainingExpectations);
|
expect(fakeProcessManager, hasNoRemainingExpectations);
|
||||||
|
expect(fakeAnalytics.sentEvents, contains(
|
||||||
|
Event.codeSizeAnalysis(platform: 'ios')
|
||||||
|
));
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
Logger: () => logger,
|
Logger: () => logger,
|
||||||
@ -801,6 +810,7 @@ void main() {
|
|||||||
Platform: () => macosPlatform,
|
Platform: () => macosPlatform,
|
||||||
FileSystemUtils: () => FileSystemUtils(fileSystem: fileSystem, platform: macosPlatform),
|
FileSystemUtils: () => FileSystemUtils(fileSystem: fileSystem, platform: macosPlatform),
|
||||||
Usage: () => usage,
|
Usage: () => usage,
|
||||||
|
Analytics: () => fakeAnalytics,
|
||||||
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
|
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ 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:test/fake.dart';
|
import 'package:test/fake.dart';
|
||||||
|
import 'package:unified_analytics/unified_analytics.dart';
|
||||||
|
|
||||||
import '../../src/common.dart';
|
import '../../src/common.dart';
|
||||||
import '../../src/context.dart';
|
import '../../src/context.dart';
|
||||||
@ -48,12 +49,13 @@ void main() {
|
|||||||
Cache.disableLocking();
|
Cache.disableLocking();
|
||||||
});
|
});
|
||||||
|
|
||||||
late FileSystem fileSystem;
|
late MemoryFileSystem fileSystem;
|
||||||
late FakeProcessManager processManager;
|
late FakeProcessManager processManager;
|
||||||
late ProcessUtils processUtils;
|
late ProcessUtils processUtils;
|
||||||
late Logger logger;
|
late Logger logger;
|
||||||
late TestUsage usage;
|
late TestUsage usage;
|
||||||
late Artifacts artifacts;
|
late Artifacts artifacts;
|
||||||
|
late FakeAnalytics fakeAnalytics;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
fileSystem = MemoryFileSystem.test();
|
fileSystem = MemoryFileSystem.test();
|
||||||
@ -66,6 +68,10 @@ void main() {
|
|||||||
logger: logger,
|
logger: logger,
|
||||||
processManager: processManager,
|
processManager: processManager,
|
||||||
);
|
);
|
||||||
|
fakeAnalytics = getInitializedFakeAnalyticsInstance(
|
||||||
|
fs: fileSystem,
|
||||||
|
fakeFlutterVersion: FakeFlutterVersion(),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Creates the mock files necessary to look like a Flutter project.
|
// Creates the mock files necessary to look like a Flutter project.
|
||||||
@ -209,12 +215,30 @@ void main() {
|
|||||||
const <String>['build', 'linux', '--no-pub']
|
const <String>['build', 'linux', '--no-pub']
|
||||||
);
|
);
|
||||||
expect(fileSystem.file('linux/flutter/ephemeral/generated_config.cmake'), exists);
|
expect(fileSystem.file('linux/flutter/ephemeral/generated_config.cmake'), exists);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
analyticsTimingEventExists(
|
||||||
|
sentEvents: fakeAnalytics.sentEvents,
|
||||||
|
workflow: 'build',
|
||||||
|
variableName: 'cmake-linux',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
analyticsTimingEventExists(
|
||||||
|
sentEvents: fakeAnalytics.sentEvents,
|
||||||
|
workflow: 'build',
|
||||||
|
variableName: 'linux-ninja',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
ProcessManager: () => processManager,
|
ProcessManager: () => processManager,
|
||||||
Platform: () => linuxPlatform,
|
Platform: () => linuxPlatform,
|
||||||
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
|
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
|
||||||
OperatingSystemUtils: () => FakeOperatingSystemUtils(),
|
OperatingSystemUtils: () => FakeOperatingSystemUtils(),
|
||||||
|
Analytics: () => fakeAnalytics,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('Handles missing cmake', () async {
|
testUsingContext('Handles missing cmake', () async {
|
||||||
@ -701,6 +725,9 @@ set(BINARY_NAME "fizz_bar")
|
|||||||
expect(usage.events, contains(
|
expect(usage.events, contains(
|
||||||
const TestUsageEvent('code-size-analysis', 'linux'),
|
const TestUsageEvent('code-size-analysis', 'linux'),
|
||||||
));
|
));
|
||||||
|
expect(fakeAnalytics.sentEvents, contains(
|
||||||
|
Event.codeSizeAnalysis(platform: 'linux')
|
||||||
|
));
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
ProcessManager: () => processManager,
|
ProcessManager: () => processManager,
|
||||||
@ -708,6 +735,7 @@ set(BINARY_NAME "fizz_bar")
|
|||||||
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
|
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
|
||||||
Usage: () => usage,
|
Usage: () => usage,
|
||||||
OperatingSystemUtils: () => FakeOperatingSystemUtils(),
|
OperatingSystemUtils: () => FakeOperatingSystemUtils(),
|
||||||
|
Analytics: () => fakeAnalytics,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('Linux on ARM64 build --release passes, and check if the LinuxBuildDirectory for arm64 can be referenced correctly by using analytics', () async {
|
testUsingContext('Linux on ARM64 build --release passes, and check if the LinuxBuildDirectory for arm64 can be referenced correctly by using analytics', () async {
|
||||||
@ -754,6 +782,9 @@ set(BINARY_NAME "fizz_bar")
|
|||||||
expect(usage.events, contains(
|
expect(usage.events, contains(
|
||||||
const TestUsageEvent('code-size-analysis', 'linux'),
|
const TestUsageEvent('code-size-analysis', 'linux'),
|
||||||
));
|
));
|
||||||
|
expect(fakeAnalytics.sentEvents, contains(
|
||||||
|
Event.codeSizeAnalysis(platform: 'linux')
|
||||||
|
));
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
ProcessManager: () => processManager,
|
ProcessManager: () => processManager,
|
||||||
@ -761,6 +792,7 @@ set(BINARY_NAME "fizz_bar")
|
|||||||
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
|
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
|
||||||
Usage: () => usage,
|
Usage: () => usage,
|
||||||
OperatingSystemUtils: () => CustomFakeOperatingSystemUtils(hostPlatform: HostPlatform.linux_arm64),
|
OperatingSystemUtils: () => CustomFakeOperatingSystemUtils(hostPlatform: HostPlatform.linux_arm64),
|
||||||
|
Analytics: () => fakeAnalytics,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ 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:unified_analytics/unified_analytics.dart';
|
||||||
|
|
||||||
import '../../src/common.dart';
|
import '../../src/common.dart';
|
||||||
import '../../src/context.dart';
|
import '../../src/context.dart';
|
||||||
@ -70,6 +71,7 @@ void main() {
|
|||||||
late BufferLogger logger;
|
late BufferLogger logger;
|
||||||
late XcodeProjectInterpreter xcodeProjectInterpreter;
|
late XcodeProjectInterpreter xcodeProjectInterpreter;
|
||||||
late Artifacts artifacts;
|
late Artifacts artifacts;
|
||||||
|
late FakeAnalytics fakeAnalytics;
|
||||||
|
|
||||||
setUpAll(() {
|
setUpAll(() {
|
||||||
Cache.disableLocking();
|
Cache.disableLocking();
|
||||||
@ -86,6 +88,10 @@ void main() {
|
|||||||
processManager: fakeProcessManager,
|
processManager: fakeProcessManager,
|
||||||
);
|
);
|
||||||
xcodeProjectInterpreter = FakeXcodeProjectInterpreter();
|
xcodeProjectInterpreter = FakeXcodeProjectInterpreter();
|
||||||
|
fakeAnalytics = getInitializedFakeAnalyticsInstance(
|
||||||
|
fs: fileSystem,
|
||||||
|
fakeFlutterVersion: FakeFlutterVersion(),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 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.
|
||||||
@ -194,11 +200,21 @@ STDERR STUFF
|
|||||||
await createTestCommandRunner(command).run(
|
await createTestCommandRunner(command).run(
|
||||||
const <String>['build', 'macos', '--no-pub']
|
const <String>['build', 'macos', '--no-pub']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
analyticsTimingEventExists(
|
||||||
|
sentEvents: fakeAnalytics.sentEvents,
|
||||||
|
workflow: 'build',
|
||||||
|
variableName: 'xcode-macos',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Platform: () => macosPlatform,
|
Platform: () => macosPlatform,
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true),
|
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true),
|
||||||
|
Analytics: () => fakeAnalytics,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('macOS build fails on non-macOS platform', () async {
|
testUsingContext('macOS build fails on non-macOS platform', () async {
|
||||||
@ -594,6 +610,7 @@ STDERR STUFF
|
|||||||
expect(usage.events, contains(
|
expect(usage.events, contains(
|
||||||
const TestUsageEvent('code-size-analysis', 'macos'),
|
const TestUsageEvent('code-size-analysis', 'macos'),
|
||||||
));
|
));
|
||||||
|
expect(fakeAnalytics.sentEvents, contains(Event.codeSizeAnalysis(platform: 'macos')));
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
|
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
|
||||||
@ -618,5 +635,6 @@ STDERR STUFF
|
|||||||
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true),
|
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true),
|
||||||
FileSystemUtils: () => FileSystemUtils(fileSystem: fileSystem, platform: macosPlatform),
|
FileSystemUtils: () => FileSystemUtils(fileSystem: fileSystem, platform: macosPlatform),
|
||||||
Usage: () => usage,
|
Usage: () => usage,
|
||||||
|
Analytics: () => fakeAnalytics,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import 'package:flutter_tools/src/features.dart';
|
|||||||
import 'package:flutter_tools/src/reporting/reporting.dart';
|
import 'package:flutter_tools/src/reporting/reporting.dart';
|
||||||
import 'package:flutter_tools/src/windows/visual_studio.dart';
|
import 'package:flutter_tools/src/windows/visual_studio.dart';
|
||||||
import 'package:test/fake.dart';
|
import 'package:test/fake.dart';
|
||||||
|
import 'package:unified_analytics/unified_analytics.dart';
|
||||||
|
|
||||||
import '../../src/common.dart';
|
import '../../src/common.dart';
|
||||||
import '../../src/context.dart';
|
import '../../src/context.dart';
|
||||||
@ -45,6 +46,7 @@ void main() {
|
|||||||
late FileSystem fileSystem;
|
late FileSystem fileSystem;
|
||||||
late ProcessManager processManager;
|
late ProcessManager processManager;
|
||||||
late TestUsage usage;
|
late TestUsage usage;
|
||||||
|
late FakeAnalytics fakeAnalytics;
|
||||||
|
|
||||||
setUpAll(() {
|
setUpAll(() {
|
||||||
Cache.disableLocking();
|
Cache.disableLocking();
|
||||||
@ -55,6 +57,10 @@ void main() {
|
|||||||
fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
|
fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
|
||||||
Cache.flutterRoot = flutterRoot;
|
Cache.flutterRoot = flutterRoot;
|
||||||
usage = TestUsage();
|
usage = TestUsage();
|
||||||
|
fakeAnalytics = getInitializedFakeAnalyticsInstance(
|
||||||
|
fs: fileSystem,
|
||||||
|
fakeFlutterVersion: FakeFlutterVersion(),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Creates the mock files necessary to look like a Flutter project.
|
// Creates the mock files necessary to look like a Flutter project.
|
||||||
@ -209,6 +215,46 @@ void main() {
|
|||||||
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
|
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testUsingContext('Windows build sends timing events', () async {
|
||||||
|
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
||||||
|
final BuildWindowsCommand command = BuildWindowsCommand(logger: BufferLogger.test())
|
||||||
|
..visualStudioOverride = fakeVisualStudio;
|
||||||
|
setUpMockProjectFilesForBuild();
|
||||||
|
|
||||||
|
processManager = FakeProcessManager.list(<FakeCommand>[
|
||||||
|
cmakeGenerationCommand(),
|
||||||
|
buildCommand('Release'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await createTestCommandRunner(command).run(
|
||||||
|
const <String>['windows', '--no-pub']
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
analyticsTimingEventExists(
|
||||||
|
sentEvents: fakeAnalytics.sentEvents,
|
||||||
|
workflow: 'build',
|
||||||
|
variableName: 'windows-cmake-generation',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
analyticsTimingEventExists(
|
||||||
|
sentEvents: fakeAnalytics.sentEvents,
|
||||||
|
workflow: 'build',
|
||||||
|
variableName: 'windows-cmake-build',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => fileSystem,
|
||||||
|
ProcessManager: () => processManager,
|
||||||
|
Platform: () => windowsPlatform,
|
||||||
|
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
|
||||||
|
Analytics: () => fakeAnalytics,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
testUsingContext('Windows build extracts errors from stdout', () async {
|
testUsingContext('Windows build extracts errors from stdout', () async {
|
||||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
||||||
final BuildWindowsCommand command = BuildWindowsCommand(logger: BufferLogger.test())
|
final BuildWindowsCommand command = BuildWindowsCommand(logger: BufferLogger.test())
|
||||||
@ -929,6 +975,9 @@ if %errorlevel% neq 0 goto :VCEnd</Command>
|
|||||||
expect(usage.events, contains(
|
expect(usage.events, contains(
|
||||||
const TestUsageEvent('code-size-analysis', 'windows'),
|
const TestUsageEvent('code-size-analysis', 'windows'),
|
||||||
));
|
));
|
||||||
|
expect(fakeAnalytics.sentEvents, contains(
|
||||||
|
Event.codeSizeAnalysis(platform: 'windows')
|
||||||
|
));
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
|
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
@ -936,6 +985,7 @@ if %errorlevel% neq 0 goto :VCEnd</Command>
|
|||||||
Platform: () => windowsPlatform,
|
Platform: () => windowsPlatform,
|
||||||
FileSystemUtils: () => FileSystemUtils(fileSystem: fileSystem, platform: windowsPlatform),
|
FileSystemUtils: () => FileSystemUtils(fileSystem: fileSystem, platform: windowsPlatform),
|
||||||
Usage: () => usage,
|
Usage: () => usage,
|
||||||
|
Analytics: () => fakeAnalytics,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Confirms that running for Windows in a directory with a
|
// Confirms that running for Windows in a directory with a
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:args/command_runner.dart';
|
import 'package:args/command_runner.dart';
|
||||||
|
import 'package:file/memory.dart';
|
||||||
import 'package:flutter_tools/src/android/android_sdk.dart';
|
import 'package:flutter_tools/src/android/android_sdk.dart';
|
||||||
import 'package:flutter_tools/src/android/android_studio.dart';
|
import 'package:flutter_tools/src/android/android_studio.dart';
|
||||||
import 'package:flutter_tools/src/android/java.dart';
|
import 'package:flutter_tools/src/android/java.dart';
|
||||||
@ -17,10 +18,11 @@ import 'package:flutter_tools/src/globals.dart' as globals;
|
|||||||
import 'package:flutter_tools/src/reporting/reporting.dart';
|
import 'package:flutter_tools/src/reporting/reporting.dart';
|
||||||
import 'package:flutter_tools/src/version.dart';
|
import 'package:flutter_tools/src/version.dart';
|
||||||
import 'package:test/fake.dart';
|
import 'package:test/fake.dart';
|
||||||
|
import 'package:unified_analytics/unified_analytics.dart';
|
||||||
|
|
||||||
import '../../src/common.dart';
|
import '../../src/common.dart';
|
||||||
import '../../src/context.dart';
|
import '../../src/context.dart';
|
||||||
import '../../src/fakes.dart';
|
import '../../src/fakes.dart' as fakes;
|
||||||
import '../../src/test_flutter_command_runner.dart';
|
import '../../src/test_flutter_command_runner.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
@ -29,23 +31,29 @@ void main() {
|
|||||||
late FakeAndroidSdk fakeAndroidSdk;
|
late FakeAndroidSdk fakeAndroidSdk;
|
||||||
late FakeFlutterVersion fakeFlutterVersion;
|
late FakeFlutterVersion fakeFlutterVersion;
|
||||||
late TestUsage testUsage;
|
late TestUsage testUsage;
|
||||||
|
late FakeAnalytics fakeAnalytics;
|
||||||
|
|
||||||
setUpAll(() {
|
setUpAll(() {
|
||||||
Cache.disableLocking();
|
Cache.disableLocking();
|
||||||
});
|
});
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
fakeJava = FakeJava();
|
fakeJava = fakes.FakeJava();
|
||||||
fakeAndroidStudio = FakeAndroidStudio();
|
fakeAndroidStudio = FakeAndroidStudio();
|
||||||
fakeAndroidSdk = FakeAndroidSdk();
|
fakeAndroidSdk = FakeAndroidSdk();
|
||||||
fakeFlutterVersion = FakeFlutterVersion();
|
fakeFlutterVersion = FakeFlutterVersion();
|
||||||
testUsage = TestUsage();
|
testUsage = TestUsage();
|
||||||
|
fakeAnalytics = getInitializedFakeAnalyticsInstance(
|
||||||
|
fs: MemoryFileSystem.test(),
|
||||||
|
fakeFlutterVersion: fakes.FakeFlutterVersion(),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
void verifyNoAnalytics() {
|
void verifyNoAnalytics() {
|
||||||
expect(testUsage.commands, isEmpty);
|
expect(testUsage.commands, isEmpty);
|
||||||
expect(testUsage.events, isEmpty);
|
expect(testUsage.events, isEmpty);
|
||||||
expect(testUsage.timings, isEmpty);
|
expect(testUsage.timings, isEmpty);
|
||||||
|
expect(fakeAnalytics.sentEvents, isEmpty);
|
||||||
}
|
}
|
||||||
|
|
||||||
group('config', () {
|
group('config', () {
|
||||||
@ -263,6 +271,7 @@ void main() {
|
|||||||
]));
|
]));
|
||||||
expect(testUsage.commands, isEmpty);
|
expect(testUsage.commands, isEmpty);
|
||||||
expect(testUsage.timings, isEmpty);
|
expect(testUsage.timings, isEmpty);
|
||||||
|
expect(fakeAnalytics.sentEvents, isEmpty);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Usage: () => testUsage,
|
Usage: () => testUsage,
|
||||||
});
|
});
|
||||||
@ -285,6 +294,7 @@ void main() {
|
|||||||
]));
|
]));
|
||||||
expect(testUsage.commands, isEmpty);
|
expect(testUsage.commands, isEmpty);
|
||||||
expect(testUsage.timings, isEmpty);
|
expect(testUsage.timings, isEmpty);
|
||||||
|
expect(fakeAnalytics.sentEvents, isEmpty);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Usage: () => testUsage,
|
Usage: () => testUsage,
|
||||||
});
|
});
|
||||||
|
@ -23,6 +23,7 @@ import 'package:flutter_tools/src/cache.dart';
|
|||||||
import 'package:flutter_tools/src/commands/packages.dart';
|
import 'package:flutter_tools/src/commands/packages.dart';
|
||||||
import 'package:flutter_tools/src/dart/pub.dart';
|
import 'package:flutter_tools/src/dart/pub.dart';
|
||||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||||
|
import 'package:unified_analytics/unified_analytics.dart';
|
||||||
|
|
||||||
import '../../src/common.dart';
|
import '../../src/common.dart';
|
||||||
import '../../src/context.dart';
|
import '../../src/context.dart';
|
||||||
@ -40,9 +41,14 @@ void main() {
|
|||||||
Cache.disableLocking();
|
Cache.disableLocking();
|
||||||
group('packages get/upgrade', () {
|
group('packages get/upgrade', () {
|
||||||
late Directory tempDir;
|
late Directory tempDir;
|
||||||
|
late FakeAnalytics fakeAnalytics;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_tools_packages_test.');
|
tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_tools_packages_test.');
|
||||||
|
fakeAnalytics = getInitializedFakeAnalyticsInstance(
|
||||||
|
fs: MemoryFileSystem.test(),
|
||||||
|
fakeFlutterVersion: FakeFlutterVersion(),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
@ -220,6 +226,15 @@ void main() {
|
|||||||
|
|
||||||
expectDependenciesResolved(projectPath);
|
expectDependenciesResolved(projectPath);
|
||||||
expectZeroPluginsInjected(projectPath);
|
expectZeroPluginsInjected(projectPath);
|
||||||
|
expect(
|
||||||
|
analyticsTimingEventExists(
|
||||||
|
sentEvents: fakeAnalytics.sentEvents,
|
||||||
|
workflow: 'pub',
|
||||||
|
variableName: 'get',
|
||||||
|
label: 'success',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Stdio: () => mockStdio,
|
Stdio: () => mockStdio,
|
||||||
Pub: () => Pub.test(
|
Pub: () => Pub.test(
|
||||||
@ -231,6 +246,7 @@ void main() {
|
|||||||
platform: globals.platform,
|
platform: globals.platform,
|
||||||
stdio: mockStdio,
|
stdio: mockStdio,
|
||||||
),
|
),
|
||||||
|
Analytics: () => fakeAnalytics,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('get --offline fetches packages', () async {
|
testUsingContext('get --offline fetches packages', () async {
|
||||||
|
@ -145,11 +145,21 @@ void main() {
|
|||||||
|
|
||||||
expect(
|
expect(
|
||||||
fakeAnalytics.sentEvents,
|
fakeAnalytics.sentEvents,
|
||||||
unorderedEquals(<Event>[
|
containsAll(<Event>[
|
||||||
Event.flutterBuildInfo(label: 'app-not-using-android-x', buildType: 'gradle'),
|
Event.flutterBuildInfo(label: 'app-not-using-android-x', buildType: 'gradle'),
|
||||||
Event.flutterBuildInfo(label: 'gradle-random-event-label-failure', buildType: 'gradle'),
|
Event.flutterBuildInfo(label: 'gradle-random-event-label-failure', buildType: 'gradle'),
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
analyticsTimingEventExists(
|
||||||
|
sentEvents: fakeAnalytics.sentEvents,
|
||||||
|
workflow: 'build',
|
||||||
|
variableName: 'gradle',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
AndroidStudio: () => FakeAndroidStudio(),
|
AndroidStudio: () => FakeAndroidStudio(),
|
||||||
});
|
});
|
||||||
@ -328,7 +338,7 @@ void main() {
|
|||||||
));
|
));
|
||||||
expect(testUsage.events, hasLength(4));
|
expect(testUsage.events, hasLength(4));
|
||||||
|
|
||||||
expect(fakeAnalytics.sentEvents, hasLength(4));
|
expect(fakeAnalytics.sentEvents, hasLength(7));
|
||||||
expect(fakeAnalytics.sentEvents, contains(
|
expect(fakeAnalytics.sentEvents, contains(
|
||||||
Event.flutterBuildInfo(
|
Event.flutterBuildInfo(
|
||||||
label: 'gradle-random-event-label-failure',
|
label: 'gradle-random-event-label-failure',
|
||||||
@ -431,7 +441,7 @@ void main() {
|
|||||||
));
|
));
|
||||||
expect(testUsage.events, hasLength(2));
|
expect(testUsage.events, hasLength(2));
|
||||||
|
|
||||||
expect(fakeAnalytics.sentEvents, hasLength(2));
|
expect(fakeAnalytics.sentEvents, hasLength(3));
|
||||||
expect(fakeAnalytics.sentEvents, contains(
|
expect(fakeAnalytics.sentEvents, contains(
|
||||||
Event.flutterBuildInfo(
|
Event.flutterBuildInfo(
|
||||||
label: 'gradle-random-event-label-failure',
|
label: 'gradle-random-event-label-failure',
|
||||||
@ -878,8 +888,18 @@ BuildVariant: paidProfile
|
|||||||
project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
|
project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
|
||||||
);
|
);
|
||||||
expect(actual, <String>['freeDebug', 'paidDebug', 'freeRelease', 'paidRelease', 'freeProfile', 'paidProfile']);
|
expect(actual, <String>['freeDebug', 'paidDebug', 'freeRelease', 'paidRelease', 'freeProfile', 'paidProfile']);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
analyticsTimingEventExists(
|
||||||
|
sentEvents: fakeAnalytics.sentEvents,
|
||||||
|
workflow: 'print',
|
||||||
|
variableName: 'android build variants',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
AndroidStudio: () => FakeAndroidStudio(),
|
AndroidStudio: () => FakeAndroidStudio(),
|
||||||
|
Analytics: () => fakeAnalytics,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('getBuildOptions returns empty list if gradle returns error', () async {
|
testUsingContext('getBuildOptions returns empty list if gradle returns error', () async {
|
||||||
@ -941,10 +961,20 @@ Gradle Crashed
|
|||||||
'freeDebug',
|
'freeDebug',
|
||||||
project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
|
project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
analyticsTimingEventExists(
|
||||||
|
sentEvents: fakeAnalytics.sentEvents,
|
||||||
|
workflow: 'outputs',
|
||||||
|
variableName: 'app link settings',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
AndroidStudio: () => FakeAndroidStudio(),
|
AndroidStudio: () => FakeAndroidStudio(),
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
ProcessManager: () => processManager,
|
ProcessManager: () => processManager,
|
||||||
|
Analytics: () => fakeAnalytics,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext("doesn't indicate how to consume an AAR when printHowToConsumeAar is false", () async {
|
testUsingContext("doesn't indicate how to consume an AAR when printHowToConsumeAar is false", () async {
|
||||||
@ -1010,8 +1040,18 @@ Gradle Crashed
|
|||||||
isFalse,
|
isFalse,
|
||||||
);
|
);
|
||||||
expect(processManager, hasNoRemainingExpectations);
|
expect(processManager, hasNoRemainingExpectations);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
analyticsTimingEventExists(
|
||||||
|
sentEvents: fakeAnalytics.sentEvents,
|
||||||
|
workflow: 'build',
|
||||||
|
variableName: 'gradle-aar',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
AndroidStudio: () => FakeAndroidStudio(),
|
AndroidStudio: () => FakeAndroidStudio(),
|
||||||
|
Analytics: () => fakeAnalytics,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('Verbose mode for AARs includes Gradle stacktrace and sets debug log level', () async {
|
testUsingContext('Verbose mode for AARs includes Gradle stacktrace and sets debug log level', () async {
|
||||||
|
@ -21,7 +21,8 @@ import 'package:flutter_tools/src/resident_devtools_handler.dart';
|
|||||||
import 'package:flutter_tools/src/resident_runner.dart';
|
import 'package:flutter_tools/src/resident_runner.dart';
|
||||||
import 'package:flutter_tools/src/run_hot.dart';
|
import 'package:flutter_tools/src/run_hot.dart';
|
||||||
import 'package:flutter_tools/src/vmservice.dart';
|
import 'package:flutter_tools/src/vmservice.dart';
|
||||||
import 'package:native_assets_cli/native_assets_cli.dart' hide BuildMode, Target;
|
import 'package:native_assets_cli/native_assets_cli.dart'
|
||||||
|
hide BuildMode, Target;
|
||||||
import 'package:native_assets_cli/native_assets_cli.dart' as native_assets_cli;
|
import 'package:native_assets_cli/native_assets_cli.dart' as native_assets_cli;
|
||||||
import 'package:package_config/package_config.dart';
|
import 'package:package_config/package_config.dart';
|
||||||
import 'package:test/fake.dart';
|
import 'package:test/fake.dart';
|
||||||
@ -36,84 +37,116 @@ import 'fake_native_assets_build_runner.dart';
|
|||||||
void main() {
|
void main() {
|
||||||
group('validateReloadReport', () {
|
group('validateReloadReport', () {
|
||||||
testUsingContext('invalid', () async {
|
testUsingContext('invalid', () async {
|
||||||
expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse(<String, dynamic>{
|
expect(
|
||||||
'type': 'ReloadReport',
|
HotRunner.validateReloadReport(
|
||||||
'success': false,
|
vm_service.ReloadReport.parse(<String, dynamic>{
|
||||||
'details': <String, dynamic>{},
|
'type': 'ReloadReport',
|
||||||
})), false);
|
'success': false,
|
||||||
expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse(<String, dynamic>{
|
'details': <String, dynamic>{},
|
||||||
'type': 'ReloadReport',
|
})),
|
||||||
'success': false,
|
false);
|
||||||
'details': <String, dynamic>{
|
expect(
|
||||||
'notices': <Map<String, dynamic>>[
|
HotRunner.validateReloadReport(
|
||||||
],
|
vm_service.ReloadReport.parse(<String, dynamic>{
|
||||||
},
|
'type': 'ReloadReport',
|
||||||
})), false);
|
'success': false,
|
||||||
expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse(<String, dynamic>{
|
'details': <String, dynamic>{
|
||||||
'type': 'ReloadReport',
|
'notices': <Map<String, dynamic>>[],
|
||||||
'success': false,
|
},
|
||||||
'details': <String, dynamic>{
|
})),
|
||||||
'notices': <String, dynamic>{
|
false);
|
||||||
'message': 'error',
|
expect(
|
||||||
},
|
HotRunner.validateReloadReport(
|
||||||
},
|
vm_service.ReloadReport.parse(<String, dynamic>{
|
||||||
})), false);
|
'type': 'ReloadReport',
|
||||||
expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse(<String, dynamic>{
|
'success': false,
|
||||||
'type': 'ReloadReport',
|
'details': <String, dynamic>{
|
||||||
'success': false,
|
'notices': <String, dynamic>{
|
||||||
'details': <String, dynamic>{
|
'message': 'error',
|
||||||
'notices': <Map<String, dynamic>>[],
|
},
|
||||||
},
|
},
|
||||||
})), false);
|
})),
|
||||||
expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse(<String, dynamic>{
|
false);
|
||||||
'type': 'ReloadReport',
|
expect(
|
||||||
'success': false,
|
HotRunner.validateReloadReport(
|
||||||
'details': <String, dynamic>{
|
vm_service.ReloadReport.parse(<String, dynamic>{
|
||||||
'notices': <Map<String, dynamic>>[
|
'type': 'ReloadReport',
|
||||||
<String, dynamic>{'message': false},
|
'success': false,
|
||||||
],
|
'details': <String, dynamic>{
|
||||||
},
|
'notices': <Map<String, dynamic>>[],
|
||||||
})), false);
|
},
|
||||||
expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse(<String, dynamic>{
|
})),
|
||||||
'type': 'ReloadReport',
|
false);
|
||||||
'success': false,
|
expect(
|
||||||
'details': <String, dynamic>{
|
HotRunner.validateReloadReport(
|
||||||
'notices': <Map<String, dynamic>>[
|
vm_service.ReloadReport.parse(<String, dynamic>{
|
||||||
<String, dynamic>{'message': <String>['error']},
|
'type': 'ReloadReport',
|
||||||
],
|
'success': false,
|
||||||
},
|
'details': <String, dynamic>{
|
||||||
})), false);
|
'notices': <Map<String, dynamic>>[
|
||||||
expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse(<String, dynamic>{
|
<String, dynamic>{'message': false},
|
||||||
'type': 'ReloadReport',
|
],
|
||||||
'success': false,
|
},
|
||||||
'details': <String, dynamic>{
|
})),
|
||||||
'notices': <Map<String, dynamic>>[
|
false);
|
||||||
<String, dynamic>{'message': 'error'},
|
expect(
|
||||||
<String, dynamic>{'message': <String>['error']},
|
HotRunner.validateReloadReport(
|
||||||
],
|
vm_service.ReloadReport.parse(<String, dynamic>{
|
||||||
},
|
'type': 'ReloadReport',
|
||||||
})), false);
|
'success': false,
|
||||||
expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse(<String, dynamic>{
|
'details': <String, dynamic>{
|
||||||
'type': 'ReloadReport',
|
'notices': <Map<String, dynamic>>[
|
||||||
'success': false,
|
<String, dynamic>{
|
||||||
'details': <String, dynamic>{
|
'message': <String>['error']
|
||||||
'notices': <Map<String, dynamic>>[
|
},
|
||||||
<String, dynamic>{'message': 'error'},
|
],
|
||||||
],
|
},
|
||||||
},
|
})),
|
||||||
})), false);
|
false);
|
||||||
expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse(<String, dynamic>{
|
expect(
|
||||||
'type': 'ReloadReport',
|
HotRunner.validateReloadReport(
|
||||||
'success': true,
|
vm_service.ReloadReport.parse(<String, dynamic>{
|
||||||
})), true);
|
'type': 'ReloadReport',
|
||||||
|
'success': false,
|
||||||
|
'details': <String, dynamic>{
|
||||||
|
'notices': <Map<String, dynamic>>[
|
||||||
|
<String, dynamic>{'message': 'error'},
|
||||||
|
<String, dynamic>{
|
||||||
|
'message': <String>['error']
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
false);
|
||||||
|
expect(
|
||||||
|
HotRunner.validateReloadReport(
|
||||||
|
vm_service.ReloadReport.parse(<String, dynamic>{
|
||||||
|
'type': 'ReloadReport',
|
||||||
|
'success': false,
|
||||||
|
'details': <String, dynamic>{
|
||||||
|
'notices': <Map<String, dynamic>>[
|
||||||
|
<String, dynamic>{'message': 'error'},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
false);
|
||||||
|
expect(
|
||||||
|
HotRunner.validateReloadReport(
|
||||||
|
vm_service.ReloadReport.parse(<String, dynamic>{
|
||||||
|
'type': 'ReloadReport',
|
||||||
|
'success': true,
|
||||||
|
})),
|
||||||
|
true);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('ReasonForCancelling toString has a hint for specific errors', () {
|
testWithoutContext(
|
||||||
|
'ReasonForCancelling toString has a hint for specific errors', () {
|
||||||
final ReasonForCancelling reasonForCancelling = ReasonForCancelling(
|
final ReasonForCancelling reasonForCancelling = ReasonForCancelling(
|
||||||
message: 'Const class cannot remove fields',
|
message: 'Const class cannot remove fields',
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(reasonForCancelling.toString(), contains('Try performing a hot restart instead.'));
|
expect(reasonForCancelling.toString(),
|
||||||
|
contains('Try performing a hot restart instead.'));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -147,7 +180,10 @@ void main() {
|
|||||||
..writeAsStringSync('\n');
|
..writeAsStringSync('\n');
|
||||||
final FakeDevice device = FakeDevice();
|
final FakeDevice device = FakeDevice();
|
||||||
final List<FlutterDevice> devices = <FlutterDevice>[
|
final List<FlutterDevice> devices = <FlutterDevice>[
|
||||||
FlutterDevice(device, generator: residentCompiler, buildInfo: BuildInfo.debug, developmentShaderCompiler: const FakeShaderCompiler())
|
FlutterDevice(device,
|
||||||
|
generator: residentCompiler,
|
||||||
|
buildInfo: BuildInfo.debug,
|
||||||
|
developmentShaderCompiler: const FakeShaderCompiler())
|
||||||
..devFS = FakeDevFs(),
|
..devFS = FakeDevFs(),
|
||||||
];
|
];
|
||||||
final OperationResult result = await HotRunner(
|
final OperationResult result = await HotRunner(
|
||||||
@ -156,7 +192,6 @@ void main() {
|
|||||||
target: 'main.dart',
|
target: 'main.dart',
|
||||||
devtoolsHandler: createNoOpHandler,
|
devtoolsHandler: createNoOpHandler,
|
||||||
analytics: fakeAnalytics,
|
analytics: fakeAnalytics,
|
||||||
|
|
||||||
).restart(fullRestart: true);
|
).restart(fullRestart: true);
|
||||||
expect(result.isOk, false);
|
expect(result.isOk, false);
|
||||||
expect(result.message, 'setupHotRestart failed');
|
expect(result.message, 'setupHotRestart failed');
|
||||||
@ -188,12 +223,13 @@ void main() {
|
|||||||
Map<FlutterDevice?, List<FlutterView>> viewCache,
|
Map<FlutterDevice?, List<FlutterView>> viewCache,
|
||||||
void Function(String message)? onSlow,
|
void Function(String message)? onSlow,
|
||||||
String reloadMessage,
|
String reloadMessage,
|
||||||
) async => ReassembleResult(
|
) async =>
|
||||||
<FlutterView?, FlutterVmService?>{null: null},
|
ReassembleResult(
|
||||||
false,
|
<FlutterView?, FlutterVmService?>{null: null},
|
||||||
true,
|
false,
|
||||||
),
|
true,
|
||||||
analytics: fakeAnalytics,
|
),
|
||||||
|
analytics: fakeAnalytics,
|
||||||
).restart();
|
).restart();
|
||||||
expect(result.isOk, false);
|
expect(result.isOk, false);
|
||||||
expect(result.message, 'setupHotReload failed');
|
expect(result.message, 'setupHotReload failed');
|
||||||
@ -220,7 +256,10 @@ void main() {
|
|||||||
..writeAsStringSync('\n');
|
..writeAsStringSync('\n');
|
||||||
final FakeDevice device = FakeDevice();
|
final FakeDevice device = FakeDevice();
|
||||||
final List<FlutterDevice> devices = <FlutterDevice>[
|
final List<FlutterDevice> devices = <FlutterDevice>[
|
||||||
FlutterDevice(device, generator: residentCompiler, buildInfo: BuildInfo.debug, developmentShaderCompiler: const FakeShaderCompiler()),
|
FlutterDevice(device,
|
||||||
|
generator: residentCompiler,
|
||||||
|
buildInfo: BuildInfo.debug,
|
||||||
|
developmentShaderCompiler: const FakeShaderCompiler()),
|
||||||
];
|
];
|
||||||
await HotRunner(
|
await HotRunner(
|
||||||
devices,
|
devices,
|
||||||
@ -243,7 +282,10 @@ void main() {
|
|||||||
..writeAsStringSync('\n');
|
..writeAsStringSync('\n');
|
||||||
final FakeDevice device = FakeDevice();
|
final FakeDevice device = FakeDevice();
|
||||||
final List<FlutterDevice> devices = <FlutterDevice>[
|
final List<FlutterDevice> devices = <FlutterDevice>[
|
||||||
FlutterDevice(device, generator: residentCompiler, buildInfo: BuildInfo.debug, developmentShaderCompiler: const FakeShaderCompiler()),
|
FlutterDevice(device,
|
||||||
|
generator: residentCompiler,
|
||||||
|
buildInfo: BuildInfo.debug,
|
||||||
|
developmentShaderCompiler: const FakeShaderCompiler()),
|
||||||
];
|
];
|
||||||
await HotRunner(
|
await HotRunner(
|
||||||
devices,
|
devices,
|
||||||
@ -268,30 +310,36 @@ void main() {
|
|||||||
successfulHotRestartSetup: true,
|
successfulHotRestartSetup: true,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
testUsingContext('correctly tracks time spent for analytics for hot restart', () async {
|
testUsingContext(
|
||||||
|
'correctly tracks time spent for analytics for hot restart',
|
||||||
|
() async {
|
||||||
final FakeDevice device = FakeDevice();
|
final FakeDevice device = FakeDevice();
|
||||||
final FakeFlutterDevice fakeFlutterDevice = FakeFlutterDevice(device);
|
final FakeFlutterDevice fakeFlutterDevice = FakeFlutterDevice(device);
|
||||||
final List<FlutterDevice> devices = <FlutterDevice>[
|
final List<FlutterDevice> devices = <FlutterDevice>[
|
||||||
fakeFlutterDevice,
|
fakeFlutterDevice,
|
||||||
];
|
];
|
||||||
|
|
||||||
fakeFlutterDevice.updateDevFSReportCallback = () async => UpdateFSReport(
|
fakeFlutterDevice.updateDevFSReportCallback =
|
||||||
success: true,
|
() async => UpdateFSReport(
|
||||||
invalidatedSourcesCount: 2,
|
success: true,
|
||||||
syncedBytes: 4,
|
invalidatedSourcesCount: 2,
|
||||||
scannedSourcesCount: 8,
|
syncedBytes: 4,
|
||||||
compileDuration: const Duration(seconds: 16),
|
scannedSourcesCount: 8,
|
||||||
transferDuration: const Duration(seconds: 32),
|
compileDuration: const Duration(seconds: 16),
|
||||||
);
|
transferDuration: const Duration(seconds: 32),
|
||||||
|
);
|
||||||
|
|
||||||
final FakeStopwatchFactory fakeStopwatchFactory = FakeStopwatchFactory(
|
final FakeStopwatchFactory fakeStopwatchFactory = FakeStopwatchFactory(
|
||||||
stopwatches: <String, Stopwatch>{
|
stopwatches: <String, Stopwatch>{
|
||||||
'fullRestartHelper': FakeStopwatch()..elapsed = const Duration(seconds: 64),
|
'fullRestartHelper': FakeStopwatch()
|
||||||
'updateDevFS': FakeStopwatch()..elapsed = const Duration(seconds: 128),
|
..elapsed = const Duration(seconds: 64),
|
||||||
|
'updateDevFS': FakeStopwatch()
|
||||||
|
..elapsed = const Duration(seconds: 128),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
(fakeFlutterDevice.devFS! as FakeDevFs).baseUri = Uri.parse('file:///base_uri');
|
(fakeFlutterDevice.devFS! as FakeDevFs).baseUri =
|
||||||
|
Uri.parse('file:///base_uri');
|
||||||
|
|
||||||
final OperationResult result = await HotRunner(
|
final OperationResult result = await HotRunner(
|
||||||
devices,
|
devices,
|
||||||
@ -304,37 +352,45 @@ void main() {
|
|||||||
|
|
||||||
expect(result.isOk, true);
|
expect(result.isOk, true);
|
||||||
expect(testUsage.events, <TestUsageEvent>[
|
expect(testUsage.events, <TestUsageEvent>[
|
||||||
const TestUsageEvent('hot', 'restart', parameters: CustomDimensions(
|
const TestUsageEvent('hot', 'restart',
|
||||||
hotEventTargetPlatform: 'flutter-tester',
|
parameters: CustomDimensions(
|
||||||
hotEventSdkName: 'Tester',
|
hotEventTargetPlatform: 'flutter-tester',
|
||||||
hotEventEmulator: false,
|
hotEventSdkName: 'Tester',
|
||||||
hotEventFullRestart: true,
|
hotEventEmulator: false,
|
||||||
hotEventOverallTimeInMs: 64000,
|
hotEventFullRestart: true,
|
||||||
hotEventSyncedBytes: 4,
|
hotEventOverallTimeInMs: 64000,
|
||||||
hotEventInvalidatedSourcesCount: 2,
|
hotEventSyncedBytes: 4,
|
||||||
hotEventTransferTimeInMs: 32000,
|
hotEventInvalidatedSourcesCount: 2,
|
||||||
hotEventCompileTimeInMs: 16000,
|
hotEventTransferTimeInMs: 32000,
|
||||||
hotEventFindInvalidatedTimeInMs: 128000,
|
hotEventCompileTimeInMs: 16000,
|
||||||
hotEventScannedSourcesCount: 8,
|
hotEventFindInvalidatedTimeInMs: 128000,
|
||||||
)),
|
hotEventScannedSourcesCount: 8,
|
||||||
|
)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(fakeAnalytics.sentEvents, contains(
|
expect(
|
||||||
Event.hotRunnerInfo(
|
fakeAnalytics.sentEvents,
|
||||||
label: 'restart',
|
contains(Event.hotRunnerInfo(
|
||||||
targetPlatform: 'flutter-tester',
|
label: 'restart',
|
||||||
sdkName: 'Tester',
|
targetPlatform: 'flutter-tester',
|
||||||
emulator: false,
|
sdkName: 'Tester',
|
||||||
fullRestart: true,
|
emulator: false,
|
||||||
syncedBytes: 4,
|
fullRestart: true,
|
||||||
invalidatedSourcesCount: 2,
|
syncedBytes: 4,
|
||||||
transferTimeInMs: 32000,
|
invalidatedSourcesCount: 2,
|
||||||
overallTimeInMs: 64000,
|
transferTimeInMs: 32000,
|
||||||
compileTimeInMs: 16000,
|
overallTimeInMs: 64000,
|
||||||
findInvalidatedTimeInMs: 128000,
|
compileTimeInMs: 16000,
|
||||||
scannedSourcesCount: 8
|
findInvalidatedTimeInMs: 128000,
|
||||||
)
|
scannedSourcesCount: 8)));
|
||||||
));
|
expect(
|
||||||
|
analyticsTimingEventExists(
|
||||||
|
sentEvents: fakeAnalytics.sentEvents,
|
||||||
|
workflow: 'hot',
|
||||||
|
variableName: 'restart',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
expect(testingConfig.updateDevFSCompleteCalled, true);
|
expect(testingConfig.updateDevFSCompleteCalled, true);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
HotRunnerConfig: () => testingConfig,
|
HotRunnerConfig: () => testingConfig,
|
||||||
@ -353,32 +409,39 @@ void main() {
|
|||||||
successfulHotReloadSetup: true,
|
successfulHotReloadSetup: true,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
testUsingContext('correctly tracks time spent for analytics for hot reload', () async {
|
testUsingContext(
|
||||||
|
'correctly tracks time spent for analytics for hot reload', () async {
|
||||||
final FakeDevice device = FakeDevice();
|
final FakeDevice device = FakeDevice();
|
||||||
final FakeFlutterDevice fakeFlutterDevice = FakeFlutterDevice(device);
|
final FakeFlutterDevice fakeFlutterDevice = FakeFlutterDevice(device);
|
||||||
final List<FlutterDevice> devices = <FlutterDevice>[
|
final List<FlutterDevice> devices = <FlutterDevice>[
|
||||||
fakeFlutterDevice,
|
fakeFlutterDevice,
|
||||||
];
|
];
|
||||||
|
|
||||||
fakeFlutterDevice.updateDevFSReportCallback = () async => UpdateFSReport(
|
fakeFlutterDevice.updateDevFSReportCallback =
|
||||||
success: true,
|
() async => UpdateFSReport(
|
||||||
invalidatedSourcesCount: 6,
|
success: true,
|
||||||
syncedBytes: 8,
|
invalidatedSourcesCount: 6,
|
||||||
scannedSourcesCount: 16,
|
syncedBytes: 8,
|
||||||
compileDuration: const Duration(seconds: 16),
|
scannedSourcesCount: 16,
|
||||||
transferDuration: const Duration(seconds: 32),
|
compileDuration: const Duration(seconds: 16),
|
||||||
);
|
transferDuration: const Duration(seconds: 32),
|
||||||
|
);
|
||||||
|
|
||||||
final FakeStopwatchFactory fakeStopwatchFactory = FakeStopwatchFactory(
|
final FakeStopwatchFactory fakeStopwatchFactory = FakeStopwatchFactory(
|
||||||
stopwatches: <String, Stopwatch>{
|
stopwatches: <String, Stopwatch>{
|
||||||
'updateDevFS': FakeStopwatch()..elapsed = const Duration(seconds: 64),
|
'updateDevFS': FakeStopwatch()
|
||||||
'reloadSources:reload': FakeStopwatch()..elapsed = const Duration(seconds: 128),
|
..elapsed = const Duration(seconds: 64),
|
||||||
'reloadSources:reassemble': FakeStopwatch()..elapsed = const Duration(seconds: 256),
|
'reloadSources:reload': FakeStopwatch()
|
||||||
'reloadSources:vm': FakeStopwatch()..elapsed = const Duration(seconds: 512),
|
..elapsed = const Duration(seconds: 128),
|
||||||
|
'reloadSources:reassemble': FakeStopwatch()
|
||||||
|
..elapsed = const Duration(seconds: 256),
|
||||||
|
'reloadSources:vm': FakeStopwatch()
|
||||||
|
..elapsed = const Duration(seconds: 512),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
(fakeFlutterDevice.devFS! as FakeDevFs).baseUri = Uri.parse('file:///base_uri');
|
(fakeFlutterDevice.devFS! as FakeDevFs).baseUri =
|
||||||
|
Uri.parse('file:///base_uri');
|
||||||
|
|
||||||
final OperationResult result = await HotRunner(
|
final OperationResult result = await HotRunner(
|
||||||
devices,
|
devices,
|
||||||
@ -410,57 +473,68 @@ void main() {
|
|||||||
Map<FlutterDevice?, List<FlutterView>> viewCache,
|
Map<FlutterDevice?, List<FlutterView>> viewCache,
|
||||||
void Function(String message)? onSlow,
|
void Function(String message)? onSlow,
|
||||||
String reloadMessage,
|
String reloadMessage,
|
||||||
) async => ReassembleResult(
|
) async =>
|
||||||
<FlutterView?, FlutterVmService?>{null: null},
|
ReassembleResult(
|
||||||
false,
|
<FlutterView?, FlutterVmService?>{null: null},
|
||||||
true,
|
false,
|
||||||
),
|
true,
|
||||||
|
),
|
||||||
).restart();
|
).restart();
|
||||||
|
|
||||||
expect(result.isOk, true);
|
expect(result.isOk, true);
|
||||||
expect(testUsage.events, <TestUsageEvent>[
|
expect(testUsage.events, <TestUsageEvent>[
|
||||||
const TestUsageEvent('hot', 'reload', parameters: CustomDimensions(
|
const TestUsageEvent('hot', 'reload',
|
||||||
hotEventFinalLibraryCount: 2,
|
parameters: CustomDimensions(
|
||||||
hotEventSyncedLibraryCount: 3,
|
hotEventFinalLibraryCount: 2,
|
||||||
hotEventSyncedClassesCount: 4,
|
hotEventSyncedLibraryCount: 3,
|
||||||
hotEventSyncedProceduresCount: 5,
|
hotEventSyncedClassesCount: 4,
|
||||||
hotEventSyncedBytes: 8,
|
hotEventSyncedProceduresCount: 5,
|
||||||
hotEventInvalidatedSourcesCount: 6,
|
hotEventSyncedBytes: 8,
|
||||||
hotEventTransferTimeInMs: 32000,
|
hotEventInvalidatedSourcesCount: 6,
|
||||||
hotEventOverallTimeInMs: 128000,
|
hotEventTransferTimeInMs: 32000,
|
||||||
hotEventTargetPlatform: 'flutter-tester',
|
hotEventOverallTimeInMs: 128000,
|
||||||
hotEventSdkName: 'Tester',
|
hotEventTargetPlatform: 'flutter-tester',
|
||||||
hotEventEmulator: false,
|
hotEventSdkName: 'Tester',
|
||||||
hotEventFullRestart: false,
|
hotEventEmulator: false,
|
||||||
hotEventCompileTimeInMs: 16000,
|
hotEventFullRestart: false,
|
||||||
hotEventFindInvalidatedTimeInMs: 64000,
|
hotEventCompileTimeInMs: 16000,
|
||||||
hotEventScannedSourcesCount: 16,
|
hotEventFindInvalidatedTimeInMs: 64000,
|
||||||
hotEventReassembleTimeInMs: 256000,
|
hotEventScannedSourcesCount: 16,
|
||||||
hotEventReloadVMTimeInMs: 512000,
|
hotEventReassembleTimeInMs: 256000,
|
||||||
)),
|
hotEventReloadVMTimeInMs: 512000,
|
||||||
|
)),
|
||||||
]);
|
]);
|
||||||
expect(fakeAnalytics.sentEvents, contains(
|
expect(
|
||||||
Event.hotRunnerInfo(
|
fakeAnalytics.sentEvents,
|
||||||
label: 'reload',
|
contains(
|
||||||
targetPlatform: 'flutter-tester',
|
Event.hotRunnerInfo(
|
||||||
sdkName: 'Tester',
|
label: 'reload',
|
||||||
emulator: false,
|
targetPlatform: 'flutter-tester',
|
||||||
fullRestart: false,
|
sdkName: 'Tester',
|
||||||
finalLibraryCount: 2,
|
emulator: false,
|
||||||
syncedLibraryCount: 3,
|
fullRestart: false,
|
||||||
syncedClassesCount: 4,
|
finalLibraryCount: 2,
|
||||||
syncedProceduresCount: 5,
|
syncedLibraryCount: 3,
|
||||||
syncedBytes: 8,
|
syncedClassesCount: 4,
|
||||||
invalidatedSourcesCount: 6,
|
syncedProceduresCount: 5,
|
||||||
transferTimeInMs: 32000,
|
syncedBytes: 8,
|
||||||
overallTimeInMs: 128000,
|
invalidatedSourcesCount: 6,
|
||||||
compileTimeInMs: 16000,
|
transferTimeInMs: 32000,
|
||||||
findInvalidatedTimeInMs: 64000,
|
overallTimeInMs: 128000,
|
||||||
scannedSourcesCount: 16,
|
compileTimeInMs: 16000,
|
||||||
reassembleTimeInMs: 256000,
|
findInvalidatedTimeInMs: 64000,
|
||||||
reloadVMTimeInMs: 512000
|
scannedSourcesCount: 16,
|
||||||
|
reassembleTimeInMs: 256000,
|
||||||
|
reloadVMTimeInMs: 512000),
|
||||||
|
));
|
||||||
|
expect(
|
||||||
|
analyticsTimingEventExists(
|
||||||
|
sentEvents: fakeAnalytics.sentEvents,
|
||||||
|
workflow: 'hot',
|
||||||
|
variableName: 'reload',
|
||||||
),
|
),
|
||||||
));
|
true,
|
||||||
|
);
|
||||||
expect(testingConfig.updateDevFSCompleteCalled, true);
|
expect(testingConfig.updateDevFSCompleteCalled, true);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
HotRunnerConfig: () => testingConfig,
|
HotRunnerConfig: () => testingConfig,
|
||||||
@ -485,7 +559,8 @@ void main() {
|
|||||||
final List<FlutterDevice> devices = <FlutterDevice>[
|
final List<FlutterDevice> devices = <FlutterDevice>[
|
||||||
fakeFlutterDevice,
|
fakeFlutterDevice,
|
||||||
];
|
];
|
||||||
fakeFlutterDevice.updateDevFSReportCallback = () async => throw Exception('updateDevFS failed');
|
fakeFlutterDevice.updateDevFSReportCallback =
|
||||||
|
() async => throw Exception('updateDevFS failed');
|
||||||
|
|
||||||
final HotRunner runner = HotRunner(
|
final HotRunner runner = HotRunner(
|
||||||
devices,
|
devices,
|
||||||
@ -495,7 +570,10 @@ void main() {
|
|||||||
analytics: fakeAnalytics,
|
analytics: fakeAnalytics,
|
||||||
);
|
);
|
||||||
|
|
||||||
await expectLater(runner.restart(fullRestart: true), throwsA(isA<Exception>().having((Exception e) => e.toString(), 'message', 'Exception: updateDevFS failed')));
|
await expectLater(
|
||||||
|
runner.restart(fullRestart: true),
|
||||||
|
throwsA(isA<Exception>().having((Exception e) => e.toString(),
|
||||||
|
'message', 'Exception: updateDevFS failed')));
|
||||||
expect(testingConfig.updateDevFSCompleteCalled, true);
|
expect(testingConfig.updateDevFSCompleteCalled, true);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
HotRunnerConfig: () => testingConfig,
|
HotRunnerConfig: () => testingConfig,
|
||||||
@ -520,7 +598,8 @@ void main() {
|
|||||||
final List<FlutterDevice> devices = <FlutterDevice>[
|
final List<FlutterDevice> devices = <FlutterDevice>[
|
||||||
fakeFlutterDevice,
|
fakeFlutterDevice,
|
||||||
];
|
];
|
||||||
fakeFlutterDevice.updateDevFSReportCallback = () async => throw Exception('updateDevFS failed');
|
fakeFlutterDevice.updateDevFSReportCallback =
|
||||||
|
() async => throw Exception('updateDevFS failed');
|
||||||
|
|
||||||
final HotRunner runner = HotRunner(
|
final HotRunner runner = HotRunner(
|
||||||
devices,
|
devices,
|
||||||
@ -530,7 +609,10 @@ void main() {
|
|||||||
analytics: fakeAnalytics,
|
analytics: fakeAnalytics,
|
||||||
);
|
);
|
||||||
|
|
||||||
await expectLater(runner.restart(), throwsA(isA<Exception>().having((Exception e) => e.toString(), 'message', 'Exception: updateDevFS failed')));
|
await expectLater(
|
||||||
|
runner.restart(),
|
||||||
|
throwsA(isA<Exception>().having((Exception e) => e.toString(),
|
||||||
|
'message', 'Exception: updateDevFS failed')));
|
||||||
expect(testingConfig.updateDevFSCompleteCalled, true);
|
expect(testingConfig.updateDevFSCompleteCalled, true);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
HotRunnerConfig: () => testingConfig,
|
HotRunnerConfig: () => testingConfig,
|
||||||
@ -555,8 +637,9 @@ void main() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('Exits with code 2 when HttpException is thrown '
|
testUsingContext(
|
||||||
'during VM service connection', () async {
|
'Exits with code 2 when HttpException is thrown '
|
||||||
|
'during VM service connection', () async {
|
||||||
fileSystem.file('.packages')
|
fileSystem.file('.packages')
|
||||||
..createSync(recursive: true)
|
..createSync(recursive: true)
|
||||||
..writeAsStringSync('\n');
|
..writeAsStringSync('\n');
|
||||||
@ -567,12 +650,14 @@ void main() {
|
|||||||
TestFlutterDevice(
|
TestFlutterDevice(
|
||||||
device: device,
|
device: device,
|
||||||
generator: residentCompiler,
|
generator: residentCompiler,
|
||||||
exception: const HttpException('Connection closed before full header was received, '
|
exception: const HttpException(
|
||||||
|
'Connection closed before full header was received, '
|
||||||
'uri = http://127.0.0.1:63394/5ZmLv8A59xY=/ws'),
|
'uri = http://127.0.0.1:63394/5ZmLv8A59xY=/ws'),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
final int exitCode = await HotRunner(devices,
|
final int exitCode = await HotRunner(
|
||||||
|
devices,
|
||||||
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
|
||||||
target: 'main.dart',
|
target: 'main.dart',
|
||||||
analytics: fakeAnalytics,
|
analytics: fakeAnalytics,
|
||||||
@ -610,7 +695,8 @@ void main() {
|
|||||||
flutterDevice2,
|
flutterDevice2,
|
||||||
];
|
];
|
||||||
|
|
||||||
await HotRunner(devices,
|
await HotRunner(
|
||||||
|
devices,
|
||||||
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
|
||||||
target: 'main.dart',
|
target: 'main.dart',
|
||||||
analytics: fakeAnalytics,
|
analytics: fakeAnalytics,
|
||||||
@ -647,17 +733,19 @@ void main() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
fakeFlutterDevice.updateDevFSReportCallback = () async => UpdateFSReport(
|
fakeFlutterDevice.updateDevFSReportCallback = () async => UpdateFSReport(
|
||||||
success: true,
|
success: true,
|
||||||
invalidatedSourcesCount: 6,
|
invalidatedSourcesCount: 6,
|
||||||
syncedBytes: 8,
|
syncedBytes: 8,
|
||||||
scannedSourcesCount: 16,
|
scannedSourcesCount: 16,
|
||||||
compileDuration: const Duration(seconds: 16),
|
compileDuration: const Duration(seconds: 16),
|
||||||
transferDuration: const Duration(seconds: 32),
|
transferDuration: const Duration(seconds: 32),
|
||||||
);
|
);
|
||||||
|
|
||||||
(fakeFlutterDevice.devFS! as FakeDevFs).baseUri = Uri.parse('file:///base_uri');
|
(fakeFlutterDevice.devFS! as FakeDevFs).baseUri =
|
||||||
|
Uri.parse('file:///base_uri');
|
||||||
|
|
||||||
final FakeNativeAssetsBuildRunner buildRunner = FakeNativeAssetsBuildRunner(
|
final FakeNativeAssetsBuildRunner buildRunner =
|
||||||
|
FakeNativeAssetsBuildRunner(
|
||||||
packagesWithNativeAssetsResult: <Package>[
|
packagesWithNativeAssetsResult: <Package>[
|
||||||
Package('bar', fileSystem.currentDirectory.uri),
|
Package('bar', fileSystem.currentDirectory.uri),
|
||||||
],
|
],
|
||||||
@ -695,28 +783,32 @@ void main() {
|
|||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
Platform: () => FakePlatform(),
|
Platform: () => FakePlatform(),
|
||||||
ProcessManager: () => FakeProcessManager.empty(),
|
ProcessManager: () => FakeProcessManager.empty(),
|
||||||
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true, isMacOSEnabled: true),
|
FeatureFlags: () =>
|
||||||
|
TestFeatureFlags(isNativeAssetsEnabled: true, isMacOSEnabled: true),
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('native assets run unsupported', () async {
|
testUsingContext('native assets run unsupported', () async {
|
||||||
final FakeDevice device = FakeDevice(targetPlatform: TargetPlatform.android_arm64);
|
final FakeDevice device =
|
||||||
|
FakeDevice(targetPlatform: TargetPlatform.android_arm64);
|
||||||
final FakeFlutterDevice fakeFlutterDevice = FakeFlutterDevice(device);
|
final FakeFlutterDevice fakeFlutterDevice = FakeFlutterDevice(device);
|
||||||
final List<FlutterDevice> devices = <FlutterDevice>[
|
final List<FlutterDevice> devices = <FlutterDevice>[
|
||||||
fakeFlutterDevice,
|
fakeFlutterDevice,
|
||||||
];
|
];
|
||||||
|
|
||||||
fakeFlutterDevice.updateDevFSReportCallback = () async => UpdateFSReport(
|
fakeFlutterDevice.updateDevFSReportCallback = () async => UpdateFSReport(
|
||||||
success: true,
|
success: true,
|
||||||
invalidatedSourcesCount: 6,
|
invalidatedSourcesCount: 6,
|
||||||
syncedBytes: 8,
|
syncedBytes: 8,
|
||||||
scannedSourcesCount: 16,
|
scannedSourcesCount: 16,
|
||||||
compileDuration: const Duration(seconds: 16),
|
compileDuration: const Duration(seconds: 16),
|
||||||
transferDuration: const Duration(seconds: 32),
|
transferDuration: const Duration(seconds: 32),
|
||||||
);
|
);
|
||||||
|
|
||||||
(fakeFlutterDevice.devFS! as FakeDevFs).baseUri = Uri.parse('file:///base_uri');
|
(fakeFlutterDevice.devFS! as FakeDevFs).baseUri =
|
||||||
|
Uri.parse('file:///base_uri');
|
||||||
|
|
||||||
final FakeNativeAssetsBuildRunner buildRunner = FakeNativeAssetsBuildRunner(
|
final FakeNativeAssetsBuildRunner buildRunner =
|
||||||
|
FakeNativeAssetsBuildRunner(
|
||||||
packagesWithNativeAssetsResult: <Package>[
|
packagesWithNativeAssetsResult: <Package>[
|
||||||
Package('bar', fileSystem.currentDirectory.uri),
|
Package('bar', fileSystem.currentDirectory.uri),
|
||||||
],
|
],
|
||||||
@ -741,28 +833,27 @@ void main() {
|
|||||||
analytics: fakeAnalytics,
|
analytics: fakeAnalytics,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
() => hotRunner.run(),
|
() => hotRunner.run(),
|
||||||
throwsToolExit( message:
|
throwsToolExit(
|
||||||
'Package(s) bar require the native assets feature. '
|
message: 'Package(s) bar require the native assets feature. '
|
||||||
'This feature has not yet been implemented for `TargetPlatform.android_arm64`. '
|
'This feature has not yet been implemented for `TargetPlatform.android_arm64`. '
|
||||||
'For more info see https://github.com/flutter/flutter/issues/129757.',
|
'For more info see https://github.com/flutter/flutter/issues/129757.',
|
||||||
)
|
));
|
||||||
);
|
|
||||||
|
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
HotRunnerConfig: () => testingConfig,
|
HotRunnerConfig: () => testingConfig,
|
||||||
Artifacts: () => Artifacts.test(),
|
Artifacts: () => Artifacts.test(),
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
Platform: () => FakePlatform(),
|
Platform: () => FakePlatform(),
|
||||||
ProcessManager: () => FakeProcessManager.empty(),
|
ProcessManager: () => FakeProcessManager.empty(),
|
||||||
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true, isMacOSEnabled: true),
|
FeatureFlags: () =>
|
||||||
|
TestFeatureFlags(isNativeAssetsEnabled: true, isMacOSEnabled: true),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class FakeDevFs extends Fake implements DevFS {
|
class FakeDevFs extends Fake implements DevFS {
|
||||||
@override
|
@override
|
||||||
Future<void> destroy() async { }
|
Future<void> destroy() async {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Uri> sources = <Uri>[];
|
List<Uri> sources = <Uri>[];
|
||||||
@ -777,10 +868,10 @@ class FakeDevFs extends Fake implements DevFS {
|
|||||||
Set<String> assetPathsToEvict = <String>{};
|
Set<String> assetPathsToEvict = <String>{};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Set<String> shaderPathsToEvict= <String>{};
|
Set<String> shaderPathsToEvict = <String>{};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Set<String> scenePathsToEvict= <String>{};
|
Set<String> scenePathsToEvict = <String>{};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Uri? baseUri;
|
Uri? baseUri;
|
||||||
@ -873,7 +964,8 @@ class FakeFlutterDevice extends Fake implements FlutterDevice {
|
|||||||
required String dillOutputPath,
|
required String dillOutputPath,
|
||||||
required List<Uri> invalidatedFiles,
|
required List<Uri> invalidatedFiles,
|
||||||
required PackageConfig packageConfig,
|
required PackageConfig packageConfig,
|
||||||
}) => updateDevFSReportCallback();
|
}) =>
|
||||||
|
updateDevFSReportCallback();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TargetPlatform? get targetPlatform => device._targetPlatform;
|
TargetPlatform? get targetPlatform => device._targetPlatform;
|
||||||
@ -884,7 +976,10 @@ class TestFlutterDevice extends FlutterDevice {
|
|||||||
required Device device,
|
required Device device,
|
||||||
required this.exception,
|
required this.exception,
|
||||||
required ResidentCompiler generator,
|
required ResidentCompiler generator,
|
||||||
}) : super(device, buildInfo: BuildInfo.debug, generator: generator, developmentShaderCompiler: const FakeShaderCompiler());
|
}) : super(device,
|
||||||
|
buildInfo: BuildInfo.debug,
|
||||||
|
generator: generator,
|
||||||
|
developmentShaderCompiler: const FakeShaderCompiler());
|
||||||
|
|
||||||
/// The exception to throw when the connect method is called.
|
/// The exception to throw when the connect method is called.
|
||||||
final Exception exception;
|
final Exception exception;
|
||||||
@ -910,7 +1005,8 @@ class TestFlutterDevice extends FlutterDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TestHotRunnerConfig extends HotRunnerConfig {
|
class TestHotRunnerConfig extends HotRunnerConfig {
|
||||||
TestHotRunnerConfig({this.successfulHotRestartSetup, this.successfulHotReloadSetup});
|
TestHotRunnerConfig(
|
||||||
|
{this.successfulHotRestartSetup, this.successfulHotReloadSetup});
|
||||||
bool? successfulHotRestartSetup;
|
bool? successfulHotRestartSetup;
|
||||||
bool? successfulHotReloadSetup;
|
bool? successfulHotReloadSetup;
|
||||||
bool shutdownHookCalled = false;
|
bool shutdownHookCalled = false;
|
||||||
@ -918,13 +1014,15 @@ class TestHotRunnerConfig extends HotRunnerConfig {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool?> setupHotRestart() async {
|
Future<bool?> setupHotRestart() async {
|
||||||
assert(successfulHotRestartSetup != null, 'setupHotRestart is not expected to be called in this test.');
|
assert(successfulHotRestartSetup != null,
|
||||||
|
'setupHotRestart is not expected to be called in this test.');
|
||||||
return successfulHotRestartSetup;
|
return successfulHotRestartSetup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool?> setupHotReload() async {
|
Future<bool?> setupHotReload() async {
|
||||||
assert(successfulHotReloadSetup != null, 'setupHotReload is not expected to be called in this test.');
|
assert(successfulHotReloadSetup != null,
|
||||||
|
'setupHotReload is not expected to be called in this test.');
|
||||||
return successfulHotReloadSetup;
|
return successfulHotReloadSetup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -949,7 +1047,9 @@ class FakeFlutterVmService extends Fake implements FlutterVmService {
|
|||||||
vm_service.VmService get service => FakeVmService();
|
vm_service.VmService get service => FakeVmService();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<FlutterView>> getFlutterViews({bool returnEarly = false, Duration delay = const Duration(milliseconds: 50)}) async {
|
Future<List<FlutterView>> getFlutterViews(
|
||||||
|
{bool returnEarly = false,
|
||||||
|
Duration delay = const Duration(milliseconds: 50)}) async {
|
||||||
return <FlutterView>[];
|
return <FlutterView>[];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -971,7 +1071,7 @@ class FakeShaderCompiler implements DevelopmentShaderCompiler {
|
|||||||
void configureCompiler(
|
void configureCompiler(
|
||||||
TargetPlatform? platform, {
|
TargetPlatform? platform, {
|
||||||
required ImpellerStatus impellerStatus,
|
required ImpellerStatus impellerStatus,
|
||||||
}) { }
|
}) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<DevFSContent> recompileShader(DevFSContent inputShader) {
|
Future<DevFSContent> recompileShader(DevFSContent inputShader) {
|
||||||
|
@ -27,6 +27,7 @@ import 'package:flutter_tools/src/ios/xcodeproj.dart';
|
|||||||
import 'package:flutter_tools/src/macos/xcode.dart';
|
import 'package:flutter_tools/src/macos/xcode.dart';
|
||||||
import 'package:flutter_tools/src/project.dart';
|
import 'package:flutter_tools/src/project.dart';
|
||||||
import 'package:test/fake.dart';
|
import 'package:test/fake.dart';
|
||||||
|
import 'package:unified_analytics/unified_analytics.dart';
|
||||||
|
|
||||||
import '../../src/common.dart';
|
import '../../src/common.dart';
|
||||||
import '../../src/context.dart' hide FakeXcodeProjectInterpreter;
|
import '../../src/context.dart' hide FakeXcodeProjectInterpreter;
|
||||||
@ -88,12 +89,13 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
group('IOSDevice.startApp succeeds in release mode', () {
|
group('IOSDevice.startApp succeeds in release mode', () {
|
||||||
late FileSystem fileSystem;
|
late MemoryFileSystem fileSystem;
|
||||||
late FakeProcessManager processManager;
|
late FakeProcessManager processManager;
|
||||||
late BufferLogger logger;
|
late BufferLogger logger;
|
||||||
late Xcode xcode;
|
late Xcode xcode;
|
||||||
late FakeXcodeProjectInterpreter fakeXcodeProjectInterpreter;
|
late FakeXcodeProjectInterpreter fakeXcodeProjectInterpreter;
|
||||||
late XcodeProjectInfo projectInfo;
|
late XcodeProjectInfo projectInfo;
|
||||||
|
late FakeAnalytics fakeAnalytics;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
logger = BufferLogger.test();
|
logger = BufferLogger.test();
|
||||||
@ -110,6 +112,10 @@ void main() {
|
|||||||
fileSystem.file('foo/.packages')
|
fileSystem.file('foo/.packages')
|
||||||
..createSync(recursive: true)
|
..createSync(recursive: true)
|
||||||
..writeAsStringSync('\n');
|
..writeAsStringSync('\n');
|
||||||
|
fakeAnalytics = getInitializedFakeAnalyticsInstance(
|
||||||
|
fs: fileSystem,
|
||||||
|
fakeFlutterVersion: FakeFlutterVersion(),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('missing TARGET_BUILD_DIR', () async {
|
testUsingContext('missing TARGET_BUILD_DIR', () async {
|
||||||
@ -135,6 +141,14 @@ void main() {
|
|||||||
expect(launchResult.started, false);
|
expect(launchResult.started, false);
|
||||||
expect(logger.errorText, contains('Xcode build is missing expected TARGET_BUILD_DIR build setting'));
|
expect(logger.errorText, contains('Xcode build is missing expected TARGET_BUILD_DIR build setting'));
|
||||||
expect(processManager, hasNoRemainingExpectations);
|
expect(processManager, hasNoRemainingExpectations);
|
||||||
|
expect(
|
||||||
|
analyticsTimingEventExists(
|
||||||
|
sentEvents: fakeAnalytics.sentEvents,
|
||||||
|
workflow: 'build',
|
||||||
|
variableName: 'xcode-ios',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
ProcessManager: () => processManager,
|
ProcessManager: () => processManager,
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
@ -145,6 +159,7 @@ void main() {
|
|||||||
'DEVELOPMENT_TEAM': '3333CCCC33',
|
'DEVELOPMENT_TEAM': '3333CCCC33',
|
||||||
}, projectInfo: projectInfo),
|
}, projectInfo: projectInfo),
|
||||||
Xcode: () => xcode,
|
Xcode: () => xcode,
|
||||||
|
Analytics: () => fakeAnalytics,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('missing project info', () async {
|
testUsingContext('missing project info', () async {
|
||||||
|
@ -41,6 +41,7 @@ import 'package:native_assets_cli/native_assets_cli.dart'
|
|||||||
import 'package:native_assets_cli/native_assets_cli.dart' as native_assets_cli;
|
import 'package:native_assets_cli/native_assets_cli.dart' as native_assets_cli;
|
||||||
import 'package:package_config/package_config.dart';
|
import 'package:package_config/package_config.dart';
|
||||||
import 'package:test/fake.dart';
|
import 'package:test/fake.dart';
|
||||||
|
import 'package:unified_analytics/src/enums.dart';
|
||||||
import 'package:unified_analytics/unified_analytics.dart';
|
import 'package:unified_analytics/unified_analytics.dart';
|
||||||
import 'package:vm_service/vm_service.dart' as vm_service;
|
import 'package:vm_service/vm_service.dart' as vm_service;
|
||||||
|
|
||||||
@ -959,8 +960,11 @@ void main() {
|
|||||||
expect(event.parameters?.hotEventTargetPlatform, getNameForTargetPlatform(TargetPlatform.android_arm));
|
expect(event.parameters?.hotEventTargetPlatform, getNameForTargetPlatform(TargetPlatform.android_arm));
|
||||||
expect(fakeVmServiceHost?.hasRemainingExpectations, false);
|
expect(fakeVmServiceHost?.hasRemainingExpectations, false);
|
||||||
|
|
||||||
|
// Parse out the event of interest since we may have timing events with
|
||||||
final Event newEvent = fakeAnalytics.sentEvents.first;
|
// the new analytics package
|
||||||
|
final List<Event> newEventList = fakeAnalytics.sentEvents.where((Event e) => e.eventName == DashEvent.hotRunnerInfo).toList();
|
||||||
|
expect(newEventList, hasLength(1));
|
||||||
|
final Event newEvent = newEventList.first;
|
||||||
expect(newEvent.eventName.label, 'hot_runner_info');
|
expect(newEvent.eventName.label, 'hot_runner_info');
|
||||||
expect(newEvent.eventData['label'], 'restart');
|
expect(newEvent.eventData['label'], 'restart');
|
||||||
expect(newEvent.eventData['targetPlatform'], getNameForTargetPlatform(TargetPlatform.android_arm));
|
expect(newEvent.eventData['targetPlatform'], getNameForTargetPlatform(TargetPlatform.android_arm));
|
||||||
|
@ -693,6 +693,13 @@ void main() {
|
|||||||
expect(testUsage.timings, const <TestTimingEvent>[
|
expect(testUsage.timings, const <TestTimingEvent>[
|
||||||
TestTimingEvent('hot', 'web-incremental-restart', Duration.zero),
|
TestTimingEvent('hot', 'web-incremental-restart', Duration.zero),
|
||||||
]);
|
]);
|
||||||
|
expect(fakeAnalytics.sentEvents, contains(
|
||||||
|
Event.timing(
|
||||||
|
workflow: 'hot',
|
||||||
|
variableName: 'web-incremental-restart',
|
||||||
|
elapsedMilliseconds: 0,
|
||||||
|
),
|
||||||
|
));
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Usage: () => testUsage,
|
Usage: () => testUsage,
|
||||||
Analytics: () => fakeAnalytics,
|
Analytics: () => fakeAnalytics,
|
||||||
@ -779,6 +786,13 @@ void main() {
|
|||||||
expect(testUsage.timings, const <TestTimingEvent>[
|
expect(testUsage.timings, const <TestTimingEvent>[
|
||||||
TestTimingEvent('hot', 'web-incremental-restart', Duration.zero),
|
TestTimingEvent('hot', 'web-incremental-restart', Duration.zero),
|
||||||
]);
|
]);
|
||||||
|
expect(fakeAnalytics.sentEvents, contains(
|
||||||
|
Event.timing(
|
||||||
|
workflow: 'hot',
|
||||||
|
variableName: 'web-incremental-restart',
|
||||||
|
elapsedMilliseconds: 0,
|
||||||
|
),
|
||||||
|
));
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Usage: () => testUsage,
|
Usage: () => testUsage,
|
||||||
Analytics: () => fakeAnalytics,
|
Analytics: () => fakeAnalytics,
|
||||||
|
@ -10,10 +10,13 @@ import 'package:flutter_tools/src/base/platform.dart';
|
|||||||
import 'package:flutter_tools/src/base/terminal.dart';
|
import 'package:flutter_tools/src/base/terminal.dart';
|
||||||
import 'package:flutter_tools/src/cache.dart';
|
import 'package:flutter_tools/src/cache.dart';
|
||||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||||
|
import 'package:flutter_tools/src/reporting/reporting.dart';
|
||||||
import 'package:flutter_tools/src/runner/flutter_command.dart';
|
import 'package:flutter_tools/src/runner/flutter_command.dart';
|
||||||
import 'package:flutter_tools/src/runner/flutter_command_runner.dart';
|
import 'package:flutter_tools/src/runner/flutter_command_runner.dart';
|
||||||
import 'package:flutter_tools/src/version.dart';
|
import 'package:flutter_tools/src/version.dart';
|
||||||
|
import 'package:unified_analytics/unified_analytics.dart';
|
||||||
|
|
||||||
|
import '../../src/common.dart';
|
||||||
import '../../src/context.dart';
|
import '../../src/context.dart';
|
||||||
import '../../src/fakes.dart';
|
import '../../src/fakes.dart';
|
||||||
import '../../src/test_flutter_command_runner.dart';
|
import '../../src/test_flutter_command_runner.dart';
|
||||||
@ -26,6 +29,8 @@ void main() {
|
|||||||
group('FlutterCommandRunner', () {
|
group('FlutterCommandRunner', () {
|
||||||
late MemoryFileSystem fileSystem;
|
late MemoryFileSystem fileSystem;
|
||||||
late Platform platform;
|
late Platform platform;
|
||||||
|
late TestUsage testUsage;
|
||||||
|
late FakeAnalytics fakeAnalytics;
|
||||||
|
|
||||||
setUpAll(() {
|
setUpAll(() {
|
||||||
Cache.disableLocking();
|
Cache.disableLocking();
|
||||||
@ -36,6 +41,11 @@ void main() {
|
|||||||
fileSystem.directory(_kFlutterRoot).createSync(recursive: true);
|
fileSystem.directory(_kFlutterRoot).createSync(recursive: true);
|
||||||
fileSystem.directory(_kProjectRoot).createSync(recursive: true);
|
fileSystem.directory(_kProjectRoot).createSync(recursive: true);
|
||||||
fileSystem.currentDirectory = _kProjectRoot;
|
fileSystem.currentDirectory = _kProjectRoot;
|
||||||
|
testUsage = TestUsage();
|
||||||
|
fakeAnalytics = getInitializedFakeAnalyticsInstance(
|
||||||
|
fs: fileSystem,
|
||||||
|
fakeFlutterVersion: FakeFlutterVersion(),
|
||||||
|
);
|
||||||
|
|
||||||
platform = FakePlatform(
|
platform = FakePlatform(
|
||||||
environment: <String, String>{
|
environment: <String, String>{
|
||||||
@ -144,14 +154,25 @@ void main() {
|
|||||||
final FakeFlutterVersion version = globals.flutterVersion as FakeFlutterVersion;
|
final FakeFlutterVersion version = globals.flutterVersion as FakeFlutterVersion;
|
||||||
|
|
||||||
await runner.run(<String>['--version']);
|
await runner.run(<String>['--version']);
|
||||||
|
|
||||||
expect(version.didFetchTagsAndUpdate, true);
|
expect(version.didFetchTagsAndUpdate, true);
|
||||||
|
expect(testUsage.commands, contains(
|
||||||
|
const TestUsageCommand('version'),
|
||||||
|
));
|
||||||
|
expect(fakeAnalytics.sentEvents, contains(
|
||||||
|
Event.flutterCommandResult(
|
||||||
|
commandPath: 'version',
|
||||||
|
result: 'success',
|
||||||
|
commandHasTerminal: false,
|
||||||
|
),
|
||||||
|
));
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
Platform: () => platform,
|
Platform: () => platform,
|
||||||
FlutterVersion: () => FakeFlutterVersion(),
|
FlutterVersion: () => FakeFlutterVersion(),
|
||||||
OutputPreferences: () => OutputPreferences.test(),
|
OutputPreferences: () => OutputPreferences.test(),
|
||||||
|
Usage: () => testUsage,
|
||||||
|
Analytics: () => fakeAnalytics,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext("Doesn't crash on invalid .packages file", () async {
|
testUsingContext("Doesn't crash on invalid .packages file", () async {
|
||||||
|
@ -27,6 +27,7 @@ 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:flutter_tools/src/runner/flutter_command.dart';
|
import 'package:flutter_tools/src/runner/flutter_command.dart';
|
||||||
import 'package:test/fake.dart';
|
import 'package:test/fake.dart';
|
||||||
|
import 'package:unified_analytics/src/enums.dart';
|
||||||
import 'package:unified_analytics/unified_analytics.dart';
|
import 'package:unified_analytics/unified_analytics.dart';
|
||||||
|
|
||||||
import '../../src/common.dart';
|
import '../../src/common.dart';
|
||||||
@ -229,14 +230,14 @@ void main() {
|
|||||||
value: 10,
|
value: 10,
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
expect(fakeAnalytics.sentEvents, <Event>[
|
expect(fakeAnalytics.sentEvents, contains(
|
||||||
Event.flutterCommandResult(
|
Event.flutterCommandResult(
|
||||||
commandPath: 'dummy',
|
commandPath: 'dummy',
|
||||||
result: 'success',
|
result: 'success',
|
||||||
maxRss: 10,
|
maxRss: 10,
|
||||||
commandHasTerminal: false,
|
commandHasTerminal: false,
|
||||||
),
|
),
|
||||||
]);
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingCommandContext('reports command that results in warning', () async {
|
testUsingCommandContext('reports command that results in warning', () async {
|
||||||
@ -263,14 +264,14 @@ void main() {
|
|||||||
value: 10,
|
value: 10,
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
expect(fakeAnalytics.sentEvents, <Event>[
|
expect(fakeAnalytics.sentEvents, contains(
|
||||||
Event.flutterCommandResult(
|
Event.flutterCommandResult(
|
||||||
commandPath: 'dummy',
|
commandPath: 'dummy',
|
||||||
result: 'warning',
|
result: 'warning',
|
||||||
maxRss: 10,
|
maxRss: 10,
|
||||||
commandHasTerminal: false,
|
commandHasTerminal: false,
|
||||||
),
|
),
|
||||||
]);
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingCommandContext('reports command that results in error', () async {
|
testUsingCommandContext('reports command that results in error', () async {
|
||||||
@ -299,14 +300,14 @@ void main() {
|
|||||||
value: 10,
|
value: 10,
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
expect(fakeAnalytics.sentEvents, <Event>[
|
expect(fakeAnalytics.sentEvents, contains(
|
||||||
Event.flutterCommandResult(
|
Event.flutterCommandResult(
|
||||||
commandPath: 'dummy',
|
commandPath: 'dummy',
|
||||||
result: 'fail',
|
result: 'fail',
|
||||||
maxRss: 10,
|
maxRss: 10,
|
||||||
commandHasTerminal: false,
|
commandHasTerminal: false,
|
||||||
),
|
),
|
||||||
]);
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('FlutterCommandResult.success()', () async {
|
test('FlutterCommandResult.success()', () async {
|
||||||
@ -413,14 +414,14 @@ void main() {
|
|||||||
value: 10,
|
value: 10,
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
expect(fakeAnalytics.sentEvents, <Event>[
|
expect(fakeAnalytics.sentEvents, contains(
|
||||||
Event.flutterCommandResult(
|
Event.flutterCommandResult(
|
||||||
commandPath: 'dummy',
|
commandPath: 'dummy',
|
||||||
result: 'killed',
|
result: 'killed',
|
||||||
maxRss: 10,
|
maxRss: 10,
|
||||||
commandHasTerminal: false,
|
commandHasTerminal: false,
|
||||||
),
|
),
|
||||||
]);
|
));
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
ProcessManager: () => processManager,
|
ProcessManager: () => processManager,
|
||||||
@ -485,6 +486,14 @@ void main() {
|
|||||||
Duration(milliseconds: 1000),
|
Duration(milliseconds: 1000),
|
||||||
label: 'fail',
|
label: 'fail',
|
||||||
)));
|
)));
|
||||||
|
expect(fakeAnalytics.sentEvents, contains(
|
||||||
|
Event.timing(
|
||||||
|
workflow: 'flutter',
|
||||||
|
variableName: 'dummy',
|
||||||
|
elapsedMilliseconds: 1000,
|
||||||
|
label: 'fail',
|
||||||
|
)
|
||||||
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingCommandContext('no timing report without usagePath', () async {
|
testUsingCommandContext('no timing report without usagePath', () async {
|
||||||
@ -496,6 +505,19 @@ void main() {
|
|||||||
await flutterCommand.run();
|
await flutterCommand.run();
|
||||||
|
|
||||||
expect(usage.timings, isEmpty);
|
expect(usage.timings, isEmpty);
|
||||||
|
// Iterate through and count all the [Event.timing] instances
|
||||||
|
int timingEventCounts = 0;
|
||||||
|
for (final Event e in fakeAnalytics.sentEvents) {
|
||||||
|
if (e.eventName == DashEvent.timing) {
|
||||||
|
timingEventCounts += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect(
|
||||||
|
timingEventCounts,
|
||||||
|
0,
|
||||||
|
reason: 'There should not be any timing events sent, there may '
|
||||||
|
'be other non-timing events',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingCommandContext('report additional FlutterCommandResult data', () async {
|
testUsingCommandContext('report additional FlutterCommandResult data', () async {
|
||||||
@ -521,6 +543,14 @@ void main() {
|
|||||||
Duration(milliseconds: 500),
|
Duration(milliseconds: 500),
|
||||||
label: 'success-blah1-blah2-blah3',
|
label: 'success-blah1-blah2-blah3',
|
||||||
)));
|
)));
|
||||||
|
expect(fakeAnalytics.sentEvents, contains(
|
||||||
|
Event.timing(
|
||||||
|
workflow: 'flutter',
|
||||||
|
variableName: 'dummy',
|
||||||
|
elapsedMilliseconds: 500,
|
||||||
|
label: 'success-blah1-blah2-blah3',
|
||||||
|
),
|
||||||
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingCommandContext('report failed execution timing too', () async {
|
testUsingCommandContext('report failed execution timing too', () async {
|
||||||
@ -545,6 +575,14 @@ void main() {
|
|||||||
label: 'fail',
|
label: 'fail',
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
expect(fakeAnalytics.sentEvents, contains(
|
||||||
|
Event.timing(
|
||||||
|
workflow: 'flutter',
|
||||||
|
variableName: 'dummy',
|
||||||
|
elapsedMilliseconds: 1000,
|
||||||
|
label: 'fail',
|
||||||
|
),
|
||||||
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('reports null safety analytics when reportNullSafety is true', () async {
|
testUsingContext('reports null safety analytics when reportNullSafety is true', () async {
|
||||||
|
@ -111,7 +111,7 @@ void main() {
|
|||||||
|
|
||||||
expect(
|
expect(
|
||||||
fakeAnalytics.sentEvents,
|
fakeAnalytics.sentEvents,
|
||||||
unorderedEquals(<Event>[
|
containsAll(<Event>[
|
||||||
Event.flutterBuildInfo(
|
Event.flutterBuildInfo(
|
||||||
label: 'web-compile',
|
label: 'web-compile',
|
||||||
buildType: 'web',
|
buildType: 'web',
|
||||||
@ -124,6 +124,14 @@ void main() {
|
|||||||
final TestTimingEvent timingEvent = testUsage.timings.single;
|
final TestTimingEvent timingEvent = testUsage.timings.single;
|
||||||
expect(timingEvent.category, 'build');
|
expect(timingEvent.category, 'build');
|
||||||
expect(timingEvent.variableName, 'dart2wasm');
|
expect(timingEvent.variableName, 'dart2wasm');
|
||||||
|
expect(
|
||||||
|
analyticsTimingEventExists(
|
||||||
|
sentEvents: fakeAnalytics.sentEvents,
|
||||||
|
workflow: 'build',
|
||||||
|
variableName: 'dart2wasm',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('WebBuilder throws tool exit on failure', () async {
|
testUsingContext('WebBuilder throws tool exit on failure', () async {
|
||||||
@ -159,5 +167,6 @@ void main() {
|
|||||||
|
|
||||||
expect(logger.errorText, contains('Target hello failed: FormatException: illegal character in input string'));
|
expect(logger.errorText, contains('Target hello failed: FormatException: illegal character in input string'));
|
||||||
expect(testUsage.timings, isEmpty);
|
expect(testUsage.timings, isEmpty);
|
||||||
|
expect(fakeAnalytics.sentEvents, isEmpty);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:args/command_runner.dart';
|
import 'package:args/command_runner.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
import 'package:file/memory.dart';
|
import 'package:file/memory.dart';
|
||||||
import 'package:flutter_tools/src/base/common.dart';
|
import 'package:flutter_tools/src/base/common.dart';
|
||||||
import 'package:flutter_tools/src/base/context.dart';
|
import 'package:flutter_tools/src/base/context.dart';
|
||||||
@ -347,3 +348,38 @@ FakeAnalytics getInitializedFakeAnalyticsInstance({
|
|||||||
clientIde: clientIde,
|
clientIde: clientIde,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns "true" if the timing event searched for exists in [sentEvents].
|
||||||
|
///
|
||||||
|
/// This utility function allows us to check for an instance of
|
||||||
|
/// [Event.timing] within a [FakeAnalytics] instance. Normally, we can
|
||||||
|
/// use the equality operator for [Event] to check if the event exists, but
|
||||||
|
/// we are unable to do so for the timing event because the elapsed time
|
||||||
|
/// is variable so we cannot predict what that value will be in tests.
|
||||||
|
///
|
||||||
|
/// This function allows us to check for the other keys that have
|
||||||
|
/// string values by removing the `elapsedMilliseconds` from the
|
||||||
|
/// [Event.eventData] map and checking for a match.
|
||||||
|
bool analyticsTimingEventExists({
|
||||||
|
required List<Event> sentEvents,
|
||||||
|
required String workflow,
|
||||||
|
required String variableName,
|
||||||
|
String? label,
|
||||||
|
}) {
|
||||||
|
final Map<String, String> lookup = <String, String>{
|
||||||
|
'workflow': workflow,
|
||||||
|
'variableName': variableName,
|
||||||
|
if (label != null) 'label': label,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (final Event e in sentEvents) {
|
||||||
|
final Map<String, Object?> eventData = e.eventData;
|
||||||
|
eventData.remove('elapsedMilliseconds');
|
||||||
|
|
||||||
|
if (const DeepCollectionEquality().equals(lookup, eventData)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user