pub mod common;
use common::give;
use serde_json::json;
#[test]
fn add() {
give(json!({"a": 1, "b": 2}), "add", json!(3));
give(json!([[0, 1], [2, 3]]), "add", json!([0, 1, 2, 3]));
}
yields!(fromdate, r#""1970-01-02T00:00:00Z" | fromdate"#, 86400);
yields!(todate, r#"86400 | todate"#, "1970-01-02T00:00:00Z");
yields!(tofromdate, "946684800 | todate | fromdate", 946684800);
yields!(
drem_nan,
"[drem(nan, 1; nan, 1)] | (.[0:-1] | all(isnan)) and .[-1] == 0.0",
true
);
yields!(
drem_range,
"[drem(3.5, -4; 6, 1.75, 2)]",
[-2.5, 0.0, -0.5, 2.0, -0.5, -0.0]
);
#[test]
fn flatten() {
let a0 = || json!([1, [{"a": 2}, [3]]]);
let a1 = || json!([1, {"a": 2}, [3]]);
let a2 = || json!([1, {"a": 2}, 3]);
give(a0(), "flatten", json!(a2()));
let f = "[flatten(0, 1, 2, 3)]";
give(a0(), f, json!([a0(), a1(), a2(), a2()]));
}
yields!(
flatten_deep,
"[[[0], 1], 2, [3, [4]]] | flatten",
[0, 1, 2, 3, 4]
);
yields!(flatten_obj, "{a: 1} | flatten", json!([{"a": 1}]));
yields!(flatten_num, "0 | flatten", [0]);
yields!(isfinite_true, "all((0, 1, nan); isfinite)", true);
yields!(
isfinite_false,
"any((infinite, -infinite, []); isfinite)",
false
);
yields!(isnormal_true, "1 | isnormal", true);
yields!(
isnormal_false,
"any(0, nan, infinite, -infinite, []; isnormal)",
false
);
yields!(logb_inf, "infinite | logb | . == infinite", true);
yields!(logb_nan, "nan | logb | isnan", true);
yields!(logb_neg_inf, "-infinite | logb | . == infinite", true);
yields!(
logb_range,
"[-2.2, -2, -1, 1, 2, 2.2] | map(logb)",
[1.0, 1.0, 0.0, 0.0, 1.0, 1.0]
);
yields!(logb_zero, "0 | logb | . == -infinite", true);
yields!(
match_many,
r#""ABab" | [match("a", "b"; "", "i") | .string]"#,
["a", "A", "b", "B"]
);
#[test]
fn min_max() {
give(json!([1, 4, 2]), "min", json!(1));
give(json!([1, 4, 2]), "max", json!(4));
give(
json!([{"a": {"b": {"c": 1}}}, {"a": {"b": {"c": 4}}}, {"a": {"b": {"c": 2}}}]),
"min_by(.a.b.c)",
json!({"a": {"b": {"c": 1}}}),
);
give(
json!([{"a": {"b": {"c": 1}}}, {"a": {"b": {"c": 4}}}, {"a": {"b": {"c": 2}}}]),
"max_by(.a.b.c)",
json!({"a": {"b": {"c": 4}}}),
);
}
yields!(min_empty, "[] | min_by(.)", json!(null));
yields!(
min_max_eq,
"[{a: 1, b: 3}, {a: 1, b: 2}] | [(min_by(.a), max_by(.a)) | .b]",
[3, 2]
);
yields!(
max_mult,
"[{a: 1, b: 3}, {a: 1, b: 2}] | max_by(.a, .b) | .b",
3
);
#[test]
fn nth() {
let fib = "[0,1] | recurse([.[1], add]) | .[0]";
give(json!(10), &format!("nth(.; {})", fib), json!(55));
let fib = "[0,1] | recurse([.[1], add])[0]";
give(json!(10), &format!("nth(.; {})", fib), json!(55));
}
#[test]
fn range_reverse() {
give(json!(null), "[range(1, 2)]", json!([0, 0, 1]));
give(json!(3), "[range(.)] | reverse", json!([2, 1, 0]));
}
#[test]
fn recurse_arr() {
let x = json!([[[0], 1], 2, [3, [4]]]);
let y = json!([[[1], 2], 3, [4, [5]]]);
give(x.clone(), "(.. | scalars) |= .+1", y);
let f = ".. |= if . < [] then .+1 else . + [42] end";
let y = json!([[[1, 42], 2, 42], 3, [4, [5, 42], 42], 42]);
give(x.clone(), f, y);
let f = ".. |= if . < [] then .+1 else [42] + . end";
let y = json!([42, [42, [42, 1], 2], 3, [42, 4, [42, 5]]]);
give(x.clone(), f, y);
}
yields!(
recurse_fib_100,
"def fib: recurse([.[1], add])[0]; nth(100; [0, 1] | fib) | tostring",
"354224848179261915075"
);
yields!(
scalb_eqv_pow2,
"[-2.2, -1.1, -0.01, 0, 0.01, 1.1, 2.2] | [scalb(1.0; .[])] == [pow(2.0; .[])]",
true
);
yields!(
scalb_nan,
"[scalb(nan, 1; nan, 1)] | (.[0:-1] | all(isnan)) and .[-1] == 2.0",
true
);
yields!(
scalb_range,
"[scalb(-2.5, 0, 2.5; 2, 2.5, 3) * 1000 | round]",
[-10000, -14142, -20000, 0, 0, 0, 10000, 14142, 20000]
);
yields!(
scan,
r#""abAB" | [scan("a", "b"; "g", "gi")]"#,
json!(["a", "a", "A", "b", "b", "B"])
);
#[test]
fn select() {
give(json!([1, 2]), ".[] | select(.>1)", json!(2));
give(json!([0, 1, 2]), "map(select(.<1, 1<.))", json!([0, 2]));
let v = json!([null, false, true, 1, 1.0, "", "a", [], [0], {}, {"a": 1}]);
let iterables = json!([[], [0], {}, {"a": 1}]);
let scalars = json!([null, false, true, 1, 1.0, "", "a"]);
let values = json!([false, true, 1, 1.0, "", "a", [], [0], {}, {"a": 1}]);
give(v.clone(), ".[] | nulls", json!(null));
give(v.clone(), "[.[] | booleans]", json!([false, true]));
give(v.clone(), "[.[] | numbers]", json!([1, 1.0]));
give(v.clone(), "[.[] | strings]", json!(["", "a"]));
give(v.clone(), "[.[] | arrays]", json!([[], [0]]));
give(v.clone(), "[.[] | objects]", json!([{}, {"a": 1}]));
give(v.clone(), "[.[] | iterables]", iterables);
give(v.clone(), "[.[] | scalars]", scalars);
give(v.clone(), "[.[] | values]", values);
}
yields!(
significand_inf,
"infinite | significand | . == infinite",
true
);
yields!(significand_nan, "nan | significand | isnan", true);
yields!(
significand_neg_inf,
"-infinite | significand | . == -infinite",
true
);
yields!(
significand_range,
"[-123.456, -2.2, -2, -1, 0, 0.00001, 1, 2, 2.2, 123.456] | map(significand)",
[-1.929, -1.1, -1.0, -1.0, 0.0, 1.31072, 1.0, 1.0, 1.1, 1.929]
);
#[test]
fn typ() {
give(json!({"a": 1, "b": 2}), "type", json!("object"));
give(json!([0, 1]), "type", json!("array"));
give(json!("Hello"), "type", json!("string"));
give(json!(1), "type", json!("number"));
give(json!(1.0), "type", json!("number"));
give(json!(true), "type", json!("boolean"));
give(json!(null), "type", json!("null"));
}
yields!(sub, r#""XYxyXYxy" | sub("x";"Q")"#, "XYQyXYxy");
yields!(gsub, r#""XYxyXYxy" | gsub("x";"Q")"#, "XYQyXYQy");
yields!(isub, r#""XYxyXYxy" | sub("x";"Q";"i")"#, "QYxyXYxy");
yields!(gisub, r#""XYxyXYxy" | gsub("x";"Q";"i")"#, "QYQyQYQy");
yields!(
gsub_swap,
r#""XYxyXYxy" | gsub("(?<upper>[A-Z])(?<lower>[a-z])"; .lower + .upper)"#,
"XxYyXxYy"
);
yields!(
gsub_many,
r#""XxYy" | [gsub("(?<upper>[A-Z])"; .upper, "!" + .upper)]"#,
["XxYy", "Xx!Yy", "!XxYy", "!Xx!Yy"]
);
yields!(
format_text,
r#"[0, 0 == 0, {}.a, "hello", {}, [] | @text]"#,
["0", "true", "null", "hello", "{}", "[]"]
);
yields!(
format_sh,
r#"[0, 0 == 0, {}.a, "O'Hara!", ["Here", "there"] | @sh]"#,
["0", "true", "null", r#"'O'\''Hara!'"#, r#"'Here' 'there'"#,]
);
yields!(
format_sh_rejects_objects,
r#"{a: "b"} | try @sh catch -1"#,
-1
);
yields!(
format_sh_rejects_nested_arrays,
r#"["fine, but", []] | try @sh catch -1"#,
-1
);
yields!(
format_uri,
r#"["abc👍 +&?/", "", null, 123, [], {} | @uri]"#,
[
"abc%F0%9F%91%8D%20%2B%26%3F%2F",
"",
"null",
"123",
"%5B%5D",
"%7B%7D"
]
);
yields!(
format_urid,
r#"["abc%F0%9F%91%8D%20%2B%26%3F%2F", "", null, 123, [], {} | try @urid catch .]"#,
["abc👍 +&?/", "", "null", "123", "[]", "{}"]
);