mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Update web-platform-tests to revision 3137d1d2d7757366a69f8a449b458b5057e0e81e
This commit is contained in:
parent
81ca858678
commit
d6ba94ca28
2339 changed files with 89274 additions and 9328 deletions
|
@ -0,0 +1,5 @@
|
|||
[2d.composite.operation.clear.html]
|
||||
type: testharness
|
||||
[Canvas test: 2d.composite.operation.clear]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[2d.drawImage.zerocanvas.html]
|
||||
type: testharness
|
||||
[Canvas test: 2d.drawImage.zerocanvas]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[2d.drawImage.zerosource.html]
|
||||
type: testharness
|
||||
[drawImage with zero-sized source rectangle draws nothing without exception]
|
||||
expected: FAIL
|
||||
|
File diff suppressed because it is too large
Load diff
26
tests/wpt/metadata/dom/events/Event-cancelBubble.html.ini
Normal file
26
tests/wpt/metadata/dom/events/Event-cancelBubble.html.ini
Normal file
|
@ -0,0 +1,26 @@
|
|||
[Event-cancelBubble.html]
|
||||
type: testharness
|
||||
[cancelBubble must be false when an event is initially created.]
|
||||
expected: FAIL
|
||||
|
||||
[Initializing an event must set cancelBubble to false.]
|
||||
expected: FAIL
|
||||
|
||||
[stopPropagation() must set cancelBubble to true.]
|
||||
expected: FAIL
|
||||
|
||||
[stopImmediatePropagation() must set cancelBubble to true.]
|
||||
expected: FAIL
|
||||
|
||||
[Event.cancelBubble=false must have no effect.]
|
||||
expected: FAIL
|
||||
|
||||
[Event.cancelBubble=false must have no effect during event propagation.]
|
||||
expected: FAIL
|
||||
|
||||
[cancelBubble must be false after an event has been dispatched.]
|
||||
expected: FAIL
|
||||
|
||||
[Event.cancelBubble=true must set the stop propagation flag.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[Event-dispatch-bubble-canceled.html]
|
||||
type: testharness
|
||||
[Setting cancelBubble=true prior to dispatchEvent()]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[Event-dispatch-multiple-cancelBubble.html]
|
||||
type: testharness
|
||||
[Multiple dispatchEvent() and cancelBubble]
|
||||
expected: FAIL
|
||||
|
5
tests/wpt/metadata/dom/events/Event-initEvent.html.ini
Normal file
5
tests/wpt/metadata/dom/events/Event-initEvent.html.ini
Normal file
|
@ -0,0 +1,5 @@
|
|||
[Event-initEvent.html]
|
||||
type: testharness
|
||||
[Calling initEvent must unset the stop propagation flag.]
|
||||
expected: FAIL
|
||||
|
5
tests/wpt/metadata/dom/events/Event-propagation.html.ini
Normal file
5
tests/wpt/metadata/dom/events/Event-propagation.html.ini
Normal file
|
@ -0,0 +1,5 @@
|
|||
[Event-propagation.html]
|
||||
type: testharness
|
||||
[After cancelBubble=true]
|
||||
expected: FAIL
|
||||
|
5
tests/wpt/metadata/dom/nodes/Node-cloneNode.html.ini
Normal file
5
tests/wpt/metadata/dom/nodes/Node-cloneNode.html.ini
Normal file
|
@ -0,0 +1,5 @@
|
|||
[Node-cloneNode.html]
|
||||
type: testharness
|
||||
[implementation.createDocument]
|
||||
expected: FAIL
|
||||
|
|
@ -54,3 +54,21 @@
|
|||
[Fetch with POST with URLSearchParams body]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with GET and mode "cors" does not need an Origin header]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with POST and mode "same-origin" needs an Origin header]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with POST and mode "no-cors" needs an Origin header]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with PUT and mode "same-origin" needs an Origin header]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with TacO and mode "same-origin" needs an Origin header]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with TacO and mode "cors" needs an Origin header]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -54,3 +54,21 @@
|
|||
[Fetch with POST with URLSearchParams body]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with GET and mode "cors" does not need an Origin header]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with POST and mode "same-origin" needs an Origin header]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with POST and mode "no-cors" needs an Origin header]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with PUT and mode "same-origin" needs an Origin header]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with TacO and mode "same-origin" needs an Origin header]
|
||||
expected: FAIL
|
||||
|
||||
[Fetch with TacO and mode "cors" needs an Origin header]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
[headers-basic.html]
|
||||
type: testharness
|
||||
[Create headers with existing headers with custom iterator]
|
||||
expected: FAIL
|
||||
|
|
@ -1,3 +1,20 @@
|
|||
[request-idl.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
||||
[Request interface: operation arrayBuffer()]
|
||||
expected: FAIL
|
||||
|
||||
[Request interface: operation blob()]
|
||||
expected: FAIL
|
||||
|
||||
[Request interface: operation formData()]
|
||||
expected: FAIL
|
||||
|
||||
[Request interface: operation json()]
|
||||
expected: FAIL
|
||||
|
||||
[Request interface: operation text()]
|
||||
expected: FAIL
|
||||
|
||||
[Request interface: new Request("") must inherit property "arrayBuffer" with the proper type (14)]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -81,3 +81,6 @@
|
|||
[Consume response's body: from fetch to arrayBuffer]
|
||||
expected: FAIL
|
||||
|
||||
[Consume response's body: from multipart form data blob to formData]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
[response-idl.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
||||
[Response interface: attribute body]
|
||||
expected: FAIL
|
||||
|
||||
[Response interface: operation arrayBuffer()]
|
||||
expected: FAIL
|
||||
|
||||
[Response interface: operation blob()]
|
||||
expected: FAIL
|
||||
|
||||
[Response interface: operation formData()]
|
||||
expected: FAIL
|
||||
|
||||
[Response interface: operation json()]
|
||||
expected: FAIL
|
||||
|
||||
[Response interface: operation text()]
|
||||
expected: FAIL
|
||||
|
||||
[Response interface: new Response() must inherit property "body" with the proper type (8)]
|
||||
expected: FAIL
|
||||
|
||||
[Response interface: new Response() must inherit property "arrayBuffer" with the proper type (11)]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
[image.html]
|
||||
type: testharness
|
||||
[URL query: ]
|
||||
expected: FAIL
|
||||
|
||||
[URL query: ?type=]
|
||||
expected: FAIL
|
||||
|
||||
[URL query: ?type=x]
|
||||
expected: FAIL
|
||||
|
||||
[URL query: ?type=x/x]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[document-exit-fullscreen-active-document.html]
|
||||
type: testharness
|
||||
[Document#exitFullscreen() when the document is not the active document]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[document-fullscreen-enabled-active-document.html]
|
||||
type: testharness
|
||||
[Document#fullscreenEnabled when the document is not the active document]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
[element-request-fullscreen-not-allowed.html]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[Element#requestFullscreen() when not allowed to request fullscreen]
|
||||
expected: TIMEOUT
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[same-url.html]
|
||||
type: testharness
|
||||
[Test same-URL navigation and its effects on history]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
[cross-origin-objects-exceptions.html]
|
||||
type: testharness
|
||||
[Basic sanity-checking]
|
||||
expected: FAIL
|
||||
|
||||
[Only whitelisted properties are accessible cross-origin]
|
||||
expected: FAIL
|
||||
|
||||
[[[GetPrototypeOf\]\] should return null]
|
||||
expected: FAIL
|
||||
|
||||
[[[SetPrototypeOf\]\] should throw]
|
||||
expected: FAIL
|
||||
|
||||
[[[PreventExtensions\]\] should throw for cross-origin objects]
|
||||
expected: FAIL
|
||||
|
||||
[[[GetOwnProperty\]\] - Property descriptors for cross-origin properties should be set up correctly]
|
||||
expected: FAIL
|
||||
|
||||
[[[Delete\]\] Should throw on cross-origin objects]
|
||||
expected: FAIL
|
||||
|
||||
[[[DefineOwnProperty\]\] Should throw for cross-origin objects]
|
||||
expected: FAIL
|
||||
|
||||
[[[Enumerate\]\] should return an empty iterator]
|
||||
expected: FAIL
|
||||
|
||||
[[[OwnPropertyKeys\]\] should return all properties from cross-origin objects]
|
||||
expected: FAIL
|
||||
|
||||
[Cross-origin functions get local Function.prototype]
|
||||
expected: FAIL
|
||||
|
||||
[Cross-origin Window accessors get local Function.prototype]
|
||||
expected: FAIL
|
||||
|
||||
[Same-origin observers get different functions for cross-origin objects]
|
||||
expected: FAIL
|
||||
|
||||
[Same-origin observers get different accessors for cross-origin Window]
|
||||
expected: FAIL
|
||||
|
||||
[Same-origin observers get different accessors for cross-origin Location]
|
||||
expected: FAIL
|
||||
|
|
@ -9831,3 +9831,156 @@
|
|||
[MessageEvent interface: operation initMessageEvent(DOMString,boolean,boolean,any,DOMString,DOMString,[object Object\],[object Object\],[object Object\])]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: attribute onauxclick]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: iframe.contentDocument must inherit property "onauxclick" with the proper type (91)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: iframe.contentDocument must inherit property "onmousewheel" with the proper type (131)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: new Document() must inherit property "onauxclick" with the proper type (91)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: new Document() must inherit property "onmousewheel" with the proper type (131)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "onauxclick" with the proper type (91)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "onmousewheel" with the proper type (131)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLElement interface: attribute onauxclick]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLElement interface: document.createElement("noscript") must inherit property "onauxclick" with the proper type (19)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLElement interface: document.createElement("noscript") must inherit property "onmousewheel" with the proper type (59)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLElement interface: document.createElement("noscript") must inherit property "contentEditable" with the proper type (82)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLElement interface: document.createElement("noscript") must inherit property "isContentEditable" with the proper type (83)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLLinkElement interface: attribute nonce]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLLinkElement interface: attribute integrity]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLLinkElement interface: attribute referrerPolicy]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLLinkElement interface: document.createElement("link") must inherit property "nonce" with the proper type (5)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLLinkElement interface: document.createElement("link") must inherit property "integrity" with the proper type (6)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLLinkElement interface: document.createElement("link") must inherit property "sizes" with the proper type (9)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLLinkElement interface: document.createElement("link") must inherit property "referrerPolicy" with the proper type (10)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLAnchorElement interface: attribute referrerPolicy]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLAnchorElement interface: document.createElement("a") must inherit property "referrerPolicy" with the proper type (8)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLAnchorElement interface: document.createElement("a") must inherit property "charset" with the proper type (10)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLImageElement interface: attribute referrerPolicy]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLImageElement interface: document.createElement("img") must inherit property "referrerPolicy" with the proper type (13)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLImageElement interface: document.createElement("img") must inherit property "lowsrc" with the proper type (15)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLImageElement interface: new Image() must inherit property "referrerPolicy" with the proper type (13)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLImageElement interface: new Image() must inherit property "lowsrc" with the proper type (15)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLIFrameElement interface: attribute allowUserMedia]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLIFrameElement interface: attribute allowPaymentRequest]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLIFrameElement interface: attribute referrerPolicy]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLIFrameElement interface: operation getSVGDocument()]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLAreaElement interface: attribute referrerPolicy]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLAreaElement interface: document.createElement("area") must inherit property "referrerPolicy" with the proper type (8)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLAreaElement interface: document.createElement("area") must inherit property "noHref" with the proper type (9)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLAreaElement interface: document.createElement("area") must inherit property "href" with the proper type (10)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLAreaElement interface: document.createElement("area") must inherit property "origin" with the proper type (11)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLAreaElement interface: document.createElement("area") must inherit property "protocol" with the proper type (12)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLAreaElement interface: document.createElement("area") must inherit property "username" with the proper type (13)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLAreaElement interface: document.createElement("area") must inherit property "password" with the proper type (14)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLAreaElement interface: document.createElement("area") must inherit property "host" with the proper type (15)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLAreaElement interface: document.createElement("area") must inherit property "hostname" with the proper type (16)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLAreaElement interface: document.createElement("area") must inherit property "port" with the proper type (17)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLAreaElement interface: document.createElement("area") must inherit property "pathname" with the proper type (18)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLAreaElement interface: document.createElement("area") must inherit property "search" with the proper type (19)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLAreaElement interface: document.createElement("area") must inherit property "hash" with the proper type (20)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLDialogElement interface: operation show()]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLDialogElement interface: operation showModal()]
|
||||
expected: FAIL
|
||||
|
||||
[Window interface: attribute onauxclick]
|
||||
expected: FAIL
|
||||
|
||||
[Window interface: window must inherit property "onauxclick" with the proper type (39)]
|
||||
expected: FAIL
|
||||
|
||||
[Window interface: window must inherit property "onmousewheel" with the proper type (79)]
|
||||
expected: FAIL
|
||||
|
||||
[Window interface: window must inherit property "createImageBitmap" with the proper type (120)]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -10020,3 +10020,531 @@
|
|||
[style.type: IDL set to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: typeof IDL attribute]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: IDL get with DOM attribute unset]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: setAttribute() to ""]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: setAttribute() to undefined]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: setAttribute() to 7]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: setAttribute() to 1.5]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: setAttribute() to true]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: setAttribute() to false]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: setAttribute() to object "[object Object\]"]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: setAttribute() to NaN]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: setAttribute() to Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: setAttribute() to -Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: setAttribute() to "\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: setAttribute() to null]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: setAttribute() to object "test-toString"]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: setAttribute() to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: IDL set to ""]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: IDL set to undefined]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: IDL set to 7]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: IDL set to 1.5]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: IDL set to true]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: IDL set to false]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: IDL set to object "[object Object\]"]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: IDL set to NaN]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: IDL set to Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: IDL set to -Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: IDL set to "\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: IDL set to null]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: IDL set to object "test-toString"]
|
||||
expected: FAIL
|
||||
|
||||
[link.nonce: IDL set to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: typeof IDL attribute]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: IDL get with DOM attribute unset]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: setAttribute() to ""]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: setAttribute() to undefined]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: setAttribute() to 7]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: setAttribute() to 1.5]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: setAttribute() to true]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: setAttribute() to false]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: setAttribute() to object "[object Object\]"]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: setAttribute() to NaN]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: setAttribute() to Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: setAttribute() to -Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: setAttribute() to "\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: setAttribute() to null]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: setAttribute() to object "test-toString"]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: setAttribute() to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: IDL set to ""]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: IDL set to undefined]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: IDL set to 7]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: IDL set to 1.5]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: IDL set to true]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: IDL set to false]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: IDL set to object "[object Object\]"]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: IDL set to NaN]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: IDL set to Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: IDL set to -Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: IDL set to "\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: IDL set to null]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: IDL set to object "test-toString"]
|
||||
expected: FAIL
|
||||
|
||||
[link.integrity: IDL set to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: typeof IDL attribute]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL get with DOM attribute unset]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to ""]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to undefined]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to 7]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to 1.5]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to true]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to false]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to object "[object Object\]"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to NaN]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to -Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to null]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to object "test-toString"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "no-referrer"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "xno-referrer"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "no-referrer\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "o-referrer"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "NO-REFERRER"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "no-referrer-when-downgrade"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "xno-referrer-when-downgrade"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "no-referrer-when-downgrade\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "o-referrer-when-downgrade"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "NO-REFERRER-WHEN-DOWNGRADE"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "same-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "xsame-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "same-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "ame-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "SAME-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "xorigin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "rigin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "strict-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "xstrict-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "strict-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "trict-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "STRICT-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "origin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "xorigin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "origin-when-cross-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "rigin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "ORIGIN-WHEN-CROSS-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "strict-origin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "xstrict-origin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "strict-origin-when-cross-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "trict-origin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "STRICT-ORIGIN-WHEN-CROSS-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "unsafe-url"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "xunsafe-url"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "unsafe-url\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "nsafe-url"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: setAttribute() to "UNSAFE-URL"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to ""]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to undefined]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to 7]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to 1.5]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to true]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to false]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to object "[object Object\]"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to NaN]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to -Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to null]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to object "test-toString"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "no-referrer"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "xno-referrer"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "no-referrer\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "o-referrer"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "NO-REFERRER"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "no-referrer-when-downgrade"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "xno-referrer-when-downgrade"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "no-referrer-when-downgrade\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "o-referrer-when-downgrade"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "NO-REFERRER-WHEN-DOWNGRADE"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "same-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "xsame-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "same-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "ame-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "SAME-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "xorigin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "rigin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "strict-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "xstrict-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "strict-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "trict-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "STRICT-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "origin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "xorigin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "origin-when-cross-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "rigin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "ORIGIN-WHEN-CROSS-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "strict-origin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "xstrict-origin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "strict-origin-when-cross-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "trict-origin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "STRICT-ORIGIN-WHEN-CROSS-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "unsafe-url"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "xunsafe-url"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "unsafe-url\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "nsafe-url"]
|
||||
expected: FAIL
|
||||
|
||||
[link.referrerPolicy: IDL set to "UNSAFE-URL"]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -17514,3 +17514,195 @@
|
|||
[undefinedelement.tabIndex: IDL set to -2147483648]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: typeof IDL attribute]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: IDL get with DOM attribute unset]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: setAttribute() to ""]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: setAttribute() to undefined]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: setAttribute() to 7]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: setAttribute() to 1.5]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: setAttribute() to true]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: setAttribute() to false]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: setAttribute() to object "[object Object\]"]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: setAttribute() to NaN]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: setAttribute() to Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: setAttribute() to -Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: setAttribute() to "\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: setAttribute() to null]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: setAttribute() to object "test-toString"]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: setAttribute() to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: IDL set to ""]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: IDL set to undefined]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: IDL set to 7]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: IDL set to 1.5]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: IDL set to true]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: IDL set to false]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: IDL set to object "[object Object\]"]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: IDL set to NaN]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: IDL set to Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: IDL set to -Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: IDL set to "\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: IDL set to null]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: IDL set to object "test-toString"]
|
||||
expected: FAIL
|
||||
|
||||
[script.nonce: IDL set to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: typeof IDL attribute]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: IDL get with DOM attribute unset]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: setAttribute() to ""]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: setAttribute() to undefined]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: setAttribute() to 7]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: setAttribute() to 1.5]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: setAttribute() to true]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: setAttribute() to false]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: setAttribute() to object "[object Object\]"]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: setAttribute() to NaN]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: setAttribute() to Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: setAttribute() to -Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: setAttribute() to "\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: setAttribute() to null]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: setAttribute() to object "test-toString"]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: setAttribute() to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: IDL set to ""]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: IDL set to undefined]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: IDL set to 7]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: IDL set to 1.5]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: IDL set to true]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: IDL set to false]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: IDL set to object "[object Object\]"]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: IDL set to NaN]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: IDL set to Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: IDL set to -Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: IDL set to "\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: IDL set to null]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: IDL set to object "test-toString"]
|
||||
expected: FAIL
|
||||
|
||||
[script.integrity: IDL set to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -34851,3 +34851,339 @@
|
|||
[wbr.tabIndex: IDL set to -2147483648]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: typeof IDL attribute]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL get with DOM attribute unset]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to ""]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to undefined]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to 7]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to 1.5]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to true]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to false]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to object "[object Object\]"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to NaN]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to -Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to null]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to object "test-toString"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "no-referrer"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "xno-referrer"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "no-referrer\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "o-referrer"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "NO-REFERRER"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "no-referrer-when-downgrade"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "xno-referrer-when-downgrade"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "no-referrer-when-downgrade\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "o-referrer-when-downgrade"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "NO-REFERRER-WHEN-DOWNGRADE"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "same-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "xsame-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "same-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "ame-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "SAME-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "xorigin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "rigin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "strict-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "xstrict-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "strict-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "trict-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "STRICT-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "origin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "xorigin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "origin-when-cross-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "rigin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "ORIGIN-WHEN-CROSS-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "strict-origin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "xstrict-origin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "strict-origin-when-cross-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "trict-origin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "STRICT-ORIGIN-WHEN-CROSS-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "unsafe-url"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "xunsafe-url"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "unsafe-url\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "nsafe-url"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: setAttribute() to "UNSAFE-URL"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to ""]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to undefined]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to 7]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to 1.5]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to true]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to false]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to object "[object Object\]"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to NaN]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to -Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to null]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to object "test-toString"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "no-referrer"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "xno-referrer"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "no-referrer\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "o-referrer"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "NO-REFERRER"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "no-referrer-when-downgrade"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "xno-referrer-when-downgrade"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "no-referrer-when-downgrade\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "o-referrer-when-downgrade"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "NO-REFERRER-WHEN-DOWNGRADE"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "same-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "xsame-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "same-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "ame-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "SAME-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "xorigin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "rigin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "strict-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "xstrict-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "strict-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "trict-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "STRICT-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "origin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "xorigin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "origin-when-cross-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "rigin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "ORIGIN-WHEN-CROSS-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "strict-origin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "xstrict-origin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "strict-origin-when-cross-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "trict-origin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "STRICT-ORIGIN-WHEN-CROSS-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "unsafe-url"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "xunsafe-url"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "unsafe-url\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "nsafe-url"]
|
||||
expected: FAIL
|
||||
|
||||
[a.referrerPolicy: IDL set to "UNSAFE-URL"]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
[allow-scripts-flag-changing-1.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
|
@ -0,0 +1,3 @@
|
|||
[allow-scripts-flag-changing-2.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
|
@ -0,0 +1,3 @@
|
|||
[dynamic-append.html]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
|
@ -0,0 +1,3 @@
|
|||
[moving-documents.html]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
|
@ -0,0 +1,5 @@
|
|||
[not-in-shadow-tree.html]
|
||||
type: testharness
|
||||
[Meta refresh only applies while in the document tree, not in a shadow tree]
|
||||
expected: FAIL
|
||||
|
|
@ -9,9 +9,3 @@
|
|||
[iframe-sandbox-allowfullscreen-dialog]
|
||||
expected: FAIL
|
||||
|
||||
[iframe-noload-noallowfullscreen]
|
||||
expected: FAIL
|
||||
|
||||
[iframe-noload-allowfullscreen]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
[basic.html]
|
||||
type: testharness
|
||||
[window.requestIdleCallback is defined]
|
||||
expected: FAIL
|
||||
|
||||
[window.cancelIdleCallback is defined]
|
||||
expected: FAIL
|
||||
|
||||
[window.requestIdleCallback() returns a number]
|
||||
expected: FAIL
|
||||
|
||||
[window.cancelIdleCallback() returns undefined]
|
||||
expected: FAIL
|
||||
|
||||
[requestIdleCallback schedules callbacks]
|
||||
expected: FAIL
|
||||
|
||||
[cancelIdleCallback cancels callbacks]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
[callback-idle-periods.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
||||
[requestIdleCallback can run multiple different requestIdleCallback callbacks in the same idle period.]
|
||||
expected: FAIL
|
||||
|
||||
[Check that if an idle callback calls requestIdleCallback the new callback doesn't run in the current idle period.]
|
||||
expected: TIMEOUT
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
[callback-timeout-with-raf.html]
|
||||
type: testharness
|
||||
[requestIdleCallback not scheduled when event loop is busy.]
|
||||
expected: FAIL
|
||||
|
||||
[requestIdleCallback scheduled with timeout when event loop is busy.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
[event-handler-onauxclick.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
|
@ -1 +1 @@
|
|||
395981742475612eac7ef0bd484b4ae1bc1dd4a8
|
||||
81ca858678953105ee97f482eb3900729fa4d696
|
|
@ -0,0 +1,47 @@
|
|||
[nav2_idlharness.html]
|
||||
type: testharness
|
||||
[PerformanceNavigationTiming interface: existence and properties of interface object]
|
||||
expected: FAIL
|
||||
|
||||
[PerformanceNavigationTiming interface object length]
|
||||
expected: FAIL
|
||||
|
||||
[PerformanceNavigationTiming interface object name]
|
||||
expected: FAIL
|
||||
|
||||
[PerformanceNavigationTiming interface: existence and properties of interface prototype object]
|
||||
expected: FAIL
|
||||
|
||||
[PerformanceNavigationTiming interface: existence and properties of interface prototype object's "constructor" property]
|
||||
expected: FAIL
|
||||
|
||||
[PerformanceNavigationTiming interface: attribute unloadEventStart]
|
||||
expected: FAIL
|
||||
|
||||
[PerformanceNavigationTiming interface: attribute unloadEventEnd]
|
||||
expected: FAIL
|
||||
|
||||
[PerformanceNavigationTiming interface: attribute domInteractive]
|
||||
expected: FAIL
|
||||
|
||||
[PerformanceNavigationTiming interface: attribute domContentLoadedEventStart]
|
||||
expected: FAIL
|
||||
|
||||
[PerformanceNavigationTiming interface: attribute domContentLoadedEventEnd]
|
||||
expected: FAIL
|
||||
|
||||
[PerformanceNavigationTiming interface: attribute domComplete]
|
||||
expected: FAIL
|
||||
|
||||
[PerformanceNavigationTiming interface: attribute loadEventStart]
|
||||
expected: FAIL
|
||||
|
||||
[PerformanceNavigationTiming interface: attribute loadEventEnd]
|
||||
expected: FAIL
|
||||
|
||||
[PerformanceNavigationTiming interface: attribute type]
|
||||
expected: FAIL
|
||||
|
||||
[PerformanceNavigationTiming interface: attribute redirectCount]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[nav2_test_attributes_exist.html]
|
||||
type: testharness
|
||||
[Performance navigation timing entries are observable.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[nav2_test_attributes_values.html]
|
||||
type: testharness
|
||||
[Performance navigation timing instance's value is reasonable.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
[nav2_test_document_open.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
|
@ -0,0 +1,5 @@
|
|||
[nav2_test_instance_accessors.html]
|
||||
type: testharness
|
||||
[Performance navigation timing entries are accessible through three different accessors.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
[nav2_test_navigate_within_document.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
|
@ -0,0 +1,3 @@
|
|||
[nav2_test_navigation_type_backforward.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
|
@ -0,0 +1,5 @@
|
|||
[nav2_test_navigation_type_navigate.html]
|
||||
type: testharness
|
||||
[Navigation type to be navigate.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
[nav2_test_navigation_type_reload.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
|
@ -0,0 +1,3 @@
|
|||
[nav2_test_open_blank_page.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
|
@ -0,0 +1,5 @@
|
|||
[nav2_test_redirect_none.html]
|
||||
type: testharness
|
||||
[Naivation without redirects.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
[nav2_test_redirect_server.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
|
@ -0,0 +1,3 @@
|
|||
[nav2_test_redirect_xserver.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
|
@ -0,0 +1,3 @@
|
|||
[nav2_test_redirect_xserver_opt_in.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
|
@ -0,0 +1,5 @@
|
|||
[nav2_test_unique_nav_instances.html]
|
||||
type: testharness
|
||||
[Each window has a unique nav timing 2 instance.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
[nav2_test_unloadEvents_no_previous_document.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
|
@ -0,0 +1,3 @@
|
|||
[nav2_test_unloadEvents_previous_document_cross_origin.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
|
@ -0,0 +1,3 @@
|
|||
[nav2_test_unloadEvents_with_cross_origin_redirects.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
|
@ -0,0 +1,3 @@
|
|||
[nav2_test_unloadEvents_with_previous_document.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
|
@ -0,0 +1,14 @@
|
|||
[inputevent-constructor.html]
|
||||
type: testharness
|
||||
[InputEvent constructor without InputEventInit.]
|
||||
expected: FAIL
|
||||
|
||||
[InputEvent construtor with InputEventInit where data is null]
|
||||
expected: FAIL
|
||||
|
||||
[InputEvent construtor with InputEventInit where data is empty string]
|
||||
expected: FAIL
|
||||
|
||||
[InputEvent construtor with InputEventInit where data is non empty string]
|
||||
expected: FAIL
|
||||
|
8
tests/wpt/metadata/url/a-element-origin-xhtml.xhtml.ini
Normal file
8
tests/wpt/metadata/url/a-element-origin-xhtml.xhtml.ini
Normal file
|
@ -0,0 +1,8 @@
|
|||
[a-element-origin-xhtml.xhtml]
|
||||
type: testharness
|
||||
[Parsing origin: <http://[::127.0.0.1\]> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing origin: <http://[0:0:0:0:0:0:13.1.68.3\]> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
8
tests/wpt/metadata/url/a-element-origin.html.ini
Normal file
8
tests/wpt/metadata/url/a-element-origin.html.ini
Normal file
|
@ -0,0 +1,8 @@
|
|||
[a-element-origin.html]
|
||||
type: testharness
|
||||
[Parsing origin: <http://[::127.0.0.1\]> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing origin: <http://[0:0:0:0:0:0:13.1.68.3\]> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
|
@ -6,3 +6,24 @@
|
|||
[Parsing: <http://[0:0:0:0:0:0:13.1.68.3\]> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <#β> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <http://www.google.com/foo?bar=baz# »> against <about:blank>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <data:test# »> against <about:blank>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <http://foo.bar/baz?qux#foo\x08bar> against <about:blank>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <http://10000000000> against <http://other.com/>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <http://4294967296> against <http://other.com/>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <http://0xffffffff1> against <http://other.com/>]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -6,3 +6,24 @@
|
|||
[Parsing: <http://[0:0:0:0:0:0:13.1.68.3\]> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <#β> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <http://www.google.com/foo?bar=baz# »> against <about:blank>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <data:test# »> against <about:blank>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <http://foo.bar/baz?qux#foo\x08bar> against <about:blank>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <http://10000000000> against <http://other.com/>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <http://4294967296> against <http://other.com/>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <http://0xffffffff1> against <http://other.com/>]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -6,3 +6,24 @@
|
|||
[Parsing: <http://[0:0:0:0:0:0:13.1.68.3\]> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <#β> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <http://www.google.com/foo?bar=baz# »> against <about:blank>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <data:test# »> against <about:blank>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <http://foo.bar/baz?qux#foo\x08bar> against <about:blank>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <http://10000000000> against <http://other.com/>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <http://4294967296> against <http://other.com/>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <http://0xffffffff1> against <http://other.com/>]
|
||||
expected: FAIL
|
||||
|
||||
|
|
8
tests/wpt/metadata/url/url-origin.html.ini
Normal file
8
tests/wpt/metadata/url/url-origin.html.ini
Normal file
|
@ -0,0 +1,8 @@
|
|||
[url-origin.html]
|
||||
type: testharness
|
||||
[Origin parsing: <http://[::127.0.0.1\]> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
||||
[Origin parsing: <http://[0:0:0:0:0:0:13.1.68.3\]> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
|
@ -396,3 +396,18 @@
|
|||
[<area>: Setting <http://example.net>.hash = '%c3%89té' Bytes already percent-encoded are left as-is]
|
||||
expected: FAIL
|
||||
|
||||
[URL: Setting <a:/>.hash = '\x00\x01\t\n\r\x1f !"#$%&'()*+,-./09:;<=>?@AZ[\\\]^_`az{|}~Éé' Simple percent-encoding; nuls, tabs, and newlines are removed]
|
||||
expected: FAIL
|
||||
|
||||
[<a>: Setting <a:/>.hash = '\x00\x01\t\n\r\x1f !"#$%&'()*+,-./09:;<=>?@AZ[\\\]^_`az{|}~Éé' Simple percent-encoding; nuls, tabs, and newlines are removed]
|
||||
expected: FAIL
|
||||
|
||||
[<area>: Setting <a:/>.hash = '\x00\x01\t\n\r\x1f !"#$%&'()*+,-./09:;<=>?@AZ[\\\]^_`az{|}~Éé' Simple percent-encoding; nuls, tabs, and newlines are removed]
|
||||
expected: FAIL
|
||||
|
||||
[URL: Setting <http://example.net>.hash = '%c3%89té' Bytes already percent-encoded are left as-is]
|
||||
expected: FAIL
|
||||
|
||||
[<a>: Setting <http://example.net>.hash = '%c3%89té' Bytes already percent-encoded are left as-is]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -2,4 +2,3 @@
|
|||
type: testharness
|
||||
expected: TIMEOUT
|
||||
bug: https://github.com/servo/servo/issues/14380
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[headers-idl.html]
|
||||
[opaque-origin.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
|
@ -2,3 +2,4 @@
|
|||
type: testharness
|
||||
[watchAdvertisements should succeed.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ _addTest(function(canvas, ctx) {
|
|||
|
||||
ctx.globalCompositeOperation = 'xor';
|
||||
ctx.globalCompositeOperation = 'clear';
|
||||
_assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
|
||||
_assertSame(ctx.globalCompositeOperation, 'clear', "ctx.globalCompositeOperation", "'clear'");
|
||||
|
||||
|
||||
});
|
||||
|
|
|
@ -25,15 +25,15 @@ ctx.fillRect(0, 0, 100, 50);
|
|||
var canvas2 = document.createElement('canvas');
|
||||
canvas2.width = 0;
|
||||
canvas2.height = 10;
|
||||
assert_throws("INVALID_STATE_ERR", function() { ctx.drawImage(canvas2, 0, 0); });
|
||||
ctx.drawImage(canvas2, 0, 0);
|
||||
|
||||
canvas2.width = 10;
|
||||
canvas2.height = 0;
|
||||
assert_throws("INVALID_STATE_ERR", function() { ctx.drawImage(canvas2, 0, 0); });
|
||||
ctx.drawImage(canvas2, 0, 0);
|
||||
|
||||
canvas2.width = 0;
|
||||
canvas2.height = 0;
|
||||
assert_throws("INVALID_STATE_ERR", function() { ctx.drawImage(canvas2, 0, 0); });
|
||||
ctx.drawImage(canvas2, 0, 0);
|
||||
|
||||
_assertPixelApprox(canvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255", 2);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<body class="show_output">
|
||||
|
||||
<h1>2d.drawImage.zerosource</h1>
|
||||
<p class="desc">drawImage with zero-sized source rectangle throws INDEX_SIZE_ERR</p>
|
||||
<p class="desc">drawImage with zero-sized source rectangle draws nothing without exception</p>
|
||||
|
||||
|
||||
<p class="output">Actual output:</p>
|
||||
|
@ -16,14 +16,14 @@
|
|||
<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
|
||||
<ul id="d"></ul>
|
||||
<script>
|
||||
var t = async_test("drawImage with zero-sized source rectangle throws INDEX_SIZE_ERR");
|
||||
var t = async_test("drawImage with zero-sized source rectangle draws nothing without exception");
|
||||
_addTest(function(canvas, ctx) {
|
||||
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(0, 0, 100, 50);
|
||||
assert_throws("INDEX_SIZE_ERR", function() { ctx.drawImage(document.getElementById('red.png'), 10, 10, 0, 1, 0, 0, 100, 50); });
|
||||
assert_throws("INDEX_SIZE_ERR", function() { ctx.drawImage(document.getElementById('red.png'), 10, 10, 1, 0, 0, 0, 100, 50); });
|
||||
assert_throws("INDEX_SIZE_ERR", function() { ctx.drawImage(document.getElementById('red.png'), 10, 10, 0, 0, 0, 0, 100, 50); });
|
||||
ctx.drawImage(document.getElementById('red.png'), 10, 10, 0, 1, 0, 0, 100, 50);
|
||||
ctx.drawImage(document.getElementById('red.png'), 10, 10, 1, 0, 0, 0, 100, 50);
|
||||
ctx.drawImage(document.getElementById('red.png'), 10, 10, 0, 0, 0, 0, 100, 50);
|
||||
_assertPixelApprox(canvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255", 2);
|
||||
|
||||
|
||||
|
|
|
@ -1,787 +1,3 @@
|
|||
# Copyright (c) 2010 Philip Taylor
|
||||
# Released under the BSD license and W3C Test Suite License: see LICENSE.txt
|
||||
from gentestutils import genTestUtils
|
||||
|
||||
# Current code status:
|
||||
#
|
||||
# This was originally written for use at
|
||||
# http://philip.html5.org/tests/canvas/suite/tests/
|
||||
#
|
||||
# It has been adapted for use with the Web Platform Test Suite suite at
|
||||
# https://github.com/w3c/web-platform-tests/
|
||||
#
|
||||
# The W3C version excludes a number of features (multiple versions of each test
|
||||
# case of varying verbosity, Mozilla mochitests, semi-automated test harness)
|
||||
# to focus on simply providing reviewable test cases. It also expects a different
|
||||
# directory structure.
|
||||
# This code attempts to support both versions, but the non-W3C version hasn't
|
||||
# been tested recently and is probably broken.
|
||||
|
||||
# To update or add test cases:
|
||||
#
|
||||
# * Modify the tests*.yaml files.
|
||||
# 'name' is an arbitrary hierarchical name to help categorise tests.
|
||||
# 'desc' is a rough description of what behaviour the test aims to test.
|
||||
# 'testing' is a list of references to spec.yaml, to show which spec sentences
|
||||
# this test case is primarily testing.
|
||||
# 'code' is JavaScript code to execute, with some special commands starting with '@'
|
||||
# 'expected' is what the final canvas output should be: a string 'green' or 'clear'
|
||||
# (100x50 images in both cases), or a string 'size 100 50' (or any other size)
|
||||
# followed by Python code using Pycairo to generate the image.
|
||||
#
|
||||
# * Run "python gentest.py".
|
||||
# This requires a few Python modules which might not be ubiquitous.
|
||||
# It has only been tested on Linux.
|
||||
# It will usually emit some warnings, which ideally should be fixed but can
|
||||
# generally be safely ignored.
|
||||
#
|
||||
# * Test the tests, add new ones to Git, remove deleted ones from Git, etc.
|
||||
|
||||
import re
|
||||
import codecs
|
||||
import time
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import xml.dom.minidom
|
||||
from xml.dom.minidom import Node
|
||||
|
||||
import cairo
|
||||
|
||||
try:
|
||||
import syck as yaml # compatible and lots faster
|
||||
except ImportError:
|
||||
import yaml
|
||||
|
||||
# Default mode is for the W3C test suite; the --standalone option
|
||||
# generates various extra files that aren't needed there
|
||||
W3CMODE = True
|
||||
if '--standalone' in sys.argv:
|
||||
W3CMODE = False
|
||||
|
||||
TESTOUTPUTDIR = '../../2dcontext'
|
||||
IMAGEOUTPUTDIR = '../../2dcontext'
|
||||
MISCOUTPUTDIR = './output'
|
||||
SPECOUTPUTDIR = '../../annotated-spec'
|
||||
|
||||
SPECOUTPUTPATH = '../annotated-spec' # relative to TESTOUTPUTDIR
|
||||
|
||||
def simpleEscapeJS(str):
|
||||
return str.replace('\\', '\\\\').replace('"', '\\"')
|
||||
|
||||
def escapeJS(str):
|
||||
str = simpleEscapeJS(str)
|
||||
str = re.sub(r'\[(\w+)\]', r'[\\""+(\1)+"\\"]', str) # kind of an ugly hack, for nicer failure-message output
|
||||
return str
|
||||
|
||||
def escapeHTML(str):
|
||||
return str.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"')
|
||||
|
||||
def expand_nonfinite(method, argstr, tail):
|
||||
"""
|
||||
>>> print expand_nonfinite('f', '<0 a>, <0 b>', ';')
|
||||
f(a, 0);
|
||||
f(0, b);
|
||||
f(a, b);
|
||||
>>> print expand_nonfinite('f', '<0 a>, <0 b c>, <0 d>', ';')
|
||||
f(a, 0, 0);
|
||||
f(0, b, 0);
|
||||
f(0, c, 0);
|
||||
f(0, 0, d);
|
||||
f(a, b, 0);
|
||||
f(a, b, d);
|
||||
f(a, 0, d);
|
||||
f(0, b, d);
|
||||
"""
|
||||
# argstr is "<valid-1 invalid1-1 invalid2-1 ...>, ..." (where usually
|
||||
# 'invalid' is Infinity/-Infinity/NaN)
|
||||
args = []
|
||||
for arg in argstr.split(', '):
|
||||
a = re.match('<(.*)>', arg).group(1)
|
||||
args.append(a.split(' '))
|
||||
calls = []
|
||||
# Start with the valid argument list
|
||||
call = [ args[j][0] for j in range(len(args)) ]
|
||||
# For each argument alone, try setting it to all its invalid values:
|
||||
for i in range(len(args)):
|
||||
for a in args[i][1:]:
|
||||
c2 = call[:]
|
||||
c2[i] = a
|
||||
calls.append(c2)
|
||||
# For all combinations of >= 2 arguments, try setting them to their
|
||||
# first invalid values. (Don't do all invalid values, because the
|
||||
# number of combinations explodes.)
|
||||
def f(c, start, depth):
|
||||
for i in range(start, len(args)):
|
||||
if len(args[i]) > 1:
|
||||
a = args[i][1]
|
||||
c2 = c[:]
|
||||
c2[i] = a
|
||||
if depth > 0: calls.append(c2)
|
||||
f(c2, i+1, depth+1)
|
||||
f(call, 0, 0)
|
||||
|
||||
return '\n'.join('%s(%s)%s' % (method, ', '.join(c), tail) for c in calls)
|
||||
|
||||
# Run with --test argument to run unit tests
|
||||
if len(sys.argv) > 1 and sys.argv[1] == '--test':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
sys.exit()
|
||||
|
||||
templates = yaml.load(open('templates.yaml', "r").read())
|
||||
name_mapping = yaml.load(open('name2dir.yaml', "r").read())
|
||||
|
||||
spec_assertions = []
|
||||
for s in yaml.load(open('spec.yaml', "r").read())['assertions']:
|
||||
if 'meta' in s:
|
||||
eval(compile(s['meta'], '<meta spec assertion>', 'exec'), {}, {'assertions':spec_assertions})
|
||||
else:
|
||||
spec_assertions.append(s)
|
||||
|
||||
tests = []
|
||||
for t in sum([ yaml.load(open(f, "r").read()) for f in ['tests.yaml', 'tests2d.yaml', 'tests2dtext.yaml']], []):
|
||||
if 'DISABLED' in t:
|
||||
continue
|
||||
if 'meta' in t:
|
||||
eval(compile(t['meta'], '<meta test>', 'exec'), {}, {'tests':tests})
|
||||
else:
|
||||
tests.append(t)
|
||||
|
||||
category_names = []
|
||||
category_contents_direct = {}
|
||||
category_contents_all = {}
|
||||
|
||||
spec_ids = {}
|
||||
for t in spec_assertions: spec_ids[t['id']] = True
|
||||
spec_refs = {}
|
||||
|
||||
def backref_html(name):
|
||||
backrefs = []
|
||||
c = ''
|
||||
for p in name.split('.')[:-1]:
|
||||
c += '.'+p
|
||||
backrefs.append('<a href="index%s.html">%s</a>.' % (c, p))
|
||||
backrefs.append(name.split('.')[-1])
|
||||
return ''.join(backrefs)
|
||||
|
||||
def make_flat_image(filename, w, h, r,g,b,a):
|
||||
if os.path.exists('%s/%s' % (IMAGEOUTPUTDIR, filename)):
|
||||
return filename
|
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
|
||||
cr = cairo.Context(surface)
|
||||
cr.set_source_rgba(r, g, b, a)
|
||||
cr.rectangle(0, 0, w, h)
|
||||
cr.fill()
|
||||
surface.write_to_png('%s/%s' % (IMAGEOUTPUTDIR, filename))
|
||||
return filename
|
||||
|
||||
# Ensure the test output directories exist
|
||||
testdirs = [TESTOUTPUTDIR, IMAGEOUTPUTDIR, MISCOUTPUTDIR]
|
||||
if not W3CMODE: testdirs.append('%s/mochitests' % MISCOUTPUTDIR)
|
||||
else:
|
||||
for map_dir in set(name_mapping.values()):
|
||||
testdirs.append("%s/%s" % (TESTOUTPUTDIR, map_dir))
|
||||
for d in testdirs:
|
||||
try: os.mkdir(d)
|
||||
except: pass # ignore if it already exists
|
||||
|
||||
mochitests = []
|
||||
used_images = {}
|
||||
|
||||
def expand_test_code(code):
|
||||
code = re.sub(r'@nonfinite ([^(]+)\(([^)]+)\)(.*)', lambda m: expand_nonfinite(m.group(1), m.group(2), m.group(3)), code) # must come before '@assert throws'
|
||||
|
||||
code = re.sub(r'@assert pixel (\d+,\d+) == (\d+,\d+,\d+,\d+);',
|
||||
r'_assertPixel(canvas, \1, \2, "\1", "\2");',
|
||||
code)
|
||||
|
||||
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+);',
|
||||
r'_assertPixelApprox(canvas, \1, \2, "\1", "\2", 2);',
|
||||
code)
|
||||
|
||||
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);',
|
||||
r'_assertPixelApprox(canvas, \1, \2, "\1", "\2", \3);',
|
||||
code)
|
||||
|
||||
code = re.sub(r'@assert throws (\S+_ERR) (.*);',
|
||||
r'assert_throws("\1", function() { \2; });',
|
||||
code)
|
||||
|
||||
code = re.sub(r'@assert throws (\S+Error) (.*);',
|
||||
r'assert_throws(new \1(), function() { \2; });',
|
||||
code)
|
||||
|
||||
code = re.sub(r'@assert throws (.*);',
|
||||
r'assert_throws(null, function() { \1; });',
|
||||
code)
|
||||
|
||||
code = re.sub(r'@assert (.*) === (.*);',
|
||||
lambda m: '_assertSame(%s, %s, "%s", "%s");'
|
||||
% (m.group(1), m.group(2), escapeJS(m.group(1)), escapeJS(m.group(2)))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'@assert (.*) !== (.*);',
|
||||
lambda m: '_assertDifferent(%s, %s, "%s", "%s");'
|
||||
% (m.group(1), m.group(2), escapeJS(m.group(1)), escapeJS(m.group(2)))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'@assert (.*) =~ (.*);',
|
||||
lambda m: 'assert_regexp_match(%s, %s);'
|
||||
% (m.group(1), m.group(2))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'@assert (.*);',
|
||||
lambda m: '_assert(%s, "%s");'
|
||||
% (m.group(1), escapeJS(m.group(1)))
|
||||
, code)
|
||||
|
||||
code = re.sub(r' @moz-todo', '', code)
|
||||
|
||||
code = re.sub(r'@moz-UniversalBrowserRead;',
|
||||
""
|
||||
, code)
|
||||
|
||||
assert('@' not in code)
|
||||
|
||||
return code
|
||||
|
||||
def expand_mochitest_code(code):
|
||||
code = re.sub(r'@nonfinite ([^(]+)\(([^)]+)\)(.*)', lambda m: expand_nonfinite(m.group(1), m.group(2), m.group(3)), code)
|
||||
|
||||
code = re.sub(r'@assert pixel (\d+,\d+) == (\d+,\d+,\d+,\d+);',
|
||||
r'isPixel(ctx, \1, \2, "\1", "\2", 0);',
|
||||
code)
|
||||
|
||||
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+);',
|
||||
r'isPixel(ctx, \1, \2, "\1", "\2", 2);',
|
||||
code)
|
||||
|
||||
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);',
|
||||
r'isPixel(ctx, \1, \2, "\1", "\2", \3);',
|
||||
code)
|
||||
|
||||
code = re.sub(r'@assert throws (\S+_ERR) (.*);',
|
||||
lambda m: 'var _thrown = undefined; try {\n %s;\n} catch (e) { _thrown = e }; ok(_thrown && _thrown.code == DOMException.%s, "should throw %s");'
|
||||
% (m.group(2), m.group(1), m.group(1))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'@assert throws (\S+Error) (.*);',
|
||||
lambda m: 'var _thrown = undefined; try {\n %s;\n} catch (e) { _thrown = e }; ok(_thrown && (_thrown instanceof %s), "should throw %s");'
|
||||
% (m.group(2), m.group(1), m.group(1))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'@assert throws (.*);',
|
||||
lambda m: 'try { var _thrown = false;\n %s;\n} catch (e) { _thrown = true; } finally { ok(_thrown, "should throw exception"); }'
|
||||
% (m.group(1))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'@assert (.*) =~ (.*);',
|
||||
lambda m: 'ok(%s.match(%s), "%s.match(%s)");'
|
||||
% (m.group(1), m.group(2), escapeJS(m.group(1)), escapeJS(m.group(2)))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'@assert (.*);',
|
||||
lambda m: 'ok(%s, "%s");'
|
||||
% (m.group(1), escapeJS(m.group(1)))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'((?:^|\n|;)\s*)ok(.*;) @moz-todo',
|
||||
lambda m: '%stodo%s'
|
||||
% (m.group(1), m.group(2))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'((?:^|\n|;)\s*)(is.*;) @moz-todo',
|
||||
lambda m: '%stodo_%s'
|
||||
% (m.group(1), m.group(2))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'@moz-UniversalBrowserRead;',
|
||||
"netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');"
|
||||
, code)
|
||||
|
||||
code = code.replace('../images/', 'image_')
|
||||
|
||||
assert '@' not in code, '@ not in code:\n%s' % code
|
||||
|
||||
return code
|
||||
|
||||
used_tests = {}
|
||||
for i in range(len(tests)):
|
||||
test = tests[i]
|
||||
|
||||
name = test['name']
|
||||
print "\r(%s)" % name, " "*32, "\t",
|
||||
|
||||
if name in used_tests:
|
||||
print "Test %s is defined twice" % name
|
||||
used_tests[name] = 1
|
||||
|
||||
mapped_name = None
|
||||
for mn in sorted(name_mapping.keys(), key=len, reverse=True):
|
||||
if name.startswith(mn):
|
||||
mapped_name = "%s/%s" % (name_mapping[mn], name)
|
||||
break
|
||||
if not mapped_name:
|
||||
print "LIKELY ERROR: %s has no defined target directory mapping" % name
|
||||
mapped_name = name
|
||||
if 'manual' in test:
|
||||
mapped_name += "-manual"
|
||||
|
||||
cat_total = ''
|
||||
for cat_part in [''] + name.split('.')[:-1]:
|
||||
cat_total += cat_part+'.'
|
||||
if not cat_total in category_names: category_names.append(cat_total)
|
||||
category_contents_all.setdefault(cat_total, []).append(name)
|
||||
category_contents_direct.setdefault(cat_total, []).append(name)
|
||||
|
||||
for ref in test.get('testing', []):
|
||||
if ref not in spec_ids:
|
||||
print "Test %s uses nonexistent spec point %s" % (name, ref)
|
||||
spec_refs.setdefault(ref, []).append(name)
|
||||
#if not (len(test.get('testing', [])) or 'mozilla' in test):
|
||||
if not test.get('testing', []):
|
||||
print "Test %s doesn't refer to any spec points" % name
|
||||
|
||||
if test.get('expected', '') == 'green' and re.search(r'@assert pixel .* 0,0,0,0;', test['code']):
|
||||
print "Probable incorrect pixel test in %s" % name
|
||||
|
||||
code = expand_test_code(test['code'])
|
||||
|
||||
mochitest = not (W3CMODE or 'manual' in test or 'disabled' in test.get('mozilla', {}))
|
||||
if mochitest:
|
||||
mochi_code = expand_mochitest_code(test['code'])
|
||||
|
||||
mochi_name = name
|
||||
if 'mozilla' in test:
|
||||
if 'throws' in test['mozilla']:
|
||||
mochi_code = templates['mochitest.exception'] % mochi_code
|
||||
if 'bug' in test['mozilla']:
|
||||
mochi_name = "%s - bug %s" % (name, test['mozilla']['bug'])
|
||||
|
||||
if 'desc' in test:
|
||||
mochi_desc = '<!-- Testing: %s -->\n' % test['desc']
|
||||
else:
|
||||
mochi_desc = ''
|
||||
|
||||
if 'deferTest' in mochi_code:
|
||||
mochi_setup = ''
|
||||
mochi_footer = ''
|
||||
else:
|
||||
mochi_setup = ''
|
||||
mochi_footer = 'SimpleTest.finish();\n'
|
||||
|
||||
for f in ['isPixel', 'todo_isPixel', 'deferTest', 'wrapFunction']:
|
||||
if f in mochi_code:
|
||||
mochi_setup += templates['mochitest.%s' % f]
|
||||
else:
|
||||
if not W3CMODE:
|
||||
print "Skipping mochitest for %s" % name
|
||||
mochi_name = ''
|
||||
mochi_desc = ''
|
||||
mochi_code = ''
|
||||
mochi_setup = ''
|
||||
mochi_footer = ''
|
||||
|
||||
expectation_html = ''
|
||||
if 'expected' in test and test['expected'] is not None:
|
||||
expected = test['expected']
|
||||
expected_img = None
|
||||
if expected == 'green':
|
||||
expected_img = make_flat_image('green-100x50.png', 100, 50, 0,1,0,1)
|
||||
if W3CMODE: expected_img = "/images/" + expected_img
|
||||
elif expected == 'clear':
|
||||
expected_img = make_flat_image('clear-100x50.png', 100, 50, 0,0,0,0)
|
||||
if W3CMODE: expected_img = "/images/" + expected_img
|
||||
else:
|
||||
if ';' in expected: print "Found semicolon in %s" % name
|
||||
expected = re.sub(r'^size (\d+) (\d+)',
|
||||
r'surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \1, \2)\ncr = cairo.Context(surface)',
|
||||
expected)
|
||||
|
||||
if mapped_name.endswith("-manual"):
|
||||
png_name = mapped_name[:-len("-manual")]
|
||||
else:
|
||||
png_name = mapped_name
|
||||
expected += "\nsurface.write_to_png('%s/%s.png')\n" % (IMAGEOUTPUTDIR, png_name)
|
||||
eval(compile(expected, '<test %s>' % test['name'], 'exec'), {}, {'cairo':cairo})
|
||||
expected_img = "%s.png" % name
|
||||
|
||||
if expected_img:
|
||||
expectation_html = ('<p class="output expectedtext">Expected output:' +
|
||||
'<p><img src="%s" class="output expected" id="expected" alt="">' % (expected_img))
|
||||
|
||||
canvas = test.get('canvas', 'width="100" height="50"')
|
||||
|
||||
prev = tests[i-1]['name'] if i != 0 else 'index'
|
||||
next = tests[i+1]['name'] if i != len(tests)-1 else 'index'
|
||||
|
||||
name_wrapped = name.replace('.', '.​') # (see https://bugzilla.mozilla.org/show_bug.cgi?id=376188)
|
||||
|
||||
refs = ''.join('<li><a href="%s/canvas.html#testrefs.%s">%s</a>\n' % (SPECOUTPUTPATH, n,n) for n in test.get('testing', []))
|
||||
if not W3CMODE and 'mozilla' in test and 'bug' in test['mozilla']:
|
||||
refs += '<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=%d">Bugzilla</a>' % test['mozilla']['bug']
|
||||
|
||||
notes = '<p class="notes">%s' % test['notes'] if 'notes' in test else ''
|
||||
|
||||
scripts = ''
|
||||
for s in test.get('scripts', []):
|
||||
scripts += '<script src="%s"></script>\n' % (s)
|
||||
|
||||
images = ''
|
||||
for i in test.get('images', []):
|
||||
id = i.split('/')[-1]
|
||||
if '/' not in i:
|
||||
used_images[i] = 1
|
||||
i = '../images/%s' % i
|
||||
images += '<img src="%s" id="%s" class="resource">\n' % (i,id)
|
||||
mochi_images = images.replace('../images/', 'image_')
|
||||
if W3CMODE: images = images.replace("../images/", "/images/")
|
||||
|
||||
fonts = ''
|
||||
fonthack = ''
|
||||
for i in test.get('fonts', []):
|
||||
fonts += '@font-face {\n font-family: %s;\n src: url("/fonts/%s.ttf");\n}\n' % (i, i)
|
||||
# Browsers require the font to actually be used in the page
|
||||
if test.get('fonthack', 1):
|
||||
fonthack += '<span style="font-family: %s; position: absolute; visibility: hidden">A</span>\n' % i
|
||||
if fonts:
|
||||
fonts = '<style>\n%s</style>\n' % fonts
|
||||
|
||||
fallback = test.get('fallback', '<p class="fallback">FAIL (fallback content)</p>')
|
||||
|
||||
desc = test.get('desc', '')
|
||||
escaped_desc = simpleEscapeJS(desc)
|
||||
template_params = {
|
||||
'name':name, 'name_wrapped':name_wrapped, 'backrefs':backref_html(name),
|
||||
'mapped_name':mapped_name,
|
||||
'desc':desc, 'escaped_desc':escaped_desc,
|
||||
'prev':prev, 'next':next, 'refs':refs, 'notes':notes, 'images':images,
|
||||
'fonts':fonts, 'fonthack':fonthack,
|
||||
'canvas':canvas, 'expected':expectation_html, 'code':code, 'scripts':scripts,
|
||||
'mochi_name':mochi_name, 'mochi_desc':mochi_desc, 'mochi_code':mochi_code,
|
||||
'mochi_setup':mochi_setup, 'mochi_footer':mochi_footer, 'mochi_images':mochi_images,
|
||||
'fallback':fallback
|
||||
}
|
||||
|
||||
if W3CMODE:
|
||||
f = codecs.open('%s/%s.html' % (TESTOUTPUTDIR, mapped_name), 'w', 'utf-8')
|
||||
f.write(templates['w3c'] % template_params)
|
||||
else:
|
||||
f = codecs.open('%s/%s.html' % (TESTOUTPUTDIR, name), 'w', 'utf-8')
|
||||
f.write(templates['standalone'] % template_params)
|
||||
|
||||
f = codecs.open('%s/framed.%s.html' % (TESTOUTPUTDIR, name), 'w', 'utf-8')
|
||||
f.write(templates['framed'] % template_params)
|
||||
|
||||
f = codecs.open('%s/minimal.%s.html' % (TESTOUTPUTDIR, name), 'w', 'utf-8')
|
||||
f.write(templates['minimal'] % template_params)
|
||||
|
||||
if mochitest:
|
||||
mochitests.append(name)
|
||||
f = codecs.open('%s/mochitests/test_%s.html' % (MISCOUTPUTDIR, name), 'w', 'utf-8')
|
||||
f.write(templates['mochitest'] % template_params)
|
||||
|
||||
def write_mochitest_makefile():
|
||||
f = open('%s/mochitests/Makefile.in' % MISCOUTPUTDIR, 'w')
|
||||
f.write(templates['mochitest.Makefile'])
|
||||
files = ['test_%s.html' % n for n in mochitests] + ['image_%s' % n for n in used_images]
|
||||
chunksize = 100
|
||||
chunks = []
|
||||
for i in range(0, len(files), chunksize):
|
||||
chunk = files[i:i+chunksize]
|
||||
name = '_TEST_FILES_%d' % (i / chunksize)
|
||||
chunks.append(name)
|
||||
f.write('%s = \\\n' % name)
|
||||
for file in chunk: f.write('\t%s \\\n' % file)
|
||||
f.write('\t$(NULL)\n\n')
|
||||
f.write('# split up into groups to work around command-line length limits\n')
|
||||
for name in chunks:
|
||||
f.write('libs:: $(%s)\n\t$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)\n\n' % name)
|
||||
|
||||
if not W3CMODE:
|
||||
for i in used_images:
|
||||
shutil.copyfile("../../images/%s" % i, "%s/mochitests/image_%s" % (MISCOUTPUTDIR, i))
|
||||
write_mochitest_makefile()
|
||||
|
||||
print
|
||||
|
||||
def write_index():
|
||||
f = open('%s/index.html' % TESTOUTPUTDIR, 'w')
|
||||
f.write(templates['index.w3c' if W3CMODE else 'index'] % { 'updated':time.strftime('%Y-%m-%d', time.gmtime()) })
|
||||
f.write('\n<ul class="testlist">\n')
|
||||
depth = 1
|
||||
for category in category_names:
|
||||
name = category[1:-1] or ''
|
||||
count = len(category_contents_all[category])
|
||||
new_depth = category.count('.')
|
||||
while new_depth < depth: f.write(' '*(depth-1) + '</ul>\n'); depth -= 1
|
||||
f.write(' '*depth + templates['index.w3c.category.item' if W3CMODE else 'index.category.item'] % (name or 'all', name, count, '' if count==1 else 's'))
|
||||
while new_depth+1 > depth: f.write(' '*depth + '<ul>\n'); depth += 1
|
||||
for item in category_contents_direct.get(category, []):
|
||||
f.write(' '*depth + '<li><a href="%s.html">%s</a>\n' % (item, item) )
|
||||
while 0 < depth: f.write(' '*(depth-1) + '</ul>\n'); depth -= 1
|
||||
|
||||
def write_category_indexes():
|
||||
for category in category_names:
|
||||
name = (category[1:-1] or 'all')
|
||||
|
||||
f = open('%s/index.%s.html' % (TESTOUTPUTDIR, name), 'w')
|
||||
f.write(templates['index.w3c.frame' if W3CMODE else 'index.frame'] % { 'backrefs':backref_html(name), 'category':name })
|
||||
for item in category_contents_all[category]:
|
||||
f.write(templates['index.w3c.frame.item' if W3CMODE else 'index.frame.item'] % item)
|
||||
|
||||
def write_reportgen():
|
||||
f = open('%s/reportgen.html' % MISCOUTPUTDIR, 'w')
|
||||
items_text = ',\n'.join(('"%s"' % item) for item in category_contents_all['.'])
|
||||
f.write(templates['reportgen'] % {'items':items_text })
|
||||
|
||||
def write_results():
|
||||
results = {}
|
||||
uas = []
|
||||
uastrings = {}
|
||||
for item in category_contents_all['.']: results[item] = {}
|
||||
|
||||
f = open('%s/results.html' % MISCOUTPUTDIR, 'w')
|
||||
f.write(templates['results'])
|
||||
|
||||
if not os.path.exists('results.yaml'):
|
||||
print "Can't find results.yaml"
|
||||
else:
|
||||
for resultset in yaml.load(open('results.yaml', "r").read()):
|
||||
#title = "%s (%s)" % (resultset['ua'], resultset['time'])
|
||||
title = resultset['name']
|
||||
#assert title not in uas # don't allow repetitions
|
||||
if title not in uas:
|
||||
uas.append(title)
|
||||
uastrings[title] = resultset['ua']
|
||||
else:
|
||||
assert uastrings[title] == resultset['ua']
|
||||
for r in resultset['results']:
|
||||
if r['id'] not in results:
|
||||
print 'Skipping results for removed test %s' % r['id']
|
||||
continue
|
||||
results[r['id']][title] = (
|
||||
r['status'].lower(),
|
||||
re.sub(r'%(..)', lambda m: chr(int(m.group(1), 16)),
|
||||
re.sub(r'%u(....)', lambda m: unichr(int(m.group(1), 16)),
|
||||
r['notes'])).encode('utf8')
|
||||
)
|
||||
|
||||
passes = {}
|
||||
for ua in uas:
|
||||
f.write('<th title="%s">%s\n' % (uastrings[ua], ua))
|
||||
passes[ua] = 0
|
||||
for id in category_contents_all['.']:
|
||||
f.write('<tr><td><a href="#%s" id="%s">#</a> <a href="%s.html">%s</a>\n' % (id, id, id, id))
|
||||
for ua in uas:
|
||||
status, details = results[id].get(ua, ('', ''))
|
||||
f.write('<td class="r %s"><ul class="d">%s</ul>\n' % (status, details))
|
||||
if status == 'pass': passes[ua] += 1
|
||||
f.write('<tr><th>Passes\n')
|
||||
for ua in uas:
|
||||
f.write('<td>%.1f%%\n' % ((100.0 * passes[ua]) / len(category_contents_all['.'])))
|
||||
f.write('<tr><td>\n')
|
||||
for ua in uas:
|
||||
f.write('<td>%s\n' % ua)
|
||||
f.write('</table>\n')
|
||||
|
||||
def getNodeText(node):
|
||||
t, offsets = '', []
|
||||
|
||||
# Skip over any previous annotations we added
|
||||
if node.nodeType == node.ELEMENT_NODE and 'testrefs' in node.getAttribute('class').split(' '):
|
||||
return t, offsets
|
||||
|
||||
if node.nodeType == node.TEXT_NODE:
|
||||
val = node.nodeValue
|
||||
val = val.replace(unichr(0xa0), ' ') # replace s
|
||||
t += val
|
||||
offsets += [ (node, len(node.nodeValue)) ]
|
||||
for n in node.childNodes:
|
||||
child_t, child_offsets = getNodeText(n)
|
||||
t += child_t
|
||||
offsets += child_offsets
|
||||
return t, offsets
|
||||
|
||||
def htmlSerializer(element):
|
||||
element.normalize()
|
||||
rv = []
|
||||
specialtext = ['style', 'script', 'xmp', 'iframe', 'noembed', 'noframes', 'noscript']
|
||||
empty = ['area', 'base', 'basefont', 'bgsound', 'br', 'col', 'embed', 'frame',
|
||||
'hr', 'img', 'input', 'link', 'meta', 'param', 'spacer', 'wbr']
|
||||
|
||||
def serializeElement(element):
|
||||
if element.nodeType == Node.DOCUMENT_TYPE_NODE:
|
||||
rv.append("<!DOCTYPE %s>" % element.name)
|
||||
elif element.nodeType == Node.DOCUMENT_NODE:
|
||||
for child in element.childNodes:
|
||||
serializeElement(child)
|
||||
elif element.nodeType == Node.COMMENT_NODE:
|
||||
rv.append("<!--%s-->" % element.nodeValue)
|
||||
elif element.nodeType == Node.TEXT_NODE:
|
||||
unescaped = False
|
||||
n = element.parentNode
|
||||
while n is not None:
|
||||
if n.nodeName in specialtext:
|
||||
unescaped = True
|
||||
break
|
||||
n = n.parentNode
|
||||
if unescaped:
|
||||
rv.append(element.nodeValue)
|
||||
else:
|
||||
rv.append(escapeHTML(element.nodeValue))
|
||||
else:
|
||||
rv.append("<%s" % element.nodeName)
|
||||
if element.hasAttributes():
|
||||
for name, value in element.attributes.items():
|
||||
rv.append(' %s="%s"' % (name, escapeHTML(value)))
|
||||
rv.append(">")
|
||||
if element.nodeName not in empty:
|
||||
for child in element.childNodes:
|
||||
serializeElement(child)
|
||||
rv.append("</%s>" % element.nodeName)
|
||||
serializeElement(element)
|
||||
return '<!DOCTYPE html>\n' + ''.join(rv)
|
||||
|
||||
def write_annotated_spec():
|
||||
# Load the stripped-down XHTMLised copy of the spec
|
||||
doc = xml.dom.minidom.parse(open('current-work-canvas.xhtml', 'r'))
|
||||
|
||||
# Insert our new stylesheet
|
||||
n = doc.getElementsByTagName('head')[0].appendChild(doc.createElement('link'))
|
||||
n.setAttribute('rel', 'stylesheet')
|
||||
n.setAttribute('href', '../common/canvas-spec.css' if W3CMODE else '../spectest.css')
|
||||
n.setAttribute('type', 'text/css')
|
||||
|
||||
spec_assertion_patterns = []
|
||||
for a in spec_assertions:
|
||||
# Warn about problems
|
||||
if a['id'] not in spec_refs:
|
||||
print "Unused spec statement %s" % a['id']
|
||||
|
||||
pattern_text = a['text']
|
||||
|
||||
if 'keyword' in a:
|
||||
# Explicit keyword override
|
||||
keyword = a['keyword']
|
||||
else:
|
||||
# Extract the marked keywords, and remove the markers
|
||||
keyword = 'none'
|
||||
for kw in ['must', 'should', 'required']:
|
||||
if ('*%s*' % kw) in pattern_text:
|
||||
keyword = kw
|
||||
pattern_text = pattern_text.replace('*%s*' % kw, kw)
|
||||
break
|
||||
# Make sure there wasn't >1 keyword
|
||||
for kw in ['must', 'should', 'required']:
|
||||
assert('*%s*' % kw not in pattern_text)
|
||||
|
||||
# Convert the special pattern format into regexp syntax
|
||||
pattern_text = (pattern_text.
|
||||
# Escape relevant characters
|
||||
replace('*', r'\*').
|
||||
replace('+', r'\+').
|
||||
replace('.', r'\.').
|
||||
replace('(', r'\(').
|
||||
replace(')', r'\)').
|
||||
replace('[', r'\[').
|
||||
replace(']', r'\]').
|
||||
# Convert special sequences back into unescaped regexp code
|
||||
replace(' ', r'\s+').
|
||||
replace(r'<\.\.\.>', r'.+').
|
||||
replace('<^>', r'()').
|
||||
replace('<eol>', r'\s*?\n')
|
||||
)
|
||||
pattern = re.compile(pattern_text, re.S)
|
||||
spec_assertion_patterns.append( (a['id'], pattern, keyword, a.get('previously', None)) )
|
||||
matched_assertions = {}
|
||||
|
||||
def process_element(e):
|
||||
if e.nodeType == e.ELEMENT_NODE and (e.getAttribute('class') == 'impl' or e.hasAttribute('data-component')):
|
||||
for c in e.childNodes:
|
||||
process_element(c)
|
||||
return
|
||||
|
||||
t, offsets = getNodeText(e)
|
||||
for id, pattern, keyword, previously in spec_assertion_patterns:
|
||||
m = pattern.search(t)
|
||||
if m:
|
||||
# When the pattern-match isn't enough to uniquely identify a sentence,
|
||||
# allow explicit back-references to earlier paragraphs
|
||||
if previously:
|
||||
if len(previously) >= 3:
|
||||
n, text, exp = previously
|
||||
else:
|
||||
n, text = previously
|
||||
exp = True
|
||||
node = e
|
||||
while n and node.previousSibling:
|
||||
node = node.previousSibling
|
||||
n -= 1
|
||||
if (text not in getNodeText(node)[0]) == exp:
|
||||
continue # discard this match
|
||||
|
||||
if id in matched_assertions:
|
||||
print "Spec statement %s matches multiple places" % id
|
||||
matched_assertions[id] = True
|
||||
|
||||
if m.lastindex != 1:
|
||||
print "Spec statement %s has incorrect number of match groups" % id
|
||||
|
||||
end = m.end(1)
|
||||
end_node = None
|
||||
for end_node, o in offsets:
|
||||
if end < o:
|
||||
break
|
||||
end -= o
|
||||
assert(end_node)
|
||||
|
||||
n1 = doc.createElement('span')
|
||||
n1.setAttribute('class', 'testrefs kw-%s' % keyword)
|
||||
n1.setAttribute('id', 'testrefs.%s' % id)
|
||||
n1.appendChild(doc.createTextNode(' '))
|
||||
|
||||
n = n1.appendChild(doc.createElement('a'))
|
||||
n.setAttribute('href', '#testrefs.%s' % id)
|
||||
n.setAttribute('title', id)
|
||||
n.appendChild(doc.createTextNode('#'))
|
||||
|
||||
n1.appendChild(doc.createTextNode(' '))
|
||||
for test_id in spec_refs.get(id, []):
|
||||
n = n1.appendChild(doc.createElement('a'))
|
||||
n.setAttribute('href', '../canvas/%s.html' % test_id)
|
||||
n.appendChild(doc.createTextNode(test_id))
|
||||
n1.appendChild(doc.createTextNode(' '))
|
||||
n0 = doc.createTextNode(end_node.nodeValue[:end])
|
||||
n2 = doc.createTextNode(end_node.nodeValue[end:])
|
||||
|
||||
p = end_node.parentNode
|
||||
p.replaceChild(n2, end_node)
|
||||
p.insertBefore(n1, n2)
|
||||
p.insertBefore(n0, n1)
|
||||
|
||||
t, offsets = getNodeText(e)
|
||||
|
||||
for e in doc.getElementsByTagName('body')[0].childNodes:
|
||||
process_element(e)
|
||||
|
||||
for s in spec_assertions:
|
||||
if s['id'] not in matched_assertions:
|
||||
print "Annotation incomplete: Unmatched spec statement %s" % s['id']
|
||||
|
||||
# Convert from XHTML back to HTML
|
||||
doc.documentElement.removeAttribute('xmlns')
|
||||
doc.documentElement.setAttribute('lang', doc.documentElement.getAttribute('xml:lang'))
|
||||
|
||||
head = doc.documentElement.getElementsByTagName('head')[0]
|
||||
head.insertBefore(doc.createElement('meta'), head.firstChild).setAttribute('charset', 'UTF-8')
|
||||
|
||||
f = codecs.open('%s/canvas.html' % SPECOUTPUTDIR, 'w', 'utf-8')
|
||||
f.write(htmlSerializer(doc))
|
||||
|
||||
if not W3CMODE:
|
||||
write_index()
|
||||
write_category_indexes()
|
||||
write_reportgen()
|
||||
write_results()
|
||||
write_annotated_spec()
|
||||
genTestUtils('../../2dcontext', '../../2dcontext', 'templates.yaml', 'name2dir.yaml', False)
|
||||
|
|
814
tests/wpt/web-platform-tests/2dcontext/tools/gentestutils.py
Normal file
814
tests/wpt/web-platform-tests/2dcontext/tools/gentestutils.py
Normal file
|
@ -0,0 +1,814 @@
|
|||
# Copyright (c) 2010 Philip Taylor
|
||||
# Released under the BSD license and W3C Test Suite License: see LICENSE.txt
|
||||
|
||||
# Current code status:
|
||||
#
|
||||
# This was originally written for use at
|
||||
# http://philip.html5.org/tests/canvas/suite/tests/
|
||||
#
|
||||
# It has been adapted for use with the Web Platform Test Suite suite at
|
||||
# https://github.com/w3c/web-platform-tests/
|
||||
#
|
||||
# The W3C version excludes a number of features (multiple versions of each test
|
||||
# case of varying verbosity, Mozilla mochitests, semi-automated test harness)
|
||||
# to focus on simply providing reviewable test cases. It also expects a different
|
||||
# directory structure.
|
||||
# This code attempts to support both versions, but the non-W3C version hasn't
|
||||
# been tested recently and is probably broken.
|
||||
|
||||
# To update or add test cases:
|
||||
#
|
||||
# * Modify the tests*.yaml files.
|
||||
# 'name' is an arbitrary hierarchical name to help categorise tests.
|
||||
# 'desc' is a rough description of what behaviour the test aims to test.
|
||||
# 'testing' is a list of references to spec.yaml, to show which spec sentences
|
||||
# this test case is primarily testing.
|
||||
# 'code' is JavaScript code to execute, with some special commands starting with '@'
|
||||
# 'expected' is what the final canvas output should be: a string 'green' or 'clear'
|
||||
# (100x50 images in both cases), or a string 'size 100 50' (or any other size)
|
||||
# followed by Python code using Pycairo to generate the image.
|
||||
#
|
||||
# * Run "python gentest.py".
|
||||
# This requires a few Python modules which might not be ubiquitous.
|
||||
# It has only been tested on Linux.
|
||||
# It will usually emit some warnings, which ideally should be fixed but can
|
||||
# generally be safely ignored.
|
||||
#
|
||||
# * Test the tests, add new ones to Git, remove deleted ones from Git, etc.
|
||||
|
||||
import re
|
||||
import codecs
|
||||
import time
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import xml.dom.minidom
|
||||
from xml.dom.minidom import Node
|
||||
|
||||
import cairo
|
||||
|
||||
try:
|
||||
import syck as yaml # compatible and lots faster
|
||||
except ImportError:
|
||||
import yaml
|
||||
|
||||
def genTestUtils(TESTOUTPUTDIR, IMAGEOUTPUTDIR, TEMPLATEFILE, NAME2DIRFILE, ISOFFSCREENCANVAS):
|
||||
|
||||
# Default mode is for the W3C test suite; the --standalone option
|
||||
# generates various extra files that aren't needed there
|
||||
W3CMODE = True
|
||||
if '--standalone' in sys.argv:
|
||||
W3CMODE = False
|
||||
|
||||
MISCOUTPUTDIR = './output'
|
||||
SPECOUTPUTDIR = '../../annotated-spec'
|
||||
|
||||
SPECOUTPUTPATH = '../annotated-spec' # relative to TESTOUTPUTDIR
|
||||
|
||||
def simpleEscapeJS(str):
|
||||
return str.replace('\\', '\\\\').replace('"', '\\"')
|
||||
|
||||
def escapeJS(str):
|
||||
str = simpleEscapeJS(str)
|
||||
str = re.sub(r'\[(\w+)\]', r'[\\""+(\1)+"\\"]', str) # kind of an ugly hack, for nicer failure-message output
|
||||
return str
|
||||
|
||||
def escapeHTML(str):
|
||||
return str.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"')
|
||||
|
||||
def expand_nonfinite(method, argstr, tail):
|
||||
"""
|
||||
>>> print expand_nonfinite('f', '<0 a>, <0 b>', ';')
|
||||
f(a, 0);
|
||||
f(0, b);
|
||||
f(a, b);
|
||||
>>> print expand_nonfinite('f', '<0 a>, <0 b c>, <0 d>', ';')
|
||||
f(a, 0, 0);
|
||||
f(0, b, 0);
|
||||
f(0, c, 0);
|
||||
f(0, 0, d);
|
||||
f(a, b, 0);
|
||||
f(a, b, d);
|
||||
f(a, 0, d);
|
||||
f(0, b, d);
|
||||
"""
|
||||
# argstr is "<valid-1 invalid1-1 invalid2-1 ...>, ..." (where usually
|
||||
# 'invalid' is Infinity/-Infinity/NaN)
|
||||
args = []
|
||||
for arg in argstr.split(', '):
|
||||
a = re.match('<(.*)>', arg).group(1)
|
||||
args.append(a.split(' '))
|
||||
calls = []
|
||||
# Start with the valid argument list
|
||||
call = [ args[j][0] for j in range(len(args)) ]
|
||||
# For each argument alone, try setting it to all its invalid values:
|
||||
for i in range(len(args)):
|
||||
for a in args[i][1:]:
|
||||
c2 = call[:]
|
||||
c2[i] = a
|
||||
calls.append(c2)
|
||||
# For all combinations of >= 2 arguments, try setting them to their
|
||||
# first invalid values. (Don't do all invalid values, because the
|
||||
# number of combinations explodes.)
|
||||
def f(c, start, depth):
|
||||
for i in range(start, len(args)):
|
||||
if len(args[i]) > 1:
|
||||
a = args[i][1]
|
||||
c2 = c[:]
|
||||
c2[i] = a
|
||||
if depth > 0: calls.append(c2)
|
||||
f(c2, i+1, depth+1)
|
||||
f(call, 0, 0)
|
||||
|
||||
return '\n'.join('%s(%s)%s' % (method, ', '.join(c), tail) for c in calls)
|
||||
|
||||
# Run with --test argument to run unit tests
|
||||
if len(sys.argv) > 1 and sys.argv[1] == '--test':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
sys.exit()
|
||||
|
||||
templates = yaml.load(open(TEMPLATEFILE, "r").read())
|
||||
name_mapping = yaml.load(open(NAME2DIRFILE, "r").read())
|
||||
|
||||
SPECFILE = 'spec.yaml'
|
||||
if ISOFFSCREENCANVAS:
|
||||
SPECFILE = '../../2dcontext/tools/spec.yaml'
|
||||
spec_assertions = []
|
||||
for s in yaml.load(open(SPECFILE, "r").read())['assertions']:
|
||||
if 'meta' in s:
|
||||
eval(compile(s['meta'], '<meta spec assertion>', 'exec'), {}, {'assertions':spec_assertions})
|
||||
else:
|
||||
spec_assertions.append(s)
|
||||
|
||||
tests = []
|
||||
TESTSFILES = ['tests.yaml', 'tests2d.yaml', 'tests2dtext.yaml']
|
||||
if ISOFFSCREENCANVAS:
|
||||
TESTSFILES = ['tests2d.yaml']
|
||||
for t in sum([ yaml.load(open(f, "r").read()) for f in TESTSFILES], []):
|
||||
if 'DISABLED' in t:
|
||||
continue
|
||||
if 'meta' in t:
|
||||
eval(compile(t['meta'], '<meta test>', 'exec'), {}, {'tests':tests})
|
||||
else:
|
||||
tests.append(t)
|
||||
|
||||
category_names = []
|
||||
category_contents_direct = {}
|
||||
category_contents_all = {}
|
||||
|
||||
spec_ids = {}
|
||||
for t in spec_assertions: spec_ids[t['id']] = True
|
||||
spec_refs = {}
|
||||
|
||||
def backref_html(name):
|
||||
backrefs = []
|
||||
c = ''
|
||||
for p in name.split('.')[:-1]:
|
||||
c += '.'+p
|
||||
backrefs.append('<a href="index%s.html">%s</a>.' % (c, p))
|
||||
backrefs.append(name.split('.')[-1])
|
||||
return ''.join(backrefs)
|
||||
|
||||
def make_flat_image(filename, w, h, r,g,b,a):
|
||||
if os.path.exists('%s/%s' % (IMAGEOUTPUTDIR, filename)):
|
||||
return filename
|
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
|
||||
cr = cairo.Context(surface)
|
||||
cr.set_source_rgba(r, g, b, a)
|
||||
cr.rectangle(0, 0, w, h)
|
||||
cr.fill()
|
||||
surface.write_to_png('%s/%s' % (IMAGEOUTPUTDIR, filename))
|
||||
return filename
|
||||
|
||||
# Ensure the test output directories exist
|
||||
testdirs = [TESTOUTPUTDIR, IMAGEOUTPUTDIR, MISCOUTPUTDIR]
|
||||
if not W3CMODE: testdirs.append('%s/mochitests' % MISCOUTPUTDIR)
|
||||
else:
|
||||
for map_dir in set(name_mapping.values()):
|
||||
testdirs.append("%s/%s" % (TESTOUTPUTDIR, map_dir))
|
||||
for d in testdirs:
|
||||
try: os.mkdir(d)
|
||||
except: pass # ignore if it already exists
|
||||
|
||||
mochitests = []
|
||||
used_images = {}
|
||||
|
||||
def expand_test_code(code):
|
||||
code = re.sub(r'@nonfinite ([^(]+)\(([^)]+)\)(.*)', lambda m: expand_nonfinite(m.group(1), m.group(2), m.group(3)), code) # must come before '@assert throws'
|
||||
|
||||
if ISOFFSCREENCANVAS:
|
||||
code = re.sub(r'@assert pixel (\d+,\d+) == (\d+,\d+,\d+,\d+);',
|
||||
r'_assertPixel(offscreenCanvas, \1, \2, "\1", "\2");',
|
||||
code)
|
||||
else:
|
||||
code = re.sub(r'@assert pixel (\d+,\d+) == (\d+,\d+,\d+,\d+);',
|
||||
r'_assertPixel(canvas, \1, \2, "\1", "\2");',
|
||||
code)
|
||||
|
||||
if ISOFFSCREENCANVAS:
|
||||
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+);',
|
||||
r'_assertPixelApprox(offscreenCanvas, \1, \2, "\1", "\2", 2);',
|
||||
code)
|
||||
else:
|
||||
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+);',
|
||||
r'_assertPixelApprox(canvas, \1, \2, "\1", "\2", 2);',
|
||||
code)
|
||||
|
||||
if ISOFFSCREENCANVAS:
|
||||
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);',
|
||||
r'_assertPixelApprox(offscreenCanvas, \1, \2, "\1", "\2", \3);',
|
||||
code)
|
||||
else:
|
||||
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);',
|
||||
r'_assertPixelApprox(canvas, \1, \2, "\1", "\2", \3);',
|
||||
code)
|
||||
|
||||
code = re.sub(r'@assert throws (\S+_ERR) (.*);',
|
||||
r'assert_throws("\1", function() { \2; });',
|
||||
code)
|
||||
|
||||
code = re.sub(r'@assert throws (\S+Error) (.*);',
|
||||
r'assert_throws(new \1(), function() { \2; });',
|
||||
code)
|
||||
|
||||
code = re.sub(r'@assert throws (.*);',
|
||||
r'assert_throws(null, function() { \1; });',
|
||||
code)
|
||||
|
||||
code = re.sub(r'@assert (.*) === (.*);',
|
||||
lambda m: '_assertSame(%s, %s, "%s", "%s");'
|
||||
% (m.group(1), m.group(2), escapeJS(m.group(1)), escapeJS(m.group(2)))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'@assert (.*) !== (.*);',
|
||||
lambda m: '_assertDifferent(%s, %s, "%s", "%s");'
|
||||
% (m.group(1), m.group(2), escapeJS(m.group(1)), escapeJS(m.group(2)))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'@assert (.*) =~ (.*);',
|
||||
lambda m: 'assert_regexp_match(%s, %s);'
|
||||
% (m.group(1), m.group(2))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'@assert (.*);',
|
||||
lambda m: '_assert(%s, "%s");'
|
||||
% (m.group(1), escapeJS(m.group(1)))
|
||||
, code)
|
||||
|
||||
code = re.sub(r' @moz-todo', '', code)
|
||||
|
||||
code = re.sub(r'@moz-UniversalBrowserRead;',
|
||||
""
|
||||
, code)
|
||||
|
||||
assert('@' not in code)
|
||||
|
||||
return code
|
||||
|
||||
def expand_mochitest_code(code):
|
||||
code = re.sub(r'@nonfinite ([^(]+)\(([^)]+)\)(.*)', lambda m: expand_nonfinite(m.group(1), m.group(2), m.group(3)), code)
|
||||
|
||||
code = re.sub(r'@assert pixel (\d+,\d+) == (\d+,\d+,\d+,\d+);',
|
||||
r'isPixel(ctx, \1, \2, "\1", "\2", 0);',
|
||||
code)
|
||||
|
||||
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+);',
|
||||
r'isPixel(ctx, \1, \2, "\1", "\2", 2);',
|
||||
code)
|
||||
|
||||
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);',
|
||||
r'isPixel(ctx, \1, \2, "\1", "\2", \3);',
|
||||
code)
|
||||
|
||||
code = re.sub(r'@assert throws (\S+_ERR) (.*);',
|
||||
lambda m: 'var _thrown = undefined; try {\n %s;\n} catch (e) { _thrown = e }; ok(_thrown && _thrown.code == DOMException.%s, "should throw %s");'
|
||||
% (m.group(2), m.group(1), m.group(1))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'@assert throws (\S+Error) (.*);',
|
||||
lambda m: 'var _thrown = undefined; try {\n %s;\n} catch (e) { _thrown = e }; ok(_thrown && (_thrown instanceof %s), "should throw %s");'
|
||||
% (m.group(2), m.group(1), m.group(1))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'@assert throws (.*);',
|
||||
lambda m: 'try { var _thrown = false;\n %s;\n} catch (e) { _thrown = true; } finally { ok(_thrown, "should throw exception"); }'
|
||||
% (m.group(1))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'@assert (.*) =~ (.*);',
|
||||
lambda m: 'ok(%s.match(%s), "%s.match(%s)");'
|
||||
% (m.group(1), m.group(2), escapeJS(m.group(1)), escapeJS(m.group(2)))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'@assert (.*);',
|
||||
lambda m: 'ok(%s, "%s");'
|
||||
% (m.group(1), escapeJS(m.group(1)))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'((?:^|\n|;)\s*)ok(.*;) @moz-todo',
|
||||
lambda m: '%stodo%s'
|
||||
% (m.group(1), m.group(2))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'((?:^|\n|;)\s*)(is.*;) @moz-todo',
|
||||
lambda m: '%stodo_%s'
|
||||
% (m.group(1), m.group(2))
|
||||
, code)
|
||||
|
||||
code = re.sub(r'@moz-UniversalBrowserRead;',
|
||||
"netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');"
|
||||
, code)
|
||||
|
||||
code = code.replace('../images/', 'image_')
|
||||
|
||||
assert '@' not in code, '@ not in code:\n%s' % code
|
||||
|
||||
return code
|
||||
|
||||
used_tests = {}
|
||||
for i in range(len(tests)):
|
||||
test = tests[i]
|
||||
|
||||
name = test['name']
|
||||
print "\r(%s)" % name, " "*32, "\t",
|
||||
|
||||
if name in used_tests:
|
||||
print "Test %s is defined twice" % name
|
||||
used_tests[name] = 1
|
||||
|
||||
mapped_name = None
|
||||
for mn in sorted(name_mapping.keys(), key=len, reverse=True):
|
||||
if name.startswith(mn):
|
||||
mapped_name = "%s/%s" % (name_mapping[mn], name)
|
||||
break
|
||||
if not mapped_name:
|
||||
print "LIKELY ERROR: %s has no defined target directory mapping" % name
|
||||
if ISOFFSCREENCANVAS:
|
||||
continue
|
||||
else:
|
||||
mapped_name = name
|
||||
if 'manual' in test:
|
||||
mapped_name += "-manual"
|
||||
|
||||
cat_total = ''
|
||||
for cat_part in [''] + name.split('.')[:-1]:
|
||||
cat_total += cat_part+'.'
|
||||
if not cat_total in category_names: category_names.append(cat_total)
|
||||
category_contents_all.setdefault(cat_total, []).append(name)
|
||||
category_contents_direct.setdefault(cat_total, []).append(name)
|
||||
|
||||
for ref in test.get('testing', []):
|
||||
if ref not in spec_ids:
|
||||
print "Test %s uses nonexistent spec point %s" % (name, ref)
|
||||
spec_refs.setdefault(ref, []).append(name)
|
||||
#if not (len(test.get('testing', [])) or 'mozilla' in test):
|
||||
if not test.get('testing', []):
|
||||
print "Test %s doesn't refer to any spec points" % name
|
||||
|
||||
if test.get('expected', '') == 'green' and re.search(r'@assert pixel .* 0,0,0,0;', test['code']):
|
||||
print "Probable incorrect pixel test in %s" % name
|
||||
|
||||
code = expand_test_code(test['code'])
|
||||
|
||||
mochitest = not (W3CMODE or 'manual' in test or 'disabled' in test.get('mozilla', {}))
|
||||
if mochitest:
|
||||
mochi_code = expand_mochitest_code(test['code'])
|
||||
|
||||
mochi_name = name
|
||||
if 'mozilla' in test:
|
||||
if 'throws' in test['mozilla']:
|
||||
mochi_code = templates['mochitest.exception'] % mochi_code
|
||||
if 'bug' in test['mozilla']:
|
||||
mochi_name = "%s - bug %s" % (name, test['mozilla']['bug'])
|
||||
|
||||
if 'desc' in test:
|
||||
mochi_desc = '<!-- Testing: %s -->\n' % test['desc']
|
||||
else:
|
||||
mochi_desc = ''
|
||||
|
||||
if 'deferTest' in mochi_code:
|
||||
mochi_setup = ''
|
||||
mochi_footer = ''
|
||||
else:
|
||||
mochi_setup = ''
|
||||
mochi_footer = 'SimpleTest.finish();\n'
|
||||
|
||||
for f in ['isPixel', 'todo_isPixel', 'deferTest', 'wrapFunction']:
|
||||
if f in mochi_code:
|
||||
mochi_setup += templates['mochitest.%s' % f]
|
||||
else:
|
||||
if not W3CMODE:
|
||||
print "Skipping mochitest for %s" % name
|
||||
mochi_name = ''
|
||||
mochi_desc = ''
|
||||
mochi_code = ''
|
||||
mochi_setup = ''
|
||||
mochi_footer = ''
|
||||
|
||||
expectation_html = ''
|
||||
if 'expected' in test and test['expected'] is not None:
|
||||
expected = test['expected']
|
||||
expected_img = None
|
||||
if expected == 'green':
|
||||
expected_img = make_flat_image('green-100x50.png', 100, 50, 0,1,0,1)
|
||||
if W3CMODE: expected_img = "/images/" + expected_img
|
||||
elif expected == 'clear':
|
||||
expected_img = make_flat_image('clear-100x50.png', 100, 50, 0,0,0,0)
|
||||
if W3CMODE: expected_img = "/images/" + expected_img
|
||||
else:
|
||||
if ';' in expected: print "Found semicolon in %s" % name
|
||||
expected = re.sub(r'^size (\d+) (\d+)',
|
||||
r'surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \1, \2)\ncr = cairo.Context(surface)',
|
||||
expected)
|
||||
|
||||
if mapped_name.endswith("-manual"):
|
||||
png_name = mapped_name[:-len("-manual")]
|
||||
else:
|
||||
png_name = mapped_name
|
||||
expected += "\nsurface.write_to_png('%s/%s.png')\n" % (IMAGEOUTPUTDIR, png_name)
|
||||
eval(compile(expected, '<test %s>' % test['name'], 'exec'), {}, {'cairo':cairo})
|
||||
expected_img = "%s.png" % name
|
||||
|
||||
if expected_img:
|
||||
expectation_html = ('<p class="output expectedtext">Expected output:' +
|
||||
'<p><img src="%s" class="output expected" id="expected" alt="">' % (expected_img))
|
||||
|
||||
canvas = test.get('canvas', 'width="100" height="50"')
|
||||
|
||||
prev = tests[i-1]['name'] if i != 0 else 'index'
|
||||
next = tests[i+1]['name'] if i != len(tests)-1 else 'index'
|
||||
|
||||
name_wrapped = name.replace('.', '.​') # (see https://bugzilla.mozilla.org/show_bug.cgi?id=376188)
|
||||
|
||||
refs = ''.join('<li><a href="%s/canvas.html#testrefs.%s">%s</a>\n' % (SPECOUTPUTPATH, n,n) for n in test.get('testing', []))
|
||||
if not W3CMODE and 'mozilla' in test and 'bug' in test['mozilla']:
|
||||
refs += '<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=%d">Bugzilla</a>' % test['mozilla']['bug']
|
||||
|
||||
notes = '<p class="notes">%s' % test['notes'] if 'notes' in test else ''
|
||||
|
||||
scripts = ''
|
||||
for s in test.get('scripts', []):
|
||||
scripts += '<script src="%s"></script>\n' % (s)
|
||||
|
||||
images = ''
|
||||
for i in test.get('images', []):
|
||||
id = i.split('/')[-1]
|
||||
if '/' not in i:
|
||||
used_images[i] = 1
|
||||
i = '../images/%s' % i
|
||||
images += '<img src="%s" id="%s" class="resource">\n' % (i,id)
|
||||
mochi_images = images.replace('../images/', 'image_')
|
||||
if W3CMODE: images = images.replace("../images/", "/images/")
|
||||
|
||||
fonts = ''
|
||||
fonthack = ''
|
||||
for i in test.get('fonts', []):
|
||||
fonts += '@font-face {\n font-family: %s;\n src: url("/fonts/%s.ttf");\n}\n' % (i, i)
|
||||
# Browsers require the font to actually be used in the page
|
||||
if test.get('fonthack', 1):
|
||||
fonthack += '<span style="font-family: %s; position: absolute; visibility: hidden">A</span>\n' % i
|
||||
if fonts:
|
||||
fonts = '<style>\n%s</style>\n' % fonts
|
||||
|
||||
fallback = test.get('fallback', '<p class="fallback">FAIL (fallback content)</p>')
|
||||
|
||||
desc = test.get('desc', '')
|
||||
escaped_desc = simpleEscapeJS(desc)
|
||||
template_params = {
|
||||
'name':name, 'name_wrapped':name_wrapped, 'backrefs':backref_html(name),
|
||||
'mapped_name':mapped_name,
|
||||
'desc':desc, 'escaped_desc':escaped_desc,
|
||||
'prev':prev, 'next':next, 'refs':refs, 'notes':notes, 'images':images,
|
||||
'fonts':fonts, 'fonthack':fonthack,
|
||||
'canvas':canvas, 'expected':expectation_html, 'code':code, 'scripts':scripts,
|
||||
'mochi_name':mochi_name, 'mochi_desc':mochi_desc, 'mochi_code':mochi_code,
|
||||
'mochi_setup':mochi_setup, 'mochi_footer':mochi_footer, 'mochi_images':mochi_images,
|
||||
'fallback':fallback
|
||||
}
|
||||
|
||||
if W3CMODE:
|
||||
f = codecs.open('%s/%s.html' % (TESTOUTPUTDIR, mapped_name), 'w', 'utf-8')
|
||||
f.write(templates['w3c'] % template_params)
|
||||
if ISOFFSCREENCANVAS:
|
||||
f = codecs.open('%s/%s.worker.js' % (TESTOUTPUTDIR, mapped_name), 'w', 'utf-8')
|
||||
f.write(templates['w3cworker'] % template_params)
|
||||
else:
|
||||
f = codecs.open('%s/%s.html' % (TESTOUTPUTDIR, name), 'w', 'utf-8')
|
||||
f.write(templates['standalone'] % template_params)
|
||||
|
||||
f = codecs.open('%s/framed.%s.html' % (TESTOUTPUTDIR, name), 'w', 'utf-8')
|
||||
f.write(templates['framed'] % template_params)
|
||||
|
||||
f = codecs.open('%s/minimal.%s.html' % (TESTOUTPUTDIR, name), 'w', 'utf-8')
|
||||
f.write(templates['minimal'] % template_params)
|
||||
|
||||
if mochitest:
|
||||
mochitests.append(name)
|
||||
f = codecs.open('%s/mochitests/test_%s.html' % (MISCOUTPUTDIR, name), 'w', 'utf-8')
|
||||
f.write(templates['mochitest'] % template_params)
|
||||
|
||||
def write_mochitest_makefile():
|
||||
f = open('%s/mochitests/Makefile.in' % MISCOUTPUTDIR, 'w')
|
||||
f.write(templates['mochitest.Makefile'])
|
||||
files = ['test_%s.html' % n for n in mochitests] + ['image_%s' % n for n in used_images]
|
||||
chunksize = 100
|
||||
chunks = []
|
||||
for i in range(0, len(files), chunksize):
|
||||
chunk = files[i:i+chunksize]
|
||||
name = '_TEST_FILES_%d' % (i / chunksize)
|
||||
chunks.append(name)
|
||||
f.write('%s = \\\n' % name)
|
||||
for file in chunk: f.write('\t%s \\\n' % file)
|
||||
f.write('\t$(NULL)\n\n')
|
||||
f.write('# split up into groups to work around command-line length limits\n')
|
||||
for name in chunks:
|
||||
f.write('libs:: $(%s)\n\t$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)\n\n' % name)
|
||||
|
||||
if not W3CMODE:
|
||||
for i in used_images:
|
||||
shutil.copyfile("../../images/%s" % i, "%s/mochitests/image_%s" % (MISCOUTPUTDIR, i))
|
||||
write_mochitest_makefile()
|
||||
|
||||
print
|
||||
|
||||
def write_index():
|
||||
f = open('%s/index.html' % TESTOUTPUTDIR, 'w')
|
||||
f.write(templates['index.w3c' if W3CMODE else 'index'] % { 'updated':time.strftime('%Y-%m-%d', time.gmtime()) })
|
||||
f.write('\n<ul class="testlist">\n')
|
||||
depth = 1
|
||||
for category in category_names:
|
||||
name = category[1:-1] or ''
|
||||
count = len(category_contents_all[category])
|
||||
new_depth = category.count('.')
|
||||
while new_depth < depth: f.write(' '*(depth-1) + '</ul>\n'); depth -= 1
|
||||
f.write(' '*depth + templates['index.w3c.category.item' if W3CMODE else 'index.category.item'] % (name or 'all', name, count, '' if count==1 else 's'))
|
||||
while new_depth+1 > depth: f.write(' '*depth + '<ul>\n'); depth += 1
|
||||
for item in category_contents_direct.get(category, []):
|
||||
f.write(' '*depth + '<li><a href="%s.html">%s</a>\n' % (item, item) )
|
||||
while 0 < depth: f.write(' '*(depth-1) + '</ul>\n'); depth -= 1
|
||||
|
||||
def write_category_indexes():
|
||||
for category in category_names:
|
||||
name = (category[1:-1] or 'all')
|
||||
|
||||
f = open('%s/index.%s.html' % (TESTOUTPUTDIR, name), 'w')
|
||||
f.write(templates['index.w3c.frame' if W3CMODE else 'index.frame'] % { 'backrefs':backref_html(name), 'category':name })
|
||||
for item in category_contents_all[category]:
|
||||
f.write(templates['index.w3c.frame.item' if W3CMODE else 'index.frame.item'] % item)
|
||||
|
||||
def write_reportgen():
|
||||
f = open('%s/reportgen.html' % MISCOUTPUTDIR, 'w')
|
||||
items_text = ',\n'.join(('"%s"' % item) for item in category_contents_all['.'])
|
||||
f.write(templates['reportgen'] % {'items':items_text })
|
||||
|
||||
def write_results():
|
||||
results = {}
|
||||
uas = []
|
||||
uastrings = {}
|
||||
for item in category_contents_all['.']: results[item] = {}
|
||||
|
||||
f = open('%s/results.html' % MISCOUTPUTDIR, 'w')
|
||||
f.write(templates['results'])
|
||||
|
||||
if not os.path.exists('results.yaml'):
|
||||
print "Can't find results.yaml"
|
||||
else:
|
||||
for resultset in yaml.load(open('results.yaml', "r").read()):
|
||||
#title = "%s (%s)" % (resultset['ua'], resultset['time'])
|
||||
title = resultset['name']
|
||||
#assert title not in uas # don't allow repetitions
|
||||
if title not in uas:
|
||||
uas.append(title)
|
||||
uastrings[title] = resultset['ua']
|
||||
else:
|
||||
assert uastrings[title] == resultset['ua']
|
||||
for r in resultset['results']:
|
||||
if r['id'] not in results:
|
||||
print 'Skipping results for removed test %s' % r['id']
|
||||
continue
|
||||
results[r['id']][title] = (
|
||||
r['status'].lower(),
|
||||
re.sub(r'%(..)', lambda m: chr(int(m.group(1), 16)),
|
||||
re.sub(r'%u(....)', lambda m: unichr(int(m.group(1), 16)),
|
||||
r['notes'])).encode('utf8')
|
||||
)
|
||||
|
||||
passes = {}
|
||||
for ua in uas:
|
||||
f.write('<th title="%s">%s\n' % (uastrings[ua], ua))
|
||||
passes[ua] = 0
|
||||
for id in category_contents_all['.']:
|
||||
f.write('<tr><td><a href="#%s" id="%s">#</a> <a href="%s.html">%s</a>\n' % (id, id, id, id))
|
||||
for ua in uas:
|
||||
status, details = results[id].get(ua, ('', ''))
|
||||
f.write('<td class="r %s"><ul class="d">%s</ul>\n' % (status, details))
|
||||
if status == 'pass': passes[ua] += 1
|
||||
f.write('<tr><th>Passes\n')
|
||||
for ua in uas:
|
||||
f.write('<td>%.1f%%\n' % ((100.0 * passes[ua]) / len(category_contents_all['.'])))
|
||||
f.write('<tr><td>\n')
|
||||
for ua in uas:
|
||||
f.write('<td>%s\n' % ua)
|
||||
f.write('</table>\n')
|
||||
|
||||
def getNodeText(node):
|
||||
t, offsets = '', []
|
||||
|
||||
# Skip over any previous annotations we added
|
||||
if node.nodeType == node.ELEMENT_NODE and 'testrefs' in node.getAttribute('class').split(' '):
|
||||
return t, offsets
|
||||
|
||||
if node.nodeType == node.TEXT_NODE:
|
||||
val = node.nodeValue
|
||||
val = val.replace(unichr(0xa0), ' ') # replace s
|
||||
t += val
|
||||
offsets += [ (node, len(node.nodeValue)) ]
|
||||
for n in node.childNodes:
|
||||
child_t, child_offsets = getNodeText(n)
|
||||
t += child_t
|
||||
offsets += child_offsets
|
||||
return t, offsets
|
||||
|
||||
def htmlSerializer(element):
|
||||
element.normalize()
|
||||
rv = []
|
||||
specialtext = ['style', 'script', 'xmp', 'iframe', 'noembed', 'noframes', 'noscript']
|
||||
empty = ['area', 'base', 'basefont', 'bgsound', 'br', 'col', 'embed', 'frame',
|
||||
'hr', 'img', 'input', 'link', 'meta', 'param', 'spacer', 'wbr']
|
||||
|
||||
def serializeElement(element):
|
||||
if element.nodeType == Node.DOCUMENT_TYPE_NODE:
|
||||
rv.append("<!DOCTYPE %s>" % element.name)
|
||||
elif element.nodeType == Node.DOCUMENT_NODE:
|
||||
for child in element.childNodes:
|
||||
serializeElement(child)
|
||||
elif element.nodeType == Node.COMMENT_NODE:
|
||||
rv.append("<!--%s-->" % element.nodeValue)
|
||||
elif element.nodeType == Node.TEXT_NODE:
|
||||
unescaped = False
|
||||
n = element.parentNode
|
||||
while n is not None:
|
||||
if n.nodeName in specialtext:
|
||||
unescaped = True
|
||||
break
|
||||
n = n.parentNode
|
||||
if unescaped:
|
||||
rv.append(element.nodeValue)
|
||||
else:
|
||||
rv.append(escapeHTML(element.nodeValue))
|
||||
else:
|
||||
rv.append("<%s" % element.nodeName)
|
||||
if element.hasAttributes():
|
||||
for name, value in element.attributes.items():
|
||||
rv.append(' %s="%s"' % (name, escapeHTML(value)))
|
||||
rv.append(">")
|
||||
if element.nodeName not in empty:
|
||||
for child in element.childNodes:
|
||||
serializeElement(child)
|
||||
rv.append("</%s>" % element.nodeName)
|
||||
serializeElement(element)
|
||||
return '<!DOCTYPE html>\n' + ''.join(rv)
|
||||
|
||||
def write_annotated_spec():
|
||||
# Load the stripped-down XHTMLised copy of the spec
|
||||
doc = xml.dom.minidom.parse(open('current-work-canvas.xhtml', 'r'))
|
||||
|
||||
# Insert our new stylesheet
|
||||
n = doc.getElementsByTagName('head')[0].appendChild(doc.createElement('link'))
|
||||
n.setAttribute('rel', 'stylesheet')
|
||||
n.setAttribute('href', '../common/canvas-spec.css' if W3CMODE else '../spectest.css')
|
||||
n.setAttribute('type', 'text/css')
|
||||
|
||||
spec_assertion_patterns = []
|
||||
for a in spec_assertions:
|
||||
# Warn about problems
|
||||
if a['id'] not in spec_refs:
|
||||
print "Unused spec statement %s" % a['id']
|
||||
|
||||
pattern_text = a['text']
|
||||
|
||||
if 'keyword' in a:
|
||||
# Explicit keyword override
|
||||
keyword = a['keyword']
|
||||
else:
|
||||
# Extract the marked keywords, and remove the markers
|
||||
keyword = 'none'
|
||||
for kw in ['must', 'should', 'required']:
|
||||
if ('*%s*' % kw) in pattern_text:
|
||||
keyword = kw
|
||||
pattern_text = pattern_text.replace('*%s*' % kw, kw)
|
||||
break
|
||||
# Make sure there wasn't >1 keyword
|
||||
for kw in ['must', 'should', 'required']:
|
||||
assert('*%s*' % kw not in pattern_text)
|
||||
|
||||
# Convert the special pattern format into regexp syntax
|
||||
pattern_text = (pattern_text.
|
||||
# Escape relevant characters
|
||||
replace('*', r'\*').
|
||||
replace('+', r'\+').
|
||||
replace('.', r'\.').
|
||||
replace('(', r'\(').
|
||||
replace(')', r'\)').
|
||||
replace('[', r'\[').
|
||||
replace(']', r'\]').
|
||||
# Convert special sequences back into unescaped regexp code
|
||||
replace(' ', r'\s+').
|
||||
replace(r'<\.\.\.>', r'.+').
|
||||
replace('<^>', r'()').
|
||||
replace('<eol>', r'\s*?\n')
|
||||
)
|
||||
pattern = re.compile(pattern_text, re.S)
|
||||
spec_assertion_patterns.append( (a['id'], pattern, keyword, a.get('previously', None)) )
|
||||
matched_assertions = {}
|
||||
|
||||
def process_element(e):
|
||||
if e.nodeType == e.ELEMENT_NODE and (e.getAttribute('class') == 'impl' or e.hasAttribute('data-component')):
|
||||
for c in e.childNodes:
|
||||
process_element(c)
|
||||
return
|
||||
|
||||
t, offsets = getNodeText(e)
|
||||
for id, pattern, keyword, previously in spec_assertion_patterns:
|
||||
m = pattern.search(t)
|
||||
if m:
|
||||
# When the pattern-match isn't enough to uniquely identify a sentence,
|
||||
# allow explicit back-references to earlier paragraphs
|
||||
if previously:
|
||||
if len(previously) >= 3:
|
||||
n, text, exp = previously
|
||||
else:
|
||||
n, text = previously
|
||||
exp = True
|
||||
node = e
|
||||
while n and node.previousSibling:
|
||||
node = node.previousSibling
|
||||
n -= 1
|
||||
if (text not in getNodeText(node)[0]) == exp:
|
||||
continue # discard this match
|
||||
|
||||
if id in matched_assertions:
|
||||
print "Spec statement %s matches multiple places" % id
|
||||
matched_assertions[id] = True
|
||||
|
||||
if m.lastindex != 1:
|
||||
print "Spec statement %s has incorrect number of match groups" % id
|
||||
|
||||
end = m.end(1)
|
||||
end_node = None
|
||||
for end_node, o in offsets:
|
||||
if end < o:
|
||||
break
|
||||
end -= o
|
||||
assert(end_node)
|
||||
|
||||
n1 = doc.createElement('span')
|
||||
n1.setAttribute('class', 'testrefs kw-%s' % keyword)
|
||||
n1.setAttribute('id', 'testrefs.%s' % id)
|
||||
n1.appendChild(doc.createTextNode(' '))
|
||||
|
||||
n = n1.appendChild(doc.createElement('a'))
|
||||
n.setAttribute('href', '#testrefs.%s' % id)
|
||||
n.setAttribute('title', id)
|
||||
n.appendChild(doc.createTextNode('#'))
|
||||
|
||||
n1.appendChild(doc.createTextNode(' '))
|
||||
for test_id in spec_refs.get(id, []):
|
||||
n = n1.appendChild(doc.createElement('a'))
|
||||
n.setAttribute('href', '../canvas/%s.html' % test_id)
|
||||
n.appendChild(doc.createTextNode(test_id))
|
||||
n1.appendChild(doc.createTextNode(' '))
|
||||
n0 = doc.createTextNode(end_node.nodeValue[:end])
|
||||
n2 = doc.createTextNode(end_node.nodeValue[end:])
|
||||
|
||||
p = end_node.parentNode
|
||||
p.replaceChild(n2, end_node)
|
||||
p.insertBefore(n1, n2)
|
||||
p.insertBefore(n0, n1)
|
||||
|
||||
t, offsets = getNodeText(e)
|
||||
|
||||
for e in doc.getElementsByTagName('body')[0].childNodes:
|
||||
process_element(e)
|
||||
|
||||
for s in spec_assertions:
|
||||
if s['id'] not in matched_assertions:
|
||||
print "Annotation incomplete: Unmatched spec statement %s" % s['id']
|
||||
|
||||
# Convert from XHTML back to HTML
|
||||
doc.documentElement.removeAttribute('xmlns')
|
||||
doc.documentElement.setAttribute('lang', doc.documentElement.getAttribute('xml:lang'))
|
||||
|
||||
head = doc.documentElement.getElementsByTagName('head')[0]
|
||||
head.insertBefore(doc.createElement('meta'), head.firstChild).setAttribute('charset', 'UTF-8')
|
||||
|
||||
f = codecs.open('%s/canvas.html' % SPECOUTPUTDIR, 'w', 'utf-8')
|
||||
f.write(htmlSerializer(doc))
|
||||
|
||||
if not W3CMODE:
|
||||
write_index()
|
||||
write_category_indexes()
|
||||
write_reportgen()
|
||||
write_results()
|
||||
write_annotated_spec()
|
|
@ -181,6 +181,8 @@ assertions:
|
|||
text: "copy<^><eol>"
|
||||
- id: 2d.composite.xor
|
||||
text: "xor<^><eol>"
|
||||
- id: 2d.composite.clear
|
||||
text: "clear<^><eol>"
|
||||
|
||||
- id: 2d.composite.operation.casesensitive
|
||||
text: "These values are all case-sensitive<^> <...> they *must* be used exactly as shown."
|
||||
|
@ -584,9 +586,9 @@ assertions:
|
|||
text: "If the image argument is <...> an HTMLVideoElement object whose readyState attribute is either HAVE_NOTHING or HAVE_METADATA<^>, then the implementation *must* return without drawing anything."
|
||||
- id: 2d.drawImage.zerocanvas
|
||||
previously: [ 10, "dw and dh" ]
|
||||
text: "If the image argument is an HTMLCanvasElement object with either a horizontal dimension or a vertical dimension equal to zero, then the implementation *must* raise an INVALID_STATE_ERR exception<^>."
|
||||
text: "If the image argument is an HTMLCanvasElement object with either a horizontal dimension or a vertical dimension equal to zero, then the implementation *must* return without drawing anything<^>."
|
||||
- id: 2d.drawImage.zerosource
|
||||
text: "If one of the sw or sh arguments is zero<^>, the implementation *must* raise an INDEX_SIZE_ERR exception."
|
||||
text: "If one of the sw or sh arguments is zero<^>, the implementation *must* return without drawing anything."
|
||||
- id: 2d.drawImage.paint
|
||||
text: "When drawImage() is invoked, the region of the image specified by the source rectangle *must* be painted on the region of the canvas specified by the destination rectangle<^>, after applying the current transformation matrix to the points of the destination rectangle."
|
||||
- id: 2d.drawImage.original
|
||||
|
|
|
@ -1307,7 +1307,7 @@
|
|||
code: |
|
||||
ctx.globalCompositeOperation = 'xor';
|
||||
ctx.globalCompositeOperation = 'clear';
|
||||
@assert ctx.globalCompositeOperation === 'xor';
|
||||
@assert ctx.globalCompositeOperation === 'clear';
|
||||
|
||||
- name: 2d.composite.operation.highlight
|
||||
testing:
|
||||
|
@ -8772,7 +8772,7 @@
|
|||
expected: green
|
||||
|
||||
- name: 2d.drawImage.zerosource
|
||||
desc: drawImage with zero-sized source rectangle throws INDEX_SIZE_ERR
|
||||
desc: drawImage with zero-sized source rectangle draws nothing without exception
|
||||
testing:
|
||||
- 2d.drawImage.zerosource
|
||||
images:
|
||||
|
@ -8780,9 +8780,9 @@
|
|||
code: |
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(0, 0, 100, 50);
|
||||
@assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 10, 10, 0, 1, 0, 0, 100, 50);
|
||||
@assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 10, 10, 1, 0, 0, 0, 100, 50);
|
||||
@assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 10, 10, 0, 0, 0, 0, 100, 50);
|
||||
ctx.drawImage(document.getElementById('red.png'), 10, 10, 0, 1, 0, 0, 100, 50);
|
||||
ctx.drawImage(document.getElementById('red.png'), 10, 10, 1, 0, 0, 0, 100, 50);
|
||||
ctx.drawImage(document.getElementById('red.png'), 10, 10, 0, 0, 0, 0, 100, 50);
|
||||
@assert pixel 50,25 ==~ 0,255,0,255;
|
||||
expected: green
|
||||
|
||||
|
@ -9001,15 +9001,15 @@
|
|||
var canvas2 = document.createElement('canvas');
|
||||
canvas2.width = 0;
|
||||
canvas2.height = 10;
|
||||
@assert throws INVALID_STATE_ERR ctx.drawImage(canvas2, 0, 0);
|
||||
ctx.drawImage(canvas2, 0, 0);
|
||||
|
||||
canvas2.width = 10;
|
||||
canvas2.height = 0;
|
||||
@assert throws INVALID_STATE_ERR ctx.drawImage(canvas2, 0, 0);
|
||||
ctx.drawImage(canvas2, 0, 0);
|
||||
|
||||
canvas2.width = 0;
|
||||
canvas2.height = 0;
|
||||
@assert throws INVALID_STATE_ERR ctx.drawImage(canvas2, 0, 0);
|
||||
ctx.drawImage(canvas2, 0, 0);
|
||||
|
||||
@assert pixel 50,25 ==~ 0,255,0,255;
|
||||
expected: green
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@inexorabletash
|
||||
@plehegar
|
||||
@zqzhang
|
||||
@zcorpan
|
||||
@jdm
|
||||
@Ms2ger
|
||||
@mkruisselbrink
|
||||
|
|
|
@ -36,6 +36,30 @@ test(function() {
|
|||
desc: "blob2."
|
||||
});
|
||||
|
||||
test_blob(function() {
|
||||
return new Blob().slice(0,0,null);
|
||||
}, {
|
||||
expected: "",
|
||||
type: "null",
|
||||
desc: "null type Blob slice"
|
||||
});
|
||||
|
||||
test_blob(function() {
|
||||
return new Blob().slice(0,0,undefined);
|
||||
}, {
|
||||
expected: "",
|
||||
type: "",
|
||||
desc: "undefined type Blob slice"
|
||||
});
|
||||
|
||||
test_blob(function() {
|
||||
return new Blob().slice(0,0);
|
||||
}, {
|
||||
expected: "",
|
||||
type: "",
|
||||
desc: "no type Blob slice"
|
||||
});
|
||||
|
||||
var arrayBuffer = new ArrayBuffer(16);
|
||||
var int8View = new Int8Array(arrayBuffer);
|
||||
for (var i = 0; i < 16; i++) {
|
||||
|
|
66
tests/wpt/web-platform-tests/IndexedDB/historical.html
Normal file
66
tests/wpt/web-platform-tests/IndexedDB/historical.html
Normal file
|
@ -0,0 +1,66 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>IndexedDB: Historical features</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
test(function() {
|
||||
// Replaced circa December 2011 by 'error'.
|
||||
assert_false('errorCode' in IDBRequest.prototype);
|
||||
}, '"errorCode" should not be supported on IDBRequest.');
|
||||
|
||||
test(function() {
|
||||
// Replaced circa May 2012 by a DOMString (later, IDBRequestReadyState enum).
|
||||
assert_false('LOADING' in IDBRequest);
|
||||
}, '"LOADING" should not be supported on IDBRequest.');
|
||||
|
||||
test(function() {
|
||||
// Replaced circa May 2012 by a DOMString (later, IDBRequestReadyState enum).
|
||||
assert_false('DONE' in IDBRequest);
|
||||
}, '"DONE" should not be supported on IDBRequest.');
|
||||
|
||||
test(function() {
|
||||
// Replaced circa December 2011 by 'oldVersion'/'newVersion'.
|
||||
assert_false('version' in IDBVersionChangeEvent.prototype);
|
||||
}, '"version" should not be supported on IDBVersionChangeEvent.');
|
||||
|
||||
test(function() {
|
||||
// Replaced circa December 2011 by open() with version.
|
||||
assert_false('setVersion' in IDBDatabase.prototype);
|
||||
}, '"setVersion" should not be supported on IDBDatabase.');
|
||||
|
||||
test(function() {
|
||||
// Replaced circa May 2012 by a DOMString (later, IDBCursorDirection enum).
|
||||
assert_false('NEXT' in IDBCursor);
|
||||
}, '"NEXT" should not be supported on IDBCursor.');
|
||||
|
||||
test(function() {
|
||||
// Replaced circa May 2012 by a DOMString (later, IDBCursorDirection enum).
|
||||
assert_false('NEXT_NO_DUPLICATE' in IDBCursor);
|
||||
}, '"NEXT_NO_DUPLICATE" should not be supported on IDBCursor.');
|
||||
|
||||
test(function() {
|
||||
// Replaced circa May 2012 by a DOMString (later, IDBCursorDirection enum).
|
||||
assert_false('PREV' in IDBCursor);
|
||||
}, '"PREV" should not be supported on IDBCursor.');
|
||||
|
||||
test(function() {
|
||||
// Replaced circa May 2012 by a DOMString (later, IDBCursorDirection enum).
|
||||
assert_false('PREV_NO_DUPLICATE' in IDBCursor);
|
||||
}, '"PREV_NO_DUPLICATE" should not be supported on IDBCursor.');
|
||||
|
||||
test(function() {
|
||||
// Replaced circa May 2012 by a DOMString (later, IDBTransactionMode enum).
|
||||
assert_false('READ_ONLY' in IDBTransaction);
|
||||
}, '"READ_ONLY" should not be supported on IDBTransaction.');
|
||||
|
||||
test(function() {
|
||||
// Replaced circa May 2012 by a DOMString (later, IDBTransactionMode enum).
|
||||
assert_false('READ_WRITE' in IDBTransaction);
|
||||
}, '"READ_WRITE" should not be supported on IDBTransaction.');
|
||||
|
||||
test(function() {
|
||||
// Replaced circa May 2012 by a DOMString (later, IDBTransactionMode enum).
|
||||
assert_false('VERSION_CHANGE' in IDBTransaction);
|
||||
}, '"VERSION_CHANGE" should not be supported on IDBTransaction.');
|
||||
</script>
|
|
@ -17,6 +17,15 @@
|
|||
assert_false(keyRange.upperOpen, "keyRange.upperOpen");
|
||||
}, "IDBKeyRange.only() - returns an IDBKeyRange and the properties are set correctly");
|
||||
|
||||
test( function() {
|
||||
assert_throws('DataError', function() { IDBKeyRange.only(undefined); }, 'undefined is not a valid key');
|
||||
assert_throws('DataError', function() { IDBKeyRange.only(null); }, 'null is not a valid key');
|
||||
assert_throws('DataError', function() { IDBKeyRange.only({}); }, 'Object is not a valid key');
|
||||
assert_throws('DataError', function() { IDBKeyRange.only(Symbol()); }, 'Symbol is not a valid key');
|
||||
assert_throws('DataError', function() { IDBKeyRange.only(true); }, 'boolean is not a valid key');
|
||||
assert_throws('DataError', function() { IDBKeyRange.only(() => {}); }, 'function is not a valid key');
|
||||
}, "IDBKeyRange.only() - throws on invalid keys");
|
||||
|
||||
// lowerBound
|
||||
test( function() {
|
||||
var keyRange = IDBKeyRange.lowerBound(1, true)
|
||||
|
@ -32,6 +41,15 @@
|
|||
assert_false(keyRange.lowerOpen, "keyRange.lowerOpen");
|
||||
}, "IDBKeyRange.lowerBound() - 'open' parameter has correct default set");
|
||||
|
||||
test( function() {
|
||||
assert_throws('DataError', function() { IDBKeyRange.lowerBound(undefined); }, 'undefined is not a valid key');
|
||||
assert_throws('DataError', function() { IDBKeyRange.lowerBound(null); }, 'null is not a valid key');
|
||||
assert_throws('DataError', function() { IDBKeyRange.lowerBound({}); }, 'Object is not a valid key');
|
||||
assert_throws('DataError', function() { IDBKeyRange.lowerBound(Symbol()); }, 'Symbol is not a valid key');
|
||||
assert_throws('DataError', function() { IDBKeyRange.lowerBound(true); }, 'boolean is not a valid key');
|
||||
assert_throws('DataError', function() { IDBKeyRange.lowerBound(() => {}); }, 'function is not a valid key');
|
||||
}, "IDBKeyRange.lowerBound() - throws on invalid keys");
|
||||
|
||||
// upperBound
|
||||
test( function() {
|
||||
var keyRange = IDBKeyRange.upperBound(1, true);
|
||||
|
@ -47,6 +65,15 @@
|
|||
assert_false(keyRange.upperOpen, "keyRange.upperOpen");
|
||||
}, "IDBKeyRange.upperBound() - 'open' parameter has correct default set");
|
||||
|
||||
test( function() {
|
||||
assert_throws('DataError', function() { IDBKeyRange.upperBound(undefined); }, 'undefined is not a valid key');
|
||||
assert_throws('DataError', function() { IDBKeyRange.upperBound(null); }, 'null is not a valid key');
|
||||
assert_throws('DataError', function() { IDBKeyRange.upperBound({}); }, 'Object is not a valid key');
|
||||
assert_throws('DataError', function() { IDBKeyRange.upperBound(Symbol()); }, 'Symbol is not a valid key');
|
||||
assert_throws('DataError', function() { IDBKeyRange.upperBound(true); }, 'boolean is not a valid key');
|
||||
assert_throws('DataError', function() { IDBKeyRange.upperBound(() => {}); }, 'function is not a valid key');
|
||||
}, "IDBKeyRange.upperBound() - throws on invalid keys");
|
||||
|
||||
// bound
|
||||
test( function() {
|
||||
var keyRange = IDBKeyRange.bound(1, 2, true, true);
|
||||
|
|
25
tests/wpt/web-platform-tests/IndexedDB/idbrequest_error.html
Normal file
25
tests/wpt/web-platform-tests/IndexedDB/idbrequest_error.html
Normal file
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>IDBRequest.error</title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=support.js></script>
|
||||
|
||||
<script>
|
||||
async_test(t => {
|
||||
var open = createdb(t);
|
||||
open.onupgradeneeded = t.step_func(e => {
|
||||
var db = e.target.result;
|
||||
db.createObjectStore('store');
|
||||
});
|
||||
open.onsuccess = t.step_func(e => {
|
||||
var db = e.target.result;
|
||||
var request = db.transaction('store').objectStore('store').get(0);
|
||||
|
||||
assert_equals(request.readyState, 'pending');
|
||||
assert_throws('InvalidStateError', () => request.error,
|
||||
'IDBRequest.error should throw if request is pending');
|
||||
t.done();
|
||||
});
|
||||
}, 'IDBRequest.error throws if ready state is pending');
|
||||
</script>
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>IDBRequest.result</title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=support.js></script>
|
||||
|
||||
<script>
|
||||
async_test(t => {
|
||||
var open = createdb(t);
|
||||
open.onupgradeneeded = t.step_func(e => {
|
||||
var db = e.target.result;
|
||||
db.createObjectStore('store');
|
||||
});
|
||||
open.onsuccess = t.step_func(e => {
|
||||
var db = e.target.result;
|
||||
var request = db.transaction('store').objectStore('store').get(0);
|
||||
|
||||
assert_equals(request.readyState, 'pending');
|
||||
assert_throws('InvalidStateError', () => request.result,
|
||||
'IDBRequest.result should throw if request is pending');
|
||||
t.done();
|
||||
});
|
||||
}, 'IDBRequest.result throws if ready state is pending');
|
||||
</script>
|
|
@ -11,28 +11,35 @@
|
|||
|
||||
<script>
|
||||
"use strict";
|
||||
setup(function() {
|
||||
var idlArray = new IdlArray();
|
||||
|
||||
async_test(function(t) {
|
||||
var request = new XMLHttpRequest();
|
||||
request.open("GET", "interfaces.idl");
|
||||
request.send();
|
||||
request.onload = function() {
|
||||
request.onload = t.step_func(function() {
|
||||
var idlArray = new IdlArray();
|
||||
var idls = request.responseText;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/browsers.html#window
|
||||
idlArray.add_untested_idls("[PrimaryGlobal] interface Window { };");
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope-mixin
|
||||
idlArray.add_untested_idls(`[NoInterfaceObject, Exposed=(Window,Worker)]
|
||||
interface WindowOrWorkerGlobalScope {};`);
|
||||
idlArray.add_untested_idls("Window implements WindowOrWorkerGlobalScope;");
|
||||
|
||||
// https://dom.spec.whatwg.org/#interface-event
|
||||
idlArray.add_untested_idls("[Exposed=(Window,Worker)] interface Event { };");
|
||||
|
||||
// https://dom.spec.whatwg.org/#interface-eventtarget
|
||||
idlArray.add_untested_idls("[Exposed=(Window,Worker)] interface EventTarget { };");
|
||||
|
||||
// From Indexed DB:
|
||||
idlArray.add_idls(idls);
|
||||
idlArray.add_idls("Window implements IDBEnvironment;");
|
||||
|
||||
idlArray.add_objects({
|
||||
IDBCursor: [],
|
||||
IDBCursorWithValue: [],
|
||||
IDBDatabase: [],
|
||||
IDBEnvironment: [],
|
||||
IDBFactory: ["window.indexedDB"],
|
||||
IDBIndex: [],
|
||||
IDBKeyRange: ["IDBKeyRange.only(0)"],
|
||||
|
@ -41,10 +48,11 @@ setup(function() {
|
|||
IDBRequest: [],
|
||||
IDBTransaction: [],
|
||||
IDBVersionChangeEvent: ["new IDBVersionChangeEvent('foo')"],
|
||||
DOMStringList: [],
|
||||
});
|
||||
|
||||
idlArray.test();
|
||||
done();
|
||||
};
|
||||
}, {explicit_done: true});
|
||||
t.done();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
enum IDBTransactionMode {
|
||||
"readonly",
|
||||
"readwrite",
|
||||
"versionchange"
|
||||
[Exposed=(Window,Worker)]
|
||||
interface IDBRequest : EventTarget {
|
||||
readonly attribute any result;
|
||||
readonly attribute DOMException? error;
|
||||
readonly attribute (IDBObjectStore or IDBIndex or IDBCursor)? source;
|
||||
readonly attribute IDBTransaction? transaction;
|
||||
readonly attribute IDBRequestReadyState readyState;
|
||||
|
||||
// Event handlers:
|
||||
attribute EventHandler onsuccess;
|
||||
attribute EventHandler onerror;
|
||||
};
|
||||
|
||||
enum IDBRequestReadyState {
|
||||
|
@ -9,53 +16,9 @@ enum IDBRequestReadyState {
|
|||
"done"
|
||||
};
|
||||
|
||||
[Exposed=(Window,Worker)]
|
||||
interface IDBKeyRange {
|
||||
readonly attribute any lower;
|
||||
readonly attribute any upper;
|
||||
readonly attribute boolean lowerOpen;
|
||||
readonly attribute boolean upperOpen;
|
||||
static IDBKeyRange only (any value);
|
||||
static IDBKeyRange lowerBound (any lower, optional boolean open = false);
|
||||
static IDBKeyRange upperBound (any upper, optional boolean open = false);
|
||||
static IDBKeyRange bound (any lower, any upper, optional boolean lowerOpen = false, optional boolean upperOpen = false);
|
||||
};
|
||||
|
||||
enum IDBCursorDirection {
|
||||
"next",
|
||||
"nextunique",
|
||||
"prev",
|
||||
"prevunique"
|
||||
};
|
||||
|
||||
dictionary IDBObjectStoreParameters {
|
||||
(DOMString or sequence<DOMString>)? keyPath = null;
|
||||
boolean autoIncrement = false;
|
||||
};
|
||||
|
||||
dictionary IDBIndexParameters {
|
||||
boolean unique = false;
|
||||
boolean multiEntry = false;
|
||||
};
|
||||
|
||||
dictionary IDBVersionChangeEventInit : EventInit {
|
||||
unsigned long long oldVersion = 0;
|
||||
unsigned long long? newVersion = null;
|
||||
};
|
||||
|
||||
[Exposed=(Window,Worker)]
|
||||
interface IDBRequest : EventTarget {
|
||||
readonly attribute any result;
|
||||
readonly attribute DOMError error;
|
||||
readonly attribute (IDBObjectStore or IDBIndex or IDBCursor)? source;
|
||||
readonly attribute IDBTransaction transaction;
|
||||
readonly attribute IDBRequestReadyState readyState;
|
||||
attribute EventHandler onsuccess;
|
||||
attribute EventHandler onerror;
|
||||
};
|
||||
|
||||
[Exposed=(Window,Worker)]
|
||||
interface IDBOpenDBRequest : IDBRequest {
|
||||
// Event handlers:
|
||||
attribute EventHandler onblocked;
|
||||
attribute EventHandler onupgradeneeded;
|
||||
};
|
||||
|
@ -67,15 +30,21 @@ interface IDBVersionChangeEvent : Event {
|
|||
readonly attribute unsigned long long? newVersion;
|
||||
};
|
||||
|
||||
[NoInterfaceObject]
|
||||
interface IDBEnvironment {
|
||||
readonly attribute IDBFactory indexedDB;
|
||||
dictionary IDBVersionChangeEventInit : EventInit {
|
||||
unsigned long long oldVersion = 0;
|
||||
unsigned long long? newVersion = null;
|
||||
};
|
||||
|
||||
partial interface WindowOrWorkerGlobalScope {
|
||||
[SameObject] readonly attribute IDBFactory indexedDB;
|
||||
};
|
||||
|
||||
[Exposed=(Window,Worker)]
|
||||
interface IDBFactory {
|
||||
IDBOpenDBRequest open (DOMString name, [EnforceRange] optional unsigned long long version);
|
||||
IDBOpenDBRequest open(DOMString name,
|
||||
[EnforceRange] optional unsigned long long version);
|
||||
IDBOpenDBRequest deleteDatabase(DOMString name);
|
||||
|
||||
short cmp(any first, any second);
|
||||
};
|
||||
|
||||
|
@ -84,16 +53,27 @@ interface IDBDatabase : EventTarget {
|
|||
readonly attribute DOMString name;
|
||||
readonly attribute unsigned long long version;
|
||||
readonly attribute DOMStringList objectStoreNames;
|
||||
IDBObjectStore createObjectStore (DOMString name, optional IDBObjectStoreParameters optionalParameters);
|
||||
void deleteObjectStore (DOMString name);
|
||||
IDBTransaction transaction ((DOMString or sequence<DOMString>) storeNames, optional IDBTransactionMode mode = "readonly");
|
||||
|
||||
IDBTransaction transaction((DOMString or sequence<DOMString>) storeNames,
|
||||
optional IDBTransactionMode mode = "readonly");
|
||||
void close();
|
||||
|
||||
IDBObjectStore createObjectStore(DOMString name,
|
||||
optional IDBObjectStoreParameters options);
|
||||
void deleteObjectStore(DOMString name);
|
||||
|
||||
// Event handlers:
|
||||
attribute EventHandler onabort;
|
||||
attribute EventHandler onclose;
|
||||
attribute EventHandler onerror;
|
||||
attribute EventHandler onversionchange;
|
||||
};
|
||||
|
||||
dictionary IDBObjectStoreParameters {
|
||||
(DOMString or sequence<DOMString>)? keyPath = null;
|
||||
boolean autoIncrement = false;
|
||||
};
|
||||
|
||||
[Exposed=(Window,Worker)]
|
||||
interface IDBObjectStore {
|
||||
attribute DOMString name;
|
||||
|
@ -101,16 +81,35 @@ interface IDBObjectStore {
|
|||
readonly attribute DOMStringList indexNames;
|
||||
readonly attribute IDBTransaction transaction;
|
||||
readonly attribute boolean autoIncrement;
|
||||
|
||||
IDBRequest put(any value, optional any key);
|
||||
IDBRequest add(any value, optional any key);
|
||||
IDBRequest delete (any key);
|
||||
IDBRequest get (any key);
|
||||
IDBRequest delete(any query);
|
||||
IDBRequest clear();
|
||||
IDBRequest openCursor (optional any range, optional IDBCursorDirection direction = "next");
|
||||
IDBIndex createIndex (DOMString name, (DOMString or sequence<DOMString>) keyPath, optional IDBIndexParameters optionalParameters);
|
||||
IDBRequest get(any query);
|
||||
IDBRequest getKey(any query);
|
||||
IDBRequest getAll(optional any query,
|
||||
[EnforceRange] optional unsigned long count);
|
||||
IDBRequest getAllKeys(optional any query,
|
||||
[EnforceRange] optional unsigned long count);
|
||||
IDBRequest count(optional any query);
|
||||
|
||||
IDBRequest openCursor(optional any query,
|
||||
optional IDBCursorDirection direction = "next");
|
||||
IDBRequest openKeyCursor(optional any query,
|
||||
optional IDBCursorDirection direction = "next");
|
||||
|
||||
IDBIndex index(DOMString name);
|
||||
|
||||
IDBIndex createIndex(DOMString name,
|
||||
(DOMString or sequence<DOMString>) keyPath,
|
||||
optional IDBIndexParameters options);
|
||||
void deleteIndex(DOMString indexName);
|
||||
IDBRequest count (optional any key);
|
||||
};
|
||||
|
||||
dictionary IDBIndexParameters {
|
||||
boolean unique = false;
|
||||
boolean multiEntry = false;
|
||||
};
|
||||
|
||||
[Exposed=(Window,Worker)]
|
||||
|
@ -120,11 +119,38 @@ interface IDBIndex {
|
|||
readonly attribute any keyPath;
|
||||
readonly attribute boolean multiEntry;
|
||||
readonly attribute boolean unique;
|
||||
IDBRequest openCursor (optional any range, optional IDBCursorDirection direction = "next");
|
||||
IDBRequest openKeyCursor (optional any range, optional IDBCursorDirection direction = "next");
|
||||
IDBRequest get (any key);
|
||||
IDBRequest getKey (any key);
|
||||
IDBRequest count (optional any key);
|
||||
|
||||
IDBRequest get(any query);
|
||||
IDBRequest getKey(any query);
|
||||
IDBRequest getAll(optional any query,
|
||||
[EnforceRange] optional unsigned long count);
|
||||
IDBRequest getAllKeys(optional any query,
|
||||
[EnforceRange] optional unsigned long count);
|
||||
IDBRequest count(optional any query);
|
||||
|
||||
IDBRequest openCursor(optional any query,
|
||||
optional IDBCursorDirection direction = "next");
|
||||
IDBRequest openKeyCursor(optional any query,
|
||||
optional IDBCursorDirection direction = "next");
|
||||
};
|
||||
|
||||
[Exposed=(Window,Worker)]
|
||||
interface IDBKeyRange {
|
||||
readonly attribute any lower;
|
||||
readonly attribute any upper;
|
||||
readonly attribute boolean lowerOpen;
|
||||
readonly attribute boolean upperOpen;
|
||||
|
||||
// Static construction methods:
|
||||
static IDBKeyRange only(any value);
|
||||
static IDBKeyRange lowerBound(any lower, optional boolean open = false);
|
||||
static IDBKeyRange upperBound(any upper, optional boolean open = false);
|
||||
static IDBKeyRange bound(any lower,
|
||||
any upper,
|
||||
optional boolean lowerOpen = false,
|
||||
optional boolean upperOpen = false);
|
||||
|
||||
boolean includes(any key);
|
||||
};
|
||||
|
||||
[Exposed=(Window,Worker)]
|
||||
|
@ -133,12 +159,22 @@ interface IDBCursor {
|
|||
readonly attribute IDBCursorDirection direction;
|
||||
readonly attribute any key;
|
||||
readonly attribute any primaryKey;
|
||||
IDBRequest update (any value);
|
||||
|
||||
void advance([EnforceRange] unsigned long count);
|
||||
void continue(optional any key);
|
||||
void continuePrimaryKey(any key, any primaryKey);
|
||||
|
||||
IDBRequest update(any value);
|
||||
IDBRequest delete();
|
||||
};
|
||||
|
||||
enum IDBCursorDirection {
|
||||
"next",
|
||||
"nextunique",
|
||||
"prev",
|
||||
"prevunique"
|
||||
};
|
||||
|
||||
[Exposed=(Window,Worker)]
|
||||
interface IDBCursorWithValue : IDBCursor {
|
||||
readonly attribute any value;
|
||||
|
@ -146,12 +182,30 @@ interface IDBCursorWithValue : IDBCursor {
|
|||
|
||||
[Exposed=(Window,Worker)]
|
||||
interface IDBTransaction : EventTarget {
|
||||
readonly attribute DOMStringList objectStoreNames;
|
||||
readonly attribute IDBTransactionMode mode;
|
||||
readonly attribute IDBDatabase db;
|
||||
readonly attribute DOMError error;
|
||||
readonly attribute DOMException error;
|
||||
|
||||
IDBObjectStore objectStore(DOMString name);
|
||||
void abort();
|
||||
|
||||
// Event handlers:
|
||||
attribute EventHandler onabort;
|
||||
attribute EventHandler oncomplete;
|
||||
attribute EventHandler onerror;
|
||||
};
|
||||
|
||||
enum IDBTransactionMode {
|
||||
"readonly",
|
||||
"readwrite",
|
||||
"versionchange"
|
||||
};
|
||||
|
||||
interface DOMStringList {
|
||||
readonly attribute unsigned long length;
|
||||
getter DOMString (unsigned long index);
|
||||
DOMString? item(unsigned long index);
|
||||
|
||||
boolean contains(DOMString str);
|
||||
};
|
||||
|
|
|
@ -3,26 +3,35 @@
|
|||
importScripts("/resources/testharness.js");
|
||||
importScripts("/resources/WebIDLParser.js", "/resources/idlharness.js");
|
||||
|
||||
async_test(function(t) {
|
||||
var request = new XMLHttpRequest();
|
||||
request.open("GET", "interfaces.idl");
|
||||
request.send();
|
||||
request.onload = function() {
|
||||
request.onload = t.step_func(function() {
|
||||
var idlArray = new IdlArray();
|
||||
var idls = request.responseText;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/workers.html#workerglobalscope
|
||||
idlArray.add_untested_idls("[Exposed=Worker] interface WorkerGlobalScope {};");
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope-mixin
|
||||
idlArray.add_untested_idls(`[NoInterfaceObject, Exposed=(Window,Worker)]
|
||||
interface WindowOrWorkerGlobalScope {};`);
|
||||
idlArray.add_untested_idls("WorkerGlobalScope implements WindowOrWorkerGlobalScope;");
|
||||
|
||||
// https://dom.spec.whatwg.org/#interface-event
|
||||
idlArray.add_untested_idls("[Exposed=(Window,Worker)] interface Event { };");
|
||||
|
||||
// https://dom.spec.whatwg.org/#interface-eventtarget
|
||||
idlArray.add_untested_idls("[Exposed=(Window,Worker)] interface EventTarget { };");
|
||||
|
||||
// From Indexed DB:
|
||||
idlArray.add_idls("WorkerGlobalScope implements IDBEnvironment;");
|
||||
idlArray.add_idls(idls);
|
||||
|
||||
idlArray.add_objects({
|
||||
IDBCursor: [],
|
||||
IDBCursorWithValue: [],
|
||||
IDBDatabase: [],
|
||||
IDBEnvironment: [],
|
||||
IDBFactory: ["self.indexedDB"],
|
||||
IDBIndex: [],
|
||||
IDBKeyRange: ["IDBKeyRange.only(0)"],
|
||||
|
@ -31,7 +40,11 @@ request.onload = function() {
|
|||
IDBRequest: [],
|
||||
IDBTransaction: [],
|
||||
IDBVersionChangeEvent: ["new IDBVersionChangeEvent('foo')"],
|
||||
DOMStringList: [],
|
||||
});
|
||||
idlArray.test();
|
||||
t.done();
|
||||
});
|
||||
});
|
||||
|
||||
done();
|
||||
};
|
||||
|
|
134
tests/wpt/web-platform-tests/IndexedDB/name-scopes.html
Normal file
134
tests/wpt/web-platform-tests/IndexedDB/name-scopes.html
Normal file
|
@ -0,0 +1,134 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>
|
||||
IndexedDB: scoping for database / object store / index names, and index keys
|
||||
</title>
|
||||
<link rel="help" href="https://w3c.github.io/IndexedDB/#constructs">
|
||||
<link rel="author" href="pwnall@chromium.org" title="Victor Costan">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="support-promises.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
// Creates the structure inside a test database.
|
||||
//
|
||||
// The structure includes two stores with identical indexes and nearly-similar
|
||||
// records. The records differ in the "path" attribute values, which are used to
|
||||
// verify that IndexedDB returns the correct records when queried.
|
||||
//
|
||||
// databaseName appears redundant, but we don't want to rely on database.name.
|
||||
const buildStores = (database, databaseName, useUniqueKeys) => {
|
||||
for (let storeName of ['x', 'y']) {
|
||||
const store = database.createObjectStore(
|
||||
storeName, { keyPath: 'pKey', autoIncrement: true });
|
||||
for (let indexName of ['x', 'y']) {
|
||||
store.createIndex(
|
||||
indexName, `${indexName}Key`, { unique: useUniqueKeys });
|
||||
}
|
||||
|
||||
for (let xKeyRoot of ['x', 'y']) {
|
||||
for (let yKeyRoot of ['x', 'y']) {
|
||||
let xKey, yKey;
|
||||
if (useUniqueKeys) {
|
||||
xKey = `${xKeyRoot}${yKeyRoot}`;
|
||||
yKey = `${yKeyRoot}${xKeyRoot}`;
|
||||
} else {
|
||||
xKey = xKeyRoot;
|
||||
yKey = yKeyRoot;
|
||||
}
|
||||
const path = `${databaseName}-${storeName}-${xKeyRoot}-${yKeyRoot}`;
|
||||
store.put({ xKey: xKey, yKey: yKey, path: path });
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Creates two databases with identical structures.
|
||||
const buildDatabases = (testCase, useUniqueKeys) => {
|
||||
return createNamedDatabase(
|
||||
testCase, 'x', database => buildStores(database, 'x', useUniqueKeys))
|
||||
.then(database => database.close())
|
||||
.then(() => createNamedDatabase(
|
||||
testCase, 'y', database => buildStores(database, 'y', useUniqueKeys)))
|
||||
.then(database => database.close());
|
||||
};
|
||||
|
||||
// Reads all the store's values using an index.
|
||||
//
|
||||
// Returns a Promise that resolves with an array of values.
|
||||
const readIndex = (testCase, index) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const results = [];
|
||||
const request = index.openCursor(IDBKeyRange.bound('a', 'z'), 'next');
|
||||
request.onsuccess = () => {
|
||||
const cursor = request.result;
|
||||
if (cursor) {
|
||||
results.push(cursor.value);
|
||||
cursor.continue();
|
||||
} else {
|
||||
resolve(results);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Verifies that a database contains the expected records.
|
||||
const checkDatabaseContent =
|
||||
(testCase, database, databaseName, usedUniqueKeys) => {
|
||||
const promises = [];
|
||||
const transaction = database.transaction(['x', 'y'], 'readonly');
|
||||
for (let storeName of ['x', 'y']) {
|
||||
const store = transaction.objectStore(storeName);
|
||||
for (let indexName of ['x', 'y']) {
|
||||
const index = store.index(indexName);
|
||||
|
||||
const promise = readIndex(testCase, index).then((results) => {
|
||||
assert_array_equals(
|
||||
results.map(result => `${result.path}:${result.pKey}`).sort(),
|
||||
[`${databaseName}-${storeName}-x-x:1`,
|
||||
`${databaseName}-${storeName}-x-y:2`,
|
||||
`${databaseName}-${storeName}-y-x:3`,
|
||||
`${databaseName}-${storeName}-y-y:4`],
|
||||
'The results should include all records put into the store');
|
||||
|
||||
let expectedKeys = (usedUniqueKeys) ?
|
||||
['xx:xx', 'xy:yx', 'yx:xy', 'yy:yy'] : ['x:x', 'x:y', 'y:x', 'y:y'];
|
||||
assert_array_equals(
|
||||
results.map(result => `${result.xKey}:${result.yKey}`).sort(),
|
||||
expectedKeys,
|
||||
'The results should include all the index keys put in the store');
|
||||
|
||||
assert_array_equals(
|
||||
results.map(result => result[`${indexName}Key`]),
|
||||
results.map(result => result[`${indexName}Key`]).sort(),
|
||||
'The results should be sorted by the index key');
|
||||
});
|
||||
promises.push(promise);
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.all(promises).then(() => database);
|
||||
}
|
||||
|
||||
promise_test(testCase => {
|
||||
return buildDatabases(testCase, false)
|
||||
.then(() => openNamedDatabase(testCase, 'x', 1))
|
||||
.then(database => checkDatabaseContent(testCase, database, 'x', false))
|
||||
.then(database => database.close())
|
||||
.then(() => openNamedDatabase(testCase, 'y', 1))
|
||||
.then(database => checkDatabaseContent(testCase, database, 'y', false))
|
||||
.then(database => database.close());
|
||||
}, 'Non-unique index keys');
|
||||
|
||||
promise_test(testCase => {
|
||||
return buildDatabases(testCase, true)
|
||||
.then(() => openNamedDatabase(testCase, 'x', 1))
|
||||
.then(database => checkDatabaseContent(testCase, database, 'x', true))
|
||||
.then(database => database.close())
|
||||
.then(() => openNamedDatabase(testCase, 'y', 1))
|
||||
.then(database => checkDatabaseContent(testCase, database, 'y', true))
|
||||
.then(database => database.close());
|
||||
}, 'Unique index keys');
|
||||
|
||||
</script>
|
|
@ -21,11 +21,27 @@ const requestWatcher = (testCase, request) => {
|
|||
// resolves to an IndexedDB database that must be closed by the caller. If the
|
||||
// versionchange transaction is aborted, the promise resolves to an error.
|
||||
const migrateDatabase = (testCase, newVersion, migrationCallback) => {
|
||||
return migrateNamedDatabase(
|
||||
testCase, databaseName(testCase), newVersion, migrationCallback);
|
||||
};
|
||||
|
||||
// Migrates an IndexedDB database.
|
||||
//
|
||||
// newVersion must be greater than the database's current version.
|
||||
//
|
||||
// migrationCallback will be called during a versionchange transaction and will
|
||||
// be given the created database and the versionchange transaction.
|
||||
//
|
||||
// Returns a promise. If the versionchange transaction goes through, the promise
|
||||
// resolves to an IndexedDB database that must be closed by the caller. If the
|
||||
// versionchange transaction is aborted, the promise resolves to an error.
|
||||
const migrateNamedDatabase =
|
||||
(testCase, databaseName, newVersion, migrationCallback) => {
|
||||
// We cannot use eventWatcher.wait_for('upgradeneeded') here, because
|
||||
// the versionchange transaction auto-commits before the Promise's then
|
||||
// callback gets called.
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = indexedDB.open(databaseName(testCase), newVersion);
|
||||
const request = indexedDB.open(databaseName, newVersion);
|
||||
request.onupgradeneeded = testCase.step_func(event => {
|
||||
const database = event.target.result;
|
||||
const transaction = event.target.transaction;
|
||||
|
@ -41,8 +57,8 @@ const migrateDatabase = (testCase, newVersion, migrationCallback) => {
|
|||
resolve(event);
|
||||
};
|
||||
request.onsuccess = () => reject(new Error(
|
||||
'indexedDB.open should not succeed after the ' +
|
||||
'versionchange transaction is aborted'));
|
||||
'indexedDB.open should not succeed after the versionchange ' +
|
||||
'transaction is aborted'));
|
||||
transactionAbort();
|
||||
abortCalled = true;
|
||||
}
|
||||
|
@ -68,11 +84,22 @@ const migrateDatabase = (testCase, newVersion, migrationCallback) => {
|
|||
// Returns a promise that resolves to an IndexedDB database. The caller must
|
||||
// close the database.
|
||||
const createDatabase = (testCase, setupCallback) => {
|
||||
const request = indexedDB.deleteDatabase(databaseName(testCase));
|
||||
return createNamedDatabase(testCase, databaseName(testCase), setupCallback);
|
||||
};
|
||||
|
||||
// Creates an IndexedDB database.
|
||||
//
|
||||
// setupCallback will be called during a versionchange transaction, and will be
|
||||
// given the created database and the versionchange transaction.
|
||||
//
|
||||
// Returns a promise that resolves to an IndexedDB database. The caller must
|
||||
// close the database.
|
||||
const createNamedDatabase = (testCase, databaseName, setupCallback) => {
|
||||
const request = indexedDB.deleteDatabase(databaseName);
|
||||
const eventWatcher = requestWatcher(testCase, request);
|
||||
|
||||
return eventWatcher.wait_for('success').then(event =>
|
||||
migrateDatabase(testCase, 1, setupCallback));
|
||||
migrateNamedDatabase(testCase, databaseName, 1, setupCallback));
|
||||
};
|
||||
|
||||
// Opens an IndexedDB database without performing schema changes.
|
||||
|
@ -82,10 +109,19 @@ const createDatabase = (testCase, setupCallback) => {
|
|||
// Returns a promise that resolves to an IndexedDB database. The caller must
|
||||
// close the database.
|
||||
const openDatabase = (testCase, version) => {
|
||||
const request = indexedDB.open(databaseName(testCase), version);
|
||||
return openNamedDatabase(testCase, databaseName(testCase), version);
|
||||
}
|
||||
|
||||
// Opens an IndexedDB database without performing schema changes.
|
||||
//
|
||||
// The given version number must match the database's current version.
|
||||
//
|
||||
// Returns a promise that resolves to an IndexedDB database. The caller must
|
||||
// close the database.
|
||||
const openNamedDatabase = (testCase, databaseName, version) => {
|
||||
const request = indexedDB.open(databaseName, version);
|
||||
const eventWatcher = requestWatcher(testCase, request);
|
||||
return eventWatcher.wait_for('success').then(
|
||||
event => event.target.result);
|
||||
return eventWatcher.wait_for('success').then(event => event.target.result);
|
||||
}
|
||||
|
||||
// The data in the 'books' object store records in the first example of the
|
||||
|
|
33
tests/wpt/web-platform-tests/LICENSE.md
Normal file
33
tests/wpt/web-platform-tests/LICENSE.md
Normal file
|
@ -0,0 +1,33 @@
|
|||
#Dual-License for W3C Test Suites
|
||||
|
||||
All documents in this Repository are licensed by contributors to be distributed under both the [W3C Test Suite License](#w3c-test-suite-license) and the [W3C 3-clause BSD License](#w3c-3-clause-bsd-license), reproduced below. The choice of license is up to the licensee. For more information, see [Licenses for W3C Test Suites](https://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright.html)
|
||||
|
||||
# W3C Test Suite License
|
||||
|
||||
This document, Test Suites and other documents that link to this statement are provided by the copyright holders under the following license: By using and/or copying this document, or the W3C document from which this statement is linked, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions:
|
||||
|
||||
Permission to copy, and distribute the contents of this document, or the W3C document from which this statement is linked, in any medium for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the document, or portions thereof, that you use:
|
||||
|
||||
* A link or URL to the original W3C document.
|
||||
* The pre-existing copyright notice of the original author, or if it doesn't exist, a notice (hypertext is preferred, but a textual representation is permitted) of the form: "Copyright © [$date-of-document] World Wide Web Consortium, (MIT, ERCIM, Keio, Beihang) and others. All Rights Reserved. http://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright.html"
|
||||
* If it exists, the STATUS of the W3C document.
|
||||
|
||||
When space permits, inclusion of the full text of this NOTICE should be provided. We request that authorship attribution be provided in any software, documents, or other items or products that you create pursuant to the implementation of the contents of this document, or any portion thereof.
|
||||
|
||||
No right to create modifications or derivatives of W3C documents is granted pursuant to this license. However, if additional requirements (documented in the Copyright FAQ) are satisfied, the right to create modifications or derivatives is sometimes granted by the W3C to individuals complying with those requirements.
|
||||
|
||||
If a Test Suite distinguishes the test harness (or, framework for navigation) and the actual tests, permission is given to remove or alter the harness or navigation if the Test Suite in question allows to do so. The tests themselves shall NOT be changed in any way.
|
||||
|
||||
The name and trademarks of W3C and other copyright holders may NOT be used in advertising or publicity pertaining to this document or other documents that link to this statement without specific, written prior permission. Title to copyright in this document will at all times remain with copyright holders. Permission is given to use the trademarked string "W3C" within claims of performance concerning W3C Specifications or features described therein, and there only, if the test suite so authorizes.
|
||||
|
||||
THIS WORK IS PROVIDED BY W3C, MIT, ERCIM, KEIO, BEIHANG, THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL W3C, MIT, ERCIM, KEIO, BEIHANG, THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# W3C 3-clause BSD License
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of works must retain the original copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the original copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the W3C nor the names of its contributors may be used to endorse or promote products derived from this work without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -18,9 +18,12 @@ Running the Tests
|
|||
=================
|
||||
|
||||
The tests are designed to be run from your local computer. The test
|
||||
environment requires Python 2.7+ (but not Python 3.x). You will also
|
||||
need a copy of OpenSSL. Users on Windows should read the
|
||||
[Windows Notes](#windows-notes) section below.
|
||||
environment requires [Python 2.7+](http://www.python.org/downloads) (but not Python 3.x).
|
||||
You will also need a copy of OpenSSL.
|
||||
|
||||
On Windows, be sure to add the Python directory (`c:\python2x`, by default) to
|
||||
your `%Path%` [Environment Variable](http://www.computerhope.com/issues/ch000549.htm),
|
||||
and read the [Windows Notes](#windows-notes) section below.
|
||||
|
||||
To get the tests running, you need to set up the test domains in your
|
||||
[`hosts` file](http://en.wikipedia.org/wiki/Hosts_%28file%29%23Location_in_the_file_system). The
|
||||
|
@ -80,18 +83,29 @@ Running wptserve with SSL enabled on Windows typically requires
|
|||
installing an OpenSSL distribution.
|
||||
[Shining Light](https://slproweb.com/products/Win32OpenSSL.html)
|
||||
provide a convenient installer that is known to work, but requires a
|
||||
little extra setup.
|
||||
little extra setup, i.e.:
|
||||
|
||||
After installation ensure that the path to OpenSSL is on your `%Path%`
|
||||
environment variable.
|
||||
Run the installer for Win32_OpenSSL_v1.1.0b (30MB). During installation,
|
||||
change the default location for where to Copy OpenSSL Dlls from the
|
||||
System directory to the /bin directory.
|
||||
|
||||
Then set the path to the default OpenSSL configuration file (usually
|
||||
something like `C:\OpenSSL-Win32\bin\openssl.cfg` in the server
|
||||
configuration. To do this copy `config.default.json` in the
|
||||
web-platform-tests root to `config.json`. Then edit the JSON so that
|
||||
the key `ssl/openssl/base_conf_path` has a value that is the path to
|
||||
the OpenSSL config file.
|
||||
After installation, ensure that the path to OpenSSL (typically,
|
||||
this will be `C:\OpenSSL-Win32\bin`) is in your `%Path%`
|
||||
[Environment Variable](http://www.computerhope.com/issues/ch000549.htm).
|
||||
If you forget to do this part, you will most likely see a 'File Not Found'
|
||||
error when you start wptserve.
|
||||
|
||||
Finally, set the path value in the server configuration file to the
|
||||
default OpenSSL configuration file location. To do this,
|
||||
copy `config.default.json` in the web-platform-tests root to `config.json`.
|
||||
Then edit the JSON so that the key `ssl/openssl/base_conf_path` has a
|
||||
value that is the path to the OpenSSL config file (typically this
|
||||
will be `C:\\OpenSSL-Win32\\bin\\openssl.cfg`).
|
||||
|
||||
Alternatively, you may also use
|
||||
[Bash on Ubuntu on Windows](https://msdn.microsoft.com/en-us/commandline/wsl/about)
|
||||
in the Windows 10 Anniversary Update build, then access your windows
|
||||
partition from there to launch wptserve.
|
||||
|
||||
Test Runner
|
||||
===========
|
||||
|
@ -228,6 +242,15 @@ because we have to go through all the tests and ensure that they match
|
|||
the specification correctly. But we look at all of them, and take
|
||||
everything that we can.
|
||||
|
||||
OWNERS files are used only to indicate who should be notified of pull
|
||||
requests. If you are interested in receiving notifications of proposed
|
||||
changes to tests in a given directory, feel free to add yourself to the
|
||||
OWNERS file. Anyone with expertise in the specification under test can
|
||||
approve a pull request. In particular, if a test change has already
|
||||
been adequately reviewed "upstream" in another repository, it can be
|
||||
pushed here without any further review by supplying a link to the
|
||||
upstream review.
|
||||
|
||||
Getting Involved
|
||||
================
|
||||
|
||||
|
|
|
@ -5,16 +5,19 @@ function run_test() {
|
|||
|
||||
var wrappers = []; // Things we wrap (and upwrap) keys with
|
||||
var keys = []; // Things to wrap and unwrap
|
||||
var ecdhPeerKey; // ECDH peer public key needed for non-extractable ECDH key comparison
|
||||
|
||||
// Generate all the keys needed, then iterate over all combinations
|
||||
// to test wrapping and unwrapping.
|
||||
Promise.all([generateWrappingKeys(), generateKeysToWrap()])
|
||||
Promise.all([generateWrappingKeys(), generateKeysToWrap(), generateEcdhPeerKey()])
|
||||
.then(function(results) {
|
||||
var promises = [];
|
||||
wrappers.forEach(function(wrapper) {
|
||||
keys.forEach(function(key) {
|
||||
testWrapping(wrapper, key);
|
||||
promises.push(testWrapping(wrapper, key));
|
||||
})
|
||||
});
|
||||
return Promise.all(promises);
|
||||
}, function(err) {
|
||||
promise_test(function(test) {
|
||||
assert_unreached("A key failed to generate: " + err.name + ": " + err.message)
|
||||
|
@ -22,7 +25,7 @@ function run_test() {
|
|||
})
|
||||
.then(function() {
|
||||
done();
|
||||
}, function(error) {
|
||||
}, function(err) {
|
||||
promise_test(function(test) {
|
||||
assert_unreached("A test failed to run: " + err.name + ": " + err.message)
|
||||
}, "Could not run all tests")
|
||||
|
@ -114,6 +117,12 @@ function run_test() {
|
|||
}));
|
||||
}
|
||||
|
||||
function generateEcdhPeerKey() {
|
||||
return subtle.generateKey({name: "ECDH", namedCurve: "P-256"},true,["deriveBits"])
|
||||
.then(function(result){
|
||||
ecdhPeerKey = result.publicKey;
|
||||
});
|
||||
}
|
||||
|
||||
// Can we successfully "round-trip" (wrap, then unwrap, a key)?
|
||||
function testWrapping(wrapper, toWrap) {
|
||||
|
@ -127,37 +136,98 @@ function run_test() {
|
|||
formats = ["raw", "jwk"]
|
||||
}
|
||||
|
||||
formats.forEach(function(fmt) {
|
||||
return Promise.all(formats.map(function(fmt) {
|
||||
var originalExport;
|
||||
|
||||
promise_test(function(test) {
|
||||
return subtle.exportKey(fmt, toWrap.key)
|
||||
.then(function(exportedKey) {
|
||||
return subtle.exportKey(fmt, toWrap.key).then(function(exportedKey) {
|
||||
originalExport = exportedKey;
|
||||
return exportedKey;
|
||||
}).then(function(exportedKey) {
|
||||
return subtle.wrapKey(fmt, toWrap.key, wrapper.wrappingKey, wrapper.parameters.wrapParameters);
|
||||
}).then(function(wrappedResult) {
|
||||
return subtle.unwrapKey(fmt, wrappedResult, wrapper.unwrappingKey, wrapper.parameters.wrapParameters, toWrap.algorithm, true, toWrap.usages)
|
||||
if (wrappingIsPossible(originalExport, wrapper.parameters.name)) {
|
||||
promise_test(function(test) {
|
||||
return subtle.wrapKey(fmt, toWrap.key, wrapper.wrappingKey, wrapper.parameters.wrapParameters)
|
||||
.then(function(wrappedResult) {
|
||||
return subtle.unwrapKey(fmt, wrappedResult, wrapper.unwrappingKey, wrapper.parameters.wrapParameters, toWrap.algorithm, true, toWrap.usages);
|
||||
}).then(function(unwrappedResult) {
|
||||
assert_true(unwrappedResult.extractable, "Unwrapped result is extractable");
|
||||
return subtle.exportKey(fmt, unwrappedResult)
|
||||
}).then(function(roundTripExport) {
|
||||
if ("byteLength" in originalExport) {
|
||||
assert_true(equalBuffers(originalExport, roundTripExport), "Post-wrap export matches original export");
|
||||
} else {
|
||||
assert_true(equalJwk(originalExport, roundTripExport), "Post-wrap export matches original export.");
|
||||
}
|
||||
assert_true(equalExport(originalExport, roundTripExport), "Post-wrap export matches original export");
|
||||
}, function(err) {
|
||||
if (wrappingIsPossible(originalExport, wrapper.parameters.name)) {
|
||||
assert_unreached("Round trip threw an error - " + err.name + ': "' + err.message + '"');
|
||||
} else {
|
||||
assert_true(true, "Skipped test due to key length restrictions");
|
||||
}
|
||||
})
|
||||
assert_unreached("Round trip for extractable key threw an error - " + err.name + ': "' + err.message + '"');
|
||||
});
|
||||
}, "Can wrap and unwrap " + toWrap.name + " keys using " + fmt + " and " + wrapper.parameters.name);
|
||||
|
||||
if (canCompareNonExtractableKeys(toWrap.key)) {
|
||||
promise_test(function(test){
|
||||
return subtle.wrapKey(fmt, toWrap.key, wrapper.wrappingKey, wrapper.parameters.wrapParameters)
|
||||
.then(function(wrappedResult) {
|
||||
return subtle.unwrapKey(fmt, wrappedResult, wrapper.unwrappingKey, wrapper.parameters.wrapParameters, toWrap.algorithm, false, toWrap.usages);
|
||||
}).then(function(unwrappedResult){
|
||||
assert_false(unwrappedResult.extractable, "Unwrapped result is non-extractable");
|
||||
return equalKeys(toWrap.key, unwrappedResult);
|
||||
}).then(function(result){
|
||||
assert_true(result, "Unwrapped key matches original");
|
||||
}).catch(function(err){
|
||||
assert_unreached("Round trip for key unwrapped non-extractable threw an error - " + err.name + ': "' + err.message + '"');
|
||||
});
|
||||
}, "Can wrap and unwrap " + toWrap.name + " keys as non-extractable using " + fmt + " and " + wrapper.parameters.name);
|
||||
|
||||
if (fmt === "jwk") {
|
||||
promise_test(function(test){
|
||||
var wrappedKey;
|
||||
return wrapAsNonExtractableJwk(toWrap.key,wrapper).then(function(wrappedResult){
|
||||
wrappedKey = wrappedResult;
|
||||
return subtle.unwrapKey("jwk", wrappedKey, wrapper.unwrappingKey, wrapper.parameters.wrapParameters, toWrap.algorithm, false, toWrap.usages);
|
||||
}).then(function(unwrappedResult){
|
||||
assert_false(unwrappedResult.extractable, "Unwrapped key is non-extractable");
|
||||
return equalKeys(toWrap.key,unwrappedResult);
|
||||
}).then(function(result){
|
||||
assert_true(result, "Unwrapped key matches original");
|
||||
}).catch(function(err){
|
||||
assert_unreached("Round trip for non-extractable key threw an error - " + err.name + ': "' + err.message + '"');
|
||||
}).then(function(){
|
||||
return subtle.unwrapKey("jwk", wrappedKey, wrapper.unwrappingKey, wrapper.parameters.wrapParameters, toWrap.algorithm, true, toWrap.usages);
|
||||
}).then(function(unwrappedResult){
|
||||
assert_unreached("Unwrapping a non-extractable JWK as extractable should fail");
|
||||
}).catch(function(err){
|
||||
assert_equals(err.name, "DataError", "Unwrapping a non-extractable JWK as extractable fails with DataError");
|
||||
});
|
||||
}, "Can unwrap " + toWrap.name + " non-extractable keys using jwk and " + wrapper.parameters.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// Implement key wrapping by hand to wrap a key as non-extractable JWK
|
||||
function wrapAsNonExtractableJwk(key, wrapper){
|
||||
var wrappingKey = wrapper.wrappingKey,
|
||||
encryptKey;
|
||||
|
||||
return subtle.exportKey("jwk",wrappingKey)
|
||||
.then(function(jwkWrappingKey){
|
||||
// Update the key generation parameters to work as key import parameters
|
||||
var params = Object.create(wrapper.parameters.generateParameters);
|
||||
if(params.name === "AES-KW") {
|
||||
params.name = "AES-CBC";
|
||||
jwkWrappingKey.alg = "A"+params.length+"CBC";
|
||||
} else if (params.name === "RSA-OAEP") {
|
||||
params.modulusLength = undefined;
|
||||
params.publicExponent = undefined;
|
||||
}
|
||||
jwkWrappingKey.key_ops = ["encrypt"];
|
||||
return subtle.importKey("jwk", jwkWrappingKey, params, true, ["encrypt"]);
|
||||
}).then(function(importedWrappingKey){
|
||||
encryptKey = importedWrappingKey;
|
||||
return subtle.exportKey("jwk",key);
|
||||
}).then(function(exportedKey){
|
||||
exportedKey.ext = false;
|
||||
var jwk = JSON.stringify(exportedKey)
|
||||
if (wrappingKey.algorithm.name === "AES-KW") {
|
||||
return aeskw(encryptKey, str2ab(jwk.slice(0,-1) + " ".repeat(jwk.length%8 ? 8-jwk.length%8 : 0) + "}"));
|
||||
} else {
|
||||
return subtle.encrypt(wrapper.parameters.wrapParameters,encryptKey,str2ab(jwk));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -189,6 +259,15 @@ function run_test() {
|
|||
|
||||
// Helper methods follow:
|
||||
|
||||
// Are two exported keys equal
|
||||
function equalExport(originalExport, roundTripExport) {
|
||||
if ("byteLength" in originalExport) {
|
||||
return equalBuffers(originalExport, roundTripExport);
|
||||
} else {
|
||||
return equalJwk(originalExport, roundTripExport);
|
||||
}
|
||||
}
|
||||
|
||||
// Are two array buffers the same?
|
||||
function equalBuffers(a, b) {
|
||||
if (a.byteLength !== b.byteLength) {
|
||||
|
@ -262,5 +341,176 @@ function run_test() {
|
|||
return "{" + keyValuePairs.join(", ") + "}";
|
||||
}
|
||||
|
||||
// Can we compare key values by using them
|
||||
function canCompareNonExtractableKeys(key){
|
||||
if (key.usages.indexOf("decrypt") !== -1) {
|
||||
return true;
|
||||
}
|
||||
if (key.usages.indexOf("sign") !== -1) {
|
||||
return true;
|
||||
}
|
||||
if (key.usages.indexOf("wrapKey") !== -1) {
|
||||
return true;
|
||||
}
|
||||
if (key.usages.indexOf("deriveBits") !== -1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compare two keys by using them (works for non-extractable keys)
|
||||
function equalKeys(expected, got){
|
||||
if ( expected.algorithm.name !== got.algorithm.name ) {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
var cryptParams, signParams, wrapParams, deriveParams;
|
||||
switch(expected.algorithm.name){
|
||||
case "AES-CTR" :
|
||||
cryptParams = {name: "AES-CTR", counter: new Uint8Array(16), length: 64};
|
||||
break;
|
||||
case "AES-CBC" :
|
||||
cryptParams = {name: "AES-CBC", iv: new Uint8Array(16) };
|
||||
break;
|
||||
case "AES-GCM" :
|
||||
cryptParams = {name: "AES-GCM", iv: new Uint8Array(16) };
|
||||
break;
|
||||
case "RSA-OAEP" :
|
||||
cryptParams = {name: "RSA-OAEP", label: new Uint8Array(8) };
|
||||
break;
|
||||
case "RSASSA-PKCS1-v1_5" :
|
||||
signParams = {name: "RSASSA-PKCS1-v1_5"};
|
||||
break;
|
||||
case "RSA-PSS" :
|
||||
signParams = {name: "RSA-PSS", saltLength: 32 };
|
||||
break;
|
||||
case "ECDSA" :
|
||||
signParams = {name: "ECDSA", hash: "SHA-256"};
|
||||
break;
|
||||
case "HMAC" :
|
||||
signParams = {name: "HMAC"};
|
||||
break;
|
||||
case "AES-KW" :
|
||||
wrapParams = {name: "AES-KW"};
|
||||
break;
|
||||
case "ECDH" :
|
||||
deriveParams = {name: "ECDH", public: ecdhPeerKey};
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unsupported algorithm for key comparison");
|
||||
}
|
||||
|
||||
if (cryptParams) {
|
||||
return subtle.exportKey("jwk",expected)
|
||||
.then(function(jwkExpectedKey){
|
||||
if (expected.algorithm.name === "RSA-OAEP") {
|
||||
["d","p","q","dp","dq","qi","oth"].forEach(function(field){ delete jwkExpectedKey[field]; });
|
||||
}
|
||||
jwkExpectedKey.key_ops = ["encrypt"];
|
||||
return subtle.importKey("jwk", jwkExpectedKey, expected.algorithm, true, ["encrypt"]);
|
||||
}).then(function(expectedEncryptKey){
|
||||
return subtle.encrypt(cryptParams, expectedEncryptKey, new Uint8Array(32));
|
||||
}).then(function(encryptedData){
|
||||
return subtle.decrypt(cryptParams, got, encryptedData);
|
||||
}).then(function(decryptedData){
|
||||
var result = new Uint8Array(decryptedData);
|
||||
return !result.some(x => x);
|
||||
});
|
||||
} else if (signParams) {
|
||||
var verifyKey;
|
||||
return subtle.exportKey("jwk",expected)
|
||||
.then(function(jwkExpectedKey){
|
||||
if (expected.algorithm.name === "RSA-PSS" || expected.algorithm.name === "RSASSA-PKCS1-v1_5") {
|
||||
["d","p","q","dp","dq","qi","oth"].forEach(function(field){ delete jwkExpectedKey[field]; });
|
||||
}
|
||||
if (expected.algorithm.name === "ECDSA") {
|
||||
delete jwkExpectedKey["d"];
|
||||
}
|
||||
jwkExpectedKey.key_ops = ["verify"];
|
||||
return subtle.importKey("jwk", jwkExpectedKey, expected.algorithm, true, ["verify"]);
|
||||
}).then(function(expectedVerifyKey){
|
||||
verifyKey = expectedVerifyKey;
|
||||
return subtle.sign(signParams, got, new Uint8Array(32));
|
||||
}).then(function(signature){
|
||||
return subtle.verify(signParams, verifyKey, signature, new Uint8Array(32));
|
||||
});
|
||||
} else if (wrapParams) {
|
||||
var aKeyToWrap, wrappedWithExpected;
|
||||
return subtle.importKey("raw", new Uint8Array(16), "AES-CBC", true, ["encrypt"])
|
||||
.then(function(key){
|
||||
aKeyToWrap = key;
|
||||
return subtle.wrapKey("raw", aKeyToWrap, expected, wrapParams);
|
||||
}).then(function(wrapResult){
|
||||
wrappedWithExpected = Array.from((new Uint8Array(wrapResult)).values());
|
||||
return subtle.wrapKey("raw", aKeyToWrap, got, wrapParams);
|
||||
}).then(function(wrapResult){
|
||||
var wrappedWithGot = Array.from((new Uint8Array(wrapResult)).values());
|
||||
return wrappedWithGot.every((x,i) => x === wrappedWithExpected[i]);
|
||||
});
|
||||
} else {
|
||||
var expectedDerivedBits;
|
||||
return subtle.deriveBits(deriveParams, expected, 128)
|
||||
.then(function(result){
|
||||
expectedDerivedBits = Array.from((new Uint8Array(result)).values());
|
||||
return subtle.deriveBits(deriveParams, got, 128);
|
||||
}).then(function(result){
|
||||
var gotDerivedBits = Array.from((new Uint8Array(result)).values());
|
||||
return gotDerivedBits.every((x,i) => x === expectedDerivedBits[i]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Raw AES encryption
|
||||
function aes( k, p ) {
|
||||
return subtle.encrypt({name: "AES-CBC", iv: new Uint8Array(16) }, k, p).then(function(ciphertext){return ciphertext.slice(0,16);});
|
||||
}
|
||||
|
||||
// AES Key Wrap
|
||||
function aeskw(key, data) {
|
||||
if (data.byteLength % 8 !== 0) {
|
||||
throw new Error("AES Key Wrap data must be a multiple of 8 bytes in length");
|
||||
}
|
||||
|
||||
var A = Uint8Array.from([0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0, 0, 0, 0, 0, 0, 0, 0]),
|
||||
Av = new DataView(A.buffer),
|
||||
R = [],
|
||||
n = data.byteLength / 8;
|
||||
|
||||
for(var i = 0; i<data.byteLength; i+=8) {
|
||||
R.push(new Uint8Array(data.slice(i,i+8)));
|
||||
}
|
||||
|
||||
function aeskw_step(j, i, final, B) {
|
||||
A.set(new Uint8Array(B.slice(0,8)));
|
||||
Av.setUint32(4,Av.getUint32(4) ^ (n*j+i+1));
|
||||
R[i] = new Uint8Array(B.slice(8,16));
|
||||
if (final) {
|
||||
R.unshift(A.slice(0,8));
|
||||
var result = new Uint8Array(R.length * 8);
|
||||
R.forEach(function(Ri,i){ result.set(Ri, i*8); });
|
||||
return result;
|
||||
} else {
|
||||
A.set(R[(i+1)%n],8);
|
||||
return aes(key,A);
|
||||
}
|
||||
}
|
||||
|
||||
var p = new Promise(function(resolve){
|
||||
A.set(R[0],8);
|
||||
resolve(aes(key,A));
|
||||
});
|
||||
|
||||
for(var j=0;j<6;++j) {
|
||||
for(var i=0;i<n;++i) {
|
||||
p = p.then(aeskw_step.bind(undefined, j, i,j===5 && i===(n-1)));
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
function str2ab(str) { return Uint8Array.from( str.split(''), function(s){return s.charCodeAt(0)} ); }
|
||||
function ab2str(ab) { return String.fromCharCode.apply(null, new Uint8Array(ab)); }
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
@kangxu
|
||||
@caitp
|
||||
@Manishearth
|
||||
@plehegar
|
||||
@jungkees
|
||||
@ibelem
|
||||
@mathiasbynens
|
||||
|
|
5
tests/wpt/web-platform-tests/accelerometer/OWNERS
Normal file
5
tests/wpt/web-platform-tests/accelerometer/OWNERS
Normal file
|
@ -0,0 +1,5 @@
|
|||
@zqzhang
|
||||
@dontcallmedom
|
||||
@tobie
|
||||
@riju
|
||||
@Honry
|
113
tests/wpt/web-platform-tests/accelerometer/idlharness.https.html
Normal file
113
tests/wpt/web-platform-tests/accelerometer/idlharness.https.html
Normal file
|
@ -0,0 +1,113 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Accelerometer Sensor IDL tests</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com">
|
||||
<link rel="help" href="https://www.w3.org/TR/accelerometer/">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/WebIDLParser.js"></script>
|
||||
<script src="/resources/idlharness.js"></script>
|
||||
<style>
|
||||
pre {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<div id="log"></div>
|
||||
|
||||
<pre id="idl">
|
||||
interface Event {
|
||||
};
|
||||
|
||||
interface EventTarget {
|
||||
};
|
||||
|
||||
interface EventHandler {
|
||||
};
|
||||
|
||||
interface Error {
|
||||
};
|
||||
|
||||
dictionary EventInit {
|
||||
};
|
||||
</pre>
|
||||
|
||||
<pre id="generic-idl">
|
||||
[SecureContext]
|
||||
interface Sensor : EventTarget {
|
||||
readonly attribute SensorState state;
|
||||
readonly attribute SensorReading? reading;
|
||||
void start();
|
||||
void stop();
|
||||
attribute EventHandler onchange;
|
||||
attribute EventHandler onactivate;
|
||||
attribute EventHandler onerror;
|
||||
};
|
||||
|
||||
dictionary SensorOptions {
|
||||
double? frequency;
|
||||
};
|
||||
|
||||
enum SensorState {
|
||||
"idle",
|
||||
"activating",
|
||||
"activated",
|
||||
"errored"
|
||||
};
|
||||
|
||||
[SecureContext]
|
||||
interface SensorReading {
|
||||
readonly attribute DOMHighResTimeStamp timeStamp;
|
||||
};
|
||||
|
||||
[SecureContext, Constructor(DOMString type, SensorErrorEventInit errorEventInitDict)]
|
||||
interface SensorErrorEvent : Event {
|
||||
readonly attribute Error error;
|
||||
};
|
||||
|
||||
dictionary SensorErrorEventInit : EventInit {
|
||||
required Error error;
|
||||
};
|
||||
|
||||
</pre>
|
||||
|
||||
<pre id="accelerometer-idl">
|
||||
[Constructor(optional AccelerometerOptions accelerometerOptions)]
|
||||
interface Accelerometer : Sensor {
|
||||
readonly attribute AccelerometerReading? reading;
|
||||
readonly attribute boolean includesGravity;
|
||||
};
|
||||
|
||||
dictionary AccelerometerOptions : SensorOptions {
|
||||
boolean includeGravity = true;
|
||||
};
|
||||
|
||||
[Constructor(AccelerometerReadingInit AccelerometerReadingInit)]
|
||||
interface AccelerometerReading : SensorReading {
|
||||
readonly attribute double x;
|
||||
readonly attribute double y;
|
||||
readonly attribute double z;
|
||||
};
|
||||
|
||||
dictionary AccelerometerReadingInit {
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
double z = 0;
|
||||
};
|
||||
</pre>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
"use strict";
|
||||
var idl_array = new IdlArray();
|
||||
idl_array.add_untested_idls(document.getElementById('idl').textContent);
|
||||
idl_array.add_untested_idls(document.getElementById('generic-idl').textContent);
|
||||
idl_array.add_idls(document.getElementById('accelerometer-idl').textContent);
|
||||
|
||||
idl_array.add_objects({
|
||||
Accelerometer: ['new Accelerometer();'],
|
||||
AccelerometerReading: ['new AccelerometerReading({x: 0.5, y: 0.5, z: 0.5});']
|
||||
});
|
||||
|
||||
idl_array.test();
|
||||
})();
|
||||
</script>
|
|
@ -6,26 +6,28 @@
|
|||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<iframe src="support-iframe.html" id="frame" style="display:none">
|
||||
<iframe src="support-iframe.html" id="frame" style="display:none" sandbox="allow-scripts">
|
||||
</iframe>
|
||||
<script>
|
||||
|
||||
async_test(function (t) {
|
||||
document.getElementById('frame').onload = t.step_func_done(function(event) {
|
||||
var iframe = document.getElementById('frame').contentWindow;
|
||||
let reading = iframe.document.getElementById('reading').value;
|
||||
assert_equals(reading, "null");
|
||||
async_test(t => {
|
||||
window.onmessage = t.step_func(e => {
|
||||
assert_equals(e.data, "SecurityError");
|
||||
t.done();
|
||||
});
|
||||
}, "sensor readings can not be fired within iframes");
|
||||
}, "throw a 'SecurityError' when firing sensor readings within iframes");
|
||||
|
||||
test(function() {
|
||||
async_test(t => {
|
||||
let sensor = new AmbientLightSensor();
|
||||
sensor.start();
|
||||
var win = window.open('', '_blank');
|
||||
let reading = String(sensor.reading);
|
||||
sensor.onactivate = t.step_func_done(() => {
|
||||
assert_not_equals(sensor.reading, null);
|
||||
let cachedReading = sensor.reading;
|
||||
let win = window.open('', '_blank');
|
||||
assert_equals(sensor.reading, cachedReading);
|
||||
win.close();
|
||||
sensor.stop();
|
||||
assert_equals(reading, "null");
|
||||
});
|
||||
}, "sensor readings can not be fired on the background tab");
|
||||
|
||||
</script>
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>AmbientLightSensor Test: insecure context</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com">
|
||||
<link rel="help" href="https://www.w3.org/TR/ambient-light/">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<h2>Precondition</h2>
|
||||
<ol>
|
||||
<li>
|
||||
Run test in an insecure context, e.g. http://example.com/.
|
||||
</li>
|
||||
</ol>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
|
||||
test(() => {
|
||||
assert_throws('SecurityError', () => {
|
||||
let sensor = new AmbientLightSensor();
|
||||
});
|
||||
}, "throw a 'SecurityError' when construct AmbientLightSensor in an insecure context");
|
||||
|
||||
</script>
|
|
@ -5,30 +5,20 @@
|
|||
<link rel="help" href="https://www.w3.org/TR/ambient-light/">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<h2>Description</h2>
|
||||
<p>
|
||||
This test validates that the "onchange" event can be invoked when changing the ambient light illuminance of the device.
|
||||
</p>
|
||||
|
||||
<h2>Precondition</h2>
|
||||
<ol>
|
||||
<li>
|
||||
Change the ambient light illuminance of the device.
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
|
||||
async_test(function(t) {
|
||||
async_test(t => {
|
||||
let sensor = new AmbientLightSensor();
|
||||
sensor.start();
|
||||
|
||||
sensor.onchange = t.step_func_done(function(event) {
|
||||
sensor.onchange = t.step_func_done(() => {
|
||||
assert_greater_than_equal(sensor.reading.illuminance, 0);
|
||||
assert_equals(sensor.state, "activated");
|
||||
sensor.stop();
|
||||
});
|
||||
|
||||
sensor.onerror = t.step_func_done(function(event) {
|
||||
sensor.onerror = t.step_func_done(event => {
|
||||
assert_unreached(event.error.name + ":" + event.error.message);
|
||||
});
|
||||
}, "event change fired");
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>AmbientLightSensor Test: onerror</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com">
|
||||
<link rel="help" href="https://www.w3.org/TR/ambient-light/">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<h2>Precondition</h2>
|
||||
<ol>
|
||||
<li>
|
||||
Disable the Ambient Light Sensor or run test on a device without Amibent Light Sensor.
|
||||
</li>
|
||||
</ol>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
let sensor;
|
||||
setup(() => {
|
||||
sensor = new AmbientLightSensor();
|
||||
});
|
||||
|
||||
async_test(t => {
|
||||
sensor.onactivate = t.step_func_done(assert_unreached);
|
||||
|
||||
sensor.onerror = t.step_func_done(event => {
|
||||
assert_equals(sensor.state, 'errored');
|
||||
assert_equals(event.error.name, 'NotFoundError');
|
||||
});
|
||||
|
||||
sensor.start();
|
||||
}, "Test that 'onerror' event is fired when sensor is not supported");
|
||||
|
||||
</script>
|
|
@ -1,39 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>AmbientLightSensor Test: onstatechange</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com">
|
||||
<link rel="help" href="https://www.w3.org/TR/ambient-light/">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
var sensor;
|
||||
setup(function() {
|
||||
sensor = new AmbientLightSensor();
|
||||
});
|
||||
|
||||
test(function() {
|
||||
assert_equals(sensor.state, "idle");
|
||||
}, "The default sensor.state is 'idle'.");
|
||||
|
||||
async_test(function(t) {
|
||||
sensor.onstatechange = t.step_func_done(function(event) {
|
||||
assert_equals(sensor.state, "activating");
|
||||
});
|
||||
sensor.onerror = t.step_func_done(function(event) {
|
||||
assert_unreached(event.error.name + ":" + event.error.message);
|
||||
});
|
||||
sensor.start();
|
||||
}, "The sensor.state changes to 'activating' after sensor.start().");
|
||||
|
||||
async_test(function(t) {
|
||||
sensor.onstatechange = t.step_func_done(function(event) {
|
||||
assert_equals(sensor.state, "idle");
|
||||
});
|
||||
sensor.onerror = t.step_func_done(function(event) {
|
||||
assert_unreached(event.error.name + ":" + event.error.message);
|
||||
});
|
||||
sensor.stop();
|
||||
}, "The sensor.state changes to 'idle' after sensor.stop().");
|
||||
|
||||
</script>
|
|
@ -0,0 +1,64 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>AmbientLightSensor Test: reading</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com">
|
||||
<link rel="help" href="https://www.w3.org/TR/ambient-light/">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
|
||||
let sensor, sensor1, sensor2, cachedReading1, cachedReading2;
|
||||
|
||||
setup(() => {
|
||||
sensor = new AmbientLightSensor();
|
||||
sensor1 = new AmbientLightSensor();
|
||||
sensor2 = new AmbientLightSensor();
|
||||
sensor1.start();
|
||||
sensor2.start();
|
||||
});
|
||||
|
||||
async_test(t => {
|
||||
let sensor = new AmbientLightSensor();
|
||||
sensor.start();
|
||||
sensor.onactivate = t.step_func_done(() => {
|
||||
let cachedReading = sensor.reading;
|
||||
let cachedIlluminance = cachedReading.illuminance;
|
||||
sensor.stop();
|
||||
assert_equals(cachedReading.illuminance, cachedIlluminance);
|
||||
});
|
||||
sensor.onerror = t.step_func_done(event => {
|
||||
assert_unreached(event.error.name + ":" + event.error.message);
|
||||
});
|
||||
}, "Test that sensor reading must be immutable.");
|
||||
|
||||
async_test(t => {
|
||||
sensor1.onactivate = t.step_func_done(() => {
|
||||
cachedReading1 = sensor1.reading;
|
||||
cachedReading2 = sensor2.reading;
|
||||
//both sensors share the same reading instance
|
||||
assert_equals(cachedReading1, cachedReading2);
|
||||
//after first sensor stops its reading is null, second sensor remains
|
||||
sensor1.stop();
|
||||
assert_equals(sensor1.reading, null);
|
||||
assert_equals(String(sensor2.reading), "[object AmbientLightSensorReading]");
|
||||
});
|
||||
sensor1.onerror = t.step_func_done(event => {
|
||||
assert_unreached(event.error.name + ":" + event.error.message);
|
||||
});
|
||||
}, "Test that sensor reading is correct.");
|
||||
|
||||
async_test(t => {
|
||||
t.step_timeout(() => {
|
||||
sensor2.onchange = t.step_func_done(() => {
|
||||
let cachedReading3 = sensor2.reading;
|
||||
assert_not_equals(cachedReading2, cachedReading3);
|
||||
sensor2.stop();
|
||||
});
|
||||
sensor2.onerror = t.step_func_done(event => {
|
||||
assert_unreached(event.error.name + ":" + event.error.message);
|
||||
});
|
||||
}, 1000);
|
||||
}, "Test that the sensor reading is updated when time passes.");
|
||||
|
||||
</script>
|
|
@ -7,25 +7,37 @@
|
|||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
var sensor, start_return;
|
||||
|
||||
setup(function() {
|
||||
let sensor, start_return;
|
||||
|
||||
setup(() => {
|
||||
sensor = new AmbientLightSensor();
|
||||
start_return = sensor.start();
|
||||
});
|
||||
|
||||
test(function() {
|
||||
assert_equals(String(sensor.reading), "[object AmbientLightSensorReading]");
|
||||
}, "the sensor.reading is AmbientLightSensorReading after executing start() method");
|
||||
test(() => {
|
||||
assert_equals(sensor.reading, null);
|
||||
}, "The default sensor.reading is 'null'");
|
||||
|
||||
test(function() {
|
||||
assert_throws("InvalidStateError", function() { sensor.start(); }, "start() twice");
|
||||
}, "throw an InvalidStateError exception when state is neither idle nor errored");
|
||||
test(() => {
|
||||
assert_equals(sensor.state, "idle");
|
||||
}, "The default sensor.state is 'idle'");
|
||||
|
||||
test(() => {
|
||||
start_return = sensor.start();
|
||||
assert_equals(sensor.state, "activating");
|
||||
}, "The sensor.state changes to 'activating' after sensor.start()");
|
||||
|
||||
//TODO: The permission is not ready.
|
||||
|
||||
test(function() {
|
||||
test(() => {
|
||||
assert_equals(start_return, undefined);
|
||||
}, "the sensor.start() return undefined");
|
||||
|
||||
test(() => {
|
||||
assert_throws("InvalidStateError", () => { sensor.start(); }, "start() twice");
|
||||
sensor.stop();
|
||||
}, "throw an InvalidStateError exception when state is neither idle nor errored");
|
||||
|
||||
|
||||
|
||||
</script>
|
|
@ -8,22 +8,27 @@
|
|||
<div id="log"></div>
|
||||
<script>
|
||||
|
||||
var sensor, stop_return;
|
||||
setup(function() {
|
||||
let sensor, stop_return;
|
||||
|
||||
setup(() => {
|
||||
sensor = new AmbientLightSensor();
|
||||
sensor.start();
|
||||
stop_return = sensor.stop();
|
||||
});
|
||||
|
||||
test(function() {
|
||||
assert_equals(String(sensor.reading), "null");
|
||||
test(() => {
|
||||
assert_equals(sensor.state, "idle");
|
||||
}, "The sensor.state changes to 'idle' after sensor.stop()");
|
||||
|
||||
test(() => {
|
||||
assert_equals(sensor.reading, null);
|
||||
}, "the sensor.reading is null after executing stop() method");
|
||||
|
||||
test(function() {
|
||||
assert_throws("InvalidStateError", function() { sensor.stop(); }, "stop() twice");
|
||||
test(() => {
|
||||
assert_throws("InvalidStateError", () => { sensor.stop(); }, "stop() twice");
|
||||
}, "throw an InvalidStateError exception when state is either idle or errored");
|
||||
|
||||
test(function() {
|
||||
test(() => {
|
||||
assert_equals(stop_return, undefined);
|
||||
}, "the sensor.stop() returns undefined");
|
||||
|
|
@ -18,6 +18,12 @@
|
|||
interface Event {
|
||||
};
|
||||
|
||||
interface EventTarget {
|
||||
};
|
||||
|
||||
interface EventHandler {
|
||||
};
|
||||
|
||||
interface Error {
|
||||
};
|
||||
|
||||
|
@ -26,13 +32,14 @@ dictionary EventInit {
|
|||
</pre>
|
||||
|
||||
<pre id="generic-idl">
|
||||
[SecureContext]
|
||||
interface Sensor : EventTarget {
|
||||
readonly attribute SensorState state;
|
||||
readonly attribute SensorReading? reading;
|
||||
void start();
|
||||
void stop();
|
||||
attribute EventHandler onchange;
|
||||
attribute EventHandler onstatechange;
|
||||
attribute EventHandler onactivate;
|
||||
attribute EventHandler onerror;
|
||||
};
|
||||
|
||||
|
@ -43,37 +50,29 @@ dictionary SensorOptions {
|
|||
enum SensorState {
|
||||
"idle",
|
||||
"activating",
|
||||
"active",
|
||||
"activated",
|
||||
"errored"
|
||||
};
|
||||
|
||||
[SecureContext]
|
||||
interface SensorReading {
|
||||
readonly attribute DOMHighResTimeStamp timeStamp;
|
||||
};
|
||||
|
||||
[Constructor(DOMString type, SensorReadingEventInit eventInitDict)]
|
||||
interface SensorReadingEvent : Event {
|
||||
readonly attribute SensorReading reading;
|
||||
};
|
||||
|
||||
dictionary SensorReadingEventInit : EventInit {
|
||||
SensorReading reading;
|
||||
};
|
||||
|
||||
[Constructor(DOMString type, SensorErrorEventInit errorEventInitDict)]
|
||||
[SecureContext, Constructor(DOMString type, SensorErrorEventInit errorEventInitDict)]
|
||||
interface SensorErrorEvent : Event {
|
||||
readonly attribute Error error;
|
||||
};
|
||||
|
||||
dictionary SensorErrorEventInit : EventInit {
|
||||
Error error;
|
||||
required Error error;
|
||||
};
|
||||
|
||||
</pre>
|
||||
|
||||
<pre id="ambient-light-idl">
|
||||
[Constructor(optional SensorOptions sensorOptions)]
|
||||
interface AmbientLightSensor : Sensor {
|
||||
readonly attribute AmbientLightSensorReading? reading;
|
||||
};
|
||||
|
||||
[Constructor(AmbientLightSensorReadingInit ambientLightSensorReadingInit)]
|
||||
|
@ -82,13 +81,12 @@ interface AmbientLightSensorReading : SensorReading {
|
|||
};
|
||||
|
||||
dictionary AmbientLightSensorReadingInit {
|
||||
unrestricted double illuminance;
|
||||
required unrestricted double illuminance;
|
||||
};
|
||||
|
||||
</pre>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
(() => {
|
||||
"use strict";
|
||||
var idl_array = new IdlArray();
|
||||
idl_array.add_untested_idls(document.getElementById('idl').textContent);
|
||||
|
@ -97,8 +95,7 @@ dictionary AmbientLightSensorReadingInit {
|
|||
|
||||
idl_array.add_objects({
|
||||
AmbientLightSensor: ['new AmbientLightSensor();'],
|
||||
AmbientLightSensorReading: ['new AmbientLightSensorReading({ illuminance: 750 });'],
|
||||
SensorReadingEvent: ['new SensorReadingEvent("reading", { reading: new AmbientLightSensorReading({ illuminance: 750 }) });']
|
||||
AmbientLightSensorReading: ['new AmbientLightSensorReading({ illuminance: 750 });']
|
||||
});
|
||||
|
||||
idl_array.test();
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue