Merge pull request 'schemagen: add regression test for nullable cyclic $ref targets' (#50) from weaselbot/weaseljson:weaselbot/issue-14 into main
CI / pre-commit (push) Successful in 53s
CI / build (-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++, clang-arm64, ubuntu-latest-arm64, true) (push) Successful in 56s
CI / build (-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, gcc-arm64, ubuntu-latest-arm64, false) (push) Successful in 53s
CI / build (-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++, clang-amd64, ubuntu-latest-amd64, true) (push) Successful in 1m36s
CI / build (-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, gcc-amd64, ubuntu-latest-amd64, false) (push) Successful in 1m28s
CI / pre-commit (push) Successful in 53s
CI / build (-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++, clang-arm64, ubuntu-latest-arm64, true) (push) Successful in 56s
CI / build (-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, gcc-arm64, ubuntu-latest-arm64, false) (push) Successful in 53s
CI / build (-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++, clang-amd64, ubuntu-latest-amd64, true) (push) Successful in 1m36s
CI / build (-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, gcc-amd64, ubuntu-latest-amd64, false) (push) Successful in 1m28s
Reviewed-on: #50
This commit was merged in pull request #50.
This commit is contained in:
@@ -353,6 +353,132 @@ class SchemagenCyclicArrayTest(unittest.TestCase):
|
|||||||
self.assertIn("std::optional<std::vector<Role>> roles;", stdout)
|
self.assertIn("std::optional<std::vector<Role>> roles;", stdout)
|
||||||
|
|
||||||
|
|
||||||
|
class SchemagenCyclicNullableObjectTest(unittest.TestCase):
|
||||||
|
"""Regression tests for issue #14: nullable cyclic $ref targets."""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.repo_root = os.path.dirname(
|
||||||
|
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
)
|
||||||
|
self.include_dir = os.path.join(self.repo_root, "include")
|
||||||
|
self.lib_src = os.path.join(self.repo_root, "src", "lib.cpp")
|
||||||
|
self.compiler = shutil.which("c++")
|
||||||
|
|
||||||
|
def _compile_harness(self, tmpdir, schema, harness):
|
||||||
|
schema_path = os.path.join(tmpdir, "schema.json")
|
||||||
|
with open(schema_path, "w") as fp:
|
||||||
|
json.dump(schema, fp)
|
||||||
|
header_path = os.path.join(tmpdir, "gen.h")
|
||||||
|
result = subprocess.run(
|
||||||
|
[
|
||||||
|
sys.executable,
|
||||||
|
SCRIPT,
|
||||||
|
schema_path,
|
||||||
|
"-o",
|
||||||
|
header_path,
|
||||||
|
"--namespace",
|
||||||
|
"test_schema",
|
||||||
|
],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
self.assertEqual(result.returncode, 0, msg=result.stderr)
|
||||||
|
|
||||||
|
lib_obj = os.path.join(tmpdir, "lib.o")
|
||||||
|
comp_lib = subprocess.run(
|
||||||
|
[
|
||||||
|
self.compiler,
|
||||||
|
"-std=c++20",
|
||||||
|
"-I",
|
||||||
|
self.include_dir,
|
||||||
|
"-I",
|
||||||
|
os.path.join(self.repo_root, "third_party", "include"),
|
||||||
|
"-I",
|
||||||
|
os.path.join(self.repo_root, "third_party", "valgrind"),
|
||||||
|
"-c",
|
||||||
|
self.lib_src,
|
||||||
|
"-o",
|
||||||
|
lib_obj,
|
||||||
|
],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
self.assertEqual(comp_lib.returncode, 0, msg=comp_lib.stderr)
|
||||||
|
|
||||||
|
cpp_path = os.path.join(tmpdir, "test.cpp")
|
||||||
|
with open(cpp_path, "w") as fp:
|
||||||
|
fp.write(harness)
|
||||||
|
|
||||||
|
exe_path = os.path.join(tmpdir, "test")
|
||||||
|
comp = subprocess.run(
|
||||||
|
[
|
||||||
|
self.compiler,
|
||||||
|
"-std=c++20",
|
||||||
|
"-I",
|
||||||
|
self.include_dir,
|
||||||
|
"-I",
|
||||||
|
tmpdir,
|
||||||
|
lib_obj,
|
||||||
|
cpp_path,
|
||||||
|
"-o",
|
||||||
|
exe_path,
|
||||||
|
],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
self.assertEqual(comp.returncode, 0, msg=comp.stderr)
|
||||||
|
run = subprocess.run([exe_path], capture_output=True, text=True, check=False)
|
||||||
|
self.assertEqual(run.returncode, 0, msg=run.stdout + run.stderr)
|
||||||
|
|
||||||
|
def test_self_referential_nullable_object_accepts_nested_null(self):
|
||||||
|
"""A nullable object $def must stay nullable on recursive $refs."""
|
||||||
|
if not self.compiler:
|
||||||
|
self.skipTest("C++ compiler not available")
|
||||||
|
schema = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {"self": {"$ref": "#/$defs/Self"}},
|
||||||
|
"$defs": {
|
||||||
|
"Self": {
|
||||||
|
"type": ["object", "null"],
|
||||||
|
"properties": {"self": {"$ref": "#/$defs/Self"}},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
harness = textwrap.dedent(
|
||||||
|
"""
|
||||||
|
#include "gen.h"
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
struct Case { const char *s; WeaselJsonStatus expected; };
|
||||||
|
int main() {
|
||||||
|
Case cases[] = {
|
||||||
|
{ R"({"self": null})", WeaselJson_OK },
|
||||||
|
{ R"({"self": {"self": null}})", WeaselJson_OK },
|
||||||
|
{ R"({"self": {"self": {}}})", WeaselJson_OK },
|
||||||
|
};
|
||||||
|
for (const auto &c : cases) {
|
||||||
|
test_schema::RootBuilder b;
|
||||||
|
char buf[256];
|
||||||
|
std::strncpy(buf, c.s, sizeof(buf) - 1);
|
||||||
|
buf[sizeof(buf) - 1] = '\\0';
|
||||||
|
WeaselJsonStatus st = b.feed(buf, std::strlen(buf));
|
||||||
|
st = b.finish();
|
||||||
|
if (st != c.expected) {
|
||||||
|
std::printf("case %s expected %d got %d\\n", c.s, c.expected, st);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
self._compile_harness(tmpdir, schema, harness)
|
||||||
|
|
||||||
|
|
||||||
class SchemagenIntegerBoundaryTest(unittest.TestCase):
|
class SchemagenIntegerBoundaryTest(unittest.TestCase):
|
||||||
"""Regression tests for issue #19: integer slot parsing near int64 boundaries."""
|
"""Regression tests for issue #19: integer slot parsing near int64 boundaries."""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user