Skip to content

Commit

Permalink
Merge pull request #203 from Orange-OpenSource/feature/use-bytearray-…
Browse files Browse the repository at this point in the history
…in-assert

Add bytes query and equals predicate for bytearray
  • Loading branch information
fabricereix authored Jun 16, 2021
2 parents 45a3ab4 + 93c2fed commit 73acfcb
Show file tree
Hide file tree
Showing 16 changed files with 205 additions and 13 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion integration/tests/bytes.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<div class="hurl-file"><div class="hurl-entry"><div class="request"><span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/bytes</span></span></div><div class="response"><span class="line"><span class="version">HTTP/1.0</span> <span class="status">200</span></span><span class="line"><span class="string">Content-Type</span><span>:</span> <span class="string">application/octet-stream</span></span><span class="line section-header">[Asserts]</span></span></div></div><span class="line"><span class="comment">#TODO create a bytes query to get e byte array</span></span><span class="line"><span class="comment">#body countEquals 1</span></span><span class="line"></span><span class="line"></span><span class="line"></span></div>
<div class="hurl-file"><div class="hurl-entry"><div class="request"><span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/bytes</span></span></div><div class="response"><span class="line"><span class="version">HTTP/1.0</span> <span class="status">200</span></span><span class="line"><span class="string">Content-Type</span><span>:</span> <span class="string">application/octet-stream</span></span><span class="line section-header">[Asserts]</span></span><span class="line"><span class="query-type">bytes</span> <span class="predicate-type">equals</span> <span class="hex">hex,ff;</span></span><span class="line"><span class="query-type">bytes</span> <span class="predicate-type">equals</span> <span class="number">1</span></span></div></div><span class="line"></span></div>
6 changes: 2 additions & 4 deletions integration/tests/bytes.hurl
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ GET http://localhost:8000/bytes
HTTP/1.0 200
Content-Type: application/octet-stream
[Asserts]
#TODO create a bytes query to get e byte array
#body countEquals 1


bytes equals hex,ff;
bytes countEquals 1

2 changes: 1 addition & 1 deletion integration/tests/bytes.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/bytes"},"response":{"version":"HTTP/1.0","status":200,"headers":[{"name":"Content-Type","value":"application/octet-stream"}]}}]}
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/bytes"},"response":{"version":"HTTP/1.0","status":200,"headers":[{"name":"Content-Type","value":"application/octet-stream"}],"asserts":[{"query":{"type":"bytes"},"predicate":{"type":"equal","value":{"value":"/w==","encoding":"base64"}}},{"query":{"type":"bytes"},"predicate":{"type":"count","value":1}}]}}]}
17 changes: 17 additions & 0 deletions packages/hurl/src/runner/predicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ fn expected(
let expected = eval_template(expected, variables)?;
Ok(format!("string <{}>", expected))
}
PredicateFuncValue::EqualHex {
value: expected, ..
} => Ok(format!("bytearray <{}>", expected.to_string())),
PredicateFuncValue::EqualExpression {
value: expected, ..
} => {
Expand Down Expand Up @@ -326,6 +329,14 @@ fn eval_something(
Ok(assert_values_equal(value, Value::String(expected)))
}

// equals hex
PredicateFuncValue::EqualHex {
value: Hex {
value: expected, ..
},
..
} => Ok(assert_values_equal(value, Value::Bytes(expected))),

// equals expression
PredicateFuncValue::EqualExpression {
value: expected, ..
Expand Down Expand Up @@ -392,6 +403,12 @@ fn eval_something(
expected: expected_value.to_string(),
type_mismatch: false,
}),
Value::Bytes(data) => Ok(AssertResult {
success: data.len() as u64 == expected_value,
actual: data.len().to_string(),
expected: expected_value.to_string(),
type_mismatch: false,
}),
_ => Ok(AssertResult {
success: false,
actual: value.clone().display(),
Expand Down
19 changes: 19 additions & 0 deletions packages/hurl/src/runner/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ pub fn eval_query(
QueryValue::Duration {} => Ok(Some(Value::Integer(
http_response.duration.as_millis() as i64
))),
QueryValue::Bytes {} => Ok(Some(Value::Bytes(http_response.body))),
}
}

Expand Down Expand Up @@ -1006,4 +1007,22 @@ pub mod tests {
assert_eq!(error.source_info, SourceInfo::init(1, 7, 1, 10));
assert_eq!(error.inner, RunnerError::InvalidRegex());
}

#[test]
fn test_query_bytes() {
let variables = HashMap::new();
assert_eq!(
eval_query(
Query {
source_info: SourceInfo::init(0, 0, 0, 0),
value: QueryValue::Bytes {},
},
&variables,
http::hello_http_response(),
)
.unwrap()
.unwrap(),
Value::Bytes(String::into_bytes(String::from("Hello World!")))
);
}
}
10 changes: 10 additions & 0 deletions packages/hurl_core/src/ast/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ pub enum QueryValue {
name: Template,
},
Duration {},
Bytes {},
}

#[derive(Clone, Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -403,6 +404,7 @@ pub enum PredicateFuncValue {
EqualFloat { space0: Whitespace, value: Float },
EqualBool { space0: Whitespace, value: bool },
EqualNull { space0: Whitespace },
EqualHex { space0: Whitespace, value: Hex },
EqualExpression { space0: Whitespace, value: Expr },
GreaterThanInt { space0: Whitespace, value: i64 },
GreaterThanFloat { space0: Whitespace, value: Float },
Expand Down Expand Up @@ -528,6 +530,14 @@ pub enum Bytes {
},
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Hex {
pub space0: Whitespace,
pub value: Vec<u8>,
pub encoded: String,
pub space1: Whitespace,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Pos {
pub line: usize,
Expand Down
10 changes: 10 additions & 0 deletions packages/hurl_core/src/ast/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,16 @@ impl fmt::Display for CookieAttribute {
}
}

impl fmt::Display for Hex {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"hex,{}{}{};",
self.space0.value, self.encoded, self.space1.value
)
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
9 changes: 9 additions & 0 deletions packages/hurl_core/src/format/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,9 @@ impl Htmlable for QueryValue {
QueryValue::Duration {} => {
buffer.push_str("<span class=\"query-type\">duration</span>");
}
QueryValue::Bytes {} => {
buffer.push_str("<span class=\"query-type\">bytes</span>");
}
}
buffer
}
Expand Down Expand Up @@ -463,6 +466,12 @@ impl Htmlable for PredicateFuncValue {
format!("<span class=\"number\">{}</span>", value.to_string()).as_str(),
);
}
PredicateFuncValue::EqualHex { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">equals</span>");
buffer.push_str(space0.to_html().as_str());
buffer
.push_str(format!("<span class=\"hex\">{}</span>", value.to_string()).as_str());
}
PredicateFuncValue::GreaterThanInt { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">greaterThan</span>");
buffer.push_str(space0.to_html().as_str());
Expand Down
9 changes: 9 additions & 0 deletions packages/hurl_core/src/parser/predicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ fn equal_predicate(reader: &mut Reader) -> ParseResult<'static, PredicateFuncVal
Ok(PredicateValue::Bool { value }) => Ok(PredicateFuncValue::EqualBool { space0, value }),
Ok(PredicateValue::Int { value }) => Ok(PredicateFuncValue::EqualInt { space0, value }),
Ok(PredicateValue::Float { value }) => Ok(PredicateFuncValue::EqualFloat { space0, value }),
Ok(PredicateValue::Hex { value }) => Ok(PredicateFuncValue::EqualHex { space0, value }),
Ok(PredicateValue::Expression { value }) => {
Ok(PredicateFuncValue::EqualExpression { space0, value })
}
Expand Down Expand Up @@ -273,6 +274,9 @@ fn include_predicate(reader: &mut Reader) -> ParseResult<'static, PredicateFuncV
Ok(PredicateValue::Template { value }) => {
Ok(PredicateFuncValue::IncludeString { space0, value })
}
Ok(PredicateValue::Hex { value: _ }) => {
todo!()
}
Ok(PredicateValue::Expression { value }) => {
Ok(PredicateFuncValue::IncludeExpression { space0, value })
}
Expand Down Expand Up @@ -332,6 +336,7 @@ enum PredicateValue {
Float { value: Float },
Bool { value: bool },
Template { value: Template },
Hex { value: Hex },
Expression { value: Expr },
}

Expand All @@ -354,6 +359,10 @@ fn predicate_value(reader: &mut Reader) -> ParseResult<'static, PredicateValue>
Ok(value) => Ok(PredicateValue::Int { value }),
Err(e) => Err(e),
},
|p1| match hex(p1) {
Ok(value) => Ok(PredicateValue::Hex { value }),
Err(e) => Err(e),
},
|p1| match expr::parse(p1) {
Ok(value) => Ok(PredicateValue::Expression { value }),
Err(e) => Err(e),
Expand Down
87 changes: 80 additions & 7 deletions packages/hurl_core/src/parser/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,42 @@ pub fn key_value(reader: &mut Reader) -> ParseResult<'static, KeyValue> {
})
}

pub fn hex(reader: &mut Reader) -> ParseResult<'static, Hex> {
try_literal("hex", reader)?;
literal(",", reader)?;
let space0 = zero_or_more_spaces(reader)?;
let mut value: Vec<u8> = vec![];
let start = reader.state.cursor;
let mut current: i32 = -1;
loop {
let s = reader.state.clone();
match hex_digit(reader) {
Ok(d) => {
if current != -1 {
value.push((current * 16 + d as i32) as u8);
current = -1;
} else {
current = d as i32;
}
}
Err(_) => {
reader.state = s;
break;
}
};
}
let encoded = reader.from(start);
let space1 = zero_or_more_spaces(reader)?;
literal(";", reader)?;

Ok(Hex {
space0,
value,
encoded,
space1,
})
}

pub fn filename(reader: &mut Reader) -> ParseResult<'static, Filename> {
// this is an absolure file
// that you have to write with a relative name
Expand Down Expand Up @@ -882,7 +918,7 @@ mod tests {
Float {
int: 1,
decimal: 0,
decimal_digits: 1
decimal_digits: 1,
}
);
assert_eq!(reader.state.cursor, 3);
Expand All @@ -893,7 +929,7 @@ mod tests {
Float {
int: -1,
decimal: 0,
decimal_digits: 1
decimal_digits: 1,
}
);
assert_eq!(reader.state.cursor, 4);
Expand All @@ -904,7 +940,7 @@ mod tests {
Float {
int: 1,
decimal: 100_000_000_000_000_000,
decimal_digits: 1
decimal_digits: 1,
}
);
assert_eq!(reader.state.cursor, 3);
Expand All @@ -915,7 +951,7 @@ mod tests {
Float {
int: 1,
decimal: 100_000_000_000_000_000,
decimal_digits: 3
decimal_digits: 3,
}
);
assert_eq!(reader.state.cursor, 5);
Expand All @@ -926,7 +962,7 @@ mod tests {
Float {
int: 1,
decimal: 10_000_000_000_000_000,
decimal_digits: 2
decimal_digits: 2,
}
);
assert_eq!(reader.state.cursor, 4);
Expand All @@ -937,7 +973,7 @@ mod tests {
Float {
int: 1,
decimal: 10_000_000_000_000_000,
decimal_digits: 3
decimal_digits: 3,
}
);
assert_eq!(reader.state.cursor, 5);
Expand All @@ -948,7 +984,7 @@ mod tests {
Float {
int: 0,
decimal: 333_333_333_333_333_333,
decimal_digits: 18
decimal_digits: 18,
}
);
assert_eq!(reader.state.cursor, 21);
Expand Down Expand Up @@ -1254,4 +1290,41 @@ mod tests {
assert_eq!(error.inner, ParseError::HexDigit {});
assert_eq!(error.recoverable, true);
}

#[test]
fn test_hex() {
let mut reader = Reader::init("hex, ff;");
assert_eq!(
hex(&mut reader).unwrap(),
Hex {
space0: Whitespace {
value: " ".to_string(),
source_info: SourceInfo::init(1, 5, 1, 6)
},
value: vec![255],
encoded: "ff".to_string(),
space1: Whitespace {
value: "".to_string(),
source_info: SourceInfo::init(1, 8, 1, 8)
},
}
);

let mut reader = Reader::init("hex,010203 ;");
assert_eq!(
hex(&mut reader).unwrap(),
Hex {
space0: Whitespace {
value: "".to_string(),
source_info: SourceInfo::init(1, 5, 1, 5)
},
value: vec![1, 2, 3],
encoded: "010203".to_string(),
space1: Whitespace {
value: " ".to_string(),
source_info: SourceInfo::init(1, 11, 1, 12)
},
}
);
}
}
6 changes: 6 additions & 0 deletions packages/hurl_core/src/parser/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ fn query_value(reader: &mut Reader) -> ParseResult<'static, QueryValue> {
regex_query,
variable_query,
duration_query,
bytes_query,
],
reader,
)
Expand Down Expand Up @@ -154,6 +155,11 @@ fn duration_query(reader: &mut Reader) -> ParseResult<'static, QueryValue> {
Ok(QueryValue::Duration {})
}

fn bytes_query(reader: &mut Reader) -> ParseResult<'static, QueryValue> {
try_literal("bytes", reader)?;
Ok(QueryValue::Bytes {})
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
1 change: 1 addition & 0 deletions packages/hurlfmt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ strict = []

[dependencies]
atty = "0.2.13"
base64 = "0.11.0"
clap = "2.33.0"
colored = "2"
hurl_core = { version = "1.1.0", path = "../hurl_core" }
Expand Down
Loading

0 comments on commit 73acfcb

Please sign in to comment.