You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
302 lines
7.2 KiB
302 lines
7.2 KiB
2 years ago
|
//
|
||
|
// Custom QUnit assertions.
|
||
|
///* global QUnit */
|
||
|
|
||
|
import { SmartComparer } from './SmartComparer.js';
|
||
|
import { ObjectLoader } from '../../../src/loaders/ObjectLoader.js';
|
||
|
|
||
|
QUnit.assert.success = function ( message ) {
|
||
|
|
||
|
// Equivalent to assert( true, message );
|
||
|
this.pushResult( {
|
||
|
result: true,
|
||
|
actual: undefined,
|
||
|
expected: undefined,
|
||
|
message: message
|
||
|
} );
|
||
|
|
||
|
};
|
||
|
|
||
|
QUnit.assert.fail = function ( message ) {
|
||
|
|
||
|
// Equivalent to assert( false, message );
|
||
|
this.pushResult( {
|
||
|
result: false,
|
||
|
actual: undefined,
|
||
|
expected: undefined,
|
||
|
message: message
|
||
|
} );
|
||
|
|
||
|
};
|
||
|
|
||
|
QUnit.assert.numEqual = function ( actual, expected, message ) {
|
||
|
|
||
|
const diff = Math.abs( actual - expected );
|
||
|
message = message || ( actual + ' should be equal to ' + expected );
|
||
|
this.pushResult( {
|
||
|
result: diff < 0.1,
|
||
|
actual: actual,
|
||
|
expected: expected,
|
||
|
message: message
|
||
|
} );
|
||
|
|
||
|
};
|
||
|
|
||
|
QUnit.assert.equalKey = function ( obj, ref, key ) {
|
||
|
|
||
|
const actual = obj[ key ];
|
||
|
const expected = ref[ key ];
|
||
|
const message = actual + ' should be equal to ' + expected + ' for key "' + key + '"';
|
||
|
this.pushResult( {
|
||
|
result: actual == expected,
|
||
|
actual: actual,
|
||
|
expected: expected,
|
||
|
message: message
|
||
|
} );
|
||
|
|
||
|
};
|
||
|
|
||
|
QUnit.assert.smartEqual = function ( actual, expected, message ) {
|
||
|
|
||
|
const cmp = new SmartComparer();
|
||
|
|
||
|
const same = cmp.areEqual( actual, expected );
|
||
|
const msg = cmp.getDiagnostic() || message;
|
||
|
|
||
|
this.pushResult( {
|
||
|
result: same,
|
||
|
actual: actual,
|
||
|
expected: expected,
|
||
|
message: msg
|
||
|
} );
|
||
|
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// GEOMETRY TEST HELPERS
|
||
|
//
|
||
|
|
||
|
function checkGeometryClone( geom ) {
|
||
|
|
||
|
// Clone
|
||
|
const 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' );
|
||
|
|
||
|
let differingProp = getDifferingProp( geom, copy );
|
||
|
QUnit.assert.ok( differingProp === undefined, 'properties are equal' );
|
||
|
|
||
|
differingProp = getDifferingProp( copy, geom );
|
||
|
QUnit.assert.ok( differingProp === undefined, 'properties are equal' );
|
||
|
|
||
|
// json round trip with clone
|
||
|
checkGeometryJsonRoundtrip( copy );
|
||
|
|
||
|
}
|
||
|
|
||
|
function getDifferingProp( geometryA, geometryB ) {
|
||
|
|
||
|
const geometryKeys = Object.keys( geometryA );
|
||
|
const cloneKeys = Object.keys( geometryB );
|
||
|
|
||
|
let differingProp = undefined;
|
||
|
|
||
|
for ( let i = 0, l = geometryKeys.length; i < l; i ++ ) {
|
||
|
|
||
|
const key = geometryKeys[ i ];
|
||
|
|
||
|
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.5', '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' );
|
||
|
|
||
|
const params = geom.parameters;
|
||
|
if ( ! params ) {
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
// All parameters from geometry should be persisted.
|
||
|
let keys = Object.keys( params );
|
||
|
for ( let 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.
|
||
|
const notParameters = [ 'metadata', 'uuid', 'type' ];
|
||
|
keys = Object.keys( json );
|
||
|
for ( let i = 0, l = keys.length; i < l; i ++ ) {
|
||
|
|
||
|
const 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 ) {
|
||
|
|
||
|
const wrap = [ json ];
|
||
|
|
||
|
const loader = new ObjectLoader();
|
||
|
const 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' );
|
||
|
|
||
|
const differing = getDifferingProp( output[ geom.uuid ], geom );
|
||
|
if ( differing ) console.log( differing );
|
||
|
|
||
|
let differingProp = getDifferingProp( output[ geom.uuid ], geom );
|
||
|
QUnit.assert.ok( differingProp === undefined, 'properties are equal' );
|
||
|
|
||
|
differingProp = getDifferingProp( geom, output[ geom.uuid ] );
|
||
|
QUnit.assert.ok( differingProp === undefined, 'properties are equal' );
|
||
|
|
||
|
}
|
||
|
|
||
|
// Verify geom -> json -> geom
|
||
|
function checkGeometryJsonRoundtrip( geom ) {
|
||
|
|
||
|
const json = geom.toJSON();
|
||
|
checkGeometryJsonWriting( geom, json );
|
||
|
checkGeometryJsonReading( json, geom );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
// Run common geometry tests.
|
||
|
function runStdGeometryTests( assert, geometries ) {
|
||
|
|
||
|
for ( let i = 0, l = geometries.length; i < l; i ++ ) {
|
||
|
|
||
|
const geom = geometries[ i ];
|
||
|
|
||
|
// Clone
|
||
|
checkGeometryClone( geom );
|
||
|
|
||
|
// json round trip
|
||
|
checkGeometryJsonRoundtrip( geom );
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// LIGHT TEST HELPERS
|
||
|
//
|
||
|
|
||
|
// Run common light tests.
|
||
|
function runStdLightTests( assert, lights ) {
|
||
|
|
||
|
for ( let i = 0, l = lights.length; i < l; i ++ ) {
|
||
|
|
||
|
const light = lights[ i ];
|
||
|
|
||
|
// copy and clone
|
||
|
checkLightCopyClone( assert, light );
|
||
|
|
||
|
// THREE.Light doesn't get parsed by ObjectLoader as it's only
|
||
|
// used as an abstract base class - so we skip the JSON tests
|
||
|
if ( light.type !== 'Light' ) {
|
||
|
|
||
|
// json round trip
|
||
|
checkLightJsonRoundtrip( assert, light );
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
function checkLightCopyClone( assert, light ) {
|
||
|
|
||
|
// copy
|
||
|
const newLight = new light.constructor( 0xc0ffee );
|
||
|
newLight.copy( light );
|
||
|
|
||
|
QUnit.assert.notEqual( newLight.uuid, light.uuid, 'Copied light\'s UUID differs from original' );
|
||
|
QUnit.assert.notEqual( newLight.id, light.id, 'Copied light\'s id differs from original' );
|
||
|
QUnit.assert.smartEqual( newLight, light, 'Copied light is equal to original' );
|
||
|
|
||
|
// real copy?
|
||
|
newLight.color.setHex( 0xc0ffee );
|
||
|
QUnit.assert.notStrictEqual(
|
||
|
newLight.color.getHex(), light.color.getHex(), 'Copied light is independent from original'
|
||
|
);
|
||
|
|
||
|
// Clone
|
||
|
const clone = light.clone(); // better get a new var
|
||
|
QUnit.assert.notEqual( clone.uuid, light.uuid, 'Cloned light\'s UUID differs from original' );
|
||
|
QUnit.assert.notEqual( clone.id, light.id, 'Clone light\'s id differs from original' );
|
||
|
QUnit.assert.smartEqual( clone, light, 'Clone light is equal to original' );
|
||
|
|
||
|
// real clone?
|
||
|
clone.color.setHex( 0xc0ffee );
|
||
|
QUnit.assert.notStrictEqual(
|
||
|
clone.color.getHex(), light.color.getHex(), 'Clone light is independent from original'
|
||
|
);
|
||
|
|
||
|
if ( light.type !== 'Light' ) {
|
||
|
|
||
|
// json round trip with clone
|
||
|
checkLightJsonRoundtrip( assert, clone );
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// Compare json file with its source Light.
|
||
|
function checkLightJsonWriting( assert, light, json ) {
|
||
|
|
||
|
assert.equal( json.metadata.version, '4.5', 'check metadata version' );
|
||
|
|
||
|
const object = json.object;
|
||
|
assert.equalKey( light, object, 'type' );
|
||
|
assert.equalKey( light, object, 'uuid' );
|
||
|
assert.equal( object.id, undefined, 'should not persist id' );
|
||
|
|
||
|
}
|
||
|
|
||
|
// Check parsing and reconstruction of json Light
|
||
|
function checkLightJsonReading( assert, json, light ) {
|
||
|
|
||
|
const loader = new ObjectLoader();
|
||
|
const outputLight = loader.parse( json );
|
||
|
|
||
|
assert.smartEqual( outputLight, light, 'Reconstruct Light from ObjectLoader' );
|
||
|
|
||
|
}
|
||
|
|
||
|
// Verify light -> json -> light
|
||
|
function checkLightJsonRoundtrip( assert, light ) {
|
||
|
|
||
|
const json = light.toJSON();
|
||
|
checkLightJsonWriting( assert, light, json );
|
||
|
checkLightJsonReading( assert, json, light );
|
||
|
|
||
|
}
|
||
|
|
||
|
export { runStdLightTests, runStdGeometryTests };
|