// // Custom QUnit assertions. // QUnit.assert.success = function( message ) { // Equivalent to assert( true, message ); QUnit.assert.push( true, undefined, undefined, message ); }; QUnit.assert.fail = function( message ) { // Equivalent to assert( false, message ); QUnit.assert.push( false, undefined, undefined, message ); }; QUnit.assert.numEqual = function( actual, expected, message ) { var diff = Math.abs(actual - expected); message = message || ( actual + " should be equal to " + expected ); QUnit.assert.push( diff < 0.1, actual, expected, message ); }; QUnit.assert.equalKey = function( obj, ref, key ) { var actual = obj[key]; var expected = ref[key]; var message = actual + ' should be equal to ' + expected + ' for key "' + key + '"'; QUnit.assert.push( actual == expected, actual, expected, message ); }; QUnit.assert.smartEqual = function( actual, expected, message ) { var cmp = new SmartComparer(); var same = cmp.areEqual(actual, expected); var msg = cmp.getDiagnostic() || message; QUnit.assert.push( same, actual, expected, msg ); }; // // GEOMETRY TEST HELPERS // function checkGeometryClone( geom ) { // Clone var copy = geom.clone(); QUnit.assert.notEqual( copy.uuid, geom.uuid, "clone uuid should differ from original" ); QUnit.assert.notEqual( copy.id, geom.id, "clone id should differ from original" ); var excludedProperties = [ 'parameters', 'widthSegments', 'heightSegments', 'depthSegments' ]; var differingProp = getDifferingProp( geom, copy, excludedProperties ); ok( differingProp === undefined, 'properties are equal' ); differingProp = getDifferingProp( copy, geom, excludedProperties ); ok( differingProp === undefined, 'properties are equal' ); // json round trip with clone checkGeometryJsonRoundtrip( copy ); } function getDifferingProp( geometryA, geometryB, excludedProperties) { excludedProperties = excludedProperties || []; var geometryKeys = Object.keys( geometryA ); var cloneKeys = Object.keys( geometryB ); var keysWhichAreNotChecked = [ 'parameters', 'widthSegments', 'heightSegments', 'depthSegments' ]; var differingProp = undefined; for ( var i = 0, l = geometryKeys.length; i < l; i++ ) { var key = geometryKeys[ i ]; if ( excludedProperties.indexOf(key) >= 0 ) { continue; } if ( cloneKeys.indexOf( key ) < 0 ) { differingProp = key; break; } } return differingProp; } // Compare json file with its source geometry. function checkGeometryJsonWriting( geom, json ) { QUnit.assert.equal( json.metadata.version, "4.4", "check metadata version" ); QUnit.assert.equalKey( geom, json, 'type' ); QUnit.assert.equalKey( geom, json, 'uuid' ); QUnit.assert.equal( json.id, undefined, "should not persist id" ); var params = geom.parameters; if ( !params ) { return; } // All parameters from geometry should be persisted. var keys = Object.keys( params ); for ( var i = 0, l = keys.length; i < l; i++ ) { QUnit.assert.equalKey( params, json, keys[ i ] ); } // All parameters from json should be transfered to the geometry. // json is flat. Ignore first level json properties that are not parameters. var notParameters = [ "metadata", "uuid", "type" ]; var keys = Object.keys( json ); for ( var i = 0, l = keys.length; i < l; i++ ) { var key = keys[ i ]; if ( notParameters.indexOf( key) === -1 ) QUnit.assert.equalKey( params, json, key ); } } // Check parsing and reconstruction of json geometry function checkGeometryJsonReading( json, geom ) { var wrap = [ json ]; var loader = new THREE.ObjectLoader(); var output = loader.parseGeometries( wrap ); QUnit.assert.ok( output[ geom.uuid ], 'geometry matching source uuid not in output' ); // QUnit.assert.smartEqual( output[ geom.uuid ], geom, 'Reconstruct geometry from ObjectLoader' ); var differing = getDifferingProp(output[ geom.uuid ], geom, ['bones']); if (differing) { console.log(differing); } var excludedProperties = [ 'bones' ]; var differingProp = getDifferingProp( output[ geom.uuid ], geom, excludedProperties ); ok( differingProp === undefined, 'properties are equal' ); differingProp = getDifferingProp( geom, output[ geom.uuid ], excludedProperties ); ok( differingProp === undefined, 'properties are equal' ); } // Verify geom -> json -> geom function checkGeometryJsonRoundtrip( geom ) { var json = geom.toJSON(); checkGeometryJsonWriting( geom, json ); checkGeometryJsonReading( json, geom ); } // Look for undefined and NaN values in numerical fieds. function checkFinite( geom ) { var allVerticesAreFinite = true; var vertices = geom.vertices || []; for ( var i = 0, l = vertices.length; i < l; i++ ) { var v = geom.vertices[ i ]; if ( !( isFinite( v.x ) || isFinite( v.y ) || isFinite( v.z ) ) ) { allVerticesAreFinite = false; break; } } // TODO Buffers, normal, etc. QUnit.assert.ok( allVerticesAreFinite, "contains only finite coordinates" ); } // Run common geometry tests. function runStdGeometryTests( assert, geometries ) { for ( var i = 0, l = geometries.length; i < l; i++ ) { var geom = geometries[ i ]; checkFinite( geom ); // Clone checkGeometryClone( geom ); // json round trip checkGeometryJsonRoundtrip( geom ); } } // // LIGHT TEST HELPERS // // Run common light tests. function runStdLightTests( assert, lights ) { for ( var i = 0, l = lights.length; i < l; i++ ) { var light = lights[i]; // Clone checkLightClone( light ); // json round trip checkLightJsonRoundtrip( light ); } } function checkLightClone( light ) { // Clone var copy = light.clone(); QUnit.assert.notEqual( copy.uuid, light.uuid, "clone uuid should differ from original" ); QUnit.assert.notEqual( copy.id, light.id, "clone id should differ from original" ); QUnit.assert.smartEqual( copy, light, "clone is equal to original" ); // json round trip with clone checkLightJsonRoundtrip( copy ); } // Compare json file with its source Light. function checkLightJsonWriting( light, json ) { QUnit.assert.equal( json.metadata.version, "4.4", "check metadata version" ); var object = json.object; QUnit.assert.equalKey( light, object, 'type' ); QUnit.assert.equalKey( light, object, 'uuid' ); QUnit.assert.equal( object.id, undefined, "should not persist id" ); } // Check parsing and reconstruction of json Light function checkLightJsonReading( json, light ) { var loader = new THREE.ObjectLoader(); var outputLight = loader.parse( json ); QUnit.assert.smartEqual( outputLight, light, 'Reconstruct Light from ObjectLoader' ); } // Verify light -> json -> light function checkLightJsonRoundtrip( light ) { var json = light.toJSON(); checkLightJsonWriting( light, json ); checkLightJsonReading( json, light ); }