#[macro_use]
#[path = "common/mod.rs"]
mod common;
use common::TvaCmd;
use test_case::test_case;
#[test_case("fmt(\"Hello, %()!\", \"world\")", "Hello, world!" ; "basic_hello")]
#[test_case("fmt(\"%() + %() = %()\", 1, 2, 3)", "1 + 2 = 3" ; "multiple_args")]
#[test_case("fmt(\"%(2) %(1)\", \"world\", \"Hello\")", "Hello world" ; "positional_args")]
fn test_fmt_basic(expr: &str, expected: &str) {
let (stdout, _) = TvaCmd::new().args(&["expr", "-E", expr]).run();
assert!(
stdout.contains(expected),
"Expected '{}' in stdout, got: {}",
expected,
stdout
);
}
#[test_case("fmt(\"%(:>10)\", \"hi\")", " hi" ; "align_right")]
#[test_case("fmt(\"%(:*<10)\", \"hi\")", "hi********" ; "align_left_fill")]
#[test_case("fmt(\"%(:^10)\", \"hi\")", " hi " ; "align_center")]
#[test_case("fmt(\"%(:+)\", 42)", "+42" ; "sign_always")]
#[test_case("fmt(\"%(:08)\", 42)", "00000042" ; "zero_pad")]
#[test_case("fmt(\"%(:.2)\", 3.14159)", "3.14" ; "float_precision")]
#[test_case("fmt(\"%(:b)\", 42)", "101010" ; "binary")]
#[test_case("fmt(\"%(:x)\", 255)", "ff" ; "hex")]
#[test_case("fmt(\"%(:#x)\", 255)", "0xff" ; "hex_with_prefix")]
#[test_case("fmt(\"%(:.5)\", \"hello world\")", "hello" ; "string_truncate")]
fn test_fmt_specifiers(expr: &str, expected: &str) {
let (stdout, _) = TvaCmd::new().args(&["expr", "-E", expr]).run();
assert!(
stdout.contains(expected),
"Expected '{}' in stdout, got: {:?}",
expected,
stdout
);
}
#[test_case(
&["Alice,100"],
"fmt(\"%(@1) has %(@2) points\")",
&["Alice has 100 points"]
; "by_index"
)]
#[test_case(
&["Alice,100"],
"fmt(\"%(): %(@2) points\", @1)",
&["Alice: 100 points"]
; "mixed"
)]
fn test_fmt_column_ref(rows: &[&str], expr: &str, expected: &[&str]) {
let mut args = vec!["expr", "-E", expr];
for row in rows {
args.push("-r");
args.push(row);
}
let (stdout, _) = TvaCmd::new().args(&args).run();
for exp in expected {
assert!(
stdout.contains(exp),
"Expected '{}' in stdout, got: {}",
exp,
stdout
);
}
}
#[test_case(
"map([1, 2, 3], x => fmt(\"value: %(x)\"))",
&["value: 1", "value: 2", "value: 3"]
; "basic"
)]
#[test_case(
"map([1, 2, 3], x => fmt(q(value: %[x])))",
&["value: 1", "value: 2", "value: 3"]
; "with_brackets"
)]
fn test_fmt_lambda(expr: &str, expected: &[&str]) {
let (stdout, _) = TvaCmd::new().args(&["expr", "-E", expr]).run();
for exp in expected {
assert!(
stdout.contains(exp),
"Expected '{}' in stdout, got: {}",
exp,
stdout
);
}
}
#[test_case("\"Bob\" as @name; fmt(\"Hello, %(@name)!\")", "Hello, Bob!" ; "basic")]
#[test_case("3.14159 as @pi; fmt(\"Pi = %(@pi:.2)\")", "Pi = 3.14" ; "with_format")]
fn test_fmt_variable(expr: &str, expected: &str) {
let (stdout, _) = TvaCmd::new().args(&["expr", "-E", expr]).run();
assert!(
stdout.contains(expected),
"Expected '{}' in stdout, got: {}",
expected,
stdout
);
}
#[test]
fn test_fmt_variable_multiple_formats() {
let (stdout, _) = TvaCmd::new()
.args(&[
"expr",
"-E",
"42 as @num; fmt(\"Hex: %(@num:#x), Bin: %(@num:b)\")",
])
.run();
assert!(
stdout.contains("Hex: 0x2a"),
"Expected 'Hex: 0x2a' in stdout, got: {}",
stdout
);
assert!(
stdout.contains("Bin: 101010"),
"Expected 'Bin: 101010' in stdout, got: {}",
stdout
);
}
#[test_case(
&["Alice,100", "Bob,200"],
"fmt(\"Hello, %(@1)! from line %(@__index)\")",
&["Hello, Alice! from line 1", "Hello, Bob! from line 2"]
; "line_index"
)]
#[test_case(
&["Alice,100", "Bob,200"],
"default(@__sum, 0) + @2 as @__sum; fmt(\"Hello, %(@1)! sum: %(@__sum)\")",
&["Hello, Alice! sum: 100", "Hello, Bob! sum: 300"]
; "accumulate"
)]
fn test_fmt_global_variable(rows: &[&str], expr: &str, expected: &[&str]) {
let mut args = vec!["expr"];
for row in rows {
args.push("-r");
args.push(row);
}
args.push("-E");
args.push(expr);
let (stdout, _) = TvaCmd::new().args(&args).run();
for exp in expected {
assert!(
stdout.contains(exp),
"Expected '{}' in stdout, got: {}",
exp,
stdout
);
}
}
#[test_case("fmt(q(Result: %[:.2]), 3.14159)", "Result: 3.14" ; "square_brackets")]
#[test_case("fmt(q(%{1:+}), 42)", "+42" ; "curly_braces")]
#[test_case("fmt(q(The \"value\" is %[1]), 42)", "The \"value\" is 42" ; "with_q_string")]
fn test_fmt_delimiter(expr: &str, expected: &str) {
let (stdout, _) = TvaCmd::new().args(&["expr", "-E", expr]).run();
assert!(
stdout.contains(expected),
"Expected '{}' in stdout, got: {:?}",
expected,
stdout
);
}
#[test]
fn test_fmt_escape_percent() {
let (stdout, _) = TvaCmd::new()
.args(&["expr", "-E", "fmt(\"100%% complete\")"])
.run();
assert!(
stdout.contains("100% complete"),
"Expected '100% complete' in stdout, got: {:?}",
stdout
);
}