Skip to content

Commit 04e3b39

Browse files
authored
Merge pull request github#17537 from github/redsun82/rust-doctest-gen
Rust: take test code also from property descriptions
2 parents 05173fa + 2a95068 commit 04e3b39

File tree

2 files changed

+38
-16
lines changed

2 files changed

+38
-16
lines changed

misc/codegen/generators/rusttestgen.py

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import dataclasses
22
import typing
3+
from collections.abc import Iterable
4+
35
import inflection
46

57
from misc.codegen.loaders import schemaloader
@@ -27,6 +29,25 @@ class TestCode:
2729
function: Function | None = None
2830

2931

32+
def _get_code(doc: list[str]) -> list[str]:
33+
adding_code = False
34+
has_code = False
35+
code = []
36+
for line in doc:
37+
match line, adding_code:
38+
case ("```", _) | ("```rust", _):
39+
adding_code = not adding_code
40+
has_code = True
41+
case _, False:
42+
code.append(f"// {line}")
43+
case _, True:
44+
code.append(line)
45+
assert not adding_code, "Unterminated code block in docstring:\n " + "\n ".join(doc)
46+
if has_code:
47+
return code
48+
return []
49+
50+
3051
def generate(opts, renderer):
3152
assert opts.ql_test_output
3253
schema = schemaloader.load_file(opts.schema)
@@ -36,24 +57,18 @@ def generate(opts, renderer):
3657
force=opts.force) as renderer:
3758
for cls in schema.classes.values():
3859
if (qlgen.should_skip_qltest(cls, schema.classes) or
39-
"rust_skip_test_from_doc" in cls.pragmas or
40-
not cls.doc):
60+
"rust_skip_doc_test" in cls.pragmas):
4161
continue
42-
code = []
43-
adding_code = False
44-
has_code = False
45-
for line in cls.doc:
46-
match line, adding_code:
47-
case ("```", _) | ("```rust", _):
48-
adding_code = not adding_code
49-
has_code = True
50-
case _, False:
51-
code.append(f"// {line}")
52-
case _, True:
53-
code.append(line)
54-
if not has_code:
62+
code = _get_code(cls.doc)
63+
for p in schema.iter_properties(cls.name):
64+
if "rust_skip_doc_test" in p.pragmas:
65+
continue
66+
property_code = _get_code(p.description)
67+
if property_code:
68+
code.append(f"// # {p.name}")
69+
code += property_code
70+
if not code:
5571
continue
56-
assert not adding_code, "Unterminated code block in docstring: " + "\n".join(cls.doc)
5772
test_name = inflection.underscore(cls.name)
5873
signature = cls.pragmas.get("rust_doc_test_signature", "() -> ()")
5974
fn = signature and Function(f"test_{test_name}", signature)

misc/codegen/lib/schema.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
""" schema format representation """
22
import abc
33
import typing
4+
from collections.abc import Iterable
45
from dataclasses import dataclass, field
56
from typing import List, Set, Union, Dict, Optional
67
from enum import Enum, auto
@@ -144,6 +145,12 @@ def root_class(self):
144145
def null_class(self):
145146
return self.classes[self.null] if self.null else None
146147

148+
def iter_properties(self, cls: str) -> Iterable[Property]:
149+
cls = self.classes[cls]
150+
for b in cls.bases:
151+
yield from self.iter_properties(b)
152+
yield from cls.properties
153+
147154

148155
predicate_marker = object()
149156

0 commit comments

Comments
 (0)