Skip to content

Commit 7ddb02b

Browse files
committed
adding validate_gantt tests file
1 parent 9e2a2f0 commit 7ddb02b

File tree

1 file changed

+215
-0
lines changed

1 file changed

+215
-0
lines changed
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
import pytest
2+
3+
from plotly import exceptions, optional_imports
4+
from plotly.figure_factory._gantt import validate_gantt
5+
6+
pd = optional_imports.get_module("pandas")
7+
REQUIRED_GANTT_KEYS = ["Task", "Start", "Finish"]
8+
9+
10+
# --- BASIC TEST CASES ---
11+
12+
def test_valid_list_of_dicts():
13+
input_data = [
14+
{"Task": "A", "Start": "2020-01-01", "Finish": "2020-01-02"},
15+
{"Task": "B", "Start": "2020-01-03", "Finish": "2020-01-04"},
16+
]
17+
18+
result = validate_gantt(input_data)
19+
assert result is input_data
20+
assert len(result) == 2
21+
assert all(isinstance(x, dict) for x in result)
22+
23+
24+
@pytest.mark.skipif(pd is None, reason="pandas is not available")
25+
def test_valid_dataframe():
26+
df = pd.DataFrame(
27+
[
28+
{"Task": "A", "Start": "2020-01-01", "Finish": "2020-01-02"},
29+
{"Task": "B", "Start": "2020-01-03", "Finish": "2020-01-04"},
30+
]
31+
)
32+
result = validate_gantt(df)
33+
assert isinstance(result, list)
34+
assert len(result) == 2
35+
assert set(result[0].keys()) == set(df.columns)
36+
assert result[0]["Task"] == "A"
37+
assert result[1]["Finish"] == "2020-01-04"
38+
39+
40+
def test_valid_list_with_extra_keys():
41+
input_data = [
42+
{"Task": "A", "Start": "2020-01-01", "Finish": "2020-01-02", "Resource": "X"},
43+
{"Task": "B", "Start": "2020-01-03", "Finish": "2020-01-04", "Resource": "Y"},
44+
]
45+
result = validate_gantt(input_data)
46+
assert result is input_data
47+
assert all("Resource" in row for row in result)
48+
49+
50+
@pytest.mark.skipif(pd is None, reason="pandas is not available")
51+
def test_valid_dataframe_with_extra_keys():
52+
df = pd.DataFrame(
53+
[
54+
{"Task": "A", "Start": "2020-01-01", "Finish": "2020-01-02", "Resource": "X"},
55+
{"Task": "B", "Start": "2020-01-03", "Finish": "2020-01-04", "Resource": "Y"},
56+
]
57+
)
58+
result = validate_gantt(df)
59+
assert len(result) == 2
60+
assert set(result[0].keys()) == set(["Task", "Start", "Finish", "Resource"])
61+
62+
63+
# --- EDGE TEST CASES ---
64+
65+
def test_missing_required_key_in_list():
66+
input_data = [
67+
{"Task": "A", "Start": "2020-01-01"}, # Missing "Finish"
68+
]
69+
# Should NOT raise: list input is not validated for keys
70+
result = validate_gantt(input_data)
71+
assert result is input_data
72+
73+
74+
@pytest.mark.skipif(pd is None, reason="pandas is not available")
75+
def test_missing_required_key_in_dataframe():
76+
df = pd.DataFrame([
77+
{"Task": "A", "Start": "2020-01-01"}, # Missing "Finish"
78+
])
79+
with pytest.raises(exceptions.PlotlyError):
80+
validate_gantt(df)
81+
82+
83+
def test_empty_list():
84+
with pytest.raises(exceptions.PlotlyError):
85+
validate_gantt([])
86+
87+
88+
def test_input_is_not_list_or_dataframe():
89+
with pytest.raises(exceptions.PlotlyError):
90+
validate_gantt("Not a list or DataFrame")
91+
92+
93+
@pytest.mark.skipif(pd is None, reason="pandas is not available")
94+
def test_dataframe_with_no_rows():
95+
df = pd.DataFrame(columns=["Task", "Start", "Finish"])
96+
result = validate_gantt(df)
97+
assert isinstance(result, list)
98+
assert result == []
99+
100+
101+
@pytest.mark.skipif(pd is None, reason="pandas is not available")
102+
def test_dataframe_with_extra_rows_and_missing_keys():
103+
df = pd.DataFrame(
104+
[
105+
{"Task": "A", "Start": "2020-01-01", "Resource": "X"},
106+
{"Task": "B", "Start": "2020-01-03", "Resource": "Y"},
107+
]
108+
)
109+
with pytest.raises(exceptions.PlotlyError):
110+
validate_gantt(df)
111+
112+
113+
def test_list_with_dict_missing_all_keys():
114+
input_data = [{"Resource": "X"}]
115+
# Should NOT raise: list input is not validated for keys
116+
result = validate_gantt(input_data)
117+
assert result is input_data
118+
119+
120+
@pytest.mark.skipif(pd is None, reason="pandas is not available")
121+
def test_dataframe_with_only_required_keys():
122+
df = pd.DataFrame([
123+
{"Task": "A", "Start": "2020-01-01", "Finish": "2020-01-02"},
124+
])
125+
result = validate_gantt(df)
126+
assert len(result) == 1
127+
assert set(result[0].keys()) == set(REQUIRED_GANTT_KEYS)
128+
129+
130+
# --- LARGE SCALE TEST CASES ---
131+
132+
def test_large_list_of_dicts():
133+
input_data = [
134+
{"Task": f"Task{i}", "Start": f"2020-01-{i%30+1:02d}", "Finish": f"2020-02-{i%28+1:02d}"}
135+
for i in range(1000)
136+
]
137+
result = validate_gantt(input_data)
138+
assert result is input_data
139+
assert len(result) == 1000
140+
141+
142+
@pytest.mark.skipif(pd is None, reason="pandas is not available")
143+
def test_large_dataframe():
144+
df = pd.DataFrame([
145+
{"Task": f"Task{i}", "Start": f"2020-01-{i%30+1:02d}", "Finish": f"2020-02-{i%28+1:02d}"}
146+
for i in range(1000)
147+
])
148+
result = validate_gantt(df)
149+
assert isinstance(result, list)
150+
assert len(result) == 1000
151+
assert set(result[0].keys()) == set(df.columns)
152+
153+
154+
@pytest.mark.skipif(pd is None, reason="pandas is not available")
155+
def test_large_dataframe_missing_key():
156+
df = pd.DataFrame([
157+
{"Task": f"Task{i}", "Start": f"2020-01-{i%30+1:02d}"} # Missing "Finish"
158+
for i in range(1000)
159+
])
160+
with pytest.raises(exceptions.PlotlyError):
161+
validate_gantt(df)
162+
163+
164+
def test_large_list_with_non_dict_first_element():
165+
input_data = [
166+
"Not a dict",
167+
*[
168+
{"Task": f"Task{i}", "Start": f"2020-01-{i%30+1:02d}", "Finish": f"2020-02-{i%28+1:02d}"}
169+
for i in range(999)
170+
],
171+
]
172+
with pytest.raises(exceptions.PlotlyError):
173+
validate_gantt(input_data)
174+
175+
176+
def test_large_list_with_non_dict_later_element():
177+
input_data = [
178+
*[
179+
{"Task": f"Task{i}", "Start": f"2020-01-{i%30+1:02d}", "Finish": f"2020-02-{i%28+1:02d}"}
180+
for i in range(999)
181+
],
182+
"Not a dict",
183+
]
184+
# Should NOT raise: only first element is checked
185+
result = validate_gantt(input_data)
186+
assert result is input_data
187+
assert len(result) == 1000
188+
189+
190+
# --- Additional determinism/robustness checks ---
191+
192+
def test_determinism_multiple_calls_list():
193+
input_data = [
194+
{"Task": "A", "Start": "2023-01-01", "Finish": "2023-01-02"},
195+
{"Task": "B", "Start": "2023-01-02", "Finish": "2023-01-03"},
196+
]
197+
out1 = validate_gantt(input_data)
198+
out2 = validate_gantt(input_data)
199+
assert out1 is input_data
200+
assert out2 is input_data
201+
202+
203+
@pytest.mark.skipif(pd is None, reason="pandas is not available")
204+
def test_dataframe_column_order_and_index():
205+
df = pd.DataFrame([
206+
{"Finish": "2023-01-02", "Start": "2023-01-01", "Task": "A"},
207+
{"Finish": "2023-01-03", "Start": "2023-01-02", "Task": "B"},
208+
], index=["x", "y"])
209+
result = validate_gantt(df)
210+
assert len(result) == 2
211+
# Ensure values preserved regardless of order/index
212+
assert result[0]["Task"] == "A"
213+
assert set(result[0].keys()) == set(["Task", "Start", "Finish"])
214+
215+

0 commit comments

Comments
 (0)