fx.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
  6. <link rel="stylesheet" href="test.css">
  7. <title>Zepto Fx unit tests</title>
  8. <script src="../vendor/evidence.js"></script>
  9. <script src="evidence_runner.js"></script>
  10. <script>
  11. // avoid caching
  12. (function(){
  13. function load(scripts){
  14. scripts.split(' ').forEach(function(script){
  15. document.write('<script src="../src/'+script+'.js?'+(+new Date)+'"></scr'+'ipt>')
  16. })
  17. }
  18. load('zepto event fx ie')
  19. })()
  20. </script>
  21. <style>
  22. @-webkit-keyframes animName {
  23. 0% {
  24. -webkit-transform: rotate(180deg) scale(.8);
  25. opacity: 1;
  26. }
  27. 100% {
  28. -webkit-transform: rotate(0deg) scale(1) translate3d(80px, 20px, 0);
  29. opacity: 0.5;
  30. }
  31. }
  32. @-moz-keyframes animName {
  33. from {
  34. -moz-transform: rotate(180deg) scale(.8) translate(0, 0);
  35. opacity: 1;
  36. }
  37. to {
  38. -moz-transform: rotate(0deg) scale(1) translate(80px, 20px);
  39. opacity: 0.5;
  40. }
  41. }
  42. @keyframes animName {
  43. from {
  44. transform: rotate(180deg) scale(.8) translate(0, 0);
  45. opacity: 1;
  46. }
  47. to {
  48. transform: rotate(0deg) scale(1) translate(80px, 20px);
  49. opacity: 0.5;
  50. }
  51. }
  52. #keyframetest {
  53. opacity: 0.5;
  54. -webkit-transform: translate3d(80px, 20px, 0);
  55. -moz-transform: translate3d(80px, 20px, 0);
  56. transform: translate3d(80px, 20px, 0);
  57. }
  58. .fixtures-left {
  59. width: 120px;
  60. float: left;
  61. }
  62. .fixtures-right {
  63. margin-left: 120px;
  64. }
  65. </style>
  66. </head>
  67. <body>
  68. <h1>Zepto Fx unit tests</h1>
  69. <p id="results">
  70. Running… see browser console for results
  71. </p>
  72. <div class=fixtures-left>
  73. <div id="animtest_1" style="width:40px;height:40px;background:red"></div>
  74. <div id="animtest_2" style="width:40px;height:40px;background:red"></div>
  75. <div id="durationtest_1" style="width:40px;height:40px;background:red"></div>
  76. <div id="durationtest_2" style="width:40px;height:40px;background:red"></div>
  77. <div id="delaytest" style="width:40px;height:40px;background:red"></div>
  78. </div>
  79. <div class=fixtures-right>
  80. <div id="durationtest_3" style="width:40px;height:40px;background:red"></div>
  81. <div id="callbacktest" style="width:40px;height:40px;background:red"><div style="width:40px;height:40px;background:blue"></div></div>
  82. <div id="keyframetest" style="width:40px;height:40px;background:red;"></div>
  83. </div>
  84. <div id="anim_zero_duration_callback_test"></div>
  85. <script>
  86. (function(){
  87. function colorToHex (color) {
  88. if (color.substr(0, 1) === '#') {
  89. return color
  90. }
  91. var digits = /(.*?)rgb\((\d+), (\d+), (\d+)\)/.exec( color.toLowerCase() ),
  92. red = parseInt(digits[2]),
  93. green = parseInt(digits[3]),
  94. blue = parseInt(digits[4]),
  95. rgb = blue | (green << 8) | (red << 16)
  96. return digits[1] + '#' + rgb.toString(16)
  97. }
  98. function defer(delay, fn) {
  99. setTimeout(fn, delay || 0)
  100. }
  101. function camelize(str) {
  102. return str.replace(/-+(.)?/g, function(_, chr){ return chr ? chr.toUpperCase() : '' })
  103. }
  104. var stylePrefix = $.fx.cssPrefix
  105. Evidence.Assertions.assertStyle = function(expected, object, property, message) {
  106. if (/^(transform|transition|animation)/.test(property)) property = stylePrefix + property
  107. if (!('nodeName' in object)) object = object.get(0)
  108. var actual = object.style[camelize(property)],
  109. expression = expected instanceof RegExp ? expected.test(actual) : expected === actual
  110. this._assertExpression(expression, message || 'Failed assertion.',
  111. 'Expected '+property+' to be '+expected+', got '+actual+'.\n'+
  112. $.fx.stylePrefix +':\n' +
  113. object.style.cssText)
  114. }
  115. Evidence('ZeptoFXTest', {
  116. testAnimate: function(t){
  117. var el = $('#animtest_1'), el2 = $('#animtest_2')
  118. el.animate({
  119. translate3d: '80px, 20px, 100px',
  120. rotateZ: '90deg',
  121. scale: '0.8',
  122. opacity: 0.5,
  123. backgroundColor: '#BADA55',
  124. backgroundPositionY: '50%'
  125. }, 200, 'ease-out')
  126. el2.animate({
  127. translate3d: '80px, 20px, 100px',
  128. rotateZ: '-90deg',
  129. backgroundColor: '#BADA55'
  130. }, {
  131. duration: 180,
  132. easing: 'ease-out'
  133. })
  134. t.assertStyle('ease-out', el, 'transition-timing-function')
  135. t.assertStyle('0.2s', el, 'transition-duration')
  136. t.assertStyle(/\bbackground-color\b/, el, 'transition-property')
  137. t.assertStyle(/\bbackground-position-y\b/, el, 'transition-property')
  138. t.assertStyle(/\btransform\b/, el, 'transition-property')
  139. t.assertStyle('0.18s', el2, 'transition-duration')
  140. t.pause()
  141. defer(250, function(){
  142. t.resume(function(){
  143. t.assertStyle('translate3d(80px, 20px, 100px) rotateZ(90deg) scale(0.8)', el, 'transform')
  144. t.assertStyle('0.5', el, 'opacity')
  145. t.assertStyle(/^(50%|center)$/, el, 'background-position-y')
  146. t.assertEqual('#BADA55', colorToHex(el.get(0).style.backgroundColor).toUpperCase())
  147. })
  148. })
  149. },
  150. testDuration: function(t){
  151. var el1 = $('#durationtest_1').anim({
  152. translate3d: '80px, 20px, 100px',
  153. rotateZ: '90deg',
  154. opacity: 0.5
  155. })
  156. var el2 = $('#durationtest_2').anim({
  157. translate3d: '80px, 20px, 100px',
  158. rotateZ: '90deg',
  159. opacity: 0.5
  160. }, 0)
  161. t.assertStyle('0.4s', el1, 'transition-duration', 'expected default duration')
  162. t.assertStyle('', el2, 'transition-duration', 'expected no animation')
  163. },
  164. testDurationString: function(t){
  165. var el = $('#durationtest_3').animate({
  166. translate3d: '80px, 20px, 100px',
  167. rotateZ: '90deg',
  168. opacity: 0.5
  169. }, 'fast')
  170. t.assertStyle('0.2s', el, 'transition-duration', 'expected fast duration')
  171. },
  172. testDelay: function(t){
  173. var duration = 100, delay = 50,
  174. start = new Date().getTime()
  175. t.pause()
  176. var el1 = $('#delaytest').animate({
  177. translate3d: '80px, 20px, 100px',
  178. rotateZ: '90deg',
  179. opacity: 0.5
  180. }, {
  181. duration: duration,
  182. delay: delay,
  183. complete: function() {
  184. t.resume(function(){
  185. var ms = new Date().getTime() - start
  186. t.assert(ms >= (duration + delay),
  187. 'Fired too early (' + ms + ' ms) after having delay')
  188. })
  189. }
  190. })
  191. t.assertStyle('0.05s', el1, 'transition-delay', 'expected delay to be set')
  192. },
  193. testCallback: function(t){
  194. var duration = 250, start = new Date().getTime()
  195. t.pause()
  196. $('#callbacktest').animate({
  197. translate3d: '80px, 20px, 100px',
  198. rotateZ: '90deg',
  199. opacity: 0.5
  200. }, duration, 'linear',
  201. function(){
  202. var context = this
  203. t.resume(function(){
  204. t.assert($(context).is('#callbacktest'), "context for callback is wrong")
  205. t.assert((new Date().getTime() - start) >= duration, 'Fired too early')
  206. t.assertStyle('', context, 'transition')
  207. t.assertStyle('', context, 'transition-property')
  208. t.assertStyle('', context, 'transition-timing-function')
  209. t.assertStyle('', context, 'transition-duration')
  210. t.assertStyle('', context, 'animation-name')
  211. t.assertStyle('', context, 'animation-duration')
  212. })
  213. })
  214. },
  215. testCallbackWithoutEasing: function(t){
  216. var duration = 250, start = new Date().getTime()
  217. t.pause()
  218. $('#callbacktest').animate({
  219. translate3d: '10px, 20px, 400px',
  220. rotateZ: '-90deg',
  221. opacity: 0.2
  222. }, duration,
  223. function(){
  224. var context = this
  225. t.resume(function(){
  226. t.assert($(context).is('#callbacktest'), "context for callback is wrong")
  227. t.assert((new Date().getTime() - start) >= duration, 'Fired too early')
  228. t.assertStyle('', context, 'transition')
  229. t.assertStyle('', context, 'transition-property')
  230. t.assertStyle('', context, 'transition-timing-function')
  231. t.assertStyle('', context, 'transition-duration')
  232. t.assertStyle('', context, 'animation-name')
  233. t.assertStyle('', context, 'animation-duration')
  234. })
  235. })
  236. },
  237. testCallbackWithoutEasingAndWithoutDuration: function(t){
  238. var duration = 250, start = new Date().getTime()
  239. t.pause()
  240. $('#callbacktest').animate({
  241. translate3d: '30px, 220px, 40px',
  242. rotateZ: '180deg',
  243. opacity: 0.9
  244. },
  245. function(){
  246. var context = this
  247. t.resume(function(){
  248. t.assert($(context).is('#callbacktest'), "context for callback is wrong")
  249. t.assert((new Date().getTime() - start) >= duration, 'Fired too early')
  250. t.assertStyle('', context, 'transition')
  251. t.assertStyle('', context, 'transition-property')
  252. t.assertStyle('', context, 'transition-timing-function')
  253. t.assertStyle('', context, 'transition-duration')
  254. t.assertStyle('', context, 'animation-name')
  255. t.assertStyle('', context, 'animation-duration')
  256. })
  257. })
  258. },
  259. testBubbling: function(t){
  260. $('#callbacktest div').anim({ opacity: 0.0 }, 0.1, 'linear')
  261. var el = $('#anim_zero_duration_callback_test'),
  262. callbackCalled = false
  263. el.anim({ opacity: 0.5 }, 0, 'linear', function () {
  264. t.assert($(this).is('#anim_zero_duration_callback_test'), "context for callback is wrong")
  265. t.assertStyle('0.5', this, 'opacity')
  266. callbackCalled = true
  267. })
  268. t.pause()
  269. defer(30, function(){
  270. t.resume(function(){
  271. t.assert(callbackCalled)
  272. })
  273. })
  274. },
  275. testKeyFrameAnimation: function(t){
  276. var el = $('#keyframetest').animate('animName', 200)
  277. t.assertStyle('animName', el, 'animation-name')
  278. t.assertStyle('0.2s', el, 'animation-duration')
  279. t.assertStyle('linear', el, 'animation-timing-function')
  280. },
  281. testEmptyCollection: function(t){
  282. t.assert($(null).animate({opacity:0}))
  283. }
  284. })
  285. })()
  286. </script>
  287. </body>
  288. </html>