diff --git a/integration/tests/assert_base64.json b/integration/tests/assert_base64.json index 599538430..484f838aa 100644 --- a/integration/tests/assert_base64.json +++ b/integration/tests/assert_base64.json @@ -1 +1 @@ -{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/assert-base64"},"response":{"version":"HTTP/1.0","status":200,"body":{"type":"base64","value":"bGluZTEKbGluZTINCmxpbmUzCg=="}}}]} +{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/assert-base64"},"response":{"version":"HTTP/1.0","status":200,"body":{"encoding":"base64","value":"bGluZTEKbGluZTINCmxpbmUzCg=="}}}]} \ No newline at end of file diff --git a/integration/tests/error_assert_base64.err b/integration/tests/error_assert_base64.err index d402bee51..5c023ea05 100644 --- a/integration/tests/error_assert_base64.err +++ b/integration/tests/error_assert_base64.err @@ -2,6 +2,6 @@ error: Assert Body Value --> tests/error_assert_base64.hurl:12:8 | 12 | base64,bGluZTEKbGluZTIKbGluZTMK; - | ^^^^^^^^^^^^^^^^^^^^^^^^ actual value is + | ^^^^^^^^^^^^^^^^^^^^^^^^ actual value is | diff --git a/integration/tests/error_assert_base64.json b/integration/tests/error_assert_base64.json index a7ed55d17..b24d88430 100644 --- a/integration/tests/error_assert_base64.json +++ b/integration/tests/error_assert_base64.json @@ -1 +1 @@ -{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/assert-base64"},"response":{"version":"HTTP/1.0","status":200,"body":{"type":"base64","value":"bGluZTEKbGluZTIKbGluZTMK"}}}]} +{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/assert-base64"},"response":{"version":"HTTP/1.0","status":200,"body":{"encoding":"base64","value":"bGluZTEKbGluZTIKbGluZTMK"}}}]} \ No newline at end of file diff --git a/integration/tests/error_assert_file.err b/integration/tests/error_assert_file.err index 23257d822..315a7c587 100644 --- a/integration/tests/error_assert_file.err +++ b/integration/tests/error_assert_file.err @@ -2,6 +2,6 @@ error: Assert Body Value --> tests/error_assert_file.hurl:8:1 | 8 | file,data.txt; - | ^ actual value is + | ^ actual value is | diff --git a/integration/tests/hello.curl b/integration/tests/hello.curl index d3a3c21c0..1cd196033 100644 --- a/integration/tests/hello.curl +++ b/integration/tests/hello.curl @@ -1,2 +1,4 @@ curl 'http://localhost:8000/hello' curl 'http://localhost:8000/hello' +curl 'http://localhost:8000/hello' +curl 'http://localhost:8000/hello' \ No newline at end of file diff --git a/integration/tests/hello.html b/integration/tests/hello.html index c0814e7c7..7cf95e9df 100644 --- a/integration/tests/hello.html +++ b/integration/tests/hello.html @@ -1 +1 @@ -
GET http://localhost:8000/hello
HTTP/1.0 200```Hello World!```
GET http://localhost:8000/hello
HTTP/1.0 200file, data.txt;
\ No newline at end of file +
GET http://localhost:8000/hello
HTTP/1.0 200```Hello World!```
GET http://localhost:8000/hello
HTTP/1.0 200file, data.txt;
GET http://localhost:8000/hello
HTTP/1.0 200hex, 48656c6c6f20576f726c6421;
GET http://localhost:8000/hello
HTTP/1.0 200base64, SGVsbG8gV29ybGQh;
\ No newline at end of file diff --git a/integration/tests/hello.hurl b/integration/tests/hello.hurl index db18048a6..15781894b 100644 --- a/integration/tests/hello.hurl +++ b/integration/tests/hello.hurl @@ -1,10 +1,15 @@ GET http://localhost:8000/hello - HTTP/1.0 200 ```Hello World!``` - GET http://localhost:8000/hello - HTTP/1.0 200 file, data.txt; + +GET http://localhost:8000/hello +HTTP/1.0 200 +hex, 48656c6c6f20576f726c6421; + +GET http://localhost:8000/hello +HTTP/1.0 200 +base64, SGVsbG8gV29ybGQh; diff --git a/integration/tests/hello.json b/integration/tests/hello.json index 16e8d05e3..8042874a9 100644 --- a/integration/tests/hello.json +++ b/integration/tests/hello.json @@ -1 +1 @@ -{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/hello"},"response":{"version":"HTTP/1.0","status":200,"body":{"type":"raw-string","value":"Hello World!"}}},{"request":{"method":"GET","url":"http://localhost:8000/hello"},"response":{"version":"HTTP/1.0","status":200,"body":{"type":"file","filename":"data.txt"}}}]} +{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/hello"},"response":{"version":"HTTP/1.0","status":200,"body":{"type":"raw-string","value":"Hello World!"}}},{"request":{"method":"GET","url":"http://localhost:8000/hello"},"response":{"version":"HTTP/1.0","status":200,"body":{"type":"file","filename":"data.txt"}}},{"request":{"method":"GET","url":"http://localhost:8000/hello"},"response":{"version":"HTTP/1.0","status":200,"body":{"encoding":"base64","value":"SGVsbG8gV29ybGQh"}}},{"request":{"method":"GET","url":"http://localhost:8000/hello"},"response":{"version":"HTTP/1.0","status":200,"body":{"encoding":"base64","value":"SGVsbG8gV29ybGQh"}}}]} \ No newline at end of file diff --git a/integration/tests/post_base64.json b/integration/tests/post_base64.json index c815dcb40..3517a16b4 100644 --- a/integration/tests/post_base64.json +++ b/integration/tests/post_base64.json @@ -1 +1 @@ -{"entries":[{"request":{"method":"POST","url":"http://localhost:8000/post-base64","body":{"type":"base64","value":"SGVsbG8gV29ybGQh"}},"response":{"version":"HTTP/1.0","status":200}}]} +{"entries":[{"request":{"method":"POST","url":"http://localhost:8000/post-base64","body":{"encoding":"base64","value":"SGVsbG8gV29ybGQh"}},"response":{"version":"HTTP/1.0","status":200}}]} \ No newline at end of file diff --git a/integration/tests/post_bytes.json b/integration/tests/post_bytes.json index 044a16656..612f638c5 100644 --- a/integration/tests/post_bytes.json +++ b/integration/tests/post_bytes.json @@ -1 +1 @@ -{"entries":[{"request":{"method":"POST","url":"http://localhost:8000/post-bytes","headers":[{"name":"Content-Type","value":"application/octet-stream"}],"body":{"type":"base64","value":"AQID"}},"response":{"version":"HTTP/1.0","status":200}}]} +{"entries":[{"request":{"method":"POST","url":"http://localhost:8000/post-bytes","headers":[{"name":"Content-Type","value":"application/octet-stream"}],"body":{"encoding":"base64","value":"AQID"}},"response":{"version":"HTTP/1.0","status":200}}]} \ No newline at end of file diff --git a/packages/hurl/src/runner/body.rs b/packages/hurl/src/runner/body.rs index ea7cd7cee..c5641d942 100644 --- a/packages/hurl/src/runner/body.rs +++ b/packages/hurl/src/runner/body.rs @@ -52,10 +52,8 @@ pub fn eval_bytes( Ok(http::Body::Text(value)) } - // Body:: Binary Bytes::Base64(Base64 { value, .. }) => Ok(http::Body::Binary(value)), - - // Body::File + Bytes::Hex(Hex { value, .. }) => Ok(http::Body::Binary(value)), Bytes::File(File { filename, .. }) => { let f = filename.value.as_str(); let path = Path::new(f); diff --git a/packages/hurl/src/runner/response.rs b/packages/hurl/src/runner/response.rs index ec1c8f418..5813037f5 100644 --- a/packages/hurl/src/runner/response.rs +++ b/packages/hurl/src/runner/response.rs @@ -188,6 +188,19 @@ pub fn eval_asserts( end: space1.source_info.start, }, }), + Bytes::Hex(Hex { + value, + space0, + space1, + .. + }) => asserts.push(AssertResult::Body { + actual: Ok(Value::Bytes(http_response.body.clone())), + expected: Ok(Value::Bytes(value)), + source_info: SourceInfo { + start: space0.source_info.end, + end: space1.source_info.start, + }, + }), Bytes::File { .. } => { let expected = match eval_body(body.clone(), variables, context_dir) { Ok(body) => Ok(Value::Bytes(body.bytes())), diff --git a/packages/hurl/src/runner/value.rs b/packages/hurl/src/runner/value.rs index f3039dc96..c1603b562 100644 --- a/packages/hurl/src/runner/value.rs +++ b/packages/hurl/src/runner/value.rs @@ -54,7 +54,7 @@ impl fmt::Display for Value { } Value::Object(_) => "Object()".to_string(), Value::Nodeset(x) => format!("Nodeset{:?}", x), - Value::Bytes(x) => format!("Bytes({:x?})", x), + Value::Bytes(v) => format!("hex, {};", hex::encode(v)), Value::Null => "null".to_string(), Value::Unit => "Unit".to_string(), }; diff --git a/packages/hurl_core/src/ast/core.rs b/packages/hurl_core/src/ast/core.rs index 4055175ce..1710e6bbe 100644 --- a/packages/hurl_core/src/ast/core.rs +++ b/packages/hurl_core/src/ast/core.rs @@ -570,6 +570,7 @@ pub enum Bytes { RawString(RawString), Base64(Base64), File(File), + Hex(Hex), } #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/packages/hurl_core/src/format/html.rs b/packages/hurl_core/src/format/html.rs index c63ed84a4..dba33cf64 100644 --- a/packages/hurl_core/src/format/html.rs +++ b/packages/hurl_core/src/format/html.rs @@ -664,6 +664,9 @@ impl Htmlable for Bytes { Bytes::Base64(value) => { buffer.push_str(value.to_html().as_str()); } + Bytes::Hex(value) => { + buffer.push_str(value.to_html().as_str()); + } Bytes::File(value) => { buffer.push_str(value.to_html().as_str()); } @@ -763,6 +766,18 @@ impl Htmlable for Base64 { buffer } } +impl Htmlable for Hex { + fn to_html(&self) -> String { + let mut buffer = String::from(""); + buffer.push_str("hex,"); + buffer.push_str(self.space0.to_html().as_str()); + buffer.push_str(self.encoded.as_str()); + buffer.push_str(self.space1.to_html().as_str()); + buffer.push(';'); + buffer.push_str(""); + buffer + } +} impl Htmlable for EncodedString { fn to_html(&self) -> String { diff --git a/packages/hurl_core/src/parser/bytes.rs b/packages/hurl_core/src/parser/bytes.rs index f6173d74c..80955e0dc 100644 --- a/packages/hurl_core/src/parser/bytes.rs +++ b/packages/hurl_core/src/parser/bytes.rs @@ -32,6 +32,7 @@ pub fn bytes(reader: &mut Reader) -> ParseResult<'static, Bytes> { json_bytes, xml_bytes, base64_bytes, + hex_bytes, file_bytes, ], reader, @@ -63,6 +64,10 @@ fn base64_bytes(reader: &mut Reader) -> ParseResult<'static, Bytes> { base64(reader).map(Bytes::Base64) } +fn hex_bytes(reader: &mut Reader) -> ParseResult<'static, Bytes> { + hex(reader).map(Bytes::Hex) +} + #[cfg(test)] mod tests { diff --git a/packages/hurlfmt/src/format/json.rs b/packages/hurlfmt/src/format/json.rs index 5b8232646..77b18307b 100644 --- a/packages/hurlfmt/src/format/json.rs +++ b/packages/hurlfmt/src/format/json.rs @@ -142,6 +142,7 @@ impl ToJson for Bytes { fn to_json(&self) -> JValue { match self { Bytes::Base64(value) => value.to_json(), + Bytes::Hex(value) => value.to_json(), Bytes::File(value) => value.to_json(), Bytes::Json { value } => JValue::Object(vec![ ("type".to_string(), JValue::String("json".to_string())), @@ -162,8 +163,22 @@ impl ToJson for Bytes { impl ToJson for Base64 { fn to_json(&self) -> JValue { JValue::Object(vec![ - ("type".to_string(), JValue::String("base64".to_string())), - ("value".to_string(), JValue::String(self.encoded.clone())), + ("encoding".to_string(), JValue::String("base64".to_string())), + ( + "value".to_string(), + JValue::String(base64::encode(&self.value)), + ), + ]) + } +} +impl ToJson for Hex { + fn to_json(&self) -> JValue { + JValue::Object(vec![ + ("encoding".to_string(), JValue::String("base64".to_string())), + ( + "value".to_string(), + JValue::String(base64::encode(&self.value)), + ), ]) } } diff --git a/packages/hurlfmt/src/format/token.rs b/packages/hurlfmt/src/format/token.rs index 94b965d4d..35e1c41fe 100644 --- a/packages/hurlfmt/src/format/token.rs +++ b/packages/hurlfmt/src/format/token.rs @@ -198,6 +198,9 @@ impl Tokenizable for Bytes { Bytes::Base64(value) => { tokens.append(&mut value.tokenize()); } + Bytes::Hex(value) => { + tokens.append(&mut value.tokenize()); + } Bytes::File(value) => { tokens.append(&mut value.tokenize()); } @@ -282,6 +285,17 @@ impl Tokenizable for Base64 { } } +impl Tokenizable for Hex { + fn tokenize(&self) -> Vec { + let mut tokens: Vec = vec![Token::Keyword(String::from("hex,"))]; + add_tokens(&mut tokens, self.space0.tokenize()); + tokens.push(Token::String(self.encoded.to_string())); + add_tokens(&mut tokens, self.space1.tokenize()); + tokens.push(Token::Keyword(String::from(";"))); + tokens + } +} + impl Tokenizable for File { fn tokenize(&self) -> Vec { let mut tokens: Vec = vec![Token::Keyword(String::from("file,"))]; diff --git a/packages/hurlfmt/src/linter/rules.rs b/packages/hurlfmt/src/linter/rules.rs index 7eaf4aeb9..3b326f109 100644 --- a/packages/hurlfmt/src/linter/rules.rs +++ b/packages/hurlfmt/src/linter/rules.rs @@ -560,6 +560,7 @@ impl Lintable for Bytes { match self { Bytes::File(value) => Bytes::File(value.lint()), Bytes::Base64(value) => Bytes::Base64(value.lint()), + Bytes::Hex(value) => Bytes::Hex(value.lint()), Bytes::Json { value } => Bytes::Json { value: value.clone(), }, @@ -586,6 +587,21 @@ impl Lintable for Base64 { } } +impl Lintable for Hex { + fn errors(&self) -> Vec { + unimplemented!() + } + + fn lint(&self) -> Hex { + Hex { + space0: one_whitespace(), + value: self.value.clone(), + encoded: self.encoded.clone(), + space1: empty_whitespace(), + } + } +} + impl Lintable for File { fn errors(&self) -> Vec { unimplemented!() @@ -688,20 +704,6 @@ fn one_whitespace() -> Whitespace { source_info: SourceInfo::init(0, 0, 0, 0), } } -impl Lintable for Hex { - fn errors(&self) -> Vec { - unimplemented!() - } - - fn lint(&self) -> Hex { - Hex { - space0: one_whitespace(), - value: self.value.clone(), - encoded: self.encoded.clone(), - space1: empty_whitespace(), - } - } -} impl Lintable for LineTerminator { fn errors(&self) -> Vec {