diff --git a/src/unittest.scad b/src/unittest.scad
new file mode 100644
index 00000000..5f82a582
--- /dev/null
+++ b/src/unittest.scad
@@ -0,0 +1,54 @@
+module fail(message) {
+ echo(
+ str(
+ "",
+ "",
+ "FAIL",
+ "",
+ ""
+ )
+ );
+ if(message != undef) {
+ echo(
+ str(
+ "",
+ " ",
+ message,
+ "",
+ ""
+ )
+ );
+ }
+}
+
+module assertEqualPoint(expected, actual) {
+ n = 10000;
+
+ function shift_to_int(pt, n) =
+ len(pt) == 2 ?
+ [round(pt[0] * n), round(pt[1] * n)] :
+ [round(pt[0] * n), round(pt[1] * n), round(pt[2] * n)];
+
+ shifted_expected = shift_to_int(
+ expected,
+ n
+ );
+
+ shifted_actual = shift_to_int(
+ actual,
+ n
+ );
+
+ if(shifted_expected != shifted_actual) {
+ fail(
+ str("expected: ", expected,
+ ", but: ", actual)
+ );
+ }
+}
+
+module assertEqualPoints(expected, actual) {
+ for(i = [0:len(actual) - 1]) {
+ assertEqualPoint(expected[i], actual[i]);
+ }
+}
\ No newline at end of file
diff --git a/test/test_shape_arc.scad b/test/test_shape_arc.scad
new file mode 100644
index 00000000..1b255db8
--- /dev/null
+++ b/test/test_shape_arc.scad
@@ -0,0 +1,11 @@
+include ;
+include ;
+
+echo("==== test_sharp_arc ====");
+
+expected_shape_pts = [[0, -12.4315], [1.30661, -12.4315], [3.86271, -11.8882], [6.25, -10.8253], [8.36413, -9.28931], [10.1127, -7.34732], [11.4193, -5.08421], [12.2268, -2.5989], [12.5, 0], [12.2268, 2.5989], [11.4193, 5.08421], [10.1127, 7.34732], [8.36413, 9.28931], [6.25, 10.8253], [3.86271, 11.8882], [1.30661, 12.4315], [0, 12.4315], [0, 7.45891], [0.783963, 7.45891], [2.31763, 7.13292], [3.75, 6.49519], [5.01848, 5.57359], [6.06763, 4.40839], [6.85159, 3.05052], [7.33611, 1.55934], [7.5, 0], [7.33611, -1.55934], [6.85159, -3.05052], [6.06763, -4.40839], [5.01848, -5.57359], [3.75, -6.49519], [2.31763, -7.13292], [0.783963, -7.45891], [0, -7.45891]];
+
+shape_pts = shape_arc(radius = 10, angle = [-90, 90], width = 5);
+
+assertEqualPoints(expected_shape_pts, shape_pts);
+