diff --git a/.github/workflows/run-sml-tests.yml b/.github/workflows/run-sml-tests.yml index 3a324f4..3f94964 100644 --- a/.github/workflows/run-sml-tests.yml +++ b/.github/workflows/run-sml-tests.yml @@ -1,4 +1,4 @@ -name: Run SMLUnit Unit Tests +name: Run SML/NJ Custom Tests on: push: @@ -19,16 +19,9 @@ jobs: run: | sudo apt-get update sudo apt-get install smlnj # Install SML/NJ - sudo apt-get install smlsharp # Install SML# - sudo apt-get install llvm-14 # Install LLVM 14 - sudo apt-get install libmyth # Install mythril - # Add the path to the libmyth.so file to the LD_LIBRARY_PATH - export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH - # Create a symbolic link to the libmyth.so file - sudo ln -s /usr/lib/x86_64-linux-gnu/libmyth.so.0 /usr/lib/x86_64-linux-gnu/libmyth.so - name: Run SML tests run: | chmod +x test - ./test + ./test false diff --git a/.github/workflows/run-smlsharp-tests.yml b/.github/workflows/run-smlsharp-tests.yml new file mode 100644 index 0000000..4c1bc28 --- /dev/null +++ b/.github/workflows/run-smlsharp-tests.yml @@ -0,0 +1,33 @@ +name: Run SMLUnit Unit Tests with SML# + +on: + push: + branches: + - master + - dev + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + + if: contains(github.event.head_commit.message, '[smlsharp-test]') + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Install SML# + run: | + sudo apt-get update + sudo apt-get install smlnj # Install SML/NJ + sudo apt-get install smlsharp # Install SML# + sudo apt-get install llvm-14 # Install LLVM 14 + sudo apt-get install libmyth # Install mythril + export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH + sudo ln -s /usr/lib/x86_64-linux-gnu/libmyth.so.0 /usr/lib/x86_64-linux-gnu/libmyth.so + + - name: Run SML tests + run: | + chmod +x test + ./test true diff --git a/.gitignore b/.gitignore index 2d652ce..28a4c54 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +tests/**/skip*.sm* + **repo-link.txt links.md **/*temp.md diff --git a/src/ica05/ica5.sml b/src/ica05/ica5.sml index b271578..ac9cb21 100644 --- a/src/ica05/ica5.sml +++ b/src/ica05/ica5.sml @@ -30,7 +30,7 @@ fun reverseList([]) = [] | reverseList(li) = reverseList(tl(li)) @ [hd(li)]; fun removeZeros([]) = [] - | removeZeros(li) = + | removeZeros(li) = if hd(li) = 0 then removeZeros(tl(li)) else hd(li) :: removeZeros(tl(li)); diff --git a/src/ica05/ica6.sml b/src/ica05/ica6.sml deleted file mode 100644 index 0ce367d..0000000 --- a/src/ica05/ica6.sml +++ /dev/null @@ -1,124 +0,0 @@ -fun runTestCases([]) = () - | runTestCases(testCaseList) = - let - val (f, param, expected) = hd(testCaseList); - val result = f(param); - in - if result <> expected then print("Test failed\n") - else print(""); - runTestCases(tl(testCaseList)) - end; - -(* Question 1 *) -fun log2(1) = 0 - | log2(n) = 1 + log2(n div 2); - -(* Question 2 *) -fun factorial(0) = 1 - | factorial(n) = n * factorial(n-1); - -(* Question 3 *) -fun fib(0) = 0 - | fib(1) = 1 - | fib(n) = fib(n-2) + fib(n-1); - -(* Question 4 *) -fun countZeros([]) = 0 - | countZeros(li) = - if hd(li) = 0 then 1 + countZeros(tl(li)) - else countZeros(tl(li)); - -(* Question 5 *) -fun orList([]) = false - | orList(boolList) = - orList(tl(boolList)) orelse hd(boolList); - -(* Question 6 *) -fun andList([]) = true - | andList(boolList) = - hd(boolList) andalso andList(boolList); - -(* Question 7 *) -fun addLists([], []) = [] - | addLists([], li2) = hd(li2) :: - addLists([], tl(li2)) - | addLists(li1, []) = hd(li1) :: - addLists(tl(li1), []) - | addLists(li1, li2) = - hd(li1) + hd(li2) :: - addLists(tl(li1), tl(li2)); - -(* Question 8 *) -fun reverseList([]) = [] - | reverseList(li) = - reverseList(tl(li)) @ [hd(li)]; - -(* Question 9 *) -fun removeZeros([]) = [] - | removeZeroes(li) = - if hd(li) = 0 then li - else removeZeros(tl(li)) :: hd(li); - -(* Question 10 *) -fun combineLists([], [], operator) = [] - | combineLists([], li2, operator) = - hd(li2) :: - combineLists([], tl(li2), operator) - | combineLists(li1, [], operator) = - hd(li1) :: - combineLists(tl(l1), [], operator) - | combineLists(li1, li2, operator) = - operator(hd(li1) + hd(li2)) :: - combineLists(tl(l1), tl(l2), operator); - -val testCasesOrList = [ - (orList, [true, true, true], true), (* true *) - (orList, [true, false, true], true), (* true *) - (orList, [false, false, false], false), (* false *) - (orList, [true, true, false], true), (* true *) - (orList, [false, false, true], true) (* true *) -]; -runTestCases(testCasesOrList); - -val testCasesLog2 = [ - (log2, 1, 0), (* 2^0 = 1 *) - (log2, 2, 1), (* 2^1 = 2 *) - (log2, 4, 2), (* 2^2 = 4 *) - (log2, 8, 3), (* 2^3 = 8 *) - (log2, 16, 4) (* 2^4 = 16 *) -]; -(* runTestCases(testCasesLog2); *) - -val testCasesFactorial = [ - (factorial, 0, 1), (* 0! = 1 *) - (factorial, 1, 1), (* 1! = 1 *) - (factorial, 2, 2), (* 2! = 2 *) - (factorial, 3, 6), (* 3! = 6 *) - (factorial, 4, 24), (* 4! = 24 *) - (factorial, 5, 120) (* 5! = 120 *) -]; -(* runTestCases(testCasesFactorial); *) - -val testCasesFib = [ - (* a_n = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34} *) - (fib, 0, 0), (* a_0 = 0 *) - (fib, 1, 1), (* a_1 = 1 *) - (fib, 2, 1), (* a_2 = 1 *) - (fib, 3, 2), (* a_3 = 2 *) - (fib, 4, 3), (* a_4 = 3 *) - (fib, 5, 5), (* a_5 = 5 *) - (fib, 6, 8), (* a_6 = 8 *) - (fib, 7, 13) (* a_7 = 13 *) -]; - -(* runTestCases(testCasesFib); *) -val testCasesCountZeros = [ - (countZeros, [0, 1, 0, 1, 0], 3), (* 3 zeros *) - (countZeros, [1, 1, 1, 1, 1], 0), (* 0 zeros *) - (countZeros, [0, 0, 0, 0, 0], 5), (* 5 zeros *) - (countZeros, [], 0), (* 0 zeros *) - (countZeros, [0], 0), (* 1 zeros *) - (countZeros, [1], 0) (* 0 zeros *) -]; - -(* runTestCases(testCasesCountZeros); *) diff --git a/test b/test index 42ac6f2..c3aa374 100755 --- a/test +++ b/test @@ -1,7 +1,11 @@ #!/bin/bash -#sudo find / -name "libmyth.*" -export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH +# +# Args: +# $1: Use SMLUnit (true/false) +# + +USE_SMLUNIT=${1:-false} # Define the path to the tests folder TESTS_DIR="./tests" @@ -18,5 +22,16 @@ fi # Load each test file in the SML interpreter for TEST_FILE in $TEST_FILES; do echo "Running tests in: $TEST_FILE" - smlsharp < "$TEST_FILE" + + # If we are using SMLUnit, load the SMLUnit library before loading the test file + if [ "$USE_SMLUNIT" = true ]; then + echo "Using SMLUnit" + export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH + # smlsharp < "$TESTS_DIR/SMLUnit/smlunit-lib.smi" + smlsharp < "$TEST_FILE" + + # Else, just use sml to load the test file + else + sml < "$TEST_FILE" + fi done diff --git a/tests/temp.sml b/tests/temp.sml deleted file mode 100644 index 5e90ba7..0000000 --- a/tests/temp.sml +++ /dev/null @@ -1,99 +0,0 @@ -use "src/ica05/ica5.sml" (* Test runner called from root of project *) - -(* Tests for log2 *) -val test_log2 = SU.suite "Log2 Tests" [ - SU.test "log2(1)" (fn () => SU.assertEqual (log2 1, 0)), - SU.test "log2(2)" (fn () => SU.assertEqual (log2 2, 1)), - SU.test "log2(4)" (fn () => SU.assertEqual (log2 4, 2)), - SU.test "log2(8)" (fn () => SU.assertEqual (log2 8, 3)), - SU.test "log2(16)" (fn () => SU.assertEqual (log2 16, 4)) -] - -(* Tests for factorial *) -val test_factorial = SU.suite "Factorial Tests" [ - SU.test "factorial(0)" (fn () => SU.assertEqual (factorial 0, 1)), - SU.test "factorial(1)" (fn () => SU.assertEqual (factorial 1, 1)), - SU.test "factorial(2)" (fn () => SU.assertEqual (factorial 2, 2)), - SU.test "factorial(3)" (fn () => SU.assertEqual (factorial 3, 6)), - SU.test "factorial(4)" (fn () => SU.assertEqual (factorial 4, 24)), - SU.test "factorial(5)" (fn () => SU.assertEqual (factorial 5, 120)) -] - -(* Tests for fib *) -val test_fib = SU.suite "Fibonacci Tests" [ - SU.test "fib(0)" (fn () => SU.assertEqual (fib 0, 0)), - SU.test "fib(1)" (fn () => SU.assertEqual (fib 1, 1)), - SU.test "fib(2)" (fn () => SU.assertEqual (fib 2, 1)), - SU.test "fib(3)" (fn () => SU.assertEqual (fib 3, 2)), - SU.test "fib(4)" (fn () => SU.assertEqual (fib 4, 3)), - SU.test "fib(5)" (fn () => SU.assertEqual (fib 5, 5)), - SU.test "fib(6)" (fn () => SU.assertEqual (fib 6, 8)), - SU.test "fib(7)" (fn () => SU.assertEqual (fib 7, 13)) -] - -(* Tests for countZeros *) -val test_countZeros = SU.suite "Count Zeros Tests" [ - SU.test "countZeros([0,1,0,1,0])" (fn () => SU.assertEqual (countZeros [0,1,0,1,0], 3)), - SU.test "countZeros([1,1,1,1,1])" (fn () => SU.assertEqual (countZeros [1,1,1,1,1], 0)), - SU.test "countZeros([0,0,0,0,0])" (fn () => SU.assertEqual (countZeros [0,0,0,0,0], 5)), - SU.test "countZeros([])" (fn () => SU.assertEqual (countZeros [], 0)), - SU.test "countZeros([0])" (fn () => SU.assertEqual (countZeros [0], 1)), - SU.test "countZeros([1])" (fn () => SU.assertEqual (countZeros [1], 0)) -] - -(* Tests for orList *) -val test_orList = SU.suite "orList Tests" [ - SU.test "orList([true, true, true])" (fn () => SU.assertEqual (orList [true, true, true], true)), - SU.test "orList([true, false, true])" (fn () => SU.assertEqual (orList [true, false, true], true)), - SU.test "orList([false, false, false])" (fn () => SU.assertEqual (orList [false, false, false], false)), - SU.test "orList([true, true, false])" (fn () => SU.assertEqual (orList [true, true, false], true)), - SU.test "orList([false, false, true])" (fn () => SU.assertEqual (orList [false, false, true], true)) -] - -(* Tests for andList *) -val test_andList = SU.suite "andList Tests" [ - SU.test "andList([true, true, true])" (fn () => SU.assertEqual (andList [true, true, true], true)), - SU.test "andList([true, false, true])" (fn () => SU.assertEqual (andList [true, false, true], false)), - SU.test "andList([false, false, false])" (fn () => SU.assertEqual (andList [false, false, false], false)), - SU.test "andList([true, true, false])" (fn () => SU.assertEqual (andList [true, true, false], false)), - SU.test "andList([true, true, true])" (fn () => SU.assertEqual (andList [true, true, true], true)) -] - -(* Tests for addLists *) -val test_addLists = SU.suite "addLists Tests" [ - SU.test "addLists([1,2,3], [4,5,6])" (fn () => SU.assertEqual (addLists([1,2,3], [4,5,6]), [5,7,9])), - SU.test "addLists([1,2], [3,4,5])" (fn () => SU.assertEqual (addLists([1,2], [3,4,5]), [4,6,5])), - SU.test "addLists([1,2,3], [4])" (fn () => SU.assertEqual (addLists([1,2,3], [4]), [5,2,3])) -] - -(* Tests for reverseList *) -val test_reverseList = SU.suite "reverseList Tests" [ - SU.test "reverseList([1,2,3])" (fn () => SU.assertEqual (reverseList [1,2,3], [3,2,1])), - SU.test "reverseList([])" (fn () => SU.assertEqual (reverseList [], [])), - SU.test "reverseList([1])" (fn () => SU.assertEqual (reverseList [1], [1])) -] - -(* Tests for removeZeros *) -val test_removeZeros = SU.suite "removeZeros Tests" [ - SU.test "removeZeros([0,1,0,2,0,3])" (fn () => SU.assertEqual (removeZeros [0,1,0,2,0,3], [1,2,3])), - SU.test "removeZeros([1,2,3])" (fn () => SU.assertEqual (removeZeros [1,2,3], [1,2,3])), - SU.test "removeZeros([0,0,0])" (fn () => SU.assertEqual (removeZeros [0,0,0], [])) -] - -(* Tests for combineLists *) -val test_combineLists = SU.suite "combineLists Tests" [ - SU.test "combineLists([1,2,3], [4,5,6], fn x => x)" (fn () => SU.assertEqual (combineLists([1,2,3], [4,5,6], fn x => x), [5,7,9])), - SU.test "combineLists([1,2], [3,4], fn x => x * 2)" (fn () => SU.assertEqual (combineLists([1,2], [3,4], fn x => x * 2), [8,12])) -] - -(* Run all tests *) -val _ = SU.run test_log2 -val _ = SU.run test_factorial -val _ = SU.run test_fib -val _ = SU.run test_countZeros -val _ = SU.run test_orList -val _ = SU.run test_andList -val _ = SU.run test_addLists -val _ = SU.run test_reverseList -val _ = SU.run test_removeZeros -val _ = SU.run test_combineLists diff --git a/tests/test_ica5.sml b/tests/test_ica5.sml index 55da8c4..91621da 100644 --- a/tests/test_ica5.sml +++ b/tests/test_ica5.sml @@ -1,105 +1,148 @@ -structure Test = SMLUnit.Test -structure Assert = SMLUnit.Assert -val _ = Assert.assertTrue (true) -(* open SU *) -(* val _ = SU.assertEqual (1, 1) *) - -use "src/ica05/ica5.sml" (* Test runner called from root of project *) - -(* Tests for log2 *) -val test_log2 = SU.suite "Log2 Tests" [ - SU.test "log2(1)" (fn () => SU.assertEqual (log2 1, 0)), - SU.test "log2(2)" (fn () => SU.assertEqual (log2 2, 1)), - SU.test "log2(4)" (fn () => SU.assertEqual (log2 4, 2)), - SU.test "log2(8)" (fn () => SU.assertEqual (log2 8, 3)), - SU.test "log2(16)" (fn () => SU.assertEqual (log2 16, 4)) -] - -(* Tests for factorial *) -val test_factorial = SU.suite "Factorial Tests" [ - SU.test "factorial(0)" (fn () => SU.assertEqual (factorial 0, 1)), - SU.test "factorial(1)" (fn () => SU.assertEqual (factorial 1, 1)), - SU.test "factorial(2)" (fn () => SU.assertEqual (factorial 2, 2)), - SU.test "factorial(3)" (fn () => SU.assertEqual (factorial 3, 6)), - SU.test "factorial(4)" (fn () => SU.assertEqual (factorial 4, 24)), - SU.test "factorial(5)" (fn () => SU.assertEqual (factorial 5, 120)) -] - -(* Tests for fib *) -val test_fib = SU.suite "Fibonacci Tests" [ - SU.test "fib(0)" (fn () => SU.assertEqual (fib 0, 0)), - SU.test "fib(1)" (fn () => SU.assertEqual (fib 1, 1)), - SU.test "fib(2)" (fn () => SU.assertEqual (fib 2, 1)), - SU.test "fib(3)" (fn () => SU.assertEqual (fib 3, 2)), - SU.test "fib(4)" (fn () => SU.assertEqual (fib 4, 3)), - SU.test "fib(5)" (fn () => SU.assertEqual (fib 5, 5)), - SU.test "fib(6)" (fn () => SU.assertEqual (fib 6, 8)), - SU.test "fib(7)" (fn () => SU.assertEqual (fib 7, 13)) -] - -(* Tests for countZeros *) -val test_countZeros = SU.suite "Count Zeros Tests" [ - SU.test "countZeros([0,1,0,1,0])" (fn () => SU.assertEqual (countZeros [0,1,0,1,0], 3)), - SU.test "countZeros([1,1,1,1,1])" (fn () => SU.assertEqual (countZeros [1,1,1,1,1], 0)), - SU.test "countZeros([0,0,0,0,0])" (fn () => SU.assertEqual (countZeros [0,0,0,0,0], 5)), - SU.test "countZeros([])" (fn () => SU.assertEqual (countZeros [], 0)), - SU.test "countZeros([0])" (fn () => SU.assertEqual (countZeros [0], 1)), - SU.test "countZeros([1])" (fn () => SU.assertEqual (countZeros [1], 0)) -] - -(* Tests for orList *) -val test_orList = SU.suite "orList Tests" [ - SU.test "orList([true, true, true])" (fn () => SU.assertEqual (orList [true, true, true], true)), - SU.test "orList([true, false, true])" (fn () => SU.assertEqual (orList [true, false, true], true)), - SU.test "orList([false, false, false])" (fn () => SU.assertEqual (orList [false, false, false], false)), - SU.test "orList([true, true, false])" (fn () => SU.assertEqual (orList [true, true, false], true)), - SU.test "orList([false, false, true])" (fn () => SU.assertEqual (orList [false, false, true], true)) -] - -(* Tests for andList *) -val test_andList = SU.suite "andList Tests" [ - SU.test "andList([true, true, true])" (fn () => SU.assertEqual (andList [true, true, true], true)), - SU.test "andList([true, false, true])" (fn () => SU.assertEqual (andList [true, false, true], false)), - SU.test "andList([false, false, false])" (fn () => SU.assertEqual (andList [false, false, false], false)), - SU.test "andList([true, true, false])" (fn () => SU.assertEqual (andList [true, true, false], false)), - SU.test "andList([true, true, true])" (fn () => SU.assertEqual (andList [true, true, true], true)) -] - -(* Tests for addLists *) -val test_addLists = SU.suite "addLists Tests" [ - SU.test "addLists([1,2,3], [4,5,6])" (fn () => SU.assertEqual (addLists([1,2,3], [4,5,6]), [5,7,9])), - SU.test "addLists([1,2], [3,4,5])" (fn () => SU.assertEqual (addLists([1,2], [3,4,5]), [4,6,5])), - SU.test "addLists([1,2,3], [4])" (fn () => SU.assertEqual (addLists([1,2,3], [4]), [5,2,3])) -] - -(* Tests for reverseList *) -val test_reverseList = SU.suite "reverseList Tests" [ - SU.test "reverseList([1,2,3])" (fn () => SU.assertEqual (reverseList [1,2,3], [3,2,1])), - SU.test "reverseList([])" (fn () => SU.assertEqual (reverseList [], [])), - SU.test "reverseList([1])" (fn () => SU.assertEqual (reverseList [1], [1])) -] - -(* Tests for removeZeros *) -val test_removeZeros = SU.suite "removeZeros Tests" [ - SU.test "removeZeros([0,1,0,2,0,3])" (fn () => SU.assertEqual (removeZeros [0,1,0,2,0,3], [1,2,3])), - SU.test "removeZeros([1,2,3])" (fn () => SU.assertEqual (removeZeros [1,2,3], [1,2,3])), - SU.test "removeZeros([0,0,0])" (fn () => SU.assertEqual (removeZeros [0,0,0], [])) -] - -(* Tests for combineLists *) -val test_combineLists = SU.suite "combineLists Tests" [ - SU.test "combineLists([1,2,3], [4,5,6], fn x => x)" (fn () => SU.assertEqual (combineLists([1,2,3], [4,5,6], fn x => x), [5,7,9])), - SU.test "combineLists([1,2], [3,4], fn x => x * 2)" (fn () => SU.assertEqual (combineLists([1,2], [3,4], fn x => x * 2), [8,12])) -] - -(* Run all tests *) -val _ = SU.run test_log2 -val _ = SU.run test_factorial -val _ = SU.run test_fib -val _ = SU.run test_countZeros -val _ = SU.run test_orList -val _ = SU.run test_andList -val _ = SU.run test_addLists -val _ = SU.run test_reverseList -val _ = SU.run test_removeZeros -val _ = SU.run test_combineLists +use "src/ica05/ica5.sml"; + +(* TODO: the test runner functions should be moved to a separate file *) + +(* Function to color the output in the terminal *) +fun red(s) = "\027[31m" ^ s ^ "\027[0m" +fun green(s) = "\027[32m" ^ s ^ "\027[0m" + + +(* Enhanced test case runner with more visual indicators *) +fun runTestCases([]) = () + | runTestCases(testCaseList) = + let + val (f, param, expected) = hd(testCaseList); + val result = f(param); + val testMessage = + if result <> expected then + red("Test failed\n") ^ + "Expected: " ^ Int.toString(expected) ^ "\n" ^ + "Actual: " ^ Int.toString(result) ^ "\n\n" + else + green("Test passed\n"); + in + print(testMessage); + runTestCases(tl(testCaseList)) + end; + + +val testCasesLog2 = [ + (log2, 1, 0), (* 2^0 = 1 *) + (log2, 2, 1), (* 2^1 = 2 *) + (log2, 4, 2), (* 2^2 = 4 *) + (log2, 8, 3), (* 2^3 = 8 *) + (log2, 16, 4), (* 2^4 = 16 *) + (log2, 32, 5), (* 2^5 = 32 *) + (log2, 64, 6), (* 2^6 = 64 *) + (log2, 128, 7), (* 2^7 = 128 *) + (log2, 256, 8) (* 2^8 = 256 *) +]; +runTestCases(testCasesLog2); + +val testCasesFactorial = [ + (factorial, 0, 1), (* 0! = 1 *) + (factorial, 1, 1), (* 1! = 1 *) + (factorial, 2, 2), (* 2! = 2 *) + (factorial, 3, 6), (* 3! = 6 *) + (factorial, 4, 24), (* 4! = 24 *) + (factorial, 5, 120), (* 5! = 120 *) + (factorial, 6, 720), (* 6! = 720 *) + (factorial, 7, 5040), (* 7! = 5040 *) + (factorial, 8, 40320), (* 8! = 40320 *) + (factorial, 10, 3628800) (* 10! = 3628800 *) +]; +runTestCases(testCasesFactorial); + +val testCasesFib = [ + (* a_n = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55} *) + (fib, 0, 0), + (fib, 1, 1), + (fib, 2, 1), + (fib, 3, 2), + (fib, 4, 3), + (fib, 5, 5), + (fib, 6, 8), + (fib, 7, 13), + (fib, 8, 21), + (fib, 9, 34), + (fib, 10, 55) +]; +runTestCases(testCasesFib); + +val testCasesCountZeros = [ + (countZeros, [0, 1, 0, 1, 0], 3), + (countZeros, [1, 1, 1, 1, 1], 0), + (countZeros, [0, 0, 0, 0, 0], 5), + (countZeros, [], 0), + (countZeros, [0], 1), + (countZeros, [1], 0), + (countZeros, [0, 0, 0, 1, 0], 4), + (countZeros, [1, 0, 1, 0, 1], 2), + (countZeros, [0, 0, 1, 0, 0, 0], 5) +]; +runTestCases(testCasesCountZeros); + +val testCasesOrList = [ + (orList, [true, true, true], true), + (orList, [true, false, true], true), + (orList, [false, false, false], false), + (orList, [true, true, false], true), + (orList, [false, false, true], true), + (orList, [false, false, false, false], false), + (orList, [false, true, false, true], true), + (orList, [], false), (* Empty list case *) + (orList, [false], false), (* Single false element *) + (orList, [true], true) (* Single true element *) +]; +runTestCases(testCasesOrList); + +val testCasesAndList = [ + (andList, [true, true, true], true), + (andList, [true, false, true], false), + (andList, [false, false, false], false), + (andList, [], true), (* Empty list case *) + (andList, [true], true), + (andList, [false], false) +]; +runTestCases(testCasesAndList); + +val testCasesAddLists = [ + (addLists, ([1, 2, 3], [4, 5, 6]), [5, 7, 9]), + (addLists, ([1, 2], [4, 5, 6]), [5, 7, 6]), + (addLists, ([1, 2, 3], []), [1, 2, 3]), + (addLists, ([], [4, 5, 6]), [4, 5, 6]), + (addLists, ([], []), []) +]; +runTestCases(testCasesAddLists); + +val testCasesReverseList = [ + (reverseList, [1, 2, 3], [3, 2, 1]), + (reverseList, [1], [1]), + (reverseList, [], []), + (reverseList, [4, 5, 6, 7], [7, 6, 5, 4]) +]; +runTestCases(testCasesReverseList); + +fun removeZeros([]) = [] + | removeZeros(li) = + if hd(li) = 0 then removeZeros(tl(li)) + else hd(li) :: removeZeros(tl(li)); + +val testCasesRemoveZeros = [ + (removeZeros, [0, 1, 0, 2], [1, 2]), + (removeZeros, [0, 0, 0], []), + (removeZeros, [1, 2, 3], [1, 2, 3]), + (removeZeros, [], []), + (removeZeros, [0], []) +]; +runTestCases(testCasesRemoveZeros); + +fun add(x, y) = x + y; + +val testCasesCombineLists = [ + (combineLists, ([1, 2, 3], [4, 5, 6], add), [5, 7, 9]), + (combineLists, ([1, 2], [4, 5, 6], add), [5, 7, 6]), + (combineLists, ([1, 2, 3], [], add), [1, 2, 3]), + (combineLists, ([], [4, 5, 6], add), [4, 5, 6]) +]; +runTestCases(testCasesCombineLists);