Commit 625dc8a9 authored by Yegor's avatar Yegor

Merge pull request #2364 from yjbanov/driver-command-type-hierarchy

[driver] serialize commands to plain strings
parents 017b4230 008785be
...@@ -148,9 +148,9 @@ class FlutterDriver { ...@@ -148,9 +148,9 @@ class FlutterDriver {
final VMIsolateRef _appIsolate; final VMIsolateRef _appIsolate;
Future<Map<String, dynamic>> _sendCommand(Command command) async { Future<Map<String, dynamic>> _sendCommand(Command command) async {
Map<String, dynamic> json = <String, dynamic>{'command': command.kind} Map<String, String> parameters = <String, String>{'command': command.kind}
..addAll(command.toJson()); ..addAll(command.serialize());
return _appIsolate.invokeExtension(_kFlutterExtensionMethod, json) return _appIsolate.invokeExtension(_kFlutterExtensionMethod, parameters)
.then((Map<String, dynamic> result) => result, onError: (error, stackTrace) { .then((Map<String, dynamic> result) => result, onError: (error, stackTrace) {
throw new DriverError( throw new DriverError(
'Failed to fulfill ${command.runtimeType} due to remote error', 'Failed to fulfill ${command.runtimeType} due to remote error',
......
...@@ -60,11 +60,11 @@ class FlutterDriverExtension { ...@@ -60,11 +60,11 @@ class FlutterDriverExtension {
}; };
_commandDeserializers = { _commandDeserializers = {
'get_health': GetHealth.fromJson, 'get_health': GetHealth.deserialize,
'find': Find.fromJson, 'find': Find.deserialize,
'tap': Tap.fromJson, 'tap': Tap.deserialize,
'get_text': GetText.fromJson, 'get_text': GetText.deserialize,
'scroll': Scroll.fromJson, 'scroll': Scroll.deserialize,
}; };
} }
......
...@@ -15,10 +15,10 @@ class Find extends Command { ...@@ -15,10 +15,10 @@ class Find extends Command {
final SearchSpecification searchSpec; final SearchSpecification searchSpec;
Map<String, dynamic> toJson() => searchSpec.toJson(); Map<String, String> serialize() => searchSpec.serialize();
static Find fromJson(Map<String, dynamic> json) { static Find deserialize(Map<String, String> json) {
return new Find(SearchSpecification.fromJson(json)); return new Find(SearchSpecification.deserialize(json));
} }
static _throwInvalidKeyValueType(String invalidType) { static _throwInvalidKeyValueType(String invalidType) {
...@@ -27,20 +27,20 @@ class Find extends Command { ...@@ -27,20 +27,20 @@ class Find extends Command {
} }
/// Describes how to the driver should search for elements. /// Describes how to the driver should search for elements.
abstract class SearchSpecification extends Message { abstract class SearchSpecification {
String get searchSpecType; String get searchSpecType;
static SearchSpecification fromJson(Map<String, dynamic> json) { static SearchSpecification deserialize(Map<String, String> json) {
String searchSpecType = json['searchSpecType']; String searchSpecType = json['searchSpecType'];
switch(searchSpecType) { switch(searchSpecType) {
case 'ByValueKey': return ByValueKey.fromJson(json); case 'ByValueKey': return ByValueKey.deserialize(json);
case 'ByTooltipMessage': return ByTooltipMessage.fromJson(json); case 'ByTooltipMessage': return ByTooltipMessage.deserialize(json);
case 'ByText': return ByText.fromJson(json); case 'ByText': return ByText.deserialize(json);
} }
throw new DriverError('Unsupported search specification type $searchSpecType'); throw new DriverError('Unsupported search specification type $searchSpecType');
} }
Map<String, dynamic> toJson() => { Map<String, String> serialize() => {
'searchSpecType': searchSpecType, 'searchSpecType': searchSpecType,
}; };
} }
...@@ -54,11 +54,11 @@ class ByTooltipMessage extends SearchSpecification { ...@@ -54,11 +54,11 @@ class ByTooltipMessage extends SearchSpecification {
/// Tooltip message text. /// Tooltip message text.
final String text; final String text;
Map<String, dynamic> toJson() => super.toJson()..addAll({ Map<String, String> serialize() => super.serialize()..addAll({
'text': text, 'text': text,
}); });
static ByTooltipMessage fromJson(Map<String, dynamic> json) { static ByTooltipMessage deserialize(Map<String, String> json) {
return new ByTooltipMessage(json['text']); return new ByTooltipMessage(json['text']);
} }
} }
...@@ -71,11 +71,11 @@ class ByText extends SearchSpecification { ...@@ -71,11 +71,11 @@ class ByText extends SearchSpecification {
final String text; final String text;
Map<String, dynamic> toJson() => super.toJson()..addAll({ Map<String, String> serialize() => super.serialize()..addAll({
'text': text, 'text': text,
}); });
static ByText fromJson(Map<String, dynamic> json) { static ByText deserialize(Map<String, String> json) {
return new ByText(json['text']); return new ByText(json['text']);
} }
} }
...@@ -103,12 +103,12 @@ class ByValueKey extends SearchSpecification { ...@@ -103,12 +103,12 @@ class ByValueKey extends SearchSpecification {
/// May be one of "String", "int". The list of supported types may change. /// May be one of "String", "int". The list of supported types may change.
final String keyValueType; final String keyValueType;
Map<String, dynamic> toJson() => super.toJson()..addAll({ Map<String, String> serialize() => super.serialize()..addAll({
'keyValueString': keyValueString, 'keyValueString': keyValueString,
'keyValueType': keyValueType, 'keyValueType': keyValueType,
}); });
static ByValueKey fromJson(Map<String, dynamic> json) { static ByValueKey deserialize(Map<String, String> json) {
String keyValueString = json['keyValueString']; String keyValueString = json['keyValueString'];
String keyValueType = json['keyValueType']; String keyValueType = json['keyValueType'];
switch(keyValueType) { switch(keyValueType) {
...@@ -130,14 +130,14 @@ class ByValueKey extends SearchSpecification { ...@@ -130,14 +130,14 @@ class ByValueKey extends SearchSpecification {
class GetText extends CommandWithTarget { class GetText extends CommandWithTarget {
final String kind = 'get_text'; final String kind = 'get_text';
static GetText fromJson(Map<String, dynamic> json) { static GetText deserialize(Map<String, String> json) {
return new GetText(new ObjectRef(json['targetRef'])); return new GetText(new ObjectRef(json['targetRef']));
} }
/// [targetRef] identifies an element that contains a piece of text. /// [targetRef] identifies an element that contains a piece of text.
GetText(ObjectRef targetRef) : super(targetRef); GetText(ObjectRef targetRef) : super(targetRef);
Map<String, dynamic> toJson() => super.toJson(); Map<String, String> serialize() => super.serialize();
} }
class GetTextResult extends Result { class GetTextResult extends Result {
......
...@@ -9,11 +9,11 @@ class Tap extends CommandWithTarget { ...@@ -9,11 +9,11 @@ class Tap extends CommandWithTarget {
Tap(ObjectRef targetRef) : super(targetRef); Tap(ObjectRef targetRef) : super(targetRef);
static Tap fromJson(Map<String, dynamic> json) { static Tap deserialize(Map<String, String> json) {
return new Tap(new ObjectRef(json['targetRef'])); return new Tap(new ObjectRef(json['targetRef']));
} }
Map<String, dynamic> toJson() => super.toJson(); Map<String, String> serialize() => super.serialize();
} }
class TapResult extends Result { class TapResult extends Result {
...@@ -37,7 +37,7 @@ class Scroll extends CommandWithTarget { ...@@ -37,7 +37,7 @@ class Scroll extends CommandWithTarget {
this.frequency this.frequency
) : super(targetRef); ) : super(targetRef);
static Scroll fromJson(Map<String, dynamic> json) { static Scroll deserialize(Map<String, dynamic> json) {
return new Scroll( return new Scroll(
new ObjectRef(json['targetRef']), new ObjectRef(json['targetRef']),
double.parse(json['dx']), double.parse(json['dx']),
...@@ -59,11 +59,11 @@ class Scroll extends CommandWithTarget { ...@@ -59,11 +59,11 @@ class Scroll extends CommandWithTarget {
/// The frequency in Hz of the generated move events. /// The frequency in Hz of the generated move events.
final int frequency; final int frequency;
Map<String, dynamic> toJson() => super.toJson()..addAll({ Map<String, String> serialize() => super.serialize()..addAll({
'dx': dx, 'dx': '$dx',
'dy': dy, 'dy': '$dy',
'duration': duration.inMicroseconds, 'duration': '${duration.inMicroseconds}',
'frequency': frequency, 'frequency': '$frequency',
}); });
} }
......
...@@ -9,9 +9,9 @@ import 'message.dart'; ...@@ -9,9 +9,9 @@ import 'message.dart';
class GetHealth implements Command { class GetHealth implements Command {
final String kind = 'get_health'; final String kind = 'get_health';
static fromJson(Map<String, dynamic> json) => new GetHealth(); static deserialize(Map<String, String> json) => new GetHealth();
Map<String, dynamic> toJson() => const {}; Map<String, String> serialize() => const {};
} }
/// Application health status. /// Application health status.
......
...@@ -4,22 +4,22 @@ ...@@ -4,22 +4,22 @@
import 'error.dart'; import 'error.dart';
/// A piece of data travelling between Flutter Driver and a Flutter application. /// An object sent from the Flutter Driver to a Flutter application to instruct
abstract class Message { /// the application to perform a task.
/// Serializes this message to a JSON map. abstract class Command {
Map<String, dynamic> toJson();
}
/// A message that travels from the Flutter Driver to a Flutter application to
/// instruct the application to perform a task.
abstract class Command extends Message {
/// Identifies the type of the command object and of the handler. /// Identifies the type of the command object and of the handler.
String get kind; String get kind;
/// Serializes this command to parameter name/value pairs.
Map<String, String> serialize();
} }
/// A message sent from a Flutter application back to the Flutter Driver in /// An object sent from a Flutter application back to the Flutter Driver in
/// response to a command. /// response to a command.
abstract class Result extends Message { } abstract class Result {
/// Serializes this message to a JSON map.
Map<String, dynamic> toJson();
}
/// A serializable reference to an object that lives in the application isolate. /// A serializable reference to an object that lives in the application isolate.
class ObjectRef extends Result { class ObjectRef extends Result {
...@@ -47,7 +47,7 @@ class ObjectRef extends Result { ...@@ -47,7 +47,7 @@ class ObjectRef extends Result {
/// A command aimed at an object represented by [targetRef]. /// A command aimed at an object represented by [targetRef].
/// ///
/// Implementations must provide a concrete [kind]. If additional data is /// Implementations must provide a concrete [kind]. If additional data is
/// required beyond the [targetRef] the implementation may override [toJson] /// required beyond the [targetRef] the implementation may override [serialize]
/// and add more keys to the returned map. /// and add more keys to the returned map.
abstract class CommandWithTarget extends Command { abstract class CommandWithTarget extends Command {
CommandWithTarget(ObjectRef ref) : this.targetRef = ref?.objectReferenceKey { CommandWithTarget(ObjectRef ref) : this.targetRef = ref?.objectReferenceKey {
...@@ -66,10 +66,10 @@ abstract class CommandWithTarget extends Command { ...@@ -66,10 +66,10 @@ abstract class CommandWithTarget extends Command {
/// ///
/// Example: /// Example:
/// ///
/// Map<String, dynamic> toJson() => super.toJson()..addAll({ /// Map<String, String> toJson() => super.toJson()..addAll({
/// 'foo': this.foo, /// 'foo': this.foo,
/// }); /// });
Map<String, dynamic> toJson() => { Map<String, String> serialize() => <String, String>{
'targetRef': targetRef, 'targetRef': targetRef,
}; };
} }
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