1 #include <math.h>
2 #include <r_diff.h>
3 #include "minunit.h"
4 
5 #define R(a,b,c,d) {(const ut8*)a, (const ut8*)b, (int)c, (int)d}
6 static struct {
7 	const ut8 *a;
8 	const ut8 *b;
9 	int di_distance;
10 	int dis_distance;
11 } tests[] = {
12 	R("", "zzz", 3, 3),
13 	R("meow", "", 4, 4),
14 	R("a", "b", 2, 1),
15 	R("aaa", "aaa", 0, 0),
16 	R("aaaaa", "aabaa", 2, 1),
17 	R("aaaa", "aabaa", 1, 1),
18 	R("aaba", "babca", 3, 2),
19 	R("foo", "foobar", 3, 3),
20 	R("wallaby", "wallet", 5, 3),
21 	R("identity", "identity", 0, 0),
22 	{NULL,NULL,0,0}
23 };
24 
test_r_diff_buffers_distance(void)25 bool test_r_diff_buffers_distance(void) {
26 	char msg[128];
27 	RDiff *diff = r_diff_new ();
28 	if (!diff) {
29 		return false;
30 	}
31 	unsigned int distance;
32 	int i;
33 
34 	// Levenshtein edit distance (deletion/insertion/substitution)
35 	diff->type = 'l';
36 	for (i = 0; tests[i].a; i++) {
37 		size_t la = strlen ((const char *)tests[i].a), lb = strlen ((const char *)tests[i].b);
38 		r_diff_buffers_distance (diff, tests[i].a, la, tests[i].b, lb, &distance, NULL);
39 		snprintf (msg, sizeof msg, "levenshtein %s/%s distance", tests[i].a, tests[i].b);
40 		mu_assert_eq (distance, tests[i].dis_distance, msg);
41 	}
42 
43 	// Eugene W. Myers' O(ND) diff algorithm, deletion/insertion edit distance
44 	diff->type = 'm';
45 	for (i = 0; tests[i].a; i++) {
46 		size_t la = strlen ((const char *)tests[i].a), lb = strlen ((const char *)tests[i].b);
47 		r_diff_buffers_distance (diff, tests[i].a, la, tests[i].b, lb, &distance, NULL);
48 		snprintf (msg, sizeof msg, "myers %s/%s distance", tests[i].a, tests[i].b);
49 		mu_assert_eq (distance, tests[i].di_distance, msg);
50 	}
51 
52 	r_diff_free (diff);
53 	mu_end;
54 }
55 
all_tests()56 int all_tests() {
57 	mu_run_test(test_r_diff_buffers_distance);
58 	return tests_passed != tests_run;
59 }
60 
main(int argc,char ** argv)61 int main(int argc, char **argv) {
62 	return all_tests();
63 }
64