Turn on avoid_dynamic_calls lint, except packages/flutter tests, make appropriate changes. (#84476)
This adds avoid_dynamic_calls to the list of lints, and fixes all instances where it was violated. Importantly, this lint is NOT turned on for flutter/packages/test, because those changes are happening in another PR: #84478
This commit is contained in:
parent
acd68cf47b
commit
88f3811055
@ -61,7 +61,7 @@ linter:
|
|||||||
# - avoid_catching_errors # we do this commonly
|
# - avoid_catching_errors # we do this commonly
|
||||||
- avoid_classes_with_only_static_members
|
- avoid_classes_with_only_static_members
|
||||||
# - avoid_double_and_int_checks # only useful when targeting JS runtime
|
# - avoid_double_and_int_checks # only useful when targeting JS runtime
|
||||||
# - avoid_dynamic_calls # not yet tested
|
- avoid_dynamic_calls
|
||||||
- avoid_empty_else
|
- avoid_empty_else
|
||||||
- avoid_equals_and_hash_code_on_mutable_classes
|
- avoid_equals_and_hash_code_on_mutable_classes
|
||||||
- avoid_escaping_inner_quotes
|
- avoid_escaping_inner_quotes
|
||||||
|
@ -595,7 +595,7 @@ class ArchivePublisher {
|
|||||||
if (!jsonData.containsKey('current_release')) {
|
if (!jsonData.containsKey('current_release')) {
|
||||||
jsonData['current_release'] = <String, String>{};
|
jsonData['current_release'] = <String, String>{};
|
||||||
}
|
}
|
||||||
jsonData['current_release'][branchName] = revision;
|
(jsonData['current_release'] as Map<String, dynamic>)[branchName] = revision;
|
||||||
if (!jsonData.containsKey('releases')) {
|
if (!jsonData.containsKey('releases')) {
|
||||||
jsonData['releases'] = <Map<String, dynamic>>[];
|
jsonData['releases'] = <Map<String, dynamic>>[];
|
||||||
}
|
}
|
||||||
|
@ -1059,7 +1059,7 @@ Future<void> _ensureChromeDriverIsRunning() async {
|
|||||||
final HttpClientResponse response = await request.close();
|
final HttpClientResponse response = await request.close();
|
||||||
final Map<String, dynamic> webDriverStatus = json.decode(await response.transform(utf8.decoder).join('')) as Map<String, dynamic>;
|
final Map<String, dynamic> webDriverStatus = json.decode(await response.transform(utf8.decoder).join('')) as Map<String, dynamic>;
|
||||||
client.close();
|
client.close();
|
||||||
final bool webDriverReady = webDriverStatus['value']['ready'] as bool;
|
final bool webDriverReady = (webDriverStatus['value'] as Map<String, dynamic>)['ready'] as bool;
|
||||||
if (!webDriverReady) {
|
if (!webDriverReady) {
|
||||||
throw Exception('WebDriver not available.');
|
throw Exception('WebDriver not available.');
|
||||||
}
|
}
|
||||||
|
@ -394,7 +394,7 @@ void main() {
|
|||||||
// Make sure the new entry is first (and hopefully it takes less than a
|
// Make sure the new entry is first (and hopefully it takes less than a
|
||||||
// minute to go from publishArchive above to this line!).
|
// minute to go from publishArchive above to this line!).
|
||||||
expect(
|
expect(
|
||||||
DateTime.now().difference(DateTime.parse(releases[0]['release_date'] as String)),
|
DateTime.now().difference(DateTime.parse((releases[0] as Map<String, dynamic>)['release_date'] as String)),
|
||||||
lessThan(const Duration(minutes: 1)),
|
lessThan(const Duration(minutes: 1)),
|
||||||
);
|
);
|
||||||
const JsonEncoder encoder = JsonEncoder.withIndent(' ');
|
const JsonEncoder encoder = JsonEncoder.withIndent(' ');
|
||||||
|
@ -255,7 +255,7 @@ class ArchiveUnpublisher {
|
|||||||
});
|
});
|
||||||
jsonData['releases'] = releases;
|
jsonData['releases'] = releases;
|
||||||
for (final Channel channel in channels) {
|
for (final Channel channel in channels) {
|
||||||
if (!revisionsBeingRemoved.contains(jsonData['current_release'][getChannelName(channel)])) {
|
if (!revisionsBeingRemoved.contains((jsonData['current_release'] as Map<String, dynamic>)[getChannelName(channel)])) {
|
||||||
// Don't replace the current release if it's not one of the revisions we're removing.
|
// Don't replace the current release if it's not one of the revisions we're removing.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -263,7 +263,7 @@ class ArchiveUnpublisher {
|
|||||||
if (replacementRelease == null) {
|
if (replacementRelease == null) {
|
||||||
throw UnpublishException('Unable to find previous release for channel ${getChannelName(channel)}.');
|
throw UnpublishException('Unable to find previous release for channel ${getChannelName(channel)}.');
|
||||||
}
|
}
|
||||||
jsonData['current_release'][getChannelName(channel)] = replacementRelease['hash'];
|
(jsonData['current_release'] as Map<String, dynamic>)[getChannelName(channel)] = replacementRelease['hash'];
|
||||||
print(
|
print(
|
||||||
'${confirmed ? 'Reverting' : 'Would revert'} current ${getChannelName(channel)} '
|
'${confirmed ? 'Reverting' : 'Would revert'} current ${getChannelName(channel)} '
|
||||||
'${getPublishedPlatform(platform)} release to ${replacementRelease['hash']} (version ${replacementRelease['version']}).'
|
'${getPublishedPlatform(platform)} release to ${replacementRelease['hash']} (version ${replacementRelease['version']}).'
|
||||||
|
@ -31,7 +31,7 @@ Future<void> main() async {
|
|||||||
final Map<String, dynamic> data = <String, dynamic>{};
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
for (final String key in withSemantics.benchmarkScoreKeys) {
|
for (final String key in withSemantics.benchmarkScoreKeys) {
|
||||||
final String deltaKey = 'delta_$key';
|
final String deltaKey = 'delta_$key';
|
||||||
data[deltaKey] = withSemantics.data[key] - withoutSemantics.data[key];
|
data[deltaKey] = (withSemantics.data[key] as num) - (withoutSemantics.data[key] as num);
|
||||||
data['semantics_$key'] = withSemantics.data[key];
|
data['semantics_$key'] = withSemantics.data[key];
|
||||||
data[key] = withoutSemantics.data[key];
|
data[key] = withoutSemantics.data[key];
|
||||||
benchmarkScoreKeys.add(deltaKey);
|
benchmarkScoreKeys.add(deltaKey);
|
||||||
|
@ -273,7 +273,7 @@ Future<Uri> _getRemoteDebuggerUrl(Uri base) async {
|
|||||||
if (jsonObject == null || jsonObject.isEmpty) {
|
if (jsonObject == null || jsonObject.isEmpty) {
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
return base.resolve(jsonObject.first['webSocketDebuggerUrl'] as String);
|
return base.resolve((jsonObject.first as Map<String, dynamic>)['webSocketDebuggerUrl'] as String);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Summarizes a Blink trace down to a few interesting values.
|
/// Summarizes a Blink trace down to a few interesting values.
|
||||||
|
@ -104,11 +104,12 @@ Manifest _validateAndParseManifest(YamlMap manifestYaml) {
|
|||||||
|
|
||||||
List<ManifestTask> _validateAndParseTasks(dynamic tasksYaml) {
|
List<ManifestTask> _validateAndParseTasks(dynamic tasksYaml) {
|
||||||
_checkType(tasksYaml is YamlMap, tasksYaml, 'Value of "tasks"', 'dictionary');
|
_checkType(tasksYaml is YamlMap, tasksYaml, 'Value of "tasks"', 'dictionary');
|
||||||
final List<dynamic> sortedKeys = (tasksYaml as YamlMap).keys.toList()..sort();
|
final List<String> sortedKeys = (tasksYaml as YamlMap).keys.toList().cast<String>()..sort();
|
||||||
return sortedKeys.map<ManifestTask>((dynamic taskName) => _validateAndParseTask(taskName, tasksYaml[taskName])).toList();
|
// ignore: avoid_dynamic_calls
|
||||||
|
return sortedKeys.map<ManifestTask>((String taskName) => _validateAndParseTask(taskName, tasksYaml[taskName])).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
ManifestTask _validateAndParseTask(dynamic taskName, dynamic taskYaml) {
|
ManifestTask _validateAndParseTask(String taskName, dynamic taskYaml) {
|
||||||
_checkType(taskName is String, taskName, 'Task name', 'string');
|
_checkType(taskName is String, taskName, 'Task name', 'string');
|
||||||
_checkType(taskYaml is YamlMap, taskYaml, 'Value of task "$taskName"', 'dictionary');
|
_checkType(taskYaml is YamlMap, taskYaml, 'Value of task "$taskName"', 'dictionary');
|
||||||
_checkKeys(taskYaml as YamlMap, 'Value of task "$taskName"', const <String>[
|
_checkKeys(taskYaml as YamlMap, 'Value of task "$taskName"', const <String>[
|
||||||
@ -119,27 +120,32 @@ ManifestTask _validateAndParseTask(dynamic taskName, dynamic taskYaml) {
|
|||||||
'timeout_in_minutes',
|
'timeout_in_minutes',
|
||||||
'on_luci',
|
'on_luci',
|
||||||
]);
|
]);
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
final dynamic isFlaky = taskYaml['flaky'];
|
final dynamic isFlaky = taskYaml['flaky'];
|
||||||
if (isFlaky != null) {
|
if (isFlaky != null) {
|
||||||
_checkType(isFlaky is bool, isFlaky, 'flaky', 'boolean');
|
_checkType(isFlaky is bool, isFlaky, 'flaky', 'boolean');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
final dynamic timeoutInMinutes = taskYaml['timeout_in_minutes'];
|
final dynamic timeoutInMinutes = taskYaml['timeout_in_minutes'];
|
||||||
if (timeoutInMinutes != null) {
|
if (timeoutInMinutes != null) {
|
||||||
_checkType(timeoutInMinutes is int, timeoutInMinutes, 'timeout_in_minutes', 'integer');
|
_checkType(timeoutInMinutes is int, timeoutInMinutes, 'timeout_in_minutes', 'integer');
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<dynamic> capabilities = _validateAndParseCapabilities(taskName as String, taskYaml['required_agent_capabilities']);
|
// ignore: avoid_dynamic_calls
|
||||||
|
final List<dynamic> capabilities = _validateAndParseCapabilities(taskName, taskYaml['required_agent_capabilities']);
|
||||||
|
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
final dynamic onLuci = taskYaml['on_luci'];
|
final dynamic onLuci = taskYaml['on_luci'];
|
||||||
if (onLuci != null) {
|
if (onLuci != null) {
|
||||||
_checkType(onLuci is bool, onLuci, 'on_luci', 'boolean');
|
_checkType(onLuci is bool, onLuci, 'on_luci', 'boolean');
|
||||||
}
|
}
|
||||||
|
|
||||||
return ManifestTask._(
|
return ManifestTask._(
|
||||||
name: taskName as String,
|
name: taskName,
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
description: taskYaml['description'] as String,
|
description: taskYaml['description'] as String,
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
stage: taskYaml['stage'] as String,
|
stage: taskYaml['stage'] as String,
|
||||||
requiredAgentCapabilities: capabilities as List<String>,
|
requiredAgentCapabilities: capabilities as List<String>,
|
||||||
isFlaky: isFlaky as bool ?? false,
|
isFlaky: isFlaky as bool ?? false,
|
||||||
@ -150,8 +156,9 @@ ManifestTask _validateAndParseTask(dynamic taskName, dynamic taskYaml) {
|
|||||||
|
|
||||||
List<String> _validateAndParseCapabilities(String taskName, dynamic capabilitiesYaml) {
|
List<String> _validateAndParseCapabilities(String taskName, dynamic capabilitiesYaml) {
|
||||||
_checkType(capabilitiesYaml is List, capabilitiesYaml, 'required_agent_capabilities', 'list');
|
_checkType(capabilitiesYaml is List, capabilitiesYaml, 'required_agent_capabilities', 'list');
|
||||||
for (int i = 0; i < (capabilitiesYaml as List<dynamic>).length; i++) {
|
final List<dynamic> capabilities = capabilitiesYaml as List<dynamic>;
|
||||||
final dynamic capability = capabilitiesYaml[i];
|
for (int i = 0; i < capabilities.length; i++) {
|
||||||
|
final dynamic capability = capabilities[i];
|
||||||
_checkType(capability is String, capability, 'required_agent_capabilities[$i]', 'string');
|
_checkType(capability is String, capability, 'required_agent_capabilities[$i]', 'string');
|
||||||
}
|
}
|
||||||
return (capabilitiesYaml as List<dynamic>).cast<String>();
|
return (capabilitiesYaml as List<dynamic>).cast<String>();
|
||||||
|
@ -31,7 +31,7 @@ class TaskResult {
|
|||||||
'result data ${prettyJson.convert(data)}';
|
'result data ${prettyJson.convert(data)}';
|
||||||
} else if (data[key] is! num) {
|
} else if (data[key] is! num) {
|
||||||
throw 'Invalid benchmark score for key "$key". It is expected to be a num '
|
throw 'Invalid benchmark score for key "$key". It is expected to be a num '
|
||||||
'but was ${data[key].runtimeType}: ${prettyJson.convert(data[key])}';
|
'but was ${(data[key] as Object).runtimeType}: ${prettyJson.convert(data[key])}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,24 +151,43 @@ TaskFunction createHotModeTest({String deviceIdOverride, Map<String, String> env
|
|||||||
|
|
||||||
return TaskResult.success(
|
return TaskResult.success(
|
||||||
<String, dynamic> {
|
<String, dynamic> {
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotReloadInitialDevFSSyncMilliseconds': smallReloadData['hotReloadInitialDevFSSyncMilliseconds'][0],
|
'hotReloadInitialDevFSSyncMilliseconds': smallReloadData['hotReloadInitialDevFSSyncMilliseconds'][0],
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotRestartMillisecondsToFrame': smallReloadData['hotRestartMillisecondsToFrame'][0],
|
'hotRestartMillisecondsToFrame': smallReloadData['hotRestartMillisecondsToFrame'][0],
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotReloadMillisecondsToFrame' : smallReloadData['hotReloadMillisecondsToFrame'][0],
|
'hotReloadMillisecondsToFrame' : smallReloadData['hotReloadMillisecondsToFrame'][0],
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotReloadDevFSSyncMilliseconds': smallReloadData['hotReloadDevFSSyncMilliseconds'][0],
|
'hotReloadDevFSSyncMilliseconds': smallReloadData['hotReloadDevFSSyncMilliseconds'][0],
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotReloadFlutterReassembleMilliseconds': smallReloadData['hotReloadFlutterReassembleMilliseconds'][0],
|
'hotReloadFlutterReassembleMilliseconds': smallReloadData['hotReloadFlutterReassembleMilliseconds'][0],
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotReloadVMReloadMilliseconds': smallReloadData['hotReloadVMReloadMilliseconds'][0],
|
'hotReloadVMReloadMilliseconds': smallReloadData['hotReloadVMReloadMilliseconds'][0],
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotReloadMillisecondsToFrameAfterChange' : smallReloadData['hotReloadMillisecondsToFrame'][1],
|
'hotReloadMillisecondsToFrameAfterChange' : smallReloadData['hotReloadMillisecondsToFrame'][1],
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotReloadDevFSSyncMillisecondsAfterChange': smallReloadData['hotReloadDevFSSyncMilliseconds'][1],
|
'hotReloadDevFSSyncMillisecondsAfterChange': smallReloadData['hotReloadDevFSSyncMilliseconds'][1],
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotReloadFlutterReassembleMillisecondsAfterChange': smallReloadData['hotReloadFlutterReassembleMilliseconds'][1],
|
'hotReloadFlutterReassembleMillisecondsAfterChange': smallReloadData['hotReloadFlutterReassembleMilliseconds'][1],
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotReloadVMReloadMillisecondsAfterChange': smallReloadData['hotReloadVMReloadMilliseconds'][1],
|
'hotReloadVMReloadMillisecondsAfterChange': smallReloadData['hotReloadVMReloadMilliseconds'][1],
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotReloadInitialDevFSSyncAfterRelaunchMilliseconds' : freshRestartReloadsData['hotReloadInitialDevFSSyncMilliseconds'][0],
|
'hotReloadInitialDevFSSyncAfterRelaunchMilliseconds' : freshRestartReloadsData['hotReloadInitialDevFSSyncMilliseconds'][0],
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotReloadMillisecondsToFrameAfterMediumChange' : mediumReloadData['hotReloadMillisecondsToFrame'][1],
|
'hotReloadMillisecondsToFrameAfterMediumChange' : mediumReloadData['hotReloadMillisecondsToFrame'][1],
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotReloadDevFSSyncMillisecondsAfterMediumChange': mediumReloadData['hotReloadDevFSSyncMilliseconds'][1],
|
'hotReloadDevFSSyncMillisecondsAfterMediumChange': mediumReloadData['hotReloadDevFSSyncMilliseconds'][1],
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotReloadFlutterReassembleMillisecondsAfterMediumChange': mediumReloadData['hotReloadFlutterReassembleMilliseconds'][1],
|
'hotReloadFlutterReassembleMillisecondsAfterMediumChange': mediumReloadData['hotReloadFlutterReassembleMilliseconds'][1],
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotReloadVMReloadMillisecondsAfterMediumChange': mediumReloadData['hotReloadVMReloadMilliseconds'][1],
|
'hotReloadVMReloadMillisecondsAfterMediumChange': mediumReloadData['hotReloadVMReloadMilliseconds'][1],
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotReloadMillisecondsToFrameAfterLargeChange' : largeReloadData['hotReloadMillisecondsToFrame'][1],
|
'hotReloadMillisecondsToFrameAfterLargeChange' : largeReloadData['hotReloadMillisecondsToFrame'][1],
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotReloadDevFSSyncMillisecondsAfterLargeChange': largeReloadData['hotReloadDevFSSyncMilliseconds'][1],
|
'hotReloadDevFSSyncMillisecondsAfterLargeChange': largeReloadData['hotReloadDevFSSyncMilliseconds'][1],
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotReloadFlutterReassembleMillisecondsAfterLargeChange': largeReloadData['hotReloadFlutterReassembleMilliseconds'][1],
|
'hotReloadFlutterReassembleMillisecondsAfterLargeChange': largeReloadData['hotReloadFlutterReassembleMilliseconds'][1],
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
'hotReloadVMReloadMillisecondsAfterLargeChange': largeReloadData['hotReloadVMReloadMilliseconds'][1],
|
'hotReloadVMReloadMillisecondsAfterLargeChange': largeReloadData['hotReloadVMReloadMilliseconds'][1],
|
||||||
},
|
},
|
||||||
benchmarkScoreKeys: <String>[
|
benchmarkScoreKeys: <String>[
|
||||||
|
@ -421,13 +421,15 @@ TaskFunction createsScrollSmoothnessPerfTest() {
|
|||||||
final Map<String, dynamic> result = <String, dynamic>{};
|
final Map<String, dynamic> result = <String, dynamic>{};
|
||||||
void addResult(dynamic data, String suffix) {
|
void addResult(dynamic data, String suffix) {
|
||||||
assert(data is Map<String, dynamic>);
|
assert(data is Map<String, dynamic>);
|
||||||
const List<String> metricKeys = <String>[
|
if (data is Map<String, dynamic>) {
|
||||||
'janky_count',
|
const List<String> metricKeys = <String>[
|
||||||
'average_abs_jerk',
|
'janky_count',
|
||||||
'dropped_frame_count',
|
'average_abs_jerk',
|
||||||
];
|
'dropped_frame_count',
|
||||||
for (final String key in metricKeys) {
|
];
|
||||||
result[key+suffix] = data[key];
|
for (final String key in metricKeys) {
|
||||||
|
result[key + suffix] = data[key];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addResult(data['resample on with 90Hz input'], '_with_resampler_90Hz');
|
addResult(data['resample on with 90Hz input'], '_with_resampler_90Hz');
|
||||||
@ -1472,15 +1474,15 @@ class DevToolsMemoryTest {
|
|||||||
final Map<String, dynamic> data = json.decode(
|
final Map<String, dynamic> data = json.decode(
|
||||||
file('$project/$_kJsonFileName').readAsStringSync(),
|
file('$project/$_kJsonFileName').readAsStringSync(),
|
||||||
) as Map<String, dynamic>;
|
) as Map<String, dynamic>;
|
||||||
final List<dynamic> samples = data['samples']['data'] as List<dynamic>;
|
final List<Map<String, dynamic>> samples = (data['samples'] as Map<String, dynamic>)['data'] as List<Map<String, dynamic>>;
|
||||||
int maxRss = 0;
|
int maxRss = 0;
|
||||||
int maxAdbTotal = 0;
|
int maxAdbTotal = 0;
|
||||||
for (final dynamic sample in samples) {
|
for (final Map<String, dynamic> sample in samples) {
|
||||||
if (sample['rss'] != null) {
|
if (sample['rss'] != null) {
|
||||||
maxRss = math.max(maxRss, sample['rss'] as int);
|
maxRss = math.max(maxRss, sample['rss'] as int);
|
||||||
}
|
}
|
||||||
if (sample['adb_memoryInfo'] != null) {
|
if (sample['adb_memoryInfo'] != null) {
|
||||||
maxAdbTotal = math.max(maxAdbTotal, sample['adb_memoryInfo']['Total'] as int);
|
maxAdbTotal = math.max(maxAdbTotal, (sample['adb_memoryInfo'] as Map<String, dynamic>)['Total'] as int);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ Future<TaskResult> runWebBenchmark({ @required bool useCanvasKit }) async {
|
|||||||
final BlinkTraceSummary traceSummary = BlinkTraceSummary.fromJson(latestPerformanceTrace);
|
final BlinkTraceSummary traceSummary = BlinkTraceSummary.fromJson(latestPerformanceTrace);
|
||||||
profile['totalUiFrame.average'] = traceSummary.averageTotalUIFrameTime.inMicroseconds;
|
profile['totalUiFrame.average'] = traceSummary.averageTotalUIFrameTime.inMicroseconds;
|
||||||
profile['scoreKeys'] ??= <dynamic>[]; // using dynamic for consistency with JSON
|
profile['scoreKeys'] ??= <dynamic>[]; // using dynamic for consistency with JSON
|
||||||
profile['scoreKeys'].add('totalUiFrame.average');
|
(profile['scoreKeys'] as List<dynamic>).add('totalUiFrame.average');
|
||||||
latestPerformanceTrace = null;
|
latestPerformanceTrace = null;
|
||||||
}
|
}
|
||||||
collectedProfiles.add(profile);
|
collectedProfiles.add(profile);
|
||||||
|
@ -46,7 +46,7 @@ class _ColorPickerSwatch extends StatelessWidget {
|
|||||||
|
|
||||||
final Color color;
|
final Color color;
|
||||||
final bool selected;
|
final bool selected;
|
||||||
final Function? onTap;
|
final VoidCallback? onTap;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build (BuildContext context) {
|
Widget build (BuildContext context) {
|
||||||
|
@ -42,7 +42,7 @@ Future<void> saveDurationsHistogram(List<Map<String, dynamic>> events, String ou
|
|||||||
frameStart = timestamp;
|
frameStart = timestamp;
|
||||||
} else {
|
} else {
|
||||||
assert(phase == 'E');
|
assert(phase == 'E');
|
||||||
final String routeName = startEvent['args']['to'] as String;
|
final String routeName = (startEvent['args'] as Map<String, dynamic>)['to'] as String;
|
||||||
durations[routeName] ??= <int>[];
|
durations[routeName] ??= <int>[];
|
||||||
durations[routeName]!.add(timestamp - frameStart!);
|
durations[routeName]!.add(timestamp - frameStart!);
|
||||||
startEvent = null;
|
startEvent = null;
|
||||||
@ -79,7 +79,7 @@ Future<void> saveDurationsHistogram(List<Map<String, dynamic>> events, String ou
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
final String routeName = eventName == 'Start Transition'
|
final String routeName = eventName == 'Start Transition'
|
||||||
? eventIter.current['args']['to'] as String
|
? (eventIter.current['args'] as Map<String, dynamic>)['to'] as String
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
if (eventName == lastEventName && routeName == lastRouteName) {
|
if (eventName == lastEventName && routeName == lastRouteName) {
|
||||||
|
@ -440,18 +440,18 @@ class LogicalKeyEntry {
|
|||||||
LogicalKeyEntry.fromJsonMapEntry(Map<String, dynamic> map)
|
LogicalKeyEntry.fromJsonMapEntry(Map<String, dynamic> map)
|
||||||
: value = map['value'] as int,
|
: value = map['value'] as int,
|
||||||
name = map['name'] as String,
|
name = map['name'] as String,
|
||||||
webNames = _toNonEmptyArray<String>(map['names']['web']),
|
webNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['web']),
|
||||||
macOSKeyCodeNames = _toNonEmptyArray<String>(map['names']['macos']),
|
macOSKeyCodeNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['macos']),
|
||||||
macOSKeyCodeValues = _toNonEmptyArray<int>(map['values']?['macos']),
|
macOSKeyCodeValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['macos']),
|
||||||
iOSKeyCodeNames = _toNonEmptyArray<String>(map['names']['ios']),
|
iOSKeyCodeNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['ios']),
|
||||||
iOSKeyCodeValues = _toNonEmptyArray<int>(map['values']?['ios']),
|
iOSKeyCodeValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['ios']),
|
||||||
gtkNames = _toNonEmptyArray<String>(map['names']['gtk']),
|
gtkNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['gtk']),
|
||||||
gtkValues = _toNonEmptyArray<int>(map['values']?['gtk']),
|
gtkValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['gtk']),
|
||||||
windowsNames = _toNonEmptyArray<String>(map['names']['windows']),
|
windowsNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['windows']),
|
||||||
windowsValues = _toNonEmptyArray<int>(map['values']?['windows']),
|
windowsValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['windows']),
|
||||||
androidNames = _toNonEmptyArray<String>(map['names']['android']),
|
androidNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['android']),
|
||||||
androidValues = _toNonEmptyArray<int>(map['values']?['android']),
|
androidValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['android']),
|
||||||
fuchsiaValues = _toNonEmptyArray<int>(map['values']?['fuchsia']),
|
fuchsiaValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['fuchsia']),
|
||||||
keyLabel = map['keyLabel'] as String?;
|
keyLabel = map['keyLabel'] as String?;
|
||||||
|
|
||||||
final int value;
|
final int value;
|
||||||
|
@ -275,17 +275,20 @@ class PhysicalKeyEntry {
|
|||||||
|
|
||||||
/// Populates the key from a JSON map.
|
/// Populates the key from a JSON map.
|
||||||
factory PhysicalKeyEntry.fromJsonMapEntry(Map<String, dynamic> map) {
|
factory PhysicalKeyEntry.fromJsonMapEntry(Map<String, dynamic> map) {
|
||||||
|
final Map<String, dynamic> names = map['names'] as Map<String, dynamic>;
|
||||||
|
final Map<String, dynamic> scanCodes = map['scanCodes'] as Map<String, dynamic>;
|
||||||
|
final Map<String, dynamic>? keyCodes = map['keyCodes'] as Map<String, dynamic>?;
|
||||||
return PhysicalKeyEntry(
|
return PhysicalKeyEntry(
|
||||||
name: map['names']['name'] as String,
|
name: names['name'] as String,
|
||||||
chromiumCode: map['names']['chromium'] as String?,
|
chromiumCode: names['chromium'] as String?,
|
||||||
usbHidCode: map['scanCodes']['usb'] as int,
|
usbHidCode: scanCodes['usb'] as int,
|
||||||
androidScanCodes: (map['scanCodes']['android'] as List<dynamic>?)?.cast<int>() ?? <int>[],
|
androidScanCodes: (scanCodes['android'] as List<dynamic>?)?.cast<int>() ?? <int>[],
|
||||||
linuxScanCode: map['scanCodes']['linux'] as int?,
|
linuxScanCode: scanCodes['linux'] as int?,
|
||||||
xKbScanCode: map['scanCodes']['xkb'] as int?,
|
xKbScanCode: scanCodes['xkb'] as int?,
|
||||||
windowsScanCode: map['scanCodes']['windows'] as int?,
|
windowsScanCode: scanCodes['windows'] as int?,
|
||||||
macOSScanCode: map['scanCodes']['macos'] as int?,
|
macOSScanCode: scanCodes['macos'] as int?,
|
||||||
iOSScanCode: map['scanCodes']['ios'] as int?,
|
iOSScanCode: scanCodes['ios'] as int?,
|
||||||
glfwKeyCodes: (map['keyCodes']?['glfw'] as List<dynamic>?)?.cast<int>() ?? <int>[],
|
glfwKeyCodes: (keyCodes?['glfw'] as List<dynamic>?)?.cast<int>() ?? <int>[],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ class _ChainedEvaluation<T> extends Animatable<T> {
|
|||||||
/// If `T` is not nullable, then [begin] and [end] must both be set to
|
/// If `T` is not nullable, then [begin] and [end] must both be set to
|
||||||
/// non-null values before using [lerp] or [transform], otherwise they
|
/// non-null values before using [lerp] or [transform], otherwise they
|
||||||
/// will throw.
|
/// will throw.
|
||||||
class Tween<T extends dynamic> extends Animatable<T> {
|
class Tween<T extends Object?> extends Animatable<T> {
|
||||||
/// Creates a tween.
|
/// Creates a tween.
|
||||||
///
|
///
|
||||||
/// The [begin] and [end] properties must be non-null before the tween is
|
/// The [begin] and [end] properties must be non-null before the tween is
|
||||||
@ -261,7 +261,8 @@ class Tween<T extends dynamic> extends Animatable<T> {
|
|||||||
// that do not conform to the Tween requirements.
|
// that do not conform to the Tween requirements.
|
||||||
dynamic result;
|
dynamic result;
|
||||||
try {
|
try {
|
||||||
result = begin + (end - begin) * t;
|
// ignore: avoid_dynamic_calls
|
||||||
|
result = (begin as dynamic) + ((end as dynamic) - (begin as dynamic)) * t;
|
||||||
result as T;
|
result as T;
|
||||||
return true;
|
return true;
|
||||||
} on NoSuchMethodError {
|
} on NoSuchMethodError {
|
||||||
@ -301,7 +302,8 @@ class Tween<T extends dynamic> extends Animatable<T> {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}());
|
}());
|
||||||
return begin + (end - begin) * t as T;
|
// ignore: avoid_dynamic_calls
|
||||||
|
return (begin as dynamic) + ((end as dynamic) - (begin as dynamic)) * t as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the interpolated value for the current value of the given animation.
|
/// Returns the interpolated value for the current value of the given animation.
|
||||||
@ -330,7 +332,7 @@ class Tween<T extends dynamic> extends Animatable<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A [Tween] that evaluates its [parent] in reverse.
|
/// A [Tween] that evaluates its [parent] in reverse.
|
||||||
class ReverseTween<T> extends Tween<T> {
|
class ReverseTween<T extends Object?> extends Tween<T> {
|
||||||
/// Construct a [Tween] that evaluates its [parent] in reverse.
|
/// Construct a [Tween] that evaluates its [parent] in reverse.
|
||||||
ReverseTween(this.parent)
|
ReverseTween(this.parent)
|
||||||
: assert(parent != null),
|
: assert(parent != null),
|
||||||
|
@ -35,13 +35,15 @@ Future<R> compute<Q, R>(isolates.ComputeCallback<Q, R> callback, Q message, { St
|
|||||||
final Completer<R> result = Completer<R>();
|
final Completer<R> result = Completer<R>();
|
||||||
errorPort.listen((dynamic errorData) {
|
errorPort.listen((dynamic errorData) {
|
||||||
assert(errorData is List<dynamic>);
|
assert(errorData is List<dynamic>);
|
||||||
assert(errorData.length == 2);
|
if (errorData is List<dynamic>) {
|
||||||
final Exception exception = Exception(errorData[0]);
|
assert(errorData.length == 2);
|
||||||
final StackTrace stack = StackTrace.fromString(errorData[1] as String);
|
final Exception exception = Exception(errorData[0]);
|
||||||
if (result.isCompleted) {
|
final StackTrace stack = StackTrace.fromString(errorData[1] as String);
|
||||||
Zone.current.handleUncaughtError(exception, stack);
|
if (result.isCompleted) {
|
||||||
} else {
|
Zone.current.handleUncaughtError(exception, stack);
|
||||||
result.completeError(exception, stack);
|
} else {
|
||||||
|
result.completeError(exception, stack);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
exitPort.listen((dynamic exitData) {
|
exitPort.listen((dynamic exitData) {
|
||||||
|
@ -86,7 +86,7 @@ class NetworkImage
|
|||||||
final Uri resolved = Uri.base.resolve(key.url);
|
final Uri resolved = Uri.base.resolve(key.url);
|
||||||
// This API only exists in the web engine implementation and is not
|
// This API only exists in the web engine implementation and is not
|
||||||
// contained in the analyzer summary for Flutter.
|
// contained in the analyzer summary for Flutter.
|
||||||
return ui.webOnlyInstantiateImageCodecFromUrl(// ignore: undefined_function
|
return ui.webOnlyInstantiateImageCodecFromUrl(// ignore: undefined_function, avoid_dynamic_calls
|
||||||
resolved,
|
resolved,
|
||||||
chunkCallback: (int bytes, int total) {
|
chunkCallback: (int bytes, int total) {
|
||||||
chunkEvents.add(ImageChunkEvent(cumulativeBytesLoaded: bytes, expectedTotalBytes: total));
|
chunkEvents.add(ImageChunkEvent(cumulativeBytesLoaded: bytes, expectedTotalBytes: total));
|
||||||
|
@ -517,7 +517,7 @@ class ImageCache {
|
|||||||
image.dispose();
|
image.dispose();
|
||||||
_cache.remove(key);
|
_cache.remove(key);
|
||||||
if (!kReleaseMode) {
|
if (!kReleaseMode) {
|
||||||
finishArgs['evictedKeys'].add(key.toString());
|
(finishArgs['evictedKeys'] as List<String>).add(key.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!kReleaseMode) {
|
if (!kReleaseMode) {
|
||||||
|
@ -1369,8 +1369,10 @@ class TextInput {
|
|||||||
_currentConnection!._client.performAction(_toTextInputAction(args[1] as String));
|
_currentConnection!._client.performAction(_toTextInputAction(args[1] as String));
|
||||||
break;
|
break;
|
||||||
case 'TextInputClient.performPrivateCommand':
|
case 'TextInputClient.performPrivateCommand':
|
||||||
|
final Map<String, dynamic> firstArg = args[1] as Map<String, dynamic>;
|
||||||
_currentConnection!._client.performPrivateCommand(
|
_currentConnection!._client.performPrivateCommand(
|
||||||
args[1]['action'] as String, args[1]['data'] as Map<String, dynamic>,
|
firstArg['action'] as String,
|
||||||
|
firstArg['data'] as Map<String, dynamic>,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 'TextInputClient.updateFloatingCursor':
|
case 'TextInputClient.updateFloatingCursor':
|
||||||
|
@ -6395,7 +6395,7 @@ FlutterErrorDetails _debugReportException(
|
|||||||
/// * [RenderObjectElement.updateChildren], which discusses why this class is
|
/// * [RenderObjectElement.updateChildren], which discusses why this class is
|
||||||
/// used as slot values for the children of a [MultiChildRenderObjectElement].
|
/// used as slot values for the children of a [MultiChildRenderObjectElement].
|
||||||
@immutable
|
@immutable
|
||||||
class IndexedSlot<T> {
|
class IndexedSlot<T extends Element?> {
|
||||||
/// Creates an [IndexedSlot] with the provided [index] and slot [value].
|
/// Creates an [IndexedSlot] with the provided [index] and slot [value].
|
||||||
const IndexedSlot(this.index, this.value);
|
const IndexedSlot(this.index, this.value);
|
||||||
|
|
||||||
|
@ -306,6 +306,9 @@ class _GlowingOverscrollIndicatorState extends State<GlowingOverscrollIndicator>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (notification is ScrollEndNotification || notification is ScrollUpdateNotification) {
|
} else if (notification is ScrollEndNotification || notification is ScrollUpdateNotification) {
|
||||||
|
// Using dynamic here to avoid layer violations of importing
|
||||||
|
// drag_details.dart from gestures.
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
if ((notification as dynamic).dragDetails != null) {
|
if ((notification as dynamic).dragDetails != null) {
|
||||||
_leadingController!.scrollEnd();
|
_leadingController!.scrollEnd();
|
||||||
_trailingController!.scrollEnd();
|
_trailingController!.scrollEnd();
|
||||||
|
7
packages/flutter/test/analysis_options.yaml
Normal file
7
packages/flutter/test/analysis_options.yaml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
include: ../analysis_options.yaml
|
||||||
|
|
||||||
|
linter:
|
||||||
|
rules:
|
||||||
|
# Turn off for tests, since we often use dynamic as a method to obtain a
|
||||||
|
# reference to a private state object or renderer in tests.
|
||||||
|
avoid_dynamic_calls: false
|
@ -209,7 +209,9 @@ class FakeAndroidPlatformViewsController {
|
|||||||
Future<dynamic> _dispose(MethodCall call) {
|
Future<dynamic> _dispose(MethodCall call) {
|
||||||
assert(call.arguments is Map);
|
assert(call.arguments is Map);
|
||||||
|
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
final int id = call.arguments['id'] as int;
|
final int id = call.arguments['id'] as int;
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
final bool hybrid = call.arguments['hybrid'] as bool;
|
final bool hybrid = call.arguments['hybrid'] as bool;
|
||||||
|
|
||||||
if (hybrid && !_views[id]!.hybrid!) {
|
if (hybrid && !_views[id]!.hybrid!) {
|
||||||
|
@ -156,12 +156,12 @@ class WebFlutterDriver extends FlutterDriver {
|
|||||||
final List<Map<String, dynamic>> events = <Map<String, dynamic>>[];
|
final List<Map<String, dynamic>> events = <Map<String, dynamic>>[];
|
||||||
for (final async_io.LogEntry entry in await _connection.logs.toList()) {
|
for (final async_io.LogEntry entry in await _connection.logs.toList()) {
|
||||||
if (_startTime.isBefore(entry.timestamp)) {
|
if (_startTime.isBefore(entry.timestamp)) {
|
||||||
final Map<String, dynamic> data = jsonDecode(entry.message!)['message'] as Map<String, dynamic>;
|
final Map<String, dynamic> data = (jsonDecode(entry.message!) as Map<String, dynamic>)['message'] as Map<String, dynamic>;
|
||||||
if (data['method'] == 'Tracing.dataCollected') {
|
if (data['method'] == 'Tracing.dataCollected') {
|
||||||
// 'ts' data collected from Chrome is in double format, conversion needed
|
// 'ts' data collected from Chrome is in double format, conversion needed
|
||||||
try {
|
try {
|
||||||
data['params']['ts'] =
|
final Map<String, dynamic> params = data['params'] as Map<String, dynamic>;
|
||||||
double.parse(data['params']['ts'].toString()).toInt();
|
params['ts'] = double.parse(params['ts'].toString()).toInt();
|
||||||
} on FormatException catch (_) {
|
} on FormatException catch (_) {
|
||||||
// data is corrupted, skip
|
// data is corrupted, skip
|
||||||
continue;
|
continue;
|
||||||
|
@ -968,16 +968,16 @@ void main() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function will verify the format of the script
|
// This function will verify the format of the script and return the actual
|
||||||
/// and return the actual script.
|
// script. The script will be in the following format:
|
||||||
/// script will be in the following format:
|
|
||||||
// window.flutterDriver('[actual script]')
|
// window.flutterDriver('[actual script]')
|
||||||
String? _checkAndEncode(dynamic script) {
|
String _checkAndEncode(dynamic script) {
|
||||||
expect(script, isA<String>());
|
expect(script, isA<String>());
|
||||||
expect(script.startsWith(_kWebScriptPrefix), isTrue);
|
final String scriptString = script as String;
|
||||||
expect(script.endsWith(_kWebScriptSuffix), isTrue);
|
expect(scriptString.startsWith(_kWebScriptPrefix), isTrue);
|
||||||
|
expect(scriptString.endsWith(_kWebScriptSuffix), isTrue);
|
||||||
// Strip prefix and suffix
|
// Strip prefix and suffix
|
||||||
return script.substring(_kWebScriptPrefix.length, script.length - 2) as String?;
|
return scriptString.substring(_kWebScriptPrefix.length, script.length - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
vms.Response? makeFakeResponse(
|
vms.Response? makeFakeResponse(
|
||||||
@ -999,7 +999,7 @@ class FakeFlutterWebConnection extends Fake implements FlutterWebConnection {
|
|||||||
@override
|
@override
|
||||||
Future<dynamic> sendCommand(String script, Duration? duration) async {
|
Future<dynamic> sendCommand(String script, Duration? duration) async {
|
||||||
commandLog.add('$script $duration');
|
commandLog.add('$script $duration');
|
||||||
final Map<String, dynamic> decoded = jsonDecode(_checkAndEncode(script)!) as Map<String, dynamic>;
|
final Map<String, dynamic> decoded = jsonDecode(_checkAndEncode(script)) as Map<String, dynamic>;
|
||||||
final dynamic response = responses[decoded['command']];
|
final dynamic response = responses[decoded['command']];
|
||||||
assert(response != null, 'Missing ${decoded['command']} in responses.');
|
assert(response != null, 'Missing ${decoded['command']} in responses.');
|
||||||
return response;
|
return response;
|
||||||
|
@ -345,14 +345,18 @@ void main() {
|
|||||||
|
|
||||||
final CustomPaint dialPaint = tester.widget(find.byKey(const ValueKey<String>('time-picker-dial')));
|
final CustomPaint dialPaint = tester.widget(find.byKey(const ValueKey<String>('time-picker-dial')));
|
||||||
final dynamic dialPainter = dialPaint.painter;
|
final dynamic dialPainter = dialPaint.painter;
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
final List<dynamic> primaryLabels = dialPainter.primaryLabels as List<dynamic>;
|
final List<dynamic> primaryLabels = dialPainter.primaryLabels as List<dynamic>;
|
||||||
expect(
|
expect(
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
primaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text! as TextSpan).text!),
|
primaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text! as TextSpan).text!),
|
||||||
labels12To11,
|
labels12To11,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
final List<dynamic> secondaryLabels = dialPainter.secondaryLabels as List<dynamic>;
|
final List<dynamic> secondaryLabels = dialPainter.secondaryLabels as List<dynamic>;
|
||||||
expect(
|
expect(
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
secondaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text! as TextSpan).text!),
|
secondaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text! as TextSpan).text!),
|
||||||
labels12To11,
|
labels12To11,
|
||||||
);
|
);
|
||||||
@ -363,14 +367,18 @@ void main() {
|
|||||||
|
|
||||||
final CustomPaint dialPaint = tester.widget(find.byKey(const ValueKey<String>('time-picker-dial')));
|
final CustomPaint dialPaint = tester.widget(find.byKey(const ValueKey<String>('time-picker-dial')));
|
||||||
final dynamic dialPainter = dialPaint.painter;
|
final dynamic dialPainter = dialPaint.painter;
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
final List<dynamic> primaryLabels = dialPainter.primaryLabels as List<dynamic>;
|
final List<dynamic> primaryLabels = dialPainter.primaryLabels as List<dynamic>;
|
||||||
expect(
|
expect(
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
primaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text! as TextSpan).text!),
|
primaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text! as TextSpan).text!),
|
||||||
labels00To22TwoDigit,
|
labels00To22TwoDigit,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
final List<dynamic> secondaryLabels = dialPainter.secondaryLabels as List<dynamic>;
|
final List<dynamic> secondaryLabels = dialPainter.secondaryLabels as List<dynamic>;
|
||||||
expect(
|
expect(
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
secondaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text! as TextSpan).text!),
|
secondaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text! as TextSpan).text!),
|
||||||
labels00To22TwoDigit,
|
labels00To22TwoDigit,
|
||||||
);
|
);
|
||||||
|
@ -866,7 +866,7 @@ class _HasGoodToStringDeep extends Matcher {
|
|||||||
@override
|
@override
|
||||||
bool matches(dynamic object, Map<dynamic, dynamic> matchState) {
|
bool matches(dynamic object, Map<dynamic, dynamic> matchState) {
|
||||||
final List<String> issues = <String>[];
|
final List<String> issues = <String>[];
|
||||||
String description = object.toStringDeep() as String;
|
String description = object.toStringDeep() as String; // ignore: avoid_dynamic_calls
|
||||||
if (description.endsWith('\n')) {
|
if (description.endsWith('\n')) {
|
||||||
// Trim off trailing \n as the remaining calculations assume
|
// Trim off trailing \n as the remaining calculations assume
|
||||||
// the description does not end with a trailing \n.
|
// the description does not end with a trailing \n.
|
||||||
@ -904,7 +904,7 @@ class _HasGoodToStringDeep extends Matcher {
|
|||||||
const String prefixOtherLines = 'PREFIX_OTHER_LINES_';
|
const String prefixOtherLines = 'PREFIX_OTHER_LINES_';
|
||||||
final List<String> prefixIssues = <String>[];
|
final List<String> prefixIssues = <String>[];
|
||||||
String descriptionWithPrefixes =
|
String descriptionWithPrefixes =
|
||||||
object.toStringDeep(prefixLineOne: prefixLineOne, prefixOtherLines: prefixOtherLines) as String;
|
object.toStringDeep(prefixLineOne: prefixLineOne, prefixOtherLines: prefixOtherLines) as String; // ignore: avoid_dynamic_calls
|
||||||
if (descriptionWithPrefixes.endsWith('\n')) {
|
if (descriptionWithPrefixes.endsWith('\n')) {
|
||||||
// Trim off trailing \n as the remaining calculations assume
|
// Trim off trailing \n as the remaining calculations assume
|
||||||
// the description does not end with a trailing \n.
|
// the description does not end with a trailing \n.
|
||||||
@ -1875,7 +1875,7 @@ class _MatchesSemanticsData extends Matcher {
|
|||||||
bool allMatched = true;
|
bool allMatched = true;
|
||||||
if (children != null) {
|
if (children != null) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
node.visitChildren((SemanticsNode child) {
|
(node as SemanticsNode).visitChildren((SemanticsNode child) {
|
||||||
allMatched = children![i].matches(child, matchState) && allMatched;
|
allMatched = children![i].matches(child, matchState) && allMatched;
|
||||||
i += 1;
|
i += 1;
|
||||||
return allMatched;
|
return allMatched;
|
||||||
|
@ -119,8 +119,9 @@ class TestTextInput {
|
|||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
switch (methodCall.method) {
|
switch (methodCall.method) {
|
||||||
case 'TextInput.setClient':
|
case 'TextInput.setClient':
|
||||||
_client = methodCall.arguments[0] as int;
|
final List<dynamic> arguments = methodCall.arguments as List<dynamic>;
|
||||||
setClientArgs = methodCall.arguments[1] as Map<String, dynamic>;
|
_client = arguments[0] as int;
|
||||||
|
setClientArgs = arguments[1] as Map<String, dynamic>;
|
||||||
break;
|
break;
|
||||||
case 'TextInput.updateConfig':
|
case 'TextInput.updateConfig':
|
||||||
setClientArgs = methodCall.arguments as Map<String, dynamic>;
|
setClientArgs = methodCall.arguments as Map<String, dynamic>;
|
||||||
|
@ -11,6 +11,7 @@ import 'package:flutter_test/flutter_test.dart';
|
|||||||
void main() {
|
void main() {
|
||||||
test('TestWindow can handle new methods without breaking', () {
|
test('TestWindow can handle new methods without breaking', () {
|
||||||
final dynamic testWindow = TestWindow(window: ui.window);
|
final dynamic testWindow = TestWindow(window: ui.window);
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
expect(testWindow.someNewProperty, null);
|
expect(testWindow.someNewProperty, null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ class MultiRootFileSystem extends ForwardingFileSystem {
|
|||||||
} else if (path is FileSystemEntity) {
|
} else if (path is FileSystemEntity) {
|
||||||
uri = path.uri;
|
uri = path.uri;
|
||||||
} else {
|
} else {
|
||||||
throw ArgumentError('Invalid type for "path": ${path?.runtimeType}');
|
throw ArgumentError('Invalid type for "path": ${(path as Object?)?.runtimeType}');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!uri.hasScheme || uri.scheme != _scheme) {
|
if (!uri.hasScheme || uri.scheme != _scheme) {
|
||||||
|
@ -15,6 +15,7 @@ import '../../base/file_system.dart';
|
|||||||
import '../../base/io.dart';
|
import '../../base/io.dart';
|
||||||
import '../../build_info.dart';
|
import '../../build_info.dart';
|
||||||
import '../../cache.dart';
|
import '../../cache.dart';
|
||||||
|
import '../../convert.dart';
|
||||||
import '../../dart/language_version.dart';
|
import '../../dart/language_version.dart';
|
||||||
import '../../dart/package_map.dart';
|
import '../../dart/package_map.dart';
|
||||||
import '../../globals_null_migrated.dart' as globals;
|
import '../../globals_null_migrated.dart' as globals;
|
||||||
@ -198,6 +199,16 @@ class Dart2JSTarget extends Target {
|
|||||||
'dart2js.d',
|
'dart2js.d',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
String _collectOutput(ProcessResult result) {
|
||||||
|
final String stdout = result.stdout is List<int>
|
||||||
|
? utf8.decode(result.stdout as List<int>)
|
||||||
|
: result.stdout as String;
|
||||||
|
final String stderr = result.stderr is List<int>
|
||||||
|
? utf8.decode(result.stderr as List<int>)
|
||||||
|
: result.stderr as String;
|
||||||
|
return stdout + stderr;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> build(Environment environment) async {
|
Future<void> build(Environment environment) async {
|
||||||
final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]);
|
final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]);
|
||||||
@ -233,7 +244,7 @@ class Dart2JSTarget extends Target {
|
|||||||
environment.buildDir.childFile('main.dart').path, // dartfile
|
environment.buildDir.childFile('main.dart').path, // dartfile
|
||||||
]);
|
]);
|
||||||
if (kernelResult.exitCode != 0) {
|
if (kernelResult.exitCode != 0) {
|
||||||
throw Exception(kernelResult.stdout + kernelResult.stderr);
|
throw Exception(_collectOutput(kernelResult));
|
||||||
}
|
}
|
||||||
|
|
||||||
final String dart2jsOptimization = environment.defines[kDart2jsOptimization];
|
final String dart2jsOptimization = environment.defines[kDart2jsOptimization];
|
||||||
@ -250,7 +261,7 @@ class Dart2JSTarget extends Target {
|
|||||||
environment.buildDir.childFile('app.dill').path, // dartfile
|
environment.buildDir.childFile('app.dill').path, // dartfile
|
||||||
]);
|
]);
|
||||||
if (javaScriptResult.exitCode != 0) {
|
if (javaScriptResult.exitCode != 0) {
|
||||||
throw Exception(javaScriptResult.stdout + javaScriptResult.stderr);
|
throw Exception(_collectOutput(javaScriptResult));
|
||||||
}
|
}
|
||||||
final File dart2jsDeps = environment.buildDir
|
final File dart2jsDeps = environment.buildDir
|
||||||
.childFile('app.dill.deps');
|
.childFile('app.dill.deps');
|
||||||
|
@ -150,7 +150,7 @@ class AnalysisServer {
|
|||||||
void _handleStatus(Map<String, dynamic> statusInfo) {
|
void _handleStatus(Map<String, dynamic> statusInfo) {
|
||||||
// {"event":"server.status","params":{"analysis":{"isAnalyzing":true}}}
|
// {"event":"server.status","params":{"analysis":{"isAnalyzing":true}}}
|
||||||
if (statusInfo['analysis'] != null && !_analyzingController.isClosed) {
|
if (statusInfo['analysis'] != null && !_analyzingController.isClosed) {
|
||||||
final bool isAnalyzing = statusInfo['analysis']['isAnalyzing'] as bool;
|
final bool isAnalyzing = (statusInfo['analysis'] as Map<String, dynamic>)['isAnalyzing'] as bool;
|
||||||
_analyzingController.add(isAnalyzing);
|
_analyzingController.add(isAnalyzing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -293,15 +293,16 @@ class WrittenError {
|
|||||||
/// "hasFix":false
|
/// "hasFix":false
|
||||||
/// }
|
/// }
|
||||||
static WrittenError fromJson(Map<String, dynamic> json) {
|
static WrittenError fromJson(Map<String, dynamic> json) {
|
||||||
|
final Map<String, dynamic> location = json['location'] as Map<String, dynamic>;
|
||||||
return WrittenError._(
|
return WrittenError._(
|
||||||
severity: json['severity'] as String,
|
severity: json['severity'] as String,
|
||||||
type: json['type'] as String,
|
type: json['type'] as String,
|
||||||
message: json['message'] as String,
|
message: json['message'] as String,
|
||||||
code: json['code'] as String,
|
code: json['code'] as String,
|
||||||
file: json['location']['file'] as String,
|
file: location['file'] as String,
|
||||||
startLine: json['location']['startLine'] as int,
|
startLine: location['startLine'] as int,
|
||||||
startColumn: json['location']['startColumn'] as int,
|
startColumn: location['startColumn'] as int,
|
||||||
offset: json['location']['offset'] as int,
|
offset: location['offset'] as int,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,10 +496,10 @@ class _DefaultPub implements Pub {
|
|||||||
|
|
||||||
// Because [loadPackageConfigWithLogging] succeeded [packageConfigFile]
|
// Because [loadPackageConfigWithLogging] succeeded [packageConfigFile]
|
||||||
// we can rely on the file to exist and be correctly formatted.
|
// we can rely on the file to exist and be correctly formatted.
|
||||||
final dynamic jsonContents =
|
final Map<String, dynamic> jsonContents =
|
||||||
json.decode(packageConfigFile.readAsStringSync());
|
json.decode(packageConfigFile.readAsStringSync()) as Map<String, dynamic>;
|
||||||
|
|
||||||
jsonContents['packages'].add(<String, dynamic>{
|
(jsonContents['packages'] as List<dynamic>).add(<String, dynamic>{
|
||||||
'name': 'flutter_gen',
|
'name': 'flutter_gen',
|
||||||
'rootUri': 'flutter_gen',
|
'rootUri': 'flutter_gen',
|
||||||
'languageVersion': '2.12',
|
'languageVersion': '2.12',
|
||||||
|
@ -247,7 +247,7 @@ class FlutterManifest {
|
|||||||
DeferredComponent(
|
DeferredComponent(
|
||||||
name: component['name'] as String,
|
name: component['name'] as String,
|
||||||
libraries: component['libraries'] == null ?
|
libraries: component['libraries'] == null ?
|
||||||
<String>[] : component['libraries'].cast<String>() as List<String>,
|
<String>[] : (component['libraries'] as List<dynamic>).cast<String>(),
|
||||||
assets: assetsUri,
|
assets: assetsUri,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -571,6 +571,7 @@ void _validateFlutter(YamlMap? yaml, List<String> errors) {
|
|||||||
void _validateListType<T>(YamlList yamlList, List<String> errors, String context, String typeAlias) {
|
void _validateListType<T>(YamlList yamlList, List<String> errors, String context, String typeAlias) {
|
||||||
for (int i = 0; i < yamlList.length; i++) {
|
for (int i = 0; i < yamlList.length; i++) {
|
||||||
if (yamlList[i] is! T) {
|
if (yamlList[i] is! T) {
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
errors.add('Expected $context to be a list of $typeAlias, but element $i was a ${yamlList[i].runtimeType}');
|
errors.add('Expected $context to be a list of $typeAlias, but element $i was a ${yamlList[i].runtimeType}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -584,6 +585,7 @@ void _validateDeferredComponents(MapEntry<Object?, Object?> kvp, List<String> er
|
|||||||
for (int i = 0; i < yamlList.length; i++) {
|
for (int i = 0; i < yamlList.length; i++) {
|
||||||
final Object? valueMap = yamlList[i];
|
final Object? valueMap = yamlList[i];
|
||||||
if (valueMap is! YamlMap) {
|
if (valueMap is! YamlMap) {
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
errors.add('Expected the $i element in "${kvp.key}" to be a map, but got ${yamlList[i]} (${yamlList[i].runtimeType}).');
|
errors.add('Expected the $i element in "${kvp.key}" to be a map, but got ${yamlList[i]} (${yamlList[i].runtimeType}).');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ class SimControl {
|
|||||||
return <String, Map<String, dynamic>>{};
|
return <String, Map<String, dynamic>>{};
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final Object decodeResult = json.decode(results.stdout)[section.name];
|
final Object decodeResult = (json.decode(results.stdout) as Map<String, dynamic>)[section.name];
|
||||||
if (decodeResult is Map<String, dynamic>) {
|
if (decodeResult is Map<String, dynamic>) {
|
||||||
return decodeResult;
|
return decodeResult;
|
||||||
}
|
}
|
||||||
|
@ -269,55 +269,52 @@ class XCDevice {
|
|||||||
|
|
||||||
final List<IOSDevice> devices = <IOSDevice>[];
|
final List<IOSDevice> devices = <IOSDevice>[];
|
||||||
for (final dynamic device in allAvailableDevices) {
|
for (final dynamic device in allAvailableDevices) {
|
||||||
if (device is! Map) {
|
if (device is Map<String, dynamic>) {
|
||||||
continue;
|
// Only include iPhone, iPad, iPod, or other iOS devices.
|
||||||
}
|
if (!_isIPhoneOSDevice(device)) {
|
||||||
final Map<String, dynamic> deviceProperties = device as Map<String, dynamic>;
|
|
||||||
|
|
||||||
// Only include iPhone, iPad, iPod, or other iOS devices.
|
|
||||||
if (!_isIPhoneOSDevice(deviceProperties)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Map<String, dynamic> errorProperties = _errorProperties(deviceProperties);
|
|
||||||
if (errorProperties != null) {
|
|
||||||
final String errorMessage = _parseErrorMessage(errorProperties);
|
|
||||||
if (errorMessage.contains('not paired')) {
|
|
||||||
UsageEvent('device', 'ios-trust-failure', flutterUsage: globals.flutterUsage).send();
|
|
||||||
}
|
|
||||||
_logger.printTrace(errorMessage);
|
|
||||||
|
|
||||||
final int code = _errorCode(errorProperties);
|
|
||||||
|
|
||||||
// Temporary error -10: iPhone is busy: Preparing debugger support for iPhone.
|
|
||||||
// Sometimes the app launch will fail on these devices until Xcode is done setting up the device.
|
|
||||||
// Other times this is a false positive and the app will successfully launch despite the error.
|
|
||||||
if (code != -10) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final Map<String, dynamic> errorProperties = _errorProperties(device);
|
||||||
|
if (errorProperties != null) {
|
||||||
|
final String errorMessage = _parseErrorMessage(errorProperties);
|
||||||
|
if (errorMessage.contains('not paired')) {
|
||||||
|
UsageEvent('device', 'ios-trust-failure', flutterUsage: globals.flutterUsage).send();
|
||||||
|
}
|
||||||
|
_logger.printTrace(errorMessage);
|
||||||
|
|
||||||
|
final int code = _errorCode(errorProperties);
|
||||||
|
|
||||||
|
// Temporary error -10: iPhone is busy: Preparing debugger support for iPhone.
|
||||||
|
// Sometimes the app launch will fail on these devices until Xcode is done setting up the device.
|
||||||
|
// Other times this is a false positive and the app will successfully launch despite the error.
|
||||||
|
if (code != -10) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final IOSDeviceInterface interface = _interfaceType(device);
|
||||||
|
|
||||||
|
// Only support USB devices, skip "network" interface (Xcode > Window > Devices and Simulators > Connect via network).
|
||||||
|
// TODO(jmagman): Remove this check once wirelessly detected devices can be observed and attached, https://github.com/flutter/flutter/issues/15072.
|
||||||
|
if (interface != IOSDeviceInterface.usb) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
devices.add(IOSDevice(
|
||||||
|
device['identifier'] as String,
|
||||||
|
name: device['name'] as String,
|
||||||
|
cpuArchitecture: _cpuArchitecture(device),
|
||||||
|
interfaceType: interface,
|
||||||
|
sdkVersion: _sdkVersion(device),
|
||||||
|
iProxy: _iProxy,
|
||||||
|
fileSystem: globals.fs,
|
||||||
|
logger: _logger,
|
||||||
|
iosDeploy: _iosDeploy,
|
||||||
|
iMobileDevice: _iMobileDevice,
|
||||||
|
platform: globals.platform,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
final IOSDeviceInterface interface = _interfaceType(deviceProperties);
|
|
||||||
|
|
||||||
// Only support USB devices, skip "network" interface (Xcode > Window > Devices and Simulators > Connect via network).
|
|
||||||
// TODO(jmagman): Remove this check once wirelessly detected devices can be observed and attached, https://github.com/flutter/flutter/issues/15072.
|
|
||||||
if (interface != IOSDeviceInterface.usb) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
devices.add(IOSDevice(
|
|
||||||
device['identifier'] as String,
|
|
||||||
name: device['name'] as String,
|
|
||||||
cpuArchitecture: _cpuArchitecture(deviceProperties),
|
|
||||||
interfaceType: interface,
|
|
||||||
sdkVersion: _sdkVersion(deviceProperties),
|
|
||||||
iProxy: _iProxy,
|
|
||||||
fileSystem: globals.fs,
|
|
||||||
logger: _logger,
|
|
||||||
iosDeploy: _iosDeploy,
|
|
||||||
iMobileDevice: _iMobileDevice,
|
|
||||||
platform: globals.platform,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
|
@ -89,13 +89,12 @@ class Plugin {
|
|||||||
factory Plugin._fromMultiPlatformYaml(
|
factory Plugin._fromMultiPlatformYaml(
|
||||||
String name,
|
String name,
|
||||||
String path,
|
String path,
|
||||||
dynamic pluginYaml,
|
YamlMap pluginYaml,
|
||||||
List<String> dependencies,
|
List<String> dependencies,
|
||||||
FileSystem fileSystem,
|
FileSystem fileSystem,
|
||||||
bool isDirectDependency,
|
bool isDirectDependency,
|
||||||
) {
|
) {
|
||||||
assert (pluginYaml != null && pluginYaml['platforms'] != null,
|
assert (pluginYaml['platforms'] != null, 'Invalid multi-platform plugin specification $name.');
|
||||||
'Invalid multi-platform plugin specification $name.');
|
|
||||||
final YamlMap platformsYaml = pluginYaml['platforms'] as YamlMap;
|
final YamlMap platformsYaml = pluginYaml['platforms'] as YamlMap;
|
||||||
|
|
||||||
assert (_validateMultiPlatformYaml(platformsYaml).isEmpty,
|
assert (_validateMultiPlatformYaml(platformsYaml).isEmpty,
|
||||||
@ -190,7 +189,7 @@ class Plugin {
|
|||||||
bool isDirectDependency,
|
bool isDirectDependency,
|
||||||
) {
|
) {
|
||||||
final Map<String, PluginPlatform> platforms = <String, PluginPlatform>{};
|
final Map<String, PluginPlatform> platforms = <String, PluginPlatform>{};
|
||||||
final String pluginClass = pluginYaml['pluginClass'] as String;
|
final String pluginClass = (pluginYaml as Map<dynamic, dynamic>)['pluginClass'] as String;
|
||||||
if (pluginYaml != null && pluginClass != null) {
|
if (pluginYaml != null && pluginClass != null) {
|
||||||
final String androidPackage = pluginYaml['androidPackage'] as String;
|
final String androidPackage = pluginYaml['androidPackage'] as String;
|
||||||
if (androidPackage != null) {
|
if (androidPackage != null) {
|
||||||
|
@ -177,8 +177,8 @@ class _BufferedStreamController<T> {
|
|||||||
_streamControllerInstance.add(event);
|
_streamControllerInstance.add(event);
|
||||||
} else {
|
} else {
|
||||||
_streamControllerInstance.addError(
|
_streamControllerInstance.addError(
|
||||||
event.first as Object,
|
(event as Iterable<dynamic>).first as Object,
|
||||||
event.last as StackTrace,
|
(event as Iterable<dynamic>).last as StackTrace,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1118,8 +1118,9 @@ Future<OperationResult> _defaultReloadSourcesHelper(
|
|||||||
// refactored, we'll probably need to send one hot reload/restart event
|
// refactored, we'll probably need to send one hot reload/restart event
|
||||||
// per device to analytics.
|
// per device to analytics.
|
||||||
firstReloadDetails.addAll(castStringKeyedMap(reloadReport.json['details']));
|
firstReloadDetails.addAll(castStringKeyedMap(reloadReport.json['details']));
|
||||||
final int loadedLibraryCount = reloadReport.json['details']['loadedLibraryCount'] as int;
|
final Map<String, dynamic> details = reloadReport.json['details'] as Map<String, dynamic>;
|
||||||
final int finalLibraryCount = reloadReport.json['details']['finalLibraryCount'] as int;
|
final int loadedLibraryCount = details['loadedLibraryCount'] as int;
|
||||||
|
final int finalLibraryCount = details['finalLibraryCount'] as int;
|
||||||
globals.printTrace('reloaded $loadedLibraryCount of $finalLibraryCount libraries');
|
globals.printTrace('reloaded $loadedLibraryCount of $finalLibraryCount libraries');
|
||||||
// reloadMessage = 'Reloaded $loadedLibraryCount of $finalLibraryCount libraries';
|
// reloadMessage = 'Reloaded $loadedLibraryCount of $finalLibraryCount libraries';
|
||||||
// Record time it took for the VM to reload the sources.
|
// Record time it took for the VM to reload the sources.
|
||||||
|
@ -737,21 +737,24 @@ class BrowserManager {
|
|||||||
|
|
||||||
/// The callback for handling messages received from the host page.
|
/// The callback for handling messages received from the host page.
|
||||||
void _onMessage(dynamic message) {
|
void _onMessage(dynamic message) {
|
||||||
switch (message['command'] as String) {
|
assert(message is Map<String, dynamic>);
|
||||||
case 'ping':
|
if (message is Map<String, dynamic>) {
|
||||||
break;
|
switch (message['command'] as String) {
|
||||||
case 'restart':
|
case 'ping':
|
||||||
_onRestartController.add(null);
|
break;
|
||||||
break;
|
case 'restart':
|
||||||
case 'resume':
|
_onRestartController.add(null);
|
||||||
if (_pauseCompleter != null) {
|
break;
|
||||||
_pauseCompleter.complete();
|
case 'resume':
|
||||||
}
|
if (_pauseCompleter != null) {
|
||||||
break;
|
_pauseCompleter.complete();
|
||||||
default:
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
// Unreachable.
|
// Unreachable.
|
||||||
assert(false);
|
assert(false);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ class VisualStudio {
|
|||||||
if (_bestVisualStudioDetails[_catalogKey] == null) {
|
if (_bestVisualStudioDetails[_catalogKey] == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return _bestVisualStudioDetails[_catalogKey][_catalogDisplayVersionKey] as String?;
|
return (_bestVisualStudioDetails[_catalogKey] as Map<String, dynamic>)[_catalogDisplayVersionKey] as String?;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The directory where Visual Studio is installed.
|
/// The directory where Visual Studio is installed.
|
||||||
|
@ -52,13 +52,14 @@ void main() {
|
|||||||
|
|
||||||
expect(testLogger.statusText, isNotEmpty);
|
expect(testLogger.statusText, isNotEmpty);
|
||||||
final dynamic jsonObject = json.decode(testLogger.statusText);
|
final dynamic jsonObject = json.decode(testLogger.statusText);
|
||||||
expect(jsonObject, isMap);
|
expect(jsonObject, const TypeMatcher<Map<String, dynamic>>());
|
||||||
|
if (jsonObject is Map<String, dynamic>) {
|
||||||
|
expect(jsonObject.containsKey('android-studio-dir'), true);
|
||||||
|
expect(jsonObject['android-studio-dir'], isNotNull);
|
||||||
|
|
||||||
expect(jsonObject.containsKey('android-studio-dir'), true);
|
expect(jsonObject.containsKey('android-sdk'), true);
|
||||||
expect(jsonObject['android-studio-dir'], isNotNull);
|
expect(jsonObject['android-sdk'], isNotNull);
|
||||||
|
}
|
||||||
expect(jsonObject.containsKey('android-sdk'), true);
|
|
||||||
expect(jsonObject['android-sdk'], isNotNull);
|
|
||||||
verifyNoAnalytics();
|
verifyNoAnalytics();
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
AndroidStudio: () => fakeAndroidStudio,
|
AndroidStudio: () => fakeAndroidStudio,
|
||||||
|
@ -93,7 +93,7 @@ void main() {
|
|||||||
|
|
||||||
expect(response['id'], 0);
|
expect(response['id'], 0);
|
||||||
expect(response['result'], isNotEmpty);
|
expect(response['result'], isNotEmpty);
|
||||||
expect(response['result']['platforms'], <String>{'macos'});
|
expect((response['result'] as Map<String, dynamic>)['platforms'], <String>{'macos'});
|
||||||
await responses.close();
|
await responses.close();
|
||||||
await commands.close();
|
await commands.close();
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
@ -111,7 +111,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
globals.printError('daemon.logMessage test');
|
globals.printError('daemon.logMessage test');
|
||||||
final Map<String, dynamic> response = await responses.stream.firstWhere((Map<String, dynamic> map) {
|
final Map<String, dynamic> response = await responses.stream.firstWhere((Map<String, dynamic> map) {
|
||||||
return map['event'] == 'daemon.logMessage' && map['params']['level'] == 'error';
|
return map['event'] == 'daemon.logMessage' && (map['params'] as Map<String, dynamic>)['level'] == 'error';
|
||||||
});
|
});
|
||||||
expect(response['id'], isNull);
|
expect(response['id'], isNull);
|
||||||
expect(response['event'], 'daemon.logMessage');
|
expect(response['event'], 'daemon.logMessage');
|
||||||
@ -347,7 +347,7 @@ void main() {
|
|||||||
unawaited(output.stream
|
unawaited(output.stream
|
||||||
.firstWhere((Map<String, dynamic> request) => request['method'] == 'app.exposeUrl')
|
.firstWhere((Map<String, dynamic> request) => request['method'] == 'app.exposeUrl')
|
||||||
.then((Map<String, dynamic> request) {
|
.then((Map<String, dynamic> request) {
|
||||||
expect(request['params']['url'], equals(originalUrl));
|
expect((request['params'] as Map<String, dynamic>)['url'], equals(originalUrl));
|
||||||
input.add(<String, dynamic>{'id': request['id'], 'result': <String, dynamic>{'url': mappedUrl}});
|
input.add(<String, dynamic>{'id': request['id'], 'result': <String, dynamic>{'url': mappedUrl}});
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -370,9 +370,10 @@ void main() {
|
|||||||
|
|
||||||
commands.add(<String, dynamic>{'id': 0, 'method': 'devtools.serve'});
|
commands.add(<String, dynamic>{'id': 0, 'method': 'devtools.serve'});
|
||||||
final Map<String, dynamic> response = await responses.stream.firstWhere((Map<String, dynamic> response) => response['id'] == 0);
|
final Map<String, dynamic> response = await responses.stream.firstWhere((Map<String, dynamic> response) => response['id'] == 0);
|
||||||
expect(response['result'], isNotEmpty);
|
final Map<String, dynamic> result = response['result'] as Map<String, dynamic>;
|
||||||
expect(response['result']['host'], '127.0.0.1');
|
expect(result, isNotEmpty);
|
||||||
expect(response['result']['port'], 1234);
|
expect(result['host'], '127.0.0.1');
|
||||||
|
expect(result['port'], 1234);
|
||||||
await responses.close();
|
await responses.close();
|
||||||
await commands.close();
|
await commands.close();
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
@ -390,9 +391,10 @@ void main() {
|
|||||||
|
|
||||||
commands.add(<String, dynamic>{'id': 0, 'method': 'devtools.serve'});
|
commands.add(<String, dynamic>{'id': 0, 'method': 'devtools.serve'});
|
||||||
final Map<String, dynamic> response = await responses.stream.firstWhere((Map<String, dynamic> response) => response['id'] == 0);
|
final Map<String, dynamic> response = await responses.stream.firstWhere((Map<String, dynamic> response) => response['id'] == 0);
|
||||||
expect(response['result'], isNotEmpty);
|
final Map<String, dynamic> result = response['result'] as Map<String, dynamic>;
|
||||||
expect(response['result']['host'], null);
|
expect(result, isNotEmpty);
|
||||||
expect(response['result']['port'], null);
|
expect(result['host'], null);
|
||||||
|
expect(result['port'], null);
|
||||||
await responses.close();
|
await responses.close();
|
||||||
await commands.close();
|
await commands.close();
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
|
@ -28,6 +28,7 @@ import 'package:process/process.dart';
|
|||||||
import 'package:pub_semver/pub_semver.dart';
|
import 'package:pub_semver/pub_semver.dart';
|
||||||
import 'package:pubspec_parse/pubspec_parse.dart';
|
import 'package:pubspec_parse/pubspec_parse.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
import 'package:yaml/yaml.dart';
|
||||||
|
|
||||||
import '../../src/common.dart';
|
import '../../src/common.dart';
|
||||||
import '../../src/context.dart';
|
import '../../src/context.dart';
|
||||||
@ -482,8 +483,9 @@ void main() {
|
|||||||
// Expect the dependency on flutter_web_plugins exists
|
// Expect the dependency on flutter_web_plugins exists
|
||||||
expect(pubspec.dependencies, contains('flutter_web_plugins'));
|
expect(pubspec.dependencies, contains('flutter_web_plugins'));
|
||||||
// The platform is correctly registered
|
// The platform is correctly registered
|
||||||
expect(pubspec.flutter['plugin']['platforms']['web']['pluginClass'], 'FlutterProjectWeb');
|
final YamlMap web = ((pubspec.flutter['plugin'] as YamlMap)['platforms'] as YamlMap)['web'] as YamlMap;
|
||||||
expect(pubspec.flutter['plugin']['platforms']['web']['fileName'], 'flutter_project_web.dart');
|
expect(web['pluginClass'], 'FlutterProjectWeb');
|
||||||
|
expect(web['fileName'], 'flutter_project_web.dart');
|
||||||
expect(logger.errorText, isNot(contains(_kNoPlatformsMessage)));
|
expect(logger.errorText, isNot(contains(_kNoPlatformsMessage)));
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
|
FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
|
||||||
|
@ -90,47 +90,54 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
expect(result['type'], 'apk');
|
expect(result['type'], 'apk');
|
||||||
|
final List<dynamic> resultChildren = result['children'] as List<dynamic>;
|
||||||
final Map<String, dynamic> androidManifestMap = result['children'][0] as Map<String, dynamic>;
|
final Map<String, dynamic> androidManifestMap = resultChildren[0] as Map<String, dynamic>;
|
||||||
expect(androidManifestMap['n'], 'AndroidManifest.xml');
|
expect(androidManifestMap['n'], 'AndroidManifest.xml');
|
||||||
expect(androidManifestMap['value'], 6);
|
expect(androidManifestMap['value'], 6);
|
||||||
|
|
||||||
final Map<String, dynamic> metaInfMap = result['children'][1] as Map<String, dynamic>;
|
final Map<String, Object?> metaInfMap = resultChildren[1] as Map<String, Object?>;
|
||||||
|
final List<Map<String, Object?>> metaInfMapChildren = metaInfMap['children']! as List<Map<String, Object?>>;
|
||||||
expect(metaInfMap['n'], 'META-INF');
|
expect(metaInfMap['n'], 'META-INF');
|
||||||
expect(metaInfMap['value'], 10);
|
expect(metaInfMap['value'], 10);
|
||||||
final Map<String, dynamic> certRsaMap = metaInfMap['children'][0] as Map<String, dynamic>;
|
final Map<String, dynamic> certRsaMap = metaInfMapChildren[0];
|
||||||
expect(certRsaMap['n'], 'CERT.RSA');
|
expect(certRsaMap['n'], 'CERT.RSA');
|
||||||
expect(certRsaMap['value'], 5);
|
expect(certRsaMap['value'], 5);
|
||||||
final Map<String, dynamic> certSfMap = metaInfMap['children'][1] as Map<String, dynamic>;
|
final Map<String, dynamic> certSfMap = metaInfMapChildren[1];
|
||||||
expect(certSfMap['n'], 'CERT.SF');
|
expect(certSfMap['n'], 'CERT.SF');
|
||||||
expect(certSfMap['value'], 5);
|
expect(certSfMap['value'], 5);
|
||||||
|
|
||||||
final Map<String, dynamic> libMap = result['children'][2] as Map<String, dynamic>;
|
final Map<String, Object?> libMap = resultChildren[2] as Map<String, Object?>;
|
||||||
|
final List<Map<String, Object?>> libMapChildren = libMap['children']! as List<Map<String, Object?>>;
|
||||||
expect(libMap['n'], 'lib');
|
expect(libMap['n'], 'lib');
|
||||||
expect(libMap['value'], 12);
|
expect(libMap['value'], 12);
|
||||||
final Map<String, dynamic> arm64Map = libMap['children'][0] as Map<String, dynamic>;
|
final Map<String, Object?> arm64Map = libMapChildren[0];
|
||||||
|
final List<Map<String, Object?>> arn64MapChildren = arm64Map['children']! as List<Map<String, Object?>>;
|
||||||
expect(arm64Map['n'], 'arm64-v8a');
|
expect(arm64Map['n'], 'arm64-v8a');
|
||||||
expect(arm64Map['value'], 12);
|
expect(arm64Map['value'], 12);
|
||||||
final Map<String, dynamic> libAppMap = arm64Map['children'][0] as Map<String, dynamic>;
|
final Map<String, Object?> libAppMap = arn64MapChildren[0];
|
||||||
|
final List<dynamic> libAppMapChildren = libAppMap['children']! as List<dynamic>;
|
||||||
expect(libAppMap['n'], 'libxyzzyapp.so (Dart AOT)');
|
expect(libAppMap['n'], 'libxyzzyapp.so (Dart AOT)');
|
||||||
expect(libAppMap['value'], 6);
|
expect(libAppMap['value'], 6);
|
||||||
expect(libAppMap['children'].length, 3);
|
expect(libAppMapChildren.length, 3);
|
||||||
final Map<String, dynamic> internalMap = libAppMap['children'][0] as Map<String, dynamic>;
|
final Map<String, Object?> internalMap = libAppMapChildren[0] as Map<String, Object?>;
|
||||||
final Map<String, dynamic> skipMap = internalMap['children'][0] as Map<String, dynamic>;
|
final List<dynamic> internalMapChildren = internalMap['children']! as List<dynamic>;
|
||||||
|
final Map<String, Object?> skipMap = internalMapChildren[0] as Map<String, Object?>;
|
||||||
expect(skipMap['n'], 'skip');
|
expect(skipMap['n'], 'skip');
|
||||||
expect(skipMap['value'], 2400);
|
expect(skipMap['value'], 2400);
|
||||||
final Map<String, dynamic> subListIterableMap = internalMap['children'][1] as Map<String, dynamic>;
|
final Map<String, Object?> subListIterableMap = internalMapChildren[1] as Map<String, Object?>;
|
||||||
expect(subListIterableMap['n'], 'new SubListIterable.');
|
expect(subListIterableMap['n'], 'new SubListIterable.');
|
||||||
expect(subListIterableMap['value'], 3560);
|
expect(subListIterableMap['value'], 3560);
|
||||||
final Map<String, dynamic> coreMap = libAppMap['children'][1] as Map<String, dynamic>;
|
final Map<String, Object?> coreMap = libAppMapChildren[1] as Map<String, Object?>;
|
||||||
final Map<String, dynamic> rangeErrorMap = coreMap['children'][0] as Map<String, dynamic>;
|
final List<dynamic> coreMapChildren = coreMap['children']! as List<dynamic>;
|
||||||
|
final Map<String, Object?> rangeErrorMap = coreMapChildren[0] as Map<String, Object?>;
|
||||||
expect(rangeErrorMap['n'], 'new RangeError.range');
|
expect(rangeErrorMap['n'], 'new RangeError.range');
|
||||||
expect(rangeErrorMap['value'], 3920);
|
expect(rangeErrorMap['value'], 3920);
|
||||||
final Map<String, dynamic> stubsMap = libAppMap['children'][2] as Map<String, dynamic>;
|
final Map<String, Object?> stubsMap = libAppMapChildren[2] as Map<String, Object?>;
|
||||||
final Map<String, dynamic> allocateMap = stubsMap['children'][0] as Map<String, dynamic>;
|
final List<dynamic> stubsMapChildren = stubsMap['children']! as List<dynamic>;
|
||||||
|
final Map<String, Object?> allocateMap = stubsMapChildren[0] as Map<String, Object?>;
|
||||||
expect(allocateMap['n'], 'Allocate ArgumentError');
|
expect(allocateMap['n'], 'Allocate ArgumentError');
|
||||||
expect(allocateMap['value'], 4650);
|
expect(allocateMap['value'], 4650);
|
||||||
final Map<String, dynamic> libFlutterMap = arm64Map['children'][1] as Map<String, dynamic>;
|
final Map<String, Object?> libFlutterMap = arn64MapChildren[1];
|
||||||
expect(libFlutterMap['n'], 'libflutter.so (Flutter Engine)');
|
expect(libFlutterMap['n'], 'libflutter.so (Flutter Engine)');
|
||||||
expect(libFlutterMap['value'], 6);
|
expect(libFlutterMap['value'], 6);
|
||||||
|
|
||||||
|
@ -104,9 +104,10 @@ void main() {
|
|||||||
final Fingerprint fingerprint = Fingerprint.fromBuildInputs(const <String>['a.dart', 'b.dart'], fileSystem);
|
final Fingerprint fingerprint = Fingerprint.fromBuildInputs(const <String>['a.dart', 'b.dart'], fileSystem);
|
||||||
|
|
||||||
final Map<String, dynamic>? jsonObject = castStringKeyedMap(json.decode(fingerprint.toJson()));
|
final Map<String, dynamic>? jsonObject = castStringKeyedMap(json.decode(fingerprint.toJson()));
|
||||||
expect(jsonObject!['files'], hasLength(2));
|
final Map<String, dynamic> files = jsonObject!['files'] as Map<String, dynamic>;
|
||||||
expect(jsonObject['files']['a.dart'], '8a21a15fad560b799f6731d436c1b698');
|
expect(files, hasLength(2));
|
||||||
expect(jsonObject['files']['b.dart'], '6f144e08b58cd0925328610fad7ac07c');
|
expect(files['a.dart'], '8a21a15fad560b799f6731d436c1b698');
|
||||||
|
expect(files['b.dart'], '6f144e08b58cd0925328610fad7ac07c');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -124,10 +125,11 @@ void main() {
|
|||||||
});
|
});
|
||||||
final Fingerprint fingerprint = Fingerprint.fromJson(jsonString);
|
final Fingerprint fingerprint = Fingerprint.fromJson(jsonString);
|
||||||
final Map<String, dynamic>? content = castStringKeyedMap(json.decode(fingerprint.toJson()));
|
final Map<String, dynamic>? content = castStringKeyedMap(json.decode(fingerprint.toJson()));
|
||||||
|
final Map<String, dynamic> files = content!['files'] as Map<String, dynamic>;
|
||||||
expect(content, hasLength(1));
|
expect(content, hasLength(1));
|
||||||
expect(content!['files'], hasLength(2));
|
expect(files, hasLength(2));
|
||||||
expect(content['files']['a.dart'], '8a21a15fad560b799f6731d436c1b698');
|
expect(files['a.dart'], '8a21a15fad560b799f6731d436c1b698');
|
||||||
expect(content['files']['b.dart'], '6f144e08b58cd0925328610fad7ac07c');
|
expect(files['b.dart'], '6f144e08b58cd0925328610fad7ac07c');
|
||||||
});
|
});
|
||||||
testWithoutContext('treats missing properties and files entries as if empty', () {
|
testWithoutContext('treats missing properties and files entries as if empty', () {
|
||||||
final String jsonString = json.encode(<String, dynamic>{});
|
final String jsonString = json.encode(<String, dynamic>{});
|
||||||
|
@ -284,7 +284,7 @@ void main() {
|
|||||||
version: 1.0.0+3
|
version: 1.0.0+3
|
||||||
''', logger: BufferLogger.test());
|
''', logger: BufferLogger.test());
|
||||||
final FlutterProject project = FlutterProject(fileSystem.systemTempDirectory,manifest,manifest);
|
final FlutterProject project = FlutterProject(fileSystem.systemTempDirectory,manifest,manifest);
|
||||||
final dynamic versionInfo = jsonDecode(project.getVersionInfo());
|
final Map<String, dynamic> versionInfo = jsonDecode(project.getVersionInfo()) as Map<String, dynamic>;
|
||||||
expect(versionInfo['app_name'],'test');
|
expect(versionInfo['app_name'],'test');
|
||||||
expect(versionInfo['version'],'1.0.0');
|
expect(versionInfo['version'],'1.0.0');
|
||||||
expect(versionInfo['build_number'],'3');
|
expect(versionInfo['build_number'],'3');
|
||||||
|
@ -81,7 +81,7 @@ void main() {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
// contains all of the experiments in features.dart
|
// contains all of the experiments in features.dart
|
||||||
expect(result.stdout.split('\n'), containsAll(<Matcher>[
|
expect((result.stdout as String).split('\n'), containsAll(<Matcher>[
|
||||||
for (final Feature feature in allFeatures)
|
for (final Feature feature in allFeatures)
|
||||||
contains(feature.configSetting),
|
contains(feature.configSetting),
|
||||||
]));
|
]));
|
||||||
|
@ -35,8 +35,8 @@ void main() {
|
|||||||
.childDirectory('.dart_tool')
|
.childDirectory('.dart_tool')
|
||||||
.childFile('package_config.json')
|
.childFile('package_config.json')
|
||||||
.readAsStringSync());
|
.readAsStringSync());
|
||||||
final dynamic collection = jsonContent['packages']
|
final Map<String, dynamic> collection = ((jsonContent as Map<String, dynamic>)['packages'] as Iterable<dynamic>)
|
||||||
.firstWhere((dynamic e) => e['name'] == 'collection');
|
.firstWhere((dynamic entry) => (entry as Map<String, dynamic>)['name'] == 'collection') as Map<String, dynamic>;
|
||||||
expect(
|
expect(
|
||||||
Uri.parse(collection['rootUri'] as String).isAbsolute,
|
Uri.parse(collection['rootUri'] as String).isAbsolute,
|
||||||
isTrue,
|
isTrue,
|
||||||
|
@ -190,6 +190,6 @@ bool _isHotReloadCompletionEvent(Map<String, dynamic> event) {
|
|||||||
return event != null &&
|
return event != null &&
|
||||||
event['event'] == 'app.progress' &&
|
event['event'] == 'app.progress' &&
|
||||||
event['params'] != null &&
|
event['params'] != null &&
|
||||||
event['params']['progressId'] == 'hot.reload' &&
|
(event['params'] as Map<String, dynamic>)['progressId'] == 'hot.reload' &&
|
||||||
event['params']['finished'] == true;
|
(event['params'] as Map<String, dynamic>)['finished'] == true;
|
||||||
}
|
}
|
||||||
|
@ -387,11 +387,14 @@ abstract class FlutterTestDriver {
|
|||||||
await subscription.cancel();
|
await subscription.cancel();
|
||||||
final StringBuffer error = StringBuffer();
|
final StringBuffer error = StringBuffer();
|
||||||
error.write('Received app.stop event while waiting for $interestingOccurrence\n\n$_errorBuffer');
|
error.write('Received app.stop event while waiting for $interestingOccurrence\n\n$_errorBuffer');
|
||||||
if (json['params'] != null && json['params']['error'] != null) {
|
if (json['params'] != null) {
|
||||||
error.write('${json['params']['error']}\n\n');
|
final Map<String, dynamic> params = json['params'] as Map<String, dynamic>;
|
||||||
}
|
if (params['error'] != null) {
|
||||||
if (json['params'] != null && json['params']['trace'] != null) {
|
error.write('${params['error']}\n\n');
|
||||||
error.write('${json['params']['trace']}\n\n');
|
}
|
||||||
|
if (json['params'] != null && params['trace'] != null) {
|
||||||
|
error.write('${params['trace']}\n\n');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
response.completeError(Exception(error.toString()));
|
response.completeError(Exception(error.toString()));
|
||||||
}
|
}
|
||||||
@ -563,7 +566,7 @@ class FlutterRunTestDriver extends FlutterTestDriver {
|
|||||||
// _process.kill() (`flutter` is a shell script so _process itself is a
|
// _process.kill() (`flutter` is a shell script so _process itself is a
|
||||||
// shell, not the flutter tool's Dart process).
|
// shell, not the flutter tool's Dart process).
|
||||||
final Map<String, dynamic> connected = await _waitFor(event: 'daemon.connected');
|
final Map<String, dynamic> connected = await _waitFor(event: 'daemon.connected');
|
||||||
_processPid = connected['params']['pid'] as int;
|
_processPid = (connected['params'] as Map<String, dynamic>)['pid'] as int;
|
||||||
|
|
||||||
// Set this up now, but we don't wait it yet. We want to make sure we don't
|
// Set this up now, but we don't wait it yet. We want to make sure we don't
|
||||||
// miss it while waiting for debugPort below.
|
// miss it while waiting for debugPort below.
|
||||||
@ -571,7 +574,7 @@ class FlutterRunTestDriver extends FlutterTestDriver {
|
|||||||
|
|
||||||
if (withDebugger) {
|
if (withDebugger) {
|
||||||
final Map<String, dynamic> debugPort = await _waitFor(event: 'app.debugPort', timeout: appStartTimeout);
|
final Map<String, dynamic> debugPort = await _waitFor(event: 'app.debugPort', timeout: appStartTimeout);
|
||||||
final String wsUriString = debugPort['params']['wsUri'] as String;
|
final String wsUriString = (debugPort['params'] as Map<String, dynamic>)['wsUri'] as String;
|
||||||
_vmServiceWsUri = Uri.parse(wsUriString);
|
_vmServiceWsUri = Uri.parse(wsUriString);
|
||||||
await connectToVmService(pauseOnExceptions: pauseOnExceptions);
|
await connectToVmService(pauseOnExceptions: pauseOnExceptions);
|
||||||
if (!startPaused) {
|
if (!startPaused) {
|
||||||
@ -588,7 +591,7 @@ class FlutterRunTestDriver extends FlutterTestDriver {
|
|||||||
|
|
||||||
// Now await the started event; if it had already happened the future will
|
// Now await the started event; if it had already happened the future will
|
||||||
// have already completed.
|
// have already completed.
|
||||||
_currentRunningAppId = (await started)['params']['appId'] as String;
|
_currentRunningAppId = ((await started)['params'] as Map<String, dynamic>)['appId'] as String;
|
||||||
prematureExitGuard.complete();
|
prematureExitGuard.complete();
|
||||||
} on Exception catch (error, stackTrace) {
|
} on Exception catch (error, stackTrace) {
|
||||||
prematureExitGuard.completeError(Exception(error.toString()), stackTrace);
|
prematureExitGuard.completeError(Exception(error.toString()), stackTrace);
|
||||||
@ -618,10 +621,10 @@ class FlutterRunTestDriver extends FlutterTestDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_debugPrint('Performing ${ pause ? "paused " : "" }${ fullRestart ? "hot restart" : "hot reload" }...');
|
_debugPrint('Performing ${ pause ? "paused " : "" }${ fullRestart ? "hot restart" : "hot reload" }...');
|
||||||
final dynamic hotReloadResponse = await _sendRequest(
|
final Map<String, dynamic> hotReloadResponse = await _sendRequest(
|
||||||
'app.restart',
|
'app.restart',
|
||||||
<String, dynamic>{'appId': _currentRunningAppId, 'fullRestart': fullRestart, 'pause': pause, 'debounce': debounce, 'debounceDurationOverrideMs': debounceDurationOverrideMs},
|
<String, dynamic>{'appId': _currentRunningAppId, 'fullRestart': fullRestart, 'pause': pause, 'debounce': debounce, 'debounceDurationOverrideMs': debounceDurationOverrideMs},
|
||||||
);
|
) as Map<String, dynamic>;
|
||||||
_debugPrint('${fullRestart ? "Hot restart" : "Hot reload"} complete.');
|
_debugPrint('${fullRestart ? "Hot restart" : "Hot reload"} complete.');
|
||||||
|
|
||||||
if (hotReloadResponse == null || hotReloadResponse['code'] != 0) {
|
if (hotReloadResponse == null || hotReloadResponse['code'] != 0) {
|
||||||
@ -760,8 +763,9 @@ class FlutterTestTestDriver extends FlutterTestDriver {
|
|||||||
_processPid = version['pid'] as int;
|
_processPid = version['pid'] as int;
|
||||||
|
|
||||||
if (withDebugger) {
|
if (withDebugger) {
|
||||||
final Map<String, dynamic> startedProcess = await _waitFor(event: 'test.startedProcess', timeout: appStartTimeout);
|
final Map<String, dynamic> startedProcessParams =
|
||||||
final String vmServiceHttpString = startedProcess['params']['observatoryUri'] as String;
|
(await _waitFor(event: 'test.startedProcess', timeout: appStartTimeout))['params'] as Map<String, dynamic>;
|
||||||
|
final String vmServiceHttpString = startedProcessParams['observatoryUri'] as String;
|
||||||
_vmServiceWsUri = Uri.parse(vmServiceHttpString).replace(scheme: 'ws', path: '/ws');
|
_vmServiceWsUri = Uri.parse(vmServiceHttpString).replace(scheme: 'ws', path: '/ws');
|
||||||
await connectToVmService(pauseOnExceptions: pauseOnExceptions);
|
await connectToVmService(pauseOnExceptions: pauseOnExceptions);
|
||||||
// Allow us to run code before we start, eg. to set up breakpoints.
|
// Allow us to run code before we start, eg. to set up breakpoints.
|
||||||
@ -824,7 +828,7 @@ Stream<String> transformToLines(Stream<List<int>> byteStream) {
|
|||||||
Map<String, dynamic> parseFlutterResponse(String line) {
|
Map<String, dynamic> parseFlutterResponse(String line) {
|
||||||
if (line.startsWith('[') && line.endsWith(']') && line.length > 2) {
|
if (line.startsWith('[') && line.endsWith(']') && line.length > 2) {
|
||||||
try {
|
try {
|
||||||
final Map<String, dynamic> response = castStringKeyedMap(json.decode(line)[0]);
|
final Map<String, dynamic> response = castStringKeyedMap((json.decode(line) as List<dynamic>)[0]);
|
||||||
return response;
|
return response;
|
||||||
} on FormatException {
|
} on FormatException {
|
||||||
// Not valid JSON, so likely some other output that was surrounded by [brackets]
|
// Not valid JSON, so likely some other output that was surrounded by [brackets]
|
||||||
|
@ -19,18 +19,19 @@ void validatePubspecForPlugin({
|
|||||||
}) {
|
}) {
|
||||||
final FlutterManifest manifest =
|
final FlutterManifest manifest =
|
||||||
FlutterManifest.createFromPath('$projectDir/pubspec.yaml', fileSystem: globals.fs, logger: globals.logger)!;
|
FlutterManifest.createFromPath('$projectDir/pubspec.yaml', fileSystem: globals.fs, logger: globals.logger)!;
|
||||||
final YamlMap platformsMap = YamlMap.wrap(manifest.supportedPlatforms!);
|
final YamlMap platformMaps = YamlMap.wrap(manifest.supportedPlatforms!);
|
||||||
for (final String platform in expectedPlatforms) {
|
for (final String platform in expectedPlatforms) {
|
||||||
expect(platformsMap[platform], isNotNull);
|
expect(platformMaps[platform], isNotNull);
|
||||||
expect(platformsMap[platform]['pluginClass'], pluginClass);
|
final YamlMap platformMap = platformMaps[platform]! as YamlMap;
|
||||||
|
expect(platformMap['pluginClass'], pluginClass);
|
||||||
if (platform == 'android') {
|
if (platform == 'android') {
|
||||||
expect(platformsMap[platform]['package'], androidIdentifier);
|
expect(platformMap['package'], androidIdentifier);
|
||||||
}
|
}
|
||||||
if (platform == 'web') {
|
if (platform == 'web') {
|
||||||
expect(platformsMap[platform]['fileName'], webFileName);
|
expect(platformMap['fileName'], webFileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (final String platform in unexpectedPlatforms) {
|
for (final String platform in unexpectedPlatforms) {
|
||||||
expect(platformsMap[platform], isNull);
|
expect(platformMaps[platform], isNull);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ class Registrar extends BinaryMessenger {
|
|||||||
/// compiling for the web.
|
/// compiling for the web.
|
||||||
void registerMessageHandler() {
|
void registerMessageHandler() {
|
||||||
// The `ui.webOnlySetPluginHandler` function below is only defined in the Web dart:ui.
|
// The `ui.webOnlySetPluginHandler` function below is only defined in the Web dart:ui.
|
||||||
// ignore: undefined_function
|
// ignore: undefined_function, avoid_dynamic_calls
|
||||||
ui.webOnlySetPluginHandler(handleFrameworkMessage);
|
ui.webOnlySetPluginHandler(handleFrameworkMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,10 +9,13 @@ import 'package:flutter_driver/flutter_driver.dart';
|
|||||||
|
|
||||||
import 'common.dart';
|
import 'common.dart';
|
||||||
|
|
||||||
|
/// A callback to use with [integrationDriver].
|
||||||
|
typedef ScreenshotCallback = Future<bool> Function(String name, List<int> image);
|
||||||
|
|
||||||
/// Example Integration Test which can also run WebDriver command depending on
|
/// Example Integration Test which can also run WebDriver command depending on
|
||||||
/// the requests coming from the test methods.
|
/// the requests coming from the test methods.
|
||||||
Future<void> integrationDriver(
|
Future<void> integrationDriver(
|
||||||
{FlutterDriver? driver, Function? onScreenshot}) async {
|
{FlutterDriver? driver, ScreenshotCallback? onScreenshot}) async {
|
||||||
driver ??= await FlutterDriver.connect();
|
driver ??= await FlutterDriver.connect();
|
||||||
// Test states that it's waiting on web driver commands.
|
// Test states that it's waiting on web driver commands.
|
||||||
// [DriverTestMessage] is converted to string since json format causes an
|
// [DriverTestMessage] is converted to string since json format causes an
|
||||||
@ -28,11 +31,12 @@ Future<void> integrationDriver(
|
|||||||
response.data!['web_driver_command'] != '${WebDriverCommandType.noop}') {
|
response.data!['web_driver_command'] != '${WebDriverCommandType.noop}') {
|
||||||
final String? webDriverCommand = response.data!['web_driver_command'] as String?;
|
final String? webDriverCommand = response.data!['web_driver_command'] as String?;
|
||||||
if (webDriverCommand == '${WebDriverCommandType.screenshot}') {
|
if (webDriverCommand == '${WebDriverCommandType.screenshot}') {
|
||||||
|
assert(onScreenshot != null, 'screenshot command requires an onScreenshot callback');
|
||||||
// Use `driver.screenshot()` method to get a screenshot of the web page.
|
// Use `driver.screenshot()` method to get a screenshot of the web page.
|
||||||
final List<int> screenshotImage = await driver.screenshot();
|
final List<int> screenshotImage = await driver.screenshot();
|
||||||
final String? screenshotName = response.data!['screenshot_name'] as String?;
|
final String screenshotName = response.data!['screenshot_name']! as String;
|
||||||
|
|
||||||
final bool screenshotSuccess = await onScreenshot!(screenshotName, screenshotImage) as bool;
|
final bool screenshotSuccess = await onScreenshot!(screenshotName, screenshotImage);
|
||||||
if (screenshotSuccess) {
|
if (screenshotSuccess) {
|
||||||
jsonResponse = await driver.requestData(DriverTestMessage.complete().toString());
|
jsonResponse = await driver.requestData(DriverTestMessage.complete().toString());
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user