Ejemplo n.º 1
0
    def test_staged_file_content(self):

        try:
            # initialize repo
            repo = BasicRepo(bare=False)

            # initialize git handle
            git_handle = GitHandle(repo.repo_path)

            # write file
            test_staged_file = path.join(repo.repo_path, "test_staged_file")
            with open(test_staged_file, "w") as foo:
                foo.write("test stage")

            # stage
            repo.repo.git.add([test_staged_file])

            # edit the file again
            with open(test_staged_file, "a") as foo:
                foo.write("\nmore")

            # get staged file path
            pth = git_handle.get_staged_files_paths()[0]

            self.assertEqual(git_handle.get_staged_file_content(pth),
                             b"test stage")

        except Exception:
            raise

        finally:
            repo.delete()
Ejemplo n.º 2
0
    def test_check_path_is_allowed(self):

        try:
            # initialize repo
            repo = BasicRepo()

            # initialize git handle
            git_handle = GitHandle(repo.repo_path)

            # test some bad paths and file names...
            with self.assertRaises(ForbiddenCharacterError):
                git_handle._check_path_is_allowed("a bad/path")

            with self.assertRaises(ForbiddenCharacterError):
                git_handle._check_path_is_allowed("/a\nice/path/")

            with self.assertRaises(ForbiddenCharacterError):
                git_handle._check_path_is_allowed("this_is_/'the'/_path")

            with self.assertRaises(ForbiddenCharacterError):
                git_handle._check_path_is_allowed(path.join("\\", "a_path"))

            with self.assertRaises(ForbiddenCharacterError):
                git_handle._check_path_is_allowed(
                    path.join("/some/path", "this is_bad.ext"))

        except Exception:
            raise

        finally:
            repo.delete()
Ejemplo n.º 3
0
    def test_get_staged_file_paths(self):

        try:
            # initialize repo
            repo = BasicRepo(bare=False)

            # initialize git handle
            git_handle = GitHandle(repo.repo_path)

            # test staging
            test_staged_file = path.join(repo.repo_path, "test_staged_file")
            with open(test_staged_file, "w") as foo:
                foo.write("test stage")

            test_staged_file1 = path.join(repo.repo_path, "test_staged_file1")
            with open(test_staged_file1, "w") as foo:
                foo.write("test stage1")

            # stage
            repo.repo.git.add([test_staged_file, test_staged_file1])

            self.assertEqual(
                set(git_handle.get_staged_files_paths()),
                set([
                    path.relpath(test_staged_file, repo.repo_path),
                    path.relpath(test_staged_file1, repo.repo_path)
                ]))

        except Exception:
            raise

        finally:
            repo.delete()
Ejemplo n.º 4
0
    def test_lint_multiple(self):
        # test ability to execute `run` method with multiple linters
        try:
            # initialize repo
            repo = BasicRepo(bare=False)

            # write a bad markdown file
            test_staged_file = path.join(repo.repo_path, "foo.md")
            w = Writer(test_staged_file)
            w.write("# Bad markdown")
            w.write("There should be an empty line before this!")
            w.write("Also, this is way too long" * 300)

            # write a bad R file
            test_staged_file1 = path.join(repo.repo_path, "bar.R")
            w1 = Writer(test_staged_file1)
            w1.write("# Bad R")
            w1.write("f=function(x) print( 'Hello' )")
            w1.write("a=5")

            # stage it
            repo.repo.git.add([test_staged_file, test_staged_file1])

            # initialize a `GitHandle`
            git_handle = GitHandle(path=repo.repo_path)

            # initialize a `Lint` object
            ell = Lint(git_handle=git_handle,
                       linters=[MarkdownLinter(), RLinter()])

            # execute the main method of the  `Lint` object
            f = StringIO()
            with redirect_stdout(f):
                n_files_with_problems = ell.run()

            self.assertEqual(n_files_with_problems, 2)

        except Exception:
            raise

        finally:
            # clean up
            w.delete()
            w1.delete()
            repo.delete()
Ejemplo n.º 5
0
    def test_get_head_hash_bare(self):

        try:
            # initialize repo
            repo = BasicRepo()

            # initialize git handle
            git_handle = GitHandle(repo.repo_path)

            # test
            self.assertEqual(git_handle.get_head_hash(),
                             "4b825dc642cb6eb9a060e54bf8d69288fbee4904")

        except Exception:
            raise

        finally:
            repo.delete()
Ejemplo n.º 6
0
    def test_get_git_root(self):

        try:
            # initialize repo
            repo = BasicRepo()

            # initialize git handle
            git_handle = GitHandle(repo.repo_path)

            # test
            self.assertEqual(path.abspath(git_handle.root),
                             path.abspath(repo.repo_path))

        except Exception:
            raise

        finally:
            repo.delete()
Ejemplo n.º 7
0
    def test_get_head_hash_not_bare(self):

        try:
            # initialize repo
            repo = BasicRepo(bare=False)

            # initialize git handle
            git_handle = GitHandle(repo.repo_path)

            # test commit
            test_commit_file = path.join(repo.repo_path, "test_commit")
            with open(test_commit_file, "w") as foo:
                foo.write("test commit")
            repo.repo.git.add(test_commit_file)
            repo.repo.git.commit("-m", "test commit")

            self.assertEqual(git_handle.get_head_hash(),
                             repo.repo.head.commit.hexsha)

        except Exception:
            raise

        finally:
            repo.delete()
Ejemplo n.º 8
0
    def test_default_install(self):
        try:
            # create a temporary directory to host the target repo
            tmp = TemporaryDirectory()

            # create a repo in the temporary directory
            repo = BasicRepo(path=tmp.name, bare=False)

            # run the installer
            pipe = Popen(["python", "install.py", repo.repo_path],
                         stdout=DEVNULL)
            _ = pipe.communicate()  # noqa

            # test exit code of installer
            self.assertEqual(pipe.returncode, 0)

            # test that the `pre_commit` subdirectory was created in
            # .git/hooks/
            self.assertTrue(
                path.isdir(
                    path.join(repo.repo_path, ".git", "hooks", "pre_commit")))

            # test that the `pre-commit` script was created in .git/hooks/
            self.assertTrue(
                path.exists(
                    path.join(repo.repo_path, ".git", "hooks", "pre-commit")))

            # test that all options are `True` in `linters.conf`
            parser = ConfigParser()
            parser.read(
                path.join(repo.repo_path, ".git", "hooks", "pre_commit",
                          "linters.conf"))

            self.assertTrue(
                all(
                    map(lambda lang: parser["linters"][lang] == "True",
                        parser["linters"])))

        except Exception:
            raise

        finally:
            tmp.cleanup()
Ejemplo n.º 9
0
    def test_uninstall(self):
        try:
            # install first
            # create a temporary directory to host the target repo
            tmp = TemporaryDirectory()

            # create a bare repo in the temporary directory
            repo = BasicRepo(path=tmp.name, bare=False)

            # run the installer
            pipe_inst = Popen(["python", "install.py", repo.repo_path],
                              stdout=DEVNULL)
            _ = pipe_inst.communicate()  # noqa

            # uninstall
            pipe_uninst = Popen([
                "python",
                path.join(repo.repo_path, ".git", "hooks", "pre_commit",
                          "uninstall.py")
            ],
                                stdout=DEVNULL)
            _ = pipe_uninst.communicate()  # noqa

            # test exit code of uninstaller
            self.assertEqual(pipe_uninst.returncode, 0)

            # test that there is no `pre_commit` subdirectory in .git/hooks/
            self.assertFalse(
                path.isdir(
                    path.join(repo.repo_path, ".git", "hooks", "pre_commit")))

            # test that there is no `pre-commit` script in .git/hooks/
            self.assertFalse(
                path.exists(
                    path.join(repo.repo_path, ".git", "hooks", "pre-commit")))

        except Exception:
            raise

        finally:
            tmp.cleanup()
Ejemplo n.º 10
0
    def test_selective_install(self):
        # this assumes that the installation is succesful as we already
        # check for that in `test_default_install`
        try:
            # create a temporary directory to host the target repo
            tmp = TemporaryDirectory()

            # create a repo in the temporary directory
            repo = BasicRepo(path=tmp.name, bare=False)

            # run the installer with selective installation of linters
            pipe = Popen(["python", "install.py", "-mp", repo.repo_path],
                         stdout=DEVNULL)
            _ = pipe.communicate()  # noqa

            # test that only the "markdown" and "python" options are `True` in
            # `linters.conf`
            parser = ConfigParser()
            parser.read(
                path.join(repo.repo_path, ".git", "hooks", "pre_commit",
                          "linters.conf"))

            md = parser["linters"]["markdown"]
            py = parser["linters"]["python"]

            # markdown and python on
            self.assertTrue(md)
            self.assertTrue(py)

            # all others off
            others = set(parser["linters"]) - {"markdown", "python"}
            self.assertFalse(
                any([parser["linters"][lang] == "True" for lang in others]))

        except Exception:
            raise

        finally:
            tmp.cleanup()
Ejemplo n.º 11
0
    def test_run(self):
        # test ability to execute `run` method with multiple linters when
        # only a subset of the files are staged;
        # also check that linting works for staged files that live in
        # subdirectories
        try:
            # initialize repo
            repo = BasicRepo(bare=False)

            # write a bad markdown file
            test_staged_file = path.join(repo.repo_path, "foo.md")
            w = Writer(test_staged_file)
            w.write("# Bad markdown")
            w.write("There should be an empty line before this!")
            w.write("Also, this is way too long" * 300)

            # write a bad R file
            test_staged_file1 = path.join(repo.repo_path, "bar.R")
            w1 = Writer(test_staged_file1)
            w1.write("# Bad R")
            w1.write("f=function(x) print( 'Hello' )")
            w1.write("a=5")

            # write a bad Python file
            test_staged_file2 = path.join(repo.repo_path, "foof.py")
            w2 = Writer(test_staged_file2)
            w2.write("# Bad Python")
            w2.write(" a=2")
            w2.write("from os import path")
            w2.write("a==2")

            # write another bad Python in a subdirectory
            subdir = path.join(repo.repo_path, "subdir")
            mkdir(subdir)
            test_staged_file3 = path.join(subdir, "fooffer.py")
            w3 = Writer(test_staged_file3)
            w3.write("# Bad Pyrhon")
            w3.write("# Wrong indentation")
            w3.write("class Foo(object):")
            w3.write("  pass")

            # stage these files
            repo.repo.git.add([
                test_staged_file, test_staged_file1, test_staged_file2,
                test_staged_file3
            ])

            # write another file which is problematic but not staged!
            test_non_staged_file = path.join(repo.repo_path, "lmao.py")
            w3 = Writer(test_non_staged_file)
            w3.write("# An unnecessary import")
            w3.write("from os import getcwd")
            w3.write("# A test on an undefined variable")
            w3.write("# And missing blank line at the end")
            w3.write("a==3", newline=False)

            # initialize a `GitHandle`
            git_handle = GitHandle(path=repo.repo_path)

            # initialize a `Lint` object
            ell = Lint(git_handle=git_handle,
                       linters=[MarkdownLinter(),
                                PythonLinter(),
                                RLinter()])

            # execute the main method of the  `Lint` object
            f = StringIO()
            with redirect_stdout(f):
                n_files_with_problems = ell.run()

            self.assertEqual(n_files_with_problems, 4)

        except Exception:
            raise

        finally:
            # clean up
            w.delete()
            w1.delete()
            w2.delete()
            w3.delete()
            repo.delete()
Ejemplo n.º 12
0
    def test_run_with_linters_config(self):
        # test ability to execute `run` method with multiple linters,
        # honoring the linters config files
        try:
            # initialize repo
            repo = BasicRepo(bare=False)

            # write a bad markdown file
            test_staged_file = path.join(repo.repo_path, "foo.md")
            w = Writer(test_staged_file)
            w.write("# Bad markdown")
            w.write("There should be an empty line before this!")

            # write the .markdownlint.json config file to ignore
            # "MD022/blanks-around-headers"
            md_config_file_path = path.join(repo.repo_path,
                                            ".markdownlint.json")
            w_md_conf = Writer(md_config_file_path)
            w_md_conf.write("{")
            w_md_conf.write('    "MD022": false')
            w_md_conf.write("}")

            # write a bad R file
            test_staged_file1 = path.join(repo.repo_path, "bar.R")
            w1 = Writer(test_staged_file1)
            w1.write("# Bad R")
            w1.write("f <- function(x) print('Hello')")

            # write the .lintr config file to ignore the "single_quotes_linter"
            r_config_file_path = path.join(repo.repo_path, ".lintr")
            w_r_conf = Writer(r_config_file_path)
            w_r_conf.write("linters: with_defaults(single_quotes_linter=NULL)")

            # write a bad Python file
            test_staged_file2 = path.join(repo.repo_path, "foof.py")
            w2 = Writer(test_staged_file2)
            w2.write("# Bad Python")
            w2.write("a=2")

            # write the `.flake8` config file instructing to
            # except "E225"
            py_config_file_path = path.join(repo.repo_path, ".flake8")
            w_py_conf = Writer(py_config_file_path)
            w_py_conf.write("[flake8]")
            w_py_conf.write("ignore = E225")

            # stage the files
            repo.repo.git.add(
                [test_staged_file, test_staged_file1, test_staged_file2])

            # initialize a `GitHandle`
            git_handle = GitHandle(path=repo.repo_path)

            # initialize a `Lint` object
            ell = Lint(git_handle=git_handle,
                       linters=[
                           MarkdownLinter(config_path=w_md_conf.path),
                           PythonLinter(config_path=w_py_conf.path),
                           RLinter(config_path=w_r_conf.path)
                       ])

            # execute the main method of the `Lint` object
            f = StringIO()
            with redirect_stdout(f):
                n_files_with_problems = ell.run()

            # all linting issues should be ignored
            self.assertEqual(n_files_with_problems, 0)

        except Exception:
            raise

        finally:
            # clean up
            w.delete()
            w_md_conf.delete()
            w1.delete()
            w_r_conf.delete()
            w2.delete()
            w_py_conf.delete()
            repo.delete()