Пример #1
0
    def _configure(
        self,
        contracts_options: List[Dict[str, Any]],
        contract_types: Optional[List[str]] = None,
        graph: Optional[ImportGraph] = None,
    ):
        session_options = {"root_package": "mypackage"}
        if not contract_types:
            contract_types = [
                "always_passes: tests.helpers.contracts.AlwaysPassesContract",
                "always_fails: tests.helpers.contracts.AlwaysFailsContract",
                "fields: tests.helpers.contracts.FieldsContract",
                "forbidden: tests.helpers.contracts.ForbiddenImportContract",
            ]
        session_options["contract_types"] = contract_types  # type: ignore

        reader = FakeUserOptionReader(
            UserOptions(session_options=session_options,
                        contracts_options=contracts_options))
        settings.configure(USER_OPTION_READERS=[reader],
                           GRAPH_BUILDER=FakeGraphBuilder(),
                           PRINTER=FakePrinter())
        if graph is None:
            graph = self._build_default_graph()

        settings.GRAPH_BUILDER.inject_graph(graph)
Пример #2
0
    def test_debug_mode_doesnt_swallow_exception(self):
        some_exception = RuntimeError("There was some sort of exception.")
        reader = ExceptionRaisingUserOptionReader(exception=some_exception)
        settings.configure(
            USER_OPTION_READERS=[reader], GRAPH_BUILDER=FakeGraphBuilder(), PRINTER=FakePrinter()
        )

        with pytest.raises(some_exception.__class__, match=str(some_exception)):
            lint_imports(is_debug_mode=True)
Пример #3
0
    def test_builder_is_called_with_root_packages(self):
        builder = FakeGraphBuilder()
        root_package_names = ["mypackageone", "mypackagetwo"]
        settings.configure(GRAPH_BUILDER=builder, PRINTER=FakePrinter())

        create_report(
            UserOptions(session_options={"root_packages": root_package_names},
                        contracts_options=[]))

        assert builder.build_arguments[
            "root_package_names"] == root_package_names
Пример #4
0
    def test_non_debug_mode_prints_exception(self):
        some_exception = RuntimeError("There was some sort of exception.")
        reader = ExceptionRaisingUserOptionReader(exception=some_exception)
        settings.configure(
            USER_OPTION_READERS=[reader], GRAPH_BUILDER=FakeGraphBuilder(), PRINTER=FakePrinter()
        )

        lint_imports(is_debug_mode=False)

        settings.PRINTER.pop_and_assert(
            """There was some sort of exception.
            """
        )
Пример #5
0
    def test_graph_can_be_mutated_without_affecting_other_contracts(self):
        # The MutationCheckContract checks that there are a certain number of modules and imports
        # in the graph, then adds one more module and one more import. We can check two such
        # contracts and the second one will fail, if the graph gets mutated by other contracts.
        session_options = {
            "root_package": "mypackage",
            "contract_types": ["mutation_check: tests.helpers.contracts.MutationCheckContract"],
        }

        reader = FakeUserOptionReader(
            UserOptions(
                session_options=session_options,
                contracts_options=[
                    {
                        "type": "mutation_check",
                        "name": "Contract one",
                        "number_of_modules": "5",
                        "number_of_imports": "2",
                    },
                    {
                        "type": "mutation_check",
                        "name": "Contract two",
                        "number_of_modules": "5",
                        "number_of_imports": "2",
                    },
                ],
            )
        )
        settings.configure(
            USER_OPTION_READERS=[reader], GRAPH_BUILDER=FakeGraphBuilder(), PRINTER=FakePrinter()
        )

        graph = ImportGraph()

        # Create a graph with five modules and two imports.
        for module in ("one", "two", "three", "four", "five"):
            graph.add_module(module)
        graph.add_import(importer="one", imported="two")
        graph.add_import(importer="one", imported="three")

        settings.GRAPH_BUILDER.inject_graph(graph)

        result = lint_imports(is_debug_mode=True)

        assert result == SUCCESS
Пример #6
0
def test_render_broken_contract():
    settings.configure(PRINTER=FakePrinter())
    contract = ForbiddenContract(
        name="Forbid contract",
        session_options={"root_packages": ["mypackage"]},
        contract_options={
            "source_modules":
            ("mypackage.one", "mypackage.two", "mypackage.three"),
            "forbidden_modules": (
                "mypackage.blue",
                "mypackage.green",
                "mypackage.yellow",
                "mypackage.purple",
            ),
        },
    )
    check = ContractCheck(
        kept=False,
        metadata={
            "invalid_chains": [
                {
                    "upstream_module":
                    "mypackage.purple",
                    "downstream_module":
                    "mypackage.two",
                    "chains": [[
                        {
                            "importer": "mypackage.two",
                            "imported": "mypackage.utils",
                            "line_numbers": (9, ),
                        },
                        {
                            "importer": "mypackage.utils",
                            "imported": "mypackage.purple",
                            "line_numbers": (1, ),
                        },
                    ]],
                },
                {
                    "upstream_module":
                    "mypackage.green",
                    "downstream_module":
                    "mypackage.three",
                    "chains": [[{
                        "importer": "mypackage.three",
                        "imported": "mypackage.green",
                        "line_numbers": (4, ),
                    }]],
                },
            ]
        },
    )

    contract.render_broken_contract(check)

    settings.PRINTER.pop_and_assert("""
        mypackage.two is not allowed to import mypackage.purple:

        -   mypackage.two -> mypackage.utils (l.9)
            mypackage.utils -> mypackage.purple (l.1)


        mypackage.three is not allowed to import mypackage.green:

        -   mypackage.three -> mypackage.green (l.4)


        """)
Пример #7
0
def test_render_broken_contract():
    settings.configure(PRINTER=FakePrinter())
    contract = LayersContract(
        name="Layers contract",
        session_options={"root_packages": ["mypackage"]},
        contract_options={"containers": ["mypackage"], "layers": ["high", "medium", "low"]},
    )
    check = ContractCheck(
        kept=False,
        metadata={
            "invalid_chains": [
                {
                    "higher_layer": "mypackage.high",
                    "lower_layer": "mypackage.low",
                    "chains": [
                        [
                            {
                                "importer": "mypackage.low.blue",
                                "imported": "mypackage.utils.red",
                                "line_numbers": (8, 16),
                            },
                            {
                                "importer": "mypackage.utils.red",
                                "imported": "mypackage.utils.yellow",
                                "line_numbers": (1,),
                            },
                            {
                                "importer": "mypackage.utils.yellow",
                                "imported": "mypackage.high.green",
                                "line_numbers": (3,),
                            },
                        ],
                        [
                            {
                                "importer": "mypackage.low.purple",
                                "imported": "mypackage.high.brown",
                                "line_numbers": (9,),
                            }
                        ],
                    ],
                },
                {
                    "higher_layer": "mypackage.medium",
                    "lower_layer": "mypackage.low",
                    "chains": [
                        [
                            {
                                "importer": "mypackage.low.blue",
                                "imported": "mypackage.medium.yellow",
                                "line_numbers": (6,),
                            }
                        ]
                    ],
                },
                {
                    "higher_layer": "mypackage.high",
                    "lower_layer": "mypackage.medium",
                    "chains": [
                        [
                            {
                                "importer": "mypackage.medium",
                                "imported": "mypackage.high.cyan.alpha",
                                "line_numbers": (2,),
                            }
                        ]
                    ],
                },
            ]
        },
    )

    contract.render_broken_contract(check)

    settings.PRINTER.pop_and_assert(
        """
        mypackage.low is not allowed to import mypackage.high:

        -   mypackage.low.blue -> mypackage.utils.red (l.8, l.16)
            mypackage.utils.red -> mypackage.utils.yellow (l.1)
            mypackage.utils.yellow -> mypackage.high.green (l.3)

        -   mypackage.low.purple -> mypackage.high.brown (l.9)


        mypackage.low is not allowed to import mypackage.medium:

        -   mypackage.low.blue -> mypackage.medium.yellow (l.6)


        mypackage.medium is not allowed to import mypackage.high:

        -   mypackage.medium -> mypackage.high.cyan.alpha (l.2)


        """
    )
Пример #8
0
def test_render_broken_contract():
    settings.configure(PRINTER=FakePrinter())
    contract = IndependenceContract(
        name="Independence contract",
        session_options={"root_packages": ["mypackage"]},
        contract_options={
            "modules":
            ["mypackage.blue", "mypackage.green", "mypackage.yellow"]
        },
    )
    check = ContractCheck(
        kept=False,
        metadata={
            "invalid_chains": [
                {
                    "upstream_module":
                    "mypackage.yellow",
                    "downstream_module":
                    "mypackage.blue",
                    "chains": [
                        [
                            {
                                "importer": "mypackage.blue.foo",
                                "imported": "mypackage.utils.red",
                                "line_numbers": (16, 102),
                            },
                            {
                                "importer": "mypackage.utils.red",
                                "imported": "mypackage.utils.brown",
                                "line_numbers": (1, ),
                            },
                            {
                                "importer": "mypackage.utils.brown",
                                "imported": "mypackage.yellow.bar",
                                "line_numbers": (3, ),
                            },
                        ],
                        [{
                            "importer": "mypackage.blue.bar",
                            "imported": "mypackage.yellow.baz",
                            "line_numbers": (5, ),
                        }],
                    ],
                },
                {
                    "upstream_module":
                    "mypackage.green",
                    "downstream_module":
                    "mypackage.yellow",
                    "chains": [[{
                        "importer": "mypackage.yellow.foo",
                        "imported": "mypackage.green.bar",
                        "line_numbers": (15, ),
                    }]],
                },
            ]
        },
    )

    contract.render_broken_contract(check)

    settings.PRINTER.pop_and_assert("""
        mypackage.blue is not allowed to import mypackage.yellow:

        -   mypackage.blue.foo -> mypackage.utils.red (l.16, l.102)
            mypackage.utils.red -> mypackage.utils.brown (l.1)
            mypackage.utils.brown -> mypackage.yellow.bar (l.3)

        -   mypackage.blue.bar -> mypackage.yellow.baz (l.5)


        mypackage.yellow is not allowed to import mypackage.green:

        -   mypackage.yellow.foo -> mypackage.green.bar (l.15)


        """)