diff --git a/packages/flutter_driver/lib/src/common/find.dart b/packages/flutter_driver/lib/src/common/find.dart index ee16f78fa83..3423876df60 100644 --- a/packages/flutter_driver/lib/src/common/find.dart +++ b/packages/flutter_driver/lib/src/common/find.dart @@ -59,14 +59,17 @@ class WaitFor extends CommandWithTarget { WaitFor.deserialize(Map json) : super.deserialize(json); @override - final String kind = 'waitFor'; + String get kind => 'waitFor'; } /// The result of a [WaitFor] command. class WaitForResult extends Result { + /// Creates a [WaitForResult]. + const WaitForResult(); + /// Deserializes the result from JSON. static WaitForResult fromJson(Map json) { - return WaitForResult(); + return const WaitForResult(); } @override @@ -86,14 +89,17 @@ class WaitForAbsent extends CommandWithTarget { WaitForAbsent.deserialize(Map json) : super.deserialize(json); @override - final String kind = 'waitForAbsent'; + String get kind => 'waitForAbsent'; } /// The result of a [WaitForAbsent] command. class WaitForAbsentResult extends Result { + /// Creates a [WaitForAbsentResult]. + const WaitForAbsentResult(); + /// Deserializes the result from JSON. static WaitForAbsentResult fromJson(Map json) { - return WaitForAbsentResult(); + return const WaitForAbsentResult(); } @override @@ -103,19 +109,23 @@ class WaitForAbsentResult extends Result { /// A Flutter Driver command that waits until there are no more transient callbacks in the queue. class WaitUntilNoTransientCallbacks extends Command { /// Creates a command that waits for there to be no transient callbacks. - WaitUntilNoTransientCallbacks({ Duration timeout }) : super(timeout: timeout); + const WaitUntilNoTransientCallbacks({ Duration timeout }) : super(timeout: timeout); /// Deserializes this command from the value generated by [serialize]. WaitUntilNoTransientCallbacks.deserialize(Map json) : super.deserialize(json); @override - final String kind = 'waitUntilNoTransientCallbacks'; + String get kind => 'waitUntilNoTransientCallbacks'; } /// Base class for Flutter Driver finders, objects that describe how the driver /// should search for elements. abstract class SerializableFinder { + + /// A const constructor to allow subclasses to be const. + const SerializableFinder(); + /// Identifies the type of finder to be used by the driver extension. String get finderType; @@ -137,7 +147,7 @@ abstract class SerializableFinder { case 'ByTooltipMessage': return ByTooltipMessage.deserialize(json); case 'BySemanticsLabel': return BySemanticsLabel.deserialize(json); case 'ByText': return ByText.deserialize(json); - case 'PageBack': return PageBack(); + case 'PageBack': return const PageBack(); } throw DriverError('Unsupported search specification type $finderType'); } @@ -146,13 +156,13 @@ abstract class SerializableFinder { /// A Flutter Driver finder that finds widgets by tooltip text. class ByTooltipMessage extends SerializableFinder { /// Creates a tooltip finder given the tooltip's message [text]. - ByTooltipMessage(this.text); + const ByTooltipMessage(this.text); /// Tooltip message text. final String text; @override - final String finderType = 'ByTooltipMessage'; + String get finderType => 'ByTooltipMessage'; @override Map serialize() => super.serialize()..addAll({ @@ -171,7 +181,7 @@ class ByTooltipMessage extends SerializableFinder { /// match. If it is a [RegExp], it will return true for [RegExp.hasMatch]. class BySemanticsLabel extends SerializableFinder { /// Creates a semantic label finder given the [label]. - BySemanticsLabel(this.label); + const BySemanticsLabel(this.label); /// A [Pattern] matching the [Semantics.properties.label]. /// @@ -179,7 +189,7 @@ class BySemanticsLabel extends SerializableFinder { final Pattern label; @override - final String finderType = 'BySemanticsLabel'; + String get finderType => 'BySemanticsLabel'; @override Map serialize() { @@ -207,13 +217,13 @@ class BySemanticsLabel extends SerializableFinder { /// [EditableText] widget. class ByText extends SerializableFinder { /// Creates a text finder given the text. - ByText(this.text); + const ByText(this.text); /// The text that appears inside the [Text] or [EditableText] widget. final String text; @override - final String finderType = 'ByText'; + String get finderType => 'ByText'; @override Map serialize() => super.serialize()..addAll({ @@ -248,7 +258,7 @@ class ByValueKey extends SerializableFinder { final String keyValueType; @override - final String finderType = 'ByValueKey'; + String get finderType => 'ByValueKey'; @override Map serialize() => super.serialize()..addAll({ @@ -274,13 +284,13 @@ class ByValueKey extends SerializableFinder { /// A Flutter Driver finder that finds widgets by their [runtimeType]. class ByType extends SerializableFinder { /// Creates a finder that given the runtime type in string form. - ByType(this.type); + const ByType(this.type); /// The widget's [runtimeType], in string form. final String type; @override - final String finderType = 'ByType'; + String get finderType => 'ByType'; @override Map serialize() => super.serialize()..addAll({ @@ -300,6 +310,9 @@ class ByType extends SerializableFinder { /// /// * [WidgetTester.pageBack], for a similar functionality in widget tests. class PageBack extends SerializableFinder { + /// Creates a [PageBack]. + const PageBack(); + @override String get finderType => 'PageBack'; } @@ -333,7 +346,7 @@ class GetSemanticsId extends CommandWithTarget { class GetSemanticsIdResult extends Result { /// Creates a new [GetSemanticsId] result. - GetSemanticsIdResult(this.id); + const GetSemanticsIdResult(this.id); /// The semantics id of the node; final int id; diff --git a/packages/flutter_driver/lib/src/common/frame_sync.dart b/packages/flutter_driver/lib/src/common/frame_sync.dart index add70fb4550..78e4c634baa 100644 --- a/packages/flutter_driver/lib/src/common/frame_sync.dart +++ b/packages/flutter_driver/lib/src/common/frame_sync.dart @@ -7,7 +7,7 @@ import 'message.dart'; /// A Flutter Driver command that enables or disables the FrameSync mechanism. class SetFrameSync extends Command { /// Creates a command to toggle the FrameSync mechanism. - SetFrameSync(this.enabled, { Duration timeout }) : super(timeout: timeout); + const SetFrameSync(this.enabled, { Duration timeout }) : super(timeout: timeout); /// Deserializes this command from the value generated by [serialize]. SetFrameSync.deserialize(Map params) @@ -18,7 +18,7 @@ class SetFrameSync extends Command { final bool enabled; @override - final String kind = 'set_frame_sync'; + String get kind => 'set_frame_sync'; @override Map serialize() => super.serialize()..addAll({ @@ -28,9 +28,12 @@ class SetFrameSync extends Command { /// The result of a [SetFrameSync] command. class SetFrameSyncResult extends Result { + /// Creates a [SetFrameSyncResult]. + const SetFrameSyncResult(); + /// Deserializes this result from JSON. static SetFrameSyncResult fromJson(Map json) { - return SetFrameSyncResult(); + return const SetFrameSyncResult(); } @override diff --git a/packages/flutter_driver/lib/src/common/geometry.dart b/packages/flutter_driver/lib/src/common/geometry.dart index cfedb9e4659..90318bd4a3c 100644 --- a/packages/flutter_driver/lib/src/common/geometry.dart +++ b/packages/flutter_driver/lib/src/common/geometry.dart @@ -47,13 +47,13 @@ class GetOffset extends CommandWithTarget { final OffsetType offsetType; @override - final String kind = 'get_offset'; + String get kind => 'get_offset'; } /// The result of the [GetRect] command. class GetOffsetResult extends Result { /// Creates a result with the offset defined by [dx] and [dy]. - GetOffsetResult({ this.dx = 0.0, this.dy = 0.0}); + const GetOffsetResult({ this.dx = 0.0, this.dy = 0.0}); /// The x component of the offset. final double dx; diff --git a/packages/flutter_driver/lib/src/common/gesture.dart b/packages/flutter_driver/lib/src/common/gesture.dart index 7dabd3f57af..e771cda0fb1 100644 --- a/packages/flutter_driver/lib/src/common/gesture.dart +++ b/packages/flutter_driver/lib/src/common/gesture.dart @@ -14,14 +14,17 @@ class Tap extends CommandWithTarget { Tap.deserialize(Map json) : super.deserialize(json); @override - final String kind = 'tap'; + String get kind => 'tap'; } /// The result of a [Tap] command. class TapResult extends Result { + /// Creates a [TapResult]. + const TapResult(); + /// Deserializes this result from JSON. static TapResult fromJson(Map json) { - return TapResult(); + return const TapResult(); } @override @@ -63,7 +66,7 @@ class Scroll extends CommandWithTarget { final int frequency; @override - final String kind = 'scroll'; + String get kind => 'scroll'; @override Map serialize() => super.serialize()..addAll({ @@ -76,9 +79,12 @@ class Scroll extends CommandWithTarget { /// The result of a [Scroll] command. class ScrollResult extends Result { + /// Creates a [ScrollResult]. + const ScrollResult(); + /// Deserializes this result from JSON. static ScrollResult fromJson(Map json) { - return ScrollResult(); + return const ScrollResult(); } @override @@ -106,7 +112,7 @@ class ScrollIntoView extends CommandWithTarget { final double alignment; @override - final String kind = 'scrollIntoView'; + String get kind => 'scrollIntoView'; @override Map serialize() => super.serialize()..addAll({ diff --git a/packages/flutter_driver/lib/src/common/health.dart b/packages/flutter_driver/lib/src/common/health.dart index 9441fa68ce2..e7144f9461b 100644 --- a/packages/flutter_driver/lib/src/common/health.dart +++ b/packages/flutter_driver/lib/src/common/health.dart @@ -8,13 +8,13 @@ import 'message.dart'; /// A Flutter Driver command that requests an application health check. class GetHealth extends Command { /// Create a health check command. - GetHealth({ Duration timeout }) : super(timeout: timeout); + const GetHealth({ Duration timeout }) : super(timeout: timeout); /// Deserializes this command from the value generated by [serialize]. GetHealth.deserialize(Map json) : super.deserialize(json); @override - final String kind = 'get_health'; + String get kind => 'get_health'; } /// A description of application state. @@ -33,7 +33,7 @@ final EnumIndex _healthStatusIndex = /// [FlutterDriver.checkHealth] test. class Health extends Result { /// Creates a [Health] object with the given [status]. - Health(this.status) + const Health(this.status) : assert(status != null); /// The status represented by this object. diff --git a/packages/flutter_driver/lib/src/common/message.dart b/packages/flutter_driver/lib/src/common/message.dart index 87bc19f1254..98e8645049d 100644 --- a/packages/flutter_driver/lib/src/common/message.dart +++ b/packages/flutter_driver/lib/src/common/message.dart @@ -47,6 +47,9 @@ abstract class Command { /// An object sent from a Flutter application back to the Flutter Driver in /// response to a command. abstract class Result { + /// A const constructor to allow subclasses to be const. + const Result(); + /// Serializes this message to a JSON map. Map toJson(); } diff --git a/packages/flutter_driver/lib/src/common/render_tree.dart b/packages/flutter_driver/lib/src/common/render_tree.dart index 6bd827ed029..89afc12d86d 100644 --- a/packages/flutter_driver/lib/src/common/render_tree.dart +++ b/packages/flutter_driver/lib/src/common/render_tree.dart @@ -7,20 +7,20 @@ import 'message.dart'; /// A Flutter Driver command that requests a string representation of the render tree. class GetRenderTree extends Command { /// Create a command to request a string representation of the render tree. - GetRenderTree({ Duration timeout }) : super(timeout: timeout); + const GetRenderTree({ Duration timeout }) : super(timeout: timeout); /// Deserializes this command from the value generated by [serialize]. GetRenderTree.deserialize(Map json) : super.deserialize(json); @override - final String kind = 'get_render_tree'; + String get kind => 'get_render_tree'; } /// A string representation of the render tree, the result of a /// [FlutterDriver.getRenderTree] method. class RenderTree extends Result { /// Creates a [RenderTree] object with the given string representation. - RenderTree(this.tree); + const RenderTree(this.tree); /// String representation of the render tree. final String tree; diff --git a/packages/flutter_driver/lib/src/common/request_data.dart b/packages/flutter_driver/lib/src/common/request_data.dart index d6d64e2777c..609de372946 100644 --- a/packages/flutter_driver/lib/src/common/request_data.dart +++ b/packages/flutter_driver/lib/src/common/request_data.dart @@ -8,7 +8,7 @@ import 'message.dart'; /// string response. class RequestData extends Command { /// Create a command that sends a message. - RequestData(this.message, { Duration timeout }) : super(timeout: timeout); + const RequestData(this.message, { Duration timeout }) : super(timeout: timeout); /// Deserializes this command from the value generated by [serialize]. RequestData.deserialize(Map params) @@ -19,7 +19,7 @@ class RequestData extends Command { final String message; @override - final String kind = 'request_data'; + String get kind => 'request_data'; @override Map serialize() => super.serialize()..addAll({ @@ -30,7 +30,7 @@ class RequestData extends Command { /// The result of the [RequestData] command. class RequestDataResult extends Result { /// Creates a result with the given [message]. - RequestDataResult(this.message); + const RequestDataResult(this.message); /// The text extracted by the [RequestData] command. final String message; diff --git a/packages/flutter_driver/lib/src/common/semantics.dart b/packages/flutter_driver/lib/src/common/semantics.dart index d44c42089c2..cf80e7787ee 100644 --- a/packages/flutter_driver/lib/src/common/semantics.dart +++ b/packages/flutter_driver/lib/src/common/semantics.dart @@ -7,7 +7,7 @@ import 'message.dart'; /// A Flutter Driver command that enables or disables semantics. class SetSemantics extends Command { /// Creates a command that enables or disables semantics. - SetSemantics(this.enabled, { Duration timeout }) : super(timeout: timeout); + const SetSemantics(this.enabled, { Duration timeout }) : super(timeout: timeout); /// Deserializes this command from the value generated by [serialize]. SetSemantics.deserialize(Map params) @@ -18,7 +18,7 @@ class SetSemantics extends Command { final bool enabled; @override - final String kind = 'set_semantics'; + String get kind => 'set_semantics'; @override Map serialize() => super.serialize()..addAll({ @@ -29,7 +29,7 @@ class SetSemantics extends Command { /// The result of a [SetSemantics] command. class SetSemanticsResult extends Result { /// Create a result with the given [changedState]. - SetSemanticsResult(this.changedState); + const SetSemanticsResult(this.changedState); /// Whether the [SetSemantics] command actually changed the state that the /// application was in. diff --git a/packages/flutter_driver/lib/src/common/text.dart b/packages/flutter_driver/lib/src/common/text.dart index b5ee236beec..c8f91d510f4 100644 --- a/packages/flutter_driver/lib/src/common/text.dart +++ b/packages/flutter_driver/lib/src/common/text.dart @@ -14,13 +14,13 @@ class GetText extends CommandWithTarget { GetText.deserialize(Map json) : super.deserialize(json); @override - final String kind = 'get_text'; + String get kind => 'get_text'; } /// The result of the [GetText] command. class GetTextResult extends Result { /// Creates a result with the given [text]. - GetTextResult(this.text); + const GetTextResult(this.text); /// The text extracted by the [GetText] command. final String text; @@ -39,7 +39,7 @@ class GetTextResult extends Result { /// A Flutter Driver command that enters text into the currently focused widget. class EnterText extends Command { /// Creates a command that enters text into the currently focused widget. - EnterText(this.text, { Duration timeout }) : super(timeout: timeout); + const EnterText(this.text, { Duration timeout }) : super(timeout: timeout); /// Deserializes this command from the value generated by [serialize]. EnterText.deserialize(Map json) @@ -50,7 +50,7 @@ class EnterText extends Command { final String text; @override - final String kind = 'enter_text'; + String get kind => 'enter_text'; @override Map serialize() => super.serialize()..addAll({ @@ -61,11 +61,11 @@ class EnterText extends Command { /// The result of the [EnterText] command. class EnterTextResult extends Result { /// Creates a successful result of entering the text. - EnterTextResult(); + const EnterTextResult(); /// Deserializes the result from JSON. static EnterTextResult fromJson(Map json) { - return EnterTextResult(); + return const EnterTextResult(); } @override @@ -75,7 +75,7 @@ class EnterTextResult extends Result { /// A Flutter Driver command that enables and disables text entry emulation. class SetTextEntryEmulation extends Command { /// Creates a command that enables and disables text entry emulation. - SetTextEntryEmulation(this.enabled, { Duration timeout }) : super(timeout: timeout); + const SetTextEntryEmulation(this.enabled, { Duration timeout }) : super(timeout: timeout); /// Deserializes this command from the value generated by [serialize]. SetTextEntryEmulation.deserialize(Map json) @@ -86,7 +86,7 @@ class SetTextEntryEmulation extends Command { final bool enabled; @override - final String kind = 'set_text_entry_emulation'; + String get kind => 'set_text_entry_emulation'; @override Map serialize() => super.serialize()..addAll({ @@ -97,11 +97,11 @@ class SetTextEntryEmulation extends Command { /// The result of the [SetTextEntryEmulation] command. class SetTextEntryEmulationResult extends Result { /// Creates a successful result. - SetTextEntryEmulationResult(); + const SetTextEntryEmulationResult(); /// Deserializes the result from JSON. static SetTextEntryEmulationResult fromJson(Map json) { - return SetTextEntryEmulationResult(); + return const SetTextEntryEmulationResult(); } @override diff --git a/packages/flutter_driver/lib/src/driver/driver.dart b/packages/flutter_driver/lib/src/driver/driver.dart index 7071c4ac731..585d8ae0c66 100644 --- a/packages/flutter_driver/lib/src/driver/driver.dart +++ b/packages/flutter_driver/lib/src/driver/driver.dart @@ -1016,7 +1016,7 @@ class CommonFinders { SerializableFinder byType(String type) => ByType(type); /// Finds the back button on a Material or Cupertino page's scaffold. - SerializableFinder pageBack() => PageBack(); + SerializableFinder pageBack() => const PageBack(); } /// An immutable 2D floating-point offset used by Flutter Driver. diff --git a/packages/flutter_driver/lib/src/extension/extension.dart b/packages/flutter_driver/lib/src/extension/extension.dart index 2c9c62e4b7a..c7afd09ec85 100644 --- a/packages/flutter_driver/lib/src/extension/extension.dart +++ b/packages/flutter_driver/lib/src/extension/extension.dart @@ -205,7 +205,7 @@ class FlutterDriverExtension { }; } - Future _getHealth(Command command) async => Health(HealthStatus.ok); + Future _getHealth(Command command) async => const Health(HealthStatus.ok); Future _getRenderTree(Command command) async { return RenderTree(RendererBinding.instance?.renderView?.toStringDeep()); @@ -325,19 +325,19 @@ class FlutterDriverExtension { _createFinder(tapCommand.finder).hitTestable() ); await _prober.tap(computedFinder); - return TapResult(); + return const TapResult(); } Future _waitFor(Command command) async { final WaitFor waitForCommand = command; await _waitForElement(_createFinder(waitForCommand.finder)); - return WaitForResult(); + return const WaitForResult(); } Future _waitForAbsent(Command command) async { final WaitForAbsent waitForAbsentCommand = command; await _waitForAbsentElement(_createFinder(waitForAbsentCommand.finder)); - return WaitForAbsentResult(); + return const WaitForAbsentResult(); } Future _waitUntilNoTransientCallbacks(Command command) async { @@ -409,14 +409,14 @@ class FlutterDriverExtension { } _prober.binding.dispatchEvent(pointer.up(), hitTest); - return ScrollResult(); + return const ScrollResult(); } Future _scrollIntoView(Command command) async { final ScrollIntoView scrollIntoViewCommand = command; final Finder target = await _waitForElement(_createFinder(scrollIntoViewCommand.finder)); await Scrollable.ensureVisible(target.evaluate().single, duration: const Duration(milliseconds: 100), alignment: scrollIntoViewCommand.alignment ?? 0.0); - return ScrollResult(); + return const ScrollResult(); } Future _getText(Command command) async { @@ -434,7 +434,7 @@ class FlutterDriverExtension { } else { _testTextInput.unregister(); } - return SetTextEntryEmulationResult(); + return const SetTextEntryEmulationResult(); } Future _enterText(Command command) async { @@ -444,7 +444,7 @@ class FlutterDriverExtension { } final EnterText enterTextCommand = command; _testTextInput.enterText(enterTextCommand.text); - return EnterTextResult(); + return const EnterTextResult(); } Future _requestData(Command command) async { @@ -455,7 +455,7 @@ class FlutterDriverExtension { Future _setFrameSync(Command command) async { final SetFrameSync setFrameSyncCommand = command; _frameSync = setFrameSyncCommand.enabled; - return SetFrameSyncResult(); + return const SetFrameSyncResult(); } SemanticsHandle _semantics; diff --git a/packages/flutter_driver/test/src/extension_test.dart b/packages/flutter_driver/test/src/extension_test.dart index 519100dd7cd..6e139f16edf 100644 --- a/packages/flutter_driver/test/src/extension_test.dart +++ b/packages/flutter_driver/test/src/extension_test.dart @@ -24,7 +24,7 @@ void main() { }); testWidgets('returns immediately when transient callback queue is empty', (WidgetTester tester) async { - extension.call(WaitUntilNoTransientCallbacks().serialize()) + extension.call(const WaitUntilNoTransientCallbacks().serialize()) .then(expectAsync1((Map r) { result = r; })); @@ -44,7 +44,7 @@ void main() { // Intentionally blank. We only care about existence of a callback. }); - extension.call(WaitUntilNoTransientCallbacks().serialize()) + extension.call(const WaitUntilNoTransientCallbacks().serialize()) .then(expectAsync1((Map r) { result = r; })); @@ -66,7 +66,7 @@ void main() { testWidgets('handler', (WidgetTester tester) async { expect(log, isEmpty); - final dynamic result = RequestDataResult.fromJson((await extension.call(RequestData('hello').serialize()))['response']); + final dynamic result = RequestDataResult.fromJson((await extension.call(const RequestData('hello').serialize()))['response']); expect(log, ['hello']); expect(result.message, '1'); }); @@ -83,7 +83,7 @@ void main() { await tester.pumpWidget( const Text('hello', textDirection: TextDirection.ltr)); - final Map arguments = GetSemanticsId(ByText('hello')).serialize(); + final Map arguments = GetSemanticsId(const ByText('hello')).serialize(); final GetSemanticsIdResult result = GetSemanticsIdResult.fromJson((await extension.call(arguments))['response']); expect(result.id, 1); @@ -94,7 +94,7 @@ void main() { await tester.pumpWidget( const Text('hello', textDirection: TextDirection.ltr)); - final Map arguments = GetSemanticsId(ByText('hello')).serialize(); + final Map arguments = GetSemanticsId(const ByText('hello')).serialize(); final Map response = await extension.call(arguments); expect(response['isError'], true); @@ -113,7 +113,7 @@ void main() { ), ); - final Map arguments = GetSemanticsId(ByText('hello')).serialize(); + final Map arguments = GetSemanticsId(const ByText('hello')).serialize(); final Map response = await extension.call(arguments); expect(response['isError'], true);