1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/style/test/test_flexbox_layout.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,184 @@ 1.4 +<!DOCTYPE HTML> 1.5 +<html> 1.6 +<!-- 1.7 +https://bugzilla.mozilla.org/show_bug.cgi?id=666041 1.8 +--> 1.9 +<head> 1.10 + <meta charset="utf-8"> 1.11 + <title>Test for Bug 666041</title> 1.12 + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> 1.13 + <script type="text/javascript" src="flexbox_layout_testcases.js"></script> 1.14 + <script type="text/javascript" src="property_database.js"></script> 1.15 + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 1.16 +</head> 1.17 +<body> 1.18 +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666041">Mozilla Bug 666041</a> 1.19 +<div id="display"> 1.20 + <div id="content"> 1.21 + </div> 1.22 +</div> 1.23 +<pre id="test"> 1.24 +<script type="application/javascript;version=1.7"> 1.25 +"use strict"; 1.26 + 1.27 +/** Test for Bug 666041 **/ 1.28 + 1.29 +/* Flexbox Layout Tests 1.30 + * -------------------- 1.31 + * This mochitest exercises our implementation of the flexbox layout algorithm 1.32 + * by creating a flex container, inserting some flexible children, and then 1.33 + * verifying that the computed width of those children is what we expect. 1.34 + * 1.35 + * See flexbox_layout_testcases.js for the actual testcases & testcase format. 1.36 + */ 1.37 + 1.38 +function getComputedStyleWrapper(elem, prop) 1.39 +{ 1.40 + return window.getComputedStyle(elem, null).getPropertyValue(prop); 1.41 +} 1.42 + 1.43 +function setPossiblyAliasedProperty(aElem, aPropertyName, aPropertyValue, 1.44 + aPropertyMapping) 1.45 +{ 1.46 + let actualPropertyName = (aPropertyName in aPropertyMapping ? 1.47 + aPropertyMapping[aPropertyName] : aPropertyName); 1.48 + 1.49 + if (!gCSSProperties[actualPropertyName]) { 1.50 + ok(false, "Bug in test: property '" + actualPropertyName + 1.51 + "' doesn't exist in gCSSProperties"); 1.52 + } else { 1.53 + let domPropertyName = gCSSProperties[actualPropertyName].domProp; 1.54 + aElem.style[domPropertyName] = aPropertyValue; 1.55 + } 1.56 +} 1.57 + 1.58 +// Helper function to strip "px" off the end of a string 1.59 +// (so that we can compare two lengths using "isfuzzy()" with an epsilon) 1.60 +function stripPx(aLengthInPx) 1.61 +{ 1.62 + let pxOffset = aLengthInPx.length - 2; // subtract off length of "px" 1.63 + 1.64 + // Sanity-check the arg: 1.65 + ok(pxOffset > 0 && aLengthInPx.substr(pxOffset) == "px", 1.66 + "expecting value with 'px' units"); 1.67 + 1.68 + return aLengthInPx.substr(0, pxOffset); 1.69 +} 1.70 + 1.71 +// The main test function. 1.72 +// aFlexboxTestcase is an entry from the list in flexbox_layout_testcases.js 1.73 +function testFlexboxTestcase(aFlexboxTestcase, aFlexDirection, aPropertyMapping) 1.74 +{ 1.75 + let content = document.getElementById("content"); 1.76 + 1.77 + // Create flex container 1.78 + let flexContainer = document.createElement("div"); 1.79 + flexContainer.style.display = "flex"; 1.80 + flexContainer.style.flexDirection = aFlexDirection; 1.81 + setPossiblyAliasedProperty(flexContainer, "_main-size", 1.82 + gDefaultFlexContainerSize, 1.83 + aPropertyMapping); 1.84 + 1.85 + // Apply testcase's customizations for flex container (if any). 1.86 + if (aFlexboxTestcase.container_properties) { 1.87 + for (let propName in aFlexboxTestcase.container_properties) { 1.88 + let propValue = aFlexboxTestcase.container_properties[propName]; 1.89 + setPossiblyAliasedProperty(flexContainer, propName, propValue, 1.90 + aPropertyMapping); 1.91 + } 1.92 + } 1.93 + 1.94 + // Create & append flex items 1.95 + aFlexboxTestcase.items.forEach(function(aChildSpec) { 1.96 + // Create an element for our item 1.97 + let child = document.createElement("div"); 1.98 + 1.99 + // Set all the specified properties on our item 1.100 + for (let propName in aChildSpec) { 1.101 + // aChildSpec[propName] is either a specified value, 1.102 + // or an array of [specifiedValue, computedValue] 1.103 + let specifiedValue = Array.isArray(aChildSpec[propName]) ? 1.104 + aChildSpec[propName][0] : 1.105 + aChildSpec[propName]; 1.106 + 1.107 + // SANITY CHECK: 1.108 + if (Array.isArray(aChildSpec[propName])) { 1.109 + ok(aChildSpec[propName].length >= 2 && 1.110 + aChildSpec[propName].length <= 3, 1.111 + "unexpected number of elements in array within child spec"); 1.112 + } 1.113 + 1.114 + if (specifiedValue !== null) { 1.115 + setPossiblyAliasedProperty(child, propName, specifiedValue, 1.116 + aPropertyMapping); 1.117 + } 1.118 + } 1.119 + 1.120 + // Append the item to the flex container 1.121 + flexContainer.appendChild(child); 1.122 + }); 1.123 + 1.124 + // Append the flex container 1.125 + content.appendChild(flexContainer); 1.126 + 1.127 + // NOW: Test the computed style on the flex items 1.128 + let child = flexContainer.firstChild; 1.129 + for (let i = 0; i < aFlexboxTestcase.items.length; i++) { 1.130 + if (!child) { // sanity 1.131 + ok(false, "should have created a child for each child-spec"); 1.132 + } 1.133 + 1.134 + let childSpec = aFlexboxTestcase.items[i]; 1.135 + for (let propName in childSpec) { 1.136 + if (Array.isArray(childSpec[propName])) { 1.137 + let expectedVal = childSpec[propName][1]; 1.138 + let actualPropName = (propName in aPropertyMapping ? 1.139 + aPropertyMapping[propName] : propName); 1.140 + let actualVal = getComputedStyleWrapper(child, actualPropName); 1.141 + let message = "computed value of '" + actualPropName + 1.142 + "' should match expected"; 1.143 + 1.144 + if (childSpec[propName].length > 2) { 1.145 + // 3rd entry in array is epsilon 1.146 + // Need to strip off "px" units in order to use epsilon: 1.147 + let actualValNoPx = stripPx(actualVal); 1.148 + let expectedValNoPx = stripPx(expectedVal); 1.149 + isfuzzy(actualValNoPx, expectedValNoPx, 1.150 + childSpec[propName][2], message); 1.151 + } else { 1.152 + is(actualVal, expectedVal, message); 1.153 + } 1.154 + } 1.155 + } 1.156 + 1.157 + child = child.nextSibling; 1.158 + } 1.159 + 1.160 + // Clean up: drop the flex container. 1.161 + content.removeChild(flexContainer); 1.162 +} 1.163 + 1.164 +function main() 1.165 +{ 1.166 + gFlexboxTestcases.forEach( 1.167 + function(aTestcase) { 1.168 + testFlexboxTestcase(aTestcase, "", 1.169 + gRowPropertyMapping); 1.170 + testFlexboxTestcase(aTestcase, "row", 1.171 + gRowPropertyMapping); 1.172 + testFlexboxTestcase(aTestcase, "row-reverse", 1.173 + gRowReversePropertyMapping); 1.174 + testFlexboxTestcase(aTestcase, "column", 1.175 + gColumnPropertyMapping); 1.176 + testFlexboxTestcase(aTestcase, "column-reverse", 1.177 + gColumnReversePropertyMapping); 1.178 + } 1.179 + ); 1.180 +} 1.181 + 1.182 +main(); 1.183 + 1.184 +</script> 1.185 +</pre> 1.186 +</body> 1.187 +</html>