use stoolap::Database;
fn setup_test_products(db: &Database) {
db.execute(
"CREATE TABLE test_products (
id INTEGER,
name TEXT,
category TEXT,
price FLOAT,
in_stock BOOLEAN,
tags TEXT,
supply_date TIMESTAMP
)",
(),
)
.expect("Failed to create test table");
let inserts = [
"INSERT INTO test_products VALUES (1, 'Laptop', 'Electronics', 1200.00, true, 'premium,tech', TIMESTAMP '2023-01-15 00:00:00')",
"INSERT INTO test_products VALUES (2, 'Smartphone', 'Electronics', 800.00, true, 'mobile,tech', TIMESTAMP '2023-02-20 00:00:00')",
"INSERT INTO test_products VALUES (3, 'Headphones', 'Electronics', 150.00, true, 'audio,tech', TIMESTAMP '2023-03-10 00:00:00')",
"INSERT INTO test_products VALUES (4, 'T-shirt', 'Clothing', 25.00, true, 'casual,cotton', TIMESTAMP '2023-01-25 00:00:00')",
"INSERT INTO test_products VALUES (5, 'Jeans', 'Clothing', 50.00, false, 'denim,casual', NULL)",
"INSERT INTO test_products VALUES (6, 'Sneakers', 'Footwear', 80.00, true, 'casual,sports', TIMESTAMP '2023-02-05 00:00:00')",
"INSERT INTO test_products VALUES (7, 'Boots', 'Footwear', 120.00, false, 'winter,leather', NULL)",
"INSERT INTO test_products VALUES (8, 'Desk', 'Furniture', 250.00, true, 'office,wood', TIMESTAMP '2023-03-25 00:00:00')",
"INSERT INTO test_products VALUES (9, 'Chair', 'Furniture', 150.00, true, 'office,comfort', TIMESTAMP '2023-03-25 00:00:00')",
"INSERT INTO test_products VALUES (10, NULL, NULL, NULL, NULL, NULL, NULL)",
];
for insert in &inserts {
db.execute(insert, ()).expect("Failed to insert row");
}
}
fn count_rows(db: &Database, query: &str) -> i64 {
let result = db.query(query, ()).expect("Failed to execute query");
let mut count = 0;
for _row in result {
count += 1;
}
count
}
#[test]
fn test_not_with_equality() {
let db = Database::open("memory://expr_not_eq").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(
&db,
"SELECT * FROM test_products WHERE NOT category = 'Electronics'",
);
assert_eq!(count, 6, "Expected 6 non-Electronics products");
}
#[test]
fn test_not_with_inequality() {
let db = Database::open("memory://expr_not_neq").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(&db, "SELECT * FROM test_products WHERE NOT price > 100");
assert!(count >= 3, "Expected at least 3 products with price <= 100");
}
#[test]
fn test_not_with_and_condition() {
let db = Database::open("memory://expr_not_and").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(
&db,
"SELECT * FROM test_products WHERE NOT (category = 'Electronics' AND price > 500)",
);
assert_eq!(
count, 8,
"Expected 8 products not (Electronics AND expensive)"
);
}
#[test]
fn test_not_with_or_condition() {
let db = Database::open("memory://expr_not_or").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(
&db,
"SELECT * FROM test_products WHERE NOT (category = 'Electronics' OR category = 'Clothing')",
);
assert!(
count >= 4,
"Expected at least 4 products not Electronics or Clothing"
);
}
#[test]
fn test_not_with_null_check() {
let db = Database::open("memory://expr_not_null").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(
&db,
"SELECT * FROM test_products WHERE NOT (category IS NULL)",
);
assert_eq!(count, 9, "Expected 9 rows with non-NULL category");
}
#[test]
fn test_not_with_composite_condition() {
let db = Database::open("memory://expr_not_composite").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(
&db,
"SELECT * FROM test_products WHERE NOT (category = 'Electronics' AND price > 500 AND in_stock = true)",
);
assert_eq!(
count, 8,
"Expected 8 products not (expensive Electronics in stock)"
);
}
#[test]
fn test_in_multiple_values() {
let db = Database::open("memory://expr_in_multi").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(
&db,
"SELECT * FROM test_products WHERE category IN ('Electronics', 'Clothing')",
);
assert_eq!(count, 5, "Expected 5 Electronics or Clothing products");
}
#[test]
fn test_in_single_value() {
let db = Database::open("memory://expr_in_single").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(
&db,
"SELECT * FROM test_products WHERE category IN ('Furniture')",
);
assert_eq!(count, 2, "Expected 2 Furniture products");
}
#[test]
fn test_in_numeric_values() {
let db = Database::open("memory://expr_in_numeric").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(
&db,
"SELECT * FROM test_products WHERE price IN (50.00, 150.00, 250.00)",
);
assert_eq!(count, 4, "Expected 4 products with these exact prices");
}
#[test]
fn test_in_no_match() {
let db = Database::open("memory://expr_in_nomatch").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(
&db,
"SELECT * FROM test_products WHERE category IN ('Unknown', 'NonExistent')",
);
assert_eq!(count, 0, "Expected 0 matches for unknown categories");
}
#[test]
fn test_in_combined_with_and() {
let db = Database::open("memory://expr_in_and").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(
&db,
"SELECT * FROM test_products WHERE category IN ('Electronics', 'Clothing') AND in_stock = true",
);
assert_eq!(
count, 4,
"Expected 4 in-stock Electronics and Clothing products"
);
}
#[test]
fn test_not_in_simple() {
let db = Database::open("memory://expr_not_in").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(
&db,
"SELECT * FROM test_products WHERE category NOT IN ('Electronics', 'Clothing')",
);
assert!(
count >= 4,
"Expected at least 4 products not in Electronics or Clothing"
);
}
#[test]
fn test_not_in_combined_with_and() {
let db = Database::open("memory://expr_not_in_and").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(
&db,
"SELECT * FROM test_products WHERE category NOT IN ('Electronics', 'Clothing') AND in_stock = true",
);
assert_eq!(
count, 3,
"Expected 3 in-stock products not in Electronics or Clothing"
);
}
#[test]
fn test_not_in_combined_with_or() {
let db = Database::open("memory://expr_not_in_or").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(
&db,
"SELECT * FROM test_products WHERE category NOT IN ('Electronics', 'Clothing') OR price > 200",
);
assert!(
count >= 5,
"Expected at least 5 products matching NOT IN OR condition"
);
}
#[test]
fn test_not_in_numeric() {
let db = Database::open("memory://expr_not_in_num").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(
&db,
"SELECT * FROM test_products WHERE id NOT IN (1, 2, 3, 4, 5)",
);
assert_eq!(count, 5, "Expected 5 products with IDs 6-10");
}
#[test]
fn test_not_in_parenthesized() {
let db = Database::open("memory://expr_not_in_paren").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(
&db,
"SELECT * FROM test_products WHERE NOT (category IN ('Electronics', 'Clothing'))",
);
assert!(
count >= 4,
"Expected at least 4 products not in Electronics or Clothing"
);
}
#[test]
fn test_complex_nested_not() {
let db = Database::open("memory://expr_complex").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(
&db,
"SELECT * FROM test_products WHERE NOT (category = 'Electronics' OR (category = 'Clothing' AND price > 30))",
);
assert!(
count >= 5,
"Expected at least 5 products matching complex condition"
);
}
#[test]
fn test_in_with_or() {
let db = Database::open("memory://expr_in_or").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(
&db,
"SELECT * FROM test_products WHERE category IN ('Electronics') OR price < 30",
);
assert_eq!(count, 4, "Expected 4 Electronics or cheap products");
}
#[test]
fn test_double_not() {
let db = Database::open("memory://expr_double_not").expect("Failed to create database");
setup_test_products(&db);
let count = count_rows(
&db,
"SELECT * FROM test_products WHERE NOT NOT category = 'Electronics'",
);
assert_eq!(count, 3, "Expected 3 Electronics products with double NOT");
}