Coverage for tests/nodes/test_struct.py: 100%

62 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-09-04 15:55 +0100

1"""Tests for the `certus.nodes.struct` module.""" 

2 

3import re 

4import string 

5 

6import hypothesis as hyp 

7import hypothesis.strategies as st 

8 

9from certus.nodes import Token, struct 

10 

11from . import common 

12 

13ST_CORE_NODES = common.st_tokens() | common.ST_COMPOSITE_NODES 

14ST_ARRAY_CORE_ELEMENT_LISTS = st.lists(ST_CORE_NODES) 

15ST_OBJECT_CORE_FIELD_DICTS = st.dictionaries(st.text(string.ascii_lowercase + "_"), ST_CORE_NODES) 

16 

17 

18def get_num_composites(node): 

19 """Get the number of explicit composite nodes in a structure.""" 

20 if isinstance(node, Token): 

21 return 0 

22 

23 child_num = sum(get_num_composites(child) for child in node.children) 

24 if isinstance(node, (struct.Array, struct.Object)): 

25 return child_num 

26 

27 return child_num + 1 

28 

29 

30@hyp.given(ST_ARRAY_CORE_ELEMENT_LISTS) 

31def test_array_init_sets_children(elements): 

32 """Check an array sets its children to be its elements.""" 

33 assert struct.Array(elements=elements).children == elements 

34 

35 

36@hyp.given(ST_ARRAY_CORE_ELEMENT_LISTS.filter(len), st.data()) 

37def test_array_get_item(elements, data): 

38 """Check you can get an element from an array with its index.""" 

39 idx = data.draw(st.integers(0, len(elements) - 1)) 

40 array = struct.Array(elements=elements) 

41 

42 assert array[idx] == elements[idx] 

43 

44 

45@hyp.given(ST_ARRAY_CORE_ELEMENT_LISTS) 

46def test_array_iterate(elements): 

47 """Check you can iterate over the elements of an array naturally.""" 

48 array = struct.Array(elements=elements) 

49 

50 for i, element in enumerate(array): 

51 assert element == elements[i] 

52 

53 

54@hyp.given(ST_ARRAY_CORE_ELEMENT_LISTS) 

55def test_array_length(elements): 

56 """Check the length of an array is the length of its elements.""" 

57 assert len(struct.Array(elements=elements)) == len(elements) 

58 

59 

60@hyp.given(ST_ARRAY_CORE_ELEMENT_LISTS) 

61def test_array_repr(elements): 

62 """Check the representation of an array is as expected.""" 

63 array = struct.Array(elements=elements) 

64 repr_ = repr(array) 

65 

66 assert isinstance(repr_, str) 

67 assert re.match(r"Array\(elements=\[.*\]\)", repr_) 

68 assert all(repr(element) in repr_ for element in elements) 

69 assert len(re.findall(r"children=", repr_)) == get_num_composites(array) 

70 

71 

72@hyp.given(ST_OBJECT_CORE_FIELD_DICTS) 

73def test_object_sets_children(fields): 

74 """Check an object sets its children to be its field-values.""" 

75 assert struct.Object(fields=fields).children == list(fields.values()) 

76 

77 

78@hyp.given(ST_OBJECT_CORE_FIELD_DICTS.filter(len), st.data()) 

79def test_object_get_item(fields, data): 

80 """Check you can get a value from an object with its key.""" 

81 key = data.draw(st.sampled_from(list(fields.keys()))) 

82 object_ = struct.Object(fields=fields) 

83 

84 assert object_[key] == fields[key] 

85 

86 

87@hyp.given(ST_OBJECT_CORE_FIELD_DICTS) 

88def test_object_repr(fields): 

89 """Check the representation of an object is as expected.""" 

90 object_ = struct.Object(fields=fields) 

91 repr_ = repr(object_) 

92 

93 assert isinstance(repr_, str) 

94 assert re.match(r"Object\(fields={.*}\)", repr_) 

95 assert all([f"'{key}': {val!r}" in repr_ for key, val in fields.items()]) 

96 assert len(re.findall(r"children=", repr_)) == get_num_composites(object_) 

97 

98 

99@hyp.given(ST_OBJECT_CORE_FIELD_DICTS.filter(len)) 

100def test_object_dict_views(fields): 

101 """Check you can use dictionary views on object nodes.""" 

102 object_ = struct.Object(fields=fields) 

103 

104 assert object_.keys() == fields.keys() 

105 assert object_.items() == fields.items() 

106 assert list(object_.values()) == list(fields.values()) # dict_values don't support equality