commit f66a063dcd6f7dbbdc9c088e43b14f8e11ec0416
parent 51df4f1dd977ef7215a9a298f176a88b0a70bb4c
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Wed, 11 Jan 2023 10:46:19 +0900
add test
Diffstat:
4 files changed, 226 insertions(+), 1 deletion(-)
diff --git a/ex9/list.c b/ex9/list.c
@@ -16,7 +16,8 @@ struct List *
 laddfront(struct List *p, void *item)
 {
 	if (item == NULL) {
-		fprintf(stderr, "laddfront: Error. Item is NULL\n");
+		// TODO: should print some message ??
+		//fprintf(stderr, "laddfront: Error. Item is NULL\n");
 		return NULL;
 	}
 
@@ -155,8 +156,43 @@ __lqsort(struct List *p, struct List *tail, int (* cmp)(void *, void *))
 void
 lswap(struct List *p, struct List *q)
 {
+	if (p == NULL || q == NULL)
+		return;
 	void *tmp;
 	tmp = p->item;
 	p->item = q->item;
 	q->item = tmp;
 }
+
+/*
+ * Leqa() returns 1 if two Lists are identicall, 0 if not.
+ * Only checks the address of each items.
+ */
+int
+leqa(struct List *p, struct List *q)
+{
+	for (;p != NULL && q != NULL; p = p->next, q = q->next) {
+		if (p->item != q->item)
+			return 0;
+	}
+	if (p == NULL && q == NULL)
+		return 1;
+	return 0;
+}
+
+/*
+ * Leqi() returns 1 if two Lists are identicall, 0 if not.
+ * Compares each items with eq().
+ */
+int
+leqi(struct List *p, struct List *q, int (*eq)(void *, void*))
+{
+	for (;p != NULL && q != NULL; p = p->next, q = q->next) {
+		if (!eq(p->item, q->item))
+			return 0;
+	}
+	if (p == NULL && q == NULL)
+		return 1;
+	return 0;
+}
+
diff --git a/ex9/list.h b/ex9/list.h
@@ -5,6 +5,8 @@ void lprint(struct List *p, void (* pfnc)(void *));
 int lbsort(struct List *p, int (* cmp)(void *, void *));
 int lqsort(struct List *p, int (* cmp)(void *, void *));
 void lswap(struct List *p, struct List *q);
+int leqa(struct List *p, struct List *q);
+int leqi(struct List *p, struct List *q, int (*eq)(void *, void *));
 
 /* Linked list. An empty list must be initialized with NULL. */
 struct List {
diff --git a/ex9/test/a.out b/ex9/test/a.out
Binary files differ.
diff --git a/ex9/test/list_t.c b/ex9/test/list_t.c
@@ -0,0 +1,187 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "../list.h"
+
+struct Item {
+	int id;
+};
+
+/* utils for testing */
+void iprint(struct Item *);
+struct Item* icreate(int);
+void ifree(struct Item *);
+int icmp(struct Item *, struct Item *);
+int ieq(struct Item *, struct Item *);
+struct List * lcreate_from_array(int nums[], int n);
+void aswap(int nums[], int i, int j);
+
+/* tests */
+void test_laddfront(void);
+void test_lswap(void);
+
+void
+iprint(struct Item *p)
+{
+	printf("[%d]", p->id);
+}
+
+struct Item*
+icreate(int id)
+{
+	struct Item *p;
+	p = (struct Item *)malloc(sizeof(struct Item));
+	p->id = id;
+	return p;
+}
+
+void
+ifree(struct Item *p)
+{
+	free(p);
+}
+
+int
+icmp(struct Item *p, struct Item *q)
+{
+	if (p->id < q->id)
+		return -1;
+	else if (p->id == q->id)
+		return 0;
+	else
+		return 1;
+}
+
+int
+ieq(struct Item *p, struct Item *q)
+{
+	return !icmp(p, q);
+}
+
+struct List *
+lcreate_from_array(int nums[], int n)
+{
+	struct List *p, *tmp;
+	p = NULL;
+	for (int i = n - 1; i >= 0; i--) {
+		tmp = laddfront(p, icreate(nums[i]));
+		if (tmp == NULL) {
+			fprintf(stderr, "lcreate_from_array(): Fatal. Laddfront() failed.\n");
+			exit(1);
+		}
+		p = tmp;
+	}
+	return p;
+}
+
+void
+aswap(int nums[], int i, int j)
+{
+	int tmp;
+	tmp = nums[i];
+	nums[i] = nums[j];
+	nums[j] = tmp;
+}
+
+
+void
+test_laddfront(void)
+{
+	int n = 3;
+	int num[n];
+	struct Item *item[n];
+	struct List *p = NULL, *tmp;
+
+	if ((tmp = laddfront(p, NULL)) != NULL)
+		fprintf(stderr, "test_laddfront: Adding NULL item should return"
+			"NULL\n");
+
+	for (int i = 0; i < n; i++)
+		item[i] = icreate(num[i]);
+	
+	for (int i = 0; i < n; i++) {
+		if ((tmp = laddfront(p, item[i])) == NULL)
+			fprintf(stderr, "test_laddfront: Adding item failed.\n");
+		p = tmp;
+	}
+	lfreei(p, (void (*)(void *))&ifree);
+}
+
+/*
+ * Test for lswap().
+ * Assume that laddfront, leqa, leqi work correctly.
+ */
+void
+test_lswap(void)
+{
+	struct List *p = NULL, *q = NULL, *tmp;
+
+	/* test for NULL List. */
+	lswap(p, p);
+	if (p != NULL)
+		fprintf(stderr, "test_lswap: Test for NULL List failed.\n");
+
+	/* test for one element List. */
+	struct Item *item;
+	item = icreate(0);
+
+	tmp = laddfront(p, item);
+	if (tmp == NULL) {
+		fprintf(stderr, "test_lswap: Fatal. laddfront() failed.\n");
+		exit(1);
+	}
+	p = tmp;
+	tmp = laddfront(q, item);
+	if (tmp == NULL) {
+		fprintf(stderr, "test_lswap: Fatal. laddfront() failed.\n");
+		exit(1);
+	}
+	q = tmp;
+	lswap(p, p);
+	if (! leqa(p, q))
+		fprintf(stderr, "test_lswap: Test for one element List failed.\n");
+	lfree(p);
+	lfree(q);
+	ifree(item);
+
+	/* test for random numbers */
+	/* swaps every pairs with lswap and aswap, then checks both are same */
+	struct List *li, *lj;
+	int i, j;
+	int lmin = 5;
+	int lmax = 15;
+	p = q = NULL;
+
+	int n = (unsigned int)rand() % (lmax - lmin) + lmin;
+	assert(lmin <= n && n < lmax);
+	int nums[n];
+
+	for (int i = 0; i < n; i++) {
+		nums[i] = rand();
+	}
+	p = lcreate_from_array(nums, n);
+	for (i = 0, li = p; i < n && li != NULL; i++, li = li->next) {
+		for (j = 0, lj = p; j < n && lj != NULL; j++, lj = lj->next) {
+			lswap(li, lj);
+			aswap(nums, i, j);
+			q = lcreate_from_array(nums, n);
+			if (!leqi(p, q, (int (*)(void *, void*))&ieq))
+				fprintf(stderr, "test_lswap: Test for longer List failed.\n");
+			lfreei(q, (void (*))(void *)&ifree);
+		}
+	}
+	if (i != j)
+		fprintf(stderr, "test_lswap: Index mismatch.\n");
+
+	lfreei(p, (void (*))(void *)&ifree);
+}
+
+int
+main(void)
+{
+	test_laddfront();
+	test_lswap();
+
+	return 0;
+}