Add integration tests for utf8Encode/utf8Decode filters.
This commit is contained in:
parent
11a36d7b83
commit
b756e18468
|
|
@ -68,6 +68,7 @@ mod tests {
|
|||
);
|
||||
assert_eq!(ret.unwrap().unwrap(), Value::Bytes(bytes));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_filter_base64_decode_ko_invalid_characters() {
|
||||
let variables = VariableSet::new();
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ use crate::runner::filter::to_string::eval_to_string;
|
|||
use crate::runner::filter::url_decode::eval_url_decode;
|
||||
use crate::runner::filter::url_encode::eval_url_encode;
|
||||
use crate::runner::filter::url_query_param::eval_url_query_param;
|
||||
use crate::runner::filter::utf8_decode::eval_utf8_decode;
|
||||
use crate::runner::filter::utf8_encode::eval_utf8_encode;
|
||||
use crate::runner::filter::xpath::eval_xpath;
|
||||
use crate::runner::{RunnerError, RunnerErrorKind, Value, VariableSet};
|
||||
|
||||
|
|
@ -78,39 +80,40 @@ pub fn eval_filter(
|
|||
variables: &VariableSet,
|
||||
in_assert: bool,
|
||||
) -> Result<Option<Value>, RunnerError> {
|
||||
let source_info = filter.source_info;
|
||||
match &filter.value {
|
||||
FilterValue::Base64Decode => eval_base64_decode(value, filter.source_info, in_assert),
|
||||
FilterValue::Base64Encode => eval_base64_encode(value, filter.source_info, in_assert),
|
||||
FilterValue::Base64Decode => eval_base64_decode(value, source_info, in_assert),
|
||||
FilterValue::Base64Encode => eval_base64_encode(value, source_info, in_assert),
|
||||
FilterValue::Base64UrlSafeDecode => {
|
||||
eval_base64_url_safe_decode(value, filter.source_info, in_assert)
|
||||
eval_base64_url_safe_decode(value, source_info, in_assert)
|
||||
}
|
||||
FilterValue::Base64UrlSafeEncode => {
|
||||
eval_base64_url_safe_encode(value, filter.source_info, in_assert)
|
||||
eval_base64_url_safe_encode(value, source_info, in_assert)
|
||||
}
|
||||
FilterValue::Count => eval_count(value, filter.source_info, in_assert),
|
||||
FilterValue::DaysAfterNow => eval_days_after_now(value, filter.source_info, in_assert),
|
||||
FilterValue::DaysBeforeNow => eval_days_before_now(value, filter.source_info, in_assert),
|
||||
FilterValue::Count => eval_count(value, source_info, in_assert),
|
||||
FilterValue::DaysAfterNow => eval_days_after_now(value, source_info, in_assert),
|
||||
FilterValue::DaysBeforeNow => eval_days_before_now(value, source_info, in_assert),
|
||||
FilterValue::Decode { encoding, .. } => {
|
||||
eval_decode(value, encoding, variables, filter.source_info, in_assert)
|
||||
eval_decode(value, encoding, variables, source_info, in_assert)
|
||||
}
|
||||
FilterValue::First => eval_first(value, filter.source_info, in_assert),
|
||||
FilterValue::First => eval_first(value, source_info, in_assert),
|
||||
FilterValue::Format { fmt, .. } => {
|
||||
eval_date_format(value, fmt, variables, filter.source_info, in_assert)
|
||||
eval_date_format(value, fmt, variables, source_info, in_assert)
|
||||
}
|
||||
FilterValue::DateFormat { fmt, .. } => {
|
||||
eval_date_format(value, fmt, variables, filter.source_info, in_assert)
|
||||
eval_date_format(value, fmt, variables, source_info, in_assert)
|
||||
}
|
||||
FilterValue::HtmlEscape => eval_html_escape(value, filter.source_info, in_assert),
|
||||
FilterValue::HtmlUnescape => eval_html_unescape(value, filter.source_info, in_assert),
|
||||
FilterValue::HtmlEscape => eval_html_escape(value, source_info, in_assert),
|
||||
FilterValue::HtmlUnescape => eval_html_unescape(value, source_info, in_assert),
|
||||
FilterValue::JsonPath { expr, .. } => {
|
||||
eval_jsonpath(value, expr, variables, filter.source_info, in_assert)
|
||||
eval_jsonpath(value, expr, variables, source_info, in_assert)
|
||||
}
|
||||
FilterValue::Last => eval_last(value, filter.source_info, in_assert),
|
||||
FilterValue::Location => eval_location(value, filter.source_info, in_assert),
|
||||
FilterValue::Last => eval_last(value, source_info, in_assert),
|
||||
FilterValue::Location => eval_location(value, source_info, in_assert),
|
||||
FilterValue::Regex {
|
||||
value: regex_value, ..
|
||||
} => eval_regex(value, regex_value, variables, filter.source_info, in_assert),
|
||||
FilterValue::Nth { n, .. } => eval_nth(value, n, variables, filter.source_info, in_assert),
|
||||
} => eval_regex(value, regex_value, variables, source_info, in_assert),
|
||||
FilterValue::Nth { n, .. } => eval_nth(value, n, variables, source_info, in_assert),
|
||||
FilterValue::Replace {
|
||||
old_value,
|
||||
new_value,
|
||||
|
|
@ -118,38 +121,31 @@ pub fn eval_filter(
|
|||
} => eval_replace(
|
||||
value,
|
||||
variables,
|
||||
filter.source_info,
|
||||
source_info,
|
||||
in_assert,
|
||||
old_value,
|
||||
new_value,
|
||||
),
|
||||
FilterValue::ReplaceRegex {
|
||||
pattern, new_value, ..
|
||||
} => eval_replace_regex(
|
||||
value,
|
||||
variables,
|
||||
filter.source_info,
|
||||
in_assert,
|
||||
pattern,
|
||||
new_value,
|
||||
),
|
||||
FilterValue::Split { sep, .. } => {
|
||||
eval_split(value, variables, filter.source_info, in_assert, sep)
|
||||
}
|
||||
} => eval_replace_regex(value, variables, source_info, in_assert, pattern, new_value),
|
||||
FilterValue::Split { sep, .. } => eval_split(value, variables, source_info, in_assert, sep),
|
||||
FilterValue::ToDate { fmt, .. } => {
|
||||
eval_to_date(value, fmt, variables, filter.source_info, in_assert)
|
||||
eval_to_date(value, fmt, variables, source_info, in_assert)
|
||||
}
|
||||
FilterValue::ToFloat => eval_to_float(value, filter.source_info, in_assert),
|
||||
FilterValue::ToHex => eval_to_hex(value, filter.source_info, in_assert),
|
||||
FilterValue::ToInt => eval_to_int(value, filter.source_info, in_assert),
|
||||
FilterValue::ToString => eval_to_string(value, filter.source_info, in_assert),
|
||||
FilterValue::UrlDecode => eval_url_decode(value, filter.source_info, in_assert),
|
||||
FilterValue::UrlEncode => eval_url_encode(value, filter.source_info, in_assert),
|
||||
FilterValue::ToFloat => eval_to_float(value, source_info, in_assert),
|
||||
FilterValue::ToHex => eval_to_hex(value, source_info, in_assert),
|
||||
FilterValue::ToInt => eval_to_int(value, source_info, in_assert),
|
||||
FilterValue::ToString => eval_to_string(value, source_info, in_assert),
|
||||
FilterValue::UrlDecode => eval_url_decode(value, source_info, in_assert),
|
||||
FilterValue::UrlEncode => eval_url_encode(value, source_info, in_assert),
|
||||
FilterValue::UrlQueryParam { param, .. } => {
|
||||
eval_url_query_param(value, param, variables, filter.source_info, in_assert)
|
||||
eval_url_query_param(value, param, variables, source_info, in_assert)
|
||||
}
|
||||
FilterValue::Utf8Decode => eval_utf8_decode(value, source_info, in_assert),
|
||||
FilterValue::Utf8Encode => eval_utf8_encode(value, source_info, in_assert),
|
||||
FilterValue::XPath { expr, .. } => {
|
||||
eval_xpath(value, expr, variables, filter.source_info, in_assert)
|
||||
eval_xpath(value, expr, variables, source_info, in_assert)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,4 +49,6 @@ mod to_string;
|
|||
mod url_decode;
|
||||
mod url_encode;
|
||||
mod url_query_param;
|
||||
mod utf8_decode;
|
||||
mod utf8_encode;
|
||||
mod xpath;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Hurl (https://hurl.dev)
|
||||
* Copyright (C) 2025 Orange
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
use crate::runner::{RunnerError, RunnerErrorKind, Value};
|
||||
use hurl_core::ast::SourceInfo;
|
||||
|
||||
pub fn eval_utf8_decode(
|
||||
value: &Value,
|
||||
source_info: SourceInfo,
|
||||
assert: bool,
|
||||
) -> Result<Option<Value>, RunnerError> {
|
||||
match value {
|
||||
Value::Bytes(value) => {
|
||||
let decoded = String::from_utf8_lossy(value);
|
||||
Ok(Some(Value::String(decoded.to_string())))
|
||||
}
|
||||
v => {
|
||||
let kind = RunnerErrorKind::FilterInvalidInput(v.kind().to_string());
|
||||
Err(RunnerError::new(source_info, kind, assert))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::runner::Number;
|
||||
use hurl_core::ast::SourceInfo;
|
||||
use hurl_core::reader::Pos;
|
||||
|
||||
#[test]
|
||||
fn eval_filter_utf8_decode_ok() {
|
||||
let datas = [
|
||||
(b"Hello World".to_vec(), "Hello World"),
|
||||
// With some replacements for invalid UTF-8 bytes
|
||||
(b"Hello \xF0\x90\x80World".to_vec(), "Hello <20>World"),
|
||||
// With emojis
|
||||
(
|
||||
b"\xF0\x9F\x8D\x8E\xF0\x9F\x8D\x8C\xF0\x9F\x8D\x90\xF0\x9F\x8D\x8A".to_vec(),
|
||||
"🍎🍌🍐🍊",
|
||||
),
|
||||
];
|
||||
let source_info = SourceInfo::new(Pos::new(1, 1), Pos::new(1, 10));
|
||||
|
||||
for (bytes, expected) in datas {
|
||||
let ret = eval_utf8_decode(&Value::Bytes(bytes), source_info, false);
|
||||
assert_eq!(ret.unwrap().unwrap(), Value::String(expected.to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_filter_utf8_decode_failed() {
|
||||
let source_info = SourceInfo::new(Pos::new(1, 1), Pos::new(1, 10));
|
||||
let ret = eval_utf8_decode(&Value::Number(Number::Integer(42)), source_info, false);
|
||||
assert!(ret.is_err());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Hurl (https://hurl.dev)
|
||||
* Copyright (C) 2025 Orange
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
use crate::runner::{RunnerError, RunnerErrorKind, Value};
|
||||
use hurl_core::ast::SourceInfo;
|
||||
|
||||
pub fn eval_utf8_encode(
|
||||
value: &Value,
|
||||
source_info: SourceInfo,
|
||||
assert: bool,
|
||||
) -> Result<Option<Value>, RunnerError> {
|
||||
match value {
|
||||
Value::String(value) => {
|
||||
let encoded = value.bytes().collect::<Vec<_>>();
|
||||
Ok(Some(Value::Bytes(encoded)))
|
||||
}
|
||||
v => {
|
||||
let kind = RunnerErrorKind::FilterInvalidInput(v.kind().to_string());
|
||||
Err(RunnerError::new(source_info, kind, assert))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -365,6 +365,8 @@ pub enum FilterValue {
|
|||
space0: Whitespace,
|
||||
param: Template,
|
||||
},
|
||||
Utf8Decode,
|
||||
Utf8Encode,
|
||||
XPath {
|
||||
space0: Whitespace,
|
||||
expr: Template,
|
||||
|
|
@ -404,6 +406,8 @@ impl FilterValue {
|
|||
FilterValue::UrlDecode => "urlDecode",
|
||||
FilterValue::UrlEncode => "urlEncode",
|
||||
FilterValue::UrlQueryParam { .. } => "urlQueryParam",
|
||||
FilterValue::Utf8Decode => "utf8Decode",
|
||||
FilterValue::Utf8Encode => "utf8Encode",
|
||||
FilterValue::XPath { .. } => "xpath",
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -485,17 +485,19 @@ pub fn walk_filter<V: Visitor>(visitor: &mut V, filter: &Filter) {
|
|||
FilterValue::ToFloat => {}
|
||||
FilterValue::ToHex => {}
|
||||
FilterValue::ToInt => {}
|
||||
FilterValue::ToString => {}
|
||||
FilterValue::UrlDecode => {}
|
||||
FilterValue::UrlEncode => {}
|
||||
FilterValue::XPath { space0, expr } => {
|
||||
visitor.visit_whitespace(space0);
|
||||
visitor.visit_template(expr);
|
||||
}
|
||||
FilterValue::ToString => {}
|
||||
FilterValue::UrlQueryParam { space0, param } => {
|
||||
visitor.visit_whitespace(space0);
|
||||
visitor.visit_template(param);
|
||||
}
|
||||
FilterValue::Utf8Decode => {}
|
||||
FilterValue::Utf8Encode => {}
|
||||
FilterValue::XPath { space0, expr } => {
|
||||
visitor.visit_whitespace(space0);
|
||||
visitor.visit_template(expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,8 @@ pub fn filter(reader: &mut Reader) -> ParseResult<Filter> {
|
|||
url_decode_filter,
|
||||
url_encode_filter,
|
||||
url_query_param_filter,
|
||||
utf8_decode_filter,
|
||||
utf8_encode_filter,
|
||||
xpath_filter,
|
||||
],
|
||||
reader,
|
||||
|
|
|
|||
|
|
@ -324,7 +324,9 @@ impl Lint for FilterValue {
|
|||
| FilterValue::ToInt
|
||||
| FilterValue::ToString
|
||||
| FilterValue::UrlDecode
|
||||
| FilterValue::UrlEncode => {}
|
||||
| FilterValue::UrlEncode
|
||||
| FilterValue::Utf8Decode
|
||||
| FilterValue::Utf8Encode => {}
|
||||
}
|
||||
s
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue