Beispiel #1
0
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")),
    }
Beispiel #2
0
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")),
    }
Beispiel #3
0
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"),
                       ])
    }
Beispiel #4
0
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"),
    }
Beispiel #5
0
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"),
    }
Beispiel #6
0
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)
Beispiel #7
0
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"),
    }