@redpanda-data/docs-extensions-and-macros 4.2.5 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.adoc +184 -21
- package/bin/doc-tools.js +328 -0
- package/cli-utils/add-caret-external-links.py +68 -0
- package/cli-utils/beta-from-antora.js +27 -0
- package/cli-utils/generate-cluster-docs.sh +83 -0
- package/cli-utils/install-test-dependencies.sh +158 -0
- package/cli-utils/python-venv.sh +20 -0
- package/cli-utils/start-cluster.sh +53 -0
- package/docker-compose/bootstrap.yml +67 -0
- package/docker-compose/docker-compose.yml +414 -0
- package/docker-compose/generate-profiles.yaml +77 -0
- package/docker-compose/rpk-profile.yaml +24 -0
- package/docker-compose/transactions-schema.json +37 -0
- package/docker-compose/transactions.md +46 -0
- package/docker-compose/transform/README.adoc +73 -0
- package/docker-compose/transform/go.mod +5 -0
- package/docker-compose/transform/go.sum +2 -0
- package/docker-compose/transform/regex.wasm +0 -0
- package/docker-compose/transform/transform.go +122 -0
- package/docker-compose/transform/transform.yaml +33 -0
- package/extension-utils/compute-out.js +38 -0
- package/extension-utils/create-asciidoc-file.js +15 -0
- package/macros/data-template.js +591 -0
- package/package.json +21 -4
- package/tools/docusaurus-to-antora-conversion-scripts/convert-docs.sh +114 -0
- package/tools/docusaurus-to-antora-conversion-scripts/get-file-changes.sh +9 -0
- package/tools/docusaurus-to-antora-conversion-scripts/post-process-asciidoc.js +63 -0
- package/tools/docusaurus-to-antora-conversion-scripts/pre-process-markdown.js +108 -0
- package/tools/fetch-from-github.js +63 -0
- package/tools/gen-rpk-ascii.py +477 -0
- package/tools/get-console-version.js +53 -0
- package/tools/get-redpanda-version.js +53 -0
- package/tools/metrics/metrics.py +199 -0
- package/tools/metrics/requirements.txt +1 -0
- package/tools/property-extractor/Makefile +99 -0
- package/tools/property-extractor/README.adoc +206 -0
- package/tools/property-extractor/definitions.json +245 -0
- package/tools/property-extractor/file_pair.py +7 -0
- package/tools/property-extractor/json-to-asciidoc/generate_docs.py +460 -0
- package/tools/property-extractor/parser.py +224 -0
- package/tools/property-extractor/property_bag.py +4 -0
- package/tools/property-extractor/property_extractor.py +243 -0
- package/tools/property-extractor/requirements.txt +2 -0
- package/tools/property-extractor/tests/transformers_test.py +376 -0
- package/tools/property-extractor/transformers.py +397 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import logging
|
|
3
|
+
import sys
|
|
4
|
+
import os
|
|
5
|
+
import json
|
|
6
|
+
import re
|
|
7
|
+
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from file_pair import FilePair
|
|
10
|
+
from tree_sitter import Language, Parser
|
|
11
|
+
|
|
12
|
+
from parser import build_treesitter_cpp_library, extract_properties_from_file_pair
|
|
13
|
+
from property_bag import PropertyBag
|
|
14
|
+
from transformers import *
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger("viewer")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def validate_paths(options):
|
|
20
|
+
path = options.path
|
|
21
|
+
|
|
22
|
+
if not os.path.exists(path):
|
|
23
|
+
logger.error(f'Path does not exist: "{path}".')
|
|
24
|
+
sys.exit(1)
|
|
25
|
+
|
|
26
|
+
if options.definitions and not os.path.exists(options.definitions):
|
|
27
|
+
logger.error(
|
|
28
|
+
f'File with the type definitions not found: "{options.definitions}".'
|
|
29
|
+
)
|
|
30
|
+
sys.exit(1)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def get_file_pairs(options):
|
|
34
|
+
path = Path(options.path)
|
|
35
|
+
|
|
36
|
+
file_iter = path.rglob("*.h") if options.recursive else path.rglob("*.h")
|
|
37
|
+
|
|
38
|
+
file_pairs = []
|
|
39
|
+
|
|
40
|
+
for i in file_iter:
|
|
41
|
+
if os.path.exists(i.with_suffix(".cc")):
|
|
42
|
+
file_pairs.append(FilePair(i.resolve(), i.with_suffix(".cc").resolve()))
|
|
43
|
+
|
|
44
|
+
return file_pairs
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def get_treesitter_cpp_parser_and_language(treesitter_dir, destination_path):
|
|
48
|
+
if not os.path.exists(destination_path):
|
|
49
|
+
build_treesitter_cpp_library(treesitter_dir, destination_path)
|
|
50
|
+
|
|
51
|
+
cpp = Language(destination_path, "cpp")
|
|
52
|
+
|
|
53
|
+
parser = Parser()
|
|
54
|
+
parser.set_language(cpp)
|
|
55
|
+
|
|
56
|
+
return parser, cpp
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def get_files_with_properties(file_pairs, treesitter_parser, cpp_language):
|
|
60
|
+
files_with_properties = []
|
|
61
|
+
|
|
62
|
+
for fp in file_pairs:
|
|
63
|
+
properties = extract_properties_from_file_pair(
|
|
64
|
+
treesitter_parser, cpp_language, fp
|
|
65
|
+
)
|
|
66
|
+
implementation_value = str(fp.implementation)
|
|
67
|
+
|
|
68
|
+
# List of file paths to check
|
|
69
|
+
file_paths = [
|
|
70
|
+
"src/v/config/configuration.cc",
|
|
71
|
+
"src/v/config/node_config.cc",
|
|
72
|
+
"src/v/kafka/client/configuration.cc",
|
|
73
|
+
"src/v/pandaproxy/rest/configuration.cc",
|
|
74
|
+
"src/v/pandaproxy/schema_registry/configuration.cc"
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
# Check if any of the paths are in fp.implementation
|
|
78
|
+
if any(path in implementation_value for path in file_paths):
|
|
79
|
+
if len(properties) > 0:
|
|
80
|
+
files_with_properties.append((fp, properties))
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
return files_with_properties
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def transform_files_with_properties(files_with_properties):
|
|
88
|
+
type_transformer = TypeTransformer()
|
|
89
|
+
transformers = [
|
|
90
|
+
EnterpriseTransformer(), ## this must be the first, as it modifies current data
|
|
91
|
+
TypeTransformer(),
|
|
92
|
+
MetaParamTransformer(),
|
|
93
|
+
BasicInfoTransformer(),
|
|
94
|
+
IsNullableTransformer(),
|
|
95
|
+
IsArrayTransformer(type_transformer),
|
|
96
|
+
NeedsRestartTransformer(),
|
|
97
|
+
GetsRestoredTransformer(),
|
|
98
|
+
VisibilityTransformer(),
|
|
99
|
+
DeprecatedTransformer(),
|
|
100
|
+
IsSecretTransformer(),
|
|
101
|
+
NumericBoundsTransformer(type_transformer),
|
|
102
|
+
DurationBoundsTransformer(type_transformer),
|
|
103
|
+
SimpleDefaultValuesTransformer(),
|
|
104
|
+
FriendlyDefaultTransformer(),
|
|
105
|
+
ExperimentalTransformer(),
|
|
106
|
+
AliasTransformer(),
|
|
107
|
+
]
|
|
108
|
+
|
|
109
|
+
all_properties = PropertyBag()
|
|
110
|
+
|
|
111
|
+
for fp, properties in files_with_properties:
|
|
112
|
+
for name in properties:
|
|
113
|
+
# ignore private properties
|
|
114
|
+
if re.match(r"^_", name):
|
|
115
|
+
continue
|
|
116
|
+
|
|
117
|
+
property_definition = PropertyBag()
|
|
118
|
+
|
|
119
|
+
for transformer in transformers:
|
|
120
|
+
if transformer.accepts(properties[name], fp):
|
|
121
|
+
transformer.parse(property_definition, properties[name], fp)
|
|
122
|
+
|
|
123
|
+
if len(property_definition) > 0:
|
|
124
|
+
all_properties[name] = property_definition
|
|
125
|
+
|
|
126
|
+
return all_properties
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
# The definitions.json file contains type definitions that the extractor uses to standardize and centralize type information. After extracting and transforming the properties from the source code, the function merge_properties_and_definitions looks up each property's type in the definitions. If a property's type (or the type of its items, in the case of arrays) matches one of the definitions, the transformer replaces that type with a JSON pointer ( such as #/definitions/<type>) to the corresponding entry in definitions.json. The final JSON output then includes both a properties section (with types now referencing the definitions) and a definitions section, so that consumers of the output can easily resolve the full type information.
|
|
130
|
+
def merge_properties_and_definitions(properties, definitions):
|
|
131
|
+
for name in properties:
|
|
132
|
+
property = properties[name]
|
|
133
|
+
# guard against missing "type"
|
|
134
|
+
prop_type = property.get("type")
|
|
135
|
+
if prop_type and prop_type in definitions:
|
|
136
|
+
properties[name]["type"] = "#/definitions/{prop_type}"
|
|
137
|
+
elif (
|
|
138
|
+
prop_type == "array"
|
|
139
|
+
and property.get("items", {}).get("type") in definitions
|
|
140
|
+
):
|
|
141
|
+
properties[name]["items"]["type"] = (
|
|
142
|
+
f"#/definitions/{property['items']['type']}"
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
return dict(properties=properties, definitions=definitions)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def main():
|
|
149
|
+
import argparse
|
|
150
|
+
|
|
151
|
+
def generate_options():
|
|
152
|
+
arg_parser = argparse.ArgumentParser(
|
|
153
|
+
description="Extract all properties from the Redpanda's source code and generate a JSON output with their definitions"
|
|
154
|
+
)
|
|
155
|
+
arg_parser.add_argument(
|
|
156
|
+
"--path",
|
|
157
|
+
type=str,
|
|
158
|
+
required=True,
|
|
159
|
+
help="Path to the Redpanda's source dir to extract the properties",
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
arg_parser.add_argument(
|
|
163
|
+
"--recursive", action="store_true", help="Scan the path recursively"
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
arg_parser.add_argument(
|
|
167
|
+
"--output",
|
|
168
|
+
type=str,
|
|
169
|
+
required=False,
|
|
170
|
+
help="File to store the JSON output. If no file is provided, the JSON will be printed to the standard output",
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
arg_parser.add_argument(
|
|
174
|
+
"--definitions",
|
|
175
|
+
type=str,
|
|
176
|
+
required=False,
|
|
177
|
+
default=os.path.dirname(os.path.realpath(__file__)) + "/definitions.json",
|
|
178
|
+
help='JSON file with the type definitions. This file will be merged in the output under the "definitions" field',
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
arg_parser.add_argument("-v", "--verbose", action="store_true")
|
|
182
|
+
|
|
183
|
+
return arg_parser
|
|
184
|
+
|
|
185
|
+
arg_parser = generate_options()
|
|
186
|
+
options, _ = arg_parser.parse_known_args()
|
|
187
|
+
|
|
188
|
+
if options.verbose:
|
|
189
|
+
logging.basicConfig(level="DEBUG")
|
|
190
|
+
else:
|
|
191
|
+
logging.basicConfig(level="INFO")
|
|
192
|
+
|
|
193
|
+
validate_paths(options)
|
|
194
|
+
|
|
195
|
+
file_pairs = get_file_pairs(options)
|
|
196
|
+
|
|
197
|
+
if not file_pairs:
|
|
198
|
+
logging.error("No h/cc file pairs were found")
|
|
199
|
+
sys.exit(-1)
|
|
200
|
+
|
|
201
|
+
definitions = None
|
|
202
|
+
|
|
203
|
+
if options.definitions:
|
|
204
|
+
try:
|
|
205
|
+
with open(options.definitions) as json_file:
|
|
206
|
+
definitions = json.load(json_file)
|
|
207
|
+
except json.JSONDecodeError as e:
|
|
208
|
+
logging.error(f"Failed to parse definitions file: {e}")
|
|
209
|
+
sys.exit(1)
|
|
210
|
+
|
|
211
|
+
treesitter_dir = os.path.join(os.getcwd(), "tree-sitter/tree-sitter-cpp")
|
|
212
|
+
destination_path = os.path.join(treesitter_dir, "tree-sitter-cpp.so")
|
|
213
|
+
|
|
214
|
+
if not os.path.exists(os.path.join(treesitter_dir, "src/parser.c")):
|
|
215
|
+
logging.error("Missing parser.c. Ensure Tree-sitter submodules are initialized.")
|
|
216
|
+
sys.exit(1)
|
|
217
|
+
|
|
218
|
+
treesitter_parser, cpp_language = get_treesitter_cpp_parser_and_language(
|
|
219
|
+
treesitter_dir, destination_path
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
files_with_properties = get_files_with_properties(
|
|
223
|
+
file_pairs, treesitter_parser, cpp_language
|
|
224
|
+
)
|
|
225
|
+
properties = transform_files_with_properties(files_with_properties)
|
|
226
|
+
properties_and_definitions = merge_properties_and_definitions(
|
|
227
|
+
properties, definitions
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
json_output = json.dumps(properties_and_definitions, indent=4, sort_keys=True)
|
|
231
|
+
|
|
232
|
+
if options.output:
|
|
233
|
+
try:
|
|
234
|
+
with open(options.output, "w+") as json_file:
|
|
235
|
+
json_file.write(json_output)
|
|
236
|
+
except IOError as e:
|
|
237
|
+
logging.error(f"Failed to write output file: {e}")
|
|
238
|
+
sys.exit(1)
|
|
239
|
+
else:
|
|
240
|
+
print(json_output)
|
|
241
|
+
|
|
242
|
+
if __name__ == "__main__":
|
|
243
|
+
main()
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from property_bag import PropertyBag
|
|
3
|
+
from file_pair import FilePair
|
|
4
|
+
from transformers import *
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def create_property_info(
|
|
8
|
+
name,
|
|
9
|
+
description,
|
|
10
|
+
declaration=None,
|
|
11
|
+
metadata=None,
|
|
12
|
+
default_value="{}",
|
|
13
|
+
default_value_type="initializer_list",
|
|
14
|
+
):
|
|
15
|
+
info = PropertyBag()
|
|
16
|
+
info["name_in_file"] = name
|
|
17
|
+
info["declaration"] = declaration
|
|
18
|
+
info["params"] = []
|
|
19
|
+
info["params"].append(PropertyBag(value=name, type="string_literal"))
|
|
20
|
+
info["params"].append(PropertyBag(value=description, type="string_literal"))
|
|
21
|
+
info["params"].append(PropertyBag(value=metadata, type="initializer_list"))
|
|
22
|
+
info["params"].append(PropertyBag(value=default_value, type="initializer_list"))
|
|
23
|
+
|
|
24
|
+
return info
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class BasicInfoTransformerTestCase(unittest.TestCase):
|
|
28
|
+
def setUp(self):
|
|
29
|
+
self.transformer = BasicInfoTransformer()
|
|
30
|
+
|
|
31
|
+
def test_accepts_everything(self):
|
|
32
|
+
self.assertTrue(self.transformer.accepts(None, None))
|
|
33
|
+
|
|
34
|
+
def test_adds_name_description_and_defined_in(self):
|
|
35
|
+
property = PropertyBag()
|
|
36
|
+
info = create_property_info("test_property", "test description")
|
|
37
|
+
self.transformer.parse(property, info, FilePair("testfile.h", "testfile.cc"))
|
|
38
|
+
|
|
39
|
+
self.assertEqual("test_property", property["name"])
|
|
40
|
+
self.assertEqual("test description", property["description"])
|
|
41
|
+
self.assertEqual("testfile.cc", property["defined_in"])
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class IsArrayTransformerTestCase(unittest.TestCase):
|
|
45
|
+
def setUp(self):
|
|
46
|
+
self.transformer = IsArrayTransformer(TypeTransformer())
|
|
47
|
+
|
|
48
|
+
def test_accepts_vector(self):
|
|
49
|
+
self.assertTrue(
|
|
50
|
+
self.transformer.accepts(
|
|
51
|
+
create_property_info(
|
|
52
|
+
"test_property", "test description", "std::vector<int>"
|
|
53
|
+
),
|
|
54
|
+
None,
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
def test_rejects_other_properties(self):
|
|
59
|
+
for t in [
|
|
60
|
+
"int",
|
|
61
|
+
"std::optional",
|
|
62
|
+
"config::endpoint_tls_config",
|
|
63
|
+
"deprecated_property",
|
|
64
|
+
]:
|
|
65
|
+
with self.subTest(t):
|
|
66
|
+
self.assertFalse(
|
|
67
|
+
self.transformer.accepts(
|
|
68
|
+
create_property_info("test_property", "test description", t),
|
|
69
|
+
None,
|
|
70
|
+
)
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
def test_adds_array_field(self):
|
|
74
|
+
property = PropertyBag()
|
|
75
|
+
info = create_property_info(
|
|
76
|
+
"test_property", "test description", "std::vector<int>"
|
|
77
|
+
)
|
|
78
|
+
self.transformer.parse(property, info, FilePair("testfile.h", "testfile.cc"))
|
|
79
|
+
|
|
80
|
+
self.assertEqual("array", property["type"])
|
|
81
|
+
self.assertEqual("integer", property["items"]["type"])
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class NeedsRestartTransformerTestCase(unittest.TestCase):
|
|
85
|
+
def setUp(self):
|
|
86
|
+
self.transformer = NeedsRestartTransformer()
|
|
87
|
+
|
|
88
|
+
def test_accepts_needs_restart_metadata(self):
|
|
89
|
+
self.assertTrue(
|
|
90
|
+
self.transformer.accepts(
|
|
91
|
+
create_property_info(
|
|
92
|
+
"test_property",
|
|
93
|
+
"test description",
|
|
94
|
+
"bool",
|
|
95
|
+
PropertyBag(needs_restart="needs_restart::no"),
|
|
96
|
+
),
|
|
97
|
+
None,
|
|
98
|
+
)
|
|
99
|
+
)
|
|
100
|
+
self.assertTrue(
|
|
101
|
+
self.transformer.accepts(
|
|
102
|
+
create_property_info(
|
|
103
|
+
"test_property",
|
|
104
|
+
"test description",
|
|
105
|
+
"bool",
|
|
106
|
+
PropertyBag(needs_restart="needs_restart::yes"),
|
|
107
|
+
),
|
|
108
|
+
None,
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
def test_rejects_without_needs_restart(self):
|
|
113
|
+
self.assertFalse(
|
|
114
|
+
self.transformer.accepts(
|
|
115
|
+
create_property_info(
|
|
116
|
+
"test_property", "test description", "bool", PropertyBag()
|
|
117
|
+
),
|
|
118
|
+
None,
|
|
119
|
+
)
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
def test_adds_needs_restart_true(self):
|
|
123
|
+
property = PropertyBag()
|
|
124
|
+
info = create_property_info(
|
|
125
|
+
"test_property",
|
|
126
|
+
"test description",
|
|
127
|
+
"std::vector<int>",
|
|
128
|
+
PropertyBag(needs_restart="needs_restart::yes"),
|
|
129
|
+
)
|
|
130
|
+
self.transformer.parse(property, info, FilePair("testfile.h", "testfile.cc"))
|
|
131
|
+
|
|
132
|
+
self.assertTrue(property["needs_restart"])
|
|
133
|
+
|
|
134
|
+
def test_adds_needs_restart_false(self):
|
|
135
|
+
property = PropertyBag()
|
|
136
|
+
info = create_property_info(
|
|
137
|
+
"test_property",
|
|
138
|
+
"test description",
|
|
139
|
+
"std::vector<int>",
|
|
140
|
+
PropertyBag(needs_restart="needs_restart::no"),
|
|
141
|
+
)
|
|
142
|
+
self.transformer.parse(property, info, FilePair("testfile.h", "testfile.cc"))
|
|
143
|
+
|
|
144
|
+
self.assertFalse(property["needs_restart"])
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class VisibilityTransformerTestCase(unittest.TestCase):
|
|
148
|
+
def setUp(self):
|
|
149
|
+
self.transformer = VisibilityTransformer()
|
|
150
|
+
|
|
151
|
+
def test_accepts_visibility_metadata(self):
|
|
152
|
+
self.assertTrue(
|
|
153
|
+
self.transformer.accepts(
|
|
154
|
+
create_property_info(
|
|
155
|
+
"test_property",
|
|
156
|
+
"test description",
|
|
157
|
+
"bool",
|
|
158
|
+
PropertyBag(visibility="visibility::user"),
|
|
159
|
+
),
|
|
160
|
+
None,
|
|
161
|
+
)
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
def test_rejects_without_visibility(self):
|
|
165
|
+
self.assertFalse(
|
|
166
|
+
self.transformer.accepts(
|
|
167
|
+
create_property_info(
|
|
168
|
+
"test_property", "test description", "bool", PropertyBag()
|
|
169
|
+
),
|
|
170
|
+
None,
|
|
171
|
+
)
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
def test_adds_visibility(self):
|
|
175
|
+
for p in [
|
|
176
|
+
("user", "visibility::user"),
|
|
177
|
+
("tunable", "visibility::tunable"),
|
|
178
|
+
("deprecated", "visibility::deprecated"),
|
|
179
|
+
]:
|
|
180
|
+
with self.subTest(p[0]):
|
|
181
|
+
property = PropertyBag()
|
|
182
|
+
info = create_property_info(
|
|
183
|
+
"test_property",
|
|
184
|
+
"test description",
|
|
185
|
+
"std::vector<int>",
|
|
186
|
+
PropertyBag(visibility=p[1]),
|
|
187
|
+
)
|
|
188
|
+
self.transformer.parse(
|
|
189
|
+
property, info, FilePair("testfile.h", "testfile.cc")
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
self.assertEqual(p[0], property["visibility"])
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
class TypeTransformerTestCase(unittest.TestCase):
|
|
196
|
+
def setUp(self):
|
|
197
|
+
self.transformer = TypeTransformer()
|
|
198
|
+
|
|
199
|
+
def test_accepts_everything(self):
|
|
200
|
+
self.assertTrue(self.transformer.accepts(None, None))
|
|
201
|
+
|
|
202
|
+
def test_parse_simple_types(self):
|
|
203
|
+
types = [
|
|
204
|
+
("int", "integer"),
|
|
205
|
+
("int32_t", "integer"),
|
|
206
|
+
("int16_t", "integer"),
|
|
207
|
+
("int64_t", "integer"),
|
|
208
|
+
("double", "number"),
|
|
209
|
+
("bool", "boolean"),
|
|
210
|
+
("std::chrono::milliseconds", "integer"),
|
|
211
|
+
("std::chrono::seconds", "integer"),
|
|
212
|
+
("std::filesystem::path", "string"),
|
|
213
|
+
]
|
|
214
|
+
|
|
215
|
+
for t in types:
|
|
216
|
+
with self.subTest(t[0]):
|
|
217
|
+
property = PropertyBag()
|
|
218
|
+
info = create_property_info(
|
|
219
|
+
"test_property",
|
|
220
|
+
"test description",
|
|
221
|
+
"property<" + t[0] + ">" + " test_property;",
|
|
222
|
+
)
|
|
223
|
+
self.transformer.parse(
|
|
224
|
+
property, info, FilePair("testfile.h", "testfile.cc")
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
self.assertEqual(t[1], property["type"])
|
|
228
|
+
|
|
229
|
+
def test_parse_bounded_property(self):
|
|
230
|
+
property = PropertyBag()
|
|
231
|
+
info = create_property_info(
|
|
232
|
+
"test_property",
|
|
233
|
+
"test description",
|
|
234
|
+
"bounded_property<double, numeric_bounds> disk_reservation_percent;",
|
|
235
|
+
)
|
|
236
|
+
self.transformer.parse(property, info, FilePair("testfile.h", "testfile.cc"))
|
|
237
|
+
|
|
238
|
+
self.assertEqual("number", property["type"])
|
|
239
|
+
|
|
240
|
+
def test_parse_deprecated_property(self):
|
|
241
|
+
property = PropertyBag()
|
|
242
|
+
info = create_property_info(
|
|
243
|
+
"test_property", "test description", "deprecated_property test_property;"
|
|
244
|
+
)
|
|
245
|
+
self.transformer.parse(property, info, FilePair("testfile.h", "testfile.cc"))
|
|
246
|
+
|
|
247
|
+
self.assertEqual("deprecated_property", property["type"])
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
class DeprecatedTransformerTestCase(unittest.TestCase):
|
|
251
|
+
def setUp(self):
|
|
252
|
+
self.transformer = DeprecatedTransformer()
|
|
253
|
+
|
|
254
|
+
def test_accepts_deprecated_visibility(self):
|
|
255
|
+
self.assertTrue(
|
|
256
|
+
self.transformer.accepts(
|
|
257
|
+
create_property_info(
|
|
258
|
+
"test_property",
|
|
259
|
+
"test description",
|
|
260
|
+
"bool",
|
|
261
|
+
PropertyBag(visibility="visibility::deprecated"),
|
|
262
|
+
),
|
|
263
|
+
None,
|
|
264
|
+
)
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
def test_accepts_deprecated_property_type(self):
|
|
268
|
+
self.assertTrue(
|
|
269
|
+
self.transformer.accepts(
|
|
270
|
+
create_property_info(
|
|
271
|
+
"test_property",
|
|
272
|
+
"test description",
|
|
273
|
+
"deprecated_property",
|
|
274
|
+
PropertyBag(),
|
|
275
|
+
),
|
|
276
|
+
None,
|
|
277
|
+
)
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
def test_rejects_without_deprecated_visibility_type(self):
|
|
281
|
+
self.assertFalse(
|
|
282
|
+
self.transformer.accepts(
|
|
283
|
+
create_property_info(
|
|
284
|
+
"test_property", "test description", "bool", PropertyBag()
|
|
285
|
+
),
|
|
286
|
+
None,
|
|
287
|
+
)
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
def test_adds_deprecated_field_from_deprecated_visibility(self):
|
|
291
|
+
property = PropertyBag()
|
|
292
|
+
info = create_property_info(
|
|
293
|
+
"test_property",
|
|
294
|
+
"test description",
|
|
295
|
+
"std::vector<int>",
|
|
296
|
+
PropertyBag(visibility="visibility::deprecated"),
|
|
297
|
+
)
|
|
298
|
+
self.transformer.parse(property, info, FilePair("testfile.h", "testfile.cc"))
|
|
299
|
+
|
|
300
|
+
self.assertTrue(property["is_deprecated"])
|
|
301
|
+
self.assertFalse(property["type"])
|
|
302
|
+
|
|
303
|
+
def test_adds_deprecated_field_from_deprecated_property_type(self):
|
|
304
|
+
property = PropertyBag()
|
|
305
|
+
info = create_property_info(
|
|
306
|
+
"test_property", "test description", "deprecated_property", PropertyBag()
|
|
307
|
+
)
|
|
308
|
+
self.transformer.parse(property, info, FilePair("testfile.h", "testfile.cc"))
|
|
309
|
+
|
|
310
|
+
self.assertTrue(property["is_deprecated"])
|
|
311
|
+
self.assertFalse(property["type"])
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
class IsSecretTransformerTestCase(unittest.TestCase):
|
|
315
|
+
def setUp(self):
|
|
316
|
+
self.transformer = IsSecretTransformer()
|
|
317
|
+
|
|
318
|
+
def test_accepts_with_secret(self):
|
|
319
|
+
self.assertTrue(
|
|
320
|
+
self.transformer.accepts(
|
|
321
|
+
create_property_info(
|
|
322
|
+
"test_property",
|
|
323
|
+
"test description",
|
|
324
|
+
"bool",
|
|
325
|
+
PropertyBag(secret="is_secret::yes"),
|
|
326
|
+
),
|
|
327
|
+
None,
|
|
328
|
+
)
|
|
329
|
+
)
|
|
330
|
+
self.assertTrue(
|
|
331
|
+
self.transformer.accepts(
|
|
332
|
+
create_property_info(
|
|
333
|
+
"test_property",
|
|
334
|
+
"test description",
|
|
335
|
+
"bool",
|
|
336
|
+
PropertyBag(secret="is_secret::no"),
|
|
337
|
+
),
|
|
338
|
+
None,
|
|
339
|
+
)
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
def test_rejects_without_secret(self):
|
|
343
|
+
self.assertFalse(
|
|
344
|
+
self.transformer.accepts(
|
|
345
|
+
create_property_info(
|
|
346
|
+
"test_property", "test description", "bool", PropertyBag()
|
|
347
|
+
),
|
|
348
|
+
None,
|
|
349
|
+
)
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
def test_adds_is_secret_true(self):
|
|
353
|
+
property = PropertyBag()
|
|
354
|
+
info = create_property_info(
|
|
355
|
+
"test_property",
|
|
356
|
+
"test description",
|
|
357
|
+
"std::vector<int>",
|
|
358
|
+
PropertyBag(secret="is_secret::yes"),
|
|
359
|
+
)
|
|
360
|
+
self.transformer.parse(property, info, FilePair("testfile.h", "testfile.cc"))
|
|
361
|
+
self.assertTrue(property["is_secret"])
|
|
362
|
+
|
|
363
|
+
def test_adds_is_secret_false(self):
|
|
364
|
+
property = PropertyBag()
|
|
365
|
+
info = create_property_info(
|
|
366
|
+
"test_property",
|
|
367
|
+
"test description",
|
|
368
|
+
"std::vector<int>",
|
|
369
|
+
PropertyBag(secret="is_secret::no"),
|
|
370
|
+
)
|
|
371
|
+
self.transformer.parse(property, info, FilePair("testfile.h", "testfile.cc"))
|
|
372
|
+
self.assertFalse(property["is_secret"])
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
if __name__ == "__main__":
|
|
376
|
+
unittest.main()
|