1+ import pytest
2+
3+ from manage .config import (
4+ _expand_vars ,
5+ config_append ,
6+ config_bool ,
7+ config_dict_merge ,
8+ config_split ,
9+ config_split_append ,
10+ )
11+
12+
13+ @pytest .mark .parametrize (
14+ ("value" , "expected" ),
15+ [
16+ (None , False ),
17+ ("" , False ),
18+ ("true" , True ),
19+ (0 , False ),
20+ ("TRUE" , True ),
21+ ("True" , True ),
22+ ("yes" , True ),
23+ ("1" , True ),
24+ ("false" , False ),
25+ ("no" , False ),
26+ ("0" , False ),
27+ ("yellow" , True ),
28+ ("%PYTHON_MANAGER_CONFIRM%" , False ),
29+ (True , True ),
30+ (42 , True ),
31+ (["x" ], True ),
32+ ],
33+ ids = [
34+ "none" ,
35+ "str_empty" ,
36+ "str_true_lower" ,
37+ "int_zero" ,
38+ "str_true_upper" ,
39+ "str_true_title" ,
40+ "str_yes" ,
41+ "str_one" ,
42+ "str_false" ,
43+ "str_no" ,
44+ "str_zero" ,
45+ "str_yellow" ,
46+ "str_environment_variable" ,
47+ "bool_true" ,
48+ "int_positive" ,
49+ "list_nonempty" ,
50+ ],
51+ )
52+ def test_config_bool (value , expected ):
53+ assert config_bool (value ) is expected
54+
55+
56+ def test_config_bool_any_t_prefixed_string_is_true ():
57+ assert config_bool ("tomato" ) is True
58+
59+
60+ @pytest .mark .parametrize (
61+ ("value" , "variables" , "expected" ),
62+ [
63+ ("%FOO%" , {"FOO" : "bar" }, "bar" ),
64+ (
65+ "%LocalAppData%\\ Python" ,
66+ {"LocalAppData" : "C:\\ Temp" },
67+ "C:\\ Temp\\ Python" ,
68+ ),
69+ ("./bundled/fallback-index.json" , {}, "./bundled/fallback-index.json" ),
70+ ("%A%%B%" , {"A" : "x" , "B" : "y" }, "xy" ),
71+ (
72+ "%LocalAppData%\\ Python\\ _cache" ,
73+ {"LocalAppData" : "C:\\ Temp" },
74+ "C:\\ Temp\\ Python\\ _cache" ,
75+ ),
76+ ("%FOO%/bar" , {"FOO" : "x" }, "x/bar" ),
77+ ],
78+ ids = [
79+ "var_only" ,
80+ "var_with_separator" ,
81+ "no_vars" ,
82+ "adjacent_vars" ,
83+ "nested_path" ,
84+ "forward_slash" ,
85+ ],
86+ )
87+ def test_expand_vars (value , variables , expected ):
88+ assert _expand_vars (value , variables ) == expected
89+
90+
91+ def test_expand_vars_removes_missing_variable_and_leading_separator ():
92+ actual = _expand_vars ("%MISSING%\\ Python" , {})
93+
94+ assert actual == "Python"
95+
96+
97+ def test_expand_vars_removes_empty_variable_and_leading_separator ():
98+ actual = _expand_vars ("%EMPTY%\\ Python" , {"EMPTY" : "" })
99+
100+ assert actual == "Python"
101+
102+
103+ @pytest .mark .parametrize (
104+ ("existing" , "value" , "expected" ),
105+ [
106+ (None , "a" , ["a" ]),
107+ ("a" , "b" , ["a" , "b" ]),
108+ (["a" ], "b" , ["a" , "b" ]),
109+ ],
110+ ids = [
111+ "none" ,
112+ "scalar" ,
113+ "list" ,
114+ ],
115+ )
116+ def test_config_append (existing , value , expected ):
117+ assert config_append (existing , value ) == expected
118+
119+
120+ def test_config_append_does_not_mutate_existing_list ():
121+ existing = ["a" ]
122+
123+ actual = config_append (existing , "b" )
124+
125+ assert actual == ["a" , "b" ]
126+ assert existing == ["a" ]
127+ assert actual is not existing
128+
129+
130+ @pytest .mark .parametrize (
131+ ("existing" , "new" , "expected" ),
132+ [
133+ ({"a" : 1 }, {"b" : 2 }, {"a" : 1 , "b" : 2 }),
134+ ({"a" : 1 }, {"a" : 2 }, {"a" : 2 }),
135+ ],
136+ ids = [
137+ "distinct_keys" ,
138+ "new_value_overwrites" ,
139+ ],
140+ )
141+ def test_config_dict_merge (existing , new , expected ):
142+ assert config_dict_merge (existing , new ) == expected
143+
144+
145+ def test_config_dict_merge_does_not_mutate_inputs ():
146+ existing = {"a" : 1 }
147+ new = {"b" : 2 }
148+
149+ actual = config_dict_merge (existing , new )
150+
151+ assert actual == {"a" : 1 , "b" : 2 }
152+ assert existing == {"a" : 1 }
153+ assert new == {"b" : 2 }
154+ assert actual is not existing
155+ assert actual is not new
156+
157+
158+ @pytest .mark .parametrize (
159+ ("value" , "expected" ),
160+ [
161+ ("" , ["" ]),
162+ ("a,b" , ["a" , "b" ]),
163+ ("a,,b" , ["a" , "" , "b" ]),
164+ ("C:\\ tools" , ["C" , "\\ tools" ]),
165+ ("a;b:c|d+e" , ["a" , "b" , "c" , "d" , "e" ]),
166+ ],
167+ ids = [
168+ "empty" ,
169+ "comma" ,
170+ "consecutive_delimiters" ,
171+ "windows_path" ,
172+ "all_delimiters" ,
173+ ],
174+ )
175+ def test_config_split (value , expected ):
176+ assert config_split (value ) == expected
177+
178+
179+ @pytest .mark .parametrize (
180+ ("existing" , "value" , "expected" ),
181+ [
182+ (None , "a,b" , [["a" , "b" ]]),
183+ ("existing" , "a,b" , ["existing" , ["a" , "b" ]]),
184+ (["existing" ], "a,b" , ["existing" , ["a" , "b" ]]),
185+ ],
186+ ids = [
187+ "none" ,
188+ "scalar" ,
189+ "list" ,
190+ ],
191+ )
192+ def test_config_split_append (existing , value , expected ):
193+ assert config_split_append (existing , value ) == expected
194+
195+
196+ def test_config_split_append_does_not_mutate_existing_list ():
197+ existing = ["first" ]
198+
199+ actual = config_split_append (existing , "second,third" )
200+
201+ assert actual == ["first" , ["second" , "third" ]]
202+ assert existing == ["first" ]
203+ assert actual is not existing
0 commit comments