From 4a102698b219edfcf2e418e7f80c4b89378ca48c Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Sun, 5 Feb 2023 14:29:36 +0100 Subject: [PATCH] Add tests to math and add info in readme how to contribute. --- README.md | 9 +++ lib/std/core/values.c3 | 4 +- lib/std/math/math.c3 | 12 ++-- test/unit/stdlib/math.c3 | 134 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 154 insertions(+), 5 deletions(-) create mode 100644 test/unit/stdlib/math.c3 diff --git a/README.md b/README.md index 46dc10205..be09d89a0 100644 --- a/README.md +++ b/README.md @@ -303,3 +303,12 @@ MIT licensed. #### Editor plugins Editor plugins can be found at https://github.com/c3lang/editor-plugins. + +#### Contributing unit tests + +1. Write the test, either adding to existing test files in `/test/unit/` or add + a new file. (If testing the standard library, put it in the `/test/unit/stdlib/` subdirectory). +2. Make sure that the test functions have the `@test` attribute. +3. Run tests and see that they pass. (Recommended settings: `c3c compile-test --safe -g1 -O0 test/unit`. + - in this example `test/unit/` is the relative path to the test directory, so adjust as required) +4. Make a pull request for the new tests. \ No newline at end of file diff --git a/lib/std/core/values.c3 b/lib/std/core/values.c3 index df1e6e4eb..dadf46dcb 100644 --- a/lib/std/core/values.c3 +++ b/lib/std/core/values.c3 @@ -1,5 +1,7 @@ module std::core::values; +macro TypeKind @typekind(#value) @builtin => $typeof(#value).kindof; +macro bool @typeis(#value, $Type) @builtin => $typeof(#value).typeid == $Type.typeid; macro bool @is_int(#value) => types::is_int($typeof(#value)); macro bool @convertable_to(#a, #b) => $checks($typeof(#b) x = #a); macro bool @is_floatlike(#value) => types::is_floatlike($typeof(#value)); @@ -8,7 +10,7 @@ macro bool @is_promotable_to_floatlike(#value) => types::is_promotable_to_floatl macro bool @is_same_vector_type(#value1, #value2) => types::is_same_vector_type($typeof(#value1), $typeof(#value2)); macro promote_int(x) { - $if (values::@is_int(x)): + $if (@is_int(x)): return (double)x; $else: return x; diff --git a/lib/std/math/math.c3 b/lib/std/math/math.c3 index 21a703133..5996a29e5 100644 --- a/lib/std/math/math.c3 +++ b/lib/std/math/math.c3 @@ -116,8 +116,12 @@ macro abs(x) => $$abs(x); **/ macro sign(x) { - if (!x) return ($typeof(x))0; - return ($typeof(x))(x < 0 ? -1 : 1); + var $Type = $typeof(x); + $if ($Type.kindof == TypeKind.UNSIGNED_INT): + return ($Type)(x > 0); + $else: + return ($Type)(x > 0) - ($Type)(x < 0); + $endif; } @@ -127,7 +131,7 @@ macro sign(x) **/ macro atan2(x, y) { - $if ($typeof(x).typeid == float.typeid && $typeof(y).typeid == float.typeid): + $if (@typeis(x, float) && @typeis(y, float)): return _atan2f(x, y); $else: return _atan2(x, y); @@ -150,7 +154,7 @@ macro @sincos(x, y) /** * @require values::@is_int(x) || values::@is_float(x) "Expected an integer or floating point value" - * @checked x + y + * @checked x **/ macro atan(x) { diff --git a/test/unit/stdlib/math.c3 b/test/unit/stdlib/math.c3 new file mode 100644 index 000000000..720a68dec --- /dev/null +++ b/test/unit/stdlib/math.c3 @@ -0,0 +1,134 @@ +module math_tests; +import std::math; + +fn void! test_abs() @test +{ + int x = -21; + assert(math::abs(x) == 21); + double y = -123.0; + assert(math::abs(y) == 123.0); + float z = -21.0f; + assert(math::abs(z) == 21.0f); + $assert(@typeis(math::abs(z), float)); + int[<3>] xx = { -1, -1000, 1000 }; + assert(math::abs(xx) == int[<3>] { 1, 1000, 1000 }); + double[<3>] yy = { -1, -0.5, 1000 }; + assert(math::abs(yy) == double[<3>] { 1, 0.5, 1000 }); +} + +fn void! test_sign() @test +{ + int x = -21; + assert(math::sign(x) == -1); + x = 238219382; + assert(math::sign(x) == 1); + x = 0; + assert(math::sign(x) == 0); + uint y = 23; + assert(math::sign(y) == 1); + y = 0; + assert(math::sign(y) == 0); + y = (uint)-21; + assert(math::sign(y) == 1); + assert(@typeis(math::sign(y), uint)); +} + +fn void! test_atan() @test +{ + int x = 231; + assert(math::atan(x) == 1.5664673495078372); + x = 1; + assert(math::atan(x) == 0.7853981633974483); + x = 0; + assert(math::atan(x) == 0.0); + x = -1; + assert(math::atan(x) == -0.7853981633974483); + x = -231; + assert(math::atan(x) == -1.5664673495078372); + float f = 0; + assert(math::atan(f) == 0.0f); + f = 1; + assert(math::atan(f) == 0.7853981633974483f); + f = -1; + assert(math::atan(f) == -0.7853981633974483f); + assert(@typeis(math::atan(f), float)); + double d = 0; + assert(math::atan(d) == 0.0); + d = 1; + assert(math::atan(d) == 0.7853981633974483); + d = -1; + assert(math::atan(d) == -0.7853981633974483); + assert(@typeis(math::atan(d), double)); +} + +fn void! test_ceil() @test +{ + double d = -123.1; + assert(math::ceil(d) == -123.0); + d = 123.1; + assert(math::ceil(d) == 124.0); + d = 0.1; + assert(math::ceil(d) == 1); + d = -0.9; + assert(math::ceil(d) == 0); + $assert(@typeis(math::ceil(d), double)); + float f = -123.1f; + assert(math::ceil(f) == -123.0f); + f = 123.1f; + assert(math::ceil(f) == 124.0f); + f = 0.1f; + assert(math::ceil(f) == 1.0f); + f = -0.9f; + assert(math::ceil(f) == 0.0f); + $assert(@typeis(math::ceil(f), float)); + double[<5>] vec = { -123.1, 123.1, 0.1, -0.9, 0 }; + assert(math::ceil(vec) == double[<5>] { -123, 124, 1, 0, 0 }); +} + +fn void! test_floor() @test +{ + double d = -123.1; + assert(math::floor(d) == -124.0); + d = 123.1; + assert(math::floor(d) == 123.0); + d = 0.9; + assert(math::floor(d) == 0); + d = -0.1; + assert(math::floor(d) == -1); + $assert(@typeis(math::floor(d), double)); + float f = -123.1f; + assert(math::floor(f) == -124.0f); + f = 123.1f; + assert(math::floor(f) == 123.0f); + f = 0.9f; + assert(math::floor(f) == 0.0f); + f = -0.1f; + assert(math::floor(f) == -1.0f); + $assert(@typeis(math::floor(f), float)); + double[<5>] vec = { -123.1, 123.1, 0.9, -0.1, 0 }; + assert(math::floor(vec) == double[<5>] { -124, 123, 0, -1, 0 }); +} + +fn void! test_trunc() @test +{ + double d = -123.9; + assert(math::trunc(d) == -123.0); + d = 123.1; + assert(math::trunc(d) == 123.0); + d = 0.9; + assert(math::trunc(d) == 0); + d = -0.9; + assert(math::trunc(d) == 0); + $assert(@typeis(math::trunc(d), double)); + float f = -123.9f; + assert(math::trunc(f) == -123.0f); + f = 123.9f; + assert(math::trunc(f) == 123.0f); + f = 0.9f; + assert(math::trunc(f) == 0.0f); + f = -0.9f; + assert(math::trunc(f) == -0.0f); + $assert(@typeis(math::trunc(f), float)); + double[<5>] vec = { -123.9, 123.9, 0.9, -0.9, 0 }; + assert(math::trunc(vec) == double[<5>] { -123, 123, 0, 0, 0 }); +} \ No newline at end of file