|
1 <!DOCTYPE HTML> |
|
2 <html> |
|
3 <!-- |
|
4 https://bugzilla.mozilla.org/show_bug.cgi?id=666041 |
|
5 --> |
|
6 <head> |
|
7 <meta charset="utf-8"> |
|
8 <title>Test for Bug 666041</title> |
|
9 <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> |
|
10 <script type="text/javascript" src="flexbox_layout_testcases.js"></script> |
|
11 <script type="text/javascript" src="property_database.js"></script> |
|
12 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> |
|
13 </head> |
|
14 <body> |
|
15 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666041">Mozilla Bug 666041</a> |
|
16 <div id="display"> |
|
17 <div id="content"> |
|
18 </div> |
|
19 </div> |
|
20 <pre id="test"> |
|
21 <script type="application/javascript;version=1.7"> |
|
22 "use strict"; |
|
23 |
|
24 /** Test for Bug 666041 **/ |
|
25 |
|
26 /* Flexbox Layout Tests |
|
27 * -------------------- |
|
28 * This mochitest exercises our implementation of the flexbox layout algorithm |
|
29 * by creating a flex container, inserting some flexible children, and then |
|
30 * verifying that the computed width of those children is what we expect. |
|
31 * |
|
32 * See flexbox_layout_testcases.js for the actual testcases & testcase format. |
|
33 */ |
|
34 |
|
35 function getComputedStyleWrapper(elem, prop) |
|
36 { |
|
37 return window.getComputedStyle(elem, null).getPropertyValue(prop); |
|
38 } |
|
39 |
|
40 function setPossiblyAliasedProperty(aElem, aPropertyName, aPropertyValue, |
|
41 aPropertyMapping) |
|
42 { |
|
43 let actualPropertyName = (aPropertyName in aPropertyMapping ? |
|
44 aPropertyMapping[aPropertyName] : aPropertyName); |
|
45 |
|
46 if (!gCSSProperties[actualPropertyName]) { |
|
47 ok(false, "Bug in test: property '" + actualPropertyName + |
|
48 "' doesn't exist in gCSSProperties"); |
|
49 } else { |
|
50 let domPropertyName = gCSSProperties[actualPropertyName].domProp; |
|
51 aElem.style[domPropertyName] = aPropertyValue; |
|
52 } |
|
53 } |
|
54 |
|
55 // Helper function to strip "px" off the end of a string |
|
56 // (so that we can compare two lengths using "isfuzzy()" with an epsilon) |
|
57 function stripPx(aLengthInPx) |
|
58 { |
|
59 let pxOffset = aLengthInPx.length - 2; // subtract off length of "px" |
|
60 |
|
61 // Sanity-check the arg: |
|
62 ok(pxOffset > 0 && aLengthInPx.substr(pxOffset) == "px", |
|
63 "expecting value with 'px' units"); |
|
64 |
|
65 return aLengthInPx.substr(0, pxOffset); |
|
66 } |
|
67 |
|
68 // The main test function. |
|
69 // aFlexboxTestcase is an entry from the list in flexbox_layout_testcases.js |
|
70 function testFlexboxTestcase(aFlexboxTestcase, aFlexDirection, aPropertyMapping) |
|
71 { |
|
72 let content = document.getElementById("content"); |
|
73 |
|
74 // Create flex container |
|
75 let flexContainer = document.createElement("div"); |
|
76 flexContainer.style.display = "flex"; |
|
77 flexContainer.style.flexDirection = aFlexDirection; |
|
78 setPossiblyAliasedProperty(flexContainer, "_main-size", |
|
79 gDefaultFlexContainerSize, |
|
80 aPropertyMapping); |
|
81 |
|
82 // Apply testcase's customizations for flex container (if any). |
|
83 if (aFlexboxTestcase.container_properties) { |
|
84 for (let propName in aFlexboxTestcase.container_properties) { |
|
85 let propValue = aFlexboxTestcase.container_properties[propName]; |
|
86 setPossiblyAliasedProperty(flexContainer, propName, propValue, |
|
87 aPropertyMapping); |
|
88 } |
|
89 } |
|
90 |
|
91 // Create & append flex items |
|
92 aFlexboxTestcase.items.forEach(function(aChildSpec) { |
|
93 // Create an element for our item |
|
94 let child = document.createElement("div"); |
|
95 |
|
96 // Set all the specified properties on our item |
|
97 for (let propName in aChildSpec) { |
|
98 // aChildSpec[propName] is either a specified value, |
|
99 // or an array of [specifiedValue, computedValue] |
|
100 let specifiedValue = Array.isArray(aChildSpec[propName]) ? |
|
101 aChildSpec[propName][0] : |
|
102 aChildSpec[propName]; |
|
103 |
|
104 // SANITY CHECK: |
|
105 if (Array.isArray(aChildSpec[propName])) { |
|
106 ok(aChildSpec[propName].length >= 2 && |
|
107 aChildSpec[propName].length <= 3, |
|
108 "unexpected number of elements in array within child spec"); |
|
109 } |
|
110 |
|
111 if (specifiedValue !== null) { |
|
112 setPossiblyAliasedProperty(child, propName, specifiedValue, |
|
113 aPropertyMapping); |
|
114 } |
|
115 } |
|
116 |
|
117 // Append the item to the flex container |
|
118 flexContainer.appendChild(child); |
|
119 }); |
|
120 |
|
121 // Append the flex container |
|
122 content.appendChild(flexContainer); |
|
123 |
|
124 // NOW: Test the computed style on the flex items |
|
125 let child = flexContainer.firstChild; |
|
126 for (let i = 0; i < aFlexboxTestcase.items.length; i++) { |
|
127 if (!child) { // sanity |
|
128 ok(false, "should have created a child for each child-spec"); |
|
129 } |
|
130 |
|
131 let childSpec = aFlexboxTestcase.items[i]; |
|
132 for (let propName in childSpec) { |
|
133 if (Array.isArray(childSpec[propName])) { |
|
134 let expectedVal = childSpec[propName][1]; |
|
135 let actualPropName = (propName in aPropertyMapping ? |
|
136 aPropertyMapping[propName] : propName); |
|
137 let actualVal = getComputedStyleWrapper(child, actualPropName); |
|
138 let message = "computed value of '" + actualPropName + |
|
139 "' should match expected"; |
|
140 |
|
141 if (childSpec[propName].length > 2) { |
|
142 // 3rd entry in array is epsilon |
|
143 // Need to strip off "px" units in order to use epsilon: |
|
144 let actualValNoPx = stripPx(actualVal); |
|
145 let expectedValNoPx = stripPx(expectedVal); |
|
146 isfuzzy(actualValNoPx, expectedValNoPx, |
|
147 childSpec[propName][2], message); |
|
148 } else { |
|
149 is(actualVal, expectedVal, message); |
|
150 } |
|
151 } |
|
152 } |
|
153 |
|
154 child = child.nextSibling; |
|
155 } |
|
156 |
|
157 // Clean up: drop the flex container. |
|
158 content.removeChild(flexContainer); |
|
159 } |
|
160 |
|
161 function main() |
|
162 { |
|
163 gFlexboxTestcases.forEach( |
|
164 function(aTestcase) { |
|
165 testFlexboxTestcase(aTestcase, "", |
|
166 gRowPropertyMapping); |
|
167 testFlexboxTestcase(aTestcase, "row", |
|
168 gRowPropertyMapping); |
|
169 testFlexboxTestcase(aTestcase, "row-reverse", |
|
170 gRowReversePropertyMapping); |
|
171 testFlexboxTestcase(aTestcase, "column", |
|
172 gColumnPropertyMapping); |
|
173 testFlexboxTestcase(aTestcase, "column-reverse", |
|
174 gColumnReversePropertyMapping); |
|
175 } |
|
176 ); |
|
177 } |
|
178 |
|
179 main(); |
|
180 |
|
181 </script> |
|
182 </pre> |
|
183 </body> |
|
184 </html> |