-
-
Notifications
You must be signed in to change notification settings - Fork 767
Expand file tree
/
Copy pathrun_vader_tests_direct.sh
More file actions
executable file
·370 lines (319 loc) · 11.1 KB
/
run_vader_tests_direct.sh
File metadata and controls
executable file
·370 lines (319 loc) · 11.1 KB
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
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
#!/bin/bash
# Direct CI Test Runner - Runs Vader tests without Docker
# This script is designed to run in GitHub Actions CI environment
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
log_info() {
echo -e "${BLUE}[INFO]${NC} $*"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $*"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $*"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $*"
}
# Get script directory and project root
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
cd "${PROJECT_ROOT}"
log_info "Project root: ${PROJECT_ROOT}"
log_info "Python version: $(python3 --version 2>&1 || echo 'not available')"
log_info "Vim version: $(vim --version | head -1 || echo 'not available')"
# Check prerequisites
if ! command -v vim &> /dev/null; then
log_error "Vim is not installed"
exit 1
fi
if ! command -v python3 &> /dev/null; then
log_error "Python3 is not installed"
exit 1
fi
# Set up Vim runtime paths
VIM_HOME="${HOME}/.vim"
VADER_DIR="${VIM_HOME}/pack/vader/start/vader.vim"
PYMODE_DIR="${PROJECT_ROOT}"
# Install Vader.vim if not present
if [ ! -d "${VADER_DIR}" ]; then
log_info "Installing Vader.vim..."
mkdir -p "$(dirname "${VADER_DIR}")"
git clone --depth 1 https://github.com/junegunn/vader.vim.git "${VADER_DIR}" || {
log_error "Failed to install Vader.vim"
exit 1
}
log_success "Vader.vim installed"
else
log_info "Vader.vim already installed"
fi
# Create a CI-specific vimrc
CI_VIMRC="${PROJECT_ROOT}/tests/utils/vimrc.ci"
VIM_HOME_ESC=$(echo "${VIM_HOME}" | sed 's/\//\\\//g')
PROJECT_ROOT_ESC=$(echo "${PROJECT_ROOT}" | sed 's/\//\\\//g')
cat > "${CI_VIMRC}" << EOFVIMRC
" CI-specific vimrc for direct test execution
set nocompatible
set nomore
set shortmess=at
set cmdheight=10
set backupdir=
set directory=
set undodir=
set viewdir=
set noswapfile
set paste
set shell=bash
" Enable magic for motion support (required for text object mappings)
set magic
" Enable filetype detection
filetype plugin indent on
syntax on
" Set up runtimepath for CI environment
let s:vim_home = '${VIM_HOME_ESC}'
let s:project_root = '${PROJECT_ROOT_ESC}'
" Add Vader.vim to runtimepath
execute 'set rtp+=' . s:vim_home . '/pack/vader/start/vader.vim'
" Add python-mode to runtimepath
execute 'set rtp+=' . s:project_root
" Load python-mode configuration FIRST to set g:pymode_rope = 1
" This ensures the plugin will define all rope variables when it loads
if filereadable(s:project_root . '/tests/utils/pymoderc')
execute 'source ' . s:project_root . '/tests/utils/pymoderc'
endif
" Load python-mode plugin AFTER pymoderc so it sees rope is enabled
" and defines all rope configuration variables
runtime plugin/pymode.vim
" Ensure rope variables exist even if rope gets disabled later
" The plugin only defines these when g:pymode_rope is enabled,
" but tests expect them to exist even when rope is disabled
if !exists('g:pymode_rope_completion')
let g:pymode_rope_completion = 1
endif
if !exists('g:pymode_rope_autoimport_import_after_complete')
let g:pymode_rope_autoimport_import_after_complete = 0
endif
if !exists('g:pymode_rope_regenerate_on_write')
let g:pymode_rope_regenerate_on_write = 1
endif
if !exists('g:pymode_rope_goto_definition_bind')
let g:pymode_rope_goto_definition_bind = '<C-c>g'
endif
if !exists('g:pymode_rope_rename_bind')
let g:pymode_rope_rename_bind = '<C-c>rr'
endif
if !exists('g:pymode_rope_extract_method_bind')
let g:pymode_rope_extract_method_bind = '<C-c>rm'
endif
if !exists('g:pymode_rope_organize_imports_bind')
let g:pymode_rope_organize_imports_bind = '<C-c>ro'
endif
" Note: Tests will initialize python-mode via tests/vader/setup.vim
" which is sourced in each test's "Before" block. The setup.vim may
" disable rope (g:pymode_rope = 0), but the config variables will
" still exist because they were defined above.
EOFVIMRC
log_info "Created CI vimrc at ${CI_VIMRC}"
# Find test files
TEST_FILES=()
if [[ -d "tests/vader" ]]; then
mapfile -t TEST_FILES < <(find tests/vader -name "*.vader" -type f | sort)
fi
if [[ ${#TEST_FILES[@]} -eq 0 ]]; then
log_error "No Vader test files found in tests/vader/"
exit 1
fi
log_info "Found ${#TEST_FILES[@]} test file(s)"
# Run tests
FAILED_TESTS=()
PASSED_TESTS=()
TOTAL_ASSERTIONS=0
PASSED_ASSERTIONS=0
for test_file in "${TEST_FILES[@]}"; do
test_name=$(basename "$test_file" .vader)
log_info "Running test: ${test_name}"
# Use absolute path for test file
TEST_FILE_ABS="${PROJECT_ROOT}/${test_file}"
if [ ! -f "${TEST_FILE_ABS}" ]; then
log_error "Test file not found: ${TEST_FILE_ABS}"
FAILED_TESTS+=("${test_name}")
continue
fi
# Create output file for this test
VIM_OUTPUT_FILE=$(mktemp)
# Run Vader test
set +e # Don't exit on error, we'll check exit code
timeout 120 vim \
--not-a-term \
-es \
-i NONE \
-u "${CI_VIMRC}" \
-c "Vader! ${TEST_FILE_ABS}" \
-c "qa!" \
< /dev/null > "${VIM_OUTPUT_FILE}" 2>&1
EXIT_CODE=$?
set -e
OUTPUT=$(cat "${VIM_OUTPUT_FILE}" 2>/dev/null || echo "")
rm -f "${VIM_OUTPUT_FILE}"
# Check for timeout
if [ "${EXIT_CODE}" -eq 124 ]; then
log_error "Test timed out: ${test_name} (exceeded 120s timeout)"
FAILED_TESTS+=("${test_name}")
continue
fi
# Parse Vader output for success/failure
if echo "${OUTPUT}" | grep -qiE "Success/Total:"; then
# Extract success/total counts
SUCCESS_LINE=$(echo "${OUTPUT}" | grep -iE "Success/Total:" | tail -1)
TOTAL_TESTS=$(echo "${SUCCESS_LINE}" | sed -nE 's/.*Success\/Total:[^0-9]*([0-9]+)\/([0-9]+).*/\2/p')
PASSED_COUNT=$(echo "${SUCCESS_LINE}" | sed -nE 's/.*Success\/Total:[^0-9]*([0-9]+)\/([0-9]+).*/\1/p')
# Extract assertion counts if available
if echo "${OUTPUT}" | grep -qiE "assertions:"; then
ASSERT_LINE=$(echo "${OUTPUT}" | grep -iE "assertions:" | tail -1)
ASSERT_TOTAL=$(echo "${ASSERT_LINE}" | sed -nE 's/.*assertions:[^0-9]*([0-9]+)\/([0-9]+).*/\2/p')
ASSERT_PASSED=$(echo "${ASSERT_LINE}" | sed -nE 's/.*assertions:[^0-9]*([0-9]+)\/([0-9]+).*/\1/p')
if [ -n "${ASSERT_TOTAL}" ] && [ -n "${ASSERT_PASSED}" ]; then
TOTAL_ASSERTIONS=$((TOTAL_ASSERTIONS + ASSERT_TOTAL))
PASSED_ASSERTIONS=$((PASSED_ASSERTIONS + ASSERT_PASSED))
fi
fi
if [ -n "${TOTAL_TESTS}" ] && [ -n "${PASSED_COUNT}" ]; then
if [ "${PASSED_COUNT}" -eq "${TOTAL_TESTS}" ]; then
log_success "Test passed: ${test_name} (${PASSED_COUNT}/${TOTAL_TESTS})"
PASSED_TESTS+=("${test_name}")
else
log_error "Test failed: ${test_name} (${PASSED_COUNT}/${TOTAL_TESTS} passed)"
echo "--- Test Output for ${test_name} ---"
echo "${OUTPUT}" | tail -30
echo "--- End Output ---"
FAILED_TESTS+=("${test_name}")
fi
else
log_error "Test failed: ${test_name} (could not parse results)"
echo "--- Test Output for ${test_name} ---"
echo "${OUTPUT}" | tail -30
echo "--- End Output ---"
FAILED_TESTS+=("${test_name}")
fi
elif [ "${EXIT_CODE}" -eq 0 ] && ! echo "${OUTPUT}" | grep -qiE "(FAILED|failed|error|E[0-9]+)"; then
# Exit code 0 and no errors found - consider it a pass
log_success "Test passed: ${test_name} (exit code 0, no errors)"
PASSED_TESTS+=("${test_name}")
else
log_error "Test failed: ${test_name}"
echo "--- Test Output for ${test_name} ---"
echo "Exit code: ${EXIT_CODE}"
echo "${OUTPUT}" | tail -50
echo "--- End Output ---"
FAILED_TESTS+=("${test_name}")
fi
done
# Generate test results JSON
RESULTS_DIR="${PROJECT_ROOT}/results"
LOGS_DIR="${PROJECT_ROOT}/test-logs"
mkdir -p "${RESULTS_DIR}" "${LOGS_DIR}"
# Function to format array as JSON array with proper escaping
format_json_array() {
local arr=("$@")
if [ ${#arr[@]} -eq 0 ]; then
echo "[]"
return
fi
local result="["
local first=true
for item in "${arr[@]}"; do
if [ "$first" = true ]; then
first=false
else
result+=","
fi
# Escape JSON special characters: ", \, and control characters
local escaped=$(echo "$item" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed 's/\x00//g')
result+="\"${escaped}\""
done
result+="]"
echo "$result"
}
TEST_RESULTS_JSON="${PROJECT_ROOT}/test-results.json"
PASSED_ARRAY_JSON=$(format_json_array "${PASSED_TESTS[@]}")
FAILED_ARRAY_JSON=$(format_json_array "${FAILED_TESTS[@]}")
cat > "${TEST_RESULTS_JSON}" << EOF
{
"timestamp": $(date +%s),
"python_version": "$(python3 --version 2>&1 | awk '{print $2}')",
"vim_version": "$(vim --version | head -1 | awk '{print $5}')",
"total_tests": ${#TEST_FILES[@]},
"passed_tests": ${#PASSED_TESTS[@]},
"failed_tests": ${#FAILED_TESTS[@]},
"total_assertions": ${TOTAL_ASSERTIONS},
"passed_assertions": ${PASSED_ASSERTIONS},
"results": {
"passed": ${PASSED_ARRAY_JSON},
"failed": ${FAILED_ARRAY_JSON}
}
}
EOF
# Validate JSON syntax if jq or python is available
if command -v jq &> /dev/null; then
if ! jq empty "${TEST_RESULTS_JSON}" 2>/dev/null; then
log_error "Generated JSON is invalid!"
cat "${TEST_RESULTS_JSON}"
exit 1
fi
elif command -v python3 &> /dev/null; then
if ! python3 -m json.tool "${TEST_RESULTS_JSON}" > /dev/null 2>&1; then
log_error "Generated JSON is invalid!"
cat "${TEST_RESULTS_JSON}"
exit 1
fi
fi
# Create summary log
SUMMARY_LOG="${LOGS_DIR}/test-summary.log"
cat > "${SUMMARY_LOG}" << EOF
Test Summary
============
Python Version: $(python3 --version 2>&1)
Vim Version: $(vim --version | head -1)
Timestamp: $(date)
Total Tests: ${#TEST_FILES[@]}
Passed: ${#PASSED_TESTS[@]}
Failed: ${#FAILED_TESTS[@]}
Total Assertions: ${TOTAL_ASSERTIONS}
Passed Assertions: ${PASSED_ASSERTIONS}
Passed Tests:
$(for test in "${PASSED_TESTS[@]}"; do echo " ✓ ${test}"; done)
Failed Tests:
$(for test in "${FAILED_TESTS[@]}"; do echo " ✗ ${test}"; done)
EOF
# Print summary
echo
log_info "Test Summary"
log_info "============"
log_info "Total tests: ${#TEST_FILES[@]}"
log_info "Passed: ${#PASSED_TESTS[@]}"
log_info "Failed: ${#FAILED_TESTS[@]}"
if [ ${TOTAL_ASSERTIONS} -gt 0 ]; then
log_info "Assertions: ${PASSED_ASSERTIONS}/${TOTAL_ASSERTIONS}"
fi
if [[ ${#FAILED_TESTS[@]} -gt 0 ]]; then
echo
log_error "Failed tests:"
for test in "${FAILED_TESTS[@]}"; do
echo " ✗ ${test}"
done
echo
log_info "Test results saved to: ${TEST_RESULTS_JSON}"
log_info "Summary log saved to: ${SUMMARY_LOG}"
exit 1
else
echo
log_success "All tests passed!"
log_info "Test results saved to: ${TEST_RESULTS_JSON}"
log_info "Summary log saved to: ${SUMMARY_LOG}"
exit 0
fi