From 5f09d3182186d55b1c20fdbd904421e01c6eb770 Mon Sep 17 00:00:00 2001
From: Jakhes <dean.schmitz@schmitzbauer.de>
Date: Sat, 12 Nov 2022 00:14:05 +0100
Subject: [PATCH] Adding helper tests

---
 src/helper_files/Makefile         |   8 +
 src/helper_files/helper.pl        |  15 +-
 src/helper_files/helper_tests.cpp | 145 ++++++++++++++
 src/helper_files/helper_tests.pl  | 301 +++++++++++++++++++++++++++++-
 4 files changed, 455 insertions(+), 14 deletions(-)
 create mode 100644 src/helper_files/Makefile
 create mode 100644 src/helper_files/helper_tests.cpp

diff --git a/src/helper_files/Makefile b/src/helper_files/Makefile
new file mode 100644
index 0000000..7a9da74
--- /dev/null
+++ b/src/helper_files/Makefile
@@ -0,0 +1,8 @@
+splfr=/usr/local/sicstus4.7.1/bin/splfr
+
+METHOD_NAME=helper_tests
+
+$(METHOD_NAME).so: $(METHOD_NAME).pl $(METHOD_NAME).cpp
+	$(splfr) -larmadillo -fopenmp -lmlpack -lstdc++ -cxx --struct $(METHOD_NAME).pl $(METHOD_NAME).cpp helper.cpp
+clean:
+	rm $(METHOD_NAME).so
diff --git a/src/helper_files/helper.pl b/src/helper_files/helper.pl
index e872821..48bae6d 100644
--- a/src/helper_files/helper.pl
+++ b/src/helper_files/helper.pl
@@ -1,26 +1,28 @@
 :- module(helper, [     convert_list_to_float_array/3,
                         convert_list_to_float_array/2,
                         convert_float_array_to_list/3,
+                        convert_float_array_to_2d_list/4,
                         len/2,
                         convert_record_to_arr/2,
                         take_csv_row/3,
                         take_csv_row/4,
-                        convert_float_array_to_2d_list/4,
                         take_rows_from_iris_CSV/2]).
 
+
 :- use_module(library(structs)).
 :- use_module(library(csv)).
 
+
 %% TODO: update Comment docs
 %% TODO: test the helper predicate
 
 %% Functions for editing float arrays
 
-convert_list_to_float_array(Arr, Row_num, array(Size, Row_num,Mem)) :-
+convert_list_to_float_array(Arr, DataPointDim, array(Size, DataPointDim,Mem)) :-
         len(Arr, Size),
-        Size >= Row_num,
-        Row_num > 0,
-        mod(Size, Row_num) =:= 0,
+        Size >= DataPointDim,
+        DataPointDim > 0,
+        mod(Size, DataPointDim) =:= 0,
         new(float_array, Size, Mem),
         fill_float_array(Arr, 0, Mem).
 
@@ -76,7 +78,7 @@ len([_|Tail], List_L) :-
 %% take the elements in a csv record and put them in a list
 convert_record_to_arr([], []):- !.
 convert_record_to_arr([float(Num,_)|Tail], [Num|Rest]) :-
-        convert_record_to_arr(Tail, Rest).
+        convert_record_to_arr(Tail, Rest),!.
 convert_record_to_arr([string(_)|Tail], Rest) :-
         convert_record_to_arr(Tail, Rest).
 
@@ -85,6 +87,7 @@ take_csv_row(File, skipFirstRow, Count, H) :-
         take_csv_row(File, Count, H).
 take_csv_row(_, 0, []) :- !.
 take_csv_row(File, Count, H) :-
+        Count > 0,
         read_record(File, Rec),
         convert_record_to_arr(Rec, Out),
         NewCount is Count - 1,
diff --git a/src/helper_files/helper_tests.cpp b/src/helper_files/helper_tests.cpp
new file mode 100644
index 0000000..8d3d3e7
--- /dev/null
+++ b/src/helper_files/helper_tests.cpp
@@ -0,0 +1,145 @@
+#include <sicstus/sicstus.h>
+/* ex_glue.h is generated by splfr from the foreign/[2,3] facts.
+    Always include the glue header in your foreign resource code.
+*/
+#include "helper_tests_glue.h"
+#include <mlpack/core.hpp>
+
+// including helper functions for converting between arma structures and arrays
+#include "helper.hpp"
+
+SP_integer testing_Taking_Integer(SP_integer number)
+{
+    if (number == 1)
+        return 1;
+    else
+        return 0;
+}
+
+SP_integer testing_Taking_Double(double number)
+{
+    if (number == 1.0)
+        return 1;
+    else
+        return 0;
+}
+
+SP_integer testing_Taking_String(const char *string)
+{
+    if (strcmp(string, "true") == 0)
+        return 1;
+    else
+        return 0;
+}
+
+SP_integer testing_Taking_Float_Vector(float *arr, SP_integer size)
+{
+    double compare[] = {1.0, 2.0, 3.0, 4.0, 5.0};
+    for (size_t i = 0; i < size; i++)
+    {
+        if(compare[i] != arr[i])
+            return 0;
+    }
+
+    vec compare2(5);
+    for (double i = 0.0; i < size; i++)
+    {
+        compare2[i] = i + 1.0;
+    }
+    
+    // convert the Prolog array to arma::rowvec
+    vec arrVec = convertArrayToColvec(arr, size);
+
+    for (size_t i = 0; i < size; i++)
+    {
+        if(compare2[i] != arrVec[i])
+            return -1;
+    }
+    return 1;
+}
+
+SP_integer testing_Taking_Float_Matrix(float *arr, SP_integer size, SP_integer dataPointDim)
+{
+	// compares if the converted list is the same as an array
+	double compare[] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
+	for (size_t i = 0; i < size; i++)
+	{
+	    if(compare[i] != arr[i])
+	        return 0;
+	}
+	// creates the mat for later comparision
+    mat compareMat(dataPointDim,size/dataPointDim);
+    for (double i = 0.0; i < 8; i++)
+    {
+        compareMat[i] = i;
+    }
+
+    // converts the given arr into a mat
+    mat arrMat = convertArrayToMat(arr, size, dataPointDim);
+
+    for (size_t i = 0; i < size; i++)
+    {
+        if(compareMat[i] != arrMat[i])
+            return -1;
+    }
+    return 1;
+}
+
+SP_integer testing_Taking_Integer_Vector(SP_integer *arr, SP_integer size);
+SP_integer testing_Taking_Integer_Matrix(SP_integer *arr, SP_integer cols, SP_integer rows);
+
+
+void testing_Returning_Integer(SP_integer *number)
+{
+    *number = 1;
+}
+void testing_Returning_Double(double *number)
+{
+    *number = 1.0;
+}
+void testing_Returning_String(const char **str)
+{
+    *str = "true";
+}
+void testing_Returning_Float_Vector(float **arr, SP_integer *size)
+{
+    vec returnVector(5);
+    for (double i = 0.0; i < 5; i++)
+    {
+        returnVector[i] = i;
+    }
+
+    returnVectorInformation(returnVector, arr, size);
+}
+void testing_Returning_Float_Matrix(float **arr, SP_integer *cols, SP_integer *rows)
+{
+    mat returnMat(2,4);
+    for (double i = 0.0; i < 8; i++)
+    {
+        returnMat[i] = i;
+    }
+
+    returnMatrixInformation(returnMat, arr, cols, rows);
+}
+void testing_Returning_Integer_Vector(SP_integer **arr, SP_integer *size);
+void testing_Returning_Integer_Matrix(SP_integer **arr, SP_integer *cols, SP_integer *rows);
+
+
+void testing_Raising_SystemError(const char *message)
+{
+	raisePrologSystemExeption(message);
+}
+
+void testing_Raising_DomainError(const char *expectation, const char *culprit)
+{
+    if (strcmp(culprit, "string") == 0)
+    {
+        const char *string;
+        raisePrologDomainExeption(string,2,expectation,"raising_DomainError");
+    }
+    else
+    {
+        float number;
+        raisePrologDomainExeption(number,2,expectation,"raising_DomainError");
+    }
+}
diff --git a/src/helper_files/helper_tests.pl b/src/helper_files/helper_tests.pl
index 3c6dc20..9a87972 100644
--- a/src/helper_files/helper_tests.pl
+++ b/src/helper_files/helper_tests.pl
@@ -4,24 +4,309 @@
 :- use_module(library(plunit)).
 
 
-:- use_module(library(csv)).
+%% requirements of library(struct)
+:- load_files(library(str_decl),
+                [when(compile_time), if(changed)]).
+
+:- use_module(library(structs)).
+
 :- use_module('helper.pl').
 
+:- use_module(library(csv)).
+
+%% type definitions for the float array
+:- foreign_type
+        float32          = float_32,
+        float_array      = array(float32).
+
+
+
+%%
+%% TESTING Integer
+%%
+:- begin_tests(integer).
+
+%% Failure 
+
+test(integer_Input_Wrong_Input, [error(type_error(number, a),_)]) :-
+        testing_Taking_IntegerI(a, _).
+
+%% Success
+
+test(integer_Input, [true(Return =:= 1)]) :-
+        testing_Taking_IntegerI(1, Return).
+
+test(integer_Output, [true(Return =:= 1)]) :-
+        testing_Returning_IntegerI(Return).
+        
+:- end_tests(integer).
+
+
+%%
+%% TESTING Float
+%%
+:- begin_tests(float).
+
+%% Failure 
+test(float_Input, [true(Return =:= 0)]) :-
+        testing_Taking_DoubleI(2.0, Return).
+
+test(float_Input_Wrong_Input, [error(type_error(number, a),_)]) :-
+        testing_Taking_DoubleI(a, _).
+
+
+%% Success
+
+test(float_Input, [true(Return =:= 1)]) :-
+        testing_Taking_DoubleI(1.0, Return).
+
+
+test(float_Output, [true(Return =:= 1.0)]) :-
+        testing_Returning_DoubleI(Return).
+        
+:- end_tests(float).
+
+
+%%
+%% TESTING String
+%%
+:- begin_tests(string).
+
+%% Failure 
+test(string_Input, [true(Return =:= 0)]) :-
+        testing_Taking_StringI(false, Return).
+
+test(string_Input_Wrong_Input, [error(type_error(atom, 100),_)]) :-
+        testing_Taking_StringI(100, _).
+
+%% Success
+
+test(string_Input, [true(Return =:= 1)]) :-
+        testing_Taking_StringI(true, Return).
+
+test(string_Output) :-
+        testing_Returning_StringI('true').
+        
+:- end_tests(string).
+
+
+%%
+%% TESTING Vector
+%%
+:- begin_tests(vector).
+
+%% Failure 
+
+test(vector_Input_Empty_List, [true(Return=:=1)]) :-
+        convert_list_to_float_array([], array(Xsize, X)),
+        testing_Taking_Float_VectorI(X, Xsize, Return).
+
+test(vector_Input_Bad_List_Input, fail) :-
+        convert_list_to_float_array(2, array(Xsize, X)),
+        testing_Taking_Float_VectorI(X, Xsize, _).
+
+%% Success
+
+test(vector_Input, [true(Return =:= 1)]) :-
+        convert_list_to_float_array([1.0,2.0,3.0,4.0,5.0], array(Xsize, X)),
+        testing_Taking_Float_VectorI(X, Xsize, Return).
+
+test(vector_Input) :-
+        testing_Returning_Float_VectorI(X, Xsize),
+        convert_float_array_to_list(X, Xsize, [0.0,1.0,2.0,3.0,4.0]).
+        
+:- end_tests(vector).
+
+
+%%
+%% TESTING Matrix
+%%
+:- begin_tests(matrix).
+
+%% Failure 
+test(matrix_Input_Too_High_DataPoint_Dim, fail) :-
+        convert_list_to_float_array([0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0], 20, array(Xsize, XDataPointDim,X)),
+        testing_Taking_Float_MatrixI(X, Xsize, XDataPointDim, _).
+
+test(matrix_Input_Empty_List1, fail) :-
+        convert_list_to_float_array([], 2, array(Xsize, XDataPointDim,X)),
+        testing_Taking_Float_MatrixI(X, Xsize, XDataPointDim, _).
+
+test(matrix_Input_Empty_List2, fail) :-
+        convert_list_to_float_array([], 0, array(Xsize, XDataPointDim,X)),
+        testing_Taking_Float_MatrixI(X, Xsize, XDataPointDim, _).
+
+test(matrix_Input_Empty_List3, fail) :-
+        convert_list_to_float_array([], 1, array(Xsize, XDataPointDim,X)),
+        testing_Taking_Float_MatrixI(X, Xsize, XDataPointDim, _).
+
+test(matrix_Input_Wrong_List_Input, fail) :-
+        convert_list_to_float_array(1, 2, array(Xsize, XDataPointDim,X)),
+        testing_Taking_Float_MatrixI(X, Xsize, XDataPointDim, _).
+
+test(matrix_Input_Bad_Output_Of_Data, fail) :-
+        convert_list_to_float_array([0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0], 2, array(Xsize, X)),
+        testing_Taking_Float_MatrixI(X, Xsize, _, _).
 
-%% TODO: fully tests the helper functions and predicates
-:- begin_tests(b).
+test(matrix_Input_Different_Input, [true(Return =:= 0)]) :-
+        convert_list_to_float_array([0.0,1.0,2.0,3.0,-4.0,5.0,6.0,10.0], 2, array(Xsize, XDataPointDim,X)),
+        testing_Taking_Float_MatrixI(X, Xsize, XDataPointDim, Return).
 
-test(matrix) :-
+%% Success
+
+test(matrix_Input, [true(Return =:= 1)]) :-
+        convert_list_to_float_array([0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0], 2, array(Xsize, XDataPointDim,X)),
+        testing_Taking_Float_MatrixI(X, Xsize, XDataPointDim, Return).
+
+test(matrix_Output) :-
+        testing_Returning_Float_MatrixI(X, XDataPointAmount, XDataPointDim),
+        convert_float_array_to_2d_list(X, XDataPointAmount, XDataPointDim, [[0.0,1.0],[2.0,3.0],[4.0,5.0],[6.0,7.0]]).
+        
+:- end_tests(matrix).
+
+
+%%
+%% TESTING Conversion
+%%
+:- begin_tests(conversion).
+
+%% Failure 
+
+%% Success
+test(vector_Conversion) :-
+        convert_list_to_float_array([0.0,0.1,0.2,0.3], array(Xsize, X)),
+        convert_float_array_to_list(X, Xsize, ResultList),
+        print(ResultList),
+        print('\n').
+
+
+test(matrix_Conversion) :-
         open('src/data_csv/iris2.csv', read, File),
         take_csv_row(File, skipFirstRow, 2, Records),
         print(Records),
         print('\n'),
-        convert_list_to_float_array(Records, 4, array(Xsize, Xrownum, X)),
-        convert_float_array_to_2d_list(X, Xrownum, 2, ProbsList),
+        convert_list_to_float_array(Records, 4, array(_, XDataDimension, X)),
+        convert_float_array_to_2d_list(X, 2, XDataDimension, ProbsList),
         print(ProbsList),
         print('\n').
         
-:- end_tests(b).
+:- end_tests(conversion).
+
+
+%%
+%% TESTING Helper Predicate len/2
+%%
+:- begin_tests(len).
+
+%% Failure 
+
+test(len_Bad_Input, fail) :-
+        len(1, _).
+
+%% Success
+
+test(len_Normal_Use, [true(Length =:= 3)]) :-
+        len([1,2,3], Length).
+
+test(len_Empty_List, [true(Length =:= 0)]) :-
+        len([], Length).
+
+test(len_Mixed_List) :-
+        len([1,2,a,9.0], 4).
+        
+:- end_tests(len).
+
+
+%%
+%% TESTING Helper Predicate convert_record_to_arr/2
+%%
+:- begin_tests(convert_record_to_arr).
+
+%% Failure 
+test(convert_record_to_arr_Bad_Input, fail) :-
+        convert_record_to_arr([1,2,3,a], _).
+
+%% Success
+
+test(convert_record_to_arr_Normal_Use) :-
+        convert_record_to_arr([float(1.0,_), float(2.0,_), string(_)], [1.0,2.0]).
+        
+:- end_tests(convert_record_to_arr).
+
+
+%%
+%% TESTING Helper Predicate take_rows_from_iris_CSV
+%%
+:- begin_tests(take_rows_from_iris_CSV).
+
+%% Failure 
+test(take_rows_from_iris_CSV_Negative_Amount, fail) :-
+        take_rows_from_iris_CSV(-2, _).
+
+test(take_rows_from_iris_CSV_Taking_Too_Much, fail) :-
+        take_rows_from_iris_CSV(160, _).
+
+%% Success
+
+test(take_rows_from_iris_CSV_Normal_Use) :-
+        take_rows_from_iris_CSV(2, [5.1,3.5,1.4,0.2,4.9,3.0,1.4,0.2]).
+        
+:- end_tests(take_rows_from_iris_CSV).
+
+
+%%
+%% TESTING raising Prolog Errors
+%%
+:- begin_tests(errors).
+
+%% Failure 
+
+test(testing_Raising_SystemError_Normal_Use, [error(_, system_error('error_Message'))]) :-
+        testing_Raising_SystemErrorI(error_Message).
+
+test(testing_Raising_DomainError_Normal_Use, [error(domain_error('error_Message' , []), _)]) :-
+        testing_Raising_DomainErrorI(error_Message, string).
+
+test(testing_Raising_DomainError_Normal_Use, [error(domain_error('error_Message' , 0.0), _)]) :-
+        testing_Raising_DomainErrorI(error_Message, number).
+
+%% Success
+
+:- end_tests(errors).
+
 
 run_helper_tests :-
-        run_tests.
\ No newline at end of file
+        run_tests.
+
+
+foreign(testing_Taking_Integer, c, testing_Taking_IntegerI(+integer, [-integer])).
+foreign(testing_Taking_Double, c, testing_Taking_DoubleI(+float32, [-integer])).
+foreign(testing_Taking_String, c, testing_Taking_StringI(+string, [-integer])).
+foreign(testing_Taking_Float_Vector, c, testing_Taking_Float_VectorI(+pointer(float_array), +integer, [-integer])).
+foreign(testing_Taking_Float_Matrix, c, testing_Taking_Float_MatrixI(+pointer(float_array), +integer, +integer, [-integer])).
+
+foreign(testing_Returning_Integer, c, testing_Returning_IntegerI(-integer)).
+foreign(testing_Returning_Double, c, testing_Returning_DoubleI(-float32)).
+foreign(testing_Returning_String, c, testing_Returning_StringI(-string)).
+foreign(testing_Returning_Float_Vector, c, testing_Returning_Float_VectorI(-pointer(float_array), -integer)).
+foreign(testing_Returning_Float_Matrix, c, testing_Returning_Float_MatrixI(-pointer(float_array), -integer, -integer)).
+
+foreign(testing_Raising_SystemError, c, testing_Raising_SystemErrorI(+string)).
+foreign(testing_Raising_DomainError, c, testing_Raising_DomainErrorI(+string, +string)).
+
+
+%% Defines the functions that get connected from helper_tests.cpp
+foreign_resource(helper_tests, [testing_Taking_Integer,
+                                testing_Taking_Double,
+                                testing_Taking_String,
+                                testing_Taking_Float_Vector,
+                                testing_Taking_Float_Matrix,
+                                testing_Returning_Integer,
+                                testing_Returning_Double,
+                                testing_Returning_String,
+                                testing_Returning_Float_Vector,
+                                testing_Returning_Float_Matrix,
+                                testing_Raising_SystemError,
+                                testing_Raising_DomainError]).
+
+:- load_foreign_resource(helper_tests).
-- 
GitLab