#![cfg(all(feature = "std", feature = "fts5"))]
use std::process::Command;
fn graphite(script: &str) -> String {
let out = Command::new(env!("CARGO_BIN_EXE_graphitesql"))
.arg(":memory:")
.arg(script)
.output()
.expect("run graphitesql shell");
assert!(
out.status.success(),
"graphitesql failed for {script:?}: {}",
String::from_utf8_lossy(&out.stderr)
);
String::from_utf8_lossy(&out.stdout).into_owned()
}
fn sqlite(script: &str) -> Option<String> {
let out = Command::new("sqlite3")
.arg(":memory:")
.arg(script)
.output()
.ok()?;
assert!(
out.status.success(),
"sqlite3 failed for {script:?}: {}",
String::from_utf8_lossy(&out.stderr)
);
Some(String::from_utf8_lossy(&out.stdout).into_owned())
}
fn assert_matches_sqlite(script: &str) {
let Some(want) = sqlite(script) else {
eprintln!("sqlite3 not found; skipping bm25-value check");
return;
};
let got = graphite(script);
assert_eq!(got, want, "bm25 value diverged for script:\n{script}");
}
#[test]
fn bug_corpus_two_column_common_term() {
assert_matches_sqlite(
"CREATE VIRTUAL TABLE ft USING fts5(a,b);\n\
INSERT INTO ft VALUES('the quick brown fox','jumps'),('lazy dog','sleeps'),('quick red fox','runs');\n\
SELECT rowid, bm25(ft) FROM ft WHERE ft MATCH 'fox' ORDER BY rowid;",
);
}
#[test]
fn single_document_regression_guard() {
assert_matches_sqlite(
"CREATE VIRTUAL TABLE ft USING fts5(x);\n\
INSERT INTO ft VALUES('a b c a');\n\
SELECT bm25(ft) FROM ft WHERE ft MATCH 'a';",
);
}
#[test]
fn two_documents_one_matches() {
assert_matches_sqlite(
"CREATE VIRTUAL TABLE ft USING fts5(x);\n\
INSERT INTO ft VALUES('a b'),('a c');\n\
SELECT rowid, bm25(ft) FROM ft WHERE ft MATCH 'b' ORDER BY rowid;",
);
}
#[test]
fn many_documents_rare_term() {
assert_matches_sqlite(
"CREATE VIRTUAL TABLE ft USING fts5(x);\n\
INSERT INTO ft VALUES('apple banana'),('apple apple cherry'),('banana'),('date apple'),('cherry cherry cherry apple');\n\
SELECT rowid, bm25(ft) FROM ft WHERE ft MATCH 'date' ORDER BY rowid;",
);
}
#[test]
fn many_documents_common_term() {
assert_matches_sqlite(
"CREATE VIRTUAL TABLE ft USING fts5(x);\n\
INSERT INTO ft VALUES('apple banana'),('apple apple cherry'),('banana'),('date apple'),('cherry cherry cherry apple');\n\
SELECT rowid, bm25(ft) FROM ft WHERE ft MATCH 'apple' ORDER BY rowid;",
);
}
#[test]
fn weighted_two_column() {
assert_matches_sqlite(
"CREATE VIRTUAL TABLE ft USING fts5(a,b);\n\
INSERT INTO ft VALUES('the quick brown fox','jumps'),('lazy dog','sleeps'),('quick red fox','runs');\n\
SELECT rowid, bm25(ft, 2.0, 5.0) FROM ft WHERE ft MATCH 'fox' ORDER BY rowid;",
);
}
#[test]
fn order_by_rank_limit_returns_rank() {
assert_matches_sqlite(
"CREATE VIRTUAL TABLE ft USING fts5(a,b);\n\
INSERT INTO ft VALUES('the quick brown fox','jumps'),('lazy dog','sleeps'),('quick red fox','runs');\n\
SELECT rowid, rank FROM ft WHERE ft MATCH 'fox' ORDER BY rank LIMIT 1;",
);
}
#[test]
fn or_query_multiple_phrases() {
assert_matches_sqlite(
"CREATE VIRTUAL TABLE ft USING fts5(a,b);\n\
INSERT INTO ft VALUES('the quick brown fox','jumps'),('lazy dog','sleeps'),('quick red fox','runs');\n\
SELECT rowid, bm25(ft) FROM ft WHERE ft MATCH 'fox OR dog' ORDER BY rowid;",
);
}
#[test]
fn weighted_or_ordered_by_rank() {
assert_matches_sqlite(
"CREATE VIRTUAL TABLE ft USING fts5(a,b);\n\
INSERT INTO ft VALUES('the quick brown fox','jumps'),('lazy dog','sleeps'),('quick red fox','runs');\n\
SELECT rowid, bm25(ft, 0.5, 3.0) FROM ft WHERE ft MATCH 'quick OR jumps' ORDER BY rank;",
);
}
#[test]
fn unindexed_column_excluded_from_length() {
assert_matches_sqlite(
"CREATE VIRTUAL TABLE ft USING fts5(a,b UNINDEXED);\n\
INSERT INTO ft VALUES('the quick brown fox','jumps here now for a while'),('lazy dog','sleeps'),('quick red fox','runs');\n\
SELECT rowid, bm25(ft) FROM ft WHERE ft MATCH 'fox' ORDER BY rowid;",
);
}
#[test]
fn eight_document_corpus() {
assert_matches_sqlite(
"CREATE VIRTUAL TABLE ft USING fts5(t);\n\
INSERT INTO ft VALUES('one two three'),('two three four'),('three four five'),('four five six'),('five six seven'),('six seven eight'),('seven eight nine'),('eight nine ten');\n\
SELECT rowid, bm25(ft) FROM ft WHERE ft MATCH 'four' ORDER BY rowid;",
);
}