Completed
Pull Request — master (#623)
by
unknown
57s
created

tests.TestExternalHooks   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 94
Duplicated Lines 0 %
Metric Value
wmc 28
dl 0
loc 94
rs 10
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
4
"""
5
test_hooks
6
------------
7
8
Tests for `cookiecutter.hooks` module.
9
"""
10
11
import sys
12
13
import os
14
import pytest
15
import stat
16
17
from cookiecutter import hooks, utils
18
19
20
def make_test_repo(name):
21
    """Helper function which is called in the test setup methods."""
22
    hook_dir = os.path.join(name, 'hooks')
23
    template = os.path.join(name, 'input{{hooks}}')
24
    os.mkdir(name)
25
    os.mkdir(hook_dir)
26
    os.mkdir(template)
27
28
    with open(os.path.join(template, 'README.rst'), 'w') as f:
29
        f.write("foo\n===\n\nbar\n")
30
31
    with open(os.path.join(hook_dir, 'pre_gen_project.py'), 'w') as f:
32
        f.write("#!/usr/bin/env python\n")
33
        f.write("# -*- coding: utf-8 -*-\n")
34
        f.write("from __future__ import print_function\n")
35
        f.write("\n")
36
        f.write("print('pre generation hook')\n")
37
        f.write("f = open('python_pre.txt', 'w')\n")
38
        f.write("f.close()\n")
39
40
    if sys.platform.startswith('win'):
41
        post = 'post_gen_project.bat'
42
        with open(os.path.join(hook_dir, post), 'w') as f:
43
            f.write("@echo off\n")
44
            f.write("\n")
45
            f.write("echo post generation hook\n")
46
            f.write("echo. >shell_post.txt\n")
47
    else:
48
        post = 'post_gen_project.sh'
49
        filename = os.path.join(hook_dir, post)
50
        with open(filename, 'w') as f:
51
            f.write("#!/bin/bash\n")
52
            f.write("\n")
53
            f.write("echo 'post generation hook';\n")
54
            f.write("touch 'shell_post.txt'\n")
55
        # Set the execute bit
56
        os.chmod(filename, os.stat(filename).st_mode | stat.S_IXUSR)
57
58
    return post
59
60
61
@pytest.mark.xfail
62
class TestFindHooks(object):
63
    repo_path = 'tests/test-hooks'
64
65
    def setup_method(self, method):
66
        self.post_hook = make_test_repo(self.repo_path)
67
68
    def teardown_method(self, method):
69
        utils.rmtree(self.repo_path)
70
71
    @pytest.mark.xfail
72
    def test_find_hook(self):
73
        """Finds the specified hook."""
74
75
        with utils.work_in(self.repo_path):
76
            expected = {
77
                'pre_gen_project': os.path.abspath('hooks/pre_gen_project.py'),
78
                'post_gen_project': os.path.abspath(
79
                    os.path.join('hooks', self.post_hook)
80
                )
81
            }
82
            assert expected == hooks.find_hooks()
83
84
    @pytest.mark.xfail
85
    def test_no_hooks(self):
86
        """find_hooks should return None if the hook could not be found."""
87
88
        with utils.work_in('tests/fake-repo'):
89
            assert {} == hooks.find_hooks()
90
91
# class TestExternalHooks(object):
92
#
93
#     repo_path = os.path.abspath('tests/test-hooks/')
94
#     hooks_path = os.path.abspath('tests/test-hooks/hooks')
95
#
96
#     @pytest.mark.xfail
97
#     def setup_method(self, method):
98
#         self.post_hook = make_test_repo(self.repo_path)
99
#
100
#     @pytest.mark.xfail
101
#     def teardown_method(self, method):
102
#         utils.rmtree(self.repo_path)
103
#
104
#         if os.path.exists('python_pre.txt'):
105
#             os.remove('python_pre.txt')
106
#         if os.path.exists('shell_post.txt'):
107
#             os.remove('shell_post.txt')
108
#         if os.path.exists('tests/shell_post.txt'):
109
#             os.remove('tests/shell_post.txt')
110
#         if os.path.exists('tests/test-hooks/input{{hooks}}/python_pre.txt'):
111
#             os.remove('tests/test-hooks/input{{hooks}}/python_pre.txt')
112
#         if os.path.exists('tests/test-hooks/input{{hooks}}/shell_post.txt'):
113
#             os.remove('tests/test-hooks/input{{hooks}}/shell_post.txt')
114
#         if os.path.exists('tests/context_post.txt'):
115
#             os.remove('tests/context_post.txt')
116
#
117
#     @pytest.mark.xfail
118
#     def test_run_script(self):
119
#         """Execute a hook script, independently of project generation"""
120
#         hooks.run_script(os.path.join(self.hooks_path, self.post_hook))
121
#         assert os.path.isfile('shell_post.txt')
122
#
123
#     @pytest.mark.xfail
124
#     def test_run_script_cwd(self):
125
#         """Change directory before running hook"""
126
#         hooks.run_script(
127
#             os.path.join(self.hooks_path, self.post_hook),
128
#             'tests'
129
#         )
130
#         assert os.path.isfile('tests/shell_post.txt')
131
#         assert 'tests' not in os.getcwd()
132
#
133
#     @pytest.mark.xfail
134
#     def test_run_script_with_context(self):
135
#         """Execute a hook script, passing a context"""
136
#
137
#         hook_path = os.path.join(self.hooks_path, 'post_gen_project.sh')
138
#
139
#         if sys.platform.startswith('win'):
140
#             post = 'post_gen_project.bat'
141
#             with open(os.path.join(self.hooks_path, post), 'w') as f:
142
#                 f.write("@echo off\n")
143
#                 f.write("\n")
144
#                 f.write("echo post generation hook\n")
145
#                 f.write("echo. >{{cookiecutter.file}}\n")
146
#         else:
147
#             with open(hook_path, 'w') as fh:
148
#                 fh.write("#!/bin/bash\n")
149
#                 fh.write("\n")
150
#                 fh.write("echo 'post generation hook';\n")
151
#                 fh.write("touch 'shell_post.txt'\n")
152
#                 fh.write("touch '{{cookiecutter.file}}'\n")
153
#                 os.chmod(
154
#                       hook_path, os.stat(hook_path).st_mode | stat.S_IXUSR
155
#                   )
156
#
157
#         hooks.run_script_with_context(
158
#             os.path.join(self.hooks_path, self.post_hook),
159
#             'tests',
160
#             {
161
#                 'cookiecutter': {
162
#                     'file': 'context_post.txt'
163
#                 }
164
#             })
165
#         assert os.path.isfile('tests/context_post.txt')
166
#         assert 'tests' not in os.getcwd()
167
#
168
#     @pytest.mark.xfail
169
#     def test_run_hook(self):
170
#         """Execute hook from specified template in specified output
171
#         directory.
172
#         """
173
#         tests_dir = os.path.join(self.repo_path, 'input{{hooks}}')
174
#         with utils.work_in(self.repo_path):
175
#             hooks.run_hook('pre_gen_project', tests_dir, {})
176
#             assert os.path.isfile(os.path.join(tests_dir, 'python_pre.txt'))
177
#
178
#             hooks.run_hook('post_gen_project', tests_dir, {})
179
#             assert os.path.isfile(os.path.join(tests_dir, 'shell_post.txt'))
180
#
181
#     @pytest.mark.xfail
182
#     def test_run_failing_hook(self):
183
#         hook_path = os.path.join(self.hooks_path, 'pre_gen_project.py')
184
#         tests_dir = os.path.join(self.repo_path, 'input{{hooks}}')
185
#
186
#         with open(hook_path, 'w') as f:
187
#             f.write("#!/usr/bin/env python\n")
188
#             f.write("import sys; sys.exit(1)\n")
189
#
190
#         with utils.work_in(self.repo_path):
191
#             with pytest.raises(exceptions.FailedHookException) as excinfo:
192
#                 hooks.run_hook('pre_gen_project', tests_dir, {})
193
#             assert 'Hook script failed' in str(excinfo.value)
194