import csv
import subprocess
import sys
from io import StringIO
from pathlib import Path
def run_query(query, data_file=None):
base_dir = Path(__file__).parent.parent.parent
suffix = ".exe" if sys.platform == "win32" else ""
sql_cli = base_dir / "target" / "release" / f"sql-cli{suffix}"
if not sql_cli.exists():
raise FileNotFoundError(f"sql-cli not found at {sql_cli}")
cmd = [str(sql_cli)]
if data_file:
data_path = base_dir / "data" / data_file
if not data_path.exists():
raise FileNotFoundError(f"Data file not found: {data_path}")
cmd.append(str(data_path))
cmd.extend(["-q", query, "-o", "csv"])
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"Error running query: {result.stderr}")
return None
reader = csv.DictReader(StringIO(result.stdout))
return list(reader)
def test_datetime_from_literals():
results = run_query("SELECT DATETIME(1732, 2, 22) AS d")
assert results is not None
assert results[0]['d'] == '1732-02-22 00:00:00.000'
print("✓ test_datetime_from_literals passed")
def test_datetime_with_time_components():
results = run_query("SELECT DATETIME(2024, 1, 15, 14, 30, 0) AS d")
assert results is not None
assert results[0]['d'] == '2024-01-15 14:30:00.000'
print("✓ test_datetime_with_time_components passed")
def test_datetime_no_args_is_today():
results = run_query("SELECT DATETIME() AS d")
assert results is not None
assert results[0]['d'].endswith(' 00:00:00.000')
assert len(results[0]['d']) == len('2026-08-16 00:00:00.000')
print("✓ test_datetime_no_args_is_today passed")
def test_datetime_from_columns():
query = ("SELECT Name, DATETIME(Year, Month, Day) AS BirthDate "
"FROM president_birthdays WHERE Year = 1732")
results = run_query(query, "president_birthdays.csv")
assert results is not None
assert len(results) == 1
assert results[0]['Name'] == 'George Washington'
assert results[0]['BirthDate'] == '1732-02-22 00:00:00.000'
print("✓ test_datetime_from_columns passed")
def test_datetime_from_arithmetic():
query = ("SELECT DATETIME(Year + 100, Month, Day) AS d "
"FROM president_birthdays WHERE Year = 1732")
results = run_query(query, "president_birthdays.csv")
assert results is not None
assert results[0]['d'] == '1832-02-22 00:00:00.000'
print("✓ test_datetime_from_arithmetic passed")
def test_datetime_with_cast_argument():
query = ("SELECT DATETIME(CAST(Year AS INTEGER), Month, Day) AS d "
"FROM president_birthdays WHERE Year = 1732")
results = run_query(query, "president_birthdays.csv")
assert results is not None
assert results[0]['d'] == '1732-02-22 00:00:00.000'
print("✓ test_datetime_with_cast_argument passed")
def test_datetime_in_where_clause():
query = ("SELECT Name FROM president_birthdays "
"WHERE DATETIME(Year, Month, Day) > DATETIME(1950, 1, 1)")
results = run_query(query, "president_birthdays.csv")
assert results is not None
assert [row['Name'] for row in results] == ['Barack Hussein Obama']
print("✓ test_datetime_in_where_clause passed")
def test_datetime_feeds_date_functions():
query = ("SELECT DAYNAME(DATETIME(Year, Month, Day)) AS BornOn, "
"QUARTER(DATETIME(Year, Month, Day)) AS Qtr "
"FROM president_birthdays WHERE Year = 1732")
results = run_query(query, "president_birthdays.csv")
assert results is not None
assert results[0]['BornOn'] == 'Friday'
assert results[0]['Qtr'] == '1'
print("✓ test_datetime_feeds_date_functions passed")
def test_datetime_propagates_null():
query = "SELECT 'x' AS tag, DATETIME(NULL, 1, 15) AS d"
results = run_query(query)
assert results is not None
assert len(results) == 1
assert results[0]['tag'] == 'x'
assert results[0]['d'] == ''
print("✓ test_datetime_propagates_null passed")
def test_cast_as_datetime_still_parses():
results = run_query("SELECT CAST('2024-01-15' AS DATETIME) AS d")
assert results is not None
assert results[0]['d'].startswith('2024-01-15')
print("✓ test_cast_as_datetime_still_parses passed")
if __name__ == "__main__":
test_datetime_from_literals()
test_datetime_with_time_components()
test_datetime_no_args_is_today()
test_datetime_from_columns()
test_datetime_from_arithmetic()
test_datetime_with_cast_argument()
test_datetime_in_where_clause()
test_datetime_feeds_date_functions()
test_datetime_propagates_null()
test_cast_as_datetime_still_parses()
print("\nAll DATETIME constructor tests passed!")