aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tests/setup.sh
blob: 1457dd51ec948595ff9f73a758c01f04501347b4 (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
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
# This file should be sourced by all test-scripts
#
# Main functions:
#   prepare_tests(description) - setup for testing, i.e. create repos+config
#   run_test(description, script) - run one test, i.e. eval script
#
# Helper functions
#   cgit_query(querystring) - call cgit with the specified querystring
#   cgit_url(url) - call cgit with the specified virtual url
#
# Example script:
#
# . setup.sh
# prepare_tests "html validation"
# run_test 'repo index' 'cgit_url "/" | tidy -e'
# run_test 'repo summary' 'cgit_url "/foo" | tidy -e'


mkrepo() {
	name=$1
	count=$2
	dir=$PWD
	test -d $name && return
	printf "Creating testrepo %s\n" $name
	mkdir -p $name
	cd $name
	git init
	for ((n=1; n<=count; n++))
	do
		echo $n >file-$n
		git add file-$n
		git commit -m "commit $n"
	done
	if test "$3" = "testplus"
	then
		echo "hello" >a+b
		git add a+b
		git commit -m "add a+b"
		git branch "1+2"
	fi
	cd $dir
}

setup_repos()
{
	rm -rf trash/cache
	mkdir -p trash/cache
	mkrepo trash/repos/foo 5 >/dev/null
	mkrepo trash/repos/bar 50 >/dev/null
	mkrepo trash/repos/foo+bar 10 testplus >/dev/null
	cat >trash/cgitrc <<EOF
virtual-root=/
cache-root=$PWD/trash/cache

cache-size=1021
snapshots=tar.gz tar.bz zip
enable-log-filecount=1
enable-log-linecount=1
summary-log=5
summary-branches=5
summary-tags=5

repo.url=foo
repo.path=$PWD/trash/repos/foo/.git
# Do not specify a description for this repo, as it then will be assigned
# the constant value "[no description]" (which actually used to cause a
# segfault).

repo.url=bar
repo.path=$PWD/trash/repos/bar/.git
repo.desc=the bar repo

repo.url=foo+bar
repo.path=$PWD/trash/repos/foo+bar/.git
repo.desc=the foo+bar repo
EOF
}

prepare_tests()
{
	setup_repos
	rm -f test-output.log 2>/dev/null
	test_count=0
	test_failed=0
	echo "[$0]" "$@" >test-output.log
	echo "$@" "($0)"
}

tests_done()
{
	printf "\n"
	if test $test_failed -gt 0
	then
		printf "test: *** %s failure(s), logfile=%s\n" \
			$test_failed "$(pwd)/test-output.log"
		false
	fi
}

run_test()
{
	desc=$1
	script=$2
	((test_count++))
	printf "\ntest %d: name='%s'\n" $test_count "$desc" >>test-output.log
	printf "test %d: eval='%s'\n" $test_count "$2" >>test-output.log
	eval "$2" >>test-output.log 2>>test-output.log
	res=$?
	printf "test %d: exitcode=%d\n" $test_count $res >>test-output.log
	if test $res = 0
	then
		printf " %2d) %-60s [ok]\n" $test_count "$desc"
	else
		((test_failed++))
		printf " %2d) %-60s [failed]\n" $test_count "$desc"
	fi
}

cgit_query()
{
	CGIT_CONFIG="$PWD/trash/cgitrc" QUERY_STRING="$1" "$PWD/../cgit"
}

cgit_url()
{
	CGIT_CONFIG="$PWD/trash/cgitrc" QUERY_STRING="url=$1" "$PWD/../cgit"
}
lass="k">if (L != NULL) { memset(*L, 0, sizeof(int) * MAX_SSDIFF_SIZE); return; } // xcalloc will die if we ran out of memory; // not very helpful for debugging L = (int**)xcalloc(MAX_SSDIFF_M, sizeof(int *)); *L = (int*)xcalloc(MAX_SSDIFF_SIZE, sizeof(int)); for (i = 1; i < MAX_SSDIFF_M; i++) { L[i] = *L + i * MAX_SSDIFF_N; } } static char *longest_common_subsequence(char *A, char *B) { int i, j, ri; int m = strlen(A); int n = strlen(B); int tmp1, tmp2; int lcs_length; char *result; // We bail if the lines are too long if (m >= MAX_SSDIFF_M || n >= MAX_SSDIFF_N) return NULL; create_or_reset_lcs_table(); for (i = m; i >= 0; i--) { for (j = n; j >= 0; j--) { if (A[i] == '\0' || B[j] == '\0') { L[i][j] = 0; } else if (A[i] == B[j]) { L[i][j] = 1 + L[i + 1][j + 1]; } else { tmp1 = L[i + 1][j]; tmp2 = L[i][j + 1]; L[i][j] = (tmp1 > tmp2 ? tmp1 : tmp2); } } } lcs_length = L[0][0]; result = xmalloc(lcs_length + 2); memset(result, 0, sizeof(*result) * (lcs_length + 2)); ri = 0; i = 0; j = 0; while (i < m && j < n) { if (A[i] == B[j]) { result[ri] = A[i]; ri += 1; i += 1; j += 1; } else if (L[i + 1][j] >= L[i][j + 1]) { i += 1; } else { j += 1; } } return result; } static int line_from_hunk(char *line, char type) { char *buf1, *buf2; int len; buf1 = strchr(line, type); if (buf1 == NULL) return 0; buf1 += 1; buf2 = strchr(buf1, ','); if (buf2 == NULL) return 0; len = buf2 - buf1; buf2 = xmalloc(len + 1); strncpy(buf2, buf1, len); buf2[len] = '\0'; int res = atoi(buf2); free(buf2); return res; } static char *replace_tabs(char *line) { char *prev_buf = line; char *cur_buf; int linelen = strlen(line); int n_tabs = 0; int i; char *result; char *spaces = " "; if (linelen == 0) { result = xmalloc(1); result[0] = '\0'; return result; } for (i = 0; i < linelen; i++) if (line[i] == '\t') n_tabs += 1; result = xmalloc(linelen + n_tabs * 8 + 1); result[0] = '\0'; while (1) { cur_buf = strchr(prev_buf, '\t'); if (!cur_buf) { strcat(result, prev_buf); break; } else { strncat(result, prev_buf, cur_buf - prev_buf); strncat(result, spaces, 8 - (strlen(result) % 8)); } prev_buf = cur_buf + 1; } return result; } static int calc_deferred_lines(struct deferred_lines *start) { struct deferred_lines *item = start; int result = 0; while (item) { result += 1; item = item->next; } return result; } static void deferred_old_add(char *line, int line_no) { struct deferred_lines *item = xmalloc(sizeof(struct deferred_lines)); item->line = xstrdup(line); item->line_no = line_no; item->next = NULL; if (deferred_old) { deferred_old_last->next = item; deferred_old_last = item; } else { deferred_old = deferred_old_last = item; } } static void deferred_new_add(char *line, int line_no) { struct deferred_lines *item = xmalloc(sizeof(struct deferred_lines)); item->line = xstrdup(line); item->line_no = line_no; item->next = NULL; if (deferred_new) { deferred_new_last->next = item; deferred_new_last = item; } else { deferred_new = deferred_new_last = item; } } static void print_part_with_lcs(char *class, char *line, char *lcs) { int line_len = strlen(line); int i, j; char c[2] = " "; int same = 1; j = 0; for (i = 0; i < line_len; i++) { c[0] = line[i]; if (same) { if (line[i] == lcs[j]) j += 1; else { same = 0; htmlf("<span class='%s'>", class); } } else if (line[i] == lcs[j]) { same = 1; htmlf("</span>"); j += 1; } html_txt(c); } } static void print_ssdiff_line(char *class, int old_line_no, char *old_line, int new_line_no, char *new_line, int individual_chars) { char *lcs = NULL; if (old_line) old_line = replace_tabs(old_line + 1); if (new_line) new_line = replace_tabs(new_line + 1); if (individual_chars && old_line && new_line) lcs = longest_common_subsequence(old_line, new_line); html("<tr>\n"); if (old_line_no > 0) { struct diff_filespec *old_file = cgit_get_current_old_file(); char *lineno_str = fmt("n%d", old_line_no); char *id_str = fmt("id=%s#%s", is_null_sha1(old_file->sha1)?"HEAD":sha1_to_hex(old_rev_sha1), lineno_str); html("<td class='lineno'><a class='no' href='"); html(cgit_fileurl(ctx.repo->url, "tree", old_file->path, id_str)); htmlf("' id='%s' name='%s'>%s</a>", lineno_str, lineno_str, lineno_str + 1); html("</td>"); htmlf("<td class='%s'>", class); } else if (old_line) htmlf("<td class='lineno'></td><td class='%s'>", class); else htmlf("<td class='lineno'></td><td class='%s_dark'>", class); if (old_line) { if (lcs) print_part_with_lcs("del", old_line, lcs); else html_txt(old_line); } html("</td>\n"); if (new_line_no > 0) { struct diff_filespec *new_file = cgit_get_current_new_file(); char *lineno_str = fmt("n%d", new_line_no); char *id_str = fmt("id=%s#%s", is_null_sha1(new_file->sha1)?"HEAD":sha1_to_hex(new_rev_sha1), lineno_str); html("<td class='lineno'><a class='no' href='"); html(cgit_fileurl(ctx.repo->url, "tree", new_file->path, id_str)); htmlf("' id='%s' name='%s'>%s</a>", lineno_str, lineno_str, lineno_str + 1); html("</td>"); htmlf("<td class='%s'>", class); } else if (new_line) htmlf("<td class='lineno'></td><td class='%s'>", class); else htmlf("<td class='lineno'></td><td class='%s_dark'>", class); if (new_line) { if (lcs) print_part_with_lcs("add", new_line, lcs); else html_txt(new_line); } html("</td></tr>"); if (lcs) free(lcs); if (new_line) free(new_line); if (old_line) free(old_line); } static void print_deferred_old_lines() { struct deferred_lines *iter_old, *tmp; iter_old = deferred_old; while (iter_old) { print_ssdiff_line("del", iter_old->line_no, iter_old->line, -1, NULL, 0); tmp = iter_old->next; free(iter_old); iter_old = tmp; } } static void print_deferred_new_lines() { struct deferred_lines *iter_new, *tmp; iter_new = deferred_new; while (iter_new) { print_ssdiff_line("add", -1, NULL, iter_new->line_no, iter_new->line, 0); tmp = iter_new->next; free(iter_new); iter_new = tmp; } } static void print_deferred_changed_lines() { struct deferred_lines *iter_old, *iter_new, *tmp; int n_old_lines = calc_deferred_lines(deferred_old); int n_new_lines = calc_deferred_lines(deferred_new); int individual_chars = (n_old_lines == n_new_lines ? 1 : 0); iter_old = deferred_old; iter_new = deferred_new; while (iter_old || iter_new) { if (iter_old && iter_new) print_ssdiff_line("changed", iter_old->line_no, iter_old->line, iter_new->line_no, iter_new->line, individual_chars); else if (iter_old) print_ssdiff_line("changed", iter_old->line_no, iter_old->line, -1, NULL, 0); else if (iter_new) print_ssdiff_line("changed", -1, NULL, iter_new->line_no, iter_new->line, 0); if (iter_old) { tmp = iter_old->next; free(iter_old); iter_old = tmp; } if (iter_new) { tmp = iter_new->next; free(iter_new); iter_new = tmp; } } } void cgit_ssdiff_print_deferred_lines() { if (!deferred_old && !deferred_new) return; if (deferred_old && !deferred_new) print_deferred_old_lines(); else if (!deferred_old && deferred_new) print_deferred_new_lines(); else print_deferred_changed_lines(); deferred_old = deferred_old_last = NULL; deferred_new = deferred_new_last = NULL; } /* * print a single line returned from xdiff */ void cgit_ssdiff_line_cb(char *line, int len) { char c = line[len - 1]; line[len - 1] = '\0'; if (line[0] == '@') { current_old_line = line_from_hunk(line, '-'); current_new_line = line_from_hunk(line, '+'); } if (line[0] == ' ') { if (deferred_old || deferred_new) cgit_ssdiff_print_deferred_lines(); print_ssdiff_line("ctx", current_old_line, line, current_new_line, line, 0); current_old_line += 1; current_new_line += 1; } else if (line[0] == '+') { deferred_new_add(line, current_new_line); current_new_line += 1; } else if (line[0] == '-') { deferred_old_add(line, current_old_line); current_old_line += 1; } else if (line[0] == '@') { html("<tr><td colspan='4' class='hunk'>"); html_txt(line); html("</td></tr>"); } else { html("<tr><td colspan='4' class='ctx'>"); html_txt(line); html("</td></tr>"); } line[len - 1] = c; } void cgit_ssdiff_header_begin() { current_old_line = -1; current_new_line = -1; html("<tr><td class='space' colspan='4'><div></div></td></tr>"); html("<tr><td class='head' colspan='4'>"); } void cgit_ssdiff_header_end() { html("</td><tr>"); } void cgit_ssdiff_footer() { if (deferred_old || deferred_new) cgit_ssdiff_print_deferred_lines(); html("<tr><td class='foot' colspan='4'></td></tr>"); }