3D vectors for astrodynamics and rendering
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

vec3: add unit test suite

Adds the missing test/ directory with a small alcotest suite covering
zero, add, sub, scale, dot, cross, length, normalize, negate, distance,
equal, and pp.

+107
+3
test/dune
··· 1 + (test 2 + (name test) 3 + (libraries vec3 alcotest fmt))
+1
test/test.ml
··· 1 + let () = Alcotest.run "vec3" [ Test_vec3.suite ]
+99
test/test_vec3.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2026 Thomas Gazagnaire. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** Tests for {!Vec3} basic arithmetic and norms. *) 7 + 8 + let v = Vec3.v 9 + 10 + let approx ?(eps = 1e-12) msg expected actual = 11 + if Float.abs (expected -. actual) > eps then 12 + Alcotest.failf "%s: expected %.14g, got %.14g" msg expected actual 13 + 14 + let test_zero () = 15 + let z = Vec3.zero in 16 + approx "zero.x" 0.0 z.x; 17 + approx "zero.y" 0.0 z.y; 18 + approx "zero.z" 0.0 z.z 19 + 20 + let test_add () = 21 + let r = Vec3.add (v 1. 2. 3.) (v 4. 5. 6.) in 22 + approx "add.x" 5.0 r.x; 23 + approx "add.y" 7.0 r.y; 24 + approx "add.z" 9.0 r.z 25 + 26 + let test_sub () = 27 + let r = Vec3.sub (v 4. 5. 6.) (v 1. 2. 3.) in 28 + approx "sub.x" 3.0 r.x; 29 + approx "sub.y" 3.0 r.y; 30 + approx "sub.z" 3.0 r.z 31 + 32 + let test_scale () = 33 + let r = Vec3.scale 2.0 (v 1. 2. 3.) in 34 + approx "scale.x" 2.0 r.x; 35 + approx "scale.y" 4.0 r.y; 36 + approx "scale.z" 6.0 r.z 37 + 38 + let test_dot () = approx "dot" 32.0 (Vec3.dot (v 1. 2. 3.) (v 4. 5. 6.)) 39 + 40 + let test_cross () = 41 + (* x cross y = z *) 42 + let r = Vec3.cross (v 1. 0. 0.) (v 0. 1. 0.) in 43 + approx "cross.x" 0.0 r.x; 44 + approx "cross.y" 0.0 r.y; 45 + approx "cross.z" 1.0 r.z 46 + 47 + let test_length () = 48 + approx "length 3-4-0" 5.0 (Vec3.length (v 3. 4. 0.)); 49 + approx "length zero" 0.0 (Vec3.length Vec3.zero) 50 + 51 + let test_normalize () = 52 + let r = Vec3.normalize (v 3. 4. 0.) in 53 + approx "normalize.x" 0.6 r.x; 54 + approx "normalize.y" 0.8 r.y; 55 + approx "normalize.z" 0.0 r.z; 56 + let z = Vec3.normalize (v 1e-15 0. 0.) in 57 + approx "normalize tiny -> zero" 0.0 (Vec3.length z) 58 + 59 + let test_negate () = 60 + let r = Vec3.negate (v 1. (-2.) 3.) in 61 + approx "negate.x" (-1.0) r.x; 62 + approx "negate.y" 2.0 r.y; 63 + approx "negate.z" (-3.0) r.z 64 + 65 + let test_distance () = 66 + approx "distance" 5.0 (Vec3.distance (v 1. 1. 0.) (v 4. 5. 0.)) 67 + 68 + let test_equal () = 69 + Alcotest.(check bool) 70 + "exact equal" true 71 + (Vec3.equal (v 1. 2. 3.) (v 1. 2. 3.)); 72 + Alcotest.(check bool) 73 + "eps equal" true 74 + (Vec3.equal ~eps:1e-6 (v 1.0 2.0 3.0) (v 1.0000001 2.0 3.0)); 75 + Alcotest.(check bool) "not equal" false (Vec3.equal (v 1. 2. 3.) (v 1. 2. 4.)) 76 + 77 + let test_pp () = 78 + let s = Fmt.str "%a" Vec3.pp (v 1. 2. 3.) in 79 + Alcotest.(check bool) 80 + "pp non-empty contains coords" true 81 + (String.length s > 0 82 + && String.contains s '1' && String.contains s '2' && String.contains s '3') 83 + 84 + let suite = 85 + ( "vec3", 86 + [ 87 + Alcotest.test_case "zero" `Quick test_zero; 88 + Alcotest.test_case "add" `Quick test_add; 89 + Alcotest.test_case "sub" `Quick test_sub; 90 + Alcotest.test_case "scale" `Quick test_scale; 91 + Alcotest.test_case "dot" `Quick test_dot; 92 + Alcotest.test_case "cross x*y=z" `Quick test_cross; 93 + Alcotest.test_case "length" `Quick test_length; 94 + Alcotest.test_case "normalize" `Quick test_normalize; 95 + Alcotest.test_case "negate" `Quick test_negate; 96 + Alcotest.test_case "distance" `Quick test_distance; 97 + Alcotest.test_case "equal" `Quick test_equal; 98 + Alcotest.test_case "pp" `Quick test_pp; 99 + ] )
+4
test/test_vec3.mli
··· 1 + (** Tests for the [vec3] library. *) 2 + 3 + val suite : string * unit Alcotest.test_case list 4 + (** [suite] is the alcotest suite for vec3 arithmetic and norms. *)