44from plotly .figure_factory ._gantt import validate_gantt
55
66pd = optional_imports .get_module ("pandas" )
7- REQUIRED_GANTT_KEYS = ["Task" , "Start" , "Finish" ]
87
9-
10- # --- BASIC TEST CASES ---
11-
12-
13- def test_valid_list_of_dicts ():
14- input_data = [
15- {"Task" : "A" , "Start" : "2020-01-01" , "Finish" : "2020-01-02" },
16- {"Task" : "B" , "Start" : "2020-01-03" , "Finish" : "2020-01-04" },
17- ]
18-
19- result = validate_gantt (input_data )
20- assert result is input_data
21- assert len (result ) == 2
22- assert all (isinstance (x , dict ) for x in result )
23-
24-
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 = [
8+ @pytest .mark .parametrize ("input_type" , ["list" , "dataframe" ])
9+ def test_valid_with_extra_keys (input_type ):
10+ """Test that extra keys beyond required ones are preserved."""
11+ data = [
4212 {"Task" : "A" , "Start" : "2020-01-01" , "Finish" : "2020-01-02" , "Resource" : "X" },
4313 {"Task" : "B" , "Start" : "2020-01-03" , "Finish" : "2020-01-04" , "Resource" : "Y" },
4414 ]
45- result = validate_gantt (input_data )
46- assert result is input_data
47- assert all ("Resource" in row for row in result )
48-
15+ if input_type == "dataframe" :
16+ input_data = pd .DataFrame (data )
17+ result = validate_gantt (input_data )
18+ assert isinstance (result , list )
19+ assert set (result [0 ].keys ()) == set (input_data .columns )
20+ else :
21+ input_data = data
22+ result = validate_gantt (input_data )
23+ assert result is input_data
4924
50- def test_valid_dataframe_with_extra_keys ():
51- df = pd .DataFrame (
52- [
53- {
54- "Task" : "A" ,
55- "Start" : "2020-01-01" ,
56- "Finish" : "2020-01-02" ,
57- "Resource" : "X" ,
58- },
59- {
60- "Task" : "B" ,
61- "Start" : "2020-01-03" ,
62- "Finish" : "2020-01-04" ,
63- "Resource" : "Y" ,
64- },
65- ]
66- )
67- result = validate_gantt (df )
6825 assert len (result ) == 2
26+ assert all ("Resource" in row for row in result )
6927 assert set (result [0 ].keys ()) == set (["Task" , "Start" , "Finish" , "Resource" ])
28+ assert result [0 ]["Task" ] == "A"
29+ assert result [1 ]["Finish" ] == "2020-01-04"
7030
7131
72- # --- EDGE TEST CASES ---
73-
74-
75- def test_missing_required_key_in_list ():
76- input_data = [
77- {"Task" : "A" , "Start" : "2020-01-01" }, # Missing "Finish"
78- ]
79- # Should NOT raise: list input is not validated for keys
80- result = validate_gantt (input_data )
81- assert result is input_data
82-
8332
8433def test_missing_required_key_in_dataframe ():
8534 df = pd .DataFrame (
@@ -108,82 +57,13 @@ def test_dataframe_with_no_rows():
10857 assert result == []
10958
11059
111- def test_dataframe_with_extra_rows_and_missing_keys ():
112- df = pd .DataFrame (
113- [
114- {"Task" : "A" , "Start" : "2020-01-01" , "Resource" : "X" },
115- {"Task" : "B" , "Start" : "2020-01-03" , "Resource" : "Y" },
116- ]
117- )
118- with pytest .raises (exceptions .PlotlyError ):
119- validate_gantt (df )
120-
121-
12260def test_list_with_dict_missing_all_keys ():
12361 input_data = [{"Resource" : "X" }]
12462 # Should NOT raise: list input is not validated for keys
12563 result = validate_gantt (input_data )
12664 assert result is input_data
12765
12866
129- def test_dataframe_with_only_required_keys ():
130- df = pd .DataFrame (
131- [
132- {"Task" : "A" , "Start" : "2020-01-01" , "Finish" : "2020-01-02" },
133- ]
134- )
135- result = validate_gantt (df )
136- assert len (result ) == 1
137- assert set (result [0 ].keys ()) == set (REQUIRED_GANTT_KEYS )
138-
139-
140- # --- LARGE SCALE TEST CASES ---
141-
142-
143- def test_large_list_of_dicts ():
144- input_data = [
145- {
146- "Task" : f"Task{ i } " ,
147- "Start" : f"2020-01-{ i % 30 + 1 :02d} " ,
148- "Finish" : f"2020-02-{ i % 28 + 1 :02d} " ,
149- }
150- for i in range (1000 )
151- ]
152- result = validate_gantt (input_data )
153- assert result is input_data
154- assert len (result ) == 1000
155-
156-
157- def test_large_dataframe ():
158- df = pd .DataFrame (
159- [
160- {
161- "Task" : f"Task{ i } " ,
162- "Start" : f"2020-01-{ i % 30 + 1 :02d} " ,
163- "Finish" : f"2020-02-{ i % 28 + 1 :02d} " ,
164- }
165- for i in range (1000 )
166- ]
167- )
168- result = validate_gantt (df )
169- assert isinstance (result , list )
170- assert len (result ) == 1000
171- assert set (result [0 ].keys ()) == set (df .columns )
172-
173-
174- def test_large_dataframe_missing_key ():
175- df = pd .DataFrame (
176- [
177- {
178- "Task" : f"Task{ i } " ,
179- "Start" : f"2020-01-{ i % 30 + 1 :02d} " ,
180- } # Missing "Finish"
181- for i in range (1000 )
182- ]
183- )
184- with pytest .raises (exceptions .PlotlyError ):
185- validate_gantt (df )
186-
18767
18868def test_large_list_with_non_dict_first_element ():
18969 input_data = [
@@ -201,37 +81,6 @@ def test_large_list_with_non_dict_first_element():
20181 validate_gantt (input_data )
20282
20383
204- def test_large_list_with_non_dict_later_element ():
205- input_data = [
206- * [
207- {
208- "Task" : f"Task{ i } " ,
209- "Start" : f"2020-01-{ i % 30 + 1 :02d} " ,
210- "Finish" : f"2020-02-{ i % 28 + 1 :02d} " ,
211- }
212- for i in range (999 )
213- ],
214- "Not a dict" ,
215- ]
216- # Should NOT raise: only first element is checked
217- result = validate_gantt (input_data )
218- assert result is input_data
219- assert len (result ) == 1000
220-
221-
222- # --- Additional determinism/robustness checks ---
223-
224-
225- def test_determinism_multiple_calls_list ():
226- input_data = [
227- {"Task" : "A" , "Start" : "2023-01-01" , "Finish" : "2023-01-02" },
228- {"Task" : "B" , "Start" : "2023-01-02" , "Finish" : "2023-01-03" },
229- ]
230- out1 = validate_gantt (input_data )
231- out2 = validate_gantt (input_data )
232- assert out1 is input_data
233- assert out2 is input_data
234-
23584
23685def test_dataframe_column_order_and_index ():
23786 df = pd .DataFrame (
0 commit comments