Skip to content

Commit da4d548

Browse files
test(cleanup): better tests :)
cleanup and organize shit Signed-off-by: Shashwat Agrawal <shashwatagrawal473@gmail.com>
1 parent dc1a17b commit da4d548

File tree

5 files changed

+218
-118
lines changed

5 files changed

+218
-118
lines changed

tec_showcase.cpp

Lines changed: 38 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
#define TEC_IMPLEMENTATION
2-
#include "./include/math_utils.h"
3-
#include "./tec.h"
4-
5-
#ifdef __cplusplus
2+
#include "tec.h"
63
#include <iostream>
74
#include <memory>
85
#include <vector>
9-
TEC(cpp_Style, Vector) {
6+
7+
TEC(cpp_features, Vector) {
108
std::vector<int> my_vector(100); // THIS WILL AUTOFREE CAUSE OF RAII(dest)
119

1210
// Dynamically allocated int (manual memory management).
@@ -30,131 +28,53 @@ TEC(cpp_Style, Vector) {
3028
TEC_ASSERT(1 == 1);
3129
}
3230

33-
TEC(cpp_Style, SmartPointer) {
31+
TEC(cpp_features, SmartPointer) {
3432
std::unique_ptr<int[]> my_array(new int[100]);
3533
TEC_ASSERT(my_array != nullptr);
3634
}
37-
#else
38-
TEC_XFAIL(framework, teardown_with_cleanup) {
39-
TEC_SKIP("Fails intentionally to demonstrate try/teardown.");
40-
int *value = NULL;
41-
42-
// TRY BLOCK: Contains setup and assertions.
43-
// If an assert fails, execution jumps past this block.
44-
TEC_TRY_BLOCK {
45-
value = malloc(sizeof(int));
46-
TEC_ASSERT_NE(NULL, value);
47-
*value = 69;
48-
TEC_ASSERT_EQ(*value, 420);
49-
}
50-
51-
// FINALLY BLOCK: This code is guaranteed to run.
52-
// No keyword is needed; it's simply the code that follows the try block.
53-
free(value);
54-
// printf("Teardown complete: memory freed\n");
55-
}
56-
#endif
57-
58-
TEC(numerical, test_comparisons) {
59-
int a = 69;
60-
int b = 420;
61-
// TEC_ASSERT_GT(a, b); /* fails */
62-
// TEC_ASSERT_GE(69, 420); /* fails */
63-
TEC_ASSERT_LE(b, a);
64-
TEC_ASSERT_LT(-5, 0);
65-
TEC_ASSERT_GE(100, 100);
66-
TEC_ASSERT_LE(-99, -99);
67-
}
68-
69-
TEC(float, precision) {
70-
TEC_ASSERT_NEAR(0.1 + 0.2, 0.3, 3e-15);
71-
TEC_ASSERT_FLOAT_EQ(0.1 + 0.2, 0.3);
72-
}
73-
74-
TEC(mathutils, addition) {
75-
const int five = 5;
76-
TEC_ASSERT_EQ(add(2, 3), five);
77-
TEC_ASSERT_EQ(add(-10, 5), -5);
78-
79-
TEC_ASSERT_NE(add(2, 2), 5);
80-
}
81-
82-
TEC(mathutils, numerical_comparisons) {
83-
int five = multiply(5, 1);
84-
int ten = multiply(5, 2);
85-
86-
TEC_ASSERT(ten > five);
87-
TEC_ASSERT(five < ten);
88-
TEC_ASSERT(ten >= ten);
89-
TEC_ASSERT(five <= five);
90-
}
91-
92-
TEC(mathutils, multiply) {
93-
TEC_ASSERT_EQ(multiply(3, 4), 12);
94-
TEC_ASSERT(multiply(5, 2) % 2 == 0);
95-
TEC_ASSERT_NE(multiply(1, 1), 0);
96-
97-
int result = multiply(-2, 5);
98-
TEC_ASSERT_EQ(result, -10);
99-
TEC_ASSERT(result < 0);
100-
TEC_ASSERT_NE(result, 0);
101-
102-
result = multiply(0, 100);
103-
TEC_ASSERT_EQ(result, 0);
104-
TEC_ASSERT(result <= 0);
105-
}
106-
107-
TEC(mathutils, division) {
108-
TEC_ASSERT_EQ(divide(10, 2), 5);
109-
TEC_ASSERT(divide(9, 3) > 0);
110-
111-
int result = divide(15, 3);
112-
TEC_ASSERT_EQ(result, 5);
113-
114-
result = divide(0, 5);
115-
TEC_ASSERT_EQ(result, 0);
116-
117-
// Edge case: divide by zero
118-
result = divide(7, 0);
119-
TEC_ASSERT_EQ(result, 0);
120-
}
121-
122-
TEC(mathutils, factorial) {
123-
TEC_ASSERT_EQ(factorial(0), 1); // Edge case: 0! = 1
124-
TEC_ASSERT_EQ(factorial(5), 120);
125-
TEC_ASSERT_EQ(factorial(10), 3628800);
126-
127-
// Test for invalid input (negative numbers)
128-
TEC_ASSERT_EQ(factorial(-5), 1);
129-
}
130-
131-
TEC(logic, booleans_act_right) {
132-
TEC_ASSERT(1);
133-
TEC_ASSERT(!0);
134-
TEC_ASSERT_EQ(1 == 1, 1);
135-
TEC_ASSERT_NE(1 == 0, 1);
136-
}
137-
138-
#ifdef __cplusplus
139-
#include <stdexcept>
140-
#endif
14135

14236
void function_that_throws() {
143-
throw std::runtime_error("Something went wrong!");
37+
throw std::runtime_error("This is an expected exception.");
14438
}
145-
14639
void function_that_doesnt_throw() {}
14740

148-
TEC(Exceptions, CatchesCorrectType) {
41+
TEC(cpp_features, catches_correct_exception_type) {
14942
TEC_ASSERT_THROWS(function_that_throws(), std::runtime_error);
15043
}
151-
152-
TEC(Exceptions, FailsOnWrongType) {
44+
TEC_XFAIL(cpp_features, fails_on_wrong_exception_type) {
15345
TEC_ASSERT_THROWS(function_that_throws(), std::invalid_argument);
15446
}
155-
156-
TEC(Exceptions, FailsWhenNoThrow) {
47+
TEC_XFAIL(cpp_features, fails_when_no_exception_is_thrown) {
15748
TEC_ASSERT_THROWS(function_that_doesnt_throw(), std::runtime_error);
15849
}
15950

160-
TEC_MAIN()
51+
static int raii_sentry_counter = 0;
52+
struct RaiiSentry {
53+
RaiiSentry() { raii_sentry_counter++; }
54+
~RaiiSentry() { raii_sentry_counter--; }
55+
};
56+
57+
TEC(cpp_features, assertion_failure_is_raii_safe) {
58+
TEC_ASSERT_EQ(raii_sentry_counter, 0);
59+
try {
60+
RaiiSentry s;
61+
TEC_ASSERT_EQ(raii_sentry_counter, 1);
62+
TEC_ASSERT_EQ(1, 0); // This assertion throws
63+
} catch (...) {
64+
// THIS WILL PASS as the destructor would've restored the value so
65+
// this assertion will be logged in the passed one's
66+
TEC_ASSERT_EQ(raii_sentry_counter, 0);
67+
// Exception was caught. If the destructor ran, the counter is 0.
68+
// Rethrow the exception so that:
69+
// 1) The test framework knows this block failed.
70+
// 2) Execution stops here and other assertions won't run
71+
// after this failure (cause that's the intended behavior).
72+
throw;
73+
}
74+
75+
// THIS won't be logged cause we used throw in catch, this would've
76+
// logged if we forgot that throw;
77+
TEC_ASSERT_EQ(raii_sentry_counter, 0);
78+
}
79+
80+
TEC_MAIN();

tests/core/assertion.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#include "../../tec.h"
2+
3+
TEC(assertions, test_assert_success) {
4+
TEC_ASSERT(1 == 1);
5+
TEC_ASSERT(true);
6+
}
7+
8+
TEC_XFAIL(assertions, test_assert_failure) { TEC_ASSERT(1 == 0); }
9+
10+
TEC(assertions, test_equality_success) {
11+
TEC_ASSERT_EQ(42, 42);
12+
TEC_ASSERT_NE(42, 99);
13+
}
14+
15+
TEC_XFAIL(assertions, test_equality_failure_eq) { TEC_ASSERT_EQ(42, 99); }
16+
TEC_XFAIL(assertions, test_equality_failure_ne) { TEC_ASSERT_NE(42, 42); }
17+
18+
TEC(assertions, test_comparison_success) {
19+
TEC_ASSERT_GT(10, 5);
20+
TEC_ASSERT_GE(10, 10);
21+
TEC_ASSERT_LT(5, 10);
22+
TEC_ASSERT_LE(5, 5);
23+
}
24+
25+
TEC_XFAIL(assertions, test_comparison_failure_gt) { TEC_ASSERT_GT(5, 10); }
26+
TEC_XFAIL(assertions, test_comparison_failure_le) { TEC_ASSERT_LE(10, 5); }
27+
28+
TEC(assertions, test_string_and_pointer_success) {
29+
const char *str = "hello";
30+
const char *null_str = NULL;
31+
TEC_ASSERT_STR_EQ("hello", str);
32+
TEC_ASSERT_NOT_NULL(str);
33+
TEC_ASSERT_NULL(null_str);
34+
}
35+
36+
TEC_XFAIL(assertions, test_string_failure) {
37+
TEC_ASSERT_STR_EQ("hello", "world");
38+
}
39+
40+
TEC_XFAIL(assertions, test_pointer_failure) {
41+
const char *str = "hello";
42+
TEC_ASSERT_NULL(str);
43+
}
44+
45+
TEC(assertions, test_float_near_success) {
46+
TEC_ASSERT_FLOAT_EQ(0.1 + 0.2, 0.3);
47+
TEC_ASSERT_NEAR(3.1415, 3.141, 0.01);
48+
}
49+
50+
TEC_XFAIL(assertions, test_float_near_failure) {
51+
TEC_ASSERT_NEAR(3.1415, 3.2, 0.01);
52+
}

tests/core/control_flow.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include "../../tec.h"
2+
3+
TEC(control_flow, this_test_should_be_skipped) {
4+
TEC_SKIP("Testing the TEC_SKIP functionality.");
5+
// This assertion should never run. If it does, the test fails.
6+
TEC_ASSERT(false);
7+
}
8+
9+
TEC_XFAIL(control_flow, this_xfail_should_fail_as_expected) {
10+
// This is the correct use of XFAIL.
11+
// The test fails, so the overall result for this test is a PASS.
12+
TEC_ASSERT_EQ(1, 0);
13+
}
14+
15+
// NOTE: The following test is INTENTIONALLY broken.
16+
// When you run the test suite, this test MUST be reported as FAILED.
17+
// This is the meta-test: it proves that XFAIL correctly reports an
18+
// unexpected success as a failure of the test suite.
19+
TEC_XFAIL(control_flow,
20+
this_xfail_should_unexpectedly_pass_and_fail_the_suite) {
21+
// This assertion passes...
22+
TEC_ASSERT_EQ(1, 1);
23+
// ...which means the XFAIL contract is broken, and the runner MUST
24+
// report this specific test as a FAILURE.
25+
26+
// USING THIS SO THE SUMMARY DOESN'T LOOK THAT UGLY
27+
// TEC_ASSERT_NE(1, 1);
28+
}

tests/core/formatter.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#include "../../tec.h"
2+
3+
TEC(formatter_macros, test_signed_integers) {
4+
int8_t i8 = INT8_MIN;
5+
int16_t i16 = INT16_MIN;
6+
int32_t i32 = INT32_MIN;
7+
int64_t i64 = INT64_MIN;
8+
9+
TEC_ASSERT_EQ(i8, (int8_t)-128);
10+
TEC_ASSERT_EQ(i16, (int16_t)-32768);
11+
TEC_ASSERT_EQ(i32, (int32_t)-2147483648);
12+
TEC_ASSERT_EQ(i64, (int64_t)(-9223372036854775807LL - 1LL));
13+
}
14+
15+
TEC(formatter_macros, test_unsigned_integers) {
16+
uint8_t u8 = UINT8_MAX;
17+
uint16_t u16 = UINT16_MAX;
18+
uint32_t u32 = UINT32_MAX;
19+
20+
TEC_ASSERT_EQ(u8, (uint8_t)255);
21+
TEC_ASSERT_EQ(u16, (uint16_t)65535);
22+
TEC_ASSERT_EQ(u32, (uint32_t)4294967295);
23+
}
24+
25+
TEC(formatter_macros, test_large_unsigned_types) {
26+
size_t s_t = (size_t)-1;
27+
TEC_ASSERT_EQ(s_t, (size_t)-1);
28+
29+
// The uint64_t type is only distinct from size_t on 32-bit systems.
30+
// On 64-bit systems, the _Generic macro omits this case, and a uint64_t
31+
// value will be correctly handled by the size_t case. This test ensures
32+
// it works on both architectures.
33+
#ifndef TEC_64BIT_SYSTEM_SIZE_T_CONFLICT_UINT64
34+
uint64_t u64 = UINT64_MAX;
35+
TEC_ASSERT_EQ(u64, (uint64_t)18446744073709551615ULL);
36+
#endif
37+
}
38+
39+
TEC(formatter_macros, test_floating_point_types) {
40+
float f = 3.14f;
41+
double d = 2.71828;
42+
long double ld = 1.61803398875L;
43+
44+
TEC_ASSERT_FLOAT_EQ(f, 3.14f);
45+
TEC_ASSERT_FLOAT_EQ(d, 2.71828);
46+
TEC_ASSERT_FLOAT_EQ(ld, 1.61803398875L);
47+
}
48+
49+
TEC(formatter_macros, test_pointer_types) {
50+
const char *cstr = "hello";
51+
char buffer[] = "world";
52+
char *pstr = buffer;
53+
int x = 42;
54+
void *vptr = &x;
55+
56+
TEC_ASSERT_STR_EQ(cstr, "hello");
57+
TEC_ASSERT_STR_EQ(pstr, "world");
58+
TEC_ASSERT_EQ(vptr, (void *)&x);
59+
}
60+
61+
TEC_XFAIL(formatter_macros, verify_uint64_formatting_on_failure) {
62+
uint64_t u64 = 18446744073709551615ULL; // UINT64_MAX
63+
TEC_ASSERT_EQ(u64, (uint64_t)0);
64+
}
65+
66+
TEC_XFAIL(formatter_macros, verify_default_case_formatting) {
67+
struct SomeRandomStruct {
68+
int a;
69+
} my_struct = {1};
70+
TEC_ASSERT_EQ(my_struct.a, 2);
71+
}

tests/core/setup_fixture.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include "../../tec.h"
2+
static char *shared_buffer = NULL;
3+
4+
// Runs once before all "buffer_tests"
5+
TEC_SETUP(buffer_tests) {
6+
printf(" (Setting up suite...)\n");
7+
shared_buffer = (char *)malloc(100);
8+
}
9+
10+
// Runs once after all "buffer_tests"
11+
TEC_TEARDOWN(buffer_tests) {
12+
printf(" (Tearing down suite...)\n");
13+
free(shared_buffer);
14+
shared_buffer = NULL;
15+
}
16+
17+
// Runs before EACH test in this suite
18+
TEC_TEST_SETUP(buffer_tests) { strcpy(shared_buffer, "initial_state"); }
19+
20+
TEC(buffer_tests, test_one) {
21+
TEC_ASSERT_STR_EQ(shared_buffer, "initial_state");
22+
strcpy(shared_buffer, "modified_by_one");
23+
TEC_ASSERT_STR_EQ(shared_buffer, "modified_by_one");
24+
}
25+
26+
TEC(buffer_tests, test_two) {
27+
// This test gets a fresh state because TEC_TEST_SETUP ran again
28+
TEC_ASSERT_STR_EQ(shared_buffer, "initial_state");
29+
}

0 commit comments

Comments
 (0)