Browse Source

Add extras es6 unit tests

Tristan VALCKE 7 years ago
parent
commit
0c456ed854

+ 33 - 0
test/unit/src/extras/SceneUtils.tests.js

@@ -0,0 +1,33 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { SceneUtils } from '../../../../src/extras/SceneUtils';
+
+export default QUnit.module.todo( 'Extras', () => {
+
+	QUnit.module.todo( 'SceneUtils', () => {
+
+		// PUBLIC STUFF
+		QUnit.test( "createMultiMaterialObject", ( assert ) => {
+
+			assert.ok( false, "everything's gonna be alright" );
+
+		} );
+
+		QUnit.test( "detach", ( assert ) => {
+
+			assert.ok( false, "everything's gonna be alright" );
+
+		} );
+
+		QUnit.test( "attach", ( assert ) => {
+
+			assert.ok( false, "everything's gonna be alright" );
+
+		} );
+
+	} );
+
+} );

+ 39 - 0
test/unit/src/extras/ShapeUtils.tests.js

@@ -0,0 +1,39 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { ShapeUtils } from '../../../../src/extras/ShapeUtils';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module.todo( 'ShapeUtils', () => {
+
+		// PUBLIC STUFF
+		QUnit.test( "area", ( assert ) => {
+
+			assert.ok( false, "everything's gonna be alright" );
+
+		} );
+
+		QUnit.test( "triangulate", ( assert ) => {
+
+			assert.ok( false, "everything's gonna be alright" );
+
+		} );
+
+		QUnit.test( "triangulateShape", ( assert ) => {
+
+			assert.ok( false, "everything's gonna be alright" );
+
+		} );
+
+		QUnit.test( "isClockWise", ( assert ) => {
+
+			assert.ok( false, "everything's gonna be alright" );
+
+		} );
+
+	} );
+
+} );

+ 92 - 0
test/unit/src/extras/core/Curve.tests.js

@@ -0,0 +1,92 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { Curve } from '../../../../../src/extras/core/Curve';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Core', () => {
+
+		QUnit.module.todo( 'Curve', () => {
+
+			// INSTANCING
+			QUnit.test( "Instancing", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// PUBLIC STUFF
+			QUnit.test( "getPoint", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getPointAt", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getPoints", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getSpacedPoints", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getLength", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getLengths", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "updateArcLengths", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getUtoTmapping", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getTangent", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getTangentAt", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "computeFrenetFrames", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 99 - 0
test/unit/src/extras/core/CurvePath.tests.js

@@ -0,0 +1,99 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { CurvePath } from '../../../../../src/extras/core/CurvePath';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Core', () => {
+
+		QUnit.module.todo( 'CurvePath', () => {
+
+			// INHERITANCE
+			QUnit.test( "Extending", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// INSTANCING
+			QUnit.test( "Instancing", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// PUBLIC STUFF
+			QUnit.test( "add", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "closePath", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getPoint", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getLength", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "updateArcLengths", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getCurveLengths", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getSpacedPoints", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getPoints", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "createPointsGeometry", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "createSpacedPointsGeometry", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "createGeometry", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 38 - 0
test/unit/src/extras/core/Font.tests.js

@@ -0,0 +1,38 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { Font } from '../../../../../src/extras/core/Font';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Core', () => {
+
+		QUnit.module.todo( 'Font', () => {
+
+			// INSTANCING
+			QUnit.test( "Instancing", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// PUBLIC STUFF
+			QUnit.test( "isFont", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "generateShapes", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 37 - 0
test/unit/src/extras/core/Interpolations.tests.js

@@ -0,0 +1,37 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { CatmullRom, QuadraticBezier, CubicBezier } from '../../../../../src/extras/core/Interpolations';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Core', () => {
+
+		QUnit.module.todo( 'Interpolations', () => {
+
+			// PUBLIC STUFF
+			QUnit.test( "CatmullRom", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "QuadraticBezier", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "CubicBezier", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 25 - 0
test/unit/src/extras/core/Path.tests.js

@@ -0,0 +1,25 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { Path } from '../../../../../src/extras/core/Path';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Core', () => {
+
+		QUnit.module.todo( 'Path', () => {
+
+			// INSTANCING
+			QUnit.test( "Instancing", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 86 - 0
test/unit/src/extras/core/PathPrototype.tests.js

@@ -0,0 +1,86 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { PathPrototype } from '../../../../../src/extras/core/PathPrototype';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Core', () => {
+
+		QUnit.module.todo( 'PathPrototype', () => {
+
+			// INHERITANCE
+			QUnit.test( "Extending", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// PUBLIC STUFF
+			QUnit.test( "fromPoints", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "moveTo", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "lineTo", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "quadraticCurveTo", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "bezierCurveTo", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "splineThru", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "arc", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "absarc", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "ellipse", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "absellipse", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 51 - 0
test/unit/src/extras/core/Shape.tests.js

@@ -0,0 +1,51 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { Shape } from '../../../../../src/extras/core/Shape';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Core', () => {
+
+		QUnit.module.todo( 'Shape', () => {
+
+			// INHERITANCE
+			QUnit.test( "Extending", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// INSTANCING
+			QUnit.test( "Instancing", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// PUBLIC STUFF
+			QUnit.test( "getPointsHoles", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "extractAllPoints", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "extractPoints", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 62 - 0
test/unit/src/extras/core/ShapePath.tests.js

@@ -0,0 +1,62 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { ShapePath } from '../../../../../src/extras/core/ShapePath';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Core', () => {
+
+		QUnit.module.todo( 'ShapePath', () => {
+
+			// INSTANCING
+			QUnit.test( "Instancing", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// PUBLIC STUFF
+			QUnit.test( "moveTo", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "lineTo", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "quadraticCurveTo", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "bezierCurveTo", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "splineThru", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "toShapes", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 39 - 0
test/unit/src/extras/curves/ArcCurve.tests.js

@@ -0,0 +1,39 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { ArcCurve } from '../../../../../src/extras/curves/ArcCurve';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Curves', () => {
+
+		QUnit.module.todo( 'ArcCurve', () => {
+
+			// INHERITANCE
+			QUnit.test( "Extending", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// INSTANCING
+			QUnit.test( "Instancing", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// PUBLIC STUFF
+			QUnit.test( "isArcCurve", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 385 - 0
test/unit/src/extras/curves/CatmullRomCurve3.tests.js

@@ -0,0 +1,385 @@
+/**
+ * @author zz85 / http://joshuakoo.com
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { CatmullRomCurve3 } from '../../../../../src/extras/curves/CatmullRomCurve3';
+import { Vector3 } from '../../../../../src/math/Vector3';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Curves', () => {
+
+		QUnit.module.todo( 'CatmullRomCurve3', () => {
+
+			/* eslint-disable */
+			var positions = [
+				new Vector3( - 60, - 100,   60 ),
+				new Vector3( - 60,    20,   60 ),
+				new Vector3( - 60,   120,   60 ),
+				new Vector3(   60,    20, - 60 ),
+				new Vector3(   60, - 100, - 60 )
+			];
+			/* eslint-enable */
+
+			// INHERITANCE
+			QUnit.test( "Extending", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// INSTANCING
+			QUnit.test( "Instancing", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// PUBLIC STUFF
+			QUnit.test( "isCatmullRomCurve3", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getPoint", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// OTHERS
+			QUnit.test( "catmullrom check", ( assert ) => {
+
+				var curve = new CatmullRomCurve3( positions );
+				curve.type = 'catmullrom';
+
+				var expectedPoints = [
+
+					new Vector3( - 60, - 100, 60 ),
+					new Vector3( - 60, - 51.04, 60 ),
+					new Vector3( - 60, - 2.7199999999999998, 60 ),
+					new Vector3( - 61.92, 44.48, 61.92 ),
+					new Vector3( - 68.64, 95.36000000000001, 68.64 ),
+					new Vector3( - 60, 120, 60 ),
+					new Vector3( - 14.880000000000017, 95.36000000000001, 14.880000000000017 ),
+					new Vector3( 41.75999999999997, 44.48000000000003, - 41.75999999999997 ),
+					new Vector3( 67.68, - 2.720000000000023, - 67.68 ),
+					new Vector3( 65.75999999999999, - 51.04000000000001, - 65.75999999999999 ),
+					new Vector3( 60, - 100, - 60 )
+
+				];
+
+				var points = curve.getPoints( 10 );
+
+				assert.equal( points.length, expectedPoints.length, 'correct number of points.' );
+
+				points.forEach( function ( point, i ) {
+
+					assert.numEqual( point.x, expectedPoints[ i ].x, 'points[' + i + '].x' );
+					assert.numEqual( point.y, expectedPoints[ i ].y, 'points[' + i + '].y' );
+					assert.numEqual( point.z, expectedPoints[ i ].z, 'points[' + i + '].z' );
+
+				} );
+
+			} );
+
+			QUnit.test( "chordal basic check", ( assert ) => {
+
+				var curve = new CatmullRomCurve3( positions );
+
+				curve.type = 'chordal';
+
+				var expectedPoints = [
+					new Vector3( - 60, - 100, 60 ),
+					new Vector3( - 60, - 52, 60 ),
+					new Vector3( - 60, - 4, 60 ),
+					new Vector3( - 60.656435889910924, 41.62455386421379, 60.656435889910924 ),
+					new Vector3( - 62.95396150459915, 87.31049238896205, 62.95396150459915 ),
+					new Vector3( - 60, 120, 60 ),
+					new Vector3( - 16.302568199486444, 114.1500463116312, 16.302568199486444 ),
+					new Vector3( 42.998098664956586, 54.017050116427455, - 42.998098664956586 ),
+					new Vector3( 63.542500175682434, - 1.137153397546383, - 63.542500175682434 ),
+					new Vector3( 62.65687513176183, - 49.85286504815978, - 62.65687513176183 ),
+					new Vector3( 60.00000000000001, - 100, - 60.00000000000001 )
+				];
+
+				var points = curve.getPoints( 10 );
+
+				assert.equal( points.length, expectedPoints.length, 'correct number of points.' );
+
+				points.forEach( function ( point, i ) {
+
+					assert.numEqual( point.x, expectedPoints[ i ].x, 'points[' + i + '].x' );
+					assert.numEqual( point.y, expectedPoints[ i ].y, 'points[' + i + '].y' );
+					assert.numEqual( point.z, expectedPoints[ i ].z, 'points[' + i + '].z' );
+
+				} );
+
+			} );
+
+			QUnit.test( "centripetal basic check", ( assert ) => {
+
+				var curve = new CatmullRomCurve3( positions );
+				curve.type = 'centripetal';
+
+				var expectedPoints = [
+					new Vector3( - 60, - 100, 60 ),
+					new Vector3( - 60, - 51.47527724919028, 60 ),
+					new Vector3( - 60, - 3.300369665587032, 60 ),
+					new Vector3( - 61.13836565863938, 42.86306307781241, 61.13836565863938 ),
+					new Vector3( - 65.1226454638772, 90.69743905511538, 65.1226454638772 ),
+					new Vector3( - 60, 120, 60 ),
+					new Vector3( - 15.620412575504497, 103.10790870179872, 15.620412575504497 ),
+					new Vector3( 42.384384731047874, 48.35477686933143, - 42.384384731047874 ),
+					new Vector3( 65.25545512241153, - 1.646250966068339, - 65.25545512241153 ),
+					new Vector3( 63.94159134180865, - 50.234688224551256, - 63.94159134180865 ),
+					new Vector3( 59.99999999999999, - 100, - 59.99999999999999 ),
+				];
+
+				var points = curve.getPoints( 10 );
+
+				assert.equal( points.length, expectedPoints.length, 'correct number of points.' );
+
+				points.forEach( function ( point, i ) {
+
+					assert.numEqual( point.x, expectedPoints[ i ].x, 'points[' + i + '].x' );
+					assert.numEqual( point.y, expectedPoints[ i ].y, 'points[' + i + '].y' );
+					assert.numEqual( point.z, expectedPoints[ i ].z, 'points[' + i + '].z' );
+
+				} );
+
+			} );
+
+			QUnit.test( "closed catmullrom basic check", ( assert ) => {
+
+				var curve = new CatmullRomCurve3( positions );
+				curve.type = 'catmullrom';
+				curve.closed = true;
+
+				var expectedPoints = [
+					new Vector3( - 60, - 100, 60 ),
+					new Vector3( - 67.5, - 46.25, 67.5 ),
+					new Vector3( - 60, 20, 60 ),
+					new Vector3( - 67.5, 83.75, 67.5 ),
+					new Vector3( - 60, 120, 60 ),
+					new Vector3( 0, 83.75, 0 ),
+					new Vector3( 60, 20, - 60 ),
+					new Vector3( 75, - 46.25, - 75 ),
+					new Vector3( 60, - 100, - 60 ),
+					new Vector3( 0, - 115, 0 ),
+					new Vector3( - 60, - 100, 60 ),
+				];
+
+				var points = curve.getPoints( 10 );
+
+				assert.equal( points.length, expectedPoints.length, 'correct number of points.' );
+
+				points.forEach( function ( point, i ) {
+
+					assert.numEqual( point.x, expectedPoints[ i ].x, 'points[' + i + '].x' );
+					assert.numEqual( point.y, expectedPoints[ i ].y, 'points[' + i + '].y' );
+					assert.numEqual( point.z, expectedPoints[ i ].z, 'points[' + i + '].z' );
+
+				} );
+
+			} );
+
+			//
+			// curve.type = 'catmullrom'; only from here on
+			//
+			QUnit.test( "getLength/getLengths", ( assert ) => {
+
+				var curve = new THREE.CatmullRomCurve3( positions );
+				curve.type = 'catmullrom';
+
+				var length = curve.getLength();
+				var expectedLength = 551.549686276872;
+
+				assert.numEqual( length, expectedLength, "Correct length of curve" );
+
+				var expectedLengths = [
+					0,
+					120,
+					220,
+					416.9771560359221,
+					536.9771560359221
+				];
+				var lengths = curve.getLengths( expectedLengths.length - 1 );
+
+				assert.strictEqual( lengths.length, expectedLengths.length, "Correct number of segments" );
+
+				lengths.forEach( function ( segment, i ) {
+
+					assert.numEqual( segment, expectedLengths[ i ], "segment[" + i + "] correct" );
+
+				} );
+
+			} );
+
+			QUnit.test( "getPointAt", ( assert ) => {
+
+				var curve = new THREE.CatmullRomCurve3( positions );
+				curve.type = 'catmullrom';
+
+				var expectedPoints = [
+					new THREE.Vector3( - 60, - 100, 60 ),
+					new THREE.Vector3( - 64.84177333183106, 64.86956465359813, 64.84177333183106 ),
+					new THREE.Vector3( - 28.288507045700854, 104.83101184518996, 28.288507045700854 ),
+					new THREE.Vector3( 60, - 100, - 60 )
+				];
+
+				var points = [
+					curve.getPointAt( 0 ),
+					curve.getPointAt( 0.3 ),
+					curve.getPointAt( 0.5 ),
+					curve.getPointAt( 1 )
+				];
+
+				assert.deepEqual( points, expectedPoints, "Correct points" );
+
+			} );
+
+			QUnit.test( "getTangent/getTangentAt", ( assert ) => {
+
+				var curve = new THREE.CatmullRomCurve3( positions );
+				curve.type = 'catmullrom';
+
+				var expectedTangents = [
+					new THREE.Vector3( 0, 1, 0 ),
+					new THREE.Vector3( - 0.0001090274561657922, 0.9999999881130137, 0.0001090274561657922 ),
+					new THREE.Vector3( 0.7071067811865475, - 2.0930381713877622e-13, - 0.7071067811865475 ),
+					new THREE.Vector3( 0.43189437062802816, - 0.7917919583070032, - 0.43189437062802816 ),
+					new THREE.Vector3( - 0.00019991333100812723, - 0.9999999600346592, 0.00019991333100812723 )
+				];
+
+				var tangents = [
+					curve.getTangent( 0 ),
+					curve.getTangent( 0.25 ),
+					curve.getTangent( 0.5 ),
+					curve.getTangent( 0.75 ),
+					curve.getTangent( 1 )
+				];
+
+				expectedTangents.forEach( function ( exp, i ) {
+
+					var tangent = tangents[ i ];
+
+					assert.numEqual( tangent.x, exp.x, "getTangent #" + i + ": x correct" );
+					assert.numEqual( tangent.y, exp.y, "getTangent #" + i + ": y correct" );
+
+				} );
+
+				//
+
+				var expectedTangents = [
+					new THREE.Vector3( 0, 1, 0 ),
+					new THREE.Vector3( - 0.10709018822205997, 0.9884651653817284, 0.10709018822205997 ),
+					new THREE.Vector3( 0.6396363672964268, - 0.4262987629159402, - 0.6396363672964268 ),
+					new THREE.Vector3( 0.5077298411616501, - 0.6960034603275557, - 0.5077298411616501 ),
+					new THREE.Vector3( - 0.00019991333100812723, - 0.9999999600346592, 0.00019991333100812723 )
+				];
+
+				var tangents = [
+					curve.getTangentAt( 0 ),
+					curve.getTangentAt( 0.25 ),
+					curve.getTangentAt( 0.5 ),
+					curve.getTangentAt( 0.75 ),
+					curve.getTangentAt( 1 )
+				];
+
+				expectedTangents.forEach( function ( exp, i ) {
+
+					var tangent = tangents[ i ];
+
+					assert.numEqual( tangent.x, exp.x, "getTangentAt #" + i + ": x correct" );
+					assert.numEqual( tangent.y, exp.y, "getTangentAt #" + i + ": y correct" );
+
+				} );
+
+			} );
+
+			QUnit.test( "computeFrenetFrames", ( assert ) => {
+
+				var curve = new THREE.CatmullRomCurve3( positions );
+				curve.type = 'catmullrom';
+
+				var expected = {
+					binormals: [
+						new THREE.Vector3( - 1, 0, 0 ),
+						new THREE.Vector3( - 0.28685061854203, 0.6396363672964267, - 0.7131493814579701 ),
+						new THREE.Vector3( - 1.9982670528160395e-8, - 0.0001999133310081272, - 0.9999999800173295 )
+					],
+					normals: [
+						new THREE.Vector3( 0, 0, - 1 ),
+						new THREE.Vector3( - 0.7131493814579699, - 0.6396363672964268, - 0.2868506185420297 ),
+						new THREE.Vector3( - 0.9999999800173294, 0.00019991333100810582, - 1.99826701852146e-8 )
+					],
+					tangents: [
+						new THREE.Vector3( 0, 1, 0 ),
+						new THREE.Vector3( 0.6396363672964269, - 0.4262987629159403, - 0.6396363672964269 ),
+						new THREE.Vector3( - 0.0001999133310081273, - 0.9999999600346594, 0.0001999133310081273 )
+					]
+				};
+
+				var frames = curve.computeFrenetFrames( 2, false );
+
+				Object.keys( expected ).forEach( function ( group, i ) {
+
+					expected[ group ].forEach( function ( vec, j ) {
+
+						assert.numEqual( frames[ group ][ j ].x, vec.x, "Frenet frames [" + i + ", " + j + "].x correct" );
+						assert.numEqual( frames[ group ][ j ].y, vec.y, "Frenet frames [" + i + ", " + j + "].y correct" );
+						assert.numEqual( frames[ group ][ j ].z, vec.z, "Frenet frames [" + i + ", " + j + "].z correct" );
+
+					} );
+
+				} );
+
+			} );
+
+			QUnit.test( "getUtoTmapping", ( assert ) => {
+
+				var curve = new THREE.CatmullRomCurve3( positions );
+				curve.type = 'catmullrom';
+
+				var start = curve.getUtoTmapping( 0, 0 );
+				var end = curve.getUtoTmapping( 0, curve.getLength() );
+				var somewhere = curve.getUtoTmapping( 0.5, 500 );
+
+				var expectedSomewhere = 0.8964116382083199;
+
+				assert.strictEqual( start, 0, "getUtoTmapping( 0, 0 ) is the starting point" );
+				assert.strictEqual( end, 1, "getUtoTmapping( 0, length ) is the ending point" );
+				assert.numEqual( somewhere, expectedSomewhere, "getUtoTmapping( 0.5, 500 ) is correct" );
+
+			} );
+
+			QUnit.test( "getSpacedPoints", ( assert ) => {
+
+				var curve = new THREE.CatmullRomCurve3( positions );
+				curve.type = 'catmullrom';
+
+				var expectedPoints = [
+					new THREE.Vector3( - 60, - 100, 60 ),
+					new THREE.Vector3( - 60, 10.311489426555056, 60 ),
+					new THREE.Vector3( - 65.05889864636504, 117.99691802595966, 65.05889864636504 ),
+					new THREE.Vector3( 6.054276900088592, 78.7153118386369, - 6.054276900088592 ),
+					new THREE.Vector3( 64.9991491385602, 8.386980812799566, - 64.9991491385602 ),
+					new THREE.Vector3( 60, - 100, - 60 )
+				];
+
+				var points = curve.getSpacedPoints();
+
+				assert.strictEqual( points.length, expectedPoints.length, "Correct number of points" );
+				assert.deepEqual( points, expectedPoints, "Correct points calculated" );
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 221 - 0
test/unit/src/extras/curves/CubicBezierCurve.tests.js

@@ -0,0 +1,221 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ * @author moraxy / https://github.com/moraxy
+ */
+/* global QUnit */
+
+import { CubicBezierCurve } from '../../../../../src/extras/curves/CubicBezierCurve';
+import { Vector2 } from '../../../../../src/math/Vector2';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Curves', () => {
+
+		QUnit.module.todo( 'CubicBezierCurve', ( hooks ) => {
+
+			let curve = undefined;
+			hooks.before( function () {
+
+				curve = new CubicBezierCurve(
+					new Vector2( - 10, 0 ),
+					new Vector2( - 5, 15 ),
+					new Vector2( 20, 15 ),
+					new Vector2( 10, 0 )
+				);
+
+			} );
+
+			// INHERITANCE
+			QUnit.test( "Extending", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// INSTANCING
+			QUnit.test( "Instancing", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// PUBLIC STUFF
+			QUnit.test( "isCubicBezierCurve", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getPoint", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// OTHERS
+			QUnit.test( "Simple curve", ( assert ) => {
+
+				var expectedPoints = [
+					new Vector2( - 10, 0 ),
+					new Vector2( - 3.359375, 8.4375 ),
+					new Vector2( 5.625, 11.25 ),
+					new Vector2( 11.796875, 8.4375 ),
+					new Vector2( 10, 0 )
+				];
+
+				var points = curve.getPoints( expectedPoints.length - 1 );
+
+				assert.strictEqual( points.length, expectedPoints.length, "Correct number of points" );
+				assert.deepEqual( points, expectedPoints, "Correct points calculated" );
+
+				// symmetry
+				var curveRev = new CubicBezierCurve(
+					curve.v3, curve.v2, curve.v1, curve.v0
+				);
+
+				var points = curveRev.getPoints( expectedPoints.length - 1 );
+
+				assert.strictEqual( points.length, expectedPoints.length, "Reversed: Correct number of points" );
+				assert.deepEqual( points, expectedPoints.reverse(), "Reversed: Correct points curve" );
+
+			} );
+
+			QUnit.test( "getLength/getLengths", ( assert ) => {
+
+				var length = curve.getLength();
+				var expectedLength = 36.64630888504102;
+
+				assert.numEqual( length, expectedLength, "Correct length of curve" );
+
+				var expectedLengths = [
+					0,
+					10.737285813492393,
+					20.15159143794633,
+					26.93408340370825,
+					35.56079575637337
+				];
+				var lengths = curve.getLengths( expectedLengths.length - 1 );
+
+				assert.strictEqual( lengths.length, expectedLengths.length, "Correct number of segments" );
+
+				lengths.forEach( function ( segment, i ) {
+
+					assert.numEqual( segment, expectedLengths[ i ], "segment[" + i + "] correct" );
+
+				} );
+
+			} );
+
+			QUnit.test( "getPointAt", ( assert ) => {
+
+				var expectedPoints = [
+					new Vector2( - 10, 0 ),
+					new Vector2( - 3.3188282598022596, 8.463722639089221 ),
+					new Vector2( 3.4718554735926617, 11.07899406116314 ),
+					new Vector2( 10, 0 )
+				];
+
+				var points = [
+					curve.getPointAt( 0 ),
+					curve.getPointAt( 0.3 ),
+					curve.getPointAt( 0.5 ),
+					curve.getPointAt( 1 )
+				];
+
+				assert.deepEqual( points, expectedPoints, "Correct points" );
+
+			} );
+
+			QUnit.test( "getTangent/getTangentAt", ( assert ) => {
+
+				var expectedTangents = [
+					new Vector2( 0.316370061632252, 0.9486358543207215 ),
+					new Vector2( 0.838961283088303, 0.5441911111721949 ),
+					new Vector2( 1, 0 ),
+					new Vector2( 0.47628313192245453, - 0.8792919755383518 ),
+					new Vector2( - 0.5546041767829665, - 0.8321142992972107 )
+				];
+
+				var tangents = [
+					curve.getTangent( 0 ),
+					curve.getTangent( 0.25 ),
+					curve.getTangent( 0.5 ),
+					curve.getTangent( 0.75 ),
+					curve.getTangent( 1 )
+				];
+
+				expectedTangents.forEach( function ( exp, i ) {
+
+					var tangent = tangents[ i ];
+
+					assert.numEqual( tangent.x, exp.x, "getTangent #" + i + ": x correct" );
+					assert.numEqual( tangent.y, exp.y, "getTangent #" + i + ": y correct" );
+
+				} );
+
+				//
+
+				var expectedTangents = [
+					new Vector2( 0.316370061632252, 0.9486358543207215 ),
+					new Vector2( 0.7794223085548987, 0.6264988945935596 ),
+					new Vector2( 0.988266153082452, 0.15274164681452052 ),
+					new Vector2( 0.5004110404199416, - 0.8657879593906534 ),
+					new Vector2( - 0.5546041767829665, - 0.8321142992972107 )
+				];
+
+				var tangents = [
+					curve.getTangentAt( 0 ),
+					curve.getTangentAt( 0.25 ),
+					curve.getTangentAt( 0.5 ),
+					curve.getTangentAt( 0.75 ),
+					curve.getTangentAt( 1 )
+				];
+
+				expectedTangents.forEach( function ( exp, i ) {
+
+					var tangent = tangents[ i ];
+
+					assert.numEqual( tangent.x, exp.x, "getTangentAt #" + i + ": x correct" );
+					assert.numEqual( tangent.y, exp.y, "getTangentAt #" + i + ": y correct" );
+
+				} );
+
+			} );
+
+			QUnit.test( "getUtoTmapping", ( assert ) => {
+
+				var start = curve.getUtoTmapping( 0, 0 );
+				var end = curve.getUtoTmapping( 0, curve.getLength() );
+				var somewhere = curve.getUtoTmapping( 0.5, 1 );
+
+				var expectedSomewhere = 0.02130029182257093;
+
+				assert.strictEqual( start, 0, "getUtoTmapping( 0, 0 ) is the starting point" );
+				assert.strictEqual( end, 1, "getUtoTmapping( 0, length ) is the ending point" );
+				assert.numEqual( somewhere, expectedSomewhere, "getUtoTmapping( 0.5, 1 ) is correct" );
+
+			} );
+
+			QUnit.test( "getSpacedPoints", ( assert ) => {
+
+				var expectedPoints = [
+					new Vector2( - 10, 0 ),
+					new Vector2( - 6.16826457740703, 6.17025727295411 ),
+					new Vector2( - 0.058874033259857184, 10.1240558653185 ),
+					new Vector2( 7.123523032625162, 11.154913869041575 ),
+					new Vector2( 12.301846885754463, 6.808865855469985 ),
+					new Vector2( 10, 0 )
+				];
+
+				var points = curve.getSpacedPoints();
+
+				assert.strictEqual( points.length, expectedPoints.length, "Correct number of points" );
+				assert.deepEqual( points, expectedPoints, "Correct points calculated" );
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 257 - 0
test/unit/src/extras/curves/CubicBezierCurve3.tests.js

@@ -0,0 +1,257 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ * @author moraxy / https://github.com/moraxy
+ */
+/* global QUnit */
+
+import { CubicBezierCurve3 } from '../../../../../src/extras/curves/CubicBezierCurve3';
+import { Vector3 } from '../../../../../src/math/Vector3';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Curves', () => {
+
+		QUnit.module.todo( 'CubicBezierCurve3', ( hooks ) => {
+
+			let curve = undefined;
+			hooks.before( function () {
+
+				curve = new CubicBezierCurve3(
+					new Vector3( - 10, 0, 2 ),
+					new Vector3( - 5, 15, 4 ),
+					new Vector3( 20, 15, - 5 ),
+					new Vector3( 10, 0, 10 )
+				);
+
+			} );
+
+			// INHERITANCE
+			QUnit.test( "Extending", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// INSTANCING
+			QUnit.test( "Instancing", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// PUBLIC STUFF
+			QUnit.test( "isCubicBezierCurve3", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getPoint", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// OTHERS
+			QUnit.test( "Simple curve", ( assert ) => {
+
+				var expectedPoints = [
+					new Vector3( - 10, 0, 2 ),
+					new Vector3( - 3.359375, 8.4375, 1.984375 ),
+					new Vector3( 5.625, 11.25, 1.125 ),
+					new Vector3( 11.796875, 8.4375, 2.703125 ),
+					new Vector3( 10, 0, 10 )
+				];
+
+				var points = curve.getPoints( expectedPoints.length - 1 );
+
+				assert.strictEqual( points.length, expectedPoints.length, "Correct number of points" );
+				assert.deepEqual( points, expectedPoints, "Correct points calculated" );
+
+				// symmetry
+				var curveRev = new CubicBezierCurve3(
+					curve.v3, curve.v2, curve.v1, curve.v0
+				);
+
+				points = curveRev.getPoints( expectedPoints.length - 1 );
+
+				assert.strictEqual( points.length, expectedPoints.length, "Reversed: Correct number of points" );
+				assert.deepEqual( points, expectedPoints.reverse(), "Reversed: Correct points curve" );
+
+			} );
+
+			QUnit.test( "getLength/getLengths", ( assert ) => {
+
+				var length = curve.getLength();
+				var expectedLength = 39.58103024989427;
+
+				assert.numEqual( length, expectedLength, "Correct length of curve" );
+
+				var expectedLengths = [
+					0,
+					10.73729718231036,
+					20.19074500737662,
+					27.154413277853756,
+					38.453287150114214
+				];
+				var lengths = curve.getLengths( expectedLengths.length - 1 );
+
+				assert.strictEqual( lengths.length, expectedLengths.length, "Correct number of segments" );
+
+				lengths.forEach( function ( segment, i ) {
+
+					assert.numEqual( segment, expectedLengths[ i ], "segment[" + i + "] correct" );
+
+				} );
+
+			} );
+
+			QUnit.test( "getPointAt", ( assert ) => {
+
+				var expectedPoints = [
+					new Vector3( - 10, 0, 2 ),
+					new Vector3( - 2.591880240484318, 8.908333501170798, 1.8953420625251136 ),
+					new Vector3( 4.866251460832755, 11.22787914038507, 1.150832855206874 ),
+					new Vector3( 10, 0, 10 )
+				];
+
+				var points = [
+					curve.getPointAt( 0 ),
+					curve.getPointAt( 0.3 ),
+					curve.getPointAt( 0.5 ),
+					curve.getPointAt( 1 )
+				];
+
+				assert.deepEqual( points, expectedPoints, "Correct points" );
+
+			} );
+
+			QUnit.test( "getTangent/getTangentAt", ( assert ) => {
+
+				var expectedTangents = [
+					new Vector3( 0.3138715439944244, 0.9411440474105875, 0.12542940601858074 ),
+					new Vector3( 0.8351825262580098, 0.54174002562179, - 0.09480449605683638 ),
+					new Vector3( 0.9997531780538501, 0, - 0.02221672728433752 ),
+					new Vector3( 0.40693407933981185, - 0.7512629496079668, 0.5196235518317053 ),
+					new Vector3( - 0.42632467075185815, - 0.6396469221230213, 0.6396085444448543 )
+				];
+
+				var tangents = [
+					curve.getTangent( 0 ),
+					curve.getTangent( 0.25 ),
+					curve.getTangent( 0.5 ),
+					curve.getTangent( 0.75 ),
+					curve.getTangent( 1 )
+				];
+
+				expectedTangents.forEach( function ( exp, i ) {
+
+					var tangent = tangents[ i ];
+
+					assert.numEqual( tangent.x, exp.x, "getTangent #" + i + ": x correct" );
+					assert.numEqual( tangent.y, exp.y, "getTangent #" + i + ": y correct" );
+
+				} );
+
+				//
+
+				expectedTangents = [
+					new Vector3( 0.3138715439944244, 0.9411440474105875, 0.12542940601858074 ),
+					new Vector3( 0.8016539573770751, 0.5918626760037707, - 0.08396133262002324 ),
+					new Vector3( 0.997337559412928, 0.05740742907719314, - 0.044968652092444425 ),
+					new Vector3( 0.1389373097746809, - 0.7882209938358005, 0.5995032016837588 ),
+					new Vector3( - 0.42632467075185815, - 0.6396469221230213, 0.6396085444448543 )
+				];
+
+				tangents = [
+					curve.getTangentAt( 0 ),
+					curve.getTangentAt( 0.25 ),
+					curve.getTangentAt( 0.5 ),
+					curve.getTangentAt( 0.75 ),
+					curve.getTangentAt( 1 )
+				];
+
+				expectedTangents.forEach( function ( exp, i ) {
+
+					var tangent = tangents[ i ];
+
+					assert.numEqual( tangent.x, exp.x, "getTangentAt #" + i + ": x correct" );
+					assert.numEqual( tangent.y, exp.y, "getTangentAt #" + i + ": y correct" );
+
+				} );
+
+			} );
+
+			QUnit.test( "getUtoTmapping", ( assert ) => {
+
+				var start = curve.getUtoTmapping( 0, 0 );
+				var end = curve.getUtoTmapping( 0, curve.getLength() );
+				var somewhere = curve.getUtoTmapping( 0.5, 1 );
+
+				var expectedSomewhere = 0.021163245321323316;
+
+				assert.strictEqual( start, 0, "getUtoTmapping( 0, 0 ) is the starting point" );
+				assert.strictEqual( end, 1, "getUtoTmapping( 0, length ) is the ending point" );
+				assert.numEqual( somewhere, expectedSomewhere, "getUtoTmapping( 0.5, 1 ) is correct" );
+
+			} );
+
+			QUnit.test( "getSpacedPoints", ( assert ) => {
+
+				var expectedPoints = [
+					new Vector3( - 10, 0, 2 ),
+					new Vector3( - 5.756524515061918, 6.568020242700483, 2.22116711170301 ),
+					new Vector3( 1.0003511895116906, 10.49656064587831, 1.4727101010850698 ),
+					new Vector3( 8.767656412295171, 10.784286845278622, 1.2873599519775174 ),
+					new Vector3( 12.306772513558396, 5.545103788071547, 4.909948454535794 ),
+					new Vector3( 10, 0, 10 )
+				];
+
+				var points = curve.getSpacedPoints();
+
+				assert.strictEqual( points.length, expectedPoints.length, "Correct number of points" );
+				assert.deepEqual( points, expectedPoints, "Correct points calculated" );
+
+			} );
+
+			QUnit.test( "computeFrenetFrames", ( assert ) => {
+
+				var expected = {
+					binormals: [
+						new Vector3( - 0.9486358543207215, 0.316370061632252, - 6.938893903907228e-18 ),
+						new Vector3( - 0.05491430765311864, 0.9969838307670049, 0.054842137122173326 ),
+						new Vector3( 0.5944656510461876, 0.334836503700931, 0.7310917216844742 )
+					],
+					normals: [
+						new Vector3( 0.03968210891259515, 0.11898683173537697, - 0.9921025471723304 ),
+						new Vector3( - 0.047981365124836806, 0.05222670079466692, - 0.9974819097732357 ),
+						new Vector3( 0.6818048583242511, - 0.6919077473246573, - 0.23749906180354932 )
+					],
+					tangents: [
+						new Vector3( 0.3138715439944244, 0.9411440474105875, 0.12542940601858074 ),
+						new Vector3( 0.9973375594129282, 0.05740742907719315, - 0.04496865209244443 ),
+						new Vector3( - 0.42632467075185815, - 0.6396469221230213, 0.6396085444448543 )
+					]
+				};
+
+				var frames = curve.computeFrenetFrames( 2, false );
+
+				Object.keys( expected ).forEach( function ( group, i ) {
+
+					expected[ group ].forEach( function ( vec, j ) {
+
+						assert.numEqual( frames[ group ][ j ].x, vec.x, "Frenet frames [" + i + ", " + j + "].x correct" );
+						assert.numEqual( frames[ group ][ j ].y, vec.y, "Frenet frames [" + i + ", " + j + "].y correct" );
+						assert.numEqual( frames[ group ][ j ].z, vec.z, "Frenet frames [" + i + ", " + j + "].z correct" );
+
+					} );
+
+				} );
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 201 - 0
test/unit/src/extras/curves/EllipseCurve.tests.js

@@ -0,0 +1,201 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { EllipseCurve } from '../../../../../src/extras/curves/EllipseCurve';
+import { Vector2 } from '../../../../../src/math/Vector2';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Curves', () => {
+
+		QUnit.module.todo( 'EllipseCurve', ( hooks ) => {
+
+			let curve = undefined;
+			hooks.before( function () {
+
+				curve = new EllipseCurve(
+					0, 0, // ax, aY
+					10, 10, // xRadius, yRadius
+					0, 2 * Math.PI, // aStartAngle, aEndAngle
+					false, // aClockwise
+					0 // aRotation
+				);
+
+			} );
+
+			// INHERITANCE
+			QUnit.test( "Extending", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// INSTANCING
+			QUnit.test( "Instancing", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// PUBLIC STUFF
+			QUnit.test( "isEllipseCurve", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getPoint", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// OTHERS
+			QUnit.test( "Simple curve", ( assert ) => {
+
+				var expectedPoints = [
+					new Vector2( 10, 0 ),
+					new Vector2( 0, 10 ),
+					new Vector2( - 10, 0 ),
+					new Vector2( 0, - 10 ),
+					new Vector2( 10, 0 )
+				];
+
+				var points = curve.getPoints( expectedPoints.length - 1 );
+
+				assert.strictEqual( points.length, expectedPoints.length, "Correct number of points" );
+
+				points.forEach( function ( point, i ) {
+
+					assert.numEqual( point.x, expectedPoints[ i ].x, "point[" + i + "].x correct" );
+					assert.numEqual( point.y, expectedPoints[ i ].y, "point[" + i + "].y correct" );
+
+				} );
+
+			} );
+
+			QUnit.test( "getLength/getLengths", ( assert ) => {
+
+				var length = curve.getLength();
+				var expectedLength = 62.829269247282795;
+
+				assert.numEqual( length, expectedLength, "Correct length of curve" );
+
+				var lengths = curve.getLengths( 5 );
+				var expectedLengths = [
+					0,
+					11.755705045849462,
+					23.51141009169892,
+					35.26711513754839,
+					47.02282018339785,
+					58.77852522924731
+				];
+
+				assert.strictEqual( lengths.length, expectedLengths.length, "Correct number of segments" );
+
+				lengths.forEach( function ( segment, i ) {
+
+					assert.numEqual( segment, expectedLengths[ i ], "segment[" + i + "] correct" );
+
+				} );
+
+			} );
+
+			QUnit.test( "getPoint/getPointAt", ( assert ) => {
+
+				var testValues = [ 0, 0.3, 0.5, 0.7, 1 ];
+
+				testValues.forEach( function ( val, i ) {
+
+					var expectedX = Math.cos( val * Math.PI * 2 ) * 10;
+					var expectedY = Math.sin( val * Math.PI * 2 ) * 10;
+
+					var p = curve.getPoint( val );
+					var a = curve.getPointAt( val );
+
+					assert.numEqual( p.x, expectedX, "getPoint(" + val + ").x correct" );
+					assert.numEqual( p.y, expectedY, "getPoint(" + val + ").y correct" );
+
+					assert.numEqual( a.x, expectedX, "getPointAt(" + val + ").x correct" );
+					assert.numEqual( a.y, expectedY, "getPointAt(" + val + ").y correct" );
+
+				} );
+
+			} );
+
+			QUnit.test( "getTangent", ( assert ) => {
+
+				var expectedTangents = [
+					new Vector2( - 0.000314159260186071, 0.9999999506519786 ),
+					new Vector2( - 1, 0 ),
+					new Vector2( 0, - 1 ),
+					new Vector2( 1, 0 ),
+					new Vector2( 0.00031415926018600165, 0.9999999506519784 )
+				];
+
+				var tangents = [
+					curve.getTangent( 0 ),
+					curve.getTangent( 0.25 ),
+					curve.getTangent( 0.5 ),
+					curve.getTangent( 0.75 ),
+					curve.getTangent( 1 )
+				];
+
+				expectedTangents.forEach( function ( exp, i ) {
+
+					var tangent = tangents[ i ];
+
+					assert.numEqual( tangent.x, exp.x, "getTangent #" + i + ": x correct" );
+					assert.numEqual( tangent.y, exp.y, "getTangent #" + i + ": y correct" );
+
+				} );
+
+			} );
+
+			QUnit.test( "getUtoTmapping", ( assert ) => {
+
+				var start = curve.getUtoTmapping( 0, 0 );
+				var end = curve.getUtoTmapping( 0, curve.getLength() );
+				var somewhere = curve.getUtoTmapping( 0.7, 1 );
+
+				var expectedSomewhere = 0.01591614882650014;
+
+				assert.strictEqual( start, 0, "getUtoTmapping( 0, 0 ) is the starting point" );
+				assert.strictEqual( end, 1, "getUtoTmapping( 0, length ) is the ending point" );
+				assert.numEqual( somewhere, expectedSomewhere, "getUtoTmapping( 0.7, 1 ) is correct" );
+
+			} );
+
+			QUnit.test( "getSpacedPoints", ( assert ) => {
+
+				var expectedPoints = [
+					new Vector2( 10, 0 ),
+					new Vector2( 3.0901699437494603, 9.51056516295154 ),
+					new Vector2( - 8.090169943749492, 5.877852522924707 ),
+					new Vector2( - 8.090169943749459, - 5.877852522924751 ),
+					new Vector2( 3.0901699437494807, - 9.510565162951533 ),
+					new Vector2( 10, - 2.4492935982947065e-15 )
+				];
+
+				var points = curve.getSpacedPoints();
+
+				assert.strictEqual( points.length, expectedPoints.length, "Correct number of points" );
+
+				expectedPoints.forEach( function ( exp, i ) {
+
+					var point = points[ i ];
+
+					assert.numEqual( point.x, exp.x, "Point #" + i + ": x correct" );
+					assert.numEqual( point.y, exp.y, "Point #" + i + ": y correct" );
+
+				} );
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 194 - 0
test/unit/src/extras/curves/LineCurve.tests.js

@@ -0,0 +1,194 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { LineCurve } from '../../../../../src/extras/curves/LineCurve';
+import { Vector2 } from '../../../../../src/math/Vector2';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Curves', () => {
+
+		QUnit.module.todo( 'LineCurve', ( hooks ) => {
+
+			let _points = undefined;
+			let _curve = undefined;
+			hooks.before( function () {
+
+				_points = [
+					new Vector2( 0, 0 ),
+					new Vector2( 10, 10 ),
+					new Vector2( - 10, 10 ),
+					new Vector2( - 8, 5 )
+				];
+
+				_curve = new LineCurve( _points[ 0 ], _points[ 1 ] );
+
+			} );
+
+			// INHERITANCE
+			QUnit.test( "Extending", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// INSTANCING
+			QUnit.test( "Instancing", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// PUBLIC STUFF
+			QUnit.test( "isLineCurve", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getPoint", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getPointAt", ( assert ) => {
+
+				var curve = new LineCurve( _points[ 0 ], _points[ 3 ] );
+
+				var expectedPoints = [
+					new Vector2( 0, 0 ),
+					new Vector2( - 2.4, 1.5 ),
+					new Vector2( - 4, 2.5 ),
+					new Vector2( - 8, 5 )
+				];
+
+				var points = [
+					curve.getPointAt( 0 ),
+					curve.getPointAt( 0.3 ),
+					curve.getPointAt( 0.5 ),
+					curve.getPointAt( 1 )
+				];
+
+				assert.deepEqual( points, expectedPoints, "Correct points" );
+
+			} );
+
+			QUnit.test( "getTangent", ( assert ) => {
+
+				var curve = _curve;
+
+				var tangent = curve.getTangent( 0 );
+				var expectedTangent = Math.sqrt( 0.5 );
+
+				assert.numEqual( tangent.x, expectedTangent, "tangent.x correct" );
+				assert.numEqual( tangent.y, expectedTangent, "tangent.y correct" );
+
+			} );
+
+			// OTHERS
+			QUnit.test( "Simple curve", ( assert ) => {
+
+				var curve = _curve;
+
+				var expectedPoints = [
+					new Vector2( 0, 0 ),
+					new Vector2( 2, 2 ),
+					new Vector2( 4, 4 ),
+					new Vector2( 6, 6 ),
+					new Vector2( 8, 8 ),
+					new Vector2( 10, 10 )
+				];
+
+				var points = curve.getPoints();
+
+				assert.deepEqual( points, expectedPoints, "Correct points for first curve" );
+
+				//
+
+				curve = new LineCurve( _points[ 1 ], _points[ 2 ] );
+
+				expectedPoints = [
+					new Vector2( 10, 10 ),
+					new Vector2( 6, 10 ),
+					new Vector2( 2, 10 ),
+					new Vector2( - 2, 10 ),
+					new Vector2( - 6, 10 ),
+					new Vector2( - 10, 10 )
+				];
+
+				points = curve.getPoints();
+
+				assert.deepEqual( points, expectedPoints, "Correct points for second curve" );
+
+			} );
+
+			QUnit.test( "getLength/getLengths", ( assert ) => {
+
+				var curve = _curve;
+
+				var length = curve.getLength();
+				var expectedLength = Math.sqrt( 200 );
+
+				assert.numEqual( length, expectedLength, "Correct length of curve" );
+
+				var lengths = curve.getLengths( 5 );
+				var expectedLengths = [
+					0.0,
+					Math.sqrt( 8 ),
+					Math.sqrt( 32 ),
+					Math.sqrt( 72 ),
+					Math.sqrt( 128 ),
+					Math.sqrt( 200 )
+				];
+
+				assert.strictEqual( lengths.length, expectedLengths.length, "Correct number of segments" );
+
+				lengths.forEach( function ( segment, i ) {
+
+					assert.numEqual( segment, expectedLengths[ i ], "segment[" + i + "] correct" );
+
+				} );
+
+			} );
+
+			QUnit.test( "getUtoTmapping", ( assert ) => {
+
+				var curve = _curve;
+
+				var start = curve.getUtoTmapping( 0, 0 );
+				var end = curve.getUtoTmapping( 0, curve.getLength() );
+				var somewhere = curve.getUtoTmapping( 0.3, 0 );
+
+				assert.strictEqual( start, 0, "getUtoTmapping( 0, 0 ) is the starting point" );
+				assert.strictEqual( end, 1, "getUtoTmapping( 0, length ) is the ending point" );
+				assert.numEqual( somewhere, 0.3, "getUtoTmapping( 0.3, 0 ) is correct" );
+
+			} );
+
+			QUnit.test( "getSpacedPoints", ( assert ) => {
+
+				var curve = _curve;
+
+				var expectedPoints = [
+					new Vector2( 0, 0 ),
+					new Vector2( 2.5, 2.5 ),
+					new Vector2( 5, 5 ),
+					new Vector2( 7.5, 7.5 ),
+					new Vector2( 10, 10 )
+				];
+
+				var points = curve.getSpacedPoints( 4 );
+
+				assert.strictEqual( points.length, expectedPoints.length, "Correct number of points" );
+				assert.deepEqual( points, expectedPoints, "Correct points calculated" );
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 223 - 0
test/unit/src/extras/curves/LineCurve3.tests.js

@@ -0,0 +1,223 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { LineCurve3 } from '../../../../../src/extras/curves/LineCurve3';
+import { Vector3 } from '../../../../../src/math/Vector3';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Curves', () => {
+
+		QUnit.module.todo( 'LineCurve3', ( hooks ) => {
+
+			let _points = undefined;
+			let _curve = undefined;
+			hooks.before( function () {
+
+				_points = [
+					new Vector3( 0, 0, 0 ),
+					new Vector3( 10, 10, 10 ),
+					new Vector3( - 10, 10, - 10 ),
+					new Vector3( - 8, 5, - 7 )
+				];
+
+				_curve = new LineCurve3( _points[ 0 ], _points[ 1 ] );
+
+			} );
+
+			// INHERITANCE
+			QUnit.test( "Extending", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// INSTANCING
+			QUnit.test( "Instancing", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// PUBLIC STUFF
+			QUnit.test( "isCatmullRomCurve3", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getPoint", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getPointAt", ( assert ) => {
+
+				var curve = new LineCurve3( _points[ 0 ], _points[ 3 ] );
+
+				var expectedPoints = [
+					new Vector3( 0, 0, 0 ),
+					new Vector3( - 2.4, 1.5, - 2.1 ),
+					new Vector3( - 4, 2.5, - 3.5 ),
+					new Vector3( - 8, 5, - 7 )
+				];
+
+				var points = [
+					curve.getPointAt( 0 ),
+					curve.getPointAt( 0.3 ),
+					curve.getPointAt( 0.5 ),
+					curve.getPointAt( 1 )
+				];
+
+				assert.deepEqual( points, expectedPoints, "Correct getPointAt points" );
+
+			} );
+
+			// OTHERS
+			QUnit.test( "Simple curve", ( assert ) => {
+
+				var curve = _curve;
+
+				var expectedPoints = [
+					new Vector3( 0, 0, 0 ),
+					new Vector3( 2, 2, 2 ),
+					new Vector3( 4, 4, 4 ),
+					new Vector3( 6, 6, 6 ),
+					new Vector3( 8, 8, 8 ),
+					new Vector3( 10, 10, 10 )
+				];
+
+				var points = curve.getPoints();
+
+				assert.deepEqual( points, expectedPoints, "Correct points for first curve" );
+
+				//
+
+				curve = new LineCurve3( _points[ 1 ], _points[ 2 ] );
+
+				expectedPoints = [
+					new Vector3( 10, 10, 10 ),
+					new Vector3( 6, 10, 6 ),
+					new Vector3( 2, 10, 2 ),
+					new Vector3( - 2, 10, - 2 ),
+					new Vector3( - 6, 10, - 6 ),
+					new Vector3( - 10, 10, - 10 )
+				];
+
+				points = curve.getPoints();
+
+				assert.deepEqual( points, expectedPoints, "Correct points for second curve" );
+
+			} );
+
+			QUnit.test( "getLength/getLengths", ( assert ) => {
+
+				var curve = _curve;
+
+				var length = curve.getLength();
+				var expectedLength = Math.sqrt( 300 );
+
+				assert.numEqual( length, expectedLength, "Correct length of curve" );
+
+				var lengths = curve.getLengths( 5 );
+				var expectedLengths = [
+					0.0,
+					Math.sqrt( 12 ),
+					Math.sqrt( 48 ),
+					Math.sqrt( 108 ),
+					Math.sqrt( 192 ),
+					Math.sqrt( 300 )
+				];
+
+				assert.strictEqual( lengths.length, expectedLengths.length, "Correct number of segments" );
+
+				lengths.forEach( function ( segment, i ) {
+
+					assert.numEqual( segment, expectedLengths[ i ], "segment[" + i + "] correct" );
+
+				} );
+
+			} );
+
+			QUnit.test( "getTangent/getTangentAt", ( assert ) => {
+
+				var curve = _curve;
+
+				var tangent = curve.getTangent( 0.5 );
+				var expectedTangent = Math.sqrt( 1 / 3 );
+
+				assert.numEqual( tangent.x, expectedTangent, "tangent.x correct" );
+				assert.numEqual( tangent.y, expectedTangent, "tangent.y correct" );
+				assert.numEqual( tangent.z, expectedTangent, "tangent.z correct" );
+
+				tangent = curve.getTangentAt( 0.5 );
+
+				assert.numEqual( tangent.x, expectedTangent, "tangentAt.x correct" );
+				assert.numEqual( tangent.y, expectedTangent, "tangentAt.y correct" );
+				assert.numEqual( tangent.z, expectedTangent, "tangentAt.z correct" );
+
+			} );
+
+			QUnit.test( "computeFrenetFrames", ( assert ) => {
+
+				var curve = _curve;
+
+				var expected = {
+					binormals: new Vector3( - 0.5 * Math.sqrt( 2 ), 0.5 * Math.sqrt( 2 ), 0 ),
+					normals: new Vector3( Math.sqrt( 1 / 6 ), Math.sqrt( 1 / 6 ), - Math.sqrt( 2 / 3 ) ),
+					tangents: new Vector3( Math.sqrt( 1 / 3 ), Math.sqrt( 1 / 3 ), Math.sqrt( 1 / 3 ) )
+				};
+
+				var frames = curve.computeFrenetFrames( 1, false );
+
+				for ( var val in expected ) {
+
+					assert.numEqual( frames[ val ][ 0 ].x, expected[ val ].x, "Frenet frames " + val + ".x correct" );
+					assert.numEqual( frames[ val ][ 0 ].y, expected[ val ].y, "Frenet frames " + val + ".y correct" );
+					assert.numEqual( frames[ val ][ 0 ].z, expected[ val ].z, "Frenet frames " + val + ".z correct" );
+
+				}
+
+			} );
+
+			QUnit.test( "getUtoTmapping", ( assert ) => {
+
+				var curve = _curve;
+
+				var start = curve.getUtoTmapping( 0, 0 );
+				var end = curve.getUtoTmapping( 0, curve.getLength() );
+				var somewhere = curve.getUtoTmapping( 0.7, 0 );
+
+				assert.strictEqual( start, 0, "getUtoTmapping( 0, 0 ) is the starting point" );
+				assert.strictEqual( end, 1, "getUtoTmapping( 0, length ) is the ending point" );
+				assert.numEqual( somewhere, 0.7, "getUtoTmapping( 0.7, 0 ) is correct" );
+
+			} );
+
+			QUnit.test( "getSpacedPoints", ( assert ) => {
+
+				var curve = _curve;
+
+				var expectedPoints = [
+					new Vector3( 0, 0, 0 ),
+					new Vector3( 2.5, 2.5, 2.5 ),
+					new Vector3( 5, 5, 5 ),
+					new Vector3( 7.5, 7.5, 7.5 ),
+					new Vector3( 10, 10, 10 )
+				];
+
+				var points = curve.getSpacedPoints( 4 );
+
+				assert.strictEqual( points.length, expectedPoints.length, "Correct number of points" );
+				assert.deepEqual( points, expectedPoints, "Correct points calculated" );
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 231 - 0
test/unit/src/extras/curves/QuadraticBezierCurve.tests.js

@@ -0,0 +1,231 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { QuadraticBezierCurve } from '../../../../../src/extras/curves/QuadraticBezierCurve';
+import { Vector2 } from '../../../../../src/math/Vector2';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Curves', () => {
+
+		QUnit.module.todo( 'QuadraticBezierCurve', ( hooks ) => {
+
+			let _curve = undefined;
+			hooks.before( function () {
+
+				_curve = new QuadraticBezierCurve(
+					new Vector2( - 10, 0 ),
+					new Vector2( 20, 15 ),
+					new Vector2( 10, 0 )
+				);
+
+			} );
+
+			// INHERITANCE
+			QUnit.test( "Extending", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// INSTANCING
+			QUnit.test( "Instancing", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// PUBLIC STUFF
+			QUnit.test( "isQuadraticBezierCurve", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getPoint", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// OTHERS
+			QUnit.test( "Simple curve", ( assert ) => {
+
+				var curve = _curve;
+
+				var expectedPoints = [
+					new Vector2( - 10, 0 ),
+					new Vector2( 2.5, 5.625 ),
+					new Vector2( 10, 7.5 ),
+					new Vector2( 12.5, 5.625 ),
+					new Vector2( 10, 0 )
+				];
+
+				var points = curve.getPoints( expectedPoints.length - 1 );
+
+				assert.strictEqual( points.length, expectedPoints.length, "Correct number of points" );
+				assert.deepEqual( points, expectedPoints, "Correct points calculated" );
+
+				// symmetry
+				var curveRev = new QuadraticBezierCurve(
+					curve.v2, curve.v1, curve.v0
+				);
+
+				points = curveRev.getPoints( expectedPoints.length - 1 );
+
+				assert.strictEqual( points.length, expectedPoints.length, "Reversed: Correct number of points" );
+				assert.deepEqual( points, expectedPoints.reverse(), "Reversed: Correct points curve" );
+
+			} );
+
+			QUnit.test( "getLength/getLengths", ( assert ) => {
+
+				var curve = _curve;
+
+				var length = curve.getLength();
+				var expectedLength = 31.269026549416683;
+
+				assert.numEqual( length, expectedLength, "Correct length of curve" );
+
+				var expectedLengths = [
+					0,
+					13.707320124663317,
+					21.43814317269643,
+					24.56314317269643,
+					30.718679298818998
+				];
+				var lengths = curve.getLengths( expectedLengths.length - 1 );
+
+				assert.strictEqual( lengths.length, expectedLengths.length, "Correct number of segments" );
+
+				lengths.forEach( function ( segment, i ) {
+
+					assert.numEqual( segment, expectedLengths[ i ], "segment[" + i + "] correct" );
+
+				} );
+
+			} );
+
+			QUnit.test( "getPointAt", ( assert ) => {
+
+				var curve = _curve;
+
+				var expectedPoints = [
+					new Vector2( - 10, 0 ),
+					new Vector2( - 1.5127849599387615, 3.993582003773624 ),
+					new Vector2( 4.310076165722796, 6.269921971403917 ),
+					new Vector2( 10, 0 )
+				];
+
+				var points = [
+					curve.getPointAt( 0 ),
+					curve.getPointAt( 0.3 ),
+					curve.getPointAt( 0.5 ),
+					curve.getPointAt( 1 )
+				];
+
+				assert.deepEqual( points, expectedPoints, "Correct points" );
+
+			} );
+
+			QUnit.test( "getTangent/getTangentAt", ( assert ) => {
+
+				var curve = _curve;
+
+				var expectedTangents = [
+					new Vector2( 0.89443315420562, 0.44720166888975904 ),
+					new Vector2( 0.936329177569021, 0.3511234415884543 ),
+					new Vector2( 1, 0 ),
+					new Vector2( - 5.921189464667277e-13, - 1 ),
+					new Vector2( - 0.5546617882904897, - 0.8320758983472577 )
+				];
+
+				var tangents = [
+					curve.getTangent( 0 ),
+					curve.getTangent( 0.25 ),
+					curve.getTangent( 0.5 ),
+					curve.getTangent( 0.75 ),
+					curve.getTangent( 1 )
+				];
+
+				expectedTangents.forEach( function ( exp, i ) {
+
+					var tangent = tangents[ i ];
+
+					assert.numEqual( tangent.x, exp.x, "getTangent #" + i + ": x correct" );
+					assert.numEqual( tangent.y, exp.y, "getTangent #" + i + ": y correct" );
+
+				} );
+
+				//
+
+				expectedTangents = [
+					new Vector2( 0.89443315420562, 0.44720166888975904 ),
+					new Vector2( 0.9125211423360805, 0.40902954024086674 ),
+					new Vector2( 0.9480289098765387, 0.3181842014278863 ),
+					new Vector2( 0.7969127189169473, - 0.6040944615111106 ),
+					new Vector2( - 0.5546617882904897, - 0.8320758983472577 )
+				];
+
+				tangents = [
+					curve.getTangentAt( 0 ),
+					curve.getTangentAt( 0.25 ),
+					curve.getTangentAt( 0.5 ),
+					curve.getTangentAt( 0.75 ),
+					curve.getTangentAt( 1 )
+				];
+
+				expectedTangents.forEach( function ( exp, i ) {
+
+					var tangent = tangents[ i ];
+
+					assert.numEqual( tangent.x, exp.x, "getTangentAt #" + i + ": x correct" );
+					assert.numEqual( tangent.y, exp.y, "getTangentAt #" + i + ": y correct" );
+
+				} );
+
+			} );
+
+			QUnit.test( "getUtoTmapping", ( assert ) => {
+
+				var curve = _curve;
+
+				var start = curve.getUtoTmapping( 0, 0 );
+				var end = curve.getUtoTmapping( 0, curve.getLength() );
+				var somewhere = curve.getUtoTmapping( 0.5, 1 );
+
+				var expectedSomewhere = 0.015073978276116116;
+
+				assert.strictEqual( start, 0, "getUtoTmapping( 0, 0 ) is the starting point" );
+				assert.strictEqual( end, 1, "getUtoTmapping( 0, length ) is the ending point" );
+				assert.numEqual( somewhere, expectedSomewhere, "getUtoTmapping( 0.5, 1 ) is correct" );
+
+			} );
+
+			QUnit.test( "getSpacedPoints", ( assert ) => {
+
+				var curve = _curve;
+
+				var expectedPoints = [
+					new Vector2( - 10, 0 ),
+					new Vector2( - 4.366603655406173, 2.715408933540383 ),
+					new Vector2( 1.3752241477827831, 5.191972084404416 ),
+					new Vector2( 7.312990279153634, 7.136310044848586 ),
+					new Vector2( 12.499856644824826, 5.653289188715387 ),
+					new Vector2( 10, 0 )
+				];
+
+				var points = curve.getSpacedPoints();
+
+				assert.strictEqual( points.length, expectedPoints.length, "Correct number of points" );
+				assert.deepEqual( points, expectedPoints, "Correct points calculated" );
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 269 - 0
test/unit/src/extras/curves/QuadraticBezierCurve3.tests.js

@@ -0,0 +1,269 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { QuadraticBezierCurve3 } from '../../../../../src/extras/curves/QuadraticBezierCurve3';
+import { Vector3 } from '../../../../../src/math/Vector3';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Curves', () => {
+
+		QUnit.module.todo( 'QuadraticBezierCurve3', ( hooks ) => {
+
+			let _curve = undefined;
+			hooks.before( function () {
+
+				_curve = new QuadraticBezierCurve3(
+					new Vector3( - 10, 0, 2 ),
+					new Vector3( 20, 15, - 5 ),
+					new Vector3( 10, 0, 10 )
+				);
+
+			} );
+
+			// INHERITANCE
+			QUnit.test( "Extending", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// INSTANCING
+			QUnit.test( "Instancing", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// PUBLIC STUFF
+			QUnit.test( "isQuadraticBezierCurve3", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getPoint", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// OTHERS
+			QUnit.test( "Simple curve", ( assert ) => {
+
+				var curve = _curve;
+
+				var expectedPoints = [
+					new Vector3( - 10, 0, 2 ),
+					new Vector3( 2.5, 5.625, - 0.125 ),
+					new Vector3( 10, 7.5, 0.5 ),
+					new Vector3( 12.5, 5.625, 3.875 ),
+					new Vector3( 10, 0, 10 )
+				];
+
+				var points = curve.getPoints( expectedPoints.length - 1 );
+
+				assert.strictEqual( points.length, expectedPoints.length, "Correct number of points" );
+				assert.deepEqual( points, expectedPoints, "Correct points calculated" );
+
+				// symmetry
+				var curveRev = new QuadraticBezierCurve3(
+					curve.v2, curve.v1, curve.v0
+				);
+
+				points = curveRev.getPoints( expectedPoints.length - 1 );
+
+				assert.strictEqual( points.length, expectedPoints.length, "Reversed: Correct number of points" );
+				assert.deepEqual( points, expectedPoints.reverse(), "Reversed: Correct points curve" );
+
+			} );
+
+			QUnit.test( "getLength/getLengths", ( assert ) => {
+
+				var curve = _curve;
+
+				var length = curve.getLength();
+				var expectedLength = 35.47294274967861;
+
+				assert.numEqual( length, expectedLength, "Correct length of curve" );
+
+				var expectedLengths = [
+					0,
+					13.871057998581074,
+					21.62710402732536,
+					26.226696400568883,
+					34.91037361704809
+				];
+				var lengths = curve.getLengths( expectedLengths.length - 1 );
+
+				assert.strictEqual( lengths.length, expectedLengths.length, "Correct number of segments" );
+
+				lengths.forEach( function ( segment, i ) {
+
+					assert.numEqual( segment, expectedLengths[ i ], "segment[" + i + "] correct" );
+
+				} );
+
+			} );
+
+			QUnit.test( "getPointAt", ( assert ) => {
+
+				var curve = _curve;
+
+				var expectedPoints = [
+					new Vector3( - 10, 0, 2 ),
+					new Vector3( - 0.4981634504454243, 4.427089043881476, 0.19308849757196012 ),
+					new Vector3( 6.149415812887238, 6.838853310980195, - 0.20278120208668637 ),
+					new Vector3( 10, 0, 10 )
+				];
+
+				var points = [
+					curve.getPointAt( 0 ),
+					curve.getPointAt( 0.3 ),
+					curve.getPointAt( 0.5 ),
+					curve.getPointAt( 1 )
+				];
+
+				assert.deepEqual( points, expectedPoints, "Correct points" );
+
+			} );
+
+			QUnit.test( "getTangent/getTangentAt", ( assert ) => {
+
+				var curve = _curve;
+
+				var expectedTangents = [
+					new Vector3( 0.8755715084258769, 0.4377711603816079, - 0.2042815331129452 ),
+					new Vector3( 0.9340289249885844, 0.3502608468707904, - 0.07005216937416067 ),
+					new Vector3( 0.9284766908853163, 0, 0.37139067635396156 ),
+					new Vector3( - 3.669031233375946e-13, - 0.6196442885791218, 0.7848827655333463 ),
+					new Vector3( - 0.4263618889888853, - 0.6396068005601663, 0.6396238584473043 )
+				];
+
+				var tangents = [
+					curve.getTangent( 0 ),
+					curve.getTangent( 0.25 ),
+					curve.getTangent( 0.5 ),
+					curve.getTangent( 0.75 ),
+					curve.getTangent( 1 )
+				];
+
+				expectedTangents.forEach( function ( exp, i ) {
+
+					var tangent = tangents[ i ];
+
+					assert.numEqual( tangent.x, exp.x, "getTangent #" + i + ": x correct" );
+					assert.numEqual( tangent.y, exp.y, "getTangent #" + i + ": y correct" );
+
+				} );
+
+				//
+
+				expectedTangents = [
+					new Vector3( 0.8755715084258769, 0.4377711603816079, - 0.2042815331129452 ),
+					new Vector3( 0.9060725703490549, 0.3984742932857448, - 0.14230507668907377 ),
+					new Vector3( 0.9621604167456882, 0.2688562845452628, 0.044312872940942424 ),
+					new Vector3( 0.016586454041780826, - 0.6163270940470614, 0.7873155674098058 ),
+					new Vector3( - 0.4263618889888853, - 0.6396068005601663, 0.6396238584473043 )
+				];
+
+				tangents = [
+					curve.getTangentAt( 0 ),
+					curve.getTangentAt( 0.25 ),
+					curve.getTangentAt( 0.5 ),
+					curve.getTangentAt( 0.75 ),
+					curve.getTangentAt( 1 )
+				];
+
+				expectedTangents.forEach( function ( exp, i ) {
+
+					var tangent = tangents[ i ];
+
+					assert.numEqual( tangent.x, exp.x, "getTangentAt #" + i + ": x correct" );
+					assert.numEqual( tangent.y, exp.y, "getTangentAt #" + i + ": y correct" );
+
+				} );
+
+			} );
+
+			QUnit.test( "getUtoTmapping", ( assert ) => {
+
+				var curve = _curve;
+
+				var start = curve.getUtoTmapping( 0, 0 );
+				var end = curve.getUtoTmapping( 0, curve.getLength() );
+				var somewhere = curve.getUtoTmapping( 0.5, 1 );
+
+				var expectedSomewhere = 0.014760890927167196;
+
+				assert.strictEqual( start, 0, "getUtoTmapping( 0, 0 ) is the starting point" );
+				assert.strictEqual( end, 1, "getUtoTmapping( 0, length ) is the ending point" );
+				assert.numEqual( somewhere, expectedSomewhere, "getUtoTmapping( 0.5, 1 ) is correct" );
+
+			} );
+
+			QUnit.test( "getSpacedPoints", ( assert ) => {
+
+				var curve = _curve;
+
+				var expectedPoints = [
+					new Vector3( - 10, 0, 2 ),
+					new Vector3( - 3.712652983516992, 3.015179001762753, 0.6957120710270492 ),
+					new Vector3( 2.7830973773262975, 5.730399338061483, - 0.1452668772806931 ),
+					new Vector3( 9.575825284074465, 7.48754187603603, 0.3461104039841496 ),
+					new Vector3( 12.345199937734154, 4.575759904730531, 5.142117429101656 ),
+					new Vector3( 10, 0, 10 )
+				];
+
+				var points = curve.getSpacedPoints();
+
+				assert.strictEqual( points.length, expectedPoints.length, "Correct number of points" );
+				assert.deepEqual( points, expectedPoints, "Correct points calculated" );
+
+			} );
+
+			QUnit.test( "computeFrenetFrames", ( assert ) => {
+
+				var curve = _curve;
+
+				var expected = {
+					binormals: [
+						new Vector3( - 0.447201668889759, 0.8944331542056199, 0 ),
+						new Vector3( - 0.2684231751110917, 0.9631753839815436, - 0.01556209353802903 ),
+						new Vector3( 0.3459273556592433, 0.53807011680075, 0.7686447905324219 )
+					],
+					normals: [
+						new Vector3( - 0.18271617600817133, - 0.09135504253146765, - 0.9789121795283909 ),
+						new Vector3( 0.046865035058597876, - 0.003078628350883253, - 0.9988964863970807 ),
+						new Vector3( 0.8357929194629689, - 0.5489842348221077, 0.008155102228190641 )
+					],
+					tangents: [
+						new Vector3( 0.8755715084258767, 0.4377711603816078, - 0.20428153311294514 ),
+						new Vector3( 0.9621604167456884, 0.26885628454526284, 0.04431287294094243 ),
+						new Vector3( - 0.4263618889888853, - 0.6396068005601663, 0.6396238584473043 )
+					]
+				};
+
+				var frames = curve.computeFrenetFrames( 2, false );
+
+				Object.keys( expected ).forEach( function ( group, i ) {
+
+					expected[ group ].forEach( function ( vec, j ) {
+
+						assert.numEqual( frames[ group ][ j ].x, vec.x, "Frenet frames [" + i + ", " + j + "].x correct" );
+						assert.numEqual( frames[ group ][ j ].y, vec.y, "Frenet frames [" + i + ", " + j + "].y correct" );
+						assert.numEqual( frames[ group ][ j ].z, vec.z, "Frenet frames [" + i + ", " + j + "].z correct" );
+
+					} );
+
+				} );
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 192 - 0
test/unit/src/extras/curves/SplineCurve.tests.js

@@ -0,0 +1,192 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { SplineCurve } from '../../../../../src/extras/curves/SplineCurve';
+import { Vector2 } from '../../../../../src/math/Vector2';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Curves', () => {
+
+		QUnit.module.todo( 'SplineCurve', ( hooks ) => {
+
+			let _curve = undefined;
+			hooks.before( function () {
+
+				_curve = new SplineCurve( [
+					new Vector2( - 10, 0 ),
+					new Vector2( - 5, 5 ),
+					new Vector2( 0, 0 ),
+					new Vector2( 5, - 5 ),
+					new Vector2( 10, 0 )
+				] );
+
+			} );
+
+			// INHERITANCE
+			QUnit.test( "Extending", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// INSTANCING
+			QUnit.test( "Instancing", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// PUBLIC STUFF
+			QUnit.test( "isSplineCurve", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			QUnit.test( "getPoint", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// OTHERS
+			QUnit.test( "Simple curve", ( assert ) => {
+
+				var curve = _curve;
+
+				var expectedPoints = [
+					new Vector2( - 10, 0 ),
+					new Vector2( - 6.08, 4.56 ),
+					new Vector2( - 2, 2.48 ),
+					new Vector2( 2, - 2.48 ),
+					new Vector2( 6.08, - 4.56 ),
+					new Vector2( 10, 0 )
+				];
+
+				var points = curve.getPoints( 5 );
+
+				assert.strictEqual( points.length, expectedPoints.length, "1st: Correct number of points" );
+
+				points.forEach( function ( point, i ) {
+
+					assert.numEqual( point.x, expectedPoints[ i ].x, "points[" + i + "].x" );
+					assert.numEqual( point.y, expectedPoints[ i ].y, "points[" + i + "].y" );
+
+				} );
+
+				//
+
+				points = curve.getPoints( 4 );
+
+				assert.deepEqual( points, curve.points, "2nd: Returned points are identical to control points" );
+
+			} );
+
+			QUnit.test( "getLength/getLengths", ( assert ) => {
+
+				var curve = _curve;
+
+				var length = curve.getLength();
+				var expectedLength = 28.876950901868135;
+
+				assert.numEqual( length, expectedLength, "Correct length of curve" );
+
+				var expectedLengths = [
+					0.0,
+					Math.sqrt( 50 ),
+					Math.sqrt( 200 ),
+					Math.sqrt( 450 ),
+					Math.sqrt( 800 )
+				];
+
+				var lengths = curve.getLengths( 4 );
+
+				assert.deepEqual( lengths, expectedLengths, "Correct segment lengths" );
+
+			} );
+
+			QUnit.test( "getPointAt", ( assert ) => {
+
+				var curve = _curve;
+
+				assert.ok( curve.getPointAt( 0 ).equals( curve.points[ 0 ] ), "PointAt 0.0 correct" );
+				assert.ok( curve.getPointAt( 1 ).equals( curve.points[ 4 ] ), "PointAt 1.0 correct" );
+
+				var pointAt = curve.getPointAt( 0.5 );
+				assert.numEqual( pointAt.x, 0.0, "PointAt 0.5 x correct" );
+				assert.numEqual( pointAt.y, 0.0, "PointAt 0.5 y correct" );
+
+			} );
+
+			QUnit.test( "getTangent", ( assert ) => {
+
+				var curve = _curve;
+
+				var expectedTangent = [
+					new Vector2( 0.7068243340243188, 0.7073891155729485 ), // 0
+					new Vector2( 0.7069654305325396, - 0.7072481035902046 ), // 0.5
+					new Vector2( 0.7068243340245123, 0.7073891155727552 ) // 1
+				];
+
+				var tangents = [
+					curve.getTangent( 0 ),
+					curve.getTangent( 0.5 ),
+					curve.getTangent( 1 )
+				];
+
+				tangents.forEach( function ( tangent, i ) {
+
+					assert.numEqual( tangent.x, expectedTangent[ i ].x, "tangent[" + i + "].x" );
+					assert.numEqual( tangent.y, expectedTangent[ i ].y, "tangent[" + i + "].y" );
+
+				} );
+
+			} );
+
+			QUnit.test( "getUtoTmapping", ( assert ) => {
+
+				var curve = _curve;
+
+				var start = curve.getUtoTmapping( 0, 0 );
+				var end = curve.getUtoTmapping( 0, curve.getLength() );
+				var middle = curve.getUtoTmapping( 0.5, 0 );
+
+				assert.strictEqual( start, 0, "getUtoTmapping( 0, 0 ) is the starting point" );
+				assert.strictEqual( end, 1, "getUtoTmapping( 0, length ) is the ending point" );
+				assert.numEqual( middle, 0.5, "getUtoTmapping( 0.5, 0 ) is the middle" );
+
+			} );
+
+			QUnit.test( "getSpacedPoints", ( assert ) => {
+
+				var curve = _curve;
+
+				var expectedPoints = [
+					new Vector2( - 10, 0 ),
+					new Vector2( - 4.996509634683014, 4.999995128640857 ),
+					new Vector2( 0, 0 ),
+					new Vector2( 4.996509634683006, - 4.999995128640857 ),
+					new Vector2( 10, 0 )
+				];
+
+				var points = curve.getSpacedPoints( 4 );
+
+				assert.strictEqual( points.length, expectedPoints.length, "Correct number of points" );
+
+				points.forEach( function ( point, i ) {
+
+					assert.numEqual( point.x, expectedPoints[ i ].x, "points[" + i + "].x" );
+					assert.numEqual( point.y, expectedPoints[ i ].y, "points[" + i + "].y" );
+
+				} );
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 39 - 0
test/unit/src/extras/objects/ImmediateRenderObject.tests.js

@@ -0,0 +1,39 @@
+/**
+ * @author TristanVALCKE / https://github.com/Itee
+ */
+/* global QUnit */
+
+import { ImmediateRenderObject } from '../../../../../src/extras/objects/ImmediateRenderObject';
+
+export default QUnit.module( 'Extras', () => {
+
+	QUnit.module( 'Objects', () => {
+
+		QUnit.module.todo( 'ImmediateRenderObject', () => {
+
+			// INHERITANCE
+			QUnit.test( "Extending", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// INSTANCING
+			QUnit.test( "Instancing", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+			// PUBLIC STUFF
+			QUnit.test( "isImmediateRenderObject", ( assert ) => {
+
+				assert.ok( false, "everything's gonna be alright" );
+
+			} );
+
+		} );
+
+	} );
+
+} );