Prechádzať zdrojové kódy

Move and update previous existing files to new QUnit api, in 3 folders (editor, example, and src) and add all src missings unit test files (with a todo and console warn)

Tristan VALCKE 8 rokov pred
rodič
commit
05959c3bdc
100 zmenil súbory, kde vykonal 2568 pridanie a 222 odobranie
  1. 10 10
      test/unit/editor/TestAddObjectCommandAndRemoveObjectCommand.js
  2. 8 8
      test/unit/editor/TestAddScriptCommand.js
  3. 5 5
      test/unit/editor/TestMassUndoAndRedo.js
  4. 13 13
      test/unit/editor/TestMoveObjectCommand.js
  5. 14 14
      test/unit/editor/TestMultiCmdsCommand.js
  6. 18 18
      test/unit/editor/TestNegativeCases.js
  7. 31 31
      test/unit/editor/TestNestedDoUndoRedo.js
  8. 7 7
      test/unit/editor/TestRemoveScriptCommand.js
  9. 4 4
      test/unit/editor/TestSerialization.js
  10. 5 5
      test/unit/editor/TestSetColorCommand.js
  11. 20 20
      test/unit/editor/TestSetGeometryCommand.js
  12. 8 8
      test/unit/editor/TestSetGeometryValueCommand.js
  13. 5 5
      test/unit/editor/TestSetMaterialColorCommand.js
  14. 5 5
      test/unit/editor/TestSetMaterialCommand.js
  15. 5 5
      test/unit/editor/TestSetMaterialMapCommand.js
  16. 5 5
      test/unit/editor/TestSetMaterialValueCommand.js
  17. 11 11
      test/unit/editor/TestSetPositionCommand.js
  18. 11 11
      test/unit/editor/TestSetRotationCommand.js
  19. 11 11
      test/unit/editor/TestSetScaleCommand.js
  20. 6 6
      test/unit/editor/TestSetSceneCommand.js
  21. 8 8
      test/unit/editor/TestSetScriptValueCommand.js
  22. 5 5
      test/unit/editor/TestSetUuidCommand.js
  23. 7 7
      test/unit/editor/TestSetValueCommand.js
  24. 34 0
      test/unit/src/animation/AnimationAction.js
  25. 6 0
      test/unit/src/animation/AnimationClip.js
  26. 6 0
      test/unit/src/animation/AnimationMixer.js
  27. 107 0
      test/unit/src/animation/AnimationObjectGroup.js
  28. 6 0
      test/unit/src/animation/AnimationUtils.js
  29. 6 0
      test/unit/src/animation/KeyframeTrack.js
  30. 6 0
      test/unit/src/animation/KeyframeTrackConstructor.js
  31. 6 0
      test/unit/src/animation/KeyframeTrackPrototype.js
  32. 6 0
      test/unit/src/animation/PropertyBinding.js
  33. 6 0
      test/unit/src/animation/PropertyMixer.js
  34. 6 0
      test/unit/src/animation/tracks/BooleanKeyframeTrack.js
  35. 6 0
      test/unit/src/animation/tracks/ColorKeyframeTrack.js
  36. 6 0
      test/unit/src/animation/tracks/NumberKeyframeTrack.js
  37. 6 0
      test/unit/src/animation/tracks/QuaternionKeyframeTrack.js
  38. 6 0
      test/unit/src/animation/tracks/StringKeyframeTrack.js
  39. 6 0
      test/unit/src/animation/tracks/VectorKeyFrameTrack.js
  40. 6 0
      test/unit/src/audio/Audio.js
  41. 6 0
      test/unit/src/audio/AudioAnalyser.js
  42. 6 0
      test/unit/src/audio/AudioContext.js
  43. 6 0
      test/unit/src/audio/AudioListener.js
  44. 6 0
      test/unit/src/audio/PositionalAudio.js
  45. 25 0
      test/unit/src/cameras/Camera.js
  46. 6 0
      test/unit/src/cameras/CubeCamera.js
  47. 41 0
      test/unit/src/cameras/OrthographicCamera.js
  48. 50 0
      test/unit/src/cameras/PerspectiveCamera.js
  49. 6 0
      test/unit/src/cameras/StereoCamera.js
  50. 6 0
      test/unit/src/constants.js
  51. 117 0
      test/unit/src/core/BufferAttribute.js
  52. 311 0
      test/unit/src/core/BufferGeometry.js
  53. 38 0
      test/unit/src/core/Clock.js
  54. 6 0
      test/unit/src/core/DirectGeometry.js
  55. 76 0
      test/unit/src/core/EventDispatcher.js
  56. 58 0
      test/unit/src/core/Face3.js
  57. 106 0
      test/unit/src/core/Geometry.js
  58. 29 0
      test/unit/src/core/InstancedBufferAttribute.js
  59. 53 0
      test/unit/src/core/InstancedBufferGeometry.js
  60. 20 0
      test/unit/src/core/InstancedInterleavedBuffer.js
  61. 46 0
      test/unit/src/core/InterleavedBuffer.js
  62. 36 0
      test/unit/src/core/InterleavedBufferAttribute.js
  63. 6 0
      test/unit/src/core/Layers.js
  64. 102 0
      test/unit/src/core/Object3D.js
  65. 119 0
      test/unit/src/core/Raycaster.js
  66. 6 0
      test/unit/src/core/Uniform.js
  67. 6 0
      test/unit/src/extras/SceneUtils.js
  68. 6 0
      test/unit/src/extras/ShapeUtils.js
  69. 6 0
      test/unit/src/extras/core/Curve.js
  70. 6 0
      test/unit/src/extras/core/CurvePath.js
  71. 6 0
      test/unit/src/extras/core/Font.js
  72. 6 0
      test/unit/src/extras/core/Interpolations.js
  73. 6 0
      test/unit/src/extras/core/Path.js
  74. 6 0
      test/unit/src/extras/core/PathPrototype.js
  75. 6 0
      test/unit/src/extras/core/Shape.js
  76. 6 0
      test/unit/src/extras/core/ShapePath.js
  77. 6 0
      test/unit/src/extras/curves/ArcCurve.js
  78. 125 0
      test/unit/src/extras/curves/CatmullRomCurve3.js
  79. 6 0
      test/unit/src/extras/curves/CubicBezierCurve.js
  80. 6 0
      test/unit/src/extras/curves/CubicBezierCurve3.js
  81. 6 0
      test/unit/src/extras/curves/EllipseCurve.js
  82. 6 0
      test/unit/src/extras/curves/LineCurve.js
  83. 6 0
      test/unit/src/extras/curves/LineCurve3.js
  84. 6 0
      test/unit/src/extras/curves/QuadraticBezierCurve.js
  85. 6 0
      test/unit/src/extras/curves/QuadraticBezierCurve3.js
  86. 6 0
      test/unit/src/extras/curves/SplineCurve.js
  87. 6 0
      test/unit/src/extras/objects/ImmediateRenderObject.js
  88. 6 0
      test/unit/src/extras/objects/MorphBlendMesh.js
  89. 38 0
      test/unit/src/geometries/BoxGeometry.tests.js
  90. 38 0
      test/unit/src/geometries/CircleBufferGeometry.tests.js
  91. 38 0
      test/unit/src/geometries/CircleGeometry.tests.js
  92. 46 0
      test/unit/src/geometries/CylinderGeometry.tests.js
  93. 34 0
      test/unit/src/geometries/DodecahedronGeometry.tests.js
  94. 274 0
      test/unit/src/geometries/EdgesGeometry.js
  95. 1 0
      test/unit/src/geometries/ExtrudeGeometry.tests.js
  96. 34 0
      test/unit/src/geometries/IcosahedronGeometry.tests.js
  97. 1 0
      test/unit/src/geometries/LatheGeometry.tests.js
  98. 34 0
      test/unit/src/geometries/OctahedronGeometry.tests.js
  99. 1 0
      test/unit/src/geometries/ParametricGeometry.tests.js
  100. 38 0
      test/unit/src/geometries/PlaneBufferGeometry.tests.js

+ 10 - 10
test/unit/editor/TestAddObjectCommandAndRemoveObjectCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "AddObjectCommandAndRemoveObjectCommand" );
+QUnit.module( "AddObjectCommandAndRemoveObjectCommand" );
 
-test( "Test AddObjectCommand and RemoveObjectCommand (Undo and Redo)", function() {
+QUnit.test( "Test AddObjectCommand and RemoveObjectCommand (Undo and Redo)", function( assert ) {
 
 	// setup
 	var editor = new Editor();
@@ -23,15 +23,15 @@ test( "Test AddObjectCommand and RemoveObjectCommand (Undo and Redo)", function(
 		cmd.updatable = false;
 
 		editor.execute( cmd );
-		ok( editor.scene.children.length == 1, "OK, adding '" + object.type + "' was successful " );
+		assert.ok( editor.scene.children.length == 1, "OK, adding '" + object.type + "' was successful " );
 
 		editor.undo();
-		ok( editor.scene.children.length == 0, "OK, adding '" + object.type + "' is undone (was removed)" );
+		assert.ok( editor.scene.children.length == 0, "OK, adding '" + object.type + "' is undone (was removed)" );
 
 		editor.redo();
-		ok( editor.scene.children[ 0 ].name == object.name, "OK, removed '" + object.type + "' was added again (redo)" );
+		assert.ok( editor.scene.children[ 0 ].name == object.name, "OK, removed '" + object.type + "' was added again (redo)" );
 
-		ok( editor.selected == object, "OK, focus was set on recovered object after Add-Redo" );
+		assert.ok( editor.selected == object, "OK, focus was set on recovered object after Add-Redo" );
 
 
 		// Test Remove
@@ -39,15 +39,15 @@ test( "Test AddObjectCommand and RemoveObjectCommand (Undo and Redo)", function(
 		cmd.updatable = false;
 
 		editor.execute( cmd );
-		ok( editor.scene.children.length == 0, "OK, removing object was successful" );
+		assert.ok( editor.scene.children.length == 0, "OK, removing object was successful" );
 
 		editor.undo();
-		ok( editor.scene.children[ 0 ].name == object.name, "OK, removed object was added again (undo)" );
+		assert.ok( editor.scene.children[ 0 ].name == object.name, "OK, removed object was added again (undo)" );
 
-		ok( editor.selected == object, "OK, focus was set on recovered object after Delete-Undo" );
+		assert.ok( editor.selected == object, "OK, focus was set on recovered object after Delete-Undo" );
 
 		editor.redo();
-		ok( editor.scene.children.length == 0, "OK, object was removed again (redo)" );
+		assert.ok( editor.scene.children.length == 0, "OK, object was removed again (redo)" );
 
 
 	} );

+ 8 - 8
test/unit/editor/TestAddScriptCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "AddScriptCommand" );
+QUnit.module( "AddScriptCommand" );
 
-test( "Test AddScriptCommand (Undo and Redo)", function() {
+QUnit.test( "Test AddScriptCommand (Undo and Redo)", function( assert ) {
 
 	var editor = new Editor();
 
@@ -24,7 +24,7 @@ test( "Test AddScriptCommand (Undo and Redo)", function() {
 		editor.execute( new AddObjectCommand( item ) );
 
 	} );
-	ok( editor.scene.children.length == 2, "OK, the box and the sphere have been added" );
+	assert.ok( editor.scene.children.length == 2, "OK, the box and the sphere have been added" );
 
 	// add scripts to the objects
 	for ( var i = 0; i < scripts.length; i ++ ) {
@@ -36,24 +36,24 @@ test( "Test AddScriptCommand (Undo and Redo)", function() {
 	}
 
 	var scriptsKeys = Object.keys( editor.scripts );
-	ok( getScriptCount( editor ) == scripts.length, "OK, correct number of scripts have been added" );
+	assert.ok( getScriptCount( editor ) == scripts.length, "OK, correct number of scripts have been added" );
 
 	for ( var i = 0; i < objects.length; i ++ ) {
 
-		ok( objects[ i ].uuid == scriptsKeys[ i ], "OK, script key #" + i + " matches the object's UUID" );
+		assert.ok( objects[ i ].uuid == scriptsKeys[ i ], "OK, script key #" + i + " matches the object's UUID" );
 
 	}
 
 	editor.undo();
-	ok( getScriptCount( editor ) == scripts.length - 1, "OK, one script has been removed by undo" );
+	assert.ok( getScriptCount( editor ) == scripts.length - 1, "OK, one script has been removed by undo" );
 
 	editor.redo();
-	ok( getScriptCount( editor ) == scripts.length, "OK, one script has been added again by redo" );
+	assert.ok( getScriptCount( editor ) == scripts.length, "OK, one script has been added again by redo" );
 
 
 	for ( var i = 0; i < scriptsKeys.length; i ++ ) {
 
-		ok( editor.scripts[ scriptsKeys[ i ] ][ 0 ] == scripts[ i ], "OK, script #" + i + " is still assigned correctly" );
+		assert.ok( editor.scripts[ scriptsKeys[ i ] ][ 0 ] == scripts[ i ], "OK, script #" + i + " is still assigned correctly" );
 
 	}
 

+ 5 - 5
test/unit/editor/TestMassUndoAndRedo.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "MassUndoAndRedo" );
+QUnit.module( "MassUndoAndRedo" );
 
-test( "MassUndoAndRedo (stress test)", function() {
+QUnit.test( "MassUndoAndRedo (stress test)", function( assert ) {
 
 	var editor = new Editor();
 
@@ -24,7 +24,7 @@ test( "MassUndoAndRedo (stress test)", function() {
 
 	}
 
-	ok( editor.scene.children.lenght = MAX_OBJECTS,
+	assert.ok( editor.scene.children.lenght = MAX_OBJECTS,
 		"OK, " + MAX_OBJECTS + " objects have been added" );
 
 	// remove all objects
@@ -37,7 +37,7 @@ test( "MassUndoAndRedo (stress test)", function() {
 	}
 
 
-	ok( editor.scene.children.length == 0,
+	assert.ok( editor.scene.children.length == 0,
 		"OK, all objects have been removed by undos" );
 
 
@@ -49,7 +49,7 @@ test( "MassUndoAndRedo (stress test)", function() {
 
 	}
 
-	ok( editor.scene.children.lenght = MAX_OBJECTS,
+	assert.ok( editor.scene.children.lenght = MAX_OBJECTS,
 		"OK, " + MAX_OBJECTS + " objects have been added again by redos" );
 
 } );

+ 13 - 13
test/unit/editor/TestMoveObjectCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "MoveObjectCommand" );
+QUnit.module( "MoveObjectCommand" );
 
-test( "Test MoveObjectCommand (Undo and Redo)", function() {
+QUnit.test( "Test MoveObjectCommand (Undo and Redo)", function( assert ) {
 
 	var editor = new Editor();
 
@@ -19,24 +19,24 @@ test( "Test MoveObjectCommand (Undo and Redo)", function() {
 	editor.execute( new AddObjectCommand( lukeSkywalker ) );
 
 
-	ok( anakinSkywalker.parent.name == "Scene", "OK, Anakin's parent is 'Scene' " );
-	ok( lukeSkywalker.parent.name   == "Scene", "OK, Luke's parent is 'Scene' " );
+	assert.ok( anakinSkywalker.parent.name == "Scene", "OK, Anakin's parent is 'Scene' " );
+	assert.ok( lukeSkywalker.parent.name   == "Scene", "OK, Luke's parent is 'Scene' " );
 
 	// Tell Luke, Anakin is his father
 	editor.execute( new MoveObjectCommand( lukeSkywalker, anakinSkywalker ) );
 
-	ok( true === true, "(Luke has been told who his father is)" );
-	ok( anakinSkywalker.parent.name == "Scene", "OK, Anakin's parent is still 'Scene' " );
-	ok( lukeSkywalker.parent.name   == anakinsName, "OK, Luke's parent is '" + anakinsName + "' " );
+	assert.ok( true === true, "(Luke has been told who his father is)" );
+	assert.ok( anakinSkywalker.parent.name == "Scene", "OK, Anakin's parent is still 'Scene' " );
+	assert.ok( lukeSkywalker.parent.name   == anakinsName, "OK, Luke's parent is '" + anakinsName + "' " );
 
 	editor.undo();
-	ok( true === true, "(Statement undone)" );
-	ok( anakinSkywalker.parent.name == "Scene", "OK, Anakin's parent is still 'Scene' " );
-	ok( lukeSkywalker.parent.name   == "Scene", "OK, Luke's parent is 'Scene' again " );
+	assert.ok( true === true, "(Statement undone)" );
+	assert.ok( anakinSkywalker.parent.name == "Scene", "OK, Anakin's parent is still 'Scene' " );
+	assert.ok( lukeSkywalker.parent.name   == "Scene", "OK, Luke's parent is 'Scene' again " );
 
 	editor.redo();
-	ok( true === true, "(Statement redone)" );
-	ok( anakinSkywalker.parent.name == "Scene", "OK, Anakin's parent is still 'Scene' " );
-	ok( lukeSkywalker.parent.name   == anakinsName, "OK, Luke's parent is '" + anakinsName + "' again " );
+	assert.ok( true === true, "(Statement redone)" );
+	assert.ok( anakinSkywalker.parent.name == "Scene", "OK, Anakin's parent is still 'Scene' " );
+	assert.ok( lukeSkywalker.parent.name   == anakinsName, "OK, Luke's parent is '" + anakinsName + "' again " );
 
 } );

+ 14 - 14
test/unit/editor/TestMultiCmdsCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "MultiCmdsCommand" );
+QUnit.module( "MultiCmdsCommand" );
 
-test( "Test MultiCmdsCommand (Undo and Redo)", function() {
+QUnit.test( "Test MultiCmdsCommand (Undo and Redo)", function( assert ) {
 
 	var editor = new Editor();
 	var box = aBox( 'Multi Command Box' );
@@ -60,21 +60,21 @@ test( "Test MultiCmdsCommand (Undo and Redo)", function() {
 
 
 	// test one modified value for each command
-	ok( box.geometry.parameters.widthSegments == 7, "OK, widthSegments has been modified accordingly after two multi executes (expected: 7, actual: " + box.geometry.parameters.widthSegments + ")" );
-	ok( box.position.y == 5, "OK, y position has been modified accordingly after two multi executes (expected: 5, actual: " + box.position.y + ")" );
-	ok( box.rotation.x == 0.4, "OK, x rotation has been modified accordingly after two multi executes (expected: 0.4, actual: " + box.rotation.x + ") " );
-	ok( box.scale.z == 1.6, "OK, z scale has been modified accordingly after two multi executes (expected: 1.6, actual: " + box.scale.z + ")" );
+	assert.ok( box.geometry.parameters.widthSegments == 7, "OK, widthSegments has been modified accordingly after two multi executes (expected: 7, actual: " + box.geometry.parameters.widthSegments + ")" );
+	assert.ok( box.position.y == 5, "OK, y position has been modified accordingly after two multi executes (expected: 5, actual: " + box.position.y + ")" );
+	assert.ok( box.rotation.x == 0.4, "OK, x rotation has been modified accordingly after two multi executes (expected: 0.4, actual: " + box.rotation.x + ") " );
+	assert.ok( box.scale.z == 1.6, "OK, z scale has been modified accordingly after two multi executes (expected: 1.6, actual: " + box.scale.z + ")" );
 
 	editor.undo();
-	ok( box.geometry.parameters.widthSegments == 2, "OK, widthSegments has been modified accordingly after undo (expected: 2, actual: " + box.geometry.parameters.widthSegments + ")" );
-	ok( box.position.y == 2, "OK, y position has been modified accordingly after undo (expected: 2, actual: " + box.position.y + ")" );
-	ok( box.rotation.x == 0.1, "OK, x rotation has been modified accordingly after undo (expected: 0.1, actual: " + box.rotation.x + ")" );
-	ok( box.scale.z == 1.3, "OK, z scale has been modified accordingly after undo (expected: 1.3, actual: " + box.scale.z + ")" );
+	assert.ok( box.geometry.parameters.widthSegments == 2, "OK, widthSegments has been modified accordingly after undo (expected: 2, actual: " + box.geometry.parameters.widthSegments + ")" );
+	assert.ok( box.position.y == 2, "OK, y position has been modified accordingly after undo (expected: 2, actual: " + box.position.y + ")" );
+	assert.ok( box.rotation.x == 0.1, "OK, x rotation has been modified accordingly after undo (expected: 0.1, actual: " + box.rotation.x + ")" );
+	assert.ok( box.scale.z == 1.3, "OK, z scale has been modified accordingly after undo (expected: 1.3, actual: " + box.scale.z + ")" );
 
 	editor.redo();
-	ok( box.geometry.parameters.widthSegments == 7, "OK, widthSegments has been modified accordingly after two multi executes (expected: 7, actual: " + box.geometry.parameters.widthSegments + ")" );
-	ok( box.position.y == 5, "OK, y position has been modified accordingly after two multi executes (expected: 5, actual: " + box.position.y + ")" );
-	ok( box.rotation.x == 0.4, "OK, x rotation has been modified accordingly after two multi executes (expected: 0.4, actual: " + box.rotation.x + ") " );
-	ok( box.scale.z == 1.6, "OK, z scale has been modified accordingly after two multi executes (expected: 1.6, actual: " + box.scale.z + ")" );
+	assert.ok( box.geometry.parameters.widthSegments == 7, "OK, widthSegments has been modified accordingly after two multi executes (expected: 7, actual: " + box.geometry.parameters.widthSegments + ")" );
+	assert.ok( box.position.y == 5, "OK, y position has been modified accordingly after two multi executes (expected: 5, actual: " + box.position.y + ")" );
+	assert.ok( box.rotation.x == 0.4, "OK, x rotation has been modified accordingly after two multi executes (expected: 0.4, actual: " + box.rotation.x + ") " );
+	assert.ok( box.scale.z == 1.6, "OK, z scale has been modified accordingly after two multi executes (expected: 1.6, actual: " + box.scale.z + ")" );
 
 } );

+ 18 - 18
test/unit/editor/TestNegativeCases.js

@@ -3,21 +3,21 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "NegativeCases" );
+QUnit.module( "NegativeCases" );
 
-test( "Test unwanted situations ", function() {
+QUnit.test( "Test unwanted situations ", function( assert ) {
 
 	var editor = new Editor();
 
 	// illegal
 	editor.undo();
-	ok( editor.history.undos.length == 0, "OK, (illegal) undo did not affect the undo history" );
-	ok( editor.history.redos.length == 0, "OK, (illegal) undo did not affect the redo history" );
+	assert.ok( editor.history.undos.length == 0, "OK, (illegal) undo did not affect the undo history" );
+	assert.ok( editor.history.redos.length == 0, "OK, (illegal) undo did not affect the redo history" );
 
 	// illegal
 	editor.redo();
-	ok( editor.history.undos.length == 0, "OK, (illegal) redo did not affect the undo history" );
-	ok( editor.history.redos.length == 0, "OK, (illegal) redo did not affect the redo history" );
+	assert.ok( editor.history.undos.length == 0, "OK, (illegal) redo did not affect the undo history" );
+	assert.ok( editor.history.redos.length == 0, "OK, (illegal) redo did not affect the redo history" );
 
 
 	var box = aBox();
@@ -25,31 +25,31 @@ test( "Test unwanted situations ", function() {
 	cmd.updatable = false;
 	editor.execute( cmd );
 
-	ok( editor.history.undos.length == 1, "OK, execute changed undo history" );
-	ok( editor.history.redos.length == 0, "OK, execute did not change redo history" );
+	assert.ok( editor.history.undos.length == 1, "OK, execute changed undo history" );
+	assert.ok( editor.history.redos.length == 0, "OK, execute did not change redo history" );
 
 	// illegal
 	editor.redo();
-	ok( editor.history.undos.length == 1, "OK, (illegal) redo did not affect the undo history" );
-	ok( editor.history.redos.length == 0, "OK, (illegal) redo did not affect the redo history" );
+	assert.ok( editor.history.undos.length == 1, "OK, (illegal) redo did not affect the undo history" );
+	assert.ok( editor.history.redos.length == 0, "OK, (illegal) redo did not affect the redo history" );
 
 
 	editor.undo();
-	ok( editor.history.undos.length == 0, "OK, undo changed the undo history" );
-	ok( editor.history.redos.length == 1, "OK, undo changed the redo history" );
+	assert.ok( editor.history.undos.length == 0, "OK, undo changed the undo history" );
+	assert.ok( editor.history.redos.length == 1, "OK, undo changed the redo history" );
 
 	// illegal
 	editor.undo();
-	ok( editor.history.undos.length == 0, "OK, (illegal) undo did not affect the undo history" );
-	ok( editor.history.redos.length == 1, "OK, (illegal) undo did not affect the redo history" );
+	assert.ok( editor.history.undos.length == 0, "OK, (illegal) undo did not affect the undo history" );
+	assert.ok( editor.history.redos.length == 1, "OK, (illegal) undo did not affect the redo history" );
 
 	editor.redo();
-	ok( editor.history.undos.length == 1, "OK, redo changed the undo history" );
-	ok( editor.history.redos.length == 0, "OK, undo changed the redo history" );
+	assert.ok( editor.history.undos.length == 1, "OK, redo changed the undo history" );
+	assert.ok( editor.history.redos.length == 0, "OK, undo changed the redo history" );
 
 	// illegal
 	editor.redo();
-	ok( editor.history.undos.length == 1, "OK, (illegal) did not affect the undo history" );
-	ok( editor.history.redos.length == 0, "OK, (illegal) did not affect the redo history" );
+	assert.ok( editor.history.undos.length == 1, "OK, (illegal) did not affect the undo history" );
+	assert.ok( editor.history.redos.length == 0, "OK, (illegal) did not affect the redo history" );
 
 } );

+ 31 - 31
test/unit/editor/TestNestedDoUndoRedo.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "NestedDoUndoRedo" );
+QUnit.module( "NestedDoUndoRedo" );
 
-test( "Test nested Do's, Undo's and Redo's", function() {
+QUnit.test( "Test nested Do's, Undo's and Redo's", function( assert ) {
 
 	var editor = new Editor();
 
@@ -46,17 +46,17 @@ test( "Test nested Do's, Undo's and Redo's", function() {
 
 	/* full check */
 
-	ok( mesh.position.x ==   102, "OK, X position is correct " );
-	ok( mesh.position.y ==     3, "OK, Y position is correct " );
-	ok( mesh.position.z ==     4, "OK, Z position is correct " );
+	assert.ok( mesh.position.x ==   102, "OK, X position is correct " );
+	assert.ok( mesh.position.y ==     3, "OK, Y position is correct " );
+	assert.ok( mesh.position.z ==     4, "OK, Z position is correct " );
 
-	ok( mesh.rotation.x ==    12, "OK, X rotation is correct " );
-	ok( mesh.rotation.y ==  1013, "OK, Y rotation is correct " );
-	ok( mesh.rotation.z ==    14, "OK, Z rotation is correct " );
+	assert.ok( mesh.rotation.x ==    12, "OK, X rotation is correct " );
+	assert.ok( mesh.rotation.y ==  1013, "OK, Y rotation is correct " );
+	assert.ok( mesh.rotation.z ==    14, "OK, Z rotation is correct " );
 
-	ok( mesh.scale.x    ==    22, "OK, X scale is correct " );
-	ok( mesh.scale.y    ==    23, "OK, Y scale is correct " );
-	ok( mesh.scale.z    == 10024, "OK, Z scale is correct " );
+	assert.ok( mesh.scale.x    ==    22, "OK, X scale is correct " );
+	assert.ok( mesh.scale.y    ==    23, "OK, Y scale is correct " );
+	assert.ok( mesh.scale.z    == 10024, "OK, Z scale is correct " );
 
 
 	editor.undo();  // rescaling undone
@@ -65,44 +65,44 @@ test( "Test nested Do's, Undo's and Redo's", function() {
 
 	/* full check */
 
-	ok( mesh.position.x ==     2, "OK, X position is correct " );
-	ok( mesh.position.y ==     3, "OK, Y position is correct " );
-	ok( mesh.position.z ==     4, "OK, Z position is correct " );
+	assert.ok( mesh.position.x ==     2, "OK, X position is correct " );
+	assert.ok( mesh.position.y ==     3, "OK, Y position is correct " );
+	assert.ok( mesh.position.z ==     4, "OK, Z position is correct " );
 
-	ok( mesh.rotation.x ==    12, "OK, X rotation is correct " );
-	ok( mesh.rotation.y ==    13, "OK, Y rotation is correct " );
-	ok( mesh.rotation.z ==    14, "OK, Z rotation is correct " );
+	assert.ok( mesh.rotation.x ==    12, "OK, X rotation is correct " );
+	assert.ok( mesh.rotation.y ==    13, "OK, Y rotation is correct " );
+	assert.ok( mesh.rotation.z ==    14, "OK, Z rotation is correct " );
 
-	ok( mesh.scale.x    ==    22, "OK, X scale is correct " );
-	ok( mesh.scale.y    ==    23, "OK, Y scale is correct " );
-	ok( mesh.scale.z    ==    24, "OK, Z scale is correct " );
+	assert.ok( mesh.scale.x    ==    22, "OK, X scale is correct " );
+	assert.ok( mesh.scale.y    ==    23, "OK, Y scale is correct " );
+	assert.ok( mesh.scale.z    ==    24, "OK, Z scale is correct " );
 
 
 	editor.redo();  // translation redone
 	editor.redo();  // rotation redone
 
 	editor.execute( new RemoveObjectCommand( mesh ) );
-	ok( editor.scene.children.length == 0, "OK, object removal was successful" );
+	assert.ok( editor.scene.children.length == 0, "OK, object removal was successful" );
 
 	editor.undo();  // removal undone
-	ok( mesh.rotation.y ==    1013, "OK, Y rotation is correct " );
+	assert.ok( mesh.rotation.y ==    1013, "OK, Y rotation is correct " );
 
 
 	editor.undo();  // rotation undone (expected!)
 
 	/* full check */
 
-	ok( mesh.position.x ==   102, "OK, X position is correct " );
-	ok( mesh.position.y ==     3, "OK, Y position is correct " );
-	ok( mesh.position.z ==     4, "OK, Z position is correct " );
+	assert.ok( mesh.position.x ==   102, "OK, X position is correct " );
+	assert.ok( mesh.position.y ==     3, "OK, Y position is correct " );
+	assert.ok( mesh.position.z ==     4, "OK, Z position is correct " );
 
-	ok( mesh.rotation.x ==    12, "OK, X rotation is correct " );
-	ok( mesh.rotation.y ==    13, "OK, Y rotation is correct " );
-	ok( mesh.rotation.z ==    14, "OK, Z rotation is correct " );
+	assert.ok( mesh.rotation.x ==    12, "OK, X rotation is correct " );
+	assert.ok( mesh.rotation.y ==    13, "OK, Y rotation is correct " );
+	assert.ok( mesh.rotation.z ==    14, "OK, Z rotation is correct " );
 
-	ok( mesh.scale.x    ==    22, "OK, X scale is correct " );
-	ok( mesh.scale.y    ==    23, "OK, Y scale is correct " );
-	ok( mesh.scale.z    ==    24, "OK, Z scale is correct " );
+	assert.ok( mesh.scale.x    ==    22, "OK, X scale is correct " );
+	assert.ok( mesh.scale.y    ==    23, "OK, Y scale is correct " );
+	assert.ok( mesh.scale.z    ==    24, "OK, Z scale is correct " );
 
 
 } );

+ 7 - 7
test/unit/editor/TestRemoveScriptCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "RemoveScriptCommand" );
+QUnit.module( "RemoveScriptCommand" );
 
-test( "Test RemoveScriptCommand (Undo and Redo)", function() {
+QUnit.test( "Test RemoveScriptCommand (Undo and Redo)", function( assert ) {
 
 	var editor = new Editor();
 
@@ -24,7 +24,7 @@ test( "Test RemoveScriptCommand (Undo and Redo)", function() {
 		editor.execute( new AddObjectCommand( item ) );
 
 	} );
-	ok( editor.scene.children.length == 2, "OK, the box and the sphere have been added" );
+	assert.ok( editor.scene.children.length == 2, "OK, the box and the sphere have been added" );
 
 	// add scripts to the objects
 	for ( var i = 0; i < scripts.length; i ++ ) {
@@ -42,23 +42,23 @@ test( "Test RemoveScriptCommand (Undo and Redo)", function() {
 		editor.execute( cmd );
 
 	}
-	ok( getScriptCount( editor ) == 0, "OK, all scripts have been removed" );
+	assert.ok( getScriptCount( editor ) == 0, "OK, all scripts have been removed" );
 
 	scripts.map( function() {
 
 		editor.undo();
 
 	} );
-	ok( getScriptCount( editor ) == scripts.length, "OK, all scripts have been added again by undo(s)" );
+	assert.ok( getScriptCount( editor ) == scripts.length, "OK, all scripts have been added again by undo(s)" );
 
 	var scriptsKeys = Object.keys( editor.scripts );
 	for ( var i = 0; i < scriptsKeys.length; i ++ ) {
 
-		ok( editor.scripts[ scriptsKeys[ i ] ][ 0 ] == scripts[ i ], "OK, script #" + i + " is still assigned correctly" );
+		assert.ok( editor.scripts[ scriptsKeys[ i ] ][ 0 ] == scripts[ i ], "OK, script #" + i + " is still assigned correctly" );
 
 	}
 
 	editor.redo();
-	ok( getScriptCount( editor ) == scripts.length - 1, "OK, one script has been removed again by redo" );
+	assert.ok( getScriptCount( editor ) == scripts.length - 1, "OK, one script has been removed again by redo" );
 
 } );

+ 4 - 4
test/unit/editor/TestSerialization.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "Serialization" );
+QUnit.module( "Serialization" );
 
-test( "Test Serialization", function( assert ) {
+QUnit.test( "Test Serialization", function( assert ) {
 
 	// setup
 	var editor = new Editor();
@@ -321,7 +321,7 @@ test( "Test Serialization", function( assert ) {
 
 			var history2 = JSON.stringify( editor.history.toJSON() );
 
-			ok( history == history2, "OK, forward serializing was successful for " + name );
+			assert.ok( history == history2, "OK, forward serializing was successful for " + name );
 
 			editor.clear();
 
@@ -346,7 +346,7 @@ test( "Test Serialization", function( assert ) {
 
 			var history2 = JSON.stringify( editor.history.toJSON() );
 
-			ok( history == history2, "OK, backward serializing was successful for " + name );
+			assert.ok( history == history2, "OK, backward serializing was successful for " + name );
 
 			editor.clear();
 

+ 5 - 5
test/unit/editor/TestSetColorCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "SetColorCommand" );
+QUnit.module( "SetColorCommand" );
 
-test( "Test SetColorCommand (Undo and Redo)", function() {
+QUnit.test( "Test SetColorCommand (Undo and Redo)", function( assert ) {
 
 	var editor = new Editor();
 	var pointLight = aPointlight( "The light Light" );
@@ -25,15 +25,15 @@ test( "Test SetColorCommand (Undo and Redo)", function() {
 
 	} );
 
-	ok( pointLight.color.getHex() == colors[ colors.length - 1 ],
+	assert.ok( pointLight.color.getHex() == colors[ colors.length - 1 ],
 		"OK, color has been set successfully (expected: '" + colors[ colors.length - 1 ] + "', actual: '" + pointLight.color.getHex() + "')" );
 
 	editor.undo();
-	ok( pointLight.color.getHex() == colors[ colors.length - 2 ],
+	assert.ok( pointLight.color.getHex() == colors[ colors.length - 2 ],
 		"OK, color has been set successfully after undo (expected: '" + colors[ colors.length - 2 ] + "', actual: '" + pointLight.color.getHex() + "')" );
 
 	editor.redo();
-	ok( pointLight.color.getHex() == colors[ colors.length - 1 ],
+	assert.ok( pointLight.color.getHex() == colors[ colors.length - 1 ],
 		"OK, color has been set successfully after redo (expected: '" + colors[ colors.length - 1 ] + "', actual: '" + pointLight.color.getHex() + "')" );
 
 

+ 20 - 20
test/unit/editor/TestSetGeometryCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "SetGeometryCommand" );
+QUnit.module( "SetGeometryCommand" );
 
-test( "Test SetGeometryCommand (Undo and Redo)", function() {
+QUnit.test( "Test SetGeometryCommand (Undo and Redo)", function( assert ) {
 
 	var editor = new Editor();
 
@@ -30,34 +30,34 @@ test( "Test SetGeometryCommand (Undo and Redo)", function() {
 		var actualParams = box.geometry.parameters;
 		var expectedParams = geometryParams[ i ].geometry.parameters;
 
-		ok( actualParams.width == expectedParams.width, "OK, box width matches the corresponding value from boxGeometry"  + ( i + 1 ) );
-		ok( actualParams.height == expectedParams.height, "OK, box height matches the corresponding value from boxGeometry" + ( i + 1 ) );
-		ok( actualParams.depth == expectedParams.depth, "OK, box depth matches the corresponding value from boxGeometry"  + ( i + 1 ) );
-		ok( actualParams.widthSegments == expectedParams.widthSegments, "OK, box widthSegments matches the corresponding value from boxGeometry"  + ( i + 1 ) );
-		ok( actualParams.heightSegments == expectedParams.heightSegments, "OK, box heightSegments matches the corresponding value from boxGeometry"  + ( i + 1 ) );
-		ok( actualParams.depthSegments == expectedParams.depthSegments, "OK, box depthSegments matches the corresponding value from boxGeometry"  + ( i + 1 ) );
+		assert.ok( actualParams.width == expectedParams.width, "OK, box width matches the corresponding value from boxGeometry"  + ( i + 1 ) );
+		assert.ok( actualParams.height == expectedParams.height, "OK, box height matches the corresponding value from boxGeometry" + ( i + 1 ) );
+		assert.ok( actualParams.depth == expectedParams.depth, "OK, box depth matches the corresponding value from boxGeometry"  + ( i + 1 ) );
+		assert.ok( actualParams.widthSegments == expectedParams.widthSegments, "OK, box widthSegments matches the corresponding value from boxGeometry"  + ( i + 1 ) );
+		assert.ok( actualParams.heightSegments == expectedParams.heightSegments, "OK, box heightSegments matches the corresponding value from boxGeometry"  + ( i + 1 ) );
+		assert.ok( actualParams.depthSegments == expectedParams.depthSegments, "OK, box depthSegments matches the corresponding value from boxGeometry"  + ( i + 1 ) );
 
 	}
 
 	editor.undo();
 	var actualParams = box.geometry.parameters;
 	var expectedParams = geometryParams[ 0 ].geometry.parameters;
-	ok( actualParams.width == expectedParams.width, "OK, box width matches the corresponding value from boxGeometry1 (after undo)" );
-	ok( actualParams.height == expectedParams.height, "OK, box height matches the corresponding value from boxGeometry1 (after undo)" );
-	ok( actualParams.depth == expectedParams.depth, "OK, box depth matches the corresponding value from boxGeometry1 (after undo)" );
-	ok( actualParams.widthSegments == expectedParams.widthSegments, "OK, box widthSegments matches the corresponding value from boxGeometry1 (after undo)" );
-	ok( actualParams.heightSegments == expectedParams.heightSegments, "OK, box heightSegments matches the corresponding value from boxGeometry1 (after undo)" );
-	ok( actualParams.depthSegments == expectedParams.depthSegments, "OK, box depthSegments matches the corresponding value from boxGeometry1 (after undo)" );
+	assert.ok( actualParams.width == expectedParams.width, "OK, box width matches the corresponding value from boxGeometry1 (after undo)" );
+	assert.ok( actualParams.height == expectedParams.height, "OK, box height matches the corresponding value from boxGeometry1 (after undo)" );
+	assert.ok( actualParams.depth == expectedParams.depth, "OK, box depth matches the corresponding value from boxGeometry1 (after undo)" );
+	assert.ok( actualParams.widthSegments == expectedParams.widthSegments, "OK, box widthSegments matches the corresponding value from boxGeometry1 (after undo)" );
+	assert.ok( actualParams.heightSegments == expectedParams.heightSegments, "OK, box heightSegments matches the corresponding value from boxGeometry1 (after undo)" );
+	assert.ok( actualParams.depthSegments == expectedParams.depthSegments, "OK, box depthSegments matches the corresponding value from boxGeometry1 (after undo)" );
 
 	editor.redo();
 	var actualParams = box.geometry.parameters;
 	var expectedParams = geometryParams[ 1 ].geometry.parameters;
-	ok( actualParams.width == expectedParams.width, "OK, box width matches the corresponding value from boxGeometry2 (after redo)" );
-	ok( actualParams.height == expectedParams.height, "OK, box height matches the corresponding value from boxGeometry2 (after redo)" );
-	ok( actualParams.depth == expectedParams.depth, "OK, box depth matches the corresponding value from boxGeometry2 (after redo)" );
-	ok( actualParams.widthSegments == expectedParams.widthSegments, "OK, box widthSegments matches the corresponding value from boxGeometry2 (after redo)" );
-	ok( actualParams.heightSegments == expectedParams.heightSegments, "OK, box heightSegments matches the corresponding value from boxGeometry2 (after redo)" );
-	ok( actualParams.depthSegments == expectedParams.depthSegments, "OK, box depthSegments matches the corresponding value from boxGeometry2 (after redo)" );
+	assert.ok( actualParams.width == expectedParams.width, "OK, box width matches the corresponding value from boxGeometry2 (after redo)" );
+	assert.ok( actualParams.height == expectedParams.height, "OK, box height matches the corresponding value from boxGeometry2 (after redo)" );
+	assert.ok( actualParams.depth == expectedParams.depth, "OK, box depth matches the corresponding value from boxGeometry2 (after redo)" );
+	assert.ok( actualParams.widthSegments == expectedParams.widthSegments, "OK, box widthSegments matches the corresponding value from boxGeometry2 (after redo)" );
+	assert.ok( actualParams.heightSegments == expectedParams.heightSegments, "OK, box heightSegments matches the corresponding value from boxGeometry2 (after redo)" );
+	assert.ok( actualParams.depthSegments == expectedParams.depthSegments, "OK, box depthSegments matches the corresponding value from boxGeometry2 (after redo)" );
 
 
 } );

+ 8 - 8
test/unit/editor/TestSetGeometryValueCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "SetGeometryValueCommand" );
+QUnit.module( "SetGeometryValueCommand" );
 
-test( "Test SetGeometryValueCommand (Undo and Redo)", function() {
+QUnit.test( "Test SetGeometryValueCommand (Undo and Redo)", function( assert ) {
 
 	var editor = new Editor();
 	var box = aBox( 'The Box' );
@@ -33,19 +33,19 @@ test( "Test SetGeometryValueCommand (Undo and Redo)", function() {
 
 	}
 
-	ok( box.geometry.name == testData[ 1 ].name, "OK, box.geometry.name is correct after executes" );
-	ok( box.geometry.uuid == testData[ 1 ].uuid, "OK, box.geometry.uuid is correct after executes" );
+	assert.ok( box.geometry.name == testData[ 1 ].name, "OK, box.geometry.name is correct after executes" );
+	assert.ok( box.geometry.uuid == testData[ 1 ].uuid, "OK, box.geometry.uuid is correct after executes" );
 
 	editor.undo();
 	editor.undo();
 
-	ok( box.geometry.name == testData[ 0 ].name, "OK, box.geometry.name is correct after undos" );
-	ok( box.geometry.uuid == testData[ 0 ].uuid, "OK, box.geometry.uuid is correct after undos" );
+	assert.ok( box.geometry.name == testData[ 0 ].name, "OK, box.geometry.name is correct after undos" );
+	assert.ok( box.geometry.uuid == testData[ 0 ].uuid, "OK, box.geometry.uuid is correct after undos" );
 
 	editor.redo();
 	editor.redo();
 
-	ok( box.geometry.name == testData[ 1 ].name, "OK, box.geometry.name is correct after executes" );
-	ok( box.geometry.uuid == testData[ 1 ].uuid, "OK, box.geometry.uuid is correct after executes" );
+	assert.ok( box.geometry.name == testData[ 1 ].name, "OK, box.geometry.name is correct after executes" );
+	assert.ok( box.geometry.uuid == testData[ 1 ].uuid, "OK, box.geometry.uuid is correct after executes" );
 
 } );

+ 5 - 5
test/unit/editor/TestSetMaterialColorCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "SetMaterialColorCommand" );
+QUnit.module( "SetMaterialColorCommand" );
 
-test( "Test for SetMaterialColorCommand (Undo and Redo)", function() {
+QUnit.test( "Test for SetMaterialColorCommand (Undo and Redo)", function( assert ) {
 
 	// Setup scene
 	var editor = new Editor();
@@ -31,13 +31,13 @@ test( "Test for SetMaterialColorCommand (Undo and Redo)", function() {
 
 		} );
 
-		ok( box.material[ attributeName ].getHex() == colors[ colors.length - 1 ], "OK, " + attributeName + " was set correctly to last color " );
+		assert.ok( box.material[ attributeName ].getHex() == colors[ colors.length - 1 ], "OK, " + attributeName + " was set correctly to last color " );
 
 		editor.undo();
-		ok( box.material[ attributeName ].getHex() == colors[ colors.length - 2 ], "OK, " + attributeName + " is set correctly to second to last color after undo" );
+		assert.ok( box.material[ attributeName ].getHex() == colors[ colors.length - 2 ], "OK, " + attributeName + " is set correctly to second to last color after undo" );
 
 		editor.redo();
-		ok( box.material[ attributeName ].getHex() == colors[ colors.length - 1 ], "OK, " + attributeName + " is set correctly to last color after redo" );
+		assert.ok( box.material[ attributeName ].getHex() == colors[ colors.length - 1 ], "OK, " + attributeName + " is set correctly to last color after redo" );
 
 
 	} );

+ 5 - 5
test/unit/editor/TestSetMaterialCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "SetMaterialCommand" );
+QUnit.module( "SetMaterialCommand" );
 
-test( "Test for SetMaterialCommand (Undo and Redo)", function() {
+QUnit.test( "Test for SetMaterialCommand (Undo and Redo)", function( assert ) {
 
 	// setup
 	var editor = new Editor();
@@ -38,7 +38,7 @@ test( "Test for SetMaterialCommand (Undo and Redo)", function() {
 	var i = materialClasses.length - 1;
 
 	// initial test
-	ok( box.material.type == materialClasses[ i ],
+	assert.ok( box.material.type == materialClasses[ i ],
 		"OK, initial material type was set correctly (expected: '" + materialClasses[ i ] + "', actual: '" + box.material.type + "')" );
 
 
@@ -48,7 +48,7 @@ test( "Test for SetMaterialCommand (Undo and Redo)", function() {
 
 		editor.undo();
 		-- i;
-		ok( box.material.type == materialClasses[ i ],
+		assert.ok( box.material.type == materialClasses[ i ],
 			"OK, material type was set correctly after undo (expected: '" + materialClasses[ i ] + "', actual: '" + box.material.type + "')" );
 
 	}
@@ -58,7 +58,7 @@ test( "Test for SetMaterialCommand (Undo and Redo)", function() {
 
 		editor.redo();
 		++ i;
-		ok( box.material.type == materialClasses[ i ],
+		assert.ok( box.material.type == materialClasses[ i ],
 			"OK, material type was set correctly after redo (expected: '" + materialClasses[ i ] + "', actual: '" + box.material.type + "')" );
 
 	}

+ 5 - 5
test/unit/editor/TestSetMaterialMapCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "SetMaterialMapCommand" );
+QUnit.module( "SetMaterialMapCommand" );
 
-test( "Test for SetMaterialMapCommand (Undo and Redo)", function() {
+QUnit.test( "Test for SetMaterialMapCommand (Undo and Redo)", function( assert ) {
 
 	// setup
 	var editor = new Editor();
@@ -54,15 +54,15 @@ test( "Test for SetMaterialMapCommand (Undo and Redo)", function() {
 		} );
 
 
-		ok( box.material[ mapName ].image.src == images[ images.length - 1 ].image.src,
+		assert.ok( box.material[ mapName ].image.src == images[ images.length - 1 ].image.src,
 			"OK, " + mapName + " set correctly " );
 
 		editor.undo();
-		ok( box.material[ mapName ].image.src == images[ images.length - 2 ].image.src,
+		assert.ok( box.material[ mapName ].image.src == images[ images.length - 2 ].image.src,
 			"OK, " + mapName + " set correctly after undo " );
 
 		editor.redo();
-		ok( box.material[ mapName ].image.src == images[ images.length - 1 ].image.src,
+		assert.ok( box.material[ mapName ].image.src == images[ images.length - 1 ].image.src,
 			"OK, " + mapName + " set correctly after redo" );
 
 	} );

+ 5 - 5
test/unit/editor/TestSetMaterialValueCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "SetMaterialValueCommand" );
+QUnit.module( "SetMaterialValueCommand" );
 
-test( "Test for SetMaterialValueCommand (Undo and Redo)", function() {
+QUnit.test( "Test for SetMaterialValueCommand (Undo and Redo)", function( assert ) {
 
 	// setup scene
 	var editor = new Editor();
@@ -46,15 +46,15 @@ test( "Test for SetMaterialValueCommand (Undo and Redo)", function() {
 		} );
 
 		var length = testData[ attributeName ].length;
-		ok( box.material[ attributeName ] == testData[ attributeName ][ length - 1 ],
+		assert.ok( box.material[ attributeName ] == testData[ attributeName ][ length - 1 ],
 			"OK, " + attributeName + " was set correctly to the last value (expected: '" + testData[ attributeName ][ length - 1 ] + "', actual: '" + box.material[ attributeName ] + "')" );
 
 		editor.undo();
-		ok( box.material[ attributeName ] == testData[ attributeName ][ length - 2 ],
+		assert.ok( box.material[ attributeName ] == testData[ attributeName ][ length - 2 ],
 			"OK, " + attributeName + " was set correctly to the second to the last value after undo (expected: '" + testData[ attributeName ][ length - 2 ] + "', actual: '" + box.material[ attributeName ] + "')" );
 
 		editor.redo();
-		ok( box.material[ attributeName ] == testData[ attributeName ][ length - 1 ],
+		assert.ok( box.material[ attributeName ] == testData[ attributeName ][ length - 1 ],
 			"OK, " + attributeName + " was set correctly to the last value again after redo (expected: '" + testData[ attributeName ][ length - 1 ] + "', actual: '" + box.material[ attributeName ] + "')" );
 
 	} );

+ 11 - 11
test/unit/editor/TestSetPositionCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "SetPositionCommand" );
+QUnit.module( "SetPositionCommand" );
 
-test( "Test SetPositionCommand (Undo and Redo)", function() {
+QUnit.test( "Test SetPositionCommand (Undo and Redo)", function( assert ) {
 
 	var editor = new Editor();
 	var box = aBox();
@@ -29,20 +29,20 @@ test( "Test SetPositionCommand (Undo and Redo)", function() {
 
 	} );
 
-	ok( box.position.x == positions[ positions.length - 1 ].x, "OK, changing X position was successful" );
-	ok( box.position.y == positions[ positions.length - 1 ].y, "OK, changing Y position was successful" );
-	ok( box.position.z == positions[ positions.length - 1 ].z, "OK, changing Z position was successful" );
+	assert.ok( box.position.x == positions[ positions.length - 1 ].x, "OK, changing X position was successful" );
+	assert.ok( box.position.y == positions[ positions.length - 1 ].y, "OK, changing Y position was successful" );
+	assert.ok( box.position.z == positions[ positions.length - 1 ].z, "OK, changing Z position was successful" );
 
 
 	editor.undo();
-	ok( box.position.x == positions[ positions.length - 2 ].x, "OK, changing X position was successful (after undo)" );
-	ok( box.position.y == positions[ positions.length - 2 ].y, "OK, changing Y position was successful (after undo)" );
-	ok( box.position.z == positions[ positions.length - 2 ].z, "OK, changing Z position was successful (after undo)" );
+	assert.ok( box.position.x == positions[ positions.length - 2 ].x, "OK, changing X position was successful (after undo)" );
+	assert.ok( box.position.y == positions[ positions.length - 2 ].y, "OK, changing Y position was successful (after undo)" );
+	assert.ok( box.position.z == positions[ positions.length - 2 ].z, "OK, changing Z position was successful (after undo)" );
 
 	editor.redo();
-	ok( box.position.x == positions[ positions.length - 1 ].x, "OK, changing X position was successful (after redo)" );
-	ok( box.position.y == positions[ positions.length - 1 ].y, "OK, changing Y position was successful (after redo)" );
-	ok( box.position.z == positions[ positions.length - 1 ].z, "OK, changing Z position was successful (after redo)" );
+	assert.ok( box.position.x == positions[ positions.length - 1 ].x, "OK, changing X position was successful (after redo)" );
+	assert.ok( box.position.y == positions[ positions.length - 1 ].y, "OK, changing Y position was successful (after redo)" );
+	assert.ok( box.position.z == positions[ positions.length - 1 ].z, "OK, changing Z position was successful (after redo)" );
 
 
 } );

+ 11 - 11
test/unit/editor/TestSetRotationCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "SetRotationCommand" );
+QUnit.module( "SetRotationCommand" );
 
-test( "Test SetRotationCommand (Undo and Redo)", function() {
+QUnit.test( "Test SetRotationCommand (Undo and Redo)", function( assert ) {
 
 	// setup
 	var editor = new Editor();
@@ -32,19 +32,19 @@ test( "Test SetRotationCommand (Undo and Redo)", function() {
 	} );
 
 
-	ok( box.rotation.x == rotations[ rotations.length - 1 ].x, "OK, changing X rotation was successful" );
-	ok( box.rotation.y == rotations[ rotations.length - 1 ].y, "OK, changing Y rotation was successful" );
-	ok( box.rotation.z == rotations[ rotations.length - 1 ].z, "OK, changing Z rotation was successful" );
+	assert.ok( box.rotation.x == rotations[ rotations.length - 1 ].x, "OK, changing X rotation was successful" );
+	assert.ok( box.rotation.y == rotations[ rotations.length - 1 ].y, "OK, changing Y rotation was successful" );
+	assert.ok( box.rotation.z == rotations[ rotations.length - 1 ].z, "OK, changing Z rotation was successful" );
 
 	editor.undo();
-	ok( box.rotation.x == rotations[ rotations.length - 2 ].x, "OK, changing X rotation was successful (after undo)" );
-	ok( box.rotation.y == rotations[ rotations.length - 2 ].y, "OK, changing Y rotation was successful (after undo)" );
-	ok( box.rotation.z == rotations[ rotations.length - 2 ].z, "OK, changing Z rotation was successful (after undo)" );
+	assert.ok( box.rotation.x == rotations[ rotations.length - 2 ].x, "OK, changing X rotation was successful (after undo)" );
+	assert.ok( box.rotation.y == rotations[ rotations.length - 2 ].y, "OK, changing Y rotation was successful (after undo)" );
+	assert.ok( box.rotation.z == rotations[ rotations.length - 2 ].z, "OK, changing Z rotation was successful (after undo)" );
 
 	editor.redo();
-	ok( box.rotation.x == rotations[ rotations.length - 1 ].x, "OK, changing X rotation was successful (after redo)" );
-	ok( box.rotation.y == rotations[ rotations.length - 1 ].y, "OK, changing Y rotation was successful (after redo)" );
-	ok( box.rotation.z == rotations[ rotations.length - 1 ].z, "OK, changing Z rotation was successful (after redo)" );
+	assert.ok( box.rotation.x == rotations[ rotations.length - 1 ].x, "OK, changing X rotation was successful (after redo)" );
+	assert.ok( box.rotation.y == rotations[ rotations.length - 1 ].y, "OK, changing Y rotation was successful (after redo)" );
+	assert.ok( box.rotation.z == rotations[ rotations.length - 1 ].z, "OK, changing Z rotation was successful (after redo)" );
 
 
 

+ 11 - 11
test/unit/editor/TestSetScaleCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "SetScaleCommand" );
+QUnit.module( "SetScaleCommand" );
 
-test( "Test SetScaleCommand (Undo and Redo)", function() {
+QUnit.test( "Test SetScaleCommand (Undo and Redo)", function( assert ) {
 
 	// setup
 	var editor = new Editor();
@@ -31,21 +31,21 @@ test( "Test SetScaleCommand (Undo and Redo)", function() {
 
 	} );
 
-	ok( box.scale.x == scales[ scales.length - 1 ].x, "OK, setting X scale value was successful" );
-	ok( box.scale.y == scales[ scales.length - 1 ].y, "OK, setting Y scale value was successful" );
-	ok( box.scale.z == scales[ scales.length - 1 ].z, "OK, setting Z scale value was successful" );
+	assert.ok( box.scale.x == scales[ scales.length - 1 ].x, "OK, setting X scale value was successful" );
+	assert.ok( box.scale.y == scales[ scales.length - 1 ].y, "OK, setting Y scale value was successful" );
+	assert.ok( box.scale.z == scales[ scales.length - 1 ].z, "OK, setting Z scale value was successful" );
 
 
 	editor.undo();
-	ok( box.scale.x == scales[ scales.length - 2 ].x, "OK, X scale is correct after undo" );
-	ok( box.scale.y == scales[ scales.length - 2 ].y, "OK, Y scale is correct after undo" );
-	ok( box.scale.z == scales[ scales.length - 2 ].z, "OK, Z scale is correct after undo" );
+	assert.ok( box.scale.x == scales[ scales.length - 2 ].x, "OK, X scale is correct after undo" );
+	assert.ok( box.scale.y == scales[ scales.length - 2 ].y, "OK, Y scale is correct after undo" );
+	assert.ok( box.scale.z == scales[ scales.length - 2 ].z, "OK, Z scale is correct after undo" );
 
 
 	editor.redo();
-	ok( box.scale.x == scales[ scales.length - 1 ].x, "OK, X scale is correct after redo" );
-	ok( box.scale.y == scales[ scales.length - 1 ].y, "OK, Y scale is correct after redo" );
-	ok( box.scale.z == scales[ scales.length - 1 ].z, "OK, Z scale is correct after redo" );
+	assert.ok( box.scale.x == scales[ scales.length - 1 ].x, "OK, X scale is correct after redo" );
+	assert.ok( box.scale.y == scales[ scales.length - 1 ].y, "OK, Y scale is correct after redo" );
+	assert.ok( box.scale.z == scales[ scales.length - 1 ].z, "OK, Z scale is correct after redo" );
 
 
 } );

+ 6 - 6
test/unit/editor/TestSetSceneCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "TestCmdSetScene" );
+QUnit.module( "TestCmdSetScene" );
 
-test( "Test for SetSceneCommand (Undo and Redo)", function() {
+QUnit.test( "Test for SetSceneCommand (Undo and Redo)", function( assert ) {
 
 	// setup
 	var editor = new Editor();
@@ -36,13 +36,13 @@ test( "Test for SetSceneCommand (Undo and Redo)", function() {
 	} );
 
 	// tests
-	ok( editor.scene.children.length = scenes.length,
+	assert.ok( editor.scene.children.length = scenes.length,
 		"OK, all scenes have been merged" );
 
 	var i = 0;
 	while ( i < editor.scene.children.length ) {
 
-		ok( editor.scene.children[ i ].name == scenes[ i ].obj.name,
+		assert.ok( editor.scene.children[ i ].name == scenes[ i ].obj.name,
 			"OK, editor.scene.children[ " + i + " ].name matches scenes[ " + i + " ].obj.name" );
 		i ++;
 
@@ -52,7 +52,7 @@ test( "Test for SetSceneCommand (Undo and Redo)", function() {
 	var i = 0;
 	while ( i < editor.scene.children.length ) {
 
-		ok( editor.scene.children[ i ].name == scenes[ i ].obj.name,
+		assert.ok( editor.scene.children[ i ].name == scenes[ i ].obj.name,
 			"OK, editor.scene.children[ " + i + " ].name matches scenes[ " + i + " ].obj.name after undo" );
 		i ++;
 
@@ -63,7 +63,7 @@ test( "Test for SetSceneCommand (Undo and Redo)", function() {
 	var i = 0;
 	while ( i < editor.scene.children.length ) {
 
-		ok( editor.scene.children[ i ].name == scenes[ i ].obj.name,
+		assert.ok( editor.scene.children[ i ].name == scenes[ i ].obj.name,
 			"OK, editor.scene.children[ " + i + " ].name matches scenes[ " + i + " ].obj.name after redo" );
 		i ++;
 

+ 8 - 8
test/unit/editor/TestSetScriptValueCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "SetScriptValueCommand" );
+QUnit.module( "SetScriptValueCommand" );
 
-test( "Test SetScriptValueCommand for source (Undo and Redo)", function() {
+QUnit.test( "Test SetScriptValueCommand for source (Undo and Redo)", function( assert ) {
 
 
 	// setup
@@ -41,15 +41,15 @@ test( "Test SetScriptValueCommand for source (Undo and Redo)", function() {
 	} );
 
 	var length = testSourceData.length;
-	ok( editor.scripts[ box.uuid ][ 0 ][ 'source' ] == testSourceData[ length - 1 ].source,
+	assert.ok( editor.scripts[ box.uuid ][ 0 ][ 'source' ] == testSourceData[ length - 1 ].source,
 		"OK, 'source' was set correctly to the last value (expected: '" + testSourceData[ length - 1 ].source + "', actual: '" + editor.scripts[ box.uuid ][ 0 ][ 'source' ] + "')" );
 
 	editor.undo();
-	ok( editor.scripts[ box.uuid ][ 0 ][ 'source' ] == testSourceData[ length - 2 ].source,
+	assert.ok( editor.scripts[ box.uuid ][ 0 ][ 'source' ] == testSourceData[ length - 2 ].source,
 		"OK, 'source' was set correctly to the second to the last value after undo (expected: '" + testSourceData[ length - 2 ].source + "', actual: '" + editor.scripts[ box.uuid ][ 0 ][ 'source' ] + "')" );
 
 	editor.redo();
-	ok( editor.scripts[ box.uuid ][ 0 ][ 'source' ] == testSourceData[ length - 1 ].source,
+	assert.ok( editor.scripts[ box.uuid ][ 0 ][ 'source' ] == testSourceData[ length - 1 ].source,
 		"OK, 'source' was set correctly to the last value again after redo (expected: '" + testSourceData[ length - 1 ].source + "', actual: '" + editor.scripts[ box.uuid ][ 0 ][ 'source' ]	 + "')" );
 
 
@@ -64,14 +64,14 @@ test( "Test SetScriptValueCommand for source (Undo and Redo)", function() {
 	} );
 
 	var scriptName = editor.scripts[ box.uuid ][ 0 ][ "name" ];
-	ok( scriptName == names[ names.length - 1 ], "OK, the script name corresponds to the last script name that was assigned" );
+	assert.ok( scriptName == names[ names.length - 1 ], "OK, the script name corresponds to the last script name that was assigned" );
 
 	editor.undo();
 	scriptName = editor.scripts[ box.uuid ][ 0 ][ "name" ];
-	ok( scriptName == names[ names.length - 2 ], "OK, the script name corresponds to the second last script name that was assigned" );
+	assert.ok( scriptName == names[ names.length - 2 ], "OK, the script name corresponds to the second last script name that was assigned" );
 
 	editor.redo();
 	scriptName = editor.scripts[ box.uuid ][ 0 ][ "name" ];
-	ok( scriptName == names[ names.length - 1 ], "OK, the script name corresponds to the last script name that was assigned, again" );
+	assert.ok( scriptName == names[ names.length - 1 ], "OK, the script name corresponds to the last script name that was assigned, again" );
 
 } );

+ 5 - 5
test/unit/editor/TestSetUuidCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "SetUuidCommand" );
+QUnit.module( "SetUuidCommand" );
 
-test( "Test SetUuidCommand (Undo and Redo)", function() {
+QUnit.test( "Test SetUuidCommand (Undo and Redo)", function( assert ) {
 
 	var editor = new Editor();
 	var object = aBox( 'UUID test box' );
@@ -22,15 +22,15 @@ test( "Test SetUuidCommand (Undo and Redo)", function() {
 
 	} );
 
-	ok( object.uuid == uuids[ uuids.length - 1 ],
+	assert.ok( object.uuid == uuids[ uuids.length - 1 ],
 		"OK, UUID on actual object matches last UUID in the test data array " );
 
 	editor.undo();
-	ok( object.uuid == uuids[ uuids.length - 2 ],
+	assert.ok( object.uuid == uuids[ uuids.length - 2 ],
 		"OK, UUID on actual object matches second to the last UUID in the test data array (after undo)" );
 
 	editor.redo();
-	ok( object.uuid == uuids[ uuids.length - 1 ],
+	assert.ok( object.uuid == uuids[ uuids.length - 1 ],
 		"OK, UUID on actual object matches last UUID in the test data array again (after redo) " );
 
 

+ 7 - 7
test/unit/editor/TestSetValueCommand.js

@@ -3,9 +3,9 @@
  * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  */
 
-module( "SetValueCommand" );
+QUnit.module( "SetValueCommand" );
 
-test( "Test SetValueCommand (Undo and Redo)", function() {
+QUnit.test( "Test SetValueCommand (Undo and Redo)", function( assert ) {
 
 	var editor = new Editor();
 
@@ -20,7 +20,7 @@ test( "Test SetValueCommand (Undo and Redo)", function() {
 
 		editor.execute( new AddObjectCommand( object ) );
 
-		ok( 0 == 0, "Testing object of type '" + object.type + "'" );
+		assert.ok( 0 == 0, "Testing object of type '" + object.type + "'" );
 
 		[ 'name', 'fov', 'near', 'far', 'intensity', 'distance', 'angle', 'exponent', 'decay', 'visible', 'userData' ].map( function( item ) {
 
@@ -29,18 +29,18 @@ test( "Test SetValueCommand (Undo and Redo)", function() {
 				var cmd = new SetValueCommand( object, item, valueBefore );
 				cmd.updatable = false;
 				editor.execute( cmd );
-				ok( object[ item ] == valueBefore, " OK, the attribute '" + item + "' is correct after first execute (expected: '" + valueBefore + "', actual: '" + object[ item ] + "')" );
+				assert.ok( object[ item ] == valueBefore, " OK, the attribute '" + item + "' is correct after first execute (expected: '" + valueBefore + "', actual: '" + object[ item ] + "')" );
 
 				var cmd = new SetValueCommand( object, item, valueAfter );
 				cmd.updatable = false;
 				editor.execute( cmd );
-				ok( object[ item ] == valueAfter, " OK, the attribute '" + item + "' is correct after second execute (expected: '" + valueAfter + "', actual: '" + object[ item ] + "')" );
+				assert.ok( object[ item ] == valueAfter, " OK, the attribute '" + item + "' is correct after second execute (expected: '" + valueAfter + "', actual: '" + object[ item ] + "')" );
 
 				editor.undo();
-				ok( object[ item ] == valueBefore, " OK, the attribute '" + item + "' is correct after undo (expected: '" + valueBefore + "', actual: '" + object[ item ] + "')" );
+				assert.ok( object[ item ] == valueBefore, " OK, the attribute '" + item + "' is correct after undo (expected: '" + valueBefore + "', actual: '" + object[ item ] + "')" );
 
 				editor.redo();
-				ok( object[ item ] == valueAfter, " OK, the attribute '" + item + "' is correct after redo (expected: '" + valueAfter + "', actual: '" + object[ item ] + "')" );
+				assert.ok( object[ item ] == valueAfter, " OK, the attribute '" + item + "' is correct after redo (expected: '" + valueAfter + "', actual: '" + object[ item ] + "')" );
 
 			}
 

+ 34 - 0
test/unit/src/animation/AnimationAction.js

@@ -0,0 +1,34 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of AnimationAction")
+
+//QUnit.module( "AnimationAction" );
+//
+//QUnit.test( "Instancing", function( assert ) {
+//
+//    var mixer = new THREE.AnimationMixer();
+//    var clip = new THREE.AnimationClip();
+//
+//    assert.throws(
+//        function() {
+//            new THREE.AnimationAction()
+//        },
+//        new Error("Mixer can't be null or undefined !"),
+//        "raised error instance about undefined or null mixer"
+//    );
+//
+//    assert.throws(
+//        function() {
+//            new THREE.AnimationAction(mixer)
+//        },
+//        new Error("Clip can't be null or undefined !"),
+//        "raised error instance about undefined or null clip"
+//    );
+//
+//    var animationAction = new THREE.AnimationAction(mixer, clip);
+//    assert.ok( animationAction, "animationAction instanciated" );
+//
+//} );

+ 6 - 0
test/unit/src/animation/AnimationClip.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of AnimationClip")

+ 6 - 0
test/unit/src/animation/AnimationMixer.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of AnimationMixer")

+ 107 - 0
test/unit/src/animation/AnimationObjectGroup.js

@@ -0,0 +1,107 @@
+/**
+ * @author tschw
+ */
+
+QUnit.module( "AnimationObjectGroup" );
+
+var ObjectA = new THREE.Object3D(),
+	ObjectB = new THREE.Object3D(),
+	ObjectC = new THREE.Object3D(),
+
+	PathA = 'object.position',
+	PathB = 'object.rotation',
+	PathC = 'object.scale',
+
+	ParsedPathA = THREE.PropertyBinding.parseTrackName( PathA ),
+	ParsedPathB = THREE.PropertyBinding.parseTrackName( PathB ),
+	ParsedPathC = THREE.PropertyBinding.parseTrackName( PathC );
+
+
+QUnit.test( "smoke test", function( assert ) {
+
+	var expect = function expect( testIndex, group, bindings, path, cached, roots ) {
+
+		var rootNodes = [], pathsOk = true, nodesOk = true;
+
+		for ( var i = group.nCachedObjects_, n = bindings.length; i !== n; ++ i ) {
+
+			if ( bindings[ i ].path !== path ) pathsOk = false;
+			rootNodes.push( bindings[ i ].rootNode );
+
+		}
+
+		for ( var i = 0, n = roots.length; i !== n; ++ i ) {
+
+			if ( rootNodes.indexOf( roots[ i ] ) === -1 ) nodesOk = false;
+
+		}
+
+		assert.ok( pathsOk, testIndex + " paths" );
+		assert.ok( nodesOk, testIndex + " nodes");
+		assert.ok( group.nCachedObjects_ === cached, testIndex + " cache size" );
+		assert.ok( bindings.length - group.nCachedObjects_ === roots.length, testIndex + " object count" );
+
+	};
+
+	// initial state
+
+	var groupA = new THREE.AnimationObjectGroup();
+	assert.ok( groupA instanceof THREE.AnimationObjectGroup, "constructor (w/o args)" );
+
+	var bindingsAA = groupA.subscribe_( PathA, ParsedPathA );
+	expect( 0, groupA, bindingsAA, PathA, 0, [] );
+
+	var groupB = new THREE.AnimationObjectGroup( ObjectA, ObjectB );
+	assert.ok( groupB instanceof THREE.AnimationObjectGroup, "constructor (with args)" );
+
+	var bindingsBB = groupB.subscribe_( PathB, ParsedPathB );
+	expect( 1, groupB, bindingsBB, PathB, 0, [ ObjectA, ObjectB ] );
+
+	// add
+
+	groupA.add( ObjectA, ObjectB );
+	expect( 2, groupA, bindingsAA, PathA, 0, [ ObjectA, ObjectB ] );
+
+	groupB.add( ObjectC );
+	expect( 3, groupB, bindingsBB, PathB, 0, [ ObjectA, ObjectB, ObjectC ] );
+
+	// remove
+
+	groupA.remove( ObjectA, ObjectC );
+	expect( 4, groupA, bindingsAA, PathA, 1, [ ObjectB ] );
+
+	groupB.remove( ObjectA, ObjectB, ObjectC );
+	expect( 5, groupB, bindingsBB, PathB, 3, [] );
+
+	// subscribe after re-add
+
+	groupA.add( ObjectC );
+	expect( 6, groupA, bindingsAA, PathA, 1, [ ObjectB, ObjectC ] );
+	var bindingsAC = groupA.subscribe_( PathC, ParsedPathC );
+	expect( 7, groupA, bindingsAC, PathC, 1, [ ObjectB, ObjectC ] );
+
+	// re-add after subscribe
+
+	var bindingsBC = groupB.subscribe_( PathC, ParsedPathC );
+	groupB.add( ObjectA, ObjectB );
+	expect( 8, groupB, bindingsBB, PathB, 1, [ ObjectA, ObjectB ] );
+
+	// unsubscribe
+
+	var copyOfBindingsBC = bindingsBC.slice();
+	groupB.unsubscribe_( PathC );
+	groupB.add( ObjectC );
+	assert.deepEqual( bindingsBC, copyOfBindingsBC, "no more update after unsubscribe" );
+
+	// uncache active
+
+	groupB.uncache( ObjectA );
+	expect( 9, groupB, bindingsBB, PathB, 0, [ ObjectB, ObjectC ] );
+
+	// uncache cached
+
+	groupA.uncache( ObjectA );
+	expect( 10, groupA, bindingsAC, PathC, 0, [ ObjectB, ObjectC ] );
+
+} );
+

+ 6 - 0
test/unit/src/animation/AnimationUtils.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of AnimationUtils")

+ 6 - 0
test/unit/src/animation/KeyframeTrack.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of KeyframeTrack")

+ 6 - 0
test/unit/src/animation/KeyframeTrackConstructor.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of KeyframeTrackConstructor")

+ 6 - 0
test/unit/src/animation/KeyframeTrackPrototype.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of KeyframeTrackPrototype")

+ 6 - 0
test/unit/src/animation/PropertyBinding.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of PropertyBinding")

+ 6 - 0
test/unit/src/animation/PropertyMixer.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of PropertyMixer")

+ 6 - 0
test/unit/src/animation/tracks/BooleanKeyframeTrack.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of BooleanKeyframeTrack")

+ 6 - 0
test/unit/src/animation/tracks/ColorKeyframeTrack.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of ColorKeyframeTrack")

+ 6 - 0
test/unit/src/animation/tracks/NumberKeyframeTrack.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of NumberKeyframeTrack")

+ 6 - 0
test/unit/src/animation/tracks/QuaternionKeyframeTrack.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of QuaternionKeyframeTrack")

+ 6 - 0
test/unit/src/animation/tracks/StringKeyframeTrack.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of StringKeyframeTrack")

+ 6 - 0
test/unit/src/animation/tracks/VectorKeyFrameTrack.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of VectorKeyFrameTrack")

+ 6 - 0
test/unit/src/audio/Audio.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of Audio")

+ 6 - 0
test/unit/src/audio/AudioAnalyser.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of AudioAnalyser")

+ 6 - 0
test/unit/src/audio/AudioContext.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of AudioContext")

+ 6 - 0
test/unit/src/audio/AudioListener.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of AudioListener")

+ 6 - 0
test/unit/src/audio/PositionalAudio.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of PositionalAudio")

+ 25 - 0
test/unit/src/cameras/Camera.js

@@ -0,0 +1,25 @@
+/**
+ * @author simonThiele / https://github.com/simonThiele
+ */
+
+QUnit.module( "Camera" );
+
+QUnit.test( "lookAt" , function( assert ) {
+	var cam = new THREE.Camera();
+	cam.lookAt(new THREE.Vector3(0, 1, -1));
+
+	assert.ok( cam.rotation.x * (180 / Math.PI) === 45 , "x is equal" );
+});
+
+QUnit.test( "clone" , function( assert ) {
+	var cam = new THREE.Camera();
+
+	// fill the matrices with any nonsense values just to see if they get copied
+	cam.matrixWorldInverse.set( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 );
+	cam.projectionMatrix.set( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 );
+
+	var clonedCam = cam.clone();
+
+	assert.ok( cam.matrixWorldInverse.equals(clonedCam.matrixWorldInverse) , "matrixWorldInverse is equal" );
+	assert.ok( cam.projectionMatrix.equals(clonedCam.projectionMatrix) , "projectionMatrix is equal" );
+});

+ 6 - 0
test/unit/src/cameras/CubeCamera.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of CubeCamera")

+ 41 - 0
test/unit/src/cameras/OrthographicCamera.js

@@ -0,0 +1,41 @@
+/**
+ * @author simonThiele / https://github.com/simonThiele
+ */
+
+QUnit.module( "OrthographicCamera" );
+
+QUnit.test( "updateProjectionMatrix" , function( assert ) {
+	var left = -1, right = 1, top = 1, bottom = -1, near = 1, far = 3;
+	var cam = new THREE.OrthographicCamera(left, right, top, bottom, near, far);
+
+	// updateProjectionMatrix is called in contructor
+	var pMatrix = cam.projectionMatrix.elements;
+
+	// orthographic projection is given my the 4x4 Matrix
+	// 2/r-l		0			 0		-(l+r/r-l)
+	//   0		2/t-b		 0		-(t+b/t-b)
+	//   0			0		-2/f-n	-(f+n/f-n)
+	//   0			0			 0				1
+
+	assert.ok( pMatrix[0] === 2 / ( right - left ), "m[0,0] === 2 / (r - l)" );
+	assert.ok( pMatrix[5] === 2 / ( top - bottom ), "m[1,1] === 2 / (t - b)" );
+	assert.ok( pMatrix[10] === -2 / ( far - near ), "m[2,2] === -2 / (f - n)" );
+	assert.ok( pMatrix[12] === - ( ( right + left ) / ( right - left ) ), "m[3,0] === -(r+l/r-l)" );
+	assert.ok( pMatrix[13] === - ( ( top + bottom ) / ( top - bottom ) ), "m[3,1] === -(t+b/b-t)" );
+	assert.ok( pMatrix[14] === - ( ( far + near ) / ( far - near ) ), "m[3,2] === -(f+n/f-n)" );
+});
+
+QUnit.test( "clone" , function( assert ) {
+	var left = -1.5, right = 1.5, top = 1, bottom = -1, near = 0.1, far = 42;
+	var cam = new THREE.OrthographicCamera(left, right, top, bottom, near, far);
+
+	var clonedCam = cam.clone();
+
+	assert.ok( cam.left === clonedCam.left , "left is equal" );
+	assert.ok( cam.right === clonedCam.right , "right is equal" );
+	assert.ok( cam.top === clonedCam.top , "top is equal" );
+	assert.ok( cam.bottom === clonedCam.bottom , "bottom is equal" );
+	assert.ok( cam.near === clonedCam.near , "near is equal" );
+	assert.ok( cam.far === clonedCam.far , "far is equal" );
+	assert.ok( cam.zoom === clonedCam.zoom , "zoom is equal" );
+});

+ 50 - 0
test/unit/src/cameras/PerspectiveCamera.js

@@ -0,0 +1,50 @@
+/**
+ * @author simonThiele / https://github.com/simonThiele
+ */
+
+QUnit.module( "PerspectiveCamera" );
+
+QUnit.test( "updateProjectionMatrix" , function( assert ) {
+
+	var cam = new THREE.PerspectiveCamera( 75, 16 / 9, 0.1, 300.0 );
+
+	// updateProjectionMatrix is called in contructor
+	var m = cam.projectionMatrix;
+
+	// perspective projection is given my the 4x4 Matrix
+	// 2n/r-l		0			l+r/r-l				 0
+	//   0		2n/t-b	t+b/t-b				 0
+	//   0			0		-(f+n/f-n)	-(2fn/f-n)
+	//   0			0				-1					 0
+
+	// this matrix was calculated by hand via glMatrix.perspective(75, 16 / 9, 0.1, 300.0, pMatrix)
+	// to get a reference matrix from plain WebGL
+	var reference = new THREE.Matrix4().set(
+		0.7330642938613892, 0, 0, 0,
+		0, 1.3032253980636597, 0, 0,
+		0, 0, -1.000666856765747, -0.2000666856765747,
+		0, 0, -1, 0
+	);
+
+	assert.ok( reference.equals(m) );
+});
+
+QUnit.test( "clone" , function( assert ) {
+	var near = 1,
+			far = 3,
+			bottom = -1,
+			top = 1,
+			aspect = 16 / 9,
+			fov = 90;
+
+	var cam = new THREE.PerspectiveCamera( fov, aspect, near, far );
+
+	var clonedCam = cam.clone();
+
+	assert.ok( cam.fov === clonedCam.fov , "fov is equal" );
+	assert.ok( cam.aspect === clonedCam.aspect , "aspect is equal" );
+	assert.ok( cam.near === clonedCam.near , "near is equal" );
+	assert.ok( cam.far === clonedCam.far , "far is equal" );
+	assert.ok( cam.zoom === clonedCam.zoom , "zoom is equal" );
+	assert.ok( cam.projectionMatrix.equals(clonedCam.projectionMatrix) , "projectionMatrix is equal" );
+});

+ 6 - 0
test/unit/src/cameras/StereoCamera.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of StereoCamera")

+ 6 - 0
test/unit/src/constants.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of Constants")

+ 117 - 0
test/unit/src/core/BufferAttribute.js

@@ -0,0 +1,117 @@
+/**
+ * @author simonThiele / https://github.com/simonThiele
+ */
+
+QUnit.module( "BufferAttribute" );
+
+QUnit.test( "count" , function( assert ) {
+	assert.ok(
+		new THREE.BufferAttribute( new Float32Array( [1, 2, 3, 4, 5, 6] ), 3 ).count === 2,
+		'count is equal to the number of chunks'
+	);
+});
+
+QUnit.test( "copy" , function( assert ) {
+	var attr = new THREE.BufferAttribute( new Float32Array( [1, 2, 3, 4, 5, 6] ), 3 );
+	attr.setDynamic( true );
+	attr.needsUpdate = true;
+
+	var attrCopy = new THREE.BufferAttribute().copy( attr );
+
+	assert.ok( attr.count === attrCopy.count, 'count is equal' );
+	assert.ok( attr.itemSize === attrCopy.itemSize, 'itemSize is equal' );
+	assert.ok( attr.dynamic === attrCopy.dynamic, 'dynamic is equal' );
+	assert.ok( attr.array.length === attrCopy.array.length, 'array length is equal' );
+	assert.ok( attr.version === 1 && attrCopy.version === 0, 'version is not copied which is good' );
+});
+
+QUnit.test( "copyAt" , function( assert ) {
+	var attr = new THREE.BufferAttribute( new Float32Array( [1, 2, 3, 4, 5, 6, 7, 8, 9] ), 3 );
+	var attr2 = new THREE.BufferAttribute( new Float32Array(9), 3 );
+
+	attr2.copyAt( 1, attr, 2 );
+	attr2.copyAt( 0, attr, 1 );
+	attr2.copyAt( 2, attr, 0 );
+
+	var i = attr.array;
+	var i2 = attr2.array; // should be [4, 5, 6, 7, 8, 9, 1, 2, 3]
+
+	assert.ok( i2[0] === i[3] && i2[1] === i[4] && i2[2] === i[5], 'chunck copied to correct place' );
+	assert.ok( i2[3] === i[6] && i2[4] === i[7] && i2[5] === i[8], 'chunck copied to correct place' );
+	assert.ok( i2[6] === i[0] && i2[7] === i[1] && i2[8] === i[2], 'chunck copied to correct place' );
+});
+
+QUnit.test( "copyColorsArray" , function( assert ) {
+	var attr = new THREE.BufferAttribute( new Float32Array(6), 3 );
+
+	attr.copyColorsArray( [
+		new THREE.Color( 0, 0.5, 1 ),
+		new THREE.Color( 0.25, 1, 0 )
+	]);
+
+	var i = attr.array;
+	assert.ok( i[0] === 0 && i[1] === 0.5 && i[2] === 1, 'first color was copied correctly' );
+	assert.ok( i[3] === 0.25 && i[4] === 1 && i[5] === 0, 'second color was copied correctly' );
+});
+
+QUnit.test( "copyIndicesArray" , function( assert ) {
+	var attr = new THREE.BufferAttribute( new Float32Array(6), 3 );
+
+	attr.copyIndicesArray( [
+		{a: 1, b: 2, c: 3},
+		{a: 4, b: 5, c: 6}
+	]);
+
+	var i = attr.array;
+	assert.ok( i[0] === 1 && i[1] === 2 && i[2] === 3, 'first indices were copied correctly' );
+	assert.ok( i[3] === 4 && i[4] === 5 && i[5] === 6, 'second indices were copied correctly' );
+});
+
+QUnit.test( "copyVector2sArray" , function( assert ) {
+	var attr = new THREE.BufferAttribute( new Float32Array(4), 2 );
+
+	attr.copyVector2sArray( [
+		new THREE.Vector2(1, 2),
+		new THREE.Vector2(4, 5)
+	]);
+
+	var i = attr.array;
+	assert.ok( i[0] === 1 && i[1] === 2, 'first vector was copied correctly' );
+	assert.ok( i[2] === 4 && i[3] === 5, 'second vector was copied correctly' );
+});
+
+QUnit.test( "copyVector3sArray" , function( assert ) {
+	var attr = new THREE.BufferAttribute( new Float32Array(6), 2 );
+
+	attr.copyVector3sArray( [
+		new THREE.Vector3(1, 2, 3),
+		new THREE.Vector3(10, 20, 30)
+	]);
+
+	var i = attr.array;
+	assert.ok( i[0] === 1 && i[1] === 2 && i[2] === 3, 'first vector was copied correctly' );
+	assert.ok( i[3] === 10 && i[4] === 20 && i[5] === 30, 'second vector was copied correctly' );
+});
+
+QUnit.test( "copyVector4sArray" , function( assert ) {
+	var attr = new THREE.BufferAttribute( new Float32Array(8), 2 );
+
+	attr.copyVector4sArray( [
+		new THREE.Vector4(1, 2, 3, 4),
+		new THREE.Vector4(10, 20, 30, 40)
+	]);
+
+	var i = attr.array;
+	assert.ok( i[0] === 1 && i[1] === 2 && i[2] === 3 && i[3] === 4, 'first vector was copied correctly' );
+	assert.ok( i[4] === 10 && i[5] === 20 && i[6] === 30 && i[7] === 40, 'second vector was copied correctly' );
+});
+
+QUnit.test( "clone" , function( assert ) {
+	var attr = new THREE.BufferAttribute( new Float32Array([1, 2, 3, 4, 0.12, -12]), 2 );
+	var attrCopy = attr.clone();
+
+	assert.ok( attr.array.length === attrCopy.array.length, 'attribute was cloned' );
+	for ( var i = 0; i < attr.array.length; i++ ) {
+		assert.ok( attr.array[i] === attrCopy.array[i], 'array item is equal' );
+	}
+});

+ 311 - 0
test/unit/src/core/BufferGeometry.js

@@ -0,0 +1,311 @@
+/**
+ * @author simonThiele / https://github.com/simonThiele
+ */
+
+QUnit.module( "BufferGeometry" );
+
+var DegToRad = Math.PI / 180;
+
+QUnit.test( "add / delete Attribute", function( assert ) {
+	var geometry = new THREE.BufferGeometry();
+	var attributeName = "position";
+
+	assert.ok ( geometry.attributes[attributeName] === undefined , 'no attribute defined' );
+
+	geometry.addAttribute( attributeName, new THREE.BufferAttribute( new Float32Array( [1, 2, 3], 1 ) ) );
+
+	assert.ok ( geometry.attributes[attributeName] !== undefined , 'attribute is defined' );
+
+	geometry.removeAttribute( attributeName );
+
+	assert.ok ( geometry.attributes[attributeName] === undefined , 'no attribute defined' );
+});
+
+QUnit.test( "applyMatrix" , function( assert ) {
+	var geometry = new THREE.BufferGeometry();
+	geometry.addAttribute( "position", new THREE.BufferAttribute( new Float32Array(6), 3 ) );
+
+	var matrix = new THREE.Matrix4().set(
+		1, 0, 0, 1.5,
+		0, 1, 0, -2,
+		0, 0, 1, 3,
+		0, 0, 0, 1
+	);
+	geometry.applyMatrix(matrix);
+
+	var position = geometry.attributes.position.array;
+	var m = matrix.elements;
+	assert.ok( position[0] === m[12] && position[1] === m[13] && position[2] === m[14], "position was extracted from matrix" );
+	assert.ok( position[3] === m[12] && position[4] === m[13] && position[5] === m[14], "position was extracted from matrix twice" );
+	assert.ok( geometry.attributes.position.version === 1, "version was increased during update" );
+});
+
+QUnit.test( "rotateX/Y/Z", function( assert ) {
+	var geometry = new THREE.BufferGeometry();
+	geometry.addAttribute( "position", new THREE.BufferAttribute( new Float32Array([1, 2, 3, 4, 5, 6]), 3 ) );
+
+	var pos = geometry.attributes.position.array;
+
+	geometry.rotateX( 180 * DegToRad );
+
+	// object was rotated around x so all items should be flipped but the x ones
+	assert.ok( pos[0] === 1 && pos[1] === -2 && pos[2] === -3 &&
+			pos[3] === 4 && pos[4] === -5 && pos[5] === -6, "vertices were rotated around x by 180 degrees" );
+
+
+	geometry.rotateY( 180 * DegToRad );
+
+	// vertices were rotated around y so all items should be flipped again but the y ones
+	assert.ok( pos[0] === -1 && pos[1] === -2 && pos[2] === 3 &&
+			pos[3] === -4 && pos[4] === -5 && pos[5] === 6, "vertices were rotated around y by 180 degrees" );
+
+
+	geometry.rotateZ( 180 * DegToRad );
+
+	// vertices were rotated around z so all items should be flipped again but the z ones
+	assert.ok( pos[0] === 1 && pos[1] === 2 && pos[2] === 3 &&
+			pos[3] === 4 && pos[4] === 5 && pos[5] === 6, "vertices were rotated around z by 180 degrees" );
+});
+
+
+QUnit.test( "translate" , function( assert ) {
+	var geometry = new THREE.BufferGeometry();
+	geometry.addAttribute( "position", new THREE.BufferAttribute( new Float32Array([1, 2, 3, 4, 5, 6]), 3 ) );
+
+	var pos = geometry.attributes.position.array;
+
+	geometry.translate( 10, 20, 30 );
+
+	assert.ok( pos[0] === 11 && pos[1] === 22 && pos[2] === 33 &&
+			pos[3] === 14 && pos[4] === 25 && pos[5] === 36, "vertices were translated" );
+});
+
+QUnit.test( "scale" , function( assert ) {
+	var geometry = new THREE.BufferGeometry();
+	geometry.addAttribute( "position", new THREE.BufferAttribute( new Float32Array([-1, -1, -1, 2, 2, 2]), 3 ) );
+
+	var pos = geometry.attributes.position.array;
+
+	geometry.scale( 1, 2, 3 );
+
+	assert.ok( pos[0] === -1 && pos[1] === -2 && pos[2] === -3 &&
+			pos[3] === 2 && pos[4] === 4 && pos[5] === 6, "vertices were scaled" );
+});
+
+QUnit.test( "center" , function( assert ) {
+	var geometry = new THREE.BufferGeometry();
+	geometry.addAttribute( "position", new THREE.BufferAttribute( new Float32Array([
+		-1, -1, -1,
+		1, 1, 1,
+		4, 4, 4
+	]), 3 ) );
+
+	geometry.center();
+
+	var pos = geometry.attributes.position.array;
+	var bb = geometry.boundingBox;
+
+	// the boundingBox should go from (-1, -1, -1) to (4, 4, 4) so it has a size of (5, 5, 5)
+	// after centering it the vertices should be placed between (-2.5, -2.5, -2.5) and (2.5, 2.5, 2.5)
+	assert.ok( pos[0] === -2.5 && pos[1] === -2.5 && pos[2] === -2.5 &&
+			pos[3] === -0.5 && pos[4] === -0.5 && pos[5] === -0.5 &&
+			pos[6] === 2.5 && pos[7] === 2.5 && pos[8] === 2.5, "vertices were replaced by boundingBox dimensions" );
+});
+
+QUnit.test( "setFromObject" , function( assert ) {
+	var lineGeo = new THREE.Geometry();
+	lineGeo.vertices.push(
+		new THREE.Vector3( -10, 0, 0 ),
+		new THREE.Vector3( 0, 10, 0 ),
+		new THREE.Vector3( 10, 0, 0 )
+	);
+
+	lineGeo.colors.push(
+		new THREE.Color(1, 0, 0 ),
+		new THREE.Color(0, 1, 0 ),
+		new THREE.Color(0, 0, 1 )
+	);
+
+	var line = new THREE.Line( lineGeo, null );
+	var geometry = new THREE.BufferGeometry().setFromObject( line );
+
+	var pos = geometry.attributes.position.array;
+	var col = geometry.attributes.color.array;
+	var v = lineGeo.vertices;
+	var c = lineGeo.colors;
+
+	assert.ok(
+		 // position exists
+			pos !== undefined &&
+
+			// vertex arrays have the same size
+			v.length * 3 === pos.length &&
+
+			// there are three complete vertices (each vertex contains three values)
+			geometry.attributes.position.count === 3 &&
+
+			// check if both arrays contains the same data
+			pos[0] === v[0].x && pos[1] === v[0].y && pos[2] === v[0].z &&
+			pos[3] === v[1].x && pos[4] === v[1].y && pos[5] === v[1].z &&
+			pos[6] === v[2].x && pos[7] === v[2].y && pos[8] === v[2].z
+			, "positions are equal" );
+
+	assert.ok(
+		 // color exists
+			col !== undefined &&
+
+			// color arrays have the same size
+			c.length * 3 === col.length &&
+
+			// there are three complete colors (each color contains three values)
+			geometry.attributes.color.count === 3 &&
+
+			// check if both arrays contains the same data
+			col[0] === c[0].r && col[1] === c[0].g && col[2] === c[0].b &&
+			col[3] === c[1].r && col[4] === c[1].g && col[5] === c[1].b &&
+			col[6] === c[2].r && col[7] === c[2].g && col[8] === c[2].b
+			, "colors are equal" );
+});
+
+QUnit.test( "computeBoundingBox" , function( assert ) {
+	var bb = getBBForVertices( [-1, -2, -3, 13, -2, -3.5, -1, -20, 0, -4, 5, 6] );
+
+	assert.ok( bb.min.x === -4 && bb.min.y === -20 && bb.min.z === -3.5, "min values are set correctly" );
+	assert.ok( bb.max.x === 13 && bb.max.y === 5 && bb.max.z === 6, "max values are set correctly" );
+
+
+	bb = getBBForVertices( [-1, -1, -1] );
+
+	assert.ok( bb.min.x === bb.max.x && bb.min.y === bb.max.y && bb.min.z === bb.max.z, "since there is only one vertex, max and min are equal" );
+	assert.ok( bb.min.x === -1 && bb.min.y === -1 && bb.min.z === -1, "since there is only one vertex, min and max are this vertex" );
+});
+
+QUnit.test( "computeBoundingSphere" , function( assert ) {
+	var bs = getBSForVertices( [-10, 0, 0, 10, 0, 0] );
+
+	assert.ok( bs.radius === (10 + 10) / 2, "radius is equal to deltaMinMax / 2" )
+	assert.ok( bs.center.x === 0 && bs.center.y === 0 && bs.center.y === 0, "bounding sphere is at ( 0, 0, 0 )" )
+
+
+	var bs = getBSForVertices( [-5, 11, -3, 5, -11, 3] );
+	var radius = new THREE.Vector3(5, 11, 3).length();
+
+	assert.ok( bs.radius === radius, "radius is equal to directionLength" )
+	assert.ok( bs.center.x === 0 && bs.center.y === 0 && bs.center.y === 0, "bounding sphere is at ( 0, 0, 0 )" )
+});
+
+function getBBForVertices(vertices) {
+	var geometry = new THREE.BufferGeometry();
+
+	geometry.addAttribute( "position", new THREE.BufferAttribute( new Float32Array(vertices), 3 ) );
+	geometry.computeBoundingBox();
+
+	return geometry.boundingBox;
+}
+
+function getBSForVertices(vertices) {
+	var geometry = new THREE.BufferGeometry();
+
+	geometry.addAttribute( "position", new THREE.BufferAttribute( new Float32Array(vertices), 3 ) );
+	geometry.computeBoundingSphere();
+
+	return geometry.boundingSphere;
+}
+
+QUnit.test( "computeVertexNormals" , function( assert ) {
+	// get normals for a counter clockwise created triangle
+	var normals = getNormalsForVertices([-1, 0, 0, 1, 0, 0, 0, 1, 0], assert);
+
+	assert.ok( normals[0] === 0 && normals[1] === 0 && normals[2] === 1,
+		"first normal is pointing to screen since the the triangle was created counter clockwise" );
+
+	assert.ok( normals[3] === 0 && normals[4] === 0 && normals[5] === 1,
+		"second normal is pointing to screen since the the triangle was created counter clockwise" );
+
+	assert.ok( normals[6] === 0 && normals[7] === 0 && normals[8] === 1,
+		"third normal is pointing to screen since the the triangle was created counter clockwise" );
+
+
+	// get normals for a clockwise created triangle
+	var normals = getNormalsForVertices([1, 0, 0, -1, 0, 0, 0, 1, 0], assert);
+
+	assert.ok( normals[0] === 0 && normals[1] === 0 && normals[2] === -1,
+		"first normal is pointing to screen since the the triangle was created clockwise" );
+
+	assert.ok( normals[3] === 0 && normals[4] === 0 && normals[5] === -1,
+		"second normal is pointing to screen since the the triangle was created clockwise" );
+
+	assert.ok( normals[6] === 0 && normals[7] === 0 && normals[8] === -1,
+		"third normal is pointing to screen since the the triangle was created clockwise" );
+
+
+	var normals = getNormalsForVertices([0, 0, 1, 0, 0, -1, 1, 1, 0], assert);
+
+	// the triangle is rotated by 45 degrees to the right so the normals of the three vertices
+	// should point to (1, -1, 0).normalized(). The simplest solution is to check against a normalized
+	// vector (1, -1, 0) but you will get calculation errors because of floating calculations so another
+	// valid technique is to create a vector which stands in 90 degrees to the normals and calculate the
+	// dot product which is the cos of the angle between them. This should be < floating calculation error
+	// which can be taken from Number.EPSILON
+	var direction = new THREE.Vector3(1, 1, 0).normalize(); // a vector which should have 90 degrees difference to normals
+	var difference = direction.dot( new THREE.Vector3( normals[0], normals[1], normals[2] ) );
+	assert.ok( difference < Number.EPSILON, "normal is equal to reference vector");
+
+
+	// get normals for a line should be NAN because you need min a triangle to calculate normals
+	var normals = getNormalsForVertices([1, 0, 0, -1, 0, 0], assert);
+	for (var i = 0; i < normals.length; i++) {
+		assert.ok ( !normals[i], "normals can't be calculated which is good");
+	}
+});
+
+function getNormalsForVertices(vertices, assert) {
+	var geometry = new THREE.BufferGeometry();
+
+	geometry.addAttribute( "position", new THREE.BufferAttribute( new Float32Array(vertices), 3 ) );
+
+	geometry.computeVertexNormals();
+
+	assert.ok( geometry.attributes.normal !== undefined, "normal attribute was created" );
+
+	return geometry.attributes.normal.array;
+}
+
+QUnit.test( "merge" , function( assert ) {
+	var geometry1 = new THREE.BufferGeometry();
+	geometry1.addAttribute( "attrName", new THREE.BufferAttribute( new Float32Array([1, 2, 3, 0, 0, 0]), 3 ) );
+
+	var geometry2 = new THREE.BufferGeometry();
+	geometry2.addAttribute( "attrName", new THREE.BufferAttribute( new Float32Array([4, 5, 6]), 3 ) );
+
+	var attr = geometry1.attributes.attrName.array;
+
+	geometry1.merge(geometry2, 1);
+
+	// merged array should be 1, 2, 3, 4, 5, 6
+	for (var i = 0; i < attr.length; i++) {
+	  assert.ok( attr[i] === i + 1, "");
+	}
+
+	geometry1.merge(geometry2);
+	assert.ok( attr[0] === 4 && attr[1] === 5 && attr[2] === 6, "copied the 3 attributes without offset" );
+});
+
+QUnit.test( "copy" , function( assert ) {
+	var geometry = new THREE.BufferGeometry();
+	geometry.addAttribute( "attrName", new THREE.BufferAttribute( new Float32Array([1, 2, 3, 4, 5, 6]), 3 ) );
+	geometry.addAttribute( "attrName2", new THREE.BufferAttribute( new Float32Array([0, 1, 3, 5, 6]), 1 ) );
+
+	var copy = new THREE.BufferGeometry().copy(geometry);
+
+	assert.ok( copy !== geometry && geometry.id !== copy.id, "new object was created" );
+
+	Object.keys(geometry.attributes).forEach(function(key) {
+		var attribute = geometry.attributes[key];
+		assert.ok( attribute !== undefined, "all attributes where copied");
+
+		for (var i = 0; i < attribute.array.length; i++) {
+			assert.ok( attribute.array[i] === copy.attributes[key].array[i], "values of the attribute are equal" );
+		}
+	});
+});

+ 38 - 0
test/unit/src/core/Clock.js

@@ -0,0 +1,38 @@
+/**
+ * @author simonThiele / https://github.com/simonThiele
+ */
+
+QUnit.module( "Clock" );
+
+function mockPerformance() {
+	self.performance = {
+		deltaTime: 0,
+
+		next: function( delta ) {
+			this.deltaTime += delta;
+		},
+
+		now: function() {
+			return this.deltaTime;
+		}
+	};
+}
+
+QUnit.test( "clock with performance", function( assert ) {
+	mockPerformance();
+
+	var clock = new THREE.Clock();
+
+	clock.start();
+
+	self.performance.next(123);
+	assert.ok( clock.getElapsedTime() === 0.123 , "okay");
+
+	self.performance.next(100);
+	assert.ok( clock.getElapsedTime() === 0.223 , "okay");
+
+	clock.stop();
+
+	self.performance.next(1000);
+	assert.ok( clock.getElapsedTime() === 0.223 , "don't update time if the clock was stopped");
+});

+ 6 - 0
test/unit/src/core/DirectGeometry.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of DirectGeometry")

+ 76 - 0
test/unit/src/core/EventDispatcher.js

@@ -0,0 +1,76 @@
+/**
+ * @author simonThiele / https://github.com/simonThiele
+ */
+
+QUnit.module( "EventDispatcher" );
+
+QUnit.test( "addEventListener" , function( assert ) {
+	var eventDispatcher = new THREE.EventDispatcher();
+
+	var listener = {};
+	eventDispatcher.addEventListener( 'anyType', listener );
+
+	assert.ok( eventDispatcher._listeners.anyType.length === 1, "listener with unknown type was added" );
+	assert.ok( eventDispatcher._listeners.anyType[0] === listener, "listener with unknown type was added" );
+
+	eventDispatcher.addEventListener( 'anyType', listener );
+
+	assert.ok( eventDispatcher._listeners.anyType.length === 1, "can't add one listener twice to same type" );
+	assert.ok( eventDispatcher._listeners.anyType[0] === listener, "listener is still there" );
+});
+
+QUnit.test( "hasEventListener" , function( assert ) {
+	var eventDispatcher = new THREE.EventDispatcher();
+
+	var listener = {};
+	eventDispatcher.addEventListener( 'anyType', listener );
+
+	assert.ok( eventDispatcher.hasEventListener( 'anyType', listener ), "listener was found" );
+	assert.ok( !eventDispatcher.hasEventListener( 'anotherType', listener ), "listener was not found which is good" );
+});
+
+QUnit.test( "removeEventListener" , function( assert ) {
+	var eventDispatcher = new THREE.EventDispatcher();
+
+	var listener = {};
+
+	assert.ok( eventDispatcher._listeners === undefined, "there are no listeners by default" );
+
+	eventDispatcher.addEventListener( 'anyType', listener );
+	assert.ok( Object.keys( eventDispatcher._listeners ).length === 1 &&
+		eventDispatcher._listeners.anyType.length === 1, "if a listener was added, there is a new key" );
+
+	eventDispatcher.removeEventListener( 'anyType', listener );
+	assert.ok( eventDispatcher._listeners.anyType.length === 0, "listener was deleted" );
+
+	eventDispatcher.removeEventListener( 'unknownType', listener );
+	assert.ok( eventDispatcher._listeners.unknownType === undefined, "unknown types will be ignored" );
+
+	eventDispatcher.removeEventListener( 'anyType', undefined );
+	assert.ok( eventDispatcher._listeners.anyType.length === 0, "undefined listeners are ignored" );
+});
+
+QUnit.test( "dispatchEvent" , function( assert ) {
+	var eventDispatcher = new THREE.EventDispatcher();
+
+	var callCount = 0;
+	var listener = function() { callCount++; };
+
+	eventDispatcher.addEventListener( 'anyType', listener );
+	assert.ok( callCount === 0, "no event, no call" );
+
+	eventDispatcher.dispatchEvent( { type: 'anyType' } );
+	assert.ok( callCount === 1, "one event, one call" );
+
+	eventDispatcher.dispatchEvent( { type: 'anyType' } );
+	assert.ok( callCount === 2, "two events, two calls" );
+});
+
+
+
+
+
+
+
+
+//

+ 58 - 0
test/unit/src/core/Face3.js

@@ -0,0 +1,58 @@
+/**
+ * @author simonThiele / https://github.com/simonThiele
+ */
+
+QUnit.module( "Face3" );
+
+QUnit.test( "copy" , function( assert ) {
+	var instance = new THREE.Face3(0, 1, 2, new THREE.Vector3(0, 1, 0), new THREE.Color(0.25, 0.5, 0.75), 2);
+	var copiedInstance = instance.copy(instance);
+
+	checkCopy(copiedInstance, assert);
+	checkVertexAndColors(copiedInstance, assert);
+});
+
+QUnit.test( "copy" , function( assert ) {
+	var instance = new THREE.Face3(0, 1, 2,
+		[new THREE.Vector3(0, 1, 0), new THREE.Vector3(1, 0, 1)],
+		[new THREE.Color(0.25, 0.5, 0.75), new THREE.Color(1, 0, 0.4)],
+		2);
+	var copiedInstance = instance.copy(instance);
+
+	checkCopy(copiedInstance, assert);
+	checkVertexAndColorArrays(copiedInstance, assert);
+});
+
+QUnit.test( "clone" , function( assert ) {
+	var instance = new THREE.Face3(0, 1, 2, new THREE.Vector3(0, 1, 0), new THREE.Color(0.25, 0.5, 0.75), 2);
+	var copiedInstance = instance.clone();
+
+	checkCopy(copiedInstance, assert);
+	checkVertexAndColors(copiedInstance, assert);
+});
+
+function checkCopy(copiedInstance, assert) {
+	assert.ok( copiedInstance instanceof THREE.Face3, "copy created the correct type" );
+	assert.ok(
+		copiedInstance.a === 0 &&
+		copiedInstance.b === 1 &&
+		copiedInstance.c === 2 &&
+		copiedInstance.materialIndex === 2
+		,"properties where copied" );
+}
+
+function checkVertexAndColors(copiedInstance, assert) {
+	assert.ok(
+		copiedInstance.normal.x === 0 && copiedInstance.normal.y === 1 && copiedInstance.normal.z === 0 &&
+		copiedInstance.color.r === 0.25 && copiedInstance.color.g === 0.5 && copiedInstance.color.b === 0.75
+		,"properties where copied" );
+}
+
+function checkVertexAndColorArrays(copiedInstance, assert) {
+	assert.ok(
+		copiedInstance.vertexNormals[0].x === 0 && copiedInstance.vertexNormals[0].y === 1 && copiedInstance.vertexNormals[0].z === 0 &&
+		copiedInstance.vertexNormals[1].x === 1 && copiedInstance.vertexNormals[1].y === 0 && copiedInstance.vertexNormals[1].z === 1 &&
+		copiedInstance.vertexColors[0].r === 0.25 && copiedInstance.vertexColors[0].g === 0.5 && copiedInstance.vertexColors[0].b === 0.75 &&
+		copiedInstance.vertexColors[1].r === 1 && copiedInstance.vertexColors[1].g === 0 && copiedInstance.vertexColors[1].b === 0.4
+		,"properties where copied" );
+}

+ 106 - 0
test/unit/src/core/Geometry.js

@@ -0,0 +1,106 @@
+/**
+ * @author simonThiele / https://github.com/simonThiele
+ */
+
+QUnit.module( "Geometry" );
+
+QUnit.test( "rotateX" , function( assert ) {
+	var geometry = getGeometry();
+
+	var matrix = new THREE.Matrix4();
+	matrix.makeRotationX( Math.PI / 2 ); // 90 degree
+
+	geometry.applyMatrix( matrix );
+
+	var v0 = geometry.vertices[0], v1 = geometry.vertices[1], v2 = geometry.vertices[2];
+	assert.ok( v0.x === -0.5 && v0.y === 0 && v0.z === 0, "first vertex was rotated" );
+	assert.ok( v1.x === 0.5 && v1.y === 0 && v1.z === 0, "second vertex was rotated" );
+	assert.ok( v2.x === 0 && v2.y < Number.EPSILON && v2.z === 1, "third vertex was rotated" );
+});
+
+QUnit.test( "rotateY" , function( assert ) {
+	var geometry = getGeometry();
+
+	var matrix = new THREE.Matrix4();
+	matrix.makeRotationY( Math.PI ); // 180 degrees
+
+	geometry.applyMatrix( matrix );
+
+	var v0 = geometry.vertices[0], v1 = geometry.vertices[1], v2 = geometry.vertices[2];
+	assert.ok( v0.x === 0.5 && v0.y === 0 && v0.z < Number.EPSILON, "first vertex was rotated" );
+	assert.ok( v1.x === -0.5 && v1.y === 0 && v1.z < Number.EPSILON, "second vertex was rotated" );
+	assert.ok( v2.x === 0 && v2.y === 1 && v2.z === 0, "third vertex was rotated" );
+});
+
+QUnit.test( "rotateZ" , function( assert ) {
+	var geometry = getGeometry();
+
+	var matrix = new THREE.Matrix4();
+	matrix.makeRotationZ( Math.PI / 2 * 3 ); // 270 degrees
+
+	geometry.applyMatrix( matrix );
+
+	var v0 = geometry.vertices[0], v1 = geometry.vertices[1], v2 = geometry.vertices[2];
+	assert.ok( v0.x < Number.EPSILON && v0.y === 0.5 && v0.z === 0, "first vertex was rotated" );
+	assert.ok( v1.x < Number.EPSILON && v1.y === -0.5 && v1.z === 0, "second vertex was rotated" );
+	assert.ok( v2.x === 1 && v2.y < Number.EPSILON && v2.z === 0, "third vertex was rotated" );
+});
+
+QUnit.test( "fromBufferGeometry" , function( assert ) {
+	var bufferGeometry = new THREE.BufferGeometry();
+	bufferGeometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array( [1, 2, 3, 4, 5, 6, 7, 8, 9] ), 3 ) );
+	bufferGeometry.addAttribute('color', new THREE.BufferAttribute(new Float32Array( [0, 0, 0, 0.5, 0.5, 0.5, 1, 1, 1] ), 3 ) );
+	bufferGeometry.addAttribute('normal', new THREE.BufferAttribute(new Float32Array( [0, 1, 0, 1, 0, 1, 1, 1, 0] ), 3 ) );
+	bufferGeometry.addAttribute('uv', new THREE.BufferAttribute(new Float32Array( [0, 0, 0, 1, 1, 1] ), 2 ) );
+	bufferGeometry.addAttribute('uv2', new THREE.BufferAttribute(new Float32Array( [0, 0, 0, 1, 1, 1] ), 2 ) );
+
+	var geometry = new THREE.Geometry().fromBufferGeometry( bufferGeometry );
+
+	var colors = geometry.colors;
+	assert.ok(
+		colors[0].r === 0 && colors[0].g === 0 && colors[0].b === 0 &&
+		colors[1].r === 0.5 && colors[1].g === 0.5 && colors[1].b === 0.5 &&
+		colors[2].r === 1 && colors[2].g === 1 && colors[2].b === 1
+		, "colors were created well" );
+
+	var vertices = geometry.vertices;
+	assert.ok(
+		vertices[0].x === 1 && vertices[0].y === 2 && vertices[0].z === 3 &&
+		vertices[1].x === 4 && vertices[1].y === 5 && vertices[1].z === 6 &&
+		vertices[2].x === 7 && vertices[2].y === 8 && vertices[2].z === 9
+		, "vertices were created well" );
+
+	var vNormals = geometry.faces[0].vertexNormals;
+	assert.ok(
+		vNormals[0].x === 0 && vNormals[0].y === 1 && vNormals[0].z === 0 &&
+		vNormals[1].x === 1 && vNormals[1].y === 0 && vNormals[1].z === 1 &&
+		vNormals[2].x === 1 && vNormals[2].y === 1 && vNormals[2].z === 0
+		, "vertex normals were created well" );
+});
+
+QUnit.test( "normalize" , function( assert ) {
+	var geometry = getGeometry();
+	geometry.computeLineDistances();
+
+	var distances = geometry.lineDistances;
+	assert.ok( distances[0] === 0, "distance to the 1st point is 0" );
+	assert.ok( distances[1] === 1 + distances[0], "distance from the 1st to the 2nd is sqrt(2nd - 1st) + distance - 1" );
+	assert.ok( distances[2] === Math.sqrt( 0.5 * 0.5 + 1 ) + distances[1], "distance from the 1st to the 3nd is sqrt(3rd - 2nd) + distance - 1" );
+});
+
+function getGeometryByParams( x1, y1, z1, x2, y2, z2, x3, y3, z3 ) {
+	var geometry = new THREE.Geometry();
+
+	// a triangle
+	geometry.vertices = [
+		new THREE.Vector3( x1, y1, z1 ),
+		new THREE.Vector3( x2, y2, z2 ),
+		new THREE.Vector3( x3, y3, z3 )
+	];
+
+	return geometry;
+}
+
+function getGeometry() {
+	return getGeometryByParams( -0.5, 0, 0, 0.5, 0, 0, 0, 1, 0 );
+}

+ 29 - 0
test/unit/src/core/InstancedBufferAttribute.js

@@ -0,0 +1,29 @@
+/**
+ * @author simonThiele / https://github.com/simonThiele
+ */
+
+QUnit.module( "InstancedBufferAttribute" );
+
+QUnit.test( "can be created", function( assert ) {
+	var instance = new THREE.InstancedBufferAttribute(new Float32Array(10), 2);
+	assert.ok( instance.meshPerAttribute === 1, "ok" );
+
+	instance = new THREE.InstancedBufferAttribute(new Float32Array(10), 2, 123);
+	assert.ok( instance.meshPerAttribute === 123, "ok" );
+
+});
+
+QUnit.test( "copy" , function( assert ) {
+	var array = new Float32Array( [1, 2, 3, 7, 8, 9] );
+	var instance = new THREE.InstancedBufferAttribute( array, 2, 123 );
+	var copiedInstance = instance.copy( instance );
+
+	assert.ok( copiedInstance instanceof THREE.InstancedBufferAttribute, "the clone has the correct type" );
+	assert.ok( copiedInstance.itemSize === 2, "itemSize was copied" );
+	assert.ok( copiedInstance.meshPerAttribute === 123, "meshPerAttribute was copied" );
+
+	for (var i = 0; i < array.length; i++) {
+		assert.ok( copiedInstance.array[i] === array[i], "array was copied" );
+	}
+
+});

+ 53 - 0
test/unit/src/core/InstancedBufferGeometry.js

@@ -0,0 +1,53 @@
+/**
+ * @author simonThiele / https://github.com/simonThiele
+ */
+
+QUnit.module( "InstancedBufferGeometry" );
+
+function createClonableMock() {
+	return {
+		callCount: 0,
+
+		clone: function() {
+			this.callCount++;
+
+			return this;
+		}
+	}
+}
+
+QUnit.test( "copy" , function( assert ) {
+	var instanceMock1 = {};
+	var instanceMock2 = {};
+	var indexMock = createClonableMock();
+	var defaultAttribute1 = new THREE.BufferAttribute([1]);
+	var defaultAttribute2 = new THREE.BufferAttribute([2]);
+
+	var instance = new THREE.InstancedBufferGeometry();
+
+	instance.addGroup( 0, 10, instanceMock1 );
+	instance.addGroup( 10, 5, instanceMock2 );
+	instance.setIndex( indexMock );
+	instance.addAttribute( 'defaultAttribute1', defaultAttribute1 );
+	instance.addAttribute( 'defaultAttribute2', defaultAttribute2 );
+
+	var copiedInstance = instance.copy( instance );
+
+	assert.ok( copiedInstance instanceof THREE.InstancedBufferGeometry, "the clone has the correct type" );
+
+	assert.ok( copiedInstance.index === indexMock, "index was copied" );
+	assert.ok( copiedInstance.index.callCount === 1, "index.clone was called once" );
+
+	assert.ok( copiedInstance.attributes['defaultAttribute1'] instanceof THREE.BufferAttribute, "attribute was created" );
+	// the given attribute mock was passed to the array property of the created buffer attribute
+	assert.ok( copiedInstance.attributes['defaultAttribute1'].array[0] === defaultAttribute1.array, "attribute was copied" );
+	assert.ok( copiedInstance.attributes['defaultAttribute2'].array[0] === defaultAttribute2.array, "attribute was copied" );
+
+	assert.ok( copiedInstance.groups[0].start === 0, "group was copied" );
+	assert.ok( copiedInstance.groups[0].count === 10, "group was copied" );
+	assert.ok( copiedInstance.groups[0].instances === instanceMock1, "group was copied" );
+
+	assert.ok( copiedInstance.groups[1].start === 10, "group was copied" );
+	assert.ok( copiedInstance.groups[1].count === 5, "group was copied" );
+	assert.ok( copiedInstance.groups[1].instances === instanceMock2, "group was copied" );
+});

+ 20 - 0
test/unit/src/core/InstancedInterleavedBuffer.js

@@ -0,0 +1,20 @@
+/**
+ * @author simonThiele / https://github.com/simonThiele
+ */
+
+QUnit.module( "InstancedInterleavedBuffer" );
+
+QUnit.test( "can be created", function( assert ) {
+	var array = new Float32Array( [1, 2, 3, 7, 8, 9] );
+	var instance = new THREE.InstancedInterleavedBuffer( array, 3 );
+
+	assert.ok( instance.meshPerAttribute === 1, "ok" );
+});
+
+QUnit.test( "copy" , function( assert ) {
+	var array = new Float32Array( [1, 2, 3, 7, 8, 9] );
+	var instance = new THREE.InstancedInterleavedBuffer( array, 3 );
+	var copiedInstance = instance.copy( instance );
+
+	assert.ok( copiedInstance.meshPerAttribute === 1, "additional attribute was copied" );
+});

+ 46 - 0
test/unit/src/core/InterleavedBuffer.js

@@ -0,0 +1,46 @@
+/**
+ * @author simonThiele / https://github.com/simonThiele
+ */
+
+QUnit.module( "InterleavedBuffer" );
+
+function checkInstanceAgainstCopy( instance, copiedInstance, assert ) {
+	assert.ok( copiedInstance instanceof THREE.InterleavedBuffer, "the clone has the correct type" );
+
+	for ( var i = 0; i < instance.array.length; i++ ) {
+		assert.ok( copiedInstance.array[i] === instance.array[i], "array was copied" );
+	}
+
+	assert.ok( copiedInstance.stride === instance.stride, "stride was copied" );
+	assert.ok( copiedInstance.dynamic === true, "dynamic was copied" );
+}
+
+QUnit.test( "length and count", function( assert ) {
+	var instance = new THREE.InterleavedBuffer( new Float32Array( [1, 2, 3, 7, 8 ,9] ), 3 );
+
+	assert.ok( instance.length === 6, "length is calculated via array length" );
+	assert.ok( instance.count === 2, "count is calculated via array length / stride" );
+});
+
+QUnit.test( "copy" , function( assert ) {
+	var array = new Float32Array( [1, 2, 3, 7, 8 ,9] );
+	var instance = new THREE.InterleavedBuffer( array, 3 );
+	instance.setDynamic( true );
+
+	checkInstanceAgainstCopy(instance, instance.copy( instance ), assert );
+});
+
+QUnit.test( "clone" , function( assert ) {
+	var array = new Float32Array( [1, 2, 3, 7, 8 ,9] );
+	var instance = new THREE.InterleavedBuffer( array, 3 );
+	instance.setDynamic( true );
+
+	checkInstanceAgainstCopy( instance, instance.clone(), assert );
+});
+
+QUnit.test( "set" , function( assert ) {
+	var instance = new THREE.InterleavedBuffer( new Float32Array( [1, 2, 3, 7, 8 ,9] ), 3 );
+
+	instance.set( [0, -1] );
+	assert.ok( instance.array[0] === 0 && instance.array[1] === -1, "replace at first by default" );
+});

+ 36 - 0
test/unit/src/core/InterleavedBufferAttribute.js

@@ -0,0 +1,36 @@
+/**
+ * @author simonThiele / https://github.com/simonThiele
+ */
+
+QUnit.module( "InterleavedBufferAttribute" );
+
+QUnit.test( "length and count", function( assert ) {
+	var buffer = new THREE.InterleavedBuffer( new Float32Array( [1, 2, 3, 7, 8 ,9] ), 3 );
+	var instance = new THREE.InterleavedBufferAttribute( buffer, 2, 0 );
+
+	assert.ok( instance.count === 2, "count is calculated via array length / stride" );
+});
+
+QUnit.test( "setX" , function( assert ) {
+	var buffer = new THREE.InterleavedBuffer( new Float32Array( [1, 2, 3, 7, 8 ,9] ), 3 );
+	var instance = new THREE.InterleavedBufferAttribute( buffer, 2, 0 );
+
+	instance.setX( 0, 123 );
+	instance.setX( 1, 321 );
+
+	assert.ok( instance.data.array[0] === 123 &&
+			instance.data.array[3] === 321, "x was calculated correct based on index and default offset" );
+
+
+	buffer = new THREE.InterleavedBuffer( new Float32Array( [1, 2, 3, 7, 8 ,9] ), 3 );
+	instance = new THREE.InterleavedBufferAttribute( buffer, 2, 1 );
+
+	instance.setX( 0, 123 );
+	instance.setX( 1, 321 );
+
+	// the offset was defined as 1, so go one step futher in the array
+	assert.ok( instance.data.array[1] === 123 &&
+			instance.data.array[4] === 321, "x was calculated correct based on index and default offset" );
+});
+
+// setY, setZ and setW are calculated in the same way so not testing this

+ 6 - 0
test/unit/src/core/Layers.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of Layers")

+ 102 - 0
test/unit/src/core/Object3D.js

@@ -0,0 +1,102 @@
+/**
+ * @author simonThiele / https://github.com/simonThiele
+ */
+
+QUnit.module( "Object3D" );
+
+var RadToDeg = 180 / Math.PI;
+
+QUnit.test( "rotateX" , function( assert ) {
+	var obj = new THREE.Object3D();
+
+	var angleInRad = 1.562;
+	obj.rotateX(angleInRad);
+
+	// should calculate the correct rotation on x
+	checkIfFloatsAreEqual(obj.rotation.x, angleInRad, assert);
+});
+
+QUnit.test( "rotateY" , function( assert ) {
+	var obj = new THREE.Object3D();
+
+	var angleInRad = -0.346;
+	obj.rotateY(angleInRad);
+
+	// should calculate the correct rotation on y
+	checkIfFloatsAreEqual(obj.rotation.y, angleInRad, assert);
+});
+
+QUnit.test( "rotateZ" , function( assert ) {
+	var obj = new THREE.Object3D();
+
+	var angleInRad = 1;
+	obj.rotateZ(angleInRad);
+
+	// should calculate the correct rotation on y
+	checkIfFloatsAreEqual(obj.rotation.z, angleInRad, assert);
+});
+
+QUnit.test( "translateOnAxis" , function( assert ) {
+	var obj = new THREE.Object3D();
+
+	// get a reference object for comparing
+	var reference = {x: 1, y: 1.23, z: -4.56};
+	obj.translateOnAxis(new THREE.Vector3(1, 0, 0), 1);
+	obj.translateOnAxis(new THREE.Vector3(0, 1, 0), 1.23);
+	obj.translateOnAxis(new THREE.Vector3(0, 0, 1), -4.56);
+
+	checkIfPropsAreEqual(reference, obj.position, assert);
+});
+
+QUnit.test( "translateX" , function( assert ) {
+	var obj = new THREE.Object3D();
+	obj.translateX(1.234);
+
+	assert.ok( obj.position.x === 1.234 , "x is equal" );
+});
+
+QUnit.test( "translateY" , function( assert ) {
+	var obj = new THREE.Object3D();
+	obj.translateY(1.234);
+
+	assert.ok( obj.position.y === 1.234 , "y is equal" );
+});
+
+QUnit.test( "translateZ" , function( assert ) {
+	var obj = new THREE.Object3D();
+	obj.translateZ(1.234);
+
+	assert.ok( obj.position.z === 1.234 , "z is equal" );
+});
+
+QUnit.test( "lookAt" , function( assert ) {
+	var obj = new THREE.Object3D();
+	obj.lookAt(new THREE.Vector3(0, -1, 1));
+
+	assert.ok( obj.rotation.x * RadToDeg === 45 , "x is equal" );
+});
+
+QUnit.test( "getWorldRotation" , function( assert ) {
+	var obj = new THREE.Object3D();
+
+	obj.lookAt(new THREE.Vector3(0, -1, 1));
+	assert.ok( obj.getWorldRotation().x * RadToDeg === 45 , "x is equal" );
+
+	obj.lookAt(new THREE.Vector3(1, 0, 0));
+	assert.ok( obj.getWorldRotation().y * RadToDeg === 90 , "y is equal" );
+});
+
+function checkIfPropsAreEqual(reference, obj, assert) {
+	assert.ok( obj.x === reference.x , "x is equal" );
+	assert.ok( obj.y === reference.y , "y is equal!" );
+	assert.ok( obj.z === reference.z , "z is equal!" );
+}
+
+// since float equal checking is a mess in js, one solution is to cut off
+// decimal places
+function checkIfFloatsAreEqual(f1, f2, assert) {
+	var f1Rounded = ((f1 * 1000) | 0) / 1000;
+	var f2Rounded = ((f2 * 1000) | 0) / 1000;
+
+	assert.ok( f1Rounded === f2Rounded, "passed" );
+}

+ 119 - 0
test/unit/src/core/Raycaster.js

@@ -0,0 +1,119 @@
+/**
+ * @author simonThiele / https://github.com/simonThiele
+ */
+
+QUnit.module( "Raycaster" );
+
+QUnit.test( "intersectObjects" , function( assert ) {
+	var raycaster = getRaycaster();
+	var objectsToCheck = getObjectsToCheck();
+
+	assert.ok( raycaster.intersectObjects( objectsToCheck ).length === 1,
+		"no recursive search should lead to one hit" );
+
+	assert.ok( raycaster.intersectObjects( objectsToCheck, true ).length === 3,
+		"recursive search should lead to three hits" );
+
+	var intersections = raycaster.intersectObjects( objectsToCheck, true );
+	for ( var i = 0; i < intersections.length - 1; i++ ) {
+
+	  assert.ok( intersections[ i ].distance <= intersections[ i + 1 ].distance, "intersections are sorted" );
+
+	}
+});
+
+QUnit.test( "intersectObject" , function( assert ) {
+	var raycaster = getRaycaster();
+	var objectsToCheck = getObjectsToCheck();
+
+	assert.ok( raycaster.intersectObject( objectsToCheck[ 0 ] ).length === 1,
+		"no recursive search should lead to one hit" );
+
+	assert.ok( raycaster.intersectObject( objectsToCheck[ 0 ], true ).length === 3,
+		"recursive search should lead to three hits" );
+
+	var intersections = raycaster.intersectObject( objectsToCheck[ 0 ], true );
+	for ( var i = 0; i < intersections.length - 1; i++ ) {
+
+	  assert.ok( intersections[ i ].distance <= intersections[ i + 1 ].distance, "intersections are sorted" );
+
+	}
+});
+
+QUnit.test( "setFromCamera" , function( assert ) {
+	var raycaster = new THREE.Raycaster();
+	var rayDirection = raycaster.ray.direction;
+	var camera = new THREE.PerspectiveCamera( 90, 1, 1, 1000 );
+
+	raycaster.setFromCamera( { x : 0, y: 0 }, camera );
+	assert.ok( rayDirection.x === 0, rayDirection.y === 0, rayDirection.z === -1,
+		"camera is looking straight to -z and so does the ray in the middle of the screen" );
+
+	var step = 0.1;
+
+	for ( var x = -1; x <= 1; x += step ) {
+
+		for ( var y = -1; y <= 1; y += step ) {
+
+			raycaster.setFromCamera( { x, y }, camera );
+
+			var refVector = new THREE.Vector3( x, y, -1 ).normalize();
+
+			checkRayDirectionAgainstReferenceVector( rayDirection, refVector, assert );
+
+		}
+
+	}
+});
+
+function checkRayDirectionAgainstReferenceVector( rayDirection, refVector, assert ) {
+	assert.ok( refVector.x - rayDirection.x <= Number.EPSILON &&
+			refVector.y - rayDirection.y <= Number.EPSILON &&
+			refVector.z - rayDirection.z <= Number.EPSILON,
+			"camera is pointing to the same direction as expected" );
+}
+
+function getRaycaster() {
+	return raycaster = new THREE.Raycaster(
+		new THREE.Vector3( 0, 0, 0 ),
+		new THREE.Vector3( 0, 0, -1 ),
+		1,
+		100
+	);
+}
+
+function getObjectsToCheck() {
+	var objects = [];
+
+	var sphere1 = getSphere();
+	sphere1.position.set( 0, 0, -10 );
+	sphere1.name = 1;
+	objects.push( sphere1 );
+
+	var sphere11 = getSphere();
+	sphere11.position.set( 0, 0, 1 );
+	sphere11.name = 11;
+	sphere1.add( sphere11 );
+
+	var sphere12 = getSphere();
+	sphere12.position.set( 0, 0, -1 );
+	sphere12.name = 12;
+	sphere1.add( sphere12 );
+
+	var sphere2 = getSphere();
+	sphere2.position.set( -5, 0, -5 );
+	sphere2.name = 2;
+	objects.push( sphere2 );
+
+	for ( var i = 0; i < objects.length; i++ ) {
+
+		objects[ i ].updateMatrixWorld();
+
+	}
+
+	return objects;
+}
+
+function getSphere() {
+	return new THREE.Mesh( new THREE.SphereGeometry( 1, 100, 100 ) );
+}

+ 6 - 0
test/unit/src/core/Uniform.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of Uniform")

+ 6 - 0
test/unit/src/extras/SceneUtils.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of SceneUtils")

+ 6 - 0
test/unit/src/extras/ShapeUtils.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of ShapeUtils")

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

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of Curve")

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

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of CurvePath")

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

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of Font")

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

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of Interpolations")

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

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of Path")

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

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of PathPrototype")

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

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of Shape")

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

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of ShapePath")

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

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of ArcCurve")

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

@@ -0,0 +1,125 @@
+/**
+ * @author zz85 / http://joshuakoo.com
+ */
+
+QUnit.module( "CatmullRomCurve3" );
+
+var positions = [
+	new THREE.Vector3( - 60, - 100,  60 ),
+	new THREE.Vector3( - 60,   20,  60 ),
+	new THREE.Vector3( - 60,  120,  60 ),
+	new THREE.Vector3(  60,   20, - 60 ),
+	new THREE.Vector3(  60, - 100, - 60 )
+];
+
+QUnit.test( "catmullrom check", function( assert ) {
+
+	var curve = new THREE.CatmullRomCurve3( positions );
+	curve.type = 'catmullrom';
+
+	var catmullPoints = [
+
+		new THREE.Vector3( - 60, - 100, 60 ),
+		new THREE.Vector3( - 60, - 51.04, 60 ),
+		new THREE.Vector3( - 60, - 2.7199999999999998, 60 ),
+		new THREE.Vector3( - 61.92, 44.48, 61.92 ),
+		new THREE.Vector3( - 68.64, 95.36000000000001, 68.64 ),
+		new THREE.Vector3( - 60, 120, 60 ),
+		new THREE.Vector3( - 14.880000000000017, 95.36000000000001, 14.880000000000017 ),
+		new THREE.Vector3( 41.75999999999997, 44.48000000000003, - 41.75999999999997 ),
+		new THREE.Vector3( 67.68, - 4.640000000000025, - 67.68 ),
+		new THREE.Vector3( 65.75999999999999, - 59.68000000000002, - 65.75999999999999 ),
+		new THREE.Vector3( 60, - 100, - 60 )
+
+	];
+
+	var getPoints = curve.getPoints( 10 );
+	var error = vectorsAreEqual( getPoints, catmullPoints );
+	assert.ok( getPoints.length == 11, 'getPoints should be equal.' );
+	var desc = error ? ' ' + error : '';
+	assert.ok( ! error, 'Lists of Vectors3 should be equal.' + desc );
+
+} );
+
+QUnit.test( "chordal basic check", function( assert ) {
+
+	var curve = new THREE.CatmullRomCurve3( positions );
+
+	curve.type = 'chordal';
+
+	var chordalPoints = [
+		new THREE.Vector3( - 60, - 100, 60 ),
+		new THREE.Vector3( - 60, - 52, 60 ),
+		new THREE.Vector3( - 60, - 4, 60 ),
+		new THREE.Vector3( - 60.656435889910924, 41.62455386421379, 60.656435889910924 ),
+		new THREE.Vector3( - 62.95396150459915, 87.31049238896205, 62.95396150459915 ),
+		new THREE.Vector3( - 60, 120, 60 ),
+		new THREE.Vector3( - 16.302568199486444, 114.1500463116312, 16.302568199486444 ),
+		new THREE.Vector3( 42.998098664956586, 54.017050116427455, - 42.998098664956586 ),
+		new THREE.Vector3( 63.542500175682434, - 3.0571533975463856, - 63.542500175682434 ),
+		new THREE.Vector3( 62.65687513176183, - 58.49286504815978, - 62.65687513176183 ),
+		new THREE.Vector3( 60.00000000000001, - 100, - 60.00000000000001 )
+	];
+
+	var getPoints = curve.getPoints( 10 );
+	var error = vectorsAreEqual( getPoints, chordalPoints );
+	assert.ok( getPoints.length == 11, 'getPoints should be equal.' );
+	var desc = error ? ' ' + error : '';
+	assert.ok( ! error, 'Lists of Vectors3 should be equal.' + desc );
+
+} );
+
+QUnit.test( "centripetal basic check", function( assert ) {
+
+	var curve = new THREE.CatmullRomCurve3( positions );
+	curve.type = 'centripetal';
+
+	var centripetalPoints = [
+		new THREE.Vector3( - 60, - 100, 60 ),
+		new THREE.Vector3( - 60, - 51.47527724919028, 60 ),
+		new THREE.Vector3( - 60, - 3.300369665587032, 60 ),
+		new THREE.Vector3( - 61.13836565863938, 42.86306307781241, 61.13836565863938 ),
+		new THREE.Vector3( - 65.1226454638772, 90.69743905511538, 65.1226454638772 ),
+		new THREE.Vector3( - 60, 120, 60 ),
+		new THREE.Vector3( - 15.620412575504497, 103.10790870179872, 15.620412575504497 ),
+		new THREE.Vector3( 42.384384731047874, 48.35477686933143, - 42.384384731047874 ),
+		new THREE.Vector3( 65.25545512241153, - 3.5662509660683424, - 65.25545512241153 ),
+		new THREE.Vector3( 63.94159134180865, - 58.87468822455125, - 63.94159134180865 ),
+		new THREE.Vector3( 59.99999999999999, - 100, - 59.99999999999999 ),
+	];
+
+	var getPoints = curve.getPoints( 10 );
+	var error = vectorsAreEqual( getPoints, centripetalPoints );
+	assert.ok( getPoints.length == 11, 'getPoints should be equal.' );
+	var desc = error ? ' ' + error : '';
+	assert.ok( ! error, 'Lists of Vectors3 should be equal.' + desc );
+
+} );
+
+QUnit.test( "closed catmullrom basic check", function( assert ) {
+
+	var curve = new THREE.CatmullRomCurve3( positions );
+	curve.type = 'catmullrom';
+	curve.closed = true;
+
+	var closedSplinePoints = [
+		new THREE.Vector3( - 60, - 100, 60 ),
+		new THREE.Vector3( - 67.5, - 46.25, 67.5 ),
+		new THREE.Vector3( - 60, 20, 60 ),
+		new THREE.Vector3( - 67.5, 83.75, 67.5 ),
+		new THREE.Vector3( - 60, 120, 60 ),
+		new THREE.Vector3( 0, 83.75, 0 ),
+		new THREE.Vector3( 60, 20, - 60 ),
+		new THREE.Vector3( 75, - 46.25, - 75 ),
+		new THREE.Vector3( 60, - 100, - 60 ),
+		new THREE.Vector3( 0, - 115, 0 ),
+		new THREE.Vector3( - 60, - 100, 60 ),
+	];
+
+	var getPoints = curve.getPoints( 10 );
+	var error = vectorsAreEqual( getPoints, closedSplinePoints );
+	assert.ok( getPoints.length == 11, 'getPoints should be equal.' );
+	var desc = error ? ' ' + error : '';
+	assert.ok( ! error, 'Lists of Vectors3 should be equal.' + desc );
+
+} );

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

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of CubicBezierCurve")

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

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of CubicBezierCurve3")

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

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of EllipseCurve")

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

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of LineCurve")

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

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of LineCurve3")

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

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of QuadraticBezierCurve")

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

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of QuadraticBezierCurve")

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

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of SplineCurve")

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

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of ImmediateRenderObject")

+ 6 - 0
test/unit/src/extras/objects/MorphBlendMesh.js

@@ -0,0 +1,6 @@
+/**
+ * @author TristanVALCKE / https://github.com/TristanVALCKE
+ */
+
+//Todo
+console.warn("Todo: Unit tests of MorphBlendMesh")

+ 38 - 0
test/unit/src/geometries/BoxGeometry.tests.js

@@ -0,0 +1,38 @@
+(function () {
+
+	'use strict';
+
+	var parameters = {
+		width: 10,
+		height: 20,
+		depth: 30,
+		widthSegments: 2,
+		heightSegments: 3,
+		depthSegments: 4
+	};
+
+	var geometries;
+	var box, cube, boxWithSegments;
+
+	QUnit.module( "Extras - Geometries - BoxGeometry", {
+
+		beforeEach: function() {
+
+			box = new THREE.BoxGeometry( parameters.width, parameters.height, parameters.depth );
+			cube = new THREE.CubeGeometry( parameters.width, parameters.height, parameters.depth );
+			boxWithSegments = new THREE.BoxGeometry( parameters.width, parameters.height, parameters.depth,
+													parameters.widthSegments, parameters.heightSegments, parameters.depthSegments );
+
+			geometries = [ box, cube, boxWithSegments ];
+
+		}
+
+	});
+
+	QUnit.test( "standard geometry tests", function( assert ) {
+
+		runStdGeometryTests( assert, geometries );
+
+	});
+
+})();

+ 38 - 0
test/unit/src/geometries/CircleBufferGeometry.tests.js

@@ -0,0 +1,38 @@
+(function () {
+
+	'use strict';
+
+	var parameters = {
+		radius: 10,
+		segments: 20,
+		thetaStart: 0.1,
+		thetaLength: 0.2
+	};
+
+	var geometries;
+
+	QUnit.module( "Extras - Geometries - CircleBufferGeometry", {
+
+		beforeEach: function() {
+
+			geometries = [
+
+				new THREE.CircleBufferGeometry(),
+				new THREE.CircleBufferGeometry( parameters.radius ),
+				new THREE.CircleBufferGeometry( parameters.radius, parameters.segments ),
+				new THREE.CircleBufferGeometry( parameters.radius, parameters.segments, parameters.thetaStart ),
+				new THREE.CircleBufferGeometry( parameters.radius, parameters.segments, parameters.thetaStart, parameters.thetaLength ),
+
+			];
+
+		}
+
+	});
+
+	QUnit.test( "standard geometry tests", function( assert ) {
+
+		runStdGeometryTests( assert, geometries );
+
+	});
+
+})();

+ 38 - 0
test/unit/src/geometries/CircleGeometry.tests.js

@@ -0,0 +1,38 @@
+(function () {
+
+	'use strict';
+
+	var parameters = {
+		radius: 10,
+		segments: 20,
+		thetaStart: 0.1,
+		thetaLength: 0.2
+	};
+
+	var geometries;
+
+	QUnit.module( "Extras - Geometries - CircleGeometry", {
+
+		beforeEach: function() {
+
+			geometries = [
+
+				new THREE.CircleGeometry(),
+				new THREE.CircleGeometry( parameters.radius ),
+				new THREE.CircleGeometry( parameters.radius, parameters.segments ),
+				new THREE.CircleGeometry( parameters.radius, parameters.segments, parameters.thetaStart ),
+				new THREE.CircleGeometry( parameters.radius, parameters.segments, parameters.thetaStart, parameters.thetaLength ),
+
+			];
+
+		}
+
+	});
+
+	QUnit.test( "standard geometry tests", function( assert ) {
+
+		runStdGeometryTests( assert, geometries );
+
+	});
+
+})();

+ 46 - 0
test/unit/src/geometries/CylinderGeometry.tests.js

@@ -0,0 +1,46 @@
+(function () {
+
+	'use strict';
+
+	var parameters = {
+		radiusTop: 10,
+		radiusBottom: 20,
+		height: 30,
+		radialSegments: 20,
+		heightSegments: 30,
+		openEnded: true,
+		thetaStart: 0.1,
+		thetaLength: 2.0,
+	};
+
+	var geometries;
+
+	QUnit.module( "Extras - Geometries - CylinderGeometry", {
+
+		beforeEach: function() {
+
+			geometries = [
+
+				new THREE.CylinderGeometry(),
+				new THREE.CylinderGeometry( parameters.radiusTop ),
+				new THREE.CylinderGeometry( parameters.radiusTop, parameters.radiusBottom ),
+				new THREE.CylinderGeometry( parameters.radiusTop, parameters.radiusBottom, parameters.height ),
+				new THREE.CylinderGeometry( parameters.radiusTop, parameters.radiusBottom, parameters.height, parameters.radialSegments ),
+				new THREE.CylinderGeometry( parameters.radiusTop, parameters.radiusBottom, parameters.height, parameters.radialSegments, parameters.heightSegments ),
+				new THREE.CylinderGeometry( parameters.radiusTop, parameters.radiusBottom, parameters.height, parameters.radialSegments, parameters.heightSegments, parameters.openEnded ),
+				new THREE.CylinderGeometry( parameters.radiusTop, parameters.radiusBottom, parameters.height, parameters.radialSegments, parameters.heightSegments, parameters.openEnded, parameters.thetaStart ),
+				new THREE.CylinderGeometry( parameters.radiusTop, parameters.radiusBottom, parameters.height, parameters.radialSegments, parameters.heightSegments, parameters.openEnded, parameters.thetaStart, parameters.thetaLength ),
+
+			];
+
+		}
+
+	});
+
+	QUnit.test( "standard geometry tests", function( assert ) {
+
+		runStdGeometryTests( assert, geometries );
+
+	});
+
+})();

+ 34 - 0
test/unit/src/geometries/DodecahedronGeometry.tests.js

@@ -0,0 +1,34 @@
+(function () {
+
+	'use strict';
+
+	var parameters = {
+		radius: 10,
+		detail: undefined
+	};
+
+	var geometries;
+
+	QUnit.module( "Extras - Geometries - DodecahedronGeometry", {
+
+		beforeEach: function() {
+
+			geometries = [
+
+				new THREE.DodecahedronGeometry(),
+				new THREE.DodecahedronGeometry( parameters.radius ),
+				new THREE.DodecahedronGeometry( parameters.radius, parameters.detail ),
+
+			];
+
+		}
+
+	});
+
+	QUnit.test( "standard geometry tests", function( assert ) {
+
+		runStdGeometryTests( assert, geometries );
+
+	});
+
+})();

+ 274 - 0
test/unit/src/geometries/EdgesGeometry.js

@@ -0,0 +1,274 @@
+QUnit.module( "EdgesGeometry" );
+
+var DEBUG = false;
+
+var vertList = [
+	new THREE.Vector3(0, 0, 0),
+	new THREE.Vector3(1, 0, 0),
+	new THREE.Vector3(1, 1, 0),
+	new THREE.Vector3(0, 1, 0),
+	new THREE.Vector3(1, 1, 1),
+];
+
+QUnit.test( "singularity" , function( assert ) {
+
+	testEdges( vertList, [1, 1, 1], 0, assert );
+
+});
+
+QUnit.test( "needle" , function( assert ) {
+
+	testEdges( vertList, [0, 0, 1], 0, assert );
+
+});
+
+QUnit.test( "single triangle", function( assert ) {
+
+	testEdges( vertList, [0, 1, 2], 3, assert );
+
+});
+
+QUnit.test( "two isolated triangles", function( assert ) {
+
+	var vertList = [
+		new THREE.Vector3(0, 0, 0),
+		new THREE.Vector3(1, 0, 0),
+		new THREE.Vector3(1, 1, 0),
+		new THREE.Vector3(0, 0, 1),
+		new THREE.Vector3(1, 0, 1),
+		new THREE.Vector3(1, 1, 1),
+	];
+
+	testEdges( vertList, [0, 1, 2, 3, 4, 5], 6, assert );
+
+});
+
+QUnit.test( "two flat triangles", function( assert ) {
+
+	testEdges( vertList, [0, 1, 2, 0, 2, 3], 4, assert );
+
+});
+
+QUnit.test( "two flat triangles, inverted", function( assert ) {
+
+	testEdges( vertList, [0, 1, 2, 0, 3, 2], 5, assert );
+
+});
+
+QUnit.test( "two non-coplanar triangles", function( assert ) {
+
+	testEdges( vertList, [0, 1, 2, 0, 4, 2], 5, assert );
+
+});
+
+QUnit.test( "three triangles, coplanar first", function( assert ) {
+
+	testEdges( vertList, [0, 1, 2, 0, 2, 3, 0, 4, 2], 7, assert );
+
+});
+
+QUnit.test( "three triangles, coplanar last", function( assert ) {
+
+	testEdges( vertList, [0, 1, 2, 0, 4, 2, 0, 2, 3], 6, assert ); // Should be 7
+
+});
+
+QUnit.test( "tetrahedron" , function( assert ) {
+
+	testEdges( vertList, [0, 1, 2, 0, 1, 4, 0, 4, 2, 1, 2, 4], 6, assert );
+
+});
+
+
+
+//
+// HELPERS
+//
+
+
+function testEdges ( vertList, idxList, numAfter, assert ) {
+
+	var geoms = createGeometries ( vertList, idxList );
+
+	for ( var i = 0 ; i < geoms.length ; i ++ ) {
+
+		var geom = geoms[i];
+
+		var numBefore = idxList.length;
+		assert.equal( countEdges (geom), numBefore, "Edges before!" );
+
+		var egeom = new THREE.EdgesGeometry( geom );
+
+		assert.equal( countEdges (egeom), numAfter, "Edges after!" );
+		output( geom, egeom );
+
+	}
+
+}
+
+function createGeometries ( vertList, idxList ) {
+
+	var geomIB = createIndexedBufferGeometry ( vertList, idxList );
+	var geom = new THREE.Geometry().fromBufferGeometry( geomIB );
+	var geomB = new THREE.BufferGeometry().fromGeometry( geom );
+	var geomDC = addDrawCalls( geomIB.clone() );
+	return [ geom, geomB, geomIB, geomDC ];
+
+}
+
+function createIndexedBufferGeometry ( vertList, idxList ) {
+
+	var geom = new THREE.BufferGeometry();
+
+	var indexTable = [];
+	var numTris = idxList.length / 3;
+	var numVerts = 0;
+
+	var indices = new Uint32Array( numTris * 3 );
+	var vertices = new Float32Array( vertList.length * 3 );
+
+	for ( var i = 0; i < numTris; i ++ ) {
+
+		for ( var j = 0; j < 3; j ++ ) {
+
+			var idx = idxList[ 3 * i + j ];
+			if ( indexTable[ idx ] === undefined ) {
+
+				var v = vertList[ idx ];
+				vertices[ 3 * numVerts ] = v.x;
+				vertices[ 3 * numVerts + 1 ] = v.y;
+				vertices[ 3 * numVerts + 2 ] = v.z;
+
+				indexTable[ idx ] = numVerts;
+
+				numVerts ++;
+
+			}
+
+			indices[ 3 * i + j ] = indexTable[ idx ] ;
+
+		}
+
+	}
+
+	vertices = vertices.subarray( 0, 3 * numVerts );
+
+	geom.setIndex( new THREE.BufferAttribute( indices, 1 ) );
+	geom.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
+
+	geom.computeFaceNormals();
+
+	return geom;
+
+}
+
+function addDrawCalls ( geometry ) {
+
+	var numTris = geometry.index.count / 3;
+
+	var offset = 0;
+	for ( var i = 0 ; i < numTris; i ++ ) {
+
+		var start = i * 3;
+		var count = 3;
+
+		geometry.addGroup( start, count );
+	}
+
+	return geometry;
+
+}
+
+function countEdges ( geom ) {
+
+	if ( geom instanceof THREE.EdgesGeometry ) {
+
+		return geom.getAttribute( 'position' ).count / 2;
+
+	}
+
+	if ( geom.faces !== undefined ) {
+
+		return geom.faces.length * 3;
+
+	}
+
+	var indices = geom.index;
+	if ( indices ) {
+
+		return indices.count;
+
+	}
+
+	return geom.getAttribute( 'position' ).count;
+
+}
+
+//
+// DEBUGGING
+//
+
+var renderer;
+var camera;
+var scene = new THREE.Scene();
+var xoffset = 0;
+
+function output ( geom, egeom ) {
+
+	if ( DEBUG !== true ) return;
+
+	if ( !renderer ) initDebug();
+
+	var mesh = new THREE.Mesh( geom, undefined );
+	var edges = new THREE.LineSegments( egeom, new THREE.LineBasicMaterial( { color: 'black' } ) );
+
+	mesh.position.setX( xoffset );
+	edges.position.setX( xoffset ++ );
+	scene.add(mesh);
+	scene.add(edges);
+
+	if (scene.children.length % 8 === 0) {
+
+		xoffset += 2;
+
+	}
+
+}
+
+function initDebug () {
+
+	renderer = new THREE.WebGLRenderer({
+
+		antialias: true
+
+	});
+
+	var width = 600;
+	var height = 480;
+
+	renderer.setSize(width, height);
+	renderer.setClearColor( 0xCCCCCC );
+
+	camera = new THREE.PerspectiveCamera(45, width / height, 1, 100);
+	camera.position.x = 30;
+	camera.position.z = 40;
+	camera.lookAt(new THREE.Vector3(30, 0, 0));
+
+	document.body.appendChild(renderer.domElement);
+
+	var controls = new THREE.OrbitControls( camera, renderer.domElement );
+	controls.target = new THREE.Vector3(30, 0, 0);
+
+	animate();
+
+	function animate() {
+
+		requestAnimationFrame( animate );
+
+		controls.update();
+
+		renderer.render( scene, camera );
+
+	}
+
+}

+ 1 - 0
test/unit/src/geometries/ExtrudeGeometry.tests.js

@@ -0,0 +1 @@
+// TODO

+ 34 - 0
test/unit/src/geometries/IcosahedronGeometry.tests.js

@@ -0,0 +1,34 @@
+(function () {
+
+	'use strict';
+
+	var parameters = {
+		radius: 10,
+		detail: undefined
+	};
+
+	var geometries;
+
+	QUnit.module( "Extras - Geometries - IcosahedronGeometry", {
+
+		beforeEach: function() {
+
+			geometries = [
+
+				new THREE.IcosahedronGeometry(),
+				new THREE.IcosahedronGeometry( parameters.radius ),
+				new THREE.IcosahedronGeometry( parameters.radius, parameters.detail ),
+
+			];
+
+		}
+
+	});
+
+	QUnit.test( "standard geometry tests", function( assert ) {
+
+		runStdGeometryTests( assert, geometries );
+
+	});
+
+})();

+ 1 - 0
test/unit/src/geometries/LatheGeometry.tests.js

@@ -0,0 +1 @@
+// TODO

+ 34 - 0
test/unit/src/geometries/OctahedronGeometry.tests.js

@@ -0,0 +1,34 @@
+(function() {
+
+	'use strict';
+
+	var parameters = {
+		radius: 10,
+		detail: undefined
+	};
+
+	var geometries;
+
+	QUnit.module( "Extras - Geometries - OctahedronGeometry", {
+
+		beforeEach: function() {
+
+			geometries = [
+
+				new THREE.OctahedronGeometry(),
+				new THREE.OctahedronGeometry( parameters.radius ),
+				new THREE.OctahedronGeometry( parameters.radius, parameters.detail ),
+
+			];
+
+		}
+
+	});
+
+	QUnit.test( "standard geometry tests", function( assert ) {
+
+		runStdGeometryTests( assert, geometries );
+
+	});
+
+})();

+ 1 - 0
test/unit/src/geometries/ParametricGeometry.tests.js

@@ -0,0 +1 @@
+// TODO

+ 38 - 0
test/unit/src/geometries/PlaneBufferGeometry.tests.js

@@ -0,0 +1,38 @@
+(function () {
+
+	'use strict';
+
+	var parameters = {
+		width: 10,
+		height: 30,
+		widthSegments: 3,
+		heightSegments: 5
+	};
+
+	var geometries;
+
+	QUnit.module( "Extras - Geometries - PlaneBufferGeometry", {
+
+		beforeEach: function() {
+
+			geometries = [
+
+				new THREE.PlaneBufferGeometry(),
+				new THREE.PlaneBufferGeometry( parameters.width ),
+				new THREE.PlaneBufferGeometry( parameters.width, parameters.height ),
+				new THREE.PlaneBufferGeometry( parameters.width, parameters.height, parameters.widthSegments ),
+				new THREE.PlaneBufferGeometry( parameters.width, parameters.height, parameters.widthSegments, parameters.heightSegments ),
+
+			];
+
+		}
+
+	});
+
+	QUnit.test( "standard geometry tests", function( assert ) {
+
+		runStdGeometryTests( assert, geometries );
+
+	});
+
+})();

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov