diff --git a/Makefile b/Makefile index dcb4033..1b84f2a 100644 --- a/Makefile +++ b/Makefile @@ -1,34 +1,32 @@ -code := $(wildcard src/*) -test_directories := $(wildcard tests/*) -test_targets := $(addsuffix /pass,$(test_directories)) -existing_passes := $(wildcard tests/*/pass) -out_files := $(wildcard tests/*/*.out) -out_files += $(wildcard tests/*/out.*) - -.PHONY: help build run test clean +.PHONY: help run test clean format help: # Show help for each of the commented Makefile recipes. @grep -E '^[a-zA-Z0-9 -]+:.*#' Makefile | sort | while read -r l; \ do printf "\033[1;32m$$(echo $$l | cut -f 1 -d':')\033[00m:$$(echo $$l | cut -f 2- -d'#')\n"; done -tests/%/pass: $(code) - cd $(patsubst %/pass,%/,$@) && $(MAKE) +run: target/Main.out # Runs your compiled main code. + ./target/Main.out -build: $(code) # Builds your code alone (does not build not any unit tests). - cd src && $(MAKE) +target/Main.out: src/* + ghc -g -fprof-auto -prof -Wall src/*.hs -o target/Main.out + @rm -f src/*.o src/*.hi -run: build # Runs your compiled main code (does not pass any args or std-io). - ./target/main.out +test: tests/*.hs # Runs unit tests. + runghc -i./src/ tests/Main.hs -test: $(test_targets) # Runs test code, generating score logfiles. To run past failing tests, use: `make test --keep-going` - @#$(MAKE) grade +format: src/* # Formats code using ormolu. + ormolu --mode inplace src/*.hs tests/*.hs + +hlint: src/*.hs # HLint for lint suggestions. + hlint src/*.hs + +stan: src/*.hs # Stan for more optimization suggestions. + ghc -fwrite-ide-info src/*.hs -o target/temp.out + stan --hiedir src/ + rm -f target/temp.out src/*.hi src/*.o src/*.hie clean: # Cleans up all the generated logfiles and outfiles. - @rm -f $(test_targets) - @rm -f $(out_files) - @rm -rf .mypy_cache __pycache__ *.out *.o *.hi .gdb_history - @rm -rf build/* + @rm -rf *.out *.o *.hi @rm -rf target/* - @rm -rf .admin_files/.mypy_cache .admin_files/__pycache__ .admin_files/*.hi .admin_files/*.o - @rm -rf */.mypy_cache */__pycache__ */*.out */*.o */*.hi - @rm -rf */*/.mypy_cache */*/__pycache__ */*/*.out */*/*.o */*/*.hi */*/.gdb_history + @rm -rf */*.out */*.o */*.hi + @rm -rf */*/*.out */*/*.o */*/*.hi diff --git a/src/main.hs b/src/Main.hs similarity index 82% rename from src/main.hs rename to src/Main.hs index 4ff161f..8de7680 100644 --- a/src/main.hs +++ b/src/Main.hs @@ -1,3 +1,5 @@ +module Main where + import Control.Exception (assert) import GP import Push diff --git a/src/Makefile b/src/Makefile deleted file mode 100644 index e366b3f..0000000 --- a/src/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -../target/main.out: *.hs - ghc -g -fprof-auto -prof -Wall *.hs -o ../target/main.out - @rm -f *.o *.hi diff --git a/src/Tests.hs b/src/Tests.hs deleted file mode 100644 index e9a94c1..0000000 --- a/src/Tests.hs +++ /dev/null @@ -1,74 +0,0 @@ -module Tests where - -import qualified Data.Map as Map -import Push - -exampleState = - State - { exec = [IntGene 5, StateFunc instructionParameterLoad, StateFunc instructionIntAdd], - int = [2, 6, 3], - float = [1.2, 1.7], - bool = [True, False], - string = ["Hello", "Push"], - parameter = [IntGene 1, StringGene "Hi", BoolGene True, FloatGene 1.3], - input = Map.fromList [("in0" , IntGene 1)] - } - --- TODO: Tests for added basic int instructions - -testResult1 = [8, 3] == int (instructionIntAdd exampleState) - -testResult2 = [4, 3] == int (instructionIntSub exampleState) - -testResult3 = [12, 3] == int (instructionIntMul exampleState) - -testResult4 = [3, 3] == int (instructionIntDiv exampleState) - -testResult5 = [6, 2, 6, 3] == int (interpretExec exampleState) - -loadedState = loadProgram [IntGene 6, IntGene 6, StateFunc instructionIntAdd] emptyState -testResult6 = [12] == int (interpretExec loadedState) - -loadedState2 = loadProgram [BoolGene True, StateFunc instructionExecIf, Block [IntGene 5, IntGene 6], Block [IntGene 7, IntGene 8]] emptyState -testResult7 = [6, 5] == int (interpretExec loadedState2) - -loadedState3 = loadProgram [BoolGene False, StateFunc instructionExecIf, Block [IntGene 5, IntGene 6], Block [IntGene 7, IntGene 8]] emptyState -testResult8 = [8, 7] == int (interpretExec loadedState3) - --- Tests input map -loadedState4 = loadProgram [BoolGene False, PlaceInput "in0", StateFunc instructionIntAdd] exampleState -testResult9 = [3, 6, 3] == int (interpretExec loadedState4) - --- Tests execDup -loadedState5 = interpretExec $ loadProgram [StateFunc instructionExecDup, IntGene 2] emptyState -testResult10 = int loadedState5 !! 0 == 2 && int loadedState5 !! 1 == 2 - --- Tests execDoRange -loadedState6 = loadProgram [IntGene 2, Block [IntGene 4, IntGene 1, StateFunc instructionExecDoRange], StateFunc instructionIntAdd] emptyState -testResult11 = [12] == int (interpretExec loadedState6) - --- Tests execDoCount -loadedState7 = loadProgram [IntGene 2, Block [IntGene 4, StateFunc instructionExecDoCount], StateFunc instructionIntAdd] emptyState -testResult12 = [8] == int (interpretExec loadedState7) - --- Tests execDoTimes -loadedState8 = loadProgram [IntGene 2, Block [IntGene 4, StateFunc instructionExecDoTimes], IntGene 69] emptyState -testResult13 = [69, 69, 69, 69, 2] == int (interpretExec loadedState8) - --- Tests execWhile -loadedState9 = loadProgram [BoolGene False, BoolGene True, BoolGene True, StateFunc instructionExecWhile, IntGene 70] emptyState -testResult14 = [70, 70] == int (interpretExec loadedState9) - --- Tests execDoWhile -loadedState10 = loadProgram [BoolGene False, BoolGene True, BoolGene True, StateFunc instructionExecDoWhile, IntGene 70] emptyState -testResult15 = [70, 70, 70] == int (interpretExec loadedState10) - --- Tests execWhen -loadedState11 = loadProgram [BoolGene False, StateFunc instructionExecWhen, IntGene 71] emptyState -testResult16 = emptyState == interpretExec loadedState11 - --- Also tests execWhen -loadedState12 = loadProgram [BoolGene True, StateFunc instructionExecWhen, IntGene 71] emptyState -testResult17 = [71] == int (interpretExec loadedState12) - -allTests = and [testResult1, testResult2, testResult3, testResult4, testResult5, testResult6, testResult7, testResult8, testResult9] diff --git a/tests/Main.hs b/tests/Main.hs new file mode 100644 index 0000000..258bc65 --- /dev/null +++ b/tests/Main.hs @@ -0,0 +1,75 @@ +import Control.Exception (assert) +import qualified Data.Map as Map +import Push +import Test.Hspec +import Test.Hspec.QuickCheck +import Test.QuickCheck + +exampleState = + State + { exec = [IntGene 5, StateFunc instructionParameterLoad, StateFunc instructionIntAdd], + int = [2, 6, 3], + float = [1.2, 1.7], + bool = [True, False], + string = ["Hello", "Push"], + parameter = [IntGene 1, StringGene "Hi", BoolGene True, FloatGene 1.3], + input = Map.fromList [("in0", IntGene 1)] + } + +prop_test1 :: [Int] -> Bool +prop_test1 nums = nums == reverse (reverse nums) + +main :: IO () +main = do + quickCheck prop_test1 + assert ([8, 3] == int (instructionIntAdd exampleState)) putStrLn "Add test pass" + assert ([4, 3] == int (instructionIntSub exampleState)) putStrLn "Sub test pass" + assert ([12, 3] == int (instructionIntMul exampleState)) putStrLn "Mult test pass" + assert ([3, 3] == int (instructionIntDiv exampleState)) putStrLn "Div test pass" + assert ([6, 2, 6, 3] == int (interpretExec exampleState)) putStrLn "Interpret test pass" + + let loadedState = loadProgram [IntGene 6, IntGene 6, StateFunc instructionIntAdd] emptyState + assert ([12] == int (interpretExec loadedState)) putStrLn "Interpret test 2 pass" + + let loadedState2 = loadProgram [BoolGene True, StateFunc instructionExecIf, Block [IntGene 5, IntGene 6], Block [IntGene 7, IntGene 8]] emptyState + assert ([6, 5] == int (interpretExec loadedState2)) putStrLn "execIf" + + let loadedState3 = loadProgram [BoolGene False, StateFunc instructionExecIf, Block [IntGene 5, IntGene 6], Block [IntGene 7, IntGene 8]] emptyState + assert ([8, 7] == int (interpretExec loadedState3)) putStrLn "execIf" + + let loadedState4 = loadProgram [BoolGene False, PlaceInput "in0", StateFunc instructionIntAdd] exampleState + assert ([3, 6, 3] == int (interpretExec loadedState4)) putStrLn "input map" + + let loadedState5 = interpretExec $ loadProgram [StateFunc instructionExecDup, IntGene 2] emptyState + assert (int loadedState5 !! 0 == 2 && int loadedState5 !! 1 == 2) putStrLn "execDup" + + let loadedState6 = loadProgram [IntGene 2, Block [IntGene 4, IntGene 1, StateFunc instructionExecDoRange], StateFunc instructionIntAdd] emptyState + assert ([12] == int (interpretExec loadedState6)) putStrLn "execDoRange" + + let loadedState7 = loadProgram [IntGene 2, Block [IntGene 4, StateFunc instructionExecDoCount], StateFunc instructionIntAdd] emptyState + assert ([8] == int (interpretExec loadedState7)) putStrLn "execDoCount" + + let loadedState8 = loadProgram [IntGene 2, Block [IntGene 4, StateFunc instructionExecDoTimes], IntGene 69] emptyState + assert ([69, 69, 69, 69, 2] == int (interpretExec loadedState8)) putStrLn "execDoTimes" + + let loadedState9 = loadProgram [BoolGene False, BoolGene True, BoolGene True, StateFunc instructionExecWhile, IntGene 70] emptyState + assert ([70, 70] == int (interpretExec loadedState9)) putStrLn "execWhile" + + let loadedState10 = loadProgram [BoolGene False, BoolGene True, BoolGene True, StateFunc instructionExecDoWhile, IntGene 70] emptyState + assert ([70, 70, 70] == int (interpretExec loadedState10)) putStrLn "execDoWhile" + + let loadedState11 = loadProgram [BoolGene False, StateFunc instructionExecWhen, IntGene 71] emptyState + assert (emptyState == interpretExec loadedState11) putStrLn "execWhen" + + let loadedState12 = loadProgram [BoolGene True, StateFunc instructionExecWhen, IntGene 71] emptyState + assert ([71] == int (interpretExec loadedState12)) putStrLn "execWhen" + + hspec $ do + describe "Prelude.read" $ do + it "can parse integers" $ do + read "10" `shouldBe` (10 :: Int) + + describe "read" $ do + it "is inverse to show" $ + property $ + \x -> (read . show) x `shouldBe` (x :: Int) diff --git a/tests/argfileio01_exact/.ghci b/tests/argfileio01_exact/.ghci deleted file mode 100644 index fba3683..0000000 --- a/tests/argfileio01_exact/.ghci +++ /dev/null @@ -1,7 +0,0 @@ --- https://stackoverflow.com/questions/8867350/how-to-set-a-programs-command-line-arguments-for-ghci --- :set args is a GHCI thing: --- https://downloads.haskell.org/ghc/latest/docs/users_guide/ghci.html#ghci-commands -:set stop :list -:load ../../src/main.hs ../../src/BinaryConversions.hs -:set args "argfile.in" "argfile.out" -:step main diff --git a/tests/argfileio01_exact/Makefile b/tests/argfileio01_exact/Makefile deleted file mode 100644 index a4ed75f..0000000 --- a/tests/argfileio01_exact/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -pass: ../../src/* - cd ../../src/ && $(MAKE) - ./../../target/main.out argfile.in argfile.out - delta argfile.goal argfile.out && echo 100 >pass \ - || ([[ "$$IS_PIPELINE" ]] && exit 1 \ - || (echo "Press enter to debug:" && read && $(MAKE) debug && exit 1)) - -.PHONY: debug -debug: - ghci diff --git a/tests/argfileio01_exact/argfile.goal b/tests/argfileio01_exact/argfile.goal deleted file mode 100644 index 52a9f4e..0000000 --- a/tests/argfileio01_exact/argfile.goal +++ /dev/null @@ -1 +0,0 @@ -1010 diff --git a/tests/argfileio01_exact/argfile.in b/tests/argfileio01_exact/argfile.in deleted file mode 100644 index 9a03714..0000000 --- a/tests/argfileio01_exact/argfile.in +++ /dev/null @@ -1 +0,0 @@ -10 \ No newline at end of file diff --git a/tests/argfileio01_fuzzy/.ghci b/tests/argfileio01_fuzzy/.ghci deleted file mode 100644 index fba3683..0000000 --- a/tests/argfileio01_fuzzy/.ghci +++ /dev/null @@ -1,7 +0,0 @@ --- https://stackoverflow.com/questions/8867350/how-to-set-a-programs-command-line-arguments-for-ghci --- :set args is a GHCI thing: --- https://downloads.haskell.org/ghc/latest/docs/users_guide/ghci.html#ghci-commands -:set stop :list -:load ../../src/main.hs ../../src/BinaryConversions.hs -:set args "argfile.in" "argfile.out" -:step main diff --git a/tests/argfileio01_fuzzy/Makefile b/tests/argfileio01_fuzzy/Makefile deleted file mode 100644 index db9c425..0000000 --- a/tests/argfileio01_fuzzy/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -pass: ../../src/* - cd ../../src/ && $(MAKE) - ./../../target/main.out argfile.in argfile.out - python3 ../../.admin_files/fuzzydiffer.py argfile.goal argfile.out >pass \ - || ([[ "$$IS_PIPELINE" ]] && exit 1 \ - || (echo -e "$$(delta argfile.goal argfile.out)\nPress enter to debug:" && read && $(MAKE) debug && exit 1)) - -.PHONY: debug -debug: - ghci diff --git a/tests/argfileio01_fuzzy/argfile.goal b/tests/argfileio01_fuzzy/argfile.goal deleted file mode 100644 index 52a9f4e..0000000 --- a/tests/argfileio01_fuzzy/argfile.goal +++ /dev/null @@ -1 +0,0 @@ -1010 diff --git a/tests/argfileio01_fuzzy/argfile.in b/tests/argfileio01_fuzzy/argfile.in deleted file mode 100644 index 9a03714..0000000 --- a/tests/argfileio01_fuzzy/argfile.in +++ /dev/null @@ -1 +0,0 @@ -10 \ No newline at end of file diff --git a/tests/doctests/Makefile b/tests/doctests/Makefile deleted file mode 100644 index dc1b030..0000000 --- a/tests/doctests/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -pass: ../../src/*.hs - echo $$PATH - doctest --verbose $^ && echo 100 >pass diff --git a/tests/format/Makefile b/tests/format/Makefile deleted file mode 100644 index d35cfc9..0000000 --- a/tests/format/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -pass: ../../src/*.hs - ormolu --mode check $^ && echo 100 >pass diff --git a/tests/static_HLint/Makefile b/tests/static_HLint/Makefile deleted file mode 100644 index 6da5304..0000000 --- a/tests/static_HLint/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -pass: ../../src/*.hs - hlint $^ && echo 100 >pass diff --git a/tests/static_Stan/Makefile b/tests/static_Stan/Makefile deleted file mode 100644 index 9b1fe1c..0000000 --- a/tests/static_Stan/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -pass: ../../src/*.hs - ghc -fwrite-ide-info $^ -o main.out - stan --hiedir ../../src/ | grep "Total found observations ┃ 0" && echo 100 >pass \ - || ([[ "$$IS_PIPELINE" ]] && exit 1 \ - || (echo -e "\nPress enter to debug:" && read && $(MAKE) debug && exit 1)) - @rm -f ../../src/*.hie ../../src/*.hi ../../src/*.o main.out - -.PHONY: debug -debug: - ghc -fwrite-ide-info ../../src/*.hs -o main.out - stan --hiedir ../../src/ - @rm -f ../../src/*.hie ../../src/*.hi ../../src/*.o main.out - @echo "To get points, fix the above 'observations'." diff --git a/tests/static_Werror/Makefile b/tests/static_Werror/Makefile deleted file mode 100644 index 7f36266..0000000 --- a/tests/static_Werror/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -pass: ../../src/*.hs - ghc -Wall -Werror $^ -o main.out && echo 100 >pass || (rm main.out && exit 1) - @rm main.out diff --git a/tests/stdio01_exact/.ghci b/tests/stdio01_exact/.ghci deleted file mode 100644 index 57cfed5..0000000 --- a/tests/stdio01_exact/.ghci +++ /dev/null @@ -1,3 +0,0 @@ -:set stop :list -:load ../../src/main.hs ../../src/BinaryConversions.hs -:step main diff --git a/tests/stdio01_exact/Makefile b/tests/stdio01_exact/Makefile deleted file mode 100644 index 0d5a774..0000000 --- a/tests/stdio01_exact/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -pass: ../../src/* - cd ../../src/ && $(MAKE) - ./../../target/main.out std.out - delta std.goal std.out && echo 100 >pass \ - || ([[ "$$IS_PIPELINE" ]] && exit 1 \ - || (echo "Press enter to debug (type std.in in yourself):" && read && $(MAKE) debug && exit 1)) - -.PHONY: debug -debug: - ghci diff --git a/tests/stdio01_exact/std.goal b/tests/stdio01_exact/std.goal deleted file mode 100644 index 52a9f4e..0000000 --- a/tests/stdio01_exact/std.goal +++ /dev/null @@ -1 +0,0 @@ -1010 diff --git a/tests/stdio01_exact/std.in b/tests/stdio01_exact/std.in deleted file mode 100644 index 9a03714..0000000 --- a/tests/stdio01_exact/std.in +++ /dev/null @@ -1 +0,0 @@ -10 \ No newline at end of file diff --git a/tests/stdio01_fuzzy/.ghci b/tests/stdio01_fuzzy/.ghci deleted file mode 100644 index 57cfed5..0000000 --- a/tests/stdio01_fuzzy/.ghci +++ /dev/null @@ -1,3 +0,0 @@ -:set stop :list -:load ../../src/main.hs ../../src/BinaryConversions.hs -:step main diff --git a/tests/stdio01_fuzzy/Makefile b/tests/stdio01_fuzzy/Makefile deleted file mode 100644 index 09dd252..0000000 --- a/tests/stdio01_fuzzy/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -pass: ../../src/* - cd ../../src/ && $(MAKE) - ./../../target/main.out std.out - python3 ../../.admin_files/fuzzydiffer.py std.goal std.out >pass \ - || ([[ "$$IS_PIPELINE" ]] && exit 1 \ - || (echo -e "$$(delta std.goal std.out)\nPress enter to debug (type std.in yourself):" && read && $(MAKE) debug && exit 1)) - -.PHONY: debug -debug: - ghci diff --git a/tests/stdio01_fuzzy/std.goal b/tests/stdio01_fuzzy/std.goal deleted file mode 100644 index 52a9f4e..0000000 --- a/tests/stdio01_fuzzy/std.goal +++ /dev/null @@ -1 +0,0 @@ -1010 diff --git a/tests/stdio01_fuzzy/std.in b/tests/stdio01_fuzzy/std.in deleted file mode 100644 index 9a03714..0000000 --- a/tests/stdio01_fuzzy/std.in +++ /dev/null @@ -1 +0,0 @@ -10 \ No newline at end of file diff --git a/tests/unit01_unprotected/.ghci b/tests/unit01_unprotected/.ghci deleted file mode 100644 index 1f6bcdd..0000000 --- a/tests/unit01_unprotected/.ghci +++ /dev/null @@ -1,3 +0,0 @@ -:set stop :list -:load unit.hs ../../src/BinaryConversions.hs -:step main diff --git a/tests/unit01_unprotected/Makefile b/tests/unit01_unprotected/Makefile deleted file mode 100644 index 57f4c9b..0000000 --- a/tests/unit01_unprotected/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -pass: ../../src/* - ghc -g -fprof-auto -prof -Wall unit.hs ../../src/BinaryConversions.hs -o unit.out - @rm -f *.o *.hi - ./unit.out && echo 100 >pass \ - || ([[ "$$IS_PIPELINE" ]] && exit 1 \ - || (echo "Press enter to debug:" && read && $(MAKE) debug && exit 1)) - -.PHONY: debug -debug: - ghci diff --git a/tests/unit01_unprotected/unit.hs b/tests/unit01_unprotected/unit.hs deleted file mode 100644 index a04a9b3..0000000 --- a/tests/unit01_unprotected/unit.hs +++ /dev/null @@ -1,7 +0,0 @@ -import BinaryConversions -import Control.Exception (assert) - -main :: IO () -main = do - let nums = [1, 2 .. 10] - assert (nums == map (binToNat . natToBin) nums) pure () diff --git a/tests/unit03_QuickCheck/.ghci b/tests/unit03_QuickCheck/.ghci deleted file mode 100644 index 1f6bcdd..0000000 --- a/tests/unit03_QuickCheck/.ghci +++ /dev/null @@ -1,3 +0,0 @@ -:set stop :list -:load unit.hs ../../src/BinaryConversions.hs -:step main diff --git a/tests/unit03_QuickCheck/Makefile b/tests/unit03_QuickCheck/Makefile deleted file mode 100644 index 0ed675f..0000000 --- a/tests/unit03_QuickCheck/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -pass: ../../src/* - ghc -g -fprof-auto -prof -Wall unit.hs ../../src/BinaryConversions.hs -o unit.out - @rm -f *.o *.hi - ./unit.out | grep "OK" && echo 100 >pass \ - || ([[ "$$IS_PIPELINE" ]] && exit 1 \ - || (echo "Press enter to debug:" && read && $(MAKE) debug && exit 1)) - -.PHONY: debug -debug: - ghci diff --git a/tests/unit03_QuickCheck/unit.hs b/tests/unit03_QuickCheck/unit.hs deleted file mode 100644 index 6b30729..0000000 --- a/tests/unit03_QuickCheck/unit.hs +++ /dev/null @@ -1,10 +0,0 @@ -import BinaryConversions -import Numeric.Natural (Natural) -import Test.QuickCheck -import Test.QuickCheck.Instances.Natural () - -test :: [Natural] -> Bool -test nums = nums == map (binToNat . natToBin) nums - -main :: IO () -main = quickCheck test