-
Notifications
You must be signed in to change notification settings - Fork 102
/
git-prompt-test.sh
executable file
·282 lines (243 loc) · 6.25 KB
/
git-prompt-test.sh
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
#!/usr/bin/env bash
set -e
OPTS=$(getopt --options= --longoptions=use-existing-fixtures -n "$0" -- "$@")
if [ $? -ne 0 ]; then
exit 1
fi
eval set -- "$OPTS"
unset OPTS
while true; do
case "$1" in
--use-existing-fixtures)
readonly USE_EXISTING_FIXTURES=true
shift
continue
;;
--)
shift
break
;;
esac
done
readonly PS=$(readlink -f tmp/powershell/pwsh)
readonly SRC_DIR=$(readlink -f .)
readonly POSH_GIT_DIR=$(readlink -f tmp/posh-git)
readonly TEST_SCRATCH_DIR=$(readlink -f tmp/test-scratch)
if [ -n "$USE_EXISTING_FIXTURES" ]; then
echo -e "\e[33m[ WARN ] using preexisting test fixtures\e[0m"
else
rm -rf $TEST_SCRATCH_DIR
fi
DIFF_FLAGS=
case "$-i" in
*i*) if [ -z "$TRAVIS" ]; then
DIFF_FLAGS=--color=auto
fi ;;
*) ;;
esac
readonly DIFF_FLAGS
mkdir -p $TEST_SCRATCH_DIR
set +e
# Captures the posh command prompt for posh-git-sh and posh-git.
#
# Input:
# * the working directory is the git repository under test
#
# Output:
# * ../posh-sh
# * ../posh-ps
run_poshes() {
# Show posh-git-sh PS1. We can't use __posh_git_echo directly because its
# output includes prompt escape sequences that need to be interpreted by bash.
bash &> ../posh-sh-unfiltered -i <<EOF
PS1=
source $SRC_DIR/git-prompt.sh
__posh_git_ps1 ===TEST=== ===TEST=== '' ''
EOF
# Extract posh-git-sh PS1. Ignore the line where we actually make the call to
# __posh_git_ps1. The next line, which calls "exit", will have the updated PS1.
grep -v __posh_git_ps1 < ../posh-sh-unfiltered | sed -n 's/.*===TEST===\(.*\)===TEST===.*/\1/p' > ../posh-sh
bash > ../posh-ps <<EOF
$PS -Command '& {
Import-Module $POSH_GIT_DIR/src/posh-git.psd1
# Suppress leading space.
\$GitPromptSettings.DefaultPromptWriteStatusFirst = \$true
Write-VcsStatus
}'
EOF
}
# Strips ANSI colors from the input file.
#
# Input:
# [1] the file
strip_ansi_colors() {
sed 's/\x1B\[[0-9;]*[a-zA-Z]//g' "$1"
}
# Verifies that the files are equivalent, ignoring ANSI colors.
#
# Inputs:
# [1] $FILE1
# [2] $FILE2
# [3] (optional) label to give to $FILE1 in diff output
#
# Outputs:
# * $FILE1-nocolor
# * $FILE2-nocolor
test_poshes_ignoring_color() {
local expected=$1
local actual=$2
local expected_out
if [ -z "$3" ]; then
expected_out=$expected-nocolor
else
expected_out=$3-nocolor
fi
local actual_out=$actual-nocolor
strip_ansi_colors "$expected" > "$expected_out"
strip_ansi_colors "$actual" > "$actual_out"
diff -u --label="$expected_out" "$expected_out" --label="$actual_out" "$actual_out" $DIFF_FLAGS
}
PASSING=0
PASSING_WARNING=0
FAILING=0
FAILING_WARNING=0
# Tests posh outputs with a specified setup function to create the git
# repository under test. Does not execute the setup function if it already
# ran. In other words, if you change the test setup, you need to delete
# $testcase/git_setup_complete.
#
# Inputs:
# [1] function to set up a git repository test fixture. git init is already
# called in the working directory
#
# Outputs:
# * modifies PASSING
# * modifies FAILING
run_test() {
internal_run_test "$1" posh-ps posh-sh
}
# Like run_test, but compares against an expected string instead of against
# posh-ps.
#
# Inputs:
# [1] function to set up the git repository test fixture
# [2] the expected string
run_test_known_diff() {
internal_run_test "$1" "$2" posh-sh 'overridden-expectation'
}
internal_run_test() {
local git_setup_fn=$1
local expected=$2
local actual=$3
local expected_alternate_name=$4
local testcase=$git_setup_fn
echo '[ RUN ] '$testcase
mkdir -p $TEST_SCRATCH_DIR/$testcase
cd $TEST_SCRATCH_DIR/$testcase
if [ -f git_setup_complete ]; then
cd git
else
rm -rf git/
mkdir git
cd git
git init &>/dev/null
$git_setup_fn &>/dev/null
touch ../git_setup_complete
fi
run_poshes
cd ..
[ -n "$expected_alternate_name" ]
local overridden=$?
if (( $overridden == 0 )); then
echo -e "\e[33m[ WARN ] expectation override: $expected (while posh-ps is $(strip_ansi_colors posh-ps))\e[0m"
test_poshes_ignoring_color <(echo $expected) "$actual" "$expected_alternate_name"
else
test_poshes_ignoring_color "$expected" "$actual"
fi
local t=$?
if (( $t == 0 )); then
echo -e "\e[32m[ PASS ] $testcase\e[0m"
(( PASSING++ ))
if (( $overridden == 0 )); then
(( PASSING_WARNING++ ))
fi
else
echo -e "\e[31m[ FAIL ] $testcase\e[0m"
(( FAILING++ ))
if (( $overridden == 0 )); then
(( FAILING_WARNING++ ))
fi
fi
}
empty() {
:
}
run_test_known_diff empty '[master ?]'
one_file_unstaged() {
touch stuff
}
run_test_known_diff one_file_unstaged '[master ? +1 ~0 -0 !]'
one_file_staged() {
touch stuff
git add stuff
}
run_test_known_diff one_file_staged '[master ? +1 ~0 -0 ~]'
one_file_staged_with_unstaged_edit() {
touch stuff
git add stuff
echo stuff > stuff
}
run_test_known_diff one_file_staged_with_unstaged_edit '[master ? +1 ~0 -0 | +0 ~1 -0 !]'
one_file_typechange() {
touch file_or_link
touch target
git add .
git commit -m 'first commit'
rm file_or_link
ln -s target file_or_link
}
run_test_known_diff one_file_typechange '[master ? +0 ~1 -0 !]'
one_file_stashed() {
touch stuff
git add .
git commit -m 'initial commit'
touch more_stuff
git add .
git stash
}
run_test_known_diff one_file_stashed '[master ? (1)]'
# +1 ~1 -1 | +1 ~1 -1
added_edited_deleted_staged_and_unstaged() {
echo added > added
echo edited > edited
echo delete_me_1 > delete_me_1
echo delete_me_2 > delete_me_2
git add .
git commit -m 'stage four files'
# staged add
touch newly_added
git add newly_added
# unstaged add
touch unstaged_add
# staged edit
echo edit > edited
git add edited
# unstaged edit
echo edited again > edited
# staged delete
git rm delete_me_1
# unstaged delete
rm delete_me_2
}
run_test_known_diff added_edited_deleted_staged_and_unstaged '[master ? +1 ~1 -1 | +1 ~1 -1 !]'
# Test summary
if (( $PASSING_WARNING > 0 || $FAILING_WARNING > 0)); then
echo -e "\e[33mWARN: $PASSING_WARNING tests passed with warnings, $FAILING_WARNING tests failed with warnings\e[0m"
fi
if (( $FAILING > 0 )); then
echo -e "\e[31mFAIL: $PASSING tests passed, $FAILING tests failed\e[0m"
exit 1
else
echo -e "\e[32mPASS: $PASSING tests passed, $FAILING tests failed\e[0m"
exit 0
fi