Coverage for tests/tests/test_ramses_schema.py: 0%

1#!/usr/bin/env python3

2"""RAMSES RF - Test the RAMSES II schema."""

3

4 from ramses_rf import RQ

5 from ramses_rf.device.heat import HEAT_CLASS_BY_SLUG

6 from ramses_rf.device.hvac import HVAC_CLASS_BY_SLUG

7 from ramses_tx.const import Code, DevType

8 from ramses_tx.ramses import (

9 _DEV_KLASSES_HEAT,

10 _DEV_KLASSES_HVAC,

11 _HVAC_VC_PAIR_BY_CLASS,

12 CODE_IDX_ARE_COMPLEX,

13 CODE_IDX_ARE_NONE,

14 CODE_IDX_ARE_SIMPLE,

15 CODES_SCHEMA,

16 HVAC_KLASS_BY_VC_PAIR,

17 RQ_NO_PAYLOAD,

18)

19

20

21 def test_code_counts() -> None:

22 """All known command codes should be in the schema & vice versa."""

23

24 # assert len(Code) == len(CODES_SCHEMA)

25 assert not [c for c in CODES_SCHEMA if c not in Code]

26 assert not [c for c in Code if c not in CODES_SCHEMA]

27

28

29 def test_verb_code_pairs() -> None:

30 """Verb/code pairs are used to detect HVAC device classes: they should be unique."""

31

32 assert len(HVAC_KLASS_BY_VC_PAIR) == (

33 sum(len(v) for v in _HVAC_VC_PAIR_BY_CLASS.values())

34 ), "Coding error: There is a duplicate verb/code pair"

35

36

37 def test_device_heat_slugs() -> None:

38 """Every Heat device slug should have an entry in it domain's _DEV_KLASSES_*."""

39

40 assert not [s for s in _DEV_KLASSES_HEAT if s not in HEAT_CLASS_BY_SLUG]

41 assert not [

42 s for s in HEAT_CLASS_BY_SLUG if s not in _DEV_KLASSES_HEAT and s != DevType.HEA

43 ]

44

45

46 def test_device_hvac_slugs() -> None:

47 """Every HVAC device slug should have an entry in it domain's _DEV_KLASSES_*."""

48

49 assert not [s for s in _DEV_KLASSES_HVAC if s not in HVAC_CLASS_BY_SLUG]

50 assert not [

51 s for s in HVAC_CLASS_BY_SLUG if s not in _DEV_KLASSES_HVAC and s != DevType.HVC

52 ]

53

54

55 def assert_codes_idx_mutex(mutex_list: set, other_list: set) -> None:

56 """Assert the two lists are mutually exclusive."""

57

58 codes = sorted(c for c in mutex_list if c in other_list)

59 assert not codes

60

61

62 def test_codes_idx_mutex() -> None:

63 """Every code should be in one of the three CODE_IDX_* constants."""

64

65 codes_idx_all = CODE_IDX_ARE_COMPLEX | CODE_IDX_ARE_NONE | CODE_IDX_ARE_SIMPLE

66 assert not [c for c in CODES_SCHEMA if c not in codes_idx_all]

67

68

69 def test_codes_idx_complex_mutex() -> None:

70 """The three CODE_IDX_* constants should be mutually exclusive."""

71

72 assert_codes_idx_mutex(

73 CODE_IDX_ARE_COMPLEX, CODE_IDX_ARE_NONE | CODE_IDX_ARE_SIMPLE

74 )

75

76

77 def test_codes_idx_none_mutex() -> None:

78 """The three CODE_IDX_* constants should be mutually exclusive."""

79

80 assert_codes_idx_mutex(

81 CODE_IDX_ARE_NONE, CODE_IDX_ARE_SIMPLE | CODE_IDX_ARE_COMPLEX

82 )

83

84

85 def test_codes_idx_simple_mutex() -> None:

86 """The three CODE_IDX_* constants should be mutually exclusive."""

87

88 assert_codes_idx_mutex(

89 CODE_IDX_ARE_SIMPLE, CODE_IDX_ARE_NONE | CODE_IDX_ARE_COMPLEX

90 )

91

92

93 def test_codes_mutex() -> None:

94 assert_codes_idx_mutex(RQ_IDX_ONLY, CODE_IDX_ARE_NONE)

95

96

97 RQ_IDX_NONE = [k for k, v in CODES_SCHEMA.items() if v.get(RQ, "")[:3] == "^00"]

98 RQ_IDX_ONLY = [

99 k

100 for k, v in CODES_SCHEMA.items()

101 if k not in RQ_NO_PAYLOAD and (v.get(RQ) in (r"^0[0-9A-F]00$", r"^0[0-9A-F](00)?$"))

102]

103 RQ_IDX_UNKNOWN = [

104 k

105 for k, v in CODES_SCHEMA.items()

106 if k not in RQ_NO_PAYLOAD + RQ_IDX_ONLY and RQ in v

107]