From 9d6c5f35ee49aea2ae18a1a6dda2ad38292d42dc Mon Sep 17 00:00:00 2001
From: alex <alex@infiniteadaptability.org>
Date: Mon, 18 Oct 2021 21:02:33 -0700
Subject: [PATCH] ...

---
 inc/tree.h             |  2 +
 src/tree.c             | 27 +++++++++----
 test/unit/tree.tests.c | 91 +++++++++++++++++++++++++++++++++++-------
 3 files changed, 98 insertions(+), 22 deletions(-)

diff --git a/inc/tree.h b/inc/tree.h
index f007f6c..2bb9edd 100644
--- a/inc/tree.h
+++ b/inc/tree.h
@@ -18,6 +18,8 @@ struct tree {
 };
 
 int tree_add(struct tree*,struct file*);
+void tree_entry_free(struct tree_entry*);
+int tree_entry_init(struct tree_entry**, struct file*);
 void tree_free(struct tree*);
 int tree_init(struct tree**, const char*);
 
diff --git a/src/tree.c b/src/tree.c
index bef2cc2..30d8bd5 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -72,6 +72,24 @@ static struct tree* tree_add_directory(struct tree *root, const char *dirname) {
 	return next;
 }
 
+void tree_entry_free(struct tree_entry *p) {
+	file_free(p->file);
+	free(p);
+}
+
+int tree_entry_init(struct tree_entry **p, struct file *file) {
+	if(NULL==p) { return -1; }
+	if(NULL==file) { return -1; }
+
+	(*p) = malloc(sizeof(struct tree_entry));
+	if(NULL==(*p)) { return -1; }
+
+	(*p)->file = file;
+	(*p)->next = NULL;
+
+	return 1;
+};
+
 static int tree_add_file(struct tree *root, struct file *to_add) {
 	struct tree_entry *p, *prev, *next;
 	int i;
@@ -92,11 +110,7 @@ static int tree_add_file(struct tree *root, struct file *to_add) {
 		p = p->next;
 	}
 
-	next = malloc(sizeof(struct tree_entry));
-	if(NULL==next) { return -1; }
-
-	next->file = to_add;
-	next->next = NULL;
+	if(tree_entry_init(&next,to_add)<0) { return -1; }
 
 	if(prev!=NULL) {
 		prev->next = next;
@@ -120,8 +134,7 @@ void tree_free(struct tree *p) {
 	while(p->files!=NULL) {
 		entry = p->files;
 		p->files = p->files->next;
-		file_free(entry->file);
-		free(entry);
+		tree_entry_free(entry);
 	}
 
 	while(p->directories!=NULL) {
diff --git a/test/unit/tree.tests.c b/test/unit/tree.tests.c
index b498633..2ce9a56 100644
--- a/test/unit/tree.tests.c
+++ b/test/unit/tree.tests.c
@@ -4,6 +4,7 @@
 
 int main();
 static char *create_random_path();
+static int tree_deep_equals(struct tree *a, struct tree *b);
 static void tree_add_basic_test();
 static void tree_add_extended_test();
 static void tree_init_basic_test();
@@ -21,13 +22,51 @@ int main() {
 }
 
 static void tree_add_basic_test() {
-	struct tree *tree;
-	struct file *file1, *file2;
+	struct tree *tree, *root, *test, *test2, *hello, *nope, *helloo;
+	struct tree_entry *entry1, *entry2, *entry3, *entry4;
+	struct file *file1, *file2, *file3, *file4;
 
 	assert(1==tree_init(&tree,NULL));
 
+	assert(1==tree_init(&root,NULL));
+	assert(1==tree_init(&test,NULL));
+	assert(1==tree_init(&test2,NULL));
+	assert(1==tree_init(&hello,NULL));
+	assert(1==tree_init(&nope,NULL));
+	assert(1==tree_init(&helloo,NULL));
+
 	assert(1==file_init(&file1,"test/file1"));
 	assert(1==file_init(&file2,"test/hello/file2"));
+	assert(1==file_init(&file3,"test2/nope/helloo/file3"));
+	assert(1==file_init(&file4,"test/file4"));
+
+	assert(1==tree_entry_init(&entry1,file1));
+	assert(1==tree_entry_init(&entry2,file2));
+	assert(1==tree_entry_init(&entry3,file3));
+	assert(1==tree_entry_init(&entry4,file4));
+
+	/*
+	 * Tree:
+	 * test(d)
+	 * 	file1(f)
+	 * 	file4(f)
+	 * 	hello(d)
+	 * 		file2(f)
+	 * test2(d)
+	 * 	nope(d)
+	 * 		helloo(d)
+	 * 			file3(f)
+	 */
+
+	root->directories = test;
+	test->next = test2;
+	test->files = entry1;
+	entry1->next = entry4;
+	test->directories = hello;
+	hello->files = entry2;
+	test2->directories = nope;
+	nope->directories = helloo;
+	hello->files = entry3;
 
 	assert(-1==tree_add(NULL,NULL));
 	assert(-1==tree_add(tree,NULL));
@@ -35,26 +74,48 @@ static void tree_add_basic_test() {
 	assert(1==tree_add(tree,file1));
 	assert(1==tree_add(tree,file1));
 	assert(1==tree_add(tree,file2));
+	assert(1==tree_add(tree,file3));
 
 	assert(NULL==tree->name);
 	assert(NULL==tree->files);
-	
-	assert(strcmp(tree->directories->name,"test")==0);
-	assert(tree->directories->files!=NULL);
-	assert(tree->directories->files->file==file1);
-	assert(tree->directories->files->next==NULL);
-	assert(tree->directories->next==NULL);
-
-	assert(strcmp(tree->directories->directories->name,"hello")==0);
-	assert(tree->directories->directories->files!=NULL);
-	assert(tree->directories->directories->files->file==file2);
-	assert(tree->directories->directories->files->next==NULL);
-	assert(tree->directories->directories->directories==NULL);
-	assert(tree->directories->directories->next==NULL);
+
+	assert(tree_deep_equals(tree,root)==1);
+	assert(tree_deep_equals(tree->directories,test)==1);
+	assert(tree_deep_equals(tree->directories->next,test2)==1);
+	assert(tree_deep_equals(tree->directories->directories,hello)==1);
+	assert(tree_deep_equals(tree->directories->next->directories,nope)==1);
+	assert(tree_deep_equals(tree->directories->next->directories->directories,helloo)==1);
 
 	tree_free(tree);
 }
 
+static int tree_deep_equals(struct tree *a, struct tree *b) {
+	if((a!=NULL&&b==NULL)||(a==NULL&&b!=NULL)) { return -1; }
+	if((a->name!=NULL&&b->name==NULL)||(a->name==NULL&&b->name!=NULL)) { return -1; }
+	if(a->name!=NULL) {
+		if(strcmp(a->name,b->name)!=0) { return -1; }
+	}
+
+	{
+		struct tree_entry *p1, *p2;
+		p1 = a->files;
+		p2 = b->files;
+		while(p1!=NULL) {
+			if(p2==NULL) { return -1; }
+			if(strcmp(p1->file->name,p2->file->name)!=0) { return -1; }
+			if(strcmp(p1->file->path,p2->file->path)!=0) { return -1; }
+
+			p1 = p1->next;
+			p2 = p2->next;
+		}
+	}
+
+	if(tree_deep_equals(a->directories,b->directories)<0) { return -1; }
+	if(tree_deep_equals(a->next,b->next)<0) { return -1; }
+
+	return 1;
+}
+
 static char *create_random_path() {
 	char *str;
 	int len, index;
-- 
2.30.2