use assert_cmd::cargo::cargo_bin_cmd;
use predicates::prelude::*;
use std::path::PathBuf;
mod common;
use common::TvaCmd;
fn data_path(filename: &str) -> PathBuf {
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.push("tests/data/plot");
path.push(filename);
path
}
#[test]
fn test_plot_point_help() {
let mut cmd = cargo_bin_cmd!("tva");
cmd.args(["plot", "point", "--help"]);
cmd.assert()
.success()
.stdout(predicate::str::contains(
"Draw a scatter plot or line chart",
))
.stdout(predicate::str::contains("-x, --x"))
.stdout(predicate::str::contains("-y, --y"))
.stdout(predicate::str::contains("--color"))
.stdout(predicate::str::contains("-l, --line"));
}
#[test]
fn test_plot_point_basic() {
let tva = TvaCmd::new();
let input = "x\ty\n1\t2\n2\t4\n3\t6\n4\t8\n";
let (stdout, _stderr) = tva
.args(&["plot", "point", "-x", "1", "-y", "2"])
.stdin(input)
.run();
assert!(!stdout.is_empty());
}
#[test]
fn test_plot_point_with_column_names() {
let tva = TvaCmd::new();
let input = "x\ty\n1\t2\n2\t4\n3\t6\n";
let (stdout, _stderr) = tva
.args(&["plot", "point", "-x", "x", "-y", "y"])
.stdin(input)
.run();
assert!(!stdout.is_empty());
}
#[test]
fn test_plot_point_line() {
let tva = TvaCmd::new();
let input = "x\ty\n1\t2\n2\t4\n3\t6\n";
let (stdout, _stderr) = tva
.args(&["plot", "point", "-l", "-x", "1", "-y", "2"])
.stdin(input)
.run();
assert!(!stdout.is_empty());
}
#[test]
fn test_plot_point_with_color() {
let tva = TvaCmd::new();
let input = "x\ty\tgroup\n1\t2\tA\n2\t4\tA\n3\t6\tB\n4\t8\tB\n";
let (stdout, _stderr) = tva
.args(&["plot", "point", "-x", "1", "-y", "2", "--color", "3"])
.stdin(input)
.run();
assert!(!stdout.is_empty());
}
#[test]
fn test_plot_point_ignore_errors() {
let tva = TvaCmd::new();
let input = "x\ty\n1\t2\n2\tabc\n3\t6\n";
let (stdout, _stderr) = tva
.args(&["plot", "point", "-x", "1", "-y", "2", "--ignore"])
.stdin(input)
.run();
assert!(!stdout.is_empty());
}
#[test]
fn test_plot_point_error_on_invalid_data() {
let tva = TvaCmd::new();
let input = "x\ty\n1\t2\n2\tabc\n3\t6\n";
let (_stdout, stderr) = tva
.args(&["plot", "point", "-x", "1", "-y", "2"])
.stdin(input)
.run_fail();
assert!(stderr.contains("Cannot parse") || stderr.contains("abc"));
}
#[test]
fn test_plot_point_empty_data() {
let tva = TvaCmd::new();
let input = "x\ty\n";
let (_stdout, stderr) = tva
.args(&["plot", "point", "-x", "1", "-y", "2"])
.stdin(input)
.run_fail();
assert!(stderr.contains("No valid data points"));
}
#[test]
fn test_plot_point_invalid_column() {
let tva = TvaCmd::new();
let input = "x\ty\n1\t2\n";
let (_stdout, stderr) = tva
.args(&["plot", "point", "-x", "nonexistent", "-y", "2"])
.stdin(input)
.run_fail();
assert!(stderr.contains("Invalid column spec"));
}
#[test]
fn test_plot_point_zero_based_index() {
let tva = TvaCmd::new();
let input = "x\ty\n1\t2\n";
let (_stdout, stderr) = tva
.args(&["plot", "point", "-x", "0", "-y", "2"])
.stdin(input)
.run_fail();
assert!(stderr.contains("field index must be >= 1"));
}
#[test]
fn test_plot_point_iris_basic() {
let tva = TvaCmd::new();
let iris_path = data_path("iris.tsv");
let (stdout, _stderr) = tva
.args(&[
"plot",
"point",
"-x",
"sepal_length",
"-y",
"sepal_width",
iris_path.to_str().unwrap(),
])
.run();
assert!(!stdout.is_empty());
}
#[test]
fn test_plot_point_iris_with_color() {
let tva = TvaCmd::new();
let iris_path = data_path("iris.tsv");
let (stdout, _stderr) = tva
.args(&[
"plot",
"point",
"-x",
"petal_length",
"-y",
"petal_width",
"--color",
"label",
iris_path.to_str().unwrap(),
])
.run();
assert!(!stdout.is_empty());
}
#[test]
fn test_plot_point_iris_by_index() {
let tva = TvaCmd::new();
let iris_path = data_path("iris.tsv");
let (stdout, _stderr) = tva
.args(&[
"plot",
"point",
"-x",
"1", "-y",
"3", "--color",
"5", iris_path.to_str().unwrap(),
])
.run();
assert!(!stdout.is_empty());
}
#[test]
fn test_plot_point_iris_with_size() {
let tva = TvaCmd::new();
let iris_path = data_path("iris.tsv");
let (stdout, _stderr) = tva
.args(&[
"plot",
"point",
"-x",
"sepal_length",
"-y",
"petal_length",
"--color",
"label",
"--cols",
"80",
"--rows",
"24",
iris_path.to_str().unwrap(),
])
.run();
assert!(!stdout.is_empty());
}
#[test]
fn test_plot_point_path_basic() {
let tva = TvaCmd::new();
let input = "x\ty\n0\t0\n1\t1\n0\t2\n-1\t1\n0\t0\n";
let (stdout, _stderr) = tva
.args(&["plot", "point", "--path", "-x", "1", "-y", "2"])
.stdin(input)
.run();
assert!(!stdout.is_empty());
}
#[test]
fn test_plot_point_path_vs_line() {
let input = "x\ty\n1\t1\n3\t2\n2\t3\n4\t4\n";
let tva = TvaCmd::new();
let (stdout_path, _stderr) = tva
.args(&["plot", "point", "--path", "-x", "1", "-y", "2"])
.stdin(input)
.run();
let tva = TvaCmd::new();
let (stdout_line, _stderr) = tva
.args(&["plot", "point", "--line", "-x", "1", "-y", "2"])
.stdin(input)
.run();
assert!(!stdout_path.is_empty());
assert!(!stdout_line.is_empty());
}
#[test]
fn test_plot_point_path_and_line_mutual_exclusion() {
let tva = TvaCmd::new();
let input = "x\ty\n1\t2\n2\t4\n";
let (_stdout, stderr) = tva
.args(&["plot", "point", "--line", "--path", "-x", "1", "-y", "2"])
.stdin(input)
.run_fail();
assert!(stderr.contains("Cannot use both"));
}
#[test]
fn test_plot_point_multi_y_basic() {
let tva = TvaCmd::new();
let input = "x\ty1\ty2\n0\t0\t0\n1\t2\t1\n2\t4\t2\n3\t6\t3\n";
let (stdout, _stderr) = tva
.args(&["plot", "point", "-x", "1", "-y", "2,3"])
.stdin(input)
.run();
assert!(!stdout.is_empty());
assert!(stdout.contains("y1") || stdout.contains("y2"));
}
#[test]
fn test_plot_point_multi_y_with_names() {
let tva = TvaCmd::new();
let iris_path = data_path("iris.tsv");
let (stdout, _stderr) = tva
.args(&[
"plot",
"point",
"-x",
"sepal_length",
"-y",
"petal_length,petal_width",
iris_path.to_str().unwrap(),
])
.run();
assert!(!stdout.is_empty());
assert!(stdout.contains("petal_length") || stdout.contains("petal_width"));
}
#[test]
fn test_plot_point_multi_y_with_color() {
let tva = TvaCmd::new();
let iris_path = data_path("iris.tsv");
let (stdout, _stderr) = tva
.args(&[
"plot",
"point",
"-x",
"sepal_length",
"-y",
"petal_length,petal_width",
"--color",
"label",
"--cols",
"100",
"--rows",
"30",
iris_path.to_str().unwrap(),
])
.run();
assert!(!stdout.is_empty());
assert!(stdout.contains("2 series"));
}
#[test]
fn test_plot_point_regression_basic() {
let tva = TvaCmd::new();
let input = "x\ty\n0\t0\n1\t2\n2\t4\n3\t6\n4\t8\n";
let (stdout, _stderr) = tva
.args(&["plot", "point", "--regression", "-x", "1", "-y", "2"])
.stdin(input)
.run();
assert!(!stdout.is_empty());
}
#[test]
fn test_plot_point_regression_with_color() {
let tva = TvaCmd::new();
let iris_path = data_path("iris.tsv");
let (stdout, stderr) = tva
.args(&[
"plot",
"point",
"--regression",
"-x",
"sepal_length",
"-y",
"petal_length",
"--color",
"label",
iris_path.to_str().unwrap(),
])
.run();
if stdout.is_empty() {
eprintln!("stderr: {}", stderr);
}
assert!(!stdout.is_empty());
assert!(stdout.contains("sepal_length"));
assert!(stdout.contains("petal_length"));
}
#[test]
fn test_plot_point_regression_and_line_mutual_exclusion() {
let tva = TvaCmd::new();
let input = "x\ty\n1\t2\n2\t4\n";
let (_stdout, stderr) = tva
.args(&[
"plot",
"point",
"--regression",
"--line",
"-x",
"1",
"-y",
"2",
])
.stdin(input)
.run_fail();
assert!(stderr.contains("Cannot use"));
}
#[test]
fn test_plot_point_regression_and_path_mutual_exclusion() {
let tva = TvaCmd::new();
let input = "x\ty\n1\t2\n2\t4\n";
let (_stdout, stderr) = tva
.args(&[
"plot",
"point",
"--regression",
"--path",
"-x",
"1",
"-y",
"2",
])
.stdin(input)
.run_fail();
assert!(stderr.contains("Cannot use"));
}