Skip to content

Commit dfe0334

Browse files
committed
Add tests for features/main.py
1 parent 6a096d8 commit dfe0334

File tree

1 file changed

+277
-0
lines changed

1 file changed

+277
-0
lines changed

tests/features/test_main.py

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
import builtins
2+
import io
3+
import sys
4+
import types
5+
import pytest
6+
7+
import gardenlinux.features.__main__ as fema
8+
9+
# -------------------------------
10+
# Helper function tests
11+
# -------------------------------
12+
13+
14+
def test_get_cname_base():
15+
# Arrange
16+
sorted_features = ["base", "_hidden", "extra"]
17+
18+
# Act
19+
result = fema.get_cname_base(sorted_features)
20+
21+
# Assert
22+
assert result == "base_hidden-extra"
23+
24+
25+
def test_get_cname_base_empty_raises():
26+
# get_cname_base with empty iterable raises TypeError
27+
with pytest.raises(TypeError):
28+
fema.get_cname_base([])
29+
30+
31+
def test_sort_return_intersection_subset():
32+
# Arrange
33+
input_set = {"a", "c"}
34+
order_list = ["a", "b", "c", "d"]
35+
36+
# Act
37+
result = fema.sort_subset(input_set, order_list)
38+
39+
# Assert
40+
assert result == ["a", "c"]
41+
42+
43+
def test_sort_subset_nomatch():
44+
# Arrange
45+
input_set = {"x", "y"}
46+
order_list = ["a", "b", "c"]
47+
48+
# Act
49+
result = fema.sort_subset(input_set, order_list)
50+
51+
# Assert
52+
assert result == []
53+
54+
55+
def test_sort_subset_with_empty_order_list():
56+
# Arrange
57+
input_set = {"a", "b"}
58+
order_list = []
59+
60+
result = fema.sort_subset(input_set, order_list)
61+
62+
assert result == []
63+
64+
65+
def test_graph_mermaid():
66+
# Arrange
67+
class FakeGraph:
68+
edges = [("a", "b"), ("b", "c")]
69+
70+
flavor = "test"
71+
72+
# Act
73+
markup = fema.graph_as_mermaid_markup(flavor, FakeGraph())
74+
75+
# Assert
76+
assert "graph TD" in markup
77+
assert "a-->b" in markup
78+
assert "b-->c" in markup
79+
80+
81+
def test_get_minimal_feature_set_filters():
82+
# Arrange
83+
class FakeGraph:
84+
def in_degree(self):
85+
return [("a", 0), ("b", 1), ("c", 0)]
86+
87+
graph = FakeGraph()
88+
89+
# Act
90+
result = fema.get_minimal_feature_set(graph)
91+
92+
# Assert
93+
assert result == {"a", "c"}
94+
95+
96+
def test_get_version_and_commit_from_file(tmp_path):
97+
# Arrange
98+
commit_file = tmp_path / "COMMIT"
99+
commit_file.write_text("abcdef12\n")
100+
version_file = tmp_path / "VERSION"
101+
version_file.write_text("1.2.3\n")
102+
103+
# Act
104+
version, commit = fema.get_version_and_commit_id_from_files(str(tmp_path))
105+
106+
# Arrange
107+
assert version == "1.2.3"
108+
assert commit == "abcdef12"
109+
110+
111+
def test_get_version_missing_file_raises(tmp_path):
112+
# Arrange (one file only)
113+
(tmp_path / "COMMIT").write_text("abcdef1234\n")
114+
115+
# Act / Assert
116+
with pytest.raises(RuntimeError):
117+
fema.get_version_and_commit_id_from_files(str(tmp_path))
118+
119+
120+
# -------------------------------
121+
# Tests for main()
122+
# -------------------------------
123+
def test_main_prints_arch(monkeypatch, capsys):
124+
# Arrange
125+
argv = ["prog", "--arch", "amd64", "--features", "f1", "--version", "1.0", "arch"]
126+
monkeypatch.setattr(sys, "argv", argv)
127+
monkeypatch.setattr(fema, "Parser", lambda *a, **kw: None)
128+
129+
# Act
130+
fema.main()
131+
132+
# Assert
133+
out = capsys.readouterr().out
134+
assert "amd64" in out
135+
136+
137+
def test_main_prints_flags_elements_platforms(monkeypatch, capsys):
138+
# Arrange
139+
argv = [
140+
"prog",
141+
"--arch",
142+
"amd64",
143+
"--features",
144+
"flag1,element1,platform1",
145+
"--version",
146+
"1.0",
147+
"flags",
148+
]
149+
monkeypatch.setattr(sys, "argv", argv)
150+
151+
class FakeParser:
152+
def __init__(self, *a, **k):
153+
pass
154+
155+
@staticmethod
156+
def filter_as_dict(*a, **k):
157+
return {
158+
"flag": ["flag1"],
159+
"element": ["element1"],
160+
"platform": ["platform1"],
161+
}
162+
163+
monkeypatch.setattr(fema, "Parser", FakeParser)
164+
165+
# Act
166+
fema.main()
167+
168+
# Assert
169+
out = capsys.readouterr().out
170+
assert "flag1" in out
171+
172+
173+
def test_main_prints_version(monkeypatch, capsys):
174+
# Arrange
175+
argv = ["prog", "--arch", "amd64", "--features", "f1", "version"]
176+
monkeypatch.setattr(sys, "argv", argv)
177+
monkeypatch.setattr(
178+
fema,
179+
"Parser",
180+
lambda *a, **kw: types.SimpleNamespace(filter=lambda *a, **k: None),
181+
)
182+
# Patch get_version_and_commit_id_from_files
183+
monkeypatch.setattr(
184+
fema, "get_version_and_commit_id_from_files", lambda root: ("1.2.3", "abcdef12")
185+
)
186+
187+
# Act
188+
fema.main()
189+
190+
captured = capsys.readouterr()
191+
assert "1.2.3-abcdef12" in captured.out
192+
193+
194+
def test_main_arch_raises_missing_verison(monkeypatch, capsys):
195+
# Arrange
196+
argv = ["prog", "--arch", "amd64", "--features", "f1", "arch"]
197+
monkeypatch.setattr(sys, "argv", argv)
198+
monkeypatch.setattr(fema, "Parser", lambda *a, **kw: None)
199+
200+
# Act / Assert
201+
with pytest.raises(RuntimeError):
202+
fema.main()
203+
204+
205+
def test_main_with_cname_print_cname(monkeypatch, capsys):
206+
# Arrange
207+
class FakeCName:
208+
def __init__(self, cname, arch=None, version=None):
209+
self.arch = arch
210+
self.flavor = "flav"
211+
self.commit_id = "abc123"
212+
self.version = version
213+
214+
monkeypatch.setattr(fema, "CName", FakeCName)
215+
216+
class FakeGraph:
217+
def in_degree(self):
218+
# Simulate a graph where one feature has no dependencies
219+
return [("f1", 0)]
220+
221+
class FakeParser:
222+
def __call__(self, *a, **k):
223+
return types.SimpleNamespace(filter=lambda *a, **k: FakeGraph())
224+
225+
@staticmethod
226+
def get_cname_as_feature_set(f):
227+
return {"f1"}
228+
229+
@staticmethod
230+
def sort_graph_nodes(graph):
231+
return ["f1"]
232+
233+
@staticmethod
234+
def sort_subset(subset, length):
235+
return []
236+
237+
monkeypatch.setattr(fema, "Parser", FakeParser())
238+
239+
monkeypatch.setattr(
240+
sys,
241+
"argv",
242+
["prog", "--cname", "flav", "--arch", "amd64", "--version", "1.0", "cname"],
243+
)
244+
245+
# Act
246+
fema.main()
247+
248+
# Assert
249+
captured = capsys.readouterr()
250+
assert "flav" in captured.out
251+
252+
253+
def test_main_requires_feature_or_cname(monkeypatch):
254+
# Arrange
255+
monkeypatch.setattr(sys, "argv", ["prog", "arch"])
256+
monkeypatch.setattr(fema, "Parser", lambda *a, **kw: None)
257+
258+
# Act / Assert
259+
with pytest.raises(AssertionError):
260+
fema.main()
261+
262+
263+
def test_main_raises_no_arch_no_default(monkeypatch):
264+
# Arrange
265+
# args.type == 'cname, arch is None and no default_arch set
266+
argv = ["prog", "--features", "f1", "cname"]
267+
monkeypatch.setattr(sys, "argv", argv)
268+
monkeypatch.setattr(
269+
fema,
270+
"Parser",
271+
lambda *a, **kw: types.SimpleNamesapce(filter=lambda *a, **k: None),
272+
)
273+
monkeypatch.setattr(fema, "CName", lambda *a, **kw: None)
274+
275+
# Act / Assert
276+
with pytest.raises(RuntimeError, match="Architecture could not be determined"):
277+
fema.main()

0 commit comments

Comments
 (0)