Completed
Pull Request — master (#729)
by
unknown
01:09
created

test_empty_hooks()   A

Complexity

Conditions 4

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 4
c 2
b 0
f 0
dl 0
loc 16
rs 9.2
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
4
"""
5
test_generate_hooks
6
-------------------
7
8
Tests formerly known from a unittest residing in test_generate.py named
9
TestHooks.test_ignore_hooks_dirs
10
TestHooks.test_run_python_hooks
11
TestHooks.test_run_python_hooks_cwd
12
TestHooks.test_run_shell_hooks
13
"""
14
15
from __future__ import unicode_literals
16
import errno
17
import os
18
import sys
19
import stat
20
import pytest
21
22
from cookiecutter import generate
23
from cookiecutter import utils
24
from cookiecutter.exceptions import FailedHookException
25
26
27
@pytest.fixture(scope='function')
28
def remove_additional_folders(request):
29
    """
30
    Remove some special folders which are created by the tests.
31
    """
32
    def fin_remove_additional_folders():
33
        if os.path.exists('tests/test-pyhooks/inputpyhooks'):
34
            utils.rmtree('tests/test-pyhooks/inputpyhooks')
35
        if os.path.exists('inputpyhooks'):
36
            utils.rmtree('inputpyhooks')
37
        if os.path.exists('tests/test-shellhooks'):
38
            utils.rmtree('tests/test-shellhooks')
39
    request.addfinalizer(fin_remove_additional_folders)
40
41
42
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
43
def test_ignore_hooks_dirs():
44
    generate.generate_files(
45
        context={
46
            'cookiecutter': {'pyhooks': 'pyhooks'}
47
        },
48
        repo_dir='tests/test-pyhooks/',
49
        output_dir='tests/test-pyhooks/'
50
    )
51
    assert not os.path.exists('tests/test-pyhooks/inputpyhooks/hooks')
52
53
54
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
55
def test_run_python_hooks():
56
    generate.generate_files(
57
        context={
58
            'cookiecutter': {'pyhooks': 'pyhooks'}
59
        },
60
        repo_dir='tests/test-pyhooks/'.replace("/", os.sep),
61
        output_dir='tests/test-pyhooks/'.replace("/", os.sep)
62
    )
63
    assert os.path.exists('tests/test-pyhooks/inputpyhooks/python_pre.txt')
64
    assert os.path.exists('tests/test-pyhooks/inputpyhooks/python_post.txt')
65
66
67
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
68
def test_run_python_hooks_cwd():
69
    generate.generate_files(
70
        context={
71
            'cookiecutter': {'pyhooks': 'pyhooks'}
72
        },
73
        repo_dir='tests/test-pyhooks/'
74
    )
75
    assert os.path.exists('inputpyhooks/python_pre.txt')
76
    assert os.path.exists('inputpyhooks/python_post.txt')
77
78
79
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
80
def test_empty_hooks():
81
82
    # OSError.errno=8 is not thrown on Windows when the script is emtpy
83
    # because it always runs through shell instead of needing a shebang.
84
85
    if not sys.platform.startswith('win'):
86
        with pytest.raises(FailedHookException) as excinfo:
87
            generate.generate_files(
88
                context={
89
                    'cookiecutter': {'shellhooks': 'shellhooks'}
90
                },
91
                repo_dir='tests/test-shellhooks-empty/',
92
                overwrite_if_exists=True
93
            )
94
        assert 'shebang' in str(excinfo.value)
95
96
97
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
98
def test_oserror_hooks(mocker):
99
100
    message = 'Out of memory'
101
102
    err = OSError(message)
103
    err.errno = errno.ENOMEM
104
105
    prompt = mocker.patch('subprocess.Popen')
106
    prompt.side_effect = err
107
108
    with pytest.raises(FailedHookException) as excinfo:
109
        generate.generate_files(
110
            context={
111
                'cookiecutter': {'shellhooks': 'shellhooks'}
112
            },
113
            repo_dir='tests/test-shellhooks-empty/',
114
            overwrite_if_exists=True
115
        )
116
    assert message in str(excinfo.value)
117
118
119
def make_test_repo(name):
120
    hooks = os.path.join(name, 'hooks')
121
    template = os.path.join(name, 'input{{cookiecutter.shellhooks}}')
122
    os.mkdir(name)
123
    os.mkdir(hooks)
124
    os.mkdir(template)
125
126
    with open(os.path.join(template, 'README.rst'), 'w') as f:
127
        f.write("foo\n===\n\nbar\n")
128
129
    if sys.platform.startswith('win'):
130
        filename = os.path.join(hooks, 'pre_gen_project.bat')
131
        with open(filename, 'w') as f:
132
            f.write("@echo off\n")
133
            f.write("\n")
134
            f.write("echo pre generation hook\n")
135
            f.write("echo. >shell_pre.txt\n")
136
137
        filename = os.path.join(hooks, 'post_gen_project.bat')
138
        with open(filename, 'w') as f:
139
            f.write("@echo off\n")
140
            f.write("\n")
141
            f.write("echo post generation hook\n")
142
            f.write("echo. >shell_post.txt\n")
143
    else:
144
        filename = os.path.join(hooks, 'pre_gen_project.sh')
145
        with open(filename, 'w') as f:
146
            f.write("#!/bin/bash\n")
147
            f.write("\n")
148
            f.write("echo 'pre generation hook';\n")
149
            f.write("touch 'shell_pre.txt'\n")
150
        # Set the execute bit
151
        os.chmod(filename, os.stat(filename).st_mode | stat.S_IXUSR)
152
153
        filename = os.path.join(hooks, 'post_gen_project.sh')
154
        with open(filename, 'w') as f:
155
            f.write("#!/bin/bash\n")
156
            f.write("\n")
157
            f.write("echo 'post generation hook';\n")
158
            f.write("touch 'shell_post.txt'\n")
159
        # Set the execute bit
160
        os.chmod(filename, os.stat(filename).st_mode | stat.S_IXUSR)
161
162
163
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
164
def test_run_shell_hooks():
165
    make_test_repo('tests/test-shellhooks')
166
    generate.generate_files(
167
        context={
168
            'cookiecutter': {'shellhooks': 'shellhooks'}
169
        },
170
        repo_dir='tests/test-shellhooks/',
171
        output_dir='tests/test-shellhooks/'
172
    )
173
    shell_pre_file = 'tests/test-shellhooks/inputshellhooks/shell_pre.txt'
174
    shell_post_file = 'tests/test-shellhooks/inputshellhooks/shell_post.txt'
175
    assert os.path.exists(shell_pre_file)
176
    assert os.path.exists(shell_post_file)
177