Browse Source

Merge remote-tracking branch 'mrdoob/dev' into dev

Dusan Bosnjak 8 years ago
parent
commit
c0a6d90e0d
100 changed files with 1407 additions and 8237 deletions
  1. 6 0
      .github/ISSUE_TEMPLATE.md
  2. 61 46
      build/three.js
  3. 242 263
      build/three.min.js
  4. 61 46
      build/three.module.js
  5. 8 8
      docs/api/core/Object3D.html
  6. 1 1
      docs/api/deprecated/DeprecatedList.html
  7. 2 2
      docs/api/geometries/LatheGeometry.html
  8. 5 5
      docs/api/lights/DirectionalLight.html
  9. 78 80
      docs/api/lights/Light.html
  10. 1 1
      docs/api/lights/SpotLight.html
  11. 1 1
      docs/api/lights/shadows/DirectionalLightShadow.html
  12. 2 2
      docs/api/lights/shadows/LightShadow.html
  13. 1 1
      docs/api/lights/shadows/SpotLightShadow.html
  14. 3 3
      docs/api/objects/Mesh.html
  15. 1 1
      docs/index.html
  16. 1 1
      editor/index.html
  17. 1 1
      examples/index.html
  18. 2 2
      examples/js/controls/DragControls.js
  19. 71 3
      examples/js/loaders/FBXLoader2.js
  20. 39 13
      examples/js/loaders/GLTFLoader.js
  21. 22 19
      examples/webgl_simple_gi.html
  22. 2 0
      package.json
  23. 4 4
      src/loaders/ObjectLoader.js
  24. 4 5
      src/math/Matrix4.js
  25. 33 20
      src/renderers/webgl/WebGLUniforms.js
  26. 21 17
      src/scenes/Scene.js
  27. 248 0
      test/Three.Unit.js
  28. 40 0
      test/rollup.unit.config.js
  29. 0 41
      test/unit/cameras/OrthographicCamera.js
  30. 0 117
      test/unit/core/BufferAttribute.js
  31. 0 76
      test/unit/core/EventDispatcher.js
  32. 0 29
      test/unit/core/InstancedBufferAttribute.js
  33. 0 53
      test/unit/core/InstancedBufferGeometry.js
  34. 0 46
      test/unit/core/InterleavedBuffer.js
  35. 0 102
      test/unit/core/Object3D.js
  36. 10 10
      test/unit/editor/TestAddObjectCommandAndRemoveObjectCommand.js
  37. 8 8
      test/unit/editor/TestAddScriptCommand.js
  38. 5 5
      test/unit/editor/TestMassUndoAndRedo.js
  39. 13 13
      test/unit/editor/TestMoveObjectCommand.js
  40. 14 14
      test/unit/editor/TestMultiCmdsCommand.js
  41. 18 18
      test/unit/editor/TestNegativeCases.js
  42. 31 31
      test/unit/editor/TestNestedDoUndoRedo.js
  43. 7 7
      test/unit/editor/TestRemoveScriptCommand.js
  44. 4 4
      test/unit/editor/TestSerialization.js
  45. 5 5
      test/unit/editor/TestSetColorCommand.js
  46. 20 20
      test/unit/editor/TestSetGeometryCommand.js
  47. 8 8
      test/unit/editor/TestSetGeometryValueCommand.js
  48. 5 5
      test/unit/editor/TestSetMaterialColorCommand.js
  49. 5 5
      test/unit/editor/TestSetMaterialCommand.js
  50. 5 5
      test/unit/editor/TestSetMaterialMapCommand.js
  51. 5 5
      test/unit/editor/TestSetMaterialValueCommand.js
  52. 11 11
      test/unit/editor/TestSetPositionCommand.js
  53. 11 11
      test/unit/editor/TestSetRotationCommand.js
  54. 11 11
      test/unit/editor/TestSetScaleCommand.js
  55. 6 6
      test/unit/editor/TestSetSceneCommand.js
  56. 8 8
      test/unit/editor/TestSetScriptValueCommand.js
  57. 5 5
      test/unit/editor/TestSetUuidCommand.js
  58. 7 7
      test/unit/editor/TestSetValueCommand.js
  59. 0 87
      test/unit/extras/ImageUtils.test.js
  60. 0 246
      test/unit/math/Box2.js
  61. 0 313
      test/unit/math/Box3.js
  62. 0 280
      test/unit/math/Color.js
  63. 0 156
      test/unit/math/Frustum.js
  64. 0 69
      test/unit/math/Line3.js
  65. 0 35
      test/unit/math/Math.js
  66. 0 212
      test/unit/math/Matrix3.js
  67. 0 197
      test/unit/math/Plane.js
  68. 0 112
      test/unit/math/Sphere.js
  69. 0 191
      test/unit/math/Triangle.js
  70. 0 262
      test/unit/math/Vector2.js
  71. 0 379
      test/unit/math/Vector3.js
  72. 0 318
      test/unit/math/Vector4.js
  73. 0 291
      test/unit/qunit-1.18.0.css
  74. 0 3829
      test/unit/qunit-1.18.0.js
  75. 4 4
      test/unit/qunit-utils.js
  76. 34 0
      test/unit/src/animation/AnimationAction.js
  77. 6 0
      test/unit/src/animation/AnimationClip.js
  78. 6 0
      test/unit/src/animation/AnimationMixer.js
  79. 9 9
      test/unit/src/animation/AnimationObjectGroup.js
  80. 6 0
      test/unit/src/animation/AnimationUtils.js
  81. 6 0
      test/unit/src/animation/KeyframeTrack.js
  82. 6 0
      test/unit/src/animation/KeyframeTrackConstructor.js
  83. 6 0
      test/unit/src/animation/KeyframeTrackPrototype.js
  84. 6 0
      test/unit/src/animation/PropertyBinding.js
  85. 6 0
      test/unit/src/animation/PropertyMixer.js
  86. 6 0
      test/unit/src/animation/tracks/BooleanKeyframeTrack.js
  87. 6 0
      test/unit/src/animation/tracks/ColorKeyframeTrack.js
  88. 6 0
      test/unit/src/animation/tracks/NumberKeyframeTrack.js
  89. 6 0
      test/unit/src/animation/tracks/QuaternionKeyframeTrack.js
  90. 6 0
      test/unit/src/animation/tracks/StringKeyframeTrack.js
  91. 6 0
      test/unit/src/animation/tracks/VectorKeyFrameTrack.js
  92. 6 0
      test/unit/src/audio/Audio.js
  93. 6 0
      test/unit/src/audio/AudioAnalyser.js
  94. 6 0
      test/unit/src/audio/AudioContext.js
  95. 6 0
      test/unit/src/audio/AudioListener.js
  96. 6 0
      test/unit/src/audio/PositionalAudio.js
  97. 6 6
      test/unit/src/cameras/Camera.js
  98. 6 0
      test/unit/src/cameras/CubeCamera.js
  99. 41 0
      test/unit/src/cameras/OrthographicCamera.js
  100. 10 10
      test/unit/src/cameras/PerspectiveCamera.js

+ 6 - 0
.github/ISSUE_TEMPLATE.md

@@ -2,6 +2,12 @@
 
 
 ##### Description of the problem 
 ##### Description of the problem 
 
 
+Describe the problem/request in detail.
+Code snippet, screenshot, and small-test help us understand.
+
+You can edit for small-test.
+http://jsfiddle.net/akmcv7Lh/ (current revision)
+http://jsfiddle.net/hw9rcLL8/ (dev)
 
 
 ##### Three.js version
 ##### Three.js version
 
 

+ 61 - 46
build/three.js

@@ -3335,14 +3335,14 @@
 
 
 	function Matrix4() {
 	function Matrix4() {
 
 
-		this.elements = new Float32Array( [
+		this.elements = [
 
 
 			1, 0, 0, 0,
 			1, 0, 0, 0,
 			0, 1, 0, 0,
 			0, 1, 0, 0,
 			0, 0, 1, 0,
 			0, 0, 1, 0,
 			0, 0, 0, 1
 			0, 0, 0, 1
 
 
-		] );
+		];
 
 
 		if ( arguments.length > 0 ) {
 		if ( arguments.length > 0 ) {
 
 
@@ -3392,7 +3392,7 @@
 
 
 		copy: function ( m ) {
 		copy: function ( m ) {
 
 
-			this.elements.set( m.elements );
+			for ( var i = 0; i < 16; i ++ ) this.elements[ i ] = m.elements[ i ];
 
 
 			return this;
 			return this;
 
 
@@ -4103,8 +4103,7 @@
 				position.z = te[ 14 ];
 				position.z = te[ 14 ];
 
 
 				// scale the rotation part
 				// scale the rotation part
-
-				matrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()
+				for ( var i = 0; i < 16; i ++ ) matrix.elements[ i ] = this.elements[ i ]; // at this point matrix is incomplete so we can't use .copy()
 
 
 				var invSX = 1 / sx;
 				var invSX = 1 / sx;
 				var invSY = 1 / sy;
 				var invSY = 1 / sy;
@@ -4346,6 +4345,10 @@
 	var arrayCacheF32 = [];
 	var arrayCacheF32 = [];
 	var arrayCacheI32 = [];
 	var arrayCacheI32 = [];
 
 
+	// Float32Array cache used for uploading Matrix4 uniform
+
+	var mat4array = new Float32Array( 16 );
+
 	// Flattening for arrays of vectors and matrices
 	// Flattening for arrays of vectors and matrices
 
 
 	function flatten( array, nBlocks, blockSize ) {
 	function flatten( array, nBlocks, blockSize ) {
@@ -4456,7 +4459,16 @@
 
 
 	function setValue4fm( gl, v ) {
 	function setValue4fm( gl, v ) {
 
 
-		gl.uniformMatrix4fv( this.addr, false, v.elements || v );
+		if ( v.elements === undefined ) {
+
+			gl.uniformMatrix4fv( this.addr, false, v );
+
+		} else {
+
+			mat4array.set( v.elements );
+			gl.uniformMatrix4fv( this.addr, false, mat4array );
+
+		}
 
 
 	}
 	}
 
 
@@ -4646,7 +4658,7 @@
 
 
 	}
 	}
 
 
-	StructuredUniform.prototype.setValue = function( gl, value ) {
+	StructuredUniform.prototype.setValue = function ( gl, value ) {
 
 
 		// Note: Don't need an extra 'renderer' parameter, since samplers
 		// Note: Don't need an extra 'renderer' parameter, since samplers
 		// are not allowed in structured uniforms.
 		// are not allowed in structured uniforms.
@@ -4692,7 +4704,7 @@
 		// reset RegExp object, because of the early exit of a previous run
 		// reset RegExp object, because of the early exit of a previous run
 		RePathPart.lastIndex = 0;
 		RePathPart.lastIndex = 0;
 
 
-		for (; ;) {
+		for ( ; ; ) {
 
 
 			var match = RePathPart.exec( path ),
 			var match = RePathPart.exec( path ),
 				matchEnd = RePathPart.lastIndex,
 				matchEnd = RePathPart.lastIndex,
@@ -4703,8 +4715,8 @@
 
 
 			if ( idIsIndex ) id = id | 0; // convert to integer
 			if ( idIsIndex ) id = id | 0; // convert to integer
 
 
-			if ( subscript === undefined ||
-					subscript === '[' && matchEnd + 2 === pathLength ) {
+			if ( subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength ) {
+
 				// bare name or "pure" bottom-level array "[0]" suffix
 				// bare name or "pure" bottom-level array "[0]" suffix
 
 
 				addUniform( container, subscript === undefined ?
 				addUniform( container, subscript === undefined ?
@@ -4714,10 +4726,10 @@
 				break;
 				break;
 
 
 			} else {
 			} else {
+
 				// step into inner node / create it in case it doesn't exist
 				// step into inner node / create it in case it doesn't exist
 
 
-				var map = container.map,
-					next = map[ id ];
+				var map = container.map, next = map[ id ];
 
 
 				if ( next === undefined ) {
 				if ( next === undefined ) {
 
 
@@ -4756,7 +4768,7 @@
 
 
 	}
 	}
 
 
-	WebGLUniforms.prototype.setValue = function( gl, name, value ) {
+	WebGLUniforms.prototype.setValue = function ( gl, name, value ) {
 
 
 		var u = this.map[ name ];
 		var u = this.map[ name ];
 
 
@@ -4764,7 +4776,7 @@
 
 
 	};
 	};
 
 
-	WebGLUniforms.prototype.set = function( gl, object, name ) {
+	WebGLUniforms.prototype.set = function ( gl, object, name ) {
 
 
 		var u = this.map[ name ];
 		var u = this.map[ name ];
 
 
@@ -4772,7 +4784,7 @@
 
 
 	};
 	};
 
 
-	WebGLUniforms.prototype.setOptional = function( gl, object, name ) {
+	WebGLUniforms.prototype.setOptional = function ( gl, object, name ) {
 
 
 		var v = object[ name ];
 		var v = object[ name ];
 
 
@@ -4783,7 +4795,7 @@
 
 
 	// Static interface
 	// Static interface
 
 
-	WebGLUniforms.upload = function( gl, seq, values, renderer ) {
+	WebGLUniforms.upload = function ( gl, seq, values, renderer ) {
 
 
 		for ( var i = 0, n = seq.length; i !== n; ++ i ) {
 		for ( var i = 0, n = seq.length; i !== n; ++ i ) {
 
 
@@ -4791,8 +4803,8 @@
 				v = values[ u.id ];
 				v = values[ u.id ];
 
 
 			if ( v.needsUpdate !== false ) {
 			if ( v.needsUpdate !== false ) {
-				// note: always updating when .needsUpdate is undefined
 
 
+				// note: always updating when .needsUpdate is undefined
 				u.setValue( gl, v.value, renderer );
 				u.setValue( gl, v.value, renderer );
 
 
 			}
 			}
@@ -4801,7 +4813,7 @@
 
 
 	};
 	};
 
 
-	WebGLUniforms.seqWithValue = function( seq, values ) {
+	WebGLUniforms.seqWithValue = function ( seq, values ) {
 
 
 		var r = [];
 		var r = [];
 
 
@@ -8390,7 +8402,7 @@
 
 
 		},
 		},
 
 
-		setFromMatrix4: function( m ) {
+		setFromMatrix4: function ( m ) {
 
 
 			var me = m.elements;
 			var me = m.elements;
 
 
@@ -8490,6 +8502,7 @@
 				}
 				}
 
 
 				return this.identity();
 				return this.identity();
+
 			}
 			}
 
 
 			var detInv = 1 / det;
 			var detInv = 1 / det;
@@ -8550,7 +8563,7 @@
 
 
 			if ( offset === undefined ) offset = 0;
 			if ( offset === undefined ) offset = 0;
 
 
-			for( var i = 0; i < 9; i ++ ) {
+			for ( var i = 0; i < 9; i ++ ) {
 
 
 				this.elements[ i ] = array[ i + offset ];
 				this.elements[ i ] = array[ i + offset ];
 
 
@@ -8577,7 +8590,7 @@
 
 
 			array[ offset + 6 ] = te[ 6 ];
 			array[ offset + 6 ] = te[ 6 ];
 			array[ offset + 7 ] = te[ 7 ];
 			array[ offset + 7 ] = te[ 7 ];
-			array[ offset + 8 ]  = te[ 8 ];
+			array[ offset + 8 ] = te[ 8 ];
 
 
 			return array;
 			return array;
 
 
@@ -15020,7 +15033,7 @@
 						uvB.fromBufferAttribute( uv, b );
 						uvB.fromBufferAttribute( uv, b );
 						uvC.fromBufferAttribute( uv, c );
 						uvC.fromBufferAttribute( uv, c );
 
 
-						intersection.uv = uvIntersection( intersectionPoint,  vA, vB, vC, uvA, uvB, uvC );
+						intersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );
 
 
 					}
 					}
 
 
@@ -22667,35 +22680,37 @@
 
 
 	}
 	}
 
 
-	Scene.prototype = Object.create( Object3D.prototype );
+	Scene.prototype = Object.assign( Object.create( Object3D.prototype ), {
+
+		constructor: Scene,
 
 
-	Scene.prototype.constructor = Scene;
+		copy: function ( source, recursive ) {
 
 
-	Scene.prototype.copy = function ( source, recursive ) {
+			Object3D.prototype.copy.call( this, source, recursive );
 
 
-		Object3D.prototype.copy.call( this, source, recursive );
+			if ( source.background !== null ) this.background = source.background.clone();
+			if ( source.fog !== null ) this.fog = source.fog.clone();
+			if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();
 
 
-		if ( source.background !== null ) this.background = source.background.clone();
-		if ( source.fog !== null ) this.fog = source.fog.clone();
-		if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();
+			this.autoUpdate = source.autoUpdate;
+			this.matrixAutoUpdate = source.matrixAutoUpdate;
 
 
-		this.autoUpdate = source.autoUpdate;
-		this.matrixAutoUpdate = source.matrixAutoUpdate;
+			return this;
 
 
-		return this;
+		},
 
 
-	};
+		toJSON: function ( meta ) {
 
 
-	Scene.prototype.toJSON = function ( meta ) {
+			var data = Object3D.prototype.toJSON.call( this, meta );
 
 
-		var data = Object3D.prototype.toJSON.call( this, meta );
+			if ( this.background !== null ) data.object.background = this.background.toJSON( meta );
+			if ( this.fog !== null ) data.object.fog = this.fog.toJSON();
 
 
-		if ( this.background !== null ) data.object.background = this.background.toJSON( meta );
-		if ( this.fog !== null ) data.object.fog = this.fog.toJSON();
+			return data;
 
 
-		return data;
+		}
 
 
-	};
+	} );
 
 
 	/**
 	/**
 	 * @author mikael emtinger / http://gomo.se/
 	 * @author mikael emtinger / http://gomo.se/
@@ -33579,6 +33594,10 @@
 
 
 						break;
 						break;
 
 
+					case 'SkinnedMesh':
+
+						console.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh yet.' );
+
 					case 'Mesh':
 					case 'Mesh':
 
 
 						var geometry = getGeometry( data.geometry );
 						var geometry = getGeometry( data.geometry );
@@ -33639,10 +33658,6 @@
 
 
 						break;
 						break;
 
 
-					case 'SkinnedMesh':
-
-						console.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh type. Instantiates Object3D instead.' );
-
 					default:
 					default:
 
 
 						object = new Object3D();
 						object = new Object3D();
@@ -35443,7 +35458,7 @@
 
 
 		update: ( function () {
 		update: ( function () {
 
 
-			var instance, focus, fov, aspect, near, far, zoom;
+			var instance, focus, fov, aspect, near, far, zoom, eyeSep;
 
 
 			var eyeRight = new Matrix4();
 			var eyeRight = new Matrix4();
 			var eyeLeft = new Matrix4();
 			var eyeLeft = new Matrix4();
@@ -35452,7 +35467,7 @@
 
 
 				var needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||
 				var needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||
 													aspect !== camera.aspect * this.aspect || near !== camera.near ||
 													aspect !== camera.aspect * this.aspect || near !== camera.near ||
-													far !== camera.far || zoom !== camera.zoom;
+													far !== camera.far || zoom !== camera.zoom || eyeSep !== this.eyeSep;
 
 
 				if ( needsUpdate ) {
 				if ( needsUpdate ) {
 
 
@@ -35468,7 +35483,7 @@
 					// http://paulbourke.net/stereographics/stereorender/
 					// http://paulbourke.net/stereographics/stereorender/
 
 
 					var projectionMatrix = camera.projectionMatrix.clone();
 					var projectionMatrix = camera.projectionMatrix.clone();
-					var eyeSep = this.eyeSep / 2;
+					eyeSep = this.eyeSep / 2;
 					var eyeSepOnProjection = eyeSep * near / focus;
 					var eyeSepOnProjection = eyeSep * near / focus;
 					var ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;
 					var ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;
 					var xmin, xmax;
 					var xmin, xmax;

File diff suppressed because it is too large
+ 242 - 263
build/three.min.js


+ 61 - 46
build/three.module.js

@@ -3329,14 +3329,14 @@ Object.assign( Vector3.prototype, {
 
 
 function Matrix4() {
 function Matrix4() {
 
 
-	this.elements = new Float32Array( [
+	this.elements = [
 
 
 		1, 0, 0, 0,
 		1, 0, 0, 0,
 		0, 1, 0, 0,
 		0, 1, 0, 0,
 		0, 0, 1, 0,
 		0, 0, 1, 0,
 		0, 0, 0, 1
 		0, 0, 0, 1
 
 
-	] );
+	];
 
 
 	if ( arguments.length > 0 ) {
 	if ( arguments.length > 0 ) {
 
 
@@ -3386,7 +3386,7 @@ Object.assign( Matrix4.prototype, {
 
 
 	copy: function ( m ) {
 	copy: function ( m ) {
 
 
-		this.elements.set( m.elements );
+		for ( var i = 0; i < 16; i ++ ) this.elements[ i ] = m.elements[ i ];
 
 
 		return this;
 		return this;
 
 
@@ -4097,8 +4097,7 @@ Object.assign( Matrix4.prototype, {
 			position.z = te[ 14 ];
 			position.z = te[ 14 ];
 
 
 			// scale the rotation part
 			// scale the rotation part
-
-			matrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()
+			for ( var i = 0; i < 16; i ++ ) matrix.elements[ i ] = this.elements[ i ]; // at this point matrix is incomplete so we can't use .copy()
 
 
 			var invSX = 1 / sx;
 			var invSX = 1 / sx;
 			var invSY = 1 / sy;
 			var invSY = 1 / sy;
@@ -4340,6 +4339,10 @@ function UniformContainer() {
 var arrayCacheF32 = [];
 var arrayCacheF32 = [];
 var arrayCacheI32 = [];
 var arrayCacheI32 = [];
 
 
+// Float32Array cache used for uploading Matrix4 uniform
+
+var mat4array = new Float32Array( 16 );
+
 // Flattening for arrays of vectors and matrices
 // Flattening for arrays of vectors and matrices
 
 
 function flatten( array, nBlocks, blockSize ) {
 function flatten( array, nBlocks, blockSize ) {
@@ -4450,7 +4453,16 @@ function setValue3fm( gl, v ) {
 
 
 function setValue4fm( gl, v ) {
 function setValue4fm( gl, v ) {
 
 
-	gl.uniformMatrix4fv( this.addr, false, v.elements || v );
+	if ( v.elements === undefined ) {
+
+		gl.uniformMatrix4fv( this.addr, false, v );
+
+	} else {
+
+		mat4array.set( v.elements );
+		gl.uniformMatrix4fv( this.addr, false, mat4array );
+
+	}
 
 
 }
 }
 
 
@@ -4640,7 +4652,7 @@ function StructuredUniform( id ) {
 
 
 }
 }
 
 
-StructuredUniform.prototype.setValue = function( gl, value ) {
+StructuredUniform.prototype.setValue = function ( gl, value ) {
 
 
 	// Note: Don't need an extra 'renderer' parameter, since samplers
 	// Note: Don't need an extra 'renderer' parameter, since samplers
 	// are not allowed in structured uniforms.
 	// are not allowed in structured uniforms.
@@ -4686,7 +4698,7 @@ function parseUniform( activeInfo, addr, container ) {
 	// reset RegExp object, because of the early exit of a previous run
 	// reset RegExp object, because of the early exit of a previous run
 	RePathPart.lastIndex = 0;
 	RePathPart.lastIndex = 0;
 
 
-	for (; ;) {
+	for ( ; ; ) {
 
 
 		var match = RePathPart.exec( path ),
 		var match = RePathPart.exec( path ),
 			matchEnd = RePathPart.lastIndex,
 			matchEnd = RePathPart.lastIndex,
@@ -4697,8 +4709,8 @@ function parseUniform( activeInfo, addr, container ) {
 
 
 		if ( idIsIndex ) id = id | 0; // convert to integer
 		if ( idIsIndex ) id = id | 0; // convert to integer
 
 
-		if ( subscript === undefined ||
-				subscript === '[' && matchEnd + 2 === pathLength ) {
+		if ( subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength ) {
+
 			// bare name or "pure" bottom-level array "[0]" suffix
 			// bare name or "pure" bottom-level array "[0]" suffix
 
 
 			addUniform( container, subscript === undefined ?
 			addUniform( container, subscript === undefined ?
@@ -4708,10 +4720,10 @@ function parseUniform( activeInfo, addr, container ) {
 			break;
 			break;
 
 
 		} else {
 		} else {
+
 			// step into inner node / create it in case it doesn't exist
 			// step into inner node / create it in case it doesn't exist
 
 
-			var map = container.map,
-				next = map[ id ];
+			var map = container.map, next = map[ id ];
 
 
 			if ( next === undefined ) {
 			if ( next === undefined ) {
 
 
@@ -4750,7 +4762,7 @@ function WebGLUniforms( gl, program, renderer ) {
 
 
 }
 }
 
 
-WebGLUniforms.prototype.setValue = function( gl, name, value ) {
+WebGLUniforms.prototype.setValue = function ( gl, name, value ) {
 
 
 	var u = this.map[ name ];
 	var u = this.map[ name ];
 
 
@@ -4758,7 +4770,7 @@ WebGLUniforms.prototype.setValue = function( gl, name, value ) {
 
 
 };
 };
 
 
-WebGLUniforms.prototype.set = function( gl, object, name ) {
+WebGLUniforms.prototype.set = function ( gl, object, name ) {
 
 
 	var u = this.map[ name ];
 	var u = this.map[ name ];
 
 
@@ -4766,7 +4778,7 @@ WebGLUniforms.prototype.set = function( gl, object, name ) {
 
 
 };
 };
 
 
-WebGLUniforms.prototype.setOptional = function( gl, object, name ) {
+WebGLUniforms.prototype.setOptional = function ( gl, object, name ) {
 
 
 	var v = object[ name ];
 	var v = object[ name ];
 
 
@@ -4777,7 +4789,7 @@ WebGLUniforms.prototype.setOptional = function( gl, object, name ) {
 
 
 // Static interface
 // Static interface
 
 
-WebGLUniforms.upload = function( gl, seq, values, renderer ) {
+WebGLUniforms.upload = function ( gl, seq, values, renderer ) {
 
 
 	for ( var i = 0, n = seq.length; i !== n; ++ i ) {
 	for ( var i = 0, n = seq.length; i !== n; ++ i ) {
 
 
@@ -4785,8 +4797,8 @@ WebGLUniforms.upload = function( gl, seq, values, renderer ) {
 			v = values[ u.id ];
 			v = values[ u.id ];
 
 
 		if ( v.needsUpdate !== false ) {
 		if ( v.needsUpdate !== false ) {
-			// note: always updating when .needsUpdate is undefined
 
 
+			// note: always updating when .needsUpdate is undefined
 			u.setValue( gl, v.value, renderer );
 			u.setValue( gl, v.value, renderer );
 
 
 		}
 		}
@@ -4795,7 +4807,7 @@ WebGLUniforms.upload = function( gl, seq, values, renderer ) {
 
 
 };
 };
 
 
-WebGLUniforms.seqWithValue = function( seq, values ) {
+WebGLUniforms.seqWithValue = function ( seq, values ) {
 
 
 	var r = [];
 	var r = [];
 
 
@@ -8384,7 +8396,7 @@ Object.assign( Matrix3.prototype, {
 
 
 	},
 	},
 
 
-	setFromMatrix4: function( m ) {
+	setFromMatrix4: function ( m ) {
 
 
 		var me = m.elements;
 		var me = m.elements;
 
 
@@ -8484,6 +8496,7 @@ Object.assign( Matrix3.prototype, {
 			}
 			}
 
 
 			return this.identity();
 			return this.identity();
+
 		}
 		}
 
 
 		var detInv = 1 / det;
 		var detInv = 1 / det;
@@ -8544,7 +8557,7 @@ Object.assign( Matrix3.prototype, {
 
 
 		if ( offset === undefined ) offset = 0;
 		if ( offset === undefined ) offset = 0;
 
 
-		for( var i = 0; i < 9; i ++ ) {
+		for ( var i = 0; i < 9; i ++ ) {
 
 
 			this.elements[ i ] = array[ i + offset ];
 			this.elements[ i ] = array[ i + offset ];
 
 
@@ -8571,7 +8584,7 @@ Object.assign( Matrix3.prototype, {
 
 
 		array[ offset + 6 ] = te[ 6 ];
 		array[ offset + 6 ] = te[ 6 ];
 		array[ offset + 7 ] = te[ 7 ];
 		array[ offset + 7 ] = te[ 7 ];
-		array[ offset + 8 ]  = te[ 8 ];
+		array[ offset + 8 ] = te[ 8 ];
 
 
 		return array;
 		return array;
 
 
@@ -15014,7 +15027,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 					uvB.fromBufferAttribute( uv, b );
 					uvB.fromBufferAttribute( uv, b );
 					uvC.fromBufferAttribute( uv, c );
 					uvC.fromBufferAttribute( uv, c );
 
 
-					intersection.uv = uvIntersection( intersectionPoint,  vA, vB, vC, uvA, uvB, uvC );
+					intersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );
 
 
 				}
 				}
 
 
@@ -22661,35 +22674,37 @@ function Scene () {
 
 
 }
 }
 
 
-Scene.prototype = Object.create( Object3D.prototype );
+Scene.prototype = Object.assign( Object.create( Object3D.prototype ), {
+
+	constructor: Scene,
 
 
-Scene.prototype.constructor = Scene;
+	copy: function ( source, recursive ) {
 
 
-Scene.prototype.copy = function ( source, recursive ) {
+		Object3D.prototype.copy.call( this, source, recursive );
 
 
-	Object3D.prototype.copy.call( this, source, recursive );
+		if ( source.background !== null ) this.background = source.background.clone();
+		if ( source.fog !== null ) this.fog = source.fog.clone();
+		if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();
 
 
-	if ( source.background !== null ) this.background = source.background.clone();
-	if ( source.fog !== null ) this.fog = source.fog.clone();
-	if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();
+		this.autoUpdate = source.autoUpdate;
+		this.matrixAutoUpdate = source.matrixAutoUpdate;
 
 
-	this.autoUpdate = source.autoUpdate;
-	this.matrixAutoUpdate = source.matrixAutoUpdate;
+		return this;
 
 
-	return this;
+	},
 
 
-};
+	toJSON: function ( meta ) {
 
 
-Scene.prototype.toJSON = function ( meta ) {
+		var data = Object3D.prototype.toJSON.call( this, meta );
 
 
-	var data = Object3D.prototype.toJSON.call( this, meta );
+		if ( this.background !== null ) data.object.background = this.background.toJSON( meta );
+		if ( this.fog !== null ) data.object.fog = this.fog.toJSON();
 
 
-	if ( this.background !== null ) data.object.background = this.background.toJSON( meta );
-	if ( this.fog !== null ) data.object.fog = this.fog.toJSON();
+		return data;
 
 
-	return data;
+	}
 
 
-};
+} );
 
 
 /**
 /**
  * @author mikael emtinger / http://gomo.se/
  * @author mikael emtinger / http://gomo.se/
@@ -33573,6 +33588,10 @@ Object.assign( ObjectLoader.prototype, {
 
 
 					break;
 					break;
 
 
+				case 'SkinnedMesh':
+
+					console.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh yet.' );
+
 				case 'Mesh':
 				case 'Mesh':
 
 
 					var geometry = getGeometry( data.geometry );
 					var geometry = getGeometry( data.geometry );
@@ -33633,10 +33652,6 @@ Object.assign( ObjectLoader.prototype, {
 
 
 					break;
 					break;
 
 
-				case 'SkinnedMesh':
-
-					console.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh type. Instantiates Object3D instead.' );
-
 				default:
 				default:
 
 
 					object = new Object3D();
 					object = new Object3D();
@@ -35437,7 +35452,7 @@ Object.assign( StereoCamera.prototype, {
 
 
 	update: ( function () {
 	update: ( function () {
 
 
-		var instance, focus, fov, aspect, near, far, zoom;
+		var instance, focus, fov, aspect, near, far, zoom, eyeSep;
 
 
 		var eyeRight = new Matrix4();
 		var eyeRight = new Matrix4();
 		var eyeLeft = new Matrix4();
 		var eyeLeft = new Matrix4();
@@ -35446,7 +35461,7 @@ Object.assign( StereoCamera.prototype, {
 
 
 			var needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||
 			var needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||
 												aspect !== camera.aspect * this.aspect || near !== camera.near ||
 												aspect !== camera.aspect * this.aspect || near !== camera.near ||
-												far !== camera.far || zoom !== camera.zoom;
+												far !== camera.far || zoom !== camera.zoom || eyeSep !== this.eyeSep;
 
 
 			if ( needsUpdate ) {
 			if ( needsUpdate ) {
 
 
@@ -35462,7 +35477,7 @@ Object.assign( StereoCamera.prototype, {
 				// http://paulbourke.net/stereographics/stereorender/
 				// http://paulbourke.net/stereographics/stereorender/
 
 
 				var projectionMatrix = camera.projectionMatrix.clone();
 				var projectionMatrix = camera.projectionMatrix.clone();
-				var eyeSep = this.eyeSep / 2;
+				eyeSep = this.eyeSep / 2;
 				var eyeSepOnProjection = eyeSep * near / focus;
 				var eyeSepOnProjection = eyeSep * near / focus;
 				var ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;
 				var ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;
 				var xmin, xmax;
 				var xmin, xmax;

+ 8 - 8
docs/api/core/Object3D.html

@@ -49,7 +49,7 @@
 		<div>
 		<div>
 			Used to check whether this or derived classes are Object3Ds. Default is *true*.<br /><br />
 			Used to check whether this or derived classes are Object3Ds. Default is *true*.<br /><br />
 
 
-			You should not change this, as it used internally for optimisation.
+			You should not change this, as it is used internally for optimisation.
 		</div>
 		</div>
 
 
 		<h3>[property:Layers layers]</h3>
 		<h3>[property:Layers layers]</h3>
@@ -69,7 +69,7 @@
 
 
 		<h3>[property:Matrix4 matrixWorld]</h3>
 		<h3>[property:Matrix4 matrixWorld]</h3>
 		<div>
 		<div>
-		The global transform of the object. If the Object3d has no parent, then it's identical to
+		The global transform of the object. If the Object3D has no parent, then it's identical to
 		the local transform [page:.matrix].
 		the local transform [page:.matrix].
 		</div>
 		</div>
 
 
@@ -139,7 +139,7 @@
 
 
 		<h3>[property:object userData]</h3>
 		<h3>[property:object userData]</h3>
 		<div>
 		<div>
-		An object that can be used to store custom data about the Object3d. It should not hold
+		An object that can be used to store custom data about the Object3D. It should not hold
 		references to functions as these will not be cloned.
 		references to functions as these will not be cloned.
 		</div>
 		</div>
 
 
@@ -168,12 +168,12 @@
 		<div>
 		<div>
 			The default [page:.up up] direction for objects, also used as the default position for [page:DirectionalLight],
 			The default [page:.up up] direction for objects, also used as the default position for [page:DirectionalLight],
 			[page:HemisphereLight] and [page:Spotlight] (which creates lights shining from the top down).<br />
 			[page:HemisphereLight] and [page:Spotlight] (which creates lights shining from the top down).<br />
-			Set to (0, 1, 0) by default.
+			Set to ( 0, 1, 0 ) by default.
 		</div>
 		</div>
 
 
 		<h3>[property:Vector3 DefaultMatrixAutoUpdate]</h3>
 		<h3>[property:Vector3 DefaultMatrixAutoUpdate]</h3>
 		<div>
 		<div>
-			The default setting for [page.matrixAutoUpdate matrixAutoUpdate] for newly created Object3Ds.<br />
+			The default setting for [page:.matrixAutoUpdate matrixAutoUpdate] for newly created Object3Ds.<br />
 
 
 		</div>
 		</div>
 
 
@@ -196,7 +196,7 @@
 		<div>
 		<div>
 		recursive -- if true, descendants of the object are also cloned. Default is true.<br /><br />
 		recursive -- if true, descendants of the object are also cloned. Default is true.<br /><br />
 
 
-		Returns a clone of this object and optionaly all descendants.
+		Returns a clone of this object and optionally all descendants.
 		</div>
 		</div>
 
 
 		<h3>[method:Object3D copy]( [page:Object3D object], [page:Boolean recursive] )</h3>
 		<h3>[method:Object3D copy]( [page:Object3D object], [page:Boolean recursive] )</h3>
@@ -216,7 +216,7 @@
 
 
 		<h3>[method:Object3D getObjectByName]( [page:String name] )</h3>
 		<h3>[method:Object3D getObjectByName]( [page:String name] )</h3>
 		<div>
 		<div>
-		name -- String to match to the children's Object3d.name property. <br /><br />
+		name -- String to match to the children's Object3D.name property. <br /><br />
 
 
 		Searches through the object's children and returns the first with a matching name.<br />
 		Searches through the object's children and returns the first with a matching name.<br />
 		Note that for most objects the [property:name] is an empty string by default. You will
 		Note that for most objects the [property:name] is an empty string by default. You will
@@ -228,7 +228,7 @@
 		name -- the property name to search for. <br />
 		name -- the property name to search for. <br />
 		value -- value of the given property. <br /><br />
 		value -- value of the given property. <br /><br />
 
 
-		Searches through the object's children and returns the first with a property that matches the aclue given.
+		Searches through the object's children and returns the first with a property that matches the value given.
 		</div>
 		</div>
 
 
 		<h3>[method:Vector3 getWorldPosition]( [page:Vector3 optionalTarget] )</h3>
 		<h3>[method:Vector3 getWorldPosition]( [page:Vector3 optionalTarget] )</h3>

+ 1 - 1
docs/api/deprecated/DeprecatedList.html

@@ -186,7 +186,7 @@
 
 
 		<h3>[page:Plane]</h3>
 		<h3>[page:Plane]</h3>
 		<div>
 		<div>
-			Plane.isIntersectionLine]() has been renamed to	[page:Plane.intersectsLine]().
+			Plane.isIntersectionLine() has been renamed to	[page:Plane.intersectsLine]().
 		</div>
 		</div>
 
 
 
 

+ 2 - 2
docs/api/geometries/LatheGeometry.html

@@ -12,7 +12,7 @@
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
-		<div class="desc">Class for generating meshes with axial symmetry. Possible uses include donuts, pipes, vases etc. The lathe rotate around the Y axis.</div>
+		<div class="desc">Creates meshes with axial symmetry like vases. The lathe rotates around the Y axis.</div>
 
 
 		<iframe id="scene" src="scenes/geometry-browser.html#LatheGeometry"></iframe>
 		<iframe id="scene" src="scenes/geometry-browser.html#LatheGeometry"></iframe>
 
 
@@ -55,7 +55,7 @@
 		phiLength — the radian (0 to 2PI) range of the lathed section 2PI is a closed lathe, less than 2PI is a portion. Default is 2PI.
 		phiLength — the radian (0 to 2PI) range of the lathed section 2PI is a closed lathe, less than 2PI is a portion. Default is 2PI.
 		</div>
 		</div>
 		<div>
 		<div>
-		This creates a LatheBufferGeometry based on the parameters.
+		This creates a LatheGeometry based on the parameters.
 		</div>
 		</div>
 
 
 		<h2>Source</h2>
 		<h2>Source</h2>

+ 5 - 5
docs/api/lights/DirectionalLight.html

@@ -13,7 +13,7 @@
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
 		<div class="desc">
 		<div class="desc">
-			A light that gets emitted in a specific direction. This light will behave	as though it is
+			A light that gets emitted in a specific direction. This light will behave as though it is
 			infinitely far away and the rays produced from it are all parallel. The common use case
 			infinitely far away and the rays produced from it are all parallel. The common use case
 			for this is to simulate daylight; the sun is far enough away that its position can be
 			for this is to simulate daylight; the sun is far enough away that its position can be
 			considered to be infinite, and all light rays coming from it are parallel.<br /><br />
 			considered to be infinite, and all light rays coming from it are parallel.<br /><br />
@@ -29,7 +29,7 @@
 
 
 			This means that its direction is calculated as pointing
 			This means that its direction is calculated as pointing
 			from the light's [page:Object3D.position position] to	the [page:.target target]'s position
 			from the light's [page:Object3D.position position] to	the [page:.target target]'s position
-			(as opposed to a a 'Free Direct Light' that just has a rotation component).<br /><br />
+			(as opposed to a 'Free Direct Light' that just has a rotation component).<br /><br />
 
 
 			The reason for this is to allow the light to cast shadows - the [page:.shadow shadow]
 			The reason for this is to allow the light to cast shadows - the [page:.shadow shadow]
 			camera needs a position to calculate shadows from.<br /><br />
 			camera needs a position to calculate shadows from.<br /><br />
@@ -81,9 +81,9 @@ scene.add( directionalLight );
 
 
 		<h3>[property:Boolean isDirectionalLight]</h3>
 		<h3>[property:Boolean isDirectionalLight]</h3>
 		<div>
 		<div>
-			Used to check whether this or derived classes are dircrectional lights. Default is *true*.<br /><br />
+			Used to check whether this or derived classes are directional lights. Default is *true*.<br /><br />
 
 
-			You should not change this, as it used internally for optimisation.
+			You should not change this, as it is used internally for optimisation.
 		</div>
 		</div>
 
 
 
 
@@ -102,7 +102,7 @@ scene.add( directionalLight );
 			The DirectionalLight points from its [page:.position position] to target.position. The default
 			The DirectionalLight points from its [page:.position position] to target.position. The default
 			position of the target is *(0, 0, 0)*.<br />
 			position of the target is *(0, 0, 0)*.<br />
 
 
-			*Note*: For the the target's position to be changed to anything other than the default,
+			*Note*: For the target's position to be changed to anything other than the default,
 			it must be added to the [page:Scene scene] using
 			it must be added to the [page:Scene scene] using
 			<code>
 			<code>
 				scene.add( light.target );
 				scene.add( light.target );

+ 78 - 80
docs/api/lights/Light.html

@@ -1,81 +1,79 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
+<!DOCTYPE html>
+<html lang="en">
+	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../" />
-		<script src="list.js"></script>
-		<script src="page.js"></script>
-		<link type="text/css" rel="stylesheet" href="page.css" />
-	</head>
-	<body>
-		[page:Object3D] &rarr;
-
-		<h1>[name]</h1>
-
-		<div class="desc">
-			Abstract base class for lights - all other light types inherit the properties and methods
-			described here.
-		</div>
-
-
-		<h2>Constructor</h2>
-
-
-		<h3>[name]( [page:Integer color], [page:float intensity] )</h3>
-		<div>
-		[page:Integer color] - (optional) hexadecimal color of the light. Default is 0xffffff (white).<br />
-		[page:Float intensity] - (optional) numeric value of the light's strength/intensity. Default is 1.<br /><br />
-
-		Creates a new [name]. Note that this is not intended to be called directly (use one of <thead>
-			derived classes instead).
-		</thead>)
-		</div>
-
-		<h2>Properties</h2>
-		<div>
-			See the base [page:Object3D Object3D] class for common properties.
-		</div>
-
-		<h3>[property:Color color]</h3>
-		<div>
-			Color of the light. Defaults to a new [page:Color] set to white, if not passed in the constructor.<br />
-		</div>
-
-		<h3>[property:Float intensity]</h3>
-		<div>
-			The light's intensity, or strength.<br />
-			In [page:WebGLRenderer.physicallyCorrectLights physically correct] mode, the product of
-			[page:.color color] * intensity is interpreted as luminous intensity measured in candela.<br />
-			Default - *1.0*.
-		</div>
-
-		<h3>[property:Boolean isLight]</h3>
-		<div>
-			Used to check whether this or derived classes are lights. Default is *true*.<br /><br />
-
-			You should not change this, as it used internally for optimisation.
-		</div>
-
-
-		<h2>Methods</h2>
-		<div>
-			See the base [page:Object3D Object3D] class for common methods.
-		</div>
-
-
-		<h3>[method:Light copy]( [page:Light source] )</h3>
-		<div>
-		Copies the value of [page:.color color] and [page:.intensity intensity] from the
-		[page:Light source] light into this one.
-		</div>
-
-		<h3>[method:JSON toJSON]( [page:String meta] )</h3>
-		<div>
-		Return Light data in JSON format.
-		</div>
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Object3D] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">
+			Abstract base class for lights - all other light types inherit the properties and methods
+			described here.
+		</div>
+
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]( [page:Integer color], [page:float intensity] )</h3>
+		<div>
+		[page:Integer color] - (optional) hexadecimal color of the light. Default is 0xffffff (white).<br />
+		[page:Float intensity] - (optional) numeric value of the light's strength/intensity. Default is 1.<br /><br />
+
+		Creates a new [name]. Note that this is not intended to be called directly (use one of derived classes instead).
+		</div>
+
+		<h2>Properties</h2>
+		<div>
+			See the base [page:Object3D Object3D] class for common properties.
+		</div>
+
+		<h3>[property:Color color]</h3>
+		<div>
+			Color of the light. Defaults to a new [page:Color] set to white, if not passed in the constructor.<br />
+		</div>
+
+		<h3>[property:Float intensity]</h3>
+		<div>
+			The light's intensity, or strength.<br />
+			In [page:WebGLRenderer.physicallyCorrectLights physically correct] mode, the product of
+			[page:.color color] * intensity is interpreted as luminous intensity measured in candela.<br />
+			Default - *1.0*.
+		</div>
+
+		<h3>[property:Boolean isLight]</h3>
+		<div>
+			Used to check whether this or derived classes are lights. Default is *true*.<br /><br />
+
+			You should not change this, as it used internally for optimisation.
+		</div>
+
+
+		<h2>Methods</h2>
+		<div>
+			See the base [page:Object3D Object3D] class for common methods.
+		</div>
+
+
+		<h3>[method:Light copy]( [page:Light source] )</h3>
+		<div>
+		Copies the value of [page:.color color] and [page:.intensity intensity] from the
+		[page:Light source] light into this one.
+		</div>
+
+		<h3>[method:JSON toJSON]( [page:String meta] )</h3>
+		<div>
+		Return Light data in JSON format.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 1 - 1
docs/api/lights/SpotLight.html

@@ -155,7 +155,7 @@
 			The Spotlight points from its [page:.position position] to target.position. The default
 			The Spotlight points from its [page:.position position] to target.position. The default
 			position of the target is *(0, 0, 0)*.<br />
 			position of the target is *(0, 0, 0)*.<br />
 
 
-			*Note*: For the the target's position to be changed to anything other than the default,
+			*Note*: For the target's position to be changed to anything other than the default,
 			it must be added to the [page:Scene scene] using
 			it must be added to the [page:Scene scene] using
 			<code>
 			<code>
 				scene.add( light.target );
 				scene.add( light.target );

+ 1 - 1
docs/api/lights/shadows/DirectionalLightShadow.html

@@ -13,7 +13,7 @@
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
 		<div class="desc">
 		<div class="desc">
-			This used internally by [page:DirectionalLight DirectionalLights] for calculating shadows.<br /><br />
+			This is used internally by [page:DirectionalLight DirectionalLights] for calculating shadows.<br /><br />
 
 
 			Unlike the other shadow classes, this uses an [page:OrthographicCamera] to calculate the shadows,
 			Unlike the other shadow classes, this uses an [page:OrthographicCamera] to calculate the shadows,
 			rather than a [page:PerspectiveCamera]. This is because light rays from a [page:DirectionalLight]
 			rather than a [page:PerspectiveCamera]. This is because light rays from a [page:DirectionalLight]

+ 2 - 2
docs/api/lights/shadows/LightShadow.html

@@ -12,7 +12,7 @@
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
 		<div class="desc">
 		<div class="desc">
-			This used internally by [page:PointLight PointLights] for calculating shadows, and also serves as
+			This is used internally by [page:PointLight PointLights] for calculating shadows, and also serves as
 			a base class for the other shadow classes.
 			a base class for the other shadow classes.
 		</div>
 		</div>
 
 
@@ -108,7 +108,7 @@ scene.add( helper );
 
 
 		<h3>[property:Float radius]</h3>
 		<h3>[property:Float radius]</h3>
 		<div>
 		<div>
-			Setting this this to values greater than 1 will blur the edges of the shadow.<br />
+			Setting this to values greater than 1 will blur the edges of the shadow.<br />
 
 
 			High values will cause unwanted banding effects in the shadows - a greater [page:.mapSize mapSize]
 			High values will cause unwanted banding effects in the shadows - a greater [page:.mapSize mapSize]
 			will allow for a higher value to be used here before these effects become visible.<br /><br />
 			will allow for a higher value to be used here before these effects become visible.<br /><br />

+ 1 - 1
docs/api/lights/shadows/SpotLightShadow.html

@@ -13,7 +13,7 @@
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
 		<div class="desc">
 		<div class="desc">
-			This used internally by [page:SpotLight SpotLights] for calculating shadows.
+			This is used internally by [page:SpotLight SpotLights] for calculating shadows.
 		</div>
 		</div>
 
 
 		<h2>Example</h2>
 		<h2>Example</h2>

+ 3 - 3
docs/api/objects/Mesh.html

@@ -54,7 +54,7 @@
 		<div>
 		<div>
 			Used to check whether this or derived classes are meshes. Default is *true*.<br /><br />
 			Used to check whether this or derived classes are meshes. Default is *true*.<br /><br />
 
 
-			You should not change this, as it used internally for optimisation.
+			You should not change this, as it is used internally for optimisation.
 		</div>
 		</div>
 
 
 		<h3>[property:Geometry geometry]</h3>
 		<h3>[property:Geometry geometry]</h3>
@@ -62,7 +62,7 @@
 			An instance of [page:Geometry] or [page:BufferGeometry] (or derived classes),
 			An instance of [page:Geometry] or [page:BufferGeometry] (or derived classes),
 			defining the object's structure.<br /><br />
 			defining the object's structure.<br /><br />
 
 
-			Its recommended to always use a [page:BufferGeometry] if possible for best performance.
+			It's recommended to always use a [page:BufferGeometry] if possible for best performance.
 		</div>
 		</div>
 
 
 		<h3>[property:Material material]</h3>
 		<h3>[property:Material material]</h3>
@@ -101,7 +101,7 @@
 
 
 		<h3>[method:null updateMorphTargets]()</h3>
 		<h3>[method:null updateMorphTargets]()</h3>
 		<div>
 		<div>
-		Updates the morphtargets to have no influence on the object. Resets the
+		Updates the morphTargets to have no influence on the object. Resets the
 		[page:Mesh.morphTargetInfluences morphTargetInfluences] and
 		[page:Mesh.morphTargetInfluences morphTargetInfluences] and
 		[page:Mesh.morphTargetDictionary morphTargetDictionary] properties.
 		[page:Mesh.morphTargetDictionary morphTargetDictionary] properties.
 		</div>
 		</div>

+ 1 - 1
docs/index.html

@@ -215,7 +215,7 @@
 				<span></span>
 				<span></span>
 			</a>
 			</a>
 			<div class="filterBlock" >
 			<div class="filterBlock" >
-				<input type="text" id="filterInput" placeholder="Type to filter"/>
+				<input type="text" id="filterInput" placeholder="Type to filter" autofocus/>
 				<a href="#" id="clearFilterButton" >x</a>
 				<a href="#" id="clearFilterButton" >x</a>
 			</div>
 			</div>
 			<div id="content"></div>
 			<div id="content"></div>

+ 1 - 1
editor/index.html

@@ -20,7 +20,7 @@
 		<script src="../examples/js/loaders/AWDLoader.js"></script>
 		<script src="../examples/js/loaders/AWDLoader.js"></script>
 		<script src="../examples/js/loaders/BabylonLoader.js"></script>
 		<script src="../examples/js/loaders/BabylonLoader.js"></script>
 		<script src="../examples/js/loaders/ColladaLoader2.js"></script>
 		<script src="../examples/js/loaders/ColladaLoader2.js"></script>
-		<script src="../examples/js/loaders/FBXLoader.js"></script>
+		<script src="../examples/js/loaders/FBXLoader2.js"></script>
 		<script src="../examples/js/loaders/GLTFLoader.js"></script>
 		<script src="../examples/js/loaders/GLTFLoader.js"></script>
 		<script src="../examples/js/loaders/KMZLoader.js"></script>
 		<script src="../examples/js/loaders/KMZLoader.js"></script>
 		<script src="../examples/js/loaders/MD2Loader.js"></script>
 		<script src="../examples/js/loaders/MD2Loader.js"></script>

+ 1 - 1
examples/index.html

@@ -232,7 +232,7 @@
 				<span></span>
 				<span></span>
 			</a>
 			</a>
 			<div class="filterBlock" >
 			<div class="filterBlock" >
-				<input type="text" id="filterInput" placeholder="Type to filter"/>
+				<input type="text" id="filterInput" placeholder="Type to filter" autofocus/>
 				<a href="#" id="clearFilterButton" >x</a>
 				<a href="#" id="clearFilterButton" >x</a>
 			</div>
 			</div>
 			<div id="content"></div>
 			<div id="content"></div>

+ 2 - 2
examples/js/controls/DragControls.js

@@ -52,8 +52,8 @@ THREE.DragControls = function ( _objects, _camera, _domElement ) {
 
 
 		event.preventDefault();
 		event.preventDefault();
 
 
-		_mouse.x = ( event.clientX / _domElement.width ) * 2 - 1;
-		_mouse.y = - ( event.clientY / _domElement.height ) * 2 + 1;
+		_mouse.x = ( event.clientX / _domElement.clientWidth ) * 2 - 1;
+		_mouse.y = - ( event.clientY / _domElement.clientHeight ) * 2 + 1;
 
 
 		_raycaster.setFromCamera( _mouse, _camera );
 		_raycaster.setFromCamera( _mouse, _camera );
 
 

+ 71 - 3
examples/js/loaders/FBXLoader2.js

@@ -599,6 +599,12 @@
 
 
 							}
 							}
 
 
+							if ( 'LayerElementColor' in geometryNode.subNodes ) {
+
+								var colorInfo = getColors( geometryNode );
+
+							}
+
 							if ( 'LayerElementMaterial' in geometryNode.subNodes ) {
 							if ( 'LayerElementMaterial' in geometryNode.subNodes ) {
 
 
 								var materialInfo = getMaterials( geometryNode );
 								var materialInfo = getMaterials( geometryNode );
@@ -698,6 +704,12 @@
 
 
 								}
 								}
 
 
+								if ( colorInfo ) {
+
+									vertex.color.fromArray( getData( polygonVertexIndex, polygonIndex, vertexIndex, colorInfo ) );
+
+								}
+
 								faceVertexBuffer.push( vertex );
 								faceVertexBuffer.push( vertex );
 
 
 								if ( endOfFace ) {
 								if ( endOfFace ) {
@@ -733,6 +745,11 @@
 
 
 								geo.addAttribute( 'uv', new THREE.BufferAttribute( new Float32Array( bufferInfo.uvBuffer ), 2 ) );
 								geo.addAttribute( 'uv', new THREE.BufferAttribute( new Float32Array( bufferInfo.uvBuffer ), 2 ) );
 
 
+							}
+							if ( 'LayerElementColor' in geometryNode.subNodes ) {
+
+								geo.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( bufferInfo.colorsBuffer ), 3 ) );
+
 							}
 							}
 
 
 							if ( deformer ) {
 							if ( deformer ) {
@@ -828,6 +845,35 @@
 
 
 							}
 							}
 
 
+							/**
+							 * Parses Vertex Color information for geometry.
+							 * @param {FBXGeometryNode} geometryNode
+							 * @returns {{dataSize: number, buffer: number[], indices: number[], mappingType: string, referenceType: string}}
+							 */
+							function getColors( geometryNode ) {
+
+								var ColorNode = geometryNode.subNodes.LayerElementColor[ 0 ];
+
+								var mappingType = ColorNode.properties.MappingInformationType;
+								var referenceType = ColorNode.properties.ReferenceInformationType;
+								var buffer = parseFloatArray( ColorNode.subNodes.Colors.properties.a );
+								var indexBuffer = [];
+								if ( referenceType === 'IndexToDirect' ) {
+
+									indexBuffer = parseFloatArray( ColorNode.subNodes.ColorIndex.properties.a );
+
+								}
+
+								return {
+									dataSize: 4,
+									buffer: buffer,
+									indices: indexBuffer,
+									mappingType: mappingType,
+									referenceType: referenceType
+								};
+
+							}
+
 							/**
 							/**
 							 * Parses material application information for geometry.
 							 * Parses material application information for geometry.
 							 * @param {FBXGeometryNode}
 							 * @param {FBXGeometryNode}
@@ -1165,6 +1211,11 @@
 
 
 									material = new THREE.MeshBasicMaterial( { color: 0x3300ff } );
 									material = new THREE.MeshBasicMaterial( { color: 0x3300ff } );
 
 
+								}
+								if ( 'color' in geometry.attributes ) {
+
+									material.vertexColors = THREE.VertexColors;
+
 								}
 								}
 								if ( geometry.FBX_Deformer ) {
 								if ( geometry.FBX_Deformer ) {
 
 
@@ -1399,7 +1450,7 @@
 
 
 				/**
 				/**
 				 * @type {{
 				 * @type {{
-				     curves: Map<number, {
+						 curves: Map<number, {
 						 T: {
 						 T: {
 							id: number;
 							id: number;
 							attr: string;
 							attr: string;
@@ -1519,7 +1570,7 @@
 						}
 						}
 					 }>,
 					 }>,
 					 layers: Map<number, {
 					 layers: Map<number, {
-					 	T: {
+						T: {
 							id: number;
 							id: number;
 							attr: string;
 							attr: string;
 							internalID: number;
 							internalID: number;
@@ -1943,7 +1994,7 @@
 
 
 					/**
 					/**
 					 * @type {{
 					 * @type {{
-					 	T: {
+						T: {
 							id: number;
 							id: number;
 							attr: string;
 							attr: string;
 							internalID: number;
 							internalID: number;
@@ -3084,6 +3135,12 @@
 		 */
 		 */
 		this.uv = new THREE.Vector2( );
 		this.uv = new THREE.Vector2( );
 
 
+		/**
+		 * Color of the vertex
+		 * @type {THREE.Vector3}
+		 */
+		this.color = new THREE.Vector3();
+
 		/**
 		/**
 		 * Indices of the bones vertex is influenced by.
 		 * Indices of the bones vertex is influenced by.
 		 * @type {THREE.Vector4}
 		 * @type {THREE.Vector4}
@@ -3119,6 +3176,7 @@
 			var vertexBuffer = this.position.toArray();
 			var vertexBuffer = this.position.toArray();
 			var normalBuffer = this.normal.toArray();
 			var normalBuffer = this.normal.toArray();
 			var uvBuffer = this.uv.toArray();
 			var uvBuffer = this.uv.toArray();
+			var colorBuffer = this.color.toArray();
 			var skinIndexBuffer = this.skinIndices.toArray();
 			var skinIndexBuffer = this.skinIndices.toArray();
 			var skinWeightBuffer = this.skinWeights.toArray();
 			var skinWeightBuffer = this.skinWeights.toArray();
 
 
@@ -3126,6 +3184,7 @@
 				vertexBuffer: vertexBuffer,
 				vertexBuffer: vertexBuffer,
 				normalBuffer: normalBuffer,
 				normalBuffer: normalBuffer,
 				uvBuffer: uvBuffer,
 				uvBuffer: uvBuffer,
+				colorBuffer: colorBuffer,
 				skinIndexBuffer: skinIndexBuffer,
 				skinIndexBuffer: skinIndexBuffer,
 				skinWeightBuffer: skinWeightBuffer,
 				skinWeightBuffer: skinWeightBuffer,
 			};
 			};
@@ -3167,6 +3226,7 @@
 			var vertexBuffer = [];
 			var vertexBuffer = [];
 			var normalBuffer = [];
 			var normalBuffer = [];
 			var uvBuffer = [];
 			var uvBuffer = [];
+			var colorsBuffer = [];
 			var skinIndexBuffer = [];
 			var skinIndexBuffer = [];
 			var skinWeightBuffer = [];
 			var skinWeightBuffer = [];
 
 
@@ -3178,6 +3238,7 @@
 				vertexBuffer = vertexBuffer.concat( flatVertex.vertexBuffer );
 				vertexBuffer = vertexBuffer.concat( flatVertex.vertexBuffer );
 				normalBuffer = normalBuffer.concat( flatVertex.normalBuffer );
 				normalBuffer = normalBuffer.concat( flatVertex.normalBuffer );
 				uvBuffer = uvBuffer.concat( flatVertex.uvBuffer );
 				uvBuffer = uvBuffer.concat( flatVertex.uvBuffer );
+				colorsBuffer = colorsBuffer.concat( flatVertex.colorBuffer );
 				skinIndexBuffer = skinIndexBuffer.concat( flatVertex.skinIndexBuffer );
 				skinIndexBuffer = skinIndexBuffer.concat( flatVertex.skinIndexBuffer );
 				skinWeightBuffer = skinWeightBuffer.concat( flatVertex.skinWeightBuffer );
 				skinWeightBuffer = skinWeightBuffer.concat( flatVertex.skinWeightBuffer );
 
 
@@ -3187,6 +3248,7 @@
 				vertexBuffer: vertexBuffer,
 				vertexBuffer: vertexBuffer,
 				normalBuffer: normalBuffer,
 				normalBuffer: normalBuffer,
 				uvBuffer: uvBuffer,
 				uvBuffer: uvBuffer,
+				colorsBuffer: colorsBuffer,
 				skinIndexBuffer: skinIndexBuffer,
 				skinIndexBuffer: skinIndexBuffer,
 				skinWeightBuffer: skinWeightBuffer,
 				skinWeightBuffer: skinWeightBuffer,
 			};
 			};
@@ -3245,6 +3307,7 @@
 			var vertexBuffer = [];
 			var vertexBuffer = [];
 			var normalBuffer = [];
 			var normalBuffer = [];
 			var uvBuffer = [];
 			var uvBuffer = [];
+			var colorsBuffer = [];
 			var skinIndexBuffer = [];
 			var skinIndexBuffer = [];
 			var skinWeightBuffer = [];
 			var skinWeightBuffer = [];
 
 
@@ -3259,6 +3322,7 @@
 				vertexBuffer = vertexBuffer.concat( flatTriangle.vertexBuffer );
 				vertexBuffer = vertexBuffer.concat( flatTriangle.vertexBuffer );
 				normalBuffer = normalBuffer.concat( flatTriangle.normalBuffer );
 				normalBuffer = normalBuffer.concat( flatTriangle.normalBuffer );
 				uvBuffer = uvBuffer.concat( flatTriangle.uvBuffer );
 				uvBuffer = uvBuffer.concat( flatTriangle.uvBuffer );
+				colorsBuffer = colorsBuffer.concat( flatTriangle.colorsBuffer );
 				skinIndexBuffer = skinIndexBuffer.concat( flatTriangle.skinIndexBuffer );
 				skinIndexBuffer = skinIndexBuffer.concat( flatTriangle.skinIndexBuffer );
 				skinWeightBuffer = skinWeightBuffer.concat( flatTriangle.skinWeightBuffer );
 				skinWeightBuffer = skinWeightBuffer.concat( flatTriangle.skinWeightBuffer );
 				materialIndexBuffer = materialIndexBuffer.concat( [ materialIndex, materialIndex, materialIndex ] );
 				materialIndexBuffer = materialIndexBuffer.concat( [ materialIndex, materialIndex, materialIndex ] );
@@ -3269,6 +3333,7 @@
 				vertexBuffer: vertexBuffer,
 				vertexBuffer: vertexBuffer,
 				normalBuffer: normalBuffer,
 				normalBuffer: normalBuffer,
 				uvBuffer: uvBuffer,
 				uvBuffer: uvBuffer,
+				colorsBuffer: colorsBuffer,
 				skinIndexBuffer: skinIndexBuffer,
 				skinIndexBuffer: skinIndexBuffer,
 				skinWeightBuffer: skinWeightBuffer,
 				skinWeightBuffer: skinWeightBuffer,
 				materialIndexBuffer: materialIndexBuffer
 				materialIndexBuffer: materialIndexBuffer
@@ -3305,6 +3370,7 @@
 			var vertexBuffer = [];
 			var vertexBuffer = [];
 			var normalBuffer = [];
 			var normalBuffer = [];
 			var uvBuffer = [];
 			var uvBuffer = [];
+			var colorsBuffer = [];
 			var skinIndexBuffer = [];
 			var skinIndexBuffer = [];
 			var skinWeightBuffer = [];
 			var skinWeightBuffer = [];
 
 
@@ -3317,6 +3383,7 @@
 				vertexBuffer = vertexBuffer.concat( flatFace.vertexBuffer );
 				vertexBuffer = vertexBuffer.concat( flatFace.vertexBuffer );
 				normalBuffer = normalBuffer.concat( flatFace.normalBuffer );
 				normalBuffer = normalBuffer.concat( flatFace.normalBuffer );
 				uvBuffer = uvBuffer.concat( flatFace.uvBuffer );
 				uvBuffer = uvBuffer.concat( flatFace.uvBuffer );
+				colorsBuffer = colorsBuffer.concat( flatFace.colorsBuffer );
 				skinIndexBuffer = skinIndexBuffer.concat( flatFace.skinIndexBuffer );
 				skinIndexBuffer = skinIndexBuffer.concat( flatFace.skinIndexBuffer );
 				skinWeightBuffer = skinWeightBuffer.concat( flatFace.skinWeightBuffer );
 				skinWeightBuffer = skinWeightBuffer.concat( flatFace.skinWeightBuffer );
 				materialIndexBuffer = materialIndexBuffer.concat( flatFace.materialIndexBuffer );
 				materialIndexBuffer = materialIndexBuffer.concat( flatFace.materialIndexBuffer );
@@ -3327,6 +3394,7 @@
 				vertexBuffer: vertexBuffer,
 				vertexBuffer: vertexBuffer,
 				normalBuffer: normalBuffer,
 				normalBuffer: normalBuffer,
 				uvBuffer: uvBuffer,
 				uvBuffer: uvBuffer,
+				colorsBuffer: colorsBuffer,
 				skinIndexBuffer: skinIndexBuffer,
 				skinIndexBuffer: skinIndexBuffer,
 				skinWeightBuffer: skinWeightBuffer,
 				skinWeightBuffer: skinWeightBuffer,
 				materialIndexBuffer: materialIndexBuffer
 				materialIndexBuffer: materialIndexBuffer

+ 39 - 13
examples/js/loaders/GLTFLoader.js

@@ -567,18 +567,31 @@ THREE.GLTFLoader = ( function () {
 			results = [];
 			results = [];
 
 
 			var length = object.length;
 			var length = object.length;
+
 			for ( var idx = 0; idx < length; idx ++ ) {
 			for ( var idx = 0; idx < length; idx ++ ) {
+
 				var value = callback.call( thisObj || this, object[ idx ], idx );
 				var value = callback.call( thisObj || this, object[ idx ], idx );
+
 				if ( value ) {
 				if ( value ) {
+
 					fns.push( value );
 					fns.push( value );
+
 					if ( value instanceof Promise ) {
 					if ( value instanceof Promise ) {
+
 						value.then( function( key, value ) {
 						value.then( function( key, value ) {
+
 							results[ idx ] = value;
 							results[ idx ] = value;
+
 						}.bind( this, key ));
 						}.bind( this, key ));
+
 					} else {
 					} else {
+
 						results[ idx ] = value;
 						results[ idx ] = value;
+
 					}
 					}
+
 				}
 				}
+
 			}
 			}
 
 
 		} else {
 		} else {
@@ -586,25 +599,41 @@ THREE.GLTFLoader = ( function () {
 			results = {};
 			results = {};
 
 
 			for ( var key in object ) {
 			for ( var key in object ) {
+
 				if ( object.hasOwnProperty( key ) ) {
 				if ( object.hasOwnProperty( key ) ) {
+
 					var value = callback.call( thisObj || this, object[ key ], key );
 					var value = callback.call( thisObj || this, object[ key ], key );
+
 					if ( value ) {
 					if ( value ) {
+
 						fns.push( value );
 						fns.push( value );
+
 						if ( value instanceof Promise ) {
 						if ( value instanceof Promise ) {
+
 							value.then( function( key, value ) {
 							value.then( function( key, value ) {
+
 								results[ key ] = value;
 								results[ key ] = value;
+
 							}.bind( this, key ));
 							}.bind( this, key ));
+
 						} else {
 						} else {
+
 							results[ key ] = value;
 							results[ key ] = value;
+
 						}
 						}
+
 					}
 					}
+
 				}
 				}
+
 			}
 			}
 
 
 		}
 		}
 
 
 		return Promise.all( fns ).then( function() {
 		return Promise.all( fns ).then( function() {
+
 			return results;
 			return results;
+
 		});
 		});
 
 
 	}
 	}
@@ -1142,15 +1171,20 @@ THREE.GLTFLoader = ( function () {
 
 
 				if ( khr_material ) {
 				if ( khr_material ) {
 
 
+					// don't copy over unused values to avoid material warning spam
+					var keys = [ 'ambient', 'emission', 'transparent', 'transparency', 'doubleSided' ];
+
 					switch ( khr_material.technique ) {
 					switch ( khr_material.technique ) {
 
 
 						case 'BLINN' :
 						case 'BLINN' :
 						case 'PHONG' :
 						case 'PHONG' :
 							materialType = THREE.MeshPhongMaterial;
 							materialType = THREE.MeshPhongMaterial;
+							keys.push( 'diffuse', 'specular', 'shininess' );
 							break;
 							break;
 
 
 						case 'LAMBERT' :
 						case 'LAMBERT' :
 							materialType = THREE.MeshLambertMaterial;
 							materialType = THREE.MeshLambertMaterial;
+							keys.push( 'diffuse' );
 							break;
 							break;
 
 
 						case 'CONSTANT' :
 						case 'CONSTANT' :
@@ -1160,18 +1194,11 @@ THREE.GLTFLoader = ( function () {
 
 
 					}
 					}
 
 
-					// don't copy over unused values to avoid material warning spam
-					var c = ['ambient', 'transparent', 'transparency', 'doubleSided'];
-					var allowedValues = {
-						'CONSTANT': c.concat('emission'),
-						'LAMBERT':  c.concat('emission', 'diffuse'),
-						'BLINN':    c.concat('emission', 'diffuse', 'specular', 'shininess'),
-						'PHONG':    c.concat('emission', 'diffuse', 'specular', 'shininess')
-					};
-
-					allowedValues[khr_material.technique].forEach(function(v){
-						materialValues[v] = khr_material.values[v];
-					});
+					keys.forEach( function( v ) {
+
+						if ( khr_material.values[ v ] !== undefined ) materialValues[ v ] = khr_material.values[ v ];
+
+					} );
 
 
 					if ( khr_material.doubleSided || materialValues.doubleSided ) {
 					if ( khr_material.doubleSided || materialValues.doubleSided ) {
 
 
@@ -1639,7 +1666,6 @@ THREE.GLTFLoader = ( function () {
 
 
 						var attributes = primitive.attributes;
 						var attributes = primitive.attributes;
 
 
-
 						for ( var attributeId in attributes ) {
 						for ( var attributeId in attributes ) {
 
 
 							var attributeEntry = attributes[ attributeId ];
 							var attributeEntry = attributes[ attributeId ];

+ 22 - 19
examples/webgl_simple_gi.html

@@ -48,7 +48,7 @@
 
 
 			//
 			//
 
 
-			var GI = function ( renderer, scene ) {
+			var SimpleGI = function ( renderer, scene ) {
 
 
 				var SIZE = 32, SIZE2 = SIZE * SIZE;
 				var SIZE = 32, SIZE2 = SIZE * SIZE;
 
 
@@ -66,7 +66,7 @@
 					depthBuffer: true
 					depthBuffer: true
 				} );
 				} );
 
 
-				var rotationMatrix = new THREE.Matrix4();
+				var normalMatrix = new THREE.Matrix3();
 
 
 				var position = new THREE.Vector3();
 				var position = new THREE.Vector3();
 				var normal = new THREE.Vector3();
 				var normal = new THREE.Vector3();
@@ -90,34 +90,25 @@
 
 
 					if ( attributes.color === undefined ) {
 					if ( attributes.color === undefined ) {
 
 
-						var colors = new Float32Array( positions.length )
-						geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
+						var colors = new Float32Array( positions.length );
+						geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ).setDynamic( true ) );
 
 
 					}
 					}
 
 
 					var colors = attributes.color.array;
 					var colors = attributes.color.array;
 
 
+					var startVertex = currentVertex;
 					var totalVertex = positions.length / 3;
 					var totalVertex = positions.length / 3;
 
 
 					for ( var i = 0; i < 32; i ++ ) {
 					for ( var i = 0; i < 32; i ++ ) {
 
 
-						if ( currentVertex >= totalVertex ) {
-
-							clone = scene.clone();
-							clone.autoUpdate = false;
-
-							bounces ++
-							currentVertex = 0;
-
-							break;
-
-						}
+						if ( currentVertex >= totalVertex ) break;
 
 
 						position.fromArray( positions, currentVertex * 3 );
 						position.fromArray( positions, currentVertex * 3 );
 						position.applyMatrix4( object.matrixWorld );
 						position.applyMatrix4( object.matrixWorld );
 
 
 						normal.fromArray( normals, currentVertex * 3 );
 						normal.fromArray( normals, currentVertex * 3 );
-						normal.applyMatrix4( rotationMatrix.extractRotation( object.matrixWorld ) );
+						normal.applyMatrix3( normalMatrix.getNormalMatrix( object.matrixWorld ) ).normalize();
 
 
 						camera.position.copy( position );
 						camera.position.copy( position );
 						camera.lookAt( position.add( normal ) );
 						camera.lookAt( position.add( normal ) );
@@ -142,12 +133,24 @@
 						colors[ currentVertex * 3 + 1 ] = color[ 1 ] / ( SIZE2 * 255 );
 						colors[ currentVertex * 3 + 1 ] = color[ 1 ] / ( SIZE2 * 255 );
 						colors[ currentVertex * 3 + 2 ] = color[ 2 ] / ( SIZE2 * 255 );
 						colors[ currentVertex * 3 + 2 ] = color[ 2 ] / ( SIZE2 * 255 );
 
 
-						attributes.color.needsUpdate = true;
-
 						currentVertex ++;
 						currentVertex ++;
 
 
 					}
 					}
 
 
+					attributes.color.updateRange.offset = startVertex * 3;
+					attributes.color.updateRange.count = ( currentVertex - startVertex ) * 3;
+					attributes.color.needsUpdate = true;
+
+					if ( currentVertex >= totalVertex ) {
+
+						clone = scene.clone();
+						clone.autoUpdate = false;
+
+						bounces ++
+						currentVertex = 0;
+
+					}
+
 					requestAnimationFrame( compute );
 					requestAnimationFrame( compute );
 
 
 				}
 				}
@@ -220,7 +223,7 @@
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );
 				document.body.appendChild( renderer.domElement );
 
 
-				new GI( renderer, scene );
+				new SimpleGI( renderer, scene );
 
 
 				controls = new THREE.OrbitControls( camera );
 				controls = new THREE.OrbitControls( camera );
 
 

+ 2 - 0
package.json

@@ -28,6 +28,7 @@
   },
   },
   "scripts": {
   "scripts": {
     "build": "rollup -c",
     "build": "rollup -c",
+    "build-test": "rollup -c test/rollup.unit.config.js",
     "build-uglify": "rollup -c && uglifyjs build/three.js -cm --preamble \"// threejs.org/license\" > build/three.min.js",
     "build-uglify": "rollup -c && uglifyjs build/three.js -cm --preamble \"// threejs.org/license\" > build/three.min.js",
     "build-closure": "rollup -c && java -jar utils/build/compiler/closure-compiler-v20160713.jar --warning_level=VERBOSE --jscomp_off=globalThis --jscomp_off=checkTypes --externs utils/build/externs.js --language_in=ECMASCRIPT5_STRICT --js build/three.js --js_output_file build/three.min.js",
     "build-closure": "rollup -c && java -jar utils/build/compiler/closure-compiler-v20160713.jar --warning_level=VERBOSE --jscomp_off=globalThis --jscomp_off=checkTypes --externs utils/build/externs.js --language_in=ECMASCRIPT5_STRICT --js build/three.js --js_output_file build/three.min.js",
     "dev": "rollup -c -w",
     "dev": "rollup -c -w",
@@ -49,6 +50,7 @@
   "devDependencies": {
   "devDependencies": {
     "eslint": "^3.10.1",
     "eslint": "^3.10.1",
     "eslint-config-mdcs": "^4.2.2",
     "eslint-config-mdcs": "^4.2.2",
+    "qunitjs": "^2.1.1",
     "rollup": "^0.36.3",
     "rollup": "^0.36.3",
     "rollup-watch": "^2.5.0",
     "rollup-watch": "^2.5.0",
     "uglify-js": "^2.6.0"
     "uglify-js": "^2.6.0"

+ 4 - 4
src/loaders/ObjectLoader.js

@@ -638,6 +638,10 @@ Object.assign( ObjectLoader.prototype, {
 
 
 					break;
 					break;
 
 
+				case 'SkinnedMesh':
+
+					console.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh yet.' );
+
 				case 'Mesh':
 				case 'Mesh':
 
 
 					var geometry = getGeometry( data.geometry );
 					var geometry = getGeometry( data.geometry );
@@ -698,10 +702,6 @@ Object.assign( ObjectLoader.prototype, {
 
 
 					break;
 					break;
 
 
-				case 'SkinnedMesh':
-
-					console.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh type. Instantiates Object3D instead.' );
-
 				default:
 				default:
 
 
 					object = new Object3D();
 					object = new Object3D();

+ 4 - 5
src/math/Matrix4.js

@@ -15,14 +15,14 @@ import { Vector3 } from './Vector3';
 
 
 function Matrix4() {
 function Matrix4() {
 
 
-	this.elements = new Float32Array( [
+	this.elements = [
 
 
 		1, 0, 0, 0,
 		1, 0, 0, 0,
 		0, 1, 0, 0,
 		0, 1, 0, 0,
 		0, 0, 1, 0,
 		0, 0, 1, 0,
 		0, 0, 0, 1
 		0, 0, 0, 1
 
 
-	] );
+	];
 
 
 	if ( arguments.length > 0 ) {
 	if ( arguments.length > 0 ) {
 
 
@@ -72,7 +72,7 @@ Object.assign( Matrix4.prototype, {
 
 
 	copy: function ( m ) {
 	copy: function ( m ) {
 
 
-		this.elements.set( m.elements );
+		for ( var i = 0; i < 16; i ++ ) this.elements[ i ] = m.elements[ i ];
 
 
 		return this;
 		return this;
 
 
@@ -783,8 +783,7 @@ Object.assign( Matrix4.prototype, {
 			position.z = te[ 14 ];
 			position.z = te[ 14 ];
 
 
 			// scale the rotation part
 			// scale the rotation part
-
-			matrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()
+			for ( var i = 0; i < 16; i ++ ) matrix.elements[ i ] = this.elements[ i ]; // at this point matrix is incomplete so we can't use .copy()
 
 
 			var invSX = 1 / sx;
 			var invSX = 1 / sx;
 			var invSY = 1 / sy;
 			var invSY = 1 / sy;

+ 33 - 20
src/renderers/webgl/WebGLUniforms.js

@@ -69,6 +69,10 @@ function UniformContainer() {
 var arrayCacheF32 = [];
 var arrayCacheF32 = [];
 var arrayCacheI32 = [];
 var arrayCacheI32 = [];
 
 
+// Float32Array cache used for uploading Matrix4 uniform
+
+var mat4array = new Float32Array( 16 );
+
 // Flattening for arrays of vectors and matrices
 // Flattening for arrays of vectors and matrices
 
 
 function flatten( array, nBlocks, blockSize ) {
 function flatten( array, nBlocks, blockSize ) {
@@ -133,8 +137,8 @@ function allocTexUnits( renderer, n ) {
 
 
 // Single scalar
 // Single scalar
 
 
-function setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }
-function setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }
+function setValue1f( gl, v ) { gl.uniform1f( this.addr, v ) }
+function setValue1i( gl, v ) { gl.uniform1i( this.addr, v ) }
 
 
 // Single float vector (from flat array or THREE.VectorN)
 // Single float vector (from flat array or THREE.VectorN)
 
 
@@ -179,7 +183,16 @@ function setValue3fm( gl, v ) {
 
 
 function setValue4fm( gl, v ) {
 function setValue4fm( gl, v ) {
 
 
-	gl.uniformMatrix4fv( this.addr, false, v.elements || v );
+	if ( v.elements === undefined ) {
+
+		gl.uniformMatrix4fv( this.addr, false, v );
+
+	} else {
+
+		mat4array.set( v.elements );
+		gl.uniformMatrix4fv( this.addr, false, mat4array );
+
+	}
 
 
 }
 }
 
 
@@ -203,9 +216,9 @@ function setValueT6( gl, v, renderer ) {
 
 
 // Integer / Boolean vectors or arrays thereof (always flat arrays)
 // Integer / Boolean vectors or arrays thereof (always flat arrays)
 
 
-function setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }
-function setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }
-function setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }
+function setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ) }
+function setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ) }
+function setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ) }
 
 
 // Helper to pick the right setter for the singular case
 // Helper to pick the right setter for the singular case
 
 
@@ -236,8 +249,8 @@ function getSingularSetter( type ) {
 
 
 // Array of scalars
 // Array of scalars
 
 
-function setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }
-function setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }
+function setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ) }
+function setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ) }
 
 
 // Array of vectors (flat or from THREE classes)
 // Array of vectors (flat or from THREE classes)
 
 
@@ -369,7 +382,7 @@ function StructuredUniform( id ) {
 
 
 }
 }
 
 
-StructuredUniform.prototype.setValue = function( gl, value ) {
+StructuredUniform.prototype.setValue = function ( gl, value ) {
 
 
 	// Note: Don't need an extra 'renderer' parameter, since samplers
 	// Note: Don't need an extra 'renderer' parameter, since samplers
 	// are not allowed in structured uniforms.
 	// are not allowed in structured uniforms.
@@ -415,7 +428,7 @@ function parseUniform( activeInfo, addr, container ) {
 	// reset RegExp object, because of the early exit of a previous run
 	// reset RegExp object, because of the early exit of a previous run
 	RePathPart.lastIndex = 0;
 	RePathPart.lastIndex = 0;
 
 
-	for (; ;) {
+	for ( ; ; ) {
 
 
 		var match = RePathPart.exec( path ),
 		var match = RePathPart.exec( path ),
 			matchEnd = RePathPart.lastIndex,
 			matchEnd = RePathPart.lastIndex,
@@ -426,8 +439,8 @@ function parseUniform( activeInfo, addr, container ) {
 
 
 		if ( idIsIndex ) id = id | 0; // convert to integer
 		if ( idIsIndex ) id = id | 0; // convert to integer
 
 
-		if ( subscript === undefined ||
-				subscript === '[' && matchEnd + 2 === pathLength ) {
+		if ( subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength ) {
+
 			// bare name or "pure" bottom-level array "[0]" suffix
 			// bare name or "pure" bottom-level array "[0]" suffix
 
 
 			addUniform( container, subscript === undefined ?
 			addUniform( container, subscript === undefined ?
@@ -437,10 +450,10 @@ function parseUniform( activeInfo, addr, container ) {
 			break;
 			break;
 
 
 		} else {
 		} else {
+
 			// step into inner node / create it in case it doesn't exist
 			// step into inner node / create it in case it doesn't exist
 
 
-			var map = container.map,
-				next = map[ id ];
+			var map = container.map, next = map[ id ];
 
 
 			if ( next === undefined ) {
 			if ( next === undefined ) {
 
 
@@ -479,7 +492,7 @@ function WebGLUniforms( gl, program, renderer ) {
 
 
 }
 }
 
 
-WebGLUniforms.prototype.setValue = function( gl, name, value ) {
+WebGLUniforms.prototype.setValue = function ( gl, name, value ) {
 
 
 	var u = this.map[ name ];
 	var u = this.map[ name ];
 
 
@@ -487,7 +500,7 @@ WebGLUniforms.prototype.setValue = function( gl, name, value ) {
 
 
 };
 };
 
 
-WebGLUniforms.prototype.set = function( gl, object, name ) {
+WebGLUniforms.prototype.set = function ( gl, object, name ) {
 
 
 	var u = this.map[ name ];
 	var u = this.map[ name ];
 
 
@@ -495,7 +508,7 @@ WebGLUniforms.prototype.set = function( gl, object, name ) {
 
 
 };
 };
 
 
-WebGLUniforms.prototype.setOptional = function( gl, object, name ) {
+WebGLUniforms.prototype.setOptional = function ( gl, object, name ) {
 
 
 	var v = object[ name ];
 	var v = object[ name ];
 
 
@@ -506,7 +519,7 @@ WebGLUniforms.prototype.setOptional = function( gl, object, name ) {
 
 
 // Static interface
 // Static interface
 
 
-WebGLUniforms.upload = function( gl, seq, values, renderer ) {
+WebGLUniforms.upload = function ( gl, seq, values, renderer ) {
 
 
 	for ( var i = 0, n = seq.length; i !== n; ++ i ) {
 	for ( var i = 0, n = seq.length; i !== n; ++ i ) {
 
 
@@ -514,8 +527,8 @@ WebGLUniforms.upload = function( gl, seq, values, renderer ) {
 			v = values[ u.id ];
 			v = values[ u.id ];
 
 
 		if ( v.needsUpdate !== false ) {
 		if ( v.needsUpdate !== false ) {
-			// note: always updating when .needsUpdate is undefined
 
 
+			// note: always updating when .needsUpdate is undefined
 			u.setValue( gl, v.value, renderer );
 			u.setValue( gl, v.value, renderer );
 
 
 		}
 		}
@@ -524,7 +537,7 @@ WebGLUniforms.upload = function( gl, seq, values, renderer ) {
 
 
 };
 };
 
 
-WebGLUniforms.seqWithValue = function( seq, values ) {
+WebGLUniforms.seqWithValue = function ( seq, values ) {
 
 
 	var r = [];
 	var r = [];
 
 

+ 21 - 17
src/scenes/Scene.js

@@ -18,34 +18,38 @@ function Scene () {
 
 
 }
 }
 
 
-Scene.prototype = Object.create( Object3D.prototype );
+Scene.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 
-Scene.prototype.constructor = Scene;
+	constructor: Scene,
 
 
-Scene.prototype.copy = function ( source, recursive ) {
+	copy: function ( source, recursive ) {
 
 
-	Object3D.prototype.copy.call( this, source, recursive );
+		Object3D.prototype.copy.call( this, source, recursive );
 
 
-	if ( source.background !== null ) this.background = source.background.clone();
-	if ( source.fog !== null ) this.fog = source.fog.clone();
-	if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();
+		if ( source.background !== null ) this.background = source.background.clone();
+		if ( source.fog !== null ) this.fog = source.fog.clone();
+		if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();
 
 
-	this.autoUpdate = source.autoUpdate;
-	this.matrixAutoUpdate = source.matrixAutoUpdate;
+		this.autoUpdate = source.autoUpdate;
+		this.matrixAutoUpdate = source.matrixAutoUpdate;
 
 
-	return this;
+		return this;
 
 
-};
+	},
 
 
-Scene.prototype.toJSON = function ( meta ) {
+	toJSON: function ( meta ) {
 
 
-	var data = Object3D.prototype.toJSON.call( this, meta );
+		var data = Object3D.prototype.toJSON.call( this, meta );
 
 
-	if ( this.background !== null ) data.object.background = this.background.toJSON( meta );
-	if ( this.fog !== null ) data.object.fog = this.fog.toJSON();
+		if ( this.background !== null ) data.object.background = this.background.toJSON( meta );
+		if ( this.fog !== null ) data.object.fog = this.fog.toJSON();
+
+		return data;
+
+	}
+
+} );
 
 
-	return data;
 
 
-};
 
 
 export { Scene };
 export { Scene };

+ 248 - 0
test/Three.Unit.js

@@ -0,0 +1,248 @@
+
+//src
+import '../src/polyfills.js';
+export * from '../src/constants.js';
+export * from '../src/Three.Legacy.js';
+
+//src/animation
+export { AnimationAction } from '../src/animation/AnimationAction.js';
+export { AnimationClip } from '../src/animation/AnimationClip.js';
+export { AnimationMixer } from '../src/animation/AnimationMixer.js';
+export { AnimationObjectGroup } from '../src/animation/AnimationObjectGroup.js';
+export { AnimationUtils } from '../src/animation/AnimationUtils.js';
+export { KeyframeTrack } from '../src/animation/KeyframeTrack.js';
+export { KeyframeTrackConstructor } from '../src/animation/KeyframeTrackConstructor.js';
+export { KeyframeTrackPrototype } from '../src/animation/KeyframeTrackPrototype.js';
+export { PropertyBinding } from '../src/animation/PropertyBinding.js';
+export { PropertyMixer } from '../src/animation/PropertyMixer.js';
+
+//src/animation/tracks
+export { BooleanKeyframeTrack } from '../src/animation/tracks/BooleanKeyframeTrack.js';
+export { ColorKeyframeTrack } from '../src/animation/tracks/ColorKeyframeTrack.js';
+export { NumberKeyframeTrack } from '../src/animation/tracks/NumberKeyframeTrack.js';
+export { QuaternionKeyframeTrack } from '../src/animation/tracks/QuaternionKeyframeTrack.js';
+export { StringKeyframeTrack } from '../src/animation/tracks/StringKeyframeTrack.js';
+export { VectorKeyframeTrack } from '../src/animation/tracks/VectorKeyframeTrack.js';
+
+
+//src/audio
+export { Audio } from '../src/audio/Audio.js';
+export { AudioAnalyser } from '../src/audio/AudioAnalyser.js';
+export { AudioContext } from '../src/audio/AudioContext.js';
+export { AudioListener } from '../src/audio/AudioListener.js';
+export { PositionalAudio } from '../src/audio/PositionalAudio.js';
+
+
+//src/cameras
+export { Camera } from '../src/cameras/Camera.js';
+export { CubeCamera } from '../src/cameras/CubeCamera.js';
+export { OrthographicCamera } from '../src/cameras/OrthographicCamera.js';
+export { PerspectiveCamera } from '../src/cameras/PerspectiveCamera.js';
+export { StereoCamera } from '../src/cameras/StereoCamera.js';
+
+
+//src/core
+export * from '../src/core/BufferAttribute.js';
+export { BufferGeometry } from '../src/core/BufferGeometry.js';
+export { Clock } from '../src/core/Clock.js';
+export { DirectGeometry } from '../src/core/DirectGeometry.js';
+export { EventDispatcher } from '../src/core/EventDispatcher.js';
+export { Face3 } from '../src/core/Face3.js';
+export { GeometryIdCount, Geometry } from '../src/core/Geometry.js';
+export { InstancedBufferAttribute } from '../src/core/InstancedBufferAttribute.js';
+export { InstancedBufferGeometry } from '../src/core/InstancedBufferGeometry.js';
+export { InstancedInterleavedBuffer } from '../src/core/InstancedInterleavedBuffer.js';
+export { InterleavedBuffer } from '../src/core/InterleavedBuffer.js';
+export { InterleavedBufferAttribute } from '../src/core/InterleavedBufferAttribute.js';
+export { Layers } from '../src/core/Layers.js';
+export { Object3D } from '../src/core/Object3D.js';
+export { Raycaster } from '../src/core/Raycaster.js';
+export { Uniform } from '../src/core/Uniform.js';
+
+
+//src/extras
+export { SceneUtils } from '../src/extras/SceneUtils.js';
+export { ShapeUtils } from '../src/extras/ShapeUtils.js';
+
+//src/extras/core
+export { Curve } from '../src/extras/core/Curve.js';
+export { CurvePath } from '../src/extras/core/CurvePath.js';
+export { Font } from '../src/extras/core/Font.js';
+export * from '../src/extras/core/Interpolations.js';
+export { Path } from '../src/extras/core/Path.js';
+export { PathPrototype } from '../src/extras/core/PathPrototype.js';
+export { Shape } from '../src/extras/core/Shape.js';
+export { ShapePath } from '../src/extras/core/ShapePath.js';
+
+//src/extras/curves
+export { ArcCurve } from '../src/extras/curves/ArcCurve.js';
+export { CatmullRomCurve3 } from '../src/extras/curves/CatmullRomCurve3.js';
+export { CubicBezierCurve } from '../src/extras/curves/CubicBezierCurve.js';
+export { CubicBezierCurve3 } from '../src/extras/curves/CubicBezierCurve3.js';
+export { EllipseCurve } from '../src/extras/curves/EllipseCurve.js';
+export { LineCurve } from '../src/extras/curves/LineCurve.js';
+export { LineCurve3 } from '../src/extras/curves/LineCurve3.js';
+export { QuadraticBezierCurve } from '../src/extras/curves/QuadraticBezierCurve.js';
+export { QuadraticBezierCurve3 } from '../src/extras/curves/QuadraticBezierCurve3.js';
+export { SplineCurve } from '../src/extras/curves/SplineCurve.js';
+
+//src/extras/objects
+export { ImmediateRenderObject } from '../src/extras/objects/ImmediateRenderObject.js';
+export { MorphBlendMesh } from '../src/extras/objects/MorphBlendMesh.js';
+
+
+//src/geometries
+export * from '../src/geometries/Geometries.js';
+
+
+//src/helpers
+export { ArrowHelper } from '../src/helpers/ArrowHelper.js';
+export { AxisHelper } from '../src/helpers/AxisHelper.js';
+export { BoxHelper } from '../src/helpers/BoxHelper.js';
+export { CameraHelper } from '../src/helpers/CameraHelper.js';
+export { DirectionalLightHelper } from '../src/helpers/DirectionalLightHelper.js';
+export { FaceNormalsHelper } from '../src/helpers/FaceNormalsHelper.js';
+export { GridHelper } from '../src/helpers/GridHelper.js';
+export { HemisphereLightHelper } from '../src/helpers/HemisphereLightHelper.js';
+export { PointLightHelper } from '../src/helpers/PointLightHelper.js';
+export { PolarGridHelper } from '../src/helpers/PolarGridHelper.js';
+export { RectAreaLightHelper } from '../src/helpers/RectAreaLightHelper.js';
+export { SkeletonHelper } from '../src/helpers/SkeletonHelper.js';
+export { SpotLightHelper } from '../src/helpers/SpotLightHelper.js';
+export { VertexNormalsHelper } from '../src/helpers/VertexNormalsHelper.js';
+
+
+//src/lights
+export { AmbientLight } from '../src/lights/AmbientLight.js';
+export { DirectionalLight } from '../src/lights/DirectionalLight.js';
+export { DirectionalLightShadow } from '../src/lights/DirectionalLightShadow.js';
+export { HemisphereLight } from '../src/lights/HemisphereLight.js';
+export { Light } from '../src/lights/Light.js';
+export { LightShadow } from '../src/lights/LightShadow.js';
+export { PointLight } from '../src/lights/PointLight.js';
+export { RectAreaLight } from '../src/lights/RectAreaLight.js';
+//export { RectAreaLightShadow } from '../src/lights/RectAreaLightShadow.js'; //Todo (tristan): Need to be fixed !
+export { SpotLight } from '../src/lights/SpotLight.js';
+export { SpotLightShadow } from '../src/lights/SpotLightShadow.js';
+
+
+//src/loaders
+export { AnimationLoader } from '../src/loaders/AnimationLoader.js';
+export { AudioLoader } from '../src/loaders/AudioLoader.js';
+export { BufferGeometryLoader } from '../src/loaders/BufferGeometryLoader.js';
+export { Cache } from '../src/loaders/Cache.js';
+export { CompressedTextureLoader } from '../src/loaders/CompressedTextureLoader.js';
+export { CubeTextureLoader } from '../src/loaders/CubeTextureLoader.js';
+export { DataTextureLoader } from '../src/loaders/DataTextureLoader.js';
+export { DefaultLoadingManager, LoadingManager } from '../src/loaders/LoadingManager.js';
+export { FileLoader } from '../src/loaders/FileLoader.js';
+export { FontLoader } from '../src/loaders/FontLoader.js';
+export { ImageLoader } from '../src/loaders/ImageLoader.js';
+export { JSONLoader } from '../src/loaders/JSONLoader.js';
+export { Loader } from '../src/loaders/Loader.js';
+export { MaterialLoader } from '../src/loaders/MaterialLoader.js';
+export { ObjectLoader } from '../src/loaders/ObjectLoader.js';
+export { TextureLoader } from '../src/loaders/TextureLoader.js';
+
+
+//src/materials
+export * from '../src/materials/Materials.js';
+
+
+//src/math
+export { _Math as Math } from '../src/math/Math.js';
+export { Box2 } from '../src/math/Box2.js';
+export { Box3 } from '../src/math/Box3.js';
+export { Color } from '../src/math/Color.js';
+export { Cylindrical } from '../src/math/Cylindrical.js';
+export { Euler } from '../src/math/Euler.js';
+export { Frustum } from '../src/math/Frustum.js';
+export { Interpolant } from '../src/math/Interpolant.js';
+export { Line3 } from '../src/math/Line3.js';
+export { Matrix3 } from '../src/math/Matrix3.js';
+export { Matrix4 } from '../src/math/Matrix4.js';
+export { Plane } from '../src/math/Plane.js';
+export { Quaternion } from '../src/math/Quaternion.js';
+export { Ray } from '../src/math/Ray.js';
+export { Sphere } from '../src/math/Sphere.js';
+export { Spherical } from '../src/math/Spherical.js';
+export { Triangle } from '../src/math/Triangle.js';
+export { Vector2 } from '../src/math/Vector2.js';
+export { Vector3 } from '../src/math/Vector3.js';
+export { Vector4 } from '../src/math/Vector4.js';
+
+//src/math/interpolants
+export { CubicInterpolant } from '../src/math/interpolants/CubicInterpolant.js';
+export { DiscreteInterpolant } from '../src/math/interpolants/DiscreteInterpolant.js';
+export { LinearInterpolant } from '../src/math/interpolants/LinearInterpolant.js';
+export { QuaternionLinearInterpolant } from '../src/math/interpolants/QuaternionLinearInterpolant.js';
+
+
+//src/objects
+export { Bone } from '../src/objects/Bone.js';
+export { Group } from '../src/objects/Group.js';
+export { LensFlare } from '../src/objects/LensFlare.js';
+export { Line } from '../src/objects/Line.js';
+export { LineSegments } from '../src/objects/LineSegments.js';
+export { LOD } from '../src/objects/LOD.js';
+export { Mesh } from '../src/objects/Mesh.js';
+export { Points } from '../src/objects/Points.js';
+export { Skeleton } from '../src/objects/Skeleton.js';
+export { SkinnedMesh } from '../src/objects/SkinnedMesh.js';
+export { Sprite } from '../src/objects/Sprite.js';
+
+
+//src/renderers
+export { WebGL2Renderer } from '../src/renderers/WebGL2Renderer.js';
+export { WebGLRenderer } from '../src/renderers/WebGLRenderer.js';
+export { WebGLRenderTarget } from '../src/renderers/WebGLRenderTarget.js';
+export { WebGLRenderTargetCube } from '../src/renderers/WebGLRenderTargetCube.js';
+
+//src/renderers/shaders
+export { ShaderChunk } from '../src/renderers/shaders/ShaderChunk.js';
+export { ShaderLib } from '../src/renderers/shaders/ShaderLib.js';
+export { UniformsLib } from '../src/renderers/shaders/UniformsLib.js';
+export { UniformsUtils } from '../src/renderers/shaders/UniformsUtils.js';
+
+//src/renderers/webgl
+export { WebGLBufferRenderer } from '../src/renderers/webgl/WebGLBufferRenderer.js';
+export { WebGLCapabilities } from '../src/renderers/webgl/WebGLCapabilities.js';
+export { WebGLClipping } from '../src/renderers/webgl/WebGLClipping.js';
+export { WebGLExtensions } from '../src/renderers/webgl/WebGLExtensions.js';
+export { WebGLGeometries } from '../src/renderers/webgl/WebGLGeometries.js';
+export { WebGLIndexedBufferRenderer } from '../src/renderers/webgl/WebGLIndexedBufferRenderer.js';
+export { WebGLLights } from '../src/renderers/webgl/WebGLLights.js';
+export { WebGLObjects } from '../src/renderers/webgl/WebGLObjects.js';
+export { WebGLProgram } from '../src/renderers/webgl/WebGLProgram.js';
+export { WebGLProperties } from '../src/renderers/webgl/WebGLProperties.js';
+export { WebGLShader } from '../src/renderers/webgl/WebGLShader.js';
+export { WebGLShadowMap } from '../src/renderers/webgl/WebGLShadowMap.js';
+export { WebGLState } from '../src/renderers/webgl/WebGLState.js';
+export { WebGLTextures } from '../src/renderers/webgl/WebGLTextures.js';
+export { WebGLUniforms } from '../src/renderers/webgl/WebGLUniforms.js';
+
+//src/renderers/webgl/plugins
+export { LensFlarePlugin } from '../src/renderers/webgl/plugins/LensFlarePlugin.js';
+export { SpritePlugin } from '../src/renderers/webgl/plugins/SpritePlugin.js';
+
+
+//src/scenes
+export { Fog } from '../src/scenes/Fog.js';
+export { FogExp2 } from '../src/scenes/FogExp2.js';
+export { Scene } from '../src/scenes/Scene.js';
+
+
+//src/textures
+export { CanvasTexture } from '../src/textures/CanvasTexture.js';
+export { CompressedTexture } from '../src/textures/CompressedTexture.js';
+export { CubeTexture } from '../src/textures/CubeTexture.js';
+export { DataTexture } from '../src/textures/DataTexture.js';
+export { DepthTexture } from '../src/textures/DepthTexture.js';
+export { Texture } from '../src/textures/Texture.js';
+export { VideoTexture } from '../src/textures/VideoTexture.js';
+
+
+
+
+
+

+ 40 - 0
test/rollup.unit.config.js

@@ -0,0 +1,40 @@
+function glsl() {
+
+	return {
+
+		transform( code, id ) {
+
+			if ( /\.glsl$/.test( id ) === false ) return;
+
+			var transformedCode = 'export default ' + JSON.stringify(
+				code
+					.replace( /[ \t]*\/\/.*\n/g, '' )
+					.replace( /[ \t]*\/\*[\s\S]*?\*\//g, '' )
+					.replace( /\n{2,}/g, '\n' )
+			) + ';';
+			return {
+				code: transformedCode,
+				map: { mappings: '' }
+			};
+
+		}
+
+	};
+
+}
+
+export default {
+	entry: 'test/Three.Unit.js',
+	indent: '\t',
+	plugins: [
+		glsl()
+	],
+	// sourceMap: true,
+	targets: [
+		{
+			format: 'umd',
+			moduleName: 'THREE',
+			dest: 'test/unit/three.unit.js'
+		}
+	]
+};

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

@@ -1,41 +0,0 @@
-/**
- * @author simonThiele / https://github.com/simonThiele
- */
-
-module( "OrthographicCamera" );
-
-test( "updateProjectionMatrix", function() {
-	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
-
-	ok( pMatrix[0] === 2 / ( right - left ), "m[0,0] === 2 / (r - l)" );
-	ok( pMatrix[5] === 2 / ( top - bottom ), "m[1,1] === 2 / (t - b)" );
-	ok( pMatrix[10] === -2 / ( far - near ), "m[2,2] === -2 / (f - n)" );
-	ok( pMatrix[12] === - ( ( right + left ) / ( right - left ) ), "m[3,0] === -(r+l/r-l)" );
-	ok( pMatrix[13] === - ( ( top + bottom ) / ( top - bottom ) ), "m[3,1] === -(t+b/b-t)" );
-	ok( pMatrix[14] === - ( ( far + near ) / ( far - near ) ), "m[3,2] === -(f+n/f-n)" );
-});
-
-test( "clone", function() {
-	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();
-
-	ok( cam.left === clonedCam.left , "left is equal" );
-	ok( cam.right === clonedCam.right , "right is equal" );
-	ok( cam.top === clonedCam.top , "top is equal" );
-	ok( cam.bottom === clonedCam.bottom , "bottom is equal" );
-	ok( cam.near === clonedCam.near , "near is equal" );
-	ok( cam.far === clonedCam.far , "far is equal" );
-	ok( cam.zoom === clonedCam.zoom , "zoom is equal" );
-});

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

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

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

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

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

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

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

@@ -1,53 +0,0 @@
-/**
- * @author simonThiele / https://github.com/simonThiele
- */
-
-module( "InstancedBufferGeometry" );
-
-function createClonableMock() {
-	return {
-		callCount: 0,
-
-		clone: function() {
-			this.callCount++;
-
-			return this;
-		}
-	}
-}
-
-test( "copy", function() {
-	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 );
-
-	ok( copiedInstance instanceof THREE.InstancedBufferGeometry, "the clone has the correct type" );
-
-	ok( copiedInstance.index === indexMock, "index was copied" );
-	ok( copiedInstance.index.callCount === 1, "index.clone was called once" );
-
-	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
-	ok( copiedInstance.attributes['defaultAttribute1'].array[0] === defaultAttribute1.array, "attribute was copied" );
-	ok( copiedInstance.attributes['defaultAttribute2'].array[0] === defaultAttribute2.array, "attribute was copied" );
-
-	ok( copiedInstance.groups[0].start === 0, "group was copied" );
-	ok( copiedInstance.groups[0].count === 10, "group was copied" );
-	ok( copiedInstance.groups[0].instances === instanceMock1, "group was copied" );
-
-	ok( copiedInstance.groups[1].start === 10, "group was copied" );
-	ok( copiedInstance.groups[1].count === 5, "group was copied" );
-	ok( copiedInstance.groups[1].instances === instanceMock2, "group was copied" );
-});

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

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

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

@@ -1,102 +0,0 @@
-/**
- * @author simonThiele / https://github.com/simonThiele
- */
-
-module( "Object3D" );
-
-var RadToDeg = 180 / Math.PI;
-
-test( "rotateX", function() {
-	var obj = new THREE.Object3D();
-
-	var angleInRad = 1.562;
-	obj.rotateX(angleInRad);
-
-	// should calculate the correct rotation on x
-	checkIfFloatsAreEqual(obj.rotation.x, angleInRad);
-});
-
-test( "rotateY", function() {
-	var obj = new THREE.Object3D();
-
-	var angleInRad = -0.346;
-	obj.rotateY(angleInRad);
-
-	// should calculate the correct rotation on y
-	checkIfFloatsAreEqual(obj.rotation.y, angleInRad);
-});
-
-test( "rotateZ", function() {
-	var obj = new THREE.Object3D();
-
-	var angleInRad = 1;
-	obj.rotateZ(angleInRad);
-
-	// should calculate the correct rotation on y
-	checkIfFloatsAreEqual(obj.rotation.z, angleInRad);
-});
-
-test( "translateOnAxis", function() {
-	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);
-});
-
-test( "translateX", function() {
-	var obj = new THREE.Object3D();
-	obj.translateX(1.234);
-
-	ok( obj.position.x === 1.234 , "x is equal" );
-});
-
-test( "translateY", function() {
-	var obj = new THREE.Object3D();
-	obj.translateY(1.234);
-
-	ok( obj.position.y === 1.234 , "y is equal" );
-});
-
-test( "translateZ", function() {
-	var obj = new THREE.Object3D();
-	obj.translateZ(1.234);
-
-	ok( obj.position.z === 1.234 , "z is equal" );
-});
-
-test( "lookAt", function() {
-	var obj = new THREE.Object3D();
-	obj.lookAt(new THREE.Vector3(0, -1, 1));
-
-	ok( obj.rotation.x * RadToDeg === 45 , "x is equal" );
-});
-
-test( "getWorldRotation", function() {
-	var obj = new THREE.Object3D();
-
-	obj.lookAt(new THREE.Vector3(0, -1, 1));
-	ok( obj.getWorldRotation().x * RadToDeg === 45 , "x is equal" );
-
-	obj.lookAt(new THREE.Vector3(1, 0, 0));
-	ok( obj.getWorldRotation().y * RadToDeg === 90 , "y is equal" );
-});
-
-function checkIfPropsAreEqual(reference, obj) {
-	ok( obj.x === reference.x , "x is equal" );
-	ok( obj.y === reference.y , "y is equal!" );
-	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) {
-	var f1Rounded = ((f1 * 1000) | 0) / 1000;
-	var f2Rounded = ((f2 * 1000) | 0) / 1000;
-
-	ok( f1Rounded === f2Rounded, "passed" );
-}

+ 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)
  * 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
 	// setup
 	var editor = new Editor();
 	var editor = new Editor();
@@ -23,15 +23,15 @@ test( "Test AddObjectCommand and RemoveObjectCommand (Undo and Redo)", function(
 		cmd.updatable = false;
 		cmd.updatable = false;
 
 
 		editor.execute( cmd );
 		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();
 		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();
 		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
 		// Test Remove
@@ -39,15 +39,15 @@ test( "Test AddObjectCommand and RemoveObjectCommand (Undo and Redo)", function(
 		cmd.updatable = false;
 		cmd.updatable = false;
 
 
 		editor.execute( cmd );
 		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();
 		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();
 		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)
  * 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();
 	var editor = new Editor();
 
 
@@ -24,7 +24,7 @@ test( "Test AddScriptCommand (Undo and Redo)", function() {
 		editor.execute( new AddObjectCommand( item ) );
 		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
 	// add scripts to the objects
 	for ( var i = 0; i < scripts.length; i ++ ) {
 	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 );
 	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 ++ ) {
 	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();
 	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();
 	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 ++ ) {
 	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)
  * 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();
 	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" );
 		"OK, " + MAX_OBJECTS + " objects have been added" );
 
 
 	// remove all objects
 	// 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" );
 		"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" );
 		"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)
  * 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();
 	var editor = new Editor();
 
 
@@ -19,24 +19,24 @@ test( "Test MoveObjectCommand (Undo and Redo)", function() {
 	editor.execute( new AddObjectCommand( lukeSkywalker ) );
 	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
 	// Tell Luke, Anakin is his father
 	editor.execute( new MoveObjectCommand( lukeSkywalker, anakinSkywalker ) );
 	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();
 	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();
 	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)
  * 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 editor = new Editor();
 	var box = aBox( 'Multi Command Box' );
 	var box = aBox( 'Multi Command Box' );
@@ -60,21 +60,21 @@ test( "Test MultiCmdsCommand (Undo and Redo)", function() {
 
 
 
 
 	// test one modified value for each command
 	// 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();
 	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();
 	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)
  * 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();
 	var editor = new Editor();
 
 
 	// illegal
 	// illegal
 	editor.undo();
 	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
 	// illegal
 	editor.redo();
 	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();
 	var box = aBox();
@@ -25,31 +25,31 @@ test( "Test unwanted situations ", function() {
 	cmd.updatable = false;
 	cmd.updatable = false;
 	editor.execute( cmd );
 	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
 	// illegal
 	editor.redo();
 	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();
 	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
 	// illegal
 	editor.undo();
 	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();
 	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
 	// illegal
 	editor.redo();
 	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)
  * 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();
 	var editor = new Editor();
 
 
@@ -46,17 +46,17 @@ test( "Test nested Do's, Undo's and Redo's", function() {
 
 
 	/* full check */
 	/* 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
 	editor.undo();  // rescaling undone
@@ -65,44 +65,44 @@ test( "Test nested Do's, Undo's and Redo's", function() {
 
 
 	/* full check */
 	/* 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();  // translation redone
 	editor.redo();  // rotation redone
 	editor.redo();  // rotation redone
 
 
 	editor.execute( new RemoveObjectCommand( mesh ) );
 	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
 	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!)
 	editor.undo();  // rotation undone (expected!)
 
 
 	/* full check */
 	/* 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)
  * 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();
 	var editor = new Editor();
 
 
@@ -24,7 +24,7 @@ test( "Test RemoveScriptCommand (Undo and Redo)", function() {
 		editor.execute( new AddObjectCommand( item ) );
 		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
 	// add scripts to the objects
 	for ( var i = 0; i < scripts.length; i ++ ) {
 	for ( var i = 0; i < scripts.length; i ++ ) {
@@ -42,23 +42,23 @@ test( "Test RemoveScriptCommand (Undo and Redo)", function() {
 		editor.execute( cmd );
 		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() {
 	scripts.map( function() {
 
 
 		editor.undo();
 		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 );
 	var scriptsKeys = Object.keys( editor.scripts );
 	for ( var i = 0; i < scriptsKeys.length; i ++ ) {
 	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();
 	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)
  * 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
 	// setup
 	var editor = new Editor();
 	var editor = new Editor();
@@ -321,7 +321,7 @@ test( "Test Serialization", function( assert ) {
 
 
 			var history2 = JSON.stringify( editor.history.toJSON() );
 			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();
 			editor.clear();
 
 
@@ -346,7 +346,7 @@ test( "Test Serialization", function( assert ) {
 
 
 			var history2 = JSON.stringify( editor.history.toJSON() );
 			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();
 			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)
  * 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 editor = new Editor();
 	var pointLight = aPointlight( "The light Light" );
 	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() + "')" );
 		"OK, color has been set successfully (expected: '" + colors[ colors.length - 1 ] + "', actual: '" + pointLight.color.getHex() + "')" );
 
 
 	editor.undo();
 	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() + "')" );
 		"OK, color has been set successfully after undo (expected: '" + colors[ colors.length - 2 ] + "', actual: '" + pointLight.color.getHex() + "')" );
 
 
 	editor.redo();
 	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() + "')" );
 		"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)
  * 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();
 	var editor = new Editor();
 
 
@@ -30,34 +30,34 @@ test( "Test SetGeometryCommand (Undo and Redo)", function() {
 		var actualParams = box.geometry.parameters;
 		var actualParams = box.geometry.parameters;
 		var expectedParams = geometryParams[ i ].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();
 	editor.undo();
 	var actualParams = box.geometry.parameters;
 	var actualParams = box.geometry.parameters;
 	var expectedParams = geometryParams[ 0 ].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();
 	editor.redo();
 	var actualParams = box.geometry.parameters;
 	var actualParams = box.geometry.parameters;
 	var expectedParams = geometryParams[ 1 ].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)
  * 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 editor = new Editor();
 	var box = aBox( 'The Box' );
 	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();
 	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();
 	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)
  * 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
 	// Setup scene
 	var editor = new Editor();
 	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();
 		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();
 		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)
  * 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
 	// setup
 	var editor = new Editor();
 	var editor = new Editor();
@@ -38,7 +38,7 @@ test( "Test for SetMaterialCommand (Undo and Redo)", function() {
 	var i = materialClasses.length - 1;
 	var i = materialClasses.length - 1;
 
 
 	// initial test
 	// 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 + "')" );
 		"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();
 		editor.undo();
 		-- i;
 		-- 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 + "')" );
 			"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();
 		editor.redo();
 		++ i;
 		++ 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 + "')" );
 			"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)
  * 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
 	// setup
 	var editor = new Editor();
 	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 " );
 			"OK, " + mapName + " set correctly " );
 
 
 		editor.undo();
 		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 " );
 			"OK, " + mapName + " set correctly after undo " );
 
 
 		editor.redo();
 		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" );
 			"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)
  * 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
 	// setup scene
 	var editor = new Editor();
 	var editor = new Editor();
@@ -46,15 +46,15 @@ test( "Test for SetMaterialValueCommand (Undo and Redo)", function() {
 		} );
 		} );
 
 
 		var length = testData[ attributeName ].length;
 		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 ] + "')" );
 			"OK, " + attributeName + " was set correctly to the last value (expected: '" + testData[ attributeName ][ length - 1 ] + "', actual: '" + box.material[ attributeName ] + "')" );
 
 
 		editor.undo();
 		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 ] + "')" );
 			"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();
 		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 ] + "')" );
 			"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)
  * 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 editor = new Editor();
 	var box = aBox();
 	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();
 	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();
 	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)
  * 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
 	// setup
 	var editor = new Editor();
 	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();
 	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();
 	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)
  * 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
 	// setup
 	var editor = new Editor();
 	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();
 	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();
 	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)
  * 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
 	// setup
 	var editor = new Editor();
 	var editor = new Editor();
@@ -36,13 +36,13 @@ test( "Test for SetSceneCommand (Undo and Redo)", function() {
 	} );
 	} );
 
 
 	// tests
 	// tests
-	ok( editor.scene.children.length = scenes.length,
+	assert.ok( editor.scene.children.length = scenes.length,
 		"OK, all scenes have been merged" );
 		"OK, all scenes have been merged" );
 
 
 	var i = 0;
 	var i = 0;
 	while ( i < editor.scene.children.length ) {
 	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" );
 			"OK, editor.scene.children[ " + i + " ].name matches scenes[ " + i + " ].obj.name" );
 		i ++;
 		i ++;
 
 
@@ -52,7 +52,7 @@ test( "Test for SetSceneCommand (Undo and Redo)", function() {
 	var i = 0;
 	var i = 0;
 	while ( i < editor.scene.children.length ) {
 	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" );
 			"OK, editor.scene.children[ " + i + " ].name matches scenes[ " + i + " ].obj.name after undo" );
 		i ++;
 		i ++;
 
 
@@ -63,7 +63,7 @@ test( "Test for SetSceneCommand (Undo and Redo)", function() {
 	var i = 0;
 	var i = 0;
 	while ( i < editor.scene.children.length ) {
 	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" );
 			"OK, editor.scene.children[ " + i + " ].name matches scenes[ " + i + " ].obj.name after redo" );
 		i ++;
 		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)
  * 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
 	// setup
@@ -41,15 +41,15 @@ test( "Test SetScriptValueCommand for source (Undo and Redo)", function() {
 	} );
 	} );
 
 
 	var length = testSourceData.length;
 	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' ] + "')" );
 		"OK, 'source' was set correctly to the last value (expected: '" + testSourceData[ length - 1 ].source + "', actual: '" + editor.scripts[ box.uuid ][ 0 ][ 'source' ] + "')" );
 
 
 	editor.undo();
 	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' ] + "')" );
 		"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();
 	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' ]	 + "')" );
 		"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" ];
 	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();
 	editor.undo();
 	scriptName = editor.scripts[ box.uuid ][ 0 ][ "name" ];
 	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();
 	editor.redo();
 	scriptName = editor.scripts[ box.uuid ][ 0 ][ "name" ];
 	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)
  * 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 editor = new Editor();
 	var object = aBox( 'UUID test box' );
 	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 " );
 		"OK, UUID on actual object matches last UUID in the test data array " );
 
 
 	editor.undo();
 	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)" );
 		"OK, UUID on actual object matches second to the last UUID in the test data array (after undo)" );
 
 
 	editor.redo();
 	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) " );
 		"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)
  * 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();
 	var editor = new Editor();
 
 
@@ -20,7 +20,7 @@ test( "Test SetValueCommand (Undo and Redo)", function() {
 
 
 		editor.execute( new AddObjectCommand( object ) );
 		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 ) {
 		[ '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 );
 				var cmd = new SetValueCommand( object, item, valueBefore );
 				cmd.updatable = false;
 				cmd.updatable = false;
 				editor.execute( cmd );
 				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 );
 				var cmd = new SetValueCommand( object, item, valueAfter );
 				cmd.updatable = false;
 				cmd.updatable = false;
 				editor.execute( cmd );
 				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();
 				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();
 				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 ] + "')" );
 
 
 			}
 			}
 
 

+ 0 - 87
test/unit/extras/ImageUtils.test.js

@@ -1,87 +0,0 @@
-QUnit.module( "ImageLoader", {
-
-	beforeEach: function() {
-
-		THREE.Cache.clear();
-
-	}
-
-});
-
-
-var good_url = '../../examples/textures/sprite.png';
-var bad_url = 'url_not_found';
-
-
-QUnit.test( "test load handler", function( assert ) {
-
-	var done = assert.async();
-
-  new THREE.TextureLoader().load(good_url, function ( tex ) {
-
-		assert.success( "load handler should be called" );
-		assert.ok( tex, "texture is defined" );
-		assert.ok( tex.image, "texture.image is defined" );
-		done();
-
-	}, undefined, function () {
-
-		assert.fail( "error handler should not be called" );
-		done();
-
-	});
-});
-
-
-QUnit.test( "test error handler", function( assert ) {
-
-	var done = assert.async();
-
-	new THREE.TextureLoader().load(bad_url, function () {
-
-		assert.fail( "load handler should not be called" );
-		done();
-
-	},
-
-	undefined,
-
-	function ( event ) {
-
-		assert.success( "error handler should be called" );
-		assert.ok( event.type === 'error', "should have error event" );
-
-		done();
-
-	});
-
-});
-
-
-QUnit.test( "test cached texture", function( assert ) {
-
-	var done = assert.async();
-
-	var rtex1 = new THREE.TextureLoader().load(good_url, function ( tex1 ) {
-
-		assert.ok( rtex1.image !== undefined, "texture 1 image is loaded" );
-		assert.equal( rtex1, tex1, "texture 1 callback is equal to return" );
-
-		var rtex2 = new THREE.TextureLoader().load(good_url, function ( tex2 ) {
-
-			assert.ok( rtex2 !== undefined, "cached callback is async" );
-			assert.ok( rtex2.image !== undefined, "texture 2 image is loaded" );
-			assert.equal( rtex2, tex2, "texture 2 callback is equal to return" );
-
-			done();
-
-		});
-
-		assert.ok( rtex2, "texture 2 return is defined" );
-
-	});
-
-	assert.ok( rtex1, "texture 1 return is defined" );
-	assert.ok( rtex1.image === undefined, "texture 1 image is not loaded" );
-
-});

+ 0 - 246
test/unit/math/Box2.js

@@ -1,246 +0,0 @@
-/**
- * @author bhouston / http://exocortex.com
- */
-
-module( "Box2" );
-
-test( "constructor", function() {
-	var a = new THREE.Box2();
-	ok( a.min.equals( posInf2 ), "Passed!" );
-	ok( a.max.equals( negInf2 ), "Passed!" );
-
-	a = new THREE.Box2( zero2.clone(), zero2.clone() );
-	ok( a.min.equals( zero2 ), "Passed!" );
-	ok( a.max.equals( zero2 ), "Passed!" );
-
-	a = new THREE.Box2( zero2.clone(), one2.clone() );
-	ok( a.min.equals( zero2 ), "Passed!" );
-	ok( a.max.equals( one2 ), "Passed!" );
-});
-
-test( "copy", function() {
-	var a = new THREE.Box2( zero2.clone(), one2.clone() );
-	var b = new THREE.Box2().copy( a );
-	ok( b.min.equals( zero2 ), "Passed!" );
-	ok( b.max.equals( one2 ), "Passed!" );
-
-	// ensure that it is a true copy
-	a.min = zero2;
-	a.max = one2;
-	ok( b.min.equals( zero2 ), "Passed!" );
-	ok( b.max.equals( one2 ), "Passed!" );
-});
-
-test( "set", function() {
-	var a = new THREE.Box2();
-
-	a.set( zero2, one2 );
-	ok( a.min.equals( zero2 ), "Passed!" );
-	ok( a.max.equals( one2 ), "Passed!" );
-});
-
-test( "setFromPoints", function() {
-	var a = new THREE.Box2();
-
-	a.setFromPoints( [ zero2, one2, two2 ] );
-	ok( a.min.equals( zero2 ), "Passed!" );
-	ok( a.max.equals( two2 ), "Passed!" );
-
-	a.setFromPoints( [ one2 ] );
-	ok( a.min.equals( one2 ), "Passed!" );
-	ok( a.max.equals( one2 ), "Passed!" );
-
-	a.setFromPoints( [] );
-	ok( a.isEmpty(), "Passed!" );
-});
-
-test( "empty/makeEmpty", function() {
-	var a = new THREE.Box2();
-
-	ok( a.isEmpty(), "Passed!" );
-
-	var a = new THREE.Box2( zero2.clone(), one2.clone() );
-	ok( ! a.isEmpty(), "Passed!" );
-
-	a.makeEmpty();
-	ok( a.isEmpty(), "Passed!" );
-});
-
-test( "getCenter", function() {
-	var a = new THREE.Box2( zero2.clone(), zero2.clone() );
-
-	ok( a.getCenter().equals( zero2 ), "Passed!" );
-
-	a = new THREE.Box2( zero2, one2 );
-	var midpoint = one2.clone().multiplyScalar( 0.5 );
-	ok( a.getCenter().equals( midpoint ), "Passed!" );
-});
-
-test( "getSize", function() {
-	var a = new THREE.Box2( zero2.clone(), zero2.clone() );
-
-	ok( a.getSize().equals( zero2 ), "Passed!" );
-
-	a = new THREE.Box2( zero2.clone(), one2.clone() );
-	ok( a.getSize().equals( one2 ), "Passed!" );
-});
-
-
-test( "expandByPoint", function() {
-	var a = new THREE.Box2( zero2.clone(), zero2.clone() );
-
-	a.expandByPoint( zero2 );
-	ok( a.getSize().equals( zero2 ), "Passed!" );
-
-	a.expandByPoint( one2 );
-	ok( a.getSize().equals( one2 ), "Passed!" );
-
-	a.expandByPoint( one2.clone().negate() );
-	ok( a.getSize().equals( one2.clone().multiplyScalar( 2 ) ), "Passed!" );
-	ok( a.getCenter().equals( zero2 ), "Passed!" );
-});
-
-test( "expandByVector", function() {
-	var a = new THREE.Box2( zero2.clone(), zero2.clone() );
-
-	a.expandByVector( zero2 );
-	ok( a.getSize().equals( zero2 ), "Passed!" );
-
-	a.expandByVector( one2 );
-	ok( a.getSize().equals( one2.clone().multiplyScalar( 2 ) ), "Passed!" );
-	ok( a.getCenter().equals( zero2 ), "Passed!" );
-});
-
-test( "expandByScalar", function() {
-	var a = new THREE.Box2( zero2.clone(), zero2.clone() );
-
-	a.expandByScalar( 0 );
-	ok( a.getSize().equals( zero2 ), "Passed!" );
-
-	a.expandByScalar( 1 );
-	ok( a.getSize().equals( one2.clone().multiplyScalar( 2 ) ), "Passed!" );
-	ok( a.getCenter().equals( zero2 ), "Passed!" );
-});
-
-test( "containsPoint", function() {
-	var a = new THREE.Box2( zero2.clone(), zero2.clone() );
-
-	ok( a.containsPoint( zero2 ), "Passed!" );
-	ok( ! a.containsPoint( one2 ), "Passed!" );
-
-	a.expandByScalar( 1 );
-	ok( a.containsPoint( zero2 ), "Passed!" );
-	ok( a.containsPoint( one2 ), "Passed!" );
-	ok( a.containsPoint( one2.clone().negate() ), "Passed!" );
-});
-
-test( "containsBox", function() {
-	var a = new THREE.Box2( zero2.clone(), zero2.clone() );
-	var b = new THREE.Box2( zero2.clone(), one2.clone() );
-	var c = new THREE.Box2( one2.clone().negate(), one2.clone() );
-
-	ok( a.containsBox( a ), "Passed!" );
-	ok( ! a.containsBox( b ), "Passed!" );
-	ok( ! a.containsBox( c ), "Passed!" );
-
-	ok( b.containsBox( a ), "Passed!" );
-	ok( c.containsBox( a ), "Passed!" );
-	ok( ! b.containsBox( c ), "Passed!" );
-});
-
-test( "getParameter", function() {
-	var a = new THREE.Box2( zero2.clone(), one2.clone() );
-	var b = new THREE.Box2( one2.clone().negate(), one2.clone() );
-
-	ok( a.getParameter( new THREE.Vector2( 0, 0 ) ).equals( new THREE.Vector2( 0, 0 ) ), "Passed!" );
-	ok( a.getParameter( new THREE.Vector2( 1, 1 ) ).equals( new THREE.Vector2( 1, 1 ) ), "Passed!" );
-
-	ok( b.getParameter( new THREE.Vector2( -1, -1 ) ).equals( new THREE.Vector2( 0, 0 ) ), "Passed!" );
-	ok( b.getParameter( new THREE.Vector2( 0, 0 ) ).equals( new THREE.Vector2( 0.5, 0.5 ) ), "Passed!" );
-	ok( b.getParameter( new THREE.Vector2( 1, 1 ) ).equals( new THREE.Vector2( 1, 1 ) ), "Passed!" );
-});
-
-test( "clampPoint", function() {
-	var a = new THREE.Box2( zero2.clone(), zero2.clone() );
-	var b = new THREE.Box2( one2.clone().negate(), one2.clone() );
-
-	ok( a.clampPoint( new THREE.Vector2( 0, 0 ) ).equals( new THREE.Vector2( 0, 0 ) ), "Passed!" );
-	ok( a.clampPoint( new THREE.Vector2( 1, 1 ) ).equals( new THREE.Vector2( 0, 0 ) ), "Passed!" );
-	ok( a.clampPoint( new THREE.Vector2( -1, -1 ) ).equals( new THREE.Vector2( 0, 0 ) ), "Passed!" );
-
-	ok( b.clampPoint( new THREE.Vector2( 2, 2 ) ).equals( new THREE.Vector2( 1, 1 ) ), "Passed!" );
-	ok( b.clampPoint( new THREE.Vector2( 1, 1 ) ).equals( new THREE.Vector2( 1, 1 ) ), "Passed!" );
-	ok( b.clampPoint( new THREE.Vector2( 0, 0 ) ).equals( new THREE.Vector2( 0, 0 ) ), "Passed!" );
-	ok( b.clampPoint( new THREE.Vector2( -1, -1 ) ).equals( new THREE.Vector2( -1, -1 ) ), "Passed!" );
-	ok( b.clampPoint( new THREE.Vector2( -2, -2 ) ).equals( new THREE.Vector2( -1, -1 ) ), "Passed!" );
-});
-
-test( "distanceToPoint", function() {
-	var a = new THREE.Box2( zero2.clone(), zero2.clone() );
-	var b = new THREE.Box2( one2.clone().negate(), one2.clone() );
-
-	ok( a.distanceToPoint( new THREE.Vector2( 0, 0 ) ) == 0, "Passed!" );
-	ok( a.distanceToPoint( new THREE.Vector2( 1, 1 ) ) == Math.sqrt( 2 ), "Passed!" );
-	ok( a.distanceToPoint( new THREE.Vector2( -1, -1 ) ) == Math.sqrt( 2 ), "Passed!" );
-
-	ok( b.distanceToPoint( new THREE.Vector2( 2, 2 ) ) == Math.sqrt( 2 ), "Passed!" );
-	ok( b.distanceToPoint( new THREE.Vector2( 1, 1 ) ) == 0, "Passed!" );
-	ok( b.distanceToPoint( new THREE.Vector2( 0, 0 ) ) == 0, "Passed!" );
-	ok( b.distanceToPoint( new THREE.Vector2( -1, -1 ) ) == 0, "Passed!" );
-	ok( b.distanceToPoint( new THREE.Vector2( -2, -2 ) ) == Math.sqrt( 2 ), "Passed!" );
-});
-
-test( "intersectsBox", function() {
-	var a = new THREE.Box2( zero2.clone(), zero2.clone() );
-	var b = new THREE.Box2( zero2.clone(), one2.clone() );
-	var c = new THREE.Box2( one2.clone().negate(), one2.clone() );
-
-	ok( a.intersectsBox( a ), "Passed!" );
-	ok( a.intersectsBox( b ), "Passed!" );
-	ok( a.intersectsBox( c ), "Passed!" );
-
-	ok( b.intersectsBox( a ), "Passed!" );
-	ok( c.intersectsBox( a ), "Passed!" );
-	ok( b.intersectsBox( c ), "Passed!" );
-
-	b.translate( new THREE.Vector2( 2, 2 ) );
-	ok( ! a.intersectsBox( b ), "Passed!" );
-	ok( ! b.intersectsBox( a ), "Passed!" );
-	ok( ! b.intersectsBox( c ), "Passed!" );
-});
-
-test( "intersect", function() {
-	var a = new THREE.Box2( zero2.clone(), zero2.clone() );
-	var b = new THREE.Box2( zero2.clone(), one2.clone() );
-	var c = new THREE.Box2( one2.clone().negate(), one2.clone() );
-
-	ok( a.clone().intersect( a ).equals( a ), "Passed!" );
-	ok( a.clone().intersect( b ).equals( a ), "Passed!" );
-	ok( b.clone().intersect( b ).equals( b ), "Passed!" );
-	ok( a.clone().intersect( c ).equals( a ), "Passed!" );
-	ok( b.clone().intersect( c ).equals( b ), "Passed!" );
-	ok( c.clone().intersect( c ).equals( c ), "Passed!" );
-});
-
-test( "union", function() {
-	var a = new THREE.Box2( zero2.clone(), zero2.clone() );
-	var b = new THREE.Box2( zero2.clone(), one2.clone() );
-	var c = new THREE.Box2( one2.clone().negate(), one2.clone() );
-
-	ok( a.clone().union( a ).equals( a ), "Passed!" );
-	ok( a.clone().union( b ).equals( b ), "Passed!" );
-	ok( a.clone().union( c ).equals( c ), "Passed!" );
-	ok( b.clone().union( c ).equals( c ), "Passed!" );
-});
-
-test( "translate", function() {
-	var a = new THREE.Box2( zero2.clone(), zero2.clone() );
-	var b = new THREE.Box2( zero2.clone(), one2.clone() );
-	var c = new THREE.Box2( one2.clone().negate(), one2.clone() );
-	var d = new THREE.Box2( one2.clone().negate(), zero2.clone() );
-
-	ok( a.clone().translate( one2 ).equals( new THREE.Box2( one2, one2 ) ), "Passed!" );
-	ok( a.clone().translate( one2 ).translate( one2.clone().negate() ).equals( a ), "Passed!" );
-	ok( d.clone().translate( one2 ).equals( b ), "Passed!" );
-	ok( b.clone().translate( one2.clone().negate() ).equals( d ), "Passed!" );
-});

+ 0 - 313
test/unit/math/Box3.js

@@ -1,313 +0,0 @@
-/**
- * @author bhouston / http://exocortex.com
- */
-
-module( "Box3" );
-
-test( "constructor", function() {
-	var a = new THREE.Box3();
-	ok( a.min.equals( posInf3 ), "Passed!" );
-	ok( a.max.equals( negInf3 ), "Passed!" );
-
-	a = new THREE.Box3( zero3.clone(), zero3.clone() );
-	ok( a.min.equals( zero3 ), "Passed!" );
-	ok( a.max.equals( zero3 ), "Passed!" );
-
-	a = new THREE.Box3( zero3.clone(), one3.clone() );
-	ok( a.min.equals( zero3 ), "Passed!" );
-	ok( a.max.equals( one3 ), "Passed!" );
-});
-
-test( "copy", function() {
-	var a = new THREE.Box3( zero3.clone(), one3.clone() );
-	var b = new THREE.Box3().copy( a );
-	ok( b.min.equals( zero3 ), "Passed!" );
-	ok( b.max.equals( one3 ), "Passed!" );
-
-	// ensure that it is a true copy
-	a.min = zero3;
-	a.max = one3;
-	ok( b.min.equals( zero3 ), "Passed!" );
-	ok( b.max.equals( one3 ), "Passed!" );
-});
-
-test( "set", function() {
-	var a = new THREE.Box3();
-
-	a.set( zero3, one3 );
-	ok( a.min.equals( zero3 ), "Passed!" );
-	ok( a.max.equals( one3 ), "Passed!" );
-});
-
-test( "setFromPoints", function() {
-	var a = new THREE.Box3();
-
-	a.setFromPoints( [ zero3, one3, two3 ] );
-	ok( a.min.equals( zero3 ), "Passed!" );
-	ok( a.max.equals( two3 ), "Passed!" );
-
-	a.setFromPoints( [ one3 ] );
-	ok( a.min.equals( one3 ), "Passed!" );
-	ok( a.max.equals( one3 ), "Passed!" );
-
-	a.setFromPoints( [] );
-	ok( a.isEmpty(), "Passed!" );
-});
-
-test( "empty/makeEmpty", function() {
-	var a = new THREE.Box3();
-
-	ok( a.isEmpty(), "Passed!" );
-
-	var a = new THREE.Box3( zero3.clone(), one3.clone() );
-	ok( ! a.isEmpty(), "Passed!" );
-
-	a.makeEmpty();
-	ok( a.isEmpty(), "Passed!" );
-});
-
-test( "getCenter", function() {
-	var a = new THREE.Box3( zero3.clone(), zero3.clone() );
-
-	ok( a.getCenter().equals( zero3 ), "Passed!" );
-
-	a = new THREE.Box3( zero3.clone(), one3.clone() );
-	var midpoint = one3.clone().multiplyScalar( 0.5 );
-	ok( a.getCenter().equals( midpoint ), "Passed!" );
-});
-
-test( "getSize", function() {
-	var a = new THREE.Box3( zero3.clone(), zero3.clone() );
-
-	ok( a.getSize().equals( zero3 ), "Passed!" );
-
-	a = new THREE.Box3( zero3.clone(), one3.clone() );
-	ok( a.getSize().equals( one3 ), "Passed!" );
-});
-
-
-test( "expandByPoint", function() {
-	var a = new THREE.Box3( zero3.clone(), zero3.clone() );
-
-	a.expandByPoint( zero3 );
-	ok( a.getSize().equals( zero3 ), "Passed!" );
-
-	a.expandByPoint( one3 );
-	ok( a.getSize().equals( one3 ), "Passed!" );
-
-	a.expandByPoint( one3.clone().negate() );
-	ok( a.getSize().equals( one3.clone().multiplyScalar( 2 ) ), "Passed!" );
-	ok( a.getCenter().equals( zero3 ), "Passed!" );
-});
-
-test( "expandByVector", function() {
-	var a = new THREE.Box3( zero3.clone(), zero3.clone() );
-
-	a.expandByVector( zero3 );
-	ok( a.getSize().equals( zero3 ), "Passed!" );
-
-	a.expandByVector( one3 );
-	ok( a.getSize().equals( one3.clone().multiplyScalar( 2 ) ), "Passed!" );
-	ok( a.getCenter().equals( zero3 ), "Passed!" );
-});
-
-test( "expandByScalar", function() {
-	var a = new THREE.Box3( zero3.clone(), zero3.clone() );
-
-	a.expandByScalar( 0 );
-	ok( a.getSize().equals( zero3 ), "Passed!" );
-
-	a.expandByScalar( 1 );
-	ok( a.getSize().equals( one3.clone().multiplyScalar( 2 ) ), "Passed!" );
-	ok( a.getCenter().equals( zero3 ), "Passed!" );
-});
-
-test( "containsPoint", function() {
-	var a = new THREE.Box3( zero3.clone(), zero3.clone() );
-
-	ok( a.containsPoint( zero3 ), "Passed!" );
-	ok( ! a.containsPoint( one3 ), "Passed!" );
-
-	a.expandByScalar( 1 );
-	ok( a.containsPoint( zero3 ), "Passed!" );
-	ok( a.containsPoint( one3 ), "Passed!" );
-	ok( a.containsPoint( one3.clone().negate() ), "Passed!" );
-});
-
-test( "containsBox", function() {
-	var a = new THREE.Box3( zero3.clone(), zero3.clone() );
-	var b = new THREE.Box3( zero3.clone(), one3.clone() );
-	var c = new THREE.Box3( one3.clone().negate(), one3.clone() );
-
-	ok( a.containsBox( a ), "Passed!" );
-	ok( ! a.containsBox( b ), "Passed!" );
-	ok( ! a.containsBox( c ), "Passed!" );
-
-	ok( b.containsBox( a ), "Passed!" );
-	ok( c.containsBox( a ), "Passed!" );
-	ok( ! b.containsBox( c ), "Passed!" );
-});
-
-test( "getParameter", function() {
-	var a = new THREE.Box3( zero3.clone(), one3.clone() );
-	var b = new THREE.Box3( one3.clone().negate(), one3.clone() );
-
-	ok( a.getParameter( new THREE.Vector3( 0, 0, 0 ) ).equals( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
-	ok( a.getParameter( new THREE.Vector3( 1, 1, 1 ) ).equals( new THREE.Vector3( 1, 1, 1 ) ), "Passed!" );
-
-	ok( b.getParameter( new THREE.Vector3( -1, -1, -1 ) ).equals( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
-	ok( b.getParameter( new THREE.Vector3( 0, 0, 0 ) ).equals( new THREE.Vector3( 0.5, 0.5, 0.5 ) ), "Passed!" );
-	ok( b.getParameter( new THREE.Vector3( 1, 1, 1 ) ).equals( new THREE.Vector3( 1, 1, 1 ) ), "Passed!" );
-});
-
-test( "clampPoint", function() {
-	var a = new THREE.Box3( zero3.clone(), zero3.clone() );
-	var b = new THREE.Box3( one3.clone().negate(), one3.clone() );
-
-	ok( a.clampPoint( new THREE.Vector3( 0, 0, 0 ) ).equals( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
-	ok( a.clampPoint( new THREE.Vector3( 1, 1, 1 ) ).equals( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
-	ok( a.clampPoint( new THREE.Vector3( -1, -1, -1 ) ).equals( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
-
-	ok( b.clampPoint( new THREE.Vector3( 2, 2, 2 ) ).equals( new THREE.Vector3( 1, 1, 1 ) ), "Passed!" );
-	ok( b.clampPoint( new THREE.Vector3( 1, 1, 1 ) ).equals( new THREE.Vector3( 1, 1, 1 ) ), "Passed!" );
-	ok( b.clampPoint( new THREE.Vector3( 0, 0, 0 ) ).equals( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
-	ok( b.clampPoint( new THREE.Vector3( -1, -1, -1 ) ).equals( new THREE.Vector3( -1, -1, -1 ) ), "Passed!" );
-	ok( b.clampPoint( new THREE.Vector3( -2, -2, -2 ) ).equals( new THREE.Vector3( -1, -1, -1 ) ), "Passed!" );
-});
-
-test( "distanceToPoint", function() {
-	var a = new THREE.Box3( zero3.clone(), zero3.clone() );
-	var b = new THREE.Box3( one3.clone().negate(), one3.clone() );
-
-	ok( a.distanceToPoint( new THREE.Vector3( 0, 0, 0 ) ) == 0, "Passed!" );
-	ok( a.distanceToPoint( new THREE.Vector3( 1, 1, 1 ) ) == Math.sqrt( 3 ), "Passed!" );
-	ok( a.distanceToPoint( new THREE.Vector3( -1, -1, -1 ) ) == Math.sqrt( 3 ), "Passed!" );
-
-	ok( b.distanceToPoint( new THREE.Vector3( 2, 2, 2 ) ) == Math.sqrt( 3 ), "Passed!" );
-	ok( b.distanceToPoint( new THREE.Vector3( 1, 1, 1 ) ) == 0, "Passed!" );
-	ok( b.distanceToPoint( new THREE.Vector3( 0, 0, 0 ) ) == 0, "Passed!" );
-	ok( b.distanceToPoint( new THREE.Vector3( -1, -1, -1 ) ) == 0, "Passed!" );
-	ok( b.distanceToPoint( new THREE.Vector3( -2, -2, -2 ) ) == Math.sqrt( 3 ), "Passed!" );
-});
-
-test( "distanceToPoint", function() {
-	var a = new THREE.Box3( zero3.clone(), zero3.clone() );
-	var b = new THREE.Box3( one3.clone().negate(), one3.clone() );
-
-	ok( a.distanceToPoint( new THREE.Vector3( 0, 0, 0 ) ) == 0, "Passed!" );
-	ok( a.distanceToPoint( new THREE.Vector3( 1, 1, 1 ) ) == Math.sqrt( 3 ), "Passed!" );
-	ok( a.distanceToPoint( new THREE.Vector3( -1, -1, -1 ) ) == Math.sqrt( 3 ), "Passed!" );
-
-	ok( b.distanceToPoint( new THREE.Vector3( 2, 2, 2 ) ) == Math.sqrt( 3 ), "Passed!" );
-	ok( b.distanceToPoint( new THREE.Vector3( 1, 1, 1 ) ) == 0, "Passed!" );
-	ok( b.distanceToPoint( new THREE.Vector3( 0, 0, 0 ) ) == 0, "Passed!" );
-	ok( b.distanceToPoint( new THREE.Vector3( -1, -1, -1 ) ) == 0, "Passed!" );
-	ok( b.distanceToPoint( new THREE.Vector3( -2, -2, -2 ) ) == Math.sqrt( 3 ), "Passed!" );
-});
-
-test( "intersectsBox", function() {
-	var a = new THREE.Box3( zero3.clone(), zero3.clone() );
-	var b = new THREE.Box3( zero3.clone(), one3.clone() );
-	var c = new THREE.Box3( one3.clone().negate(), one3.clone() );
-
-	ok( a.intersectsBox( a ), "Passed!" );
-	ok( a.intersectsBox( b ), "Passed!" );
-	ok( a.intersectsBox( c ), "Passed!" );
-
-	ok( b.intersectsBox( a ), "Passed!" );
-	ok( c.intersectsBox( a ), "Passed!" );
-	ok( b.intersectsBox( c ), "Passed!" );
-
-	b.translate( new THREE.Vector3( 2, 2, 2 ) );
-	ok( ! a.intersectsBox( b ), "Passed!" );
-	ok( ! b.intersectsBox( a ), "Passed!" );
-	ok( ! b.intersectsBox( c ), "Passed!" );
-});
-
-test( "intersectsSphere", function() {
-	var a = new THREE.Box3( zero3.clone(), one3.clone() );
-	var b = new THREE.Sphere( zero3.clone(), 1 );
-
-	ok( a.intersectsSphere( b ) , "Passed!" );
-
-	b.translate( new THREE.Vector3( 2, 2, 2 ) );
-	ok( ! a.intersectsSphere( b ) , "Passed!" );
-});
-
-test( "intersectsPlane", function() {
-	var a = new THREE.Box3( zero3.clone(), one3.clone() );
-	var b = new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), 1 );
-	var c = new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), 1.25 );
-	var d = new THREE.Plane( new THREE.Vector3( 0, -1, 0 ), 1.25 );
-
-	ok( a.intersectsPlane( b ) , "Passed!" );
-	ok( ! a.intersectsPlane( c ) , "Passed!" );
-	ok( ! a.intersectsPlane( d ) , "Passed!" );
-});
-
-test( "getBoundingSphere", function() {
-	var a = new THREE.Box3( zero3.clone(), zero3.clone() );
-	var b = new THREE.Box3( zero3.clone(), one3.clone() );
-	var c = new THREE.Box3( one3.clone().negate(), one3.clone() );
-
-	ok( a.getBoundingSphere().equals( new THREE.Sphere( zero3, 0 ) ), "Passed!" );
-	ok( b.getBoundingSphere().equals( new THREE.Sphere( one3.clone().multiplyScalar( 0.5 ), Math.sqrt( 3 ) * 0.5 ) ), "Passed!" );
-	ok( c.getBoundingSphere().equals( new THREE.Sphere( zero3, Math.sqrt( 12 ) * 0.5 ) ), "Passed!" );
-});
-
-test( "intersect", function() {
-	var a = new THREE.Box3( zero3.clone(), zero3.clone() );
-	var b = new THREE.Box3( zero3.clone(), one3.clone() );
-	var c = new THREE.Box3( one3.clone().negate(), one3.clone() );
-
-	ok( a.clone().intersect( a ).equals( a ), "Passed!" );
-	ok( a.clone().intersect( b ).equals( a ), "Passed!" );
-	ok( b.clone().intersect( b ).equals( b ), "Passed!" );
-	ok( a.clone().intersect( c ).equals( a ), "Passed!" );
-	ok( b.clone().intersect( c ).equals( b ), "Passed!" );
-	ok( c.clone().intersect( c ).equals( c ), "Passed!" );
-});
-
-test( "union", function() {
-	var a = new THREE.Box3( zero3.clone(), zero3.clone() );
-	var b = new THREE.Box3( zero3.clone(), one3.clone() );
-	var c = new THREE.Box3( one3.clone().negate(), one3.clone() );
-
-	ok( a.clone().union( a ).equals( a ), "Passed!" );
-	ok( a.clone().union( b ).equals( b ), "Passed!" );
-	ok( a.clone().union( c ).equals( c ), "Passed!" );
-	ok( b.clone().union( c ).equals( c ), "Passed!" );
-});
-
-var compareBox = function ( a, b, threshold ) {
-	threshold = threshold || 0.0001;
-	return ( a.min.distanceTo( b.min ) < threshold &&
-	a.max.distanceTo( b.max ) < threshold );
-};
-
-test( "applyMatrix4", function() {
-	var a = new THREE.Box3( zero3.clone(), zero3.clone() );
-	var b = new THREE.Box3( zero3.clone(), one3.clone() );
-	var c = new THREE.Box3( one3.clone().negate(), one3.clone() );
-	var d = new THREE.Box3( one3.clone().negate(), zero3.clone() );
-
-	var m = new THREE.Matrix4().makeTranslation( 1, -2, 1 );
-	var t1 = new THREE.Vector3( 1, -2, 1 );
-
-	ok( compareBox( a.clone().applyMatrix4( m ), a.clone().translate( t1 ) ), "Passed!" );
-	ok( compareBox( b.clone().applyMatrix4( m ), b.clone().translate( t1 ) ), "Passed!" );
-	ok( compareBox( c.clone().applyMatrix4( m ), c.clone().translate( t1 ) ), "Passed!" );
-	ok( compareBox( d.clone().applyMatrix4( m ), d.clone().translate( t1 ) ), "Passed!" );
-});
-
-test( "translate", function() {
-	var a = new THREE.Box3( zero3.clone(), zero3.clone() );
-	var b = new THREE.Box3( zero3.clone(), one3.clone() );
-	var c = new THREE.Box3( one3.clone().negate(), one3.clone() );
-	var d = new THREE.Box3( one3.clone().negate(), zero3.clone() );
-
-	ok( a.clone().translate( one3 ).equals( new THREE.Box3( one3, one3 ) ), "Passed!" );
-	ok( a.clone().translate( one3 ).translate( one3.clone().negate() ).equals( a ), "Passed!" );
-	ok( d.clone().translate( one3 ).equals( b ), "Passed!" );
-	ok( b.clone().translate( one3.clone().negate() ).equals( d ), "Passed!" );
-});

+ 0 - 280
test/unit/math/Color.js

@@ -1,280 +0,0 @@
-module( "Color" );
-
-test( "constructor", function(){
-    var c = new THREE.Color();
-    ok( c.r, "Red: " + c.r );
-    ok( c.g, "Green: " + c.g );
-    ok( c.b, "Blue: " + c.b );
-});
-
-test( "rgb constructor", function(){
-    var c = new THREE.Color( 1, 1, 1 );
-    ok( c.r == 1, "Passed" );
-    ok( c.g == 1, "Passed" );
-    ok( c.b == 1, "Passed" );
-});
-
-test( "copyHex", function(){
-    var c = new THREE.Color();
-    var c2 = new THREE.Color(0xF5FFFA);
-    c.copy(c2);
-    ok(c.getHex() == c2.getHex(), "Hex c: " + c.getHex() + " Hex c2: " + c2.getHex());
-});
-
-test( "copyColorString", function(){
-    var c = new THREE.Color();
-    var c2 = new THREE.Color('ivory');
-    c.copy(c2);
-    ok(c.getHex() == c2.getHex(), "Hex c: " + c.getHex() + " Hex c2: " + c2.getHex());
-});
-
-test( "setRGB", function(){
-    var c = new THREE.Color();
-    c.setRGB(1, 0.2, 0.1);
-    ok( c.r == 1, "Red: " + c.r );
-    ok( c.g == 0.2, "Green: " + c.g );
-    ok( c.b == 0.1, "Blue: " + c.b );
-});
-
-test( "copyGammaToLinear", function(){
-    var c = new THREE.Color();
-    var c2 = new THREE.Color();
-    c2.setRGB(0.3, 0.5, 0.9);
-    c.copyGammaToLinear(c2);
-    ok( c.r == 0.09, "Red c: " + c.r + " Red c2: " + c2.r);
-    ok( c.g == 0.25, "Green c: " + c.g + " Green c2: " + c2.g);
-    ok( c.b == 0.81, "Blue c: " + c.b + " Blue c2: " + c2.b);
-});
-
-test( "copyLinearToGamma", function(){
-    var c = new THREE.Color();
-    var c2 = new THREE.Color();
-    c2.setRGB(0.09, 0.25, 0.81);
-    c.copyLinearToGamma(c2);
-    ok( c.r == 0.3, "Red c: " + c.r + " Red c2: " + c2.r);
-    ok( c.g == 0.5, "Green c: " + c.g + " Green c2: " + c2.g);
-    ok( c.b == 0.9, "Blue c: " + c.b + " Blue c2: " + c2.b);
-});
-
-
-test( "convertGammaToLinear", function(){
-    var c = new THREE.Color();
-    c.setRGB(0.3, 0.5, 0.9);
-    c.convertGammaToLinear();
-    ok( c.r == 0.09, "Red: " + c.r );
-    ok( c.g == 0.25, "Green: " + c.g );
-    ok( c.b == 0.81, "Blue: " + c.b );
-});
-
-
-test( "convertLinearToGamma", function(){
-    var c = new THREE.Color();
-    c.setRGB(4, 9, 16);
-    c.convertLinearToGamma();
-    ok( c.r == 2, "Red: " + c.r );
-    ok( c.g == 3, "Green: " + c.g );
-    ok( c.b == 4, "Blue: " + c.b );
-});
-
-test("setWithNum", function(){
-    var c = new THREE.Color();
-    c.set(0xFF0000);
-    ok( c.r == 1, "Red: " + c.r );
-    ok( c.g === 0, "Green: " + c.g );
-    ok( c.b === 0, "Blue: " + c.b );
-});
-
-
-test( "setWithString", function(){
-    var c = new THREE.Color();
-    c.set('silver');
-    ok(c.getHex() == 0xC0C0C0, "Hex c: " + c.getHex());
-});
-
-
-test( "clone", function(){
-    var c = new THREE.Color('teal');
-    var c2 = c.clone();
-    ok(c2.getHex() == 0x008080, "Hex c2: " + c2.getHex());
-});
-
-test( "lerp", function(){
-    var c = new THREE.Color();
-    var c2 = new THREE.Color();
-    c.setRGB(0, 0, 0);
-    c.lerp(c2, 0.2);
-    ok( c.r == 0.2, "Red: " + c.r );
-    ok( c.g == 0.2, "Green: " + c.g );
-    ok( c.b == 0.2, "Blue: " + c.b );
-    
-});
-
-
-test( "setStyleRGBRed", function(){
-    var c = new THREE.Color();
-    c.setStyle('rgb(255,0,0)');
-    ok( c.r == 1, "Red: " + c.r );
-    ok( c.g === 0, "Green: " + c.g );
-    ok( c.b === 0, "Blue: " + c.b );
-});
-
-test( "setStyleRGBARed", function(){
-    var c = new THREE.Color();
-    c.setStyle('rgba(255,0,0,0.5)');
-    ok( c.r == 1, "Red: " + c.r );
-    ok( c.g === 0, "Green: " + c.g );
-    ok( c.b === 0, "Blue: " + c.b );
-});
-
-test( "setStyleRGBRedWithSpaces", function(){
-    var c = new THREE.Color();
-    c.setStyle('rgb( 255 , 0,   0 )');
-    ok( c.r == 1, "Red: " + c.r );
-    ok( c.g === 0, "Green: " + c.g );
-    ok( c.b === 0, "Blue: " + c.b );
-});
-
-test( "setStyleRGBARedWithSpaces", function(){
-    var c = new THREE.Color();
-    c.setStyle('rgba( 255,  0,  0  , 1 )');
-    ok( c.r == 1, "Red: " + c.r );
-    ok( c.g === 0, "Green: " + c.g );
-    ok( c.b === 0, "Blue: " + c.b );
-});
-
-test( "setStyleRGBPercent", function(){
-    var c = new THREE.Color();
-    c.setStyle('rgb(100%,50%,10%)');
-    ok( c.r == 1, "Red: " + c.r );
-    ok( c.g == 0.5, "Green: " + c.g );
-    ok( c.b == 0.1, "Blue: " + c.b );
-});
-
-test( "setStyleRGBAPercent", function(){
-    var c = new THREE.Color();
-    c.setStyle('rgba(100%,50%,10%, 0.5)');
-    ok( c.r == 1, "Red: " + c.r );
-    ok( c.g == 0.5, "Green: " + c.g );
-    ok( c.b == 0.1, "Blue: " + c.b );
-});
-
-test( "setStyleRGBPercentWithSpaces", function(){
-    var c = new THREE.Color();
-    c.setStyle('rgb( 100% ,50%  , 10% )');
-    ok( c.r == 1, "Red: " + c.r );
-    ok( c.g == 0.5, "Green: " + c.g );
-    ok( c.b == 0.1, "Blue: " + c.b );
-});
-
-test( "setStyleRGBAPercentWithSpaces", function(){
-    var c = new THREE.Color();
-    c.setStyle('rgba( 100% ,50%  ,  10%, 0.5 )');
-    ok( c.r == 1, "Red: " + c.r );
-    ok( c.g == 0.5, "Green: " + c.g );
-    ok( c.b == 0.1, "Blue: " + c.b );
-});
-
-test( "setStyleHSLRed", function(){
-    var c = new THREE.Color();
-    c.setStyle('hsl(360,100%,50%)');
-    ok( c.r == 1, "Red: " + c.r );
-    ok( c.g === 0, "Green: " + c.g );
-    ok( c.b === 0, "Blue: " + c.b );
-});
-
-test( "setStyleHSLARed", function(){
-    var c = new THREE.Color();
-    c.setStyle('hsla(360,100%,50%,0.5)');
-    ok( c.r == 1, "Red: " + c.r );
-    ok( c.g === 0, "Green: " + c.g );
-    ok( c.b === 0, "Blue: " + c.b );
-});
-
-test( "setStyleHSLRedWithSpaces", function(){
-    var c = new THREE.Color();
-    c.setStyle('hsl(360,  100% , 50% )');
-    ok( c.r == 1, "Red: " + c.r );
-    ok( c.g === 0, "Green: " + c.g );
-    ok( c.b === 0, "Blue: " + c.b );
-});
-
-test( "setStyleHSLARedWithSpaces", function(){
-    var c = new THREE.Color();
-    c.setStyle('hsla( 360,  100% , 50%,  0.5 )');
-    ok( c.r == 1, "Red: " + c.r );
-    ok( c.g === 0, "Green: " + c.g );
-    ok( c.b === 0, "Blue: " + c.b );
-});
-
-test( "setStyleHexSkyBlue", function(){
-    var c = new THREE.Color();
-    c.setStyle('#87CEEB');
-    ok(c.getHex() == 0x87CEEB, "Hex c: " + c.getHex());
-});
-
-test( "setStyleHexSkyBlueMixed", function(){
-    var c = new THREE.Color();
-    c.setStyle('#87cEeB');
-    ok(c.getHex() == 0x87CEEB, "Hex c: " + c.getHex());
-});
-
-test( "setStyleHex2Olive", function(){
-    var c = new THREE.Color();
-    c.setStyle('#F00');
-    ok(c.getHex() == 0xFF0000, "Hex c: " + c.getHex());
-});
-
-test( "setStyleHex2OliveMixed", function(){
-    var c = new THREE.Color();
-    c.setStyle('#f00');
-    ok(c.getHex() == 0xFF0000, "Hex c: " + c.getHex());
-});
-
-test( "setStyleColorName", function(){
-    var c = new THREE.Color();
-    c.setStyle('powderblue');
-    ok(c.getHex() == 0xB0E0E6, "Hex c: " + c.getHex());
-});
-
-test( "getHex", function(){
-    var c = new THREE.Color('red');
-    var res = c.getHex();
-    ok( res == 0xFF0000, "Hex: " + res );
-});
-
-test( "setHex", function(){
-    var c = new THREE.Color();
-    c.setHex(0xFA8072);
-    ok( c.getHex() == 0xFA8072, "Hex: " + c.getHex());
-});
-
-test( "getHexString", function(){
-    var c = new THREE.Color('tomato');
-    var res = c.getHexString();
-    ok( res == 'ff6347', "Hex: " + res );
-});
-
-test( "getStyle", function(){
-    var c = new THREE.Color('plum');
-    var res = c.getStyle();
-    ok( res == 'rgb(221,160,221)', "style: " + res );
-});
-
-test( "getHSL", function () {
-    var c = new THREE.Color( 0x80ffff );
-    var hsl = c.getHSL();
-
-    ok( hsl.h == 0.5, "hue: " + hsl.h );
-    ok( hsl.s == 1.0, "saturation: " + hsl.s );
-    ok( (Math.round(parseFloat(hsl.l)*100)/100) == 0.75, "lightness: " + hsl.l );
-});
-
-test( "setHSL", function () {
-    var c = new THREE.Color();
-    c.setHSL(0.75, 1.0, 0.25);
-    var hsl = c.getHSL();
-
-    ok( hsl.h == 0.75, "hue: " + hsl.h );
-    ok( hsl.s == 1.00, "saturation: " + hsl.s );
-    ok( hsl.l == 0.25, "lightness: " + hsl.l );
-});

+ 0 - 156
test/unit/math/Frustum.js

@@ -1,156 +0,0 @@
-/**
- * @author bhouston / http://exocortex.com
- */
-
-module( "Frustum" );
-
-var unit3 = new THREE.Vector3( 1, 0, 0 );
-
-var planeEquals = function ( a, b, tolerance ) {
-
-	tolerance = tolerance || 0.0001;
-
-	if ( a.normal.distanceTo( b.normal ) > tolerance ) return false;
-	if ( Math.abs( a.constant - b.constant ) > tolerance ) return false;
-
-	return true;
-
-};
-
-test( "constructor", function() {
-	var a = new THREE.Frustum();
-
-	ok( a.planes !== undefined, "Passed!" );
-	ok( a.planes.length === 6, "Passed!" );
-
-	var pDefault = new THREE.Plane();
-	for( var i = 0; i < 6; i ++ ) {
-		ok( a.planes[i].equals( pDefault ), "Passed!" );
-	}
-
-	var p0 = new THREE.Plane( unit3, -1 );
-	var p1 = new THREE.Plane( unit3, 1 );
-	var p2 = new THREE.Plane( unit3, 2 );
-	var p3 = new THREE.Plane( unit3, 3 );
-	var p4 = new THREE.Plane( unit3, 4 );
-	var p5 = new THREE.Plane( unit3, 5 );
-
-	a = new THREE.Frustum( p0, p1, p2, p3, p4, p5 );
-	ok( a.planes[0].equals( p0 ), "Passed!" );
-	ok( a.planes[1].equals( p1 ), "Passed!" );
-	ok( a.planes[2].equals( p2 ), "Passed!" );
-	ok( a.planes[3].equals( p3 ), "Passed!" );
-	ok( a.planes[4].equals( p4 ), "Passed!" );
-	ok( a.planes[5].equals( p5 ), "Passed!" );
-});
-
-test( "copy", function() {
-
-	var p0 = new THREE.Plane( unit3, -1 );
-	var p1 = new THREE.Plane( unit3, 1 );
-	var p2 = new THREE.Plane( unit3, 2 );
-	var p3 = new THREE.Plane( unit3, 3 );
-	var p4 = new THREE.Plane( unit3, 4 );
-	var p5 = new THREE.Plane( unit3, 5 );
-
-	var b = new THREE.Frustum( p0, p1, p2, p3, p4, p5 );
-	var a = new THREE.Frustum().copy( b );
-	ok( a.planes[0].equals( p0 ), "Passed!" );
-	ok( a.planes[1].equals( p1 ), "Passed!" );
-	ok( a.planes[2].equals( p2 ), "Passed!" );
-	ok( a.planes[3].equals( p3 ), "Passed!" );
-	ok( a.planes[4].equals( p4 ), "Passed!" );
-	ok( a.planes[5].equals( p5 ), "Passed!" );
-
-	// ensure it is a true copy by modifying source
-	b.planes[0] = p1;
-	ok( a.planes[0].equals( p0 ), "Passed!" );
-});
-
-test( "setFromMatrix/makeOrthographic/containsPoint", function() {
-	var m = new THREE.Matrix4().makeOrthographic( -1, 1, -1, 1, 1, 100 );
-	var a = new THREE.Frustum().setFromMatrix( m );
-
-	ok( ! a.containsPoint( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
-	ok( a.containsPoint( new THREE.Vector3( 0, 0, -50 ) ), "Passed!" );
-	ok( a.containsPoint( new THREE.Vector3( 0, 0, -1.001 ) ), "Passed!" );
-	ok( a.containsPoint( new THREE.Vector3( -1, -1, -1.001 ) ), "Passed!" );
-	ok( ! a.containsPoint( new THREE.Vector3( -1.1, -1.1, -1.001 ) ), "Passed!" );
-	ok( a.containsPoint( new THREE.Vector3( 1, 1, -1.001 ) ), "Passed!" );
-	ok( ! a.containsPoint( new THREE.Vector3( 1.1, 1.1, -1.001 ) ), "Passed!" );
-	ok( a.containsPoint( new THREE.Vector3( 0, 0, -100 ) ), "Passed!" );
-	ok( a.containsPoint( new THREE.Vector3( -1, -1, -100 ) ), "Passed!" );
-	ok( ! a.containsPoint( new THREE.Vector3( -1.1, -1.1, -100.1 ) ), "Passed!" );
-	ok( a.containsPoint( new THREE.Vector3( 1, 1, -100 ) ), "Passed!" );
-	ok( ! a.containsPoint( new THREE.Vector3( 1.1, 1.1, -100.1 ) ), "Passed!" );
-	ok( ! a.containsPoint( new THREE.Vector3( 0, 0, -101 ) ), "Passed!" );
-
-});
-
-test( "setFromMatrix/makePerspective/containsPoint", function() {
-	var m = new THREE.Matrix4().makePerspective( -1, 1, 1, -1, 1, 100 );
-	var a = new THREE.Frustum().setFromMatrix( m );
-
-	ok( ! a.containsPoint( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
-	ok( a.containsPoint( new THREE.Vector3( 0, 0, -50 ) ), "Passed!" );
-	ok( a.containsPoint( new THREE.Vector3( 0, 0, -1.001 ) ), "Passed!" );
-	ok( a.containsPoint( new THREE.Vector3( -1, -1, -1.001 ) ), "Passed!" );
-	ok( ! a.containsPoint( new THREE.Vector3( -1.1, -1.1, -1.001 ) ), "Passed!" );
-	ok( a.containsPoint( new THREE.Vector3( 1, 1, -1.001 ) ), "Passed!" );
-	ok( ! a.containsPoint( new THREE.Vector3( 1.1, 1.1, -1.001 ) ), "Passed!" );
-	ok( a.containsPoint( new THREE.Vector3( 0, 0, -99.999 ) ), "Passed!" );
-	ok( a.containsPoint( new THREE.Vector3( -99.999, -99.999, -99.999 ) ), "Passed!" );
-	ok( ! a.containsPoint( new THREE.Vector3( -100.1, -100.1, -100.1 ) ), "Passed!" );
-	ok( a.containsPoint( new THREE.Vector3( 99.999, 99.999, -99.999 ) ), "Passed!" );
-	ok( ! a.containsPoint( new THREE.Vector3( 100.1, 100.1, -100.1 ) ), "Passed!" );
-	ok( ! a.containsPoint( new THREE.Vector3( 0, 0, -101 ) ), "Passed!" );
-});
-
-test( "setFromMatrix/makePerspective/intersectsSphere", function() {
-	var m = new THREE.Matrix4().makePerspective( -1, 1, 1, -1, 1, 100 );
-	var a = new THREE.Frustum().setFromMatrix( m );
-
-	ok( ! a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( 0, 0, 0 ), 0 ) ), "Passed!" );
-	ok( ! a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( 0, 0, 0 ), 0.9 ) ), "Passed!" );
-	ok( a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( 0, 0, 0 ), 1.1 ) ), "Passed!" );
-	ok( a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( 0, 0, -50 ), 0 ) ), "Passed!" );
-	ok( a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( 0, 0, -1.001 ), 0 ) ), "Passed!" );
-	ok( a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( -1, -1, -1.001 ), 0 ) ), "Passed!" );
-	ok( ! a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( -1.1, -1.1, -1.001 ), 0 ) ), "Passed!" );
-	ok( a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( -1.1, -1.1, -1.001 ), 0.5 ) ), "Passed!" );
-	ok( a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( 1, 1, -1.001 ), 0 ) ), "Passed!" );
-	ok( ! a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( 1.1, 1.1, -1.001 ), 0 ) ), "Passed!" );
-	ok( a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( 1.1, 1.1, -1.001 ), 0.5 ) ), "Passed!" );
-	ok( a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( 0, 0, -99.999 ), 0 ) ), "Passed!" );
-	ok( a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( -99.999, -99.999, -99.999 ), 0 ) ), "Passed!" );
-	ok( ! a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( -100.1, -100.1, -100.1 ), 0 ) ), "Passed!" );
-	ok( a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( -100.1, -100.1, -100.1 ), 0.5 ) ), "Passed!" );
-	ok( a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( 99.999, 99.999, -99.999 ), 0 ) ), "Passed!" );
-	ok( ! a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( 100.1, 100.1, -100.1 ), 0 ) ), "Passed!" );
-	ok( a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( 100.1, 100.1, -100.1 ), 0.2 ) ), "Passed!" );
-	ok( ! a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( 0, 0, -101 ), 0 ) ), "Passed!" );
-	ok( a.intersectsSphere( new THREE.Sphere( new THREE.Vector3( 0, 0, -101 ), 1.1 ) ), "Passed!" );
-});
-
-test( "clone", function() {
-
-	var p0 = new THREE.Plane( unit3, -1 );
-	var p1 = new THREE.Plane( unit3, 1 );
-	var p2 = new THREE.Plane( unit3, 2 );
-	var p3 = new THREE.Plane( unit3, 3 );
-	var p4 = new THREE.Plane( unit3, 4 );
-	var p5 = new THREE.Plane( unit3, 5 );
-
-	var b = new THREE.Frustum( p0, p1, p2, p3, p4, p5 );
-	var a = b.clone();
-	ok( a.planes[0].equals( p0 ), "Passed!" );
-	ok( a.planes[1].equals( p1 ), "Passed!" );
-	ok( a.planes[2].equals( p2 ), "Passed!" );
-	ok( a.planes[3].equals( p3 ), "Passed!" );
-	ok( a.planes[4].equals( p4 ), "Passed!" );
-	ok( a.planes[5].equals( p5 ), "Passed!" );
-
-	// ensure it is a true copy by modifying source
-	a.planes[0].copy( p1 );
-	ok( b.planes[0].equals( p0 ), "Passed!" );
-});

+ 0 - 69
test/unit/math/Line3.js

@@ -1,69 +0,0 @@
-/**
- * @author bhouston / http://exocortex.com
- */
-
-module( "Line3" );
-
-test( "constructor/equals", function() {
-	var a = new THREE.Line3();
-	ok( a.start.equals( zero3 ), "Passed!" );
-	ok( a.end.equals( zero3 ), "Passed!" );
-
-	a = new THREE.Line3( two3.clone(), one3.clone() );
-	ok( a.start.equals( two3 ), "Passed!" );
-	ok( a.end.equals( one3 ), "Passed!" );
-});
-
-test( "copy/equals", function() {
-	var a = new THREE.Line3( zero3.clone(), one3.clone() );
-	var b = new THREE.Line3().copy( a );
-	ok( b.start.equals( zero3 ), "Passed!" );
-	ok( b.end.equals( one3 ), "Passed!" );
-
-	// ensure that it is a true copy
-	a.start = zero3;
-	a.end = one3;
-	ok( b.start.equals( zero3 ), "Passed!" );
-	ok( b.end.equals( one3 ), "Passed!" );
-});
-
-test( "set", function() {
-	var a = new THREE.Line3();
-
-	a.set( one3, one3 );
-	ok( a.start.equals( one3 ), "Passed!" );
-	ok( a.end.equals( one3 ), "Passed!" );
-});
-
-test( "at", function() {
-	var a = new THREE.Line3( one3.clone(), new THREE.Vector3( 1, 1, 2 ) );
-
-	ok( a.at( -1 ).distanceTo( new THREE.Vector3( 1, 1, 0 ) ) < 0.0001, "Passed!" );
-	ok( a.at( 0 ).distanceTo( one3.clone() ) < 0.0001, "Passed!" );
-	ok( a.at( 1 ).distanceTo( new THREE.Vector3( 1, 1, 2 ) ) < 0.0001, "Passed!" );
-	ok( a.at( 2 ).distanceTo( new THREE.Vector3( 1, 1, 3 ) ) < 0.0001, "Passed!" );
-});
-
-test( "closestPointToPoint/closestPointToPointParameter", function() {
-	var a = new THREE.Line3( one3.clone(), new THREE.Vector3( 1, 1, 2 ) );
-
-	// nearby the ray
-	ok( a.closestPointToPointParameter( zero3.clone(), true ) == 0, "Passed!" );
-	var b1 = a.closestPointToPoint( zero3.clone(), true );
-	ok( b1.distanceTo( new THREE.Vector3( 1, 1, 1 ) ) < 0.0001, "Passed!" );
-
-	// nearby the ray
-	ok( a.closestPointToPointParameter( zero3.clone(), false ) == -1, "Passed!" );
-	var b2 = a.closestPointToPoint( zero3.clone(), false );
-	ok( b2.distanceTo( new THREE.Vector3( 1, 1, 0 ) ) < 0.0001, "Passed!" );
-
-	// nearby the ray
-	ok( a.closestPointToPointParameter( new THREE.Vector3( 1, 1, 5 ), true ) == 1, "Passed!" );
-	var b = a.closestPointToPoint( new THREE.Vector3( 1, 1, 5 ), true );
-	ok( b.distanceTo( new THREE.Vector3( 1, 1, 2 ) ) < 0.0001, "Passed!" );
-
-	// exactly on the ray
-	ok( a.closestPointToPointParameter( one3.clone(), true ) == 0, "Passed!" );
-	var c = a.closestPointToPoint( one3.clone(), true );
-	ok( c.distanceTo( one3.clone() ) < 0.0001, "Passed!" );
-});

+ 0 - 35
test/unit/math/Math.js

@@ -1,35 +0,0 @@
-/**
- * @author humbletim / https://github.com/humbletim
- */
-
-module( "Math" );
-
-//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign
-//http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.sign
-/* 
-20.2.2.29 Math.sign(x)
-
-Returns the sign of the x, indicating whether x is positive, negative or zero.
-
-If x is NaN, the result is NaN.
-If x is -0, the result is -0.
-If x is +0, the result is +0.
-If x is negative and not -0, the result is -1.
-If x is positive and not +0, the result is +1.
-*/
-
-test( "Math.sign/polyfill", function() {
-
-	ok( isNaN( Math.sign(NaN) ) , "If x is NaN<NaN>, the result is NaN.");
-	ok( isNaN( Math.sign(new THREE.Vector3()) ) , "If x is NaN<object>, the result is NaN.");
-	ok( isNaN( Math.sign() ) , "If x is NaN<undefined>, the result is NaN.");
-	ok( isNaN( Math.sign('--3') ) , "If x is NaN<'--3'>, the result is NaN.");
-	ok( Math.sign(-0) === -0 , "If x is -0, the result is -0.");
-	ok( Math.sign(+0) === +0 , "If x is +0, the result is +0.");
-	ok( Math.sign(-Infinity) === -1 , "If x is negative<-Infinity> and not -0, the result is -1.");
-	ok( Math.sign('-3') === -1 , "If x is negative<'-3'> and not -0, the result is -1.");
-	ok( Math.sign('-1e-10') === -1 , "If x is negative<'-1e-10'> and not -0, the result is -1.");
-	ok( Math.sign(+Infinity) === +1 , "If x is positive<+Infinity> and not +0, the result is +1.");
-	ok( Math.sign('+3') === +1 , "If x is positive<'+3'> and not +0, the result is +1.");
-
-});

+ 0 - 212
test/unit/math/Matrix3.js

@@ -1,212 +0,0 @@
-/**
- * @author bhouston / http://exocortex.com
- */
-
-module( "Matrix3" );
-
-var matrixEquals3 = function( a, b, tolerance ) {
-	tolerance = tolerance || 0.0001;
-	if( a.elements.length != b.elements.length ) {
-		return false;
-	}
-	for( var i = 0, il = a.elements.length; i < il; i ++ ) {
-		var delta = a.elements[i] - b.elements[i];
-		if( delta > tolerance ) {
-			return false;
-		}
-	}
-	return true;
-};
-
-
-var toMatrix4 = function( m3 ) {
-	var result = new THREE.Matrix4();
-	var re = result.elements;
-	var me = m3.elements;
-	re[0] = me[0];
-	re[1] = me[1];
-	re[2] = me[2];
-	re[4] = me[3];
-	re[5] = me[4];
-	re[6] = me[5];
-	re[8] = me[6];
-	re[9] = me[7];
-	re[10] = me[8];
-
-	return result;
-};
-
-test( "constructor", function() {
-	var a = new THREE.Matrix3();
-	ok( a.determinant() == 1, "Passed!" );
-
-	var b = new THREE.Matrix3().set( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
-	ok( b.elements[0] == 0 );
-	ok( b.elements[1] == 3 );
-	ok( b.elements[2] == 6 );
-	ok( b.elements[3] == 1 );
-	ok( b.elements[4] == 4 );
-	ok( b.elements[5] == 7 );
-	ok( b.elements[6] == 2 );
-	ok( b.elements[7] == 5 );
-	ok( b.elements[8] == 8 );
-
-	ok( ! matrixEquals3( a, b ), "Passed!" );
-});
-
-test( "copy", function() {
-	var a = new THREE.Matrix3().set( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
-	var b = new THREE.Matrix3().copy( a );
-
-	ok( matrixEquals3( a, b ), "Passed!" );
-
-	// ensure that it is a true copy
-	a.elements[0] = 2;
-	ok( ! matrixEquals3( a, b ), "Passed!" );
-});
-
-test( "set", function() {
-	var b = new THREE.Matrix3();
-	ok( b.determinant() == 1, "Passed!" );
-
-	b.set( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
-	ok( b.elements[0] == 0 );
-	ok( b.elements[1] == 3 );
-	ok( b.elements[2] == 6 );
-	ok( b.elements[3] == 1 );
-	ok( b.elements[4] == 4 );
-	ok( b.elements[5] == 7 );
-	ok( b.elements[6] == 2 );
-	ok( b.elements[7] == 5 );
-	ok( b.elements[8] == 8 );
-});
-
-test( "identity", function() {
-	var b = new THREE.Matrix3().set( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
-	ok( b.elements[0] == 0 );
-	ok( b.elements[1] == 3 );
-	ok( b.elements[2] == 6 );
-	ok( b.elements[3] == 1 );
-	ok( b.elements[4] == 4 );
-	ok( b.elements[5] == 7 );
-	ok( b.elements[6] == 2 );
-	ok( b.elements[7] == 5 );
-	ok( b.elements[8] == 8 );
-
-	var a = new THREE.Matrix3();
-	ok( ! matrixEquals3( a, b ), "Passed!" );
-
-	b.identity();
-	ok( matrixEquals3( a, b ), "Passed!" );
-});
-
-test( "multiplyScalar", function() {
-	var b = new THREE.Matrix3().set( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
-	ok( b.elements[0] == 0 );
-	ok( b.elements[1] == 3 );
-	ok( b.elements[2] == 6 );
-	ok( b.elements[3] == 1 );
-	ok( b.elements[4] == 4 );
-	ok( b.elements[5] == 7 );
-	ok( b.elements[6] == 2 );
-	ok( b.elements[7] == 5 );
-	ok( b.elements[8] == 8 );
-
-	b.multiplyScalar( 2 );
-	ok( b.elements[0] == 0*2 );
-	ok( b.elements[1] == 3*2 );
-	ok( b.elements[2] == 6*2 );
-	ok( b.elements[3] == 1*2 );
-	ok( b.elements[4] == 4*2 );
-	ok( b.elements[5] == 7*2 );
-	ok( b.elements[6] == 2*2 );
-	ok( b.elements[7] == 5*2 );
-	ok( b.elements[8] == 8*2 );
-});
-
-
-test( "determinant", function() {
-	var a = new THREE.Matrix3();
-	ok( a.determinant() == 1, "Passed!" );
-
-	a.elements[0] = 2;
-	ok( a.determinant() == 2, "Passed!" );
-
-	a.elements[0] = 0;
-	ok( a.determinant() == 0, "Passed!" );
-
-	// calculated via http://www.euclideanspace.com/maths/algebra/matrix/functions/determinant/threeD/index.htm
-	a.set( 2, 3, 4, 5, 13, 7, 8, 9, 11 );
-	ok( a.determinant() == -73, "Passed!" );
-});
-
-
-test( "getInverse", function() {
-	var identity = new THREE.Matrix3();
-	var identity4 = new THREE.Matrix4();
-	var a = new THREE.Matrix3();
-	var b = new THREE.Matrix3().set( 0, 0, 0, 0, 0, 0, 0, 0, 0 );
-	var c = new THREE.Matrix3().set( 0, 0, 0, 0, 0, 0, 0, 0, 0 );
-
-	b.getInverse( a, false );
-	ok( matrixEquals3( a, identity ), "Passed!" );
-
-	try { 
-		b.getInverse( c, true );
-		ok( false, "Passed!" ); // should never get here.
-	}
-	catch( err ) {
-		ok( true, "Passed!" );
-	}
-
-	var testMatrices = [
-		new THREE.Matrix4().makeRotationX( 0.3 ),
-		new THREE.Matrix4().makeRotationX( -0.3 ),
-		new THREE.Matrix4().makeRotationY( 0.3 ),
-		new THREE.Matrix4().makeRotationY( -0.3 ),
-		new THREE.Matrix4().makeRotationZ( 0.3 ),
-		new THREE.Matrix4().makeRotationZ( -0.3 ),
-		new THREE.Matrix4().makeScale( 1, 2, 3 ),
-		new THREE.Matrix4().makeScale( 1/8, 1/2, 1/3 )
-		];
-
-	for( var i = 0, il = testMatrices.length; i < il; i ++ ) {
-		var m = testMatrices[i];
-
-		a.setFromMatrix4( m );
-		var mInverse3 = b.getInverse( a );
-
-		var mInverse = toMatrix4( mInverse3 );
-
-		// the determinant of the inverse should be the reciprocal
-		ok( Math.abs( a.determinant() * mInverse3.determinant() - 1 ) < 0.0001, "Passed!" );
-		ok( Math.abs( m.determinant() * mInverse.determinant() - 1 ) < 0.0001, "Passed!" );
-
-		var mProduct = new THREE.Matrix4().multiplyMatrices( m, mInverse );
-		ok( Math.abs( mProduct.determinant() - 1 ) < 0.0001, "Passed!" );
-		ok( matrixEquals3( mProduct, identity4 ), "Passed!" );
-	}
-});
-
-test( "transpose", function() {
-	var a = new THREE.Matrix3();
-	var b = a.clone().transpose();
-	ok( matrixEquals3( a, b ), "Passed!" );
-
-	b = new THREE.Matrix3().set( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
-	var c = b.clone().transpose();
-	ok( ! matrixEquals3( b, c ), "Passed!" ); 
-	c.transpose();
-	ok( matrixEquals3( b, c ), "Passed!" ); 
-});
-
-test( "clone", function() {
-	var a = new THREE.Matrix3().set( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
-	var b = a.clone();
-
-	ok( matrixEquals3( a, b ), "Passed!" );
-
-	// ensure that it is a true copy
-	a.elements[0] = 2;
-	ok( ! matrixEquals3( a, b ), "Passed!" );
-});

+ 0 - 197
test/unit/math/Plane.js

@@ -1,197 +0,0 @@
-/**
- * @author bhouston / http://exocortex.com
- */
-
-module( "Plane" );
-
-var comparePlane = function ( a, b, threshold ) {
-	threshold = threshold || 0.0001;
-	return ( a.normal.distanceTo( b.normal ) < threshold &&
-	Math.abs( a.constant - b.constant ) < threshold );
-};
-
-
-test( "constructor", function() {
-	var a = new THREE.Plane();
-	ok( a.normal.x == 1, "Passed!" );
-	ok( a.normal.y == 0, "Passed!" );
-	ok( a.normal.z == 0, "Passed!" );
-	ok( a.constant == 0, "Passed!" );
-
-	a = new THREE.Plane( one3.clone(), 0 );
-	ok( a.normal.x == 1, "Passed!" );
-	ok( a.normal.y == 1, "Passed!" );
-	ok( a.normal.z == 1, "Passed!" );
-	ok( a.constant == 0, "Passed!" );
-
-	a = new THREE.Plane( one3.clone(), 1 );
-	ok( a.normal.x == 1, "Passed!" );
-	ok( a.normal.y == 1, "Passed!" );
-	ok( a.normal.z == 1, "Passed!" );
-	ok( a.constant == 1, "Passed!" );
-});
-
-test( "copy", function() {
-	var a = new THREE.Plane( new THREE.Vector3( x, y, z ), w );
-	var b = new THREE.Plane().copy( a );
-	ok( b.normal.x == x, "Passed!" );
-	ok( b.normal.y == y, "Passed!" );
-	ok( b.normal.z == z, "Passed!" );
-	ok( b.constant == w, "Passed!" );
-
-	// ensure that it is a true copy
-	a.normal.x = 0;
-	a.normal.y = -1;
-	a.normal.z = -2;
-	a.constant = -3;
-	ok( b.normal.x == x, "Passed!" );
-	ok( b.normal.y == y, "Passed!" );
-	ok( b.normal.z == z, "Passed!" );
-	ok( b.constant == w, "Passed!" );
-});
-
-test( "set", function() {
-	var a = new THREE.Plane();
-	ok( a.normal.x == 1, "Passed!" );
-	ok( a.normal.y == 0, "Passed!" );
-	ok( a.normal.z == 0, "Passed!" );
-	ok( a.constant == 0, "Passed!" );
-
-	var b = a.clone().set( new THREE.Vector3( x, y, z ), w );
-	ok( b.normal.x == x, "Passed!" );
-	ok( b.normal.y == y, "Passed!" );
-	ok( b.normal.z == z, "Passed!" );
-	ok( b.constant == w, "Passed!" );
-});
-
-test( "setComponents", function() {
-	var a = new THREE.Plane();
-	ok( a.normal.x == 1, "Passed!" );
-	ok( a.normal.y == 0, "Passed!" );
-	ok( a.normal.z == 0, "Passed!" );
-	ok( a.constant == 0, "Passed!" );
-
-	var b = a.clone().setComponents( x, y, z , w );
-	ok( b.normal.x == x, "Passed!" );
-	ok( b.normal.y == y, "Passed!" );
-	ok( b.normal.z == z, "Passed!" );
-	ok( b.constant == w, "Passed!" );
-});
-
-test( "setFromNormalAndCoplanarPoint", function() {
-	var normal = one3.clone().normalize();
-	var a = new THREE.Plane().setFromNormalAndCoplanarPoint( normal, zero3 );
-
-	ok( a.normal.equals( normal ), "Passed!" );
-	ok( a.constant == 0, "Passed!" );
-});
-
-test( "normalize", function() {
-	var a = new THREE.Plane( new THREE.Vector3( 2, 0, 0 ), 2 );
-
-	a.normalize();
-	ok( a.normal.length() == 1, "Passed!" );
-	ok( a.normal.equals( new THREE.Vector3( 1, 0, 0 ) ), "Passed!" );
-	ok( a.constant == 1, "Passed!" );
-});
-
-test( "negate/distanceToPoint", function() {
-	var a = new THREE.Plane( new THREE.Vector3( 2, 0, 0 ), -2 );
-
-	a.normalize();
-	ok( a.distanceToPoint( new THREE.Vector3( 4, 0, 0 ) ) === 3, "Passed!" );
-	ok( a.distanceToPoint( new THREE.Vector3( 1, 0, 0 ) ) === 0, "Passed!" );
-
-	a.negate();
-	ok( a.distanceToPoint( new THREE.Vector3( 4, 0, 0 ) ) === -3, "Passed!" );
-	ok( a.distanceToPoint( new THREE.Vector3( 1, 0, 0 ) ) === 0, "Passed!" );
-});
-
-test( "distanceToPoint", function() {
-	var a = new THREE.Plane( new THREE.Vector3( 2, 0, 0 ), -2 );
-
-	a.normalize();
-	ok( a.distanceToPoint( a.projectPoint( zero3.clone() ) ) === 0, "Passed!" );
-	ok( a.distanceToPoint( new THREE.Vector3( 4, 0, 0 ) ) === 3, "Passed!" );
-});
-
-test( "distanceToSphere", function() {
-	var a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 );
-
-	var b = new THREE.Sphere( new THREE.Vector3( 2, 0, 0 ), 1 );
-
-	ok( a.distanceToSphere( b ) === 1, "Passed!" );
-
-	a.set( new THREE.Vector3( 1, 0, 0 ), 2 );
-	ok( a.distanceToSphere( b ) === 3, "Passed!" );
-	a.set( new THREE.Vector3( 1, 0, 0 ), -2 );
-	ok( a.distanceToSphere( b ) === -1, "Passed!" );
-});
-
-test( "isInterestionLine/intersectLine", function() {
-	var a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 );
-
-	var l1 = new THREE.Line3( new THREE.Vector3( -10, 0, 0 ), new THREE.Vector3( 10, 0, 0 ) );
-	ok( a.intersectsLine( l1 ), "Passed!" );
-	ok( a.intersectLine( l1 ).equals( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
-
-	a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), -3 );
-
-	ok( a.intersectsLine( l1 ), "Passed!" );
-	ok( a.intersectLine( l1 ).equals( new THREE.Vector3( 3, 0, 0 ) ), "Passed!" );
-
-
-	a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), -11 );
-
-	ok( ! a.intersectsLine( l1 ), "Passed!" );
-	ok( a.intersectLine( l1 ) === undefined, "Passed!" );
-
-	a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 11 );
-
-	ok( ! a.intersectsLine( l1 ), "Passed!" );
-	ok( a.intersectLine( l1 ) === undefined, "Passed!" );
-
-});
-
-test( "projectPoint", function() {
-	var a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 );
-
-	ok( a.projectPoint( new THREE.Vector3( 10, 0, 0 ) ).equals( zero3 ), "Passed!" );
-	ok( a.projectPoint( new THREE.Vector3( -10, 0, 0 ) ).equals( zero3 ), "Passed!" );
-
-	a = new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), -1 );
-	ok( a.projectPoint( new THREE.Vector3( 0, 0, 0 ) ).equals( new THREE.Vector3( 0, 1, 0 ) ), "Passed!" );
-	ok( a.projectPoint( new THREE.Vector3( 0, 1, 0 ) ).equals( new THREE.Vector3( 0, 1, 0 ) ), "Passed!" );
-
-});
-
-test( "orthoPoint", function() {
-	var a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 );
-
-	ok( a.orthoPoint( new THREE.Vector3( 10, 0, 0 ) ).equals( new THREE.Vector3( 10, 0, 0 ) ), "Passed!" );
-	ok( a.orthoPoint( new THREE.Vector3( -10, 0, 0 ) ).equals( new THREE.Vector3( -10, 0, 0 ) ), "Passed!" );
-});
-
-test( "coplanarPoint", function() {
-	var a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 );
-	ok( a.distanceToPoint( a.coplanarPoint() ) === 0, "Passed!" );
-
-	a = new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), -1 );
-	ok( a.distanceToPoint( a.coplanarPoint() ) === 0, "Passed!" );
-});
-
-test( "applyMatrix4/translate", function() {
-
-	var a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 );
-
-	var m = new THREE.Matrix4();
-	m.makeRotationZ( Math.PI * 0.5 );
-
-	ok( comparePlane( a.clone().applyMatrix4( m ), new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), 0 ) ), "Passed!" );
-
-	a = new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), -1 );
-	ok( comparePlane( a.clone().applyMatrix4( m ), new THREE.Plane( new THREE.Vector3( -1, 0, 0 ), -1 ) ), "Passed!" );
-
-	m.makeTranslation( 1, 1, 1 );
-	ok( comparePlane( a.clone().applyMatrix4( m ), a.clone().translate( new THREE.Vector3( 1, 1, 1 ) ) ), "Passed!" );
-});

+ 0 - 112
test/unit/math/Sphere.js

@@ -1,112 +0,0 @@
-/**
- * @author bhouston / http://exocortex.com
- */
-
-module( "Sphere" );
-
-test( "constructor", function() {
-	var a = new THREE.Sphere();
-	ok( a.center.equals( zero3 ), "Passed!" );
-	ok( a.radius == 0, "Passed!" );
-
-	a = new THREE.Sphere( one3.clone(), 1 );
-	ok( a.center.equals( one3 ), "Passed!" );
-	ok( a.radius == 1, "Passed!" );
-});
-
-test( "copy", function() {
-	var a = new THREE.Sphere( one3.clone(), 1 );
-	var b = new THREE.Sphere().copy( a );
-
-	ok( b.center.equals( one3 ), "Passed!" );
-	ok( b.radius == 1, "Passed!" );
-
-	// ensure that it is a true copy
-	a.center = zero3;
-	a.radius = 0;
-	ok( b.center.equals( one3 ), "Passed!" );
-	ok( b.radius == 1, "Passed!" );
-});
-
-test( "set", function() {
-	var a = new THREE.Sphere();
-	ok( a.center.equals( zero3 ), "Passed!" );
-	ok( a.radius == 0, "Passed!" );
-
-	a.set( one3, 1 );
-	ok( a.center.equals( one3 ), "Passed!" );
-	ok( a.radius == 1, "Passed!" );
-});
-
-test( "empty", function() {
-	var a = new THREE.Sphere();
-	ok( a.empty(), "Passed!" );
-
-	a.set( one3, 1 );
-	ok( ! a.empty(), "Passed!" );
-});
-
-test( "containsPoint", function() {
-	var a = new THREE.Sphere( one3.clone(), 1 );
-
-	ok( ! a.containsPoint( zero3 ), "Passed!" );
-	ok( a.containsPoint( one3 ), "Passed!" );
-});
-
-test( "distanceToPoint", function() {
-	var a = new THREE.Sphere( one3.clone(), 1 );
-
-	ok( ( a.distanceToPoint( zero3 ) - 0.7320 ) < 0.001, "Passed!" );
-	ok( a.distanceToPoint( one3 ) === -1, "Passed!" );
-});
-
-test( "intersectsSphere", function() {
-	var a = new THREE.Sphere( one3.clone(), 1 );
-	var b = new THREE.Sphere( zero3.clone(), 1 );
-	var c = new THREE.Sphere( zero3.clone(), 0.25 );
-
-	ok( a.intersectsSphere( b ) , "Passed!" );
-	ok( ! a.intersectsSphere( c ) , "Passed!" );
-});
-
-test( "intersectsPlane", function() {
-	var a = new THREE.Sphere( zero3.clone(), 1 );
-	var b = new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), 1 );
-	var c = new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), 1.25 );
-	var d = new THREE.Plane( new THREE.Vector3( 0, -1, 0 ), 1.25 );
-
-	ok( a.intersectsPlane( b ) , "Passed!" );
-	ok( ! a.intersectsPlane( c ) , "Passed!" );
-	ok( ! a.intersectsPlane( d ) , "Passed!" );
-});
-
-test( "clampPoint", function() {
-	var a = new THREE.Sphere( one3.clone(), 1 );
-
-	ok( a.clampPoint( new THREE.Vector3( 1, 1, 3 ) ).equals( new THREE.Vector3( 1, 1, 2 ) ), "Passed!" );
-	ok( a.clampPoint( new THREE.Vector3( 1, 1, -3 ) ).equals( new THREE.Vector3( 1, 1, 0 ) ), "Passed!" );
-});
-
-test( "getBoundingBox", function() {
-	var a = new THREE.Sphere( one3.clone(), 1 );
-
-	ok( a.getBoundingBox().equals( new THREE.Box3( zero3, two3 ) ), "Passed!" );
-
-	a.set( zero3, 0 );
-	ok( a.getBoundingBox().equals( new THREE.Box3( zero3, zero3 ) ), "Passed!" );
-});
-
-test( "applyMatrix4", function() {
-	var a = new THREE.Sphere( one3.clone(), 1 );
-
-	var m = new THREE.Matrix4().makeTranslation( 1, -2, 1 );
-
-	ok( a.clone().applyMatrix4( m ).getBoundingBox().equals( a.getBoundingBox().applyMatrix4( m ) ), "Passed!" );
-});
-
-test( "translate", function() {
-	var a = new THREE.Sphere( one3.clone(), 1 );
-
-	a.translate( one3.clone().negate() );
-	ok( a.center.equals( zero3 ), "Passed!" );
-});

+ 0 - 191
test/unit/math/Triangle.js

@@ -1,191 +0,0 @@
-/**
- * @author bhouston / http://exocortex.com
- */
-
-module( "Triangle" );
-
-test( "constructor", function() {
-	var a = new THREE.Triangle();
-	ok( a.a.equals( zero3 ), "Passed!" );
-	ok( a.b.equals( zero3 ), "Passed!" );
-	ok( a.c.equals( zero3 ), "Passed!" );
-
-	a = new THREE.Triangle( one3.clone().negate(), one3.clone(), two3.clone() );
-	ok( a.a.equals( one3.clone().negate() ), "Passed!" );
-	ok( a.b.equals( one3 ), "Passed!" );
-	ok( a.c.equals( two3 ), "Passed!" );
-});
-
-test( "copy", function() {
-	var a = new THREE.Triangle( one3.clone().negate(), one3.clone(), two3.clone() );
-	var b = new THREE.Triangle().copy( a );
-	ok( b.a.equals( one3.clone().negate() ), "Passed!" );
-	ok( b.b.equals( one3 ), "Passed!" );
-	ok( b.c.equals( two3 ), "Passed!" );
-
-	// ensure that it is a true copy
-	a.a = one3;
-	a.b = zero3;
-	a.c = zero3;
-	ok( b.a.equals( one3.clone().negate() ), "Passed!" );
-	ok( b.b.equals( one3 ), "Passed!" );
-	ok( b.c.equals( two3 ), "Passed!" );
-});
-
-test( "setFromPointsAndIndices", function() {
-	var a = new THREE.Triangle();
-
-	var points = [ one3, one3.clone().negate(), two3 ];
-	a.setFromPointsAndIndices( points, 1, 0, 2 );
-	ok( a.a.equals( one3.clone().negate() ), "Passed!" );
-	ok( a.b.equals( one3 ), "Passed!" );
-	ok( a.c.equals( two3 ), "Passed!" );
-
-});
-
-test( "set", function() {
-	var a = new THREE.Triangle();
-
-	a.set( one3.clone().negate(), one3, two3 );
-	ok( a.a.equals( one3.clone().negate() ), "Passed!" );
-	ok( a.b.equals( one3 ), "Passed!" );
-	ok( a.c.equals( two3 ), "Passed!" );
-
-});
-
-test( "area", function() {
-	var a = new THREE.Triangle();
-
-	ok( a.area() == 0, "Passed!" );
-
-	a = new THREE.Triangle( new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( 0, 1, 0 ) );
-	ok( a.area() == 0.5, "Passed!" );
-
-	a = new THREE.Triangle( new THREE.Vector3( 2, 0, 0 ), new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 0, 2 ) );
-	ok( a.area() == 2, "Passed!" );
-
-	// colinear triangle.
-	a = new THREE.Triangle( new THREE.Vector3( 2, 0, 0 ), new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 3, 0, 0 ) );
-	ok( a.area() == 0, "Passed!" );
-});
-
-test( "midpoint", function() {
-	var a = new THREE.Triangle();
-
-	ok( a.midpoint().equals( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
-
-	a = new THREE.Triangle( new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( 0, 1, 0 ) );
-	ok( a.midpoint().equals( new THREE.Vector3( 1/3, 1/3, 0 ) ), "Passed!" );
-
-	a = new THREE.Triangle( new THREE.Vector3( 2, 0, 0 ), new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 0, 2 ) );
-	ok( a.midpoint().equals( new THREE.Vector3( 2/3, 0, 2/3 ) ), "Passed!" );
-});
-
-test( "normal", function() {
-	var a = new THREE.Triangle();
-
-	ok( a.normal().equals( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
-
-	a = new THREE.Triangle( new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( 0, 1, 0 ) );
-	ok( a.normal().equals( new THREE.Vector3( 0, 0, 1 ) ), "Passed!" );
-
-	a = new THREE.Triangle( new THREE.Vector3( 2, 0, 0 ), new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 0, 2 ) );
-	ok( a.normal().equals( new THREE.Vector3( 0, 1, 0 ) ), "Passed!" );
-});
-
-test( "plane", function() {
-	var a = new THREE.Triangle();
-
-	// artificial normal is created in this case.
-	ok( a.plane().distanceToPoint( a.a ) == 0, "Passed!" );
-	ok( a.plane().distanceToPoint( a.b ) == 0, "Passed!" );
-	ok( a.plane().distanceToPoint( a.c ) == 0, "Passed!" );
-	ok( a.plane().normal.equals( a.normal() ), "Passed!" );
-
-	a = new THREE.Triangle( new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( 0, 1, 0 ) );
-	ok( a.plane().distanceToPoint( a.a ) == 0, "Passed!" );
-	ok( a.plane().distanceToPoint( a.b ) == 0, "Passed!" );
-	ok( a.plane().distanceToPoint( a.c ) == 0, "Passed!" );
-	ok( a.plane().normal.equals( a.normal() ), "Passed!" );
-
-	a = new THREE.Triangle( new THREE.Vector3( 2, 0, 0 ), new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 0, 2 ) );
-	ok( a.plane().distanceToPoint( a.a ) == 0, "Passed!" );
-	ok( a.plane().distanceToPoint( a.b ) == 0, "Passed!" );
-	ok( a.plane().distanceToPoint( a.c ) == 0, "Passed!" );
-	ok( a.plane().normal.clone().normalize().equals( a.normal() ), "Passed!" );
-});
-
-test( "barycoordFromPoint", function() {
-	var a = new THREE.Triangle();
-
-	var bad = new THREE.Vector3( -2, -1, -1 );
-
-	ok( a.barycoordFromPoint( a.a ).equals( bad ), "Passed!" );
-	ok( a.barycoordFromPoint( a.b ).equals( bad ), "Passed!" );
-	ok( a.barycoordFromPoint( a.c ).equals( bad ), "Passed!" );
-
-	a = new THREE.Triangle( new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( 0, 1, 0 ) );
-	ok( a.barycoordFromPoint( a.a ).equals( new THREE.Vector3( 1, 0, 0 ) ), "Passed!" );
-	ok( a.barycoordFromPoint( a.b ).equals( new THREE.Vector3( 0, 1, 0 ) ), "Passed!" );
-	ok( a.barycoordFromPoint( a.c ).equals( new THREE.Vector3( 0, 0, 1 ) ), "Passed!" );
-	ok( a.barycoordFromPoint( a.midpoint() ).distanceTo( new THREE.Vector3( 1/3, 1/3, 1/3 ) ) < 0.0001, "Passed!" );
-
-	a = new THREE.Triangle( new THREE.Vector3( 2, 0, 0 ), new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 0, 2 ) );
-	ok( a.barycoordFromPoint( a.a ).equals( new THREE.Vector3( 1, 0, 0 ) ), "Passed!" );
-	ok( a.barycoordFromPoint( a.b ).equals( new THREE.Vector3( 0, 1, 0 ) ), "Passed!" );
-	ok( a.barycoordFromPoint( a.c ).equals( new THREE.Vector3( 0, 0, 1 ) ), "Passed!" );
-	ok( a.barycoordFromPoint( a.midpoint() ).distanceTo( new THREE.Vector3( 1/3, 1/3, 1/3 ) ) < 0.0001, "Passed!" );
-});
-
-test( "containsPoint", function() {
-	var a = new THREE.Triangle();
-
-	ok( ! a.containsPoint( a.a ), "Passed!" );
-	ok( ! a.containsPoint( a.b ), "Passed!" );
-	ok( ! a.containsPoint( a.c ), "Passed!" );
-
-	a = new THREE.Triangle( new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( 0, 1, 0 ) );
-	ok( a.containsPoint( a.a ), "Passed!" );
-	ok( a.containsPoint( a.b ), "Passed!" );
-	ok( a.containsPoint( a.c ), "Passed!" );
-	ok( a.containsPoint( a.midpoint() ), "Passed!" );
-	ok( ! a.containsPoint( new THREE.Vector3( -1, -1, -1 ) ), "Passed!" );
-
-	a = new THREE.Triangle( new THREE.Vector3( 2, 0, 0 ), new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 0, 2 ) );
-	ok( a.containsPoint( a.a ), "Passed!" );
-	ok( a.containsPoint( a.b ), "Passed!" );
-	ok( a.containsPoint( a.c ), "Passed!" );
-	ok( a.containsPoint( a.midpoint() ), "Passed!" );
-	ok( ! a.containsPoint( new THREE.Vector3( -1, -1, -1 ) ), "Passed!" );
-});
-
-test( "closestPointToPoint", function() {
-
-	var a = new THREE.Triangle( new THREE.Vector3( -1, 0, 0 ), new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( 0, 1, 0 ) );
-
-	// point lies inside the triangle
-	var b0 = a.closestPointToPoint( new THREE.Vector3( 0, 0.5, 0 ) );
-	ok( b0.equals( new THREE.Vector3( 0, 0.5, 0 ) ), "Passed!" );
-
-	// point lies on a vertex
-	b0 = a.closestPointToPoint( a.a );
-	ok( b0.equals( a.a ), "Passed!" );
-	b0 = a.closestPointToPoint( a.b );
-	ok( b0.equals( a.b ), "Passed!" );
-	b0 = a.closestPointToPoint( a.c );
-	ok( b0.equals( a.c ), "Passed!" );
-
-	// point lies on an edge
-	b0 = a.closestPointToPoint( zero3.clone() );
-	ok( b0.equals( zero3.clone() ), "Passed!" );
-
-	// point lies outside the triangle
-	b0 = a.closestPointToPoint( new THREE.Vector3( -2, 0, 0 ) );
-	ok( b0.equals( new THREE.Vector3( -1, 0, 0 ) ), "Passed!" );
-	b0 = a.closestPointToPoint( new THREE.Vector3( 2, 0, 0 ) );
-	ok( b0.equals( new THREE.Vector3( 1, 0, 0 ) ), "Passed!" );
-	b0 = a.closestPointToPoint( new THREE.Vector3( 0, 2, 0 ) );
-	ok( b0.equals( new THREE.Vector3( 0, 1, 0 ) ), "Passed!" );
-	b0 = a.closestPointToPoint( new THREE.Vector3( 0, -2, 0 ) );
-	ok( b0.equals( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
-});

+ 0 - 262
test/unit/math/Vector2.js

@@ -1,262 +0,0 @@
-/**
- * @author bhouston / http://exocortex.com
- */
-
-module( "Vector2" );
-
-test( "constructor", function() {
-	var a = new THREE.Vector2();
-	ok( a.x == 0, "Passed!" );
-	ok( a.y == 0, "Passed!" );
-
-	a = new THREE.Vector2( x, y );
-	ok( a.x === x, "Passed!" );
-	ok( a.y === y, "Passed!" );
-});
-
-test( "copy", function() {
-	var a = new THREE.Vector2( x, y );
-	var b = new THREE.Vector2().copy( a );
-	ok( b.x == x, "Passed!" );
-	ok( b.y == y, "Passed!" );
-
-	// ensure that it is a true copy
-	a.x = 0;
-	a.y = -1;
-	ok( b.x == x, "Passed!" );
-	ok( b.y == y, "Passed!" );
-});
-
-test( "set", function() {
-	var a = new THREE.Vector2();
-	ok( a.x == 0, "Passed!" );
-	ok( a.y == 0, "Passed!" );
-
-	a.set( x, y );
-	ok( a.x == x, "Passed!" );
-	ok( a.y == y, "Passed!" );
-});
-
-test( "setX,setY", function() {
-	var a = new THREE.Vector2();
-	ok( a.x == 0, "Passed!" );
-	ok( a.y == 0, "Passed!" );
-
-	a.setX( x );
-	a.setY( y );
-	ok( a.x == x, "Passed!" );
-	ok( a.y == y, "Passed!" );
-});
-
-test( "setComponent,getComponent", function() {
-	var a = new THREE.Vector2();
-	ok( a.x == 0, "Passed!" );
-	ok( a.y == 0, "Passed!" );
-
-	a.setComponent( 0, 1 );
-	a.setComponent( 1, 2 );
-	ok( a.getComponent( 0 ) == 1, "Passed!" );
-	ok( a.getComponent( 1 ) == 2, "Passed!" );
-});
-
-test( "add", function() {
-	var a = new THREE.Vector2( x, y );
-	var b = new THREE.Vector2( -x, -y );
-
-	a.add( b );
-	ok( a.x == 0, "Passed!" );
-	ok( a.y == 0, "Passed!" );
-
-	var c = new THREE.Vector2().addVectors( b, b );
-	ok( c.x == -2*x, "Passed!" );
-	ok( c.y == -2*y, "Passed!" );
-});
-
-test( "sub", function() {
-	var a = new THREE.Vector2( x, y );
-	var b = new THREE.Vector2( -x, -y );
-
-	a.sub( b );
-	ok( a.x == 2*x, "Passed!" );
-	ok( a.y == 2*y, "Passed!" );
-
-	var c = new THREE.Vector2().subVectors( a, a );
-	ok( c.x == 0, "Passed!" );
-	ok( c.y == 0, "Passed!" );
-});
-
-test( "multiply/divide", function() {
-	var a = new THREE.Vector2( x, y );
-	var b = new THREE.Vector2( -x, -y );
-
-	a.multiplyScalar( -2 );
-	ok( a.x == x*-2, "Passed!" );
-	ok( a.y == y*-2, "Passed!" );
-
-	b.multiplyScalar( -2 );
-	ok( b.x == 2*x, "Passed!" );
-	ok( b.y == 2*y, "Passed!" );
-
-	a.divideScalar( -2 );
-	ok( a.x == x, "Passed!" );
-	ok( a.y == y, "Passed!" );
-
-	b.divideScalar( -2 );
-	ok( b.x == -x, "Passed!" );
-	ok( b.y == -y, "Passed!" );
-});
-
-
-test( "min/max/clamp", function() {
-	var a = new THREE.Vector2( x, y );
-	var b = new THREE.Vector2( -x, -y );
-	var c = new THREE.Vector2();
-
-	c.copy( a ).min( b );
-	ok( c.x == -x, "Passed!" );
-	ok( c.y == -y, "Passed!" );
-
-	c.copy( a ).max( b );
-	ok( c.x == x, "Passed!" );
-	ok( c.y == y, "Passed!" );
-
-	c.set( -2*x, 2*y );
-	c.clamp( b, a );
-	ok( c.x == -x, "Passed!" );
-	ok( c.y == y, "Passed!" );
-
-	c.set(-2*x, 2*x);
-	c.clampScalar( -x, x );
-	equal( c.x, -x, "scalar clamp x" );
-	equal( c.y,  x, "scalar clamp y" );
-});
-
-test( "rounding", function() {
-	deepEqual( new THREE.Vector2( -0.1, 0.1 ).floor(), new THREE.Vector2( -1, 0 ), "floor .1" );
-	deepEqual( new THREE.Vector2( -0.5, 0.5 ).floor(), new THREE.Vector2( -1, 0 ), "floor .5" );
-	deepEqual( new THREE.Vector2( -0.9, 0.9 ).floor(), new THREE.Vector2( -1, 0 ), "floor .9" );
-
-	deepEqual( new THREE.Vector2( -0.1, 0.1 ).ceil(), new THREE.Vector2( 0, 1 ), "ceil .1" );
-	deepEqual( new THREE.Vector2( -0.5, 0.5 ).ceil(), new THREE.Vector2( 0, 1 ), "ceil .5" );
-	deepEqual( new THREE.Vector2( -0.9, 0.9 ).ceil(), new THREE.Vector2( 0, 1 ), "ceil .9" );
-
-	deepEqual( new THREE.Vector2( -0.1, 0.1 ).round(), new THREE.Vector2( 0, 0 ), "round .1" );
-	deepEqual( new THREE.Vector2( -0.5, 0.5 ).round(), new THREE.Vector2( 0, 1 ), "round .5" );
-	deepEqual( new THREE.Vector2( -0.9, 0.9 ).round(), new THREE.Vector2( -1, 1 ), "round .9" );
-
-	deepEqual( new THREE.Vector2( -0.1, 0.1 ).roundToZero(), new THREE.Vector2( 0, 0 ), "roundToZero .1" );
-	deepEqual( new THREE.Vector2( -0.5, 0.5 ).roundToZero(), new THREE.Vector2( 0, 0 ), "roundToZero .5" );
-	deepEqual( new THREE.Vector2( -0.9, 0.9 ).roundToZero(), new THREE.Vector2( 0, 0 ), "roundToZero .9" );
-	deepEqual( new THREE.Vector2( -1.1, 1.1 ).roundToZero(), new THREE.Vector2( -1, 1 ), "roundToZero 1.1" );
-	deepEqual( new THREE.Vector2( -1.5, 1.5 ).roundToZero(), new THREE.Vector2( -1, 1 ), "roundToZero 1.5" );
-	deepEqual( new THREE.Vector2( -1.9, 1.9 ).roundToZero(), new THREE.Vector2( -1, 1 ), "roundToZero 1.9" );
-});
-
-test( "negate", function() {
-	var a = new THREE.Vector2( x, y );
-
-	a.negate();
-	ok( a.x == -x, "Passed!" );
-	ok( a.y == -y, "Passed!" );
-});
-
-test( "dot", function() {
-	var a = new THREE.Vector2( x, y );
-	var b = new THREE.Vector2( -x, -y );
-	var c = new THREE.Vector2();
-
-	var result = a.dot( b );
-	ok( result == (-x*x-y*y), "Passed!" );
-
-	result = a.dot( c );
-	ok( result == 0, "Passed!" );
-});
-
-test( "length/lengthSq", function() {
-	var a = new THREE.Vector2( x, 0 );
-	var b = new THREE.Vector2( 0, -y );
-	var c = new THREE.Vector2();
-
-	ok( a.length() == x, "Passed!" );
-	ok( a.lengthSq() == x*x, "Passed!" );
-	ok( b.length() == y, "Passed!" );
-	ok( b.lengthSq() == y*y, "Passed!" );
-	ok( c.length() == 0, "Passed!" );
-	ok( c.lengthSq() == 0, "Passed!" );
-
-	a.set( x, y );
-	ok( a.length() == Math.sqrt( x*x + y*y ), "Passed!" );
-	ok( a.lengthSq() == ( x*x + y*y ), "Passed!" );
-});
-
-test( "normalize", function() {
-	var a = new THREE.Vector2( x, 0 );
-	var b = new THREE.Vector2( 0, -y );
-	var c = new THREE.Vector2();
-
-	a.normalize();
-	ok( a.length() == 1, "Passed!" );
-	ok( a.x == 1, "Passed!" );
-
-	b.normalize();
-	ok( b.length() == 1, "Passed!" );
-	ok( b.y == -1, "Passed!" );
-});
-
-test( "distanceTo/distanceToSquared", function() {
-	var a = new THREE.Vector2( x, 0 );
-	var b = new THREE.Vector2( 0, -y );
-	var c = new THREE.Vector2();
-
-	ok( a.distanceTo( c ) == x, "Passed!" );
-	ok( a.distanceToSquared( c ) == x*x, "Passed!" );
-
-	ok( b.distanceTo( c ) == y, "Passed!" );
-	ok( b.distanceToSquared( c ) == y*y, "Passed!" );
-});
-
-test( "setLength", function() {
-	var a = new THREE.Vector2( x, 0 );
-
-	ok( a.length() == x, "Passed!" );
-	a.setLength( y );
-	ok( a.length() == y, "Passed!" );
-
-	a = new THREE.Vector2( 0, 0 );
-	ok( a.length() == 0, "Passed!" );
-	a.setLength( y );
-	ok( a.length() == 0, "Passed!" );
-});
-
-test( "lerp/clone", function() {
-	var a = new THREE.Vector2( x, 0 );
-	var b = new THREE.Vector2( 0, -y );
-
-	ok( a.lerp( a, 0 ).equals( a.lerp( a, 0.5 ) ), "Passed!" );
-	ok( a.lerp( a, 0 ).equals( a.lerp( a, 1 ) ), "Passed!" );
-
-	ok( a.clone().lerp( b, 0 ).equals( a ), "Passed!" );
-
-	ok( a.clone().lerp( b, 0.5 ).x == x*0.5, "Passed!" );
-	ok( a.clone().lerp( b, 0.5 ).y == -y*0.5, "Passed!" );
-
-	ok( a.clone().lerp( b, 1 ).equals( b ), "Passed!" );
-});
-
-test( "equals", function() {
-	var a = new THREE.Vector2( x, 0 );
-	var b = new THREE.Vector2( 0, -y );
-
-	ok( a.x != b.x, "Passed!" );
-	ok( a.y != b.y, "Passed!" );
-
-	ok( ! a.equals( b ), "Passed!" );
-	ok( ! b.equals( a ), "Passed!" );
-
-	a.copy( b );
-	ok( a.x == b.x, "Passed!" );
-	ok( a.y == b.y, "Passed!" );
-
-	ok( a.equals( b ), "Passed!" );
-	ok( b.equals( a ), "Passed!" );
-});

+ 0 - 379
test/unit/math/Vector3.js

@@ -1,379 +0,0 @@
-/**
- * @author bhouston / http://exocortex.com
- */
-
-module( "Vector3" );
-
-test( "constructor", function() {
-	var a = new THREE.Vector3();
-	ok( a.x == 0, "Passed!" );
-	ok( a.y == 0, "Passed!" );
-	ok( a.z == 0, "Passed!" );
-
-	a = new THREE.Vector3( x, y, z );
-	ok( a.x === x, "Passed!" );
-	ok( a.y === y, "Passed!" );
-	ok( a.z === z, "Passed!" );
-});
-
-test( "copy", function() {
-	var a = new THREE.Vector3( x, y, z );
-	var b = new THREE.Vector3().copy( a );
-	ok( b.x == x, "Passed!" );
-	ok( b.y == y, "Passed!" );
-	ok( b.z == z, "Passed!" );
-
-	// ensure that it is a true copy
-	a.x = 0;
-	a.y = -1;
-	a.z = -2;
-	ok( b.x == x, "Passed!" );
-	ok( b.y == y, "Passed!" );
-	ok( b.z == z, "Passed!" );
-});
-
-test( "set", function() {
-	var a = new THREE.Vector3();
-	ok( a.x == 0, "Passed!" );
-	ok( a.y == 0, "Passed!" );
-	ok( a.z == 0, "Passed!" );
-
-	a.set( x, y, z );
-	ok( a.x == x, "Passed!" );
-	ok( a.y == y, "Passed!" );
-	ok( a.z == z, "Passed!" );
-});
-
-test( "setX,setY,setZ", function() {
-	var a = new THREE.Vector3();
-	ok( a.x == 0, "Passed!" );
-	ok( a.y == 0, "Passed!" );
-	ok( a.z == 0, "Passed!" );
-
-	a.setX( x );
-	a.setY( y );
-	a.setZ( z );
-
-	ok( a.x == x, "Passed!" );
-	ok( a.y == y, "Passed!" );
-	ok( a.z == z, "Passed!" );
-});
-
-test( "setComponent,getComponent", function() {
-	var a = new THREE.Vector3();
-	ok( a.x == 0, "Passed!" );
-	ok( a.y == 0, "Passed!" );
-	ok( a.z == 0, "Passed!" );
-
-	a.setComponent( 0, 1 );
-	a.setComponent( 1, 2 );
-	a.setComponent( 2, 3 );
-	ok( a.getComponent( 0 ) == 1, "Passed!" );
-	ok( a.getComponent( 1 ) == 2, "Passed!" );
-	ok( a.getComponent( 2 ) == 3, "Passed!" );
-});
-
-test( "add", function() {
-	var a = new THREE.Vector3( x, y, z );
-	var b = new THREE.Vector3( -x, -y, -z );
-
-	a.add( b );
-	ok( a.x == 0, "Passed!" );
-	ok( a.y == 0, "Passed!" );
-	ok( a.z == 0, "Passed!" );
-
-	var c = new THREE.Vector3().addVectors( b, b );
-	ok( c.x == -2*x, "Passed!" );
-	ok( c.y == -2*y, "Passed!" );
-	ok( c.z == -2*z, "Passed!" );
-});
-
-test( "sub", function() {
-	var a = new THREE.Vector3( x, y, z );
-	var b = new THREE.Vector3( -x, -y, -z );
-
-	a.sub( b );
-	ok( a.x == 2*x, "Passed!" );
-	ok( a.y == 2*y, "Passed!" );
-	ok( a.z == 2*z, "Passed!" );
-
-	var c = new THREE.Vector3().subVectors( a, a );
-	ok( c.x == 0, "Passed!" );
-	ok( c.y == 0, "Passed!" );
-	ok( c.z == 0, "Passed!" );
-});
-
-test( "multiply/divide", function() {
-	var a = new THREE.Vector3( x, y, z );
-	var b = new THREE.Vector3( -x, -y, -z );
-
-	a.multiplyScalar( -2 );
-	ok( a.x == x*-2, "Passed!" );
-	ok( a.y == y*-2, "Passed!" );
-	ok( a.z == z*-2, "Passed!" );
-
-	b.multiplyScalar( -2 );
-	ok( b.x == 2*x, "Passed!" );
-	ok( b.y == 2*y, "Passed!" );
-	ok( b.z == 2*z, "Passed!" );
-
-	a.divideScalar( -2 );
-	ok( a.x == x, "Passed!" );
-	ok( a.y == y, "Passed!" );
-	ok( a.z == z, "Passed!" );
-
-	b.divideScalar( -2 );
-	ok( b.x == -x, "Passed!" );
-	ok( b.y == -y, "Passed!" );
-	ok( b.z == -z, "Passed!" );
-});
-
-test( "min/max/clamp", function() {
-	var a = new THREE.Vector3( x, y, z );
-	var b = new THREE.Vector3( -x, -y, -z );
-	var c = new THREE.Vector3();
-
-	c.copy( a ).min( b );
-	ok( c.x == -x, "Passed!" );
-	ok( c.y == -y, "Passed!" );
-	ok( c.z == -z, "Passed!" );
-
-	c.copy( a ).max( b );
-	ok( c.x == x, "Passed!" );
-	ok( c.y == y, "Passed!" );
-	ok( c.z == z, "Passed!" );
-
-	c.set( -2*x, 2*y, -2*z );
-	c.clamp( b, a );
-	ok( c.x == -x, "Passed!" );
-	ok( c.y == y, "Passed!" );
-	ok( c.z == -z, "Passed!" );
-});
-
-test( "negate", function() {
-	var a = new THREE.Vector3( x, y, z );
-
-	a.negate();
-	ok( a.x == -x, "Passed!" );
-	ok( a.y == -y, "Passed!" );
-	ok( a.z == -z, "Passed!" );
-});
-
-test( "dot", function() {
-	var a = new THREE.Vector3( x, y, z );
-	var b = new THREE.Vector3( -x, -y, -z );
-	var c = new THREE.Vector3();
-
-	var result = a.dot( b );
-	ok( result == (-x*x-y*y-z*z), "Passed!" );
-
-	result = a.dot( c );
-	ok( result == 0, "Passed!" );
-});
-
-test( "length/lengthSq", function() {
-	var a = new THREE.Vector3( x, 0, 0 );
-	var b = new THREE.Vector3( 0, -y, 0 );
-	var c = new THREE.Vector3( 0, 0, z );
-	var d = new THREE.Vector3();
-
-	ok( a.length() == x, "Passed!" );
-	ok( a.lengthSq() == x*x, "Passed!" );
-	ok( b.length() == y, "Passed!" );
-	ok( b.lengthSq() == y*y, "Passed!" );
-	ok( c.length() == z, "Passed!" );
-	ok( c.lengthSq() == z*z, "Passed!" );
-	ok( d.length() == 0, "Passed!" );
-	ok( d.lengthSq() == 0, "Passed!" );
-
-	a.set( x, y, z );
-	ok( a.length() == Math.sqrt( x*x + y*y + z*z ), "Passed!" );
-	ok( a.lengthSq() == ( x*x + y*y + z*z ), "Passed!" );
-});
-
-test( "normalize", function() {
-	var a = new THREE.Vector3( x, 0, 0 );
-	var b = new THREE.Vector3( 0, -y, 0 );
-	var c = new THREE.Vector3( 0, 0, z );
-
-	a.normalize();
-	ok( a.length() == 1, "Passed!" );
-	ok( a.x == 1, "Passed!" );
-
-	b.normalize();
-	ok( b.length() == 1, "Passed!" );
-	ok( b.y == -1, "Passed!" );
-
-	c.normalize();
-	ok( c.length() == 1, "Passed!" );
-	ok( c.z == 1, "Passed!" );
-});
-
-test( "distanceTo/distanceToSquared", function() {
-	var a = new THREE.Vector3( x, 0, 0 );
-	var b = new THREE.Vector3( 0, -y, 0 );
-	var c = new THREE.Vector3( 0, 0, z );
-	var d = new THREE.Vector3();
-
-	ok( a.distanceTo( d ) == x, "Passed!" );
-	ok( a.distanceToSquared( d ) == x*x, "Passed!" );
-
-	ok( b.distanceTo( d ) == y, "Passed!" );
-	ok( b.distanceToSquared( d ) == y*y, "Passed!" );
-
-	ok( c.distanceTo( d ) == z, "Passed!" );
-	ok( c.distanceToSquared( d ) == z*z, "Passed!" );
-});
-
-test( "setLength", function() {
-	var a = new THREE.Vector3( x, 0, 0 );
-
-	ok( a.length() == x, "Passed!" );
-	a.setLength( y );
-	ok( a.length() == y, "Passed!" );
-
-	a = new THREE.Vector3( 0, 0, 0 );
-	ok( a.length() == 0, "Passed!" );
-	a.setLength( y );
-	ok( a.length() == 0, "Passed!" );
-
-});
-
-test( "projectOnVector", function() {
-	var a = new THREE.Vector3( 1, 0, 0 );
-	var b = new THREE.Vector3();
-	var normal = new THREE.Vector3( 10, 0, 0 );
-
-	ok( b.copy( a ).projectOnVector( normal ).equals( new THREE.Vector3( 1, 0, 0 ) ), "Passed!" );
-
-	a.set( 0, 1, 0 );
-	ok( b.copy( a ).projectOnVector( normal ).equals( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
-
-	a.set( 0, 0, -1 );
-	ok( b.copy( a ).projectOnVector( normal ).equals( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
-
-	a.set( -1, 0, 0 );
-	ok( b.copy( a ).projectOnVector( normal ).equals( new THREE.Vector3( -1, 0, 0 ) ), "Passed!" );
-
-});
-
-test( "projectOnPlane", function() {
-	var a = new THREE.Vector3( 1, 0, 0 );
-	var b = new THREE.Vector3();
-	var normal = new THREE.Vector3( 1, 0, 0 );
-
-	ok( b.copy( a ).projectOnPlane( normal ).equals( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
-
-	a.set( 0, 1, 0 );
-	ok( b.copy( a ).projectOnPlane( normal ).equals( new THREE.Vector3( 0, 1, 0 ) ), "Passed!" );
-
-	a.set( 0, 0, -1 );
-	ok( b.copy( a ).projectOnPlane( normal ).equals( new THREE.Vector3( 0, 0, -1 ) ), "Passed!" );
-
-	a.set( -1, 0, 0 );
-	ok( b.copy( a ).projectOnPlane( normal ).equals( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
-
-});
-
-test( "reflect", function() {
-	var a = new THREE.Vector3();
-	var normal = new THREE.Vector3( 0, 1, 0 );
-	var b = new THREE.Vector3();
-
-	a.set( 0, -1, 0 );
-	ok( b.copy( a ).reflect( normal ).equals( new THREE.Vector3( 0, 1, 0 ) ), "Passed!" );
-
-	a.set( 1, -1, 0 );
-	ok( b.copy( a ).reflect( normal ).equals( new THREE.Vector3( 1, 1, 0 ) ), "Passed!" );
-
-	a.set( 1, -1, 0 );
-	normal.set( 0, -1, 0 );
-	ok( b.copy( a ).reflect( normal ).equals( new THREE.Vector3( 1, 1, 0 ) ), "Passed!" );
-});
-
-test( "angleTo", function() {
-	var a = new THREE.Vector3( 0, -0.18851655680720186, 0.9820700116639124 );
-	var b = new THREE.Vector3( 0, 0.18851655680720186, -0.9820700116639124 );
-
-	equal( a.angleTo( a ), 0 );
-	equal( a.angleTo( b ), Math.PI );
-
-	var x = new THREE.Vector3( 1, 0, 0 );
-	var y = new THREE.Vector3( 0, 1, 0 );
-	var z = new THREE.Vector3( 0, 0, 1 );
-
-	equal( x.angleTo( y ), Math.PI / 2 );
-	equal( x.angleTo( z ), Math.PI / 2 );
-	equal( z.angleTo( x ), Math.PI / 2 );
-
-	ok( Math.abs( x.angleTo( new THREE.Vector3( 1, 1, 0 ) ) - ( Math.PI / 4 ) ) < 0.0000001 );
-});
-
-test( "lerp/clone", function() {
-	var a = new THREE.Vector3( x, 0, z );
-	var b = new THREE.Vector3( 0, -y, 0 );
-
-	ok( a.lerp( a, 0 ).equals( a.lerp( a, 0.5 ) ), "Passed!" );
-	ok( a.lerp( a, 0 ).equals( a.lerp( a, 1 ) ), "Passed!" );
-
-	ok( a.clone().lerp( b, 0 ).equals( a ), "Passed!" );
-
-	ok( a.clone().lerp( b, 0.5 ).x == x*0.5, "Passed!" );
-	ok( a.clone().lerp( b, 0.5 ).y == -y*0.5, "Passed!" );
-	ok( a.clone().lerp( b, 0.5 ).z == z*0.5, "Passed!" );
-
-	ok( a.clone().lerp( b, 1 ).equals( b ), "Passed!" );
-});
-
-test( "equals", function() {
-	var a = new THREE.Vector3( x, 0, z );
-	var b = new THREE.Vector3( 0, -y, 0 );
-
-	ok( a.x != b.x, "Passed!" );
-	ok( a.y != b.y, "Passed!" );
-	ok( a.z != b.z, "Passed!" );
-
-	ok( ! a.equals( b ), "Passed!" );
-	ok( ! b.equals( a ), "Passed!" );
-
-	a.copy( b );
-	ok( a.x == b.x, "Passed!" );
-	ok( a.y == b.y, "Passed!" );
-	ok( a.z == b.z, "Passed!" );
-
-	ok( a.equals( b ), "Passed!" );
-	ok( b.equals( a ), "Passed!" );
-});
-
-test( "applyMatrix4", function() {
-
-	var a = new THREE.Vector3( x, y, z );
-	var b = new THREE.Vector4( x, y, z, 1 );
-
-	var m = new THREE.Matrix4().makeRotationX( Math.PI );
-	a.applyMatrix4( m );
-	b.applyMatrix4( m );
-	ok( a.x == b.x / b.w, "Passed!" );
-	ok( a.y == b.y / b.w, "Passed!" );
-	ok( a.z == b.z / b.w, "Passed!" );
-
-	m = new THREE.Matrix4().makeTranslation( 3, 2, 1 );
-	a.applyMatrix4( m );
-	b.applyMatrix4( m );
-	ok( a.x == b.x / b.w, "Passed!" );
-	ok( a.y == b.y / b.w, "Passed!" );
-	ok( a.z == b.z / b.w, "Passed!" );
-
-	m = new THREE.Matrix4().set(
-		1, 0, 0, 0,
-		0, 1, 0, 0,
-		0, 0, 1, 0,
-		0, 0, 1, 0
-	);
-	a.applyMatrix4( m );
-	b.applyMatrix4( m );
-	ok( a.x == b.x / b.w, "Passed!" );
-	ok( a.y == b.y / b.w, "Passed!" );
-	ok( a.z == b.z / b.w, "Passed!" );
-
-});

+ 0 - 318
test/unit/math/Vector4.js

@@ -1,318 +0,0 @@
-/**
- * @author bhouston / http://exocortex.com
- */
-
-module( "Vector4" );
-
-test( "constructor", function() {
-	var a = new THREE.Vector4();
-	ok( a.x == 0, "Passed!" );
-	ok( a.y == 0, "Passed!" );
-	ok( a.z == 0, "Passed!" );
-	ok( a.w == 1, "Passed!" );
-
-	a = new THREE.Vector4( x, y, z, w );
-	ok( a.x === x, "Passed!" );
-	ok( a.y === y, "Passed!" );
-	ok( a.z === z, "Passed!" );
-	ok( a.w === w, "Passed!" );
-});
-
-test( "copy", function() {
-	var a = new THREE.Vector4( x, y, z, w );
-	var b = new THREE.Vector4().copy( a );
-	ok( b.x == x, "Passed!" );
-	ok( b.y == y, "Passed!" );
-	ok( b.z == z, "Passed!" );
-	ok( b.w == w, "Passed!" );
-
-	// ensure that it is a true copy
-	a.x = 0;
-	a.y = -1;
-	a.z = -2;
-	a.w = -3;
-	ok( b.x == x, "Passed!" );
-	ok( b.y == y, "Passed!" );
-	ok( b.z == z, "Passed!" );
-	ok( b.w == w, "Passed!" );
-});
-
-test( "set", function() {
-	var a = new THREE.Vector4();
-	ok( a.x == 0, "Passed!" );
-	ok( a.y == 0, "Passed!" );
-	ok( a.z == 0, "Passed!" );
-	ok( a.w == 1, "Passed!" );
-
-	a.set( x, y, z, w );
-	ok( a.x == x, "Passed!" );
-	ok( a.y == y, "Passed!" );
-	ok( a.z == z, "Passed!" );
-	ok( a.w == w, "Passed!" );
-});
-
-test( "setX,setY,setZ,setW", function() {
-	var a = new THREE.Vector4();
-	ok( a.x == 0, "Passed!" );
-	ok( a.y == 0, "Passed!" );
-	ok( a.z == 0, "Passed!" );
-	ok( a.w == 1, "Passed!" );
-
-	a.setX( x );
-	a.setY( y );
-	a.setZ( z );
-	a.setW( w );
-
-	ok( a.x == x, "Passed!" );
-	ok( a.y == y, "Passed!" );
-	ok( a.z == z, "Passed!" );
-	ok( a.w == w, "Passed!" );
-});
-
-test( "setComponent,getComponent", function() {
-	var a = new THREE.Vector4();
-	ok( a.x == 0, "Passed!" );
-	ok( a.y == 0, "Passed!" );
-	ok( a.z == 0, "Passed!" );
-	ok( a.w == 1, "Passed!" );
-
-	a.setComponent( 0, 1 );
-	a.setComponent( 1, 2 );
-	a.setComponent( 2, 3 );
-	a.setComponent( 3, 4 );
-	ok( a.getComponent( 0 ) == 1, "Passed!" );
-	ok( a.getComponent( 1 ) == 2, "Passed!" );
-	ok( a.getComponent( 2 ) == 3, "Passed!" );
-	ok( a.getComponent( 3 ) == 4, "Passed!" );
-});
-
-test( "add", function() {
-	var a = new THREE.Vector4( x, y, z, w );
-	var b = new THREE.Vector4( -x, -y, -z, -w );
-
-	a.add( b );
-	ok( a.x == 0, "Passed!" );
-	ok( a.y == 0, "Passed!" );
-	ok( a.z == 0, "Passed!" );
-	ok( a.w == 0, "Passed!" );
-
-	var c = new THREE.Vector4().addVectors( b, b );
-	ok( c.x == -2*x, "Passed!" );
-	ok( c.y == -2*y, "Passed!" );
-	ok( c.z == -2*z, "Passed!" );
-	ok( c.w == -2*w, "Passed!" );
-});
-
-test( "sub", function() {
-	var a = new THREE.Vector4( x, y, z, w );
-	var b = new THREE.Vector4( -x, -y, -z, -w );
-
-	a.sub( b );
-	ok( a.x == 2*x, "Passed!" );
-	ok( a.y == 2*y, "Passed!" );
-	ok( a.z == 2*z, "Passed!" );
-	ok( a.w == 2*w, "Passed!" );
-
-	var c = new THREE.Vector4().subVectors( a, a );
-	ok( c.x == 0, "Passed!" );
-	ok( c.y == 0, "Passed!" );
-	ok( c.z == 0, "Passed!" );
-	ok( c.w == 0, "Passed!" );
-});
-
-test( "multiply/divide", function() {
-	var a = new THREE.Vector4( x, y, z, w );
-	var b = new THREE.Vector4( -x, -y, -z, -w );
-
-	a.multiplyScalar( -2 );
-	ok( a.x == x*-2, "Passed!" );
-	ok( a.y == y*-2, "Passed!" );
-	ok( a.z == z*-2, "Passed!" );
-	ok( a.w == w*-2, "Passed!" );
-
-	b.multiplyScalar( -2 );
-	ok( b.x == 2*x, "Passed!" );
-	ok( b.y == 2*y, "Passed!" );	
-	ok( b.z == 2*z, "Passed!" );	
-	ok( b.w == 2*w, "Passed!" );	
-
-	a.divideScalar( -2 );
-	ok( a.x == x, "Passed!" );
-	ok( a.y == y, "Passed!" );
-	ok( a.z == z, "Passed!" );
-	ok( a.w == w, "Passed!" );
-
-	b.divideScalar( -2 );
-	ok( b.x == -x, "Passed!" );
-	ok( b.y == -y, "Passed!" );
-	ok( b.z == -z, "Passed!" );
-	ok( b.w == -w, "Passed!" );
-});
-
-test( "min/max/clamp", function() {
-	var a = new THREE.Vector4( x, y, z, w );
-	var b = new THREE.Vector4( -x, -y, -z, -w );
-	var c = new THREE.Vector4();
-
-	c.copy( a ).min( b );
-	ok( c.x == -x, "Passed!" );
-	ok( c.y == -y, "Passed!" );
-	ok( c.z == -z, "Passed!" );
-	ok( c.w == -w, "Passed!" );
-
-	c.copy( a ).max( b );
-	ok( c.x == x, "Passed!" );
-	ok( c.y == y, "Passed!" );
-	ok( c.z == z, "Passed!" );
-	ok( c.w == w, "Passed!" );
-
-	c.set( -2*x, 2*y, -2*z, 2*w );
-	c.clamp( b, a );
-	ok( c.x == -x, "Passed!" );
-	ok( c.y == y, "Passed!" );
-	ok( c.z == -z, "Passed!" );
-	ok( c.w == w, "Passed!" );
-});
-
-test( "negate", function() {
-	var a = new THREE.Vector4( x, y, z, w );
-
-	a.negate();
-	ok( a.x == -x, "Passed!" );
-	ok( a.y == -y, "Passed!" );
-	ok( a.z == -z, "Passed!" );
-	ok( a.w == -w, "Passed!" );
-});
-
-test( "dot", function() {
-	var a = new THREE.Vector4( x, y, z, w );
-	var b = new THREE.Vector4( -x, -y, -z, -w );
-	var c = new THREE.Vector4( 0, 0, 0, 0 );
-
-	var result = a.dot( b );
-	ok( result == (-x*x-y*y-z*z-w*w), "Passed!" );
-
-	result = a.dot( c );
-	ok( result == 0, "Passed!" );
-});
-
-test( "length/lengthSq", function() {
-	var a = new THREE.Vector4( x, 0, 0, 0 );
-	var b = new THREE.Vector4( 0, -y, 0, 0 );
-	var c = new THREE.Vector4( 0, 0, z, 0 );
-	var d = new THREE.Vector4( 0, 0, 0, w );
-	var e = new THREE.Vector4( 0, 0, 0, 0 );
-	
-	ok( a.length() == x, "Passed!" );
-	ok( a.lengthSq() == x*x, "Passed!" );
-	ok( b.length() == y, "Passed!" );
-	ok( b.lengthSq() == y*y, "Passed!" );
-	ok( c.length() == z, "Passed!" );
-	ok( c.lengthSq() == z*z, "Passed!" );
-	ok( d.length() == w, "Passed!" );
-	ok( d.lengthSq() == w*w, "Passed!" );
-	ok( e.length() == 0, "Passed!" );
-	ok( e.lengthSq() == 0, "Passed!" );
-
-	a.set( x, y, z, w );
-	ok( a.length() == Math.sqrt( x*x + y*y + z*z + w*w ), "Passed!" );
-	ok( a.lengthSq() == ( x*x + y*y + z*z + w*w ), "Passed!" );
-});
-
-test( "normalize", function() {
-	var a = new THREE.Vector4( x, 0, 0, 0 );
-	var b = new THREE.Vector4( 0, -y, 0, 0 );
-	var c = new THREE.Vector4( 0, 0, z, 0 );
-	var d = new THREE.Vector4( 0, 0, 0, -w );
-	
-	a.normalize();
-	ok( a.length() == 1, "Passed!" );
-	ok( a.x == 1, "Passed!" );
-
-	b.normalize();
-	ok( b.length() == 1, "Passed!" );
-	ok( b.y == -1, "Passed!" );
-
-	c.normalize();
-	ok( c.length() == 1, "Passed!" );
-	ok( c.z == 1, "Passed!" );
-
-	d.normalize();
-	ok( d.length() == 1, "Passed!" );
-	ok( d.w == -1, "Passed!" );
-});
-
-/*
-test( "distanceTo/distanceToSquared", function() {
-	var a = new THREE.Vector4( x, 0, 0, 0 );
-	var b = new THREE.Vector4( 0, -y, 0, 0 );
-	var c = new THREE.Vector4( 0, 0, z, 0 );
-	var d = new THREE.Vector4( 0, 0, 0, -w );
-	var e = new THREE.Vector4();
-	
-	ok( a.distanceTo( e ) == x, "Passed!" );
-	ok( a.distanceToSquared( e ) == x*x, "Passed!" );
-
-	ok( b.distanceTo( e ) == y, "Passed!" );
-	ok( b.distanceToSquared( e ) == y*y, "Passed!" );
-
-	ok( c.distanceTo( e ) == z, "Passed!" );
-	ok( c.distanceToSquared( e ) == z*z, "Passed!" );
-
-	ok( d.distanceTo( e ) == w, "Passed!" );
-	ok( d.distanceToSquared( e ) == w*w, "Passed!" );
-});
-*/
-
-
-test( "setLength", function() {
-	var a = new THREE.Vector4( x, 0, 0, 0 );
-
-	ok( a.length() == x, "Passed!" );
-	a.setLength( y );
-	ok( a.length() == y, "Passed!" );
-
-	a = new THREE.Vector4( 0, 0, 0, 0 );
-	ok( a.length() == 0, "Passed!" );
-	a.setLength( y );
-	ok( a.length() == 0, "Passed!" );
-});
-
-test( "lerp/clone", function() {
-	var a = new THREE.Vector4( x, 0, z, 0 );
-	var b = new THREE.Vector4( 0, -y, 0, -w );
-
-	ok( a.lerp( a, 0 ).equals( a.lerp( a, 0.5 ) ), "Passed!" );
-	ok( a.lerp( a, 0 ).equals( a.lerp( a, 1 ) ), "Passed!" );
-
-	ok( a.clone().lerp( b, 0 ).equals( a ), "Passed!" );
-
-	ok( a.clone().lerp( b, 0.5 ).x == x*0.5, "Passed!" );
-	ok( a.clone().lerp( b, 0.5 ).y == -y*0.5, "Passed!" );
-	ok( a.clone().lerp( b, 0.5 ).z == z*0.5, "Passed!" );
-	ok( a.clone().lerp( b, 0.5 ).w == -w*0.5, "Passed!" );
-
-	ok( a.clone().lerp( b, 1 ).equals( b ), "Passed!" );
-});
-
-test( "equals", function() {
-	var a = new THREE.Vector4( x, 0, z, 0 );
-	var b = new THREE.Vector4( 0, -y, 0, -w );
-
-	ok( a.x != b.x, "Passed!" );
-	ok( a.y != b.y, "Passed!" );
-	ok( a.z != b.z, "Passed!" );
-	ok( a.w != b.w, "Passed!" );
-
-	ok( ! a.equals( b ), "Passed!" );
-	ok( ! b.equals( a ), "Passed!" );
-
-	a.copy( b );
-	ok( a.x == b.x, "Passed!" );
-	ok( a.y == b.y, "Passed!" );
-	ok( a.z == b.z, "Passed!" );
-	ok( a.w == b.w, "Passed!" );
-
-	ok( a.equals( b ), "Passed!" );
-	ok( b.equals( a ), "Passed!" );
-});

+ 0 - 291
test/unit/qunit-1.18.0.css

@@ -1,291 +0,0 @@
-/*!
- * QUnit 1.18.0
- * http://qunitjs.com/
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2015-04-03T10:23Z
- */
-
-/** Font Family and Sizes */
-
-#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
-	font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
-}
-
-#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
-#qunit-tests { font-size: smaller; }
-
-
-/** Resets */
-
-#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
-	margin: 0;
-	padding: 0;
-}
-
-
-/** Header */
-
-#qunit-header {
-	padding: 0.5em 0 0.5em 1em;
-
-	color: #8699A4;
-	background-color: #0D3349;
-
-	font-size: 1.5em;
-	line-height: 1em;
-	font-weight: 400;
-
-	border-radius: 5px 5px 0 0;
-}
-
-#qunit-header a {
-	text-decoration: none;
-	color: #C2CCD1;
-}
-
-#qunit-header a:hover,
-#qunit-header a:focus {
-	color: #FFF;
-}
-
-#qunit-testrunner-toolbar label {
-	display: inline-block;
-	padding: 0 0.5em 0 0.1em;
-}
-
-#qunit-banner {
-	height: 5px;
-}
-
-#qunit-testrunner-toolbar {
-	padding: 0.5em 1em 0.5em 1em;
-	color: #5E740B;
-	background-color: #EEE;
-	overflow: hidden;
-}
-
-#qunit-userAgent {
-	padding: 0.5em 1em 0.5em 1em;
-	background-color: #2B81AF;
-	color: #FFF;
-	text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
-}
-
-#qunit-modulefilter-container {
-	float: right;
-	padding: 0.2em;
-}
-
-.qunit-url-config {
-	display: inline-block;
-	padding: 0.1em;
-}
-
-.qunit-filter {
-	display: block;
-	float: right;
-	margin-left: 1em;
-}
-
-/** Tests: Pass/Fail */
-
-#qunit-tests {
-	list-style-position: inside;
-}
-
-#qunit-tests li {
-	padding: 0.4em 1em 0.4em 1em;
-	border-bottom: 1px solid #FFF;
-	list-style-position: inside;
-}
-
-#qunit-tests > li {
-	display: none;
-}
-
-#qunit-tests li.running,
-#qunit-tests li.pass,
-#qunit-tests li.fail,
-#qunit-tests li.skipped {
-	display: list-item;
-}
-
-#qunit-tests.hidepass li.running,
-#qunit-tests.hidepass li.pass {
-	visibility: hidden;
-	position: absolute;
-	width:   0px;
-	height:  0px;
-	padding: 0;
-	border:  0;
-	margin:  0;
-}
-
-#qunit-tests li strong {
-	cursor: pointer;
-}
-
-#qunit-tests li.skipped strong {
-	cursor: default;
-}
-
-#qunit-tests li a {
-	padding: 0.5em;
-	color: #C2CCD1;
-	text-decoration: none;
-}
-
-#qunit-tests li p a {
-	padding: 0.25em;
-	color: #6B6464;
-}
-#qunit-tests li a:hover,
-#qunit-tests li a:focus {
-	color: #000;
-}
-
-#qunit-tests li .runtime {
-	float: right;
-	font-size: smaller;
-}
-
-.qunit-assert-list {
-	margin-top: 0.5em;
-	padding: 0.5em;
-
-	background-color: #FFF;
-
-	border-radius: 5px;
-}
-
-.qunit-collapsed {
-	display: none;
-}
-
-#qunit-tests table {
-	border-collapse: collapse;
-	margin-top: 0.2em;
-}
-
-#qunit-tests th {
-	text-align: right;
-	vertical-align: top;
-	padding: 0 0.5em 0 0;
-}
-
-#qunit-tests td {
-	vertical-align: top;
-}
-
-#qunit-tests pre {
-	margin: 0;
-	white-space: pre-wrap;
-	word-wrap: break-word;
-}
-
-#qunit-tests del {
-	background-color: #E0F2BE;
-	color: #374E0C;
-	text-decoration: none;
-}
-
-#qunit-tests ins {
-	background-color: #FFCACA;
-	color: #500;
-	text-decoration: none;
-}
-
-/*** Test Counts */
-
-#qunit-tests b.counts                       { color: #000; }
-#qunit-tests b.passed                       { color: #5E740B; }
-#qunit-tests b.failed                       { color: #710909; }
-
-#qunit-tests li li {
-	padding: 5px;
-	background-color: #FFF;
-	border-bottom: none;
-	list-style-position: inside;
-}
-
-/*** Passing Styles */
-
-#qunit-tests li li.pass {
-	color: #3C510C;
-	background-color: #FFF;
-	border-left: 10px solid #C6E746;
-}
-
-#qunit-tests .pass                          { color: #528CE0; background-color: #D2E0E6; }
-#qunit-tests .pass .test-name               { color: #366097; }
-
-#qunit-tests .pass .test-actual,
-#qunit-tests .pass .test-expected           { color: #999; }
-
-#qunit-banner.qunit-pass                    { background-color: #C6E746; }
-
-/*** Failing Styles */
-
-#qunit-tests li li.fail {
-	color: #710909;
-	background-color: #FFF;
-	border-left: 10px solid #EE5757;
-	white-space: pre;
-}
-
-#qunit-tests > li:last-child {
-	border-radius: 0 0 5px 5px;
-}
-
-#qunit-tests .fail                          { color: #000; background-color: #EE5757; }
-#qunit-tests .fail .test-name,
-#qunit-tests .fail .module-name             { color: #000; }
-
-#qunit-tests .fail .test-actual             { color: #EE5757; }
-#qunit-tests .fail .test-expected           { color: #008000; }
-
-#qunit-banner.qunit-fail                    { background-color: #EE5757; }
-
-/*** Skipped tests */
-
-#qunit-tests .skipped {
-	background-color: #EBECE9;
-}
-
-#qunit-tests .qunit-skipped-label {
-	background-color: #F4FF77;
-	display: inline-block;
-	font-style: normal;
-	color: #366097;
-	line-height: 1.8em;
-	padding: 0 0.5em;
-	margin: -0.4em 0.4em -0.4em 0;
-}
-
-/** Result */
-
-#qunit-testresult {
-	padding: 0.5em 1em 0.5em 1em;
-
-	color: #2B81AF;
-	background-color: #D2E0E6;
-
-	border-bottom: 1px solid #FFF;
-}
-#qunit-testresult .module-name {
-	font-weight: 700;
-}
-
-/** Fixture */
-
-#qunit-fixture {
-	position: absolute;
-	top: -10000px;
-	left: -10000px;
-	width: 1000px;
-	height: 1000px;
-}

+ 0 - 3829
test/unit/qunit-1.18.0.js

@@ -1,3829 +0,0 @@
-/*!
- * QUnit 1.18.0
- * http://qunitjs.com/
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2015-04-03T10:23Z
- */
-
-(function( window ) {
-
-var QUnit,
-	config,
-	onErrorFnPrev,
-	loggingCallbacks = {},
-	fileName = ( sourceFromStacktrace( 0 ) || "" ).replace( /(:\d+)+\)?/, "" ).replace( /.+\//, "" ),
-	toString = Object.prototype.toString,
-	hasOwn = Object.prototype.hasOwnProperty,
-	// Keep a local reference to Date (GH-283)
-	Date = window.Date,
-	now = Date.now || function() {
-		return new Date().getTime();
-	},
-	globalStartCalled = false,
-	runStarted = false,
-	setTimeout = window.setTimeout,
-	clearTimeout = window.clearTimeout,
-	defined = {
-		document: window.document !== undefined,
-		setTimeout: window.setTimeout !== undefined,
-		sessionStorage: (function() {
-			var x = "qunit-test-string";
-			try {
-				sessionStorage.setItem( x, x );
-				sessionStorage.removeItem( x );
-				return true;
-			} catch ( e ) {
-				return false;
-			}
-		}())
-	},
-	/**
-	 * Provides a normalized error string, correcting an issue
-	 * with IE 7 (and prior) where Error.prototype.toString is
-	 * not properly implemented
-	 *
-	 * Based on http://es5.github.com/#x15.11.4.4
-	 *
-	 * @param {String|Error} error
-	 * @return {String} error message
-	 */
-	errorString = function( error ) {
-		var name, message,
-			errorString = error.toString();
-		if ( errorString.substring( 0, 7 ) === "[object" ) {
-			name = error.name ? error.name.toString() : "Error";
-			message = error.message ? error.message.toString() : "";
-			if ( name && message ) {
-				return name + ": " + message;
-			} else if ( name ) {
-				return name;
-			} else if ( message ) {
-				return message;
-			} else {
-				return "Error";
-			}
-		} else {
-			return errorString;
-		}
-	},
-	/**
-	 * Makes a clone of an object using only Array or Object as base,
-	 * and copies over the own enumerable properties.
-	 *
-	 * @param {Object} obj
-	 * @return {Object} New object with only the own properties (recursively).
-	 */
-	objectValues = function( obj ) {
-		var key, val,
-			vals = QUnit.is( "array", obj ) ? [] : {};
-		for ( key in obj ) {
-			if ( hasOwn.call( obj, key ) ) {
-				val = obj[ key ];
-				vals[ key ] = val === Object( val ) ? objectValues( val ) : val;
-			}
-		}
-		return vals;
-	};
-
-QUnit = {};
-
-/**
- * Config object: Maintain internal state
- * Later exposed as QUnit.config
- * `config` initialized at top of scope
- */
-config = {
-	// The queue of tests to run
-	queue: [],
-
-	// block until document ready
-	blocking: true,
-
-	// by default, run previously failed tests first
-	// very useful in combination with "Hide passed tests" checked
-	reorder: true,
-
-	// by default, modify document.title when suite is done
-	altertitle: true,
-
-	// by default, scroll to top of the page when suite is done
-	scrolltop: true,
-
-	// when enabled, all tests must call expect()
-	requireExpects: false,
-
-	// depth up-to which object will be dumped
-	maxDepth: 0,
-
-	// add checkboxes that are persisted in the query-string
-	// when enabled, the id is set to `true` as a `QUnit.config` property
-	urlConfig: [
-		{
-			id: "hidepassed",
-			label: "Hide passed tests",
-			tooltip: "Only show tests and assertions that fail. Stored as query-strings."
-		},
-		{
-			id: "noglobals",
-			label: "Check for Globals",
-			tooltip: "Enabling this will test if any test introduces new properties on the " +
-				"`window` object. Stored as query-strings."
-		},
-		{
-			id: "notrycatch",
-			label: "No try-catch",
-			tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging " +
-				"exceptions in IE reasonable. Stored as query-strings."
-		}
-	],
-
-	// Set of all modules.
-	modules: [],
-
-	// The first unnamed module
-	currentModule: {
-		name: "",
-		tests: []
-	},
-
-	callbacks: {}
-};
-
-// Push a loose unnamed module to the modules collection
-config.modules.push( config.currentModule );
-
-// Initialize more QUnit.config and QUnit.urlParams
-(function() {
-	var i, current,
-		location = window.location || { search: "", protocol: "file:" },
-		params = location.search.slice( 1 ).split( "&" ),
-		length = params.length,
-		urlParams = {};
-
-	if ( params[ 0 ] ) {
-		for ( i = 0; i < length; i++ ) {
-			current = params[ i ].split( "=" );
-			current[ 0 ] = decodeURIComponent( current[ 0 ] );
-
-			// allow just a key to turn on a flag, e.g., test.html?noglobals
-			current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
-			if ( urlParams[ current[ 0 ] ] ) {
-				urlParams[ current[ 0 ] ] = [].concat( urlParams[ current[ 0 ] ], current[ 1 ] );
-			} else {
-				urlParams[ current[ 0 ] ] = current[ 1 ];
-			}
-		}
-	}
-
-	if ( urlParams.filter === true ) {
-		delete urlParams.filter;
-	}
-
-	QUnit.urlParams = urlParams;
-
-	// String search anywhere in moduleName+testName
-	config.filter = urlParams.filter;
-
-	if ( urlParams.maxDepth ) {
-		config.maxDepth = parseInt( urlParams.maxDepth, 10 ) === -1 ?
-			Number.POSITIVE_INFINITY :
-			urlParams.maxDepth;
-	}
-
-	config.testId = [];
-	if ( urlParams.testId ) {
-
-		// Ensure that urlParams.testId is an array
-		urlParams.testId = decodeURIComponent( urlParams.testId ).split( "," );
-		for ( i = 0; i < urlParams.testId.length; i++ ) {
-			config.testId.push( urlParams.testId[ i ] );
-		}
-	}
-
-	// Figure out if we're running the tests from a server or not
-	QUnit.isLocal = location.protocol === "file:";
-
-	// Expose the current QUnit version
-	QUnit.version = "1.18.0";
-}());
-
-// Root QUnit object.
-// `QUnit` initialized at top of scope
-extend( QUnit, {
-
-	// call on start of module test to prepend name to all tests
-	module: function( name, testEnvironment ) {
-		var currentModule = {
-			name: name,
-			testEnvironment: testEnvironment,
-			tests: []
-		};
-
-		// DEPRECATED: handles setup/teardown functions,
-		// beforeEach and afterEach should be used instead
-		if ( testEnvironment && testEnvironment.setup ) {
-			testEnvironment.beforeEach = testEnvironment.setup;
-			delete testEnvironment.setup;
-		}
-		if ( testEnvironment && testEnvironment.teardown ) {
-			testEnvironment.afterEach = testEnvironment.teardown;
-			delete testEnvironment.teardown;
-		}
-
-		config.modules.push( currentModule );
-		config.currentModule = currentModule;
-	},
-
-	// DEPRECATED: QUnit.asyncTest() will be removed in QUnit 2.0.
-	asyncTest: function( testName, expected, callback ) {
-		if ( arguments.length === 2 ) {
-			callback = expected;
-			expected = null;
-		}
-
-		QUnit.test( testName, expected, callback, true );
-	},
-
-	test: function( testName, expected, callback, async ) {
-		var test;
-
-		if ( arguments.length === 2 ) {
-			callback = expected;
-			expected = null;
-		}
-
-		test = new Test({
-			testName: testName,
-			expected: expected,
-			async: async,
-			callback: callback
-		});
-
-		test.queue();
-	},
-
-	skip: function( testName ) {
-		var test = new Test({
-			testName: testName,
-			skip: true
-		});
-
-		test.queue();
-	},
-
-	// DEPRECATED: The functionality of QUnit.start() will be altered in QUnit 2.0.
-	// In QUnit 2.0, invoking it will ONLY affect the `QUnit.config.autostart` blocking behavior.
-	start: function( count ) {
-		var globalStartAlreadyCalled = globalStartCalled;
-
-		if ( !config.current ) {
-			globalStartCalled = true;
-
-			if ( runStarted ) {
-				throw new Error( "Called start() outside of a test context while already started" );
-			} else if ( globalStartAlreadyCalled || count > 1 ) {
-				throw new Error( "Called start() outside of a test context too many times" );
-			} else if ( config.autostart ) {
-				throw new Error( "Called start() outside of a test context when " +
-					"QUnit.config.autostart was true" );
-			} else if ( !config.pageLoaded ) {
-
-				// The page isn't completely loaded yet, so bail out and let `QUnit.load` handle it
-				config.autostart = true;
-				return;
-			}
-		} else {
-
-			// If a test is running, adjust its semaphore
-			config.current.semaphore -= count || 1;
-
-			// Don't start until equal number of stop-calls
-			if ( config.current.semaphore > 0 ) {
-				return;
-			}
-
-			// throw an Error if start is called more often than stop
-			if ( config.current.semaphore < 0 ) {
-				config.current.semaphore = 0;
-
-				QUnit.pushFailure(
-					"Called start() while already started (test's semaphore was 0 already)",
-					sourceFromStacktrace( 2 )
-				);
-				return;
-			}
-		}
-
-		resumeProcessing();
-	},
-
-	// DEPRECATED: QUnit.stop() will be removed in QUnit 2.0.
-	stop: function( count ) {
-
-		// If there isn't a test running, don't allow QUnit.stop() to be called
-		if ( !config.current ) {
-			throw new Error( "Called stop() outside of a test context" );
-		}
-
-		// If a test is running, adjust its semaphore
-		config.current.semaphore += count || 1;
-
-		pauseProcessing();
-	},
-
-	config: config,
-
-	// Safe object type checking
-	is: function( type, obj ) {
-		return QUnit.objectType( obj ) === type;
-	},
-
-	objectType: function( obj ) {
-		if ( typeof obj === "undefined" ) {
-			return "undefined";
-		}
-
-		// Consider: typeof null === object
-		if ( obj === null ) {
-			return "null";
-		}
-
-		var match = toString.call( obj ).match( /^\[object\s(.*)\]$/ ),
-			type = match && match[ 1 ] || "";
-
-		switch ( type ) {
-			case "Number":
-				if ( isNaN( obj ) ) {
-					return "nan";
-				}
-				return "number";
-			case "String":
-			case "Boolean":
-			case "Array":
-			case "Date":
-			case "RegExp":
-			case "Function":
-				return type.toLowerCase();
-		}
-		if ( typeof obj === "object" ) {
-			return "object";
-		}
-		return undefined;
-	},
-
-	extend: extend,
-
-	load: function() {
-		config.pageLoaded = true;
-
-		// Initialize the configuration options
-		extend( config, {
-			stats: { all: 0, bad: 0 },
-			moduleStats: { all: 0, bad: 0 },
-			started: 0,
-			updateRate: 1000,
-			autostart: true,
-			filter: ""
-		}, true );
-
-		config.blocking = false;
-
-		if ( config.autostart ) {
-			resumeProcessing();
-		}
-	}
-});
-
-// Register logging callbacks
-(function() {
-	var i, l, key,
-		callbacks = [ "begin", "done", "log", "testStart", "testDone",
-			"moduleStart", "moduleDone" ];
-
-	function registerLoggingCallback( key ) {
-		var loggingCallback = function( callback ) {
-			if ( QUnit.objectType( callback ) !== "function" ) {
-				throw new Error(
-					"QUnit logging methods require a callback function as their first parameters."
-				);
-			}
-
-			config.callbacks[ key ].push( callback );
-		};
-
-		// DEPRECATED: This will be removed on QUnit 2.0.0+
-		// Stores the registered functions allowing restoring
-		// at verifyLoggingCallbacks() if modified
-		loggingCallbacks[ key ] = loggingCallback;
-
-		return loggingCallback;
-	}
-
-	for ( i = 0, l = callbacks.length; i < l; i++ ) {
-		key = callbacks[ i ];
-
-		// Initialize key collection of logging callback
-		if ( QUnit.objectType( config.callbacks[ key ] ) === "undefined" ) {
-			config.callbacks[ key ] = [];
-		}
-
-		QUnit[ key ] = registerLoggingCallback( key );
-	}
-})();
-
-// `onErrorFnPrev` initialized at top of scope
-// Preserve other handlers
-onErrorFnPrev = window.onerror;
-
-// Cover uncaught exceptions
-// Returning true will suppress the default browser handler,
-// returning false will let it run.
-window.onerror = function( error, filePath, linerNr ) {
-	var ret = false;
-	if ( onErrorFnPrev ) {
-		ret = onErrorFnPrev( error, filePath, linerNr );
-	}
-
-	// Treat return value as window.onerror itself does,
-	// Only do our handling if not suppressed.
-	if ( ret !== true ) {
-		if ( QUnit.config.current ) {
-			if ( QUnit.config.current.ignoreGlobalErrors ) {
-				return true;
-			}
-			QUnit.pushFailure( error, filePath + ":" + linerNr );
-		} else {
-			QUnit.test( "global failure", extend(function() {
-				QUnit.pushFailure( error, filePath + ":" + linerNr );
-			}, { validTest: true } ) );
-		}
-		return false;
-	}
-
-	return ret;
-};
-
-function done() {
-	var runtime, passed;
-
-	config.autorun = true;
-
-	// Log the last module results
-	if ( config.previousModule ) {
-		runLoggingCallbacks( "moduleDone", {
-			name: config.previousModule.name,
-			tests: config.previousModule.tests,
-			failed: config.moduleStats.bad,
-			passed: config.moduleStats.all - config.moduleStats.bad,
-			total: config.moduleStats.all,
-			runtime: now() - config.moduleStats.started
-		});
-	}
-	delete config.previousModule;
-
-	runtime = now() - config.started;
-	passed = config.stats.all - config.stats.bad;
-
-	runLoggingCallbacks( "done", {
-		failed: config.stats.bad,
-		passed: passed,
-		total: config.stats.all,
-		runtime: runtime
-	});
-}
-
-// Doesn't support IE6 to IE9, it will return undefined on these browsers
-// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
-function extractStacktrace( e, offset ) {
-	offset = offset === undefined ? 4 : offset;
-
-	var stack, include, i;
-
-	if ( e.stack ) {
-		stack = e.stack.split( "\n" );
-		if ( /^error$/i.test( stack[ 0 ] ) ) {
-			stack.shift();
-		}
-		if ( fileName ) {
-			include = [];
-			for ( i = offset; i < stack.length; i++ ) {
-				if ( stack[ i ].indexOf( fileName ) !== -1 ) {
-					break;
-				}
-				include.push( stack[ i ] );
-			}
-			if ( include.length ) {
-				return include.join( "\n" );
-			}
-		}
-		return stack[ offset ];
-
-	// Support: Safari <=6 only
-	} else if ( e.sourceURL ) {
-
-		// exclude useless self-reference for generated Error objects
-		if ( /qunit.js$/.test( e.sourceURL ) ) {
-			return;
-		}
-
-		// for actual exceptions, this is useful
-		return e.sourceURL + ":" + e.line;
-	}
-}
-
-function sourceFromStacktrace( offset ) {
-	var error = new Error();
-
-	// Support: Safari <=7 only, IE <=10 - 11 only
-	// Not all browsers generate the `stack` property for `new Error()`, see also #636
-	if ( !error.stack ) {
-		try {
-			throw error;
-		} catch ( err ) {
-			error = err;
-		}
-	}
-
-	return extractStacktrace( error, offset );
-}
-
-function synchronize( callback, last ) {
-	if ( QUnit.objectType( callback ) === "array" ) {
-		while ( callback.length ) {
-			synchronize( callback.shift() );
-		}
-		return;
-	}
-	config.queue.push( callback );
-
-	if ( config.autorun && !config.blocking ) {
-		process( last );
-	}
-}
-
-function process( last ) {
-	function next() {
-		process( last );
-	}
-	var start = now();
-	config.depth = ( config.depth || 0 ) + 1;
-
-	while ( config.queue.length && !config.blocking ) {
-		if ( !defined.setTimeout || config.updateRate <= 0 ||
-				( ( now() - start ) < config.updateRate ) ) {
-			if ( config.current ) {
-
-				// Reset async tracking for each phase of the Test lifecycle
-				config.current.usedAsync = false;
-			}
-			config.queue.shift()();
-		} else {
-			setTimeout( next, 13 );
-			break;
-		}
-	}
-	config.depth--;
-	if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
-		done();
-	}
-}
-
-function begin() {
-	var i, l,
-		modulesLog = [];
-
-	// If the test run hasn't officially begun yet
-	if ( !config.started ) {
-
-		// Record the time of the test run's beginning
-		config.started = now();
-
-		verifyLoggingCallbacks();
-
-		// Delete the loose unnamed module if unused.
-		if ( config.modules[ 0 ].name === "" && config.modules[ 0 ].tests.length === 0 ) {
-			config.modules.shift();
-		}
-
-		// Avoid unnecessary information by not logging modules' test environments
-		for ( i = 0, l = config.modules.length; i < l; i++ ) {
-			modulesLog.push({
-				name: config.modules[ i ].name,
-				tests: config.modules[ i ].tests
-			});
-		}
-
-		// The test run is officially beginning now
-		runLoggingCallbacks( "begin", {
-			totalTests: Test.count,
-			modules: modulesLog
-		});
-	}
-
-	config.blocking = false;
-	process( true );
-}
-
-function resumeProcessing() {
-	runStarted = true;
-
-	// A slight delay to allow this iteration of the event loop to finish (more assertions, etc.)
-	if ( defined.setTimeout ) {
-		setTimeout(function() {
-			if ( config.current && config.current.semaphore > 0 ) {
-				return;
-			}
-			if ( config.timeout ) {
-				clearTimeout( config.timeout );
-			}
-
-			begin();
-		}, 13 );
-	} else {
-		begin();
-	}
-}
-
-function pauseProcessing() {
-	config.blocking = true;
-
-	if ( config.testTimeout && defined.setTimeout ) {
-		clearTimeout( config.timeout );
-		config.timeout = setTimeout(function() {
-			if ( config.current ) {
-				config.current.semaphore = 0;
-				QUnit.pushFailure( "Test timed out", sourceFromStacktrace( 2 ) );
-			} else {
-				throw new Error( "Test timed out" );
-			}
-			resumeProcessing();
-		}, config.testTimeout );
-	}
-}
-
-function saveGlobal() {
-	config.pollution = [];
-
-	if ( config.noglobals ) {
-		for ( var key in window ) {
-			if ( hasOwn.call( window, key ) ) {
-				// in Opera sometimes DOM element ids show up here, ignore them
-				if ( /^qunit-test-output/.test( key ) ) {
-					continue;
-				}
-				config.pollution.push( key );
-			}
-		}
-	}
-}
-
-function checkPollution() {
-	var newGlobals,
-		deletedGlobals,
-		old = config.pollution;
-
-	saveGlobal();
-
-	newGlobals = diff( config.pollution, old );
-	if ( newGlobals.length > 0 ) {
-		QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join( ", " ) );
-	}
-
-	deletedGlobals = diff( old, config.pollution );
-	if ( deletedGlobals.length > 0 ) {
-		QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join( ", " ) );
-	}
-}
-
-// returns a new Array with the elements that are in a but not in b
-function diff( a, b ) {
-	var i, j,
-		result = a.slice();
-
-	for ( i = 0; i < result.length; i++ ) {
-		for ( j = 0; j < b.length; j++ ) {
-			if ( result[ i ] === b[ j ] ) {
-				result.splice( i, 1 );
-				i--;
-				break;
-			}
-		}
-	}
-	return result;
-}
-
-function extend( a, b, undefOnly ) {
-	for ( var prop in b ) {
-		if ( hasOwn.call( b, prop ) ) {
-
-			// Avoid "Member not found" error in IE8 caused by messing with window.constructor
-			if ( !( prop === "constructor" && a === window ) ) {
-				if ( b[ prop ] === undefined ) {
-					delete a[ prop ];
-				} else if ( !( undefOnly && typeof a[ prop ] !== "undefined" ) ) {
-					a[ prop ] = b[ prop ];
-				}
-			}
-		}
-	}
-
-	return a;
-}
-
-function runLoggingCallbacks( key, args ) {
-	var i, l, callbacks;
-
-	callbacks = config.callbacks[ key ];
-	for ( i = 0, l = callbacks.length; i < l; i++ ) {
-		callbacks[ i ]( args );
-	}
-}
-
-// DEPRECATED: This will be removed on 2.0.0+
-// This function verifies if the loggingCallbacks were modified by the user
-// If so, it will restore it, assign the given callback and print a console warning
-function verifyLoggingCallbacks() {
-	var loggingCallback, userCallback;
-
-	for ( loggingCallback in loggingCallbacks ) {
-		if ( QUnit[ loggingCallback ] !== loggingCallbacks[ loggingCallback ] ) {
-
-			userCallback = QUnit[ loggingCallback ];
-
-			// Restore the callback function
-			QUnit[ loggingCallback ] = loggingCallbacks[ loggingCallback ];
-
-			// Assign the deprecated given callback
-			QUnit[ loggingCallback ]( userCallback );
-
-			if ( window.console && window.console.warn ) {
-				window.console.warn(
-					"QUnit." + loggingCallback + " was replaced with a new value.\n" +
-					"Please, check out the documentation on how to apply logging callbacks.\n" +
-					"Reference: http://api.qunitjs.com/category/callbacks/"
-				);
-			}
-		}
-	}
-}
-
-// from jquery.js
-function inArray( elem, array ) {
-	if ( array.indexOf ) {
-		return array.indexOf( elem );
-	}
-
-	for ( var i = 0, length = array.length; i < length; i++ ) {
-		if ( array[ i ] === elem ) {
-			return i;
-		}
-	}
-
-	return -1;
-}
-
-function Test( settings ) {
-	var i, l;
-
-	++Test.count;
-
-	extend( this, settings );
-	this.assertions = [];
-	this.semaphore = 0;
-	this.usedAsync = false;
-	this.module = config.currentModule;
-	this.stack = sourceFromStacktrace( 3 );
-
-	// Register unique strings
-	for ( i = 0, l = this.module.tests; i < l.length; i++ ) {
-		if ( this.module.tests[ i ].name === this.testName ) {
-			this.testName += " ";
-		}
-	}
-
-	this.testId = generateHash( this.module.name, this.testName );
-
-	this.module.tests.push({
-		name: this.testName,
-		testId: this.testId
-	});
-
-	if ( settings.skip ) {
-
-		// Skipped tests will fully ignore any sent callback
-		this.callback = function() {};
-		this.async = false;
-		this.expected = 0;
-	} else {
-		this.assert = new Assert( this );
-	}
-}
-
-Test.count = 0;
-
-Test.prototype = {
-	before: function() {
-		if (
-
-			// Emit moduleStart when we're switching from one module to another
-			this.module !== config.previousModule ||
-
-				// They could be equal (both undefined) but if the previousModule property doesn't
-				// yet exist it means this is the first test in a suite that isn't wrapped in a
-				// module, in which case we'll just emit a moduleStart event for 'undefined'.
-				// Without this, reporters can get testStart before moduleStart  which is a problem.
-				!hasOwn.call( config, "previousModule" )
-		) {
-			if ( hasOwn.call( config, "previousModule" ) ) {
-				runLoggingCallbacks( "moduleDone", {
-					name: config.previousModule.name,
-					tests: config.previousModule.tests,
-					failed: config.moduleStats.bad,
-					passed: config.moduleStats.all - config.moduleStats.bad,
-					total: config.moduleStats.all,
-					runtime: now() - config.moduleStats.started
-				});
-			}
-			config.previousModule = this.module;
-			config.moduleStats = { all: 0, bad: 0, started: now() };
-			runLoggingCallbacks( "moduleStart", {
-				name: this.module.name,
-				tests: this.module.tests
-			});
-		}
-
-		config.current = this;
-
-		this.testEnvironment = extend( {}, this.module.testEnvironment );
-		delete this.testEnvironment.beforeEach;
-		delete this.testEnvironment.afterEach;
-
-		this.started = now();
-		runLoggingCallbacks( "testStart", {
-			name: this.testName,
-			module: this.module.name,
-			testId: this.testId
-		});
-
-		if ( !config.pollution ) {
-			saveGlobal();
-		}
-	},
-
-	run: function() {
-		var promise;
-
-		config.current = this;
-
-		if ( this.async ) {
-			QUnit.stop();
-		}
-
-		this.callbackStarted = now();
-
-		if ( config.notrycatch ) {
-			promise = this.callback.call( this.testEnvironment, this.assert );
-			this.resolvePromise( promise );
-			return;
-		}
-
-		try {
-			promise = this.callback.call( this.testEnvironment, this.assert );
-			this.resolvePromise( promise );
-		} catch ( e ) {
-			this.pushFailure( "Died on test #" + ( this.assertions.length + 1 ) + " " +
-				this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );
-
-			// else next test will carry the responsibility
-			saveGlobal();
-
-			// Restart the tests if they're blocking
-			if ( config.blocking ) {
-				QUnit.start();
-			}
-		}
-	},
-
-	after: function() {
-		checkPollution();
-	},
-
-	queueHook: function( hook, hookName ) {
-		var promise,
-			test = this;
-		return function runHook() {
-			config.current = test;
-			if ( config.notrycatch ) {
-				promise = hook.call( test.testEnvironment, test.assert );
-				test.resolvePromise( promise, hookName );
-				return;
-			}
-			try {
-				promise = hook.call( test.testEnvironment, test.assert );
-				test.resolvePromise( promise, hookName );
-			} catch ( error ) {
-				test.pushFailure( hookName + " failed on " + test.testName + ": " +
-					( error.message || error ), extractStacktrace( error, 0 ) );
-			}
-		};
-	},
-
-	// Currently only used for module level hooks, can be used to add global level ones
-	hooks: function( handler ) {
-		var hooks = [];
-
-		// Hooks are ignored on skipped tests
-		if ( this.skip ) {
-			return hooks;
-		}
-
-		if ( this.module.testEnvironment &&
-				QUnit.objectType( this.module.testEnvironment[ handler ] ) === "function" ) {
-			hooks.push( this.queueHook( this.module.testEnvironment[ handler ], handler ) );
-		}
-
-		return hooks;
-	},
-
-	finish: function() {
-		config.current = this;
-		if ( config.requireExpects && this.expected === null ) {
-			this.pushFailure( "Expected number of assertions to be defined, but expect() was " +
-				"not called.", this.stack );
-		} else if ( this.expected !== null && this.expected !== this.assertions.length ) {
-			this.pushFailure( "Expected " + this.expected + " assertions, but " +
-				this.assertions.length + " were run", this.stack );
-		} else if ( this.expected === null && !this.assertions.length ) {
-			this.pushFailure( "Expected at least one assertion, but none were run - call " +
-				"expect(0) to accept zero assertions.", this.stack );
-		}
-
-		var i,
-			bad = 0;
-
-		this.runtime = now() - this.started;
-		config.stats.all += this.assertions.length;
-		config.moduleStats.all += this.assertions.length;
-
-		for ( i = 0; i < this.assertions.length; i++ ) {
-			if ( !this.assertions[ i ].result ) {
-				bad++;
-				config.stats.bad++;
-				config.moduleStats.bad++;
-			}
-		}
-
-		runLoggingCallbacks( "testDone", {
-			name: this.testName,
-			module: this.module.name,
-			skipped: !!this.skip,
-			failed: bad,
-			passed: this.assertions.length - bad,
-			total: this.assertions.length,
-			runtime: this.runtime,
-
-			// HTML Reporter use
-			assertions: this.assertions,
-			testId: this.testId,
-
-			// DEPRECATED: this property will be removed in 2.0.0, use runtime instead
-			duration: this.runtime
-		});
-
-		// QUnit.reset() is deprecated and will be replaced for a new
-		// fixture reset function on QUnit 2.0/2.1.
-		// It's still called here for backwards compatibility handling
-		QUnit.reset();
-
-		config.current = undefined;
-	},
-
-	queue: function() {
-		var bad,
-			test = this;
-
-		if ( !this.valid() ) {
-			return;
-		}
-
-		function run() {
-
-			// each of these can by async
-			synchronize([
-				function() {
-					test.before();
-				},
-
-				test.hooks( "beforeEach" ),
-
-				function() {
-					test.run();
-				},
-
-				test.hooks( "afterEach" ).reverse(),
-
-				function() {
-					test.after();
-				},
-				function() {
-					test.finish();
-				}
-			]);
-		}
-
-		// `bad` initialized at top of scope
-		// defer when previous test run passed, if storage is available
-		bad = QUnit.config.reorder && defined.sessionStorage &&
-				+sessionStorage.getItem( "qunit-test-" + this.module.name + "-" + this.testName );
-
-		if ( bad ) {
-			run();
-		} else {
-			synchronize( run, true );
-		}
-	},
-
-	push: function( result, actual, expected, message ) {
-		var source,
-			details = {
-				module: this.module.name,
-				name: this.testName,
-				result: result,
-				message: message,
-				actual: actual,
-				expected: expected,
-				testId: this.testId,
-				runtime: now() - this.started
-			};
-
-		if ( !result ) {
-			source = sourceFromStacktrace();
-
-			if ( source ) {
-				details.source = source;
-			}
-		}
-
-		runLoggingCallbacks( "log", details );
-
-		this.assertions.push({
-			result: !!result,
-			message: message
-		});
-	},
-
-	pushFailure: function( message, source, actual ) {
-		if ( !this instanceof Test ) {
-			throw new Error( "pushFailure() assertion outside test context, was " +
-				sourceFromStacktrace( 2 ) );
-		}
-
-		var details = {
-				module: this.module.name,
-				name: this.testName,
-				result: false,
-				message: message || "error",
-				actual: actual || null,
-				testId: this.testId,
-				runtime: now() - this.started
-			};
-
-		if ( source ) {
-			details.source = source;
-		}
-
-		runLoggingCallbacks( "log", details );
-
-		this.assertions.push({
-			result: false,
-			message: message
-		});
-	},
-
-	resolvePromise: function( promise, phase ) {
-		var then, message,
-			test = this;
-		if ( promise != null ) {
-			then = promise.then;
-			if ( QUnit.objectType( then ) === "function" ) {
-				QUnit.stop();
-				then.call(
-					promise,
-					QUnit.start,
-					function( error ) {
-						message = "Promise rejected " +
-							( !phase ? "during" : phase.replace( /Each$/, "" ) ) +
-							" " + test.testName + ": " + ( error.message || error );
-						test.pushFailure( message, extractStacktrace( error, 0 ) );
-
-						// else next test will carry the responsibility
-						saveGlobal();
-
-						// Unblock
-						QUnit.start();
-					}
-				);
-			}
-		}
-	},
-
-	valid: function() {
-		var include,
-			filter = config.filter && config.filter.toLowerCase(),
-			module = QUnit.urlParams.module && QUnit.urlParams.module.toLowerCase(),
-			fullName = ( this.module.name + ": " + this.testName ).toLowerCase();
-
-		// Internally-generated tests are always valid
-		if ( this.callback && this.callback.validTest ) {
-			return true;
-		}
-
-		if ( config.testId.length > 0 && inArray( this.testId, config.testId ) < 0 ) {
-			return false;
-		}
-
-		if ( module && ( !this.module.name || this.module.name.toLowerCase() !== module ) ) {
-			return false;
-		}
-
-		if ( !filter ) {
-			return true;
-		}
-
-		include = filter.charAt( 0 ) !== "!";
-		if ( !include ) {
-			filter = filter.slice( 1 );
-		}
-
-		// If the filter matches, we need to honour include
-		if ( fullName.indexOf( filter ) !== -1 ) {
-			return include;
-		}
-
-		// Otherwise, do the opposite
-		return !include;
-	}
-
-};
-
-// Resets the test setup. Useful for tests that modify the DOM.
-/*
-DEPRECATED: Use multiple tests instead of resetting inside a test.
-Use testStart or testDone for custom cleanup.
-This method will throw an error in 2.0, and will be removed in 2.1
-*/
-QUnit.reset = function() {
-
-	// Return on non-browser environments
-	// This is necessary to not break on node tests
-	if ( typeof window === "undefined" ) {
-		return;
-	}
-
-	var fixture = defined.document && document.getElementById &&
-			document.getElementById( "qunit-fixture" );
-
-	if ( fixture ) {
-		fixture.innerHTML = config.fixture;
-	}
-};
-
-QUnit.pushFailure = function() {
-	if ( !QUnit.config.current ) {
-		throw new Error( "pushFailure() assertion outside test context, in " +
-			sourceFromStacktrace( 2 ) );
-	}
-
-	// Gets current test obj
-	var currentTest = QUnit.config.current;
-
-	return currentTest.pushFailure.apply( currentTest, arguments );
-};
-
-// Based on Java's String.hashCode, a simple but not
-// rigorously collision resistant hashing function
-function generateHash( module, testName ) {
-	var hex,
-		i = 0,
-		hash = 0,
-		str = module + "\x1C" + testName,
-		len = str.length;
-
-	for ( ; i < len; i++ ) {
-		hash  = ( ( hash << 5 ) - hash ) + str.charCodeAt( i );
-		hash |= 0;
-	}
-
-	// Convert the possibly negative integer hash code into an 8 character hex string, which isn't
-	// strictly necessary but increases user understanding that the id is a SHA-like hash
-	hex = ( 0x100000000 + hash ).toString( 16 );
-	if ( hex.length < 8 ) {
-		hex = "0000000" + hex;
-	}
-
-	return hex.slice( -8 );
-}
-
-function Assert( testContext ) {
-	this.test = testContext;
-}
-
-// Assert helpers
-QUnit.assert = Assert.prototype = {
-
-	// Specify the number of expected assertions to guarantee that failed test
-	// (no assertions are run at all) don't slip through.
-	expect: function( asserts ) {
-		if ( arguments.length === 1 ) {
-			this.test.expected = asserts;
-		} else {
-			return this.test.expected;
-		}
-	},
-
-	// Increment this Test's semaphore counter, then return a single-use function that
-	// decrements that counter a maximum of once.
-	async: function() {
-		var test = this.test,
-			popped = false;
-
-		test.semaphore += 1;
-		test.usedAsync = true;
-		pauseProcessing();
-
-		return function done() {
-			if ( !popped ) {
-				test.semaphore -= 1;
-				popped = true;
-				resumeProcessing();
-			} else {
-				test.pushFailure( "Called the callback returned from `assert.async` more than once",
-					sourceFromStacktrace( 2 ) );
-			}
-		};
-	},
-
-	// Exports test.push() to the user API
-	push: function( /* result, actual, expected, message */ ) {
-		var assert = this,
-			currentTest = ( assert instanceof Assert && assert.test ) || QUnit.config.current;
-
-		// Backwards compatibility fix.
-		// Allows the direct use of global exported assertions and QUnit.assert.*
-		// Although, it's use is not recommended as it can leak assertions
-		// to other tests from async tests, because we only get a reference to the current test,
-		// not exactly the test where assertion were intended to be called.
-		if ( !currentTest ) {
-			throw new Error( "assertion outside test context, in " + sourceFromStacktrace( 2 ) );
-		}
-
-		if ( currentTest.usedAsync === true && currentTest.semaphore === 0 ) {
-			currentTest.pushFailure( "Assertion after the final `assert.async` was resolved",
-				sourceFromStacktrace( 2 ) );
-
-			// Allow this assertion to continue running anyway...
-		}
-
-		if ( !( assert instanceof Assert ) ) {
-			assert = currentTest.assert;
-		}
-		return assert.test.push.apply( assert.test, arguments );
-	},
-
-	ok: function( result, message ) {
-		message = message || ( result ? "okay" : "failed, expected argument to be truthy, was: " +
-			QUnit.dump.parse( result ) );
-		this.push( !!result, result, true, message );
-	},
-
-	notOk: function( result, message ) {
-		message = message || ( !result ? "okay" : "failed, expected argument to be falsy, was: " +
-			QUnit.dump.parse( result ) );
-		this.push( !result, result, false, message );
-	},
-
-	equal: function( actual, expected, message ) {
-		/*jshint eqeqeq:false */
-		this.push( expected == actual, actual, expected, message );
-	},
-
-	notEqual: function( actual, expected, message ) {
-		/*jshint eqeqeq:false */
-		this.push( expected != actual, actual, expected, message );
-	},
-
-	propEqual: function( actual, expected, message ) {
-		actual = objectValues( actual );
-		expected = objectValues( expected );
-		this.push( QUnit.equiv( actual, expected ), actual, expected, message );
-	},
-
-	notPropEqual: function( actual, expected, message ) {
-		actual = objectValues( actual );
-		expected = objectValues( expected );
-		this.push( !QUnit.equiv( actual, expected ), actual, expected, message );
-	},
-
-	deepEqual: function( actual, expected, message ) {
-		this.push( QUnit.equiv( actual, expected ), actual, expected, message );
-	},
-
-	notDeepEqual: function( actual, expected, message ) {
-		this.push( !QUnit.equiv( actual, expected ), actual, expected, message );
-	},
-
-	strictEqual: function( actual, expected, message ) {
-		this.push( expected === actual, actual, expected, message );
-	},
-
-	notStrictEqual: function( actual, expected, message ) {
-		this.push( expected !== actual, actual, expected, message );
-	},
-
-	"throws": function( block, expected, message ) {
-		var actual, expectedType,
-			expectedOutput = expected,
-			ok = false,
-			currentTest = ( this instanceof Assert && this.test ) || QUnit.config.current;
-
-		// 'expected' is optional unless doing string comparison
-		if ( message == null && typeof expected === "string" ) {
-			message = expected;
-			expected = null;
-		}
-
-		currentTest.ignoreGlobalErrors = true;
-		try {
-			block.call( currentTest.testEnvironment );
-		} catch (e) {
-			actual = e;
-		}
-		currentTest.ignoreGlobalErrors = false;
-
-		if ( actual ) {
-			expectedType = QUnit.objectType( expected );
-
-			// we don't want to validate thrown error
-			if ( !expected ) {
-				ok = true;
-				expectedOutput = null;
-
-			// expected is a regexp
-			} else if ( expectedType === "regexp" ) {
-				ok = expected.test( errorString( actual ) );
-
-			// expected is a string
-			} else if ( expectedType === "string" ) {
-				ok = expected === errorString( actual );
-
-			// expected is a constructor, maybe an Error constructor
-			} else if ( expectedType === "function" && actual instanceof expected ) {
-				ok = true;
-
-			// expected is an Error object
-			} else if ( expectedType === "object" ) {
-				ok = actual instanceof expected.constructor &&
-					actual.name === expected.name &&
-					actual.message === expected.message;
-
-			// expected is a validation function which returns true if validation passed
-			} else if ( expectedType === "function" && expected.call( {}, actual ) === true ) {
-				expectedOutput = null;
-				ok = true;
-			}
-		}
-
-		currentTest.assert.push( ok, actual, expectedOutput, message );
-	}
-};
-
-// Provide an alternative to assert.throws(), for enviroments that consider throws a reserved word
-// Known to us are: Closure Compiler, Narwhal
-(function() {
-	/*jshint sub:true */
-	Assert.prototype.raises = Assert.prototype[ "throws" ];
-}());
-
-// Test for equality any JavaScript type.
-// Author: Philippe Rathé <[email protected]>
-QUnit.equiv = (function() {
-
-	// Call the o related callback with the given arguments.
-	function bindCallbacks( o, callbacks, args ) {
-		var prop = QUnit.objectType( o );
-		if ( prop ) {
-			if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) {
-				return callbacks[ prop ].apply( callbacks, args );
-			} else {
-				return callbacks[ prop ]; // or undefined
-			}
-		}
-	}
-
-	// the real equiv function
-	var innerEquiv,
-
-		// stack to decide between skip/abort functions
-		callers = [],
-
-		// stack to avoiding loops from circular referencing
-		parents = [],
-		parentsB = [],
-
-		getProto = Object.getPrototypeOf || function( obj ) {
-			/* jshint camelcase: false, proto: true */
-			return obj.__proto__;
-		},
-		callbacks = (function() {
-
-			// for string, boolean, number and null
-			function useStrictEquality( b, a ) {
-
-				/*jshint eqeqeq:false */
-				if ( b instanceof a.constructor || a instanceof b.constructor ) {
-
-					// to catch short annotation VS 'new' annotation of a
-					// declaration
-					// e.g. var i = 1;
-					// var j = new Number(1);
-					return a == b;
-				} else {
-					return a === b;
-				}
-			}
-
-			return {
-				"string": useStrictEquality,
-				"boolean": useStrictEquality,
-				"number": useStrictEquality,
-				"null": useStrictEquality,
-				"undefined": useStrictEquality,
-
-				"nan": function( b ) {
-					return isNaN( b );
-				},
-
-				"date": function( b, a ) {
-					return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf();
-				},
-
-				"regexp": function( b, a ) {
-					return QUnit.objectType( b ) === "regexp" &&
-
-						// the regex itself
-						a.source === b.source &&
-
-						// and its modifiers
-						a.global === b.global &&
-
-						// (gmi) ...
-						a.ignoreCase === b.ignoreCase &&
-						a.multiline === b.multiline &&
-						a.sticky === b.sticky;
-				},
-
-				// - skip when the property is a method of an instance (OOP)
-				// - abort otherwise,
-				// initial === would have catch identical references anyway
-				"function": function() {
-					var caller = callers[ callers.length - 1 ];
-					return caller !== Object && typeof caller !== "undefined";
-				},
-
-				"array": function( b, a ) {
-					var i, j, len, loop, aCircular, bCircular;
-
-					// b could be an object literal here
-					if ( QUnit.objectType( b ) !== "array" ) {
-						return false;
-					}
-
-					len = a.length;
-					if ( len !== b.length ) {
-						// safe and faster
-						return false;
-					}
-
-					// track reference to avoid circular references
-					parents.push( a );
-					parentsB.push( b );
-					for ( i = 0; i < len; i++ ) {
-						loop = false;
-						for ( j = 0; j < parents.length; j++ ) {
-							aCircular = parents[ j ] === a[ i ];
-							bCircular = parentsB[ j ] === b[ i ];
-							if ( aCircular || bCircular ) {
-								if ( a[ i ] === b[ i ] || aCircular && bCircular ) {
-									loop = true;
-								} else {
-									parents.pop();
-									parentsB.pop();
-									return false;
-								}
-							}
-						}
-						if ( !loop && !innerEquiv( a[ i ], b[ i ] ) ) {
-							parents.pop();
-							parentsB.pop();
-							return false;
-						}
-					}
-					parents.pop();
-					parentsB.pop();
-					return true;
-				},
-
-				"object": function( b, a ) {
-
-					/*jshint forin:false */
-					var i, j, loop, aCircular, bCircular,
-						// Default to true
-						eq = true,
-						aProperties = [],
-						bProperties = [];
-
-					// comparing constructors is more strict than using
-					// instanceof
-					if ( a.constructor !== b.constructor ) {
-
-						// Allow objects with no prototype to be equivalent to
-						// objects with Object as their constructor.
-						if ( !( ( getProto( a ) === null && getProto( b ) === Object.prototype ) ||
-							( getProto( b ) === null && getProto( a ) === Object.prototype ) ) ) {
-							return false;
-						}
-					}
-
-					// stack constructor before traversing properties
-					callers.push( a.constructor );
-
-					// track reference to avoid circular references
-					parents.push( a );
-					parentsB.push( b );
-
-					// be strict: don't ensure hasOwnProperty and go deep
-					for ( i in a ) {
-						loop = false;
-						for ( j = 0; j < parents.length; j++ ) {
-							aCircular = parents[ j ] === a[ i ];
-							bCircular = parentsB[ j ] === b[ i ];
-							if ( aCircular || bCircular ) {
-								if ( a[ i ] === b[ i ] || aCircular && bCircular ) {
-									loop = true;
-								} else {
-									eq = false;
-									break;
-								}
-							}
-						}
-						aProperties.push( i );
-						if ( !loop && !innerEquiv( a[ i ], b[ i ] ) ) {
-							eq = false;
-							break;
-						}
-					}
-
-					parents.pop();
-					parentsB.pop();
-					callers.pop(); // unstack, we are done
-
-					for ( i in b ) {
-						bProperties.push( i ); // collect b's properties
-					}
-
-					// Ensures identical properties name
-					return eq && innerEquiv( aProperties.sort(), bProperties.sort() );
-				}
-			};
-		}());
-
-	innerEquiv = function() { // can take multiple arguments
-		var args = [].slice.apply( arguments );
-		if ( args.length < 2 ) {
-			return true; // end transition
-		}
-
-		return ( (function( a, b ) {
-			if ( a === b ) {
-				return true; // catch the most you can
-			} else if ( a === null || b === null || typeof a === "undefined" ||
-					typeof b === "undefined" ||
-					QUnit.objectType( a ) !== QUnit.objectType( b ) ) {
-
-				// don't lose time with error prone cases
-				return false;
-			} else {
-				return bindCallbacks( a, callbacks, [ b, a ] );
-			}
-
-			// apply transition with (1..n) arguments
-		}( args[ 0 ], args[ 1 ] ) ) &&
-			innerEquiv.apply( this, args.splice( 1, args.length - 1 ) ) );
-	};
-
-	return innerEquiv;
-}());
-
-// Based on jsDump by Ariel Flesler
-// http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html
-QUnit.dump = (function() {
-	function quote( str ) {
-		return "\"" + str.toString().replace( /"/g, "\\\"" ) + "\"";
-	}
-	function literal( o ) {
-		return o + "";
-	}
-	function join( pre, arr, post ) {
-		var s = dump.separator(),
-			base = dump.indent(),
-			inner = dump.indent( 1 );
-		if ( arr.join ) {
-			arr = arr.join( "," + s + inner );
-		}
-		if ( !arr ) {
-			return pre + post;
-		}
-		return [ pre, inner + arr, base + post ].join( s );
-	}
-	function array( arr, stack ) {
-		var i = arr.length,
-			ret = new Array( i );
-
-		if ( dump.maxDepth && dump.depth > dump.maxDepth ) {
-			return "[object Array]";
-		}
-
-		this.up();
-		while ( i-- ) {
-			ret[ i ] = this.parse( arr[ i ], undefined, stack );
-		}
-		this.down();
-		return join( "[", ret, "]" );
-	}
-
-	var reName = /^function (\w+)/,
-		dump = {
-
-			// objType is used mostly internally, you can fix a (custom) type in advance
-			parse: function( obj, objType, stack ) {
-				stack = stack || [];
-				var res, parser, parserType,
-					inStack = inArray( obj, stack );
-
-				if ( inStack !== -1 ) {
-					return "recursion(" + ( inStack - stack.length ) + ")";
-				}
-
-				objType = objType || this.typeOf( obj  );
-				parser = this.parsers[ objType ];
-				parserType = typeof parser;
-
-				if ( parserType === "function" ) {
-					return;
-					stack.push( obj );
-					res = parser.call( this, obj, stack );
-					stack.pop();
-					return res;
-				}
-				return ( parserType === "string" ) ? parser : this.parsers.error;
-			},
-			typeOf: function( obj ) {
-				var type;
-				if ( obj === null ) {
-					type = "null";
-				} else if ( typeof obj === "undefined" ) {
-					type = "undefined";
-				} else if ( QUnit.is( "regexp", obj ) ) {
-					type = "regexp";
-				} else if ( QUnit.is( "date", obj ) ) {
-					type = "date";
-				} else if ( QUnit.is( "function", obj ) ) {
-					type = "function";
-				} else if ( obj.setInterval !== undefined &&
-						obj.document !== undefined &&
-						obj.nodeType === undefined ) {
-					type = "window";
-				} else if ( obj.nodeType === 9 ) {
-					type = "document";
-				} else if ( obj.nodeType ) {
-					type = "node";
-				} else if (
-
-					// native arrays
-					toString.call( obj ) === "[object Array]" ||
-
-					// NodeList objects
-					( typeof obj.length === "number" && obj.item !== undefined &&
-					( obj.length ? obj.item( 0 ) === obj[ 0 ] : ( obj.item( 0 ) === null &&
-					obj[ 0 ] === undefined ) ) )
-				) {
-					type = "array";
-				} else if ( obj.constructor === Error.prototype.constructor ) {
-					type = "error";
-				} else {
-					type = typeof obj;
-				}
-				return type;
-			},
-			separator: function() {
-				return this.multiline ? this.HTML ? "<br />" : "\n" : this.HTML ? "&#160;" : " ";
-			},
-			// extra can be a number, shortcut for increasing-calling-decreasing
-			indent: function( extra ) {
-				if ( !this.multiline ) {
-					return "";
-				}
-				var chr = this.indentChar;
-				if ( this.HTML ) {
-					chr = chr.replace( /\t/g, "   " ).replace( / /g, "&#160;" );
-				}
-				return new Array( this.depth + ( extra || 0 ) ).join( chr );
-			},
-			up: function( a ) {
-				this.depth += a || 1;
-			},
-			down: function( a ) {
-				this.depth -= a || 1;
-			},
-			setParser: function( name, parser ) {
-				this.parsers[ name ] = parser;
-			},
-			// The next 3 are exposed so you can use them
-			quote: quote,
-			literal: literal,
-			join: join,
-			//
-			depth: 1,
-			maxDepth: QUnit.config.maxDepth,
-
-			// This is the list of parsers, to modify them, use dump.setParser
-			parsers: {
-				window: "[Window]",
-				document: "[Document]",
-				error: function( error ) {
-					return "Error(\"" + error.message + "\")";
-				},
-				unknown: "[Unknown]",
-				"null": "null",
-				"undefined": "undefined",
-				"function": function( fn ) {
-					var ret = "function",
-
-						// functions never have name in IE
-						name = "name" in fn ? fn.name : ( reName.exec( fn ) || [] )[ 1 ];
-
-					if ( name ) {
-						ret += " " + name;
-					}
-					ret += "( ";
-
-					ret = [ ret, dump.parse( fn, "functionArgs" ), "){" ].join( "" );
-					return join( ret, dump.parse( fn, "functionCode" ), "}" );
-				},
-				array: array,
-				nodelist: array,
-				"arguments": array,
-				object: function( map, stack ) {
-					var keys, key, val, i, nonEnumerableProperties,
-						ret = [];
-
-					if ( dump.maxDepth && dump.depth > dump.maxDepth ) {
-						return "[object Object]";
-					}
-
-					dump.up();
-					keys = [];
-					for ( key in map ) {
-						keys.push( key );
-					}
-
-					// Some properties are not always enumerable on Error objects.
-					nonEnumerableProperties = [ "message", "name" ];
-					for ( i in nonEnumerableProperties ) {
-						key = nonEnumerableProperties[ i ];
-						if ( key in map && inArray( key, keys ) < 0 ) {
-							keys.push( key );
-						}
-					}
-					keys.sort();
-					for ( i = 0; i < keys.length; i++ ) {
-						key = keys[ i ];
-						val = map[ key ];
-						ret.push( dump.parse( key, "key" ) + ": " +
-							dump.parse( val, undefined, stack ) );
-					}
-					dump.down();
-					return join( "{", ret, "}" );
-				},
-				node: function( node ) {
-					var len, i, val,
-						open = dump.HTML ? "&lt;" : "<",
-						close = dump.HTML ? "&gt;" : ">",
-						tag = node.nodeName.toLowerCase(),
-						ret = open + tag,
-						attrs = node.attributes;
-
-					if ( attrs ) {
-						for ( i = 0, len = attrs.length; i < len; i++ ) {
-							val = attrs[ i ].nodeValue;
-
-							// IE6 includes all attributes in .attributes, even ones not explicitly
-							// set. Those have values like undefined, null, 0, false, "" or
-							// "inherit".
-							if ( val && val !== "inherit" ) {
-								ret += " " + attrs[ i ].nodeName + "=" +
-									dump.parse( val, "attribute" );
-							}
-						}
-					}
-					ret += close;
-
-					// Show content of TextNode or CDATASection
-					if ( node.nodeType === 3 || node.nodeType === 4 ) {
-						ret += node.nodeValue;
-					}
-
-					return ret + open + "/" + tag + close;
-				},
-
-				// function calls it internally, it's the arguments part of the function
-				functionArgs: function( fn ) {
-					var args,
-						l = fn.length;
-
-					if ( !l ) {
-						return "";
-					}
-
-					args = new Array( l );
-					while ( l-- ) {
-
-						// 97 is 'a'
-						args[ l ] = String.fromCharCode( 97 + l );
-					}
-					return " " + args.join( ", " ) + " ";
-				},
-				// object calls it internally, the key part of an item in a map
-				key: quote,
-				// function calls it internally, it's the content of the function
-				functionCode: "[code]",
-				// node calls it internally, it's an html attribute value
-				attribute: quote,
-				string: quote,
-				date: quote,
-				regexp: literal,
-				number: literal,
-				"boolean": literal
-			},
-			// if true, entities are escaped ( <, >, \t, space and \n )
-			HTML: false,
-			// indentation unit
-			indentChar: "  ",
-			// if true, items in a collection, are separated by a \n, else just a space.
-			multiline: true
-		};
-
-	return dump;
-}());
-
-// back compat
-QUnit.jsDump = QUnit.dump;
-
-// For browser, export only select globals
-if ( typeof window !== "undefined" ) {
-
-	// Deprecated
-	// Extend assert methods to QUnit and Global scope through Backwards compatibility
-	(function() {
-		var i,
-			assertions = Assert.prototype;
-
-		function applyCurrent( current ) {
-			return function() {
-				var assert = new Assert( QUnit.config.current );
-				current.apply( assert, arguments );
-			};
-		}
-
-		for ( i in assertions ) {
-			QUnit[ i ] = applyCurrent( assertions[ i ] );
-		}
-	})();
-
-	(function() {
-		var i, l,
-			keys = [
-				"test",
-				"module",
-				"expect",
-				"asyncTest",
-				"start",
-				"stop",
-				"ok",
-				"notOk",
-				"equal",
-				"notEqual",
-				"propEqual",
-				"notPropEqual",
-				"deepEqual",
-				"notDeepEqual",
-				"strictEqual",
-				"notStrictEqual",
-				"throws"
-			];
-
-		for ( i = 0, l = keys.length; i < l; i++ ) {
-			window[ keys[ i ] ] = QUnit[ keys[ i ] ];
-		}
-	})();
-
-	window.QUnit = QUnit;
-}
-
-// For nodejs
-if ( typeof module !== "undefined" && module && module.exports ) {
-	module.exports = QUnit;
-
-	// For consistency with CommonJS environments' exports
-	module.exports.QUnit = QUnit;
-}
-
-// For CommonJS with exports, but without module.exports, like Rhino
-if ( typeof exports !== "undefined" && exports ) {
-	exports.QUnit = QUnit;
-}
-
-if ( typeof define === "function" && define.amd ) {
-	define( function() {
-		return QUnit;
-	} );
-	QUnit.config.autostart = false;
-}
-
-// Get a reference to the global object, like window in browsers
-}( (function() {
-	return this;
-})() ));
-
-/*istanbul ignore next */
-// jscs:disable maximumLineLength
-/*
- * This file is a modified version of google-diff-match-patch's JavaScript implementation
- * (https://code.google.com/p/google-diff-match-patch/source/browse/trunk/javascript/diff_match_patch_uncompressed.js),
- * modifications are licensed as more fully set forth in LICENSE.txt.
- *
- * The original source of google-diff-match-patch is attributable and licensed as follows:
- *
- * Copyright 2006 Google Inc.
- * http://code.google.com/p/google-diff-match-patch/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * More Info:
- *  https://code.google.com/p/google-diff-match-patch/
- *
- * Usage: QUnit.diff(expected, actual)
- *
- * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) === "the  quick <del>brown </del> fox jump<ins>s</ins><del>ed</del over"
- */
-QUnit.diff = (function() {
-
-    function DiffMatchPatch() {
-
-        // Defaults.
-        // Redefine these in your program to override the defaults.
-
-        // Number of seconds to map a diff before giving up (0 for infinity).
-        this.DiffTimeout = 1.0;
-        // Cost of an empty edit operation in terms of edit characters.
-        this.DiffEditCost = 4;
-    }
-
-    //  DIFF FUNCTIONS
-
-    /**
-     * The data structure representing a diff is an array of tuples:
-     * [[DIFF_DELETE, 'Hello'], [DIFF_INSERT, 'Goodbye'], [DIFF_EQUAL, ' world.']]
-     * which means: delete 'Hello', add 'Goodbye' and keep ' world.'
-     */
-    var DIFF_DELETE = -1,
-		DIFF_INSERT = 1,
-		DIFF_EQUAL = 0;
-
-    /**
-     * Find the differences between two texts.  Simplifies the problem by stripping
-     * any common prefix or suffix off the texts before diffing.
-     * @param {string} text1 Old string to be diffed.
-     * @param {string} text2 New string to be diffed.
-     * @param {boolean=} optChecklines Optional speedup flag. If present and false,
-     *     then don't run a line-level diff first to identify the changed areas.
-     *     Defaults to true, which does a faster, slightly less optimal diff.
-     * @param {number} optDeadline Optional time when the diff should be complete
-     *     by.  Used internally for recursive calls.  Users should set DiffTimeout
-     *     instead.
-     * @return {!Array.<!DiffMatchPatch.Diff>} Array of diff tuples.
-     */
-    DiffMatchPatch.prototype.DiffMain = function( text1, text2, optChecklines, optDeadline ) {
-        var deadline, checklines, commonlength,
-			commonprefix, commonsuffix, diffs;
-        // Set a deadline by which time the diff must be complete.
-        if ( typeof optDeadline === "undefined" ) {
-            if ( this.DiffTimeout <= 0 ) {
-                optDeadline = Number.MAX_VALUE;
-            } else {
-                optDeadline = ( new Date() ).getTime() + this.DiffTimeout * 1000;
-            }
-        }
-        deadline = optDeadline;
-
-        // Check for null inputs.
-        if ( text1 === null || text2 === null ) {
-            throw new Error( "Null input. (DiffMain)" );
-        }
-
-        // Check for equality (speedup).
-        if ( text1 === text2 ) {
-            if ( text1 ) {
-                return [
-                    [ DIFF_EQUAL, text1 ]
-                ];
-            }
-            return [];
-        }
-
-        if ( typeof optChecklines === "undefined" ) {
-            optChecklines = true;
-        }
-
-        checklines = optChecklines;
-
-        // Trim off common prefix (speedup).
-        commonlength = this.diffCommonPrefix( text1, text2 );
-        commonprefix = text1.substring( 0, commonlength );
-        text1 = text1.substring( commonlength );
-        text2 = text2.substring( commonlength );
-
-        // Trim off common suffix (speedup).
-        /////////
-        commonlength = this.diffCommonSuffix( text1, text2 );
-        commonsuffix = text1.substring( text1.length - commonlength );
-        text1 = text1.substring( 0, text1.length - commonlength );
-        text2 = text2.substring( 0, text2.length - commonlength );
-
-        // Compute the diff on the middle block.
-        diffs = this.diffCompute( text1, text2, checklines, deadline );
-
-        // Restore the prefix and suffix.
-        if ( commonprefix ) {
-            diffs.unshift( [ DIFF_EQUAL, commonprefix ] );
-        }
-        if ( commonsuffix ) {
-            diffs.push( [ DIFF_EQUAL, commonsuffix ] );
-        }
-        this.diffCleanupMerge( diffs );
-        return diffs;
-    };
-
-    /**
-     * Reduce the number of edits by eliminating operationally trivial equalities.
-     * @param {!Array.<!DiffMatchPatch.Diff>} diffs Array of diff tuples.
-     */
-    DiffMatchPatch.prototype.diffCleanupEfficiency = function( diffs ) {
-        var changes, equalities, equalitiesLength, lastequality,
-			pointer, preIns, preDel, postIns, postDel;
-        changes = false;
-        equalities = []; // Stack of indices where equalities are found.
-        equalitiesLength = 0; // Keeping our own length var is faster in JS.
-        /** @type {?string} */
-        lastequality = null;
-        // Always equal to diffs[equalities[equalitiesLength - 1]][1]
-        pointer = 0; // Index of current position.
-        // Is there an insertion operation before the last equality.
-        preIns = false;
-        // Is there a deletion operation before the last equality.
-        preDel = false;
-        // Is there an insertion operation after the last equality.
-        postIns = false;
-        // Is there a deletion operation after the last equality.
-        postDel = false;
-        while ( pointer < diffs.length ) {
-            if ( diffs[ pointer ][ 0 ] === DIFF_EQUAL ) { // Equality found.
-                if ( diffs[ pointer ][ 1 ].length < this.DiffEditCost && ( postIns || postDel ) ) {
-                    // Candidate found.
-                    equalities[ equalitiesLength++ ] = pointer;
-                    preIns = postIns;
-                    preDel = postDel;
-                    lastequality = diffs[ pointer ][ 1 ];
-                } else {
-                    // Not a candidate, and can never become one.
-                    equalitiesLength = 0;
-                    lastequality = null;
-                }
-                postIns = postDel = false;
-            } else { // An insertion or deletion.
-                if ( diffs[ pointer ][ 0 ] === DIFF_DELETE ) {
-                    postDel = true;
-                } else {
-                    postIns = true;
-                }
-                /*
-                 * Five types to be split:
-                 * <ins>A</ins><del>B</del>XY<ins>C</ins><del>D</del>
-                 * <ins>A</ins>X<ins>C</ins><del>D</del>
-                 * <ins>A</ins><del>B</del>X<ins>C</ins>
-                 * <ins>A</del>X<ins>C</ins><del>D</del>
-                 * <ins>A</ins><del>B</del>X<del>C</del>
-                 */
-                if ( lastequality && ( ( preIns && preDel && postIns && postDel ) ||
-                        ( ( lastequality.length < this.DiffEditCost / 2 ) &&
-                            ( preIns + preDel + postIns + postDel ) === 3 ) ) ) {
-                    // Duplicate record.
-                    diffs.splice( equalities[equalitiesLength - 1], 0, [ DIFF_DELETE, lastequality ] );
-                    // Change second copy to insert.
-                    diffs[ equalities[ equalitiesLength - 1 ] + 1 ][ 0 ] = DIFF_INSERT;
-                    equalitiesLength--; // Throw away the equality we just deleted;
-                    lastequality = null;
-                    if (preIns && preDel) {
-                        // No changes made which could affect previous entry, keep going.
-                        postIns = postDel = true;
-                        equalitiesLength = 0;
-                    } else {
-                        equalitiesLength--; // Throw away the previous equality.
-                        pointer = equalitiesLength > 0 ? equalities[ equalitiesLength - 1 ] : -1;
-                        postIns = postDel = false;
-                    }
-                    changes = true;
-                }
-            }
-            pointer++;
-        }
-
-        if ( changes ) {
-            this.diffCleanupMerge( diffs );
-        }
-    };
-
-    /**
-     * Convert a diff array into a pretty HTML report.
-     * @param {!Array.<!DiffMatchPatch.Diff>} diffs Array of diff tuples.
-     * @param {integer} string to be beautified.
-     * @return {string} HTML representation.
-     */
-    DiffMatchPatch.prototype.diffPrettyHtml = function( diffs ) {
-        var op, data, x, html = [];
-        for ( x = 0; x < diffs.length; x++ ) {
-            op = diffs[x][0]; // Operation (insert, delete, equal)
-            data = diffs[x][1]; // Text of change.
-            switch ( op ) {
-                case DIFF_INSERT:
-                    html[x] = "<ins>" + data + "</ins>";
-                    break;
-                case DIFF_DELETE:
-                    html[x] = "<del>" + data + "</del>";
-                    break;
-                case DIFF_EQUAL:
-                    html[x] = "<span>" + data + "</span>";
-                    break;
-            }
-        }
-        return html.join("");
-    };
-
-    /**
-     * Determine the common prefix of two strings.
-     * @param {string} text1 First string.
-     * @param {string} text2 Second string.
-     * @return {number} The number of characters common to the start of each
-     *     string.
-     */
-    DiffMatchPatch.prototype.diffCommonPrefix = function( text1, text2 ) {
-        var pointermid, pointermax, pointermin, pointerstart;
-        // Quick check for common null cases.
-        if ( !text1 || !text2 || text1.charAt(0) !== text2.charAt(0) ) {
-            return 0;
-        }
-        // Binary search.
-        // Performance analysis: http://neil.fraser.name/news/2007/10/09/
-        pointermin = 0;
-        pointermax = Math.min( text1.length, text2.length );
-        pointermid = pointermax;
-        pointerstart = 0;
-        while ( pointermin < pointermid ) {
-            if ( text1.substring( pointerstart, pointermid ) === text2.substring( pointerstart, pointermid ) ) {
-                pointermin = pointermid;
-                pointerstart = pointermin;
-            } else {
-                pointermax = pointermid;
-            }
-            pointermid = Math.floor( ( pointermax - pointermin ) / 2 + pointermin );
-        }
-        return pointermid;
-    };
-
-    /**
-     * Determine the common suffix of two strings.
-     * @param {string} text1 First string.
-     * @param {string} text2 Second string.
-     * @return {number} The number of characters common to the end of each string.
-     */
-    DiffMatchPatch.prototype.diffCommonSuffix = function( text1, text2 ) {
-        var pointermid, pointermax, pointermin, pointerend;
-        // Quick check for common null cases.
-        if (!text1 || !text2 || text1.charAt(text1.length - 1) !== text2.charAt(text2.length - 1)) {
-            return 0;
-        }
-        // Binary search.
-        // Performance analysis: http://neil.fraser.name/news/2007/10/09/
-        pointermin = 0;
-        pointermax = Math.min(text1.length, text2.length);
-        pointermid = pointermax;
-        pointerend = 0;
-        while ( pointermin < pointermid ) {
-            if (text1.substring( text1.length - pointermid, text1.length - pointerend ) ===
-                text2.substring( text2.length - pointermid, text2.length - pointerend ) ) {
-                pointermin = pointermid;
-                pointerend = pointermin;
-            } else {
-                pointermax = pointermid;
-            }
-            pointermid = Math.floor( ( pointermax - pointermin ) / 2 + pointermin );
-        }
-        return pointermid;
-    };
-
-    /**
-     * Find the differences between two texts.  Assumes that the texts do not
-     * have any common prefix or suffix.
-     * @param {string} text1 Old string to be diffed.
-     * @param {string} text2 New string to be diffed.
-     * @param {boolean} checklines Speedup flag.  If false, then don't run a
-     *     line-level diff first to identify the changed areas.
-     *     If true, then run a faster, slightly less optimal diff.
-     * @param {number} deadline Time when the diff should be complete by.
-     * @return {!Array.<!DiffMatchPatch.Diff>} Array of diff tuples.
-     * @private
-     */
-    DiffMatchPatch.prototype.diffCompute = function( text1, text2, checklines, deadline ) {
-        var diffs, longtext, shorttext, i, hm,
-			text1A, text2A, text1B, text2B,
-			midCommon, diffsA, diffsB;
-
-        if ( !text1 ) {
-            // Just add some text (speedup).
-            return [
-                [ DIFF_INSERT, text2 ]
-            ];
-        }
-
-        if (!text2) {
-            // Just delete some text (speedup).
-            return [
-                [ DIFF_DELETE, text1 ]
-            ];
-        }
-
-        longtext = text1.length > text2.length ? text1 : text2;
-        shorttext = text1.length > text2.length ? text2 : text1;
-        i = longtext.indexOf( shorttext );
-        if ( i !== -1 ) {
-            // Shorter text is inside the longer text (speedup).
-            diffs = [
-                [ DIFF_INSERT, longtext.substring( 0, i ) ],
-                [ DIFF_EQUAL, shorttext ],
-                [ DIFF_INSERT, longtext.substring( i + shorttext.length ) ]
-            ];
-            // Swap insertions for deletions if diff is reversed.
-            if ( text1.length > text2.length ) {
-                diffs[0][0] = diffs[2][0] = DIFF_DELETE;
-            }
-            return diffs;
-        }
-
-        if ( shorttext.length === 1 ) {
-            // Single character string.
-            // After the previous speedup, the character can't be an equality.
-            return [
-                [ DIFF_DELETE, text1 ],
-                [ DIFF_INSERT, text2 ]
-            ];
-        }
-
-        // Check to see if the problem can be split in two.
-        hm = this.diffHalfMatch(text1, text2);
-        if (hm) {
-            // A half-match was found, sort out the return data.
-            text1A = hm[0];
-            text1B = hm[1];
-            text2A = hm[2];
-            text2B = hm[3];
-            midCommon = hm[4];
-            // Send both pairs off for separate processing.
-            diffsA = this.DiffMain(text1A, text2A, checklines, deadline);
-            diffsB = this.DiffMain(text1B, text2B, checklines, deadline);
-            // Merge the results.
-            return diffsA.concat([
-                [ DIFF_EQUAL, midCommon ]
-            ], diffsB);
-        }
-
-        if (checklines && text1.length > 100 && text2.length > 100) {
-            return this.diffLineMode(text1, text2, deadline);
-        }
-
-        return this.diffBisect(text1, text2, deadline);
-    };
-
-    /**
-     * Do the two texts share a substring which is at least half the length of the
-     * longer text?
-     * This speedup can produce non-minimal diffs.
-     * @param {string} text1 First string.
-     * @param {string} text2 Second string.
-     * @return {Array.<string>} Five element Array, containing the prefix of
-     *     text1, the suffix of text1, the prefix of text2, the suffix of
-     *     text2 and the common middle.  Or null if there was no match.
-     * @private
-     */
-    DiffMatchPatch.prototype.diffHalfMatch = function(text1, text2) {
-        var longtext, shorttext, dmp,
-			text1A, text2B, text2A, text1B, midCommon,
-			hm1, hm2, hm;
-        if (this.DiffTimeout <= 0) {
-            // Don't risk returning a non-optimal diff if we have unlimited time.
-            return null;
-        }
-        longtext = text1.length > text2.length ? text1 : text2;
-        shorttext = text1.length > text2.length ? text2 : text1;
-        if (longtext.length < 4 || shorttext.length * 2 < longtext.length) {
-            return null; // Pointless.
-        }
-        dmp = this; // 'this' becomes 'window' in a closure.
-
-        /**
-         * Does a substring of shorttext exist within longtext such that the substring
-         * is at least half the length of longtext?
-         * Closure, but does not reference any external variables.
-         * @param {string} longtext Longer string.
-         * @param {string} shorttext Shorter string.
-         * @param {number} i Start index of quarter length substring within longtext.
-         * @return {Array.<string>} Five element Array, containing the prefix of
-         *     longtext, the suffix of longtext, the prefix of shorttext, the suffix
-         *     of shorttext and the common middle.  Or null if there was no match.
-         * @private
-         */
-        function diffHalfMatchI(longtext, shorttext, i) {
-            var seed, j, bestCommon, prefixLength, suffixLength,
-				bestLongtextA, bestLongtextB, bestShorttextA, bestShorttextB;
-            // Start with a 1/4 length substring at position i as a seed.
-            seed = longtext.substring(i, i + Math.floor(longtext.length / 4));
-            j = -1;
-            bestCommon = "";
-            while ((j = shorttext.indexOf(seed, j + 1)) !== -1) {
-                prefixLength = dmp.diffCommonPrefix(longtext.substring(i),
-                    shorttext.substring(j));
-                suffixLength = dmp.diffCommonSuffix(longtext.substring(0, i),
-                    shorttext.substring(0, j));
-                if (bestCommon.length < suffixLength + prefixLength) {
-                    bestCommon = shorttext.substring(j - suffixLength, j) +
-                        shorttext.substring(j, j + prefixLength);
-                    bestLongtextA = longtext.substring(0, i - suffixLength);
-                    bestLongtextB = longtext.substring(i + prefixLength);
-                    bestShorttextA = shorttext.substring(0, j - suffixLength);
-                    bestShorttextB = shorttext.substring(j + prefixLength);
-                }
-            }
-            if (bestCommon.length * 2 >= longtext.length) {
-                return [ bestLongtextA, bestLongtextB,
-                    bestShorttextA, bestShorttextB, bestCommon
-                ];
-            } else {
-                return null;
-            }
-        }
-
-        // First check if the second quarter is the seed for a half-match.
-        hm1 = diffHalfMatchI(longtext, shorttext,
-            Math.ceil(longtext.length / 4));
-        // Check again based on the third quarter.
-        hm2 = diffHalfMatchI(longtext, shorttext,
-            Math.ceil(longtext.length / 2));
-        if (!hm1 && !hm2) {
-            return null;
-        } else if (!hm2) {
-            hm = hm1;
-        } else if (!hm1) {
-            hm = hm2;
-        } else {
-            // Both matched.  Select the longest.
-            hm = hm1[4].length > hm2[4].length ? hm1 : hm2;
-        }
-
-        // A half-match was found, sort out the return data.
-        text1A, text1B, text2A, text2B;
-        if (text1.length > text2.length) {
-            text1A = hm[0];
-            text1B = hm[1];
-            text2A = hm[2];
-            text2B = hm[3];
-        } else {
-            text2A = hm[0];
-            text2B = hm[1];
-            text1A = hm[2];
-            text1B = hm[3];
-        }
-        midCommon = hm[4];
-        return [ text1A, text1B, text2A, text2B, midCommon ];
-    };
-
-    /**
-     * Do a quick line-level diff on both strings, then rediff the parts for
-     * greater accuracy.
-     * This speedup can produce non-minimal diffs.
-     * @param {string} text1 Old string to be diffed.
-     * @param {string} text2 New string to be diffed.
-     * @param {number} deadline Time when the diff should be complete by.
-     * @return {!Array.<!DiffMatchPatch.Diff>} Array of diff tuples.
-     * @private
-     */
-    DiffMatchPatch.prototype.diffLineMode = function(text1, text2, deadline) {
-        var a, diffs, linearray, pointer, countInsert,
-			countDelete, textInsert, textDelete, j;
-        // Scan the text on a line-by-line basis first.
-        a = this.diffLinesToChars(text1, text2);
-        text1 = a.chars1;
-        text2 = a.chars2;
-        linearray = a.lineArray;
-
-        diffs = this.DiffMain(text1, text2, false, deadline);
-
-        // Convert the diff back to original text.
-        this.diffCharsToLines(diffs, linearray);
-        // Eliminate freak matches (e.g. blank lines)
-        this.diffCleanupSemantic(diffs);
-
-        // Rediff any replacement blocks, this time character-by-character.
-        // Add a dummy entry at the end.
-        diffs.push( [ DIFF_EQUAL, "" ] );
-        pointer = 0;
-        countDelete = 0;
-        countInsert = 0;
-        textDelete = "";
-        textInsert = "";
-        while (pointer < diffs.length) {
-            switch ( diffs[pointer][0] ) {
-                case DIFF_INSERT:
-                    countInsert++;
-                    textInsert += diffs[pointer][1];
-                    break;
-                case DIFF_DELETE:
-                    countDelete++;
-                    textDelete += diffs[pointer][1];
-                    break;
-                case DIFF_EQUAL:
-                    // Upon reaching an equality, check for prior redundancies.
-                    if (countDelete >= 1 && countInsert >= 1) {
-                        // Delete the offending records and add the merged ones.
-                        diffs.splice(pointer - countDelete - countInsert,
-                            countDelete + countInsert);
-                        pointer = pointer - countDelete - countInsert;
-                        a = this.DiffMain(textDelete, textInsert, false, deadline);
-                        for (j = a.length - 1; j >= 0; j--) {
-                            diffs.splice( pointer, 0, a[j] );
-                        }
-                        pointer = pointer + a.length;
-                    }
-                    countInsert = 0;
-                    countDelete = 0;
-                    textDelete = "";
-                    textInsert = "";
-                    break;
-            }
-            pointer++;
-        }
-        diffs.pop(); // Remove the dummy entry at the end.
-
-        return diffs;
-    };
-
-    /**
-     * Find the 'middle snake' of a diff, split the problem in two
-     * and return the recursively constructed diff.
-     * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations.
-     * @param {string} text1 Old string to be diffed.
-     * @param {string} text2 New string to be diffed.
-     * @param {number} deadline Time at which to bail if not yet complete.
-     * @return {!Array.<!DiffMatchPatch.Diff>} Array of diff tuples.
-     * @private
-     */
-    DiffMatchPatch.prototype.diffBisect = function(text1, text2, deadline) {
-        var text1Length, text2Length, maxD, vOffset, vLength,
-			v1, v2, x, delta, front, k1start, k1end, k2start,
-			k2end, k2Offset, k1Offset, x1, x2, y1, y2, d, k1, k2;
-        // Cache the text lengths to prevent multiple calls.
-        text1Length = text1.length;
-        text2Length = text2.length;
-        maxD = Math.ceil((text1Length + text2Length) / 2);
-        vOffset = maxD;
-        vLength = 2 * maxD;
-        v1 = new Array(vLength);
-        v2 = new Array(vLength);
-        // Setting all elements to -1 is faster in Chrome & Firefox than mixing
-        // integers and undefined.
-        for (x = 0; x < vLength; x++) {
-            v1[x] = -1;
-            v2[x] = -1;
-        }
-        v1[vOffset + 1] = 0;
-        v2[vOffset + 1] = 0;
-        delta = text1Length - text2Length;
-        // If the total number of characters is odd, then the front path will collide
-        // with the reverse path.
-        front = (delta % 2 !== 0);
-        // Offsets for start and end of k loop.
-        // Prevents mapping of space beyond the grid.
-        k1start = 0;
-        k1end = 0;
-        k2start = 0;
-        k2end = 0;
-        for (d = 0; d < maxD; d++) {
-            // Bail out if deadline is reached.
-            if ((new Date()).getTime() > deadline) {
-                break;
-            }
-
-            // Walk the front path one step.
-            for (k1 = -d + k1start; k1 <= d - k1end; k1 += 2) {
-                k1Offset = vOffset + k1;
-                if ( k1 === -d || ( k1 !== d && v1[ k1Offset - 1 ] < v1[ k1Offset + 1 ] ) ) {
-                    x1 = v1[k1Offset + 1];
-                } else {
-                    x1 = v1[k1Offset - 1] + 1;
-                }
-                y1 = x1 - k1;
-                while (x1 < text1Length && y1 < text2Length &&
-                    text1.charAt(x1) === text2.charAt(y1)) {
-                    x1++;
-                    y1++;
-                }
-                v1[k1Offset] = x1;
-                if (x1 > text1Length) {
-                    // Ran off the right of the graph.
-                    k1end += 2;
-                } else if (y1 > text2Length) {
-                    // Ran off the bottom of the graph.
-                    k1start += 2;
-                } else if (front) {
-                    k2Offset = vOffset + delta - k1;
-                    if (k2Offset >= 0 && k2Offset < vLength && v2[k2Offset] !== -1) {
-                        // Mirror x2 onto top-left coordinate system.
-                        x2 = text1Length - v2[k2Offset];
-                        if (x1 >= x2) {
-                            // Overlap detected.
-                            return this.diffBisectSplit(text1, text2, x1, y1, deadline);
-                        }
-                    }
-                }
-            }
-
-            // Walk the reverse path one step.
-            for (k2 = -d + k2start; k2 <= d - k2end; k2 += 2) {
-                k2Offset = vOffset + k2;
-                if ( k2 === -d || (k2 !== d && v2[ k2Offset - 1 ] < v2[ k2Offset + 1 ] ) ) {
-                    x2 = v2[k2Offset + 1];
-                } else {
-                    x2 = v2[k2Offset - 1] + 1;
-                }
-                y2 = x2 - k2;
-                while (x2 < text1Length && y2 < text2Length &&
-                    text1.charAt(text1Length - x2 - 1) ===
-                    text2.charAt(text2Length - y2 - 1)) {
-                    x2++;
-                    y2++;
-                }
-                v2[k2Offset] = x2;
-                if (x2 > text1Length) {
-                    // Ran off the left of the graph.
-                    k2end += 2;
-                } else if (y2 > text2Length) {
-                    // Ran off the top of the graph.
-                    k2start += 2;
-                } else if (!front) {
-                    k1Offset = vOffset + delta - k2;
-                    if (k1Offset >= 0 && k1Offset < vLength && v1[k1Offset] !== -1) {
-                        x1 = v1[k1Offset];
-                        y1 = vOffset + x1 - k1Offset;
-                        // Mirror x2 onto top-left coordinate system.
-                        x2 = text1Length - x2;
-                        if (x1 >= x2) {
-                            // Overlap detected.
-                            return this.diffBisectSplit(text1, text2, x1, y1, deadline);
-                        }
-                    }
-                }
-            }
-        }
-        // Diff took too long and hit the deadline or
-        // number of diffs equals number of characters, no commonality at all.
-        return [
-            [ DIFF_DELETE, text1 ],
-            [ DIFF_INSERT, text2 ]
-        ];
-    };
-
-    /**
-     * Given the location of the 'middle snake', split the diff in two parts
-     * and recurse.
-     * @param {string} text1 Old string to be diffed.
-     * @param {string} text2 New string to be diffed.
-     * @param {number} x Index of split point in text1.
-     * @param {number} y Index of split point in text2.
-     * @param {number} deadline Time at which to bail if not yet complete.
-     * @return {!Array.<!DiffMatchPatch.Diff>} Array of diff tuples.
-     * @private
-     */
-    DiffMatchPatch.prototype.diffBisectSplit = function( text1, text2, x, y, deadline ) {
-        var text1a, text1b, text2a, text2b, diffs, diffsb;
-        text1a = text1.substring(0, x);
-        text2a = text2.substring(0, y);
-        text1b = text1.substring(x);
-        text2b = text2.substring(y);
-
-        // Compute both diffs serially.
-        diffs = this.DiffMain(text1a, text2a, false, deadline);
-        diffsb = this.DiffMain(text1b, text2b, false, deadline);
-
-        return diffs.concat(diffsb);
-    };
-
-    /**
-     * Reduce the number of edits by eliminating semantically trivial equalities.
-     * @param {!Array.<!DiffMatchPatch.Diff>} diffs Array of diff tuples.
-     */
-    DiffMatchPatch.prototype.diffCleanupSemantic = function(diffs) {
-        var changes, equalities, equalitiesLength, lastequality,
-			pointer, lengthInsertions2, lengthDeletions2, lengthInsertions1,
-			lengthDeletions1, deletion, insertion, overlapLength1, overlapLength2;
-        changes = false;
-        equalities = []; // Stack of indices where equalities are found.
-        equalitiesLength = 0; // Keeping our own length var is faster in JS.
-        /** @type {?string} */
-        lastequality = null;
-        // Always equal to diffs[equalities[equalitiesLength - 1]][1]
-        pointer = 0; // Index of current position.
-        // Number of characters that changed prior to the equality.
-        lengthInsertions1 = 0;
-        lengthDeletions1 = 0;
-        // Number of characters that changed after the equality.
-        lengthInsertions2 = 0;
-        lengthDeletions2 = 0;
-        while (pointer < diffs.length) {
-            if (diffs[pointer][0] === DIFF_EQUAL) { // Equality found.
-                equalities[equalitiesLength++] = pointer;
-                lengthInsertions1 = lengthInsertions2;
-                lengthDeletions1 = lengthDeletions2;
-                lengthInsertions2 = 0;
-                lengthDeletions2 = 0;
-                lastequality = diffs[pointer][1];
-            } else { // An insertion or deletion.
-                if (diffs[pointer][0] === DIFF_INSERT) {
-                    lengthInsertions2 += diffs[pointer][1].length;
-                } else {
-                    lengthDeletions2 += diffs[pointer][1].length;
-                }
-                // Eliminate an equality that is smaller or equal to the edits on both
-                // sides of it.
-                if (lastequality && (lastequality.length <=
-                        Math.max(lengthInsertions1, lengthDeletions1)) &&
-                    (lastequality.length <= Math.max(lengthInsertions2,
-                        lengthDeletions2))) {
-                    // Duplicate record.
-                    diffs.splice( equalities[ equalitiesLength - 1 ], 0, [ DIFF_DELETE, lastequality ] );
-                    // Change second copy to insert.
-                    diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT;
-                    // Throw away the equality we just deleted.
-                    equalitiesLength--;
-                    // Throw away the previous equality (it needs to be reevaluated).
-                    equalitiesLength--;
-                    pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1;
-                    lengthInsertions1 = 0; // Reset the counters.
-                    lengthDeletions1 = 0;
-                    lengthInsertions2 = 0;
-                    lengthDeletions2 = 0;
-                    lastequality = null;
-                    changes = true;
-                }
-            }
-            pointer++;
-        }
-
-        // Normalize the diff.
-        if (changes) {
-            this.diffCleanupMerge(diffs);
-        }
-
-        // Find any overlaps between deletions and insertions.
-        // e.g: <del>abcxxx</del><ins>xxxdef</ins>
-        //   -> <del>abc</del>xxx<ins>def</ins>
-        // e.g: <del>xxxabc</del><ins>defxxx</ins>
-        //   -> <ins>def</ins>xxx<del>abc</del>
-        // Only extract an overlap if it is as big as the edit ahead or behind it.
-        pointer = 1;
-        while (pointer < diffs.length) {
-            if (diffs[pointer - 1][0] === DIFF_DELETE &&
-                diffs[pointer][0] === DIFF_INSERT) {
-                deletion = diffs[pointer - 1][1];
-                insertion = diffs[pointer][1];
-                overlapLength1 = this.diffCommonOverlap(deletion, insertion);
-                overlapLength2 = this.diffCommonOverlap(insertion, deletion);
-                if (overlapLength1 >= overlapLength2) {
-                    if (overlapLength1 >= deletion.length / 2 ||
-                        overlapLength1 >= insertion.length / 2) {
-                        // Overlap found.  Insert an equality and trim the surrounding edits.
-                        diffs.splice( pointer, 0, [ DIFF_EQUAL, insertion.substring( 0, overlapLength1 ) ] );
-                        diffs[pointer - 1][1] =
-                            deletion.substring(0, deletion.length - overlapLength1);
-                        diffs[pointer + 1][1] = insertion.substring(overlapLength1);
-                        pointer++;
-                    }
-                } else {
-                    if (overlapLength2 >= deletion.length / 2 ||
-                        overlapLength2 >= insertion.length / 2) {
-                        // Reverse overlap found.
-                        // Insert an equality and swap and trim the surrounding edits.
-                        diffs.splice( pointer, 0, [ DIFF_EQUAL, deletion.substring( 0, overlapLength2 ) ] );
-                        diffs[pointer - 1][0] = DIFF_INSERT;
-                        diffs[pointer - 1][1] =
-                            insertion.substring(0, insertion.length - overlapLength2);
-                        diffs[pointer + 1][0] = DIFF_DELETE;
-                        diffs[pointer + 1][1] =
-                            deletion.substring(overlapLength2);
-                        pointer++;
-                    }
-                }
-                pointer++;
-            }
-            pointer++;
-        }
-    };
-
-    /**
-     * Determine if the suffix of one string is the prefix of another.
-     * @param {string} text1 First string.
-     * @param {string} text2 Second string.
-     * @return {number} The number of characters common to the end of the first
-     *     string and the start of the second string.
-     * @private
-     */
-    DiffMatchPatch.prototype.diffCommonOverlap = function(text1, text2) {
-        var text1Length, text2Length, textLength,
-			best, length, pattern, found;
-        // Cache the text lengths to prevent multiple calls.
-        text1Length = text1.length;
-        text2Length = text2.length;
-        // Eliminate the null case.
-        if (text1Length === 0 || text2Length === 0) {
-            return 0;
-        }
-        // Truncate the longer string.
-        if (text1Length > text2Length) {
-            text1 = text1.substring(text1Length - text2Length);
-        } else if (text1Length < text2Length) {
-            text2 = text2.substring(0, text1Length);
-        }
-        textLength = Math.min(text1Length, text2Length);
-        // Quick check for the worst case.
-        if (text1 === text2) {
-            return textLength;
-        }
-
-        // Start by looking for a single character match
-        // and increase length until no match is found.
-        // Performance analysis: http://neil.fraser.name/news/2010/11/04/
-        best = 0;
-        length = 1;
-        while (true) {
-            pattern = text1.substring(textLength - length);
-            found = text2.indexOf(pattern);
-            if (found === -1) {
-                return best;
-            }
-            length += found;
-            if (found === 0 || text1.substring(textLength - length) ===
-                text2.substring(0, length)) {
-                best = length;
-                length++;
-            }
-        }
-    };
-
-    /**
-     * Split two texts into an array of strings.  Reduce the texts to a string of
-     * hashes where each Unicode character represents one line.
-     * @param {string} text1 First string.
-     * @param {string} text2 Second string.
-     * @return {{chars1: string, chars2: string, lineArray: !Array.<string>}}
-     *     An object containing the encoded text1, the encoded text2 and
-     *     the array of unique strings.
-     *     The zeroth element of the array of unique strings is intentionally blank.
-     * @private
-     */
-    DiffMatchPatch.prototype.diffLinesToChars = function(text1, text2) {
-        var lineArray, lineHash, chars1, chars2;
-        lineArray = []; // e.g. lineArray[4] === 'Hello\n'
-        lineHash = {}; // e.g. lineHash['Hello\n'] === 4
-
-        // '\x00' is a valid character, but various debuggers don't like it.
-        // So we'll insert a junk entry to avoid generating a null character.
-        lineArray[0] = "";
-
-        /**
-         * Split a text into an array of strings.  Reduce the texts to a string of
-         * hashes where each Unicode character represents one line.
-         * Modifies linearray and linehash through being a closure.
-         * @param {string} text String to encode.
-         * @return {string} Encoded string.
-         * @private
-         */
-        function diffLinesToCharsMunge(text) {
-            var chars, lineStart, lineEnd, lineArrayLength, line;
-            chars = "";
-            // Walk the text, pulling out a substring for each line.
-            // text.split('\n') would would temporarily double our memory footprint.
-            // Modifying text would create many large strings to garbage collect.
-            lineStart = 0;
-            lineEnd = -1;
-            // Keeping our own length variable is faster than looking it up.
-            lineArrayLength = lineArray.length;
-            while (lineEnd < text.length - 1) {
-                lineEnd = text.indexOf("\n", lineStart);
-                if (lineEnd === -1) {
-                    lineEnd = text.length - 1;
-                }
-                line = text.substring(lineStart, lineEnd + 1);
-                lineStart = lineEnd + 1;
-
-                if (lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) :
-                    (lineHash[line] !== undefined)) {
-                    chars += String.fromCharCode( lineHash[ line ] );
-                } else {
-                    chars += String.fromCharCode(lineArrayLength);
-                    lineHash[line] = lineArrayLength;
-                    lineArray[lineArrayLength++] = line;
-                }
-            }
-            return chars;
-        }
-
-        chars1 = diffLinesToCharsMunge(text1);
-        chars2 = diffLinesToCharsMunge(text2);
-        return {
-            chars1: chars1,
-            chars2: chars2,
-            lineArray: lineArray
-        };
-    };
-
-    /**
-     * Rehydrate the text in a diff from a string of line hashes to real lines of
-     * text.
-     * @param {!Array.<!DiffMatchPatch.Diff>} diffs Array of diff tuples.
-     * @param {!Array.<string>} lineArray Array of unique strings.
-     * @private
-     */
-    DiffMatchPatch.prototype.diffCharsToLines = function( diffs, lineArray ) {
-        var x, chars, text, y;
-        for ( x = 0; x < diffs.length; x++ ) {
-            chars = diffs[x][1];
-            text = [];
-            for ( y = 0; y < chars.length; y++ ) {
-                text[y] = lineArray[chars.charCodeAt(y)];
-            }
-            diffs[x][1] = text.join("");
-        }
-    };
-
-    /**
-     * Reorder and merge like edit sections.  Merge equalities.
-     * Any edit section can move as long as it doesn't cross an equality.
-     * @param {!Array.<!DiffMatchPatch.Diff>} diffs Array of diff tuples.
-     */
-    DiffMatchPatch.prototype.diffCleanupMerge = function(diffs) {
-        var pointer, countDelete, countInsert, textInsert, textDelete,
-			commonlength, changes;
-        diffs.push( [ DIFF_EQUAL, "" ] ); // Add a dummy entry at the end.
-        pointer = 0;
-        countDelete = 0;
-        countInsert = 0;
-        textDelete = "";
-        textInsert = "";
-        commonlength;
-        while (pointer < diffs.length) {
-            switch ( diffs[ pointer ][ 0 ] ) {
-                case DIFF_INSERT:
-                    countInsert++;
-                    textInsert += diffs[pointer][1];
-                    pointer++;
-                    break;
-                case DIFF_DELETE:
-                    countDelete++;
-                    textDelete += diffs[pointer][1];
-                    pointer++;
-                    break;
-                case DIFF_EQUAL:
-                    // Upon reaching an equality, check for prior redundancies.
-                    if (countDelete + countInsert > 1) {
-                        if (countDelete !== 0 && countInsert !== 0) {
-                            // Factor out any common prefixies.
-                            commonlength = this.diffCommonPrefix(textInsert, textDelete);
-                            if (commonlength !== 0) {
-                                if ((pointer - countDelete - countInsert) > 0 &&
-                                    diffs[pointer - countDelete - countInsert - 1][0] ===
-                                    DIFF_EQUAL) {
-                                    diffs[pointer - countDelete - countInsert - 1][1] +=
-                                        textInsert.substring(0, commonlength);
-                                } else {
-                                    diffs.splice( 0, 0, [ DIFF_EQUAL,
-                                        textInsert.substring( 0, commonlength )
-                                     ] );
-                                    pointer++;
-                                }
-                                textInsert = textInsert.substring(commonlength);
-                                textDelete = textDelete.substring(commonlength);
-                            }
-                            // Factor out any common suffixies.
-                            commonlength = this.diffCommonSuffix(textInsert, textDelete);
-                            if (commonlength !== 0) {
-                                diffs[pointer][1] = textInsert.substring(textInsert.length -
-                                    commonlength) + diffs[pointer][1];
-                                textInsert = textInsert.substring(0, textInsert.length -
-                                    commonlength);
-                                textDelete = textDelete.substring(0, textDelete.length -
-                                    commonlength);
-                            }
-                        }
-                        // Delete the offending records and add the merged ones.
-                        if (countDelete === 0) {
-                            diffs.splice( pointer - countInsert,
-                                countDelete + countInsert, [ DIFF_INSERT, textInsert ] );
-                        } else if (countInsert === 0) {
-                            diffs.splice( pointer - countDelete,
-                                countDelete + countInsert, [ DIFF_DELETE, textDelete ] );
-                        } else {
-                            diffs.splice( pointer - countDelete - countInsert,
-                                countDelete + countInsert, [ DIFF_DELETE, textDelete ], [ DIFF_INSERT, textInsert ] );
-                        }
-                        pointer = pointer - countDelete - countInsert +
-                            (countDelete ? 1 : 0) + (countInsert ? 1 : 0) + 1;
-                    } else if (pointer !== 0 && diffs[pointer - 1][0] === DIFF_EQUAL) {
-                        // Merge this equality with the previous one.
-                        diffs[pointer - 1][1] += diffs[pointer][1];
-                        diffs.splice(pointer, 1);
-                    } else {
-                        pointer++;
-                    }
-                    countInsert = 0;
-                    countDelete = 0;
-                    textDelete = "";
-                    textInsert = "";
-                    break;
-            }
-        }
-        if (diffs[diffs.length - 1][1] === "") {
-            diffs.pop(); // Remove the dummy entry at the end.
-        }
-
-        // Second pass: look for single edits surrounded on both sides by equalities
-        // which can be shifted sideways to eliminate an equality.
-        // e.g: A<ins>BA</ins>C -> <ins>AB</ins>AC
-        changes = false;
-        pointer = 1;
-        // Intentionally ignore the first and last element (don't need checking).
-        while (pointer < diffs.length - 1) {
-            if (diffs[pointer - 1][0] === DIFF_EQUAL &&
-                diffs[pointer + 1][0] === DIFF_EQUAL) {
-                // This is a single edit surrounded by equalities.
-                if ( diffs[ pointer ][ 1 ].substring( diffs[ pointer ][ 1 ].length -
-                        diffs[ pointer - 1 ][ 1 ].length ) === diffs[ pointer - 1 ][ 1 ] ) {
-                    // Shift the edit over the previous equality.
-                    diffs[pointer][1] = diffs[pointer - 1][1] +
-                        diffs[pointer][1].substring(0, diffs[pointer][1].length -
-                            diffs[pointer - 1][1].length);
-                    diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1];
-                    diffs.splice(pointer - 1, 1);
-                    changes = true;
-                } else if ( diffs[ pointer ][ 1 ].substring( 0, diffs[ pointer + 1 ][ 1 ].length ) ===
-                    diffs[ pointer + 1 ][ 1 ] ) {
-                    // Shift the edit over the next equality.
-                    diffs[pointer - 1][1] += diffs[pointer + 1][1];
-                    diffs[pointer][1] =
-                        diffs[pointer][1].substring(diffs[pointer + 1][1].length) +
-                        diffs[pointer + 1][1];
-                    diffs.splice(pointer + 1, 1);
-                    changes = true;
-                }
-            }
-            pointer++;
-        }
-        // If shifts were made, the diff needs reordering and another shift sweep.
-        if (changes) {
-            this.diffCleanupMerge(diffs);
-        }
-    };
-
-    return function(o, n) {
-		var diff, output, text;
-        diff = new DiffMatchPatch();
-        output = diff.DiffMain(o, n);
-        //console.log(output);
-        diff.diffCleanupEfficiency(output);
-        text = diff.diffPrettyHtml(output);
-
-        return text;
-    };
-}());
-// jscs:enable
-
-(function() {
-
-// Deprecated QUnit.init - Ref #530
-// Re-initialize the configuration options
-QUnit.init = function() {
-	var tests, banner, result, qunit,
-		config = QUnit.config;
-
-	config.stats = { all: 0, bad: 0 };
-	config.moduleStats = { all: 0, bad: 0 };
-	config.started = 0;
-	config.updateRate = 1000;
-	config.blocking = false;
-	config.autostart = true;
-	config.autorun = false;
-	config.filter = "";
-	config.queue = [];
-
-	// Return on non-browser environments
-	// This is necessary to not break on node tests
-	if ( typeof window === "undefined" ) {
-		return;
-	}
-
-	qunit = id( "qunit" );
-	if ( qunit ) {
-		qunit.innerHTML =
-			"<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
-			"<h2 id='qunit-banner'></h2>" +
-			"<div id='qunit-testrunner-toolbar'></div>" +
-			"<h2 id='qunit-userAgent'></h2>" +
-			"<ol id='qunit-tests'></ol>";
-	}
-
-	tests = id( "qunit-tests" );
-	banner = id( "qunit-banner" );
-	result = id( "qunit-testresult" );
-
-	if ( tests ) {
-		tests.innerHTML = "";
-	}
-
-	if ( banner ) {
-		banner.className = "";
-	}
-
-	if ( result ) {
-		result.parentNode.removeChild( result );
-	}
-
-	if ( tests ) {
-		result = document.createElement( "p" );
-		result.id = "qunit-testresult";
-		result.className = "result";
-		tests.parentNode.insertBefore( result, tests );
-		result.innerHTML = "Running...<br />&#160;";
-	}
-};
-
-// Don't load the HTML Reporter on non-Browser environments
-if ( typeof window === "undefined" ) {
-	return;
-}
-
-var config = QUnit.config,
-	hasOwn = Object.prototype.hasOwnProperty,
-	defined = {
-		document: window.document !== undefined,
-		sessionStorage: (function() {
-			var x = "qunit-test-string";
-			try {
-				sessionStorage.setItem( x, x );
-				sessionStorage.removeItem( x );
-				return true;
-			} catch ( e ) {
-				return false;
-			}
-		}())
-	},
-	modulesList = [];
-
-/**
-* Escape text for attribute or text content.
-*/
-function escapeText( s ) {
-	if ( !s ) {
-		return "";
-	}
-	s = s + "";
-
-	// Both single quotes and double quotes (for attributes)
-	return s.replace( /['"<>&]/g, function( s ) {
-		switch ( s ) {
-		case "'":
-			return "&#039;";
-		case "\"":
-			return "&quot;";
-		case "<":
-			return "&lt;";
-		case ">":
-			return "&gt;";
-		case "&":
-			return "&amp;";
-		}
-	});
-}
-
-/**
- * @param {HTMLElement} elem
- * @param {string} type
- * @param {Function} fn
- */
-function addEvent( elem, type, fn ) {
-	if ( elem.addEventListener ) {
-
-		// Standards-based browsers
-		elem.addEventListener( type, fn, false );
-	} else if ( elem.attachEvent ) {
-
-		// support: IE <9
-		elem.attachEvent( "on" + type, function() {
-			var event = window.event;
-			if ( !event.target ) {
-				event.target = event.srcElement || document;
-			}
-
-			fn.call( elem, event );
-		});
-	}
-}
-
-/**
- * @param {Array|NodeList} elems
- * @param {string} type
- * @param {Function} fn
- */
-function addEvents( elems, type, fn ) {
-	var i = elems.length;
-	while ( i-- ) {
-		addEvent( elems[ i ], type, fn );
-	}
-}
-
-function hasClass( elem, name ) {
-	return ( " " + elem.className + " " ).indexOf( " " + name + " " ) >= 0;
-}
-
-function addClass( elem, name ) {
-	if ( !hasClass( elem, name ) ) {
-		elem.className += ( elem.className ? " " : "" ) + name;
-	}
-}
-
-function toggleClass( elem, name ) {
-	if ( hasClass( elem, name ) ) {
-		removeClass( elem, name );
-	} else {
-		addClass( elem, name );
-	}
-}
-
-function removeClass( elem, name ) {
-	var set = " " + elem.className + " ";
-
-	// Class name may appear multiple times
-	while ( set.indexOf( " " + name + " " ) >= 0 ) {
-		set = set.replace( " " + name + " ", " " );
-	}
-
-	// trim for prettiness
-	elem.className = typeof set.trim === "function" ? set.trim() : set.replace( /^\s+|\s+$/g, "" );
-}
-
-function id( name ) {
-	return defined.document && document.getElementById && document.getElementById( name );
-}
-
-function getUrlConfigHtml() {
-	var i, j, val,
-		escaped, escapedTooltip,
-		selection = false,
-		len = config.urlConfig.length,
-		urlConfigHtml = "";
-
-	for ( i = 0; i < len; i++ ) {
-		val = config.urlConfig[ i ];
-		if ( typeof val === "string" ) {
-			val = {
-				id: val,
-				label: val
-			};
-		}
-
-		escaped = escapeText( val.id );
-		escapedTooltip = escapeText( val.tooltip );
-
-		if ( config[ val.id ] === undefined ) {
-			config[ val.id ] = QUnit.urlParams[ val.id ];
-		}
-
-		if ( !val.value || typeof val.value === "string" ) {
-			urlConfigHtml += "<input id='qunit-urlconfig-" + escaped +
-				"' name='" + escaped + "' type='checkbox'" +
-				( val.value ? " value='" + escapeText( val.value ) + "'" : "" ) +
-				( config[ val.id ] ? " checked='checked'" : "" ) +
-				" title='" + escapedTooltip + "' /><label for='qunit-urlconfig-" + escaped +
-				"' title='" + escapedTooltip + "'>" + val.label + "</label>";
-		} else {
-			urlConfigHtml += "<label for='qunit-urlconfig-" + escaped +
-				"' title='" + escapedTooltip + "'>" + val.label +
-				": </label><select id='qunit-urlconfig-" + escaped +
-				"' name='" + escaped + "' title='" + escapedTooltip + "'><option></option>";
-
-			if ( QUnit.is( "array", val.value ) ) {
-				for ( j = 0; j < val.value.length; j++ ) {
-					escaped = escapeText( val.value[ j ] );
-					urlConfigHtml += "<option value='" + escaped + "'" +
-						( config[ val.id ] === val.value[ j ] ?
-							( selection = true ) && " selected='selected'" : "" ) +
-						">" + escaped + "</option>";
-				}
-			} else {
-				for ( j in val.value ) {
-					if ( hasOwn.call( val.value, j ) ) {
-						urlConfigHtml += "<option value='" + escapeText( j ) + "'" +
-							( config[ val.id ] === j ?
-								( selection = true ) && " selected='selected'" : "" ) +
-							">" + escapeText( val.value[ j ] ) + "</option>";
-					}
-				}
-			}
-			if ( config[ val.id ] && !selection ) {
-				escaped = escapeText( config[ val.id ] );
-				urlConfigHtml += "<option value='" + escaped +
-					"' selected='selected' disabled='disabled'>" + escaped + "</option>";
-			}
-			urlConfigHtml += "</select>";
-		}
-	}
-
-	return urlConfigHtml;
-}
-
-// Handle "click" events on toolbar checkboxes and "change" for select menus.
-// Updates the URL with the new state of `config.urlConfig` values.
-function toolbarChanged() {
-	var updatedUrl, value,
-		field = this,
-		params = {};
-
-	// Detect if field is a select menu or a checkbox
-	if ( "selectedIndex" in field ) {
-		value = field.options[ field.selectedIndex ].value || undefined;
-	} else {
-		value = field.checked ? ( field.defaultValue || true ) : undefined;
-	}
-
-	params[ field.name ] = value;
-	updatedUrl = setUrl( params );
-
-	if ( "hidepassed" === field.name && "replaceState" in window.history ) {
-		config[ field.name ] = value || false;
-		if ( value ) {
-			addClass( id( "qunit-tests" ), "hidepass" );
-		} else {
-			removeClass( id( "qunit-tests" ), "hidepass" );
-		}
-
-		// It is not necessary to refresh the whole page
-		window.history.replaceState( null, "", updatedUrl );
-	} else {
-		window.location = updatedUrl;
-	}
-}
-
-function setUrl( params ) {
-	var key,
-		querystring = "?";
-
-	params = QUnit.extend( QUnit.extend( {}, QUnit.urlParams ), params );
-
-	for ( key in params ) {
-		if ( hasOwn.call( params, key ) ) {
-			if ( params[ key ] === undefined ) {
-				continue;
-			}
-			querystring += encodeURIComponent( key );
-			if ( params[ key ] !== true ) {
-				querystring += "=" + encodeURIComponent( params[ key ] );
-			}
-			querystring += "&";
-		}
-	}
-	return location.protocol + "//" + location.host +
-		location.pathname + querystring.slice( 0, -1 );
-}
-
-function applyUrlParams() {
-	var selectedModule,
-		modulesList = id( "qunit-modulefilter" ),
-		filter = id( "qunit-filter-input" ).value;
-
-	selectedModule = modulesList ?
-		decodeURIComponent( modulesList.options[ modulesList.selectedIndex ].value ) :
-		undefined;
-
-	window.location = setUrl({
-		module: ( selectedModule === "" ) ? undefined : selectedModule,
-		filter: ( filter === "" ) ? undefined : filter,
-
-		// Remove testId filter
-		testId: undefined
-	});
-}
-
-function toolbarUrlConfigContainer() {
-	var urlConfigContainer = document.createElement( "span" );
-
-	urlConfigContainer.innerHTML = getUrlConfigHtml();
-	addClass( urlConfigContainer, "qunit-url-config" );
-
-	// For oldIE support:
-	// * Add handlers to the individual elements instead of the container
-	// * Use "click" instead of "change" for checkboxes
-	addEvents( urlConfigContainer.getElementsByTagName( "input" ), "click", toolbarChanged );
-	addEvents( urlConfigContainer.getElementsByTagName( "select" ), "change", toolbarChanged );
-
-	return urlConfigContainer;
-}
-
-function toolbarLooseFilter() {
-	var filter = document.createElement( "form" ),
-		label = document.createElement( "label" ),
-		input = document.createElement( "input" ),
-		button = document.createElement( "button" );
-
-	addClass( filter, "qunit-filter" );
-
-	label.innerHTML = "Filter: ";
-
-	input.type = "text";
-	input.value = config.filter || "";
-	input.name = "filter";
-	input.id = "qunit-filter-input";
-
-	button.innerHTML = "Go";
-
-	label.appendChild( input );
-
-	filter.appendChild( label );
-	filter.appendChild( button );
-	addEvent( filter, "submit", function( ev ) {
-		applyUrlParams();
-
-		if ( ev && ev.preventDefault ) {
-			ev.preventDefault();
-		}
-
-		return false;
-	});
-
-	return filter;
-}
-
-function toolbarModuleFilterHtml() {
-	var i,
-		moduleFilterHtml = "";
-
-	if ( !modulesList.length ) {
-		return false;
-	}
-
-	modulesList.sort(function( a, b ) {
-		return a.localeCompare( b );
-	});
-
-	moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label>" +
-		"<select id='qunit-modulefilter' name='modulefilter'><option value='' " +
-		( QUnit.urlParams.module === undefined ? "selected='selected'" : "" ) +
-		">< All Modules ></option>";
-
-	for ( i = 0; i < modulesList.length; i++ ) {
-		moduleFilterHtml += "<option value='" +
-			escapeText( encodeURIComponent( modulesList[ i ] ) ) + "' " +
-			( QUnit.urlParams.module === modulesList[ i ] ? "selected='selected'" : "" ) +
-			">" + escapeText( modulesList[ i ] ) + "</option>";
-	}
-	moduleFilterHtml += "</select>";
-
-	return moduleFilterHtml;
-}
-
-function toolbarModuleFilter() {
-	var toolbar = id( "qunit-testrunner-toolbar" ),
-		moduleFilter = document.createElement( "span" ),
-		moduleFilterHtml = toolbarModuleFilterHtml();
-
-	if ( !toolbar || !moduleFilterHtml ) {
-		return false;
-	}
-
-	moduleFilter.setAttribute( "id", "qunit-modulefilter-container" );
-	moduleFilter.innerHTML = moduleFilterHtml;
-
-	addEvent( moduleFilter.lastChild, "change", applyUrlParams );
-
-	toolbar.appendChild( moduleFilter );
-}
-
-function appendToolbar() {
-	var toolbar = id( "qunit-testrunner-toolbar" );
-
-	if ( toolbar ) {
-		toolbar.appendChild( toolbarUrlConfigContainer() );
-		toolbar.appendChild( toolbarLooseFilter() );
-	}
-}
-
-function appendHeader() {
-	var header = id( "qunit-header" );
-
-	if ( header ) {
-		header.innerHTML = "<a href='" +
-			setUrl({ filter: undefined, module: undefined, testId: undefined }) +
-			"'>" + header.innerHTML + "</a> ";
-	}
-}
-
-function appendBanner() {
-	var banner = id( "qunit-banner" );
-
-	if ( banner ) {
-		banner.className = "";
-	}
-}
-
-function appendTestResults() {
-	var tests = id( "qunit-tests" ),
-		result = id( "qunit-testresult" );
-
-	if ( result ) {
-		result.parentNode.removeChild( result );
-	}
-
-	if ( tests ) {
-		tests.innerHTML = "";
-		result = document.createElement( "p" );
-		result.id = "qunit-testresult";
-		result.className = "result";
-		tests.parentNode.insertBefore( result, tests );
-		result.innerHTML = "Running...<br />&#160;";
-	}
-}
-
-function storeFixture() {
-	var fixture = id( "qunit-fixture" );
-	if ( fixture ) {
-		config.fixture = fixture.innerHTML;
-	}
-}
-
-function appendUserAgent() {
-	var userAgent = id( "qunit-userAgent" );
-
-	if ( userAgent ) {
-		userAgent.innerHTML = "";
-		userAgent.appendChild(
-			document.createTextNode(
-				"QUnit " + QUnit.version  + "; " + navigator.userAgent
-			)
-		);
-	}
-}
-
-function appendTestsList( modules ) {
-	var i, l, x, z, test, moduleObj;
-
-	for ( i = 0, l = modules.length; i < l; i++ ) {
-		moduleObj = modules[ i ];
-
-		if ( moduleObj.name ) {
-			modulesList.push( moduleObj.name );
-		}
-
-		for ( x = 0, z = moduleObj.tests.length; x < z; x++ ) {
-			test = moduleObj.tests[ x ];
-
-			appendTest( test.name, test.testId, moduleObj.name );
-		}
-	}
-}
-
-function appendTest( name, testId, moduleName ) {
-	var title, rerunTrigger, testBlock, assertList,
-		tests = id( "qunit-tests" );
-
-	if ( !tests ) {
-		return;
-	}
-
-	title = document.createElement( "strong" );
-	title.innerHTML = getNameHtml( name, moduleName );
-
-	rerunTrigger = document.createElement( "a" );
-	rerunTrigger.innerHTML = "Rerun";
-	rerunTrigger.href = setUrl({ testId: testId });
-
-	testBlock = document.createElement( "li" );
-	testBlock.appendChild( title );
-	testBlock.appendChild( rerunTrigger );
-	testBlock.id = "qunit-test-output-" + testId;
-
-	assertList = document.createElement( "ol" );
-	assertList.className = "qunit-assert-list";
-
-	testBlock.appendChild( assertList );
-
-	tests.appendChild( testBlock );
-}
-
-// HTML Reporter initialization and load
-QUnit.begin(function( details ) {
-	var qunit = id( "qunit" );
-
-	// Fixture is the only one necessary to run without the #qunit element
-	storeFixture();
-
-	if ( qunit ) {
-		qunit.innerHTML =
-			"<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
-			"<h2 id='qunit-banner'></h2>" +
-			"<div id='qunit-testrunner-toolbar'></div>" +
-			"<h2 id='qunit-userAgent'></h2>" +
-			"<ol id='qunit-tests'></ol>";
-	}
-
-	appendHeader();
-	appendBanner();
-	appendTestResults();
-	appendUserAgent();
-	appendToolbar();
-	appendTestsList( details.modules );
-	toolbarModuleFilter();
-
-	if ( qunit && config.hidepassed ) {
-		addClass( qunit.lastChild, "hidepass" );
-	}
-});
-
-QUnit.done(function( details ) {
-	var i, key,
-		banner = id( "qunit-banner" ),
-		tests = id( "qunit-tests" ),
-		html = [
-			"Tests completed in ",
-			details.runtime,
-			" milliseconds.<br />",
-			"<span class='passed'>",
-			details.passed,
-			"</span> assertions of <span class='total'>",
-			details.total,
-			"</span> passed, <span class='failed'>",
-			details.failed,
-			"</span> failed."
-		].join( "" );
-
-	if ( banner ) {
-		banner.className = details.failed ? "qunit-fail" : "qunit-pass";
-	}
-
-	if ( tests ) {
-		id( "qunit-testresult" ).innerHTML = html;
-	}
-
-	if ( config.altertitle && defined.document && document.title ) {
-
-		// show ✖ for good, ✔ for bad suite result in title
-		// use escape sequences in case file gets loaded with non-utf-8-charset
-		document.title = [
-			( details.failed ? "\u2716" : "\u2714" ),
-			document.title.replace( /^[\u2714\u2716] /i, "" )
-		].join( " " );
-	}
-
-	// clear own sessionStorage items if all tests passed
-	if ( config.reorder && defined.sessionStorage && details.failed === 0 ) {
-		for ( i = 0; i < sessionStorage.length; i++ ) {
-			key = sessionStorage.key( i++ );
-			if ( key.indexOf( "qunit-test-" ) === 0 ) {
-				sessionStorage.removeItem( key );
-			}
-		}
-	}
-
-	// scroll back to top to show results
-	if ( config.scrolltop && window.scrollTo ) {
-		window.scrollTo( 0, 0 );
-	}
-});
-
-function getNameHtml( name, module ) {
-	var nameHtml = "";
-
-	if ( module ) {
-		nameHtml = "<span class='module-name'>" + escapeText( module ) + "</span>: ";
-	}
-
-	nameHtml += "<span class='test-name'>" + escapeText( name ) + "</span>";
-
-	return nameHtml;
-}
-
-QUnit.testStart(function( details ) {
-	var running, testBlock, bad;
-
-	testBlock = id( "qunit-test-output-" + details.testId );
-	if ( testBlock ) {
-		testBlock.className = "running";
-	} else {
-
-		// Report later registered tests
-		appendTest( details.name, details.testId, details.module );
-	}
-
-	running = id( "qunit-testresult" );
-	if ( running ) {
-		bad = QUnit.config.reorder && defined.sessionStorage &&
-			+sessionStorage.getItem( "qunit-test-" + details.module + "-" + details.name );
-
-		running.innerHTML = ( bad ?
-			"Rerunning previously failed test: <br />" :
-			"Running: <br />" ) +
-			getNameHtml( details.name, details.module );
-	}
-
-});
-
-QUnit.log(function( details ) {
-	var assertList, assertLi,
-		message, expected, actual,
-		testItem = id( "qunit-test-output-" + details.testId );
-
-	if ( !testItem ) {
-		return;
-	}
-
-	message = escapeText( details.message ) || ( details.result ? "okay" : "failed" );
-	message = "<span class='test-message'>" + message + "</span>";
-	message += "<span class='runtime'>@ " + details.runtime + " ms</span>";
-
-	// pushFailure doesn't provide details.expected
-	// when it calls, it's implicit to also not show expected and diff stuff
-	// Also, we need to check details.expected existence, as it can exist and be undefined
-	if ( !details.result && hasOwn.call( details, "expected" ) ) {
-		expected = escapeText( QUnit.dump.parse( details.expected ) );
-		actual = escapeText( QUnit.dump.parse( details.actual ) );
-		message += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" +
-			expected +
-			"</pre></td></tr>";
-
-		if ( actual !== expected ) {
-			message += "<tr class='test-actual'><th>Result: </th><td><pre>" +
-				actual + "</pre></td></tr>" +
-				"<tr class='test-diff'><th>Diff: </th><td><pre>" +
-				QUnit.diff( expected, actual ) + "</pre></td></tr>";
-		} else {
-			if ( expected.indexOf( "[object Array]" ) !== -1 ||
-					expected.indexOf( "[object Object]" ) !== -1 ) {
-				message += "<tr class='test-message'><th>Message: </th><td>" +
-					"Diff suppressed as the depth of object is more than current max depth (" +
-					QUnit.config.maxDepth + ").<p>Hint: Use <code>QUnit.dump.maxDepth</code> to " +
-					" run with a higher max depth or <a href='" + setUrl({ maxDepth: -1 }) + "'>" +
-					"Rerun</a> without max depth.</p></td></tr>";
-			}
-		}
-
-		if ( details.source ) {
-			message += "<tr class='test-source'><th>Source: </th><td><pre>" +
-				escapeText( details.source ) + "</pre></td></tr>";
-		}
-
-		message += "</table>";
-
-	// this occours when pushFailure is set and we have an extracted stack trace
-	} else if ( !details.result && details.source ) {
-		message += "<table>" +
-			"<tr class='test-source'><th>Source: </th><td><pre>" +
-			escapeText( details.source ) + "</pre></td></tr>" +
-			"</table>";
-	}
-
-	assertList = testItem.getElementsByTagName( "ol" )[ 0 ];
-
-	assertLi = document.createElement( "li" );
-	assertLi.className = details.result ? "pass" : "fail";
-	assertLi.innerHTML = message;
-	assertList.appendChild( assertLi );
-});
-
-QUnit.testDone(function( details ) {
-	var testTitle, time, testItem, assertList,
-		good, bad, testCounts, skipped,
-		tests = id( "qunit-tests" );
-
-	if ( !tests ) {
-		return;
-	}
-
-	testItem = id( "qunit-test-output-" + details.testId );
-
-	assertList = testItem.getElementsByTagName( "ol" )[ 0 ];
-
-	good = details.passed;
-	bad = details.failed;
-
-	// store result when possible
-	if ( config.reorder && defined.sessionStorage ) {
-		if ( bad ) {
-			sessionStorage.setItem( "qunit-test-" + details.module + "-" + details.name, bad );
-		} else {
-			sessionStorage.removeItem( "qunit-test-" + details.module + "-" + details.name );
-		}
-	}
-
-	if ( bad === 0 ) {
-		addClass( assertList, "qunit-collapsed" );
-	}
-
-	// testItem.firstChild is the test name
-	testTitle = testItem.firstChild;
-
-	testCounts = bad ?
-		"<b class='failed'>" + bad + "</b>, " + "<b class='passed'>" + good + "</b>, " :
-		"";
-
-	testTitle.innerHTML += " <b class='counts'>(" + testCounts +
-		details.assertions.length + ")</b>";
-
-	if ( details.skipped ) {
-		testItem.className = "skipped";
-		skipped = document.createElement( "em" );
-		skipped.className = "qunit-skipped-label";
-		skipped.innerHTML = "skipped";
-		testItem.insertBefore( skipped, testTitle );
-	} else {
-		addEvent( testTitle, "click", function() {
-			toggleClass( assertList, "qunit-collapsed" );
-		});
-
-		testItem.className = bad ? "fail" : "pass";
-
-		time = document.createElement( "span" );
-		time.className = "runtime";
-		time.innerHTML = details.runtime + " ms";
-		testItem.insertBefore( time, assertList );
-	}
-});
-
-if ( defined.document ) {
-	if ( document.readyState === "complete" ) {
-		QUnit.load();
-	} else {
-		addEvent( window, "load", QUnit.load );
-	}
-} else {
-	config.pageLoaded = true;
-	config.autorun = true;
-}
-
-})();

+ 4 - 4
test/unit/qunit-utils.js

@@ -60,10 +60,10 @@ function checkGeometryClone( geom ) {
 	var excludedProperties = [ 'parameters', 'widthSegments', 'heightSegments', 'depthSegments' ];
 	var excludedProperties = [ 'parameters', 'widthSegments', 'heightSegments', 'depthSegments' ];
 
 
 	var differingProp = getDifferingProp( geom, copy, excludedProperties );
 	var differingProp = getDifferingProp( geom, copy, excludedProperties );
-	ok( differingProp === undefined, 'properties are equal' );
+	QUnit.assert.ok( differingProp === undefined, 'properties are equal' );
 
 
 	differingProp = getDifferingProp( copy, geom, excludedProperties );
 	differingProp = getDifferingProp( copy, geom, excludedProperties );
-	ok( differingProp === undefined, 'properties are equal' );
+	QUnit.assert.ok( differingProp === undefined, 'properties are equal' );
 
 
 	// json round trip with clone
 	// json round trip with clone
 	checkGeometryJsonRoundtrip( copy );
 	checkGeometryJsonRoundtrip( copy );
@@ -151,10 +151,10 @@ function checkGeometryJsonReading( json, geom ) {
 	var excludedProperties = [ 'bones' ];
 	var excludedProperties = [ 'bones' ];
 
 
 	var differingProp = getDifferingProp( output[ geom.uuid ], geom, excludedProperties );
 	var differingProp = getDifferingProp( output[ geom.uuid ], geom, excludedProperties );
-	ok( differingProp === undefined, 'properties are equal' );
+	QUnit.assert.ok( differingProp === undefined, 'properties are equal' );
 
 
 	differingProp = getDifferingProp( geom, output[ geom.uuid ], excludedProperties );
 	differingProp = getDifferingProp( geom, output[ geom.uuid ], excludedProperties );
-	ok( differingProp === undefined, 'properties are equal' );
+	QUnit.assert.ok( differingProp === undefined, 'properties are equal' );
 }
 }
 
 
 // Verify geom -> json -> geom
 // Verify geom -> json -> geom

+ 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")

+ 9 - 9
test/unit/animation/AnimationObjectGroup.js → test/unit/src/animation/AnimationObjectGroup.js

@@ -2,7 +2,7 @@
  * @author tschw
  * @author tschw
  */
  */
 
 
-module( "AnimationObjectGroup" );
+QUnit.module( "AnimationObjectGroup" );
 
 
 var ObjectA = new THREE.Object3D(),
 var ObjectA = new THREE.Object3D(),
 	ObjectB = new THREE.Object3D(),
 	ObjectB = new THREE.Object3D(),
@@ -17,7 +17,7 @@ var ObjectA = new THREE.Object3D(),
 	ParsedPathC = THREE.PropertyBinding.parseTrackName( PathC );
 	ParsedPathC = THREE.PropertyBinding.parseTrackName( PathC );
 
 
 
 
-test( "smoke test", function() {
+QUnit.test( "smoke test", function( assert ) {
 
 
 	var expect = function expect( testIndex, group, bindings, path, cached, roots ) {
 	var expect = function expect( testIndex, group, bindings, path, cached, roots ) {
 
 
@@ -36,23 +36,23 @@ test( "smoke test", function() {
 
 
 		}
 		}
 
 
-		ok( pathsOk, testIndex + " paths" );
-		ok( nodesOk, testIndex + " nodes");
-		ok( group.nCachedObjects_ === cached, testIndex + " cache size" );
-		ok( bindings.length - group.nCachedObjects_ === roots.length, testIndex + " object count" );
+		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
 	// initial state
 
 
 	var groupA = new THREE.AnimationObjectGroup();
 	var groupA = new THREE.AnimationObjectGroup();
-	ok( groupA instanceof THREE.AnimationObjectGroup, "constructor (w/o args)" );
+	assert.ok( groupA instanceof THREE.AnimationObjectGroup, "constructor (w/o args)" );
 
 
 	var bindingsAA = groupA.subscribe_( PathA, ParsedPathA );
 	var bindingsAA = groupA.subscribe_( PathA, ParsedPathA );
 	expect( 0, groupA, bindingsAA, PathA, 0, [] );
 	expect( 0, groupA, bindingsAA, PathA, 0, [] );
 
 
 	var groupB = new THREE.AnimationObjectGroup( ObjectA, ObjectB );
 	var groupB = new THREE.AnimationObjectGroup( ObjectA, ObjectB );
-	ok( groupB instanceof THREE.AnimationObjectGroup, "constructor (with args)" );
+	assert.ok( groupB instanceof THREE.AnimationObjectGroup, "constructor (with args)" );
 
 
 	var bindingsBB = groupB.subscribe_( PathB, ParsedPathB );
 	var bindingsBB = groupB.subscribe_( PathB, ParsedPathB );
 	expect( 1, groupB, bindingsBB, PathB, 0, [ ObjectA, ObjectB ] );
 	expect( 1, groupB, bindingsBB, PathB, 0, [ ObjectA, ObjectB ] );
@@ -91,7 +91,7 @@ test( "smoke test", function() {
 	var copyOfBindingsBC = bindingsBC.slice();
 	var copyOfBindingsBC = bindingsBC.slice();
 	groupB.unsubscribe_( PathC );
 	groupB.unsubscribe_( PathC );
 	groupB.add( ObjectC );
 	groupB.add( ObjectC );
-	deepEqual( bindingsBC, copyOfBindingsBC, "no more update after unsubscribe" );
+	assert.deepEqual( bindingsBC, copyOfBindingsBC, "no more update after unsubscribe" );
 
 
 	// uncache active
 	// uncache active
 
 

+ 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")

+ 6 - 6
test/unit/cameras/Camera.js → test/unit/src/cameras/Camera.js

@@ -2,16 +2,16 @@
  * @author simonThiele / https://github.com/simonThiele
  * @author simonThiele / https://github.com/simonThiele
  */
  */
 
 
-module( "Camera" );
+QUnit.module( "Camera" );
 
 
-test( "lookAt", function() {
+QUnit.test( "lookAt" , function( assert ) {
 	var cam = new THREE.Camera();
 	var cam = new THREE.Camera();
 	cam.lookAt(new THREE.Vector3(0, 1, -1));
 	cam.lookAt(new THREE.Vector3(0, 1, -1));
 
 
-	ok( cam.rotation.x * (180 / Math.PI) === 45 , "x is equal" );
+	assert.ok( cam.rotation.x * (180 / Math.PI) === 45 , "x is equal" );
 });
 });
 
 
-test( "clone", function() {
+QUnit.test( "clone" , function( assert ) {
 	var cam = new THREE.Camera();
 	var cam = new THREE.Camera();
 
 
 	// fill the matrices with any nonsense values just to see if they get copied
 	// fill the matrices with any nonsense values just to see if they get copied
@@ -20,6 +20,6 @@ test( "clone", function() {
 
 
 	var clonedCam = cam.clone();
 	var clonedCam = cam.clone();
 
 
-	ok( cam.matrixWorldInverse.equals(clonedCam.matrixWorldInverse) , "matrixWorldInverse is equal" );
-	ok( cam.projectionMatrix.equals(clonedCam.projectionMatrix) , "projectionMatrix is equal" );
+	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" );
+});

+ 10 - 10
test/unit/cameras/PerspectiveCamera.js → test/unit/src/cameras/PerspectiveCamera.js

@@ -2,9 +2,9 @@
  * @author simonThiele / https://github.com/simonThiele
  * @author simonThiele / https://github.com/simonThiele
  */
  */
 
 
-module( "PerspectiveCamera" );
+QUnit.module( "PerspectiveCamera" );
 
 
-test( "updateProjectionMatrix", function() {
+QUnit.test( "updateProjectionMatrix" , function( assert ) {
 
 
 	var cam = new THREE.PerspectiveCamera( 75, 16 / 9, 0.1, 300.0 );
 	var cam = new THREE.PerspectiveCamera( 75, 16 / 9, 0.1, 300.0 );
 
 
@@ -26,10 +26,10 @@ test( "updateProjectionMatrix", function() {
 		0, 0, -1, 0
 		0, 0, -1, 0
 	);
 	);
 
 
-	ok( reference.equals(m) );
+	assert.ok( reference.equals(m) );
 });
 });
 
 
-test( "clone", function() {
+QUnit.test( "clone" , function( assert ) {
 	var near = 1,
 	var near = 1,
 			far = 3,
 			far = 3,
 			bottom = -1,
 			bottom = -1,
@@ -41,10 +41,10 @@ test( "clone", function() {
 
 
 	var clonedCam = cam.clone();
 	var clonedCam = cam.clone();
 
 
-	ok( cam.fov === clonedCam.fov , "fov is equal" );
-	ok( cam.aspect === clonedCam.aspect , "aspect is equal" );
-	ok( cam.near === clonedCam.near , "near is equal" );
-	ok( cam.far === clonedCam.far , "far is equal" );
-	ok( cam.zoom === clonedCam.zoom , "zoom is equal" );
-	ok( cam.projectionMatrix.equals(clonedCam.projectionMatrix) , "projectionMatrix is equal" );
+	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" );
 });
 });

Some files were not shown because too many files changed in this diff