FUNK TESTING
===========================

All of our tests involved white, black, and grey box testing.

=== Unit testing (Lexer, parser, code generation) ===
We tested those components individually throughout the semester. For the lexer, we hand tested the different cases of input by injecting those cases in to the scanner and printing them at the parser level. The parser was tested by writing Funk code and then verifying it with our own version of printing the AST (dot.ml). The AST would then be verified to be the correct form of the tree. Code generation was hand tested with a basic hello world in addition to a fibonacci program.

=== Integration testing ===
Testing syntax and lexical conventions below individually. The purpose of the code is to sanity check the compiler with our language end-to-end (i.e. from lexer to code generation). The generated code is then compiled with gcc and run to verify the expected output and/or result.

Identifiers
Testing variable names or function names that start with a letter or underscore followed by alphanumeric or underscores. e.g. var i int, var _i9 int 

Keywords
Keywords are a subset of identifiers which are reserved for our language. To verify, sufficient testing was conducted on cases such as var i int for a positive case or var if int for a negative case.

Statements and Blocks
These were tested standalone and nested in a function and then referenced in later code:
var
func
async
{}

Control flow
Control flow was unit tested in the following way: if, if/else, for (with and without loop condition expressions), break, and return. Negative cases were also tested, such as having an else by itself or an incorrect for loop

Types
We support four types int, double, bool, and char. Testing was done on those types including negative test cases such as assigning an int to a bool or a char to a double.

Arrays
We test the declaration and usage of arrays of different types to verify the correctness. We use printing to verify the result.

Built-in functions
The five built-in functions were tested (print, double2int, int2double, bool2int, int2bool)

Constants/Literals
Integer/double/boolean/characters/strings were tested individually and verified by using if statements or printing them to the screen. Escape sequences were tested (\n, \r, \t, \a, \", \\)

Comments
Comments were placed randomly in the code to ensure these were scanned correctly. We tested for both single and multi-line comments.

Operators
Binary, unary, and value binding (=) were tested by using them with a declare variable or two and printing the result to the screen to ensure their correctness

Variable and function declarations
This is similar to the Statement and Blocks section above. Here we implement global and nested variables and functions. We try different parameters for functions and different return types. In addition, we test multiple variable declarations on one line e.g. var a, b int = 0, 1

=== System testing ===
HELLO WORLD created and tested.
More meaningful tests were run here. A few selected algorithms were fed to our compiler and the output verified. Scoping rules and function closures were also tested.
--- ADD MORE STUFF FOR SYSTEM TESTING, THIS IS SUPPOSED TO TEST THE ACTUAL PURPOSE OF OUR LANGUAGE. HAS TO BE A MORE COMPLEX PROGRAM THAT SHOWS THAT FUNK IS A BETTER CHOICE FOR THAT PROBLEM THAN ANY OTHER LANGUAGE. KEEP IN MIND FUNCTION CLOSURES AND SCOPING WERE NOT REALLY TESTED YET ---
