Unverified Commit a172de01 authored by Kenzie Schmoll's avatar Kenzie Schmoll Committed by GitHub

Send ServiceExtensionToggled event when service extension is set to a value. (#26426)

parent 7c434a5c
...@@ -129,8 +129,9 @@ abstract class BindingBase { ...@@ -129,8 +129,9 @@ abstract class BindingBase {
} }
assert(() { assert(() {
const String platformOverrideExtensionName = 'platformOverride';
registerServiceExtension( registerServiceExtension(
name: 'platformOverride', name: platformOverrideExtensionName,
callback: (Map<String, String> parameters) async { callback: (Map<String, String> parameters) async {
if (parameters.containsKey('value')) { if (parameters.containsKey('value')) {
switch (parameters['value']) { switch (parameters['value']) {
...@@ -147,6 +148,10 @@ abstract class BindingBase { ...@@ -147,6 +148,10 @@ abstract class BindingBase {
default: default:
debugDefaultTargetPlatformOverride = null; debugDefaultTargetPlatformOverride = null;
} }
_postExtensionStateChangedEvent(
platformOverrideExtensionName,
defaultTargetPlatform.toString().substring('$TargetPlatform.'.length),
);
await reassembleApplication(); await reassembleApplication();
} }
return <String, dynamic>{ return <String, dynamic>{
...@@ -295,8 +300,10 @@ abstract class BindingBase { ...@@ -295,8 +300,10 @@ abstract class BindingBase {
registerServiceExtension( registerServiceExtension(
name: name, name: name,
callback: (Map<String, String> parameters) async { callback: (Map<String, String> parameters) async {
if (parameters.containsKey('enabled')) if (parameters.containsKey('enabled')) {
await setter(parameters['enabled'] == 'true'); await setter(parameters['enabled'] == 'true');
_postExtensionStateChangedEvent(name, await getter() ? 'true' : 'false');
}
return <String, dynamic>{ 'enabled': await getter() ? 'true' : 'false' }; return <String, dynamic>{ 'enabled': await getter() ? 'true' : 'false' };
} }
); );
...@@ -327,13 +334,44 @@ abstract class BindingBase { ...@@ -327,13 +334,44 @@ abstract class BindingBase {
registerServiceExtension( registerServiceExtension(
name: name, name: name,
callback: (Map<String, String> parameters) async { callback: (Map<String, String> parameters) async {
if (parameters.containsKey(name)) if (parameters.containsKey(name)) {
await setter(double.parse(parameters[name])); await setter(double.parse(parameters[name]));
_postExtensionStateChangedEvent(name, (await getter()).toString());
}
return <String, dynamic>{ name: (await getter()).toString() }; return <String, dynamic>{ name: (await getter()).toString() };
} }
); );
} }
/// Sends an event when a service extension's state is changed.
///
/// Clients should listen for this event to stay aware of the current service
/// extension state. Any service extension that manages a state should call
/// this method on state change.
///
/// `value` reflects the newly updated service extension value.
///
/// This will be called automatically for service extensions registered via
/// [registerBoolServiceExtension], [registerNumericServiceExtension], or
/// [registerStringServiceExtension].
void _postExtensionStateChangedEvent(String name, dynamic value) {
postEvent(
'Flutter.ServiceExtensionStateChanged',
<String, dynamic>{
'extension': 'ext.flutter.$name',
'value': value,
},
);
}
/// All events dispatched by a [BindingBase] use this method instead of
/// calling [developer.postEvent] directly so that tests for [BindingBase]
/// can track which events were dispatched by overriding this method.
@protected
void postEvent(String eventKind, Map<String, dynamic> eventData) {
developer.postEvent(eventKind, eventData);
}
/// Registers a service extension method with the given name (full name /// Registers a service extension method with the given name (full name
/// "ext.flutter.name"), which optionally takes a single argument with the /// "ext.flutter.name"), which optionally takes a single argument with the
/// name "value". If the argument is omitted, the value is to be read, /// name "value". If the argument is omitted, the value is to be read,
...@@ -358,8 +396,10 @@ abstract class BindingBase { ...@@ -358,8 +396,10 @@ abstract class BindingBase {
registerServiceExtension( registerServiceExtension(
name: name, name: name,
callback: (Map<String, String> parameters) async { callback: (Map<String, String> parameters) async {
if (parameters.containsKey('value')) if (parameters.containsKey('value')) {
await setter(parameters['value']); await setter(parameters['value']);
_postExtensionStateChangedEvent(name, await getter());
}
return <String, dynamic>{ 'value': await getter() }; return <String, dynamic>{ 'value': await getter() };
} }
); );
......
...@@ -868,13 +868,36 @@ mixin WidgetInspectorService { ...@@ -868,13 +868,36 @@ mixin WidgetInspectorService {
registerServiceExtension( registerServiceExtension(
name: name, name: name,
callback: (Map<String, String> parameters) async { callback: (Map<String, String> parameters) async {
if (parameters.containsKey('enabled')) if (parameters.containsKey('enabled')) {
await setter(parameters['enabled'] == 'true'); final bool value = parameters['enabled'] == 'true';
await setter(value);
_postExtensionStateChangedEvent(name, value);
}
return <String, dynamic>{ 'enabled': await getter() ? 'true' : 'false' }; return <String, dynamic>{ 'enabled': await getter() ? 'true' : 'false' };
}, },
); );
} }
/// Sends an event when a service extension's state is changed.
///
/// Clients should listen for this event to stay aware of the current service
/// extension state. Any service extension that manages a state should call
/// this method on state change.
///
/// `value` reflects the newly updated service extension value.
///
/// This will be called automatically for service extensions registered via
/// [registerBoolServiceExtension].
void _postExtensionStateChangedEvent(String name, dynamic value) {
postEvent(
'Flutter.ServiceExtensionStateChanged',
<String, dynamic>{
'extension': 'ext.flutter.inspector.$name',
'value': value,
},
);
}
/// Registers a service extension method with the given name (full /// Registers a service extension method with the given name (full
/// name "ext.flutter.inspector.name") which takes an optional parameter named /// name "ext.flutter.inspector.name") which takes an optional parameter named
/// "arg" and a required parameter named "objectGroup" used to control the /// "arg" and a required parameter named "objectGroup" used to control the
......
...@@ -26,6 +26,8 @@ class TestServiceExtensionsBinding extends BindingBase ...@@ -26,6 +26,8 @@ class TestServiceExtensionsBinding extends BindingBase
final Map<String, ServiceExtensionCallback> extensions = <String, ServiceExtensionCallback>{}; final Map<String, ServiceExtensionCallback> extensions = <String, ServiceExtensionCallback>{};
final Map<String, List<Map<String, dynamic>>> eventsDispatched = <String, List<Map<String, dynamic>>>{};
@override @override
void registerServiceExtension({ void registerServiceExtension({
@required String name, @required String name,
...@@ -35,6 +37,20 @@ class TestServiceExtensionsBinding extends BindingBase ...@@ -35,6 +37,20 @@ class TestServiceExtensionsBinding extends BindingBase
extensions[name] = callback; extensions[name] = callback;
} }
@override
void postEvent(String eventKind, Map<dynamic, dynamic> eventData) {
getEventsDispatched(eventKind).add(eventData);
}
List<Map<String, dynamic>> getEventsDispatched(String eventKind) {
return eventsDispatched.putIfAbsent(eventKind, () => <Map<String, dynamic>>[]);
}
Iterable<Map<String, dynamic>> getServiceExtensionStateChangedEvents(String extensionName) {
return getEventsDispatched('Flutter.ServiceExtensionStateChanged')
.where((Map<String, dynamic> event) => event['extension'] == extensionName);
}
Future<Map<String, dynamic>> testExtension(String name, Map<String, String> arguments) { Future<Map<String, dynamic>> testExtension(String name, Map<String, String> arguments) {
expect(extensions.containsKey(name), isTrue); expect(extensions.containsKey(name), isTrue);
return extensions[name](arguments); return extensions[name](arguments);
...@@ -228,6 +244,8 @@ void main() { ...@@ -228,6 +244,8 @@ void main() {
}); });
test('Service extensions - debugPaint', () async { test('Service extensions - debugPaint', () async {
final Iterable<Map<String, dynamic>> extensionChangedEvents = binding.getServiceExtensionStateChangedEvents('ext.flutter.debugPaint');
Map<String, dynamic> extensionChangedEvent;
Map<String, dynamic> result; Map<String, dynamic> result;
Future<Map<String, dynamic>> pendingResult; Future<Map<String, dynamic>> pendingResult;
bool completed; bool completed;
...@@ -237,6 +255,7 @@ void main() { ...@@ -237,6 +255,7 @@ void main() {
result = await binding.testExtension('debugPaint', <String, String>{}); result = await binding.testExtension('debugPaint', <String, String>{});
expect(result, <String, String>{ 'enabled': 'false' }); expect(result, <String, String>{ 'enabled': 'false' });
expect(debugPaintSizeEnabled, false); expect(debugPaintSizeEnabled, false);
expect(extensionChangedEvents, isEmpty);
expect(binding.frameScheduled, isFalse); expect(binding.frameScheduled, isFalse);
pendingResult = binding.testExtension('debugPaint', <String, String>{ 'enabled': 'true' }); pendingResult = binding.testExtension('debugPaint', <String, String>{ 'enabled': 'true' });
completed = false; completed = false;
...@@ -251,9 +270,14 @@ void main() { ...@@ -251,9 +270,14 @@ void main() {
result = await pendingResult; result = await pendingResult;
expect(result, <String, String>{ 'enabled': 'true' }); expect(result, <String, String>{ 'enabled': 'true' });
expect(debugPaintSizeEnabled, true); expect(debugPaintSizeEnabled, true);
expect(extensionChangedEvents.length, 1);
extensionChangedEvent = extensionChangedEvents.last;
expect(extensionChangedEvent['extension'], 'ext.flutter.debugPaint');
expect(extensionChangedEvent['value'], 'true');
result = await binding.testExtension('debugPaint', <String, String>{}); result = await binding.testExtension('debugPaint', <String, String>{});
expect(result, <String, String>{ 'enabled': 'true' }); expect(result, <String, String>{ 'enabled': 'true' });
expect(debugPaintSizeEnabled, true); expect(debugPaintSizeEnabled, true);
expect(extensionChangedEvents.length, 1);
expect(binding.frameScheduled, isFalse); expect(binding.frameScheduled, isFalse);
pendingResult = binding.testExtension('debugPaint', <String, String>{ 'enabled': 'false' }); pendingResult = binding.testExtension('debugPaint', <String, String>{ 'enabled': 'false' });
await binding.flushMicrotasks(); await binding.flushMicrotasks();
...@@ -263,9 +287,14 @@ void main() { ...@@ -263,9 +287,14 @@ void main() {
result = await pendingResult; result = await pendingResult;
expect(result, <String, String>{ 'enabled': 'false' }); expect(result, <String, String>{ 'enabled': 'false' });
expect(debugPaintSizeEnabled, false); expect(debugPaintSizeEnabled, false);
expect(extensionChangedEvents.length, 2);
extensionChangedEvent = extensionChangedEvents.last;
expect(extensionChangedEvent['extension'], 'ext.flutter.debugPaint');
expect(extensionChangedEvent['value'], 'false');
result = await binding.testExtension('debugPaint', <String, String>{}); result = await binding.testExtension('debugPaint', <String, String>{});
expect(result, <String, String>{ 'enabled': 'false' }); expect(result, <String, String>{ 'enabled': 'false' });
expect(debugPaintSizeEnabled, false); expect(debugPaintSizeEnabled, false);
expect(extensionChangedEvents.length, 2);
expect(binding.frameScheduled, isFalse); expect(binding.frameScheduled, isFalse);
}); });
...@@ -373,6 +402,8 @@ void main() { ...@@ -373,6 +402,8 @@ void main() {
}); });
test('Service extensions - platformOverride', () async { test('Service extensions - platformOverride', () async {
final Iterable<Map<String, dynamic>> extensionChangedEvents = binding.getServiceExtensionStateChangedEvents('ext.flutter.platformOverride');
Map<String, dynamic> extensionChangedEvent;
Map<String, dynamic> result; Map<String, dynamic> result;
expect(binding.reassembled, 0); expect(binding.reassembled, 0);
...@@ -380,30 +411,55 @@ void main() { ...@@ -380,30 +411,55 @@ void main() {
result = await binding.testExtension('platformOverride', <String, String>{}); result = await binding.testExtension('platformOverride', <String, String>{});
expect(result, <String, String>{'value': 'android'}); expect(result, <String, String>{'value': 'android'});
expect(defaultTargetPlatform, TargetPlatform.android); expect(defaultTargetPlatform, TargetPlatform.android);
expect(extensionChangedEvents, isEmpty);
result = await hasReassemble(binding.testExtension('platformOverride', <String, String>{'value': 'iOS'})); result = await hasReassemble(binding.testExtension('platformOverride', <String, String>{'value': 'iOS'}));
expect(result, <String, String>{'value': 'iOS'}); expect(result, <String, String>{'value': 'iOS'});
expect(binding.reassembled, 1); expect(binding.reassembled, 1);
expect(defaultTargetPlatform, TargetPlatform.iOS); expect(defaultTargetPlatform, TargetPlatform.iOS);
expect(extensionChangedEvents.length, 1);
extensionChangedEvent = extensionChangedEvents.last;
expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
expect(extensionChangedEvent['value'], 'iOS');
result = await hasReassemble(binding.testExtension('platformOverride', <String, String>{'value': 'android'})); result = await hasReassemble(binding.testExtension('platformOverride', <String, String>{'value': 'android'}));
expect(result, <String, String>{'value': 'android'}); expect(result, <String, String>{'value': 'android'});
expect(binding.reassembled, 2); expect(binding.reassembled, 2);
expect(defaultTargetPlatform, TargetPlatform.android); expect(defaultTargetPlatform, TargetPlatform.android);
expect(extensionChangedEvents.length, 2);
extensionChangedEvent = extensionChangedEvents.last;
expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
expect(extensionChangedEvent['value'], 'android');
result = await hasReassemble(binding.testExtension('platformOverride', <String, String>{'value': 'fuchsia'})); result = await hasReassemble(binding.testExtension('platformOverride', <String, String>{'value': 'fuchsia'}));
expect(result, <String, String>{'value': 'fuchsia'}); expect(result, <String, String>{'value': 'fuchsia'});
expect(binding.reassembled, 3); expect(binding.reassembled, 3);
expect(defaultTargetPlatform, TargetPlatform.fuchsia); expect(defaultTargetPlatform, TargetPlatform.fuchsia);
expect(extensionChangedEvents.length, 3);
extensionChangedEvent = extensionChangedEvents.last;
expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
expect(extensionChangedEvent['value'], 'fuchsia');
result = await hasReassemble(binding.testExtension('platformOverride', <String, String>{'value': 'default'})); result = await hasReassemble(binding.testExtension('platformOverride', <String, String>{'value': 'default'}));
expect(result, <String, String>{'value': 'android'}); expect(result, <String, String>{'value': 'android'});
expect(binding.reassembled, 4); expect(binding.reassembled, 4);
expect(defaultTargetPlatform, TargetPlatform.android); expect(defaultTargetPlatform, TargetPlatform.android);
expect(extensionChangedEvents.length, 4);
extensionChangedEvent = extensionChangedEvents.last;
expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
expect(extensionChangedEvent['value'], 'android');
result = await hasReassemble(binding.testExtension('platformOverride', <String, String>{'value': 'iOS'})); result = await hasReassemble(binding.testExtension('platformOverride', <String, String>{'value': 'iOS'}));
expect(result, <String, String>{'value': 'iOS'}); expect(result, <String, String>{'value': 'iOS'});
expect(binding.reassembled, 5); expect(binding.reassembled, 5);
expect(defaultTargetPlatform, TargetPlatform.iOS); expect(defaultTargetPlatform, TargetPlatform.iOS);
expect(extensionChangedEvents.length, 5);
extensionChangedEvent = extensionChangedEvents.last;
expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
expect(extensionChangedEvent['value'], 'iOS');
result = await hasReassemble(binding.testExtension('platformOverride', <String, String>{'value': 'bogus'})); result = await hasReassemble(binding.testExtension('platformOverride', <String, String>{'value': 'bogus'}));
expect(result, <String, String>{'value': 'android'}); expect(result, <String, String>{'value': 'android'});
expect(binding.reassembled, 6); expect(binding.reassembled, 6);
expect(defaultTargetPlatform, TargetPlatform.android); expect(defaultTargetPlatform, TargetPlatform.android);
expect(extensionChangedEvents.length, 6);
extensionChangedEvent = extensionChangedEvents.last;
expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
expect(extensionChangedEvent['value'], 'android');
binding.reassembled = 0; binding.reassembled = 0;
}); });
...@@ -518,6 +574,8 @@ void main() { ...@@ -518,6 +574,8 @@ void main() {
}); });
test('Service extensions - timeDilation', () async { test('Service extensions - timeDilation', () async {
final Iterable<Map<String, dynamic>> extensionChangedEvents = binding.getServiceExtensionStateChangedEvents('ext.flutter.timeDilation');
Map<String, dynamic> extensionChangedEvent;
Map<String, dynamic> result; Map<String, dynamic> result;
expect(binding.frameScheduled, isFalse); expect(binding.frameScheduled, isFalse);
...@@ -525,18 +583,29 @@ void main() { ...@@ -525,18 +583,29 @@ void main() {
result = await binding.testExtension('timeDilation', <String, String>{}); result = await binding.testExtension('timeDilation', <String, String>{});
expect(result, <String, String>{ 'timeDilation': '1.0' }); expect(result, <String, String>{ 'timeDilation': '1.0' });
expect(timeDilation, 1.0); expect(timeDilation, 1.0);
expect(extensionChangedEvents, isEmpty);
result = await binding.testExtension('timeDilation', <String, String>{ 'timeDilation': '100.0' }); result = await binding.testExtension('timeDilation', <String, String>{ 'timeDilation': '100.0' });
expect(result, <String, String>{ 'timeDilation': '100.0' }); expect(result, <String, String>{ 'timeDilation': '100.0' });
expect(timeDilation, 100.0); expect(timeDilation, 100.0);
expect(extensionChangedEvents.length, 1);
extensionChangedEvent = extensionChangedEvents.last;
expect(extensionChangedEvent['extension'], 'ext.flutter.timeDilation');
expect(extensionChangedEvent['value'], '100.0');
result = await binding.testExtension('timeDilation', <String, String>{}); result = await binding.testExtension('timeDilation', <String, String>{});
expect(result, <String, String>{ 'timeDilation': '100.0' }); expect(result, <String, String>{ 'timeDilation': '100.0' });
expect(timeDilation, 100.0); expect(timeDilation, 100.0);
expect(extensionChangedEvents.length, 1);
result = await binding.testExtension('timeDilation', <String, String>{ 'timeDilation': '1.0' }); result = await binding.testExtension('timeDilation', <String, String>{ 'timeDilation': '1.0' });
expect(result, <String, String>{ 'timeDilation': '1.0' }); expect(result, <String, String>{ 'timeDilation': '1.0' });
expect(timeDilation, 1.0); expect(timeDilation, 1.0);
expect(extensionChangedEvents.length, 2);
extensionChangedEvent = extensionChangedEvents.last;
expect(extensionChangedEvent['extension'], 'ext.flutter.timeDilation');
expect(extensionChangedEvent['value'], '1.0');
result = await binding.testExtension('timeDilation', <String, String>{}); result = await binding.testExtension('timeDilation', <String, String>{});
expect(result, <String, String>{ 'timeDilation': '1.0' }); expect(result, <String, String>{ 'timeDilation': '1.0' });
expect(timeDilation, 1.0); expect(timeDilation, 1.0);
expect(extensionChangedEvents.length, 2);
expect(binding.frameScheduled, isFalse); expect(binding.frameScheduled, isFalse);
}); });
......
...@@ -194,8 +194,7 @@ void main() { ...@@ -194,8 +194,7 @@ void main() {
class TestWidgetInspectorService extends Object with WidgetInspectorService { class TestWidgetInspectorService extends Object with WidgetInspectorService {
final Map<String, InspectorServiceExtensionCallback> extensions = <String, InspectorServiceExtensionCallback>{}; final Map<String, InspectorServiceExtensionCallback> extensions = <String, InspectorServiceExtensionCallback>{};
final Map<String, List<Map<Object, Object>>> eventsDispatched = final Map<String, List<Map<Object, Object>>> eventsDispatched = <String, List<Map<Object, Object>>>{};
<String, List<Map<Object, Object>>>{};
@override @override
void registerServiceExtension({ void registerServiceExtension({
...@@ -215,6 +214,11 @@ class TestWidgetInspectorService extends Object with WidgetInspectorService { ...@@ -215,6 +214,11 @@ class TestWidgetInspectorService extends Object with WidgetInspectorService {
return eventsDispatched.putIfAbsent(eventKind, () => <Map<Object, Object>>[]); return eventsDispatched.putIfAbsent(eventKind, () => <Map<Object, Object>>[]);
} }
Iterable<Map<Object, Object>> getServiceExtensionStateChangedEvents(String extensionName) {
return getEventsDispatched('Flutter.ServiceExtensionStateChanged')
.where((Map<Object, Object> event) => event['extension'] == extensionName);
}
Future<Object> testExtension(String name, Map<String, String> arguments) async { Future<Object> testExtension(String name, Map<String, String> arguments) async {
expect(extensions.containsKey(name), isTrue); expect(extensions.containsKey(name), isTrue);
// Encode and decode to JSON to match behavior using a real service // Encode and decode to JSON to match behavior using a real service
...@@ -1725,15 +1729,33 @@ class TestWidgetInspectorService extends Object with WidgetInspectorService { ...@@ -1725,15 +1729,33 @@ class TestWidgetInspectorService extends Object with WidgetInspectorService {
}, skip: !WidgetInspectorService.instance.isWidgetCreationTracked()); // Test requires --track-widget-creation flag. }, skip: !WidgetInspectorService.instance.isWidgetCreationTracked()); // Test requires --track-widget-creation flag.
testWidgets('ext.flutter.inspector.show', (WidgetTester tester) async { testWidgets('ext.flutter.inspector.show', (WidgetTester tester) async {
final Iterable<Map<Object, Object>> extensionChangedEvents = service.getServiceExtensionStateChangedEvents('ext.flutter.inspector.show');
Map<Object, Object> extensionChangedEvent;
service.rebuildCount = 0; service.rebuildCount = 0;
expect(extensionChangedEvents, isEmpty);
expect(await service.testBoolExtension('show', <String, String>{'enabled': 'true'}), equals('true')); expect(await service.testBoolExtension('show', <String, String>{'enabled': 'true'}), equals('true'));
expect(extensionChangedEvents.length, equals(1));
extensionChangedEvent = extensionChangedEvents.last;
expect(extensionChangedEvent['extension'], equals('ext.flutter.inspector.show'));
expect(extensionChangedEvent['value'], isTrue);
expect(service.rebuildCount, equals(1)); expect(service.rebuildCount, equals(1));
expect(await service.testBoolExtension('show', <String, String>{}), equals('true')); expect(await service.testBoolExtension('show', <String, String>{}), equals('true'));
expect(WidgetsApp.debugShowWidgetInspectorOverride, isTrue); expect(WidgetsApp.debugShowWidgetInspectorOverride, isTrue);
expect(extensionChangedEvents.length, equals(1));
expect(await service.testBoolExtension('show', <String, String>{'enabled': 'true'}), equals('true')); expect(await service.testBoolExtension('show', <String, String>{'enabled': 'true'}), equals('true'));
expect(extensionChangedEvents.length, equals(2));
extensionChangedEvent = extensionChangedEvents.last;
expect(extensionChangedEvent['extension'], equals('ext.flutter.inspector.show'));
expect(extensionChangedEvent['value'], isTrue);
expect(service.rebuildCount, equals(1)); expect(service.rebuildCount, equals(1));
expect(await service.testBoolExtension('show', <String, String>{'enabled': 'false'}), equals('false')); expect(await service.testBoolExtension('show', <String, String>{'enabled': 'false'}), equals('false'));
expect(extensionChangedEvents.length, equals(3));
extensionChangedEvent = extensionChangedEvents.last;
expect(extensionChangedEvent['extension'], equals('ext.flutter.inspector.show'));
expect(extensionChangedEvent['value'], isFalse);
expect(await service.testBoolExtension('show', <String, String>{}), equals('false')); expect(await service.testBoolExtension('show', <String, String>{}), equals('false'));
expect(extensionChangedEvents.length, equals(3));
expect(service.rebuildCount, equals(2)); expect(service.rebuildCount, equals(2));
expect(WidgetsApp.debugShowWidgetInspectorOverride, isFalse); expect(WidgetsApp.debugShowWidgetInspectorOverride, isFalse);
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment