summaryrefslogtreecommitdiff
path: root/pkgs/development/interpreters/python/hooks/pytest-check-hook.sh
blob: 84643a3b50ca75280c2d9985fdb2d40b915131b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# Setup hook for pytest
# shellcheck shell=bash

echo "Sourcing pytest-check-hook"

function _pytestIncludeExcludeExpr() {
    local includeListName="$1"
    local -n includeListRef="$includeListName"
    local excludeListName="$2"
    local -n excludeListRef="$excludeListName"
    local includeString excludeString
    if [[ -n "${includeListRef[*]-}" ]]; then
        # ((element1) or (element2))
        includeString="(($(concatStringsSep ") or (" "$includeListName")))"
    fi
    if [[ -n "${excludeListRef[*]-}" ]]; then
        # and not (element1) and not (element2)
        excludeString="${includeString:+ and }not ($(concatStringsSep ") and not (" "$excludeListName"))"
    fi
    echo "$includeString$excludeString"
}

function pytestCheckPhase() {
    echo "Executing pytestCheckPhase"
    runHook preCheck

    # Compose arguments
    local -a flagsArray=(-m pytest)

    local -a _pathsArray
    local path

    _pathsArray=()
    concatTo _pathsArray enabledTestPaths
    for path in "${_pathsArray[@]}"; do
        if [[ "$path" =~ "::" ]]; then
            flagsArray+=("$path")
        else
            # The `|| kill "$$"` trick propagates the errors from the process substitutiton subshell,
            # which is suggested by a StackOverflow answer: https://unix.stackexchange.com/a/217643
            readarray -t -O"${#flagsArray[@]}" flagsArray < <(
                @pythonCheckInterpreter@ - "$path" <<EOF || kill "$$"
import glob
import sys
path_glob=sys.argv[1]
if not len(path_glob):
    sys.exit('Got an empty enabled tests path glob. Aborting')
path_expanded = glob.glob(path_glob)
if not len(path_expanded):
    sys.exit('Enabled tests path glob "{}" does not match any paths. Aborting'.format(path_glob))
for path in path_expanded:
    print(path)
EOF
            )
        fi
    done

    _pathsArray=()
    concatTo _pathsArray disabledTestPaths
    for path in "${_pathsArray[@]}"; do
        if [[ "$path" =~ "::" ]]; then
            flagsArray+=("--deselect=$path")
        else
            # Check if every path glob matches at least one path
            @pythonCheckInterpreter@ - "$path" <<EOF
import glob
import sys
path_glob=sys.argv[1]
if not len(path_glob):
    sys.exit('Got an empty disabled tests path glob. Aborting')
if next(glob.iglob(path_glob), None) is None:
    sys.exit('Disabled tests path glob "{}" does not match any paths. Aborting'.format(path_glob))
EOF
            flagsArray+=("--ignore-glob=$path")
        fi
    done

    if [[ -n "${enabledTests[*]-}" ]] || [[ -n "${disabledTests[*]-}" ]]; then
        flagsArray+=(-k "$(_pytestIncludeExcludeExpr enabledTests disabledTests)")
    fi

    if [[ -n "${enabledTestMarks[*]-}" ]] || [[ -n "${disabledTestMarks[*]-}" ]]; then
        flagsArray+=(-m "$(_pytestIncludeExcludeExpr enabledTestMarks disabledTestMarks)")
    fi

    # Compatibility layer to the obsolete pytestFlagsArray
    eval "flagsArray+=(${pytestFlagsArray[*]-})"

    concatTo flagsArray pytestFlags
    echoCmd 'pytest flags' "${flagsArray[@]}"
    @pythonCheckInterpreter@ "${flagsArray[@]}"

    runHook postCheck
    echo "Finished executing pytestCheckPhase"
}

if [ -z "${dontUsePytestCheck-}" ] && [ -z "${installCheckPhase-}" ]; then
    echo "Using pytestCheckPhase"
    appendToVar preDistPhases pytestCheckPhase
fi