From c856b5ff90a3d69801f2f837e5242b57816a8d58 Mon Sep 17 00:00:00 2001
From: anon <anon@anon.anon>
Date: Sat, 30 Nov 2024 12:52:01 +0100
Subject: [PATCH] introduce cmdtest into the project + basic tests

---
 .gitignore                |  2 ++
 Makefile                  |  5 +++++
 test/CMDTEST_main.rb      | 39 +++++++++++++++++++++++++++++++++++++++
 test/dummy_project/h.c    | 10 ++++++++++
 test/dummy_project/h.h    |  6 ++++++
 test/dummy_project/main.c | 16 ++++++++++++++++
 6 files changed, 78 insertions(+)
 create mode 100644 test/CMDTEST_main.rb
 create mode 100644 test/dummy_project/h.c
 create mode 100644 test/dummy_project/h.h
 create mode 100644 test/dummy_project/main.c

diff --git a/.gitignore b/.gitignore
index c657bb9..9ccf699 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,5 @@
 csope
 source/lex.yy.c
 main.plist
+tmp-cmdtest-*
+.cmdtest-filter
diff --git a/Makefile b/Makefile
index d26f217..97ef2f6 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,5 @@
+.PHONY: test
+
 LIBS:=ncurses readline
 
 CFLAGS += $(if $(SAN),-fsanitize=${SAN}) -Wno-unused-result
@@ -46,3 +48,6 @@ clean:
 	-${RM} ${GENYACC}
 	-${RM} ${object}
 	-${RM} ${OUTPUT}
+
+test:
+	cmdtest --fast
diff --git a/test/CMDTEST_main.rb b/test/CMDTEST_main.rb
new file mode 100644
index 0000000..a2f9002
--- /dev/null
+++ b/test/CMDTEST_main.rb
@@ -0,0 +1,39 @@
+# NOTE: Kernel mode should be used accross the board,
+#        because system headers are volatile.
+#       Writting tests for them would be foolish.
+#       They could even introduce interfering
+#        symbols in the future by pure chance,
+#        if not completely ignored.
+
+# The following variables are magick numbers based on `dummy_project/`.
+$f_definition_line = 5
+
+class CMDTEST_misc_batch < Cmdtest::Testcase
+  def test_no_arg
+    cmd "csope" do
+      stdout_equal /.+/
+      stderr_equal /.+/
+      exit_status 1
+    end
+  end
+end
+
+class CMDTEST_dummy_project < Cmdtest::Testcase
+  def setup
+    import_directory "test/dummy_project/", "./dummy_project/"
+  end
+
+  def test_find_f
+    cmd "csope -k -L -0 f -s dummy_project/" do
+      created_files ["cscope.out"]
+      stdout_equal /\A(.*\n){2}\Z/
+    end
+  end
+
+  def test_find_def_f
+    cmd "csope -k -L -1 f -s dummy_project/" do
+      created_files ["cscope.out"]
+      stdout_equal /\A.+#{$f_definition_line}.+\n\Z/
+    end
+  end
+end
diff --git a/test/dummy_project/h.c b/test/dummy_project/h.c
new file mode 100644
index 0000000..0c6e081
--- /dev/null
+++ b/test/dummy_project/h.c
@@ -0,0 +1,10 @@
+#include "h.h"
+#include <stdlib.h>
+
+double h(int i) {
+    if (i < 100000) {
+        return rand() % i;
+    } else {
+        return i / 10;
+    }
+}
diff --git a/test/dummy_project/h.h b/test/dummy_project/h.h
new file mode 100644
index 0000000..e2b94f8
--- /dev/null
+++ b/test/dummy_project/h.h
@@ -0,0 +1,6 @@
+#ifndef H_H
+#define H_H
+
+extern double h(int i);
+
+#endif
diff --git a/test/dummy_project/main.c b/test/dummy_project/main.c
new file mode 100644
index 0000000..d447ccc
--- /dev/null
+++ b/test/dummy_project/main.c
@@ -0,0 +1,16 @@
+// @BAKE gcc -o dummy.out main.c h.c
+#include <stdlib.h>
+#include "h.h"
+
+int f(void) {
+    int r = 0;
+    for (int i = 0; i < 100; i++) {
+        r += (int)h(r);
+    }
+    return r;
+}
+
+
+signed main(void) {
+    return f();
+}