예제 #1
0
    def test_contrib(self):
        config = LintConfig()
        contrib_rules = ["contrib-title-conventional-commits", "CC1"]
        config.set_general_option("contrib", ",".join(contrib_rules))
        self.assertEqual(config.contrib, contrib_rules)

        # Check contrib-title-conventional-commits contrib rule
        actual_rule = config.rules.find_rule(
            "contrib-title-conventional-commits")
        self.assertTrue(actual_rule.is_contrib)

        self.assertEqual(ustr(type(actual_rule)),
                         "<class 'conventional_commit.ConventionalCommit'>")
        self.assertEqual(actual_rule.id, 'CT1')
        self.assertEqual(actual_rule.name,
                         u'contrib-title-conventional-commits')
        self.assertEqual(actual_rule.target, rules.CommitMessageTitle)

        expected_rule_option = options.ListOption(
            "types",
            [
                "fix", "feat", "chore", "docs", "style", "refactor", "perf",
                "test", "revert"
            ],
            "Comma separated list of allowed commit types.",
        )

        self.assertListEqual(actual_rule.options_spec, [expected_rule_option])
        self.assertDictEqual(actual_rule.options,
                             {'types': expected_rule_option})

        # Check contrib-body-requires-signed-off-by contrib rule
        actual_rule = config.rules.find_rule(
            "contrib-body-requires-signed-off-by")
        self.assertTrue(actual_rule.is_contrib)

        self.assertEqual(ustr(type(actual_rule)),
                         "<class 'signedoff_by.SignedOffBy'>")
        self.assertEqual(actual_rule.id, 'CC1')
        self.assertEqual(actual_rule.name,
                         u'contrib-body-requires-signed-off-by')

        # reset value (this is a different code path)
        config.set_general_option("contrib",
                                  "contrib-body-requires-signed-off-by")
        self.assertEqual(
            actual_rule,
            config.rules.find_rule("contrib-body-requires-signed-off-by"))
        self.assertIsNone(
            config.rules.find_rule("contrib-title-conventional-commits"))

        # empty value
        config.set_general_option("contrib", "")
        self.assertListEqual(config.contrib, [])
예제 #2
0
    def test_set_general_option_negative(self):
        config = LintConfig()

        # Note that we shouldn't test whether we can set unicode because python just doesn't allow unicode attributes
        with self.assertRaisesRegex(LintConfigError, "'foo' is not a valid gitlint option"):
            config.set_general_option("foo", u"bår")

        # try setting _config_path, this is a real attribute of LintConfig, but the code should prevent it from
        # being set
        with self.assertRaisesRegex(LintConfigError, "'_config_path' is not a valid gitlint option"):
            config.set_general_option("_config_path", u"bår")

        # invalid verbosity`
        incorrect_values = [-1, u"föo"]
        for value in incorrect_values:
            expected_msg = ustr(r"Option 'verbosity' must be a positive integer \(current value: '{0}'\)").format(value)
            with self.assertRaisesRegex(LintConfigError, expected_msg):
                config.verbosity = value

        incorrect_values = [4]
        for value in incorrect_values:
            with self.assertRaisesRegex(LintConfigError, "Option 'verbosity' must be set between 0 and 3"):
                config.verbosity = value

        # invalid ignore_xxx_commits
        ignore_attributes = ["ignore_merge_commits", "ignore_fixup_commits", "ignore_squash_commits",
                             "ignore_revert_commits"]
        incorrect_values = [-1, 4, u"föo"]
        for attribute in ignore_attributes:
            for value in incorrect_values:
                option_name = attribute.replace("_", "-")
                with self.assertRaisesRegex(LintConfigError,
                                            "Option '{0}' must be either 'true' or 'false'".format(option_name)):
                    setattr(config, attribute, value)

        # invalid ignore -> not here because ignore is a ListOption which converts everything to a string before
        # splitting which means it it will accept just about everything

        # invalid debug
        with self.assertRaisesRegex(LintConfigError, "Option 'debug' must be either 'true' or 'false'"):
            config.debug = u"föobar"

        # extra-path has its own negative test

        # invalid target
        with self.assertRaisesRegex(LintConfigError,
                                    ustr(r"Option target must be an existing directory \(current value: 'föo/bar'\)")):
            config.target = u"föo/bar"
예제 #3
0
    def test_extra_path_negative(self):
        config = LintConfig()
        regex = ustr(r"Option extra-path must be either an existing directory or file \(current value: 'föo/bar'\)")
        # incorrect extra_path
        with self.assertRaisesRegex(LintConfigError, regex):
            config.extra_path = u"föo/bar"

        # extra path contains classes with errors
        with self.assertRaisesRegex(LintConfigError,
                                    "User-defined rule class 'MyUserLineRule' must have a 'validate' method"):
            config.extra_path = self.get_sample_path("user_rules/incorrect_linerule")
예제 #4
0
    def test_contrib_negative(self):
        config = LintConfig()
        # non-existent contrib rule
        with self.assertRaisesRegex(LintConfigError, u"No contrib rule with id or name 'föo' found."):
            config.contrib = u"contrib-title-conventional-commits,föo"

        # UserRuleError, RuleOptionError should be re-raised as LintConfigErrors
        side_effects = [rules.UserRuleError(u"üser-rule"), options.RuleOptionError(u"rüle-option")]
        for side_effect in side_effects:
            with patch('gitlint.config.rule_finder.find_rule_classes', side_effect=side_effect):
                with self.assertRaisesRegex(LintConfigError, ustr(side_effect)):
                    config.contrib = u"contrib-title-conventional-commits"
예제 #5
0
    def test_int_option(self):
        # normal behavior
        option = IntOption("test-name", 123, "Test Description")
        self.assertEqual(option.value, 123)
        self.assertEqual(option.name, "test-name")
        self.assertEqual(option.description, "Test Description")

        # re-set value
        option.set(456)
        self.assertEqual(option.value, 456)

        # error on negative int when not allowed
        expected_error = ustr(
            r"Option 'test-name' must be a positive integer \(current value: '-123'\)"
        )
        with self.assertRaisesRegex(RuleOptionError, expected_error):
            option.set(-123)

        # error on non-int value
        expected_error = ustr(
            r"Option 'test-name' must be a positive integer \(current value: 'foo'\)"
        )
        with self.assertRaisesRegex(RuleOptionError, expected_error):
            option.set("foo")

        # no error on negative value when allowed and negative int is passed
        option = IntOption("test-name",
                           123,
                           "Test Description",
                           allow_negative=True)
        option.set(-456)
        self.assertEqual(option.value, -456)

        # error on non-int value when negative int is allowed
        expected_error = ustr(
            r"Option 'test-name' must be an integer \(current value: 'foo'\)")
        with self.assertRaisesRegex(RuleOptionError, expected_error):
            option.set("foo")
예제 #6
0
    def test_set_from_config_file_negative(self):
        config_builder = LintConfigBuilder()

        # bad config file load
        foo_path = self.get_sample_path(u"föo")
        expected_error_msg = u"Invalid file path: {0}".format(
            re.escape(foo_path))
        with self.assertRaisesRegex(LintConfigError, expected_error_msg):
            config_builder.set_from_config_file(foo_path)

        # error during file parsing
        path = self.get_sample_path("config/no-sections")
        expected_error_msg = u"File contains no section headers."
        with self.assertRaisesRegex(LintConfigError, expected_error_msg):
            config_builder.set_from_config_file(path)

        # non-existing rule
        path = self.get_sample_path("config/nonexisting-rule")
        config_builder = LintConfigBuilder()
        config_builder.set_from_config_file(path)
        expected_error_msg = u"No such rule 'föobar'"
        with self.assertRaisesRegex(LintConfigError, expected_error_msg):
            config_builder.build()

        # non-existing general option
        path = self.get_sample_path("config/nonexisting-general-option")
        config_builder = LintConfigBuilder()
        config_builder.set_from_config_file(path)
        expected_error_msg = u"'foo' is not a valid gitlint option"
        with self.assertRaisesRegex(LintConfigError, expected_error_msg):
            config_builder.build()

        # non-existing option
        path = self.get_sample_path("config/nonexisting-option")
        config_builder = LintConfigBuilder()
        config_builder.set_from_config_file(path)
        expected_error_msg = u"Rule 'title-max-length' has no option 'föobar'"
        with self.assertRaisesRegex(LintConfigError, expected_error_msg):
            config_builder.build()

        # invalid option value
        path = self.get_sample_path("config/invalid-option-value")
        config_builder = LintConfigBuilder()
        config_builder.set_from_config_file(path)
        expected_error_msg = u"'föo' is not a valid value for option 'title-max-length.line-length'. " + \
                             ustr(r"Option 'line-length' must be a positive integer \(current value: 'föo'\).")
        with self.assertRaisesRegex(LintConfigError, expected_error_msg):
            config_builder.build()
예제 #7
0
    def test_set_rule_option_negative(self):
        config = LintConfig()

        # non-existing rule
        expected_error_msg = u"No such rule 'föobar'"
        with self.assertRaisesRegex(LintConfigError, expected_error_msg):
            config.set_rule_option(u'föobar', u'lïne-length', 60)

        # non-existing option
        expected_error_msg = u"Rule 'title-max-length' has no option 'föobar'"
        with self.assertRaisesRegex(LintConfigError, expected_error_msg):
            config.set_rule_option('title-max-length', u'föobar', 60)

        # invalid option value
        expected_error_msg = u"'föo' is not a valid value for option 'title-max-length.line-length'. " + \
                             ustr(r"Option 'line-length' must be a positive integer \(current value: 'föo'\).")
        with self.assertRaisesRegex(LintConfigError, expected_error_msg):
            config.set_rule_option('title-max-length', 'line-length', u"föo")
예제 #8
0
    def test_extra_path(self):
        config = LintConfig()

        config.set_general_option("extra-path", self.get_user_rules_path())
        self.assertEqual(config.extra_path, self.get_user_rules_path())
        actual_rule = config.rules.find_rule('UC1')
        self.assertTrue(actual_rule.is_user_defined)
        self.assertEqual(ustr(type(actual_rule)), "<class 'my_commit_rules.MyUserCommitRule'>")
        self.assertEqual(actual_rule.id, 'UC1')
        self.assertEqual(actual_rule.name, u'my-üser-commit-rule')
        self.assertEqual(actual_rule.target, None)
        expected_rule_option = options.IntOption('violation-count', 1, u"Number of violåtions to return")
        self.assertListEqual(actual_rule.options_spec, [expected_rule_option])
        self.assertDictEqual(actual_rule.options, {'violation-count': expected_rule_option})

        # reset value (this is a different code path)
        config.set_general_option("extra-path", self.SAMPLES_DIR)
        self.assertEqual(config.extra_path, self.SAMPLES_DIR)
        self.assertIsNone(config.rules.find_rule("UC1"))
예제 #9
0
    def test_path_option(self):
        option = PathOption("test-directory",
                            ".",
                            u"Test Description",
                            type=u"dir")
        self.assertEqual(option.value, os.getcwd())
        self.assertEqual(option.name, "test-directory")
        self.assertEqual(option.description, u"Test Description")
        self.assertEqual(option.type, u"dir")

        # re-set value
        option.set(self.SAMPLES_DIR)
        self.assertEqual(option.value, self.SAMPLES_DIR)

        # set to int
        expected = ustr(
            r"Option test-directory must be an existing directory \(current value: '1234'\)"
        )
        with self.assertRaisesRegex(RuleOptionError, expected):
            option.set(1234)

        # set to non-existing directory
        non_existing_path = os.path.join(u"/föo", u"bar")
        expected = ustr(
            r"Option test-directory must be an existing directory \(current value: '{0}'\)"
        )
        with self.assertRaisesRegex(RuleOptionError,
                                    expected.format(non_existing_path)):
            option.set(non_existing_path)

        # set to a file, should raise exception since option.type = dir
        sample_path = self.get_sample_path(
            os.path.join("commit_message", "sample1"))
        expected = ustr(
            r"Option test-directory must be an existing directory \(current value: '{0}'\)"
        ).format(re.escape(sample_path))
        with self.assertRaisesRegex(RuleOptionError, expected):
            option.set(sample_path)

        # set option.type = file, file should now be accepted, directories not
        option.type = u"file"
        option.set(sample_path)
        self.assertEqual(option.value, sample_path)
        expected = ustr(
            r"Option test-directory must be an existing file \(current value: '{0}'\)"
        ).format(re.escape(self.get_sample_path()))
        with self.assertRaisesRegex(RuleOptionError, expected):
            option.set(self.get_sample_path())

        # set option.type = both, files and directories should now be accepted
        option.type = u"both"
        option.set(sample_path)
        self.assertEqual(option.value, sample_path)
        option.set(self.get_sample_path())
        self.assertEqual(option.value, self.get_sample_path())

        # Expect exception if path type is invalid
        option.type = u'föo'
        expected = ustr(
            r"Option test-directory type must be one of: 'file', 'dir', 'both' \(current: 'föo'\)"
        )
        with self.assertRaisesRegex(RuleOptionError, expected):
            option.set("haha")