1
+ import os
2
+ import sys
3
+
1
4
import pytest
2
5
6
+ from pre_commit_hooks import check_executables_have_shebangs
3
7
from pre_commit_hooks .check_executables_have_shebangs import main
8
+ from pre_commit_hooks .util import cmd_output
9
+
10
+ skip_win32 = pytest .mark .skipif (
11
+ sys .platform == 'win32' ,
12
+ reason = "non-git checks aren't relevant on windows" ,
13
+ )
4
14
5
15
16
+ @skip_win32 # pragma: win32 no cover
6
17
@pytest .mark .parametrize (
7
18
'content' , (
8
19
b'#!/bin/bash\n hello world\n ' ,
@@ -17,14 +28,14 @@ def test_has_shebang(content, tmpdir):
17
28
assert main ((path .strpath ,)) == 0
18
29
19
30
31
+ @skip_win32 # pragma: win32 no cover
20
32
@pytest .mark .parametrize (
21
33
'content' , (
22
34
b'' ,
23
35
b' #!python\n ' ,
24
36
b'\n #!python\n ' ,
25
37
b'python\n ' ,
26
38
'☃' .encode (),
27
-
28
39
),
29
40
)
30
41
def test_bad_shebang (content , tmpdir , capsys ):
@@ -33,3 +44,67 @@ def test_bad_shebang(content, tmpdir, capsys):
33
44
assert main ((path .strpath ,)) == 1
34
45
_ , stderr = capsys .readouterr ()
35
46
assert stderr .startswith (f'{ path } : marked executable but' )
47
+
48
+
49
+ def test_check_git_filemode_passing (tmpdir ):
50
+ with tmpdir .as_cwd ():
51
+ cmd_output ('git' , 'init' , '.' )
52
+
53
+ f = tmpdir .join ('f' )
54
+ f .write ('#!/usr/bin/env bash' )
55
+ f_path = str (f )
56
+ cmd_output ('chmod' , '+x' , f_path )
57
+ cmd_output ('git' , 'add' , f_path )
58
+ cmd_output ('git' , 'update-index' , '--chmod=+x' , f_path )
59
+
60
+ g = tmpdir .join ('g' ).ensure ()
61
+ g_path = str (g )
62
+ cmd_output ('git' , 'add' , g_path )
63
+
64
+ # this is potentially a problem, but not something the script intends
65
+ # to check for -- we're only making sure that things that are
66
+ # executable have shebangs
67
+ h = tmpdir .join ('h' )
68
+ h .write ('#!/usr/bin/env bash' )
69
+ h_path = str (h )
70
+ cmd_output ('git' , 'add' , h_path )
71
+
72
+ files = (f_path , g_path , h_path )
73
+ assert check_executables_have_shebangs ._check_git_filemode (files ) == 0
74
+
75
+
76
+ def test_check_git_filemode_failing (tmpdir ):
77
+ with tmpdir .as_cwd ():
78
+ cmd_output ('git' , 'init' , '.' )
79
+
80
+ f = tmpdir .join ('f' ).ensure ()
81
+ f_path = str (f )
82
+ cmd_output ('chmod' , '+x' , f_path )
83
+ cmd_output ('git' , 'add' , f_path )
84
+ cmd_output ('git' , 'update-index' , '--chmod=+x' , f_path )
85
+
86
+ files = (f_path ,)
87
+ assert check_executables_have_shebangs ._check_git_filemode (files ) == 1
88
+
89
+
90
+ @pytest .mark .parametrize (
91
+ ('content' , 'mode' , 'expected' ),
92
+ (
93
+ pytest .param ('#!python' , '+x' , 0 , id = 'shebang with executable' ),
94
+ pytest .param ('#!python' , '-x' , 0 , id = 'shebang without executable' ),
95
+ pytest .param ('' , '+x' , 1 , id = 'no shebang with executable' ),
96
+ pytest .param ('' , '-x' , 0 , id = 'no shebang without executable' ),
97
+ ),
98
+ )
99
+ def test_git_executable_shebang (temp_git_dir , content , mode , expected ):
100
+ with temp_git_dir .as_cwd ():
101
+ path = temp_git_dir .join ('path' )
102
+ path .write (content )
103
+ cmd_output ('git' , 'add' , str (path ))
104
+ cmd_output ('chmod' , mode , str (path ))
105
+ cmd_output ('git' , 'update-index' , f'--chmod={ mode } ' , str (path ))
106
+
107
+ # simulate how identify choses that something is executable
108
+ filenames = [path for path in [str (path )] if os .access (path , os .X_OK )]
109
+
110
+ assert main (filenames ) == expected
0 commit comments