1# Setup hook for pytest
2# shellcheck shell=bash
3
4echo "Sourcing pytest-check-hook"
5
6function _pytestIncludeExcludeExpr() {
7 local includeListName="$1"
8 local -n includeListRef="$includeListName"
9 local excludeListName="$2"
10 local -n excludeListRef="$excludeListName"
11 local includeString excludeString
12 if [[ -n "${includeListRef[*]-}" ]]; then
13 # ((element1) or (element2))
14 includeString="(($(concatStringsSep ") or (" "$includeListName")))"
15 fi
16 if [[ -n "${excludeListRef[*]-}" ]]; then
17 # and not (element1) and not (element2)
18 excludeString="${includeString:+ and }not ($(concatStringsSep ") and not (" "$excludeListName"))"
19 fi
20 echo "$includeString$excludeString"
21}
22
23function pytestCheckPhase() {
24 echo "Executing pytestCheckPhase"
25 runHook preCheck
26
27 # Compose arguments
28 local -a flagsArray=(-m pytest)
29
30 local -a _pathsArray
31 local path
32
33 _pathsArray=()
34 concatTo _pathsArray enabledTestPaths
35 for path in "${_pathsArray[@]}"; do
36 if [[ "$path" =~ "::" ]]; then
37 flagsArray+=("$path")
38 else
39 # The `|| kill "$$"` trick propagates the errors from the process substitutiton subshell,
40 # which is suggested by a StackOverflow answer: https://unix.stackexchange.com/a/217643
41 readarray -t -O"${#flagsArray[@]}" flagsArray < <(
42 @pythonCheckInterpreter@ - "$path" <<EOF || kill "$$"
43import glob
44import sys
45path_glob=sys.argv[1]
46if not len(path_glob):
47 sys.exit('Got an empty enabled tests path glob. Aborting')
48path_expanded = glob.glob(path_glob)
49if not len(path_expanded):
50 sys.exit('Enabled tests path glob "{}" does not match any paths. Aborting'.format(path_glob))
51for path in path_expanded:
52 print(path)
53EOF
54 )
55 fi
56 done
57
58 _pathsArray=()
59 concatTo _pathsArray disabledTestPaths
60 for path in "${_pathsArray[@]}"; do
61 if [[ "$path" =~ "::" ]]; then
62 flagsArray+=("--deselect=$path")
63 else
64 # Check if every path glob matches at least one path
65 @pythonCheckInterpreter@ - "$path" <<EOF
66import glob
67import sys
68path_glob=sys.argv[1]
69if not len(path_glob):
70 sys.exit('Got an empty disabled tests path glob. Aborting')
71if next(glob.iglob(path_glob), None) is None:
72 sys.exit('Disabled tests path glob "{}" does not match any paths. Aborting'.format(path_glob))
73EOF
74 flagsArray+=("--ignore-glob=$path")
75 fi
76 done
77
78 if [[ -n "${enabledTests[*]-}" ]] || [[ -n "${disabledTests[*]-}" ]]; then
79 flagsArray+=(-k "$(_pytestIncludeExcludeExpr enabledTests disabledTests)")
80 fi
81
82 if [[ -n "${enabledTestMarks[*]-}" ]] || [[ -n "${disabledTestMarks[*]-}" ]]; then
83 flagsArray+=(-m "$(_pytestIncludeExcludeExpr enabledTestMarks disabledTestMarks)")
84 fi
85
86 # Compatibility layer to the obsolete pytestFlagsArray
87 eval "flagsArray+=(${pytestFlagsArray[*]-})"
88
89 concatTo flagsArray pytestFlags
90 echoCmd 'pytest flags' "${flagsArray[@]}"
91 @pythonCheckInterpreter@ "${flagsArray[@]}"
92
93 runHook postCheck
94 echo "Finished executing pytestCheckPhase"
95}
96
97if [ -z "${dontUsePytestCheck-}" ] && [ -z "${installCheckPhase-}" ]; then
98 echo "Using pytestCheckPhase"
99 appendToVar preDistPhases pytestCheckPhase
100fi