Example #1
0
def test_not_passing_rules_with_import_from() -> None:
    """
    Test result with a set rules that accept files.
    """
    # Given
    dep_rules = {
        "module": [ModuleWildcard("module%"), ModuleWildcard("amodule.submodule")]
    }
    configuration = Configuration(dep_rules)
    source_file = SourceFile(
        Module("module"), SourceCode("from amodule import othermodule, submodule\n")
    )
    report_printer = Mock()
    use_case = CheckDependenciesUC(
        configuration, report_printer, PARSER, iter([source_file])
    )

    # When
    with pytest.raises(ForbiddenDepencyError):
        use_case.run()

    # Then
    assert set(report_printer.print_report.call_args[0][0]) == set(
        (
            DependencyError(
                Module("module"),
                Module("amodule.othermodule"),
                tuple(sorted(dep_rules["module"])),
            ),
        )
    )
Example #2
0
def test_passing_rules(source_files) -> None:
    """
    Test result with a set rules that accept files.
    """
    # Given
    configuration = Configuration(
        dependency_rules={
            SIMPLE_FILE.module:
            [ModuleWildcard("module%"),
             ModuleWildcard("amodule")],
            "amodule.*": [
                ModuleWildcard("module"),
                ModuleWildcard("module.inside.*"),
                ModuleWildcard("amodule%"),
            ],
        })
    report_printer = Mock()
    use_case = CheckDependenciesUC(configuration, report_printer, PARSER,
                                   source_files)

    # When
    use_case.run()

    # Then
    report_printer.print_report.assert_called_with([], set(), 3)
Example #3
0
    def _get_rules(self, module: Module) -> Rules:
        """
        Return rules in configuration that match a given module.
        """
        matching_rules: Rules = set()
        for module_wildcard, rules in self.configuration.dependency_rules.items(
        ):
            if re.match(
                    "{}$".format(
                        self.parser.wildcard_to_regex(
                            ModuleWildcard(module_wildcard))),
                    module,
            ):
                matching_rules.update(
                    (ModuleWildcard(module_wildcard), r) for r in rules)

        return matching_rules
Example #4
0
    def wildcard_to_regex(self, module: ModuleWildcard) -> str:
        """
        Return a regex expression for the Module from wildcard
        """
        module_regex = module.replace(".", "\\.").replace("*", ".*")
        module_regex = module_regex.replace("[!", "[^").replace("?", ".?")

        # Special char including a module along with all its sub-modules:
        module_regex = module_regex.replace("%", r"(\..*)?$")
        return module_regex
def test_passing_case() -> None:
    """
    Test a passing case.
    """
    # Given
    dependency = Dependency(Module("toto"))
    rules: Rules = [
        (ModuleWildcard("toto"), ModuleWildcard("to*")),
        (ModuleWildcard("toto"), ModuleWildcard("titi.tata")),
    ]

    # When
    error = None
    try:
        check_dependency(PARSER, dependency, rules)
    except NotAllowedDependencyException as exception:
        error = exception

    # Then
    assert not error
Example #6
0
def test_passing_rules_with_import_from() -> None:
    """
    Test result with a set rules that accept files.
    """
    # Given
    configuration = Configuration(
        dependency_rules={
            "module": [ModuleWildcard("module%"), ModuleWildcard("amodule.submodule")]
        }
    )
    source_file = SourceFile("module", SourceCode("from amodule import submodule"))
    report_printer = Mock()
    use_case = CheckDependenciesUC(
        configuration, report_printer, PARSER, iter([source_file])
    )

    # When
    use_case.run()

    # Then
    assert report_printer.print_report.call_args[0][0] == []
Example #7
0
    def test_empty() -> None:
        """
        Test empty case.
        """
        # Given
        module = ModuleWildcard("")

        # When
        regex = PARSER.wildcard_to_regex(module)

        # Then
        assert regex == ""
Example #8
0
    def test_simple_module() -> None:
        """
        Test simple case.
        """
        # Given
        module = ModuleWildcard("toto")

        # When
        regex = PARSER.wildcard_to_regex(module)

        # Then
        assert re.match(regex, "toto")
        assert not re.match(regex, "tata")
        assert not re.match(regex, "titi.toto")
Example #9
0
    def test_percentage() -> None:
        """
        Test percentage case
        """
        # Given
        module = ModuleWildcard("toto.tata%")

        # When
        regex = PARSER.wildcard_to_regex(module)

        # Then
        assert re.match(regex, "toto.tata")
        assert re.match(regex, "toto.tata.titi")
        assert re.match(regex, "toto.tata.titi.tutu.tototata.tititutu")
        assert not re.match(regex, "toto")
        assert not re.match(regex, "toto.tata_123")
Example #10
0
def test_nominal(source_files) -> None:
    """
    Test result with a set source files.
    """
    # Given
    dependencies_writer = Mock()
    use_case = BuildConfigurationUC(dependencies_writer, PARSER, source_files, "python")

    # When
    use_case.run()

    # Then
    dependencies_writer.write.assert_called()  # type: ignore
    configuration = dependencies_writer.write.call_args[0][0]
    assert not configuration.local_init
    dependency_rules = {
        module_regex: set(rules)
        for module_regex, rules in configuration.dependency_rules.items()
    }
    assert dependency_rules == {
        "simple_module": set(
            (
                ModuleWildcard("module"),
                ModuleWildcard("module.inside.module"),
                ModuleWildcard("amodule"),
            )
        ),
        "amodule.local_module": set(
            (
                ModuleWildcard("module"),
                ModuleWildcard("module.inside.module"),
                ModuleWildcard("amodule"),
                ModuleWildcard("amodule.inside"),
            )
        ),
        "amodule.std_module": set(
            (ModuleWildcard("module"), ModuleWildcard("module.inside.module"))
        ),
    }
Example #11
0
    def test_asterisk() -> None:
        """
        Test asterisk case
        """
        # Given
        module = ModuleWildcard("toto*.*")

        # When
        regex = PARSER.wildcard_to_regex(module)

        # Then
        assert re.match(regex, "toto.tata")
        assert re.match(regex, "toto_2351.titi")
        assert re.match(regex, "toto_azerty.titi.toto.tata")
        assert not re.match(regex, "toto")
        assert not re.match(regex, "tototata")
        assert not re.match(regex, "toti.toto")
Example #12
0
    def test_quesiton_mark() -> None:
        """
        Test question mark case
        """
        # Given
        module = ModuleWildcard("t?to.?at?")

        # When
        regex = PARSER.wildcard_to_regex(module)

        # Then
        assert re.match(regex, "toto.tata")
        assert re.match(regex, "t2to.bato")
        assert re.match(regex, "t#to.!at&")
        assert not re.match(regex, "toto")
        assert not re.match(regex, "tata")
        assert not re.match(regex, "toti.toto")
Example #13
0
def test_not_passing_rules(source_files) -> None:
    """
    Test result with a set rules that not accept files.
    """
    # Given
    dep_rules = {
        "simple_module": [ModuleWildcard("module.*"), ModuleWildcard("amodule")],
        "amodule.local_module": [
            ModuleWildcard("module"),
            ModuleWildcard("module.inside.*"),
            ModuleWildcard("amod"),
        ],
        "amodule.std_module": [ModuleWildcard("mod")],
    }

    configuration = Configuration(dependency_rules=dep_rules)
    report_printer = Mock()
    use_case = CheckDependenciesUC(configuration, report_printer, PARSER, source_files)

    # When
    with pytest.raises(ForbiddenDepencyError):
        use_case.run()

    # Then
    simple = SIMPLE_FILE.module
    local = FILE_WITH_LOCAL_IMPORT.module
    std = FILE_WITH_STD_IMPORT.module

    assert set(report_printer.print_report.call_args[0][0]) == set(
        (
            DependencyError(
                simple, Module("module"), tuple(sorted(dep_rules["simple_module"]))
            ),
            DependencyError(
                local,
                Module("amodule.aclass"),
                tuple(sorted(dep_rules["amodule.local_module"])),
            ),
            DependencyError(
                local,
                Module("amodule.inside.aclass"),
                tuple(sorted(dep_rules["amodule.local_module"])),
            ),
            DependencyError(
                std, Module("module"), tuple(sorted(dep_rules["amodule.std_module"]))
            ),
            DependencyError(
                std,
                Module("module.inside.module"),
                tuple(sorted(dep_rules["amodule.std_module"])),
            ),
        )
    )
Example #14
0
    def run(self) -> None:
        """
        Build configuration from existing source files.
        """
        global_dependencies: Dict[Module, Dependencies] = {}
        for source_file in self.source_files:
            dependencies = get_dependencies(source_file, self.parser)
            dependencies = self.std_lib_filter.filter(dependencies)

            global_dependencies[source_file.module] = dependencies

        dependency_rules = {}
        for module, dependencies in global_dependencies.items():
            dependency_rules[str(module)] = [
                ModuleWildcard(dependency.main_import) for dependency in dependencies
            ]

        self.printer.write(Configuration(dependency_rules))
Example #15
0
    def run(self) -> None:
        errors = []
        nb_files = 0

        for source_file in self.source_files:
            nb_files += 1
            for error in self._iter_error(source_file):
                errors.append(error)

        all_rules: Rules = set(
            (ModuleWildcard(wildcard), rule)
            for wildcard, rules in self.configuration.dependency_rules.items()
            for rule in rules)
        unused = all_rules.difference(self.used_rules)
        self.report_printer.print_report(errors, unused, nb_files)

        if self.configuration.error_on_unused and unused:
            raise ForbiddenUnusedRuleError

        if errors:
            raise ForbiddenDepencyError
def test_not_passing_case() -> None:
    """
    Test a not passing case.
    """
    # Given
    dependency = Dependency(Module("toto.tata"))
    rules: Rules = [
        (ModuleWildcard("toto.*"), ModuleWildcard("toto")),
        (ModuleWildcard("toto.*"), ModuleWildcard("te.*")),
        (ModuleWildcard("toto.*"), ModuleWildcard("titi\\.tata")),
    ]

    # When
    with raises(NotAllowedDependencyException) as error:
        check_dependency(PARSER, dependency, rules)

    # Then
    assert error
    assert error.value.dependency == dependency.main_import
    assert error.value.authorized_modules == [r for _, r in rules]
Example #17
0
def test_error_on_unused(source_files) -> None:
    """
    Test result with a set rules that accept files.
    """
    # Given
    configuration = Configuration(
        dependency_rules={
            SIMPLE_FILE.module: [ModuleWildcard("module%"), ModuleWildcard("amodule")],
            "amodule.*": [
                ModuleWildcard("module"),
                ModuleWildcard("module.inside.*"),
                ModuleWildcard("amodule%"),
                ModuleWildcard("unused%"),
            ],
            "unused_wildcard.*": [ModuleWildcard("unused%")],
        },
        error_on_unused=True,
    )
    report_printer = Mock()
    use_case = CheckDependenciesUC(configuration, report_printer, PARSER, source_files)

    # When
    with pytest.raises(ForbiddenUnusedRuleError):
        use_case.run()

    # Then
    report_printer.print_report.assert_called_with(
        [],
        {
            (ModuleWildcard("amodule.*"), ModuleWildcard("unused%")),
            (ModuleWildcard("unused_wildcard.*"), ModuleWildcard("unused%")),
        },
        3,
    )