Bug 1564417 - Add first response types to Marionette crate. r=ato

Differential Revision: https://phabricator.services.mozilla.com/D38322

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nupur Baghel 2019-07-18 13:15:16 +00:00
Родитель 1e51ee6ad5
Коммит 1dc247d75c
4 изменённых файлов: 153 добавлений и 6 удалений

Просмотреть файл

@ -3,6 +3,7 @@ pub mod error;
pub mod common; pub mod common;
pub mod marionette; pub mod marionette;
pub mod message; pub mod message;
pub mod result;
pub mod webdriver; pub mod webdriver;
#[cfg(test)] #[cfg(test)]

Просмотреть файл

@ -6,6 +6,7 @@ use std::fmt;
use crate::error::MarionetteError; use crate::error::MarionetteError;
use crate::marionette; use crate::marionette;
use crate::result::MarionetteResult;
use crate::webdriver; use crate::webdriver;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -47,7 +48,6 @@ enum MessageDirection {
} }
type MessageId = u32; type MessageId = u32;
type Payload = Map<String, Value>;
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
struct Request(MessageId, Command); struct Request(MessageId, Command);
@ -85,7 +85,7 @@ impl Serialize for Request {
enum Response { enum Response {
Result { Result {
id: MessageId, id: MessageId,
result: Payload, result: MarionetteResult,
}, },
Error { Error {
id: MessageId, id: MessageId,
@ -172,7 +172,7 @@ impl<'de> Visitor<'de> for MessageVisitor {
.ok_or_else(|| de::Error::invalid_type(Unexpected::Unit, &self))?; .ok_or_else(|| de::Error::invalid_type(Unexpected::Unit, &self))?;
Response::Error { id, error } Response::Error { id, error }
} else { } else {
let result: Payload = seq let result: MarionetteResult = seq
.next_element()? .next_element()?
.ok_or_else(|| de::Error::invalid_length(3, &self))?; .ok_or_else(|| de::Error::invalid_length(3, &self))?;
Response::Result { id, result } Response::Result { id, result }
@ -269,9 +269,7 @@ mod tests {
#[test] #[test]
fn test_outgoing_result() { fn test_outgoing_result() {
let json = json!([1, 42, null, { "value": null }]); let json = json!([1, 42, null, { "value": null }]);
// TODO: payload is currently untyped let result = MarionetteResult::Null;
let mut result = Map::new();
result.insert("value".into(), Value::Null);
let msg = Message::Outgoing(Response::Result { id: 42, result }); let msg = Message::Outgoing(Response::Result { id: 42, result });
assert_ser_de(&msg, json); assert_ser_de(&msg, json);

Просмотреть файл

@ -0,0 +1,137 @@
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_json::Value;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct WebElement {
#[serde(rename = "element-6066-11e4-a52e-4f735466cecf")]
element: String,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Timeouts {
implicit: u64,
#[serde(rename = "pageLoad", alias = "page load")]
page_load: u64,
script: Option<u64>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum MarionetteResult {
#[serde(deserialize_with = "from_value", serialize_with = "to_value")]
String(String),
Timeouts(Timeouts),
#[serde(deserialize_with = "from_value", serialize_with = "to_value")]
WebElement(WebElement),
#[serde(deserialize_with = "from_value", serialize_with = "to_empty_value")]
Null,
}
fn to_value<T, S>(data: T, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: Serialize,
{
#[derive(Serialize)]
struct Wrapper<T> {
value: T,
}
Wrapper { value: data }.serialize(serializer)
}
fn to_empty_value<S>(serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
#[derive(Serialize)]
struct Wrapper {
value: Value,
}
Wrapper { value: Value::Null }.serialize(serializer)
}
fn from_value<'de, D, T>(deserializer: D) -> Result<T, D::Error>
where
D: Deserializer<'de>,
T: serde::de::DeserializeOwned,
T: std::fmt::Debug,
{
#[derive(Debug, Deserialize)]
struct Wrapper<T> {
value: T,
}
let w = Wrapper::deserialize(deserializer)?;
Ok(w.value)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test::{assert_de, assert_ser_de, ELEMENT_KEY};
use serde_json::json;
#[test]
fn test_web_element() {
let data = WebElement {
element: "foo".into(),
};
assert_ser_de(&data, json!({"element-6066-11e4-a52e-4f735466cecf": "foo"}));
}
#[test]
fn test_timeouts() {
let data = Timeouts {
implicit: 1000,
page_load: 200000,
script: Some(60000),
};
assert_ser_de(
&data,
json!({"implicit":1000,"pageLoad":200000,"script":60000}),
);
assert_de(
&data,
json!({"implicit":1000,"page load":200000,"script":60000}),
);
}
#[test]
fn test_web_element_response() {
let data = WebElement {
element: "foo".into(),
};
assert_ser_de(
&MarionetteResult::WebElement(data),
json!({"value": {ELEMENT_KEY: "foo"}}),
);
}
#[test]
fn test_timeouts_response() {
let data = Timeouts {
implicit: 1000,
page_load: 200000,
script: Some(60000),
};
assert_ser_de(
&MarionetteResult::Timeouts(data),
json!({"implicit":1000,"pageLoad":200000,"script":60000}),
);
}
#[test]
fn test_string_response() {
assert_ser_de(
&MarionetteResult::String("foo".into()),
json!({"value": "foo"}),
);
}
#[test]
fn test_null_response() {
assert_ser_de(&MarionetteResult::Null, json!({ "value": null }));
}
}

Просмотреть файл

@ -1,3 +1,5 @@
pub static ELEMENT_KEY: &'static str = "element-6066-11e4-a52e-4f735466cecf";
pub fn assert_ser_de<T>(data: &T, json: serde_json::Value) pub fn assert_ser_de<T>(data: &T, json: serde_json::Value)
where where
T: std::fmt::Debug, T: std::fmt::Debug,
@ -18,3 +20,12 @@ where
{ {
assert_eq!(serde_json::to_value(data).unwrap(), json); assert_eq!(serde_json::to_value(data).unwrap(), json);
} }
pub fn assert_de<T>(data: &T, json: serde_json::Value)
where
T: std::fmt::Debug,
T: std::cmp::PartialEq,
T: serde::de::DeserializeOwned,
{
assert_eq!(data, &serde_json::from_value::<T>(json).unwrap());
}