diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart index dcb16ae416..6c98710b00 100644 --- a/packages/flutter_tools/lib/src/run_hot.dart +++ b/packages/flutter_tools/lib/src/run_hot.dart @@ -412,7 +412,24 @@ class HotRunner extends ResidentRunner { /// Prints errors if [printErrors] is [true]. static bool validateReloadReport(Map reloadReport, { bool printErrors: true }) { - if (reloadReport['type'] != 'ReloadReport') { + if (reloadReport == null) { + if (printErrors) + printError('Hot reload did not receive reload report.'); + return false; + } + if (!(reloadReport['type'] == 'ReloadReport' && + (reloadReport['success'] == true || + (reloadReport['success'] == false && + (reloadReport['details'] is Map && + reloadReport['details']['notices'] is List && + reloadReport['details']['notices'].isNotEmpty && + reloadReport['details']['notices'].every( + (dynamic item) => item is Map && item['message'] is String + ) + ) + ) + ) + )) { if (printErrors) printError('Hot reload received invalid response: $reloadReport'); return false; diff --git a/packages/flutter_tools/test/hot_test.dart b/packages/flutter_tools/test/hot_test.dart index a09d1743ab..73f7fd816d 100644 --- a/packages/flutter_tools/test/hot_test.dart +++ b/packages/flutter_tools/test/hot_test.dart @@ -11,9 +11,76 @@ void main() { group('validateReloadReport', () { testUsingContext('invalid', () async { expect(HotRunner.validateReloadReport({}), false); - expect(HotRunner.validateReloadReport( - {'type': 'ReloadReport', 'success': true, 'details': {}}), - true); + expect(HotRunner.validateReloadReport({ + 'type': 'ReloadReport', + 'success': false, + 'details': {}, + }), false); + expect(HotRunner.validateReloadReport({ + 'type': 'ReloadReport', + 'success': false, + 'details': { + 'notices': >[ + ], + }, + }), false); + expect(HotRunner.validateReloadReport({ + 'type': 'ReloadReport', + 'success': false, + 'details': { + 'notices': { + 'message': 'error', + }, + }, + }), false); + expect(HotRunner.validateReloadReport({ + 'type': 'ReloadReport', + 'success': false, + 'details': { + 'notices': >[], + }, + }), false); + expect(HotRunner.validateReloadReport({ + 'type': 'ReloadReport', + 'success': false, + 'details': { + 'notices': >[ + { 'message': false, } + ], + }, + }), false); + expect(HotRunner.validateReloadReport({ + 'type': 'ReloadReport', + 'success': false, + 'details': { + 'notices': >[ + { 'message': ['error'], }, + ], + }, + }), false); + expect(HotRunner.validateReloadReport({ + 'type': 'ReloadReport', + 'success': false, + 'details': { + 'notices': >[ + { 'message': 'error', }, + { 'message': ['error'], }, + ], + }, + }), false); + expect(HotRunner.validateReloadReport({ + 'type': 'ReloadReport', + 'success': false, + 'details': { + 'notices': >[ + { 'message': 'error', }, + ], + }, + }), false); + expect(HotRunner.validateReloadReport({ + 'type': 'ReloadReport', + 'success': true, + }), true); }); }); }