def test_test_properties_deduplicated(opts, generate_tests): write(opts.ql_test_output / "Final" / "test.swift") assert generate_tests([ schema.Class("Base", derived={"A", "B"}, properties=[ schema.SingleProperty("x", "string"), schema.RepeatedProperty("y", "int"), ]), schema.Class("A", bases={"Base"}, derived={"Final"}), schema.Class("B", bases={"Base"}, derived={"Final"}), schema.Class("Final", bases={"A", "B"}), ]) == { "Final/Final.ql": ql.ClassTester(class_name="Final", properties=[ ql.PropertyForTest(getter="getX", is_single=True, type="string"), ]), "Final/Final_getY.ql": ql.PropertyTester(class_name="Final", property=ql.PropertyForTest(getter="getY", is_repeated=True, type="int")), }
def test_test_partial_properties(opts, generate_tests): write(opts.ql_test_output / "B" / "test.swift") assert generate_tests([ schema.Class("A", derived={"B"}, properties=[ schema.OptionalProperty("x", "string"), ]), schema.Class("B", bases={"A"}, properties=[ schema.RepeatedProperty("y", "int"), ]), ]) == { "B/B.ql": ql.ClassTester(class_name="B"), "B/B_getX.ql": ql.PropertyTester(class_name="B", property=ql.PropertyForTest(getter="getX", type="string")), "B/B_getY.ql": ql.PropertyTester(class_name="B", property=ql.PropertyForTest(getter="getY", is_repeated=True, type="int")), }
def test_test_total_properties(opts, generate_tests): write(opts.ql_test_output / "B" / "test.swift") assert generate_tests([ schema.Class("A", derived={"B"}, properties=[ schema.SingleProperty("x", "string"), ]), schema.Class("B", bases={"A"}, properties=[ schema.PredicateProperty("y", "int"), ]), ]) == { "B/B.ql": ql.ClassTester(class_name="B", properties=[ ql.PropertyForTest(getter="getX", is_single=True, type="string"), ql.PropertyForTest(getter="y", is_predicate=True, type="predicate"), ]) }
def test_test_source_present_with_dir(opts, generate_tests): write(opts.ql_test_output / "foo" / "A" / "test.swift") assert generate_tests([ schema.Class("A", dir=pathlib.Path("foo")), ]) == { "foo/A/A.ql": ql.ClassTester(class_name="A"), }
def test_test_source_present(opts, generate_tests): write(opts.ql_test_output / "A" / "test.swift") assert generate_tests([ schema.Class("A"), ]) == { "A/A.ql": ql.ClassTester(class_name="A"), }
def generate(opts, renderer): input = opts.schema out = opts.ql_output stub_out = opts.ql_stub_output test_out = opts.ql_test_output missing_test_source_filename = "MISSING_SOURCE.txt" existing = {q for q in out.rglob("*.qll")} existing |= {q for q in stub_out.rglob("*.qll") if is_generated(q)} existing |= {q for q in test_out.rglob("*.ql")} existing |= {q for q in test_out.rglob(missing_test_source_filename)} data = schema.load(input) classes = [get_ql_class(cls) for cls in data.classes] lookup = {cls.name: cls for cls in classes} classes.sort(key=lambda cls: (cls.dir, cls.name)) imports = {} for c in classes: imports[c.name] = get_import(stub_out / c.path, opts.swift_dir) for c in classes: qll = out / c.path.with_suffix(".qll") c.imports = [imports[t] for t in get_classes_used_by(c)] renderer.render(c, qll) stub_file = stub_out / c.path.with_suffix(".qll") if not stub_file.is_file() or is_generated(stub_file): stub = ql.Stub( name=c.name, base_import=get_import(qll, opts.swift_dir)) renderer.render(stub, stub_file) # for example path/to/elements -> path/to/elements.qll include_file = stub_out.with_suffix(".qll") renderer.render(ql.ImportList(list(imports.values())), include_file) renderer.render(ql.GetParentImplementation( classes), out / 'GetImmediateParent.qll') for c in classes: if not c.final or c.skip_qltest: continue test_dir = test_out / c.path test_dir.mkdir(parents=True, exist_ok=True) if not any(test_dir.glob("*.swift")): log.warning(f"no test source in {c.path}") renderer.render(ql.MissingTestInstructions(), test_dir / missing_test_source_filename) continue total_props, partial_props = _partition(_get_all_properties_to_be_tested(c, lookup), lambda p: p.is_single or p.is_predicate) renderer.render(ql.ClassTester(class_name=c.name, properties=total_props), test_dir / f"{c.name}.ql") for p in partial_props: renderer.render(ql.PropertyTester(class_name=c.name, property=p), test_dir / f"{c.name}_{p.getter}.ql") renderer.cleanup(existing) if opts.ql_format: format(opts.codeql_binary, renderer.written)
def test_test_base_class_skipped(opts, generate_tests): write(opts.ql_test_output / "Derived" / "test.swift") assert generate_tests([ schema.Class("Base", derived={"Derived"}, tags=["no_qltest", "foo"], properties=[ schema.SingleProperty("x", "string"), schema.RepeatedProperty("y", "int"), ]), schema.Class("Derived", bases={"Base"}), ]) == { "Derived/Derived.ql": ql.ClassTester(class_name="Derived"), }