mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-04 08:54:20 +01:00
Replace tcl with python tests and add to makefile
This commit is contained in:
4
Makefile
4
Makefile
@@ -57,11 +57,11 @@ limbo-wasm:
|
||||
cargo build --package limbo-wasm --target wasm32-wasi
|
||||
.PHONY: limbo-wasm
|
||||
|
||||
test: limbo test-compat test-sqlite3
|
||||
test: limbo test-compat test-sqlite3 test-shell
|
||||
.PHONY: test
|
||||
|
||||
test-shell: limbo
|
||||
./testing/memory-repl.tcl
|
||||
./testing/shelltests.py
|
||||
.PHONY: test-shell
|
||||
|
||||
test-compat:
|
||||
|
||||
51
cli/app.rs
51
cli/app.rs
@@ -18,9 +18,9 @@ use std::{
|
||||
#[command(name = "limbo")]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
pub struct Opts {
|
||||
#[clap(index = 1)]
|
||||
#[clap(index = 1, help = "SQLite database file", default_value = ":memory:")]
|
||||
pub database: Option<PathBuf>,
|
||||
#[clap(index = 2)]
|
||||
#[clap(index = 2, help = "Optional SQL command to execute")]
|
||||
pub sql: Option<String>,
|
||||
#[clap(short = 'm', long, default_value_t = OutputMode::Raw)]
|
||||
pub output_mode: OutputMode,
|
||||
@@ -190,21 +190,14 @@ impl Limbo {
|
||||
#[allow(clippy::arc_with_non_send_sync)]
|
||||
pub fn new() -> anyhow::Result<Self> {
|
||||
let opts = Opts::parse();
|
||||
let io: Arc<dyn limbo_core::IO> = match opts.database {
|
||||
Some(ref path) if path.exists() => Arc::new(limbo_core::PlatformIO::new()?),
|
||||
_ => Arc::new(limbo_core::MemoryIO::new()?),
|
||||
};
|
||||
let db_file = opts
|
||||
.database
|
||||
.as_ref()
|
||||
.map_or(":memory:".to_string(), |p| p.to_string_lossy().to_string());
|
||||
|
||||
let io = get_io(&db_file)?;
|
||||
let db = Database::open_file(io.clone(), &db_file)?;
|
||||
let conn = db.connect();
|
||||
let writer: Box<dyn Write> = if !opts.output.is_empty() {
|
||||
Box::new(std::fs::File::create(&opts.output)?)
|
||||
} else {
|
||||
Box::new(io::stdout())
|
||||
};
|
||||
let interrupt_count = Arc::new(AtomicUsize::new(0));
|
||||
{
|
||||
let interrupt_count: Arc<AtomicUsize> = Arc::clone(&interrupt_count);
|
||||
@@ -217,7 +210,7 @@ impl Limbo {
|
||||
let mut app = Self {
|
||||
prompt: PROMPT.to_string(),
|
||||
io,
|
||||
writer,
|
||||
writer: get_writer(&opts.output),
|
||||
conn,
|
||||
interrupt_count,
|
||||
input_buff: String::new(),
|
||||
@@ -309,7 +302,7 @@ impl Limbo {
|
||||
}
|
||||
|
||||
fn set_output_file(&mut self, path: &str) -> Result<(), String> {
|
||||
if path.is_empty() || path.eq_ignore_ascii_case("stdout") {
|
||||
if path.is_empty() || path.trim().eq_ignore_ascii_case("stdout") {
|
||||
self.set_output_stdout();
|
||||
return Ok(());
|
||||
}
|
||||
@@ -317,6 +310,7 @@ impl Limbo {
|
||||
Ok(file) => {
|
||||
self.writer = Box::new(file);
|
||||
self.opts.is_stdout = false;
|
||||
self.opts.output_mode = OutputMode::Raw;
|
||||
self.opts.output_filename = path.to_string();
|
||||
return Ok(());
|
||||
}
|
||||
@@ -332,8 +326,13 @@ impl Limbo {
|
||||
self.opts.is_stdout = true;
|
||||
}
|
||||
|
||||
fn set_mode(&mut self, mode: OutputMode) {
|
||||
fn set_mode(&mut self, mode: OutputMode) -> Result<(), String> {
|
||||
if mode == OutputMode::Pretty && !self.opts.is_stdout {
|
||||
return Err("pretty output can only be written to a tty".to_string());
|
||||
} else {
|
||||
self.opts.output_mode = mode;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn write_fmt(&mut self, fmt: std::fmt::Arguments) -> io::Result<()> {
|
||||
@@ -440,7 +439,9 @@ impl Limbo {
|
||||
}
|
||||
Command::OutputMode => match OutputMode::from_str(args[1], true) {
|
||||
Ok(mode) => {
|
||||
self.set_mode(mode);
|
||||
if let Err(e) = self.set_mode(mode) {
|
||||
let _ = self.write_fmt(format_args!("Error: {}", e));
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
let _ = self.writeln(e);
|
||||
@@ -622,6 +623,26 @@ impl Limbo {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_writer(output: &str) -> Box<dyn Write> {
|
||||
match output {
|
||||
"" => Box::new(io::stdout()),
|
||||
_ => match std::fs::File::create(output) {
|
||||
Ok(file) => Box::new(file),
|
||||
Err(e) => {
|
||||
eprintln!("Error: {}", e);
|
||||
Box::new(io::stdout())
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn get_io(db: &str) -> anyhow::Result<Arc<dyn limbo_core::IO>> {
|
||||
Ok(match db {
|
||||
":memory:" => Arc::new(limbo_core::MemoryIO::new()?),
|
||||
_ => Arc::new(limbo_core::PlatformIO::new()?),
|
||||
})
|
||||
}
|
||||
|
||||
const HELP_MSG: &str = r#"
|
||||
Limbo SQL Shell Help
|
||||
==============
|
||||
|
||||
@@ -1,222 +0,0 @@
|
||||
#!/usr/bin/env tclsh
|
||||
|
||||
set sqlite_exec "./target/debug/limbo"
|
||||
set cwd [pwd]
|
||||
|
||||
proc start_sqlite_repl {sqlite_exec init_commands} {
|
||||
set command [list $sqlite_exec -q]
|
||||
set pipe [open "|[join $command]" RDWR]
|
||||
puts $pipe $init_commands
|
||||
flush $pipe
|
||||
fconfigure $pipe -buffering none -blocking 0 -translation binary
|
||||
puts [fconfigure $pipe]
|
||||
return $pipe
|
||||
}
|
||||
|
||||
proc execute_sql {pipe sql} {
|
||||
puts $pipe $sql
|
||||
flush $pipe
|
||||
puts $pipe "SELECT 'END_OF_RESULT';"
|
||||
flush $pipe
|
||||
set output ""
|
||||
while {true} {
|
||||
if {[gets $pipe line] >= 0} {
|
||||
if {$line eq "END_OF_RESULT"} {
|
||||
break
|
||||
}
|
||||
append output "$line\n"
|
||||
} elseif {[eof $pipe]} {
|
||||
puts "EOF reached."
|
||||
break
|
||||
}
|
||||
}
|
||||
return [string trim $output]
|
||||
}
|
||||
|
||||
proc run_test {pipe sql expected_output} {
|
||||
set actual_output [execute_sql $pipe $sql]
|
||||
if {$actual_output ne $expected_output} {
|
||||
puts "Test FAILED: '$sql'"
|
||||
puts "expected '$expected_output'"
|
||||
puts "returned '$actual_output'"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
proc do_execsql_test {pipe test_name sql expected_output} {
|
||||
puts "Running test: $test_name"
|
||||
run_test $pipe $sql $expected_output
|
||||
}
|
||||
|
||||
|
||||
set init_commands {
|
||||
CREATE TABLE users (id INTEGER PRIMARY KEY, first_name TEXT, last_name TEXT, age INTEGER);
|
||||
CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT, price INTEGER);
|
||||
INSERT INTO users (id, first_name, last_name, age) VALUES
|
||||
(1, 'Alice', 'Smith', 30), (2, 'Bob', 'Johnson', 25), (3, 'Charlie', 'Brown', 66), (4, 'David', 'Nichols', 70); INSERT INTO products (id, name, price) VALUES (1, 'Hat', 19.99), (2, 'Shirt', 29.99), (3, 'Shorts', 39.99), (4, 'Dress', 49.99);
|
||||
CREATE TABLE t (x1, x2, x3, x4);
|
||||
INSERT INTO t VALUES (zeroblob(1024 - 1), zeroblob(1024 - 2), zeroblob(1024 - 3), zeroblob(1024 - 4));
|
||||
}
|
||||
|
||||
set pipe [start_sqlite_repl $sqlite_exec $init_commands]
|
||||
|
||||
do_execsql_test $pipe select-1 {
|
||||
SELECT 1;
|
||||
} {1}
|
||||
|
||||
do_execsql_test $pipe schema-1 {
|
||||
.schema
|
||||
} {CREATE TABLE users (id INTEGER PRIMARY KEY, first_name TEXT, last_name TEXT, age INTEGER);
|
||||
CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT, price INTEGER);
|
||||
CREATE TABLE t (x1, x2, x3, x4);}
|
||||
|
||||
do_execsql_test $pipe select-avg {
|
||||
SELECT avg(age) FROM users;
|
||||
} {47.75}
|
||||
|
||||
do_execsql_test $pipe select-avg-text {
|
||||
SELECT avg(first_name) FROM users;
|
||||
} {0.0}
|
||||
|
||||
do_execsql_test $pipe select-sum {
|
||||
SELECT sum(age) FROM users;
|
||||
} {191}
|
||||
|
||||
do_execsql_test $pipe select-sum-text {
|
||||
SELECT sum(first_name) FROM users;
|
||||
} {0.0}
|
||||
|
||||
do_execsql_test $pipe select-total {
|
||||
SELECT total(age) FROM users;
|
||||
} {191.0}
|
||||
|
||||
do_execsql_test $pipe select-total-text {
|
||||
SELECT total(first_name) FROM users WHERE id < 3;
|
||||
} {0.0}
|
||||
|
||||
do_execsql_test $pipe select-limit {
|
||||
SELECT typeof(id) FROM users LIMIT 1;
|
||||
} {integer}
|
||||
|
||||
do_execsql_test $pipe select-count {
|
||||
SELECT count(id) FROM users;
|
||||
} {4}
|
||||
|
||||
do_execsql_test $pipe select-count {
|
||||
SELECT count(*) FROM users;
|
||||
} {4}
|
||||
|
||||
do_execsql_test $pipe select-count-constant-true {
|
||||
SELECT count(*) FROM users WHERE true;
|
||||
} {4}
|
||||
|
||||
do_execsql_test $pipe select-count-constant-false {
|
||||
SELECT count(*) FROM users WHERE false;
|
||||
} {0}
|
||||
|
||||
|
||||
# test that we can open new connection
|
||||
puts $pipe ".open testing/testing.db"
|
||||
flush $pipe
|
||||
|
||||
# run a few random tests to be sure we are connected to right db
|
||||
do_execsql_test $pipe schema-1 {
|
||||
.schema users
|
||||
} {CREATE TABLE users (
|
||||
id INTEGER PRIMARY KEY,
|
||||
first_name TEXT,
|
||||
last_name TEXT,
|
||||
email TEXT,
|
||||
phone_number TEXT,
|
||||
address TEXT,
|
||||
city TEXT,
|
||||
state TEXT,
|
||||
zipcode TEXT,
|
||||
age INTEGER
|
||||
);
|
||||
CREATE INDEX age_idx on users (age);}
|
||||
|
||||
do_execsql_test $pipe cross-join {
|
||||
select * from users, products limit 1;
|
||||
} {1|Jamie|Foster|dylan00@example.com|496-522-9493|62375 Johnson Rest Suite 322|West Lauriestad|IL|35865|94|1|hat|79.0}
|
||||
|
||||
do_execsql_test $pipe left-join-self {
|
||||
select u1.first_name as user_name, u2.first_name as neighbor_name from users u1 left join users as u2 on u1.id = u2.id + 1 limit 2;
|
||||
} {Jamie|
|
||||
Cindy|Jamie}
|
||||
|
||||
do_execsql_test $pipe where-clause-eq-string {
|
||||
select count(1) from users where last_name = 'Rodriguez';
|
||||
} {61}
|
||||
|
||||
|
||||
# Test the null value can be set/unset
|
||||
|
||||
puts $pipe ".nullvalue limbo"
|
||||
|
||||
do_execsql_test $pipe test-select-nullvalue {
|
||||
SELECT NULL;
|
||||
} {limbo}
|
||||
|
||||
do_execsql_test $pipe test-set-nullvalue {
|
||||
.nullvalue ''
|
||||
} {}
|
||||
|
||||
do_execsql_test $pipe test-set-nullvalue-back {
|
||||
SELECT NULL;
|
||||
} {''}
|
||||
|
||||
|
||||
# Test that the .show command demonstrates which db is open
|
||||
do_execsql_test $pipe test-show {
|
||||
.show
|
||||
} [subst {Settings:
|
||||
Output mode: raw
|
||||
DB: testing/testing.db
|
||||
Output: STDOUT
|
||||
Null value: ''
|
||||
CWD: $cwd
|
||||
Echo: off}]
|
||||
|
||||
|
||||
# Set up the output file name
|
||||
set output_file "limbo_output.txt"
|
||||
|
||||
puts $pipe ".output $output_file"
|
||||
flush $pipe
|
||||
|
||||
# Run the .show command to capture its output
|
||||
puts $pipe ".show"
|
||||
flush $pipe
|
||||
|
||||
# Stop redirecting output to the file
|
||||
puts $pipe ".output"
|
||||
flush $pipe
|
||||
|
||||
do_execsql_test $pipe test-set-outputfile-stdout {
|
||||
SELECT 1;
|
||||
} {1}
|
||||
|
||||
# Check if the output file exists
|
||||
if {![file exists $output_file]} {
|
||||
puts "Test FAILED: output file not created"
|
||||
exit 1
|
||||
}
|
||||
|
||||
set file_contents [read [open $output_file]]
|
||||
|
||||
set expected_line "Output: $output_file"
|
||||
if {[string first $expected_line $file_contents] == -1} {
|
||||
puts "Test FAILED: Expected line not found in file"
|
||||
puts "Expected: $expected_line"
|
||||
puts "File contents:\n$file_contents"
|
||||
exit 1
|
||||
} else {
|
||||
puts "Test PASSED: File contains the expected line"
|
||||
}
|
||||
|
||||
file delete -force $output_file
|
||||
|
||||
puts "All tests passed successfully."
|
||||
close $pipe
|
||||
exit 0
|
||||
239
testing/shelltests.py
Executable file
239
testing/shelltests.py
Executable file
@@ -0,0 +1,239 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
# Configuration
|
||||
sqlite_exec = "./target/debug/limbo"
|
||||
cwd = os.getcwd()
|
||||
|
||||
# Initial setup commands
|
||||
init_commands = """
|
||||
CREATE TABLE users (id INTEGER PRIMARY KEY, first_name TEXT, last_name TEXT, age INTEGER);
|
||||
CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT, price INTEGER);
|
||||
INSERT INTO users (id, first_name, last_name, age) VALUES
|
||||
(1, 'Alice', 'Smith', 30), (2, 'Bob', 'Johnson', 25), (3, 'Charlie', 'Brown', 66), (4, 'David', 'Nichols', 70);
|
||||
INSERT INTO products (id, name, price) VALUES
|
||||
(1, 'Hat', 19.99), (2, 'Shirt', 29.99), (3, 'Shorts', 39.99), (4, 'Dress', 49.99);
|
||||
CREATE TABLE t (x1, x2, x3, x4);
|
||||
INSERT INTO t VALUES (zeroblob(1024 - 1), zeroblob(1024 - 2), zeroblob(1024 - 3), zeroblob(1024 - 4));
|
||||
"""
|
||||
|
||||
|
||||
def start_sqlite_repl(sqlite_exec, init_commands):
|
||||
# start limbo shell in quiet mode and pipe in init_commands
|
||||
pipe = subprocess.Popen(
|
||||
[sqlite_exec, "-q"],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
universal_newlines=True,
|
||||
bufsize=0,
|
||||
)
|
||||
if init_commands and pipe.stdin is not None:
|
||||
pipe.stdin.write(init_commands + "\n")
|
||||
pipe.stdin.flush()
|
||||
return pipe
|
||||
|
||||
|
||||
# get new pipe to limbo shell
|
||||
pipe = start_sqlite_repl(sqlite_exec, init_commands)
|
||||
|
||||
|
||||
def execute_sql(pipe, sql):
|
||||
write_to_pipe(sql + "\n")
|
||||
write_to_pipe("SELECT 'END_OF_RESULT';\n")
|
||||
|
||||
output = []
|
||||
while True:
|
||||
line = pipe.stdout.readline().strip()
|
||||
if line == "END_OF_RESULT":
|
||||
break
|
||||
output.append(line)
|
||||
return "\n".join(output).strip()
|
||||
|
||||
|
||||
def run_test(pipe, sql, expected_output):
|
||||
actual_output = execute_sql(pipe, sql)
|
||||
if actual_output != expected_output:
|
||||
print(f"Test FAILED: '{sql}'")
|
||||
print(f"Expected: {expected_output}")
|
||||
print(f"Returned: {actual_output}")
|
||||
exit(1)
|
||||
|
||||
|
||||
def do_execshell_test(pipe, test_name, sql, expected_output):
|
||||
print(f"Running test: {test_name}")
|
||||
run_test(pipe, sql, expected_output)
|
||||
|
||||
|
||||
def write_to_pipe(line):
|
||||
if pipe.stdin is None:
|
||||
print("Failed to start SQLite REPL")
|
||||
exit(1)
|
||||
pipe.stdin.write(line + "\n")
|
||||
pipe.stdin.flush()
|
||||
|
||||
|
||||
# Run tests
|
||||
do_execshell_test(pipe, "select-1", "SELECT 1;", "1")
|
||||
do_execshell_test(
|
||||
pipe,
|
||||
"schema-memory",
|
||||
".schema",
|
||||
"""CREATE TABLE users (id INTEGER PRIMARY KEY, first_name TEXT, last_name TEXT, age INTEGER);
|
||||
CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT, price INTEGER);
|
||||
CREATE TABLE t (x1, x2, x3, x4);""",
|
||||
)
|
||||
do_execshell_test(pipe, "select-avg", "SELECT avg(age) FROM users;", "47.75")
|
||||
do_execshell_test(pipe, "select-sum", "SELECT sum(age) FROM users;", "191")
|
||||
|
||||
do_execshell_test(pipe, "mem-sum-zero", "SELECT sum(first_name) FROM users;", "0.0")
|
||||
do_execshell_test(pipe, "mem-total-age", "SELECT total(age) FROM users;", "191.0")
|
||||
do_execshell_test(
|
||||
pipe, "mem-typeof", "SELECT typeof(id) FROM users LIMIT 1;", "integer"
|
||||
)
|
||||
|
||||
# test we can open a different db file and can attach to it
|
||||
do_execshell_test(pipe, "file-schema-1", ".open testing/testing.db", "")
|
||||
|
||||
# test some random queries to ensure the proper schema
|
||||
do_execshell_test(
|
||||
pipe,
|
||||
"file-schema-1",
|
||||
".schema users",
|
||||
"""CREATE TABLE users (
|
||||
id INTEGER PRIMARY KEY,
|
||||
first_name TEXT,
|
||||
last_name TEXT,
|
||||
email TEXT,
|
||||
phone_number TEXT,
|
||||
address TEXT,
|
||||
city TEXT,
|
||||
state TEXT,
|
||||
zipcode TEXT,
|
||||
age INTEGER
|
||||
);
|
||||
CREATE INDEX age_idx on users (age);""",
|
||||
)
|
||||
|
||||
do_execshell_test(pipe, "file-users-count", "select count(*) from users;", "10000")
|
||||
|
||||
do_execshell_test(
|
||||
pipe,
|
||||
"file-cross-join",
|
||||
"select * from users, products limit 1;",
|
||||
"1|Jamie|Foster|dylan00@example.com|496-522-9493|62375 Johnson Rest Suite 322|West Lauriestad|IL|35865|94|1|hat|79.0",
|
||||
)
|
||||
|
||||
do_execshell_test(
|
||||
pipe,
|
||||
"file-left-join-self",
|
||||
"select u1.first_name as user_name, u2.first_name as neighbor_name from users u1 left join users as u2 on u1.id = u2.id + 1 limit 2;",
|
||||
"Jamie|\nCindy|Jamie",
|
||||
)
|
||||
|
||||
do_execshell_test(
|
||||
pipe,
|
||||
"where-clause-eq-string",
|
||||
"select count(1) from users where last_name = 'Rodriguez';",
|
||||
"61",
|
||||
)
|
||||
|
||||
# test we can cd into a directory
|
||||
dir = "testing"
|
||||
outfile = "limbo_output.txt"
|
||||
|
||||
write_to_pipe(f".cd {dir}")
|
||||
|
||||
# test we can enable echo
|
||||
write_to_pipe(".echo on")
|
||||
|
||||
# Redirect output to a file in the new directory
|
||||
write_to_pipe(f".output {outfile}")
|
||||
|
||||
# make sure we cannot use pretty mode while outfile isnt a tty
|
||||
write_to_pipe(".mode pretty")
|
||||
|
||||
# this should print an error to the new outfile
|
||||
|
||||
write_to_pipe("SELECT 'TEST_ECHO';")
|
||||
write_to_pipe("")
|
||||
|
||||
write_to_pipe(".echo off")
|
||||
|
||||
# test we can set the null value
|
||||
write_to_pipe(".nullvalue LIMBO")
|
||||
|
||||
# print settings to evaluate in file
|
||||
write_to_pipe(".show")
|
||||
|
||||
# set output back to stdout
|
||||
write_to_pipe(".output stdout")
|
||||
|
||||
do_execshell_test(
|
||||
pipe,
|
||||
"test-switch-output-stdout",
|
||||
".show",
|
||||
f"""Settings:
|
||||
Output mode: raw
|
||||
DB: testing/testing.db
|
||||
Output: STDOUT
|
||||
Null value: LIMBO
|
||||
CWD: {cwd}/testing
|
||||
Echo: off""",
|
||||
)
|
||||
# test we can set the null value
|
||||
|
||||
write_to_pipe(".open :memory:")
|
||||
|
||||
do_execshell_test(
|
||||
pipe,
|
||||
"test-can-switch-back-to-in-memory",
|
||||
".schema users",
|
||||
"Error: Table 'users' not found.",
|
||||
)
|
||||
|
||||
do_execshell_test(pipe, "test-verify-null-value", "select NULL;", "LIMBO")
|
||||
|
||||
|
||||
# Verify the output file exists and contains expected content
|
||||
filepath = os.path.join(cwd, dir, outfile)
|
||||
|
||||
if not os.path.exists(filepath):
|
||||
print("Test FAILED: Output file not created")
|
||||
exit(1)
|
||||
|
||||
with open(filepath, "r") as f:
|
||||
file_contents = f.read()
|
||||
|
||||
# verify command was echo'd as well as mode was unchanged
|
||||
expected_lines = {
|
||||
f"Output: {outfile}": "Can direct output to a file",
|
||||
"Output mode: raw": "Output mode doesn't change when redirected from stdout",
|
||||
"Error: pretty output can only be written to a tty": "No ansi characters printed to non-tty",
|
||||
"SELECT 'TEST_ECHO'": "Echo properly echoes the command",
|
||||
"TEST_ECHO": "Echo properly prints the result",
|
||||
"Null value: LIMBO": "Null value is set properly",
|
||||
f"CWD: {cwd}/testing": "Shell can change directory",
|
||||
"DB: testing/testing.db": "Shell can open a different db file",
|
||||
"Echo: off": "Echo can be toggled on and off",
|
||||
}
|
||||
|
||||
all_lines_found = True
|
||||
for line, value in expected_lines.items():
|
||||
if line not in file_contents:
|
||||
print(f"Test FAILED: Expected line not found in file: {line}")
|
||||
all_lines_found = False
|
||||
else:
|
||||
print(f"Testing that: {value}")
|
||||
|
||||
if all_lines_found:
|
||||
print("Test PASSED: File contains all expected lines")
|
||||
else:
|
||||
print(f"File contents:\n{file_contents}")
|
||||
exit(1)
|
||||
|
||||
# Cleanup
|
||||
os.remove(filepath)
|
||||
pipe.terminate()
|
||||
print("All shell tests passed successfully.")
|
||||
Reference in New Issue
Block a user