🐛🧪 cli, vanth: Fix SQLite store bug and add CLI tests

- Modified `Sqlite::get_all_of_ty` to return stored rows instead of empty results.
- Added `Send` requirement to `Backend` trait.
- Implemented `ContentHash::hex` method for hexadecimal representation.
- Added integration test for CLI `write` and `get` commands with `run_vanth` helper.
- Configured CLI tracing to log to stderr instead of stdout.
- Added `serde` dependency to `cli` crate for test struct serialization.
- Modified `handle_write` to print content hash after successful storage.
This commit is contained in:
Markus Scully 2025-08-10 17:41:54 +03:00
parent af6bfadff8
commit 1001819e4c
Signed by: mascully
GPG key ID: 93CA5814B698101C
7 changed files with 97 additions and 5 deletions

View file

@ -5,6 +5,7 @@ edition.workspace = true
[dependencies]
clap.workspace = true
serde.workspace = true
serde_json.workspace = true
vanth = { path = "../vanth" }
tracing.workspace = true

View file

@ -137,6 +137,8 @@ fn handle_write(args: &WriteArgs) {
eprintln!("Error writing to store: {:?}", e);
process::exit(1);
});
println!("{}", content_hash.hex());
}
fn handle_get(args: &GetArgs) {

View file

@ -6,6 +6,7 @@ pub use cli::*;
fn main() {
tracing_subscriber::fmt()
.with_writer(std::io::stderr)
.with_max_level(tracing::Level::TRACE)
.init();

View file

@ -0,0 +1,83 @@
use std::io::Write;
use std::path::Path;
use std::process::Command;
use serde::{Deserialize, Serialize};
use serde_json::{Value, json};
use tempfile::tempdir;
use vanth::{ContentHash, Vanth, hash as vanth_hash};
fn run_vanth(args: &[&str], input: Option<&str>) -> (String, String, i32) {
let mut cmd = Command::new(env!("CARGO_BIN_EXE_vanth_cli"));
cmd.args(args);
if let Some(inp) = input {
let mut child = cmd
.stdin(std::process::Stdio::piped())
.stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::piped())
.spawn()
.unwrap();
{
let stdin = child.stdin.as_mut().unwrap();
stdin.write_all(inp.as_bytes()).unwrap();
}
let output = child.wait_with_output().unwrap();
(
String::from_utf8(output.stdout).unwrap(),
String::from_utf8(output.stderr).unwrap(),
output.status.code().unwrap(),
)
} else {
let output = cmd.output().unwrap();
(
String::from_utf8(output.stdout).unwrap(),
String::from_utf8(output.stderr).unwrap(),
output.status.code().unwrap(),
)
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, Vanth)]
struct Foo {
inner: i32,
}
#[derive(Clone, Debug, Deserialize, Serialize, Vanth)]
struct Bar {
inner: f64,
}
/// Create a value in the database with the `write` command, gets its hash from the CLI stdout output, and retrieve it
/// again with the `get` command.
#[test]
fn test_write_get() {
let tempdir = tempdir().unwrap();
let db_path = tempdir.path().join("test.sqlite").to_str().unwrap().to_string();
let foo = Foo { inner: 6 };
let (stdout, stderr, exit) = run_vanth(
&[
"write",
"--db",
&db_path,
"--ty",
&Foo::ty().to_string(),
"--value",
&serde_json::to_string(&foo).unwrap(),
],
None,
);
if exit != 0 {
panic!("{}", stderr);
}
let hash = stdout.trim();
println!("x{}x", hash);
let (stdout, stderr, exit) = run_vanth(&["get", "--db", &db_path, "--ty", &Foo::ty().to_string(), &hash], None);
if exit != 0 {
panic!("{}", stderr);
}
let recovered_foo = serde_json::from_str(&stdout).unwrap();
assert_eq!(foo, recovered_foo);
}