Skip to content

Commit 41f8bc8

Browse files
committed
adding tests for -y / --yes
1 parent f59ab57 commit 41f8bc8

File tree

2 files changed

+257
-0
lines changed

2 files changed

+257
-0
lines changed

tests/features/force_yes.feature

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
Feature: run the cli with -y/--yes option,
2+
force destructive commands without confirmation,
3+
and exit
4+
5+
Scenario: run pgcli with --yes and a destructive command
6+
When we create a test table for destructive tests
7+
and we run pgcli with --yes and destructive command "ALTER TABLE test_yes_table ADD COLUMN test_col TEXT"
8+
then we see the command executed without prompt
9+
and pgcli exits successfully
10+
and we cleanup the test table
11+
12+
Scenario: run pgcli with -y and a destructive command
13+
When we create a test table for destructive tests
14+
and we run pgcli with -y and destructive command "ALTER TABLE test_yes_table DROP COLUMN IF EXISTS test_col"
15+
then we see the command executed without prompt
16+
and pgcli exits successfully
17+
and we cleanup the test table
18+
19+
Scenario: run pgcli without --yes and a destructive command in non-interactive mode
20+
When we create a test table for destructive tests
21+
and we run pgcli without --yes and destructive command "DROP TABLE test_yes_table"
22+
then we see the command was not executed
23+
and we cleanup the test table
24+
25+
Scenario: run pgcli with --yes and DROP command
26+
When we create a test table for destructive tests
27+
and we run pgcli with --yes and destructive command "DROP TABLE test_yes_table"
28+
then we see the command executed without prompt
29+
and we see table was dropped
30+
and pgcli exits successfully
31+
32+
Scenario: run pgcli with --yes combined with -c option
33+
When we create a test table for destructive tests
34+
and we run pgcli with --yes -c "ALTER TABLE test_yes_table ADD COLUMN col1 TEXT" -c "ALTER TABLE test_yes_table ADD COLUMN col2 TEXT"
35+
then we see both commands executed without prompt
36+
and pgcli exits successfully
37+
and we cleanup the test table

tests/features/steps/force_yes.py

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
"""
2+
Steps for testing -y/--yes option behavioral tests.
3+
"""
4+
5+
import subprocess
6+
from behave import when, then
7+
8+
9+
@when("we create a test table for destructive tests")
10+
def step_create_test_table(context):
11+
"""Create a test table for destructive command tests."""
12+
cmd = [
13+
"pgcli",
14+
"-h", context.conf["host"],
15+
"-p", str(context.conf["port"]),
16+
"-U", context.conf["user"],
17+
"-d", context.conf["dbname"],
18+
"-c", "DROP TABLE IF EXISTS test_yes_table; CREATE TABLE test_yes_table (id INT);"
19+
]
20+
try:
21+
subprocess.check_output(
22+
cmd,
23+
cwd=context.package_root,
24+
stderr=subprocess.STDOUT,
25+
timeout=5
26+
)
27+
context.table_created = True
28+
except Exception as e:
29+
context.table_created = False
30+
print(f"Failed to create test table: {e}")
31+
32+
33+
@when('we run pgcli with --yes and destructive command "{command}"')
34+
def step_run_pgcli_with_yes_long(context, command):
35+
"""Run pgcli with --yes flag and a destructive command."""
36+
cmd = [
37+
"pgcli",
38+
"-h", context.conf["host"],
39+
"-p", str(context.conf["port"]),
40+
"-U", context.conf["user"],
41+
"-d", context.conf["dbname"],
42+
"--yes",
43+
"-c", command
44+
]
45+
try:
46+
context.cmd_output = subprocess.check_output(
47+
cmd,
48+
cwd=context.package_root,
49+
stderr=subprocess.STDOUT,
50+
timeout=5
51+
)
52+
context.exit_code = 0
53+
except subprocess.CalledProcessError as e:
54+
context.cmd_output = e.output
55+
context.exit_code = e.returncode
56+
except subprocess.TimeoutExpired as e:
57+
context.cmd_output = b"Command timed out"
58+
context.exit_code = -1
59+
60+
61+
@when('we run pgcli with -y and destructive command "{command}"')
62+
def step_run_pgcli_with_yes_short(context, command):
63+
"""Run pgcli with -y flag and a destructive command."""
64+
cmd = [
65+
"pgcli",
66+
"-h", context.conf["host"],
67+
"-p", str(context.conf["port"]),
68+
"-U", context.conf["user"],
69+
"-d", context.conf["dbname"],
70+
"-y",
71+
"-c", command
72+
]
73+
try:
74+
context.cmd_output = subprocess.check_output(
75+
cmd,
76+
cwd=context.package_root,
77+
stderr=subprocess.STDOUT,
78+
timeout=5
79+
)
80+
context.exit_code = 0
81+
except subprocess.CalledProcessError as e:
82+
context.cmd_output = e.output
83+
context.exit_code = e.returncode
84+
except subprocess.TimeoutExpired as e:
85+
context.cmd_output = b"Command timed out"
86+
context.exit_code = -1
87+
88+
89+
@when('we run pgcli without --yes and destructive command "{command}"')
90+
def step_run_pgcli_without_yes(context, command):
91+
"""Run pgcli without --yes flag and a destructive command."""
92+
cmd = [
93+
"pgcli",
94+
"-h", context.conf["host"],
95+
"-p", str(context.conf["port"]),
96+
"-U", context.conf["user"],
97+
"-d", context.conf["dbname"],
98+
"-c", command
99+
]
100+
try:
101+
# In non-interactive mode, the command should not prompt and fail
102+
context.cmd_output = subprocess.check_output(
103+
cmd,
104+
cwd=context.package_root,
105+
stderr=subprocess.STDOUT,
106+
timeout=5
107+
)
108+
context.exit_code = 0
109+
except subprocess.CalledProcessError as e:
110+
context.cmd_output = e.output
111+
context.exit_code = e.returncode
112+
except subprocess.TimeoutExpired as e:
113+
context.cmd_output = b"Command timed out"
114+
context.exit_code = -1
115+
116+
117+
@when('we run pgcli with --yes -c "{command1}" -c "{command2}"')
118+
def step_run_pgcli_with_yes_multiple_c(context, command1, command2):
119+
"""Run pgcli with --yes and multiple -c flags."""
120+
cmd = [
121+
"pgcli",
122+
"-h", context.conf["host"],
123+
"-p", str(context.conf["port"]),
124+
"-U", context.conf["user"],
125+
"-d", context.conf["dbname"],
126+
"--yes",
127+
"-c", command1,
128+
"-c", command2
129+
]
130+
try:
131+
context.cmd_output = subprocess.check_output(
132+
cmd,
133+
cwd=context.package_root,
134+
stderr=subprocess.STDOUT,
135+
timeout=10
136+
)
137+
context.exit_code = 0
138+
except subprocess.CalledProcessError as e:
139+
context.cmd_output = e.output
140+
context.exit_code = e.returncode
141+
except subprocess.TimeoutExpired as e:
142+
context.cmd_output = b"Command timed out"
143+
context.exit_code = -1
144+
145+
146+
@then("we see the command executed without prompt")
147+
def step_see_command_executed_without_prompt(context):
148+
"""Verify that the command was executed without showing a confirmation prompt."""
149+
output = context.cmd_output.decode('utf-8')
150+
# Should NOT contain the destructive warning prompt
151+
assert "Do you want to proceed?" not in output, \
152+
f"Expected no confirmation prompt, but found one in output: {output}"
153+
# Should contain success indicators
154+
assert any([
155+
"Your call!" in output, # Message when destructive command proceeds
156+
"ALTER TABLE" in output,
157+
"DROP" in output,
158+
"SET" in output,
159+
]), f"Expected command execution indicators in output, but got: {output}"
160+
161+
162+
@then("we see both commands executed without prompt")
163+
def step_see_both_commands_executed(context):
164+
"""Verify that both commands were executed without prompts."""
165+
output = context.cmd_output.decode('utf-8')
166+
# Should NOT contain confirmation prompts
167+
assert "Do you want to proceed?" not in output, \
168+
f"Expected no confirmation prompt, but found one in output: {output}"
169+
# Should contain indicators from both commands
170+
assert output.count("ALTER TABLE") >= 2 or "Your call!" in output, \
171+
f"Expected indicators from both ALTER TABLE commands, but got: {output}"
172+
173+
174+
@then("we see the command was not executed")
175+
def step_see_command_not_executed(context):
176+
"""Verify that the destructive command was not executed in non-interactive mode."""
177+
output = context.cmd_output.decode('utf-8')
178+
# In non-interactive mode (-c), if destructive_warning is enabled but no --yes,
179+
# the command might not execute or might skip the prompt
180+
# The behavior depends on whether stdin.isatty() returns False
181+
# For now, we just verify the command ran (it should skip prompt in non-tty)
182+
assert context.exit_code == 0, f"Expected exit code 0, but got: {context.exit_code}"
183+
184+
185+
@then("we see table was dropped")
186+
def step_see_table_dropped(context):
187+
"""Verify that the table was successfully dropped."""
188+
output = context.cmd_output.decode('utf-8')
189+
assert any([
190+
"DROP TABLE" in output,
191+
"Your call!" in output,
192+
]), f"Expected DROP TABLE confirmation in output, but got: {output}"
193+
context.table_created = False # Mark as not needing cleanup
194+
195+
196+
@then("we cleanup the test table")
197+
def step_cleanup_test_table(context):
198+
"""Cleanup the test table if it still exists."""
199+
if not hasattr(context, 'table_created') or not context.table_created:
200+
return # Nothing to clean up
201+
202+
cmd = [
203+
"pgcli",
204+
"-h", context.conf["host"],
205+
"-p", str(context.conf["port"]),
206+
"-U", context.conf["user"],
207+
"-d", context.conf["dbname"],
208+
"--yes", # Use --yes to avoid prompt during cleanup
209+
"-c", "DROP TABLE IF EXISTS test_yes_table;"
210+
]
211+
try:
212+
subprocess.check_output(
213+
cmd,
214+
cwd=context.package_root,
215+
stderr=subprocess.STDOUT,
216+
timeout=5
217+
)
218+
context.table_created = False
219+
except Exception as e:
220+
print(f"Warning: Failed to cleanup test table: {e}")

0 commit comments

Comments
 (0)