forked from project-chip/connectedhomeip
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_idl_generator.py
executable file
·138 lines (105 loc) · 4.62 KB
/
test_idl_generator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/env python3
# Copyright (c) 2022 Project CHIP Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
import unittest
from difflib import unified_diff
from typing import List, Optional
try:
from matter_idl.matter_idl_parser import CreateParser
except ImportError:
sys.path.append(os.path.abspath(
os.path.join(os.path.dirname(__file__), '..')))
from matter_idl.matter_idl_parser import CreateParser
from matter_idl.generators import GeneratorStorage
from matter_idl.generators.idl import IdlGenerator
from matter_idl.matter_idl_types import Idl
class TestCaseStorage(GeneratorStorage):
def __init__(self):
super().__init__()
self.content: Optional[str] = None
def get_existing_data(self, relative_path: str):
# Force re-generation each time
return None
def write_new_data(self, relative_path: str, content: str):
if self.content:
raise Exception(
"Unexpected extra data: single file generation expected")
self.content = content
def ReadMatterIdl(repo_path: str) -> str:
path = os.path.join(os.path.dirname(__file__), "../../..", repo_path)
with open(path, "rt") as stream:
return stream.read()
def ParseMatterIdl(repo_path: str, skip_meta: bool) -> Idl:
return CreateParser(skip_meta=skip_meta).parse(ReadMatterIdl(repo_path))
def RenderAsIdlTxt(idl: Idl) -> str:
storage = TestCaseStorage()
IdlGenerator(storage=storage, idl=idl).render(dry_run=False)
return storage.content or ""
def SkipLeadingComments(txt: str, also_strip: List[str] = list()) -> str:
"""Skips leading lines starting with // in a file. """
lines = txt.split("\n")
idx = 0
while lines[idx].startswith("//") or not lines[idx]:
idx = idx + 1
result = "\n".join(lines[idx:])
for s in also_strip:
result = result.replace(s, "")
return result
class TestIdlRendering(unittest.TestCase):
def assertTextEqual(self, a: str, b: str):
if a == b:
# seems the same. This will just pass
self.assertEqual(a, b)
return
delta = unified_diff(a.splitlines(keepends=True),
b.splitlines(keepends=True),
fromfile='actual.matter',
tofile='expected.matter',
)
self.assertEqual(a, b, '\n' + ''.join(delta))
def test_client_clusters(self):
# IDL renderer was updated to have IDENTICAL output for client side
# cluster rendering, so this diff will be verbatim
#
# Comparison made text-mode so that meta-data is read and doc-comments are
# available
path = "src/controller/data_model/controller-clusters.matter"
# Files MUST be identical except the header comments which are different
original = SkipLeadingComments(ReadMatterIdl(path), also_strip=[
" // NOTE: Default/not specifically set"])
generated = SkipLeadingComments(RenderAsIdlTxt(
ParseMatterIdl(path, skip_meta=False)))
self.assertTextEqual(original, generated)
def test_app_rendering(self):
# When endpoints are involved, default value formatting is lost
# (e.g. "0x0000" becomes "0") and ordering of emitted events is not preserved
# because the events are a
# as such, this test validates that parsing + generating + re-parsing results
# in the same data being parsed
test_paths = [
"examples/lock-app/lock-common/lock-app.matter",
"examples/lighting-app/lighting-common/lighting-app.matter",
"examples/all-clusters-app/all-clusters-common/all-clusters-app.matter",
"examples/thermostat/thermostat-common/thermostat.matter",
]
for path in test_paths:
idl = ParseMatterIdl(path, skip_meta=True)
txt = RenderAsIdlTxt(idl)
idl2 = CreateParser(skip_meta=True).parse(txt)
# checks that data types and content is the same
self.assertEqual(idl, idl2)
if __name__ == '__main__':
unittest.main()