Repository: duckdb/duckdb
File: tools/shell/tests/test_shell_basics.py (Python)

Code before:
    )
    random_dir_result = random_dir_test.run()
    random_dir_result.check_not_exist(pwd_dir)
    random_dir_result.check_stderr(None)

def test_changes_on(shell):
    test = (
        ShellTest(shell)
        .statement("CREATE TABLE a (I INTEGER)")
        .statement(".changes on")
        .statement("INSERT INTO a VALUES (42)")
        .statement("INSERT INTO a VALUES (42)")
        .statement("INSERT INTO a VALUES (42)")
        .statement("DROP TABLE a")
    )
    result = test.run()
    result.check_stdout("total_changes: 3")

def test_changes_off(shell):
    test = (
        ShellTest(shell)
        .statement("CREATE TABLE a (I INTEGER);")
        .statement(".changes off")
        .statement("INSERT INTO a VALUES (42);")
        .statement("DROP TABLE a;")
    )
    result = test.run()
    result.check_not_exist("changes:")
    result.check_stdout(None)

def test_echo(shell):
    test = (
        ShellTest(shell)
        .statement(".echo on")
        .statement("SELECT 42;")
    )
    result = test.run()
    result.check_stdout("SELECT 42")

def test_invalid_sql(shell):
    test = ShellTest(shell).statement("invalid command;")
    result = test.run()
    assert result.status_code == 1
    result.check_stderr("Parser Error: syntax error at or near \"invalid\"")

@pytest.mark.parametrize("alias", ["exit", "quit"])
def test_exit(shell, alias):
    test = ShellTest(shell).statement(f".{alias}").statement("invalid command;")
    result = test.run()
    # Shows that the exit & quit dot commands exit the shell prior to the error
    # Still indirect but ensures a failure if they do not work as expected

Review comment (suggestion):
Specifying `None` while defaulting to `False` for an empty string allows for a more explicit assertion.

Code after:
    random_dir_result.check_stderr(None)

def test_changes_on(shell):
    test = (
        ShellTest(shell)
        .statement("CREATE TABLE a (I INTEGER)")
        .statement(".changes on")
        .statement("INSERT INTO a VALUES (42)")
        .statement("INSERT INTO a VALUES (42)")
        .statement("INSERT INTO a VALUES (42)")
        .statement("DROP TABLE a")
    )
    result = test.run()
    result.check_stdout("total_changes: 3")

def test_changes_off(shell):
    test = (
        ShellTest(shell)
        .statement("CREATE TABLE a (I INTEGER);")
        .statement(".changes off")
        .statement("INSERT INTO a VALUES (42);")
        .statement("DROP TABLE a;")
    )
    result = test.run()
    result.check_not_exist("changes:")
    result.check_stdout(None)

def test_echo(shell):
    test = (
        ShellTest(shell)
        .statement(".echo on")
        .statement("SELECT 42;")
    )
    result = test.run()
    result.check_stdout("SELECT 42")

def test_invalid_sql(shell):
    test = ShellTest(shell).statement("invalid command;")
    result = test.run()
    assert result.status_code == 1
    result.check_stderr("Parser Error: syntax error at or near \"invalid\"")

@pytest.mark.parametrize("alias", ["exit", "quit"])
def test_exit(shell, alias):
    test = ShellTest(shell).statement(f".{alias}").statement("invalid command;")
    result = test.run()
    # Shows that the exit & quit dot commands exit the shell prior to the error
    # Still indirect but ensures a failure if they do not work as expected
    assert result.status_code == 0

def test_exit_rc(shell):