PropertyBinding.tests.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. import { PropertyBinding } from '../../../../src/animation/PropertyBinding.js';
  2. import { BoxGeometry } from '../../../../src/geometries/BoxGeometry.js';
  3. import { Mesh } from '../../../../src/objects/Mesh.js';
  4. import { MeshBasicMaterial } from '../../../../src/materials/MeshBasicMaterial.js';
  5. export default QUnit.module( 'Animation', () => {
  6. QUnit.module( 'PropertyBinding', () => {
  7. // INSTANCING
  8. QUnit.test( 'Instancing', ( assert ) => {
  9. const geometry = new BoxGeometry();
  10. const material = new MeshBasicMaterial();
  11. const mesh = new Mesh( geometry, material );
  12. const path = '.material.opacity';
  13. const parsedPath = {
  14. nodeName: '',
  15. objectName: 'material',
  16. objectIndex: undefined,
  17. propertyName: 'opacity',
  18. propertyIndex: undefined
  19. };
  20. // mesh, path
  21. const object = new PropertyBinding( mesh, path );
  22. assert.ok( object, 'Can instantiate a PropertyBinding.' );
  23. // mesh, path, parsedPath
  24. const object_all = new PropertyBinding( mesh, path, parsedPath );
  25. assert.ok( object_all, 'Can instantiate a PropertyBinding with mesh, path, and parsedPath.' );
  26. } );
  27. // STATIC
  28. QUnit.test( 'sanitizeNodeName', ( assert ) => {
  29. assert.equal(
  30. PropertyBinding.sanitizeNodeName( 'valid-name-123_' ),
  31. 'valid-name-123_',
  32. 'Leaves valid name intact.'
  33. );
  34. assert.equal(
  35. PropertyBinding.sanitizeNodeName( '急須' ),
  36. '急須',
  37. 'Leaves non-latin unicode characters intact.'
  38. );
  39. assert.equal(
  40. PropertyBinding.sanitizeNodeName( 'space separated name 123_ -' ),
  41. 'space_separated_name_123__-',
  42. 'Replaces spaces with underscores.'
  43. );
  44. assert.equal(
  45. PropertyBinding.sanitizeNodeName( '"Mátyás" %_* 😇' ),
  46. '"Mátyás"_%_*_😇',
  47. 'Allows various punctuation and symbols.'
  48. );
  49. assert.equal(
  50. PropertyBinding.sanitizeNodeName( '/invalid: name ^123.[_]' ),
  51. 'invalid_name_^123_',
  52. 'Strips reserved characters.'
  53. );
  54. } );
  55. QUnit.test( 'parseTrackName', ( assert ) => {
  56. const paths = [
  57. [
  58. '.property',
  59. {
  60. nodeName: undefined,
  61. objectName: undefined,
  62. objectIndex: undefined,
  63. propertyName: 'property',
  64. propertyIndex: undefined
  65. }
  66. ],
  67. [
  68. 'nodeName.property',
  69. {
  70. nodeName: 'nodeName',
  71. objectName: undefined,
  72. objectIndex: undefined,
  73. propertyName: 'property',
  74. propertyIndex: undefined
  75. }
  76. ],
  77. [
  78. 'a.property',
  79. {
  80. nodeName: 'a',
  81. objectName: undefined,
  82. objectIndex: undefined,
  83. propertyName: 'property',
  84. propertyIndex: undefined
  85. }
  86. ],
  87. [
  88. 'no.de.Name.property',
  89. {
  90. nodeName: 'no.de.Name',
  91. objectName: undefined,
  92. objectIndex: undefined,
  93. propertyName: 'property',
  94. propertyIndex: undefined
  95. }
  96. ],
  97. [
  98. 'no.d-e.Name.property',
  99. {
  100. nodeName: 'no.d-e.Name',
  101. objectName: undefined,
  102. objectIndex: undefined,
  103. propertyName: 'property',
  104. propertyIndex: undefined
  105. }
  106. ],
  107. [
  108. 'nodeName.property[accessor]',
  109. {
  110. nodeName: 'nodeName',
  111. objectName: undefined,
  112. objectIndex: undefined,
  113. propertyName: 'property',
  114. propertyIndex: 'accessor'
  115. }
  116. ],
  117. [
  118. 'nodeName.material.property[accessor]',
  119. {
  120. nodeName: 'nodeName',
  121. objectName: 'material',
  122. objectIndex: undefined,
  123. propertyName: 'property',
  124. propertyIndex: 'accessor'
  125. }
  126. ],
  127. [
  128. 'no.de.Name.material.property',
  129. {
  130. nodeName: 'no.de.Name',
  131. objectName: 'material',
  132. objectIndex: undefined,
  133. propertyName: 'property',
  134. propertyIndex: undefined
  135. }
  136. ],
  137. [
  138. 'no.de.Name.material[materialIndex].property',
  139. {
  140. nodeName: 'no.de.Name',
  141. objectName: 'material',
  142. objectIndex: 'materialIndex',
  143. propertyName: 'property',
  144. propertyIndex: undefined
  145. }
  146. ],
  147. [
  148. 'uuid.property[accessor]',
  149. {
  150. nodeName: 'uuid',
  151. objectName: undefined,
  152. objectIndex: undefined,
  153. propertyName: 'property',
  154. propertyIndex: 'accessor'
  155. }
  156. ],
  157. [
  158. 'uuid.objectName[objectIndex].propertyName[propertyIndex]',
  159. {
  160. nodeName: 'uuid',
  161. objectName: 'objectName',
  162. objectIndex: 'objectIndex',
  163. propertyName: 'propertyName',
  164. propertyIndex: 'propertyIndex'
  165. }
  166. ],
  167. [
  168. 'parentName/nodeName.property',
  169. {
  170. // directoryName is currently unused.
  171. nodeName: 'nodeName',
  172. objectName: undefined,
  173. objectIndex: undefined,
  174. propertyName: 'property',
  175. propertyIndex: undefined
  176. }
  177. ],
  178. [
  179. 'parentName/no.de.Name.property',
  180. {
  181. // directoryName is currently unused.
  182. nodeName: 'no.de.Name',
  183. objectName: undefined,
  184. objectIndex: undefined,
  185. propertyName: 'property',
  186. propertyIndex: undefined
  187. }
  188. ],
  189. [
  190. 'parentName/parentName/nodeName.property[index]',
  191. {
  192. // directoryName is currently unused.
  193. nodeName: 'nodeName',
  194. objectName: undefined,
  195. objectIndex: undefined,
  196. propertyName: 'property',
  197. propertyIndex: 'index'
  198. }
  199. ],
  200. [
  201. '.bone[Armature.DEF_cog].position',
  202. {
  203. nodeName: undefined,
  204. objectName: 'bone',
  205. objectIndex: 'Armature.DEF_cog',
  206. propertyName: 'position',
  207. propertyIndex: undefined
  208. }
  209. ],
  210. [
  211. 'scene:helium_balloon_model:helium_balloon_model.position',
  212. {
  213. nodeName: 'helium_balloon_model',
  214. objectName: undefined,
  215. objectIndex: undefined,
  216. propertyName: 'position',
  217. propertyIndex: undefined
  218. }
  219. ],
  220. [
  221. '急須.材料[零]',
  222. {
  223. nodeName: '急須',
  224. objectName: undefined,
  225. objectIndex: undefined,
  226. propertyName: '材料',
  227. propertyIndex: '零'
  228. }
  229. ],
  230. [
  231. '📦.🎨[🔴]',
  232. {
  233. nodeName: '📦',
  234. objectName: undefined,
  235. objectIndex: undefined,
  236. propertyName: '🎨',
  237. propertyIndex: '🔴'
  238. }
  239. ]
  240. ];
  241. paths.forEach( function ( path ) {
  242. assert.smartEqual(
  243. PropertyBinding.parseTrackName( path[ 0 ] ),
  244. path[ 1 ],
  245. 'Parses track name: ' + path[ 0 ]
  246. );
  247. } );
  248. } );
  249. // PUBLIC STUFF
  250. QUnit.test( 'setValue', ( assert ) => {
  251. const paths = [
  252. '.material.opacity',
  253. '.material[opacity]'
  254. ];
  255. paths.forEach( function ( path ) {
  256. const originalValue = 0;
  257. const expectedValue = 1;
  258. const geometry = new BoxGeometry();
  259. const material = new MeshBasicMaterial();
  260. material.opacity = originalValue;
  261. const mesh = new Mesh( geometry, material );
  262. const binding = new PropertyBinding( mesh, path, null );
  263. binding.bind();
  264. assert.equal(
  265. material.opacity,
  266. originalValue,
  267. 'Sets property of material with "' + path + '" (pre-setValue)'
  268. );
  269. binding.setValue( [ expectedValue ], 0 );
  270. assert.equal(
  271. material.opacity,
  272. expectedValue,
  273. 'Sets property of material with "' + path + '" (post-setValue)'
  274. );
  275. } );
  276. } );
  277. } );
  278. } );
粤ICP备19079148号