Base: Add a test page for the various element classList APIs

This commit is contained in:
Timothy Flynn 2021-10-18 13:23:15 -04:00 committed by Andreas Kling
parent 14349f058a
commit 72b409a2f7
2 changed files with 244 additions and 0 deletions

View file

@ -0,0 +1,243 @@
<head>
<style>
.pass, .fail {
height: 30px;
line-height: 30px;
color: white;
display: block;
border: 1px solid black;
margin: 3px;
padding: 3px;
}
.pass { background-color: green; }
.fail { background-color: red; }
</style>
</head>
<body>
<div id=test0></div>
<div id=test1></div>
<div id=test2></div>
<script>
let test0 = document.getElementById('test0');
let test1 = document.getElementById('test1');
let test2 = document.getElementById('test2');
const bindMethodsForTest = (method) => {
let failures = 0;
const pass = (message) => {
if (failures > 0)
return;
const span = document.createElement('span');
span.innerHTML = `Pass! ${method}`;
span.setAttribute('class', 'pass');
document.body.appendChild(span);
test0.className = '';
test1.className = '';
test2.className = '';
};
const fail = (message) => {
const span = document.createElement('span');
span.innerHTML = `Fail! ${method}: ${message}`;
span.setAttribute('class', 'fail');
document.body.appendChild(span);
++failures;
};
const invalidTokenTest = () => {
const test = (args1, args2) => {
try {
test0.classList[method](...args1);
fail(`Expected classList.${method}(${args1}) to throw due to empty token`);
} catch (error) {
if (error.name !== 'SyntaxError')
fail(`Expected exception to be a DOMException of type SyntaxError but is "${error.name}"`);
}
try {
test0.classList[method](...args2);
fail(`Expected classList.${method}(${args2}) to throw due to token containing a space`);
} catch (error) {
if (error.name !== 'InvalidCharacterError')
fail(`Expected exception to be a DOMException of type InvalidCharacterError but is "${error.name}"`);
}
};
if (test0.classList[method].length === 2) {
test(['', 'foo'], ['foo bar', 'foobar']);
test(['foo', ''], ['foobar', 'foo bar']);
} else {
test([''], ['foo bar']);
}
};
return [pass, fail, invalidTokenTest];
};
(() => {
const [pass, fail] = bindMethodsForTest('contains');
test0.className = 'foo';
test1.className = 'foo bar';
if (!test0.classList.contains('foo'))
fail('test0 should contain class "foo"');
if (test0.classList.contains('bar'))
fail('test0 should not contain class "bar"');
if (!test1.classList.contains('foo'))
fail('test1 should contain class "foo"');
if (!test1.classList.contains('bar'))
fail('test1 should contain class "bar"');
pass();
})();
(() => {
const [pass, fail, invalidTokenTest] = bindMethodsForTest('add');
invalidTokenTest();
test0.classList.add('foo');
test1.classList.add('foo', 'bar');
test2.classList.add('foo', 'bar', 'foo');
if (test0.className !== 'foo')
fail(`test0 should have a class name of "foo" but has "${test0.className}"`)
if (test1.className !== 'foo bar')
fail(`test1 should have a class name of "foo bar" but has "${test1.className}"`)
if (test2.className !== 'foo bar')
fail(`test2 should have a class name of "foo bar" but has "${test2.className}"`)
pass();
})();
(() => {
const [pass, fail, invalidTokenTest] = bindMethodsForTest('remove');
invalidTokenTest();
test0.className = 'foo';
test1.className = 'foo bar';
test2.className = 'foo bar';
test0.classList.remove('foo');
test1.classList.remove('foo', 'bar');
test2.classList.remove('bar');
if (test0.className !== '')
fail(`test0 should have a class name of "" but has "${test0.className}"`)
if (test1.className !== '')
fail(`test1 should have a class name of "" but has "${test1.className}"`)
if (test2.className !== 'foo')
fail(`test2 should have a class name of "foo" but has "${test2.className}"`)
pass();
})();
(() => {
const [pass, fail, invalidTokenTest] = bindMethodsForTest('toggle');
invalidTokenTest();
if (!test0.classList.toggle('foo'))
fail('test0 should contain class "foo"');
if (!test0.classList.toggle('bar', true))
fail('test0 should contain class "bar"');
if (test0.classList.toggle('baz', false))
fail('test0 should not contain class "baz"');
if (test0.classList.toggle('foo'))
fail('test0 should not contain class "foo"');
if (!test0.classList.toggle('bar', true))
fail('test0 should contain class "bar"');
if (test0.classList.toggle('bar', false))
fail('test0 should not contain class "bar"');
pass();
})();
(() => {
const [pass, fail, invalidTokenTest] = bindMethodsForTest('replace');
invalidTokenTest();
if (test0.classList.replace('foo', 'bar'))
fail('test0 should not have contained class "bar"');
if (test0.className !== '')
fail(`test0 should have a class name of "" but has "${test0.className}"`)
test0.className = 'foo';
if (!test0.classList.replace('foo', 'bar'))
fail('test0 should have contained class "bar"');
if (test0.className !== 'bar')
fail(`test0 should have a class name of "bar" but has "${test0.className}"`)
test0.className = 'foo bar';
if (!test0.classList.replace('bar', 'baz'))
fail('test0 should have contained class "bar"');
if (test0.className !== 'foo baz')
fail(`test0 should have a class name of "foo baz" but has "${test0.className}"`)
test0.className = 'foo bar baz';
if (!test0.classList.replace('foo', 'baz'))
fail('test0 should have contained class "bar"');
if (test0.className !== 'baz bar')
fail(`test0 should have a class name of "baz bar" but has "${test0.className}"`)
test0.className = 'baz bar foo';
if (!test0.classList.replace('foo', 'baz'))
fail('test0 should have contained class "bar"');
if (test0.className !== 'baz bar')
fail(`test0 should have a class name of "baz bar" but has "${test0.className}"`)
test0.className = 'foo bar baz';
if (!test0.classList.replace('baz', 'baz'))
fail('test0 should have contained class "bar"');
if (test0.className !== 'foo bar baz')
fail(`test0 should have a class name of "foo bar baz" but has "${test0.className}"`)
pass();
})();
(() => {
const [pass, fail] = bindMethodsForTest('supports');
try {
test0.classList.supports('foo');
fail('Expected supports to throw due to no defined supported tokens');
} catch (error) {
if (error.name !== 'TypeError')
fail(`Expected exception to be a DOMException of type TypeError but is "${error.name}"`);
}
pass();
})();
(() => {
const [pass, fail] = bindMethodsForTest('value');
test0.classList.value = 'foo';
if (test0.className !== 'foo')
fail(`test0 should have a class name of "foo" but has "${test0.className}"`)
if (test0.classList.value !== 'foo')
fail(`test0 should have a class name of "foo" but has "${test0.className}"`)
test0.classList.value = 'foo bar';
if (test0.className !== 'foo bar')
fail(`test0 should have a class name of "foo bar" but has "${test0.className}"`)
if (test0.classList.value !== 'foo bar')
fail(`test0 should have a class name of "foo bar" but has "${test0.className}"`)
pass();
})();
</script>
</body>

View file

@ -111,6 +111,7 @@
<li><a href="clear-1.html">Float clearing</a></li>
<li><a href="overflow.html">Overflow</a></li>
<li><a href="attributes.html">Attributes</a></li>
<li><a href="class-list.html">Class List</a></li>
<li><h3>Features</h3></li>
<li><a href="css.html">Basic functionality</a></li>
<li><a href="colors.html">css colors</a></li>