2010-10-04 Erik Arvidsson <arv@chromium.org>
[WebKit.git] / LayoutTests / fast / dom / HTMLElement / script-tests / class-list.js
1 description('Tests the classList attribute and its properties.');
2
3 var element;
4
5 function createElement(className)
6 {
7     element = document.createElement('p');
8     element.className = className;
9 }
10
11 debug('Tests from http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/');
12
13 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/setting/001.htm
14 // Firefox throws here but WebKit does not throw on setting readonly idl
15 // attributes.
16 createElement('x');
17 try {
18     element.classList = 'y';
19     shouldBeEqualToString('String(element.classList)', 'x');
20 } catch (ex) {
21     testPassed('Throwing on set is acceptable');
22 }
23
24 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/001.htm
25 createElement('');
26 shouldEvaluateTo('element.classList.length', 0);
27
28 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/002.htm
29 createElement('x');
30 shouldEvaluateTo('element.classList.length', 1);
31
32 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/003.htm
33 createElement('x x');
34 shouldEvaluateTo('element.classList.length', 2);
35
36 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/004.htm
37 createElement('x y');
38 shouldEvaluateTo('element.classList.length', 2);
39
40 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/005.htm
41 createElement('');
42 element.classList.add('x');
43 shouldBeEqualToString('element.className', 'x');
44
45 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/006.htm
46 createElement('x');
47 element.classList.add('x');
48 shouldBeEqualToString('element.className', 'x');
49
50 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/007.htm
51 createElement('x  x');
52 element.classList.add('x');
53 shouldBeEqualToString('element.className', 'x  x');
54
55 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/008.htm
56 createElement('y');
57 element.classList.add('x');
58 shouldBeEqualToString('element.className', 'y x');
59
60 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/009.htm
61 createElement('');
62 element.classList.remove('x');
63 shouldBeEqualToString('element.className', '');
64
65 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/010.htm
66 createElement('x');
67 element.classList.remove('x');
68 shouldBeEqualToString('element.className', '');
69
70 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/011.htm
71 createElement(' y x  y ');
72 element.classList.remove('x');
73 shouldBeEqualToString('element.className', ' y y ');
74
75 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/012.htm
76 createElement(' x y  x ');
77 element.classList.remove('x');
78 shouldBeEqualToString('element.className', 'y');
79
80
81 debug('Ensure that we can handle empty class name correctly');
82 element = document.createElement('span');
83 element.classList.toggle('x');
84 shouldBeEqualToString('element.className', 'x');
85 element.classList.toggle('x');
86 shouldBeEqualToString('element.className', '');
87
88 element = document.createElement('span');
89 shouldBeFalse('element.classList.contains(\'x\')');
90 shouldBeNull('element.classList[1]');
91 element.classList.remove('x');
92 element.classList.add('x')
93
94
95 debug('Testing add in presence of trailing white spaces.');
96
97 createElement('x ');
98 element.classList.add('y');
99 shouldBeEqualToString('element.className', 'x y');
100
101 createElement('x\t');
102 element.classList.add('y');
103 shouldBeEqualToString('element.className', 'x\t y');
104
105 createElement(' ');
106 element.classList.add('y');
107 shouldBeEqualToString('element.className', ' y');
108
109
110 debug('Test invalid tokens');
111
112 // Testing exception due to invalid token
113
114 // shouldThrow from js-test-pre.js is not sufficient.
115 function shouldThrowDOMException(f, ec)
116 {
117     try {
118         f();
119         testFailed('Expected an exception');
120     } catch (ex) {
121         if (!(ex instanceof DOMException)) {
122             testFailed('Exception is not an instance of DOMException, found: ' +
123                        Object.toString.call(ex));
124             return;
125         }
126         if (ec !== ex.code) {
127             testFailed('Wrong exception code: ' + ex.code);
128             return;
129         }
130     }
131     var formattedFunction = String(f).replace(/^function.+\{\s*/m, '').
132         replace(/;?\s+\}/m, '');
133     testPassed(formattedFunction + ' threw expected DOMException with code ' + ec);
134 }
135
136 createElement('x');
137 shouldThrowDOMException(function() {
138     element.classList.contains('');
139 }, DOMException.SYNTAX_ERR);
140
141 createElement('x y');
142 shouldThrowDOMException(function() {
143     element.classList.contains('x y');
144 }, DOMException.INVALID_CHARACTER_ERR);
145
146 createElement('');
147 shouldThrowDOMException(function() {
148     element.classList.add('');
149 }, DOMException.SYNTAX_ERR);
150
151 createElement('');
152 shouldThrowDOMException(function() {
153     element.classList.add('x y');
154 }, DOMException.INVALID_CHARACTER_ERR);
155
156 createElement('');
157 shouldThrowDOMException(function() {
158     element.classList.remove('');
159 }, DOMException.SYNTAX_ERR);
160
161 createElement('');
162 shouldThrowDOMException(function() {
163     element.classList.remove('x y');
164 }, DOMException.INVALID_CHARACTER_ERR);
165
166 createElement('');
167 shouldThrowDOMException(function() {
168     element.classList.toggle('');
169 }, DOMException.SYNTAX_ERR);
170
171 createElement('x y');
172 shouldThrowDOMException(function() {
173     element.classList.toggle('x y');
174 }, DOMException.INVALID_CHARACTER_ERR);
175
176
177 debug('Indexing');
178
179 createElement('x');
180 shouldBeEqualToString('element.classList[0]', 'x');
181 shouldBeEqualToString('element.classList.item(0)', 'x');
182
183 createElement('x x');
184 shouldBeEqualToString('element.classList[1]', 'x');
185 shouldBeEqualToString('element.classList.item(1)', 'x');
186
187 createElement('x y');
188 shouldBeEqualToString('element.classList[1]', 'y');
189 shouldBeEqualToString('element.classList.item(1)', 'y');
190
191 createElement('');
192 shouldBeNull('element.classList[0]');
193 shouldBeNull('element.classList.item(0)');
194
195 createElement('x y z');
196 shouldBeNull('element.classList[4]');
197 shouldBeNull('element.classList.item(4)');
198 shouldBeUndefined('element.classList[-1]');  // Not a valid index so should not trigger item().
199 shouldBeNull('element.classList.item(-1)');
200
201 debug('Test case since DOMTokenList is case sensitive');
202
203 createElement('x');
204 shouldBeTrue('element.classList.contains(\'x\')');
205 shouldBeFalse('element.classList.contains(\'X\')');
206 shouldBeEqualToString('element.classList[0]', 'x');
207
208 createElement('X');
209 shouldBeTrue('element.classList.contains(\'X\')');
210 shouldBeFalse('element.classList.contains(\'x\')');
211 shouldBeEqualToString('element.classList[0]', 'X');
212
213
214 debug('Testing whitespace');
215 // U+0020 SPACE, U+0009 CHARACTER TABULATION (tab), U+000A LINE FEED (LF),
216 // U+000C FORM FEED (FF), and U+000D CARRIAGE RETURN (CR)
217
218 createElement('x\u0020y');
219 shouldEvaluateTo('element.classList.length', 2);
220
221 createElement('x\u0009y');
222 shouldEvaluateTo('element.classList.length', 2);
223
224 createElement('x\u000Ay');
225 shouldEvaluateTo('element.classList.length', 2);
226
227 createElement('x\u000Cy');
228 shouldEvaluateTo('element.classList.length', 2);
229
230 createElement('x\u000Dy');
231 shouldEvaluateTo('element.classList.length', 2);
232
233
234 debug('DOMTokenList presence and type');
235
236
237 // Safari returns object
238 // Firefox returns object
239 // IE8 returns object
240 // Chrome returns function
241 // assertEquals('object', typeof DOMTokenList);
242 shouldBeTrue('\'undefined\' != typeof DOMTokenList');
243
244 shouldBeEqualToString('typeof DOMTokenList.prototype', 'object');
245
246 createElement('x');
247 shouldBeEqualToString('typeof element.classList', 'object');
248
249 shouldEvaluateTo('element.classList.constructor', 'DOMTokenList');
250
251 shouldBeTrue('element.classList === element.classList');
252
253 var successfullyParsed = true;