Completed
Push — master ( c7ac89...94f163 )
by
unknown
01:00
created

test_oserror_hooks()   A

Complexity

Conditions 3

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

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