dqn: Use defer loops for testing framework
This commit is contained in:
		
							parent
							
								
									b22c7dbfce
								
							
						
					
					
						commit
						6d22734aaf
					
				
							
								
								
									
										
											BIN
										
									
								
								Project/dqn.rdbg
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Project/dqn.rdbg
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										4
									
								
								dqn.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								dqn.h
									
									
									
									
									
								
							| @ -2066,7 +2066,7 @@ DQN_API Dqn_M4  Dqn_M4_SubF(Dqn_M4 lhs, Dqn_f32 rhs); | |||||||
| DQN_API Dqn_M4  Dqn_M4_MulF(Dqn_M4 lhs, Dqn_f32 rhs); | DQN_API Dqn_M4  Dqn_M4_MulF(Dqn_M4 lhs, Dqn_f32 rhs); | ||||||
| DQN_API Dqn_M4  Dqn_M4_DivF(Dqn_M4 lhs, Dqn_f32 rhs); | DQN_API Dqn_M4  Dqn_M4_DivF(Dqn_M4 lhs, Dqn_f32 rhs); | ||||||
| 
 | 
 | ||||||
| #if defined(DQN_WITH_FIXED_STRING) | #if !defined(DQN_NO_FSTRING8) | ||||||
| DQN_API Dqn_FString8<256> Dqn_M4_ColumnMajorString(Dqn_M4 mat); | DQN_API Dqn_FString8<256> Dqn_M4_ColumnMajorString(Dqn_M4 mat); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| @ -6205,7 +6205,7 @@ DQN_API Dqn_M4 Dqn_M4_DivF(Dqn_M4 lhs, Dqn_f32 rhs) | |||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #if defined(DQN_WITH_FIXED_STRING) | #if !defined(DQN_NO_FSTRING8) | ||||||
| DQN_API Dqn_FString8<256> Dqn_M4_ColumnMajorString(Dqn_M4 mat) | DQN_API Dqn_FString8<256> Dqn_M4_ColumnMajorString(Dqn_M4 mat) | ||||||
| { | { | ||||||
|     Dqn_FString8<256> result = {}; |     Dqn_FString8<256> result = {}; | ||||||
|  | |||||||
							
								
								
									
										114
									
								
								dqn_tester.h
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								dqn_tester.h
									
									
									
									
									
								
							| @ -60,18 +60,22 @@ | |||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #define DQN_TESTER_COLOR_RESET "\x1b[0m" | #define DQN_TESTER_COLOR_RESET "\x1b[0m" | ||||||
|  | #define DQN_TESTER_TOKEN_COMBINE2(x, y) x ## y_ | ||||||
|  | #define DQN_TESTER_TOKEN_COMBINE(x, y) DQN_TESTER_TOKEN_COMBINE2(x, y) | ||||||
| 
 | 
 | ||||||
| #define DQN_TESTER_BEGIN_GROUP(fmt, ...) fprintf(stdout, fmt "\n", ##__VA_ARGS__) | /// Creates <prefix><line_number>_ .e. group_123_
 | ||||||
| #define DQN_TESTER_END_GROUP(test)                                                    \ | #define DQN_TESTER_UNIQUE_NAME(prefix) \ | ||||||
|     do {                                                                              \ |     DQN_TESTER_TOKEN_COMBINE(DQN_TESTER_TOKEN_COMBINE(prefix, __LINE__), _) | ||||||
|         bool all_clear = (test)->num_tests_ok_in_group == (test)->num_tests_in_group; \ | 
 | ||||||
|         fprintf(stdout,                                                               \ | #define DQN_TESTER_GROUP(group, fmt, ...) \ | ||||||
|                 "%s\n  %02d/%02d tests passed -- %s\n\n" DQN_TESTER_COLOR_RESET,      \ |     for (Dqn_Tester *test_group_ = (group = Dqn_Tester_BeginGroup(fmt, ## __VA_ARGS__), &group); \ | ||||||
|                 all_clear ? DQN_TESTER_GOOD_COLOR : DQN_TESTER_BAD_COLOR,             \ |          !test_group_->finished; \ | ||||||
|                 (test)->num_tests_ok_in_group,                                        \ |          Dqn_Tester_EndGroup(test_group_)) | ||||||
|                 (test)->num_tests_in_group,                                           \ | 
 | ||||||
|                 all_clear ? "OK" : "FAILED");                                         \ | #define DQN_TESTER_TEST(fmt, ...) \ | ||||||
|     } while (0) |     for (int DQN_TESTER_UNIQUE_NAME(dummy_) = (Dqn_Tester_Begin(test_group_, fmt, ## __VA_ARGS__), 0); \ | ||||||
|  |          (void)DQN_TESTER_UNIQUE_NAME(dummy_), test_group_->state == Dqn_TesterTestState_TestBegun; \ | ||||||
|  |          Dqn_Tester_End(test_group_)) | ||||||
| 
 | 
 | ||||||
| #define DQN_TESTER_ASSERTF(test, expr, fmt, ...) \ | #define DQN_TESTER_ASSERTF(test, expr, fmt, ...) \ | ||||||
|     DQN_TESTER_ASSERTF_AT((test), __FILE__, __LINE__, (expr), fmt, ##__VA_ARGS__) |     DQN_TESTER_ASSERTF_AT((test), __FILE__, __LINE__, (expr), fmt, ##__VA_ARGS__) | ||||||
| @ -92,7 +96,7 @@ | |||||||
|             if ((test)->log_count++ == 0) {                     \ |             if ((test)->log_count++ == 0) {                     \ | ||||||
|                 fprintf(stdout, "\n");                          \ |                 fprintf(stdout, "\n");                          \ | ||||||
|             }                                                   \ |             }                                                   \ | ||||||
|             (test)->state = Dqn_TesterState_TestFailed;         \ |             (test)->state = Dqn_TesterTestState_TestFailed;         \ | ||||||
|             fprintf(stderr,                                     \ |             fprintf(stderr,                                     \ | ||||||
|                     "%*sAssertion Triggered\n"                  \ |                     "%*sAssertion Triggered\n"                  \ | ||||||
|                     "%*sFile: %s:%d\n"                          \ |                     "%*sFile: %s:%d\n"                          \ | ||||||
| @ -118,7 +122,7 @@ | |||||||
|             if ((test)->log_count++ == 0) {             \ |             if ((test)->log_count++ == 0) {             \ | ||||||
|                 fprintf(stdout, "\n");                  \ |                 fprintf(stdout, "\n");                  \ | ||||||
|             }                                           \ |             }                                           \ | ||||||
|             (test)->state = Dqn_TesterState_TestFailed; \ |             (test)->state = Dqn_TesterTestState_TestFailed; \ | ||||||
|             fprintf(stderr,                             \ |             fprintf(stderr,                             \ | ||||||
|                     "%*sFile: %s:%d\n"                  \ |                     "%*sFile: %s:%d\n"                  \ | ||||||
|                     "%*sExpression: [" #expr "]\n",     \ |                     "%*sExpression: [" #expr "]\n",     \ | ||||||
| @ -133,43 +137,71 @@ | |||||||
| 
 | 
 | ||||||
| // NOTE: Header
 | // NOTE: Header
 | ||||||
| // -----------------------------------------------------------------------------
 | // -----------------------------------------------------------------------------
 | ||||||
| enum Dqn_TesterState { | typedef enum Dqn_TesterTestState { | ||||||
|     Dqn_TesterState_Nil, |     Dqn_TesterTestState_Nil, | ||||||
|     Dqn_TesterState_TestBegun, |     Dqn_TesterTestState_TestBegun, | ||||||
|     Dqn_TesterState_TestFailed, |     Dqn_TesterTestState_TestFailed, | ||||||
| }; | } Dqn_TesterTestState; | ||||||
| 
 | 
 | ||||||
| typedef struct Dqn_Tester { | typedef struct Dqn_Tester { | ||||||
|     int                 num_tests_in_group; |     int                 num_tests_in_group; | ||||||
|     int                 num_tests_ok_in_group; |     int                 num_tests_ok_in_group; | ||||||
|     int                 log_count; |     int                 log_count; | ||||||
|     Dqn_TesterState state; |     Dqn_TesterTestState state; | ||||||
|  |     bool                finished; | ||||||
| } Dqn_Tester; | } Dqn_Tester; | ||||||
| 
 | 
 | ||||||
|  | Dqn_Tester Dqn_Tester_BeginGroupV(char const *fmt, va_list args); | ||||||
|  | Dqn_Tester Dqn_Tester_BeginGroup(char const *fmt, ...); | ||||||
|  | void Dqn_Tester_EndGroup(Dqn_Tester *test); | ||||||
|  | 
 | ||||||
| void Dqn_Tester_BeginV(Dqn_Tester *test, char const *fmt, va_list args); | void Dqn_Tester_BeginV(Dqn_Tester *test, char const *fmt, va_list args); | ||||||
| void Dqn_Tester_Begin(Dqn_Tester *test, char const *fmt, ...); | void Dqn_Tester_Begin(Dqn_Tester *test, char const *fmt, ...); | ||||||
| void Dqn_Tester_End(Dqn_Tester *test); | void Dqn_Tester_End(Dqn_Tester *test); | ||||||
| 
 | 
 | ||||||
| #if defined(__cplusplus) |  | ||||||
| struct Dqn_TesterBeginScopedTest { |  | ||||||
|     Dqn_TesterBeginScopedTest(Dqn_Tester *test, char const *fmt, ...); |  | ||||||
|     ~Dqn_TesterBeginScopedTest(); |  | ||||||
|     Dqn_Tester *test; |  | ||||||
| }; |  | ||||||
| #endif // __cplusplus
 |  | ||||||
| #endif // DQN_TESTER_H
 |  | ||||||
| 
 |  | ||||||
| // NOTE: Implementation
 | // NOTE: Implementation
 | ||||||
| // -----------------------------------------------------------------------------
 | // -----------------------------------------------------------------------------
 | ||||||
| #if defined(DQN_TESTER_IMPLEMENTATION) | #if defined(DQN_TESTER_IMPLEMENTATION) | ||||||
|  | Dqn_Tester Dqn_Tester_BeginGroupV(char const *fmt, va_list args) | ||||||
|  | { | ||||||
|  |     fprintf(stdout, fmt, args); | ||||||
|  |     fputc('\n', stdout); | ||||||
|  |     Dqn_Tester result = {}; | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Dqn_Tester Dqn_Tester_BeginGroup(char const *fmt, ...) | ||||||
|  | { | ||||||
|  |     va_list args; | ||||||
|  |     va_start(args, fmt); | ||||||
|  |     Dqn_Tester result = Dqn_Tester_BeginGroupV(fmt, args); | ||||||
|  |     va_end(args); | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Dqn_Tester_EndGroup(Dqn_Tester *test) | ||||||
|  | { | ||||||
|  |     if (test->finished) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     test->finished = true; | ||||||
|  |     bool all_clear = test->num_tests_ok_in_group == test->num_tests_in_group; | ||||||
|  |     fprintf(stdout, | ||||||
|  |             "%s\n  %02d/%02d tests passed -- %s\n\n" DQN_TESTER_COLOR_RESET, | ||||||
|  |             all_clear ? DQN_TESTER_GOOD_COLOR : DQN_TESTER_BAD_COLOR, | ||||||
|  |             test->num_tests_ok_in_group, | ||||||
|  |             test->num_tests_in_group, | ||||||
|  |             all_clear ? "OK" : "FAILED"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void Dqn_Tester_BeginV(Dqn_Tester *test, char const *fmt, va_list args) | void Dqn_Tester_BeginV(Dqn_Tester *test, char const *fmt, va_list args) | ||||||
| { | { | ||||||
|     assert(test->state == Dqn_TesterState_Nil && |     assert(test->state == Dqn_TesterTestState_Nil && | ||||||
|            "Nesting a unit test within another unit test is not allowed, ensure" |            "Nesting a unit test within another unit test is not allowed, ensure" | ||||||
|            "the first test has finished by calling Dqn_Tester_End"); |            "the first test has finished by calling Dqn_Tester_End"); | ||||||
| 
 | 
 | ||||||
|     test->num_tests_in_group++; |     test->num_tests_in_group++; | ||||||
|     test->state     = Dqn_TesterState_TestBegun; |     test->state     = Dqn_TesterTestState_TestBegun; | ||||||
|     test->log_count = 0; |     test->log_count = 0; | ||||||
| 
 | 
 | ||||||
|     int size_required = 0; |     int size_required = 0; | ||||||
| @ -196,7 +228,7 @@ void Dqn_Tester_Begin(Dqn_Tester *test, char const *fmt, ...) | |||||||
| 
 | 
 | ||||||
| void Dqn_Tester_End(Dqn_Tester *test) | void Dqn_Tester_End(Dqn_Tester *test) | ||||||
| { | { | ||||||
|     assert(test->state != Dqn_TesterState_Nil && "Test was marked as ended but a test was never commenced using Dqn_Tester_Begin"); |     assert(test->state != Dqn_TesterTestState_Nil && "Test was marked as ended but a test was never commenced using Dqn_Tester_Begin"); | ||||||
|     if (test->log_count != 0) { |     if (test->log_count != 0) { | ||||||
|         // NOTE: We try and print the result on the same line as the test name,
 |         // NOTE: We try and print the result on the same line as the test name,
 | ||||||
|         // but if there were logs printed throughout the test then we must print
 |         // but if there were logs printed throughout the test then we must print
 | ||||||
| @ -206,7 +238,7 @@ void Dqn_Tester_End(Dqn_Tester *test) | |||||||
|             putc(DQN_TESTER_RESULT_PAD_CHAR, stdout); |             putc(DQN_TESTER_RESULT_PAD_CHAR, stdout); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (test->state == Dqn_TesterState_TestFailed) { |     if (test->state == Dqn_TesterTestState_TestFailed) { | ||||||
|         fprintf(stdout, DQN_TESTER_BAD_COLOR " FAILED"); |         fprintf(stdout, DQN_TESTER_BAD_COLOR " FAILED"); | ||||||
|     } else { |     } else { | ||||||
|         fprintf(stdout, DQN_TESTER_GOOD_COLOR " OK"); |         fprintf(stdout, DQN_TESTER_GOOD_COLOR " OK"); | ||||||
| @ -218,21 +250,7 @@ void Dqn_Tester_End(Dqn_Tester *test) | |||||||
|         putc('\n', stdout); |         putc('\n', stdout); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     test->state = Dqn_TesterState_Nil; |     test->state = Dqn_TesterTestState_Nil; | ||||||
| } | } | ||||||
| 
 |  | ||||||
| #if defined(__cplusplus) |  | ||||||
| Dqn_TesterBeginScopedTest::Dqn_TesterBeginScopedTest(Dqn_Tester *test, char const *fmt, ...) |  | ||||||
| : test(test) |  | ||||||
| { |  | ||||||
|     va_list args; |  | ||||||
|     va_start(args, fmt); |  | ||||||
|     Dqn_Tester_BeginV(test, fmt, args); |  | ||||||
|     va_end(args); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Dqn_TesterBeginScopedTest::~Dqn_TesterBeginScopedTest() { |  | ||||||
|     Dqn_Tester_End(test); |  | ||||||
| } |  | ||||||
| #endif // __cplusplus
 |  | ||||||
| #endif // DQN_TESTER_IMPLEMENTATION
 | #endif // DQN_TESTER_IMPLEMENTATION
 | ||||||
|  | #endif // DQN_TESTER_H
 | ||||||
|  | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user