Skip to content

Commit 0eeabb2

Browse files
committed
test: add some reasonable unit tests
Signed-off-by: Artifizer <artifizer@gmail.com>
1 parent e112b58 commit 0eeabb2

4 files changed

Lines changed: 1188 additions & 0 deletions

File tree

tests/test_entities.py

Lines changed: 335 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,335 @@
1+
"""Tests for JsonEntity and related classes."""
2+
3+
from gts.entities import (
4+
JsonFile,
5+
JsonEntity,
6+
ValidationError,
7+
ValidationResult,
8+
DEFAULT_GTS_CONFIG,
9+
)
10+
from gts.gts import GtsID
11+
12+
13+
class TestValidationError:
14+
"""Tests for ValidationError dataclass."""
15+
16+
def test_validation_error_creation(self):
17+
"""Test creating a validation error."""
18+
error = ValidationError(
19+
instancePath="/property",
20+
schemaPath="#/properties/property",
21+
keyword="type",
22+
message="must be string",
23+
params={"type": "string"},
24+
)
25+
assert error.instancePath == "/property"
26+
assert error.keyword == "type"
27+
28+
29+
class TestValidationResult:
30+
"""Tests for ValidationResult dataclass."""
31+
32+
def test_empty_validation_result(self):
33+
"""Test empty validation result."""
34+
result = ValidationResult()
35+
assert result.errors == []
36+
37+
def test_validation_result_with_errors(self):
38+
"""Test validation result with errors."""
39+
error = ValidationError(
40+
instancePath="/prop",
41+
schemaPath="#/prop",
42+
keyword="required",
43+
message="missing",
44+
params={},
45+
)
46+
result = ValidationResult(errors=[error])
47+
assert len(result.errors) == 1
48+
49+
50+
class TestJsonFile:
51+
"""Tests for JsonFile dataclass."""
52+
53+
def test_json_file_single_content(self):
54+
"""Test JsonFile with single content."""
55+
content = {"name": "test"}
56+
jf = JsonFile(path="/path/to/file.json", name="file.json", content=content)
57+
58+
assert jf.path == "/path/to/file.json"
59+
assert jf.name == "file.json"
60+
assert jf.sequencesCount == 1
61+
assert jf.sequenceContent[0] == content
62+
63+
def test_json_file_list_content(self):
64+
"""Test JsonFile with list content."""
65+
content = [{"id": 1}, {"id": 2}, {"id": 3}]
66+
jf = JsonFile(path="/path/to/file.json", name="file.json", content=content)
67+
68+
assert jf.sequencesCount == 3
69+
assert jf.sequenceContent[0] == {"id": 1}
70+
assert jf.sequenceContent[1] == {"id": 2}
71+
assert jf.sequenceContent[2] == {"id": 3}
72+
73+
74+
class TestGtsConfig:
75+
"""Tests for GtsConfig."""
76+
77+
def test_default_config(self):
78+
"""Test default config has expected fields."""
79+
assert "$id" in DEFAULT_GTS_CONFIG.entity_id_fields
80+
assert "gtsId" in DEFAULT_GTS_CONFIG.entity_id_fields
81+
assert "$schema" in DEFAULT_GTS_CONFIG.schema_id_fields
82+
assert "gtsType" in DEFAULT_GTS_CONFIG.schema_id_fields
83+
84+
85+
class TestJsonEntity:
86+
"""Tests for JsonEntity class."""
87+
88+
def test_entity_with_gts_id(self):
89+
"""Test entity creation with explicit GTS ID."""
90+
gts_id = GtsID("gts.vendor.package.namespace.type.v1~")
91+
entity = JsonEntity(
92+
content={"name": "test"},
93+
gts_id=gts_id,
94+
)
95+
96+
assert entity.gts_id == gts_id
97+
assert entity.content == {"name": "test"}
98+
99+
def test_entity_schema_detection_http(self):
100+
"""Test schema detection via http json-schema.org URL."""
101+
entity = JsonEntity(
102+
content={
103+
"$schema": "http://json-schema.org/draft-07/schema#",
104+
"type": "object",
105+
},
106+
)
107+
108+
assert entity.is_schema is True
109+
110+
def test_entity_schema_detection_https(self):
111+
"""Test schema detection via https json-schema.org URL."""
112+
entity = JsonEntity(
113+
content={
114+
"$schema": "https://json-schema.org/draft/2020-12/schema",
115+
"type": "object",
116+
},
117+
)
118+
119+
assert entity.is_schema is True
120+
121+
def test_entity_schema_detection_gts_uri(self):
122+
"""Test schema detection via gts:// URI."""
123+
entity = JsonEntity(
124+
content={
125+
"$schema": "gts://vendor.package.namespace.meta.v1~",
126+
"type": "object",
127+
},
128+
)
129+
130+
assert entity.is_schema is True
131+
132+
def test_entity_schema_detection_gts_prefix(self):
133+
"""Test schema detection via gts. prefix."""
134+
entity = JsonEntity(
135+
content={
136+
"$schema": "gts.vendor.package.namespace.meta.v1~",
137+
"type": "object",
138+
},
139+
)
140+
141+
assert entity.is_schema is True
142+
143+
def test_entity_not_schema(self):
144+
"""Test non-schema entity."""
145+
entity = JsonEntity(
146+
content={"name": "test", "value": 42},
147+
)
148+
149+
assert entity.is_schema is False
150+
151+
def test_entity_id_calculation(self):
152+
"""Test entity ID calculation from content fields."""
153+
entity = JsonEntity(
154+
content={
155+
"$id": "gts.vendor.package.namespace.type.v1~",
156+
"name": "test",
157+
},
158+
cfg=DEFAULT_GTS_CONFIG,
159+
)
160+
161+
assert entity.gts_id is not None
162+
assert entity.gts_id.id == "gts.vendor.package.namespace.type.v1~"
163+
assert entity.selected_entity_field == "$id"
164+
165+
def test_entity_schema_id_calculation(self):
166+
"""Test schema ID calculation from content fields."""
167+
entity = JsonEntity(
168+
content={
169+
"$schema": "gts.vendor.package.namespace.type.v1~",
170+
"name": "test",
171+
},
172+
cfg=DEFAULT_GTS_CONFIG,
173+
)
174+
175+
assert entity.schemaId == "gts.vendor.package.namespace.type.v1~"
176+
assert entity.selected_schema_id_field == "$schema"
177+
178+
def test_entity_label_from_file(self):
179+
"""Test entity label derived from file."""
180+
jf = JsonFile(path="/path/to/file.json", name="file.json", content={})
181+
entity = JsonEntity(
182+
file=jf,
183+
list_sequence=0,
184+
content={"name": "test"},
185+
)
186+
187+
assert entity.label == "file.json#0"
188+
189+
def test_entity_label_from_gts_id(self):
190+
"""Test entity label derived from GTS ID."""
191+
gts_id = GtsID("gts.vendor.package.namespace.type.v1~")
192+
entity = JsonEntity(
193+
content={},
194+
gts_id=gts_id,
195+
)
196+
197+
assert entity.label == "gts.vendor.package.namespace.type.v1~"
198+
199+
def test_entity_description_extraction(self):
200+
"""Test description extraction from content."""
201+
entity = JsonEntity(
202+
content={
203+
"description": "This is a test entity",
204+
"name": "test",
205+
},
206+
)
207+
208+
assert entity.description == "This is a test entity"
209+
210+
def test_entity_description_empty(self):
211+
"""Test empty description when not present."""
212+
entity = JsonEntity(
213+
content={"name": "test"},
214+
)
215+
216+
assert entity.description == ""
217+
218+
219+
class TestJsonEntityRefs:
220+
"""Tests for GTS reference extraction in JsonEntity."""
221+
222+
def test_extract_gts_refs_simple(self):
223+
"""Test extracting GTS refs from content."""
224+
entity = JsonEntity(
225+
content={
226+
"ref": "gts.vendor.package.namespace.other.v1~",
227+
},
228+
)
229+
230+
assert len(entity.gts_refs) == 1
231+
assert entity.gts_refs[0]["id"] == "gts.vendor.package.namespace.other.v1~"
232+
assert entity.gts_refs[0]["sourcePath"] == "ref"
233+
234+
def test_extract_gts_refs_nested(self):
235+
"""Test extracting nested GTS refs."""
236+
entity = JsonEntity(
237+
content={
238+
"data": {"nested": {"ref": "gts.vendor.package.namespace.deep.v1~"}}
239+
},
240+
)
241+
242+
assert len(entity.gts_refs) == 1
243+
assert entity.gts_refs[0]["sourcePath"] == "data.nested.ref"
244+
245+
def test_extract_gts_refs_in_array(self):
246+
"""Test extracting GTS refs from arrays."""
247+
entity = JsonEntity(
248+
content={
249+
"items": [
250+
"gts.vendor.package.namespace.item0.v1~",
251+
"gts.vendor.package.namespace.item1.v1~",
252+
]
253+
},
254+
)
255+
256+
assert len(entity.gts_refs) == 2
257+
paths = [r["sourcePath"] for r in entity.gts_refs]
258+
assert "items[0]" in paths
259+
assert "items[1]" in paths
260+
261+
def test_extract_schema_refs(self):
262+
"""Test extracting $ref strings from schema."""
263+
entity = JsonEntity(
264+
content={
265+
"$schema": "http://json-schema.org/draft-07/schema#",
266+
"type": "object",
267+
"properties": {
268+
"user": {"$ref": "gts.vendor.package.namespace.user.v1~"}
269+
},
270+
},
271+
)
272+
273+
assert entity.is_schema is True
274+
assert len(entity.schemaRefs) == 1
275+
assert entity.schemaRefs[0]["id"] == "gts.vendor.package.namespace.user.v1~"
276+
277+
def test_deduplicate_refs(self):
278+
"""Test that duplicate refs are deduplicated."""
279+
entity = JsonEntity(
280+
content={
281+
"ref1": "gts.vendor.package.namespace.same.v1~",
282+
"ref2": "gts.vendor.package.namespace.same.v1~",
283+
},
284+
)
285+
286+
# Both should be included as they have different paths
287+
assert len(entity.gts_refs) == 2
288+
289+
290+
class TestJsonEntityResolvePath:
291+
"""Tests for resolve_path method."""
292+
293+
def test_resolve_path_simple(self):
294+
"""Test simple path resolution."""
295+
gts_id = GtsID("gts.vendor.package.namespace.type.v1~")
296+
entity = JsonEntity(
297+
content={"name": "test", "value": 42},
298+
gts_id=gts_id,
299+
)
300+
301+
result = entity.resolve_path("name")
302+
assert result.resolved is True
303+
assert result.value == "test"
304+
305+
def test_resolve_path_nested(self):
306+
"""Test nested path resolution."""
307+
gts_id = GtsID("gts.vendor.package.namespace.type.v1~")
308+
entity = JsonEntity(
309+
content={"data": {"inner": "deep"}},
310+
gts_id=gts_id,
311+
)
312+
313+
result = entity.resolve_path("data.inner")
314+
assert result.resolved is True
315+
assert result.value == "deep"
316+
317+
318+
class TestJsonEntityGetGraph:
319+
"""Tests for get_graph method."""
320+
321+
def test_get_graph_basic(self):
322+
"""Test basic graph generation."""
323+
gts_id = GtsID("gts.vendor.package.namespace.type.v1~")
324+
entity = JsonEntity(
325+
content={
326+
"ref": "gts.vendor.package.namespace.other.v1~",
327+
},
328+
gts_id=gts_id,
329+
schemaId="gts.vendor.package.namespace.type.v1~",
330+
)
331+
332+
graph = entity.get_graph()
333+
assert graph["id"] == "gts.vendor.package.namespace.type.v1~"
334+
assert graph["schema_id"] == "gts.vendor.package.namespace.type.v1~"
335+
assert "refs" in graph

0 commit comments

Comments
 (0)