diff --git a/Makefile b/Makefile
index 145a7ee..28fc450 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
all: all-examples
EXAMPLES = ex/example1 ex/example2 ex/example3 ex/example4 \
- ex/example5 ex/example6 ex/example7 ex/example8 \
+ ex/example5 ex/example6 ex/example7 ex/example8 ex/example11 ex/main-wrap \
'ex ws/example1 ws' 'ex ws/example2 ws' 'ex ws/example3 ws' 'ex ws/example4 ws' \
'ex ws/example5 ws' 'ex ws/example6 ws' 'ex ws/example7 ws' 'ex ws/example8 ws'
diff --git a/TODO.md b/TODO.md
new file mode 100644
index 0000000..38bf864
--- /dev/null
+++ b/TODO.md
@@ -0,0 +1,148 @@
+# Todo (nick)
+
+- [x] Look if possible to invoke task from launch.json, and shows in button.
+- > conclusion: Not possible to add button, or custom "Run" task: possible to just run it
+- [x] Determine if file is implementation or test (in tests directory)
+- [x] CLion debugging
+
+## 19.04
+
+- [/] investigate files appearing when running run configurations
+- [/] analyze problem of shell scripts (when/where interpreter is chosen)
+- [/] look workings with shell/IO tests
+
+- If time, generate automatically tests
+ - ~ CLI to generate folder and file structure
+ - lookup Unity C
+
+-> Ideas: m4 to fill up boilerplate
+ ```m4
+ include(bt.m4) // implicit
+
+ Suite(name) // sets current suite/file to generate
+ Test_compile()
+ Test_alloc_ok(type) // type is the type declaration
+
+ ```
+-> Nope
+
+## 26.04
+
+- [ ] look workings with shell/IO tests
+ - Run can just run everything
+ - Debug has to make choiches, so better to have a debug target handling it?:
+ - make debug file.ext
+ - > if ext == c; then compile, cp to debugme, and run it (ez, done);
+ > if ext == in | expected; then needs some input redirection (hard);
+ > if ext == sh; then needs to run the program as in the shell script?? (Hardest);
+- [x] investigate files appearing when running run configurations
+ - ? touch only with `if [[ -f ... ]]; then touch ... fi;`?
+ - touch $fileName$ can create file in projectDir directory;
+ -> TODO: should all be from same dir as makefile, instead of projectDir?
+- [ ] analyze problem of shell scripts (when/where interpreter is chosen)
+- [x] VScode not showning tasks anymore (ex/example11)
+ -> .vscode or .idea folder must be in root of the project
+
+## 10.05
+
+- Will there ever be test sets with more than one of IO / sh / c-cxx?
+ - (y/n): (__**Kinda, shell could also be IO, but all confined in .sh file**__)
+ - Specific run configuration file for each type of set?
+ - makefile to make all decisions, based on `TESTS_(IO|SH|C|CXX)` variables?
+
+- Types
+ - Shell: Used to test/run binary implementation with specific arguments (e.g cli), (!?!)or other uses?
+ - I/O: Used to test/run binary implementation, with specific stdin, and expected output
+ - c/cpp src files: Used to test library implementations
+
+- Debugging problems:
+ - Library: None, just copy the test
+ - Binary programs:
+ - how to select the correct compiled binary, to copy into a file named `debugme`?
+ - Need to open src file anyway?
+ - Makefile script to choose when project is library, or test suite, so which compiled binary to copy.
+ - usually I/O or shell, so see below problems
+ - Shell:
+ - how to get the arguments present in the shell script, to pass to the binary?
+ - I/O: choose which .in file to run
+ - Manual prompt?
+
+
+- Proposal:
+ - Common `Run all` configuration
+ - CLion: Run configuration (Button)
+ - VScode: Run task, instructions needed for keyboard shortcut
+ - Ctrl + Shift + B
+ - Specific debug configuration, for each test suite type (either)
+ - Library: currently open `test.c` or `test.cc` file
+ - IO: prompt to pickup file for stdin redirect
+ - Clion: either file, or name prompt
+ - VScode: can be configurable/generetable, by adding a specific field at the end of the file
+
+### TODO
+
+- [ ] Stabilize current solution
+ - Check which files are necessary to make everything work
+ - check that current stuff works
+- [ ] explore debugging for sh files
+- [x] complete section 1 of report, start section 2
+
+## 17.05
+
+- Linker: wrap (dll-library to substitute symbols)
+ - anche per test IO
+ - studente crea un main
+ - altro programma con "vero" main, va a chiamare main altro!
+ - linker:`--wrap = main`
+ - Take every undefined reference to symbol, and transform in symbol `__wrap_symbol_`
+ - => define wrapper
+ - IO: intercept stodut of program: more difficult
+ - New version: capture IO functions (mostly O), for pinpoint comparison!
+ From LD manual:
+```txt --wrap=symbol
+Use a wrapper function for symbol. Any undefined reference to
+symbol will be resolved to "__wrap_symbol". Any undefined
+reference to "__real_symbol" will be resolved to symbol.
+
+This can be used to provide a wrapper for a system function. The
+wrapper function should be called "__wrap_symbol". If it wishes to
+call the system function, it should call "__real_symbol".
+
+Here is a trivial example:
+
+ void *
+ __wrap_malloc (size_t c)
+ {
+ printf ("malloc called with %zu\n", c);
+ return __real_malloc (c);
+ }
+
+If you link other code with this file using --wrap malloc, then all
+calls to "malloc" will call the function "__wrap_malloc" instead.
+The call to "__real_malloc" in "__wrap_malloc" will call the real
+"malloc" function.
+
+You may wish to provide a "__real_malloc" function as well, so that
+links without the --wrap option will succeed. If you do this, you
+should not put the definition of "__real_malloc" in the same file
+as "__wrap_malloc"; if you do, the assembler may resolve the call
+before the linker has a chance to wrap it to "malloc".
+
+Only undefined references are replaced by the linker. So,
+translation unit internal references to symbol are not resolved to
+"__wrap_symbol". In the next example, the call to "f" in "g" is
+not resolved to "__wrap_f".
+
+ int
+ f (void)
+ {
+ return 123;
+ }
+
+ int
+ g (void)
+ {
+ return f();
+ }
+```
+Order of compilation may matter.
diff --git a/basic_testing.h b/basic_testing.h
index 92b0437..85c4b03 100644
--- a/basic_testing.h
+++ b/basic_testing.h
@@ -448,4 +448,26 @@ int bt_test_driver(int argc, char * argv[]) {
}
#endif
+// IO tests macros
+#define FILENAME(ext) \
+ char ext##_filename[128] = {0}; \
+ strncat(ext##_filename, __FILE__, strlen(__FILE__)-1); \
+ strcat(ext##_filename, #ext)
+
+#define RUN_PROGRAM(...) \
+ extern int __real_main(int, char*[]); \
+ int __wrap_main() { \
+ FILENAME(in); \
+ FILENAME(out); \
+ FILENAME(expected); \
+ BT_POSSIBLY_UNUSED FILE* in_file = freopen(in_filename, "r", stdin); \
+ BT_POSSIBLY_UNUSED FILE* out_file = freopen(out_filename, "w", stdout); \
+ int result = __real_main(2, (char*[]) { __VA_ARGS__ }); \
+ if (in_file != NULL) fclose(in_file); \
+ fclose(out_file); \
+ if (result != 0) { \
+ fprintf(stderr, "Implementation exited with value: %d", result);} \
+ return result; \
+ }
+
#endif /* BASIC_TESTING_H_INCLUDED */
diff --git a/basic_testing.mk b/basic_testing.mk
index b6f8bdf..2c772fd 100644
--- a/basic_testing.mk
+++ b/basic_testing.mk
@@ -21,6 +21,8 @@ TESTS_BIN:=$(patsubst $(TESTS_DIR)/%.c, $(TESTS_DIR)/%, $(TESTS_C)) \
$(patsubst $(TESTS_DIR)/%.cc, $(TESTS_DIR)/%, $(TESTS_CXX))
TESTS_BIN_NAMES:=$(sort $(patsubst $(TESTS_DIR)/%.c, %, $(TESTS_C)) $(patsubst $(TESTS_DIR)/%.cc, %, $(TESTS_CXX)))
+TESTS_HYBRID:=$(wildcard $(TESTS_DIR)/*.expected)
+
.PHONY: all
all: compile check
@@ -49,7 +51,12 @@ SUPPRESS_DIAGNOSTICS=yes
else
SUPPRESS_DIAGNOSTICS=
endif
+
TEST_COLORS=yes
+# $TERM variable not always defined, but required by tput (Eg, CLion run console).
+ifeq ($(TERM),)
+TEST_COLORS=no
+endif
ifeq ($(TEST_COLORS),no)
COLOR_RED :=
COLOR_GREEN :=
@@ -171,7 +178,7 @@ check-io-sh: compile $(TESTS_IO) $(TESTS_SH) $(PROGRAMS_DRIVERS)
else \
test_ko FAIL ;\
test_diag "see $(TESTS_DIR)/$$t.sh" ;\
- test_diag "run diff $$t.out $(TESTS_DIR)/$$t.expected";\
+ test_diag "run diff -c $$t.out $(TESTS_DIR)/$$t.expected";\
test_diag "to see the difference between the actual and expected output";\
fi; \
fi; \
@@ -199,19 +206,50 @@ check-bin: $(TESTS_BIN)
"$(TESTS_DIR)/$$t" -q &\
fi; \
$(SCRIPT_GET_TEST_RESULT); \
+ if test $$res = KO || test "$(TESTS_HYBRID)" != "" && ! cmp -s "$(TESTS_DIR)/$$t.out" "$(TESTS_DIR)/$$t.expected"; then \
+ if test "$(TESTS_HYBRID)" != ""; then \
+ test_ko FAIL ; \
+ test_diag "run 'diff -c $(TESTS_DIR)/$$t.out $(TESTS_DIR)/$$t.expected' to see the mistakes"; \
+ else \
+ test_diag "run '$(TESTS_DIR)/$$t' to see what went wrong"; \
+ fi; \
+ test_diag "run '$(TESTS_DIR)/$$t -d' with a debugger" ; \
+ else \
+ test_ok PASS; \
+ if test ! -z $$TESTS_HYBRID; then rm -f "$(TESTS_DIR)/$$t.out"; fi; \
+ fi; \
+ done; \
+ test_summary 'Summary: PASS '
+
+.PHONY: check-single-bin
+check-single-bin: $(BIN_NAME)
+ @exec 2> /dev/null; \
+ if test -z $$BIN_NAME; then \
+ echo "Error: Missing test to run, please set BIN_NAME="; \
+ echo " example: \'make check-single-bin BIN_NAME=tests/test0\'"; \
+ exit 1; fi; \
+ $(SCRIPT_INIT); \
+ t=$$BIN_NAME; \
+ test_start "$$t"; \
+ if test -n "$(WITH_VALGRIND)"; then \
+ echo ;\
+ valgrind $(VALGRIND_FLAGS) "$(TESTS_DIR)/$$t" 2>&1 &\
+ else \
+ "$(TESTS_DIR)/$$t" $(BIN_FLAGS) &\
+ fi; \
+ $(SCRIPT_GET_TEST_RESULT); \
if test $$res = KO; then \
test_diag "run '$(TESTS_DIR)/$$t' to see what went wrong" ; \
test_diag "run '$(TESTS_DIR)/$$t -d' with a debugger" ; \
else \
test_ok PASS; \
fi; \
- done; \
test_summary 'Summary: PASS '
.PHONY: clean
clean:
rm -f $(PROGRAMS) *-valgrind $(OBJECTS) tests/*.o $(TESTS_BIN) \
- *.gcov *.gcda *.gcno tests/*.gcov tests/*.gcda tests/*.gcno
+ tests/debugme *.gcov *.gcda *.gcno tests/*.gcov tests/*.gcda tests/*.gcno tests/*.out
.PHONY: coverage
coverage:
diff --git a/ex/.idea/.gitignore b/ex/.idea/.gitignore
new file mode 100644
index 0000000..54d4519
--- /dev/null
+++ b/ex/.idea/.gitignore
@@ -0,0 +1,3 @@
+/workspace.xml
+/vcs.xml
+/editor.xml
diff --git a/ex/.idea/CLion-bt-tools.zip b/ex/.idea/CLion-bt-tools.zip
new file mode 100644
index 0000000..7f8a379
Binary files /dev/null and b/ex/.idea/CLion-bt-tools.zip differ
diff --git a/ex/.idea/README.md b/ex/.idea/README.md
new file mode 100644
index 0000000..d9b337a
--- /dev/null
+++ b/ex/.idea/README.md
@@ -0,0 +1,17 @@
+# Basic testing Jetbrains CLion config
+
+## Setup
+
+- Import the external tools from the `CLion-bt-tools.zip` into your IDE, from `File > Manage IDE settings > import settings...`;
+> These tools are used to interface the IDE with the make scripts, and are necessary to use the run/debug configurations from CLion.
+> They are stored globally, but you can easely delete them once they're not needed anymore.
+- ensure that the `.idea` folder is located in the root of the exercise, and the folder of the exercise is the only one opened.
+
+## Files
+
+Contains:
+- 3 configurations
+ - `Run`: to run a single test file (file in the `tests/` folder) selected in the editor, or all the tests when an implementation file is selected (or any file in the same folder as the `Makefile`)
+ - `Debug Single test`: when run in `Debug` mode, allows to use the integrated debugger of CLion to debug a C or C++ test (opened and selected in the editor)
+ - `Debug IO`: when run in `Debug` mode, allows to debug the IO tests (with `test.in` and `test.out` files)
+- `CLion-bt-tools.zip`: Tools folder to import tests
diff --git a/ex/.idea/customTargets.xml b/ex/.idea/customTargets.xml
new file mode 100644
index 0000000..f8984c7
--- /dev/null
+++ b/ex/.idea/customTargets.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ex/.idea/misc.xml b/ex/.idea/misc.xml
new file mode 100644
index 0000000..53624c9
--- /dev/null
+++ b/ex/.idea/misc.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ex/.idea/runConfigurations/Debug_IO.xml b/ex/.idea/runConfigurations/Debug_IO.xml
new file mode 100644
index 0000000..bc31ad5
--- /dev/null
+++ b/ex/.idea/runConfigurations/Debug_IO.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ex/.idea/runConfigurations/Debug_single_test.xml b/ex/.idea/runConfigurations/Debug_single_test.xml
new file mode 100644
index 0000000..887bb14
--- /dev/null
+++ b/ex/.idea/runConfigurations/Debug_single_test.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ex/.idea/runConfigurations/Run.xml b/ex/.idea/runConfigurations/Run.xml
new file mode 100644
index 0000000..10969af
--- /dev/null
+++ b/ex/.idea/runConfigurations/Run.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ex/.idea/tools/Basic Testing.xml b/ex/.idea/tools/Basic Testing.xml
new file mode 100644
index 0000000..2716789
--- /dev/null
+++ b/ex/.idea/tools/Basic Testing.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ex/.vscode/README.md b/ex/.vscode/README.md
new file mode 100644
index 0000000..2c9804d
--- /dev/null
+++ b/ex/.vscode/README.md
@@ -0,0 +1,14 @@
+# Basic testing VScode config
+
+## Setup
+
+- ensure that the `.vscode` folder is located in the root of the project opened in VScode; this can either be the folder of the single exercise, or a folder containing all other exercise's folders.
+
+## Files
+
+Contains 2 json files:
+- `tasks.json`: build and run tasks, to run either all tests, or a single one (C test file opened in the editor).
+ - Ctrl + Shift + B, to run default build
+ - Ctrl + P to open command panel, type "task " to show all tasks
+- `launch.json`: debug binary tests or implementation, and I/O tests (name of input file selectable from the dropdown).
+ - Ctrl + Shift + D to open Debug panel
diff --git a/ex/.vscode/launch.json b/ex/.vscode/launch.json
new file mode 100644
index 0000000..797b772
--- /dev/null
+++ b/ex/.vscode/launch.json
@@ -0,0 +1,84 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "debug library test (gdb/lldb)",
+ // Requires C/C++ extension from Microsoft
+ "type": "cppdbg",
+ "request": "launch",
+ "cwd": "${fileDirname}",
+ "preLaunchTask": "Build single test",
+ "program": "${fileDirname}/${fileBasenameNoExtension}",
+ "args": ["-d"],
+ // Requires C/C++ extension from Microsoft
+ "MIMode": "${input:debugger}",
+ // "MIMode": "gdb",
+ // "MIMode": "lldb",
+ "setupCommands": [
+ {
+ "description": "Enable pretty-printing for gdb",
+ "text": "-enable-pretty-printing",
+ "ignoreFailures": true
+ },
+ {
+ "description": "Set Disassembly Flavor to Intel",
+ "text": "-gdb-set disassembly-flavor intel",
+ "ignoreFailures": true
+ }
+ ],
+ },
+ {
+ "name": "debug binary IO (gdb/lldb)",
+ // Requires C/C++ extension from Microsoft
+ "type": "cppdbg",
+ "request": "launch",
+ "cwd": "${fileDirname}",
+ "preLaunchTask": "Build and run tests",
+ "program": "${fileDirname}/${fileBasenameNoExtension}",
+ "args": ["-d", "<", "tests/${input:test}"],
+ // Requires C/C++ extension from Microsoft
+ "MIMode": "${input:debugger}",
+ // "MIMode": "gdb",
+ // "MIMode": "lldb",
+ "setupCommands": [
+ {
+ "description": "Enable pretty-printing for gdb",
+ "text": "-enable-pretty-printing",
+ "ignoreFailures": true
+ },
+ {
+ "description": "Set Disassembly Flavor to Intel",
+ "text": "-gdb-set disassembly-flavor intel",
+ "ignoreFailures": true
+ }
+ ],
+ },
+ ],
+ "inputs": [
+ {
+ "type": "pickString",
+ "id": "debugger",
+ "description": "Which debugger do you want to use?",
+ "options": [
+ "gdb",
+ "lldb",
+ ],
+ "default": "gdb"
+ },
+ {
+ "type": "pickString",
+ "id": "test",
+ "description": "Pick the input file to pass to the program",
+ // TODO: make it so it's generated at runtime, or on test generation!
+ "options": [
+ "test0.in",
+ "test1.in",
+ "test2.in",
+ ],
+ "default": "test0.in"
+ },
+ ],
+}
diff --git a/ex/.vscode/tasks.json b/ex/.vscode/tasks.json
new file mode 100644
index 0000000..caa354f
--- /dev/null
+++ b/ex/.vscode/tasks.json
@@ -0,0 +1,74 @@
+
+{
+"version": "2.0.0",
+"tasks": [
+ {
+ "label": "Build and run tests",
+ "detail": "Runs all tests, or a single test when opened in the editor",
+ "type": "shell",
+ "presentation": {
+ "reveal": "always"
+ },
+ "options": {
+ "cwd": "${fileDirname}/",
+ },
+ "command": " if [[ ${fileDirnameBasename} == tests ]]; then touch ${file}; cd .. && make check-single-bin BIN_NAME=tests/${fileBasenameNoExtension}; else touch ${file}; make; fi",
+ "problemMatcher": ["$gcc",
+ {
+ "owner": "make",
+ "fileLocation":[
+ "relative",
+ "${fileDirname}/tests/"
+ ],
+ "pattern":
+ {
+ // Matches "Running test test_name... FAIL"
+ "regexp": "^Running test\\s(.+)\\.\\.\\.\\s+FAIL$",
+ "file": 1,
+ "message": 1,
+ "kind": "file"
+ },
+ }
+ ],
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ }
+ },
+ {
+ "label": "Build single test",
+ "detail": "Builds and runs a single test (open file in editor)",
+ "type": "shell",
+ "presentation": {
+ "reveal": "always",
+ "focus": true
+ },
+ "options": {
+ "cwd": "${fileDirname}/..",
+ },
+ "command": "make check-single-bin BIN_NAME=tests/${fileBasenameNoExtension}",
+ "problemMatcher": ["$gcc",
+ {
+ "owner": "make",
+ "fileLocation":[
+ "relative",
+ "${fileDirname}/tests/"
+ ],
+ "pattern":
+ {
+ // Matches "Running test test_name... FAIL"
+ "regexp": "^Running test\\s(.+)\\.\\.\\.\\s+FAIL$",
+ "file": 1,
+ "message": 1,
+ "kind": "file"
+ },
+ }
+ ],
+ "group": {
+ "kind": "test",
+ "isDefault": true
+ }
+ }
+
+]
+}
diff --git a/ex/example11.expected b/ex/example11.expected
new file mode 100644
index 0000000..3e54e16
--- /dev/null
+++ b/ex/example11.expected
@@ -0,0 +1,4 @@
+Running test fail... FAIL
+Running test test0... PASS
+Running test test1... PASS
+Running test timeout... FAIL
diff --git a/ex/example11/.idea b/ex/example11/.idea
new file mode 120000
index 0000000..a3f7d20
--- /dev/null
+++ b/ex/example11/.idea
@@ -0,0 +1 @@
+../.idea/
\ No newline at end of file
diff --git a/ex/example11/.vscode b/ex/example11/.vscode
new file mode 120000
index 0000000..7796dd0
--- /dev/null
+++ b/ex/example11/.vscode
@@ -0,0 +1 @@
+../.vscode/
\ No newline at end of file
diff --git a/ex/example11/Makefile b/ex/example11/Makefile
new file mode 100644
index 0000000..e3e112e
--- /dev/null
+++ b/ex/example11/Makefile
@@ -0,0 +1,3 @@
+OBJECTS=implementation.o
+
+include ../../basic_testing.mk
diff --git a/ex/example11/implementation.c b/ex/example11/implementation.c
new file mode 100644
index 0000000..8d61712
--- /dev/null
+++ b/ex/example11/implementation.c
@@ -0,0 +1,7 @@
+#include "implementation.h"
+
+int init_foo(struct foo* data) {
+ int result = 1;
+ data->character = '0';
+ return 1;
+}
diff --git a/ex/example11/implementation.h b/ex/example11/implementation.h
new file mode 100644
index 0000000..b6861d8
--- /dev/null
+++ b/ex/example11/implementation.h
@@ -0,0 +1,5 @@
+struct foo {
+ char character;
+};
+
+int init_foo(struct foo*);
\ No newline at end of file
diff --git a/ex/example11/tests/fail.c b/ex/example11/tests/fail.c
new file mode 100644
index 0000000..70451b4
--- /dev/null
+++ b/ex/example11/tests/fail.c
@@ -0,0 +1,12 @@
+#include "basic_testing.h"
+
+TEST(fail) {
+ int result = 0;
+ TEST_FAILED;
+}
+
+TEST(fail_second) {
+ TEST_FAILED;
+}
+
+MAIN_TEST_DRIVER(fail, fail_second);
diff --git a/ex/example11/tests/test0.c b/ex/example11/tests/test0.c
new file mode 100644
index 0000000..64932a1
--- /dev/null
+++ b/ex/example11/tests/test0.c
@@ -0,0 +1,14 @@
+#include "basic_testing.h"
+#include "../implementation.h"
+
+TEST(compile) {
+ TEST_PASSED;
+}
+
+TEST(with_variable) {
+ int variable = 0;
+ variable++;
+ TEST_PASSED;
+}
+
+MAIN_TEST_DRIVER(compile, with_variable);
diff --git a/ex/example11/tests/test1.c b/ex/example11/tests/test1.c
new file mode 100644
index 0000000..a3ca2b2
--- /dev/null
+++ b/ex/example11/tests/test1.c
@@ -0,0 +1,10 @@
+#include "basic_testing.h"
+#include "../implementation.h"
+
+TEST(initialize) {
+ struct foo data;
+ int result = init_foo(&data);
+ TEST_PASSED;
+}
+
+MAIN_TEST_DRIVER(initialize);
\ No newline at end of file
diff --git a/ex/example11/tests/timeout.c b/ex/example11/tests/timeout.c
new file mode 100644
index 0000000..0ce4ef7
--- /dev/null
+++ b/ex/example11/tests/timeout.c
@@ -0,0 +1,10 @@
+#include "basic_testing.h"
+#include
+
+
+TEST(timeout) {
+ sleep(10);
+ TEST_PASSED;
+}
+
+MAIN_TEST_DRIVER(timeout);
\ No newline at end of file
diff --git a/ex/example5/.idea b/ex/example5/.idea
new file mode 120000
index 0000000..a3f7d20
--- /dev/null
+++ b/ex/example5/.idea
@@ -0,0 +1 @@
+../.idea/
\ No newline at end of file
diff --git a/ex/main-wrap.expected b/ex/main-wrap.expected
new file mode 100644
index 0000000..2787976
--- /dev/null
+++ b/ex/main-wrap.expected
@@ -0,0 +1,2 @@
+Running test test0... PASS
+Running test test4... PASS
diff --git a/ex/main-wrap/Makefile b/ex/main-wrap/Makefile
new file mode 100644
index 0000000..7b1d7c9
--- /dev/null
+++ b/ex/main-wrap/Makefile
@@ -0,0 +1,9 @@
+# PROGRAMS = diamond # we need to treat the binary file as an object, to be able to link on it with the --wrap option
+OBJECTS=diamond.o
+LDFLAGS=-Wl,--wrap=main
+
+# TODO: check if it's still required!
+TESTS_IO:=$(wildcard $(TESTS_DIR)/*.in)
+TESTS_IO_NAMES:=$(sort $(patsubst $(TESTS_DIR)/%.in, %, $(TESTS_IO)))
+
+include ../../basic_testing.mk
diff --git a/ex/main-wrap/diamond.c b/ex/main-wrap/diamond.c
new file mode 100644
index 0000000..b87dbb6
--- /dev/null
+++ b/ex/main-wrap/diamond.c
@@ -0,0 +1,26 @@
+#include
+#include
+
+void print_diamond(int n) {
+ for (int i = 1; i <= n; ++i) {
+ for (int j = n - i; j > 0; --j)
+ putchar(' ');
+ for (int j = 1; j < 2*i; ++j)
+ putchar('#');
+ putchar('\n');
+ }
+ for (int i = n-1; i >= 1; --i) {
+ for (int j = n - i; j > 0; --j)
+ putchar(' ');
+ for (int j = 1; j < 2*i; ++j)
+ putchar('#');
+ putchar('\n');
+ }
+}
+
+int main(int argc, char * argv[]) {
+ int n = 10;
+ if (argc > 1)
+ n = atoi(argv[1]);
+ print_diamond(n);
+}
diff --git a/ex/main-wrap/tests/test0.c b/ex/main-wrap/tests/test0.c
new file mode 100644
index 0000000..a10e123
--- /dev/null
+++ b/ex/main-wrap/tests/test0.c
@@ -0,0 +1,4 @@
+#include "basic_testing.h"
+
+RUN_PROGRAM("diamond", "0");
+
diff --git a/ex/main-wrap/tests/test0.expected b/ex/main-wrap/tests/test0.expected
new file mode 100644
index 0000000..e69de29
diff --git a/ex/main-wrap/tests/test4.c b/ex/main-wrap/tests/test4.c
new file mode 100644
index 0000000..6925789
--- /dev/null
+++ b/ex/main-wrap/tests/test4.c
@@ -0,0 +1,3 @@
+#include "basic_testing.h"
+
+RUN_PROGRAM("diamond", "10");
diff --git a/ex/main-wrap/tests/test4.expected b/ex/main-wrap/tests/test4.expected
new file mode 100644
index 0000000..a70af5d
--- /dev/null
+++ b/ex/main-wrap/tests/test4.expected
@@ -0,0 +1,19 @@
+ #
+ ###
+ #####
+ #######
+ #########
+ ###########
+ #############
+ ###############
+ #################
+###################
+ #################
+ ###############
+ #############
+ ###########
+ #########
+ #######
+ #####
+ ###
+ #
diff --git a/ex/main-wrap/tests/test4.in b/ex/main-wrap/tests/test4.in
new file mode 100644
index 0000000..3045e4e
--- /dev/null
+++ b/ex/main-wrap/tests/test4.in
@@ -0,0 +1 @@
+HEllo world, from redirected stdin!