Skip to content

Commit 63357d7

Browse files
authored
Rust: Add test for helper functions (#118)
* Rust: Add test for helper functions Signed-off-by: Arthit Suriyawongkul <arthit@gmail.com> * Add test_prop_ctx_name Signed-off-by: Arthit Suriyawongkul <arthit@gmail.com> --------- Signed-off-by: Arthit Suriyawongkul <arthit@gmail.com>
1 parent ed3c9e3 commit 63357d7

2 files changed

Lines changed: 83 additions & 6 deletions

File tree

src/shacl2code/lang/rust.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#
2-
# Copyright (c) 2024 Joshua Watt
3-
#
1+
# SPDX-FileContributor: Stefano Tondo
2+
# SPDX-FileCopyrightText: 2026 Joshua Watt
3+
# SPDX-FileType: SOURCE
44
# SPDX-License-Identifier: MIT
55
"""Rust language binding renderer"""
66

tests/test_rust.py

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
#
2-
# Copyright (c) 2024 Joshua Watt
3-
#
1+
# SPDX-FileContributor: Stefano Tondo
2+
# SPDX-FileContributor: Joshua Watt
3+
# SPDX-FileContributor: Arthit Suriyawongkul
4+
# SPDX-FileCopyrightText: 2026 Joshua Watt
5+
# SPDX-FileType: SOURCE
46
# SPDX-License-Identifier: MIT
57

68
import json
@@ -12,6 +14,13 @@
1214
import pytest
1315

1416
from testfixtures import jsonvalidation, timetests
17+
from shacl2code.lang.rust import (
18+
is_effectively_extensible,
19+
prop_ctx_name,
20+
prop_defining_class,
21+
type_name,
22+
varname,
23+
)
1524

1625
THIS_FILE = Path(__file__)
1726
THIS_DIR = THIS_FILE.parent
@@ -709,3 +718,71 @@ def test_extensible_context(compile_test, roundtrip):
709718
"Missing extension property");
710719
""",
711720
)
721+
722+
723+
# --- Unit tests for shacl2code.lang.rust helper functions ---
724+
725+
726+
class _Prop:
727+
def __init__(self, path, varname=None):
728+
self.path = path
729+
self.varname = varname if varname is not None else path
730+
731+
732+
class _Class:
733+
def __init__(self, cid, prop_paths=(), parent_ids=(), is_extensible=False):
734+
self.clsname = [cid]
735+
self.properties = [_Prop(p) for p in prop_paths]
736+
self.parent_ids = list(parent_ids)
737+
self.is_extensible = is_extensible
738+
739+
740+
class _Classes:
741+
def __init__(self, *classes):
742+
self._map = {c.clsname[0]: c for c in classes}
743+
744+
def get(self, cid):
745+
return self._map[cid]
746+
747+
748+
def test_varname_empty_becomes_field():
749+
assert varname("") == "field"
750+
751+
752+
def test_varname_rust_keyword_gets_raw_prefix():
753+
assert varname("type") == "r#type"
754+
assert varname("self") == "r#self"
755+
756+
757+
def test_type_name_empty_becomes_type():
758+
assert type_name("") == "Type"
759+
assert type_name("_") == "Type"
760+
761+
762+
def test_prop_defining_class_returns_none_when_not_found():
763+
cls_a = _Class("A", prop_paths=["prop1"])
764+
cls_b = _Class("B", parent_ids=["A"])
765+
classes = _Classes(cls_a, cls_b)
766+
# prop2 is not defined in A or B
767+
result = prop_defining_class(cls_b, _Prop("prop2"), classes)
768+
assert result is None
769+
770+
771+
def test_is_effectively_extensible_false_when_no_ancestor_extensible():
772+
cls_a = _Class("A", is_extensible=False)
773+
cls_b = _Class("B", parent_ids=["A"], is_extensible=False)
774+
classes = _Classes(cls_a, cls_b)
775+
assert is_effectively_extensible(cls_b, classes) is False
776+
777+
778+
def test_is_effectively_extensible_true_via_ancestor():
779+
cls_a = _Class("A", is_extensible=True)
780+
cls_b = _Class("B", parent_ids=["A"], is_extensible=False)
781+
classes = _Classes(cls_a, cls_b)
782+
assert is_effectively_extensible(cls_b, classes) is True
783+
784+
785+
def test_prop_ctx_name():
786+
cls_a = _Class("A")
787+
prop = _Prop("prop1", varname="prop1")
788+
assert prop_ctx_name(cls_a, prop) == "a_prop1_ctx"

0 commit comments

Comments
 (0)