From b5cac727ee77d998283ea661e3f6d5fc684cec50 Mon Sep 17 00:00:00 2001 From: Brian Birtles Date: Mon, 20 Oct 2014 13:55:43 +0900 Subject: [PATCH] Bug 1070745 part 1 - Factor out new_div etc. to animation_utils.js; r=dholbert We use new_div, check_events etc. in a number of animation-related mochitests and with this bug we'll want to use them in a few more. This patch factors them out into animation_utils.js and tidies them up a little. --- layout/style/test/animation_utils.js | 105 ++++++++++++++++ layout/style/test/test_animations.html | 115 +++++------------- layout/style/test/test_animations_omta.html | 84 ++----------- .../test_flexbox_flex_grow_and_shrink.html | 44 ++----- 4 files changed, 159 insertions(+), 189 deletions(-) diff --git a/layout/style/test/animation_utils.js b/layout/style/test/animation_utils.js index 6e5b46fb51b..992d7e695e6 100644 --- a/layout/style/test/animation_utils.js +++ b/layout/style/test/animation_utils.js @@ -1,3 +1,108 @@ +//---------------------------------------------------------------------- +// +// Common testing functions +// +//---------------------------------------------------------------------- + +function advance_clock(milliseconds) { + SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(milliseconds); +} + +// Test-element creation/destruction and event checking +(function() { + var gElem; + var gEventsReceived = []; + + function new_div(style) { + return new_element("div", style); + } + + // Creates a new |tagname| element with inline style |style| and appends + // it as a child of the element with ID 'display'. + // The element will also be given the class 'target' which can be used + // for additional styling. + function new_element(tagname, style) { + if (gElem) { + ok(false, "test author forgot to call done_div/done_elem"); + } + if (typeof(style) != "string") { + ok(false, "test author forgot to pass argument"); + } + if (!document.getElementById("display")) { + ok(false, "no 'display' element to append to"); + } + gElem = document.createElement(tagname); + gElem.setAttribute("style", style); + gElem.classList.add("target"); + document.getElementById("display").appendChild(gElem); + return [ gElem, getComputedStyle(gElem, "") ]; + } + + function listen() { + if (!gElem) { + ok(false, "test author forgot to call new_div before listen"); + } + gEventsReceived = []; + function listener(event) { + gEventsReceived.push(event); + } + gElem.addEventListener("animationstart", listener, false); + gElem.addEventListener("animationiteration", listener, false); + gElem.addEventListener("animationend", listener, false); + } + + function check_events(eventsExpected, desc) { + // This function checks that the list of eventsExpected matches + // the received events -- but it only checks the properties that + // are present on eventsExpected. + is(gEventsReceived.length, gEventsReceived.length, + "number of events received for " + desc); + for (var i = 0, + i_end = Math.min(eventsExpected.length, gEventsReceived.length); + i != i_end; ++i) { + var exp = eventsExpected[i]; + var rec = gEventsReceived[i]; + for (var prop in exp) { + if (prop == "elapsedTime") { + // Allow floating point error. + ok(Math.abs(rec.elapsedTime - exp.elapsedTime) < 0.000002, + "events[" + i + "]." + prop + " for " + desc + + " received=" + rec.elapsedTime + " expected=" + exp.elapsedTime); + } else { + is(rec[prop], exp[prop], + "events[" + i + "]." + prop + " for " + desc); + } + } + } + for (var i = eventsExpected.length; i < gEventsReceived.length; ++i) { + ok(false, "unexpected " + gEventsReceived[i].type + " event for " + desc); + } + gEventsReceived = []; + } + + function done_element() { + if (!gElem) { + ok(false, "test author called done_element/done_div without matching" + + " call to new_element/new_div"); + } + gElem.remove(); + gElem = null; + if (gEventsReceived.length) { + ok(false, "caller should have called check_events"); + } + } + + [ new_div + , new_element + , listen + , check_events + , done_element ] + .forEach(function(fn) { + window[fn.name] = fn; + }); + window.done_div = done_element; +})(); + function px_to_num(str) { return Number(String(str).match(/^([\d.]+)px$/)[1]); diff --git a/layout/style/test/test_animations.html b/layout/style/test/test_animations.html index 5c22d2f4051..ec86765bd9d 100644 --- a/layout/style/test/test_animations.html +++ b/layout/style/test/test_animations.html @@ -165,73 +165,12 @@ is(e.elapsedTime, 0.5); is(e.pseudoElement, "pseudo"); is(e.isTrusted, false) -function advance_clock(milliseconds) { - SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(milliseconds); -} - -var display = document.getElementById("display"); -var div = null; -var cs = null; -var events_received = []; -function new_div(style) { - return new_element("div", style); -} -function new_element(tagname, style) { - if (div != null || cs != null) { - ok(false, "test author forgot to call done_div"); - } - if (typeof(style) != "string") { - ok(false, "test author forgot to pass argument"); - } - div = document.createElement(tagname); - div.setAttribute("style", style); - display.appendChild(div); - cs = getComputedStyle(div, ""); -} -function listen() { - events_received = []; - function listener(event) { - events_received.push(event); - } - div.addEventListener("animationstart", listener, false); - div.addEventListener("animationiteration", listener, false); - div.addEventListener("animationend", listener, false); -} -function check_events(events_expected, desc) { - // This function checks that the list of events_expected matches - // the received events -- but it only checks the properties that - // are present on events_expected. - is(events_received.length, events_expected.length, - "number of events received for " + desc); - for (var i = 0, - i_end = Math.min(events_expected.length, events_received.length); - i != i_end; ++i) { - var exp = events_expected[i]; - var rec = events_received[i]; - for (var prop in exp) { - if (prop == "elapsedTime") { - // Allow floating point error. - ok(Math.abs(rec.elapsedTime - exp.elapsedTime) < 0.000002, - "events[" + i + "]." + prop + " for " + desc + - " received=" + rec.elapsedTime + " expected=" + exp.elapsedTime); - } else { - is(rec[prop], exp[prop], "events[" + i + "]." + prop + " for " + desc); - } - } - } - for (var i = events_expected.length; i < events_received.length; ++i) { - ok(false, "unexpected " + events_received[i].type + " event for " + desc); - } - events_received = []; -} -function done_div() { - display.removeChild(div); - div = null; - cs = null; - if (events_received.length) { - ok(false, "caller should have called check_events"); - } -} +// Shortcut new_div to update div, cs +var div, cs; +var originalNewDiv = window.new_div; +window.new_div = function(style) { + [ div, cs ] = originalNewDiv(style); +}; // take over the refresh driver right from the start. advance_clock(0); @@ -820,7 +759,9 @@ is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01, "animation-iteration-count test 1 at 8.1s"); done_div(); -new_div("animation: anim2 ease-in 10s 0.3, anim3 ease-out 20s 1.2 alternate forwards, anim4 ease-in-out 5s 1.6 forwards"); +new_div("animation: anim2 ease-in 10s 0.3" + + ", anim3 ease-out 20s 1.2 alternate forwards" + + ", anim4 ease-in-out 5s 1.6 forwards"); is(cs.marginRight, "0px", "animation-iteration-count test 2 at 0s"); is(cs.marginTop, "0px", "animation-iteration-count test 3 at 0s"); is(cs.marginBottom, "0px", "animation-iteration-count test 4 at 0s"); @@ -1378,10 +1319,12 @@ done_div(); // This test depends on forms.css having a rule // select { line-height: !important } // If that rule changes, we should rewrite it to depend on a different rule. -new_element("select", ""); +var select; +[ select, cs ] = new_element("select", ""); var default_line_height = cs.lineHeight; -done_div(); -new_element("select", "animation: uaoverride 2s linear infinite"); +done_element(); +[ select, cs ] = new_element("select", + "animation: uaoverride 2s linear infinite"); is(cs.lineHeight, default_line_height, "animations should not override UA !important at 0ms"); is(cs.marginTop, "20px", @@ -1391,14 +1334,15 @@ is(cs.lineHeight, default_line_height, "animations should not override UA !important at 200ms"); is(cs.marginTop, "40px", "rest of animation should still work when UA !important present at 200ms"); -done_div(); +done_element(); // Test that author !important rules override animations, but // that animations override regular author rules. new_div("animation: always_fifty 1s linear infinite; margin-left: 200px"); is(cs.marginLeft, "50px", "animations override regular author rules"); done_div(); -new_div("animation: always_fifty 1s linear infinite; margin-left: 200px ! important;"); +new_div("animation: always_fifty 1s linear infinite;" + + " margin-left: 200px ! important;"); is(cs.marginLeft, "200px", "important author rules override animations"); done_div(); @@ -1515,11 +1459,17 @@ done_div(); // start animations. // note: anim2 animates margin-right from 0 to 100px // note: anim3 animates margin-top from 0 to 100px -new_div("animation-name: anim2, anim3; animation-duration: 1s; animation-timing-function: linear; animation-delay: -250ms, -250ms, -750ms, -500ms;"); +new_div("animation-name: anim2, anim3;" + + " animation-duration: 1s;" + + " animation-timing-function: linear;" + + " animation-delay: -250ms, -250ms, -750ms, -500ms;"); is(cs.marginRight, "25px", "animation-name list length is the length that matters"); is(cs.marginTop, "25px", "animation-name list length is the length that matters"); done_div(); -new_div("animation-name: anim2, anim3, anim2; animation-duration: 1s; animation-timing-function: linear; animation-delay: -250ms, -250ms, -750ms, -500ms;"); +new_div("animation-name: anim2, anim3, anim2;" + + " animation-duration: 1s;" + + " animation-timing-function: linear;" + + " animation-delay: -250ms, -250ms, -750ms, -500ms;"); is(cs.marginRight, "75px", "animation-name list length is the length that matters, and the last occurrence of a name wins"); is(cs.marginTop, "25px", "animation-name list length is the length that matters"); done_div(); @@ -1652,7 +1602,8 @@ check_events([]); done_div(); // Test with animation-direction reverse -new_div("margin-right: 200px; animation: anim2 0s 1s both reverse"); +new_div("margin-right: 200px;" + + " animation: anim2 0s 1s both reverse"); advance_clock(0); is(cs.getPropertyValue("margin-right"), "100px", "margin-right during backwards fill of reversed zero-duration animation"); @@ -1693,8 +1644,8 @@ is(cs.getPropertyValue("margin-right"), "100px", done_div(); // Test with animation-direction alternate and non-integral number of iterations -new_div("margin-right: 200px; " + - "animation: anim2 0s 1s both alternate 7.3 linear"); +new_div("margin-right: 200px;" + + " animation: anim2 0s 1s both alternate 7.3 linear"); advance_clock(0); is(cs.getPropertyValue("margin-right"), "0px", "margin-right during backwards fill of alternating zero-duration " + @@ -1743,8 +1694,8 @@ is(cs.getPropertyValue("margin-right"), "0px", done_div(); // Test with infinite iteration count and alternate-reverse direction -new_div("margin-right: 200px; " + - "animation: anim2 0s 1s alternate-reverse infinite both"); +new_div("margin-right: 200px;" + + " animation: anim2 0s 1s alternate-reverse infinite both"); advance_clock(0); is(cs.getPropertyValue("margin-right"), "100px", "margin-right during backwards fill of infinitely repeating and " + @@ -1756,8 +1707,8 @@ is(cs.getPropertyValue("margin-right"), "100px", done_div(); // Test with negative delay -new_div("margin-right: 200px; " + - "animation: anim2 0s -1s both reverse 12.7 linear"); +new_div("margin-right: 200px;" + + " animation: anim2 0s -1s both reverse 12.7 linear"); listen(); advance_clock(0); is(cs.getPropertyValue("margin-right"), "30px", diff --git a/layout/style/test/test_animations_omta.html b/layout/style/test/test_animations_omta.html index fc34f560ae0..6f7caf34fee 100644 --- a/layout/style/test/test_animations_omta.html +++ b/layout/style/test/test_animations_omta.html @@ -168,9 +168,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=964646 /** Test for css3-animations running on the compositor thread (Bug 964646) **/ // Global state -var gDisplay = document.getElementById("display"), - gDiv = null, - gEventsReceived = []; +var gDisplay = document.getElementById("display") + , gDiv = null; // Shortcut omta_is and friends by filling in the initial 'elem' argument // with gDiv. @@ -185,6 +184,17 @@ var gDisplay = document.getElementById("display"), }; }); +// Shortcut new_div and done_div to update gDiv +var originalNewDiv = window.new_div; +window.new_div = function(style) { + [ gDiv ] = originalNewDiv(style); +}; +var originalDoneDiv = window.done_div; +window.done_div = function() { + originalDoneDiv(); + gDiv = null; +}; + SimpleTest.waitForExplicitFinish(); runOMTATest(function() { var onAbort = function() { @@ -2073,73 +2083,5 @@ addAsyncAnimTest(function *() { visitedLink.remove(); }); -//---------------------------------------------------------------------- -// -// Helper functions from test_animations.html -// -//---------------------------------------------------------------------- - -function new_div(style) { - if (gDiv !== null) { - ok(false, "test author forgot to call done_div"); - } - if (typeof(style) != "string") { - ok(false, "test author forgot to pass style argument"); - } - gDiv = document.createElement("div"); - gDiv.classList.add("target"); - gDiv.setAttribute("style", style); - gDisplay.appendChild(gDiv); -} - -function done_div() { - if (gDiv === null) { - ok(false, "test author forgot to call new_div"); - } - gDisplay.removeChild(gDiv); - gDiv = null; -} - -function listen() { - gEventsReceived = []; - function listener(event) { - gEventsReceived.push(event); - } - gDiv.addEventListener("animationstart", listener, false); - gDiv.addEventListener("animationiteration", listener, false); - gDiv.addEventListener("animationend", listener, false); -} - -function check_events(events_expected, desc) { - // This function checks that the list of events_expected matches - // the received events -- but it only checks the properties that - // are present on events_expected. - is(gEventsReceived.length, events_expected.length, - "number of events received for " + desc); - for (var i = 0, - i_end = Math.min(events_expected.length, gEventsReceived.length); - i != i_end; ++i) { - var exp = events_expected[i]; - var rec = gEventsReceived[i]; - for (var prop in exp) { - if (prop == "elapsedTime") { - // Allow floating point error. - ok(Math.abs(rec.elapsedTime - exp.elapsedTime) < 0.000002, - "events[" + i + "]." + prop + " for " + desc + - " received=" + rec.elapsedTime + " expected=" + exp.elapsedTime); - } else { - is(rec[prop], exp[prop], "events[" + i + "]." + prop + " for " + desc); - } - } - } - for (i = events_expected.length; i < gEventsReceived.length; ++i) { - ok(false, "unexpected " + gEventsReceived[i].type + " event for " + desc); - } - gEventsReceived = []; -} - -function advance_clock(milliseconds) { - SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(milliseconds); -} diff --git a/layout/style/test/test_flexbox_flex_grow_and_shrink.html b/layout/style/test/test_flexbox_flex_grow_and_shrink.html index e34de180434..357d9f7382e 100644 --- a/layout/style/test/test_flexbox_flex_grow_and_shrink.html +++ b/layout/style/test/test_flexbox_flex_grow_and_shrink.html @@ -63,34 +63,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=696253 /** Test for flex-grow and flex-shrink animation (Bug 696253) **/ -function advance_clock(milliseconds) { - SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(milliseconds); -} - -var display = document.getElementById("display"); -var div = null; -var cs = null; -function new_div(style) { - return new_element("div", style); -} -function new_element(tagname, style) { - if (div != null || cs != null) { - ok(false, "test author forgot to call done_div"); - } - if (typeof(style) != "string") { - ok(false, "test author forgot to pass argument"); - } - div = document.createElement(tagname); - div.setAttribute("style", style); - display.appendChild(div); - cs = getComputedStyle(div, ""); -} - -function done_div() { - display.removeChild(div); - div = null; - cs = null; -} // take over the refresh driver advance_clock(0); @@ -98,7 +70,7 @@ advance_clock(0); // -------------------------------------------- // flexGrowTwoToThree: 2.0 at 0%, 2.5 at 50%, 10 after animation is over -new_div("animation: flexGrowTwoToThree linear 1s"); +var [ div, cs ] = new_div("animation: flexGrowTwoToThree linear 1s"); is_approx(cs.flexGrow, 2, 0.01, "flexGrowTwoToThree at 0.0s"); advance_clock(500); is_approx(cs.flexGrow, 2.5, 0.01, "flexGrowTwoToThree at 0.5s"); @@ -107,7 +79,7 @@ is(cs.flexGrow, 10, "flexGrowTwoToThree at 1.5s"); done_div(); // flexShrinkTwoToThree: 2.0 at 0%, 2.5 at 50%, 20 after animation is over -new_div("animation: flexShrinkTwoToThree linear 1s"); +[ div, cs ] = new_div("animation: flexShrinkTwoToThree linear 1s"); is_approx(cs.flexShrink, 2, 0.01, "flexShrinkTwoToThree at 0.0s"); advance_clock(500); is_approx(cs.flexShrink, 2.5, 0.01, "flexShrinkTwoToThree at 0.5s"); @@ -116,7 +88,7 @@ is(cs.flexShrink, 20, "flexShrinkTwoToThree at 1.5s"); done_div(); // flexGrowZeroToZero: 0 at 0%, 0 at 50%, 10 after animation is over -new_div("animation: flexGrowZeroToZero linear 1s"); +[ div, cs ] = new_div("animation: flexGrowZeroToZero linear 1s"); is(cs.flexGrow, 0, "flexGrowZeroToZero at 0.0s"); advance_clock(500); is(cs.flexGrow, 0, "flexGrowZeroToZero at 0.5s"); @@ -125,7 +97,7 @@ is(cs.flexGrow, 10, "flexGrowZeroToZero at 1.5s"); done_div(); // flexShrinkZeroToZero: 0 at 0%, 0 at 50%, 20 after animation is over -new_div("animation: flexShrinkZeroToZero linear 1s"); +[ div, cs ] = new_div("animation: flexShrinkZeroToZero linear 1s"); is(cs.flexShrink, 0, "flexShrinkZeroToZero at 0.0s"); advance_clock(500); is(cs.flexShrink, 0, "flexShrinkZeroToZero at 0.5s"); @@ -139,7 +111,7 @@ done_div(); // allowed to animate between 0 and other values. But now that's allowed.) // flexGrowZeroToOne: 0 at 0%, 0.5 at 50%, 10 after animation is over. -new_div("animation: flexGrowZeroToOne linear 1s"); +[ div, cs ] = new_div("animation: flexGrowZeroToOne linear 1s"); is(cs.flexGrow, 0, "flexGrowZeroToOne at 0.0s"); advance_clock(500); is(cs.flexGrow, 0.5, "flexGrowZeroToOne at 0.5s"); @@ -148,7 +120,7 @@ is(cs.flexGrow, 10, "flexGrowZeroToOne at 1.5s"); done_div(); // flexShrinkZeroToOne: 0 at 0%, 0.5 at 50%, 20 after animation is over. -new_div("animation: flexShrinkZeroToOne linear 1s"); +[ div, cs ] = new_div("animation: flexShrinkZeroToOne linear 1s"); is(cs.flexShrink, 0, "flexShrinkZeroToOne at 0.0s"); advance_clock(500); is(cs.flexShrink, 0.5, "flexShrinkZeroToOne at 0.5s"); @@ -157,7 +129,7 @@ is(cs.flexShrink, 20, "flexShrinkZeroToOne at 1.5s"); done_div(); // flexGrowOneToZero: 1 at 0%, 0.5 at 50%, 10 after animation is over. -new_div("animation: flexGrowOneToZero linear 1s"); +[ div, cs ] = new_div("animation: flexGrowOneToZero linear 1s"); is(cs.flexGrow, 1, "flexGrowOneToZero at 0.0s"); advance_clock(500); is(cs.flexGrow, 0.5, "flexGrowOneToZero at 0.5s"); @@ -166,7 +138,7 @@ is(cs.flexGrow, 10, "flexGrowOneToZero at 1.5s"); done_div(); // flexShrinkOneToZero: 1 at 0%, 0.5 at 50%, 20 after animation is over. -new_div("animation: flexShrinkOneToZero linear 1s"); +[ div, cs ] = new_div("animation: flexShrinkOneToZero linear 1s"); is(cs.flexShrink, 1, "flexShrinkOneToZero at 0.0s"); advance_clock(500); is(cs.flexShrink, 0.5, "flexShrinkOneToZero at 0.5s");