Bug 1103906 - Update web-platform-tests to revision 551060ba2eb3fa6d1c713c179d52fdf1132ea50c, a=testonly

--HG--
rename : testing/web-platform/tests/dom/nodes/Document-createComment.html => testing/web-platform/tests/dom/nodes/Document-createTextNode.html
rename : testing/web-platform/tests/selectors-api/tests/submissions/Opera/level2-baseline.html => testing/web-platform/tests/selectors-api/tests/submissions/Opera/Element-matches.html
rename : testing/web-platform/tests/selectors-api/tests/submissions/Opera/level2-baseline.html => testing/web-platform/tests/selectors-api/tests/submissions/Opera/ParentNode-find-findAll.html
rename : testing/web-platform/tests/selectors-api/tests/submissions/Opera/level2-lib.js => testing/web-platform/tests/selectors-api/tests/submissions/Opera/ParentNode-find-findAll.js
This commit is contained in:
James Graham 2014-11-24 12:56:30 +00:00
parent 1b1a24b820
commit 174983d7b3
72 changed files with 1682 additions and 1115 deletions

View File

@ -0,0 +1,83 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Re-initializing events while dispatching them</title>
<link rel="author" title="Josh Matthews" href="mailto:josh@joshmatthews.net">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
var events = {
'KeyboardEvent': {
'constructor': function() { return new KeyboardEvent("type", {key: "A"}); },
'init': function(ev) { ev.initKeyboardEvent("type2", true, true, null, "a", 1, "", true, "") },
'check': function(ev) {
assert_equals(ev.key, "A", "initKeyboardEvent key setter should short-circuit");
assert_false(ev.repeat, "initKeyboardEvent repeat setter should short-circuit");
assert_equals(ev.location, 0, "initKeyboardEvent location setter should short-circuit");
}
},
'MouseEvent': {
'constructor': function() { return new MouseEvent("type"); },
'init': function(ev) { ev.initMouseEvent("type2", true, true, null, 0, 1, 1, 1, 1, true, true, true, true, 1, null) },
'check': function(ev) {
assert_equals(ev.screenX, 0, "initMouseEvent screenX setter should short-circuit");
assert_equals(ev.screenY, 0, "initMouseEvent screenY setter should short-circuit");
assert_equals(ev.clientX, 0, "initMouseEvent clientX setter should short-circuit");
assert_equals(ev.clientY, 0, "initMouseEvent clientY setter should short-circuit");
assert_false(ev.ctrlKey, "initMouseEvent ctrlKey setter should short-circuit");
assert_false(ev.altKey, "initMouseEvent altKey setter should short-circuit");
assert_false(ev.shiftKey, "initMouseEvent shiftKey setter should short-circuit");
assert_false(ev.metaKey, "initMouseEvent metaKey setter should short-circuit");
assert_equals(ev.button, 0, "initMouseEvent button setter should short-circuit");
}
},
'CustomEvent': {
'constructor': function() { return new CustomEvent("type") },
'init': function(ev) { ev.initCustomEvent("type2", true, true, 1) },
'check': function(ev) {
assert_equals(ev.detail, null, "initCustomEvent detail setter should short-circuit");
}
},
'UIEvent': {
'constructor': function() { return new UIEvent("type") },
'init': function(ev) { ev.initUIEvent("type2", true, true, window, 1) },
'check': function(ev) {
assert_equals(ev.view, null, "initUIEvent view setter should short-circuit");
assert_equals(ev.detail, 0, "initUIEvent detail setter should short-circuit");
}
},
'Event': {
'constructor': function() { return new Event("type") },
'init': function(ev) { ev.initEvent("type2", true, true) },
'check': function(ev) {
assert_equals(ev.bubbles, false, "initEvent bubbles setter should short-circuit");
assert_equals(ev.cancelable, false, "initEvent cancelable setter should short-circuit");
assert_equals(ev.type, "type", "initEvent type setter should short-circuit");
}
}
};
var names = Object.keys(events);
for (var i = 0; i < names.length; i++) {
var t = async_test("Calling init" + names[i] + " while dispatching.");
t.step(function() {
var e = events[names[i]].constructor();
var target = document.createElement("div")
target.addEventListener("type", t.step_func(function() {
events[names[i]].init(e);
var o = e;
while ((o = Object.getPrototypeOf(o))) {
if (!(o.constructor.name in events)) {
break;
}
events[o.constructor.name].check(e);
}
}), false);
assert_equals(target.dispatchEvent(e), true, "dispatchEvent must return true")
});
t.done();
}
</script>

View File

@ -1,75 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title> addEventListener() optional parameter: useCapture </title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
var EVENT = "foo";
var TARGET = document.getElementById("target");
var PARENT = document.getElementById("parent");
var TBODY = document.getElementById("table-body");
var TABLE = document.getElementById("table");
var BODY = document.body;
var HTML = document.documentElement;
var CurrentTargets = [TARGET, PARENT, TBODY, TABLE, BODY, HTML, document, window];
var ExpectResult = CurrentTargets;
var ActualResult = [];
var ExpectPhases = [2,3,3,3,3,3,3,3];
var ActualPhases = [];
var description = "Test Description: " +
"useCapture is an optional parameter for EventTarget.addEventListener and EventTarget.removeEventListener. " +
"If it is not provided, both methods must behave as if useCapture were specified to be false.";
var EventHandlers = [ function(evt){ TestEvent(evt, 0); }, function(evt){ TestEvent(evt, 1); } ]
test(function()
{
for (var i=0; i < CurrentTargets.length; i++)
{
CurrentTargets[i].addEventListener(EVENT, TestEvent);
}
var evt = document.createEvent("Event");
evt.initEvent(EVENT, true, true);
TARGET.dispatchEvent(evt);
for (var i=0; i < CurrentTargets.length; i++)
{
CurrentTargets[i].removeEventListener(EVENT, TestEvent);
}
TARGET.dispatchEvent(evt);
assert_array_equals(ActualResult, ExpectResult, "ActualResult");
assert_array_equals(ActualPhases, ExpectPhases, "ActualPhases");
}, description);
function TestEvent(evt, i)
{
ActualResult.push(evt.currentTarget);
ActualPhases.push(evt.eventPhase);
}
</script>
</body>
</html>

View File

@ -1,61 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title> dispatchEvent() return value and Event.preventDefault() </title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
var EVENT = "foo";
var TARGET = document.getElementById("target");
var PARENT = document.getElementById("parent");
var DefaultPrevented = false;
var description = "Test Description: " +
"dispatchEvent() return value indicates whether any of the listeners which handled the event called " +
"Event.preventDefault(). If Event.preventDefault() was called the returned value must be false, else " +
"it must be true.";
test(function()
{
PARENT.addEventListener(EVENT, function(e){TestEvent(e, 0)}, true);
TARGET.addEventListener(EVENT, function(e){TestEvent(e, 1)}, true);
TARGET.addEventListener(EVENT, function(e){TestEvent(e, 2)}, true);
var evt = document.createEvent("Event");
evt.initEvent(EVENT, true, true);
var ReturnValue1 = PARENT.dispatchEvent(evt);
var ReturnValue2 = TARGET.dispatchEvent(evt);
assert_array_equals([DefaultPrevented, ReturnValue1, ReturnValue2], [true, true, false]);
}, description);
function TestEvent(evt, i)
{
if (1 == i)
{
evt.preventDefault();
DefaultPrevented = evt.defaultPrevented;
}
}
</script>
</body>
</html>

View File

@ -1,75 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title> addEventListener() optional parameter: useCapture </title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
var EVENT = "foo";
var TARGET = document.getElementById("target");
var PARENT = document.getElementById("parent");
var TBODY = document.getElementById("table-body");
var TABLE = document.getElementById("table");
var BODY = document.body;
var HTML = document.documentElement;
var CurrentTargets = [TARGET, PARENT, TBODY, TABLE, BODY, HTML, document, window];
var ExpectResult = CurrentTargets;
var ActualResult = [];
var ExpectPhases = [2,3,3,3,3,3,3,3];
var ActualPhases = [];
var description = "Test Description: " +
"useCapture is an optional parameter for EventTarget.addEventListener and EventTarget.removeEventListener. " +
"If it is not provided, both methods must behave as if useCapture were specified to be false.";
var EventHandlers = [ function(evt){ TestEvent(evt, 0); }, function(evt){ TestEvent(evt, 1); } ]
test(function()
{
for (var i=0; i < CurrentTargets.length; i++)
{
CurrentTargets[i].addEventListener(EVENT, TestEvent);
}
var evt = document.createEvent("Event");
evt.initEvent(EVENT, true, true);
TARGET.dispatchEvent(evt);
for (var i=0; i < CurrentTargets.length; i++)
{
CurrentTargets[i].removeEventListener(EVENT, TestEvent);
}
TARGET.dispatchEvent(evt);
assert_array_equals(ActualResult, ExpectResult, "ActualResult");
assert_array_equals(ActualPhases, ExpectPhases, "ActualPhases");
}, description);
function TestEvent(evt, i)
{
ActualResult.push(evt.currentTarget);
ActualPhases.push(evt.eventPhase);
}
</script>
</body>
</html>

View File

@ -1,62 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title> dispatchEvent() return value and Event.preventDefault() </title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
var EVENT = "foo";
var TARGET = document.getElementById("target");
var PARENT = document.getElementById("parent");
var DefaultPrevented = false;
var description = "Test Description: " +
"dispatchEvent() return value indicates whether any of the listeners which handled the event called " +
"Event.preventDefault(). If Event.preventDefault() was called the returned value must be false, else " +
"it must be true.";
test(function()
{
PARENT.addEventListener(EVENT, function(e){TestEvent(e, 0)}, true);
TARGET.addEventListener(EVENT, function(e){TestEvent(e, 1)}, true);
TARGET.addEventListener(EVENT, function(e){TestEvent(e, 2)}, true);
var evt = document.createEvent("Event");
evt.initEvent(EVENT, true, true);
var ReturnValue1 = PARENT.dispatchEvent(evt);
var ReturnValue2 = TARGET.dispatchEvent(evt);
assert_array_equals([DefaultPrevented, ReturnValue1, ReturnValue2], [true, true, false]);
}, description);
function TestEvent(evt, i)
{
if (1 == i)
{
evt.preventDefault();
DefaultPrevented = evt.defaultPrevented;
}
}
</script>
</body>
</html>

View File

@ -10,9 +10,42 @@
<div id=log></div>
<script type=text/plain class=untested>
[Constructor(DOMString type, optional EventInit eventInitDict)/*,
Exposed=(Window,Worker)*/]
interface Event {
readonly attribute DOMString type;
readonly attribute EventTarget? target;
readonly attribute EventTarget? currentTarget;
const unsigned short NONE = 0;
const unsigned short CAPTURING_PHASE = 1;
const unsigned short AT_TARGET = 2;
const unsigned short BUBBLING_PHASE = 3;
readonly attribute unsigned short eventPhase;
void stopPropagation();
void stopImmediatePropagation();
readonly attribute boolean bubbles;
readonly attribute boolean cancelable;
void preventDefault();
readonly attribute boolean defaultPrevented;
[Unforgeable] readonly attribute boolean isTrusted;
readonly attribute DOMTimeStamp timeStamp;
void initEvent(DOMString type, boolean bubbles, boolean cancelable);
};
dictionary EventInit {
boolean bubbles = false;
boolean cancelable = false;
};
/*[Exposed=(Window,Worker)]*/
interface EventTarget {
void addEventListener(DOMString type, EventListener? callback, optional boolean capture /* = false */);
void removeEventListener(DOMString type, EventListener? callback, optional boolean capture /* = false */);
void addEventListener(DOMString type, EventListener? callback, optional boolean capture = false);
void removeEventListener(DOMString type, EventListener? callback, optional boolean capture = false);
boolean dispatchEvent(Event event);
};
</script>
@ -22,7 +55,8 @@ callback EventHandlerNonNull = any (Event event);
typedef EventHandlerNonNull? EventHandler;
</script>
<script type=text/plain>
[NoInterfaceObject]
[NoInterfaceObject/*,
Exposed=(Window,Worker)*/]
interface XMLHttpRequestEventTarget : EventTarget {
// event handlers
attribute EventHandler onloadstart;
@ -34,6 +68,7 @@ interface XMLHttpRequestEventTarget : EventTarget {
attribute EventHandler onloadend;
};
/*[Exposed=(Window,Worker)]*/
interface XMLHttpRequestUpload : XMLHttpRequestEventTarget {
};
@ -46,7 +81,8 @@ enum XMLHttpRequestResponseType {
"text"
};
[Constructor]
[Constructor/*,
Exposed=(Window,Worker)*/]
interface XMLHttpRequest : XMLHttpRequestEventTarget {
// event handler
attribute EventHandler onreadystatechange;
@ -60,16 +96,17 @@ interface XMLHttpRequest : XMLHttpRequestEventTarget {
readonly attribute unsigned short readyState;
// request
void open(ByteString method, /*[EnsureUTF16]*/ DOMString url);
void open(ByteString method, /*[EnsureUTF16]*/ DOMString url, boolean async, optional /*[EnsureUTF16]*/ DOMString? username = null, optional /*[EnsureUTF16]*/ DOMString? password = null);
void open(ByteString method, USVString url);
void open(ByteString method, USVString url, boolean async, optional USVString? username = null, optional USVString? password = null);
void setRequestHeader(ByteString name, ByteString value);
attribute unsigned long timeout;
attribute boolean withCredentials;
readonly attribute XMLHttpRequestUpload upload;
void send(optional (ArrayBufferView or Blob or Document or /*[EnsureUTF16]*/ DOMString or FormData or URLSearchParams)? data = null);
void send(optional (Document or BodyInit)? body = null);
void abort();
// response
readonly attribute USVString responseURL;
readonly attribute unsigned short status;
readonly attribute ByteString statusText;
ByteString? getResponseHeader(ByteString name);
@ -77,19 +114,38 @@ interface XMLHttpRequest : XMLHttpRequestEventTarget {
void overrideMimeType(DOMString mime);
attribute XMLHttpRequestResponseType responseType;
readonly attribute any response;
readonly attribute DOMString responseText;
readonly attribute Document? responseXML;
readonly attribute USVString responseText;
[Exposed=Window] readonly attribute Document? responseXML;
};
typedef (File or USVString) FormDataEntryValue;
[Constructor(optional HTMLFormElement form)/*,
Exposed=(Window,Worker)*/]
interface FormData {
void append(/*[EnsureUTF16]*/ DOMString name, Blob value, optional /*[EnsureUTF16]*/ DOMString filename);
void append(/*[EnsureUTF16]*/ DOMString name, /*[EnsureUTF16]*/ DOMString value);
void delete(/*[EnsureUTF16]*/ DOMString name);
FormDataEntryValue? get(/*[EnsureUTF16]*/ DOMString name);
sequence<FormDataEntryValue> getAll(/*[EnsureUTF16]*/ DOMString name);
boolean has(/*[EnsureUTF16]*/ DOMString name);
void set(/*[EnsureUTF16]*/ DOMString name, Blob value, optional /*[EnsureUTF16]*/ DOMString filename);
void set(/*[EnsureUTF16]*/ DOMString name, /*[EnsureUTF16]*/ DOMString value);
void append(USVString name, Blob value, optional USVString filename);
void append(USVString name, USVString value);
void delete(USVString name);
FormDataEntryValue? get(USVString name);
sequence<FormDataEntryValue> getAll(USVString name);
boolean has(USVString name);
void set(USVString name, Blob value, optional USVString filename);
void set(USVString name, USVString value);
/*iterable<USVString, FormDataEntryValue>;*/
};
[Constructor(DOMString type, optional ProgressEventInit eventInitDict)/*,
Exposed=(Window,Worker)*/]
interface ProgressEvent : Event {
readonly attribute boolean lengthComputable;
readonly attribute unsigned long long loaded;
readonly attribute unsigned long long total;
};
dictionary ProgressEventInit : EventInit {
boolean lengthComputable = false;
unsigned long long loaded = 0;
unsigned long long total = 0;
};
</script>
<script>

View File

@ -1,9 +1,10 @@
import imp
import os
here = os.path.split(os.path.abspath(__file__))[0]
def main(request, response):
auth = imp.load_source("", os.path.join(os.path.abspath(os.curdir),
"XMLHttpRequest",
"resources",
auth = imp.load_source("", os.path.join(here,
"..",
"authentication.py"))
return auth.main(request, response)

View File

@ -1,9 +1,10 @@
import imp
import os
here = os.path.split(os.path.abspath(__file__))[0]
def main(request, response):
auth = imp.load_source("", os.path.join(os.path.abspath(os.curdir),
"XMLHttpRequest",
"resources",
auth = imp.load_source("", os.path.join(here,
"..",
"authentication.py"))
return auth.main(request, response)

View File

@ -1,9 +1,10 @@
import imp
import os
here = os.path.split(os.path.abspath(__file__))[0]
def main(request, response):
auth = imp.load_source("", os.path.join(os.path.abspath(os.curdir),
"XMLHttpRequest",
"resources",
auth = imp.load_source("", os.path.join(here,
"..",
"authentication.py"))
return auth.main(request, response)

View File

@ -1,9 +1,10 @@
import imp
import os
here = os.path.split(os.path.abspath(__file__))[0]
def main(request, response):
auth = imp.load_source("", os.path.join(os.path.abspath(os.curdir),
"XMLHttpRequest",
"resources",
auth = imp.load_source("", os.path.join(here,
"..",
"authentication.py"))
return auth.main(request, response)

View File

@ -0,0 +1,61 @@
<!doctype html>
<meta charset=utf-8>
<title>XMLHttpRequest: passing objects to send()</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol/li[4]" />
<link rel="help" href="https://heycam.github.io/webidl/#es-union" data-tested-assertations="following::ol/li[16]" />
<div id="log"></div>
<script>
function do_test(obj, expected, name) {
var test = async_test(name)
test.step(function() {
var client = new XMLHttpRequest()
client.onload = test.step_func(function () {
assert_equals(client.responseText, expected)
test.done()
});
client.open('POST', 'resources/content.py')
if (expected.exception) {
assert_throws(expected.exception, function(){client.send(obj)})
test.done()
} else {
client.send(obj)
}
});
}
do_test({}, '[object Object]', 'sending a plain empty object')
do_test(Math, '[object Math]', 'sending the ES Math object')
do_test(new XMLHttpRequest, '[object XMLHttpRequest]', 'sending a new XHR instance')
do_test({toString:function(){}}, 'undefined', 'sending object that stringifies to undefined')
do_test({toString:function(){return null}}, 'null', 'sending object that stringifies to null')
var ancestor = {toString: function(){
var ar=[]
for (var prop in this) {
if (this.hasOwnProperty(prop)) {
ar.push(prop+'='+this[prop])
}
};
return ar.join('&')
}};
var myObj = Object.create(ancestor, {foo:{value:1, enumerable: true}, bar:{value:'foo', enumerable:true}})
do_test(myObj, 'foo=1&bar=foo', 'object that stringifies to query string')
var myFakeJSON = {a:'a', b:'b', toString:function(){ return JSON.stringify(this, function(key, val){ return key ==='toString'?undefined:val; }) }}
do_test(myFakeJSON, '{"a":"a","b":"b"}', 'object that stringifies to JSON string')
var myFakeDoc1 = {valueOf:function(){return document}}
do_test(myFakeDoc1, '[object Object]', 'object whose valueOf() returns a document - ignore valueOf(), stringify')
var myFakeDoc2 = {toString:function(){return document}}
do_test(myFakeDoc2, {exception:new TypeError()}, 'object whose toString() returns a document, expected to throw')
var myThrower = {toString:function(){throw {name:'FooError', message:'bar'}}}
do_test(myThrower, {exception:{name:'FooError'}}, 'object whose toString() throws, expected to throw')
</script>

View File

@ -0,0 +1,57 @@
<!doctype html>
<meta charset=utf-8>
<title>XMLHttpRequest: passing objects that interfere with the XHR instance to send()</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol/li[4]" />
<link rel="help" href="https://heycam.github.io/webidl/#es-union" data-tested-assertations="following::ol/li[16]" />
<div id="log"></div>
<script>
var test1 = async_test('abort() called from data stringification')
test1.step(function() {
var client = new XMLHttpRequest()
var objAbortsOnStringification = {toString:function(){
client.abort();
}}
client.open('POST', 'resources/content.py')
assert_throws("InvalidStateError", function(){
client.send(objAbortsOnStringification)
})
test1.done()
});
var test2 = async_test('open() called from data stringification')
test2.step(function() {
var client = new XMLHttpRequest()
var objOpensOnStringification = {toString:function(){
client.open('POST', 'resources/status.py?text=second_open_wins');
}}
client.onloadend = test2.step_func(function(){
assert_equals(client.statusText, 'second_open_wins')
test2.done()
})
client.open('POST', 'resources/status.py?text=first_open_wins')
client.send(objOpensOnStringification)
});
var test3 = async_test('send() called from data stringification')
test3.step(function() {
var client = new XMLHttpRequest()
var objSendsOnStringification = {toString:function(){
client.send('bomb!');
}}
client.onload = test3.step_func(function(){
assert_equals(client.responseText, 'bomb!')
test3.done()
})
client.open('POST', 'resources/content.py')
assert_throws('InvalidStateError', function(){
client.send(objSendsOnStringification)
})
});
</script>

View File

@ -22,7 +22,7 @@ edge-cases like tests that cause the browser to crash or hang.
## By Automating the Browser
For automated test running designed to be robust enough to use in a CI
environment, the [wptrunner](http://github.com/wptrunner) test runner
environment, the [wptrunner](http://github.com/w3c/wptrunner) test runner
can be used. This is a test runner written in Python and designed to
control the browser from the outside using some remote control
protocol such as WebDriver. This allows it to handle cases such as the

View File

@ -5,7 +5,6 @@
// Everything is done in functions in this test harness, so we have to declare
// all the variables before use to make sure they can be reused.
var selection;
var testDiv, paras, detachedDiv, detachedPara1, detachedPara2,
foreignDoc, foreignPara1, foreignPara2, xmlDoc, xmlElement,
detachedXmlElement, detachedTextNode, foreignTextNode,
@ -17,7 +16,6 @@ var testDiv, paras, detachedDiv, detachedPara1, detachedPara2,
var testRangesShort, testRanges, testPoints, testNodesShort, testNodes;
function setupRangeTests() {
selection = getSelection();
testDiv = document.querySelector("#test");
if (testDiv) {
testDiv.parentNode.removeChild(testDiv);

View File

@ -0,0 +1,70 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>EventTarget.addEventListener: capture argument omitted</title>
<link rel="help" href="https://dom.spec.whatwg.org/#dom-eventtarget-addeventlistener">
<link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
test(function() {
var event_type = "foo";
var target = document.getElementById("target");
var targets = [
target,
document.getElementById("parent"),
document.getElementById("table-body"),
document.getElementById("table"),
document.body,
document.documentElement,
document,
window
];
var phases = [
Event.AT_TARGET,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE
];
var actual_targets = [], actual_phases = [];
var test_event = function(evt) {
actual_targets.push(evt.currentTarget);
actual_phases.push(evt.eventPhase);
}
for (var i = 0; i < targets.length; i++) {
targets[i].addEventListener(event_type, test_event);
}
var evt = document.createEvent("Event");
evt.initEvent(event_type, true, true);
target.dispatchEvent(evt);
for (var i = 0; i < targets.length; i++) {
targets[i].removeEventListener(event_type, test_event);
}
target.dispatchEvent(evt);
assert_array_equals(actual_targets, targets, "targets");
assert_array_equals(actual_phases, phases, "phases");
}, "EventTarget.addEventListener with the capture argument omitted");
</script>

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>EventTarget.dispatchEvent: return value</title>
<link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-event-preventdefault">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-event-defaultprevented">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
test(function() {
var event_type = "foo";
var target = document.getElementById("target");
var parent = document.getElementById("parent");
var default_prevented;
parent.addEventListener(event_type, function(e) {}, true);
target.addEventListener(event_type, function(e) {
evt.preventDefault();
default_prevented = evt.defaultPrevented;
}, true);
target.addEventListener(event_type, function(e) {}, true);
var evt = document.createEvent("Event");
evt.initEvent(event_type, true, true);
assert_true(parent.dispatchEvent(evt));
assert_false(target.dispatchEvent(evt));
assert_true(default_prevented);
}, "Return value of EventTarget.dispatchEvent.");
</script>

View File

@ -360,7 +360,8 @@ interface Attr {
readonly attribute DOMString localName;
readonly attribute DOMString name;
attribute DOMString value;
attribute DOMString textContent; // alias of .value
attribute DOMString nodeValue; // legacy alias of .value
attribute DOMString textContent; // legacy alias of .value
readonly attribute Element? ownerElement;

View File

@ -0,0 +1,77 @@
function test_constructor(ctor) {
test(function() {
var object = new window[ctor]();
assert_equals(Object.getPrototypeOf(object),
window[ctor].prototype, "Prototype chain: " + ctor);
assert_equals(Object.getPrototypeOf(Object.getPrototypeOf(object)),
CharacterData.prototype, "Prototype chain: CharacterData");
assert_equals(Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(object))),
Node.prototype, "Prototype chain: Node");
}, "new " + ctor + "(): prototype chain");
test(function() {
var object = new window[ctor]();
assert_true(object instanceof Node, "Should be a Node");
assert_true(object instanceof CharacterData, "Should be a CharacterData");
assert_true(object instanceof window[ctor], "Should be a " + ctor);
}, "new " + ctor + "(): instanceof");
test(function() {
var object = new window[ctor]();
assert_equals(object.data, "");
assert_equals(object.nodeValue, "");
assert_equals(object.ownerDocument, document);
}, "new " + ctor + "(): no arguments");
var arguments = [
[undefined, ""],
[null, "null"],
[42, "42"],
["", ""],
["-", "-"],
["--", "--"],
["-->", "-->"],
["<!--", "<!--"],
["\u0000", "\u0000"],
["\u0000test", "\u0000test"],
["&amp;", "&amp;"],
];
arguments.forEach(function(a) {
var argument = a[0], expected = a[1];
test(function() {
var object = new window[ctor](argument);
assert_equals(object.data, expected);
assert_equals(object.nodeValue, expected);
assert_equals(object.ownerDocument, document);
}, "new " + ctor + "(): " + format_value(argument));
});
test(function() {
var called = [];
var object = new window[ctor]({
toString: function() {
called.push("first");
return "text";
}
}, {
toString: function() {
called.push("second");
assert_unreached("Should not look at the second argument.");
}
});
assert_equals(object.data, "text");
assert_equals(object.nodeValue, "text");
assert_equals(object.ownerDocument, document);
assert_array_equals(called, ["first"]);
}, "new " + ctor + "(): two arguments")
async_test("new " + ctor + "() should get the correct ownerDocument across globals").step(function() {
var iframe = document.createElement("iframe");
iframe.onload = this.step_func_done(function() {
var object = new iframe.contentWindow[ctor]();
assert_equals(object.ownerDocument, iframe.contentDocument);
});
document.body.appendChild(iframe);
});
}

View File

@ -4,81 +4,8 @@
<link rel=help href="https://dom.spec.whatwg.org/#dom-comment">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="Comment-Text-constructor.js"></script>
<div id="log"></div>
<script>
test(function() {
var comment = new Comment();
assert_equals(Object.getPrototypeOf(comment),
Comment.prototype, "Prototype chain: Comment");
assert_equals(Object.getPrototypeOf(Object.getPrototypeOf(comment)),
CharacterData.prototype, "Prototype chain: CharacterData");
assert_equals(Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(comment))),
Node.prototype, "Prototype chain: Node");
}, "new Comment(): prototype chain");
test(function() {
var comment = new Comment();
assert_true(comment instanceof Node, "Should be a Node");
assert_true(comment instanceof CharacterData, "Should be a CharacterData");
assert_true(comment instanceof Comment, "Should be a Comment");
}, "new Comment(): instanceof");
test(function() {
var comment = new Comment();
assert_equals(comment.data, "");
assert_equals(comment.nodeValue, "");
assert_equals(comment.ownerDocument, document);
}, "new Comment(): no arguments");
var arguments = [
[undefined, ""],
[null, "null"],
[42, "42"],
["", ""],
["-", "-"],
["--", "--"],
["-->", "-->"],
["<!--", "<!--"],
["\u0000", "\u0000"],
["\u0000test", "\u0000test"],
["&amp;", "&amp;"],
];
arguments.forEach(function(a) {
var argument = a[0], expected = a[1];
test(function() {
var comment = new Comment(argument);
assert_equals(comment.data, expected);
assert_equals(comment.nodeValue, expected);
assert_equals(comment.ownerDocument, document);
}, "new Comment(): " + format_value(argument));
});
test(function() {
var called = [];
var comment = new Comment({
toString: function() {
called.push("first");
return "text";
}
}, {
toString: function() {
called.push("second");
assert_unreached("Should not look at the second argument.");
}
});
assert_equals(comment.data, "text");
assert_equals(comment.nodeValue, "text");
assert_equals(comment.ownerDocument, document);
assert_array_equals(called, ["first"]);
}, "new Comment(): two arguments")
async_test("new Comment() should get the correct ownerDocument across globals").step(function() {
var iframe = document.createElement("iframe");
iframe.onload = this.step_func_done(function() {
var comment = new iframe.contentWindow.Comment();
assert_equals(comment.ownerDocument, iframe.contentDocument);
});
document.body.appendChild(iframe);
});
test_constructor("Comment");
</script>

View File

@ -107,6 +107,7 @@ test(function() {
assert_equals(doc.contentType, "application/xml")
assert_equals(doc.URL, "about:blank")
assert_equals(doc.documentURI, "about:blank")
assert_equals(doc.createElement("DIV").localName, "DIV");
}, "createDocument test " + i + ": metadata for " +
[namespace, qualifiedName, doctype].map(function(el) { return format_value(el) }))
}

View File

@ -10,48 +10,58 @@
<link rel=help href="https://dom.spec.whatwg.org/#dom-document-documentelement">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="DOMImplementation-createHTMLDocument.js"></script>
<div id="log"></div>
<script>
function checkDoc(title, expectedtitle, normalizedtitle) {
test(function() {
var doc = document.implementation.createHTMLDocument(title);
assert_equals(doc.doctype.name, "html")
assert_equals(doc.doctype.publicId, "")
assert_equals(doc.doctype.systemId, "")
assert_equals(doc.documentElement.localName, "html")
assert_equals(doc.documentElement.firstChild.localName, "head")
if (title !== undefined) {
assert_equals(doc.documentElement.firstChild.childNodes.length, 1)
assert_equals(doc.documentElement.firstChild.firstChild.localName, "title")
assert_equals(doc.documentElement.firstChild.firstChild.firstChild.data,
expectedtitle)
} else {
assert_equals(doc.documentElement.firstChild.childNodes.length, 0)
}
assert_equals(doc.documentElement.lastChild.localName, "body")
assert_equals(doc.documentElement.lastChild.childNodes.length, 0)
})
}
checkDoc("", "", "")
checkDoc(null, "null", "null")
checkDoc(undefined, "", "")
checkDoc("foo bar baz", "foo bar baz", "foo bar baz")
checkDoc("foo\t\tbar baz", "foo\t\tbar baz", "foo bar baz")
checkDoc("foo\n\nbar baz", "foo\n\nbar baz", "foo bar baz")
checkDoc("foo\f\fbar baz", "foo\f\fbar baz", "foo bar baz")
checkDoc("foo\r\rbar baz", "foo\r\rbar baz", "foo bar baz")
createHTMLDocuments(function(doc, expectedtitle, normalizedtitle) {
assert_true(doc instanceof Document, "Should be a Document")
assert_true(doc instanceof Node, "Should be a Node")
assert_equals(doc.childNodes.length, 2,
"Document should have two child nodes")
test(function() {
var doc = document.implementation.createHTMLDocument();
assert_equals(doc.doctype.name, "html")
assert_equals(doc.doctype.publicId, "")
assert_equals(doc.doctype.systemId, "")
assert_equals(doc.documentElement.localName, "html")
assert_equals(doc.documentElement.firstChild.localName, "head")
assert_equals(doc.documentElement.firstChild.childNodes.length, 0)
assert_equals(doc.documentElement.lastChild.localName, "body")
assert_equals(doc.documentElement.lastChild.childNodes.length, 0)
}, "Missing title argument");
var doctype = doc.doctype
assert_true(doctype instanceof DocumentType,
"Doctype should be a DocumentType")
assert_true(doctype instanceof Node, "Doctype should be a Node")
assert_equals(doctype.name, "html")
assert_equals(doctype.publicId, "")
assert_equals(doctype.systemId, "")
var documentElement = doc.documentElement
assert_true(documentElement instanceof HTMLHtmlElement,
"Document element should be a HTMLHtmlElement")
assert_equals(documentElement.childNodes.length, 2,
"Document element should have two child nodes")
assert_equals(documentElement.localName, "html")
assert_equals(documentElement.tagName, "HTML")
var head = documentElement.firstChild
assert_true(head instanceof HTMLHeadElement,
"Head should be a HTMLHeadElement")
assert_equals(head.localName, "head")
assert_equals(head.tagName, "HEAD")
if (expectedtitle !== undefined) {
assert_equals(head.childNodes.length, 1)
var title = head.firstChild
assert_true(title instanceof HTMLTitleElement,
"Title should be a HTMLTitleElement")
assert_equals(title.localName, "title")
assert_equals(title.tagName, "TITLE")
assert_equals(title.childNodes.length, 1)
assert_equals(title.firstChild.data, expectedtitle)
} else {
assert_equals(head.childNodes.length, 0)
}
var body = documentElement.lastChild
assert_true(body instanceof HTMLBodyElement,
"Body should be a HTMLBodyElement")
assert_equals(body.localName, "body")
assert_equals(body.tagName, "BODY")
assert_equals(body.childNodes.length, 0)
})
test(function() {
var doc = document.implementation.createHTMLDocument("test");

View File

@ -0,0 +1,25 @@
function createHTMLDocuments(checkDoc) {
var tests = [
["", "", ""],
[null, "null", "null"],
[undefined, undefined, ""],
["foo bar baz", "foo bar baz", "foo bar baz"],
["foo\t\tbar baz", "foo\t\tbar baz", "foo bar baz"],
["foo\n\nbar baz", "foo\n\nbar baz", "foo bar baz"],
["foo\f\fbar baz", "foo\f\fbar baz", "foo bar baz"],
["foo\r\rbar baz", "foo\r\rbar baz", "foo bar baz"],
]
tests.forEach(function(t, i) {
var title = t[0], expectedtitle = t[1], normalizedtitle = t[2]
test(function() {
var doc = document.implementation.createHTMLDocument(title);
checkDoc(doc, expectedtitle, normalizedtitle)
}, "createHTMLDocument test " + i + ": " + t.map(function(el) { return format_value(el) }))
})
test(function() {
var doc = document.implementation.createHTMLDocument();
checkDoc(doc, undefined, "")
}, "Missing title argument");
}

View File

@ -15,11 +15,11 @@ invalid_names.forEach(function(name) {
}, "createAttribute(" + format_value(name) + ")");
});
var tests = ["title", "TITLE"];
var tests = ["title", "TITLE", null, undefined];
tests.forEach(function(name) {
test(function() {
var attribute = document.createAttribute(name);
attr_is(attribute, "", name, null, null, name);
attr_is(attribute, "", String(name), null, null, String(name));
assert_equals(attribute.ownerElement, null);
}, "createAttribute(" + format_value(name) + ")");
});

View File

@ -0,0 +1,22 @@
function test_create(method, iface, nodeType, nodeName) {
["\u000b", "a -- b", "a-", "-b", null, undefined].forEach(function(value) {
test(function() {
var c = document[method](value);
var expected = String(value);
assert_true(c instanceof iface);
assert_true(c instanceof CharacterData);
assert_true(c instanceof Node);
assert_equals(c.ownerDocument, document);
assert_equals(c.data, expected, "data");
assert_equals(c.nodeValue, expected, "nodeValue");
assert_equals(c.textContent, expected, "textContent");
assert_equals(c.length, expected.length);
assert_equals(c.nodeType, nodeType);
assert_equals(c.nodeName, nodeName);
assert_equals(c.hasChildNodes(), false);
assert_equals(c.childNodes.length, 0);
assert_equals(c.firstChild, null);
assert_equals(c.lastChild, null);
}, method + "(" + format_value(value) + ")");
});
}

View File

@ -14,27 +14,8 @@
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-lastchild">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="Document-createComment-createTextNode.js"></script>
<div id="log"></div>
<script>
test(function() {
["\u000b", "a -- b", "a-", "-b", null, undefined].forEach(function(value) {
test(function() {
var c = document.createComment(value);
var expected = String(value);
assert_true(c instanceof Comment);
assert_true(c instanceof Node);
assert_equals(c.ownerDocument, document);
assert_equals(c.data, expected, "data");
assert_equals(c.nodeValue, expected, "nodeValue");
assert_equals(c.textContent, expected, "textContent");
assert_equals(c.length, expected.length);
assert_equals(c.nodeType, 8);
assert_equals(c.nodeName, "#comment");
assert_equals(c.hasChildNodes(), false);
assert_equals(c.childNodes.length, 0);
assert_equals(c.firstChild, null);
assert_equals(c.lastChild, null);
}, "createComment(" + format_value(value) + ")");
});
});
test_create("createComment", Comment, 8, "#comment");
</script>

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Document.createTextNode</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-document-createtextnode">
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-ownerdocument">
<link rel=help href="https://dom.spec.whatwg.org/#dom-characterdata-data">
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-nodevalue">
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-textcontent">
<link rel=help href="https://dom.spec.whatwg.org/#dom-characterdata-length">
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-nodetype">
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-haschildnodes">
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-childnodes">
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-firstchild">
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-lastchild">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="Document-createComment-createTextNode.js"></script>
<div id="log"></div>
<script>
test_create("createTextNode", Text, 3, "#text");
</script>

View File

@ -289,9 +289,9 @@
}, "where insertion order and tree order don't match");
test(function() {
let TEST_ID = "test14";
let a = document.createElement("a");
let b = document.createElement("b");
var TEST_ID = "test14";
var a = document.createElement("a");
var b = document.createElement("b");
a.appendChild(b);
b.id = TEST_ID;
assert_equals(document.getElementById(TEST_ID), null);

View File

@ -0,0 +1,11 @@
<!doctype html>
<meta charset=utf-8>
<title>Text constructor</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-text">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="Comment-Text-constructor.js"></script>
<div id="log"></div>
<script>
test_constructor("Text");
</script>

View File

@ -1,5 +1,6 @@
function attr_is(attr, v, ln, ns, p, n) {
assert_equals(attr.value, v)
assert_equals(attr.nodeValue, v)
assert_equals(attr.textContent, v)
assert_equals(attr.localName, ln)
assert_equals(attr.namespaceURI, ns)

View File

@ -0,0 +1,21 @@
<!doctype html>
<meta charset=gb18030> <!-- if the server overrides this, it is stupid, as this is a testsuite -->
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<div id=log></div>
<script>
function encode(input, output, desc) {
test(function() {
var a = document.createElement("a") // <a> uses document encoding for URL's query
a.href = "https://example.com/?" + input
assert_equals(a.search.substr(1), output) // remove leading "?"
}, "gb18030 encoder: " + desc)
}
encode("s", "s", "very basic")
encode("\u20AC", "%A2%E3", "Euro")
encode("\u4E02", "%81@", "character")
encode("\uE4C6", "%A1@", "PUA")
encode("\uE4C5", "%FE%FE", "PUA #2")
encode("\ud83d\udca9", "%949%DA3", "poo")
</script>

View File

@ -0,0 +1,21 @@
<!doctype html>
<meta charset=gbk> <!-- if the server overrides this, it is stupid, as this is a testsuite -->
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<div id=log></div>
<script>
function encode(input, output, desc) {
test(function() {
var a = document.createElement("a") // <a> uses document encoding for URL's query
a.href = "https://example.com/?" + input
assert_equals(a.search.substr(1), output) // remove leading "?"
}, "gbk encoder: " + desc)
}
encode("s", "s", "very basic")
encode("\u20AC", "%80", "Euro")
encode("\u4E02", "%81@", "character")
encode("\uE4C6", "%A1@", "PUA")
encode("\uE4C5", "%FE%FE", "PUA #2")
encode("\ud83d\udca9", "%26%23128169%3B", "poo")
</script>

View File

@ -0,0 +1,57 @@
<!doctype html>
<meta charset=utf-8>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<div id=log></div>
<script>
function decode(input, output, desc) {
test(function() {
var d = new TextDecoder("iso-2022-jp"),
buffer = new ArrayBuffer(input.length),
view = new Int8Array(buffer)
for(var i = 0, l = input.length; i < l; i++) {
view[i] = input[i]
}
assert_equals(d.decode(view), output)
}, "iso-2022-jp decoder: " + desc)
}
decode([0x1b, 0x24], "<22>$", "Error ESC")
decode([0x1b, 0x24, 0x50], "<22>$P", "Error ESC, character")
decode([0x1b, 0x28, 0x42, 0x50], "<22>P", "ASCII ESC, character")
decode([0x1b, 0x28, 0x42, 0x1b, 0x28, 0x42, 0x50], "<22><>P", "Double ASCII ESC, character")
decode([0x50, 0x1b, 0x28, 0x42, 0x50], "PP", "character, ASCII ESC, character")
decode([0x5C, 0x5D, 0x7E], "\\]~", "characters")
decode([0x0D, 0x0E, 0x0F, 0x10], "\x0D<30><44>\x10", "SO / SI")
decode([0x1b, 0x28, 0x4A, 0x5C, 0x5D, 0x7E], "¥]‾", "Roman ESC, characters")
decode([0x1b, 0x28, 0x4A, 0x0D, 0x0E, 0x0F, 0x10], "\x0D<30><44>\x10", "Roman ESC, SO / SI")
decode([0x1b, 0x28, 0x4A, 0x1b, 0x1b, 0x28, 0x49, 0x50], "<22>ミ", "Roman ESC, error ESC, Katakana ESC")
decode([0x1b, 0x28, 0x49, 0x50], "ミ", "Katakana ESC, character")
decode([0x1b, 0x28, 0x49, 0x1b, 0x24, 0x40, 0x50, 0x50], "<22>佩", "Katakana ESC, multibyte ESC, character")
decode([0x1b, 0x28, 0x49, 0x1b, 0x50], "<22>ミ", "Katakana ESC, error ESC, character")
decode([0x1b, 0x28, 0x49, 0x1b, 0x24, 0x50], "<22>、ミ", "Katakana ESC, error ESC #2, character")
decode([0x1b, 0x28, 0x49, 0x50, 0x1b, 0x28, 0x49, 0x50], "ミミ", "Katakana ESC, character, Katakana ESC, character")
decode([0x1b, 0x28, 0x49, 0x0D, 0x0E, 0x0F, 0x10], "<22><><EFBFBD><EFBFBD>", "Katakana ESC, SO / SI")
decode([0x1b, 0x24, 0x40, 0x50, 0x50], "佩", "Multibyte ESC, character")
decode([0x1b, 0x24, 0x42, 0x50, 0x50], "佩", "Multibyte ESC #2, character")
decode([0x1b, 0x24, 0x42, 0x1b, 0x50, 0x50], "<22>佩", "Multibyte ESC, error ESC, character")
decode([0x1b, 0x24, 0x40, 0x1b, 0x24, 0x40], "<22>", "Double multibyte ESC")
decode([0x1b, 0x24, 0x40, 0x1b, 0x24, 0x40, 0x50, 0x50], "<22>佩", "Double multibyte ESC, character")
decode([0x1b, 0x24, 0x40, 0x1b, 0x24, 0x42, 0x50, 0x50], "<22>佩", "Double multibyte ESC #2, character")
decode([0x1b, 0x24, 0x40, 0x1b, 0x24, 0x50, 0x50], "<22><EFBFBD>", "Multibyte ESC, error ESC #2, character")
decode([0x1b, 0x24, 0x40, 0x50, 0x1b, 0x24, 0x40, 0x50, 0x50], "<22>佩", "Multibyte ESC, single byte, multibyte ESC, character")
decode([0x1b, 0x24, 0x40, 0x20, 0x50], "<22><>", "Multibyte ESC, lead error byte")
decode([0x1b, 0x24, 0x40, 0x50, 0x20], "<22>", "Multibyte ESC, trail error byte")
decode([0x50, 0x1b], "P<>", "character, error ESC")
decode([0x50, 0x1b, 0x24], "P<>$", "character, error ESC #2")
decode([0x50, 0x1b, 0x50], "P<>P", "character, error ESC #3")
decode([0x50, 0x1b, 0x28, 0x42], "P", "character, ASCII ESC")
decode([0x50, 0x1b, 0x28, 0x4A], "P", "character, Roman ESC")
decode([0x50, 0x1b, 0x28, 0x49], "P", "character, Katakana ESC")
decode([0x50, 0x1b, 0x24, 0x40], "P", "character, Multibyte ESC")
decode([0x50, 0x1b, 0x24, 0x42], "P", "character, Multibyte ESC #2")
</script>

View File

@ -0,0 +1,18 @@
<!doctype html>
<meta charset=iso-2022-jp> <!-- if the server overrides this, it is stupid, as this is a testsuite -->
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<div id=log></div>
<script>
function encode(input, output, desc) {
test(function() {
var a = document.createElement("a") // <a> uses document encoding for URL's query
a.href = "https://example.com/?" + input
assert_equals(a.search.substr(1), output) // remove leading "?"
}, "iso-2022-jp encoder: " + desc)
}
encode("s", "s", "very basic")
encode("\u00A5\u203Es\\\uFF90\u4F69", "%1B(J\\~s%1B(B\\%1B$B%_PP%1B(B", "basics")
encode("\x0E\x0F\x1Bx", "%0E%0F%1Bx", "SO/SI ESC")
</script>

View File

@ -0,0 +1,3 @@
def main(request, response):
response.headers.set("Content-Type", "text/plain;charset=" + request.GET.first("label"))
response.content = "".join(chr(byte) for byte in xrange(255))

View File

@ -0,0 +1,176 @@
<!doctype html>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<div id=log></div>
<script>
// https://encoding.spec.whatwg.org/encodings.json
var singleByteEncodings = [{
"labels": [ "866", "cp866", "csibm866", "ibm866" ],
"name": "ibm866"
},{
"labels": [ "csisolatin2", "iso-8859-2", "iso-ir-101", "iso8859-2", "iso88592", "iso_8859-2", "iso_8859-2:1987", "l2", "latin2" ],
"name": "iso-8859-2"
},{
"labels": [ "csisolatin3", "iso-8859-3", "iso-ir-109", "iso8859-3", "iso88593", "iso_8859-3", "iso_8859-3:1988", "l3", "latin3" ],
"name": "iso-8859-3"
},{
"labels": [ "csisolatin4", "iso-8859-4", "iso-ir-110", "iso8859-4", "iso88594", "iso_8859-4", "iso_8859-4:1988", "l4", "latin4" ],
"name": "iso-8859-4"
},{
"labels": [ "csisolatincyrillic", "cyrillic", "iso-8859-5", "iso-ir-144", "iso8859-5", "iso88595", "iso_8859-5", "iso_8859-5:1988" ],
"name": "iso-8859-5"
},{
"labels": [ "arabic", "asmo-708", "csiso88596e", "csiso88596i", "csisolatinarabic", "ecma-114", "iso-8859-6", "iso-8859-6-e", "iso-8859-6-i", "iso-ir-127", "iso8859-6", "iso88596", "iso_8859-6", "iso_8859-6:1987" ],
"name": "iso-8859-6"
},{
"labels": [ "csisolatingreek", "ecma-118", "elot_928", "greek", "greek8", "iso-8859-7", "iso-ir-126", "iso8859-7", "iso88597", "iso_8859-7", "iso_8859-7:1987", "sun_eu_greek" ],
"name": "iso-8859-7"
},{
"labels": [ "csiso88598e", "csisolatinhebrew", "hebrew", "iso-8859-8", "iso-8859-8-e", "iso-ir-138", "iso8859-8", "iso88598", "iso_8859-8", "iso_8859-8:1988", "visual" ],
"name": "iso-8859-8"
},{
"labels": [ "csiso88598i", "iso-8859-8-i", "logical" ],
"name": "iso-8859-8-i"
},{
"labels": [ "csisolatin6", "iso-8859-10", "iso-ir-157", "iso8859-10", "iso885910", "l6", "latin6" ],
"name": "iso-8859-10"
},{
"labels": [ "iso-8859-13", "iso8859-13", "iso885913" ],
"name": "iso-8859-13"
},{
"labels": [ "iso-8859-14", "iso8859-14", "iso885914" ],
"name": "iso-8859-14"
},{
"labels": [ "csisolatin9", "iso-8859-15", "iso8859-15", "iso885915", "iso_8859-15", "l9" ],
"name": "iso-8859-15"
},{
"labels": [ "iso-8859-16" ],
"name": "iso-8859-16"
},{
"labels": [ "cskoi8r", "koi", "koi8", "koi8-r", "koi8_r" ],
"name": "koi8-r"
},{
"labels": [ "koi8-u" ],
"name": "koi8-u"
},{
"labels": [ "csmacintosh", "mac", "macintosh", "x-mac-roman" ],
"name": "macintosh"
},{
"labels": [ "dos-874", "iso-8859-11", "iso8859-11", "iso885911", "tis-620", "windows-874" ],
"name": "windows-874"
},{
"labels": [ "cp1250", "windows-1250", "x-cp1250" ],
"name": "windows-1250"
},{
"labels": [ "cp1251", "windows-1251", "x-cp1251" ],
"name": "windows-1251"
},{
"labels": [ "ansi_x3.4-1968", "ascii", "cp1252", "cp819", "csisolatin1", "ibm819", "iso-8859-1", "iso-ir-100", "iso8859-1", "iso88591", "iso_8859-1", "iso_8859-1:1987", "l1", "latin1", "us-ascii", "windows-1252", "x-cp1252" ],
"name": "windows-1252"
},{
"labels": [ "cp1253", "windows-1253", "x-cp1253" ],
"name": "windows-1253"
},{
"labels": [ "cp1254", "csisolatin5", "iso-8859-9", "iso-ir-148", "iso8859-9", "iso88599", "iso_8859-9", "iso_8859-9:1989", "l5", "latin5", "windows-1254", "x-cp1254" ],
"name": "windows-1254"
},{
"labels": [ "cp1255", "windows-1255", "x-cp1255" ],
"name": "windows-1255"
},{
"labels": [ "cp1256", "windows-1256", "x-cp1256" ],
"name": "windows-1256"
},{
"labels": [ "cp1257", "windows-1257", "x-cp1257" ],
"name": "windows-1257"
},{
"labels": [ "cp1258", "windows-1258", "x-cp1258" ],
"name": "windows-1258"
},{
"labels": [ "x-mac-cyrillic", "x-mac-ukrainian" ],
"name": "x-mac-cyrillic"
}],
// https://encoding.spec.whatwg.org/indexes.json
singleByteIndexes = {
"ibm866":[1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,9617,9618,9619,9474,9508,9569,9570,9558,9557,9571,9553,9559,9565,9564,9563,9488,9492,9524,9516,9500,9472,9532,9566,9567,9562,9556,9577,9574,9568,9552,9580,9575,9576,9572,9573,9561,9560,9554,9555,9579,9578,9496,9484,9608,9604,9612,9616,9600,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1025,1105,1028,1108,1031,1111,1038,1118,176,8729,183,8730,8470,164,9632,160],
"iso-8859-2":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,260,728,321,164,317,346,167,168,352,350,356,377,173,381,379,176,261,731,322,180,318,347,711,184,353,351,357,378,733,382,380,340,193,194,258,196,313,262,199,268,201,280,203,282,205,206,270,272,323,327,211,212,336,214,215,344,366,218,368,220,221,354,223,341,225,226,259,228,314,263,231,269,233,281,235,283,237,238,271,273,324,328,243,244,337,246,247,345,367,250,369,252,253,355,729],
"iso-8859-3":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,294,728,163,164,null,292,167,168,304,350,286,308,173,null,379,176,295,178,179,180,181,293,183,184,305,351,287,309,189,null,380,192,193,194,null,196,266,264,199,200,201,202,203,204,205,206,207,null,209,210,211,212,288,214,215,284,217,218,219,220,364,348,223,224,225,226,null,228,267,265,231,232,233,234,235,236,237,238,239,null,241,242,243,244,289,246,247,285,249,250,251,252,365,349,729],
"iso-8859-4":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,260,312,342,164,296,315,167,168,352,274,290,358,173,381,175,176,261,731,343,180,297,316,711,184,353,275,291,359,330,382,331,256,193,194,195,196,197,198,302,268,201,280,203,278,205,206,298,272,325,332,310,212,213,214,215,216,370,218,219,220,360,362,223,257,225,226,227,228,229,230,303,269,233,281,235,279,237,238,299,273,326,333,311,244,245,246,247,248,371,250,251,252,361,363,729],
"iso-8859-5":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,173,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,8470,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,167,1118,1119],
"iso-8859-6":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,null,null,null,164,null,null,null,null,null,null,null,1548,173,null,null,null,null,null,null,null,null,null,null,null,null,null,1563,null,null,null,1567,null,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,null,null,null,null,null,1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,1614,1615,1616,1617,1618,null,null,null,null,null,null,null,null,null,null,null,null,null],
"iso-8859-7":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,8216,8217,163,8364,8367,166,167,168,169,890,171,172,173,null,8213,176,177,178,179,900,901,902,183,904,905,906,187,908,189,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,null,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,null],
"iso-8859-8":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,null,162,163,164,165,166,167,168,169,215,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,247,187,188,189,190,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,8215,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,null,null,8206,8207,null],
"iso-8859-10":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,260,274,290,298,296,310,167,315,272,352,358,381,173,362,330,176,261,275,291,299,297,311,183,316,273,353,359,382,8213,363,331,256,193,194,195,196,197,198,302,268,201,280,203,278,205,206,207,208,325,332,211,212,213,214,360,216,370,218,219,220,221,222,223,257,225,226,227,228,229,230,303,269,233,281,235,279,237,238,239,240,326,333,243,244,245,246,361,248,371,250,251,252,253,254,312],
"iso-8859-13":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,8221,162,163,164,8222,166,167,216,169,342,171,172,173,174,198,176,177,178,179,8220,181,182,183,248,185,343,187,188,189,190,230,260,302,256,262,196,197,280,274,268,201,377,278,290,310,298,315,352,323,325,211,332,213,214,215,370,321,346,362,220,379,381,223,261,303,257,263,228,229,281,275,269,233,378,279,291,311,299,316,353,324,326,243,333,245,246,247,371,322,347,363,252,380,382,8217],
"iso-8859-14":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,7682,7683,163,266,267,7690,167,7808,169,7810,7691,7922,173,174,376,7710,7711,288,289,7744,7745,182,7766,7809,7767,7811,7776,7923,7812,7813,7777,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,372,209,210,211,212,213,214,7786,216,217,218,219,220,221,374,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,373,241,242,243,244,245,246,7787,248,249,250,251,252,253,375,255],
"iso-8859-15":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,8364,165,352,167,353,169,170,171,172,173,174,175,176,177,178,179,381,181,182,183,382,185,186,187,338,339,376,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255],
"iso-8859-16":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,260,261,321,8364,8222,352,167,353,169,536,171,377,173,378,379,176,177,268,322,381,8221,182,183,382,269,537,187,338,339,376,380,192,193,194,258,196,262,198,199,200,201,202,203,204,205,206,207,272,323,210,211,212,336,214,346,368,217,218,219,220,280,538,223,224,225,226,259,228,263,230,231,232,233,234,235,236,237,238,239,273,324,242,243,244,337,246,347,369,249,250,251,252,281,539,255],
"koi8-r":[9472,9474,9484,9488,9492,9496,9500,9508,9516,9524,9532,9600,9604,9608,9612,9616,9617,9618,9619,8992,9632,8729,8730,8776,8804,8805,160,8993,176,178,183,247,9552,9553,9554,1105,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,1025,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,169,1102,1072,1073,1094,1076,1077,1092,1075,1093,1080,1081,1082,1083,1084,1085,1086,1087,1103,1088,1089,1090,1091,1078,1074,1100,1099,1079,1096,1101,1097,1095,1098,1070,1040,1041,1062,1044,1045,1060,1043,1061,1048,1049,1050,1051,1052,1053,1054,1055,1071,1056,1057,1058,1059,1046,1042,1068,1067,1047,1064,1069,1065,1063,1066],
"koi8-u":[9472,9474,9484,9488,9492,9496,9500,9508,9516,9524,9532,9600,9604,9608,9612,9616,9617,9618,9619,8992,9632,8729,8730,8776,8804,8805,160,8993,176,178,183,247,9552,9553,9554,1105,1108,9556,1110,1111,9559,9560,9561,9562,9563,1169,9565,9566,9567,9568,9569,1025,1028,9571,1030,1031,9574,9575,9576,9577,9578,1168,9580,169,1102,1072,1073,1094,1076,1077,1092,1075,1093,1080,1081,1082,1083,1084,1085,1086,1087,1103,1088,1089,1090,1091,1078,1074,1100,1099,1079,1096,1101,1097,1095,1098,1070,1040,1041,1062,1044,1045,1060,1043,1061,1048,1049,1050,1051,1052,1053,1054,1055,1071,1056,1057,1058,1059,1046,1042,1068,1067,1047,1064,1069,1065,1063,1066],
"macintosh":[196,197,199,201,209,214,220,225,224,226,228,227,229,231,233,232,234,235,237,236,238,239,241,243,242,244,246,245,250,249,251,252,8224,176,162,163,167,8226,182,223,174,169,8482,180,168,8800,198,216,8734,177,8804,8805,165,181,8706,8721,8719,960,8747,170,186,937,230,248,191,161,172,8730,402,8776,8710,171,187,8230,160,192,195,213,338,339,8211,8212,8220,8221,8216,8217,247,9674,255,376,8260,8364,8249,8250,64257,64258,8225,183,8218,8222,8240,194,202,193,203,200,205,206,207,204,211,212,63743,210,218,219,217,305,710,732,175,728,729,730,184,733,731,711],
"windows-874":[8364,129,130,131,132,8230,134,135,136,137,138,139,140,141,142,143,144,8216,8217,8220,8221,8226,8211,8212,152,153,154,155,156,157,158,159,160,3585,3586,3587,3588,3589,3590,3591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606,3607,3608,3609,3610,3611,3612,3613,3614,3615,3616,3617,3618,3619,3620,3621,3622,3623,3624,3625,3626,3627,3628,3629,3630,3631,3632,3633,3634,3635,3636,3637,3638,3639,3640,3641,3642,null,null,null,null,3647,3648,3649,3650,3651,3652,3653,3654,3655,3656,3657,3658,3659,3660,3661,3662,3663,3664,3665,3666,3667,3668,3669,3670,3671,3672,3673,3674,3675,null,null,null,null],
"windows-1250":[8364,129,8218,131,8222,8230,8224,8225,136,8240,352,8249,346,356,381,377,144,8216,8217,8220,8221,8226,8211,8212,152,8482,353,8250,347,357,382,378,160,711,728,321,164,260,166,167,168,169,350,171,172,173,174,379,176,177,731,322,180,181,182,183,184,261,351,187,317,733,318,380,340,193,194,258,196,313,262,199,268,201,280,203,282,205,206,270,272,323,327,211,212,336,214,215,344,366,218,368,220,221,354,223,341,225,226,259,228,314,263,231,269,233,281,235,283,237,238,271,273,324,328,243,244,337,246,247,345,367,250,369,252,253,355,729],
"windows-1251":[1026,1027,8218,1107,8222,8230,8224,8225,8364,8240,1033,8249,1034,1036,1035,1039,1106,8216,8217,8220,8221,8226,8211,8212,152,8482,1113,8250,1114,1116,1115,1119,160,1038,1118,1032,164,1168,166,167,1025,169,1028,171,172,173,174,1031,176,177,1030,1110,1169,181,182,183,1105,8470,1108,187,1112,1029,1109,1111,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103],
"windows-1252":[8364,129,8218,402,8222,8230,8224,8225,710,8240,352,8249,338,141,381,143,144,8216,8217,8220,8221,8226,8211,8212,732,8482,353,8250,339,157,382,376,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255],
"windows-1253":[8364,129,8218,402,8222,8230,8224,8225,136,8240,138,8249,140,141,142,143,144,8216,8217,8220,8221,8226,8211,8212,152,8482,154,8250,156,157,158,159,160,901,902,163,164,165,166,167,168,169,null,171,172,173,174,8213,176,177,178,179,900,181,182,183,904,905,906,187,908,189,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,null,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,null],
"windows-1254":[8364,129,8218,402,8222,8230,8224,8225,710,8240,352,8249,338,141,142,143,144,8216,8217,8220,8221,8226,8211,8212,732,8482,353,8250,339,157,158,376,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,286,209,210,211,212,213,214,215,216,217,218,219,220,304,350,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,287,241,242,243,244,245,246,247,248,249,250,251,252,305,351,255],
"windows-1255":[8364,129,8218,402,8222,8230,8224,8225,710,8240,138,8249,140,141,142,143,144,8216,8217,8220,8221,8226,8211,8212,732,8482,154,8250,156,157,158,159,160,161,162,163,8362,165,166,167,168,169,215,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,247,187,188,189,190,191,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,null,1467,1468,1469,1470,1471,1472,1473,1474,1475,1520,1521,1522,1523,1524,null,null,null,null,null,null,null,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,null,null,8206,8207,null],
"windows-1256":[8364,1662,8218,402,8222,8230,8224,8225,710,8240,1657,8249,338,1670,1688,1672,1711,8216,8217,8220,8221,8226,8211,8212,1705,8482,1681,8250,339,8204,8205,1722,160,1548,162,163,164,165,166,167,168,169,1726,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,1563,187,188,189,190,1567,1729,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,215,1591,1592,1593,1594,1600,1601,1602,1603,224,1604,226,1605,1606,1607,1608,231,232,233,234,235,1609,1610,238,239,1611,1612,1613,1614,244,1615,1616,247,1617,249,1618,251,252,8206,8207,1746],
"windows-1257":[8364,129,8218,131,8222,8230,8224,8225,136,8240,138,8249,140,168,711,184,144,8216,8217,8220,8221,8226,8211,8212,152,8482,154,8250,156,175,731,159,160,null,162,163,164,null,166,167,216,169,342,171,172,173,174,198,176,177,178,179,180,181,182,183,248,185,343,187,188,189,190,230,260,302,256,262,196,197,280,274,268,201,377,278,290,310,298,315,352,323,325,211,332,213,214,215,370,321,346,362,220,379,381,223,261,303,257,263,228,229,281,275,269,233,378,279,291,311,299,316,353,324,326,243,333,245,246,247,371,322,347,363,252,380,382,729],
"windows-1258":[8364,129,8218,402,8222,8230,8224,8225,710,8240,138,8249,338,141,142,143,144,8216,8217,8220,8221,8226,8211,8212,732,8482,154,8250,339,157,158,376,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,258,196,197,198,199,200,201,202,203,768,205,206,207,272,209,777,211,212,416,214,215,216,217,218,219,220,431,771,223,224,225,226,259,228,229,230,231,232,233,234,235,769,237,238,239,273,241,803,243,244,417,246,247,248,249,250,251,252,432,8363,255],
"x-mac-cyrillic":[1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,8224,176,1168,163,167,8226,182,1030,174,169,8482,1026,1106,8800,1027,1107,8734,177,8804,8805,1110,181,1169,1032,1028,1108,1031,1111,1033,1113,1034,1114,1112,1029,172,8730,402,8776,8710,171,187,8230,160,1035,1115,1036,1116,1109,8211,8212,8220,8221,8216,8217,247,8222,1038,1118,1039,1119,8470,1025,1105,1103,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,8364]
}
// For TextDecoder tests
var buffer = ArrayBuffer(255),
view = Uint8Array(buffer)
for(var i = 0, l = view.byteLength; i < l; i++) {
view[i] = i
}
// For XMLHttpRequest and TextDecoder tests
function assert_decode(data, encoding) {
if(encoding == "iso-8859-8-i") {
encoding = "iso-8859-8"
}
for(var i = 0, l = data.length; i < l; i++) {
var cp = data.charCodeAt(i),
expectedCp = (i < 0x80) ? i : singleByteIndexes[encoding][i-0x80]
if(expectedCp == null) {
expectedCp = 0xFFFD
}
assert_equals(cp, expectedCp, encoding + ":" + i)
}
}
// Setting up all the tests
for(var i = 0, l = singleByteEncodings.length; i < l; i++) {
var encoding = singleByteEncodings[i]
for(var ii = 0, ll = encoding.labels.length; ii < ll; ii++) {
var label = encoding.labels[ii]
async_test(function(t) {
var xhr = new XMLHttpRequest,
name = encoding.name // need scoped variable
xhr.open("GET", "resources/single-byte-raw.py?label=" + label)
xhr.send(null)
xhr.onload = t.step_func_done(function() { assert_decode(xhr.responseText, name) })
}, encoding.name + ": " + label + " (XMLHttpRequest)")
test(function() {
var d = new TextDecoder(label),
data = d.decode(view)
assert_equals(d.encoding, encoding.name)
assert_decode(data, encoding.name)
}, encoding.name + ": " + label + " (TextDecoder)")
async_test(function(t) {
var frame = document.createElement("iframe"),
name = encoding.name
frame.src = "resources/single-byte-raw.py?label=" + label
frame.onload = t.step_func_done(function() { assert_equals(frame.contentDocument.characterSet, name) })
t.add_cleanup(function() { document.body.removeChild(frame) })
document.body.appendChild(frame)
}, encoding.name + ": " + label + " (document.characterSet)")
}
}
</script>

View File

@ -2,25 +2,10 @@
<title>Document.title and DOMImplementation.createHTMLDocument</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/dom/nodes/DOMImplementation-createHTMLDocument.js"></script>
<div id="log"></div>
<script>
function checkDoc(title, expectedtitle, normalizedtitle) {
test(function() {
var doc = document.implementation.createHTMLDocument(title);
assert_equals(doc.title, normalizedtitle)
})
}
checkDoc("", "", "")
checkDoc(null, "null", "null")
checkDoc(undefined, "", "")
checkDoc("foo bar baz", "foo bar baz", "foo bar baz")
checkDoc("foo\t\tbar baz", "foo\t\tbar baz", "foo bar baz")
checkDoc("foo\n\nbar baz", "foo\n\nbar baz", "foo bar baz")
checkDoc("foo\f\fbar baz", "foo\f\fbar baz", "foo bar baz")
checkDoc("foo\r\rbar baz", "foo\r\rbar baz", "foo bar baz")
test(function() {
var doc = document.implementation.createHTMLDocument()
assert_equals(doc.title, "")
}, "Missing title argument");
createHTMLDocuments(function(doc, expectedtitle, normalizedtitle) {
assert_equals(doc.title, normalizedtitle)
})
</script>

View File

@ -9,12 +9,12 @@
onload = function() {
var ifr = document.getElementsByTagName('iframe')[0];
ifr.contentDocument.body.appendChild(ifr.contentDocument.createElement('p')).textContent = 'Modified document';
setTimeout(function () {
document.getElementById('target').appendChild(ifr);
setTimeout(function() {
setTimeout(function() {
ifr.onload = function() {
assert_equals(ifr.contentDocument.body.textContent.indexOf('Modified'), -1);
done();
}, 100);
};
document.getElementById('target').appendChild(ifr);
}, 100);
}
</script>

View File

@ -12,11 +12,11 @@ onload = function() {
ifr.contentDocument.write('Modified document');
ifr.contentDocument.close();
setTimeout(function() {
document.getElementById('target').appendChild(ifr);
setTimeout(function() {
ifr.onload = function() {
assert_equals(ifr.contentDocument.body.textContent.indexOf('Modified'), -1);
done();
}, 100);
};
document.getElementById('target').appendChild(ifr);
}, 100);
}
</script>

View File

@ -10,11 +10,11 @@ onload = function() {
var ifr = document.getElementsByTagName('iframe')[0];
ifr.contentDocument.body.appendChild(ifr.contentDocument.createElement('p')).textContent = 'Modified document';
setTimeout(function() {
document.getElementById('target').appendChild(ifr);
setTimeout(function() {
ifr.onload = function() {
assert_equals(ifr.contentDocument.body.textContent.indexOf('Modified'), -1);
done();
}, 100);
};
document.getElementById('target').appendChild(ifr);
}, 100);
}
</script>

View File

@ -11,12 +11,12 @@ onload = function(){
ifr.contentDocument.open();
ifr.contentDocument.write('Modified document');
ifr.contentDocument.close();
setTimeout(function () {
document.getElementById('target').appendChild(ifr);
setTimeout(function () {
setTimeout(function() {
ifr.onload = function () {
assert_equals(ifr.contentDocument.body.textContent.indexOf('Modified'), -1);
done();
}, 100);
};
document.getElementById('target').appendChild(ifr);
}, 100);
}
</script>

View File

@ -10,7 +10,6 @@
<div id="log"></div>
<script>
var video = document.createElement('video');
var contents = {'/media/white.webm': 'video/webm; codecs="vorbis,vp8"',
'/media/white.mp4' : 'video/mp4'};
@ -49,13 +48,15 @@ function mediaTest(file, mime) {
mediaSource.addEventListener('sourceopen', function(e) {
sourceBuffer = mediaSource.addSourceBuffer(mime);
mediaSource.endOfStream();
assert_equals(mediaSource.readyState, 'ended',
'mediaSource.readyState is "ended" after endOfStream()');
});
mediaSource.addEventListener('sourceclose', function(e) {
mediaSource.addEventListener('sourceended', t.step_func_done(function(e) {
assert_throws({name: 'InvalidStateError'}, function() {
sourceBuffer.abort();
});
t.done();
});
}));
var video = document.createElement('video');
video.src = window.URL.createObjectURL(mediaSource);
});
}, 'SourceBuffer#abort() (' + mime + ') : If the readyState attribute ' +

View File

@ -10,7 +10,6 @@
<div id="log"></div>
<script>
var video = document.createElement('video');
var mimes = ['video/webm; codecs="vorbis,vp8"', 'video/mp4'];
//check the browser supports the MIME used in this test
@ -30,18 +29,16 @@ function mediaTest(mime) {
return;
}
var mediaSource = new MediaSource();
mediaSource.addEventListener('sourceopen', function(e) {
mediaSource.addEventListener('sourceopen', t.step_func_done(function(e) {
var sourceBuffer = mediaSource.addSourceBuffer(mime);
mediaSource.removeSourceBuffer(sourceBuffer);
t.step(function() {
assert_throws({name: 'InvalidStateError'},
function() {
sourceBuffer.abort();
},
'SourceBuffer#abort() after removing the SourceBuffer object');
});
t.done();
}, false);
assert_throws({name: 'InvalidStateError'},
function() {
sourceBuffer.abort();
},
'SourceBuffer#abort() after removing the SourceBuffer object');
}), false);
var video = document.createElement('video');
video.src = window.URL.createObjectURL(mediaSource);
}, 'SourceBuffer#abort (' + mime + ') : ' +
'if this object has been removed from the sourceBuffers attribute of the parent media source, ' +

View File

@ -10,7 +10,6 @@
<div id="log"></div>
<script>
var video = document.createElement('video');
var contents = {'/media/white.webm': 'video/webm; codecs="vorbis,vp8"',
'/media/white.mp4' : 'video/mp4'};
@ -47,26 +46,22 @@ function mediaTest(file, mime) {
var mediaSource = new MediaSource();
var num_updateend = 0;
var events = [];
mediaSource.addEventListener('sourceopen', function(e) {
mediaSource.addEventListener('sourceopen', t.step_func(function(e) {
var sourceBuffer = mediaSource.addSourceBuffer(mime);
t.step(function() {
assert_equals(sourceBuffer.updating, false);
});
sourceBuffer.addEventListener('updatestart', function(e) {
assert_equals(sourceBuffer.updating, false);
sourceBuffer.addEventListener('updatestart', t.step_func(function(e) {
events.push('updatestart');
//abort when sourceBuffer#updating is true
sourceBuffer.abort();
t.step(function() {
assert_equals(sourceBuffer.updating, false,
'Check updating value after calling abort.');
assert_equals(sourceBuffer.appendWindowStart, 0);
assert_equals(sourceBuffer.appendWindowEnd, Number.POSITIVE_INFINITY);
});
});
sourceBuffer.addEventListener('update', function(e) {
assert_equals(sourceBuffer.updating, false,
'Check updating value after calling abort.');
assert_equals(sourceBuffer.appendWindowStart, 0);
assert_equals(sourceBuffer.appendWindowEnd, Number.POSITIVE_INFINITY);
}));
sourceBuffer.addEventListener('update', t.step_func(function(e) {
assert_unreached("Can't touch this");
});
}));
sourceBuffer.addEventListener('updateend', function(e) {
events.push('updateend');
mediaSource.endOfStream();
@ -74,19 +69,17 @@ function mediaTest(file, mime) {
sourceBuffer.addEventListener('abort', function(e) {
events.push('abort');
});
sourceBuffer.addEventListener('error', function(e) {
sourceBuffer.addEventListener('error', t.step_func(function(e) {
assert_unreached("Can't touch this");
});
}));
sourceBuffer.appendBuffer(data);
});
mediaSource.addEventListener('sourceended', function(e) {
t.step(function() {
assert_array_equals(events,
['updatestart', 'abort', 'updateend'],
'Check the sequence of fired events.');
});
t.done();
});
}));
mediaSource.addEventListener('sourceended', t.step_func_done(function(e) {
assert_array_equals(events,
['updatestart', 'abort', 'updateend'],
'Check the sequence of fired events.');
}));
var video = document.createElement('video');
video.src = window.URL.createObjectURL(mediaSource);
});
}, 'SourceBuffer#abort() (' + mime + ') : Check the algorithm when the updating attribute is true.');

View File

@ -10,40 +10,24 @@
<div id="log"></div>
<script>
var video = document.createElement('video');
var mimes = ['video/webm; codecs="vorbis,vp8"', 'video/mp4'];
//check the browser supports the MIME used in this test
function isTypeSupported(mime) {
if(!MediaSource.isTypeSupported(mime)) {
this.step(function() {
assert_unreached("Browser doesn't support the MIME used in this test: " + mime);
});
this.done();
return false;
}
return true;
}
function mediaTest(mime) {
async_test(function(t) {
if(!isTypeSupported.bind(t)(mime)) {
return;
}
mimes.forEach(function(mime) {
async_test(function() {
assert_true(MediaSource.isTypeSupported(mime),
"Browser doesn't support the MIME used in this test: " + mime);
var mediaSource = new MediaSource();
mediaSource.addEventListener('sourceopen', function(e) {
mediaSource.addEventListener('sourceopen', this.step_func_done(function(e) {
var sourceBuffer = mediaSource.addSourceBuffer(mime);
sourceBuffer.abort();
t.step(function() {
assert_equals(sourceBuffer.appendWindowStart, 0);
assert_equals(sourceBuffer.appendWindowEnd, Number.POSITIVE_INFINITY);
});
t.done();
});
assert_equals(sourceBuffer.appendWindowStart, 0);
assert_equals(sourceBuffer.appendWindowEnd, Number.POSITIVE_INFINITY);
}));
var video = document.createElement('video');
video.src = window.URL.createObjectURL(mediaSource);
}, 'SourceBuffer#abort() (' + mime + '): Check the values of appendWindowStart and appendWindowEnd.');
}
mimes.forEach(function(mime) {
mediaTest(mime);
});
</script>
</body>

View File

@ -15,7 +15,7 @@
<ol>
<li> Put your mouse over the lower rectangle. pointerover should be received for the purple rectangle
<li> Press and hold left mouse button over "Set Capture" button
<li> Put your mouse over the lower rectangle. pointerover should be received for the black rectangle
<li> Put your mouse over the upper rectangle. pointerover should be received for the black rectangle
<li> Release left mouse button to complete the test.
</ol>
</h4>

View File

@ -1,5 +1,5 @@
def main(request, response):
response.headers.extend([('Transfer-Encoding', 'chunked'),
response.headers.update([('Transfer-Encoding', 'chunked'),
('Content-Type', 'text/html'),
('Connection', 'keep-alive')])
response.write_status_headers()

View File

@ -426,6 +426,9 @@ IdlArray.prototype.assert_type_is = function(value, type)
return;
case "DOMString":
case "ByteString":
case "USVString":
// TODO: https://github.com/w3c/testharness.js/issues/92
assert_equals(typeof value, "string");
return;
@ -1798,6 +1801,8 @@ function create_suitable_object(type)
return 7;
case "DOMString":
case "ByteString":
case "USVString":
return "foo";
case "object":

View File

@ -16,7 +16,8 @@ To use testharness.js you must include two scripts, in the order given:
## Full documentation ##
Full documentation of the API is kept in the source of testharness.js.
Full user documentation for the API is in the
[docs/api.md](https://github.com/w3c/testharness.js/blob/master/docs/api.md) file.
You can also read a tutorial on
[Using testharness.js](http://darobin.github.com/test-harness-tutorial/docs/using-testharness.html).

View File

@ -0,0 +1,87 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>Selectors-API Level 2 Test Suite: HTML with Selectors Level 3</title>
<!-- Selectors API Test Suite Version 3 -->
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/dom/nodes/selectors.js"></script>
<script src="level2-lib.js"></script>
<script src="Element-matches.js"></script>
<style>iframe { visibility: hidden; position: absolute; }</style>
<div id="log">This test requires JavaScript.</div>
<script>
var docType = "html"; // Only run tests suitable for HTML
var frame = document.createElement("iframe"),
doc;
frame.onload = init;
frame.src = "/dom/nodes/ParentNode-querySelector-All-content.html#target";
document.body.appendChild(frame);
function init() {
/*
* This test suite tests Selectors API methods in 4 different contexts:
* 1. Document node
* 2. In-document Element node
* 3. Detached Element node (an element with no parent, not in the document)
* 4. Document Fragment node
*
* For each context, the following tests are run:
*
* The interface check tests ensure that each type of node exposes the Selectors API methods.
*
* The matches() tests are run
* All the selectors tested for both the valid and invalid selector tests are found in selectors.js.
* See comments in that file for documentation of the format used.
*
* The level2-lib.js file contains all the common test functions for running each of the aforementioned tests
*/
// Prepare the nodes for testing
doc = frame.contentDocument; // Document Node tests
var element = doc.getElementById("root"); // In-document Element Node tests
//Setup the namespace tests
setupSpecialElements(element);
var outOfScope = element.cloneNode(true); // Append this to the body before running the in-document
// Element tests, but after running the Document tests. This
// tests that no elements that are not descendants of element
// are selected.
traverse(outOfScope, function(elem) { // Annotate each element as being a clone; used for verifying
elem.setAttribute("data-clone", ""); // that none of these elements ever match.
});
var detached = element.cloneNode(true); // Detached Element Node tests
var fragment = doc.createDocumentFragment(); // Fragment Node tests
fragment.appendChild(element.cloneNode(true));
// Setup Tests
interfaceCheckMatches("Document", doc);
interfaceCheckMatches("Detached Element", detached);
interfaceCheckMatches("Fragment", fragment);
interfaceCheckMatches("In-document Element", element);
runSpecialMatchesTests("DIV Element", element);
runSpecialMatchesTests("NULL Element", document.createElement("null"));
runSpecialMatchesTests("UNDEFINED Element", document.createElement("undefined"));
runInvalidSelectorTestMatches("Document", doc, invalidSelectors);
runInvalidSelectorTestMatches("Detached Element", detached, invalidSelectors);
runInvalidSelectorTestMatches("Fragment", fragment, invalidSelectors);
runInvalidSelectorTestMatches("In-document Element", element, invalidSelectors);
runMatchesTest("In-document", doc, validSelectors, "html");
runMatchesTest("Detached", detached, validSelectors, "html");
runMatchesTest("Fragment", fragment, validSelectors, "html");
runMatchesTest("In-document", doc, scopedSelectors, "html");
}
</script>

View File

@ -0,0 +1,127 @@
/*
* Check that the matches() method exists on the given Node
*/
function interfaceCheckMatches(type, obj) {
if (obj.nodeType === obj.ELEMENT_NODE) {
test(function() {
assert_idl_attribute(obj, "matches", type + " supports matches");
}, type + " supports matches")
}
}
function runSpecialMatchesTests(type, element) {
test(function() { // 1
if (element.tagName.toLowerCase() === "null") {
assert_true(element.matches(null), "An element with the tag name '" + element.tagName.toLowerCase() + "' should match.");
} else {
assert_false(element.matches(null), "An element with the tag name '" + element.tagName.toLowerCase() + "' should not match.");
}
}, type + ".matches(null)")
test(function() { // 2
if (element.tagName.toLowerCase() === "undefined") {
assert_true(element.matches(undefined), "An element with the tag name '" + element.tagName.toLowerCase() + "' should match.");
} else {
assert_false(element.matches(undefined), "An element with the tag name '" + element.tagName.toLowerCase() + "' should not match.");
}
}, type + ".matches(undefined)")
test(function() { // 3
assert_throws(TypeError(), function() {
element.matches();
}, "This should throw a TypeError.")
}, type + ".matches no parameter")
}
/*
* Execute queries with the specified invalid selectors for matches()
* Only run these tests when errors are expected. Don't run for valid selector tests.
*/
function runInvalidSelectorTestMatches(type, root, selectors) {
if (root.nodeType === root.ELEMENT_NODE) {
for (var i = 0; i < selectors.length; i++) {
var s = selectors[i];
var n = s["name"];
var q = s["selector"];
test(function() {
assert_throws("SyntaxError", function() {
root.matches(q)
})
}, type + ".matches: " + n + ": " + q);
}
}
}
function runMatchesTest(type, root, selectors, docType) {
var nodeType = getNodeType(root);
for (var i = 0; i < selectors.length; i++) {
var s = selectors[i];
var n = s["name"];
var q = s["selector"];
var e = s["expect"];
var u = s["unexpected"];
var ctx = s["ctx"];
var ref = s["ref"];
if ((!s["exclude"] || (s["exclude"].indexOf(nodeType) === -1 && s["exclude"].indexOf(docType) === -1))
&& (s["testType"] & TEST_MATCH) ) {
if (ctx && !ref) {
test(function() {
var j, element, refNode;
for (j = 0; j < e.length; j++) {
element = root.querySelector("#" + e[j]);
refNode = root.querySelector(ctx);
assert_true(element.matches(q, refNode), "The element #" + e[j] + " should match the selector.")
}
if (u) {
for (j = 0; j < u.length; j++) {
element = root.querySelector("#" + u[j]);
refNode = root.querySelector(ctx);
assert_false(element.matches(q, refNode), "The element #" + u[j] + " should not match the selector.")
}
}
}, type + " Element.matches: " + n + " (with refNode Element): " + q);
}
if (ref) {
test(function() {
var j, element, refNodes;
for (j = 0; j < e.length; j++) {
element = root.querySelector("#" + e[j]);
refNodes = root.querySelectorAll(ref);
assert_true(element.matches(q, refNodes), "The element #" + e[j] + " should match the selector.")
}
if (u) {
for (j = 0; j < u.length; j++) {
element = root.querySelector("#" + u[j]);
refNodes = root.querySelectorAll(ref);
assert_false(element.matches(q, refNodes), "The element #" + u[j] + " should not match the selector.")
}
}
}, type + " Element.matches: " + n + " (with refNodes NodeList): " + q);
}
if (!ctx && !ref) {
test(function() {
for (var j = 0; j < e.length; j++) {
var element = root.querySelector("#" + e[j]);
assert_true(element.matches(q), "The element #" + e[j] + " should match the selector.")
}
if (u) {
for (j = 0; j < u.length; j++) {
element = root.querySelector("#" + u[j]);
assert_false(element.matches(q), "The element #" + u[j] + " should not match the selector.")
}
}
}, type + " Element.matches: " + n + " (with no refNodes): " + q);
}
}
}
}

View File

@ -6,12 +6,12 @@
<script src="/resources/testharnessreport.js"></script>
<script src="/dom/nodes/selectors.js"></script>
<script src="level2-lib.js"></script>
<script src="ParentNode-find-findAll.js"></script>
<style>iframe { visibility: hidden; position: absolute; }</style>
<div id="log">This test requires JavaScript.</div>
<script>
var testType = TEST_FIND | TEST_MATCH;
var docType = "html"; // Only run tests suitable for HTML
var frame = document.createElement("iframe"),
@ -64,36 +64,26 @@ function init() {
fragment.appendChild(element.cloneNode(true));
// Setup Tests
interfaceCheck("Document", doc, testType);
interfaceCheck("Detached Element", detached, testType);
interfaceCheck("Fragment", fragment, testType);
interfaceCheck("In-document Element", element, testType);
interfaceCheckFind("Document", doc);
interfaceCheckFind("Detached Element", detached);
interfaceCheckFind("Fragment", fragment);
interfaceCheckFind("In-document Element", element);
runSpecialSelectorTests("Document", doc);
runSpecialSelectorTests("Detached Element", detached);
runSpecialSelectorTests("Fragment", fragment);
runSpecialSelectorTests("In-document Element", element);
runSpecialMatchesTests("DIV Element", element);
runSpecialMatchesTests("NULL Element", document.createElement("null"));
runSpecialMatchesTests("UNDEFINED Element", document.createElement("undefined"));
verifyStaticList("Document", doc);
verifyStaticList("Detached Element", detached);
verifyStaticList("Fragment", fragment);
verifyStaticList("In-document Element", element);
runInvalidSelectorTest("Document", doc, invalidSelectors);
runInvalidSelectorTest("Detached Element", detached, invalidSelectors);
runInvalidSelectorTest("Fragment", fragment, invalidSelectors);
runInvalidSelectorTest("In-document Element", element, invalidSelectors);
runInvalidSelectorTestFind("Document", doc, invalidSelectors);
runInvalidSelectorTestFind("Detached Element", detached, invalidSelectors);
runInvalidSelectorTestFind("Fragment", fragment, invalidSelectors);
runInvalidSelectorTestFind("In-document Element", element, invalidSelectors);
runMatchesTest("In-document", doc, validSelectors, testType, "html");
runMatchesTest("Detached", detached, validSelectors, testType, "html");
runMatchesTest("Fragment", fragment, validSelectors, testType, "html");
runMatchesTest("In-document", doc, scopedSelectors, testType, "html");
runValidSelectorTest("In-document", doc, scopedSelectors, testType, "html");
runValidSelectorTest("In-document", doc, scopedSelectors, "html");
}
</script>

View File

@ -0,0 +1,278 @@
/*
* Check that the find and findAll methods exist on the given Node
*/
function interfaceCheckFind(type, obj) {
test(function() {
var q = typeof obj.find === "function";
assert_true(q, type + " supports find.");
}, type + " supports find")
test(function() {
var qa = typeof obj.findAll === "function";
assert_true( qa, type + " supports findAll.");
}, type + " supports findAll")
}
/*
* Verify that the NodeList returned by findAll is static and and that a new list is created after
* each call. A static list should not be affected by subsequent changes to the DOM.
*/
function verifyStaticList(type, root) {
var pre, post, preLength;
test(function() {
pre = root.findAll("div");
preLength = pre.length;
var div = doc.createElement("div");
(root.body || root).appendChild(div);
assert_equals(pre.length, preLength, "The length of the NodeList should not change.")
}, type + ": static NodeList")
test(function() {
post = root.findAll("div"),
assert_equals(post.length, preLength + 1, "The length of the new NodeList should be 1 more than the previous list.")
}, type + ": new NodeList")
}
/*
* Verify handling of special values for the selector parameter, including stringification of
* null and undefined, and the handling of the empty string.
*/
function runSpecialSelectorTests(type, root) {
test(function() { // 1
assert_equals(root.findAll(null).length, 1, "This should find one element with the tag name 'NULL'.");
}, type + ".findAll null")
test(function() { // 2
assert_equals(root.findAll(undefined).length, 1, "This should find one elements with the tag name 'UNDEFINED'.");
}, type + ".findAll undefined")
test(function() { // 3
assert_throws(TypeError(), function() {
root.findAll();
}, "This should throw a TypeError.")
}, type + ".findAll no parameter")
test(function() { // 4
var elm = root.find(null)
assert_not_equals(elm, null, "This should find an element.");
assert_equals(elm.tagName.toUpperCase(), "NULL", "The tag name should be 'NULL'.")
}, type + ".find null")
test(function() { // 5
var elm = root.find(undefined)
assert_not_equals(elm, undefined, "This should find an element.");
assert_equals(elm.tagName.toUpperCase(), "UNDEFINED", "The tag name should be 'UNDEFINED'.")
}, type + ".find undefined")
test(function() { // 6
assert_throws(TypeError(), function() {
root.find();
}, "This should throw a TypeError.")
}, type + ".find no parameter.")
test(function() { // 7
result = root.findAll("*");
var i = 0;
traverse(root, function(elem) {
if (elem !== root) {
assert_equals(elem, result[i++], "The result in index " + i + " should be in tree order.")
}
})
}, type + ".findAll tree order");
}
/*
* Execute queries with the specified valid selectors for both find() and findAll()
* Only run these tests when results are expected. Don't run for syntax error tests.
*
* context.findAll(selector, refNodes)
* context.findAll(selector) // Only if refNodes is not specified
* root.findAll(selector, context) // Only if refNodes is not specified
* root.findAll(selector, refNodes) // Only if context is not specified
* root.findAll(selector) // Only if neither context nor refNodes is specified
*
* Equivalent tests will be run for .find() as well.
*/
function runValidSelectorTest(type, root, selectors, docType) {
var nodeType = getNodeType(root);
for (var i = 0; i < selectors.length; i++) {
var s = selectors[i];
var n = s["name"];
var q = s["selector"];
var e = s["expect"];
var ctx = s["ctx"];
var ref = s["ref"];
if (!s["exclude"] || (s["exclude"].indexOf(nodeType) === -1 && s["exclude"].indexOf(docType) === -1)) {
//console.log("Running tests " + nodeType + ": " + s["testType"] + "&" + testType + "=" + (s["testType"] & testType) + ": " + JSON.stringify(s))
var foundall, found, context, refNodes, refArray;
if (s["testType"] & TEST_FIND) {
/*
* If ctx and ref are specified:
* context.findAll(selector, refNodes)
* context.find(selector, refNodes)
*/
if (ctx && ref) {
context = root.querySelector(ctx);
refNodes = root.querySelectorAll(ref);
refArray = Array.prototype.slice.call(refNodes, 0);
test(function() {
foundall = context.findAll(q, refNodes);
verifyNodeList(foundall, expect);
}, type + " [Context Element].findAll: " + n + " (with refNodes NodeList): " + q);
test(function() {
foundall = context.findAll(q, refArray);
verifyNodeList(foundall, expect);
}, type + " [Context Element].findAll: " + n + " (with refNodes Array): " + q);
test(function() {
found = context.find(q, refNodes);
verifyElement(found, foundall, expect)
}, type + " [Context Element].find: " + n + " (with refNodes NodeList): " + q);
test(function() {
found = context.find(q, refArray);
verifyElement(found, foundall, expect)
}, type + " [Context Element].find: " + n + " (with refNodes Array): " + q);
}
/*
* If ctx is specified, ref is not:
* context.findAll(selector)
* context.find(selector)
* root.findAll(selector, context)
* root.find(selector, context)
*/
if (ctx && !ref) {
context = root.querySelector(ctx);
test(function() {
foundall = context.findAll(q);
verifyNodeList(foundall, expect);
}, type + " [Context Element].findAll: " + n + " (with no refNodes): " + q);
test(function() {
found = context.find(q);
verifyElement(found, foundall, expect)
}, type + " [Context Element].find: " + n + " (with no refNodes): " + q);
test(function() {
foundall = root.findAll(q, context);
verifyNodeList(foundall, expect);
}, type + " [Root Node].findAll: " + n + " (with refNode Element): " + q);
test(function() {
foundall = root.find(q, context);
verifyElement(found, foundall, expect);
}, type + " [Root Node].find: " + n + " (with refNode Element): " + q);
}
/*
* If ref is specified, ctx is not:
* root.findAll(selector, refNodes)
* root.find(selector, refNodes)
*/
if (!ctx && ref) {
refNodes = root.querySelectorAll(ref);
refArray = Array.prototype.slice.call(refNodes, 0);
test(function() {
foundall = root.findAll(q, refNodes);
verifyNodeList(foundall, expect);
}, type + " [Root Node].findAll: " + n + " (with refNodes NodeList): " + q);
test(function() {
foundall = root.findAll(q, refArray);
verifyNodeList(foundall, expect);
}, type + " [Root Node].findAll: " + n + " (with refNodes Array): " + q);
test(function() {
found = root.find(q, refNodes);
verifyElement(found, foundall, expect);
}, type + " [Root Node].find: " + n + " (with refNodes NodeList): " + q);
test(function() {
found = root.find(q, refArray);
verifyElement(found, foundall, expect);
}, type + " [Root Node].find: " + n + " (with refNodes Array): " + q);
}
/*
* If neither ctx nor ref is specified:
* root.findAll(selector)
* root.find(selector)
*/
if (!ctx && !ref) {
test(function() {
foundall = root.findAll(q);
verifyNodeList(foundall, expect);
}, type + ".findAll: " + n + " (with no refNodes): " + q);
test(function() {
found = root.find(q);
verifyElement(found, foundall, expect);
}, type + ".find: " + n + " (with no refNodes): " + q);
}
}
} else {
//console.log("Excluding for " + nodeType + ": " + s["testType"] + "&" + testType + "=" + (s["testType"] & testType) + ": " + JSON.stringify(s))
}
}
}
/*
* Execute queries with the specified invalid selectors for both find() and findAll()
* Only run these tests when errors are expected. Don't run for valid selector tests.
*/
function runInvalidSelectorTestFind(type, root, selectors) {
for (var i = 0; i < selectors.length; i++) {
var s = selectors[i];
var n = s["name"];
var q = s["selector"];
test(function() {
assert_throws("SyntaxError", function() {
root.find(q)
})
}, type + ".find: " + n + ": " + q);
test(function() {
assert_throws("SyntaxError", function() {
root.findAll(q)
})
}, type + ".findAll: " + n + ": " + q);
}
}
function verifyNodeList(resultAll, expect) {
assert_not_equals(resultAll, null, "The method should not return null.");
assert_equals(resultAll.length, e.length, "The method should return the expected number of matches.");
for (var i = 0; i < e.length; i++) {
assert_not_equals(resultAll[i], null, "The item in index " + i + " should not be null.")
assert_equals(resultAll[i].getAttribute("id"), e[i], "The item in index " + i + " should have the expected ID.");
assert_false(resultAll[i].hasAttribute("data-clone"), "This should not be a cloned element.");
}
}
function verifyElement(result, resultAll, expect) {
if (expect.length > 0) {
assert_not_equals(result, null, "The method should return a match.")
assert_equals(found.getAttribute("id"), e[0], "The method should return the first match.");
assert_equals(result, resultAll[0], "The result should match the first item from querySelectorAll.");
assert_false(found.hasAttribute("data-clone"), "This should not be annotated as a cloned element.");
} else {
assert_equals(result, null, "The method should not match anything.");
}
}

View File

@ -47,403 +47,14 @@ function setupSpecialElements(parent) {
parent.appendChild(noNS);
}
/*
* Check that the find, findAll and matches() methods exist on the given Node
*/
function interfaceCheck(type, obj) {
test(function() {
var q = typeof obj.find === "function";
assert_true(q, type + " supports find.");
}, type + " supports find")
test(function() {
var qa = typeof obj.findAll === "function";
assert_true( qa, type + " supports findAll.");
}, type + " supports findAll")
if (obj.nodeType === obj.ELEMENT_NODE) {
test(function() {
assert_idl_attribute(obj, "matches", type + " supports matches");
}, type + " supports matches")
}
}
/*
* Verify that the NodeList returned by findAll is static and and that a new list is created after
* each call. A static list should not be affected by subsequent changes to the DOM.
*/
function verifyStaticList(type, root) {
var pre, post, preLength;
test(function() {
pre = root.findAll("div");
preLength = pre.length;
var div = doc.createElement("div");
(root.body || root).appendChild(div);
assert_equals(pre.length, preLength, "The length of the NodeList should not change.")
}, type + ": static NodeList")
test(function() {
post = root.findAll("div"),
assert_equals(post.length, preLength + 1, "The length of the new NodeList should be 1 more than the previous list.")
}, type + ": new NodeList")
}
/*
* Verify handling of special values for the selector parameter, including stringification of
* null and undefined, and the handling of the empty string.
*/
function runSpecialSelectorTests(type, root) {
test(function() { // 1
assert_equals(root.findAll(null).length, 1, "This should find one element with the tag name 'NULL'.");
}, type + ".findAll null")
test(function() { // 2
assert_equals(root.findAll(undefined).length, 1, "This should find one elements with the tag name 'UNDEFINED'.");
}, type + ".findAll undefined")
test(function() { // 3
assert_throws(TypeError(), function() {
root.findAll();
}, "This should throw a TypeError.")
}, type + ".findAll no parameter")
test(function() { // 4
var elm = root.find(null)
assert_not_equals(elm, null, "This should find an element.");
assert_equals(elm.tagName.toUpperCase(), "NULL", "The tag name should be 'NULL'.")
}, type + ".find null")
test(function() { // 5
var elm = root.find(undefined)
assert_not_equals(elm, undefined, "This should find an element.");
assert_equals(elm.tagName.toUpperCase(), "UNDEFINED", "The tag name should be 'UNDEFINED'.")
}, type + ".find undefined")
test(function() { // 6
assert_throws(TypeError(), function() {
root.find();
}, "This should throw a TypeError.")
}, type + ".find no parameter.")
test(function() { // 7
result = root.findAll("*");
var i = 0;
traverse(root, function(elem) {
if (elem !== root) {
assert_equals(elem, result[i++], "The result in index " + i + " should be in tree order.")
}
})
}, type + ".findAll tree order");
}
function runSpecialMatchesTests(type, element) {
test(function() { // 1
if (element.tagName.toLowerCase() === "null") {
assert_true(element.matches(null), "An element with the tag name '" + element.tagName.toLowerCase() + "' should match.");
} else {
assert_false(element.matches(null), "An element with the tag name '" + element.tagName.toLowerCase() + "' should not match.");
}
}, type + ".matches(null)")
test(function() { // 2
if (element.tagName.toLowerCase() === "undefined") {
assert_true(element.matches(undefined), "An element with the tag name '" + element.tagName.toLowerCase() + "' should match.");
} else {
assert_false(element.matches(undefined), "An element with the tag name '" + element.tagName.toLowerCase() + "' should not match.");
}
}, type + ".matches(undefined)")
test(function() { // 3
assert_throws(TypeError(), function() {
element.matches();
}, "This should throw a TypeError.")
}, type + ".matches no parameter")
}
/*
* Execute queries with the specified valid selectors for both find() and findAll()
* Only run these tests when results are expected. Don't run for syntax error tests.
*
* Where testType is TEST_FIND_BASELINE or TEST_FIND_ADDITIONAL:
*
* context.findAll(selector, refNodes)
* context.findAll(selector) // Only if refNodes is not specified
* root.findAll(selector, context) // Only if refNodes is not specified
* root.findAll(selector, refNodes) // Only if context is not specified
* root.findAll(selector) // Only if neither context nor refNodes is specified
*
* Where testType is TEST_QSA_BASELINE or TEST_QSA_ADDITIONAL
*
* context.querySelectorAll(selector) // Only if refNodes is not specified
* root.querySelectorAll(selector) // Only if neither context nor refNodes is specified
*
* Equivalent tests will be run for .find() as well.
* Note: Do not specify a testType of TEST_QSA_* where either implied :scope or explicit refNodes
* are required.
*/
function runValidSelectorTest(type, root, selectors, testType, docType) {
var nodeType = getNodeType(root);
for (var i = 0; i < selectors.length; i++) {
var s = selectors[i];
var n = s["name"];
var q = s["selector"];
var e = s["expect"];
var ctx = s["ctx"];
var ref = s["ref"];
if (!s["exclude"] || (s["exclude"].indexOf(nodeType) === -1 && s["exclude"].indexOf(docType) === -1)) {
//console.log("Running tests " + nodeType + ": " + s["testType"] + "&" + testType + "=" + (s["testType"] & testType) + ": " + JSON.stringify(s))
var foundall, found, context, refNodes, refArray;
if (s["testType"] & testType & (TEST_FIND)) {
/*
* If ctx and ref are specified:
* context.findAll(selector, refNodes)
* context.find(selector, refNodes)
*/
if (ctx && ref) {
context = root.querySelector(ctx);
refNodes = root.querySelectorAll(ref);
refArray = Array.prototype.slice.call(refNodes, 0);
test(function() {
foundall = context.findAll(q, refNodes);
verifyNodeList(foundall, expect);
}, type + " [Context Element].findAll: " + n + " (with refNodes NodeList): " + q);
test(function() {
foundall = context.findAll(q, refArray);
verifyNodeList(foundall, expect);
}, type + " [Context Element].findAll: " + n + " (with refNodes Array): " + q);
test(function() {
found = context.find(q, refNodes);
verifyElement(found, foundall, expect)
}, type + " [Context Element].find: " + n + " (with refNodes NodeList): " + q);
test(function() {
found = context.find(q, refArray);
verifyElement(found, foundall, expect)
}, type + " [Context Element].find: " + n + " (with refNodes Array): " + q);
}
/*
* If ctx is specified, ref is not:
* context.findAll(selector)
* context.find(selector)
* root.findAll(selector, context)
* root.find(selector, context)
*/
if (ctx && !ref) {
context = root.querySelector(ctx);
test(function() {
foundall = context.findAll(q);
verifyNodeList(foundall, expect);
}, type + " [Context Element].findAll: " + n + " (with no refNodes): " + q);
test(function() {
found = context.find(q);
verifyElement(found, foundall, expect)
}, type + " [Context Element].find: " + n + " (with no refNodes): " + q);
test(function() {
foundall = root.findAll(q, context);
verifyNodeList(foundall, expect);
}, type + " [Root Node].findAll: " + n + " (with refNode Element): " + q);
test(function() {
foundall = root.find(q, context);
verifyElement(found, foundall, expect);
}, type + " [Root Node].find: " + n + " (with refNode Element): " + q);
}
/*
* If ref is specified, ctx is not:
* root.findAll(selector, refNodes)
* root.find(selector, refNodes)
*/
if (!ctx && ref) {
refNodes = root.querySelectorAll(ref);
refArray = Array.prototype.slice.call(refNodes, 0);
test(function() {
foundall = root.findAll(q, refNodes);
verifyNodeList(foundall, expect);
}, type + " [Root Node].findAll: " + n + " (with refNodes NodeList): " + q);
test(function() {
foundall = root.findAll(q, refArray);
verifyNodeList(foundall, expect);
}, type + " [Root Node].findAll: " + n + " (with refNodes Array): " + q);
test(function() {
found = root.find(q, refNodes);
verifyElement(found, foundall, expect);
}, type + " [Root Node].find: " + n + " (with refNodes NodeList): " + q);
test(function() {
found = root.find(q, refArray);
verifyElement(found, foundall, expect);
}, type + " [Root Node].find: " + n + " (with refNodes Array): " + q);
}
/*
* If neither ctx nor ref is specified:
* root.findAll(selector)
* root.find(selector)
*/
if (!ctx && !ref) {
test(function() {
foundall = root.findAll(q);
verifyNodeList(foundall, expect);
}, type + ".findAll: " + n + " (with no refNodes): " + q);
test(function() {
found = root.find(q);
verifyElement(found, foundall, expect);
}, type + ".find: " + n + " (with no refNodes): " + q);
}
}
if (s["testType"] & testType & (TEST_QSA)) {
if (ctx && !ref) {
// context.querySelectorAll(selector) // Only if refNodes is not specified
}
if (!ctx && !ref) {
// root.querySelectorAll(selector) // Only if neither context nor refNodes is specified
}
}
} else {
//console.log("Excluding for " + nodeType + ": " + s["testType"] + "&" + testType + "=" + (s["testType"] & testType) + ": " + JSON.stringify(s))
}
}
}
/*
* Execute queries with the specified invalid selectors for both find() and findAll()
* Only run these tests when errors are expected. Don't run for valid selector tests.
*/
function runInvalidSelectorTest(type, root, selectors) {
for (var i = 0; i < selectors.length; i++) {
var s = selectors[i];
var n = s["name"];
var q = s["selector"];
test(function() {
assert_throws("SyntaxError", function() {
root.find(q)
})
}, type + ".find: " + n + ": " + q);
test(function() {
assert_throws("SyntaxError", function() {
root.findAll(q)
})
}, type + ".findAll: " + n + ": " + q);
if (root.nodeType === root.ELEMENT_NODE) {
test(function() {
assert_throws("SyntaxError", function() {
root.matches(q)
})
}, type + ".matches: " + n + ": " + q);
}
}
}
function runMatchesTest(type, root, selectors, testType, docType) {
var nodeType = getNodeType(root);
for (var i = 0; i < selectors.length; i++) {
var s = selectors[i];
var n = s["name"];
var q = s["selector"];
var e = s["expect"];
var u = s["unexpected"];
var ctx = s["ctx"];
var ref = s["ref"];
if ((!s["exclude"] || (s["exclude"].indexOf(nodeType) === -1 && s["exclude"].indexOf(docType) === -1))
&& (s["testType"] & testType & (TEST_MATCH)) ) {
if (ctx && !ref) {
test(function() {
var j, element, refNode;
for (j = 0; j < e.length; j++) {
element = root.querySelector("#" + e[j]);
refNode = root.querySelector(ctx);
assert_true(element.matches(q, refNode), "The element #" + e[j] + " should match the selector.")
}
if (u) {
for (j = 0; j < u.length; j++) {
element = root.querySelector("#" + u[j]);
refNode = root.querySelector(ctx);
assert_false(element.matches(q, refNode), "The element #" + u[j] + " should not match the selector.")
}
}
}, type + " Element.matches: " + n + " (with refNode Element): " + q);
}
if (ref) {
test(function() {
var j, element, refNodes;
for (j = 0; j < e.length; j++) {
element = root.querySelector("#" + e[j]);
refNodes = root.querySelectorAll(ref);
assert_true(element.matches(q, refNodes), "The element #" + e[j] + " should match the selector.")
}
if (u) {
for (j = 0; j < u.length; j++) {
element = root.querySelector("#" + u[j]);
refNodes = root.querySelectorAll(ref);
assert_false(element.matches(q, refNodes), "The element #" + u[j] + " should not match the selector.")
}
}
}, type + " Element.matches: " + n + " (with refNodes NodeList): " + q);
}
if (!ctx && !ref) {
test(function() {
for (var j = 0; j < e.length; j++) {
var element = root.querySelector("#" + e[j]);
assert_true(element.matches(q), "The element #" + e[j] + " should match the selector.")
}
if (u) {
for (j = 0; j < u.length; j++) {
element = root.querySelector("#" + u[j]);
assert_false(element.matches(q), "The element #" + u[j] + " should not match the selector.")
}
}
}, type + " Element.matches: " + n + " (with no refNodes): " + q);
}
}
}
}
function traverse(elem, fn) {
if (elem.nodeType === elem.ELEMENT_NODE) {
fn(elem);
elem = elem.firstChild;
while (elem) {
traverse(elem, fn);
elem = elem.nextSibling;
}
}
elem = elem.firstChild;
while (elem) {
traverse(elem, fn);
elem = elem.nextSibling;
}
}
@ -460,25 +71,3 @@ function getNodeType(node) {
return "unknown"; // This should never happen.
}
}
function verifyNodeList(resultAll, expect) {
assert_not_equals(resultAll, null, "The method should not return null.");
assert_equals(resultAll.length, e.length, "The method should return the expected number of matches.");
for (var i = 0; i < e.length; i++) {
assert_not_equals(resultAll[i], null, "The item in index " + i + " should not be null.")
assert_equals(resultAll[i].getAttribute("id"), e[i], "The item in index " + i + " should have the expected ID.");
assert_false(resultAll[i].hasAttribute("data-clone"), "This should not be a cloned element.");
}
}
function verifyElement(result, resultAll, expect) {
if (expect.length > 0) {
assert_not_equals(result, null, "The method should return a match.")
assert_equals(found.getAttribute("id"), e[0], "The method should return the first match.");
assert_equals(result, resultAll[0], "The result should match the first item from querySelectorAll.");
assert_false(found.hasAttribute("data-clone"), "This should not be annotated as a cloned element.");
} else {
assert_equals(result, null, "The method should not match anything.");
}
}

View File

@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
import argparse
import json
import logging
import os
import signal
import socket
@ -19,6 +18,8 @@ repo_root = os.path.abspath(os.path.split(__file__)[0])
sys.path.insert(1, os.path.join(repo_root, "tools", "wptserve"))
from wptserve import server as wptserve, handlers
from wptserve.router import any_method
from wptserve.logger import set_logger
sys.path.insert(1, os.path.join(repo_root, "tools", "pywebsocket", "src"))
from mod_pywebsocket import standalone as pywebsocket
@ -39,12 +40,12 @@ subdomains = [u"www",
u"天気の良い日",
u"élève"]
logger = None
def default_logger(level):
def setup_logger(level):
import logging
global logger
logger = logging.getLogger("web-platform-tests")
logging.basicConfig(level=getattr(logging, level.upper()))
return logger
set_logger(logger)
def open_socket(port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@ -323,12 +324,10 @@ def load_config(default_path, override_path=None):
return rv
def main():
global logger
config = load_config("config.default.json",
"config.json")
logger = default_logger(config["log_level"])
setup_logger(config["log_level"])
config_, servers = start(config)

View File

@ -21,7 +21,7 @@ interface ServiceWorkerGlobalScope : WorkerGlobalScope {
readonly attribute ServiceWorkerClients clients;
[Unforgeable] readonly attribute DOMString scope;
Promise<any> fetch((Request or USVString) request);
Promise<any> fetch((Request or ScalarValueString) request);
void update();
void unregister();
@ -55,7 +55,7 @@ synchronous requests MUST NOT be initiated inside of a Service Worker.
interface CacheStorage {};
interface ServiceWorkerClients {};
interface Request {};
interface USVString {};
interface ScalarValueString {};
interface EventHandler {};
interface WorkerGlobalScope {};
</pre>

View File

@ -15,11 +15,11 @@
<script type=text/plain id="idl_0">
[Constructor]
interface Cache {
Promise<AbstractResponse> match((Request or USVString) request, optional QueryParams params);
Promise<sequence<AbstractResponse>> matchAll((Request or USVString) request, optional QueryParams params);
Promise<any> add((Request or USVString)... requests);
Promise<any> put((Request or USVString) request, AbstractResponse response);
Promise<any> delete((Request or USVString) request, optional QueryParams params);
Promise<AbstractResponse> match((Request or ScalarValueString) request, optional QueryParams params);
Promise<sequence<AbstractResponse>> matchAll((Request or ScalarValueString) request, optional QueryParams params);
Promise<any> add((Request or ScalarValueString)... requests);
Promise<any> put((Request or ScalarValueString) request, AbstractResponse response);
Promise<any> delete((Request or ScalarValueString) request, optional QueryParams params);
Promise<any> each(CacheIterationCallback callback, optional object thisArg);
};
@ -30,7 +30,7 @@ dictionary QueryParams {
boolean prefixMatch;
};
callback CacheIterationCallback = void (AbstractResponse value, (Request or USVString) key, Cache map);
callback CacheIterationCallback = void (AbstractResponse value, (Request or ScalarValueString) key, Cache map);
</pre>
@ -38,7 +38,7 @@ callback CacheIterationCallback = void (AbstractResponse value, (Request or USVS
<script type=text/plain id="untested_idls">
interface AbstractResponse {};
interface Request {};
interface USVString {};
interface ScalarValueString {};
</pre>
<script>

View File

@ -15,7 +15,7 @@
<script type=text/plain id="idl_0">
[Constructor(sequence<any> iterable)]
interface CacheStorage {
Promise<any> match(USVString url, optional DOMString cacheName);
Promise<any> match(ScalarValueString url, optional DOMString cacheName);
Promise<Cache> get(DOMString key);
Promise<boolean> has(DOMString key);
Promise<any> set(DOMString key, Cache val);
@ -42,7 +42,7 @@ convenience methods.
<script type=text/plain id="untested_idls">
interface USVString {};
interface ScalarValueString {};
interface Cache {};
</pre>

View File

@ -21,7 +21,7 @@ interface FetchEvent : Event {
readonly attribute boolean isReload;
void respondWith(Promise<AbstractResponse> r);
Promise<any> forwardTo(USVString url);
Promise<any> forwardTo(ScalarValueString url);
Promise<any> default();
};
@ -51,7 +51,7 @@ Service Workers use the `[FetchEvent][1]` interface for `[fetch][2]` event.
interface Request {};
interface Client {};
interface AbstractResponse {};
interface USVString {};
interface ScalarValueString {};
interface Event {};
</pre>

View File

@ -1,6 +1,5 @@
import cgi
import json
import logging
import os
import traceback
import urllib
@ -9,14 +8,13 @@ import urlparse
from constants import content_types
from pipes import Pipeline, template
from ranges import RangeParser
from request import Authentication
from response import MultipartContent
from utils import HTTPException
logger = logging.getLogger("wptserve")
__all__ = ["file_handler", "python_script_handler",
"FunctionHandler", "handler", "json_handler",
"as_is_handler", "ErrorHandler"]
"as_is_handler", "ErrorHandler", "BasicAuthHandler"]
def guess_content_type(path):
@ -38,10 +36,15 @@ def filesystem_path(base_path, request, url_base="/"):
path = path[len(url_base):]
if ".." in path:
raise HTTPException(500)
raise HTTPException(404)
return os.path.join(base_path, path)
new_path = os.path.join(base_path, path)
# Otherwise setting path to / allows access outside the root directory
if not new_path.startswith(base_path):
raise HTTPException(404)
return new_path
class DirectoryHandler(object):
def __init__(self, base_path=None, url_base="/"):
@ -153,7 +156,8 @@ class FileHandler(object):
except IOError:
return []
else:
data = template(request, data)
if use_sub:
data = template(request, data)
return [tuple(item.strip() for item in line.split(":", 1))
for line in data.splitlines() if line]
@ -222,7 +226,7 @@ def FunctionHandler(func):
def inner(request, response):
try:
rv = func(request, response)
except:
except Exception:
msg = traceback.format_exc()
raise HTTPException(500, message=msg)
if rv is not None:
@ -267,7 +271,7 @@ class AsIsHandler(object):
self.base_path = base_path
self.url_base = url_base
def __call__(request, response):
def __call__(self, request, response):
path = filesystem_path(self.base_path, request, self.url_base)
try:
@ -279,6 +283,33 @@ class AsIsHandler(object):
as_is_handler = AsIsHandler()
class BasicAuthHandler(object):
def __init__(self, handler, user, password):
"""
A Basic Auth handler
:Args:
- handler: a secondary handler for the request after authentication is successful (example file_handler)
- user: string of the valid user name or None if any / all credentials are allowed
- password: string of the password required
"""
self.user = user
self.password = password
self.handler = handler
def __call__(self, request, response):
if "authorization" not in request.headers:
response.status = 401
response.headers.set("WWW-Authenticate", "Basic")
return response
else:
auth = Authentication(request.headers)
if self.user is not None and (self.user != auth.username or self.password != auth.password):
response.set_error(403, "Invalid username or password")
return response
return self.handler(request, response)
basic_auth_handler = BasicAuthHandler(file_handler, None, None)
class ErrorHandler(object):
def __init__(self, status):

View File

@ -0,0 +1,29 @@
class NoOpLogger(object):
def critical(self, msg):
pass
def error(self, msg):
pass
def info(self, msg):
pass
def warning(self, msg):
pass
def debug(self, msg):
pass
logger = NoOpLogger()
_set_logger = False
def set_logger(new_logger):
global _set_logger
if _set_logger:
raise Exception("Logger must be set at most once")
global logger
logger = new_logger
_set_logger = True
def get_logger():
return logger

View File

@ -1,14 +1,11 @@
from cgi import escape
import gzip as gzip_module
import logging
import re
import time
import types
import uuid
from cStringIO import StringIO
logger = logging.getLogger("wptserve")
def resolve_content(response):
rv = "".join(item for item in response.iter_content())
@ -289,7 +286,7 @@ class ReplacementTokenizer(object):
token = token[1:-1]
try:
token = int(token)
except:
except ValueError:
token = unicode(token, "utf8")
return ("index", token)
@ -311,9 +308,9 @@ class FirstWrapper(object):
def __getitem__(self, key):
try:
return self.params.first(key)
return self.params.first(key)
except KeyError:
return ""
return ""
@pipe()
@ -442,7 +439,7 @@ def gzip(request, response):
out = StringIO()
with gzip_module.GzipFile(fileobj=out, mode="w") as f:
f.write(content)
f.write(content)
response.content = out.getvalue()
response.headers.set("Content-Length", len(response.content))

View File

@ -1,8 +1,6 @@
import base64
import cgi
import Cookie
import logging
import os
import StringIO
import tempfile
import urlparse
@ -10,7 +8,6 @@ import urlparse
import stash
from utils import HTTPException
logger = logging.getLogger("wptserve")
missing = object()
@ -374,7 +371,7 @@ class RequestHeaders(dict):
a list"""
try:
return dict.__getitem__(self, key.lower())
except:
except KeyError:
if default is not missing:
return default
else:

View File

@ -2,17 +2,15 @@ from collections import OrderedDict
from datetime import datetime, timedelta
import Cookie
import json
import logging
import types
import uuid
import socket
from constants import response_codes
from logger import get_logger
logger = logging.getLogger("wptserve")
missing = object()
class Response(object):
"""Object representing the response to a HTTP request
@ -77,6 +75,8 @@ class Response(object):
self.headers = ResponseHeaders()
self.content = []
self.logger = get_logger()
@property
def status(self):
return self._status
@ -213,7 +213,7 @@ class Response(object):
("Content-Length", len(data))]
self.content = data
if code == 500:
logger.error(message)
self.logger.error(message)
class MultipartContent(object):
@ -403,7 +403,7 @@ class ResponseWriter(object):
self.write_default_headers()
self.write("\r\n")
if not "content-length" in self._headers_seen:
if "content-length" not in self._headers_seen:
self._response.close_connection = True
if not self._response.explicit_flush:
self.flush()

View File

@ -1,10 +1,8 @@
import itertools
import logging
import re
import types
logger = logging.getLogger("wptserve")
logger.setLevel(logging.DEBUG)
from logger import get_logger
any_method = object()
@ -99,6 +97,7 @@ class Router(object):
def __init__(self, doc_root, routes):
self.doc_root = doc_root
self.routes = []
self.logger = get_logger()
for route in reversed(routes):
self.register(*route)
@ -140,7 +139,7 @@ class Router(object):
methods = [methods]
for method in methods:
self.routes.append((method, compile_path_match(path), handler))
logger.debug("Route pattern: %s" % self.routes[-1][1].pattern)
self.logger.debug("Route pattern: %s" % self.routes[-1][1].pattern)
def get_handler(self, request):
"""Get a handler for a request or None if there is no handler.
@ -158,7 +157,7 @@ class Router(object):
name = handler.__name__
else:
name = handler.__class__.__name__
logger.debug("Found handler %s" % name)
self.logger.debug("Found handler %s" % name)
match_parts = m.groupdict().copy()
if len(match_parts) < len(m.groups()):

View File

@ -1,6 +1,5 @@
import BaseHTTPServer
import errno
import logging
import os
import re
import socket
@ -12,16 +11,14 @@ import traceback
import types
import urlparse
import routes as default_routes
from logger import get_logger
from request import Server, Request
from response import Response
from router import Router
import routes as default_routes
from utils import HTTPException
logger = logging.getLogger("wptserve")
logger.setLevel(logging.DEBUG)
"""HTTP server designed for testing purposes.
The server is designed to provide flexibility in the way that
@ -67,6 +64,7 @@ class RequestRewriter(object):
self.rules = {}
for rule in reversed(rules):
self.register(*rule)
self.logger = get_logger()
def register(self, methods, input_path, output_path):
"""Register a rewrite rule.
@ -95,7 +93,7 @@ class RequestRewriter(object):
if split_url.path in self.rules:
methods, destination = self.rules[split_url.path]
if "*" in methods or request_handler.command in methods:
logger.debug("Rewriting request path %s to %s" %
self.logger.debug("Rewriting request path %s to %s" %
(request_handler.path, destination))
new_url = list(split_url)
new_url[2] = destination
@ -106,6 +104,7 @@ class RequestRewriter(object):
class WebTestServer(ThreadingMixIn, BaseHTTPServer.HTTPServer):
allow_reuse_address = True
acceptable_errors = (errno.EPIPE, errno.ECONNABORTED)
request_queue_size = 2000
# Ensure that we don't hang on shutdown waiting for requests
daemon_threads = True
@ -143,6 +142,7 @@ class WebTestServer(ThreadingMixIn, BaseHTTPServer.HTTPServer):
self.rewriter = rewriter
self.scheme = "https" if use_ssl else "http"
self.logger = get_logger()
if bind_hostname:
hostname_port = server_address
@ -155,7 +155,7 @@ class WebTestServer(ThreadingMixIn, BaseHTTPServer.HTTPServer):
if config is not None:
Server.config = config
else:
logger.debug("Using default configuration")
self.logger.debug("Using default configuration")
Server.config = {"host": server_address[0],
"domains": {"": server_address[0]},
"ports": {"http": [self.server_address[1]]}}
@ -177,7 +177,7 @@ class WebTestServer(ThreadingMixIn, BaseHTTPServer.HTTPServer):
error.errno in self.acceptable_errors)):
pass # remote hang up before the result is sent
else:
logger.error(traceback.format_exc())
self.logger.error(traceback.format_exc())
class WebTestRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
@ -187,6 +187,7 @@ class WebTestRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def handle_one_request(self):
response = None
logger = get_logger()
try:
self.close_connection = False
request_line_is_valid = self.get_request_line()
@ -225,8 +226,11 @@ class WebTestRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
err = []
err.append(traceback.format_exc())
response.set_error(500, "\n".join(err))
logger.info("%i %s %s (%s) %i" % (response.status[0], request.method,
request.request_path, request.headers.get('Referer'), request.raw_input.length))
logger.debug("%i %s %s (%s) %i" % (response.status[0],
request.method,
request.request_path,
request.headers.get('Referer'),
request.raw_input.length))
if not response.writer.content_written:
response.write()
@ -261,10 +265,10 @@ class WebTestRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
self.close_connection = True
return False
if len(self.raw_requestline) > 65536:
self.requestline = ''
self.request_version = ''
self.command = ''
return False
self.requestline = ''
self.request_version = ''
self.command = ''
return False
if not self.raw_requestline:
self.close_connection = True
return True
@ -334,6 +338,7 @@ class WebTestHttpd(object):
self.rewriter = rewriter_cls(rewrites if rewrites is not None else [])
self.use_ssl = use_ssl
self.logger = get_logger()
if server_cls is None:
server_cls = WebTestServer
@ -357,7 +362,7 @@ class WebTestHttpd(object):
_host, self.port = self.httpd.socket.getsockname()
except Exception:
logger.error('Init failed! You may need to modify your hosts file. Refer to README.md.');
self.logger.error('Init failed! You may need to modify your hosts file. Refer to README.md.');
raise
def start(self, block=False):
@ -365,7 +370,7 @@ class WebTestHttpd(object):
:param block: True to run the server on the current thread, blocking,
False to run on a separate thread."""
logger.info("Starting http server on %s:%s" % (self.host, self.port))
self.logger.info("Starting http server on %s:%s" % (self.host, self.port))
self.started = True
if block:
self.httpd.serve_forever()
@ -386,7 +391,7 @@ class WebTestHttpd(object):
self.httpd.server_close()
self.server_thread.join()
self.server_thread = None
logger.info("Stopped http server on %s:%s" % (self.host, self.port))
self.logger.info("Stopped http server on %s:%s" % (self.host, self.port))
except AttributeError:
pass
self.started = False

View File

@ -12,26 +12,26 @@
[Constructor(DOMString url, optional DOMString base = "about:blank"),
Exposed=Window,Worker]
interface URL {
static DOMString domainToASCII(USVString domain);
static DOMString domainToUnicode(USVString domain);
static DOMString domainToASCII(ScalarValueString domain);
static DOMString domainToUnicode(ScalarValueString domain);
};
URL implements URLUtils;
[NoInterfaceObject]
interface URLUtils {
stringifier attribute USVString href;
stringifier attribute ScalarValueString href;
readonly attribute DOMString origin;
attribute USVString protocol;
attribute USVString username;
attribute USVString password;
attribute USVString host;
attribute USVString hostname;
attribute USVString port;
attribute USVString pathname;
attribute USVString search;
attribute ScalarValueString protocol;
attribute ScalarValueString username;
attribute ScalarValueString password;
attribute ScalarValueString host;
attribute ScalarValueString hostname;
attribute ScalarValueString port;
attribute ScalarValueString pathname;
attribute ScalarValueString search;
attribute URLSearchParams searchParams;
attribute USVString hash;
attribute ScalarValueString hash;
};
[NoInterfaceObject]
@ -48,15 +48,15 @@ interface URLUtilsReadOnly {
readonly attribute DOMString hash;
};
interface URLSearchParams {
void append(USVString name, USVString value);
void delete(USVString name);
DOMString? get(USVString name);
sequence<DOMString> getAll(USVString name);
boolean has(USVString name);
void set(USVString name, USVString value);
void append(ScalarValueString name, ScalarValueString value);
void delete(ScalarValueString name);
DOMString? get(ScalarValueString name);
sequence<DOMString> getAll(ScalarValueString name);
boolean has(ScalarValueString name);
void set(ScalarValueString name, ScalarValueString value);
stringifier;
};
typedef DOMString USVString;
typedef DOMString ScalarValueString;
</script>
<script>
"use strict";

View File

@ -91,7 +91,7 @@ mailto:example.com/ s:mailto p:example.com/
/a/\s/c s:http h:example.org p:/a/%20/c
/a%2fc s:http h:example.org p:/a%2fc
/a/%2f/c s:http h:example.org p:/a/%2f/c
\#\u03B2 s:http h:example.org p:/foo/bar f:#\u03B2
\#\u03B2 s:http h:example.org p:/foo/bar f:#%CE%B2
data:text/html,test#test s:data p:text/html,test f:#test
# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/file.html
@ -166,7 +166,7 @@ http://www.google.com/foo?bar=baz# about:blank s:http h:www.google.com p:/foo q:
http://www.google.com/foo?bar=baz#\s\u00BB s:http h:www.google.com p:/foo q:?bar=baz f:#\s%C2%BB
http://[www.google.com]/
http://www.google.com s:http h:www.google.com p:/
http://192.0x00A80001 s:http h:192.0x00a80001 p:/
http://192.0x00A80001 s:http h:192.168.0.1 p:/
http://www/foo%2Ehtml s:http h:www p:/foo%2Ehtml
http://www/foo/%2E/html s:http h:www p:/foo/html
http://user:pass@/
@ -315,9 +315,9 @@ http://hello%00
# Escaped numbers should be treated like IP addresses if they are.
# No special handling for IPv4 or IPv4-like URLs
http://%30%78%63%30%2e%30%32%35%30.01 s:http p:/ h:0xc0.0250.01
http://%30%78%63%30%2e%30%32%35%30.01 s:http p:/ h:192.168.0.1
http://%30%78%63%30%2e%30%32%35%30.01%2e s:http p:/ h:0xc0.0250.01.
http://192.168.0.257 s:http p:/ h:192.168.0.257
http://192.168.0.257
# Invalid escaping should trigger the regular host error handling.
http://%3g%78%63%30%2e%30%32%35%30%2E.01
@ -328,7 +328,13 @@ http://192.168.0.1\shello
# Fullwidth and escaped UTF-8 fullwidth should still be treated as IP.
# These are "0Xc0.0250.01" in fullwidth.
http://\uff10\uff38\uff43\uff10\uff0e\uff10\uff12\uff15\uff10\uff0e\uff10\uff11 s:http p:/ h:0xc0.0250.01
http://\uff10\uff38\uff43\uff10\uff0e\uff10\uff12\uff15\uff10\uff0e\uff10\uff11 s:http p:/ h:192.168.0.1
# Broken IPv6
http://[google.com]
# Misc Unicode
http://foo:\uD83D\uDCA9@example.com/bar s:http h:example.com p:/bar u:foo pass:%F0%9F%92%A9
# resolving a relative reference against an unknown scheme results in an error
x test:test

View File

@ -5,8 +5,6 @@
<title>Vibration API: test a simple array parameter to vibrate()</title>
<link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
<link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
<meta name='flags' content='dom, interact'/>
<link rel='stylesheet' href='/resources/testharness.css' media='all'/>
</head>
<body>
<h1>Description</h1>
@ -15,20 +13,11 @@
</p>
<button id='vib'>Vibrate!</button>
<div id='log'></div>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<script src='/common/vendor-prefix.js' data-prefixed-objects='[{"ancestors":["navigator"], "name":"vibrate"}]'></script>
<script>
if (undefined !== navigator.vibrate) {
setup({explicit_done:true});
var t = async_test("Tests that vibrate returns true");
document.getElementById("vib").onclick = t.step_func(function () {
assert_true(navigator.vibrate([2000]), "vibrate() returns a boolean");
t.done();
done();
}, "Calling vibrate returns true");
}
document.getElementById("vib").onclick = function () {
navigator.vibrate([2000]);
};
</script>
</body>
</html>

View File

@ -24,3 +24,8 @@ mode: compatibility
[ios-driver]
capabilities: {"browserName": "iphone"}
mode: compatibility
[blackberry]
url: http://169.254.0.1:1338
capabilities: {"browserName": "blackberry"}
mode: compatibility

View File

@ -1,6 +1,6 @@
<!--
onmessage = function(e) {
postMessage(e.ports === null);
postMessage(e.ports instanceof Array && e.ports.length === 0);
}
/*
-->

View File

@ -25,7 +25,7 @@ function compare_primitive(actual, input, test_obj) {
if (test_obj)
test_obj.done();
}
function compare_Array(callback) {
function compare_Array(callback, callback_is_async) {
return function(actual, input, test_obj) {
if (typeof actual === 'string')
assert_unreached(actual);
@ -33,12 +33,12 @@ function compare_Array(callback) {
assert_not_equals(actual, input);
assert_equals(actual.length, input.length, 'length');
callback(actual, input);
if (test_obj)
if (test_obj && !callback_is_async)
test_obj.done();
}
}
function compare_Object(callback) {
function compare_Object(callback, callback_is_async) {
return function(actual, input, test_obj) {
if (typeof actual === 'string')
assert_unreached(actual);
@ -46,15 +46,15 @@ function compare_Object(callback) {
assert_false(actual instanceof Array, 'instanceof Array');
assert_not_equals(actual, input);
callback(actual, input);
if (test_obj)
if (test_obj && !callback_is_async)
test_obj.done();
}
}
function enumerate_props(compare_func) {
function enumerate_props(compare_func, test_obj) {
return function(actual, input) {
for (var x in input) {
compare_func(actual[x], input[x]);
compare_func(actual[x], input[x], test_obj);
}
};
}
@ -339,41 +339,41 @@ function func_Blob_NUL() {
check('Blob NUL', func_Blob_NUL, compare_Blob);
async_test(function(test_obj) {
check(test_obj.name, [test_obj.step(func_Blob_basic)], compare_Array(enumerate_props(compare_Blob)), test_obj);
check(test_obj.name, [test_obj.step(func_Blob_basic)], compare_Array(enumerate_props(compare_Blob, test_obj), true), test_obj);
}, 'Array Blob object, Blob basic');
async_test(function(test_obj) {
check(test_obj.name, [test_obj.step(func_Blob_bytes([0xD800]))], compare_Array(enumerate_props(compare_Blob)), test_obj);
check(test_obj.name, [test_obj.step(func_Blob_bytes([0xD800]))], compare_Array(enumerate_props(compare_Blob, test_obj), true), test_obj);
}, 'Array Blob object, Blob unpaired high surrogate (invalid utf-8)');
async_test(function(test_obj) {
check(test_obj.name, [test_obj.step(func_Blob_bytes([0xDC00]))], compare_Array(enumerate_props(compare_Blob)), test_obj);
check(test_obj.name, [test_obj.step(func_Blob_bytes([0xDC00]))], compare_Array(enumerate_props(compare_Blob, test_obj), true), test_obj);
}, 'Array Blob object, Blob unpaired low surrogate (invalid utf-8)');
async_test(function(test_obj) {
check(test_obj.name, [test_obj.step(func_Blob_bytes([0xD800, 0xDC00]))], compare_Array(enumerate_props(compare_Blob)), test_obj);
check(test_obj.name, [test_obj.step(func_Blob_bytes([0xD800, 0xDC00]))], compare_Array(enumerate_props(compare_Blob, test_obj), true), test_obj);
}, 'Array Blob object, Blob paired surrogates (invalid utf-8)');
async_test(function(test_obj) {
check(test_obj.name, [test_obj.step(func_Blob_empty)], compare_Array(enumerate_props(compare_Blob)), test_obj);
check(test_obj.name, [test_obj.step(func_Blob_empty)], compare_Array(enumerate_props(compare_Blob, test_obj), true), test_obj);
}, 'Array Blob object, Blob empty');
async_test(function(test_obj) {
check(test_obj.name, [test_obj.step(func_Blob_NUL)], compare_Array(enumerate_props(compare_Blob)), test_obj);
check(test_obj.name, [test_obj.step(func_Blob_NUL)], compare_Array(enumerate_props(compare_Blob, test_obj), true), test_obj);
}, 'Array Blob object, Blob NUL');
async_test(function(test_obj) {
check(test_obj.name, {'x':test_obj.step(func_Blob_basic)}, compare_Object(enumerate_props(compare_Blob)), test_obj);
check(test_obj.name, {'x':test_obj.step(func_Blob_basic)}, compare_Object(enumerate_props(compare_Blob, test_obj), true), test_obj);
}, 'Object Blob object, Blob basic');
async_test(function(test_obj) {
check(test_obj.name, {'x':test_obj.step(func_Blob_bytes([0xD800]))}, compare_Object(enumerate_props(compare_Blob)), test_obj);
check(test_obj.name, {'x':test_obj.step(func_Blob_bytes([0xD800]))}, compare_Object(enumerate_props(compare_Blob, test_obj), true), test_obj);
}, 'Object Blob object, Blob unpaired high surrogate (invalid utf-8)');
async_test(function(test_obj) {
check(test_obj.name, {'x':test_obj.step(func_Blob_bytes([0xDC00]))}, compare_Object(enumerate_props(compare_Blob)), test_obj);
check(test_obj.name, {'x':test_obj.step(func_Blob_bytes([0xDC00]))}, compare_Object(enumerate_props(compare_Blob, test_obj), true), test_obj);
}, 'Object Blob object, Blob unpaired low surrogate (invalid utf-8)');
async_test(function(test_obj) {
check(test_obj.name, {'x':test_obj.step(func_Blob_bytes([0xD800, 0xDC00]))}, compare_Object(enumerate_props(compare_Blob)), test_obj);
check(test_obj.name, {'x':test_obj.step(func_Blob_bytes([0xD800, 0xDC00]))}, compare_Object(enumerate_props(compare_Blob, test_obj), true), test_obj);
}, 'Object Blob object, Blob paired surrogates (invalid utf-8)');
async_test(function(test_obj) {
check(test_obj.name, {'x':test_obj.step(func_Blob_empty)}, compare_Object(enumerate_props(compare_Blob)), test_obj);
check(test_obj.name, {'x':test_obj.step(func_Blob_empty)}, compare_Object(enumerate_props(compare_Blob, test_obj), true), test_obj);
}, 'Object Blob object, Blob empty');
async_test(function(test_obj) {
check(test_obj.name, {'x':test_obj.step(func_Blob_NUL)}, compare_Object(enumerate_props(compare_Blob)), test_obj);
check(test_obj.name, {'x':test_obj.step(func_Blob_NUL)}, compare_Object(enumerate_props(compare_Blob, test_obj), true), test_obj);
}, 'Object Blob object, Blob NUL');
function compare_File(actual, input, test_obj) {

View File

@ -9,8 +9,9 @@ function check_true(actual, msg) {
return true;
}
function check_Blob(msg, input, port, expect_File) {
function check_Blob(msg, input, port, expect_File, orig_input) {
expect_File = !!expect_File;
orig_input = orig_input || input;
try {
var expected;
switch (msg) {
@ -64,7 +65,7 @@ function check_Blob(msg, input, port, expect_File) {
check_true(view.getUint8(i) === expected[i], 'view.getUint8('+i+') === expected['+i+']')
}
if (log.length === 0) {
port.postMessage(input);
port.postMessage(orig_input);
} else {
port.postMessage('FAIL '+log);
}
@ -724,7 +725,7 @@ function check(input, port) {
case 'Array Blob object, Blob NUL':
if (check_true(input instanceof Array, 'input instanceof Array') &&
check_true(input.length === 1, 'input.length === 1')) {
check_Blob(msg.substr('Array Blob object, '.length), input[0], port);
check_Blob(msg.substr('Array Blob object, '.length), input[0], port, false, input);
// no postMessage or close here, check_Blob takes care of that
}
break;
@ -742,7 +743,7 @@ function check(input, port) {
i++;
}
if (check_true(i === 1, 'i === 1')) {
check_Blob(msg.substr('Object Blob object, '.length), input['x'], port);
check_Blob(msg.substr('Object Blob object, '.length), input['x'], port, false, input);
// no postMessage or close here, check_Blob takes care of that
}
}