qunit-utils.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. //
  2. // Custom QUnit assertions.
  3. import { SmartComparer } from './SmartComparer.js';
  4. import { ObjectLoader } from '../../../src/loaders/ObjectLoader.js';
  5. QUnit.assert.success = function ( message ) {
  6. // Equivalent to assert( true, message );
  7. this.pushResult( {
  8. result: true,
  9. actual: undefined,
  10. expected: undefined,
  11. message: message
  12. } );
  13. };
  14. QUnit.assert.fail = function ( message ) {
  15. // Equivalent to assert( false, message );
  16. this.pushResult( {
  17. result: false,
  18. actual: undefined,
  19. expected: undefined,
  20. message: message
  21. } );
  22. };
  23. QUnit.assert.numEqual = function ( actual, expected, message ) {
  24. const diff = Math.abs( actual - expected );
  25. message = message || ( actual + ' should be equal to ' + expected );
  26. this.pushResult( {
  27. result: diff < 0.1,
  28. actual: actual,
  29. expected: expected,
  30. message: message
  31. } );
  32. };
  33. QUnit.assert.equalKey = function ( obj, ref, key ) {
  34. const actual = obj[ key ];
  35. const expected = ref[ key ];
  36. const message = actual + ' should be equal to ' + expected + ' for key "' + key + '"';
  37. this.pushResult( {
  38. result: actual == expected,
  39. actual: actual,
  40. expected: expected,
  41. message: message
  42. } );
  43. };
  44. QUnit.assert.smartEqual = function ( actual, expected, message ) {
  45. const cmp = new SmartComparer();
  46. const same = cmp.areEqual( actual, expected );
  47. const msg = cmp.getDiagnostic() || message;
  48. this.pushResult( {
  49. result: same,
  50. actual: actual,
  51. expected: expected,
  52. message: msg
  53. } );
  54. };
  55. //
  56. // GEOMETRY TEST HELPERS
  57. //
  58. function checkGeometryClone( geom ) {
  59. // Clone
  60. const copy = geom.clone();
  61. QUnit.assert.notEqual( copy.uuid, geom.uuid, 'clone uuid should differ from original' );
  62. QUnit.assert.notEqual( copy.id, geom.id, 'clone id should differ from original' );
  63. let differingProp = getDifferingProp( geom, copy );
  64. QUnit.assert.ok( differingProp === undefined, 'properties are equal' );
  65. differingProp = getDifferingProp( copy, geom );
  66. QUnit.assert.ok( differingProp === undefined, 'properties are equal' );
  67. // json round trip with clone
  68. checkGeometryJsonRoundtrip( copy );
  69. }
  70. function getDifferingProp( geometryA, geometryB ) {
  71. const geometryKeys = Object.keys( geometryA );
  72. const cloneKeys = Object.keys( geometryB );
  73. let differingProp = undefined;
  74. for ( let i = 0, l = geometryKeys.length; i < l; i ++ ) {
  75. const key = geometryKeys[ i ];
  76. if ( cloneKeys.indexOf( key ) < 0 ) {
  77. differingProp = key;
  78. break;
  79. }
  80. }
  81. return differingProp;
  82. }
  83. // Compare json file with its source geometry.
  84. function checkGeometryJsonWriting( geom, json ) {
  85. QUnit.assert.equal( json.metadata.version, '4.7', 'check metadata version' );
  86. QUnit.assert.equalKey( geom, json, 'type' );
  87. QUnit.assert.equalKey( geom, json, 'uuid' );
  88. QUnit.assert.equal( json.id, undefined, 'should not persist id' );
  89. const params = geom.parameters;
  90. if ( ! params ) {
  91. return;
  92. }
  93. // All parameters from geometry should be persisted.
  94. let keys = Object.keys( params );
  95. for ( let i = 0, l = keys.length; i < l; i ++ ) {
  96. QUnit.assert.equalKey( params, json, keys[ i ] );
  97. }
  98. // All parameters from json should be transferred to the geometry.
  99. // json is flat. Ignore first level json properties that are not parameters.
  100. const notParameters = [ 'metadata', 'uuid', 'type' ];
  101. keys = Object.keys( json );
  102. for ( let i = 0, l = keys.length; i < l; i ++ ) {
  103. const key = keys[ i ];
  104. if ( notParameters.indexOf( key ) === - 1 ) QUnit.assert.equalKey( params, json, key );
  105. }
  106. }
  107. // Check parsing and reconstruction of json geometry
  108. function checkGeometryJsonReading( json, geom ) {
  109. const wrap = [ json ];
  110. const loader = new ObjectLoader();
  111. const output = loader.parseGeometries( wrap );
  112. QUnit.assert.ok( output[ geom.uuid ], 'geometry matching source uuid not in output' );
  113. // QUnit.assert.smartEqual( output[ geom.uuid ], geom, 'Reconstruct geometry from ObjectLoader' );
  114. const differing = getDifferingProp( output[ geom.uuid ], geom );
  115. if ( differing ) console.log( differing );
  116. let differingProp = getDifferingProp( output[ geom.uuid ], geom );
  117. QUnit.assert.ok( differingProp === undefined, 'properties are equal' );
  118. differingProp = getDifferingProp( geom, output[ geom.uuid ] );
  119. QUnit.assert.ok( differingProp === undefined, 'properties are equal' );
  120. }
  121. // Verify geom -> json -> geom
  122. function checkGeometryJsonRoundtrip( geom ) {
  123. const json = geom.toJSON();
  124. checkGeometryJsonWriting( geom, json );
  125. checkGeometryJsonReading( json, geom );
  126. }
  127. // Run common geometry tests.
  128. function runStdGeometryTests( assert, geometries ) {
  129. for ( let i = 0, l = geometries.length; i < l; i ++ ) {
  130. const geom = geometries[ i ];
  131. // Clone
  132. checkGeometryClone( geom );
  133. // json round trip
  134. checkGeometryJsonRoundtrip( geom );
  135. }
  136. }
  137. //
  138. // LIGHT TEST HELPERS
  139. //
  140. // Run common light tests.
  141. function runStdLightTests( assert, lights ) {
  142. for ( let i = 0, l = lights.length; i < l; i ++ ) {
  143. const light = lights[ i ];
  144. // copy and clone
  145. checkLightCopyClone( assert, light );
  146. // THREE.Light doesn't get parsed by ObjectLoader as it's only
  147. // used as an abstract base class - so we skip the JSON tests
  148. if ( light.type !== 'Light' ) {
  149. // json round trip
  150. checkLightJsonRoundtrip( assert, light );
  151. }
  152. }
  153. }
  154. function checkLightCopyClone( assert, light ) {
  155. // copy
  156. const newLight = new light.constructor( 0xc0ffee );
  157. newLight.copy( light );
  158. QUnit.assert.notEqual( newLight.uuid, light.uuid, 'Copied light\'s UUID differs from original' );
  159. QUnit.assert.notEqual( newLight.id, light.id, 'Copied light\'s id differs from original' );
  160. QUnit.assert.smartEqual( newLight, light, 'Copied light is equal to original' );
  161. // real copy?
  162. newLight.color.setHex( 0xc0ffee );
  163. QUnit.assert.notStrictEqual(
  164. newLight.color.getHex(), light.color.getHex(), 'Copied light is independent from original'
  165. );
  166. // Clone
  167. const clone = light.clone(); // better get a new clone
  168. QUnit.assert.notEqual( clone.uuid, light.uuid, 'Cloned light\'s UUID differs from original' );
  169. QUnit.assert.notEqual( clone.id, light.id, 'Clone light\'s id differs from original' );
  170. QUnit.assert.smartEqual( clone, light, 'Clone light is equal to original' );
  171. // real clone?
  172. clone.color.setHex( 0xc0ffee );
  173. QUnit.assert.notStrictEqual(
  174. clone.color.getHex(), light.color.getHex(), 'Clone light is independent from original'
  175. );
  176. if ( light.type !== 'Light' ) {
  177. // json round trip with clone
  178. checkLightJsonRoundtrip( assert, clone );
  179. }
  180. }
  181. // Compare json file with its source Light.
  182. function checkLightJsonWriting( assert, light, json ) {
  183. assert.equal( json.metadata.version, '4.7', 'check metadata version' );
  184. const object = json.object;
  185. assert.equalKey( light, object, 'type' );
  186. assert.equalKey( light, object, 'uuid' );
  187. assert.equal( object.id, undefined, 'should not persist id' );
  188. }
  189. // Check parsing and reconstruction of json Light
  190. function checkLightJsonReading( assert, json, light ) {
  191. const loader = new ObjectLoader();
  192. const outputLight = loader.parse( json );
  193. assert.smartEqual( outputLight, light, 'Reconstruct Light from ObjectLoader' );
  194. }
  195. // Verify light -> json -> light
  196. function checkLightJsonRoundtrip( assert, light ) {
  197. const json = light.toJSON();
  198. checkLightJsonWriting( assert, light, json );
  199. checkLightJsonReading( assert, json, light );
  200. }
  201. export { runStdLightTests, runStdGeometryTests };
粤ICP备19079148号