WebKit Bugzilla
Attachment 342209 Details for
Bug 186411
: Sync web-platform-test directories: "payment-request" through "workers"
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-186411-20180607175916.patch (text/plain), 3.75 MB, created by
Brendan McLoughlin
on 2018-06-07 14:59:18 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Brendan McLoughlin
Created:
2018-06-07 14:59:18 PDT
Size:
3.75 MB
patch
obsolete
>Subversion Revision: 232579 >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 832cf6b825d504222f40d9ab9d7384aada1a6b00..cb2149857117d2fc2825889e7f5352f623ceb791 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,15 @@ >+2018-06-07 Brendan McLoughlin <brendan@bocoup.com> >+ >+ Sync web-platform-test directories: "payment-request" through "workers" >+ https://bugs.webkit.org/show_bug.cgi?id=186411 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * TestExpectations: >+ * platform/mac/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-history-backward-navigation-manual.https-expected.txt: Added. >+ * platform/mac/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-history-forward-navigation-manual.https-expected.txt: Added. >+ * platform/mac/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-reload-navigation-manual.https-expected.txt: Added. >+ > 2018-06-06 Youenn Fablet <youenn@apple.com> > > HTTP Header values validation is too strict >diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog >index 5a93191889e5049d1c39fde137cd84bbda1bd4cb..a61c54d6b8b6c618e5d1ad06332594f61a41a34e 100644 >--- a/LayoutTests/imported/w3c/ChangeLog >+++ b/LayoutTests/imported/w3c/ChangeLog >@@ -1,3 +1,2294 @@ >+2018-06-07 Brendan McLoughlin <brendan@bocoup.com> >+ >+ Sync web-platform-test directories: "payment-request" through "workers" >+ Synced directores: >+ - payment-request >+ - permissions >+ - picture-in-picture >+ - priority-hints >+ - quirks >+ - resource-timing >+ - resources >+ - secure-contexts >+ - server-timing >+ - service-workers >+ - shadow-dom >+ - streams >+ - url >+ - user-timing >+ - visual-viewport >+ - wake-lock >+ - webaudio >+ - webrtc >+ - webxr >+ - workers >+ >+ https://bugs.webkit.org/show_bug.cgi?id=186411 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * web-platform-tests/payment-request/PaymentAddress/attributes-and-toJSON-method-manual.https.html: >+ * web-platform-tests/payment-request/PaymentItem/type_member.https-expected.txt: Added. >+ * web-platform-tests/payment-request/PaymentItem/type_member.https.html: Added. >+ * web-platform-tests/payment-request/PaymentItem/w3c-import.log: Added. >+ * web-platform-tests/payment-request/algorithms-manual.https.html: >+ * web-platform-tests/payment-request/change-shipping-option-manual.https.html: >+ * web-platform-tests/payment-request/change-shipping-option-select-last-manual.https-expected.txt: Added. >+ * web-platform-tests/payment-request/change-shipping-option-select-last-manual.https.html: Added. >+ * web-platform-tests/payment-request/interfaces.https-expected.txt: >+ * web-platform-tests/payment-request/payment-request-abort-method-manual.https-expected.txt: Removed. >+ * web-platform-tests/payment-request/payment-request-abort-method-manual.https.html: Removed. >+ * web-platform-tests/payment-request/payment-request-abort-method.https-expected.txt: Added. >+ * web-platform-tests/payment-request/payment-request-abort-method.https.html: Added. >+ * web-platform-tests/payment-request/payment-request-canmakepayment-method-manual.https.html: >+ * web-platform-tests/payment-request/payment-request-insecure.http-expected.txt: Added. >+ * web-platform-tests/payment-request/payment-request-insecure.http.html: Added. >+ * web-platform-tests/payment-request/payment-request-not-exposed.https.worker-expected.txt: Added. >+ * web-platform-tests/payment-request/payment-request-not-exposed.https.worker.html: Added. >+ * web-platform-tests/payment-request/payment-request-not-exposed.https.worker.js: Added. >+ (test): >+ * web-platform-tests/payment-request/payment-request-show-method-manual.https-expected.txt: Added. >+ * web-platform-tests/payment-request/payment-request-show-method-manual.https.html: Added. >+ * web-platform-tests/payment-request/payment-request-show-method.https.html: >+ * web-platform-tests/payment-request/payment-response/complete-method-manual.https.html: >+ * web-platform-tests/payment-request/payment-response/methodName-attribute-manual.https.html: >+ * web-platform-tests/payment-request/payment-response/payerEmail-attribute-manual.https.html: >+ * web-platform-tests/payment-request/payment-response/payerName-attribute-manual.https.html: >+ * web-platform-tests/payment-request/payment-response/payerPhone-attribute-manual.https.html: >+ * web-platform-tests/payment-request/payment-response/requestId-attribute-manual.https.html: >+ * web-platform-tests/payment-request/payment-response/shippingAddress-attribute-manual.https.html: >+ * web-platform-tests/payment-request/payment-response/shippingOption-attribute-manual.https.html: >+ * web-platform-tests/payment-request/shipping-address-changed-manual.https.html: >+ * web-platform-tests/payment-request/show-method-optional-promise-rejects-manual.https-expected.txt: Added. >+ * web-platform-tests/payment-request/show-method-optional-promise-rejects-manual.https.html: Added. >+ * web-platform-tests/payment-request/show-method-optional-promise-resolves-manual.https-expected.txt: Added. >+ * web-platform-tests/payment-request/show-method-optional-promise-resolves-manual.https.html: Added. >+ * web-platform-tests/payment-request/show-method-postmessage-iframe.html: Added. >+ * web-platform-tests/payment-request/show-method-postmessage-manual.https-expected.txt: Added. >+ * web-platform-tests/payment-request/show-method-postmessage-manual.https.html: Added. >+ * web-platform-tests/payment-request/updateWith-method-pmi-handling-manual.https.html: >+ * web-platform-tests/payment-request/user-abort-algorithm-manual.https.html: >+ * web-platform-tests/payment-request/user-accepts-payment-request-algo-manual.https.html: >+ * web-platform-tests/payment-request/w3c-import.log: >+ * web-platform-tests/resource-timing/clear_resource_timing_functionality-expected.txt: Added. >+ * web-platform-tests/resource-timing/clear_resource_timing_functionality.html: Added. >+ * web-platform-tests/resource-timing/resource-timing-tojson-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource-timing-tojson.html: Added. >+ * web-platform-tests/resource-timing/resource_TAO_cross_origin_redirect_chain-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_TAO_cross_origin_redirect_chain.html: Added. >+ * web-platform-tests/resource-timing/resource_dedicated_worker-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_dedicated_worker.html: Added. >+ * web-platform-tests/resource-timing/resource_ignore_data_url-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_ignore_data_url.html: Added. >+ * web-platform-tests/resource-timing/resource_ignore_failures-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_ignore_failures.html: Added. >+ * web-platform-tests/resource-timing/resource_initiator_types-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_initiator_types.html: Added. >+ * web-platform-tests/resource-timing/resource_memory_cached.sub-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_memory_cached.sub.html: Added. >+ * web-platform-tests/resource-timing/resource_redirects-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_redirects.html: Added. >+ * web-platform-tests/resource-timing/resource_reparenting-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_reparenting.html: Added. >+ * web-platform-tests/resource-timing/resource_script_types-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_script_types.html: Added. >+ * web-platform-tests/resource-timing/resource_subframe_self_navigation-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_subframe_self_navigation.html: Added. >+ * web-platform-tests/resource-timing/resource_timing.worker-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_timing.worker.html: Added. >+ * web-platform-tests/resource-timing/resource_timing.worker.js: Added. >+ (check): >+ (async_test.t.then): >+ * web-platform-tests/resource-timing/resource_timing_TAO_cross_origin_redirect-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_timing_TAO_cross_origin_redirect.html: Added. >+ * web-platform-tests/resource-timing/resource_timing_buffer_full_eventually-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_timing_buffer_full_eventually.html: Added. >+ * web-platform-tests/resource-timing/resource_timing_buffer_full_when_populate_entries-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_timing_buffer_full_when_populate_entries.html: Added. >+ * web-platform-tests/resource-timing/resource_timing_buffer_full_when_shrink_buffer_size-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_timing_buffer_full_when_shrink_buffer_size.html: Added. >+ * web-platform-tests/resource-timing/resource_timing_cross_origin_redirect-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_timing_cross_origin_redirect.html: Added. >+ * web-platform-tests/resource-timing/resource_timing_cross_origin_redirect_chain-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_timing_cross_origin_redirect_chain.html: Added. >+ * web-platform-tests/resource-timing/resource_timing_same_origin_redirect-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_timing_same_origin_redirect.html: Added. >+ * web-platform-tests/resource-timing/resource_timing_store_and_clear_during_callback-expected.txt: Added. >+ * web-platform-tests/resource-timing/resource_timing_store_and_clear_during_callback.html: Added. >+ * web-platform-tests/resource-timing/resources/TAOResponse.py: >+ (main): >+ * web-platform-tests/resource-timing/resources/all_resource_types.htm: Added. >+ * web-platform-tests/resource-timing/resources/blank_page_green.htm: Added. >+ * web-platform-tests/resource-timing/resources/empty.js: Added. >+ * web-platform-tests/resource-timing/resources/empty.py: Added. >+ (main): >+ * web-platform-tests/resource-timing/resources/empty_script.js: Added. >+ * web-platform-tests/resource-timing/resources/eventsource.py: Added. >+ (main): >+ * web-platform-tests/resource-timing/resources/green_frame.htm: Added. >+ * web-platform-tests/resource-timing/resources/multi_redirect.py: Added. >+ (main): >+ * web-platform-tests/resource-timing/resources/nested.css: Added. >+ (@import "resource_timing_test0.css?id=n1";): >+ (ol): >+ * web-platform-tests/resource-timing/resources/notify_parent.html: Added. >+ * web-platform-tests/resource-timing/resources/self_navigation.html: Added. >+ * web-platform-tests/resource-timing/resources/worker_with_images.js: Added. >+ (checkDone): >+ (makeRequest.xhr.onreadystatechange): >+ (makeRequest): >+ * web-platform-tests/resource-timing/w3c-import.log: >+ * web-platform-tests/resources/check-layout-th.js: >+ (window.checkLayout): >+ * web-platform-tests/resources/chromium/chooser_service.mojom.js: >+ (UsbChooserService_GetPermission_Params.validate): >+ (UsbChooserService_GetPermission_ResponseParams.validate): >+ * web-platform-tests/resources/chromium/device.mojom.js: >+ (UsbEndpointInfo.validate): >+ (UsbAlternateInterfaceInfo.validate): >+ (UsbInterfaceInfo.validate): >+ (UsbConfigurationInfo.validate): >+ (UsbDeviceInfo.validate): >+ (UsbControlTransferParams.validate): >+ (UsbIsochronousPacket.validate): >+ (UsbDevice_Open_ResponseParams.validate): >+ (UsbDevice_ControlTransferIn_Params.validate): >+ (UsbDevice_ControlTransferIn_ResponseParams.validate): >+ (UsbDevice_ControlTransferOut_Params.validate): >+ (UsbDevice_ControlTransferOut_ResponseParams.validate): >+ (UsbDevice_GenericTransferIn_ResponseParams.validate): >+ (UsbDevice_GenericTransferOut_Params.validate): >+ (UsbDevice_GenericTransferOut_ResponseParams.validate): >+ (UsbDevice_IsochronousTransferIn_Params.validate): >+ (UsbDevice_IsochronousTransferIn_ResponseParams.validate): >+ (UsbDevice_IsochronousTransferOut_Params.validate): >+ (UsbDevice_IsochronousTransferOut_ResponseParams.validate): >+ * web-platform-tests/resources/chromium/device_manager.mojom.js: >+ (UsbDeviceFilter.validate): >+ (UsbEnumerationOptions.validate): >+ (UsbDeviceManager_GetDevices_Params.validate): >+ (UsbDeviceManager_GetDevices_ResponseParams.validate): >+ (UsbDeviceManager_GetDevice_Params.validate): >+ (UsbDeviceManager_SetClient_Params.validate): >+ (UsbDeviceManagerClient_OnDeviceAdded_Params.validate): >+ (UsbDeviceManagerClient_OnDeviceRemoved_Params.validate): >+ * web-platform-tests/resources/chromium/fake_bluetooth.mojom.js: Added. >+ (mojo.internal.isMojomLoaded): >+ (CentralState.isKnownEnumValue): >+ (CentralState.validate): >+ (Appearance): >+ (Appearance.prototype.initDefaults_): >+ (Appearance.prototype.initFields_): >+ (Appearance.validate): >+ (Appearance.decode): >+ (Appearance.encode): >+ (Power): >+ (Power.prototype.initDefaults_): >+ (Power.prototype.initFields_): >+ (Power.validate): >+ (Power.decode): >+ (Power.encode): >+ (ServiceDataMap): >+ (ServiceDataMap.prototype.initDefaults_): >+ (ServiceDataMap.prototype.initFields_): >+ (ServiceDataMap.validate): >+ (ServiceDataMap.decode): >+ (ServiceDataMap.encode): >+ (ScanRecord): >+ (ScanRecord.prototype.initDefaults_): >+ (ScanRecord.prototype.initFields_): >+ (ScanRecord.validate): >+ (ScanRecord.decode): >+ (ScanRecord.encode): >+ (ScanResult): >+ (ScanResult.prototype.initDefaults_): >+ (ScanResult.prototype.initFields_): >+ (ScanResult.validate): >+ (ScanResult.decode): >+ (ScanResult.encode): >+ (CharacteristicProperties): >+ (CharacteristicProperties.prototype.initDefaults_): >+ (CharacteristicProperties.prototype.initFields_): >+ (CharacteristicProperties.validate): >+ (CharacteristicProperties.decode): >+ (CharacteristicProperties.encode): >+ (FakeBluetooth_SetLESupported_Params): >+ (FakeBluetooth_SetLESupported_Params.prototype.initDefaults_): >+ (FakeBluetooth_SetLESupported_Params.prototype.initFields_): >+ (FakeBluetooth_SetLESupported_Params.validate): >+ (FakeBluetooth_SetLESupported_Params.decode): >+ (FakeBluetooth_SetLESupported_Params.encode): >+ (FakeBluetooth_SetLESupported_ResponseParams): >+ (FakeBluetooth_SetLESupported_ResponseParams.prototype.initDefaults_): >+ (FakeBluetooth_SetLESupported_ResponseParams.prototype.initFields_): >+ (FakeBluetooth_SetLESupported_ResponseParams.validate): >+ (FakeBluetooth_SetLESupported_ResponseParams.decode): >+ (FakeBluetooth_SetLESupported_ResponseParams.encode): >+ (FakeBluetooth_SimulateCentral_Params): >+ (FakeBluetooth_SimulateCentral_Params.prototype.initDefaults_): >+ (FakeBluetooth_SimulateCentral_Params.prototype.initFields_): >+ (FakeBluetooth_SimulateCentral_Params.validate): >+ (FakeBluetooth_SimulateCentral_Params.decode): >+ (FakeBluetooth_SimulateCentral_Params.encode): >+ (FakeBluetooth_SimulateCentral_ResponseParams): >+ (FakeBluetooth_SimulateCentral_ResponseParams.prototype.initDefaults_): >+ (FakeBluetooth_SimulateCentral_ResponseParams.prototype.initFields_): >+ (FakeBluetooth_SimulateCentral_ResponseParams.validate): >+ (FakeBluetooth_SimulateCentral_ResponseParams.decode): >+ (FakeBluetooth_SimulateCentral_ResponseParams.encode): >+ (FakeBluetooth_AllResponsesConsumed_Params): >+ (FakeBluetooth_AllResponsesConsumed_Params.prototype.initDefaults_): >+ (FakeBluetooth_AllResponsesConsumed_Params.prototype.initFields_): >+ (FakeBluetooth_AllResponsesConsumed_Params.validate): >+ (FakeBluetooth_AllResponsesConsumed_Params.decode): >+ (FakeBluetooth_AllResponsesConsumed_Params.encode): >+ (FakeBluetooth_AllResponsesConsumed_ResponseParams): >+ (FakeBluetooth_AllResponsesConsumed_ResponseParams.prototype.initDefaults_): >+ (FakeBluetooth_AllResponsesConsumed_ResponseParams.prototype.initFields_): >+ (FakeBluetooth_AllResponsesConsumed_ResponseParams.validate): >+ (FakeBluetooth_AllResponsesConsumed_ResponseParams.decode): >+ (FakeBluetooth_AllResponsesConsumed_ResponseParams.encode): >+ (FakeCentral_SimulatePreconnectedPeripheral_Params): >+ (FakeCentral_SimulatePreconnectedPeripheral_Params.prototype.initDefaults_): >+ (FakeCentral_SimulatePreconnectedPeripheral_Params.prototype.initFields_): >+ (FakeCentral_SimulatePreconnectedPeripheral_Params.validate): >+ (FakeCentral_SimulatePreconnectedPeripheral_Params.decode): >+ (FakeCentral_SimulatePreconnectedPeripheral_Params.encode): >+ (FakeCentral_SimulatePreconnectedPeripheral_ResponseParams): >+ (FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.prototype.initFields_): >+ (FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.validate): >+ (FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.decode): >+ (FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.encode): >+ (FakeCentral_SimulateAdvertisementReceived_Params): >+ (FakeCentral_SimulateAdvertisementReceived_Params.prototype.initDefaults_): >+ (FakeCentral_SimulateAdvertisementReceived_Params.prototype.initFields_): >+ (FakeCentral_SimulateAdvertisementReceived_Params.validate): >+ (FakeCentral_SimulateAdvertisementReceived_Params.decode): >+ (FakeCentral_SimulateAdvertisementReceived_Params.encode): >+ (FakeCentral_SimulateAdvertisementReceived_ResponseParams): >+ (FakeCentral_SimulateAdvertisementReceived_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_SimulateAdvertisementReceived_ResponseParams.prototype.initFields_): >+ (FakeCentral_SimulateAdvertisementReceived_ResponseParams.validate): >+ (FakeCentral_SimulateAdvertisementReceived_ResponseParams.decode): >+ (FakeCentral_SimulateAdvertisementReceived_ResponseParams.encode): >+ (FakeCentral_SetNextGATTConnectionResponse_Params): >+ (FakeCentral_SetNextGATTConnectionResponse_Params.prototype.initDefaults_): >+ (FakeCentral_SetNextGATTConnectionResponse_Params.prototype.initFields_): >+ (FakeCentral_SetNextGATTConnectionResponse_Params.validate): >+ (FakeCentral_SetNextGATTConnectionResponse_Params.decode): >+ (FakeCentral_SetNextGATTConnectionResponse_Params.encode): >+ (FakeCentral_SetNextGATTConnectionResponse_ResponseParams): >+ (FakeCentral_SetNextGATTConnectionResponse_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_SetNextGATTConnectionResponse_ResponseParams.prototype.initFields_): >+ (FakeCentral_SetNextGATTConnectionResponse_ResponseParams.validate): >+ (FakeCentral_SetNextGATTConnectionResponse_ResponseParams.decode): >+ (FakeCentral_SetNextGATTConnectionResponse_ResponseParams.encode): >+ (FakeCentral_SetNextGATTDiscoveryResponse_Params): >+ (FakeCentral_SetNextGATTDiscoveryResponse_Params.prototype.initDefaults_): >+ (FakeCentral_SetNextGATTDiscoveryResponse_Params.prototype.initFields_): >+ (FakeCentral_SetNextGATTDiscoveryResponse_Params.validate): >+ (FakeCentral_SetNextGATTDiscoveryResponse_Params.decode): >+ (FakeCentral_SetNextGATTDiscoveryResponse_Params.encode): >+ (FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams): >+ (FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.prototype.initFields_): >+ (FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.validate): >+ (FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.decode): >+ (FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.encode): >+ (FakeCentral_SimulateGATTDisconnection_Params): >+ (FakeCentral_SimulateGATTDisconnection_Params.prototype.initDefaults_): >+ (FakeCentral_SimulateGATTDisconnection_Params.prototype.initFields_): >+ (FakeCentral_SimulateGATTDisconnection_Params.validate): >+ (FakeCentral_SimulateGATTDisconnection_Params.decode): >+ (FakeCentral_SimulateGATTDisconnection_Params.encode): >+ (FakeCentral_SimulateGATTDisconnection_ResponseParams): >+ (FakeCentral_SimulateGATTDisconnection_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_SimulateGATTDisconnection_ResponseParams.prototype.initFields_): >+ (FakeCentral_SimulateGATTDisconnection_ResponseParams.validate): >+ (FakeCentral_SimulateGATTDisconnection_ResponseParams.decode): >+ (FakeCentral_SimulateGATTDisconnection_ResponseParams.encode): >+ (FakeCentral_SimulateGATTServicesChanged_Params): >+ (FakeCentral_SimulateGATTServicesChanged_Params.prototype.initDefaults_): >+ (FakeCentral_SimulateGATTServicesChanged_Params.prototype.initFields_): >+ (FakeCentral_SimulateGATTServicesChanged_Params.validate): >+ (FakeCentral_SimulateGATTServicesChanged_Params.decode): >+ (FakeCentral_SimulateGATTServicesChanged_Params.encode): >+ (FakeCentral_SimulateGATTServicesChanged_ResponseParams): >+ (FakeCentral_SimulateGATTServicesChanged_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_SimulateGATTServicesChanged_ResponseParams.prototype.initFields_): >+ (FakeCentral_SimulateGATTServicesChanged_ResponseParams.validate): >+ (FakeCentral_SimulateGATTServicesChanged_ResponseParams.decode): >+ (FakeCentral_SimulateGATTServicesChanged_ResponseParams.encode): >+ (FakeCentral_AddFakeService_Params): >+ (FakeCentral_AddFakeService_Params.prototype.initDefaults_): >+ (FakeCentral_AddFakeService_Params.prototype.initFields_): >+ (FakeCentral_AddFakeService_Params.validate): >+ (FakeCentral_AddFakeService_Params.decode): >+ (FakeCentral_AddFakeService_Params.encode): >+ (FakeCentral_AddFakeService_ResponseParams): >+ (FakeCentral_AddFakeService_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_AddFakeService_ResponseParams.prototype.initFields_): >+ (FakeCentral_AddFakeService_ResponseParams.validate): >+ (FakeCentral_AddFakeService_ResponseParams.decode): >+ (FakeCentral_AddFakeService_ResponseParams.encode): >+ (FakeCentral_RemoveFakeService_Params): >+ (FakeCentral_RemoveFakeService_Params.prototype.initDefaults_): >+ (FakeCentral_RemoveFakeService_Params.prototype.initFields_): >+ (FakeCentral_RemoveFakeService_Params.validate): >+ (FakeCentral_RemoveFakeService_Params.decode): >+ (FakeCentral_RemoveFakeService_Params.encode): >+ (FakeCentral_RemoveFakeService_ResponseParams): >+ (FakeCentral_RemoveFakeService_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_RemoveFakeService_ResponseParams.prototype.initFields_): >+ (FakeCentral_RemoveFakeService_ResponseParams.validate): >+ (FakeCentral_RemoveFakeService_ResponseParams.decode): >+ (FakeCentral_RemoveFakeService_ResponseParams.encode): >+ (FakeCentral_AddFakeCharacteristic_Params): >+ (FakeCentral_AddFakeCharacteristic_Params.prototype.initDefaults_): >+ (FakeCentral_AddFakeCharacteristic_Params.prototype.initFields_): >+ (FakeCentral_AddFakeCharacteristic_Params.validate): >+ (FakeCentral_AddFakeCharacteristic_Params.decode): >+ (FakeCentral_AddFakeCharacteristic_Params.encode): >+ (FakeCentral_AddFakeCharacteristic_ResponseParams): >+ (FakeCentral_AddFakeCharacteristic_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_AddFakeCharacteristic_ResponseParams.prototype.initFields_): >+ (FakeCentral_AddFakeCharacteristic_ResponseParams.validate): >+ (FakeCentral_AddFakeCharacteristic_ResponseParams.decode): >+ (FakeCentral_AddFakeCharacteristic_ResponseParams.encode): >+ (FakeCentral_RemoveFakeCharacteristic_Params): >+ (FakeCentral_RemoveFakeCharacteristic_Params.prototype.initDefaults_): >+ (FakeCentral_RemoveFakeCharacteristic_Params.prototype.initFields_): >+ (FakeCentral_RemoveFakeCharacteristic_Params.validate): >+ (FakeCentral_RemoveFakeCharacteristic_Params.decode): >+ (FakeCentral_RemoveFakeCharacteristic_Params.encode): >+ (FakeCentral_RemoveFakeCharacteristic_ResponseParams): >+ (FakeCentral_RemoveFakeCharacteristic_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_RemoveFakeCharacteristic_ResponseParams.prototype.initFields_): >+ (FakeCentral_RemoveFakeCharacteristic_ResponseParams.validate): >+ (FakeCentral_RemoveFakeCharacteristic_ResponseParams.decode): >+ (FakeCentral_RemoveFakeCharacteristic_ResponseParams.encode): >+ (FakeCentral_AddFakeDescriptor_Params): >+ (FakeCentral_AddFakeDescriptor_Params.prototype.initDefaults_): >+ (FakeCentral_AddFakeDescriptor_Params.prototype.initFields_): >+ (FakeCentral_AddFakeDescriptor_Params.validate): >+ (FakeCentral_AddFakeDescriptor_Params.decode): >+ (FakeCentral_AddFakeDescriptor_Params.encode): >+ (FakeCentral_AddFakeDescriptor_ResponseParams): >+ (FakeCentral_AddFakeDescriptor_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_AddFakeDescriptor_ResponseParams.prototype.initFields_): >+ (FakeCentral_AddFakeDescriptor_ResponseParams.validate): >+ (FakeCentral_AddFakeDescriptor_ResponseParams.decode): >+ (FakeCentral_AddFakeDescriptor_ResponseParams.encode): >+ (FakeCentral_RemoveFakeDescriptor_Params): >+ (FakeCentral_RemoveFakeDescriptor_Params.prototype.initDefaults_): >+ (FakeCentral_RemoveFakeDescriptor_Params.prototype.initFields_): >+ (FakeCentral_RemoveFakeDescriptor_Params.validate): >+ (FakeCentral_RemoveFakeDescriptor_Params.decode): >+ (FakeCentral_RemoveFakeDescriptor_Params.encode): >+ (FakeCentral_RemoveFakeDescriptor_ResponseParams): >+ (FakeCentral_RemoveFakeDescriptor_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_RemoveFakeDescriptor_ResponseParams.prototype.initFields_): >+ (FakeCentral_RemoveFakeDescriptor_ResponseParams.validate): >+ (FakeCentral_RemoveFakeDescriptor_ResponseParams.decode): >+ (FakeCentral_RemoveFakeDescriptor_ResponseParams.encode): >+ (FakeCentral_SetNextReadCharacteristicResponse_Params): >+ (FakeCentral_SetNextReadCharacteristicResponse_Params.prototype.initDefaults_): >+ (FakeCentral_SetNextReadCharacteristicResponse_Params.prototype.initFields_): >+ (FakeCentral_SetNextReadCharacteristicResponse_Params.validate): >+ (FakeCentral_SetNextReadCharacteristicResponse_Params.decode): >+ (FakeCentral_SetNextReadCharacteristicResponse_Params.encode): >+ (FakeCentral_SetNextReadCharacteristicResponse_ResponseParams): >+ (FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.prototype.initFields_): >+ (FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.validate): >+ (FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.decode): >+ (FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.encode): >+ (FakeCentral_SetNextWriteCharacteristicResponse_Params): >+ (FakeCentral_SetNextWriteCharacteristicResponse_Params.prototype.initDefaults_): >+ (FakeCentral_SetNextWriteCharacteristicResponse_Params.prototype.initFields_): >+ (FakeCentral_SetNextWriteCharacteristicResponse_Params.validate): >+ (FakeCentral_SetNextWriteCharacteristicResponse_Params.decode): >+ (FakeCentral_SetNextWriteCharacteristicResponse_Params.encode): >+ (FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams): >+ (FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.prototype.initFields_): >+ (FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.validate): >+ (FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.decode): >+ (FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.encode): >+ (FakeCentral_SetNextSubscribeToNotificationsResponse_Params): >+ (FakeCentral_SetNextSubscribeToNotificationsResponse_Params.prototype.initDefaults_): >+ (FakeCentral_SetNextSubscribeToNotificationsResponse_Params.prototype.initFields_): >+ (FakeCentral_SetNextSubscribeToNotificationsResponse_Params.validate): >+ (FakeCentral_SetNextSubscribeToNotificationsResponse_Params.decode): >+ (FakeCentral_SetNextSubscribeToNotificationsResponse_Params.encode): >+ (FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams): >+ (FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.prototype.initFields_): >+ (FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.validate): >+ (FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.decode): >+ (FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.encode): >+ (FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params): >+ (FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.prototype.initDefaults_): >+ (FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.prototype.initFields_): >+ (FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.validate): >+ (FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.decode): >+ (FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.encode): >+ (FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams): >+ (FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.prototype.initFields_): >+ (FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.validate): >+ (FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.decode): >+ (FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.encode): >+ (FakeCentral_IsNotifying_Params): >+ (FakeCentral_IsNotifying_Params.prototype.initDefaults_): >+ (FakeCentral_IsNotifying_Params.prototype.initFields_): >+ (FakeCentral_IsNotifying_Params.validate): >+ (FakeCentral_IsNotifying_Params.decode): >+ (FakeCentral_IsNotifying_Params.encode): >+ (FakeCentral_IsNotifying_ResponseParams): >+ (FakeCentral_IsNotifying_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_IsNotifying_ResponseParams.prototype.initFields_): >+ (FakeCentral_IsNotifying_ResponseParams.validate): >+ (FakeCentral_IsNotifying_ResponseParams.decode): >+ (FakeCentral_IsNotifying_ResponseParams.encode): >+ (FakeCentral_GetLastWrittenCharacteristicValue_Params): >+ (FakeCentral_GetLastWrittenCharacteristicValue_Params.prototype.initDefaults_): >+ (FakeCentral_GetLastWrittenCharacteristicValue_Params.prototype.initFields_): >+ (FakeCentral_GetLastWrittenCharacteristicValue_Params.validate): >+ (FakeCentral_GetLastWrittenCharacteristicValue_Params.decode): >+ (FakeCentral_GetLastWrittenCharacteristicValue_Params.encode): >+ (FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams): >+ (FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.prototype.initFields_): >+ (FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.validate): >+ (FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.decode): >+ (FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.encode): >+ (FakeCentral_SetNextReadDescriptorResponse_Params): >+ (FakeCentral_SetNextReadDescriptorResponse_Params.prototype.initDefaults_): >+ (FakeCentral_SetNextReadDescriptorResponse_Params.prototype.initFields_): >+ (FakeCentral_SetNextReadDescriptorResponse_Params.validate): >+ (FakeCentral_SetNextReadDescriptorResponse_Params.decode): >+ (FakeCentral_SetNextReadDescriptorResponse_Params.encode): >+ (FakeCentral_SetNextReadDescriptorResponse_ResponseParams): >+ (FakeCentral_SetNextReadDescriptorResponse_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_SetNextReadDescriptorResponse_ResponseParams.prototype.initFields_): >+ (FakeCentral_SetNextReadDescriptorResponse_ResponseParams.validate): >+ (FakeCentral_SetNextReadDescriptorResponse_ResponseParams.decode): >+ (FakeCentral_SetNextReadDescriptorResponse_ResponseParams.encode): >+ (FakeCentral_SetNextWriteDescriptorResponse_Params): >+ (FakeCentral_SetNextWriteDescriptorResponse_Params.prototype.initDefaults_): >+ (FakeCentral_SetNextWriteDescriptorResponse_Params.prototype.initFields_): >+ (FakeCentral_SetNextWriteDescriptorResponse_Params.validate): >+ (FakeCentral_SetNextWriteDescriptorResponse_Params.decode): >+ (FakeCentral_SetNextWriteDescriptorResponse_Params.encode): >+ (FakeCentral_SetNextWriteDescriptorResponse_ResponseParams): >+ (FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.prototype.initFields_): >+ (FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.validate): >+ (FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.decode): >+ (FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.encode): >+ (FakeCentral_GetLastWrittenDescriptorValue_Params): >+ (FakeCentral_GetLastWrittenDescriptorValue_Params.prototype.initDefaults_): >+ (FakeCentral_GetLastWrittenDescriptorValue_Params.prototype.initFields_): >+ (FakeCentral_GetLastWrittenDescriptorValue_Params.validate): >+ (FakeCentral_GetLastWrittenDescriptorValue_Params.decode): >+ (FakeCentral_GetLastWrittenDescriptorValue_Params.encode): >+ (FakeCentral_GetLastWrittenDescriptorValue_ResponseParams): >+ (FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.prototype.initDefaults_): >+ (FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.prototype.initFields_): >+ (FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.validate): >+ (FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.decode): >+ (FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.encode): >+ (FakeBluetoothPtr): >+ (FakeBluetoothAssociatedPtr): >+ (FakeBluetoothProxy): >+ (FakeBluetoothPtr.prototype.setLESupported): >+ (FakeBluetoothProxy.prototype.setLESupported): >+ (FakeBluetoothPtr.prototype.simulateCentral): >+ (FakeBluetoothProxy.prototype.simulateCentral): >+ (FakeBluetoothPtr.prototype.allResponsesConsumed): >+ (FakeBluetoothProxy.prototype.allResponsesConsumed): >+ (FakeBluetoothStub.prototype.setLESupported): >+ (FakeBluetoothStub.prototype.simulateCentral): >+ (FakeBluetoothStub.prototype.allResponsesConsumed): >+ (FakeBluetoothStub.prototype.accept): >+ (FakeBluetoothStub.prototype.acceptWithResponder): >+ (validateFakeBluetoothRequest): >+ (validateFakeBluetoothResponse): >+ (FakeCentralPtr): >+ (FakeCentralAssociatedPtr): >+ (FakeCentralProxy): >+ (FakeCentralPtr.prototype.simulatePreconnectedPeripheral): >+ (FakeCentralProxy.prototype.simulatePreconnectedPeripheral): >+ (FakeCentralPtr.prototype.simulateAdvertisementReceived): >+ (FakeCentralProxy.prototype.simulateAdvertisementReceived): >+ (FakeCentralPtr.prototype.setNextGATTConnectionResponse): >+ (FakeCentralProxy.prototype.setNextGATTConnectionResponse): >+ (FakeCentralPtr.prototype.setNextGATTDiscoveryResponse): >+ (FakeCentralProxy.prototype.setNextGATTDiscoveryResponse): >+ (FakeCentralPtr.prototype.simulateGATTDisconnection): >+ (FakeCentralProxy.prototype.simulateGATTDisconnection): >+ (FakeCentralPtr.prototype.simulateGATTServicesChanged): >+ (FakeCentralProxy.prototype.simulateGATTServicesChanged): >+ (FakeCentralPtr.prototype.addFakeService): >+ (FakeCentralProxy.prototype.addFakeService): >+ (FakeCentralPtr.prototype.removeFakeService): >+ (FakeCentralProxy.prototype.removeFakeService): >+ (FakeCentralPtr.prototype.addFakeCharacteristic): >+ (FakeCentralProxy.prototype.addFakeCharacteristic): >+ (FakeCentralPtr.prototype.removeFakeCharacteristic): >+ (FakeCentralProxy.prototype.removeFakeCharacteristic): >+ (FakeCentralPtr.prototype.addFakeDescriptor): >+ (FakeCentralProxy.prototype.addFakeDescriptor): >+ (FakeCentralPtr.prototype.removeFakeDescriptor): >+ (FakeCentralProxy.prototype.removeFakeDescriptor): >+ (FakeCentralPtr.prototype.setNextReadCharacteristicResponse): >+ (FakeCentralProxy.prototype.setNextReadCharacteristicResponse): >+ (FakeCentralPtr.prototype.setNextWriteCharacteristicResponse): >+ (FakeCentralProxy.prototype.setNextWriteCharacteristicResponse): >+ (FakeCentralPtr.prototype.setNextSubscribeToNotificationsResponse): >+ (FakeCentralProxy.prototype.setNextSubscribeToNotificationsResponse): >+ (FakeCentralPtr.prototype.setNextUnsubscribeFromNotificationsResponse): >+ (FakeCentralProxy.prototype.setNextUnsubscribeFromNotificationsResponse): >+ (FakeCentralPtr.prototype.isNotifying): >+ (FakeCentralProxy.prototype.isNotifying): >+ (FakeCentralPtr.prototype.getLastWrittenCharacteristicValue): >+ (FakeCentralProxy.prototype.getLastWrittenCharacteristicValue): >+ (FakeCentralPtr.prototype.setNextReadDescriptorResponse): >+ (FakeCentralProxy.prototype.setNextReadDescriptorResponse): >+ (FakeCentralPtr.prototype.setNextWriteDescriptorResponse): >+ (FakeCentralProxy.prototype.setNextWriteDescriptorResponse): >+ (FakeCentralPtr.prototype.getLastWrittenDescriptorValue): >+ (FakeCentralProxy.prototype.getLastWrittenDescriptorValue): >+ (FakeCentralStub.prototype.simulatePreconnectedPeripheral): >+ (FakeCentralStub.prototype.simulateAdvertisementReceived): >+ (FakeCentralStub.prototype.setNextGATTConnectionResponse): >+ (FakeCentralStub.prototype.setNextGATTDiscoveryResponse): >+ (FakeCentralStub.prototype.simulateGATTDisconnection): >+ (FakeCentralStub.prototype.simulateGATTServicesChanged): >+ (FakeCentralStub.prototype.addFakeService): >+ (FakeCentralStub.prototype.removeFakeService): >+ (FakeCentralStub.prototype.addFakeCharacteristic): >+ (FakeCentralStub.prototype.removeFakeCharacteristic): >+ (FakeCentralStub.prototype.addFakeDescriptor): >+ (FakeCentralStub.prototype.removeFakeDescriptor): >+ (FakeCentralStub.prototype.setNextReadCharacteristicResponse): >+ (FakeCentralStub.prototype.setNextWriteCharacteristicResponse): >+ (FakeCentralStub.prototype.setNextSubscribeToNotificationsResponse): >+ (FakeCentralStub.prototype.setNextUnsubscribeFromNotificationsResponse): >+ (FakeCentralStub.prototype.isNotifying): >+ (FakeCentralStub.prototype.getLastWrittenCharacteristicValue): >+ (FakeCentralStub.prototype.setNextReadDescriptorResponse): >+ (FakeCentralStub.prototype.setNextWriteDescriptorResponse): >+ (FakeCentralStub.prototype.getLastWrittenDescriptorValue): >+ (FakeCentralStub.prototype.accept): >+ (FakeCentralStub.prototype.acceptWithResponder): >+ (validateFakeCentralRequest): >+ (validateFakeCentralResponse): >+ * web-platform-tests/resources/chromium/fake_bluetooth.mojom.js.headers: Copied from LayoutTests/imported/w3c/web-platform-tests/resources/testharness.js.headers. >+ * web-platform-tests/resources/chromium/fake_bluetooth_chooser.mojom.js: Added. >+ (mojo.internal.isMojomLoaded): >+ (ChooserEventType.isKnownEnumValue): >+ (ChooserEventType.validate): >+ (FakeBluetoothChooserEvent): >+ (FakeBluetoothChooserEvent.prototype.initDefaults_): >+ (FakeBluetoothChooserEvent.prototype.initFields_): >+ (FakeBluetoothChooserEvent.validate): >+ (FakeBluetoothChooserEvent.decode): >+ (FakeBluetoothChooserEvent.encode): >+ (FakeBluetoothChooser_WaitForEvents_Params): >+ (FakeBluetoothChooser_WaitForEvents_Params.prototype.initDefaults_): >+ (FakeBluetoothChooser_WaitForEvents_Params.prototype.initFields_): >+ (FakeBluetoothChooser_WaitForEvents_Params.validate): >+ (FakeBluetoothChooser_WaitForEvents_Params.decode): >+ (FakeBluetoothChooser_WaitForEvents_Params.encode): >+ (FakeBluetoothChooser_WaitForEvents_ResponseParams): >+ (FakeBluetoothChooser_WaitForEvents_ResponseParams.prototype.initDefaults_): >+ (FakeBluetoothChooser_WaitForEvents_ResponseParams.prototype.initFields_): >+ (FakeBluetoothChooser_WaitForEvents_ResponseParams.validate): >+ (FakeBluetoothChooser_WaitForEvents_ResponseParams.decode): >+ (FakeBluetoothChooser_WaitForEvents_ResponseParams.encode): >+ (FakeBluetoothChooser_SelectPeripheral_Params): >+ (FakeBluetoothChooser_SelectPeripheral_Params.prototype.initDefaults_): >+ (FakeBluetoothChooser_SelectPeripheral_Params.prototype.initFields_): >+ (FakeBluetoothChooser_SelectPeripheral_Params.validate): >+ (FakeBluetoothChooser_SelectPeripheral_Params.decode): >+ (FakeBluetoothChooser_SelectPeripheral_Params.encode): >+ (FakeBluetoothChooser_SelectPeripheral_ResponseParams): >+ (FakeBluetoothChooser_SelectPeripheral_ResponseParams.prototype.initDefaults_): >+ (FakeBluetoothChooser_SelectPeripheral_ResponseParams.prototype.initFields_): >+ (FakeBluetoothChooser_SelectPeripheral_ResponseParams.validate): >+ (FakeBluetoothChooser_SelectPeripheral_ResponseParams.decode): >+ (FakeBluetoothChooser_SelectPeripheral_ResponseParams.encode): >+ (FakeBluetoothChooser_Cancel_Params): >+ (FakeBluetoothChooser_Cancel_Params.prototype.initDefaults_): >+ (FakeBluetoothChooser_Cancel_Params.prototype.initFields_): >+ (FakeBluetoothChooser_Cancel_Params.validate): >+ (FakeBluetoothChooser_Cancel_Params.decode): >+ (FakeBluetoothChooser_Cancel_Params.encode): >+ (FakeBluetoothChooser_Cancel_ResponseParams): >+ (FakeBluetoothChooser_Cancel_ResponseParams.prototype.initDefaults_): >+ (FakeBluetoothChooser_Cancel_ResponseParams.prototype.initFields_): >+ (FakeBluetoothChooser_Cancel_ResponseParams.validate): >+ (FakeBluetoothChooser_Cancel_ResponseParams.decode): >+ (FakeBluetoothChooser_Cancel_ResponseParams.encode): >+ (FakeBluetoothChooser_Rescan_Params): >+ (FakeBluetoothChooser_Rescan_Params.prototype.initDefaults_): >+ (FakeBluetoothChooser_Rescan_Params.prototype.initFields_): >+ (FakeBluetoothChooser_Rescan_Params.validate): >+ (FakeBluetoothChooser_Rescan_Params.decode): >+ (FakeBluetoothChooser_Rescan_Params.encode): >+ (FakeBluetoothChooser_Rescan_ResponseParams): >+ (FakeBluetoothChooser_Rescan_ResponseParams.prototype.initDefaults_): >+ (FakeBluetoothChooser_Rescan_ResponseParams.prototype.initFields_): >+ (FakeBluetoothChooser_Rescan_ResponseParams.validate): >+ (FakeBluetoothChooser_Rescan_ResponseParams.decode): >+ (FakeBluetoothChooser_Rescan_ResponseParams.encode): >+ (FakeBluetoothChooserPtr): >+ (FakeBluetoothChooserAssociatedPtr): >+ (FakeBluetoothChooserProxy): >+ (FakeBluetoothChooserPtr.prototype.waitForEvents): >+ (FakeBluetoothChooserProxy.prototype.waitForEvents): >+ (FakeBluetoothChooserPtr.prototype.selectPeripheral): >+ (FakeBluetoothChooserProxy.prototype.selectPeripheral): >+ (FakeBluetoothChooserPtr.prototype.cancel): >+ (FakeBluetoothChooserProxy.prototype.cancel): >+ (FakeBluetoothChooserPtr.prototype.rescan): >+ (FakeBluetoothChooserProxy.prototype.rescan): >+ (FakeBluetoothChooserStub.prototype.waitForEvents): >+ (FakeBluetoothChooserStub.prototype.selectPeripheral): >+ (FakeBluetoothChooserStub.prototype.cancel): >+ (FakeBluetoothChooserStub.prototype.rescan): >+ (FakeBluetoothChooserStub.prototype.accept): >+ (FakeBluetoothChooserStub.prototype.acceptWithResponder): >+ (validateFakeBluetoothChooserRequest): >+ (validateFakeBluetoothChooserResponse): >+ * web-platform-tests/resources/chromium/fake_bluetooth_chooser.mojom.js.headers: Copied from LayoutTests/imported/w3c/web-platform-tests/resources/testharness.js.headers. >+ * web-platform-tests/resources/chromium/generic_sensor_mocks.js: Added. >+ (GenericSensorTest): >+ (GenericSensorTest.prototype.getDefaultConfiguration): >+ (GenericSensorTest.prototype.addConfiguration): >+ (GenericSensorTest.prototype.removeConfiguration): >+ (GenericSensorTest.prototype.suspend): >+ (GenericSensorTest.prototype.resume): >+ (GenericSensorTest.prototype.reset): >+ (GenericSensorTest.prototype.startReading): >+ (GenericSensorTest.prototype.stopReading): >+ (GenericSensorTest.prototype.get isReading): >+ (GenericSensorTest.MockSensorProvider): >+ (GenericSensorTest.MockSensorProvider.prototype.async.getSensor): >+ (GenericSensorTest.MockSensorProvider.prototype.async.reset.schedule): >+ (GenericSensorTest.MockSensorProvider.prototype.async.reset): >+ (GenericSensorTest.GenericSensorTestChromium): >+ (GenericSensorTest.GenericSensorTestChromium.prototype.initialize): >+ (GenericSensorTest.GenericSensorTestChromium.prototype.async.reset): >+ * web-platform-tests/resources/chromium/generic_sensor_mocks.js.headers: Copied from LayoutTests/imported/w3c/web-platform-tests/resources/testharness.js.headers. >+ * web-platform-tests/resources/chromium/mojo_layouttest_test.mojom.js: Added. >+ (mojo.internal.isMojomLoaded): >+ (MojoLayoutTestHelper_Reverse_Params): >+ (MojoLayoutTestHelper_Reverse_Params.prototype.initDefaults_): >+ (MojoLayoutTestHelper_Reverse_Params.prototype.initFields_): >+ (MojoLayoutTestHelper_Reverse_Params.validate): >+ (MojoLayoutTestHelper_Reverse_Params.decode): >+ (MojoLayoutTestHelper_Reverse_Params.encode): >+ (MojoLayoutTestHelper_Reverse_ResponseParams): >+ (MojoLayoutTestHelper_Reverse_ResponseParams.prototype.initDefaults_): >+ (MojoLayoutTestHelper_Reverse_ResponseParams.prototype.initFields_): >+ (MojoLayoutTestHelper_Reverse_ResponseParams.validate): >+ (MojoLayoutTestHelper_Reverse_ResponseParams.decode): >+ (MojoLayoutTestHelper_Reverse_ResponseParams.encode): >+ (MojoLayoutTestHelperPtr): >+ (MojoLayoutTestHelperAssociatedPtr): >+ (MojoLayoutTestHelperProxy): >+ (MojoLayoutTestHelperPtr.prototype.reverse): >+ (MojoLayoutTestHelperProxy.prototype.reverse): >+ (MojoLayoutTestHelperStub.prototype.reverse): >+ (MojoLayoutTestHelperStub.prototype.accept): >+ (MojoLayoutTestHelperStub.prototype.acceptWithResponder): >+ (validateMojoLayoutTestHelperRequest): >+ (validateMojoLayoutTestHelperResponse): >+ * web-platform-tests/resources/chromium/mojo_layouttest_test.mojom.js.headers: Copied from LayoutTests/imported/w3c/web-platform-tests/resources/testharness.js.headers. >+ * web-platform-tests/resources/chromium/sensor.mojom.js: Added. >+ (mojo.internal.isMojomLoaded): >+ (SensorType.isKnownEnumValue): >+ (SensorType.validate): >+ (ReportingMode.isKnownEnumValue): >+ (ReportingMode.validate): >+ (SensorConfiguration): >+ (SensorConfiguration.prototype.initDefaults_): >+ (SensorConfiguration.prototype.initFields_): >+ (SensorConfiguration.validate): >+ (SensorConfiguration.decode): >+ (SensorConfiguration.encode): >+ (Sensor_GetDefaultConfiguration_Params): >+ (Sensor_GetDefaultConfiguration_Params.prototype.initDefaults_): >+ (Sensor_GetDefaultConfiguration_Params.prototype.initFields_): >+ (Sensor_GetDefaultConfiguration_Params.validate): >+ (Sensor_GetDefaultConfiguration_Params.decode): >+ (Sensor_GetDefaultConfiguration_Params.encode): >+ (Sensor_GetDefaultConfiguration_ResponseParams): >+ (Sensor_GetDefaultConfiguration_ResponseParams.prototype.initDefaults_): >+ (Sensor_GetDefaultConfiguration_ResponseParams.prototype.initFields_): >+ (Sensor_GetDefaultConfiguration_ResponseParams.validate): >+ (Sensor_GetDefaultConfiguration_ResponseParams.decode): >+ (Sensor_GetDefaultConfiguration_ResponseParams.encode): >+ (Sensor_AddConfiguration_Params): >+ (Sensor_AddConfiguration_Params.prototype.initDefaults_): >+ (Sensor_AddConfiguration_Params.prototype.initFields_): >+ (Sensor_AddConfiguration_Params.validate): >+ (Sensor_AddConfiguration_Params.decode): >+ (Sensor_AddConfiguration_Params.encode): >+ (Sensor_AddConfiguration_ResponseParams): >+ (Sensor_AddConfiguration_ResponseParams.prototype.initDefaults_): >+ (Sensor_AddConfiguration_ResponseParams.prototype.initFields_): >+ (Sensor_AddConfiguration_ResponseParams.validate): >+ (Sensor_AddConfiguration_ResponseParams.decode): >+ (Sensor_AddConfiguration_ResponseParams.encode): >+ (Sensor_RemoveConfiguration_Params): >+ (Sensor_RemoveConfiguration_Params.prototype.initDefaults_): >+ (Sensor_RemoveConfiguration_Params.prototype.initFields_): >+ (Sensor_RemoveConfiguration_Params.validate): >+ (Sensor_RemoveConfiguration_Params.decode): >+ (Sensor_RemoveConfiguration_Params.encode): >+ (Sensor_Suspend_Params): >+ (Sensor_Suspend_Params.prototype.initDefaults_): >+ (Sensor_Suspend_Params.prototype.initFields_): >+ (Sensor_Suspend_Params.validate): >+ (Sensor_Suspend_Params.decode): >+ (Sensor_Suspend_Params.encode): >+ (Sensor_Resume_Params): >+ (Sensor_Resume_Params.prototype.initDefaults_): >+ (Sensor_Resume_Params.prototype.initFields_): >+ (Sensor_Resume_Params.validate): >+ (Sensor_Resume_Params.decode): >+ (Sensor_Resume_Params.encode): >+ (Sensor_ConfigureReadingChangeNotifications_Params): >+ (Sensor_ConfigureReadingChangeNotifications_Params.prototype.initDefaults_): >+ (Sensor_ConfigureReadingChangeNotifications_Params.prototype.initFields_): >+ (Sensor_ConfigureReadingChangeNotifications_Params.validate): >+ (Sensor_ConfigureReadingChangeNotifications_Params.decode): >+ (Sensor_ConfigureReadingChangeNotifications_Params.encode): >+ (SensorClient_RaiseError_Params): >+ (SensorClient_RaiseError_Params.prototype.initDefaults_): >+ (SensorClient_RaiseError_Params.prototype.initFields_): >+ (SensorClient_RaiseError_Params.validate): >+ (SensorClient_RaiseError_Params.decode): >+ (SensorClient_RaiseError_Params.encode): >+ (SensorClient_SensorReadingChanged_Params): >+ (SensorClient_SensorReadingChanged_Params.prototype.initDefaults_): >+ (SensorClient_SensorReadingChanged_Params.prototype.initFields_): >+ (SensorClient_SensorReadingChanged_Params.validate): >+ (SensorClient_SensorReadingChanged_Params.decode): >+ (SensorClient_SensorReadingChanged_Params.encode): >+ (SensorPtr): >+ (SensorAssociatedPtr): >+ (SensorProxy): >+ (SensorPtr.prototype.getDefaultConfiguration): >+ (SensorProxy.prototype.getDefaultConfiguration): >+ (SensorPtr.prototype.addConfiguration): >+ (SensorProxy.prototype.addConfiguration): >+ (SensorPtr.prototype.removeConfiguration): >+ (SensorProxy.prototype.removeConfiguration): >+ (SensorPtr.prototype.suspend): >+ (SensorProxy.prototype.suspend): >+ (SensorPtr.prototype.resume): >+ (SensorProxy.prototype.resume): >+ (SensorPtr.prototype.configureReadingChangeNotifications): >+ (SensorProxy.prototype.configureReadingChangeNotifications): >+ (SensorStub): >+ (SensorStub.prototype.getDefaultConfiguration): >+ (SensorStub.prototype.addConfiguration): >+ (SensorStub.prototype.removeConfiguration): >+ (SensorStub.prototype.suspend): >+ (SensorStub.prototype.resume): >+ (SensorStub.prototype.configureReadingChangeNotifications): >+ (SensorStub.prototype.accept): >+ (SensorStub.prototype.acceptWithResponder): >+ (validateSensorRequest): >+ (validateSensorResponse): >+ (SensorClientPtr): >+ (SensorClientAssociatedPtr): >+ (SensorClientProxy): >+ (SensorClientPtr.prototype.raiseError): >+ (SensorClientProxy.prototype.raiseError): >+ (SensorClientPtr.prototype.sensorReadingChanged): >+ (SensorClientProxy.prototype.sensorReadingChanged): >+ (SensorClientStub): >+ (SensorClientStub.prototype.raiseError): >+ (SensorClientStub.prototype.sensorReadingChanged): >+ (SensorClientStub.prototype.accept): >+ (SensorClientStub.prototype.acceptWithResponder): >+ (validateSensorClientRequest): >+ (validateSensorClientResponse): >+ * web-platform-tests/resources/chromium/sensor_provider.mojom.js: Added. >+ (mojo.internal.isMojomLoaded): >+ (SensorCreationResult.isKnownEnumValue): >+ (SensorCreationResult.validate): >+ (SensorInitParams): >+ (SensorInitParams.prototype.initDefaults_): >+ (SensorInitParams.prototype.initFields_): >+ (SensorInitParams.validate): >+ (SensorInitParams.decode): >+ (SensorInitParams.encode): >+ (SensorProvider_GetSensor_Params): >+ (SensorProvider_GetSensor_Params.prototype.initDefaults_): >+ (SensorProvider_GetSensor_Params.prototype.initFields_): >+ (SensorProvider_GetSensor_Params.validate): >+ (SensorProvider_GetSensor_Params.decode): >+ (SensorProvider_GetSensor_Params.encode): >+ (SensorProvider_GetSensor_ResponseParams): >+ (SensorProvider_GetSensor_ResponseParams.prototype.initDefaults_): >+ (SensorProvider_GetSensor_ResponseParams.prototype.initFields_): >+ (SensorProvider_GetSensor_ResponseParams.validate): >+ (SensorProvider_GetSensor_ResponseParams.decode): >+ (SensorProvider_GetSensor_ResponseParams.encode): >+ (SensorProviderPtr): >+ (SensorProviderAssociatedPtr): >+ (SensorProviderProxy): >+ (SensorProviderPtr.prototype.getSensor): >+ (SensorProviderProxy.prototype.getSensor): >+ (SensorProviderStub.prototype.getSensor): >+ (SensorProviderStub.prototype.accept): >+ (SensorProviderStub.prototype.acceptWithResponder): >+ (validateSensorProviderRequest): >+ (validateSensorProviderResponse): >+ * web-platform-tests/resources/chromium/string16.mojom.js: >+ * web-platform-tests/resources/chromium/uuid.mojom.js: Added. >+ (mojo.internal.isMojomLoaded): >+ (UUID): >+ (UUID.prototype.initDefaults_): >+ (UUID.prototype.initFields_): >+ (UUID.validate): >+ (UUID.decode): >+ (UUID.encode): >+ * web-platform-tests/resources/chromium/uuid.mojom.js.headers: Copied from LayoutTests/imported/w3c/web-platform-tests/resources/testharness.js.headers. >+ * web-platform-tests/resources/chromium/w3c-import.log: >+ * web-platform-tests/resources/chromium/web-bluetooth-test.js: Added. >+ (toMojoCentralState): >+ (canonicalizeAndConvertToMojoUUID): >+ (convertToMojoMap): >+ (ArrayToMojoCharacteristicProperties): >+ (FakeBluetooth): >+ (FakeBluetooth.prototype.async.setLESupported): >+ (FakeBluetooth.prototype.async.simulateCentral): >+ (FakeBluetooth.prototype.async.allResponsesConsumed): >+ (FakeBluetooth.prototype.async.getManualChooser): >+ (FakeCentral): >+ (FakeCentral.prototype.async.simulatePreconnectedPeripheral): >+ (FakeCentral.prototype.async.simulateAdvertisementReceived): >+ (FakeCentral.prototype.fetchOrCreatePeripheral_): >+ (FakePeripheral): >+ (FakePeripheral.prototype.async.addFakeService): >+ (FakePeripheral.prototype.async.setNextGATTConnectionResponse): >+ (FakePeripheral.prototype.async.setNextGATTDiscoveryResponse): >+ (FakePeripheral.prototype.async.simulateGATTDisconnection): >+ (FakePeripheral.prototype.async.simulateGATTServicesChanged): >+ (FakeRemoteGATTService): >+ (FakeRemoteGATTService.prototype.async.addFakeCharacteristic): >+ (FakeRemoteGATTService.prototype.async.remove): >+ (FakeRemoteGATTCharacteristic): >+ (FakeRemoteGATTCharacteristic.prototype.async.addFakeDescriptor): >+ (FakeRemoteGATTCharacteristic.prototype.async.setNextReadResponse): >+ (FakeRemoteGATTCharacteristic.prototype.async.setNextWriteResponse): >+ (FakeRemoteGATTCharacteristic.prototype.async.setNextSubscribeToNotificationsResponse): >+ (FakeRemoteGATTCharacteristic.prototype.async.setNextUnsubscribeFromNotificationsResponse): >+ (FakeRemoteGATTCharacteristic.prototype.async.isNotifying): >+ (FakeRemoteGATTCharacteristic.prototype.async.getLastWrittenValue): >+ (FakeRemoteGATTCharacteristic.prototype.async.remove): >+ (FakeRemoteGATTDescriptor): >+ (FakeRemoteGATTDescriptor.prototype.async.setNextReadResponse): >+ (FakeRemoteGATTDescriptor.prototype.async.setNextWriteResponse): >+ (FakeRemoteGATTDescriptor.prototype.async.getLastWrittenValue): >+ (FakeRemoteGATTDescriptor.prototype.async.remove): >+ (FakeChooser): >+ * web-platform-tests/resources/chromium/web-bluetooth-test.js.headers: Copied from LayoutTests/imported/w3c/web-platform-tests/resources/testharness.js.headers. >+ * web-platform-tests/resources/chromium/webusb-test.js: >+ (prototype.getDevice): >+ * web-platform-tests/resources/idlharness.js: >+ (self.IdlArray): >+ (IdlArray.prototype.add_untested_idls): >+ (IdlArray.prototype.mark_as_untested): >+ (IdlArray.prototype.is_excluded_by_options): >+ (const.process): >+ (IdlArray.prototype.add_dependency_idls): >+ (IdlArray.prototype.internal_add_idls): >+ (IdlArray.prototype.test): >+ (IdlArray.prototype.assert_type_is): >+ (IdlInterface.prototype.get_inheritance_stack): >+ (IdlInterface.prototype.test_self): >+ (IdlInterface.prototype.test_member_iterable): >+ (IdlInterface.prototype.test_interface_of): >+ (should_skip): Deleted. >+ * web-platform-tests/resources/readme.md: >+ * web-platform-tests/resources/test/README.md: >+ * web-platform-tests/resources/test/config.test.json: Removed. >+ * web-platform-tests/resources/test/conftest.py: >+ (pytest_collect_file): >+ (pytest_configure): >+ (HTMLItem.__init__): >+ (HTMLItem.runtest): >+ (HTMLItem): >+ (HTMLItem._run_unit_test): >+ (HTMLItem._run_functional_test): >+ (HTMLItem._summarize): >+ (HTMLItem._assert_sequence): >+ (HTMLItem._scrub_stack): >+ * web-platform-tests/resources/test/idl-helper.js: Added. >+ (interfaceFrom): >+ (memberFrom): >+ (typeFrom): >+ * web-platform-tests/resources/test/tests/functional/add_cleanup.html: Added. >+ * web-platform-tests/resources/test/tests/functional/add_cleanup_count.html: Added. >+ * web-platform-tests/resources/test/tests/functional/add_cleanup_err.html: Added. >+ * web-platform-tests/resources/test/tests/functional/add_cleanup_err_multi.html: Added. >+ * web-platform-tests/resources/test/tests/functional/api-tests-1.html: Added. >+ * web-platform-tests/resources/test/tests/functional/api-tests-2.html: Added. >+ * web-platform-tests/resources/test/tests/functional/api-tests-3.html: Added. >+ * web-platform-tests/resources/test/tests/functional/force_timeout.html: Added. >+ * web-platform-tests/resources/test/tests/functional/generate-callback.html: Added. >+ * web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/test_immutable_prototype.html: Added. >+ * web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/test_primary_interface_of.html: Added. >+ * web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/test_to_json_operation.html: Added. >+ * web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/w3c-import.log: Added. >+ * web-platform-tests/resources/test/tests/functional/iframe-callback.html: Added. >+ * web-platform-tests/resources/test/tests/functional/iframe-consolidate-errors.html: Added. >+ * web-platform-tests/resources/test/tests/functional/iframe-consolidate-tests.html: Added. >+ * web-platform-tests/resources/test/tests/functional/iframe-msg.html: Added. >+ * web-platform-tests/resources/test/tests/functional/order.html: Added. >+ * web-platform-tests/resources/test/tests/functional/promise-async.html: Added. >+ * web-platform-tests/resources/test/tests/functional/promise.html: Added. >+ * web-platform-tests/resources/test/tests/functional/single-page-test-fail.html: Added. >+ * web-platform-tests/resources/test/tests/functional/single-page-test-no-assertions.html: Added. >+ * web-platform-tests/resources/test/tests/functional/single-page-test-no-body.html: Added. >+ * web-platform-tests/resources/test/tests/functional/single-page-test-pass.html: Added. >+ * web-platform-tests/resources/test/tests/functional/uncaught-exception-handle.html: Added. >+ * web-platform-tests/resources/test/tests/functional/uncaught-exception-ignore.html: Added. >+ * web-platform-tests/resources/test/tests/functional/w3c-import.log: Added. >+ * web-platform-tests/resources/test/tests/functional/worker-dedicated.html: Added. >+ * web-platform-tests/resources/test/tests/functional/worker-error.js: Added. >+ * web-platform-tests/resources/test/tests/functional/worker-service.html: Added. >+ * web-platform-tests/resources/test/tests/functional/worker-shared.html: Added. >+ * web-platform-tests/resources/test/tests/functional/worker.js: Added. >+ (test): >+ (async_test): >+ * web-platform-tests/resources/test/tests/unit/IdlArray/is_json_type.html: Added. >+ * web-platform-tests/resources/test/tests/unit/IdlArray/w3c-import.log: Added. >+ * web-platform-tests/resources/test/tests/unit/IdlDictionary/get_inheritance_stack.html: Added. >+ * web-platform-tests/resources/test/tests/unit/IdlDictionary/test_partial_dictionary.html: Added. >+ * web-platform-tests/resources/test/tests/unit/IdlDictionary/w3c-import.log: Added. >+ * web-platform-tests/resources/test/tests/unit/IdlInterface/default_to_json_operation.html: Added. >+ * web-platform-tests/resources/test/tests/unit/IdlInterface/get_inheritance_stack.html: Added. >+ * web-platform-tests/resources/test/tests/unit/IdlInterface/has_default_to_json_regular_operation.html: Added. >+ * web-platform-tests/resources/test/tests/unit/IdlInterface/has_to_json_regular_operation.html: Added. >+ * web-platform-tests/resources/test/tests/unit/IdlInterface/test_primary_interface_of_undefined.html: Added. >+ * web-platform-tests/resources/test/tests/unit/IdlInterface/traverse_inherited_and_consequential_interfaces.html: Added. >+ * web-platform-tests/resources/test/tests/unit/IdlInterface/w3c-import.log: Added. >+ * web-platform-tests/resources/test/tests/unit/IdlInterfaceMember/is_to_json_regular_operation.html: Added. >+ * web-platform-tests/resources/test/tests/unit/IdlInterfaceMember/w3c-import.log: Added. >+ * web-platform-tests/resources/test/tests/unit/OWNERS: Added. >+ * web-platform-tests/resources/test/tests/unit/basic.html: Added. >+ * web-platform-tests/resources/test/tests/unit/w3c-import.log: Added. >+ * web-platform-tests/resources/test/tox.ini: >+ * web-platform-tests/resources/test/w3c-import.log: >+ * web-platform-tests/resources/test/wptserver.py: >+ (WPTServer): >+ (WPTServer.__init__): >+ (WPTServer.start): >+ (WPTServer.stop): >+ (WPTServer.url): >+ * web-platform-tests/resources/testdriver-vendor.js: Added. >+ * web-platform-tests/resources/testdriver-vendor.js.headers: Added. >+ * web-platform-tests/resources/testdriver.js: Added. >+ (getInViewCenterPoint): >+ (getPointerInteractablePaintTree): >+ (inView): >+ (window.test_driver.click): >+ (window.test_driver.send_keys): >+ (window.test_driver.freeze): >+ (window.test_driver_internal.click): >+ (window.test_driver_internal.send_keys): >+ (window.test_driver_internal.freeze): >+ * web-platform-tests/resources/testdriver.js.headers: Added. >+ * web-platform-tests/resources/testharness.css.headers: >+ * web-platform-tests/resources/testharness.js: >+ (ShellTestEnvironment): >+ (ShellTestEnvironment.prototype.next_default_test_name): >+ (ShellTestEnvironment.prototype.on_new_harness_properties): >+ (ShellTestEnvironment.prototype.on_tests_ready): >+ (ShellTestEnvironment.prototype.add_on_loaded_callback): >+ (ShellTestEnvironment.prototype.test_timeout): >+ (create_test_environment): >+ (is_shared_worker): >+ (is_service_worker): >+ (WindowTestEnvironment.prototype.global_scope): Deleted. >+ (WorkerTestEnvironment.prototype.global_scope): Deleted. >+ * web-platform-tests/resources/testharness.js.headers: >+ * web-platform-tests/resources/testharnessreport.js.headers: >+ * web-platform-tests/resources/w3c-import.log: >+ * web-platform-tests/resources/webidl2/CHANGELOG.md: Added. >+ * web-platform-tests/resources/webidl2/README.md: >+ * web-platform-tests/resources/webidl2/lib/webidl2.js: >+ (attemptTokenMatch): >+ (tokenise): >+ (consume): >+ (count): >+ (ws): >+ (integer_type): >+ (float_type): >+ (primitive_type): >+ (const_value): >+ (type_suffix): >+ (single_type): >+ (union_type): >+ (type): >+ (type_with_extended_attributes): >+ (argument): >+ (argument_list): >+ (simple_extended_attr): >+ (extended_attrs): >+ (default_): >+ (const_): >+ (inheritance): >+ (operation_rest): >+ (callback): >+ (attribute): >+ (attribute_rest): >+ (return_type): >+ (operation): >+ (identifiers): >+ (iterable_type): >+ (readonly_iterable_type): >+ (iterable): >+ (interface_rest): >+ (mixin_rest): >+ (namespace): >+ (noninherited_attribute): >+ (partial): >+ (dictionary): >+ (enum_): >+ (typedef): >+ (implements_): >+ (includes): >+ (definition): >+ (definitions): >+ (parse): >+ (all_ws): Deleted. >+ * web-platform-tests/resources/webidl2/lib/writer.js: >+ (write): >+ (write.): >+ (noop): Deleted. >+ (literal): Deleted. >+ (wsPea): Deleted. >+ (wsTPea): Deleted. >+ (lineComment): Deleted. >+ (multilineComment): Deleted. >+ (type): Deleted. >+ (const_value): Deleted. >+ (argument): Deleted. >+ (args): Deleted. >+ (make_ext_at): Deleted. >+ (extended_attributes): Deleted. >+ (operation): Deleted. >+ (attribute): Deleted. >+ (interface_): Deleted. >+ (dictionary): Deleted. >+ (field): Deleted. >+ (exception): Deleted. >+ (const_): Deleted. >+ (typedef): Deleted. >+ (implements_): Deleted. >+ (callback): Deleted. >+ (enum_): Deleted. >+ (serializer): Deleted. >+ (iterable): Deleted. >+ (legacyiterable): Deleted. >+ (maplike): Deleted. >+ (setlike): Deleted. >+ (callbackInterface): Deleted. >+ (dispatch): Deleted. >+ (iterate): Deleted. >+ (obj.write): Deleted. >+ (else): Deleted. >+ * web-platform-tests/resources/webidl2/package-lock.json: Added. >+ * web-platform-tests/resources/webidl2/package.json: >+ * web-platform-tests/resources/webidl2/test/invalid.js: >+ (const.test.of.collect): >+ (idls.fs.readdirSync.dir.filter): Deleted. >+ (map): Deleted. >+ (errors.idls.map): Deleted. >+ (i.func): Deleted. >+ * web-platform-tests/resources/webidl2/test/invalid/idl/array.widl: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/idl/caller.widl: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/idl/duplicate.widl: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/idl/exception.widl: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/idl/iterator.widl: Renamed from LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/iterator.widl. >+ * web-platform-tests/resources/webidl2/test/invalid/idl/maplike-1type.widl: >+ * web-platform-tests/resources/webidl2/test/invalid/idl/no-semicolon-callback.widl: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/idl/no-semicolon.widl: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/idl/promise-with-extended-attribute.widl: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/idl/readonly-iterable.widl: >+ * web-platform-tests/resources/webidl2/test/invalid/idl/record-key-with-extended-attribute.widl: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/idl/setlike-2types.widl: >+ * web-platform-tests/resources/webidl2/test/invalid/idl/setter-creator.widl: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/idl/special-omittable.widl: >+ * web-platform-tests/resources/webidl2/test/invalid/idl/stray-slash.widl: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/idl/stringconstants.widl: Renamed from LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/stringconstants.idl. >+ * web-platform-tests/resources/webidl2/test/invalid/idl/typedef-nested.widl: >+ * web-platform-tests/resources/webidl2/test/invalid/idl/w3c-import.log: >+ * web-platform-tests/resources/webidl2/test/invalid/json/array.json: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/json/caller.json: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/json/dict-required-default.json: >+ * web-platform-tests/resources/webidl2/test/invalid/json/duplicate.json: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/json/enum.json: >+ * web-platform-tests/resources/webidl2/test/invalid/json/exception.json: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/json/iterator.json: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/json/maplike-1type.json: >+ * web-platform-tests/resources/webidl2/test/invalid/json/module.json: >+ * web-platform-tests/resources/webidl2/test/invalid/json/no-semicolon-callback.json: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/json/no-semicolon.json: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/json/nonnullableany.json: >+ * web-platform-tests/resources/webidl2/test/invalid/json/nonnullableobjects.json: >+ * web-platform-tests/resources/webidl2/test/invalid/json/promise-with-extended-attribute.json: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/json/raises.json: >+ * web-platform-tests/resources/webidl2/test/invalid/json/readonly-iterable.json: >+ * web-platform-tests/resources/webidl2/test/invalid/json/record-key-with-extended-attribute.json: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/json/record-key.json: >+ * web-platform-tests/resources/webidl2/test/invalid/json/scopedname.json: >+ * web-platform-tests/resources/webidl2/test/invalid/json/sequenceAsAttribute.json: >+ * web-platform-tests/resources/webidl2/test/invalid/json/setlike-2types.json: >+ * web-platform-tests/resources/webidl2/test/invalid/json/setter-creator.json: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/json/special-omittable.json: >+ * web-platform-tests/resources/webidl2/test/invalid/json/stray-slash.json: Added. >+ * web-platform-tests/resources/webidl2/test/invalid/json/stringconstants.json: >+ * web-platform-tests/resources/webidl2/test/invalid/json/typedef-nested.json: >+ * web-platform-tests/resources/webidl2/test/invalid/json/w3c-import.log: >+ * web-platform-tests/resources/webidl2/test/syntax.js: >+ (const.test.of.collect): >+ (idls.fs.readdirSync.dir.filter): Deleted. >+ (map): Deleted. >+ (jsons.idls.map): Deleted. >+ (i.func): Deleted. >+ * web-platform-tests/resources/webidl2/test/syntax/idl/array.widl: Removed. >+ * web-platform-tests/resources/webidl2/test/syntax/idl/attributes.widl: >+ * web-platform-tests/resources/webidl2/test/syntax/idl/caller.widl: Removed. >+ * web-platform-tests/resources/webidl2/test/syntax/idl/constants.widl: >+ * web-platform-tests/resources/webidl2/test/syntax/idl/equivalent-decl.widl: >+ * web-platform-tests/resources/webidl2/test/syntax/idl/exception-inheritance.widl: Removed. >+ * web-platform-tests/resources/webidl2/test/syntax/idl/exception.widl: Removed. >+ * web-platform-tests/resources/webidl2/test/syntax/idl/extended-attributes.widl: >+ * web-platform-tests/resources/webidl2/test/syntax/idl/generic.widl: >+ * web-platform-tests/resources/webidl2/test/syntax/idl/identifier-qualified-names.widl: >+ * web-platform-tests/resources/webidl2/test/syntax/idl/indexed-properties.widl: >+ * web-platform-tests/resources/webidl2/test/syntax/idl/iterable.widl: >+ * web-platform-tests/resources/webidl2/test/syntax/idl/legacyiterable.widl: >+ * web-platform-tests/resources/webidl2/test/syntax/idl/linecomment.widl: Added. >+ * web-platform-tests/resources/webidl2/test/syntax/idl/maplike.widl: >+ * web-platform-tests/resources/webidl2/test/syntax/idl/mixin.widl: Added. >+ * web-platform-tests/resources/webidl2/test/syntax/idl/overloading.widl: >+ * web-platform-tests/resources/webidl2/test/syntax/idl/primitives.widl: >+ * web-platform-tests/resources/webidl2/test/syntax/idl/record.widl: >+ * web-platform-tests/resources/webidl2/test/syntax/idl/reg-operations.widl: >+ * web-platform-tests/resources/webidl2/test/syntax/idl/sequence.widl: >+ * web-platform-tests/resources/webidl2/test/syntax/idl/serializer.widl: Removed. >+ * web-platform-tests/resources/webidl2/test/syntax/idl/setlike.widl: >+ * web-platform-tests/resources/webidl2/test/syntax/idl/stringifier.widl: >+ * web-platform-tests/resources/webidl2/test/syntax/idl/typedef-union.widl: Renamed from LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/typedef-union.idl. >+ * web-platform-tests/resources/webidl2/test/syntax/idl/typesuffixes.widl: >+ * web-platform-tests/resources/webidl2/test/syntax/idl/w3c-import.log: >+ * web-platform-tests/resources/webidl2/test/syntax/json/allowany.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/array.json: Removed. >+ * web-platform-tests/resources/webidl2/test/syntax/json/attributes.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/callback.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/caller.json: Removed. >+ * web-platform-tests/resources/webidl2/test/syntax/json/constants.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/constructor.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/dictionary-inherits.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/dictionary.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/documentation-dos.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/documentation.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/enum.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/equivalent-decl.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/exception-inheritance.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/exception.json: Removed. >+ * web-platform-tests/resources/webidl2/test/syntax/json/extended-attributes.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/generic.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/getter-setter.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/identifier-qualified-names.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/implements.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/indexed-properties.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/inherits-getter.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/interface-inherits.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/iterable.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/iterator.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/legacyiterable.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/linecomment.json: Added. >+ * web-platform-tests/resources/webidl2/test/syntax/json/maplike.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/mixin.json: Added. >+ * web-platform-tests/resources/webidl2/test/syntax/json/namedconstructor.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/namespace.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/nointerfaceobject.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/nullable.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/nullableobjects.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/operation-optional-arg.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/overloading.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/overridebuiltins.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/partial-interface.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/primitives.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/prototyperoot.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/putforwards.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/record.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/reg-operations.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/replaceable.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/sequence.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/serializer.json: Removed. >+ * web-platform-tests/resources/webidl2/test/syntax/json/setlike.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/static.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/stringifier-attribute.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/stringifier-custom.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/stringifier.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/treatasnull.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/treatasundefined.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/typedef-union.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/typedef.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/typesuffixes.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/uniontype.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/variadic-operations.json: >+ * web-platform-tests/resources/webidl2/test/syntax/json/w3c-import.log: >+ * web-platform-tests/resources/webidl2/test/syntax/opt/linecomment.json: Added. >+ * web-platform-tests/resources/webidl2/test/syntax/opt/w3c-import.log: >+ * web-platform-tests/resources/webidl2/test/util/acquire.js: Added. >+ (const.test.of.collect): >+ * web-platform-tests/resources/webidl2/test/util/collect.js: Added. >+ (collect): >+ * web-platform-tests/resources/webidl2/test/util/w3c-import.log: Added. >+ * web-platform-tests/resources/webidl2/test/w3c-import.log: >+ * web-platform-tests/resources/webidl2/test/writer.js: Added. >+ (const.test.of.collect): >+ * web-platform-tests/resources/webidl2/w3c-import.log: >+ * web-platform-tests/secure-contexts/OWNERS: Added. >+ * web-platform-tests/secure-contexts/w3c-import.log: >+ * web-platform-tests/server-timing/OWNERS: Added. >+ * web-platform-tests/server-timing/sw.js: >+ (importScripts.string_appeared_here.promise_test): >+ * web-platform-tests/server-timing/w3c-import.log: >+ * web-platform-tests/service-workers/OWNERS: >+ * web-platform-tests/service-workers/cache-storage/resources/cache-keys-attributes-for-service-worker.js: Added. >+ (event.params.has): >+ (event.event.respondWith.Promise.resolve.then.async): >+ * web-platform-tests/service-workers/cache-storage/resources/w3c-import.log: >+ * web-platform-tests/service-workers/cache-storage/script-tests/cache-abort.js: Added. >+ (const.methodsToTest.put.async): >+ (const.method.in.methodsToTest.cache_test.async): >+ (const.method.in.methodsToTest.return.promise_rejects): >+ (const.method.in.methodsToTest.return.fetch): >+ * web-platform-tests/service-workers/cache-storage/script-tests/cache-match.js: >+ (cache_test.async): >+ * web-platform-tests/service-workers/cache-storage/script-tests/w3c-import.log: >+ * web-platform-tests/service-workers/cache-storage/serviceworker/cache-abort.https-expected.txt: Added. >+ * web-platform-tests/service-workers/cache-storage/serviceworker/cache-abort.https.html: Added. >+ * web-platform-tests/service-workers/cache-storage/serviceworker/cache-keys-attributes-for-service-worker.https-expected.txt: Added. >+ * web-platform-tests/service-workers/cache-storage/serviceworker/cache-keys-attributes-for-service-worker.https.html: Added. >+ * web-platform-tests/service-workers/cache-storage/serviceworker/cache-match.https-expected.txt: >+ * web-platform-tests/service-workers/cache-storage/serviceworker/w3c-import.log: >+ * web-platform-tests/service-workers/cache-storage/window/cache-abort.https-expected.txt: Added. >+ * web-platform-tests/service-workers/cache-storage/window/cache-abort.https.html: Added. >+ * web-platform-tests/service-workers/cache-storage/window/cache-match.https-expected.txt: >+ * web-platform-tests/service-workers/cache-storage/window/cache-match.https.html: >+ * web-platform-tests/service-workers/cache-storage/window/w3c-import.log: >+ * web-platform-tests/service-workers/cache-storage/worker/cache-abort.https-expected.txt: Added. >+ * web-platform-tests/service-workers/cache-storage/worker/cache-abort.https.html: Added. >+ * web-platform-tests/service-workers/cache-storage/worker/cache-match.https-expected.txt: >+ * web-platform-tests/service-workers/cache-storage/worker/w3c-import.log: >+ * web-platform-tests/service-workers/service-worker/Service-Worker-Allowed-header.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/Service-Worker-Allowed-header.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-controlling-worker.html: Added. >+ * web-platform-tests/service-workers/service-worker/about-blank-replacement.https-expected.txt: >+ * web-platform-tests/service-workers/service-worker/about-blank-replacement.https.html: >+ * web-platform-tests/service-workers/service-worker/activation.https.html: >+ * web-platform-tests/service-workers/service-worker/dedicated-worker-service-worker-interception.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/dedicated-worker-service-worker-interception.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/detached-context.https.html: >+ * web-platform-tests/service-workers/service-worker/embed-and-object-are-not-intercepted.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/embed-and-object-are-not-intercepted.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-cache.https-expected.txt: Removed. >+ * web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-cache.https.html: Removed. >+ * web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image-cache.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image-cache.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-cache.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-cache.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-with-range-request.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-with-range-request.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-canvas-tainting.https-expected.txt: Removed. >+ * web-platform-tests/service-workers/service-worker/fetch-canvas-tainting.https.html: Removed. >+ * web-platform-tests/service-workers/service-worker/fetch-cors-exposed-header-names.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-cors-exposed-header-names.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-event-is-history-backward-navigation-manual.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-event-is-history-forward-navigation-manual.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-event-is-reload-iframe-navigation-manual.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-event-is-reload-iframe-navigation-manual.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-event-is-reload-navigation-manual.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-event-redirect.https-expected.txt: >+ * web-platform-tests/service-workers/service-worker/fetch-event-redirect.https.html: >+ * web-platform-tests/service-workers/service-worker/fetch-event-referrer-policy.https-expected.txt: >+ * web-platform-tests/service-workers/service-worker/fetch-event-referrer-policy.https.html: >+ * web-platform-tests/service-workers/service-worker/fetch-event-respond-with-custom-response.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-event-respond-with-custom-response.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-event-respond-with-readable-stream.https-expected.txt: >+ * web-platform-tests/service-workers/service-worker/fetch-event-respond-with-readable-stream.https.html: >+ * web-platform-tests/service-workers/service-worker/fetch-event.https-expected.txt: >+ * web-platform-tests/service-workers/service-worker/fetch-event.https.html: >+ * web-platform-tests/service-workers/service-worker/fetch-request-css-cross-origin-mime-check.https-expected.txt: Removed. >+ * web-platform-tests/service-workers/service-worker/fetch-request-css-cross-origin-mime-check.https.html: Removed. >+ * web-platform-tests/service-workers/service-worker/fetch-request-css-cross-origin.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-request-css-cross-origin.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-request-no-freshness-headers.https-expected.txt: >+ * web-platform-tests/service-workers/service-worker/fetch-request-resources.https.html: >+ * web-platform-tests/service-workers/service-worker/fetch-request-xhr-sync-on-worker.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-request-xhr-sync-on-worker.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/fetch-response-taint.https-expected.txt: >+ * web-platform-tests/service-workers/service-worker/fetch-response-taint.https.html: >+ * web-platform-tests/service-workers/service-worker/import-scripts-updated-flag.https-expected.txt: >+ * web-platform-tests/service-workers/service-worker/import-scripts-updated-flag.https.html: >+ * web-platform-tests/service-workers/service-worker/interfaces-sw.https-expected.txt: >+ * web-platform-tests/service-workers/service-worker/interfaces-window.https-expected.txt: >+ * web-platform-tests/service-workers/service-worker/interfaces-window.https.html: >+ * web-platform-tests/service-workers/service-worker/local-url-inherit-controller.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/local-url-inherit-controller.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/multipart-image.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/multipart-image.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/navigate-window.https.html: >+ * web-platform-tests/service-workers/service-worker/navigation-preload/broken-chunked-encoding.https.html: >+ * web-platform-tests/service-workers/service-worker/navigation-preload/resource-timing.https.html: >+ * web-platform-tests/service-workers/service-worker/navigation-preload/resources/broken-chunked-encoding-worker.js: >+ * web-platform-tests/service-workers/service-worker/navigation-preload/resources/chunked-encoding-scope.py: >+ (main): >+ * web-platform-tests/service-workers/service-worker/navigation-preload/resources/empty-preload-response-body-scope.html: Added. >+ * web-platform-tests/service-workers/service-worker/navigation-redirect.https.html: >+ * web-platform-tests/service-workers/service-worker/navigation-timing.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/navigation-timing.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/postmessage.https.html: >+ * web-platform-tests/service-workers/service-worker/registration-iframe.https.html: >+ * web-platform-tests/service-workers/service-worker/registration-security-error.https-expected.txt: >+ * web-platform-tests/service-workers/service-worker/registration-updateviacache.https-expected.txt: >+ * web-platform-tests/service-workers/service-worker/registration-updateviacache.https.html: >+ * web-platform-tests/service-workers/service-worker/resource-timing-cross-origin.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/resource-timing-cross-origin.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/resource-timing.https-expected.txt: >+ * web-platform-tests/service-workers/service-worker/resource-timing.https.html: >+ * web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-blank-dynamic-nested-frame.html: Added. >+ * web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-blank-nested-frame.html: Added. >+ * web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-popup-frame.py: >+ * web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-srcdoc-nested-frame.html: Added. >+ * web-platform-tests/service-workers/service-worker/resources/client-navigate-worker.js: >+ (importScripts.string_appeared_here.importScripts.string_appeared_here.self.onfetch): >+ * web-platform-tests/service-workers/service-worker/resources/clients-get-worker.js: >+ (self.onfetch): >+ * web-platform-tests/service-workers/service-worker/resources/dummy-shared-worker-interceptor.js: >+ (self.onfetch): >+ * web-platform-tests/service-workers/service-worker/resources/dummy-shared-worker-interceptor.js.headers: Added. >+ * web-platform-tests/service-workers/service-worker/resources/echo-content.py: Added. >+ (main): >+ * web-platform-tests/service-workers/service-worker/resources/embed-and-object-are-not-intercepted-worker.js: Added. >+ (e.e.request.url.indexOf): >+ * web-platform-tests/service-workers/service-worker/resources/embed-image-is-not-intercepted-iframe.html: Added. >+ * web-platform-tests/service-workers/service-worker/resources/embed-is-not-intercepted-iframe.html: Added. >+ * web-platform-tests/service-workers/service-worker/resources/embedded-content-from-server.html: Added. >+ * web-platform-tests/service-workers/service-worker/resources/embedded-content-from-service-worker.html: Added. >+ * web-platform-tests/service-workers/service-worker/resources/fetch-access-control.py: >+ (main): >+ * web-platform-tests/service-workers/service-worker/resources/fetch-canvas-tainting-iframe.html: >+ * web-platform-tests/service-workers/service-worker/resources/fetch-canvas-tainting-tests.js: Added. >+ (canvas_taint_test): >+ (do_canvas_tainting_tests.): >+ * web-platform-tests/service-workers/service-worker/resources/fetch-cors-exposed-header-names-worker.js: Added. >+ * web-platform-tests/service-workers/service-worker/resources/fetch-event-network-fallback-worker.js: Added. >+ * web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-custom-response-worker.js: Added. >+ (event.else): >+ * web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-iframe.html: Removed. >+ * web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-worker.js: >+ (event.url.searchParams.has): >+ (event.const.stream.new.ReadableStream.start): >+ * web-platform-tests/service-workers/service-worker/resources/fetch-event-test-worker.js: >+ (handleIsReloadNavigation): >+ (handleIsHistoryNavigation): >+ * web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-iframe.html: >+ * web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-worker.js: Removed. >+ * web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-read-contents.html: Added. >+ * web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-worker.js: Added. >+ (add_pipe_header): >+ * web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-iframe.html: >+ * web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-script.py: Added. >+ (main): >+ * web-platform-tests/service-workers/service-worker/resources/fetch-request-redirect-iframe.html: >+ * web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html: >+ * web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-sync-on-worker-worker.js: Added. >+ (self.onfetch): >+ * web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-worker.js: >+ (event.respondWith.new.Promise): >+ * web-platform-tests/service-workers/service-worker/resources/fetch-rewrite-worker.js: >+ (event.respondWith.new.Promise.): >+ (event.respondWith.new.Promise): >+ * web-platform-tests/service-workers/service-worker/resources/iframe-with-image.html: Added. >+ * web-platform-tests/service-workers/service-worker/resources/import-scripts-updated-flag-worker.js: >+ (test_import): >+ * web-platform-tests/service-workers/service-worker/resources/install-worker.html: Added. >+ * web-platform-tests/service-workers/service-worker/resources/interfaces-idls.js: >+ * web-platform-tests/service-workers/service-worker/resources/interfaces-worker.sub.js: >+ (promise_test.async): >+ (promise_test): Deleted. >+ * web-platform-tests/service-workers/service-worker/resources/local-url-inherit-controller-frame.html: Added. >+ * web-platform-tests/service-workers/service-worker/resources/local-url-inherit-controller-worker.js: Added. >+ (evt.evt.request.url.includes): >+ * web-platform-tests/service-workers/service-worker/resources/multipart-image-iframe.html: Added. >+ * web-platform-tests/service-workers/service-worker/resources/multipart-image-worker.js: Added. >+ (event.url.indexOf): >+ (event.else.url.indexOf): >+ * web-platform-tests/service-workers/service-worker/resources/multipart-image.py: Added. >+ (create_part): >+ (main): >+ * web-platform-tests/service-workers/service-worker/resources/navigation-timing-worker.js: Added. >+ (event.url.indexOf): >+ * web-platform-tests/service-workers/service-worker/resources/object-image-is-not-intercepted-iframe.html: Added. >+ * web-platform-tests/service-workers/service-worker/resources/object-is-not-intercepted-iframe.html: Added. >+ * web-platform-tests/service-workers/service-worker/resources/pass-through-worker.js: Added. >+ * web-platform-tests/service-workers/service-worker/resources/pass.txt: Added. >+ * web-platform-tests/service-workers/service-worker/resources/range-request-to-different-origins-worker.js: Added. >+ (is_initial_request): >+ (e.url.search.indexOf): >+ (e.is_initial_request): >+ * web-platform-tests/service-workers/service-worker/resources/range-request-with-different-cors-modes-worker.js: Added. >+ (is_initial_request): >+ (e.url.search.indexOf): >+ (e.is_initial_request): >+ * web-platform-tests/service-workers/service-worker/resources/registration-tests-security-error.js: >+ (registration_tests_security_error): >+ * web-platform-tests/service-workers/service-worker/resources/resource-timing-iframe.sub.html: >+ * web-platform-tests/service-workers/service-worker/resources/resource-timing-worker.js: >+ (event.request.url.indexOf): >+ (else.event.request.url.indexOf): >+ * web-platform-tests/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-iframe.html: >+ * web-platform-tests/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-iframe.py: Added. >+ (main): >+ * web-platform-tests/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-worker.js: >+ (event.waitUntil.self.clients.matchAll.then): >+ * web-platform-tests/service-workers/service-worker/resources/scope1/redirect.py: Added. >+ * web-platform-tests/service-workers/service-worker/resources/scope1/w3c-import.log: Added. >+ * web-platform-tests/service-workers/service-worker/resources/scope2/w3c-import.log: Added. >+ * web-platform-tests/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py: Added. >+ * web-platform-tests/service-workers/service-worker/resources/service-worker-header.py: Added. >+ (main): >+ * web-platform-tests/service-workers/service-worker/resources/service-worker-interception-dynamic-import-worker.js: Added. >+ * web-platform-tests/service-workers/service-worker/resources/service-worker-interception-network-worker.js: Added. >+ * web-platform-tests/service-workers/service-worker/resources/service-worker-interception-service-worker.js: Added. >+ * web-platform-tests/service-workers/service-worker/resources/service-worker-interception-static-import-worker.js: Added. >+ * web-platform-tests/service-workers/service-worker/resources/simple-intercept-worker.js.headers: Added. >+ * web-platform-tests/service-workers/service-worker/resources/square.png.sub.headers: Added. >+ * web-platform-tests/service-workers/service-worker/resources/test-helpers.sub.js: >+ (wait_for_state): >+ (async.wait_for_activation_on_dummy_scope): >+ (login_https): Deleted. >+ * web-platform-tests/service-workers/service-worker/resources/vtt-frame.html: Added. >+ * web-platform-tests/service-workers/service-worker/resources/w3c-import.log: >+ * web-platform-tests/service-workers/service-worker/resources/worker-client-id-worker.js: Added. >+ (evt.evt.request.url.includes): >+ * web-platform-tests/service-workers/service-worker/resources/worker-fetching-cross-origin.js: Added. >+ (event.event.request.url.indexOf): >+ * web-platform-tests/service-workers/service-worker/resources/worker-interception-redirect-serviceworker.js: Added. >+ (evt.evt.request.url.indexOf): >+ * web-platform-tests/service-workers/service-worker/resources/worker-interception-redirect-webworker.js: Added. >+ (self.onconnect.async): >+ * web-platform-tests/service-workers/service-worker/resources/worker_interception_redirect_webworker.py: Added. >+ (main): >+ * web-platform-tests/service-workers/service-worker/sandboxed-iframe-fetch-event.https.html: >+ * web-platform-tests/service-workers/service-worker/service-worker-header.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/service-worker-header.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https-expected.txt: >+ * web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https.html: >+ * web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https-expected.txt: >+ * web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https.html: >+ * web-platform-tests/service-workers/service-worker/svg-target-reftest.https-expected.html: Added. >+ * web-platform-tests/service-workers/service-worker/svg-target-reftest.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/unregister-then-register-new-script.https-expected.txt: >+ * web-platform-tests/service-workers/service-worker/unregister-then-register-new-script.https.html: >+ * web-platform-tests/service-workers/service-worker/update-result.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/update-result.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/w3c-import.log: >+ * web-platform-tests/service-workers/service-worker/webvtt-cross-origin.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/webvtt-cross-origin.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/windowclient-navigate.https.html: >+ * web-platform-tests/service-workers/service-worker/worker-client-id.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/worker-client-id.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/worker-interception-redirect.https-expected.txt: Added. >+ * web-platform-tests/service-workers/service-worker/worker-interception-redirect.https.html: Added. >+ * web-platform-tests/service-workers/service-worker/worker-interception.https-expected.txt: >+ * web-platform-tests/service-workers/service-worker/worker-interception.https.html: >+ * web-platform-tests/service-workers/stub-3.1-service-worker-obj-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-3.1-service-worker-obj.html: Added. >+ * web-platform-tests/service-workers/stub-3.1.1-service-worker-scope-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-3.1.1-service-worker-scope.html: Added. >+ * web-platform-tests/service-workers/stub-3.1.2-service-worker-url-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-3.1.2-service-worker-url.html: Added. >+ * web-platform-tests/service-workers/stub-3.1.3-service-worker-state-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-3.1.3-service-worker-state.html: Added. >+ * web-platform-tests/service-workers/stub-3.1.4-service-worker-on-state-change-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-3.1.4-service-worker-on-state-change.html: Added. >+ * web-platform-tests/service-workers/stub-3.2-navigator-service-worker-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-3.2-navigator-service-worker.html: Added. >+ * web-platform-tests/service-workers/stub-3.2.1-navigator-service-worker-installing-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-3.2.1-navigator-service-worker-installing.html: Added. >+ * web-platform-tests/service-workers/stub-3.2.10-navigator-service-worker-oncontrollerchange-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-3.2.10-navigator-service-worker-oncontrollerchange.html: Added. >+ * web-platform-tests/service-workers/stub-3.2.11-navigator-service-worker-onreloadpage-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-3.2.11-navigator-service-worker-onreloadpage.html: Added. >+ * web-platform-tests/service-workers/stub-3.2.12-navigator-service-worker-onerror-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-3.2.12-navigator-service-worker-onerror.html: Added. >+ * web-platform-tests/service-workers/stub-3.2.2-navigator-service-worker-waiting-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-3.2.2-navigator-service-worker-waiting.html: Added. >+ * web-platform-tests/service-workers/stub-3.2.3-navigator-service-worker-active-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-3.2.3-navigator-service-worker-active.html: Added. >+ * web-platform-tests/service-workers/stub-3.2.4-navigator-service-worker-controller-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-3.2.4-navigator-service-worker-controller.html: Added. >+ * web-platform-tests/service-workers/stub-3.2.5-navigator-service-worker-ready-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-3.2.5-navigator-service-worker-ready.html: Added. >+ * web-platform-tests/service-workers/stub-3.2.6-navigator-service-worker-getAll-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-3.2.6-navigator-service-worker-getAll.html: Added. >+ * web-platform-tests/service-workers/stub-3.2.7-navigator-service-worker-register-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-3.2.7-navigator-service-worker-register.html: Added. >+ * web-platform-tests/service-workers/stub-3.2.8-navigator-service-worker-unregister-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-3.2.8-navigator-service-worker-unregister.html: Added. >+ * web-platform-tests/service-workers/stub-3.2.9-navigator-service-worker-onupdatefound-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-3.2.9-navigator-service-worker-onupdatefound.html: Added. >+ * web-platform-tests/service-workers/stub-4.1-service-worker-global-scope-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.1-service-worker-global-scope.html: Added. >+ * web-platform-tests/service-workers/stub-4.1.1-service-worker-global-scope-caches-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.1.1-service-worker-global-scope-caches.html: Added. >+ * web-platform-tests/service-workers/stub-4.1.2-service-worker-global-scope-clients-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.1.2-service-worker-global-scope-clients.html: Added. >+ * web-platform-tests/service-workers/stub-4.1.3-service-worker-global-scope-scope-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.1.3-service-worker-global-scope-scope.html: Added. >+ * web-platform-tests/service-workers/stub-4.1.4-service-worker-global-scope-fetch-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.1.4-service-worker-global-scope-fetch.html: Added. >+ * web-platform-tests/service-workers/stub-4.1.5-service-worker-global-scope-update-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.1.5-service-worker-global-scope-update.html: Added. >+ * web-platform-tests/service-workers/stub-4.1.6-service-worker-global-scope-unregister-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.1.6-service-worker-global-scope-unregister.html: Added. >+ * web-platform-tests/service-workers/stub-4.1.7-service-worker-global-scope-onmessage-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.1.7-service-worker-global-scope-onmessage.html: Added. >+ * web-platform-tests/service-workers/stub-4.2-client-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.2-client.html: Added. >+ * web-platform-tests/service-workers/stub-4.3-service-worker-clients-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.3-service-worker-clients.html: Added. >+ * web-platform-tests/service-workers/stub-4.3.1-get-serviced-method-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.3.1-get-serviced-method.html: Added. >+ * web-platform-tests/service-workers/stub-4.3.2-reloadall-method-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.3.2-reloadall-method.html: Added. >+ * web-platform-tests/service-workers/stub-4.4-request-objects-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.4-request-objects.html: Added. >+ * web-platform-tests/service-workers/stub-4.5-response-objects-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.5-response-objects.html: Added. >+ * web-platform-tests/service-workers/stub-4.5.2-response-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.5.2-response.html: Added. >+ * web-platform-tests/service-workers/stub-4.5.4-opaque-response-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.5.4-opaque-response.html: Added. >+ * web-platform-tests/service-workers/stub-4.6-cache-objects-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.6-cache-objects.html: Added. >+ * web-platform-tests/service-workers/stub-4.6.1-cache-lifetimes-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.6.1-cache-lifetimes.html: Added. >+ * web-platform-tests/service-workers/stub-4.6.2-cache-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.6.2-cache.html: Added. >+ * web-platform-tests/service-workers/stub-4.6.3-cache-storage-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.6.3-cache-storage.html: Added. >+ * web-platform-tests/service-workers/stub-4.7.1-install-phase-event-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.7.1-install-phase-event.html: Added. >+ * web-platform-tests/service-workers/stub-4.7.1.1-wait-until-method-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.7.1.1-wait-until-method.html: Added. >+ * web-platform-tests/service-workers/stub-4.7.2-install-event-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.7.2-install-event.html: Added. >+ * web-platform-tests/service-workers/stub-4.7.2.1-install-event-section-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.7.2.1-install-event-section.html: Added. >+ * web-platform-tests/service-workers/stub-4.7.2.2-replace-method-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.7.2.2-replace-method.html: Added. >+ * web-platform-tests/service-workers/stub-4.7.3-activate-event-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.7.3-activate-event.html: Added. >+ * web-platform-tests/service-workers/stub-4.7.4.1-fetch-event-section-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.7.4.1-fetch-event-section.html: Added. >+ * web-platform-tests/service-workers/stub-4.7.4.2-respond-with-method-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.7.4.2-respond-with-method.html: Added. >+ * web-platform-tests/service-workers/stub-4.7.4.3-default-method-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.7.4.3-default-method.html: Added. >+ * web-platform-tests/service-workers/stub-4.7.4.4-is-reload-attribute-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-4.7.4.4-is-reload-attribute.html: Added. >+ * web-platform-tests/service-workers/stub-5.1-origin-relativity-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-5.1-origin-relativity.html: Added. >+ * web-platform-tests/service-workers/stub-5.2-cross-origin-resources-expected.txt: Added. >+ * web-platform-tests/service-workers/stub-5.2-cross-origin-resources.html: Added. >+ * web-platform-tests/service-workers/tools/blink-import.py: >+ (main): >+ * web-platform-tests/shadow-dom/Document-prototype-currentScript-expected.txt: >+ * web-platform-tests/shadow-dom/Document-prototype-currentScript.html: >+ * web-platform-tests/shadow-dom/DocumentOrShadowRoot-prototype-elementFromPoint-expected.txt: Added. >+ * web-platform-tests/shadow-dom/DocumentOrShadowRoot-prototype-elementFromPoint.html: Added. >+ * web-platform-tests/shadow-dom/Element-interface-attachShadow-custom-element-expected.txt: Added. >+ * web-platform-tests/shadow-dom/Element-interface-attachShadow-custom-element.html: Added. >+ * web-platform-tests/shadow-dom/Extensions-to-Event-Interface-expected.txt: >+ * web-platform-tests/shadow-dom/Extensions-to-Event-Interface.html: >+ * web-platform-tests/shadow-dom/event-composed-path-after-dom-mutation-expected.txt: Added. >+ * web-platform-tests/shadow-dom/event-composed-path-after-dom-mutation.html: Added. >+ * web-platform-tests/shadow-dom/form-control-form-attribute-expected.txt: Added. >+ * web-platform-tests/shadow-dom/form-control-form-attribute.html: Added. >+ * web-platform-tests/shadow-dom/input-element-list-expected.txt: Added. >+ * web-platform-tests/shadow-dom/input-element-list.html: Added. >+ * web-platform-tests/shadow-dom/layout-slot-no-longer-assigned-expected.html: Added. >+ * web-platform-tests/shadow-dom/layout-slot-no-longer-assigned.html: Added. >+ * web-platform-tests/shadow-dom/layout-slot-no-longer-fallback-expected.html: Added. >+ * web-platform-tests/shadow-dom/layout-slot-no-longer-fallback.html: Added. >+ * web-platform-tests/shadow-dom/resources/event-path-test-helpers.js: >+ (dispatchEventWithEventLog): >+ * web-platform-tests/shadow-dom/slotchange-event-expected.txt: >+ * web-platform-tests/shadow-dom/w3c-import.log: >+ * web-platform-tests/streams/generate-test-wrappers.js: >+ * web-platform-tests/streams/piping/general-expected.txt: >+ * web-platform-tests/streams/readable-byte-streams/construct-byob-request-expected.txt: Added. >+ * web-platform-tests/streams/readable-byte-streams/construct-byob-request.dedicatedworker-expected.txt: Added. >+ * web-platform-tests/streams/readable-byte-streams/construct-byob-request.dedicatedworker.html: Added. >+ * web-platform-tests/streams/readable-byte-streams/construct-byob-request.html: Added. >+ * web-platform-tests/streams/readable-byte-streams/construct-byob-request.js: Added. >+ (getRealByteStreamController): >+ (createDummyObject): >+ (runTests): >+ * web-platform-tests/streams/readable-byte-streams/construct-byob-request.serviceworker.https-expected.txt: Added. >+ * web-platform-tests/streams/readable-byte-streams/construct-byob-request.serviceworker.https.html: Added. >+ * web-platform-tests/streams/readable-byte-streams/construct-byob-request.sharedworker-expected.txt: Added. >+ * web-platform-tests/streams/readable-byte-streams/construct-byob-request.sharedworker.html: Added. >+ * web-platform-tests/streams/readable-byte-streams/constructor-expected.txt: Added. >+ * web-platform-tests/streams/readable-byte-streams/constructor.dedicatedworker-expected.txt: Added. >+ * web-platform-tests/streams/readable-byte-streams/constructor.dedicatedworker.html: Added. >+ * web-platform-tests/streams/readable-byte-streams/constructor.html: Added. >+ * web-platform-tests/streams/readable-byte-streams/constructor.js: Added. >+ (const.failureOp.of.operations.test): >+ * web-platform-tests/streams/readable-byte-streams/constructor.serviceworker.https-expected.txt: Added. >+ * web-platform-tests/streams/readable-byte-streams/constructor.serviceworker.https.html: Added. >+ * web-platform-tests/streams/readable-byte-streams/constructor.sharedworker-expected.txt: Added. >+ * web-platform-tests/streams/readable-byte-streams/constructor.sharedworker.html: Added. >+ * web-platform-tests/streams/readable-byte-streams/w3c-import.log: >+ * web-platform-tests/streams/readable-streams/constructor-expected.txt: Added. >+ * web-platform-tests/streams/readable-streams/constructor.dedicatedworker-expected.txt: Added. >+ * web-platform-tests/streams/readable-streams/constructor.dedicatedworker.html: Added. >+ * web-platform-tests/streams/readable-streams/constructor.html: Added. >+ * web-platform-tests/streams/readable-streams/constructor.js: Added. >+ (const.failureOp.of.operations.test): >+ * web-platform-tests/streams/readable-streams/constructor.serviceworker.https-expected.txt: Added. >+ * web-platform-tests/streams/readable-streams/constructor.serviceworker.https.html: Added. >+ * web-platform-tests/streams/readable-streams/constructor.sharedworker-expected.txt: Added. >+ * web-platform-tests/streams/readable-streams/constructor.sharedworker.html: Added. >+ * web-platform-tests/streams/readable-streams/patched-global-expected.txt: Added. >+ * web-platform-tests/streams/readable-streams/patched-global.dedicatedworker-expected.txt: Added. >+ * web-platform-tests/streams/readable-streams/patched-global.dedicatedworker.html: Added. >+ * web-platform-tests/streams/readable-streams/patched-global.html: Added. >+ * web-platform-tests/streams/readable-streams/patched-global.js: Added. >+ (isReadableStream): >+ (test.t.const.property.of.trappedProperties.get throw): >+ * web-platform-tests/streams/readable-streams/patched-global.serviceworker.https-expected.txt: Added. >+ * web-platform-tests/streams/readable-streams/patched-global.serviceworker.https.html: Added. >+ * web-platform-tests/streams/readable-streams/patched-global.sharedworker-expected.txt: Added. >+ * web-platform-tests/streams/readable-streams/patched-global.sharedworker.html: Added. >+ * web-platform-tests/streams/readable-streams/reentrant-strategies-expected.txt: Added. >+ * web-platform-tests/streams/readable-streams/reentrant-strategies.dedicatedworker-expected.txt: Added. >+ * web-platform-tests/streams/readable-streams/reentrant-strategies.dedicatedworker.html: Added. >+ * web-platform-tests/streams/readable-streams/reentrant-strategies.html: Added. >+ * web-platform-tests/streams/readable-streams/reentrant-strategies.js: Added. >+ (promise_test): >+ (promise_test.t.const.rs.new.ReadableStream.start): >+ (promise_test.t.size): >+ (promise_test.t.controller.enqueue): >+ * web-platform-tests/streams/readable-streams/reentrant-strategies.serviceworker.https-expected.txt: Added. >+ * web-platform-tests/streams/readable-streams/reentrant-strategies.serviceworker.https.html: Added. >+ * web-platform-tests/streams/readable-streams/reentrant-strategies.sharedworker-expected.txt: Added. >+ * web-platform-tests/streams/readable-streams/reentrant-strategies.sharedworker.html: Added. >+ * web-platform-tests/streams/readable-streams/w3c-import.log: >+ * web-platform-tests/streams/resources/constructor-ordering.js: Added. >+ (Op): >+ (Op.prototype.toString): >+ (Op.prototype.equals): >+ (op): >+ (OpRecorder): >+ (OpRecorder.prototype.recordAndCheck): >+ (OpRecorder.prototype.check): >+ (OpRecorder.prototype.actual): >+ (createRecordingObjectWithProperties): >+ (defineCheckedProperty): >+ (createRecordingNumberObject): >+ (expectedAsString): >+ * web-platform-tests/streams/resources/w3c-import.log: >+ * web-platform-tests/streams/transform-streams/backpressure-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/backpressure.dedicatedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/backpressure.dedicatedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/backpressure.html: Added. >+ * web-platform-tests/streams/transform-streams/backpressure.js: Added. >+ (promise_test): >+ (promise_test.t.return.delay.0.then): >+ (promise_test.t.const.rs.new.ReadableStream.start): >+ * web-platform-tests/streams/transform-streams/backpressure.serviceworker.https-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/backpressure.serviceworker.https.html: Added. >+ * web-platform-tests/streams/transform-streams/backpressure.sharedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/backpressure.sharedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/brand-checks-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/brand-checks.dedicatedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/brand-checks.dedicatedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/brand-checks.html: Added. >+ * web-platform-tests/streams/transform-streams/brand-checks.js: Added. >+ (getTransformStreamDefaultControllerConstructor): >+ (fakeTS): >+ (get realTS): >+ (fakeTSDefaultController): >+ (get realTSDefaultController): >+ (test): >+ * web-platform-tests/streams/transform-streams/brand-checks.serviceworker.https-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/brand-checks.serviceworker.https.html: Added. >+ * web-platform-tests/streams/transform-streams/brand-checks.sharedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/brand-checks.sharedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/constructor-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/constructor.dedicatedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/constructor.dedicatedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/constructor.html: Added. >+ * web-platform-tests/streams/transform-streams/constructor.js: Added. >+ (const.failureOp.of.operations.test): >+ * web-platform-tests/streams/transform-streams/constructor.serviceworker.https-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/constructor.serviceworker.https.html: Added. >+ * web-platform-tests/streams/transform-streams/constructor.sharedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/constructor.sharedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/errors-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/errors.dedicatedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/errors.dedicatedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/errors.html: Added. >+ * web-platform-tests/streams/transform-streams/errors.js: Added. >+ (promise_test.t.const.ts.new.TransformStream.transform): >+ (promise_test.t.const.ts.new.TransformStream.flush): >+ (test): >+ (promise_test.t.const.ts.new.TransformStream.start): >+ (promise_test.t.return.delay.0.then): >+ (promise_test.t.return.ts.writable.abort.thrownError.then): >+ (promise_test.t.string_appeared_here.then): >+ * web-platform-tests/streams/transform-streams/errors.serviceworker.https-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/errors.serviceworker.https.html: Added. >+ * web-platform-tests/streams/transform-streams/errors.sharedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/errors.sharedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/flush-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/flush.dedicatedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/flush.dedicatedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/flush.html: Added. >+ * web-platform-tests/streams/transform-streams/flush.js: Added. >+ (promise_test): >+ (promise_test.t.const.ts.new.TransformStream.flush): >+ * web-platform-tests/streams/transform-streams/flush.serviceworker.https-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/flush.serviceworker.https.html: Added. >+ * web-platform-tests/streams/transform-streams/flush.sharedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/flush.sharedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/general-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/general.dedicatedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/general.dedicatedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/general.html: Added. >+ * web-platform-tests/streams/transform-streams/general.js: Added. >+ (test): >+ (promise_test): >+ (promise_test.t.const.ts.new.TransformStream.start): >+ (promise_test.t.const.ts.new.TransformStream.transform): >+ (promise_test.t.const.ts.new.TransformStream.flush): >+ (promise_test.t.return.writer.close.then): >+ * web-platform-tests/streams/transform-streams/general.serviceworker.https-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/general.serviceworker.https.html: Added. >+ * web-platform-tests/streams/transform-streams/general.sharedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/general.sharedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/lipfuzz-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/lipfuzz.dedicatedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/lipfuzz.dedicatedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/lipfuzz.html: Added. >+ * web-platform-tests/streams/transform-streams/lipfuzz.js: Added. >+ (LipFuzzTransformer): >+ (LipFuzzTransformer.prototype.transform): >+ (LipFuzzTransformer.prototype.promise_test): >+ * web-platform-tests/streams/transform-streams/lipfuzz.serviceworker.https-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/lipfuzz.serviceworker.https.html: Added. >+ * web-platform-tests/streams/transform-streams/lipfuzz.sharedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/lipfuzz.sharedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/patched-global-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/patched-global.dedicatedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/patched-global.dedicatedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/patched-global.html: Added. >+ * web-platform-tests/streams/transform-streams/patched-global.js: Added. >+ (test.t.ReadableStream): >+ (test.t.WritableStream): >+ * web-platform-tests/streams/transform-streams/patched-global.serviceworker.https-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/patched-global.serviceworker.https.html: Added. >+ * web-platform-tests/streams/transform-streams/patched-global.sharedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/patched-global.sharedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/properties-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/properties.dedicatedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/properties.dedicatedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/properties.html: Added. >+ * web-platform-tests/streams/transform-streams/properties.js: Added. >+ (IsConstructor): >+ (test): >+ (self.TransformStreamDefaultController): >+ (const.c.in.expected.const.name.in.properties.test): >+ (const.c.in.expected.const.name.in.properties.assert_false): >+ (const.c.in.expected.const.name.in.properties.switch.case.string_appeared_here.case.string_appeared_here.test): >+ (const.c.in.expected.const.name.in.properties.switch.set get break): >+ (const.c.in.expected.const.name.in.properties.switch): >+ * web-platform-tests/streams/transform-streams/properties.serviceworker.https-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/properties.serviceworker.https.html: Added. >+ * web-platform-tests/streams/transform-streams/properties.sharedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/properties.sharedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/reentrant-strategies-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/reentrant-strategies.dedicatedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/reentrant-strategies.dedicatedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/reentrant-strategies.html: Added. >+ * web-platform-tests/streams/transform-streams/reentrant-strategies.js: Added. >+ (promise_test): >+ (promise_test.t.const.ts.new.TransformStream.start): >+ (promise_test.t.size): >+ (promise_test.t.return.writer.write.string_appeared_here.then): >+ (promise_test.t.return.delay.0.then): >+ * web-platform-tests/streams/transform-streams/reentrant-strategies.serviceworker.https-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/reentrant-strategies.serviceworker.https.html: Added. >+ * web-platform-tests/streams/transform-streams/reentrant-strategies.sharedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/reentrant-strategies.sharedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/strategies-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/strategies.dedicatedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/strategies.dedicatedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/strategies.html: Added. >+ * web-platform-tests/streams/transform-streams/strategies.js: Added. >+ (test): >+ (promise_test): >+ (promise_test.t.const.ts.new.TransformStream.transform): >+ (promise_test.t.size): >+ (promise_test.t.return.ts.writable.getWriter.write.then): >+ (const.objectThatConvertsTo42.toString): >+ (promise_test.t.return.writer.write.then): >+ * web-platform-tests/streams/transform-streams/strategies.serviceworker.https-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/strategies.serviceworker.https.html: Added. >+ * web-platform-tests/streams/transform-streams/strategies.sharedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/strategies.sharedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/terminate-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/terminate.dedicatedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/terminate.dedicatedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/terminate.html: Added. >+ * web-platform-tests/streams/transform-streams/terminate.js: Added. >+ (promise_test.t.const.rs.new.ReadableStream.start): >+ (promise_test.t.string_appeared_here.then): >+ (promise_test.t.return.delay.0.then): >+ (promise_test.t.then): >+ (test): >+ (promise_test.t.const.ts.new.TransformStream.start): >+ (promise_test): >+ * web-platform-tests/streams/transform-streams/terminate.serviceworker.https-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/terminate.serviceworker.https.html: Added. >+ * web-platform-tests/streams/transform-streams/terminate.sharedworker-expected.txt: Added. >+ * web-platform-tests/streams/transform-streams/terminate.sharedworker.html: Added. >+ * web-platform-tests/streams/transform-streams/w3c-import.log: Added. >+ * web-platform-tests/touch-events/create-touch-touchlist-expected.txt: Removed. >+ * web-platform-tests/touch-events/create-touch-touchlist.html: Removed. >+ * web-platform-tests/touch-events/historical.html: >+ * web-platform-tests/touch-events/w3c-import.log: >+ * web-platform-tests/update-built-tests.sh: >+ * web-platform-tests/url/README.md: >+ * web-platform-tests/url/a-element-expected.txt: >+ * web-platform-tests/url/a-element-origin-xhtml.xhtml: >+ * web-platform-tests/url/a-element-origin.html: >+ * web-platform-tests/url/a-element-origin.js: Removed. >+ * web-platform-tests/url/a-element-xhtml-expected.txt: >+ * web-platform-tests/url/a-element-xhtml.xhtml: >+ * web-platform-tests/url/a-element.html: >+ * web-platform-tests/url/a-element.js: Removed. >+ * web-platform-tests/url/data-uri-fragment-expected.txt: Added. >+ * web-platform-tests/url/data-uri-fragment.html: Added. >+ * web-platform-tests/url/failure.html: >+ * web-platform-tests/url/resources/a-element-origin.js: Added. >+ * web-platform-tests/url/resources/a-element.js: Added. >+ * web-platform-tests/url/resources/setters_tests.json: Added. >+ * web-platform-tests/url/resources/toascii.json: Renamed from LayoutTests/imported/w3c/web-platform-tests/url/toascii.json. >+ * web-platform-tests/url/resources/urltestdata.json: Added. >+ * web-platform-tests/url/resources/w3c-import.log: Added. >+ * web-platform-tests/url/setters_tests.json: Removed. >+ * web-platform-tests/url/toascii.window.js: >+ (async_test.t.string_appeared_here.request.send.request.responseType.string_appeared_here.request.onload.t.step_func_done): Deleted. >+ (string_appeared_here.makeURL): Deleted. >+ * web-platform-tests/url/url-constructor-expected.txt: >+ * web-platform-tests/url/url-constructor.html: >+ * web-platform-tests/url/url-origin.html: >+ * web-platform-tests/url/url-setters-expected.txt: >+ * web-platform-tests/url/url-setters.html: >+ * web-platform-tests/url/urlsearchparams-foreach-expected.txt: >+ * web-platform-tests/url/urlsearchparams-foreach.html: >+ * web-platform-tests/url/urltestdata.json: Removed. >+ * web-platform-tests/url/w3c-import.log: >+ * web-platform-tests/user-timing/clearMarks-expected.txt: Added. >+ * web-platform-tests/user-timing/clearMarks.html: Added. >+ * web-platform-tests/user-timing/clearMeasures-expected.txt: Added. >+ * web-platform-tests/user-timing/clearMeasures.html: Added. >+ * web-platform-tests/user-timing/mark-expected.txt: Added. >+ * web-platform-tests/user-timing/mark.html: Added. >+ * web-platform-tests/user-timing/mark_exceptions-expected.txt: >+ * web-platform-tests/user-timing/mark_exceptions.html: >+ * web-platform-tests/user-timing/measure_associated_with_navigation_timing-expected.txt: Added. >+ * web-platform-tests/user-timing/measure_associated_with_navigation_timing.html: Added. >+ * web-platform-tests/user-timing/measure_exception-expected.txt: Added. >+ * web-platform-tests/user-timing/measure_exception.html: Added. >+ * web-platform-tests/user-timing/measures-expected.txt: Added. >+ * web-platform-tests/user-timing/measures.html: Added. >+ * web-platform-tests/user-timing/resources/webperftestharnessextension.js: >+ (performance_entrylist_checker.entry_check): >+ (performance_entrylist_checker.entrylist_order_check): >+ (performance_entrylist_checker.entrylist_check): >+ (performance_entrylist_checker): >+ * web-platform-tests/user-timing/user-timing-tojson-expected.txt: Added. >+ * web-platform-tests/user-timing/user-timing-tojson.html: Added. >+ * web-platform-tests/user-timing/w3c-import.log: >+ * web-platform-tests/visual-viewport/OWNERS: Added. >+ * web-platform-tests/w3c-import.log: >+ * web-platform-tests/webaudio/js/helpers.js: >+ (trimEmptyElements): >+ * web-platform-tests/webaudio/resources/audio-param.js: Added. >+ (audioParamLinearRamp): >+ (audioParamExponentialRamp): >+ (audioParamSetTarget): >+ (audioParamSetValueCurve): >+ * web-platform-tests/webaudio/resources/audionodeoptions.js: Added. >+ (testAudioNodeOptions): >+ (initializeContext): >+ (testInvalidConstructor): >+ (testDefaultConstructor): >+ (testDefaultAttributes): >+ * web-platform-tests/webaudio/resources/biquad-testing.js: Added. >+ (createImpulseBuffer): >+ (createTestAndRun): >+ (generateReference): >+ (checkFilterResponse): >+ * web-platform-tests/webaudio/resources/mix-testing.js: Added. >+ (createToneBuffer): >+ * web-platform-tests/webaudio/resources/mixing-rules.js: Added. >+ (createShiftedImpulseBuffer): >+ (stringifyBuffer): >+ (computeNumberOfChannels): >+ (speakersSum): >+ (discreteSum): >+ (processUpMix): >+ (processDownMix): >+ * web-platform-tests/webaudio/resources/w3c-import.log: >+ * web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-basic-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-basic.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-sizing-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-sizing.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/w3c-import.log: >+ * web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-getChannelData-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-getChannelData.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/ctor-audiobuffer-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/ctor-audiobuffer.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/idl-test-expected.txt: >+ * web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/w3c-import.log: >+ * web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/w3c-import.log: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-getoutputtimestamp-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-getoutputtimestamp.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-suspend-resume-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-suspend-resume.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/w3c-import.log: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audiodestinationnode-interface/idl-test-expected.txt: >+ * web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-channel-rules-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-channel-rules.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-order-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-order.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audionode-interface/channel-mode-interp-basic-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audionode-interface/channel-mode-interp-basic.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audionode-interface/w3c-import.log: >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-connect-audioratesignal-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-connect-audioratesignal.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exceptional-values-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exceptional-values.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exponentialRampToValueAtTime-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exponentialRampToValueAtTime.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-large-endtime-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-large-endtime.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-linearRampToValueAtTime-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-linearRampToValueAtTime.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-method-chaining-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-method-chaining.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setTargetAtTime-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setTargetAtTime.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueAtTime-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueAtTime.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurveAtTime-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurveAtTime.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-summingjunction-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-summingjunction.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate-testing.js: Added. >+ (doTest): >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-audioworklet.https-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-audioworklet.https.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-biquad-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-biquad.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-constant-source-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-constant-source.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-delay-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-delay.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-gain-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-gain.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-oscillator-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-oscillator.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-panner-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-panner.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-stereo-panner-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-stereo-panner.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/w3c-import.log: >+ * web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-automatic-pull.https-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-automatic-pull.https.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/w3c-import.log: >+ * web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/zero-output-processor.js: Added. >+ (ZeroOuttputProcessor): >+ (ZeroOuttputProcessor.prototype.process): >+ * web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/w3c-import.log: >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-allpass-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-allpass.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-bandpass-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-bandpass.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-basic-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-basic.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-getFrequencyResponse-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-getFrequencyResponse.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highpass-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highpass.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highshelf-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highshelf.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowpass-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowpass.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowshelf-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowshelf.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-notch-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-notch.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-peaking-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-peaking.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-tail-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-tail.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquadfilternode-basic-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquadfilternode-basic.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/ctor-biquadfilter-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/ctor-biquadfilter.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/no-dezippering-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/no-dezippering.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/w3c-import.log: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/ctor-channelmerger-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/ctor-channelmerger.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/w3c-import.log: >+ * web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/ctor-channelsplitter-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/ctor-channelsplitter.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/w3c-import.log: >+ * web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/ctor-constantsource-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/ctor-constantsource.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/w3c-import.log: >+ * web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/ctor-convolver-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/ctor-convolver.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/w3c-import.log: >+ * web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/ctor-delay-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/ctor-delay.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/idl-test-expected.txt: Removed. >+ * web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/idl-test.html: Removed. >+ * web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/w3c-import.log: >+ * web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/ctor-dynamicscompressor-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/ctor-dynamicscompressor.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/w3c-import.log: >+ * web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/ctor-gain-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/ctor-gain.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/idl-test-expected.txt: Removed. >+ * web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/idl-test.html: Removed. >+ * web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/w3c-import.log: >+ * web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/ctor-iirfilter-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/ctor-iirfilter.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/w3c-import.log: >+ * web-platform-tests/webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest-expected.txt: >+ * web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/ctor-offlineaudiocontext-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/ctor-offlineaudiocontext.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/w3c-import.log: >+ * web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/ctor-oscillator-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/ctor-oscillator.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/w3c-import.log: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/w3c-import.log: >+ * web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/ctor-stereopanner-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/ctor-stereopanner.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/w3c-import.log: >+ * web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/ctor-waveshaper-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/ctor-waveshaper.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/silent-inputs-expected.txt: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/silent-inputs.html: Added. >+ * web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/w3c-import.log: >+ * web-platform-tests/webrtc/RTCDTMFSender-insertDTMF.https.html: >+ * web-platform-tests/webrtc/RTCDTMFSender-ontonechange.https-expected.txt: >+ * web-platform-tests/webrtc/RTCDTMFSender-ontonechange.https.html: >+ * web-platform-tests/webrtc/RTCIceTransport.html: >+ * web-platform-tests/webrtc/RTCPeerConnection-add-track-no-deadlock.https-expected.txt: Added. >+ * web-platform-tests/webrtc/RTCPeerConnection-add-track-no-deadlock.https.html: Added. >+ * web-platform-tests/webrtc/RTCPeerConnection-canTrickleIceCandidates.html: >+ * web-platform-tests/webrtc/RTCPeerConnection-createOffer-offerToReceive-expected.txt: Added. >+ * web-platform-tests/webrtc/RTCPeerConnection-getIdentityAssertion.html: Removed. >+ * web-platform-tests/webrtc/RTCPeerConnection-getIdentityAssertion.sub-expected.txt: Added. >+ * web-platform-tests/webrtc/RTCPeerConnection-getIdentityAssertion.sub.html: Added. >+ * web-platform-tests/webrtc/RTCPeerConnection-getStats.https.html: >+ * web-platform-tests/webrtc/RTCPeerConnection-helper.js: >+ * web-platform-tests/webrtc/RTCPeerConnection-peerIdentity.html: >+ * web-platform-tests/webrtc/RTCPeerConnection-setDescription-transceiver-expected.txt: >+ * web-platform-tests/webrtc/RTCPeerConnection-setDescription-transceiver.html: >+ * web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-expected.txt: >+ * web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-replaceTrack.https-expected.txt: Added. >+ * web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-replaceTrack.https.html: Added. >+ * web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https-expected.txt: Added. >+ * web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html: Added. >+ * web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription.html: >+ * web-platform-tests/webrtc/RTCPeerConnection-track-stats.https-expected.txt: Added. >+ * web-platform-tests/webrtc/RTCPeerConnection-track-stats.https.html: Added. >+ * web-platform-tests/webrtc/RTCPeerConnewarning: inexact rename detection was skipped due to too many files.: Added. >+ * web-platform-tests/webrtc/RTCRtpReceiver-getContributingSources.https.html: >+ * web-platform-tests/webrtc/RTCRtpReceiver-getStats.https.html: >+ * web-platform-tests/webrtc/RTCRtpReceiver-getSynchronizationSources.https.html: >+ * web-platform-tests/webrtc/RTCRtpSender-getStats.https.html: >+ * web-platform-tests/webrtc/RTCSctpTransport-maxMessageSize-expected.txt: Added. >+ * web-platform-tests/webrtc/RTCSctpTransport-maxMessageSize.html: Added. >+ * web-platform-tests/webrtc/identity-helper.js: Removed. >+ * web-platform-tests/webrtc/identity-helper.sub.js: Added. >+ (getIdpDomains): >+ * web-platform-tests/webrtc/protocol/README.txt: Added. >+ * web-platform-tests/webrtc/protocol/video-codecs.https-expected.txt: Added. >+ * web-platform-tests/webrtc/protocol/video-codecs.https.html: Added. >+ * web-platform-tests/webrtc/protocol/w3c-import.log: Added. >+ * web-platform-tests/webrtc/tools/README.md: Added. >+ * web-platform-tests/webrtc/tools/package-lock.json: Added. >+ * web-platform-tests/webrtc/tools/package.json: Added. >+ * web-platform-tests/webrtc/tools/w3c-import.log: Added. >+ * web-platform-tests/webrtc/w3c-import.log: >+ * web-platform-tests/webxr/OWNERS: Added. >+ * web-platform-tests/webxr/interfaces.https-expected.txt: Added. >+ * web-platform-tests/webxr/interfaces.https.html: Added. >+ * web-platform-tests/webxr/resources/w3c-import.log: Added. >+ * web-platform-tests/webxr/resources/webxr_check.html: Added. >+ * web-platform-tests/webxr/resources/webxr_util.js: Added. >+ (forEachWebxrObject): >+ * web-platform-tests/webxr/w3c-import.log: Added. >+ * web-platform-tests/webxr/webxr_availability.http.sub-expected.txt: Added. >+ * web-platform-tests/webxr/webxr_availability.http.sub.html: Added. >+ * web-platform-tests/workers/SharedWorkerPerformanceNow-expected.txt: Added. >+ * web-platform-tests/workers/SharedWorkerPerformanceNow.html: Added. >+ * web-platform-tests/workers/SharedWorker_dataUrl-expected.txt: Added. >+ * web-platform-tests/workers/SharedWorker_dataUrl.html: Added. >+ * web-platform-tests/workers/WorkerGlobalScope_requestAnimationFrame-expected.txt: Added. >+ * web-platform-tests/workers/WorkerGlobalScope_requestAnimationFrame.htm: Added. >+ * web-platform-tests/workers/WorkerPerformanceNow-expected.txt: Added. >+ * web-platform-tests/workers/WorkerPerformanceNow.html: Added. >+ * web-platform-tests/workers/interfaces/WorkerUtils/WindowTimers/005-expected.txt: Added. >+ * web-platform-tests/workers/interfaces/WorkerUtils/WindowTimers/005.html: Added. >+ * web-platform-tests/workers/interfaces/WorkerUtils/WindowTimers/w3c-import.log: >+ * web-platform-tests/workers/interfaces/WorkerUtils/importScripts/1.headers: Added. >+ * web-platform-tests/workers/interfaces/WorkerUtils/importScripts/null.headers: Added. >+ * web-platform-tests/workers/interfaces/WorkerUtils/importScripts/undefined.headers: Added. >+ * web-platform-tests/workers/interfaces/WorkerUtils/importScripts/w3c-import.log: >+ * web-platform-tests/workers/modules/dedicated-worker-import-csp-expected.txt: Added. >+ * web-platform-tests/workers/modules/dedicated-worker-import-csp.html: Added. >+ * web-platform-tests/workers/modules/dedicated-worker-import-expected.txt: Added. >+ * web-platform-tests/workers/modules/dedicated-worker-import-failure-expected.txt: Added. >+ * web-platform-tests/workers/modules/dedicated-worker-import-failure.html: Added. >+ * web-platform-tests/workers/modules/dedicated-worker-import-meta-expected.txt: Added. >+ * web-platform-tests/workers/modules/dedicated-worker-import-meta.html: Added. >+ * web-platform-tests/workers/modules/dedicated-worker-import-referrer-expected.txt: Added. >+ * web-platform-tests/workers/modules/dedicated-worker-import-referrer.html: Added. >+ * web-platform-tests/workers/modules/dedicated-worker-import.html: Added. >+ * web-platform-tests/workers/modules/dedicated-worker-options-credentials-expected.txt: Added. >+ * web-platform-tests/workers/modules/dedicated-worker-options-credentials.html: Added. >+ * web-platform-tests/workers/modules/dedicated-worker-options-credentials.html.headers: Added. >+ * web-platform-tests/workers/modules/dedicated-worker-options-type-expected.txt: Added. >+ * web-platform-tests/workers/modules/dedicated-worker-options-type.html: Added. >+ * web-platform-tests/workers/modules/resources/credentials.py: Added. >+ (main): >+ * web-platform-tests/workers/modules/resources/dynamic-import-and-then-static-import-worker.js: Added. >+ * web-platform-tests/workers/modules/resources/dynamic-import-given-url-worker.js: Added. >+ * web-platform-tests/workers/modules/resources/dynamic-import-remote-origin-referrer-checker-worker.sub.js: Added. >+ * web-platform-tests/workers/modules/resources/dynamic-import-remote-origin-script-worker.sub.js: Added. >+ * web-platform-tests/workers/modules/resources/dynamic-import-same-origin-referrer-checker-worker.js: Added. >+ * web-platform-tests/workers/modules/resources/dynamic-import-worker.js: Added. >+ * web-platform-tests/workers/modules/resources/empty-worker.js: Added. >+ * web-platform-tests/workers/modules/resources/eval-dynamic-import-worker.js: Added. >+ * web-platform-tests/workers/modules/resources/export-on-dynamic-import-script.js: Added. >+ * web-platform-tests/workers/modules/resources/export-on-load-script.js: Added. >+ * web-platform-tests/workers/modules/resources/export-on-load-script.js.headers: Added. >+ * web-platform-tests/workers/modules/resources/export-on-static-import-script.js: Added. >+ * web-platform-tests/workers/modules/resources/import-meta-url-worker.js: Added. >+ * web-platform-tests/workers/modules/resources/import-scripts-worker.js: Added. >+ (catch): >+ * web-platform-tests/workers/modules/resources/nested-dynamic-import-worker.js: Added. >+ * web-platform-tests/workers/modules/resources/nested-static-import-worker.js: Added. >+ * web-platform-tests/workers/modules/resources/new-worker-window.html: Added. >+ * web-platform-tests/workers/modules/resources/post-message-on-load-worker.js: Added. >+ * web-platform-tests/workers/modules/resources/referrer-checker.py: Added. >+ (main): >+ * web-platform-tests/workers/modules/resources/static-import-and-then-dynamic-import-worker.js: Added. >+ * web-platform-tests/workers/modules/resources/static-import-non-existent-script-worker.js: Added. >+ * web-platform-tests/workers/modules/resources/static-import-remote-origin-referrer-checker-worker.sub.js: Added. >+ * web-platform-tests/workers/modules/resources/static-import-remote-origin-script-worker.sub.js: Added. >+ * web-platform-tests/workers/modules/resources/static-import-same-origin-referrer-checker-worker.js: Added. >+ * web-platform-tests/workers/modules/resources/static-import-worker.js: Added. >+ * web-platform-tests/workers/modules/resources/w3c-import.log: Added. >+ * web-platform-tests/workers/modules/w3c-import.log: Added. >+ * web-platform-tests/workers/name-property.html: >+ * web-platform-tests/workers/nested_worker.worker.js: >+ (async_test): >+ * web-platform-tests/workers/opaque-origin.html: >+ * web-platform-tests/workers/semantics/multiple-workers/003.html: >+ * web-platform-tests/workers/semantics/multiple-workers/005.html: >+ * web-platform-tests/workers/semantics/multiple-workers/006.html: >+ * web-platform-tests/workers/semantics/multiple-workers/007.html: >+ * web-platform-tests/workers/semantics/multiple-workers/008.html: >+ * web-platform-tests/workers/support/WorkerSendingPerformanceNow.js: Added. >+ (calcResponse): >+ (self.onmessage): >+ (port.onmessage): >+ * web-platform-tests/workers/support/iframe_sw_dataUrl.html: Added. >+ * web-platform-tests/workers/support/w3c-import.log: >+ * web-platform-tests/workers/w3c-import.log: >+ * web-platform-tests/xhr/resources/inspect-headers.py: >+ (get_response): >+ > 2018-06-06 Youenn Fablet <youenn@apple.com> > > HTTP Header values validation is too strict >diff --git a/LayoutTests/TestExpectations b/LayoutTests/TestExpectations >index 49d2ae1b4c9eb8bf1c2686c751270600ffc33a90..c0c768c68aa332e7ae1e378a30433301f679cbf1 100644 >--- a/LayoutTests/TestExpectations >+++ b/LayoutTests/TestExpectations >@@ -213,8 +213,6 @@ imported/w3c/web-platform-tests/fetch/api/redirect/redirect-mode-worker.html [ D > imported/w3c/web-platform-tests/fetch/api/redirect/redirect-to-dataurl.html [ DumpJSConsoleLogInStdErr ] > > webkit.org/b/181901 imported/w3c/web-platform-tests/service-workers/service-worker/fetch-cors-xhr.https.html [ DumpJSConsoleLogInStdErr ] >-webkit.org/b/181897 imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting.https.html [ DumpJSConsoleLogInStdErr ] >-webkit.org/b/181900 imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-cache.https.html [ DumpJSConsoleLogInStdErr ] > imported/w3c/web-platform-tests/service-workers/service-worker/fetch-response-taint.https.html [ DumpJSConsoleLogInStdErr ] > imported/w3c/web-platform-tests/service-workers/service-worker/register-closed-window.https.html [ DumpJSConsoleLogInStdErr ] > imported/w3c/web-platform-tests/service-workers/service-worker/registration-security-error.https.html [ DumpJSConsoleLogInStdErr ] >@@ -2012,3 +2010,15 @@ webkit.org/b/184800 http/tests/workers/worker-importScripts-banned-mimetype.html > webkit.org/b/184802 http/tests/security/contentTypeOptions/nosniff-importScript-blocked.html [ Pass Timeout ] > > webkit.org/b/181100 inspector/worker/worker-recover-if-inspector-close.html [ Pass Failure ] >+ >+imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_eventually.html [ Skip ] >+imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video.https.html [ Skip ] >+imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-with-range-request.https.html [ Skip ] >+imported/w3c/web-platform-tests/service-workers/service-worker/svg-target-reftest.https.html [ ImageOnlyFailure ] >+imported/w3c/web-platform-tests/service-workers/service-worker/embed-and-object-are-not-intercepted.https.html [ Skip ] >+imported/w3c/web-platform-tests/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https.html [ Failure ] >+imported/w3c/web-platform-tests/resource-timing/resource_initiator_types.html [ Failure Pass ] >+imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-cache.https.html [ Timeout Pass Failure ] >+imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html [ Failure Pass ] >+imported/w3c/web-platform-tests/service-workers/service-worker/worker-client-id.https.html [ Failure Pass ] >+imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image-cache.https.html [ Failure Pass ] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/PaymentAddress/attributes-and-toJSON-method-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/PaymentAddress/attributes-and-toJSON-method-manual.https.html >index 3925cdd81e6aed5d19c520c68bac17466c437976..0b3f9535ed89797d5b0183a9e195e8f836b50e0b 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/PaymentAddress/attributes-and-toJSON-method-manual.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/PaymentAddress/attributes-and-toJSON-method-manual.https.html >@@ -68,7 +68,7 @@ function runManualTest(button, expected = {}) { > <button onclick=" > const expectedAddress = { > country: 'AU', >- regionCode: 'AU-QLD', >+ regionCode: 'QLD', > addressLine: '55 test st', > city: 'Chapel Hill', > dependentLocality: '', >@@ -90,8 +90,10 @@ function runManualTest(button, expected = {}) { > <dd>55 test st</dd> > <dt>Country</dt> > <dd>Australia</dd> >- <dt>Suburb</dt> >+ <dt>City</dt> > <dd>Chapel Hill</dd> >+ <dd>State/Region</dd> >+ <dd>Queensland</dd> > <dt>postal code </dt> > <dd>6095</dd> > <dt>organization</dt> >@@ -102,6 +104,6 @@ function runManualTest(button, expected = {}) { > </li> > </ol> > <small> >- If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a> >- and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>. >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. > </small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/PaymentItem/type_member.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/PaymentItem/type_member.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..e6b02017170325ef29703ae2427db5bcdc00925b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/PaymentItem/type_member.https-expected.txt >@@ -0,0 +1,10 @@ >+ >+PASS Smoke test >+FAIL An invalid enum value for PaymentDetailsInit.total's type throws TypeError assert_throws: function "() => { >+ new PaymentRequest(validMethods, invalidDetails); >+ }" did not throw >+FAIL Invalid enum value for PaymentItem.type member throws a TypeError assert_throws: function "() => { >+ new PaymentRequest(validMethods, invalidDetails); >+ }" did not throw >+PASS Valid enum values for PaymentItem.type member does not throw >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/PaymentItem/type_member.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/PaymentItem/type_member.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..dc62a83f597a0b53c686689fb8f549130982242a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/PaymentItem/type_member.https.html >@@ -0,0 +1,77 @@ >+<!doctype html> >+<meta charset="utf8"> >+<link rel="help" href="https://w3c.github.io/payment-request/#dom-paymentitem-type"> >+<title> >+ PaymentItem type member >+</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+const validMethods = [ >+ { supportedMethods: "basic-card" }, >+ { supportedMethods: "https://apple.com/apple-pay" }, >+]; >+const validTotal = { >+ label: "Total", >+ amount: { >+ currency: "USD", >+ value: "5.00", >+ }, >+}; >+const validDisplayItem = { >+ label: "Item", >+ amount: { >+ currency: "USD", >+ value: "1.00", >+ }, >+}; >+const validDetails = { >+ total: validTotal, >+ displayItems: [validDisplayItem], >+}; >+ >+test(() => { >+ new PaymentRequest(validMethods, validDetails); >+}, "Smoke test"); >+ >+test(() => { >+ // Let's make an invalid DisplayItem for the total >+ const invalidTotal = Object.assign({}, validTotal, { >+ type: "this is not valid", >+ }); >+ const invalidDetails = Object.assign({}, validDetails, { >+ total: invalidTotal, >+ }); >+ assert_throws(new TypeError(), () => { >+ new PaymentRequest(validMethods, invalidDetails); >+ }); >+}, "An invalid enum value for PaymentDetailsInit.total's type throws TypeError"); >+ >+test(() => { >+ // Let's make an invalid DisplayItem to add to displayItems >+ const invalidDisplayItem = Object.assign({}, validDisplayItem, { >+ type: "this is not valid", >+ }); >+ const invalidDetails = Object.assign({}, validDetails, { >+ displayItems: [invalidDisplayItem, validDisplayItem], >+ }); >+ assert_throws(new TypeError(), () => { >+ new PaymentRequest(validMethods, invalidDetails); >+ }); >+}, "Invalid enum value for PaymentItem.type member throws a TypeError"); >+ >+test(() => { >+ // Let's make an invalid DisplayItem to add to displayItems >+ const taxDisplayItem = Object.assign({}, validDisplayItem, { type: "tax" }); >+ const taxTotal = Object.assign({}, validTotal, { type: "tax" }); >+ const validDetailsWithType = Object.assign({}, validDetails, { >+ total: taxTotal, >+ displayItems: [taxDisplayItem], >+ }); >+ try { >+ new PaymentRequest(validMethods, validDetailsWithType); >+ } catch (err) { >+ assert_unexpected(err.message); >+ } >+}, "Valid enum values for PaymentItem.type member does not throw"); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/PaymentItem/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/payment-request/PaymentItem/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..aa66e72fa4b700e4b205033149670e40b977c220 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/PaymentItem/w3c-import.log >@@ -0,0 +1,17 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/payment-request/PaymentItem/type_member.https.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/algorithms-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/algorithms-manual.https.html >index 2e4140ae0d628cdc7c06d8883add0c42c8679fd4..a40590586d876f70f70cf40be21887bf8c906880 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/algorithms-manual.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/algorithms-manual.https.html >@@ -161,6 +161,6 @@ async function runAbortTest(button) { > </section> > > <small> >- If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a> >- and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>. >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. > </small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/change-shipping-option-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/change-shipping-option-manual.https.html >index eefc45f29210ca2f6e81df19b5ab0adc61460199..e70ac2a0cd924a2f6fce4a8072d00ab51ea32639 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/change-shipping-option-manual.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/change-shipping-option-manual.https.html >@@ -89,6 +89,6 @@ function testShippingOptionChanged() { > </li> > </ol> > <small> >- If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a> >- and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>. >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. > </small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/change-shipping-option-select-last-manual.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/change-shipping-option-select-last-manual.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..78d38f2b3c95258451161e253237123aca2addf2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/change-shipping-option-select-last-manual.https-expected.txt >@@ -0,0 +1,12 @@ >+PaymentRequest shippingOption attribute >+ >+Click on each button in sequence from top to bottom without refreshing the page. Each button will bring up the Payment Request UI window. >+ >+When the payment sheet is presented, hit pay. >+ >+When default shipping option is pre-selected, must not fire onshippingoptionchange and PaymentResponse must reflect the pre-selected option. >+If you find a buggy test, please file a bug and tag one of the owners. >+ >+Harness Error (TIMEOUT), message = null >+ >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/change-shipping-option-select-last-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/change-shipping-option-select-last-manual.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2d6e1e62f8402cd4fc0969d1d2e9d9fd4a0502f4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/change-shipping-option-select-last-manual.https.html >@@ -0,0 +1,92 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Test for PaymentDetailsBase's shippingOptions member</title> >+<link rel="help" href="https://w3c.github.io/payment-request/#dom-paymentdetailsbase-shippingoptions"> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+setup({ explicit_done: true, explicit_timeout: true }); >+const validMethods = Object.freeze([ >+ { supportedMethods: "basic-card" }, >+ { supportedMethods: "https://apple.com/apple-pay" }, >+]); >+const validAmount = Object.freeze({ currency: "USD", value: "5.00" }); >+const validTotal = Object.freeze({ >+ label: "label", >+ amount: validAmount, >+}); >+const validDetails = Object.freeze({ total: validTotal }); >+ >+const validShippingOption1 = Object.freeze({ >+ id: "fail-if-selected-1", >+ label: "FAIL if selected 1", >+ amount: validAmount, >+ selected: true, >+}); >+ >+const validShippingOption2 = Object.freeze({ >+ id: "fail-if-selected-2", >+ label: "FAIL if selected 2", >+ amount: validAmount, >+ selected: false, >+}); >+ >+const validShippingOption3 = Object.freeze({ >+ id: "pass-if-selected", >+ label: "THIS MUST BE AUTOMATICALLY SELECTED", >+ amount: validAmount, >+ selected: true, >+}); >+ >+function testShippingOptionChanged(button) { >+ button.disabled = true; >+ promise_test(async t => { >+ const detailsWithShippingOptions = { >+ ...validDetails, >+ shippingOptions: [ >+ validShippingOption1, >+ validShippingOption2, >+ validShippingOption3, >+ ], >+ }; >+ const request = new PaymentRequest( >+ validMethods, >+ detailsWithShippingOptions, >+ { requestShipping: true } >+ ); >+ assert_equals( >+ request.shippingOption, >+ "pass-if-selected", >+ "Must be 'pass-if-selected', as the selected member is true" >+ ); >+ request.onshippingoptionchange = () => { >+ assert_unreached("onshippingoptionchange fired unexpectedly"); >+ }; >+ const response = await request.show(); >+ assert_equals(response.shippingOption, "pass-if-selected"); >+ response.complete(); >+ }, button.textContent.trim()); >+ done(); >+} >+</script> >+ >+<h2>PaymentRequest shippingOption attribute</h2> >+<p> >+ Click on each button in sequence from top to bottom without refreshing the page. >+ Each button will bring up the Payment Request UI window. >+</p> >+<p> >+ When the payment sheet is presented, hit pay. >+</p> >+<ol> >+ <li> >+ <button onclick="testShippingOptionChanged(this)"> >+ When default shipping option is pre-selected, must not fire onshippingoptionchange >+ and PaymentResponse must reflect the pre-selected option. >+ </button> >+ </li> >+</ol> >+<small> >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. >+</small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/interfaces.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/interfaces.https-expected.txt >index 6aaf39d0d967e4c98b3f8d51265ac67f30a3d372..dce8d6516b6a355509fe23bbf22d4b1bc5a09921 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/interfaces.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/interfaces.https-expected.txt >@@ -1,5 +1,5 @@ >-CONSOLE MESSAGE: line 331: callback not yet supported >-CONSOLE MESSAGE: line 331: callback not yet supported >+CONSOLE MESSAGE: line 440: callback not yet supported >+CONSOLE MESSAGE: line 440: callback not yet supported > > PASS Setup for Payment Request API IDL tests. > PASS PaymentRequest interface: existence and properties of interface object >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method-manual.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method-manual.https-expected.txt >deleted file mode 100644 >index b0f6b295d86378c3f93d41bcf322570314dada4a..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method-manual.https-expected.txt >+++ /dev/null >@@ -1,12 +0,0 @@ >-Test for PaymentRequest.abort() method >- >-Click on each button in sequence from top to bottom without refreshing the page. No payment sheet will be shown, but the tests will run in the background. >- >-Calling abort must not change the [[state]] until after "interactive". >-Calling .abort() causes acceptPromise to reject and closes the request. >-If you find a buggy test, please file a bug and tag one of the owners. >- >-Harness Error (TIMEOUT), message = null >- >-PASS Throws if the promise [[state]] is not "interactive" >- >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method-manual.https.html >deleted file mode 100644 >index 9552c3ce3fdefedfd90faa3d6d8edb2518b4e002..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method-manual.https.html >+++ /dev/null >@@ -1,95 +0,0 @@ >-<!DOCTYPE html> >-<meta charset="utf-8"> >-<title>Test for PaymentRequest.abort() method</title> >-<link rel="help" href="https://w3c.github.io/browser-payment-api/#abort-method"> >-<script src="/resources/testharness.js"></script> >-<script src="/resources/testharnessreport.js"></script> >-<script> >-"use strict"; >-setup({ >- // Ignore unhandled rejections resulting from .show()'s acceptPromise >- // not being explicitly handled. >- allow_uncaught_exception: true, >- explicit_done: true, >- explicit_timeout: true, >-}); >-const basicCard = Object.freeze({ supportedMethods: "basic-card" }); >-const defaultMethods = Object.freeze([basicCard]); >-const defaultDetails = Object.freeze({ >- total: { >- label: "Total", >- amount: { >- currency: "USD", >- value: "1.00", >- }, >- }, >-}); >- >-promise_test(async t => { >- // request is in "created" state >- const request = new PaymentRequest(defaultMethods, defaultDetails); >- await promise_rejects(t, "InvalidStateError", request.abort()); >-}, `Throws if the promise [[state]] is not "interactive"`); >- >-function manualTest1(elem){ >- elem.disabled = true; >- promise_test(async t => { >- // request is in "created" state. >- const request = new PaymentRequest(defaultMethods, defaultDetails); >- await promise_rejects(t, "InvalidStateError", request.abort()); >- // Call it again, for good measure. >- await promise_rejects(t, "InvalidStateError", request.abort()); >- // The request's state is "created", so let's show it >- // which changes the state to "interactive.". >- const acceptPromise = request.show(); >- // Let's set request the state to "closed" by calling .abort() >- try { >- await request.abort(); >- } catch (err) { >- assert_unreached("Unexpected promise rejection: " + err.message); >- } >- // The request is now "closed", so... >- await promise_rejects(t, "InvalidStateError", request.abort()); >- await promise_rejects(t, "AbortError", acceptPromise); >- }, elem.textContent.trim()); >-} >- >-function manualTest2(elem){ >- elem.disabled = true; >- promise_test(async t => { >- const request = new PaymentRequest(defaultMethods, defaultDetails); >- const acceptPromise = request.show(); >- try { >- await request.abort(); >- } catch (err) { >- assert_unreached("Unexpected promise rejection: " + err.message); >- } >- await promise_rejects(t, "AbortError", acceptPromise); >- // As request is now "closed", trying to show it will fail >- await promise_rejects(t, "InvalidStateError", request.show()); >- }, elem.textContent.trim()); >- done(); >-} >-</script> >- >-<h2>Test for PaymentRequest.abort() method</h2> >-<p> >- Click on each button in sequence from top to bottom without refreshing the page. >- No payment sheet will be shown, but the tests will run in the background. >-</p> >-<ol> >- <li> >- <button onclick="manualTest1(this)"> >- Calling abort must not change the [[state]] until after "interactive". >- </button> >- </li> >- <li> >- <button onclick="manualTest2(this)"> >- Calling .abort() causes acceptPromise to reject and closes the request. >- </button> >- </li> >-</ol> >-<small> >- If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a> >- and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>. >-</small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..63edcbf8d5553446369fa1d03bd7e56a86868a14 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method.https-expected.txt >@@ -0,0 +1,6 @@ >+ >+ >+PASS Throws if the promise [[state]] is not "interactive" >+FAIL Test for PaymentRequest.abort() method promise_test: Unhandled rejection with value: object "Error: unimplemented" >+FAIL Test for PaymentRequest.abort() method 1 promise_test: Unhandled rejection with value: object "Error: unimplemented" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d1f693a6ceff90e50a4f4db2f4d8bbe1d32cac88 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method.https.html >@@ -0,0 +1,78 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Test for PaymentRequest.abort() method</title> >+<link rel="help" href="https://w3c.github.io/browser-payment-api/#abort-method"> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src='/resources/testdriver-vendor.js'></script> >+<script src="/resources/testdriver.js"></script> >+<script> >+"use strict"; >+setup({ >+ // Ignore unhandled rejections resulting from .show()'s acceptPromise >+ // not being explicitly handled. >+ allow_uncaught_exception: true, >+ explicit_timeout: true, >+}); >+const basicCard = Object.freeze({ supportedMethods: "basic-card" }); >+const defaultMethods = Object.freeze([basicCard]); >+const defaultDetails = Object.freeze({ >+ total: { >+ label: "Total", >+ amount: { >+ currency: "USD", >+ value: "1.00", >+ }, >+ }, >+}); >+ >+window.onload = async () => { >+ promise_test(async t => { >+ // request is in "created" state >+ const request = new PaymentRequest(defaultMethods, defaultDetails); >+ await promise_rejects(t, "InvalidStateError", request.abort()); >+ }, `Throws if the promise [[state]] is not "interactive"`); >+ >+ const button = document.getElementById("button"); >+ >+ promise_test(async t => { >+ button.onclick = async () => { >+ const request = new PaymentRequest(defaultMethods, defaultDetails); >+ const acceptPromise = request.show(); >+ try { >+ await request.abort(); >+ } catch (err) { >+ assert_unreached("Unexpected promise rejection: " + err.message); >+ } >+ await promise_rejects(t, "AbortError", acceptPromise); >+ // As request is now "closed", trying to show it will fail >+ await promise_rejects(t, "InvalidStateError", request.show()); >+ }; >+ await test_driver.click(button); >+ }); >+ >+ promise_test(async t => { >+ button.onclick = async () => { >+ // request is in "created" state. >+ const request = new PaymentRequest(defaultMethods, defaultDetails); >+ await promise_rejects(t, "InvalidStateError", request.abort()); >+ // Call it again, for good measure. >+ await promise_rejects(t, "InvalidStateError", request.abort()); >+ // The request's state is "created", so let's show it >+ // which changes the state to "interactive.". >+ const acceptPromise = request.show(); >+ // Let's set request the state to "closed" by calling .abort() >+ try { >+ await request.abort(); >+ } catch (err) { >+ assert_unreached("Unexpected promise rejection: " + err.message); >+ } >+ // The request is now "closed", so... >+ await promise_rejects(t, "InvalidStateError", request.abort()); >+ await promise_rejects(t, "AbortError", acceptPromise); >+ }; >+ await test_driver.click(button); >+ }); >+}; >+</script> >+<button id="button"></button> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-canmakepayment-method-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-canmakepayment-method-manual.https.html >index caf43d1cb0cc77091616203e0f8ad9079c3dcc15..0311e84c942d48920bb88e1f7c6e3b8d3bf40ab8 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-canmakepayment-method-manual.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-canmakepayment-method-manual.https.html >@@ -191,6 +191,6 @@ function manualTest2(elem){ > </li> > </ol> > <small> >- If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a> >- and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>. >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. > </small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-insecure.http-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-insecure.http-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..9c35c876bffecea75e25ff30634878334af39124 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-insecure.http-expected.txt >@@ -0,0 +1,3 @@ >+ >+FAIL PaymentRequest constructor must not be exposed in insecure context assert_false: expected false got true >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-insecure.http.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-insecure.http.html >new file mode 100644 >index 0000000000000000000000000000000000000000..02122203d51eaff6c6639c9762b1495173bbf66e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-insecure.http.html >@@ -0,0 +1,13 @@ >+<!DOCTYPE html> >+<!-- Copyright © 2017 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). --> >+<meta charset="utf-8"> >+<title>Test for PaymentRequest Constructor (insecure)</title> >+<link rel="help" href="https://w3c.github.io/payment-request/#paymentrequest-interface"> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+test(() => { >+ assert_false(isSecureContext); >+ assert_false("PaymentRequest" in window); >+}, "PaymentRequest constructor must not be exposed in insecure context"); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-not-exposed.https.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-not-exposed.https.worker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..ef2fdc3821fa12c005a0699db0c7a44a17a22ab8 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-not-exposed.https.worker-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS PaymentRequest constructor must not be exposed in worker global scope >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-not-exposed.https.worker.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-not-exposed.https.worker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2382913528e693b3a5d56c660a45060980b548c3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-not-exposed.https.worker.html >@@ -0,0 +1 @@ >+<!-- This file is required for WebKit test infrastructure to run the templated test --> >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-not-exposed.https.worker.js b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-not-exposed.https.worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..e5576e673520ea33504d8ddea0e862d54b28e8fb >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-not-exposed.https.worker.js >@@ -0,0 +1,7 @@ >+importScripts("/resources/testharness.js"); >+ >+test(() => { >+ assert_true(isSecureContext); >+ assert_false('PaymentRequest' in self); >+}, "PaymentRequest constructor must not be exposed in worker global scope"); >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method-manual.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method-manual.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..196d231c34003df9d37d0545b39b438d9779eafe >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method-manual.https-expected.txt >@@ -0,0 +1,13 @@ >+Test for PaymentRequest.show() method >+ >+Click on each button in sequence from top to bottom without refreshing the page. >+ >+Throws if the promise [[state]] is not "created" >+If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException. >+If payment method consultation produces no supported method of payment, then return a promise rejected with a "NotSupportedError" DOMException. >+If you find a buggy test, please file a bug and tag one of the owners. >+ >+Harness Error (TIMEOUT), message = null >+ >+PASS Must be possible to construct a payment request >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method-manual.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..5c710da479523d036b2a702ce94a503abf4ec6a7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method-manual.https.html >@@ -0,0 +1,95 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Test for PaymentRequest.show() method</title> >+<link rel="help" href="https://w3c.github.io/browser-payment-api/#show-method"> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+"use strict"; >+setup({ >+ explicit_done: true, >+ explicit_timeout: true, >+}); >+const basicCard = Object.freeze({ supportedMethods: "basic-card" }); >+const defaultMethods = Object.freeze([basicCard]); >+const defaultDetails = Object.freeze({ >+ total: { >+ label: "Total", >+ amount: { >+ currency: "USD", >+ value: "1.00", >+ }, >+ }, >+}); >+ >+test(() => { >+ try { >+ new PaymentRequest(defaultMethods, defaultDetails); >+ } catch (err) { >+ done(); >+ throw err; >+ } >+}, "Must be possible to construct a payment request"); >+ >+function manualTest1(button){ >+ button.disabled = true; >+ promise_test(async t => { >+ const request = new PaymentRequest(defaultMethods, defaultDetails); >+ const acceptPromise = request.show(); // Sets state to "interactive" >+ await promise_rejects(t, "InvalidStateError", request.show()); >+ await request.abort(); >+ await promise_rejects(t, "AbortError", acceptPromise); >+ }, button.textContent.trim()); >+} >+ >+function manualTest2(button){ >+ button.disabled = true; >+ promise_test(async t => { >+ const request1 = new PaymentRequest(defaultMethods, defaultDetails); >+ const request2 = new PaymentRequest(defaultMethods, defaultDetails); >+ const acceptPromise1 = request1.show(); >+ const acceptPromise2 = request2.show(); >+ await promise_rejects(t, "AbortError", acceptPromise2); >+ await request1.abort(); >+ await promise_rejects(t, "AbortError", acceptPromise1); >+ }, button.textContent.trim()); >+} >+ >+function manualTest3(button){ >+ button.disabled = true; >+ promise_test(async t => { >+ const request = new PaymentRequest( >+ [{ supportedMethods: "this-is-not-supported" }], >+ defaultDetails); >+ const acceptPromise = request.show(); >+ await promise_rejects(t, "NotSupportedError", acceptPromise); >+ }, button.textContent.trim()); >+ done(); >+} >+</script> >+ >+<h2>Test for PaymentRequest.show() method</h2> >+<p> >+ Click on each button in sequence from top to bottom without refreshing the page. >+</p> >+<ol> >+ <li> >+ <button onclick="manualTest1(this)"> >+ Throws if the promise [[state]] is not "created" >+ </button> >+ </li> >+ <li> >+ <button onclick="manualTest2(this)"> >+ If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException. >+ </button> >+ </li> >+ <li> >+ <button onclick="manualTest3(this)"> >+ If payment method consultation produces no supported method of payment, then return a promise rejected with a "NotSupportedError" DOMException. >+ </button> >+ </li> >+</ol> >+<small> >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. >+</small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method.https.html >index 32b56680e7fb3870432fa67b7532ed1b505fb591..147e55dfe5cb0224b2c96084f4c33d35bcc0a4ae 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method.https.html >@@ -9,7 +9,7 @@ > 'use strict'; > const defaultMethods = Object.freeze([ > { supportedMethods: "basic-card" }, >- { supportedMethods: "https://apple.com/pay" } >+ { supportedMethods: "https://apple.com/apple-pay" } > ]); > > const defaultDetails = Object.freeze({ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/complete-method-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/complete-method-manual.https.html >index 509fa4d110b91ac8874a081c7263427fe61047df..3b6d9ad4900e748104bcca02be7404da9891f685 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/complete-method-manual.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/complete-method-manual.https.html >@@ -79,6 +79,6 @@ async function runManualTest({ completeWith: result }, button) { > </li> > </ol> > <small> >- If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a> >- and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>. >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. > </small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/methodName-attribute-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/methodName-attribute-manual.https.html >index cd25e942c6f16f410f2fe50d609babf7ccc9eecd..840d330a88093eb6aabf3c85eaae52a94aaec1f2 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/methodName-attribute-manual.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/methodName-attribute-manual.https.html >@@ -23,6 +23,6 @@ > </li> > </ol> > <small> >- If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a> >- and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>. >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. > </small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/payerEmail-attribute-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/payerEmail-attribute-manual.https.html >index c7eaf65ffccaa4cd7ec8898377c0252c3ce85bf2..676542abae3d71a1235c7500139e8bdb07a503ac 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/payerEmail-attribute-manual.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/payerEmail-attribute-manual.https.html >@@ -43,6 +43,6 @@ > </li> > </ol> > <small> >- If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a> >- and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>. >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. > </small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/payerName-attribute-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/payerName-attribute-manual.https.html >index b2636e37cb872620274b49d9d95c80d5aab086cd..b4950d2b0a37310e0490a99e78c9ae4e727dcf76 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/payerName-attribute-manual.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/payerName-attribute-manual.https.html >@@ -43,6 +43,6 @@ > </li> > </ol> > <small> >- If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a> >- and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>. >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. > </small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/payerPhone-attribute-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/payerPhone-attribute-manual.https.html >index c74f45e9c2338aa43583a16aabcd694f87052bf1..3a5710a755e8f0bdd5b9b4037a3d246e4d0a9ce0 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/payerPhone-attribute-manual.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/payerPhone-attribute-manual.https.html >@@ -43,6 +43,6 @@ > </li> > </ol> > <small> >- If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a> >- and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>. >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. > </small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/requestId-attribute-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/requestId-attribute-manual.https.html >index 653ed55bdf9d85b8ed2daf98f86048c93f385ed4..80477435bdf9f0020e33a0f5fe60b62479628dad 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/requestId-attribute-manual.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/requestId-attribute-manual.https.html >@@ -29,6 +29,6 @@ > </li> > </ol> > <small> >- If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a> >- and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>. >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. > </small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/shippingAddress-attribute-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/shippingAddress-attribute-manual.https.html >index b5a4082d7f69350b50acb70c8b20e322d9a6de09..c8f5c720a1bd85ca2a4817d7680be60fdebd624c 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/shippingAddress-attribute-manual.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/shippingAddress-attribute-manual.https.html >@@ -96,6 +96,6 @@ async function runManualTest(button, options = {}, expected = {}, id) { > </li> > </ol> > <small> >- If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a> >- and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>. >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. > </small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/shippingOption-attribute-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/shippingOption-attribute-manual.https.html >index eec7a4d9bded702c391796db0c237ff925fb41de..15d1a487e72eb20ab7a46471c5a9e72ecda0c5bd 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/shippingOption-attribute-manual.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-response/shippingOption-attribute-manual.https.html >@@ -38,6 +38,6 @@ > </li> > </ol> > <small> >- If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a> >- and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>. >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. > </small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/shipping-address-changed-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/shipping-address-changed-manual.https.html >index 1ce6e527b12178601fe75ef8e6eefee957bb208a..03d8faca36f64a467c0f92d859ad3c4d67f1855d 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/shipping-address-changed-manual.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/shipping-address-changed-manual.https.html >@@ -80,6 +80,6 @@ function testShippingAddressChange() { > </li> > </ol> > <small> >- If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a> >- and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>. >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. > </small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-optional-promise-rejects-manual.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-optional-promise-rejects-manual.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..9e6d070e93234ae7f8f8bdba2fda7b43d1c76b57 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-optional-promise-rejects-manual.https-expected.txt >@@ -0,0 +1,24 @@ >+PaymentRequest .show(optional detailsPromise) tests >+ >+Bad details - causes `detailsPromise` to reject. >+ >+Click on each button in sequence from top to bottom without refreshing the page. No payment sheet should be shown, as all provided values cause an error. >+ >+If you see a payment sheet, it means the test has failed. >+ >+Rejection of detailsPromise must abort the update with an 'AbortError' DOMException. >+Total in the update is a string, so converting to IDL must abort the update with a TypeError. >+Total is recursive, so converting to IDL must abort the update with a TypeError. >+Updating with a negative total results in a TypeError. >+Updating with a displayItem with an invalid currency results in RangeError. >+Updating with duplicate shippingOptions (same IDs) results in a TypeError. >+Updating with a shippingOption with an invalid currency value results in a RangError. >+Must throw a RangeError when a modifier's total item has an invalid currency. >+Must throw a RangeError when a modifier display item has an invalid currency. >+Must throw as Modifier has a recursive dictionary. >+Done! >+If you find a buggy test, please file a bug and tag one of the owners. >+ >+Harness Error (TIMEOUT), message = null >+ >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-optional-promise-rejects-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-optional-promise-rejects-manual.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..888942f78a3cb94d4590b2be2917c4c39e1b7133 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-optional-promise-rejects-manual.https.html >@@ -0,0 +1,281 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Test for PaymentRequest.show(optional detailsPromise) method</title> >+<link rel="help" href="https://w3c.github.io/browser-payment-api/#show-method"> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+ // See function testBadUpdate() for test details! >+ setup({ >+ allow_uncaught_exception: true, >+ explicit_done: true, >+ explicit_timeout: true, >+ }); >+ >+ // == TEST DATA === >+ // PaymentMethod >+ const validMethod = Object.freeze({ >+ supportedMethods: "valid-but-wont-ever-match", >+ }); >+ >+ const validMethodBasicCard = Object.freeze({ >+ supportedMethods: "basic-card", >+ }); >+ >+ const validMethodApplePay = Object.freeze({ >+ supportedMethods: "https://apple.com/apple-pay", >+ }); >+ >+ // Methods >+ const validMethods = Object.freeze([ >+ validMethodBasicCard, >+ validMethod, >+ validMethodApplePay, >+ ]); >+ >+ // Amounts >+ const validAmount = Object.freeze({ >+ currency: "USD", >+ value: "1.00", >+ }); >+ >+ const invalidAmount = Object.freeze({ >+ currency: "¡INVALID!", >+ value: "A1.0", >+ }); >+ >+ const negativeAmount = Object.freeze({ >+ currency: "USD", >+ value: "-1.00", >+ }); >+ >+ // Totals >+ const validTotal = Object.freeze({ >+ label: "Valid Total", >+ amount: validAmount, >+ }); >+ >+ const invalidTotal = Object.freeze({ >+ label: "Invalid Total", >+ amount: invalidAmount, >+ }); >+ >+ const invalidNegativeTotal = Object.freeze({ >+ label: "Invalid negative total", >+ amount: negativeAmount, >+ }); >+ >+ // PaymentDetailsInit >+ const validDetails = Object.freeze({ >+ total: validTotal, >+ }); >+ >+ const invalidDetailsNegativeTotal = Object.freeze({ >+ total: invalidNegativeTotal, >+ }); >+ >+ // PaymentOptions >+ const validOptions = Object.freeze({ >+ requestShipping: true, >+ }); >+ >+ // PaymentItem >+ const validPaymentItem = Object.freeze({ >+ amount: validAmount, >+ label: "Valid payment item", >+ }); >+ >+ const invalidPaymentItem = Object.freeze({ >+ amount: invalidAmount, >+ label: "Invalid payment item", >+ }); >+ >+ // PaymentItem >+ const validPaymentItems = Object.freeze([validPaymentItem]); >+ const invalidPaymentItems = Object.freeze([invalidPaymentItem]); >+ >+ // PaymentShippingOption >+ const invalidShippingOption = Object.freeze({ >+ id: "abc", >+ label: "Invalid shipping option", >+ amount: invalidAmount, >+ selected: true, >+ }); >+ >+ // PaymentShippingOptions >+ const validShippingOption = Object.freeze({ >+ id: "abc", >+ label: "valid shipping option", >+ amount: validAmount, >+ }); >+ >+ const validShippingOptions = Object.freeze([validShippingOption]); >+ const invalidShippingOptions = Object.freeze([invalidShippingOption]); >+ >+ // PaymentDetailsModifier >+ const validModifier = Object.freeze({ >+ additionalDisplayItems: validPaymentItems, >+ supportedMethods: "valid-but-wont-ever-match", >+ total: validTotal, >+ }); >+ >+ const modifierWithInvalidDisplayItems = Object.freeze({ >+ additionalDisplayItems: invalidPaymentItems, >+ supportedMethods: "basic-card", >+ total: validTotal, >+ }); >+ >+ const modifierWithValidDisplayItems = Object.freeze({ >+ additionalDisplayItems: validPaymentItems, >+ supportedMethods: "basic-card", >+ total: validTotal, >+ }); >+ >+ const modifierWithInvalidTotal = Object.freeze({ >+ additionalDisplayItems: validPaymentItems, >+ supportedMethods: "basic-card", >+ total: invalidTotal, >+ }); >+ >+ const recursiveData = {}; >+ recursiveData.foo = recursiveData; >+ Object.freeze(recursiveData); >+ >+ const modifierWithRecursiveData = Object.freeze({ >+ supportedMethods: validMethodBasicCard, >+ total: validTotal, >+ data: recursiveData, >+ }); >+ // == END OF TEST DATA === >+ /* >+ These test work by creating a "valid" payment request and then >+ performing a bad update via `show(detailsPromise)`. >+ The `badDetails` cause detailsPromise to reject with `expectedError`. >+ */ >+ function testBadUpdate(testAssertion, badDetails, expectedError) { >+ promise_test(async t => { >+ const request = new PaymentRequest( >+ validMethods, >+ validDetails, >+ validOptions >+ ); >+ const detailsPromise = Promise.resolve(badDetails); >+ const acceptPromise = request.show(detailsPromise); >+ await promise_rejects( >+ t, >+ expectedError, >+ acceptPromise, >+ "badDetails must cause acceptPromise to reject with expectedError" >+ ); >+ }, testAssertion); >+ } >+</script> >+<h2> >+ PaymentRequest <code>.show(optional detailsPromise)</code> tests >+</h2> >+<h3> >+ Bad details - causes `detailsPromise` to reject. >+</h3> >+<p> >+ Click on each button in sequence from top to bottom without refreshing the page. >+ No payment sheet should be shown, as all provided values cause an error. >+</p> >+<p> >+ <strong> >+ If you see a payment sheet, it means the test has failed. >+ </strong> >+</p> >+<ol> >+ <li><button onclick=" >+ const rejectedPromise = Promise.reject(new SyntaxError('test')) >+ .catch(err => err); >+ testBadUpdate(this.textContent, rejectedPromise, 'AbortError'); >+ "> >+ Rejection of detailsPromise must abort the update with an 'AbortError' DOMException. >+ </button></li> >+ >+ <li><button onclick=" >+ const invalidDetails = { total: `this will cause a TypeError!` }; >+ testBadUpdate(this.textContent, invalidDetails, new TypeError()); >+ "> >+ Total in the update is a string, so converting to IDL must abort the update with a TypeError. >+ </button></li> >+ >+ <li><button onclick=" >+ const invalidDetails = { total: recursiveData }; >+ testBadUpdate(this.textContent, invalidDetails, new TypeError()); >+ "> >+ Total is recursive, so converting to IDL must abort the update with a TypeError. >+ </button></li> >+ >+ <li><button onclick=" >+ testBadUpdate(this.textContent, invalidDetailsNegativeTotal, new TypeError()); >+ "> >+ Updating with a negative total results in a TypeError. >+ </button></li> >+ >+ <li><button onclick=" >+ const badDetails = Object.assign({}, validDetails, { >+ displayItems: invalidPaymentItems >+ }); >+ testBadUpdate(this.textContent, badDetails, new RangeError()); >+ "> >+ Updating with a displayItem with an invalid currency results in RangeError. >+ </button></li> >+ >+ <li><button onclick=" >+ const duplicateShippingOptions = [validShippingOption, validShippingOption]; >+ const badDetails = Object.assign({}, validDetails, { >+ shippingOptions: duplicateShippingOptions, >+ }); >+ testBadUpdate(this.textContent, badDetails, new TypeError()); >+ "> >+ Updating with duplicate shippingOptions (same IDs) results in a TypeError. >+ </button></li> >+ <li><button onclick=" >+ const badDetails = Object.assign({}, validDetails, { >+ shippingOptions: invalidShippingOptions, >+ }); >+ testBadUpdate(this.textContent, badDetails, new RangeError()); >+ "> >+ Updating with a shippingOption with an invalid currency value results in a RangError. >+ </button></li> >+ >+ <li><button onclick=" >+ // validModifier is there as to avoid false positives >+ const badModifiers = { modifiers: [modifierWithInvalidTotal, validModifier] }; >+ const badDetails = Object.assign({}, validDetails, badModifiers); >+ testBadUpdate(this.textContent, badDetails, new RangeError()); >+ "> >+ Must throw a RangeError when a modifier's total item has an invalid currency. >+ </button></li> >+ >+ <li><button onclick=" >+ // validModifier is there as to avoid false positives >+ const badModifiers = { >+ modifiers: [modifierWithInvalidDisplayItems, validModifier], >+ }; >+ const badDetails = Object.assign({}, validDetails, badModifiers); >+ testBadUpdate(this.textContent, badDetails, new RangeError()); >+ "> >+ Must throw a RangeError when a modifier display item has an invalid currency. >+ </button></li> >+ >+ <li><button onclick=" >+ // validModifier is there as to avoid false positives >+ const badModifiers = { >+ modifiers: [modifierWithRecursiveData, validModifier], >+ }; >+ const badDetails = Object.assign({}, validDetails, badModifiers); >+ testBadUpdate(this.textContent, badDetails, new TypeError()); >+ "> >+ Must throw as Modifier has a recursive dictionary. >+ </button></li> >+ >+ <li><button onclick="done();">Done!</button></li> >+</ol> >+ >+<small> >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. >+</small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-optional-promise-resolves-manual.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-optional-promise-resolves-manual.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..870088964e4e03d6ca1e338579d8173e26296007 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-optional-promise-resolves-manual.https-expected.txt >@@ -0,0 +1,22 @@ >+PaymentRequest .show(optional detailsPromise) tests >+ >+These test cause detailsPromise to resolve successfully with some updated value. As such, that will cause something in the payment sheet to change. Each test describes what is expected to change - if anything. >+ >+Instructions: Click on each button in sequence from top to bottom without refreshing the page. The payment sheet will be shown. If required, confirm that the expected value appears in the payment sheet. Finally, manually abort/cancel the payment request by closing the payment sheet. >+ >+If the payment sheet is shown, the test has failed. >+When the payment sheet is shown, the provided `id` must have no effect on the payment request. >+When the payment sheet is shown, the total must be CAD$50 with the label "â TEST HAS PASSED â ". >+When the payment sheet is shown, there must be a one display item with a value of CAD$50 with the label "â TEST HAS PASSED â ". >+When the payment sheet is shown, there must be two display items: One with a value of CAD$50, another with value AUD$40 that is pending. >+When the payment sheet is shown, there must be a one shipping option with a value of CAD$50. >+When the payment sheet is shown, there must be two shipping options: One with a value of CAD$50, another with value AUD$40 that is selected. >+When the payment sheet is shown, the total should be CAD$50. >+When the payment sheet is shown, the string "â TEST HAS PASSED â " should be shown somewhere in the user interface. Alternatively, the payment sheet must indicate to the end user that it's not possible to ship their order. >+When the payment sheet is shown, there should not be any errors shown. >+Done! >+If you find a buggy test, please file a bug and tag one of the owners. >+ >+Harness Error (TIMEOUT), message = null >+ >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-optional-promise-resolves-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-optional-promise-resolves-manual.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..5d1bf2fcb8eb73dd96924acb5365fbf06df66b32 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-optional-promise-resolves-manual.https.html >@@ -0,0 +1,319 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Test for PaymentRequest.show(optional promise) method</title> >+<link rel="help" href="https://w3c.github.io/browser-payment-api/#show-method"> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+"use strict"; >+setup({ >+ allow_uncaught_exception: true, >+ explicit_done: true, >+ explicit_timeout: true, >+}); >+ >+// DATA USED BY TESTS >+// PaymentMethods >+const validMethods = Object.freeze([ >+ { >+ supportedMethods: "valid-but-wont-ever-match", >+ }, >+ { >+ supportedMethods: "basic-card", >+ }, >+ { >+ supportedMethods: "https://apple.com/apple-pay", >+ }, >+]); >+ >+// Amounts >+const failAmount = Object.freeze({ >+ currency: "USD", >+ value: "1.00", >+}); >+const passAmount = Object.freeze({ >+ currency: "CAD", >+ value: "50.00", >+}); >+const neutralAmount = Object.freeze({ >+ currency: "AUD", >+ value: "0.00", >+}); >+ >+// Labels >+const failLabel = "ð¥ TEST HAS FAILED ð¥"; >+const passLabel = "â TEST HAS PASSED â "; >+const neutralLabel = "Ignore this label"; >+// Totals >+const failTotal = Object.freeze({ >+ label: failLabel, >+ amount: failAmount, >+}); >+const passTotal = Object.freeze({ >+ label: passLabel, >+ amount: passAmount, >+}); >+const neutralTotal = Object.freeze({ >+ label: neutralLabel, >+ amount: passAmount, >+}); >+ >+// PaymentItem >+const failPaymentItem = Object.freeze({ >+ amount: failAmount, >+ label: failLabel, >+}); >+const failPaymentItems = Object.freeze([failPaymentItem]); >+ >+const passPaymentItem = Object.freeze({ >+ amount: passAmount, >+ label: passLabel, >+}); >+const passPaymentItems = Object.freeze([passPaymentItem]); >+ >+// PaymentShippingOptions >+const failShippingOption = Object.freeze({ >+ id: "fail", >+ label: failLabel, >+ amount: failAmount, >+}); >+const failShippingOptions = Object.freeze([failShippingOption]); >+ >+const neutralShippingOption = Object.freeze({ >+ id: "neutral", >+ label: neutralLabel, >+ amount: neutralAmount, >+}); >+ >+const updatedShippingOption1 = Object.freeze({ >+ id: "updated-1", >+ label: `${passLabel} - option 1`, >+ amount: passAmount, >+}); >+const updatedShippingOption2 = Object.freeze({ >+ id: "updated-2", >+ label: `${passLabel} - option 2 (MUST BE SELECTED!)`, >+ amount: passAmount, >+ selected: true, >+}); >+const passShippingOptions = Object.freeze([ >+ updatedShippingOption1, >+ updatedShippingOption2, >+]); >+ >+// Modifiers >+// create a modifier objects for each validMethods >+// and single additional display item >+const failModifiers = validMethods.map(modifier => { >+ const label = `${failLabel} - (${modifier.supportedMethods})`; >+ return { >+ ...modifier, >+ total: { >+ ...failTotal, >+ label, >+ }, >+ additionalDisplayItems: [ >+ { >+ ...failPaymentItem, >+ label, >+ }, >+ ], >+ }; >+}); >+// Updates the total for each, and changes the additionalDisplayItems >+const passModifiers = failModifiers.map(modifier => { >+ const label = `${passLabel} - (${modifier.supportedMethods})`; >+ return { >+ ...modifier, >+ total: { >+ ...passTotal, >+ label, >+ }, >+ additionalDisplayItems: [ >+ { >+ ...passPaymentItem, >+ label, >+ }, >+ ], >+ }; >+}); >+ >+// PaymentDetailsInit >+const failDetails = Object.freeze({ >+ displayItems: failPaymentItems, >+ id: "this cannot be changed", >+ modifiers: failModifiers, >+ shippingOptions: failShippingOptions, >+ total: failTotal, >+}); >+ >+const neutralDetails = Object.freeze({ >+ displayItems: [], >+ modifiers: [], >+ shippingOptions: [neutralShippingOption], >+ total: neutralTotal, >+}); >+ >+function smokeTest() { >+ promise_test(async t => { >+ const request = new PaymentRequest(validMethods, failDetails); >+ await promise_rejects( >+ t, >+ new TypeError(), >+ request.show({ >+ total: "This throws a TypeError", >+ }), >+ "expected TypeError" >+ ); >+ }, "smoke test - checks if the optional details are supported on show() method"); >+} >+ >+function runUpdateDetailsAlgorithm( >+ buttonElement, >+ details, >+ options = { >+ requestShipping: true, >+ } >+) { >+ const testAssertion = buttonElement.textContent.trim(); >+ buttonElement.disabled = true; >+ promise_test(async t => { >+ const request = new PaymentRequest(validMethods, failDetails, options); >+ const detailsPromise = Promise.resolve(details); >+ const acceptPromise = request.show(detailsPromise); >+ assert_equals(request.id, "this cannot be changed", "id must never change."); >+ await promise_rejects( >+ t, >+ "AbortError", >+ acceptPromise, >+ "expected AbortError" >+ ); >+ }, testAssertion); >+} >+</script> >+<h2> >+ PaymentRequest <code>.show(optional detailsPromise)</code> tests >+</h2> >+<p> >+ These test cause <code>detailsPromise</code> to resolve successfully with some updated value. As such, that will cause >+ something in the payment sheet to change. Each test describes what is expected to change - if anything. >+</p> >+<p> >+ <strong>Instructions:</strong> Click on each button in sequence from top to bottom without refreshing the page. The payment >+ sheet will be shown. If required, confirm that the expected value appears in the payment sheet. Finally, manually abort/cancel >+ the payment request by closing the payment sheet. >+</p> >+<ol> >+ <li><button onclick="smokeTest()">If the payment sheet is shown, the test has failed.</button></li> >+ <li><button onclick=" >+ const details = { >+ ...neutralDetails, >+ id: 'fail', >+ }; >+ runUpdateDetailsAlgorithm(this, details); >+ "> >+ When the payment sheet is shown, the provided `id` must have no effect on the payment request. >+ </button></li> >+ <li><button onclick=" >+ const details = { >+ ...neutralDetails, >+ total: passTotal >+ }; >+ runUpdateDetailsAlgorithm(this, details); >+ "> >+ When the payment sheet is shown, the total must be CAD$50 with the label "â TEST HAS PASSED â ". >+ </button></li> >+ <li><button onclick=" >+ const details = { >+ ...neutralDetails, >+ displayItems: passPaymentItems, >+ }; >+ runUpdateDetailsAlgorithm(this, details); >+ "> >+ When the payment sheet is shown, there must be a one display item with a value of CAD$50 with the label "â TEST HAS PASSED â ". >+ </button> >+ </li> >+ <li><button onclick=" >+ const auItem = { >+ ...passPaymentItem, >+ amount: { value: '40', currency: 'AUD'}, >+ pending: true >+ } >+ const details = { >+ ...neutralDetails, >+ displayItems: passPaymentItems.concat(auItem), >+ }; >+ runUpdateDetailsAlgorithm(this, details); >+ "> >+ When the payment sheet is shown, there must be >+ two display items: One with a value of CAD$50, another with >+ value AUD$40 that is pending. >+ </button> >+ </li> >+ <li><button onclick=" >+ const details = { >+ ...neutralDetails, >+ shippingOptions: [updatedShippingOption1], >+ }; >+ runUpdateDetailsAlgorithm(this, details); >+ "> >+ When the payment sheet is shown, there must be a one shipping option >+ with a value of CAD$50. >+ </button> >+ </li> >+ <li><button onclick=" >+ const details = { >+ ...neutralDetails, >+ shippingOptions: passShippingOptions, >+ }; >+ runUpdateDetailsAlgorithm(this, details); >+ "> >+ When the payment sheet is shown, there must be >+ two shipping options: One with a value of CAD$50, another with >+ value AUD$40 that is selected. >+ </button> >+ </li> >+ <li><button onclick=" >+ const details = { >+ ...neutralDetails, >+ modifiers: passModifiers, >+ }; >+ runUpdateDetailsAlgorithm(this, details); >+ "> >+ When the payment sheet is shown, the total should be CAD$50. >+ </button> >+ </li> >+ <li> >+ <button onclick=" >+ const details = { >+ ...neutralDetails, >+ shippingOptions: [], >+ error: passLabel, >+ }; >+ runUpdateDetailsAlgorithm(this, details); >+ "> >+ When the payment sheet is shown, the string "â TEST HAS PASSED â " should be shown >+ somewhere in the user interface. Alternatively, the payment sheet must indicate to the >+ end user that it's not possible to ship their order. >+ </button> >+ </li> >+ <li> >+ <button onclick=" >+ const details = { >+ ...neutralDetails, >+ error: failLabel, >+ }; >+ runUpdateDetailsAlgorithm(this, details, {requestShipping: false}); >+ "> >+ When the payment sheet is shown, there should not be any errors shown. >+ </button> >+ </li> >+ <li> >+ <button onclick="done();">Done!</button> >+ </li> >+</ol> >+ >+<small> >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. >+</small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-postmessage-iframe.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-postmessage-iframe.html >new file mode 100644 >index 0000000000000000000000000000000000000000..12a1e0cef82886f0514cae56eb9f4e11321ab5de >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-postmessage-iframe.html >@@ -0,0 +1,40 @@ >+<h1>This iframe calls shows() via postMessage()</h1> >+<script> >+"use strict"; >+const defaultMethods = Object.freeze([ >+ { supportedMethods: "basic-card" }, >+ { supportedMethods: "https://apple.com/apple-pay" }, >+]); >+ >+const defaultDetails = Object.freeze({ >+ id: "fail", >+ total: { >+ label: "Total", >+ amount: { >+ currency: "USD", >+ value: "1.00", >+ }, >+ }, >+}); >+ >+// We are going to use the id to prove that this works >+// which we will pass back to the caller >+window.onmessage = async event => { >+ const { source, data: { id, request } } = event; >+ switch (request) { >+ case "show-payment-request": { >+ const details = Object.assign({}, defaultDetails, { id }); >+ const request = new PaymentRequest(defaultMethods, details); >+ try { >+ const response = await request.show(); >+ source.postMessage(response.toJSON(), window.location.origin); >+ await response.complete(); >+ } catch (err) { >+ source.postMessage({ requestId: "fail" }, window.location.origin); >+ await request.abort(); >+ } >+ } >+ } >+}; >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-postmessage-manual.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-postmessage-manual.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..79a133a0d9968d0a30679a806abc430a204241ac >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-postmessage-manual.https-expected.txt >@@ -0,0 +1,19 @@ >+CONSOLE MESSAGE: Unhandled Promise Rejection: SecurityError: show() must be triggered by user activation. >+CONSOLE MESSAGE: Unhandled Promise Rejection: InvalidStateError: The object is in an invalid state. >+Test PaymentRequest.show() triggered by user activation using postMessage() >+ >+Tests that user activation works over postMessage(). >+ >+Click on bottom below. Hit "Pay". >+ >+show() is triggered by user activation passed through postMessage() and a promise >+ >+If you find a buggy test, please file a bug and tag one of the owners. >+ >+ >+FAIL Test for PaymentRequest.show() method assert_throws: throws a SecurityError if not triggered by user activation function "() => { >+ const request = new PaymentRequest(defaultMethods, defaultDetails); >+ request.show(); // <--- should throw here >+ request.abort(); >+ }" did not throw >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-postmessage-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-postmessage-manual.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..a848ee6a005f35b59870e7393d2324c37f145a36 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-postmessage-manual.https.html >@@ -0,0 +1,81 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Test for PaymentRequest.show() method</title> >+<link rel="help" href="https://w3c.github.io/browser-payment-api/#show-method"> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+"use strict"; >+setup({ >+ explicit_done: true, >+ explicit_timeout: true, >+ allow_uncaught_exception: true, >+}); >+ >+const defaultMethods = Object.freeze([ >+ { supportedMethods: "basic-card" }, >+ { supportedMethods: "https://apple.com/apple-pay" }, >+]); >+ >+const defaultDetails = Object.freeze({ >+ id: "fail", >+ total: { >+ label: "Total", >+ amount: { >+ currency: "USD", >+ value: "1.00", >+ }, >+ }, >+}); >+ >+test(() => { >+ assert_throws( >+ "SecurityError", >+ () => { >+ const request = new PaymentRequest(defaultMethods, defaultDetails); >+ request.show(); // <--- should throw here >+ request.abort(); >+ }, >+ "throws a SecurityError if not triggered by user activation" >+ ); >+}); >+ >+async function runUserActivation(button) { >+ button.disabled = true; >+ const { contentWindow: iframeWindow } = document.getElementById("iframe"); >+ const expectedId = "pass123"; >+ await Promise.resolve(); // next tick >+ const promiseForResponse = new Promise(resolve => { >+ window.onmessage = ({ data: { requestId } }) => resolve(requestId); >+ }); >+ const ops = { id: expectedId, request: "show-payment-request" }; >+ iframeWindow.postMessage(ops, window.location.origin); >+ promise_test(async () => { >+ const actualId = await promiseForResponse; >+ assert_equals(actualId, expectedId, "ids must match"); >+ }, button.textContent.trim()); >+ done(); >+} >+ >+</script> >+<h2>Test PaymentRequest.show() triggered by user activation using postMessage()</h2> >+<p> >+ Tests that user activation works over postMessage(). >+</p> >+<p> >+ Click on bottom below. Hit "Pay". >+</p> >+<ol> >+ <li> >+ <button onclick="runUserActivation(this)"> >+ show() is triggered by user activation passed through postMessage() and a promise >+ </button> >+ </li> >+</ol> >+<iframe width="100%" id="iframe" src="show-method-postmessage-iframe.html" allowpaymentrequest></iframe> >+<p> >+ <small> >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. >+ </small> >+</p> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/updateWith-method-pmi-handling-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/updateWith-method-pmi-handling-manual.https.html >index adc3d6aaefdbbf134d05999234611d4ea7476d0b..1374557fa638c1878473db7eadc4e0945be933e6 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/updateWith-method-pmi-handling-manual.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/updateWith-method-pmi-handling-manual.https.html >@@ -126,6 +126,6 @@ function manualTest(button, { invalidMethod }) { > </li> > </ol> > <small> >- If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a> >- and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>. >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. > </small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/user-abort-algorithm-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/user-abort-algorithm-manual.https.html >index bfc83ab942c4cf585bbb5dcc7c26829aa5c15612..7eb4cfffe547ab7c0d7f323aab1e3df1402a79a6 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/user-abort-algorithm-manual.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/user-abort-algorithm-manual.https.html >@@ -65,6 +65,6 @@ async function runAbortTest(button) { > </li> > </ol> > <small> >- If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a> >- and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>. >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. > </small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/user-accepts-payment-request-algo-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/user-accepts-payment-request-algo-manual.https.html >index c4d390f273d8a8d8d8df13fc923e52e1d8f1e4d4..07a09be916c86c30afc421b98ca93fa33064d693 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/user-accepts-payment-request-algo-manual.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/user-accepts-payment-request-algo-manual.https.html >@@ -215,6 +215,6 @@ function testAcceptRequestAlgorithm( > </ol> > </section> > <small> >- If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a> >- and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>. >+ If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> >+ and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/OWNERS">owners</a>. > </small> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/payment-request/w3c-import.log >index dfabbd2ad85007f0cc5b1b1a1219805e5caa8178..906f170cb7b65b398d8d812ed15b7ad16da73540 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/payment-request/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/payment-request/w3c-import.log >@@ -17,23 +17,31 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/payment-request/OWNERS > /LayoutTests/imported/w3c/web-platform-tests/payment-request/algorithms-manual.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/change-shipping-option-manual.https.html >+/LayoutTests/imported/w3c/web-platform-tests/payment-request/change-shipping-option-select-last-manual.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/historical.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/interfaces.https.html >-/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method-manual.https.html >+/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-canmakepayment-method-manual.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-constructor-crash.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-constructor.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-ctor-currency-code-checks.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-ctor-pmi-handling.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-id-attribute.https.html >+/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-insecure.http.html >+/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-not-exposed.https.worker.js > /LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-onshippingaddresschange-attribute.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-onshippingoptionchange-attribute.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-shippingAddress-attribute.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-shippingOption-attribute.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-shippingType-attribute.https.html >+/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method-manual.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/rejects_if_not_active.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/shipping-address-changed-manual.https.html >+/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-optional-promise-rejects-manual.https.html >+/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-optional-promise-resolves-manual.https.html >+/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-postmessage-iframe.html >+/LayoutTests/imported/w3c/web-platform-tests/payment-request/show-method-postmessage-manual.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/updateWith-method-pmi-handling-manual.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/user-abort-algorithm-manual.https.html > /LayoutTests/imported/w3c/web-platform-tests/payment-request/user-accepts-payment-request-algo-manual.https.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/clear_resource_timing_functionality-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/clear_resource_timing_functionality-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2212bd8a9199fabf78780074abc8a8e9e77803b6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/clear_resource_timing_functionality-expected.txt >@@ -0,0 +1,4 @@ >+ >+PASS 4 resource timing entries should be stored in this page. >+PASS No resource timing entries should be stored after clearResourceTimings. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/clear_resource_timing_functionality.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/clear_resource_timing_functionality.html >new file mode 100644 >index 0000000000000000000000000000000000000000..eaf21b483ccd6ec63bcb8dc87c9e19a4305bf43d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/clear_resource_timing_functionality.html >@@ -0,0 +1,26 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>This test validates the functionality of clearResourceTimings method in resource timing.</title> >+<link rel="author" title="Intel" href="http://www.intel.com/" /> >+<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+<script> >+ setup({ explicit_done: true }); >+ const context = new PerformanceContext(performance); >+ function onload_test() >+ { >+ test_equals(context.getEntriesByType('resource').length, 4, 4 + ' resource timing entries should be stored in this page.'); >+ context.clearResourceTimings(); >+ test_equals(context.getEntriesByType('resource').length, 0, 'No resource timing entries should be stored after clearResourceTimings.'); >+ done(); >+ } >+</script> >+</head> >+<body onload=onload_test()> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource-timing-tojson-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource-timing-tojson-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..076a46807a6362e71e03fe528e36d4883a5aa25f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource-timing-tojson-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS Test toJSON() in PerformanceResourceTiming >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource-timing-tojson.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource-timing-tojson.html >new file mode 100644 >index 0000000000000000000000000000000000000000..77094f4b843a43fb30aeca48c505337b4322ca81 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource-timing-tojson.html >@@ -0,0 +1,51 @@ >+<!doctype html> >+<html> >+<head> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+</head> >+<body> >+<script> >+ const img_url = "resources/blue.png"; >+ const img = document.createElement("img"); >+ img.src = img_url; >+ window.onload = function() { >+ test(() => { >+ const entries = performance.getEntriesByType('resource'); >+ assert_greater_than_equal(entries.length, 1); >+ const entry = entries[0]; >+ assert_equals(typeof(entry.toJSON), 'function'); >+ const json = entry.toJSON(); >+ assert_equals(typeof(json), 'object'); >+ >+ const performanceResourceTimingKeys = [ >+ 'name', >+ 'entryType', >+ 'startTime', >+ 'duration', >+ 'initiatorType', >+ 'nextHopProtocol', >+ 'workerStart', >+ 'redirectStart', >+ 'fetchStart', >+ 'domainLookupStart', >+ 'domainLookupEnd', >+ 'connectStart', >+ 'connectEnd', >+ 'secureConnectionStart', >+ 'requestStart', >+ 'responseStart', >+ 'responseEnd', >+ 'transferSize', >+ 'encodedBodySize', >+ 'decodedBodySize' >+ ]; >+ for (const key of performanceResourceTimingKeys) { >+ assert_equals(json[key], entry[key], >+ `entry.toJSON().${key} should match entry.${key}`); >+ } >+ }, 'Test toJSON() in PerformanceResourceTiming'); >+ }; >+</script> >+</body> >+</html> >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_TAO_cross_origin_redirect_chain-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_TAO_cross_origin_redirect_chain-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..91d95c4d25e7549571b726881eb443b3da747ab6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_TAO_cross_origin_redirect_chain-expected.txt >@@ -0,0 +1,10 @@ >+Blocked access to external URL http://www.localhost:8800/resource-timing/resources/multi_redirect.py?page_origin=http://localhost:8800&cross_origin=http://www.localhost:8800&timing_allow=1 >+CONSOLE MESSAGE: line 26: TypeError: undefined is not an object (evaluating 'entry.redirectStart') >+ >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'entry.redirectStart') >+ >+PASS window.performance is defined >+PASS window.performance.getEntriesByName is defined >+FAIL There should be one entry. assert_equals: There should be one entry. expected 1 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_TAO_cross_origin_redirect_chain.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_TAO_cross_origin_redirect_chain.html >new file mode 100644 >index 0000000000000000000000000000000000000000..af3d31eabd17dcbfbd3900c5d4009ff723987fd1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_TAO_cross_origin_redirect_chain.html >@@ -0,0 +1,47 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>This test validates resource timing information for a timing allowed cross-origin redirect chain.</title> >+<link rel="author" title="Intel" href="http://www.intel.com/" /> >+<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+ >+<script> >+ setup({explicit_done: true}); >+ test_namespace('getEntriesByName'); >+ const pageOrigin = document.location.host; >+ const crossOrigin = 'www.' + pageOrigin; >+ >+ function onload_test() >+ { >+ const context = new PerformanceContext(performance); >+ const entries = context.getEntriesByName(document.getElementById('frameContext').src, 'resource'); >+ test_equals(entries.length, 1, 'There should be one entry.'); >+ const entry = entries[0]; >+ >+ test_greater_than(entry.redirectStart, 0, 'redirectStart > 0 in timing allowed cross-origin redirect.'); >+ test_equals(entry.redirectStart, entry.startTime, 'redirectStart == startTime in timing allowed cross-origin redirect.'); >+ test_greater_than(entry.redirectEnd, entry.redirectStart, 'redirectEnd > redirectStart in timing allowed cross-origin redirect.'); >+ test_greater_or_equals(entry.fetchStart, entry.redirectEnd, 'fetchStart >= redirectEnd in timing allowed cross-origin redirect.'); >+ done(); >+ } >+</script> >+ >+</head> >+<body> >+<iframe id="frameContext" src="" style="width: 250px; height: 250px;"></iframe> >+<script> >+ let destUrl = 'http://' + crossOrigin + '/resource-timing/resources/multi_redirect.py?'; >+ destUrl += 'page_origin=' + 'http://' + pageOrigin; >+ destUrl += '&cross_origin=' + 'http://' + crossOrigin; >+ destUrl += '&timing_allow=1'; >+ const frameContext = document.getElementById('frameContext'); >+ frameContext.onload = onload_test; >+ frameContext.src = destUrl; >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_dedicated_worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_dedicated_worker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..b4abe9bf4acd5358a583e6323e03d3ff575d8615 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_dedicated_worker-expected.txt >@@ -0,0 +1,7 @@ >+Description >+ >+This test validates that resources requested by dedicated workers don't appear in the main document. >+ >+ >+PASS There should be six entries: 4 scripts, 1 stylesheet, and the worker itself >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_dedicated_worker.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_dedicated_worker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..6d27245ab9cc9a5a6a6ab1721a036b7d4c6ba4f9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_dedicated_worker.html >@@ -0,0 +1,28 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>Resource Timing in dedicated workers</title> >+<link rel="author" title="Google" href="http://www.google.com/" /> >+<link rel="help" href="http://www.w3.org/TR/resource-timing/"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+<link rel="stylesheet" href="resources/resource_timing_test0.css" /> >+<script> >+setup({explicit_done: true}); >+const worker = new Worker("resources/worker_with_images.js"); >+worker.onmessage = function(event) { >+ const context = new PerformanceContext(window.performance); >+ const entries = context.getEntriesByType('resource'); >+ test_equals(entries.length, 6, "There should be six entries: 4 scripts, 1 stylesheet, and the worker itself"); >+ done(); >+} >+</script> >+</head> >+<body> >+<h1>Description</h1> >+<p>This test validates that resources requested by dedicated workers don't appear in the main document.</p> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_ignore_data_url-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_ignore_data_url-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..f6bb331873c37d17da4d14628ab4aa4668c27777 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_ignore_data_url-expected.txt >@@ -0,0 +1,7 @@ >+Description >+ >+This test validates that resources with data: URIs aren't present in the Resource Timing buffer. >+ >+ >+PASS entries.length == 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_ignore_data_url.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_ignore_data_url.html >new file mode 100644 >index 0000000000000000000000000000000000000000..f8ca2f1187e934fc9b07b5dbc31769f887528b51 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_ignore_data_url.html >@@ -0,0 +1,33 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>Resource Timing ignores requests for data: URIs</title> >+<link rel="author" title="Google" href="http://www.google.com/" /> >+<link rel="help" href="http://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-initiatortype"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+<script> >+let iframe; >+function setup_iframe() { >+ const iframe_content = '<img src="data:image/gif;base64,R0lGODlhAQABAIAAAOTm7AAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="></img>'; >+ iframe = document.getElementById('frameContext'); >+ iframe.contentWindow.document.write(iframe_content); >+} >+function onload_test() { >+ const context = new PerformanceContext(iframe.contentWindow.performance); >+ const entries = context.getEntriesByType('resource'); >+ test_true(entries.length == 0, "entries.length == 0"); >+} >+window.setup_iframe = setup_iframe; >+</script> >+</head> >+<body> >+<h1>Description</h1> >+<p>This test validates that resources with data: URIs aren't present in the Resource Timing buffer.</p> >+<div id="log"></div> >+<iframe id="frameContext" onload="onload_test();" src="resources/inject_resource_test.html"></iframe> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_ignore_failures-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_ignore_failures-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..bff5c9ebc9fbe2834c15c124112dcc4bc90d9693 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_ignore_failures-expected.txt >@@ -0,0 +1,7 @@ >+Description >+ >+This test validates that failed resources aren't present in the Resource Timing buffer. >+ >+ >+PASS entries.length == 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_ignore_failures.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_ignore_failures.html >new file mode 100644 >index 0000000000000000000000000000000000000000..fa9e411ea989218489adf02224b15aa46bcfbd9a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_ignore_failures.html >@@ -0,0 +1,33 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>Resource Timing ignores failed resources</title> >+<link rel="author" title="Google" href="http://www.google.com/" /> >+<link rel="help" href="http://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-initiatortype"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+<script> >+let iframe; >+function setup_iframe() { >+ const iframe_content = '<img src="resources/non-existing-file.png"></img>'; >+ iframe = document.getElementById('frameContext'); >+ iframe.contentWindow.document.write(iframe_content); >+} >+function onload_test() { >+ const context = new PerformanceContext(iframe.contentWindow.performance); >+ const entries = context.getEntriesByType('resource'); >+ test_true(entries.length == 0, "entries.length == 0"); >+} >+window.setup_iframe = setup_iframe; >+</script> >+</head> >+<body> >+<h1>Description</h1> >+<p>This test validates that failed resources aren't present in the Resource Timing buffer.</p> >+<div id="log"></div> >+<iframe id="frameContext" onload="onload_test();" src="resources/inject_resource_test.html"></iframe> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_initiator_types-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_initiator_types-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..bd0d6f768b4365f15a457c3fe7a40c84970d038a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_initiator_types-expected.txt >@@ -0,0 +1,36 @@ >+Description >+ >+This test validates that all of the initiator types are represented. >+ >+ >+FAIL /resource-timing/resources/empty.py?id=audio-source-mpeg is not expected to have duplicate entries assert_unreached: Reached unreachable code >+FAIL /resource-timing/resources/eventsource.py?id=eventsource is not expected to have duplicate entries assert_unreached: Reached unreachable code >+PASS http://localhost:8800/fonts/Ahem.ttf is expected to have initiatorType css >+PASS http://localhost:8800/fonts/Ahem.ttf?id=n1 is expected to have initiatorType css >+PASS http://localhost:8800/resource-timing/resources/blank_page_green.htm is expected to have initiatorType iframe >+PASS http://localhost:8800/resource-timing/resources/blank_page_green.htm?id=frame is expected to have initiatorType frame >+PASS http://localhost:8800/resource-timing/resources/blue.png?id=1 is expected to have initiatorType css >+PASS http://localhost:8800/resource-timing/resources/blue.png?id=2 is expected to have initiatorType css >+PASS http://localhost:8800/resource-timing/resources/blue.png?id=async_xhr is expected to have initiatorType xmlhttprequest >+PASS http://localhost:8800/resource-timing/resources/blue.png?id=body is expected to have initiatorType body >+PASS http://localhost:8800/resource-timing/resources/blue.png?id=cursor is expected to have initiatorType css >+PASS http://localhost:8800/resource-timing/resources/blue.png?id=input is expected to have initiatorType input >+PASS http://localhost:8800/resource-timing/resources/blue.png?id=n1 is expected to have initiatorType css >+PASS http://localhost:8800/resource-timing/resources/blue.png?id=object is expected to have initiatorType object >+PASS http://localhost:8800/resource-timing/resources/blue.png?id=picture-99x-img-src is expected to have initiatorType img >+PASS http://localhost:8800/resource-timing/resources/blue.png?id=picture-img-srcset is expected to have initiatorType img >+PASS http://localhost:8800/resource-timing/resources/blue.png?id=picture-notsupported-img is expected to have initiatorType img >+PASS http://localhost:8800/resource-timing/resources/blue.png?id=picture-source is expected to have initiatorType img >+PASS http://localhost:8800/resource-timing/resources/blue.png?id=video-poster is expected to have initiatorType video >+FAIL http://localhost:8800/resource-timing/resources/empty.py?id=audio-source-mpeg is expected to have initiatorType audio assert_equals: http://localhost:8800/resource-timing/resources/empty.py?id=audio-source-mpeg is expected to have initiatorType audio expected "audio" but got "video" >+PASS http://localhost:8800/resource-timing/resources/empty.py?id=audio-source-wav is expected to have initiatorType audio >+PASS http://localhost:8800/resource-timing/resources/empty.py?id=audio-src is expected to have initiatorType audio >+PASS http://localhost:8800/resource-timing/resources/empty.py?id=fetch is expected to have initiatorType fetch >+PASS http://localhost:8800/resource-timing/resources/empty_script.js is expected to have initiatorType script >+FAIL http://localhost:8800/resource-timing/resources/eventsource.py?id=eventsource is expected to have initiatorType other assert_equals: http://localhost:8800/resource-timing/resources/eventsource.py?id=eventsource is expected to have initiatorType other expected "other" but got "video" >+PASS http://localhost:8800/resource-timing/resources/nested.css is expected to have initiatorType link >+PASS http://localhost:8800/resource-timing/resources/nested.css?id=preload is expected to have initiatorType link >+PASS http://localhost:8800/resource-timing/resources/resource_timing_test0.css?id=n1 is expected to have initiatorType css >+PASS http://localhost:8800/resource-timing/resources/resource_timing_test0.png is expected to have initiatorType img >+PASS http://localhost:8800/resource-timing/resources/resource_timing_test0.png?id=srcset-srcset is expected to have initiatorType img >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_initiator_types.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_initiator_types.html >new file mode 100644 >index 0000000000000000000000000000000000000000..9912da7c3400138d73245acc372463ca174e6f58 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_initiator_types.html >@@ -0,0 +1,164 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>Resource Timing initiator types</title> >+<link rel="author" title="Google" href="http://www.google.com/" /> >+<link rel="help" href="http://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-initiatortype"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+<script> >+setup({explicit_done: true, timeout: 30000}); >+ >+let background_loaded = false; >+let page_loaded = false; >+let ol_font_loaded = false; >+let ul_font_loaded = false; >+let xhr_loaded = false; >+let tests_run = false; >+let frameset_loaded = false; >+ >+function check_finished() { >+ if (!ul_font_loaded) { >+ ul_font_loaded = check_font_loaded('ul'); >+ } >+ if (!ol_font_loaded) { >+ ol_font_loaded = check_font_loaded('ol'); >+ } >+ if (page_loaded && ol_font_loaded && ul_font_loaded && background_loaded && xhr_loaded && frameset_loaded) { >+ perform_test(); >+ } else { >+ step_timeout(check_finished, 100); >+ } >+} >+ >+function check_font_loaded(type) { >+ const width_var_name = 'original_width_' + type; >+ const element_var_name = 'element_' + type; >+ if (!this.hasOwnProperty(width_var_name)) { >+ const d = document.getElementById('frameContext').contentWindow.document; >+ const list = d.createElement(type); >+ const li = d.createElement('li'); >+ li.innerHTML = 'width_test'; >+ list.appendChild(li); >+ d.getElementsByTagName('body')[0].appendChild(list); >+ this[element_var_name] = list; >+ this[width_var_name] = li.offsetHeight; >+ } >+ return this[width_var_name] != this[element_var_name].offsetHeight; >+} >+ >+function onload_test() { >+ page_loaded = true; >+ >+ const image = document.createElement('img'); >+ image.src = 'resources/blue.png?id=n1'; >+ background_loaded = image.complete; >+ if (!background_loaded) { >+ image.onload = function() { >+ background_loaded = true; >+ } >+ } >+ >+ step_timeout(check_finished, 100); >+} >+ >+function frameset_onload() { >+ frameset_loaded = true; >+ >+ step_timeout(check_finished, 100); >+} >+ >+function perform_test() { >+ if (tests_run) { >+ return; >+ } >+ tests_run = true; >+ const context = new PerformanceContext(document.getElementById('frameContext').contentWindow.performance); >+ let entries = context.getEntriesByType('resource'); >+ >+ // check for frameset >+ if (document.getElementById('frameContext2') && >+ document.getElementById('frameContext2').contentWindow) { >+ const context2 = new PerformanceContext(document.getElementById('frameContext2').contentWindow.performance); >+ entries = entries.concat(context2.getEntriesByType('resource')); >+ } >+ >+ const index = window.location.pathname.lastIndexOf('/'); >+ const pathname = window.location.pathname.substring(0, index) + '/resources/'; >+ const font_pathname = window.location.pathname.substring(0, index - 15) + 'fonts/Ahem.ttf'; >+ >+ let expected_entries = {}; >+ addEntryIfExists(entries, expected_entries, font_pathname, 'css'); >+ addEntryIfExists(entries, expected_entries, pathname + 'resource_timing_test0.png', 'img'); >+ addEntryIfExists(entries, expected_entries, pathname + 'resource_timing_test0.png?id=srcset-srcset', 'img'); >+ addEntryIfExists(entries, expected_entries, pathname + 'resource_timing_test0.png?id=srcset-src', 'img'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blank_page_green.htm', 'iframe'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blank_page_green.htm?id=frame', 'frame'); >+ addEntryIfExists(entries, expected_entries, pathname + 'empty_script.js', 'script'); >+ addEntryIfExists(entries, expected_entries, pathname + 'resource_timing_test0.css?id=embed', 'embed'); >+ addEntryIfExists(entries, expected_entries, pathname + 'resource_timing_test0.css?id=n1', 'css'); >+ addEntryIfExists(entries, expected_entries, font_pathname + '?id=n1', 'css'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blue.png?id=cursor', 'css'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blue.png?id=1', 'css'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blue.png?id=2', 'css'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blue.png?id=async_xhr', 'xmlhttprequest'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blue.png?id=body', 'body'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blue.png?id=input', 'input'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blue.png?id=n1', 'css'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blue.png?id=object', 'object'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blue.png?id=video-poster', 'video'); >+ addEntryIfExists(entries, expected_entries, '/media/test.mp4?id=video-src', 'video'); >+ addEntryIfExists(entries, expected_entries, '/media/test.mp4?id=video-source', 'video'); >+ addEntryIfExists(entries, expected_entries, '/media/test.ogv?id=video-source', 'video'); >+ addEntryIfExists(entries, expected_entries, pathname + 'empty.py?id=video-track', 'track'); >+ addEntryIfExists(entries, expected_entries, pathname + 'empty.py?id=audio-src', 'audio'); >+ addEntryIfExists(entries, expected_entries, pathname + 'empty.py?id=audio-source-wav', 'audio'); >+ addEntryIfExists(entries, expected_entries, pathname + 'empty.py?id=audio-source-mpeg', 'audio'); >+ addEntryIfExists(entries, expected_entries, pathname + 'empty.py?id=audio-source-ogg', 'audio'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blue.png?id=picture-source', 'img'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blue.png?id=picture-img', 'img'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blue.png?id=picture-notsupported-img', 'img'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blue.png?id=picture-img-src', 'img'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blue.png?id=picture-img-srcset', 'img'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blue.png?id=picture-99x-img-src', 'img'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blue.png?id=svg-image', 'image'); >+ addEntryIfExists(entries, expected_entries, pathname + 'nested.css', 'link'); >+ addEntryIfExists(entries, expected_entries, pathname + 'nested.css?id=prefetch', 'link'); >+ addEntryIfExists(entries, expected_entries, pathname + 'nested.css?id=preload', 'link'); >+ addEntryIfExists(entries, expected_entries, pathname + 'blank_page_green.htm?id=prerender', 'link'); >+ addEntryIfExists(entries, expected_entries, pathname + 'manifest.json', 'link'); >+ addEntryIfExists(entries, expected_entries, pathname + 'empty.py?id=beacon', 'beacon'); >+ addEntryIfExists(entries, expected_entries, pathname + 'empty.py?id=fetch', 'fetch'); >+ addEntryIfExists(entries, expected_entries, pathname + 'empty.py?favicon', 'link'); >+ addEntryIfExists(entries, expected_entries, pathname + 'eventsource.py?id=eventsource', 'other'); >+ >+ test_resource_entries(entries, expected_entries); >+ done(); >+} >+ >+function addEntryIfExists(entries, expected_entries, path, initiatorType) { >+ const url = window.location.protocol + "//" + window.location.host + path; >+ >+ if (entries.find(function(entry) { return entry.name === url; })) { >+ expected_entries[path] = initiatorType; >+ } >+} >+ >+window.on_test_body_created = check_finished; >+window.on_async_xhr_done = function() { >+ xhr_loaded = true; >+ check_finished(); >+} >+</script> >+</head> >+<body> >+<h1>Description</h1> >+<p>This test validates that all of the initiator types are represented.</p> >+<div id="log"></div> >+<iframe id="frameContext" onload="onload_test();" src="resources/all_resource_types.htm" style="width: 250px; height: 250px;"></iframe> >+<iframe id="frameContext2" onload="frameset_onload();" src="resources/green_frame.htm" style="width: 250px; height: 250px;"></iframe> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_memory_cached.sub-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_memory_cached.sub-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..624e24ec78231561307962f64c574c8eda667773 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_memory_cached.sub-expected.txt >@@ -0,0 +1,16 @@ >+Blocked access to external URL http://www1.localhost:8801/resource-timing/resources/blue.png?id=cached >+Blocked access to external URL http://www1.localhost:8801/resource-timing/resources/blue.png?id=cached >+Blocked access to external URL http://www1.localhost:8801/resource-timing/resources/blue.png?id=cached >+Description >+ >+This test validates that a memory cached resource appears in the buffer once. >+ >+ >+Harness Error (TIMEOUT), message = null >+ >+PASS There should be only one entry >+PASS http://localhost:8800/resource-timing/resources/blue.png?id=cached is expected to have initiatorType img >+PASS requestStart should be non-zero on the same-origin request >+PASS responseEnd should not be before startTime >+PASS duration should not be negative >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_memory_cached.sub.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_memory_cached.sub.html >new file mode 100644 >index 0000000000000000000000000000000000000000..236f69fba72eb7921230da08fc780cbb66d61e03 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_memory_cached.sub.html >@@ -0,0 +1,84 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>Resource Timing memory cached resources</title> >+<link rel="author" title="Google" href="http://www.google.com/" /> >+<link rel="help" href="http://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-initiatortype"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+<script> >+setup({explicit_done: true}); >+let d; >+let iframe; >+let iframeBody; >+let count = 0; >+function onload_prep() { >+ iframe = document.getElementById('frameContext'); >+ d = iframe.contentWindow.document; >+ iframeBody = d.body; >+ >+ const image = d.createElement('img'); >+ image.addEventListener('load', function() { >+ step_timeout(onload_test, 0); }); >+ image.src = 'blue.png?id=cached'; >+ iframeBody.appendChild(image); >+ >+ const image2 = d.createElement('img'); >+ image2.addEventListener('load', function() { >+ step_timeout(onload_test, 0); }); >+ image2.src = 'blue.png?id=cached'; >+ iframeBody.appendChild(image2); >+} >+ >+function onload_test() { >+ ++count; >+ if (count < 2) >+ return; >+ >+ const context = new PerformanceContext(iframe.contentWindow.performance); >+ const entries = context.getEntriesByType('resource'); >+ test_equals(entries.length, 1, "There should be only one entry"); >+ >+ const index = window.location.pathname.lastIndexOf('/'); >+ const pathname = window.location.pathname.substring(0, index); >+ let expected_entries = {}; >+ expected_entries[pathname + '/resources/blue.png?id=cached'] = 'img'; >+ test_resource_entries(entries, expected_entries); >+ test_greater_than(entries[0].requestStart, 0, 'requestStart should be non-zero on the same-origin request'); >+ test_greater_or_equals(entries[0].responseEnd, entries[0].startTime, 'responseEnd should not be before startTime'); >+ test_greater_or_equals(entries[0].duration, 0, 'duration should not be negative'); >+ >+ context.clearResourceTimings(); >+ start_crossorigin_test(); >+} >+function start_crossorigin_test() { >+ const image3 = d.createElement('img'); >+ image3.addEventListener("load", function() { step_timeout(finish_crossorigin_test, 0); }); >+ image3.src = 'http://{{domains[www1]}}:{{ports[http][1]}}{{location[path]}}/../resources/blue.png?id=cached'; >+ iframeBody.appendChild(image3); >+} >+function finish_crossorigin_test() { >+ const context = new PerformanceContext(iframe.contentWindow.performance); >+ const entries = context.getEntriesByType('resource'); >+ test_equals(entries.length, 1, 'There should be one entry in second test'); >+ test_true(entries[0].name.startsWith('http://{{domains[www1]}}:{{ports[http][1]}}'), 'Entry name should start with cross-origin domain'); >+ test_true(entries[0].name.endsWith('/resources/blue.png?id=cached'), 'Entry name should end with file name'); >+ test_equals(entries[0].requestStart, 0, 'requestStart should be 0 on the cross-origin request'); >+ done(); >+} >+window.setup_iframe = () => {}; >+window.addEventListener('load', onload_prep); >+</script> >+</head> >+<body> >+<h1>Description</h1> >+<p>This test validates that a memory cached resource appears in the buffer once.</p> >+<div id="log"></div> >+<iframe id="frameContext" src="resources/inject_resource_test.html"></iframe> >+<img src="resources/blue.png?id=cached"></img> >+<img src="http://{{domains[www1]}}:{{ports[http][1]}}{{location[path]}}/../resources/blue.png?id=cached"></img> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_redirects-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_redirects-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..10cff5895c89c403d7a314c3cd6309a96437e631 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_redirects-expected.txt >@@ -0,0 +1,11 @@ >+Description >+ >+This test validates that redirects do not alter the URL. >+ >+ >+PASS http://localhost:8800/common/redirect.py?location=/resource-timing/resources/blank_page_green.htm is expected to have initiatorType iframe >+PASS http://localhost:8800/common/redirect.py?location=/resource-timing/resources/blank_page_green.htm?id=xhr is expected to have initiatorType xmlhttprequest >+PASS http://localhost:8800/common/redirect.py?location=/resource-timing/resources/blue.png is expected to have initiatorType img >+PASS http://localhost:8800/common/redirect.py?location=/resource-timing/resources/empty_script.js is expected to have initiatorType script >+PASS http://localhost:8800/common/redirect.py?location=/resource-timing/resources/resource_timing_test0.css is expected to have initiatorType link >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_redirects.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_redirects.html >new file mode 100644 >index 0000000000000000000000000000000000000000..606662afda4401dd0dccbac2b71b66f3b1961e6f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_redirects.html >@@ -0,0 +1,53 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>Resource Timing redirect names</title> >+<link rel="author" title="Google" href="http://www.google.com/" /> >+<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+<script> >+let iframe; >+function setup_iframe() { >+ const iframe_content = >+ '<link rel="stylesheet" href="/common/redirect.py?location=/resource-timing/resources/resource_timing_test0.css"></link>' + >+ '<img src="/common/redirect.py?location=/resource-timing/resources/blue.png"></img>' + >+ '<iframe src="/common/redirect.py?location=/resource-timing/resources/blank_page_green.htm"></iframe>' + >+ '<script src="/common/redirect.py?location=/resource-timing/resources/empty_script.js"></scr' + 'ipt>' + >+ '<scr' + 'ipt>' + >+ 'const xhr = new XMLHttpRequest;' + >+ 'xhr.open("GET", "/common/redirect.py?location=/resource-timing/resources/blank_page_green.htm?id=xhr", false);' + >+ 'xhr.send();' + >+ '</scr' + 'ipt>'; >+ iframe = document.getElementById('frameContext'); >+ iframe.contentWindow.document.write(iframe_content); >+} >+function onload_test() { >+ const context = new PerformanceContext(iframe.contentWindow.performance); >+ const entries = context.getEntriesByType('resource'); >+ >+ const index = window.location.pathname.lastIndexOf('resource-timing'); >+ const pathname = window.location.pathname.substring(0, index) + >+ 'common/redirect.py?location=/resource-timing/resources/'; >+ let expected_entries = {}; >+ expected_entries[pathname + 'resource_timing_test0.css'] = 'link'; >+ expected_entries[pathname + 'blue.png'] = 'img'; >+ expected_entries[pathname + 'blank_page_green.htm'] = 'iframe'; >+ expected_entries[pathname + 'empty_script.js'] = 'script'; >+ expected_entries[pathname + 'blank_page_green.htm?id=xhr'] = 'xmlhttprequest'; >+ >+ test_resource_entries(entries, expected_entries); >+} >+window.setup_iframe = setup_iframe; >+</script> >+</head> >+<body> >+<h1>Description</h1> >+<p>This test validates that redirects do not alter the URL.</p> >+<div id="log"></div> >+<iframe id="frameContext" onload="onload_test();" src="resources/inject_resource_test.html"></iframe> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_reparenting-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_reparenting-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..269f193e862693877eb3e088342f6c596b69e5bd >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_reparenting-expected.txt >@@ -0,0 +1,8 @@ >+Description >+ >+This test validates that reparenting an element doesn't change the initiator document. >+ >+ >+FAIL http://localhost:8800/resource-timing/resources/blue.png?id=move_to_parent is not expected to be in the Resource Timing buffer assert_unreached: Reached unreachable code >+FAIL http://localhost:8800/resource-timing/resources/blue.png?id=move_to_child is expected to be in the Resource Timing buffer assert_unreached: Reached unreachable code >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_reparenting.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_reparenting.html >new file mode 100644 >index 0000000000000000000000000000000000000000..7d4947fa7703d13a5adb465ff5eebbb4456cace9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_reparenting.html >@@ -0,0 +1,53 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>Resource Timing reparenting elements</title> >+<link rel="author" title="Google" href="http://www.google.com/" /> >+<link rel="help" href="http://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-initiatortype"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+<script> >+let iframe; >+function setup_iframe() { >+ iframe = document.getElementById('frameContext'); >+ const d = iframe.contentWindow.document; >+ const iframeBody = d.createElement('body'); >+ >+ const move_to_parent = d.createElement('img'); >+ move_to_parent.src = 'blue.png?id=move_to_parent'; >+ iframeBody.appendChild(move_to_parent); >+ iframeBody.removeChild(move_to_parent); >+ >+ const parentBody = document.getElementsByTagName('body')[0]; >+ parentBody.appendChild(move_to_parent); >+ >+ const move_to_child = document.createElement('img'); >+ move_to_child.src = 'blue.png?id=move_to_child'; >+ parentBody.appendChild(move_to_child); >+ parentBody.removeChild(move_to_child); >+ iframeBody.appendChild(move_to_child); >+} >+function onload_test() { >+ const context = new PerformanceContext(iframe.contentWindow.performance); >+ const entries = context.getEntriesByType('resource'); >+ >+ const index = window.location.pathname.lastIndexOf('/'); >+ const pathname = window.location.pathname.substring(0, index); >+ let expected_entries = {}; >+ expected_entries[pathname + '/resources/blue.png?id=move_to_child'] = 'img'; >+ >+ test_resource_entries(entries, expected_entries); >+} >+window.setup_iframe = setup_iframe; >+</script> >+</head> >+<body> >+<h1>Description</h1> >+<p>This test validates that reparenting an element doesn't change the initiator document.</p> >+<div id="log"></div> >+<iframe id="frameContext" onload="onload_test();" src="resources/inject_resource_test.html"></iframe> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_script_types-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_script_types-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..0c7697214a889756351a128eb41a472839b87f23 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_script_types-expected.txt >@@ -0,0 +1,15 @@ >+Description >+ >+This test validates that all of the different types of script loads are reported with the correct initiator. >+ >+ >+PASS http://localhost:8800/resource-timing/resources/empty_script.js?id=1 is expected to have initiatorType script >+PASS http://localhost:8800/resource-timing/resources/empty_script.js?id=2 is expected to have initiatorType script >+PASS http://localhost:8800/resource-timing/resources/empty_script.js?id=3 is expected to have initiatorType script >+PASS http://localhost:8800/resource-timing/resources/empty_script.js?id=4 is expected to have initiatorType script >+PASS http://localhost:8800/resource-timing/resources/empty_script.js?id=5 is expected to have initiatorType script >+PASS http://localhost:8800/resource-timing/resources/empty_script.js?id=6 is expected to have initiatorType script >+PASS http://localhost:8800/resource-timing/resources/empty_script.js?id=7 is expected to have initiatorType script >+PASS http://localhost:8800/resource-timing/resources/empty_script.js?id=8 is expected to have initiatorType script >+PASS http://localhost:8800/resource-timing/resources/empty_script.js?id=9 is expected to have initiatorType script >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_script_types.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_script_types.html >new file mode 100644 >index 0000000000000000000000000000000000000000..898fa0cee2cb29f69c11d70d831c2eade5b75036 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_script_types.html >@@ -0,0 +1,72 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>Resource Timing script initiator types</title> >+<link rel="author" title="Google" href="http://www.google.com/" /> >+<link rel="help" href="http://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-initiatortype"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+<script> >+setup({explicit_done: true}); >+let iframe; >+function setup_iframe() { >+ const iframe_content = >+ '<script src="empty_script.js?id=1"></scr' + 'ipt>' + >+ '<script src="empty_script.js?id=2" async></scr' + 'ipt>' + >+ '<script src="empty_script.js?id=3" async=false></scr' + 'ipt>' + >+ '<script src="empty_script.js?id=4" defer></scr' + 'ipt>' + >+ '<script>' + >+ 'document.write("<script src=\\"empty_script.js?id=5\\"></scr" + "ipt>");' + >+ 'const s1 = document.createElement("script");' + >+ 's1.src = "empty_script.js?id=6";' + >+ 'document.getElementsByTagName("head")[0].appendChild(s1);' + >+ 'const s2 = document.createElement("script");' + >+ 's2.src = "empty_script.js?id=7";' + >+ 's2.async = true;' + >+ 'document.getElementsByTagName("head")[0].appendChild(s2);' + >+ 'const s3 = document.createElement("script");' + >+ 's3.src = "empty_script.js?id=8";' + >+ 's3.async = false;' + >+ 'document.getElementsByTagName("head")[0].appendChild(s3);' + >+ 'const s4 = document.createElement("script");' + >+ 's4.src = "empty_script.js?id=9";' + >+ 's4.defer = true;' + >+ 'document.getElementsByTagName("head")[0].appendChild(s4);' + >+ '</scr' + 'ipt>'; >+ iframe = document.getElementById('frameContext'); >+ iframe.contentWindow.document.write(iframe_content); >+} >+function onload_test() { >+ const context = new PerformanceContext(iframe.contentWindow.performance); >+ const entries = context.getEntriesByType('resource'); >+ >+ const index = window.location.pathname.lastIndexOf('/'); >+ const pathname = window.location.pathname.substring(0, index) + >+ '/resources/empty_script.js?id='; >+ let expected_entries = {}; >+ expected_entries[pathname + '1'] = 'script'; >+ expected_entries[pathname + '2'] = 'script'; >+ expected_entries[pathname + '3'] = 'script'; >+ expected_entries[pathname + '4'] = 'script'; >+ expected_entries[pathname + '5'] = 'script'; >+ expected_entries[pathname + '6'] = 'script'; >+ expected_entries[pathname + '7'] = 'script'; >+ expected_entries[pathname + '8'] = 'script'; >+ expected_entries[pathname + '9'] = 'script'; >+ >+ test_resource_entries(entries, expected_entries); >+ done(); >+} >+window.setup_iframe = setup_iframe; >+</script> >+</head> >+<body> >+<h1>Description</h1> >+<p>This test validates that all of the different types of script loads are reported with the correct initiator.</p> >+<div id="log"></div> >+<iframe id="frameContext" onload="onload_test();" src="resources/inject_resource_test.html"></iframe> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_subframe_self_navigation-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_subframe_self_navigation-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..57784d1c10971e8dabf641dc74ccf4d9ddced03d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_subframe_self_navigation-expected.txt >@@ -0,0 +1,6 @@ >+ >+PASS Subsequent <iframe> navigations don't appear in the resource-timing buffer. >+PASS Subsequent <frame> navigations don't appear in the resource-timing buffer. >+PASS Subsequent <embed> navigations don't appear in the resource-timing buffer. >+PASS Subsequent <object> navigations don't appear in the resource-timing buffer. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_subframe_self_navigation.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_subframe_self_navigation.html >new file mode 100644 >index 0000000000000000000000000000000000000000..5843f88307233e9326c84106f460039baf09162e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_subframe_self_navigation.html >@@ -0,0 +1,53 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<body> >+<script> >+function numberOfDownloads(url) { >+ let absoluteURL = new URL(url, location.href).href; >+ return performance.getEntriesByName(absoluteURL).length; >+} >+ >+function waitForSubFrameLoad() { >+ return new Promise((resolve) => { >+ window.subFrameLoaded = () => { >+ window.subFrameLoaded = null; >+ resolve(); >+ }; >+ }); >+} >+ >+function runTest(type) { >+ performance.clearResourceTimings(); >+ let elem = document.createElement(type); >+ if (type === 'object') >+ elem.data = 'resources/self_navigation.html?' + type; >+ else >+ elem.src = 'resources/self_navigation.html?' + type; >+ document.body.appendChild(elem); >+ return waitForSubFrameLoad().then(() => { >+ let resources = performance.getEntriesByType('resource'); >+ assert_equals(numberOfDownloads('resources/self_navigation.html?' + type), 1); >+ assert_equals(numberOfDownloads('resources/notify_parent.html?redirected'), 0); >+ document.body.removeChild(elem); >+ }); >+} >+ >+promise_test( >+ () => runTest('iframe'), >+ "Subsequent <iframe> navigations don't appear in the resource-timing buffer."); >+ >+promise_test( >+ () => runTest('frame'), >+ "Subsequent <frame> navigations don't appear in the resource-timing buffer."); >+ >+promise_test( >+ () => runTest('embed'), >+ "Subsequent <embed> navigations don't appear in the resource-timing buffer."); >+ >+promise_test( >+ () => runTest('object'), >+ "Subsequent <object> navigations don't appear in the resource-timing buffer."); >+ >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing.worker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..1f50e798d3d3d3473aa1ec843ce854abfa064b03 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing.worker-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS Performance Resouce Entries in workers >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing.worker.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing.worker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2382913528e693b3a5d56c660a45060980b548c3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing.worker.html >@@ -0,0 +1 @@ >+<!-- This file is required for WebKit test infrastructure to run the templated test --> >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing.worker.js b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing.worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..92687f0f7b62b92e414d0e8a900faac570735c9d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing.worker.js >@@ -0,0 +1,64 @@ >+importScripts("/resources/testharness.js"); >+ >+function check(initiatorType, protocol) { >+ let entries = performance.getEntries(); >+ assert_equals(entries.length, 1); >+ >+ assert_true(entries[0] instanceof PerformanceEntry); >+ assert_equals(entries[0].entryType, "resource"); >+ assert_true(entries[0].startTime > 0); >+ assert_true(entries[0].duration > 0); >+ >+ assert_true(entries[0] instanceof PerformanceResourceTiming); >+ assert_equals(entries[0].initiatorType, initiatorType); >+ assert_equals(entries[0].nextHopProtocol, protocol); >+} >+ >+async_test(t => { >+ performance.clearResourceTimings(); >+ >+ // Fetch >+ fetch("resources/empty.js") >+ .then(r => r.blob()) >+ .then(blob => { >+ check("fetch", "http/1.1"); >+ }) >+ >+ // XMLHttpRequest >+ .then(() => { >+ return new Promise(resolve => { >+ performance.clearResourceTimings(); >+ let xhr = new XMLHttpRequest(); >+ xhr.onload = () => { >+ check("xmlhttprequest", "http/1.1"); >+ resolve(); >+ }; >+ xhr.open("GET", "resources/empty.js"); >+ xhr.send(); >+ }); >+ }) >+ >+ // Sync XMLHttpREquest >+ .then(() => { >+ performance.clearResourceTimings(); >+ let xhr = new XMLHttpRequest(); >+ xhr.open("GET", "resources/empty.js", false); >+ xhr.send(); >+ >+ check("xmlhttprequest", "http/1.1"); >+ }) >+ >+ // ImportScripts >+ .then(() => { >+ performance.clearResourceTimings(); >+ importScripts(["resources/empty.js"]); >+ check("other", "http/1.1"); >+ }) >+ >+ // All done. >+ .then(() => { >+ t.done(); >+ }); >+}, "Performance Resouce Entries in workers"); >+ >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_TAO_cross_origin_redirect-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_TAO_cross_origin_redirect-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..10a523641018161d19cf33feff43b045a839182a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_TAO_cross_origin_redirect-expected.txt >@@ -0,0 +1,7 @@ >+ >+ >+PASS redirectStart should be greater than 0 in timing allowed cross-origin redirect. >+PASS redirectStart should be equal to startTime in timing allowed cross-origin redirect. >+PASS redirectEnd should be no less than redirectStart in timing allowed cross-origin redirect. >+PASS fetchStart should be no less than redirectEnd in timing allowed cross-origin redirect. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_TAO_cross_origin_redirect.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_TAO_cross_origin_redirect.html >new file mode 100644 >index 0000000000000000000000000000000000000000..a91eaf8a1f647f84c63bc855a1368fe312d64991 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_TAO_cross_origin_redirect.html >@@ -0,0 +1,38 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>This test validates the values in resource timing for a timing allowed cross-origin redirect.</title> >+<link rel="author" title="Intel" href="http://www.intel.com/" /> >+<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+ >+<script> >+ setup({explicit_done: true}); >+ function onload_test() { >+ const context = new PerformanceContext(performance); >+ const entry = context.getEntriesByName(document.getElementById('frameContext').src, 'resource')[0]; >+ >+ test_greater_than(entry.redirectStart, 0, 'redirectStart should be greater than 0 in timing allowed cross-origin redirect.'); >+ test_equals(entry.redirectStart, entry.startTime, 'redirectStart should be equal to startTime in timing allowed cross-origin redirect.'); >+ test_greater_or_equals(entry.redirectEnd, entry.redirectStart, 'redirectEnd should be no less than redirectStart in timing allowed cross-origin redirect.'); >+ test_greater_or_equals(entry.fetchStart, entry.redirectEnd, 'fetchStart should be no less than redirectEnd in timing allowed cross-origin redirect.'); >+ done(); >+ } >+</script> >+ >+</head> >+<body> >+<iframe id="frameContext" src="" style="width: 250px; height: 250px;"></iframe> >+<script> >+ const destUrl = '/common/redirect.py?location=/resource-timing/resources/iframe_TAO_match_origin.html'; >+ >+ const frameContext = document.getElementById('frameContext'); >+ frameContext.onload = onload_test; >+ frameContext.src = destUrl; >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_eventually-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_eventually-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2e870b45deb43f7c5e667f96aa89c39c1259f0b8 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_eventually-expected.txt >@@ -0,0 +1,5 @@ >+#PID UNRESPONSIVE - com.apple.WebKit.WebContent.Development (pid 44894) >+FAIL: Timed out waiting for notifyDone to be called >+ >+#EOF >+#EOF >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_eventually.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_eventually.html >new file mode 100644 >index 0000000000000000000000000000000000000000..7ca8237b02cc398786d78dd61aea3dcb1163d48a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_eventually.html >@@ -0,0 +1,31 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<meta charset="utf-8" /> >+<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> >+<title>This test validates that resource timing implementations have a finite number of entries in their buffer.</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+</head> >+<body> >+<script> >+ const t = async_test("Finite resource timing entries buffer size"); >+ performance.onresourcetimingbufferfull = t.step_func_done(function() { >+ }); >+ window.onload = t.step_func( >+ function() { >+ // Scripts appended in JS to ensure setResourceTimingBufferSize is called before. >+ let counter = performance.getEntriesByType("resource").length; >+ function appendScript() { >+ const src = "resources/empty.js?" + counter; >+ const script = document.createElement('script'); >+ script.type = 'text/javascript'; >+ script.onload = function() { ++counter; appendScript()}; >+ script.src = src; >+ document.body.appendChild(script); >+ } >+ appendScript(); >+ }); >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_when_populate_entries-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_when_populate_entries-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..63b25cf06793b484f46c8c61d2cd87e4b8fdc60d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_when_populate_entries-expected.txt >@@ -0,0 +1,4 @@ >+ >+PASS There should only be |bufferSize| resource entries. >+PASS onresourcetimingbufferfull should have been invoked once buffer is full. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_when_populate_entries.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_when_populate_entries.html >new file mode 100644 >index 0000000000000000000000000000000000000000..3e62b199a32b1cb7ff5eafc7fc690b379409b660 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_when_populate_entries.html >@@ -0,0 +1,41 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<meta charset="utf-8" /> >+<link rel="author" title="Intel" href="http://www.intel.com/" /> >+<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> >+<title>This test validates the functionality of onresourcetimingbufferfull in resource timing.</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+</head> >+<body onload=onload_test()> >+<script> >+ const context = new PerformanceContext(performance); >+ const bufferSize = 5; >+ context.setResourceTimingBufferSize(bufferSize); >+ let bufferFullCount = 0; >+ function buffer_full_callback() { >+ bufferFullCount++; >+ } >+ context.registerResourceTimingBufferFullCallback(buffer_full_callback); >+ // Scripts appended in JS to ensure setResourceTimingBufferSize is called before. >+ function appendScript(src) { >+ const script = document.createElement('script'); >+ script.type = 'text/javascript'; >+ script.src = src; >+ document.body.appendChild(script); >+ } >+ appendScript('resources/empty.js'); >+ appendScript('resources/empty_script.js'); >+ appendScript('resources/resource_timing_test0.js'); >+ setup({ explicit_done: true }); >+ function onload_test() { >+ test_equals(context.getEntriesByType('resource').length, bufferSize, 'There should only be |bufferSize| resource entries.'); >+ test_equals(bufferFullCount, 1, 'onresourcetimingbufferfull should have been invoked once buffer is full.'); >+ done(); >+ } >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_when_shrink_buffer_size-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_when_shrink_buffer_size-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..e125414e69cf541e7f23d892ffccedf8164acb8a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_when_shrink_buffer_size-expected.txt >@@ -0,0 +1,4 @@ >+ >+PASS There are 4 scripts, and setResourceTimingBufferSize does not reduce the size. >+PASS onresourcetimingbufferfull should not be invoked during setResourceTimingBufferSize. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_when_shrink_buffer_size.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_when_shrink_buffer_size.html >new file mode 100644 >index 0000000000000000000000000000000000000000..e42c19d05e081ec3673606b4f0d686f0e69e65d8 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_when_shrink_buffer_size.html >@@ -0,0 +1,31 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>This test validates the functionality of onresourcetimingbufferfull in resource timing.</title> >+<link rel="author" title="Intel" href="http://www.intel.com/" /> >+<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+<script> >+ const context = new PerformanceContext(performance); >+ let bufferFullCount = 0; >+ function buffer_full_call_back() { >+ bufferFullCount++; >+ } >+ context.registerResourceTimingBufferFullCallback(buffer_full_call_back); >+ setup({ explicit_done: true }); >+ function onload_test() { >+ context.setResourceTimingBufferSize(3); >+ context.setResourceTimingBufferSize(0); >+ test_equals(context.getEntriesByType('resource').length, 4, 'There are 4 scripts, and setResourceTimingBufferSize does not reduce the size.'); >+ test_equals(bufferFullCount, 0, 'onresourcetimingbufferfull should not be invoked during setResourceTimingBufferSize.'); >+ done(); >+ } >+</script> >+</head> >+<body onload=onload_test()> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_cross_origin_redirect-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_cross_origin_redirect-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..f3cae8347eb0f2877035bc2e4243dab8567477d6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_cross_origin_redirect-expected.txt >@@ -0,0 +1,6 @@ >+Blocked access to external URL http://www.localhost:8800/resource-timing/resources/blank_page_green.htm >+ >+ >+Harness Error (TIMEOUT), message = null >+ >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_cross_origin_redirect.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_cross_origin_redirect.html >new file mode 100644 >index 0000000000000000000000000000000000000000..9342f5b88389d2bf0f831dcf669192f5644024d5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_cross_origin_redirect.html >@@ -0,0 +1,46 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>This test validates the values in resource timing for a cross-origin redirect.</title> >+<link rel="author" title="Intel" href="http://www.intel.com/" /> >+<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+ >+<script> >+ setup({explicit_done: true}); >+ function onload_test() { >+ const context = new PerformanceContext(performance); >+ const entry = context.getEntriesByName(document.getElementById('frameContext').src, 'resource')[0]; >+ >+ test_equals(entry.redirectStart, 0, 'redirectStart should be 0 in cross-origin redirect.'); >+ test_equals(entry.redirectEnd, 0, 'redirectEnd should be 0 in cross-origin redirect.'); >+ test_equals(entry.domainLookupStart, 0, 'domainLookupStart should be 0 in cross-origin redirect.'); >+ test_equals(entry.domainLookupEnd, 0, 'domainLookupEnd should be 0 in cross-origin redirect.'); >+ test_equals(entry.connectStart, 0, 'connectStart should be 0 in cross-origin redirect.'); >+ test_equals(entry.connectEnd, 0, 'connectEnd should be 0 in cross-origin redirect.'); >+ test_equals(entry.requestStart, 0, 'requestStart should be 0 in cross-origin redirect.'); >+ test_equals(entry.responseStart, 0, 'responseStart should be 0 in cross-origin redirect.'); >+ test_equals(entry.secureConnectionStart, 0, 'secureConnectionStart should be 0 in cross-origin redirect.'); >+ test_greater_than(entry.fetchStart, 0, 'fetchStart should be greater than 0 in cross-origin redirect.'); >+ test_greater_than(entry.responseEnd, 0, 'responseEnd should be greater than 0 in cross-origin redirect.'); >+ done(); >+ } >+</script> >+</head> >+<body> >+<iframe id="frameContext" src="" style="width: 250px; height: 250px;"></iframe> >+<script> >+ let destUrl = '/common/redirect.py?location='; >+ // Add www to get a cross origin frame. >+ destUrl += 'http://www.' + document.location.host + '/resource-timing/resources/blank_page_green.htm'; >+ >+ const frameContext = document.getElementById('frameContext'); >+ frameContext.onload = onload_test; >+ frameContext.src = destUrl; >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_cross_origin_redirect_chain-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_cross_origin_redirect_chain-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..b46f1b5edfd71f8d79f3089681d999b178ea5799 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_cross_origin_redirect_chain-expected.txt >@@ -0,0 +1,10 @@ >+Blocked access to external URL http://www.localhost:8800/resource-timing/resources/multi_redirect.py?page_origin=http://localhost:8800&cross_origin=http://www.localhost:8800 >+CONSOLE MESSAGE: line 26: TypeError: undefined is not an object (evaluating 'entry.redirectStart') >+ >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'entry.redirectStart') >+ >+PASS window.performance is defined >+PASS window.performance.getEntriesByName is defined >+FAIL There should be one entry. assert_equals: There should be one entry. expected 1 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_cross_origin_redirect_chain.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_cross_origin_redirect_chain.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2a7b2f7ce64152f932a3ee7dea9781acac92efe6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_cross_origin_redirect_chain.html >@@ -0,0 +1,46 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>This test validates resource timing information for a cross-origin redirect chain.</title> >+<link rel="author" title="Intel" href="http://www.intel.com/" /> >+<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+ >+<script> >+ setup({explicit_done: true}); >+ test_namespace('getEntriesByName'); >+ const pageOrigin = document.location.host; >+ const crossOrigin = 'www.' + pageOrigin; >+ >+ function onload_test() >+ { >+ const context = new PerformanceContext(performance); >+ const entries = context.getEntriesByName(document.getElementById('frameContext').src, 'resource'); >+ test_equals(entries.length, 1, 'There should be one entry.'); >+ const entry = entries[0]; >+ >+ test_equals(entry.redirectStart, 0, 'redirectStart == 0 in cross-origin redirect.'); >+ test_equals(entry.redirectEnd, 0, 'redirectEnd == 0 in cross-origin redirect.'); >+ test_greater_than(entry.fetchStart, 0, 'fetchStart > 0 in cross-origin redirect.'); >+ test_equals(entry.startTime, entry.fetchStart, 'startTime == fetchStart in cross-origin redirect.'); >+ done(); >+ } >+</script> >+ >+</head> >+<body> >+<iframe id="frameContext" src="" style="width: 250px; height: 250px;"></iframe> >+<script> >+ let destUrl = 'http://' + crossOrigin + '/resource-timing/resources/multi_redirect.py?'; >+ destUrl += 'page_origin=' + 'http://' + pageOrigin; >+ destUrl += '&cross_origin=' + 'http://' + crossOrigin; >+ const frameContext = document.getElementById('frameContext'); >+ frameContext.onload = onload_test; >+ frameContext.src = destUrl; >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_same_origin_redirect-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_same_origin_redirect-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..c9580a2a3d213bf6601976f058649bb010567f4a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_same_origin_redirect-expected.txt >@@ -0,0 +1,7 @@ >+ >+ >+PASS redirectStart should be greater than 0 in same-origin redirect. >+PASS redirectStart should be equal to startTime in same-origin redirect. >+PASS redirectEnd should be no less than redirectStart in same-origin redirect. >+PASS fetchStart should be no less than redirectEnd in same-origin redirect. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_same_origin_redirect.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_same_origin_redirect.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d9fbf944f6c65b7a247b4764ee39e6aa33bc465d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_same_origin_redirect.html >@@ -0,0 +1,39 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>This test validates the values of the redirectStart/End in resource timing for a same-origin resource redirect.</title> >+<link rel="author" title="Intel" href="http://www.intel.com/" /> >+<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+ >+<script> >+ setup({explicit_done: true}); >+ function onload_test() { >+ const context = new PerformanceContext(performance); >+ const entry = context.getEntriesByName(document.getElementById('frameContext').src, 'resource')[0]; >+ >+ test_greater_than(entry.redirectStart, 0, 'redirectStart should be greater than 0 in same-origin redirect.'); >+ test_equals(entry.redirectStart, entry.startTime, 'redirectStart should be equal to startTime in same-origin redirect.'); >+ test_noless_than(entry.redirectEnd, entry.redirectStart, 'redirectEnd should be no less than redirectStart in same-origin redirect.'); >+ test_noless_than(entry.fetchStart, entry.redirectEnd, 'fetchStart should be no less than redirectEnd in same-origin redirect.'); >+ done(); >+ } >+</script> >+ >+</head> >+<body> >+<iframe id="frameContext" src="" style="width: 250px; height: 250px;"></iframe> >+<script> >+ let destUrl = '/common/redirect.py'; >+ destUrl += '?location=/resource-timing/resources/blank_page_green.htm'; >+ >+ const frameContext = document.getElementById('frameContext'); >+ frameContext.onload = onload_test; >+ frameContext.src = destUrl; >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_store_and_clear_during_callback-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_store_and_clear_during_callback-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..5d7ca6278e0d8000ff23cb8ba973c8e51e926437 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_store_and_clear_during_callback-expected.txt >@@ -0,0 +1,11 @@ >+ >+FAIL No entry should be stored in resource timing buffer since its cleared once an item arrived. assert_equals: No entry should be stored in resource timing buffer since its cleared once an item arrived. expected 0 but got 1 >+PASS 6 resource timing entries should be moved to global buffer. >+FAIL http://localhost:8800/resource-timing/resources/empty.js is not expected to be in the Resource Timing buffer assert_unreached: Reached unreachable code >+PASS http://localhost:8800/resource-timing/resources/empty_script.js is expected to have initiatorType script >+PASS http://localhost:8800/resource-timing/resources/webperftestharness.js is expected to have initiatorType script >+PASS http://localhost:8800/resource-timing/resources/webperftestharnessextension.js is expected to have initiatorType script >+PASS http://localhost:8800/resources/testharness.js is expected to have initiatorType script >+PASS http://localhost:8800/resources/testharnessreport.js is expected to have initiatorType script >+FAIL http://localhost:8800/resource-timing/resources/resource_timing_test0.js is expected to be in the Resource Timing buffer assert_unreached: Reached unreachable code >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_store_and_clear_during_callback.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_store_and_clear_during_callback.html >new file mode 100644 >index 0000000000000000000000000000000000000000..218fc0c2bcd5f987c2aee511bb66fd338476215f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_store_and_clear_during_callback.html >@@ -0,0 +1,56 @@ >+<!DOCTYPE HTML> >+<html> >+<head onload> >+<meta charset="utf-8" /> >+<title>This test validates the behavior of read and clear operation in onresourcetimingbufferfull callback of resource timing.</title> >+<link rel="author" title="Intel" href="http://www.intel.com/" /> >+<link rel="help" href="http://www.w3.org/TR/resource-timing/#performanceresourcetiming"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+</head> >+<body onload=onload_test()> >+<script> >+ const context = new PerformanceContext(performance); >+ const resource_timing_buffer_size = 1; >+ let global_buffer = []; >+ function store_and_clear() { >+ const entryList = context.getEntriesByType('resource'); >+ entryList.forEach(function (entry) { >+ global_buffer.push(entry); >+ }); >+ context.clearResourceTimings(); >+ } >+ context.registerResourceTimingBufferFullCallback(store_and_clear); >+ context.setResourceTimingBufferSize(resource_timing_buffer_size); >+ // Scripts appended in JS to ensure setResourceTimingBufferSize is called before. >+ function appendScript(src) { >+ const script = document.createElement('script'); >+ script.type = 'text/javascript'; >+ script.src = src; >+ document.body.appendChild(script); >+ } >+ appendScript('resources/empty.js'); >+ appendScript('resources/empty_script.js'); >+ appendScript('resources/resource_timing_test0.js'); >+ setup({ explicit_done: true }); >+ function onload_test() { >+ test_equals(context.getEntriesByType('resource').length, 0, 'No entry should be stored in resource timing buffer since its cleared once an item arrived.'); >+ // The entry for empty.js must not be in the global buffer, but all others should be. >+ test_equals(global_buffer.length, 6, '6 resource timing entries should be moved to global buffer.'); >+ const index = window.location.pathname.lastIndexOf('resource-timing'); >+ const pathname = window.location.pathname.substring(0, index); >+ let expected_entries = {}; >+ expected_entries[pathname + 'resources/testharness.js'] = 'script'; >+ expected_entries[pathname + 'resources/testharnessreport.js'] = 'script'; >+ expected_entries[pathname + 'resource-timing/resources/webperftestharness.js'] = 'script'; >+ expected_entries[pathname + 'resource-timing/resources/webperftestharnessextension.js'] = 'script'; >+ expected_entries[pathname + 'resource-timing/resources/empty_script.js'] = 'script'; >+ expected_entries[pathname + 'resource-timing/resources/resource_timing_test0.js'] = 'script'; >+ test_resource_entries(global_buffer, expected_entries); >+ done(); >+ } >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/TAOResponse.py b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/TAOResponse.py >index cc8fa5f0f93f5d80d008eed91c1c809af4820eef..dcd75a415457333cf6188330115d021f0d7c31c9 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/TAOResponse.py >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/TAOResponse.py >@@ -20,19 +20,19 @@ def main(request, response): > # space seperated list of origin and wildcard, fail > response.headers.set('Timing-Allow-Origin', (origin + ' *')) > elif tao == 'multi': >- # more than one TAO values, seperated by common, pass >+ # more than one TAO values, seperated by comma, pass > response.headers.set('Timing-Allow-Origin', origin) > response.headers.append('Timing-Allow-Origin', '*') > elif tao == 'match_origin': >- # contains a match of origin, seperated by common, pass >+ # contains a match of origin, seperated by comma, pass > response.headers.set('Timing-Allow-Origin', origin) > response.headers.append('Timing-Allow-Origin', "fake") > elif tao == 'match_wildcard': >- # contains a wildcard, seperated by common, pass >+ # contains a wildcard, seperated by comma, pass > response.headers.set('Timing-Allow-Origin', "fake") > response.headers.append('Timing-Allow-Origin', '*') > elif tao == 'uppercase': > # non-case-sensitive match for origin, fail > response.headers.set('Timing-Allow-Origin', origin.upper()) > else: >- pass >\ No newline at end of file >+ pass >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/all_resource_types.htm b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/all_resource_types.htm >new file mode 100644 >index 0000000000000000000000000000000000000000..bc7101c219230376ffec008dce73bc42f06cbe3f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/all_resource_types.htm >@@ -0,0 +1,107 @@ >+<!DOCTYPE HTML> >+<html> >+ <head> >+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> >+ <title>All Resource Types Test Page</title> >+ <link rel="shortcut icon" href="empty.py?favicon"> >+ </head> >+ <body background='blue.png?id=body'> >+ <script> >+ if (window.parent.hasOwnProperty('on_test_body_created')) >+ window.parent.on_test_body_created(); >+ </script> >+ <link rel="stylesheet" href="nested.css"></link> >+ <link rel="prefetch" href="nested.css?id=prefetch"></link> >+ <link rel="preload" href="nested.css?id=preload" as="style"></link> >+ <link rel="prerender" href="blank_page_green.htm?id=prerender"></link> >+ <link rel="manifest" href="manifest.json"></link> >+ <img src="resource_timing_test0.png"></img> >+ <img src="resource_timing_test0.png?id=srcset-src" >+ srcset="resource_timing_test0.png?id=srcset-srcset 67w" >+ sizes="67px"></img> >+ <iframe src="blank_page_green.htm" width="100px" height="100px"></iframe> >+ <script src="empty_script.js"></script> >+ <script> >+ var async_xhr = new XMLHttpRequest; >+ async_xhr.open('GET', 'blue.png?id=async_xhr', true); >+ async_xhr.onreadystatechange = function() { >+ if (async_xhr.readyState == 4 && async_xhr.status == 200 && parent.hasOwnProperty('on_async_xhr_done')) >+ parent.on_async_xhr_done(); >+ } >+ async_xhr.send(); >+ >+ if (window.navigator && navigator.sendBeacon) { >+ navigator.sendBeacon('empty.py?id=beacon'); >+ } >+ >+ if (window.fetch) { >+ fetch('empty.py?id=fetch'); >+ } >+ >+ if (window.EventSource) { >+ var evtSource = new EventSource('eventsource.py?id=eventsource'); >+ } >+ </script> >+ <style> >+ @font-face { >+ font-family: remoteFontAhem; >+ src: url('/fonts/Ahem.ttf'); >+ } >+ iframe { >+ background: url('blue.png?id=1'); >+ } >+ body { >+ cursor: url('blue.png?id=cursor'), pointer; >+ } >+ ul { >+ font-family: remoteFontAhem; >+ list-style-image: url('blue.png?id=2'); >+ } >+ </style> >+ <ul> >+ <li>Test</li> >+ </ul> >+ <ol> >+ <li>Test</li> >+ </ol> >+ <embed src="resource_timing_test0.css?id=embed" type="text/css"></embed> >+ <input type="image" src="blue.png?id=input"></input> >+ <object type="image/png" data="blue.png?id=object"></object> >+ <video poster="blue.png?id=video-poster"></video> >+ <video src="/media/test.mp4?id=video-src" autoplay="true"></video> >+ <video autoplay="true"> >+ <source src="/media/test.mp4?id=video-source" type="video/mp4"> >+ <source src="/media/test.ogv?id=video-source" type="video/ogg"> >+ <track kind="subtitles" src="empty.py?id=video-track" srclang="en" default> >+ </video> >+ <audio src="empty.py?id=audio-src"></audio> >+ <audio> >+ <source src="empty.py?id=audio-source-wav" type="audio/wav" /> >+ <source src="empty.py?id=audio-source-mpeg" type="audio/mpeg" /> >+ <source src="empty.py?id=audio-source-ogg" type="audio/ogg" /> >+ </audio> >+ <svg width=200 height=200 >+ xmlns="http://www.w3.org/2000/svg" >+ xmlns:xlink="http://www.w3.org/1999/xlink"> >+ <image href="blue.png?id=svg-image" height="200" width="200"/> >+ </svg> >+ <picture> >+ <source srcset="blue.png?id=picture-source" type="image/png" /> >+ <img src="blue.png?id=picture-img" /> >+ </picture> >+ <picture> >+ <source srcset="blue.png?id=picture-notsupported-source" type="image/notsupported" /> >+ <img src="blue.png?id=picture-notsupported-img" /> >+ </picture> >+ <picture> >+ <img src="blue.png?id=picture-img-src" >+ srcset="blue.png?id=picture-img-srcset" >+ sizes="67px"></img> >+ </picture> >+ <picture> >+ <img src="blue.png?id=picture-99x-img-src" >+ srcset="blue.png?id=picture-99x-img-srcset 99x" >+ sizes="67px"></img> >+ </picture> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/blank_page_green.htm b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/blank_page_green.htm >new file mode 100644 >index 0000000000000000000000000000000000000000..b8a1947b77e25ac6b0d100c75932e8c0a67d846f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/blank_page_green.htm >@@ -0,0 +1,10 @@ >+<!DOCTYPE HTML> >+<html> >+ <head> >+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> >+ <title>Green Test Page</title> >+ </head> >+ <body style="background-color:#00FF00;"> >+ <h1>Placeholder</h1> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/empty.js b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/empty.js >new file mode 100644 >index 0000000000000000000000000000000000000000..3b44754e301ded90e559f6343df641e476803542 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/empty.js >@@ -0,0 +1 @@ >+/* Nothing here */ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/empty.py b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/empty.py >new file mode 100644 >index 0000000000000000000000000000000000000000..e5ccfbe9739b1b1069200951509c1b664733066f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/empty.py >@@ -0,0 +1,3 @@ >+def main(request, response): >+ response.headers.set("Content-Type", "text/plain") >+ return "" >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/empty_script.js b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/empty_script.js >new file mode 100644 >index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/eventsource.py b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/eventsource.py >new file mode 100644 >index 0000000000000000000000000000000000000000..5095ea9b34ffab7ca7e2f05dae316ce249cf651d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/eventsource.py >@@ -0,0 +1,3 @@ >+def main(request, response): >+ response.headers.set("Content-Type", "text/event-stream") >+ return "" >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/green_frame.htm b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/green_frame.htm >new file mode 100644 >index 0000000000000000000000000000000000000000..f3f03245dcc8bde7e969d7682d03c9b89bcb4a1c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/green_frame.htm >@@ -0,0 +1,7 @@ >+<html> >+ <head> >+ <frameset> >+ <frame src="blank_page_green.htm?id=frame"> >+ </frameset> >+ </head> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/multi_redirect.py b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/multi_redirect.py >new file mode 100644 >index 0000000000000000000000000000000000000000..d1802a1e02d9aacad091e814cc2955d244d2f977 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/multi_redirect.py >@@ -0,0 +1,40 @@ >+def main(request, response): >+ """Handler that causes multiple redirections. >+ The request has two mandatory and one optional query parameters: >+ page_origin - The page origin, used for redirection and to set TAO. This is a mandatory parameter. >+ cross_origin - The cross origin used to make this a cross-origin redirect. This is a mandatory parameter. >+ timing_allow - Whether TAO should be set or not in the redirect chain. This is an optional parameter. Default: not set. >+ Note that |step| is a parameter used internally for the multi-redirect. It's the step we're at in the redirect chain. >+ """ >+ step = 1 >+ if "step" in request.GET: >+ try: >+ step = int(request.GET.first("step")) >+ except ValueError: >+ pass >+ >+ page_origin = request.GET.first("page_origin") >+ cross_origin = request.GET.first("cross_origin") >+ timing_allow = "0" >+ if "timing_allow" in request.GET: >+ timing_allow = request.GET.first("timing_allow") >+ >+ redirect_url = "/resource-timing/resources/multi_redirect.py?" >+ redirect_url += "page_origin=" + page_origin >+ redirect_url += "&cross_origin=" + cross_origin >+ redirect_url += "&timing_allow=" + timing_allow >+ redirect_url += "&step=" >+ >+ if step == 1: >+ redirect_url = cross_origin + redirect_url + "2" >+ if timing_allow != "0": >+ response.headers.set("timing-allow-origin", page_origin) >+ elif step == 2: >+ redirect_url = page_origin + redirect_url + "3" >+ if timing_allow != "0": >+ response.headers.set("timing-allow-origin", page_origin) >+ else: >+ redirect_url = page_origin + "/resource-timing/resources/blank_page_green.htm" >+ >+ response.status = 302 >+ response.headers.set("Location", redirect_url) >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/nested.css b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/nested.css >new file mode 100644 >index 0000000000000000000000000000000000000000..90d61b04acc4443430c42331d8c7f21993b0ae4d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/nested.css >@@ -0,0 +1,10 @@ >+@import "resource_timing_test0.css?id=n1"; >+ >+@font-face { >+ font-family: remoteFont; >+ src: url('/fonts/Ahem.ttf?id=n1'); >+} >+ol { >+ font-family: remoteFont; >+ list-style-image: url('blue.png?id=n1'); >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/notify_parent.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/notify_parent.html >new file mode 100644 >index 0000000000000000000000000000000000000000..c104f3c8f0695a96646cf24a730eef0342f95876 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/notify_parent.html >@@ -0,0 +1,4 @@ >+<!DOCTYPE html> >+<script> >+window.parent.subFrameLoaded(); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/self_navigation.html b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/self_navigation.html >new file mode 100644 >index 0000000000000000000000000000000000000000..beb12f5da551780fcb4378bef4661b9699a5d009 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/self_navigation.html >@@ -0,0 +1 @@ >+<meta http-equiv="refresh" content="0;url=notify_parent.html?redirected"> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/worker_with_images.js b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/worker_with_images.js >new file mode 100644 >index 0000000000000000000000000000000000000000..2d7688fcf9941a23bb75ef20abc93211fc224ca5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/worker_with_images.js >@@ -0,0 +1,21 @@ >+let numComplete = 0; >+ >+function checkDone() { >+ ++numComplete; >+ if (numComplete == 2) { >+ postMessage(''); >+ } >+} >+ >+function makeRequest(request) { >+ var xhr = new XMLHttpRequest; >+ xhr.open('get', request, true); >+ xhr.onreadystatechange = function() { >+ if (xhr.readyState == 4) { >+ checkDone(); >+ } >+ } >+ xhr.send(); >+} >+makeRequest('blue.png'); >+makeRequest('resource_timing_test0.png'); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/w3c-import.log >index 8d53a8b8b63bab52551e546bc5001176eac0144e..dba2dbde26d5a9449e9a024e13153309a2a9a5e8 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resource-timing/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/resource-timing/w3c-import.log >@@ -16,10 +16,13 @@ None > List of files: > /LayoutTests/imported/w3c/web-platform-tests/resource-timing/OWNERS > /LayoutTests/imported/w3c/web-platform-tests/resource-timing/SyntheticResponse.py >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/clear_resource_timing_functionality.html > /LayoutTests/imported/w3c/web-platform-tests/resource-timing/idlharness.html > /LayoutTests/imported/w3c/web-platform-tests/resource-timing/iframe-setdomain.sub.html >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource-timing-tojson.html > /LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource-timing.html > /LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource-timing.js >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_TAO_cross_origin_redirect_chain.html > /LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_TAO_match_origin.htm > /LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_TAO_match_wildcard.htm > /LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_TAO_multi.htm >@@ -31,7 +34,25 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_TAO_zero.htm > /LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_cached.htm > /LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_connection_reuse.html >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_dedicated_worker.html > /LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_dynamic_insertion.html >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_ignore_data_url.html >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_ignore_failures.html >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_initiator_types.html >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_memory_cached.sub.html >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_redirects.html >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_reparenting.html >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_script_types.html >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_subframe_self_navigation.html >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing.worker.js >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_TAO_cross_origin_redirect.html >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_eventually.html >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_when_populate_entries.html >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_buffer_full_when_shrink_buffer_size.html >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_cross_origin_redirect.html >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_cross_origin_redirect_chain.html >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_same_origin_redirect.html >+/LayoutTests/imported/w3c/web-platform-tests/resource-timing/resource_timing_store_and_clear_during_callback.html > /LayoutTests/imported/w3c/web-platform-tests/resource-timing/single-entry-per-resource.html > /LayoutTests/imported/w3c/web-platform-tests/resource-timing/test_resource_timing.html > /LayoutTests/imported/w3c/web-platform-tests/resource-timing/test_resource_timing.js >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/check-layout-th.js b/LayoutTests/imported/w3c/web-platform-tests/resources/check-layout-th.js >index 3f257d4ac250e5f592bd463fb2a0d6a9f0fb0c8e..928b0cf2a1041ecb831fadb44943e8907a29b872 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/check-layout-th.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/check-layout-th.js >@@ -161,16 +161,16 @@ function checkExpectedValues(t, node, prefix) > return output.checked; > } > >-window.checkLayout = function(selectorList, outputContainer) >+var testNumber = 0; >+ >+window.checkLayout = function(selectorList, callDone = true) > { > if (!selectorList) { > console.error("You must provide a CSS selector of nodes to check."); > return; > } > var nodes = document.querySelectorAll(selectorList); >- var testNumber = 0; > nodes = Array.prototype.slice.call(nodes); >- nodes.reverse(); > var checkedLayout = false; > Array.prototype.forEach.call(nodes, function(node) { > test(function(t) { >@@ -189,7 +189,8 @@ window.checkLayout = function(selectorList, outputContainer) > if (!checkedLayout) { > console.error("No valid data-* attributes found in selector list : " + selectorList); > } >- done(); >+ if (callDone) >+ done(); > }; > > })(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/chooser_service.mojom.js b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/chooser_service.mojom.js >index 30bba4baad9bb88913d4b39ec545eb936a968f4c..fd344e71faf7806a8ee687bd2049537b26e89ae2 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/chooser_service.mojom.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/chooser_service.mojom.js >@@ -2,19 +2,15 @@ > // Use of this source code is governed by a BSD-style license that can be > // found in the LICENSE file. > >- > 'use strict'; > > (function() { >- var mojomId = 'device/usb/public/interfaces/chooser_service.mojom'; >+ var mojomId = 'device/usb/public/mojom/chooser_service.mojom'; > if (mojo.internal.isMojomLoaded(mojomId)) { > console.warn('The following mojom is loaded multiple times: ' + mojomId); > return; > } > mojo.internal.markMojomLoaded(mojomId); >- >- // TODO(yzshen): Define these aliases to minimize the differences between the >- // old/new modes. Remove them when the old mode goes away. > var bindings = mojo; > var associatedBindings = mojo; > var codec = mojo.internal; >@@ -25,13 +21,13 @@ > mojo.internal.exposeNamespace('device.mojom'); > if (mojo.config.autoLoadMojomDeps) { > mojo.internal.loadMojomIfNecessary( >- 'device/usb/public/interfaces/device.mojom', 'device.mojom.js'); >+ 'device/usb/public/mojom/device.mojom', 'device.mojom.js'); > } > var device_manager$ = > mojo.internal.exposeNamespace('device.mojom'); > if (mojo.config.autoLoadMojomDeps) { > mojo.internal.loadMojomIfNecessary( >- 'device/usb/public/interfaces/device_manager.mojom', 'device_manager.mojom.js'); >+ 'device/usb/public/mojom/device_manager.mojom', 'device_manager.mojom.js'); > } > > >@@ -66,7 +62,6 @@ > return err; > > >- > // validate UsbChooserService_GetPermission_Params.deviceFilters > err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, new codec.PointerTo(device_manager$.UsbDeviceFilter), false, [0], 0); > if (err !== validator.validationError.NONE) >@@ -122,7 +117,6 @@ > return err; > > >- > // validate UsbChooserService_GetPermission_ResponseParams.result > err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, device$.UsbDeviceInfo, true); > if (err !== validator.validationError.NONE) >@@ -263,7 +257,7 @@ > } > > var UsbChooserService = { >- name: 'device::mojom::UsbChooserService', >+ name: 'device.mojom.UsbChooserService', > kVersion: 0, > ptrClass: UsbChooserServicePtr, > proxyClass: UsbChooserServiceProxy, >@@ -276,4 +270,4 @@ > exports.UsbChooserService = UsbChooserService; > exports.UsbChooserServicePtr = UsbChooserServicePtr; > exports.UsbChooserServiceAssociatedPtr = UsbChooserServiceAssociatedPtr; >-})(); >\ No newline at end of file >+})(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/device.mojom.js b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/device.mojom.js >index ce5660cd52edae6571d22d31430f4fe0b5d1697b..435fc1fc7addabfddb093e003795512c28360357 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/device.mojom.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/device.mojom.js >@@ -2,19 +2,15 @@ > // Use of this source code is governed by a BSD-style license that can be > // found in the LICENSE file. > >- > 'use strict'; > > (function() { >- var mojomId = 'device/usb/public/interfaces/device.mojom'; >+ var mojomId = 'device/usb/public/mojom/device.mojom'; > if (mojo.internal.isMojomLoaded(mojomId)) { > console.warn('The following mojom is loaded multiple times: ' + mojomId); > return; > } > mojo.internal.markMojomLoaded(mojomId); >- >- // TODO(yzshen): Define these aliases to minimize the differences between the >- // old/new modes. Remove them when the old mode goes away. > var bindings = mojo; > var associatedBindings = mojo; > var codec = mojo.internal; >@@ -25,7 +21,7 @@ > mojo.internal.exposeNamespace('mojo.common.mojom'); > if (mojo.config.autoLoadMojomDeps) { > mojo.internal.loadMojomIfNecessary( >- 'mojo/common/string16.mojom', '../../../../mojo/common/string16.mojom.js'); >+ 'mojo/public/mojom/base/string16.mojom', '../../../../mojo/public/mojom/base/string16.mojom.js'); > } > > >@@ -212,14 +208,12 @@ > > > >- > // validate UsbEndpointInfo.direction > err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 4, UsbTransferDirection); > if (err !== validator.validationError.NONE) > return err; > > >- > // validate UsbEndpointInfo.type > err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 8, UsbTransferType); > if (err !== validator.validationError.NONE) >@@ -297,14 +291,12 @@ > > > >- > // validate UsbAlternateInterfaceInfo.interfaceName > err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, string16$.String16, true); > if (err !== validator.validationError.NONE) > return err; > > >- > // validate UsbAlternateInterfaceInfo.endpoints > err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 16, 8, new codec.PointerTo(UsbEndpointInfo), false, [0], 0); > if (err !== validator.validationError.NONE) >@@ -380,7 +372,6 @@ > > > >- > // validate UsbInterfaceInfo.alternates > err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 8, new codec.PointerTo(UsbAlternateInterfaceInfo), false, [0], 0); > if (err !== validator.validationError.NONE) >@@ -455,14 +446,12 @@ > > > >- > // validate UsbConfigurationInfo.configurationName > err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, string16$.String16, true); > if (err !== validator.validationError.NONE) > return err; > > >- > // validate UsbConfigurationInfo.interfaces > err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 16, 8, new codec.PointerTo(UsbInterfaceInfo), false, [0], 0); > if (err !== validator.validationError.NONE) >@@ -552,7 +541,6 @@ > return err; > > >- > // validate UsbDeviceInfo.guid > err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) > if (err !== validator.validationError.NONE) >@@ -570,21 +558,18 @@ > > > >- > // validate UsbDeviceInfo.manufacturerName > err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 24, string16$.String16, true); > if (err !== validator.validationError.NONE) > return err; > > >- > // validate UsbDeviceInfo.productName > err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 32, string16$.String16, true); > if (err !== validator.validationError.NONE) > return err; > > >- > // validate UsbDeviceInfo.serialNumber > err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 40, string16$.String16, true); > if (err !== validator.validationError.NONE) >@@ -592,7 +577,6 @@ > > > >- > // validate UsbDeviceInfo.configurations > err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 48, 8, new codec.PointerTo(UsbConfigurationInfo), false, [0], 0); > if (err !== validator.validationError.NONE) >@@ -688,14 +672,12 @@ > return err; > > >- > // validate UsbControlTransferParams.type > err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, UsbControlTransferType); > if (err !== validator.validationError.NONE) > return err; > > >- > // validate UsbControlTransferParams.recipient > err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 4, UsbControlTransferRecipient); > if (err !== validator.validationError.NONE) >@@ -772,7 +754,6 @@ > > > >- > // validate UsbIsochronousPacket.status > err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 8, UsbTransferStatus); > if (err !== validator.validationError.NONE) >@@ -886,7 +867,6 @@ > return err; > > >- > // validate UsbDevice_Open_ResponseParams.error > err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, UsbOpenDeviceError); > if (err !== validator.validationError.NONE) >@@ -1814,7 +1794,6 @@ > return err; > > >- > // validate UsbDevice_ControlTransferIn_Params.params > err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, UsbControlTransferParams, false); > if (err !== validator.validationError.NONE) >@@ -1877,16 +1856,14 @@ > return err; > > >- > // validate UsbDevice_ControlTransferIn_ResponseParams.status > err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, UsbTransferStatus); > if (err !== validator.validationError.NONE) > return err; > > >- > // validate UsbDevice_ControlTransferIn_ResponseParams.data >- err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 1, codec.Uint8, true, [0], 0); >+ err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 1, codec.Uint8, false, [0], 0); > if (err !== validator.validationError.NONE) > return err; > >@@ -1952,14 +1929,12 @@ > return err; > > >- > // validate UsbDevice_ControlTransferOut_Params.params > err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, UsbControlTransferParams, false); > if (err !== validator.validationError.NONE) > return err; > > >- > // validate UsbDevice_ControlTransferOut_Params.data > err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 1, codec.Uint8, false, [0], 0); > if (err !== validator.validationError.NONE) >@@ -2028,7 +2003,6 @@ > return err; > > >- > // validate UsbDevice_ControlTransferOut_ResponseParams.status > err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, UsbTransferStatus); > if (err !== validator.validationError.NONE) >@@ -2165,16 +2139,14 @@ > return err; > > >- > // validate UsbDevice_GenericTransferIn_ResponseParams.status > err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, UsbTransferStatus); > if (err !== validator.validationError.NONE) > return err; > > >- > // validate UsbDevice_GenericTransferIn_ResponseParams.data >- err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 1, codec.Uint8, true, [0], 0); >+ err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 1, codec.Uint8, false, [0], 0); > if (err !== validator.validationError.NONE) > return err; > >@@ -2241,7 +2213,6 @@ > > > >- > // validate UsbDevice_GenericTransferOut_Params.data > err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 1, codec.Uint8, false, [0], 0); > if (err !== validator.validationError.NONE) >@@ -2308,7 +2279,6 @@ > return err; > > >- > // validate UsbDevice_GenericTransferOut_ResponseParams.status > err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, UsbTransferStatus); > if (err !== validator.validationError.NONE) >@@ -2375,7 +2345,6 @@ > > > >- > // validate UsbDevice_IsochronousTransferIn_Params.packetLengths > err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 4, codec.Uint32, false, [0], 0); > if (err !== validator.validationError.NONE) >@@ -2443,14 +2412,12 @@ > return err; > > >- > // validate UsbDevice_IsochronousTransferIn_ResponseParams.data >- err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 1, codec.Uint8, true, [0], 0); >+ err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 1, codec.Uint8, false, [0], 0); > if (err !== validator.validationError.NONE) > return err; > > >- > // validate UsbDevice_IsochronousTransferIn_ResponseParams.packets > err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 8, new codec.PointerTo(UsbIsochronousPacket), false, [0], 0); > if (err !== validator.validationError.NONE) >@@ -2512,14 +2479,12 @@ > > > >- > // validate UsbDevice_IsochronousTransferOut_Params.data > err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 1, codec.Uint8, false, [0], 0); > if (err !== validator.validationError.NONE) > return err; > > >- > // validate UsbDevice_IsochronousTransferOut_Params.packetLengths > err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 16, 4, codec.Uint32, false, [0], 0); > if (err !== validator.validationError.NONE) >@@ -2588,7 +2553,6 @@ > return err; > > >- > // validate UsbDevice_IsochronousTransferOut_ResponseParams.packets > err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, new codec.PointerTo(UsbIsochronousPacket), false, [0], 0); > if (err !== validator.validationError.NONE) >@@ -3431,7 +3395,7 @@ > } > > var UsbDevice = { >- name: 'device::mojom::UsbDevice', >+ name: 'device.mojom.UsbDevice', > kVersion: 0, > ptrClass: UsbDevicePtr, > proxyClass: UsbDeviceProxy, >@@ -3457,4 +3421,4 @@ > exports.UsbDevice = UsbDevice; > exports.UsbDevicePtr = UsbDevicePtr; > exports.UsbDeviceAssociatedPtr = UsbDeviceAssociatedPtr; >-})(); >\ No newline at end of file >+})(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/device_manager.mojom.js b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/device_manager.mojom.js >index 99ebd854be03c2721d5f5d07e486cbe21d5737d8..2d76263ba9b7a3608e05c72a8ae2666e20bb376f 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/device_manager.mojom.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/device_manager.mojom.js >@@ -2,19 +2,15 @@ > // Use of this source code is governed by a BSD-style license that can be > // found in the LICENSE file. > >- > 'use strict'; > > (function() { >- var mojomId = 'device/usb/public/interfaces/device_manager.mojom'; >+ var mojomId = 'device/usb/public/mojom/device_manager.mojom'; > if (mojo.internal.isMojomLoaded(mojomId)) { > console.warn('The following mojom is loaded multiple times: ' + mojomId); > return; > } > mojo.internal.markMojomLoaded(mojomId); >- >- // TODO(yzshen): Define these aliases to minimize the differences between the >- // old/new modes. Remove them when the old mode goes away. > var bindings = mojo; > var associatedBindings = mojo; > var codec = mojo.internal; >@@ -25,13 +21,13 @@ > mojo.internal.exposeNamespace('device.mojom'); > if (mojo.config.autoLoadMojomDeps) { > mojo.internal.loadMojomIfNecessary( >- 'device/usb/public/interfaces/device.mojom', 'device.mojom.js'); >+ 'device/usb/public/mojom/device.mojom', 'device.mojom.js'); > } > var string16$ = > mojo.internal.exposeNamespace('mojo.common.mojom'); > if (mojo.config.autoLoadMojomDeps) { > mojo.internal.loadMojomIfNecessary( >- 'mojo/common/string16.mojom', '../../../../mojo/common/string16.mojom.js'); >+ 'mojo/public/mojom/base/string16.mojom', '../../../../mojo/public/mojom/base/string16.mojom.js'); > } > > >@@ -86,7 +82,6 @@ > > > >- > // validate UsbDeviceFilter.serialNumber > err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, string16$.String16, true); > if (err !== validator.validationError.NONE) >@@ -165,7 +160,6 @@ > return err; > > >- > // validate UsbEnumerationOptions.filters > err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, new codec.PointerTo(UsbDeviceFilter), false, [0], 0); > if (err !== validator.validationError.NONE) >@@ -221,7 +215,6 @@ > return err; > > >- > // validate UsbDeviceManager_GetDevices_Params.options > err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, UsbEnumerationOptions, true); > if (err !== validator.validationError.NONE) >@@ -277,7 +270,6 @@ > return err; > > >- > // validate UsbDeviceManager_GetDevices_ResponseParams.results > err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, new codec.PointerTo(device$.UsbDeviceInfo), false, [0], 0); > if (err !== validator.validationError.NONE) >@@ -334,14 +326,12 @@ > return err; > > >- > // validate UsbDeviceManager_GetDevice_Params.guid > err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) > if (err !== validator.validationError.NONE) > return err; > > >- > // validate UsbDeviceManager_GetDevice_Params.deviceRequest > err = messageValidator.validateInterfaceRequest(offset + codec.kStructHeaderSize + 8, false) > if (err !== validator.validationError.NONE) >@@ -407,7 +397,6 @@ > return err; > > >- > // validate UsbDeviceManager_SetClient_Params.client > err = messageValidator.validateInterface(offset + codec.kStructHeaderSize + 0, false); > if (err !== validator.validationError.NONE) >@@ -463,7 +452,6 @@ > return err; > > >- > // validate UsbDeviceManagerClient_OnDeviceAdded_Params.deviceInfo > err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, device$.UsbDeviceInfo, false); > if (err !== validator.validationError.NONE) >@@ -519,7 +507,6 @@ > return err; > > >- > // validate UsbDeviceManagerClient_OnDeviceRemoved_Params.deviceInfo > err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, device$.UsbDeviceInfo, false); > if (err !== validator.validationError.NONE) >@@ -715,7 +702,7 @@ > } > > var UsbDeviceManager = { >- name: 'device::mojom::UsbDeviceManager', >+ name: 'device.mojom.UsbDeviceManager', > kVersion: 0, > ptrClass: UsbDeviceManagerPtr, > proxyClass: UsbDeviceManagerProxy, >@@ -835,7 +822,7 @@ > } > > var UsbDeviceManagerClient = { >- name: 'device::mojom::UsbDeviceManagerClient', >+ name: 'device.mojom.UsbDeviceManagerClient', > kVersion: 0, > ptrClass: UsbDeviceManagerClientPtr, > proxyClass: UsbDeviceManagerClientProxy, >@@ -853,4 +840,4 @@ > exports.UsbDeviceManagerClient = UsbDeviceManagerClient; > exports.UsbDeviceManagerClientPtr = UsbDeviceManagerClientPtr; > exports.UsbDeviceManagerClientAssociatedPtr = UsbDeviceManagerClientAssociatedPtr; >-})(); >\ No newline at end of file >+})(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/fake_bluetooth.mojom.js b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/fake_bluetooth.mojom.js >new file mode 100644 >index 0000000000000000000000000000000000000000..da443362248a1ae60e4412ec48141cce40fe34bf >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/fake_bluetooth.mojom.js >@@ -0,0 +1,5323 @@ >+// Copyright 2014 The Chromium Authors. All rights reserved. >+// Use of this source code is governed by a BSD-style license that can be >+// found in the LICENSE file. >+ >+'use strict'; >+ >+(function() { >+ var mojomId = 'device/bluetooth/public/mojom/test/fake_bluetooth.mojom'; >+ if (mojo.internal.isMojomLoaded(mojomId)) { >+ console.warn('The following mojom is loaded multiple times: ' + mojomId); >+ return; >+ } >+ mojo.internal.markMojomLoaded(mojomId); >+ var bindings = mojo; >+ var associatedBindings = mojo; >+ var codec = mojo.internal; >+ var validator = mojo.internal; >+ >+ var exports = mojo.internal.exposeNamespace('bluetooth.mojom'); >+ var uuid$ = >+ mojo.internal.exposeNamespace('bluetooth.mojom'); >+ if (mojo.config.autoLoadMojomDeps) { >+ mojo.internal.loadMojomIfNecessary( >+ 'device/bluetooth/public/mojom/uuid.mojom', '../uuid.mojom.js'); >+ } >+ >+ >+ var kHCISuccess = 0x0000; >+ var kHCIConnectionTimeout = 0x0008; >+ var kGATTSuccess = 0x0000; >+ var kGATTInvalidHandle = 0x0001; >+ var CentralState = {}; >+ CentralState.ABSENT = 0; >+ CentralState.POWERED_ON = CentralState.ABSENT + 1; >+ CentralState.POWERED_OFF = CentralState.POWERED_ON + 1; >+ >+ CentralState.isKnownEnumValue = function(value) { >+ switch (value) { >+ case 0: >+ case 1: >+ case 2: >+ return true; >+ } >+ return false; >+ }; >+ >+ CentralState.validate = function(enumValue) { >+ var isExtensible = false; >+ if (isExtensible || this.isKnownEnumValue(enumValue)) >+ return validator.validationError.NONE; >+ >+ return validator.validationError.UNKNOWN_ENUM_VALUE; >+ }; >+ >+ function Appearance(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ Appearance.prototype.initDefaults_ = function() { >+ this.hasValue = false; >+ this.value = 0; >+ }; >+ Appearance.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ Appearance.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ Appearance.encodedSize = codec.kStructHeaderSize + 8; >+ >+ Appearance.decode = function(decoder) { >+ var packed; >+ var val = new Appearance(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.hasValue = (packed >> 0) & 1 ? true : false; >+ val.value = decoder.decodeStruct(codec.Int8); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ Appearance.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(Appearance.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.hasValue & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.encodeStruct(codec.Int8, val.value); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function Power(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ Power.prototype.initDefaults_ = function() { >+ this.hasValue = false; >+ this.value = 0; >+ }; >+ Power.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ Power.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ Power.encodedSize = codec.kStructHeaderSize + 8; >+ >+ Power.decode = function(decoder) { >+ var packed; >+ var val = new Power(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.hasValue = (packed >> 0) & 1 ? true : false; >+ val.value = decoder.decodeStruct(codec.Int8); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ Power.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(Power.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.hasValue & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.encodeStruct(codec.Int8, val.value); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function ServiceDataMap(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ ServiceDataMap.prototype.initDefaults_ = function() { >+ this.serviceData = null; >+ }; >+ ServiceDataMap.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ ServiceDataMap.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate ServiceDataMap.serviceData >+ err = messageValidator.validateMapPointer(offset + codec.kStructHeaderSize + 0, false, codec.String, new codec.ArrayOf(codec.Uint8), false); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ ServiceDataMap.encodedSize = codec.kStructHeaderSize + 8; >+ >+ ServiceDataMap.decode = function(decoder) { >+ var packed; >+ var val = new ServiceDataMap(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.serviceData = decoder.decodeMapPointer(codec.String, new codec.ArrayOf(codec.Uint8)); >+ return val; >+ }; >+ >+ ServiceDataMap.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(ServiceDataMap.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeMapPointer(codec.String, new codec.ArrayOf(codec.Uint8), val.serviceData); >+ }; >+ function ScanRecord(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ ScanRecord.prototype.initDefaults_ = function() { >+ this.name = null; >+ this.uuids = null; >+ this.appearance = null; >+ this.txPower = null; >+ this.manufacturerData = null; >+ this.serviceData = null; >+ }; >+ ScanRecord.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ ScanRecord.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 56} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate ScanRecord.name >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, true) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate ScanRecord.uuids >+ err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 8, new codec.PointerTo(uuid$.UUID), true, [0], 0); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate ScanRecord.appearance >+ err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 16, Appearance, false); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate ScanRecord.txPower >+ err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 24, Power, false); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate ScanRecord.manufacturerData >+ err = messageValidator.validateMapPointer(offset + codec.kStructHeaderSize + 32, true, codec.Uint8, new codec.ArrayOf(codec.Uint8), false); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate ScanRecord.serviceData >+ err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 40, ServiceDataMap, true); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ ScanRecord.encodedSize = codec.kStructHeaderSize + 48; >+ >+ ScanRecord.decode = function(decoder) { >+ var packed; >+ var val = new ScanRecord(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.name = decoder.decodeStruct(codec.NullableString); >+ val.uuids = decoder.decodeArrayPointer(new codec.PointerTo(uuid$.UUID)); >+ val.appearance = decoder.decodeStructPointer(Appearance); >+ val.txPower = decoder.decodeStructPointer(Power); >+ val.manufacturerData = decoder.decodeMapPointer(codec.Uint8, new codec.ArrayOf(codec.Uint8)); >+ val.serviceData = decoder.decodeStructPointer(ServiceDataMap); >+ return val; >+ }; >+ >+ ScanRecord.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(ScanRecord.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.NullableString, val.name); >+ encoder.encodeArrayPointer(new codec.PointerTo(uuid$.UUID), val.uuids); >+ encoder.encodeStructPointer(Appearance, val.appearance); >+ encoder.encodeStructPointer(Power, val.txPower); >+ encoder.encodeMapPointer(codec.Uint8, new codec.ArrayOf(codec.Uint8), val.manufacturerData); >+ encoder.encodeStructPointer(ServiceDataMap, val.serviceData); >+ }; >+ function ScanResult(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ ScanResult.prototype.initDefaults_ = function() { >+ this.deviceAddress = null; >+ this.rssi = 0; >+ this.scanRecord = null; >+ }; >+ ScanResult.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ ScanResult.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 32} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate ScanResult.deviceAddress >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ >+ // validate ScanResult.scanRecord >+ err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 16, ScanRecord, false); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ ScanResult.encodedSize = codec.kStructHeaderSize + 24; >+ >+ ScanResult.decode = function(decoder) { >+ var packed; >+ var val = new ScanResult(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.deviceAddress = decoder.decodeStruct(codec.String); >+ val.rssi = decoder.decodeStruct(codec.Int8); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ val.scanRecord = decoder.decodeStructPointer(ScanRecord); >+ return val; >+ }; >+ >+ ScanResult.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(ScanResult.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.String, val.deviceAddress); >+ encoder.encodeStruct(codec.Int8, val.rssi); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.encodeStructPointer(ScanRecord, val.scanRecord); >+ }; >+ function CharacteristicProperties(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ CharacteristicProperties.prototype.initDefaults_ = function() { >+ this.broadcast = false; >+ this.read = false; >+ this.writeWithoutResponse = false; >+ this.write = false; >+ this.notify = false; >+ this.indicate = false; >+ this.authenticatedSignedWrites = false; >+ this.extendedProperties = false; >+ }; >+ CharacteristicProperties.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ CharacteristicProperties.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ CharacteristicProperties.encodedSize = codec.kStructHeaderSize + 8; >+ >+ CharacteristicProperties.decode = function(decoder) { >+ var packed; >+ var val = new CharacteristicProperties(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.broadcast = (packed >> 0) & 1 ? true : false; >+ val.read = (packed >> 1) & 1 ? true : false; >+ val.writeWithoutResponse = (packed >> 2) & 1 ? true : false; >+ val.write = (packed >> 3) & 1 ? true : false; >+ val.notify = (packed >> 4) & 1 ? true : false; >+ val.indicate = (packed >> 5) & 1 ? true : false; >+ val.authenticatedSignedWrites = (packed >> 6) & 1 ? true : false; >+ val.extendedProperties = (packed >> 7) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ CharacteristicProperties.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(CharacteristicProperties.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.broadcast & 1) << 0 >+ packed |= (val.read & 1) << 1 >+ packed |= (val.writeWithoutResponse & 1) << 2 >+ packed |= (val.write & 1) << 3 >+ packed |= (val.notify & 1) << 4 >+ packed |= (val.indicate & 1) << 5 >+ packed |= (val.authenticatedSignedWrites & 1) << 6 >+ packed |= (val.extendedProperties & 1) << 7 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeBluetooth_SetLESupported_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeBluetooth_SetLESupported_Params.prototype.initDefaults_ = function() { >+ this.available = false; >+ }; >+ FakeBluetooth_SetLESupported_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeBluetooth_SetLESupported_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeBluetooth_SetLESupported_Params.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeBluetooth_SetLESupported_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeBluetooth_SetLESupported_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.available = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeBluetooth_SetLESupported_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeBluetooth_SetLESupported_Params.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.available & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeBluetooth_SetLESupported_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeBluetooth_SetLESupported_ResponseParams.prototype.initDefaults_ = function() { >+ }; >+ FakeBluetooth_SetLESupported_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeBluetooth_SetLESupported_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 8} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeBluetooth_SetLESupported_ResponseParams.encodedSize = codec.kStructHeaderSize + 0; >+ >+ FakeBluetooth_SetLESupported_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeBluetooth_SetLESupported_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ return val; >+ }; >+ >+ FakeBluetooth_SetLESupported_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeBluetooth_SetLESupported_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ }; >+ function FakeBluetooth_SimulateCentral_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeBluetooth_SimulateCentral_Params.prototype.initDefaults_ = function() { >+ this.state = 0; >+ }; >+ FakeBluetooth_SimulateCentral_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeBluetooth_SimulateCentral_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeBluetooth_SimulateCentral_Params.state >+ err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, CentralState); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeBluetooth_SimulateCentral_Params.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeBluetooth_SimulateCentral_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeBluetooth_SimulateCentral_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.state = decoder.decodeStruct(codec.Int32); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeBluetooth_SimulateCentral_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeBluetooth_SimulateCentral_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.Int32, val.state); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeBluetooth_SimulateCentral_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeBluetooth_SimulateCentral_ResponseParams.prototype.initDefaults_ = function() { >+ this.fakeCentral = new FakeCentralPtr(); >+ }; >+ FakeBluetooth_SimulateCentral_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeBluetooth_SimulateCentral_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeBluetooth_SimulateCentral_ResponseParams.fakeCentral >+ err = messageValidator.validateInterface(offset + codec.kStructHeaderSize + 0, false); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeBluetooth_SimulateCentral_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeBluetooth_SimulateCentral_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeBluetooth_SimulateCentral_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.fakeCentral = decoder.decodeStruct(new codec.Interface(FakeCentralPtr)); >+ return val; >+ }; >+ >+ FakeBluetooth_SimulateCentral_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeBluetooth_SimulateCentral_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(new codec.Interface(FakeCentralPtr), val.fakeCentral); >+ }; >+ function FakeBluetooth_AllResponsesConsumed_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeBluetooth_AllResponsesConsumed_Params.prototype.initDefaults_ = function() { >+ }; >+ FakeBluetooth_AllResponsesConsumed_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeBluetooth_AllResponsesConsumed_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 8} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeBluetooth_AllResponsesConsumed_Params.encodedSize = codec.kStructHeaderSize + 0; >+ >+ FakeBluetooth_AllResponsesConsumed_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeBluetooth_AllResponsesConsumed_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ return val; >+ }; >+ >+ FakeBluetooth_AllResponsesConsumed_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeBluetooth_AllResponsesConsumed_Params.encodedSize); >+ encoder.writeUint32(0); >+ }; >+ function FakeBluetooth_AllResponsesConsumed_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeBluetooth_AllResponsesConsumed_ResponseParams.prototype.initDefaults_ = function() { >+ this.consumed = false; >+ }; >+ FakeBluetooth_AllResponsesConsumed_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeBluetooth_AllResponsesConsumed_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeBluetooth_AllResponsesConsumed_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeBluetooth_AllResponsesConsumed_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeBluetooth_AllResponsesConsumed_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.consumed = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeBluetooth_AllResponsesConsumed_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeBluetooth_AllResponsesConsumed_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.consumed & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeCentral_SimulatePreconnectedPeripheral_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SimulatePreconnectedPeripheral_Params.prototype.initDefaults_ = function() { >+ this.address = null; >+ this.name = null; >+ this.knownServiceUuids = null; >+ }; >+ FakeCentral_SimulatePreconnectedPeripheral_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SimulatePreconnectedPeripheral_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 32} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SimulatePreconnectedPeripheral_Params.address >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SimulatePreconnectedPeripheral_Params.name >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SimulatePreconnectedPeripheral_Params.knownServiceUuids >+ err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 16, 8, new codec.PointerTo(uuid$.UUID), false, [0], 0); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SimulatePreconnectedPeripheral_Params.encodedSize = codec.kStructHeaderSize + 24; >+ >+ FakeCentral_SimulatePreconnectedPeripheral_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SimulatePreconnectedPeripheral_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.address = decoder.decodeStruct(codec.String); >+ val.name = decoder.decodeStruct(codec.String); >+ val.knownServiceUuids = decoder.decodeArrayPointer(new codec.PointerTo(uuid$.UUID)); >+ return val; >+ }; >+ >+ FakeCentral_SimulatePreconnectedPeripheral_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SimulatePreconnectedPeripheral_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.String, val.address); >+ encoder.encodeStruct(codec.String, val.name); >+ encoder.encodeArrayPointer(new codec.PointerTo(uuid$.UUID), val.knownServiceUuids); >+ }; >+ function FakeCentral_SimulatePreconnectedPeripheral_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.prototype.initDefaults_ = function() { >+ }; >+ FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 8} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.encodedSize = codec.kStructHeaderSize + 0; >+ >+ FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SimulatePreconnectedPeripheral_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ return val; >+ }; >+ >+ FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ }; >+ function FakeCentral_SimulateAdvertisementReceived_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SimulateAdvertisementReceived_Params.prototype.initDefaults_ = function() { >+ this.result = null; >+ }; >+ FakeCentral_SimulateAdvertisementReceived_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SimulateAdvertisementReceived_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SimulateAdvertisementReceived_Params.result >+ err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, ScanResult, false); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SimulateAdvertisementReceived_Params.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_SimulateAdvertisementReceived_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SimulateAdvertisementReceived_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.result = decoder.decodeStructPointer(ScanResult); >+ return val; >+ }; >+ >+ FakeCentral_SimulateAdvertisementReceived_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SimulateAdvertisementReceived_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStructPointer(ScanResult, val.result); >+ }; >+ function FakeCentral_SimulateAdvertisementReceived_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SimulateAdvertisementReceived_ResponseParams.prototype.initDefaults_ = function() { >+ }; >+ FakeCentral_SimulateAdvertisementReceived_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SimulateAdvertisementReceived_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 8} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SimulateAdvertisementReceived_ResponseParams.encodedSize = codec.kStructHeaderSize + 0; >+ >+ FakeCentral_SimulateAdvertisementReceived_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SimulateAdvertisementReceived_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ return val; >+ }; >+ >+ FakeCentral_SimulateAdvertisementReceived_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SimulateAdvertisementReceived_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ }; >+ function FakeCentral_SetNextGATTConnectionResponse_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SetNextGATTConnectionResponse_Params.prototype.initDefaults_ = function() { >+ this.address = null; >+ this.code = 0; >+ }; >+ FakeCentral_SetNextGATTConnectionResponse_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SetNextGATTConnectionResponse_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 24} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SetNextGATTConnectionResponse_Params.address >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SetNextGATTConnectionResponse_Params.encodedSize = codec.kStructHeaderSize + 16; >+ >+ FakeCentral_SetNextGATTConnectionResponse_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SetNextGATTConnectionResponse_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.address = decoder.decodeStruct(codec.String); >+ val.code = decoder.decodeStruct(codec.Uint16); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeCentral_SetNextGATTConnectionResponse_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SetNextGATTConnectionResponse_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.String, val.address); >+ encoder.encodeStruct(codec.Uint16, val.code); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeCentral_SetNextGATTConnectionResponse_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SetNextGATTConnectionResponse_ResponseParams.prototype.initDefaults_ = function() { >+ this.success = false; >+ }; >+ FakeCentral_SetNextGATTConnectionResponse_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SetNextGATTConnectionResponse_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SetNextGATTConnectionResponse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_SetNextGATTConnectionResponse_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SetNextGATTConnectionResponse_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.success = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeCentral_SetNextGATTConnectionResponse_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SetNextGATTConnectionResponse_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.success & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeCentral_SetNextGATTDiscoveryResponse_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SetNextGATTDiscoveryResponse_Params.prototype.initDefaults_ = function() { >+ this.address = null; >+ this.code = 0; >+ }; >+ FakeCentral_SetNextGATTDiscoveryResponse_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SetNextGATTDiscoveryResponse_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 24} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SetNextGATTDiscoveryResponse_Params.address >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SetNextGATTDiscoveryResponse_Params.encodedSize = codec.kStructHeaderSize + 16; >+ >+ FakeCentral_SetNextGATTDiscoveryResponse_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SetNextGATTDiscoveryResponse_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.address = decoder.decodeStruct(codec.String); >+ val.code = decoder.decodeStruct(codec.Uint16); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeCentral_SetNextGATTDiscoveryResponse_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SetNextGATTDiscoveryResponse_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.String, val.address); >+ encoder.encodeStruct(codec.Uint16, val.code); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.prototype.initDefaults_ = function() { >+ this.success = false; >+ }; >+ FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.success = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.success & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeCentral_SimulateGATTDisconnection_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SimulateGATTDisconnection_Params.prototype.initDefaults_ = function() { >+ this.address = null; >+ }; >+ FakeCentral_SimulateGATTDisconnection_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SimulateGATTDisconnection_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SimulateGATTDisconnection_Params.address >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SimulateGATTDisconnection_Params.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_SimulateGATTDisconnection_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SimulateGATTDisconnection_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.address = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ FakeCentral_SimulateGATTDisconnection_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SimulateGATTDisconnection_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.String, val.address); >+ }; >+ function FakeCentral_SimulateGATTDisconnection_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SimulateGATTDisconnection_ResponseParams.prototype.initDefaults_ = function() { >+ this.success = false; >+ }; >+ FakeCentral_SimulateGATTDisconnection_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SimulateGATTDisconnection_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SimulateGATTDisconnection_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_SimulateGATTDisconnection_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SimulateGATTDisconnection_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.success = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeCentral_SimulateGATTDisconnection_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SimulateGATTDisconnection_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.success & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeCentral_SimulateGATTServicesChanged_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SimulateGATTServicesChanged_Params.prototype.initDefaults_ = function() { >+ this.address = null; >+ }; >+ FakeCentral_SimulateGATTServicesChanged_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SimulateGATTServicesChanged_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SimulateGATTServicesChanged_Params.address >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SimulateGATTServicesChanged_Params.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_SimulateGATTServicesChanged_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SimulateGATTServicesChanged_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.address = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ FakeCentral_SimulateGATTServicesChanged_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SimulateGATTServicesChanged_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.String, val.address); >+ }; >+ function FakeCentral_SimulateGATTServicesChanged_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SimulateGATTServicesChanged_ResponseParams.prototype.initDefaults_ = function() { >+ this.success = false; >+ }; >+ FakeCentral_SimulateGATTServicesChanged_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SimulateGATTServicesChanged_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SimulateGATTServicesChanged_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_SimulateGATTServicesChanged_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SimulateGATTServicesChanged_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.success = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeCentral_SimulateGATTServicesChanged_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SimulateGATTServicesChanged_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.success & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeCentral_AddFakeService_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_AddFakeService_Params.prototype.initDefaults_ = function() { >+ this.peripheralAddress = null; >+ this.serviceUuid = null; >+ }; >+ FakeCentral_AddFakeService_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_AddFakeService_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 24} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_AddFakeService_Params.peripheralAddress >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_AddFakeService_Params.serviceUuid >+ err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, uuid$.UUID, false); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_AddFakeService_Params.encodedSize = codec.kStructHeaderSize + 16; >+ >+ FakeCentral_AddFakeService_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_AddFakeService_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.peripheralAddress = decoder.decodeStruct(codec.String); >+ val.serviceUuid = decoder.decodeStructPointer(uuid$.UUID); >+ return val; >+ }; >+ >+ FakeCentral_AddFakeService_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_AddFakeService_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.String, val.peripheralAddress); >+ encoder.encodeStructPointer(uuid$.UUID, val.serviceUuid); >+ }; >+ function FakeCentral_AddFakeService_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_AddFakeService_ResponseParams.prototype.initDefaults_ = function() { >+ this.serviceId = null; >+ }; >+ FakeCentral_AddFakeService_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_AddFakeService_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_AddFakeService_ResponseParams.serviceId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, true) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_AddFakeService_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_AddFakeService_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_AddFakeService_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.serviceId = decoder.decodeStruct(codec.NullableString); >+ return val; >+ }; >+ >+ FakeCentral_AddFakeService_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_AddFakeService_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.NullableString, val.serviceId); >+ }; >+ function FakeCentral_RemoveFakeService_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_RemoveFakeService_Params.prototype.initDefaults_ = function() { >+ this.serviceId = null; >+ this.peripheralAddress = null; >+ }; >+ FakeCentral_RemoveFakeService_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_RemoveFakeService_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 24} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_RemoveFakeService_Params.serviceId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_RemoveFakeService_Params.peripheralAddress >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_RemoveFakeService_Params.encodedSize = codec.kStructHeaderSize + 16; >+ >+ FakeCentral_RemoveFakeService_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_RemoveFakeService_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.serviceId = decoder.decodeStruct(codec.String); >+ val.peripheralAddress = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ FakeCentral_RemoveFakeService_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_RemoveFakeService_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.String, val.serviceId); >+ encoder.encodeStruct(codec.String, val.peripheralAddress); >+ }; >+ function FakeCentral_RemoveFakeService_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_RemoveFakeService_ResponseParams.prototype.initDefaults_ = function() { >+ this.success = false; >+ }; >+ FakeCentral_RemoveFakeService_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_RemoveFakeService_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_RemoveFakeService_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_RemoveFakeService_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_RemoveFakeService_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.success = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeCentral_RemoveFakeService_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_RemoveFakeService_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.success & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeCentral_AddFakeCharacteristic_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_AddFakeCharacteristic_Params.prototype.initDefaults_ = function() { >+ this.characteristicUuid = null; >+ this.properties = null; >+ this.serviceId = null; >+ this.peripheralAddress = null; >+ }; >+ FakeCentral_AddFakeCharacteristic_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_AddFakeCharacteristic_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 40} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_AddFakeCharacteristic_Params.characteristicUuid >+ err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, uuid$.UUID, false); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_AddFakeCharacteristic_Params.properties >+ err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, CharacteristicProperties, false); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_AddFakeCharacteristic_Params.serviceId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_AddFakeCharacteristic_Params.peripheralAddress >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_AddFakeCharacteristic_Params.encodedSize = codec.kStructHeaderSize + 32; >+ >+ FakeCentral_AddFakeCharacteristic_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_AddFakeCharacteristic_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.characteristicUuid = decoder.decodeStructPointer(uuid$.UUID); >+ val.properties = decoder.decodeStructPointer(CharacteristicProperties); >+ val.serviceId = decoder.decodeStruct(codec.String); >+ val.peripheralAddress = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ FakeCentral_AddFakeCharacteristic_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_AddFakeCharacteristic_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStructPointer(uuid$.UUID, val.characteristicUuid); >+ encoder.encodeStructPointer(CharacteristicProperties, val.properties); >+ encoder.encodeStruct(codec.String, val.serviceId); >+ encoder.encodeStruct(codec.String, val.peripheralAddress); >+ }; >+ function FakeCentral_AddFakeCharacteristic_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_AddFakeCharacteristic_ResponseParams.prototype.initDefaults_ = function() { >+ this.characteristicId = null; >+ }; >+ FakeCentral_AddFakeCharacteristic_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_AddFakeCharacteristic_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_AddFakeCharacteristic_ResponseParams.characteristicId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, true) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_AddFakeCharacteristic_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_AddFakeCharacteristic_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_AddFakeCharacteristic_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.characteristicId = decoder.decodeStruct(codec.NullableString); >+ return val; >+ }; >+ >+ FakeCentral_AddFakeCharacteristic_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_AddFakeCharacteristic_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.NullableString, val.characteristicId); >+ }; >+ function FakeCentral_RemoveFakeCharacteristic_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_RemoveFakeCharacteristic_Params.prototype.initDefaults_ = function() { >+ this.identifier = null; >+ this.serviceId = null; >+ this.peripheralAddress = null; >+ }; >+ FakeCentral_RemoveFakeCharacteristic_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_RemoveFakeCharacteristic_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 32} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_RemoveFakeCharacteristic_Params.identifier >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_RemoveFakeCharacteristic_Params.serviceId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_RemoveFakeCharacteristic_Params.peripheralAddress >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_RemoveFakeCharacteristic_Params.encodedSize = codec.kStructHeaderSize + 24; >+ >+ FakeCentral_RemoveFakeCharacteristic_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_RemoveFakeCharacteristic_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.identifier = decoder.decodeStruct(codec.String); >+ val.serviceId = decoder.decodeStruct(codec.String); >+ val.peripheralAddress = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ FakeCentral_RemoveFakeCharacteristic_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_RemoveFakeCharacteristic_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.String, val.identifier); >+ encoder.encodeStruct(codec.String, val.serviceId); >+ encoder.encodeStruct(codec.String, val.peripheralAddress); >+ }; >+ function FakeCentral_RemoveFakeCharacteristic_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_RemoveFakeCharacteristic_ResponseParams.prototype.initDefaults_ = function() { >+ this.success = false; >+ }; >+ FakeCentral_RemoveFakeCharacteristic_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_RemoveFakeCharacteristic_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_RemoveFakeCharacteristic_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_RemoveFakeCharacteristic_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_RemoveFakeCharacteristic_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.success = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeCentral_RemoveFakeCharacteristic_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_RemoveFakeCharacteristic_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.success & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeCentral_AddFakeDescriptor_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_AddFakeDescriptor_Params.prototype.initDefaults_ = function() { >+ this.descriptorUuid = null; >+ this.characteristicId = null; >+ this.serviceId = null; >+ this.peripheralAddress = null; >+ }; >+ FakeCentral_AddFakeDescriptor_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_AddFakeDescriptor_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 40} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_AddFakeDescriptor_Params.descriptorUuid >+ err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, uuid$.UUID, false); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_AddFakeDescriptor_Params.characteristicId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_AddFakeDescriptor_Params.serviceId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_AddFakeDescriptor_Params.peripheralAddress >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_AddFakeDescriptor_Params.encodedSize = codec.kStructHeaderSize + 32; >+ >+ FakeCentral_AddFakeDescriptor_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_AddFakeDescriptor_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.descriptorUuid = decoder.decodeStructPointer(uuid$.UUID); >+ val.characteristicId = decoder.decodeStruct(codec.String); >+ val.serviceId = decoder.decodeStruct(codec.String); >+ val.peripheralAddress = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ FakeCentral_AddFakeDescriptor_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_AddFakeDescriptor_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStructPointer(uuid$.UUID, val.descriptorUuid); >+ encoder.encodeStruct(codec.String, val.characteristicId); >+ encoder.encodeStruct(codec.String, val.serviceId); >+ encoder.encodeStruct(codec.String, val.peripheralAddress); >+ }; >+ function FakeCentral_AddFakeDescriptor_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_AddFakeDescriptor_ResponseParams.prototype.initDefaults_ = function() { >+ this.descriptorId = null; >+ }; >+ FakeCentral_AddFakeDescriptor_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_AddFakeDescriptor_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_AddFakeDescriptor_ResponseParams.descriptorId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, true) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_AddFakeDescriptor_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_AddFakeDescriptor_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_AddFakeDescriptor_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.descriptorId = decoder.decodeStruct(codec.NullableString); >+ return val; >+ }; >+ >+ FakeCentral_AddFakeDescriptor_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_AddFakeDescriptor_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.NullableString, val.descriptorId); >+ }; >+ function FakeCentral_RemoveFakeDescriptor_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_RemoveFakeDescriptor_Params.prototype.initDefaults_ = function() { >+ this.descriptorId = null; >+ this.characteristicId = null; >+ this.serviceId = null; >+ this.peripheralAddress = null; >+ }; >+ FakeCentral_RemoveFakeDescriptor_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_RemoveFakeDescriptor_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 40} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_RemoveFakeDescriptor_Params.descriptorId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_RemoveFakeDescriptor_Params.characteristicId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_RemoveFakeDescriptor_Params.serviceId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_RemoveFakeDescriptor_Params.peripheralAddress >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_RemoveFakeDescriptor_Params.encodedSize = codec.kStructHeaderSize + 32; >+ >+ FakeCentral_RemoveFakeDescriptor_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_RemoveFakeDescriptor_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.descriptorId = decoder.decodeStruct(codec.String); >+ val.characteristicId = decoder.decodeStruct(codec.String); >+ val.serviceId = decoder.decodeStruct(codec.String); >+ val.peripheralAddress = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ FakeCentral_RemoveFakeDescriptor_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_RemoveFakeDescriptor_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.String, val.descriptorId); >+ encoder.encodeStruct(codec.String, val.characteristicId); >+ encoder.encodeStruct(codec.String, val.serviceId); >+ encoder.encodeStruct(codec.String, val.peripheralAddress); >+ }; >+ function FakeCentral_RemoveFakeDescriptor_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_RemoveFakeDescriptor_ResponseParams.prototype.initDefaults_ = function() { >+ this.success = false; >+ }; >+ FakeCentral_RemoveFakeDescriptor_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_RemoveFakeDescriptor_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_RemoveFakeDescriptor_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_RemoveFakeDescriptor_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_RemoveFakeDescriptor_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.success = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeCentral_RemoveFakeDescriptor_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_RemoveFakeDescriptor_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.success & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeCentral_SetNextReadCharacteristicResponse_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SetNextReadCharacteristicResponse_Params.prototype.initDefaults_ = function() { >+ this.gattCode = 0; >+ this.value = null; >+ this.characteristicId = null; >+ this.serviceId = null; >+ this.peripheralAddress = null; >+ }; >+ FakeCentral_SetNextReadCharacteristicResponse_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SetNextReadCharacteristicResponse_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 48} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ >+ // validate FakeCentral_SetNextReadCharacteristicResponse_Params.value >+ err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 1, codec.Uint8, true, [0], 0); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SetNextReadCharacteristicResponse_Params.characteristicId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SetNextReadCharacteristicResponse_Params.serviceId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SetNextReadCharacteristicResponse_Params.peripheralAddress >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 32, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SetNextReadCharacteristicResponse_Params.encodedSize = codec.kStructHeaderSize + 40; >+ >+ FakeCentral_SetNextReadCharacteristicResponse_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SetNextReadCharacteristicResponse_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.gattCode = decoder.decodeStruct(codec.Uint16); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ val.value = decoder.decodeArrayPointer(codec.Uint8); >+ val.characteristicId = decoder.decodeStruct(codec.String); >+ val.serviceId = decoder.decodeStruct(codec.String); >+ val.peripheralAddress = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ FakeCentral_SetNextReadCharacteristicResponse_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SetNextReadCharacteristicResponse_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.Uint16, val.gattCode); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.encodeArrayPointer(codec.Uint8, val.value); >+ encoder.encodeStruct(codec.String, val.characteristicId); >+ encoder.encodeStruct(codec.String, val.serviceId); >+ encoder.encodeStruct(codec.String, val.peripheralAddress); >+ }; >+ function FakeCentral_SetNextReadCharacteristicResponse_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.prototype.initDefaults_ = function() { >+ this.success = false; >+ }; >+ FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SetNextReadCharacteristicResponse_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.success = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.success & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeCentral_SetNextWriteCharacteristicResponse_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SetNextWriteCharacteristicResponse_Params.prototype.initDefaults_ = function() { >+ this.gattCode = 0; >+ this.characteristicId = null; >+ this.serviceId = null; >+ this.peripheralAddress = null; >+ }; >+ FakeCentral_SetNextWriteCharacteristicResponse_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SetNextWriteCharacteristicResponse_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 40} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ >+ // validate FakeCentral_SetNextWriteCharacteristicResponse_Params.characteristicId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SetNextWriteCharacteristicResponse_Params.serviceId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SetNextWriteCharacteristicResponse_Params.peripheralAddress >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SetNextWriteCharacteristicResponse_Params.encodedSize = codec.kStructHeaderSize + 32; >+ >+ FakeCentral_SetNextWriteCharacteristicResponse_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SetNextWriteCharacteristicResponse_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.gattCode = decoder.decodeStruct(codec.Uint16); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ val.characteristicId = decoder.decodeStruct(codec.String); >+ val.serviceId = decoder.decodeStruct(codec.String); >+ val.peripheralAddress = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ FakeCentral_SetNextWriteCharacteristicResponse_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SetNextWriteCharacteristicResponse_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.Uint16, val.gattCode); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.encodeStruct(codec.String, val.characteristicId); >+ encoder.encodeStruct(codec.String, val.serviceId); >+ encoder.encodeStruct(codec.String, val.peripheralAddress); >+ }; >+ function FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.prototype.initDefaults_ = function() { >+ this.success = false; >+ }; >+ FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.success = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.success & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeCentral_SetNextSubscribeToNotificationsResponse_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SetNextSubscribeToNotificationsResponse_Params.prototype.initDefaults_ = function() { >+ this.gattCode = 0; >+ this.characteristicId = null; >+ this.serviceId = null; >+ this.peripheralAddress = null; >+ }; >+ FakeCentral_SetNextSubscribeToNotificationsResponse_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SetNextSubscribeToNotificationsResponse_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 40} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ >+ // validate FakeCentral_SetNextSubscribeToNotificationsResponse_Params.characteristicId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SetNextSubscribeToNotificationsResponse_Params.serviceId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SetNextSubscribeToNotificationsResponse_Params.peripheralAddress >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SetNextSubscribeToNotificationsResponse_Params.encodedSize = codec.kStructHeaderSize + 32; >+ >+ FakeCentral_SetNextSubscribeToNotificationsResponse_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SetNextSubscribeToNotificationsResponse_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.gattCode = decoder.decodeStruct(codec.Uint16); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ val.characteristicId = decoder.decodeStruct(codec.String); >+ val.serviceId = decoder.decodeStruct(codec.String); >+ val.peripheralAddress = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ FakeCentral_SetNextSubscribeToNotificationsResponse_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SetNextSubscribeToNotificationsResponse_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.Uint16, val.gattCode); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.encodeStruct(codec.String, val.characteristicId); >+ encoder.encodeStruct(codec.String, val.serviceId); >+ encoder.encodeStruct(codec.String, val.peripheralAddress); >+ }; >+ function FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.prototype.initDefaults_ = function() { >+ this.success = false; >+ }; >+ FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.success = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.success & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.prototype.initDefaults_ = function() { >+ this.gattCode = 0; >+ this.characteristicId = null; >+ this.serviceId = null; >+ this.peripheralAddress = null; >+ }; >+ FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 40} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ >+ // validate FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.characteristicId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.serviceId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.peripheralAddress >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.encodedSize = codec.kStructHeaderSize + 32; >+ >+ FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.gattCode = decoder.decodeStruct(codec.Uint16); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ val.characteristicId = decoder.decodeStruct(codec.String); >+ val.serviceId = decoder.decodeStruct(codec.String); >+ val.peripheralAddress = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.Uint16, val.gattCode); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.encodeStruct(codec.String, val.characteristicId); >+ encoder.encodeStruct(codec.String, val.serviceId); >+ encoder.encodeStruct(codec.String, val.peripheralAddress); >+ }; >+ function FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.prototype.initDefaults_ = function() { >+ this.success = false; >+ }; >+ FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.success = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.success & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeCentral_IsNotifying_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_IsNotifying_Params.prototype.initDefaults_ = function() { >+ this.characteristicId = null; >+ this.serviceId = null; >+ this.peripheralAddress = null; >+ }; >+ FakeCentral_IsNotifying_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_IsNotifying_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 32} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_IsNotifying_Params.characteristicId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_IsNotifying_Params.serviceId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_IsNotifying_Params.peripheralAddress >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_IsNotifying_Params.encodedSize = codec.kStructHeaderSize + 24; >+ >+ FakeCentral_IsNotifying_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_IsNotifying_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.characteristicId = decoder.decodeStruct(codec.String); >+ val.serviceId = decoder.decodeStruct(codec.String); >+ val.peripheralAddress = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ FakeCentral_IsNotifying_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_IsNotifying_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.String, val.characteristicId); >+ encoder.encodeStruct(codec.String, val.serviceId); >+ encoder.encodeStruct(codec.String, val.peripheralAddress); >+ }; >+ function FakeCentral_IsNotifying_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_IsNotifying_ResponseParams.prototype.initDefaults_ = function() { >+ this.success = false; >+ this.isNotifying = false; >+ }; >+ FakeCentral_IsNotifying_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_IsNotifying_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_IsNotifying_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_IsNotifying_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_IsNotifying_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.success = (packed >> 0) & 1 ? true : false; >+ val.isNotifying = (packed >> 1) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeCentral_IsNotifying_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_IsNotifying_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.success & 1) << 0 >+ packed |= (val.isNotifying & 1) << 1 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeCentral_GetLastWrittenCharacteristicValue_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_GetLastWrittenCharacteristicValue_Params.prototype.initDefaults_ = function() { >+ this.characteristicId = null; >+ this.serviceId = null; >+ this.peripheralAddress = null; >+ }; >+ FakeCentral_GetLastWrittenCharacteristicValue_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_GetLastWrittenCharacteristicValue_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 32} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_GetLastWrittenCharacteristicValue_Params.characteristicId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_GetLastWrittenCharacteristicValue_Params.serviceId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_GetLastWrittenCharacteristicValue_Params.peripheralAddress >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_GetLastWrittenCharacteristicValue_Params.encodedSize = codec.kStructHeaderSize + 24; >+ >+ FakeCentral_GetLastWrittenCharacteristicValue_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_GetLastWrittenCharacteristicValue_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.characteristicId = decoder.decodeStruct(codec.String); >+ val.serviceId = decoder.decodeStruct(codec.String); >+ val.peripheralAddress = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ FakeCentral_GetLastWrittenCharacteristicValue_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_GetLastWrittenCharacteristicValue_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.String, val.characteristicId); >+ encoder.encodeStruct(codec.String, val.serviceId); >+ encoder.encodeStruct(codec.String, val.peripheralAddress); >+ }; >+ function FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.prototype.initDefaults_ = function() { >+ this.success = false; >+ this.value = null; >+ }; >+ FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 24} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ >+ // validate FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.value >+ err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 1, codec.Uint8, true, [0], 0); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.encodedSize = codec.kStructHeaderSize + 16; >+ >+ FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.success = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ val.value = decoder.decodeArrayPointer(codec.Uint8); >+ return val; >+ }; >+ >+ FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.success & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.encodeArrayPointer(codec.Uint8, val.value); >+ }; >+ function FakeCentral_SetNextReadDescriptorResponse_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SetNextReadDescriptorResponse_Params.prototype.initDefaults_ = function() { >+ this.gattCode = 0; >+ this.value = null; >+ this.descriptorId = null; >+ this.characteristicId = null; >+ this.serviceId = null; >+ this.peripheralAddress = null; >+ }; >+ FakeCentral_SetNextReadDescriptorResponse_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SetNextReadDescriptorResponse_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 56} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ >+ // validate FakeCentral_SetNextReadDescriptorResponse_Params.value >+ err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 1, codec.Uint8, true, [0], 0); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SetNextReadDescriptorResponse_Params.descriptorId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SetNextReadDescriptorResponse_Params.characteristicId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SetNextReadDescriptorResponse_Params.serviceId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 32, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SetNextReadDescriptorResponse_Params.peripheralAddress >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 40, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SetNextReadDescriptorResponse_Params.encodedSize = codec.kStructHeaderSize + 48; >+ >+ FakeCentral_SetNextReadDescriptorResponse_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SetNextReadDescriptorResponse_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.gattCode = decoder.decodeStruct(codec.Uint16); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ val.value = decoder.decodeArrayPointer(codec.Uint8); >+ val.descriptorId = decoder.decodeStruct(codec.String); >+ val.characteristicId = decoder.decodeStruct(codec.String); >+ val.serviceId = decoder.decodeStruct(codec.String); >+ val.peripheralAddress = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ FakeCentral_SetNextReadDescriptorResponse_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SetNextReadDescriptorResponse_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.Uint16, val.gattCode); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.encodeArrayPointer(codec.Uint8, val.value); >+ encoder.encodeStruct(codec.String, val.descriptorId); >+ encoder.encodeStruct(codec.String, val.characteristicId); >+ encoder.encodeStruct(codec.String, val.serviceId); >+ encoder.encodeStruct(codec.String, val.peripheralAddress); >+ }; >+ function FakeCentral_SetNextReadDescriptorResponse_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SetNextReadDescriptorResponse_ResponseParams.prototype.initDefaults_ = function() { >+ this.success = false; >+ }; >+ FakeCentral_SetNextReadDescriptorResponse_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SetNextReadDescriptorResponse_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SetNextReadDescriptorResponse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_SetNextReadDescriptorResponse_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SetNextReadDescriptorResponse_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.success = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeCentral_SetNextReadDescriptorResponse_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SetNextReadDescriptorResponse_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.success & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeCentral_SetNextWriteDescriptorResponse_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SetNextWriteDescriptorResponse_Params.prototype.initDefaults_ = function() { >+ this.gattCode = 0; >+ this.descriptorId = null; >+ this.characteristicId = null; >+ this.serviceId = null; >+ this.peripheralAddress = null; >+ }; >+ FakeCentral_SetNextWriteDescriptorResponse_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SetNextWriteDescriptorResponse_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 48} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ >+ // validate FakeCentral_SetNextWriteDescriptorResponse_Params.descriptorId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SetNextWriteDescriptorResponse_Params.characteristicId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SetNextWriteDescriptorResponse_Params.serviceId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_SetNextWriteDescriptorResponse_Params.peripheralAddress >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 32, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SetNextWriteDescriptorResponse_Params.encodedSize = codec.kStructHeaderSize + 40; >+ >+ FakeCentral_SetNextWriteDescriptorResponse_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SetNextWriteDescriptorResponse_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.gattCode = decoder.decodeStruct(codec.Uint16); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ val.descriptorId = decoder.decodeStruct(codec.String); >+ val.characteristicId = decoder.decodeStruct(codec.String); >+ val.serviceId = decoder.decodeStruct(codec.String); >+ val.peripheralAddress = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ FakeCentral_SetNextWriteDescriptorResponse_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SetNextWriteDescriptorResponse_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.Uint16, val.gattCode); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.encodeStruct(codec.String, val.descriptorId); >+ encoder.encodeStruct(codec.String, val.characteristicId); >+ encoder.encodeStruct(codec.String, val.serviceId); >+ encoder.encodeStruct(codec.String, val.peripheralAddress); >+ }; >+ function FakeCentral_SetNextWriteDescriptorResponse_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.prototype.initDefaults_ = function() { >+ this.success = false; >+ }; >+ FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_SetNextWriteDescriptorResponse_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.success = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.success & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeCentral_GetLastWrittenDescriptorValue_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_GetLastWrittenDescriptorValue_Params.prototype.initDefaults_ = function() { >+ this.descriptorId = null; >+ this.characteristicId = null; >+ this.serviceId = null; >+ this.peripheralAddress = null; >+ }; >+ FakeCentral_GetLastWrittenDescriptorValue_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_GetLastWrittenDescriptorValue_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 40} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_GetLastWrittenDescriptorValue_Params.descriptorId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_GetLastWrittenDescriptorValue_Params.characteristicId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_GetLastWrittenDescriptorValue_Params.serviceId >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeCentral_GetLastWrittenDescriptorValue_Params.peripheralAddress >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_GetLastWrittenDescriptorValue_Params.encodedSize = codec.kStructHeaderSize + 32; >+ >+ FakeCentral_GetLastWrittenDescriptorValue_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_GetLastWrittenDescriptorValue_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.descriptorId = decoder.decodeStruct(codec.String); >+ val.characteristicId = decoder.decodeStruct(codec.String); >+ val.serviceId = decoder.decodeStruct(codec.String); >+ val.peripheralAddress = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ FakeCentral_GetLastWrittenDescriptorValue_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_GetLastWrittenDescriptorValue_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.String, val.descriptorId); >+ encoder.encodeStruct(codec.String, val.characteristicId); >+ encoder.encodeStruct(codec.String, val.serviceId); >+ encoder.encodeStruct(codec.String, val.peripheralAddress); >+ }; >+ function FakeCentral_GetLastWrittenDescriptorValue_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.prototype.initDefaults_ = function() { >+ this.success = false; >+ this.value = null; >+ }; >+ FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 24} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ >+ // validate FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.value >+ err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 1, codec.Uint8, true, [0], 0); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.encodedSize = codec.kStructHeaderSize + 16; >+ >+ FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeCentral_GetLastWrittenDescriptorValue_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.success = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ val.value = decoder.decodeArrayPointer(codec.Uint8); >+ return val; >+ }; >+ >+ FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.success & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.encodeArrayPointer(codec.Uint8, val.value); >+ }; >+ var kFakeBluetooth_SetLESupported_Name = 0; >+ var kFakeBluetooth_SimulateCentral_Name = 1; >+ var kFakeBluetooth_AllResponsesConsumed_Name = 2; >+ >+ function FakeBluetoothPtr(handleOrPtrInfo) { >+ this.ptr = new bindings.InterfacePtrController(FakeBluetooth, >+ handleOrPtrInfo); >+ } >+ >+ function FakeBluetoothAssociatedPtr(associatedInterfacePtrInfo) { >+ this.ptr = new associatedBindings.AssociatedInterfacePtrController( >+ FakeBluetooth, associatedInterfacePtrInfo); >+ } >+ >+ FakeBluetoothAssociatedPtr.prototype = >+ Object.create(FakeBluetoothPtr.prototype); >+ FakeBluetoothAssociatedPtr.prototype.constructor = >+ FakeBluetoothAssociatedPtr; >+ >+ function FakeBluetoothProxy(receiver) { >+ this.receiver_ = receiver; >+ } >+ FakeBluetoothPtr.prototype.setLESupported = function() { >+ return FakeBluetoothProxy.prototype.setLESupported >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeBluetoothProxy.prototype.setLESupported = function(available) { >+ var params = new FakeBluetooth_SetLESupported_Params(); >+ params.available = available; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeBluetooth_SetLESupported_Name, >+ codec.align(FakeBluetooth_SetLESupported_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeBluetooth_SetLESupported_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeBluetooth_SetLESupported_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeBluetoothPtr.prototype.simulateCentral = function() { >+ return FakeBluetoothProxy.prototype.simulateCentral >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeBluetoothProxy.prototype.simulateCentral = function(state) { >+ var params = new FakeBluetooth_SimulateCentral_Params(); >+ params.state = state; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeBluetooth_SimulateCentral_Name, >+ codec.align(FakeBluetooth_SimulateCentral_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeBluetooth_SimulateCentral_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeBluetooth_SimulateCentral_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeBluetoothPtr.prototype.allResponsesConsumed = function() { >+ return FakeBluetoothProxy.prototype.allResponsesConsumed >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeBluetoothProxy.prototype.allResponsesConsumed = function() { >+ var params = new FakeBluetooth_AllResponsesConsumed_Params(); >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeBluetooth_AllResponsesConsumed_Name, >+ codec.align(FakeBluetooth_AllResponsesConsumed_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeBluetooth_AllResponsesConsumed_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeBluetooth_AllResponsesConsumed_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ >+ function FakeBluetoothStub(delegate) { >+ this.delegate_ = delegate; >+ } >+ FakeBluetoothStub.prototype.setLESupported = function(available) { >+ return this.delegate_ && this.delegate_.setLESupported && this.delegate_.setLESupported(available); >+ } >+ FakeBluetoothStub.prototype.simulateCentral = function(state) { >+ return this.delegate_ && this.delegate_.simulateCentral && this.delegate_.simulateCentral(state); >+ } >+ FakeBluetoothStub.prototype.allResponsesConsumed = function() { >+ return this.delegate_ && this.delegate_.allResponsesConsumed && this.delegate_.allResponsesConsumed(); >+ } >+ >+ FakeBluetoothStub.prototype.accept = function(message) { >+ var reader = new codec.MessageReader(message); >+ switch (reader.messageName) { >+ default: >+ return false; >+ } >+ }; >+ >+ FakeBluetoothStub.prototype.acceptWithResponder = >+ function(message, responder) { >+ var reader = new codec.MessageReader(message); >+ switch (reader.messageName) { >+ case kFakeBluetooth_SetLESupported_Name: >+ var params = reader.decodeStruct(FakeBluetooth_SetLESupported_Params); >+ this.setLESupported(params.available).then(function(response) { >+ var responseParams = >+ new FakeBluetooth_SetLESupported_ResponseParams(); >+ var builder = new codec.MessageV1Builder( >+ kFakeBluetooth_SetLESupported_Name, >+ codec.align(FakeBluetooth_SetLESupported_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeBluetooth_SetLESupported_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeBluetooth_SimulateCentral_Name: >+ var params = reader.decodeStruct(FakeBluetooth_SimulateCentral_Params); >+ this.simulateCentral(params.state).then(function(response) { >+ var responseParams = >+ new FakeBluetooth_SimulateCentral_ResponseParams(); >+ responseParams.fakeCentral = response.fakeCentral; >+ var builder = new codec.MessageV1Builder( >+ kFakeBluetooth_SimulateCentral_Name, >+ codec.align(FakeBluetooth_SimulateCentral_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeBluetooth_SimulateCentral_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeBluetooth_AllResponsesConsumed_Name: >+ var params = reader.decodeStruct(FakeBluetooth_AllResponsesConsumed_Params); >+ this.allResponsesConsumed().then(function(response) { >+ var responseParams = >+ new FakeBluetooth_AllResponsesConsumed_ResponseParams(); >+ responseParams.consumed = response.consumed; >+ var builder = new codec.MessageV1Builder( >+ kFakeBluetooth_AllResponsesConsumed_Name, >+ codec.align(FakeBluetooth_AllResponsesConsumed_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeBluetooth_AllResponsesConsumed_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ default: >+ return false; >+ } >+ }; >+ >+ function validateFakeBluetoothRequest(messageValidator) { >+ var message = messageValidator.message; >+ var paramsClass = null; >+ switch (message.getName()) { >+ case kFakeBluetooth_SetLESupported_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeBluetooth_SetLESupported_Params; >+ break; >+ case kFakeBluetooth_SimulateCentral_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeBluetooth_SimulateCentral_Params; >+ break; >+ case kFakeBluetooth_AllResponsesConsumed_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeBluetooth_AllResponsesConsumed_Params; >+ break; >+ } >+ if (paramsClass === null) >+ return validator.validationError.NONE; >+ return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); >+ } >+ >+ function validateFakeBluetoothResponse(messageValidator) { >+ var message = messageValidator.message; >+ var paramsClass = null; >+ switch (message.getName()) { >+ case kFakeBluetooth_SetLESupported_Name: >+ if (message.isResponse()) >+ paramsClass = FakeBluetooth_SetLESupported_ResponseParams; >+ break; >+ case kFakeBluetooth_SimulateCentral_Name: >+ if (message.isResponse()) >+ paramsClass = FakeBluetooth_SimulateCentral_ResponseParams; >+ break; >+ case kFakeBluetooth_AllResponsesConsumed_Name: >+ if (message.isResponse()) >+ paramsClass = FakeBluetooth_AllResponsesConsumed_ResponseParams; >+ break; >+ } >+ if (paramsClass === null) >+ return validator.validationError.NONE; >+ return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); >+ } >+ >+ var FakeBluetooth = { >+ name: 'bluetooth.mojom.FakeBluetooth', >+ kVersion: 0, >+ ptrClass: FakeBluetoothPtr, >+ proxyClass: FakeBluetoothProxy, >+ stubClass: FakeBluetoothStub, >+ validateRequest: validateFakeBluetoothRequest, >+ validateResponse: validateFakeBluetoothResponse, >+ }; >+ FakeBluetoothStub.prototype.validator = validateFakeBluetoothRequest; >+ FakeBluetoothProxy.prototype.validator = validateFakeBluetoothResponse; >+ var kFakeCentral_SimulatePreconnectedPeripheral_Name = 0; >+ var kFakeCentral_SimulateAdvertisementReceived_Name = 1; >+ var kFakeCentral_SetNextGATTConnectionResponse_Name = 2; >+ var kFakeCentral_SetNextGATTDiscoveryResponse_Name = 3; >+ var kFakeCentral_SimulateGATTDisconnection_Name = 4; >+ var kFakeCentral_SimulateGATTServicesChanged_Name = 5; >+ var kFakeCentral_AddFakeService_Name = 6; >+ var kFakeCentral_RemoveFakeService_Name = 7; >+ var kFakeCentral_AddFakeCharacteristic_Name = 8; >+ var kFakeCentral_RemoveFakeCharacteristic_Name = 9; >+ var kFakeCentral_AddFakeDescriptor_Name = 10; >+ var kFakeCentral_RemoveFakeDescriptor_Name = 11; >+ var kFakeCentral_SetNextReadCharacteristicResponse_Name = 12; >+ var kFakeCentral_SetNextWriteCharacteristicResponse_Name = 13; >+ var kFakeCentral_SetNextSubscribeToNotificationsResponse_Name = 14; >+ var kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name = 15; >+ var kFakeCentral_IsNotifying_Name = 16; >+ var kFakeCentral_GetLastWrittenCharacteristicValue_Name = 17; >+ var kFakeCentral_SetNextReadDescriptorResponse_Name = 18; >+ var kFakeCentral_SetNextWriteDescriptorResponse_Name = 19; >+ var kFakeCentral_GetLastWrittenDescriptorValue_Name = 20; >+ >+ function FakeCentralPtr(handleOrPtrInfo) { >+ this.ptr = new bindings.InterfacePtrController(FakeCentral, >+ handleOrPtrInfo); >+ } >+ >+ function FakeCentralAssociatedPtr(associatedInterfacePtrInfo) { >+ this.ptr = new associatedBindings.AssociatedInterfacePtrController( >+ FakeCentral, associatedInterfacePtrInfo); >+ } >+ >+ FakeCentralAssociatedPtr.prototype = >+ Object.create(FakeCentralPtr.prototype); >+ FakeCentralAssociatedPtr.prototype.constructor = >+ FakeCentralAssociatedPtr; >+ >+ function FakeCentralProxy(receiver) { >+ this.receiver_ = receiver; >+ } >+ FakeCentralPtr.prototype.simulatePreconnectedPeripheral = function() { >+ return FakeCentralProxy.prototype.simulatePreconnectedPeripheral >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.simulatePreconnectedPeripheral = function(address, name, knownServiceUuids) { >+ var params = new FakeCentral_SimulatePreconnectedPeripheral_Params(); >+ params.address = address; >+ params.name = name; >+ params.knownServiceUuids = knownServiceUuids; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SimulatePreconnectedPeripheral_Name, >+ codec.align(FakeCentral_SimulatePreconnectedPeripheral_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_SimulatePreconnectedPeripheral_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_SimulatePreconnectedPeripheral_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.simulateAdvertisementReceived = function() { >+ return FakeCentralProxy.prototype.simulateAdvertisementReceived >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.simulateAdvertisementReceived = function(result) { >+ var params = new FakeCentral_SimulateAdvertisementReceived_Params(); >+ params.result = result; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SimulateAdvertisementReceived_Name, >+ codec.align(FakeCentral_SimulateAdvertisementReceived_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_SimulateAdvertisementReceived_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_SimulateAdvertisementReceived_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.setNextGATTConnectionResponse = function() { >+ return FakeCentralProxy.prototype.setNextGATTConnectionResponse >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.setNextGATTConnectionResponse = function(address, code) { >+ var params = new FakeCentral_SetNextGATTConnectionResponse_Params(); >+ params.address = address; >+ params.code = code; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SetNextGATTConnectionResponse_Name, >+ codec.align(FakeCentral_SetNextGATTConnectionResponse_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_SetNextGATTConnectionResponse_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_SetNextGATTConnectionResponse_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.setNextGATTDiscoveryResponse = function() { >+ return FakeCentralProxy.prototype.setNextGATTDiscoveryResponse >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.setNextGATTDiscoveryResponse = function(address, code) { >+ var params = new FakeCentral_SetNextGATTDiscoveryResponse_Params(); >+ params.address = address; >+ params.code = code; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SetNextGATTDiscoveryResponse_Name, >+ codec.align(FakeCentral_SetNextGATTDiscoveryResponse_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_SetNextGATTDiscoveryResponse_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.simulateGATTDisconnection = function() { >+ return FakeCentralProxy.prototype.simulateGATTDisconnection >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.simulateGATTDisconnection = function(address) { >+ var params = new FakeCentral_SimulateGATTDisconnection_Params(); >+ params.address = address; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SimulateGATTDisconnection_Name, >+ codec.align(FakeCentral_SimulateGATTDisconnection_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_SimulateGATTDisconnection_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_SimulateGATTDisconnection_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.simulateGATTServicesChanged = function() { >+ return FakeCentralProxy.prototype.simulateGATTServicesChanged >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.simulateGATTServicesChanged = function(address) { >+ var params = new FakeCentral_SimulateGATTServicesChanged_Params(); >+ params.address = address; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SimulateGATTServicesChanged_Name, >+ codec.align(FakeCentral_SimulateGATTServicesChanged_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_SimulateGATTServicesChanged_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_SimulateGATTServicesChanged_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.addFakeService = function() { >+ return FakeCentralProxy.prototype.addFakeService >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.addFakeService = function(peripheralAddress, serviceUuid) { >+ var params = new FakeCentral_AddFakeService_Params(); >+ params.peripheralAddress = peripheralAddress; >+ params.serviceUuid = serviceUuid; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_AddFakeService_Name, >+ codec.align(FakeCentral_AddFakeService_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_AddFakeService_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_AddFakeService_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.removeFakeService = function() { >+ return FakeCentralProxy.prototype.removeFakeService >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.removeFakeService = function(serviceId, peripheralAddress) { >+ var params = new FakeCentral_RemoveFakeService_Params(); >+ params.serviceId = serviceId; >+ params.peripheralAddress = peripheralAddress; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_RemoveFakeService_Name, >+ codec.align(FakeCentral_RemoveFakeService_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_RemoveFakeService_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_RemoveFakeService_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.addFakeCharacteristic = function() { >+ return FakeCentralProxy.prototype.addFakeCharacteristic >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.addFakeCharacteristic = function(characteristicUuid, properties, serviceId, peripheralAddress) { >+ var params = new FakeCentral_AddFakeCharacteristic_Params(); >+ params.characteristicUuid = characteristicUuid; >+ params.properties = properties; >+ params.serviceId = serviceId; >+ params.peripheralAddress = peripheralAddress; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_AddFakeCharacteristic_Name, >+ codec.align(FakeCentral_AddFakeCharacteristic_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_AddFakeCharacteristic_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_AddFakeCharacteristic_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.removeFakeCharacteristic = function() { >+ return FakeCentralProxy.prototype.removeFakeCharacteristic >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.removeFakeCharacteristic = function(identifier, serviceId, peripheralAddress) { >+ var params = new FakeCentral_RemoveFakeCharacteristic_Params(); >+ params.identifier = identifier; >+ params.serviceId = serviceId; >+ params.peripheralAddress = peripheralAddress; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_RemoveFakeCharacteristic_Name, >+ codec.align(FakeCentral_RemoveFakeCharacteristic_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_RemoveFakeCharacteristic_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_RemoveFakeCharacteristic_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.addFakeDescriptor = function() { >+ return FakeCentralProxy.prototype.addFakeDescriptor >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.addFakeDescriptor = function(descriptorUuid, characteristicId, serviceId, peripheralAddress) { >+ var params = new FakeCentral_AddFakeDescriptor_Params(); >+ params.descriptorUuid = descriptorUuid; >+ params.characteristicId = characteristicId; >+ params.serviceId = serviceId; >+ params.peripheralAddress = peripheralAddress; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_AddFakeDescriptor_Name, >+ codec.align(FakeCentral_AddFakeDescriptor_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_AddFakeDescriptor_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_AddFakeDescriptor_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.removeFakeDescriptor = function() { >+ return FakeCentralProxy.prototype.removeFakeDescriptor >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.removeFakeDescriptor = function(descriptorId, characteristicId, serviceId, peripheralAddress) { >+ var params = new FakeCentral_RemoveFakeDescriptor_Params(); >+ params.descriptorId = descriptorId; >+ params.characteristicId = characteristicId; >+ params.serviceId = serviceId; >+ params.peripheralAddress = peripheralAddress; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_RemoveFakeDescriptor_Name, >+ codec.align(FakeCentral_RemoveFakeDescriptor_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_RemoveFakeDescriptor_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_RemoveFakeDescriptor_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.setNextReadCharacteristicResponse = function() { >+ return FakeCentralProxy.prototype.setNextReadCharacteristicResponse >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.setNextReadCharacteristicResponse = function(gattCode, value, characteristicId, serviceId, peripheralAddress) { >+ var params = new FakeCentral_SetNextReadCharacteristicResponse_Params(); >+ params.gattCode = gattCode; >+ params.value = value; >+ params.characteristicId = characteristicId; >+ params.serviceId = serviceId; >+ params.peripheralAddress = peripheralAddress; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SetNextReadCharacteristicResponse_Name, >+ codec.align(FakeCentral_SetNextReadCharacteristicResponse_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_SetNextReadCharacteristicResponse_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_SetNextReadCharacteristicResponse_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.setNextWriteCharacteristicResponse = function() { >+ return FakeCentralProxy.prototype.setNextWriteCharacteristicResponse >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.setNextWriteCharacteristicResponse = function(gattCode, characteristicId, serviceId, peripheralAddress) { >+ var params = new FakeCentral_SetNextWriteCharacteristicResponse_Params(); >+ params.gattCode = gattCode; >+ params.characteristicId = characteristicId; >+ params.serviceId = serviceId; >+ params.peripheralAddress = peripheralAddress; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SetNextWriteCharacteristicResponse_Name, >+ codec.align(FakeCentral_SetNextWriteCharacteristicResponse_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_SetNextWriteCharacteristicResponse_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.setNextSubscribeToNotificationsResponse = function() { >+ return FakeCentralProxy.prototype.setNextSubscribeToNotificationsResponse >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.setNextSubscribeToNotificationsResponse = function(gattCode, characteristicId, serviceId, peripheralAddress) { >+ var params = new FakeCentral_SetNextSubscribeToNotificationsResponse_Params(); >+ params.gattCode = gattCode; >+ params.characteristicId = characteristicId; >+ params.serviceId = serviceId; >+ params.peripheralAddress = peripheralAddress; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SetNextSubscribeToNotificationsResponse_Name, >+ codec.align(FakeCentral_SetNextSubscribeToNotificationsResponse_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_SetNextSubscribeToNotificationsResponse_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.setNextUnsubscribeFromNotificationsResponse = function() { >+ return FakeCentralProxy.prototype.setNextUnsubscribeFromNotificationsResponse >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.setNextUnsubscribeFromNotificationsResponse = function(gattCode, characteristicId, serviceId, peripheralAddress) { >+ var params = new FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params(); >+ params.gattCode = gattCode; >+ params.characteristicId = characteristicId; >+ params.serviceId = serviceId; >+ params.peripheralAddress = peripheralAddress; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name, >+ codec.align(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.isNotifying = function() { >+ return FakeCentralProxy.prototype.isNotifying >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.isNotifying = function(characteristicId, serviceId, peripheralAddress) { >+ var params = new FakeCentral_IsNotifying_Params(); >+ params.characteristicId = characteristicId; >+ params.serviceId = serviceId; >+ params.peripheralAddress = peripheralAddress; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_IsNotifying_Name, >+ codec.align(FakeCentral_IsNotifying_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_IsNotifying_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_IsNotifying_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.getLastWrittenCharacteristicValue = function() { >+ return FakeCentralProxy.prototype.getLastWrittenCharacteristicValue >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.getLastWrittenCharacteristicValue = function(characteristicId, serviceId, peripheralAddress) { >+ var params = new FakeCentral_GetLastWrittenCharacteristicValue_Params(); >+ params.characteristicId = characteristicId; >+ params.serviceId = serviceId; >+ params.peripheralAddress = peripheralAddress; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_GetLastWrittenCharacteristicValue_Name, >+ codec.align(FakeCentral_GetLastWrittenCharacteristicValue_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_GetLastWrittenCharacteristicValue_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.setNextReadDescriptorResponse = function() { >+ return FakeCentralProxy.prototype.setNextReadDescriptorResponse >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.setNextReadDescriptorResponse = function(gattCode, value, descriptorId, characteristicId, serviceId, peripheralAddress) { >+ var params = new FakeCentral_SetNextReadDescriptorResponse_Params(); >+ params.gattCode = gattCode; >+ params.value = value; >+ params.descriptorId = descriptorId; >+ params.characteristicId = characteristicId; >+ params.serviceId = serviceId; >+ params.peripheralAddress = peripheralAddress; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SetNextReadDescriptorResponse_Name, >+ codec.align(FakeCentral_SetNextReadDescriptorResponse_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_SetNextReadDescriptorResponse_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_SetNextReadDescriptorResponse_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.setNextWriteDescriptorResponse = function() { >+ return FakeCentralProxy.prototype.setNextWriteDescriptorResponse >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.setNextWriteDescriptorResponse = function(gattCode, descriptorId, characteristicId, serviceId, peripheralAddress) { >+ var params = new FakeCentral_SetNextWriteDescriptorResponse_Params(); >+ params.gattCode = gattCode; >+ params.descriptorId = descriptorId; >+ params.characteristicId = characteristicId; >+ params.serviceId = serviceId; >+ params.peripheralAddress = peripheralAddress; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SetNextWriteDescriptorResponse_Name, >+ codec.align(FakeCentral_SetNextWriteDescriptorResponse_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_SetNextWriteDescriptorResponse_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_SetNextWriteDescriptorResponse_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeCentralPtr.prototype.getLastWrittenDescriptorValue = function() { >+ return FakeCentralProxy.prototype.getLastWrittenDescriptorValue >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeCentralProxy.prototype.getLastWrittenDescriptorValue = function(descriptorId, characteristicId, serviceId, peripheralAddress) { >+ var params = new FakeCentral_GetLastWrittenDescriptorValue_Params(); >+ params.descriptorId = descriptorId; >+ params.characteristicId = characteristicId; >+ params.serviceId = serviceId; >+ params.peripheralAddress = peripheralAddress; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_GetLastWrittenDescriptorValue_Name, >+ codec.align(FakeCentral_GetLastWrittenDescriptorValue_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeCentral_GetLastWrittenDescriptorValue_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeCentral_GetLastWrittenDescriptorValue_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ >+ function FakeCentralStub(delegate) { >+ this.delegate_ = delegate; >+ } >+ FakeCentralStub.prototype.simulatePreconnectedPeripheral = function(address, name, knownServiceUuids) { >+ return this.delegate_ && this.delegate_.simulatePreconnectedPeripheral && this.delegate_.simulatePreconnectedPeripheral(address, name, knownServiceUuids); >+ } >+ FakeCentralStub.prototype.simulateAdvertisementReceived = function(result) { >+ return this.delegate_ && this.delegate_.simulateAdvertisementReceived && this.delegate_.simulateAdvertisementReceived(result); >+ } >+ FakeCentralStub.prototype.setNextGATTConnectionResponse = function(address, code) { >+ return this.delegate_ && this.delegate_.setNextGATTConnectionResponse && this.delegate_.setNextGATTConnectionResponse(address, code); >+ } >+ FakeCentralStub.prototype.setNextGATTDiscoveryResponse = function(address, code) { >+ return this.delegate_ && this.delegate_.setNextGATTDiscoveryResponse && this.delegate_.setNextGATTDiscoveryResponse(address, code); >+ } >+ FakeCentralStub.prototype.simulateGATTDisconnection = function(address) { >+ return this.delegate_ && this.delegate_.simulateGATTDisconnection && this.delegate_.simulateGATTDisconnection(address); >+ } >+ FakeCentralStub.prototype.simulateGATTServicesChanged = function(address) { >+ return this.delegate_ && this.delegate_.simulateGATTServicesChanged && this.delegate_.simulateGATTServicesChanged(address); >+ } >+ FakeCentralStub.prototype.addFakeService = function(peripheralAddress, serviceUuid) { >+ return this.delegate_ && this.delegate_.addFakeService && this.delegate_.addFakeService(peripheralAddress, serviceUuid); >+ } >+ FakeCentralStub.prototype.removeFakeService = function(serviceId, peripheralAddress) { >+ return this.delegate_ && this.delegate_.removeFakeService && this.delegate_.removeFakeService(serviceId, peripheralAddress); >+ } >+ FakeCentralStub.prototype.addFakeCharacteristic = function(characteristicUuid, properties, serviceId, peripheralAddress) { >+ return this.delegate_ && this.delegate_.addFakeCharacteristic && this.delegate_.addFakeCharacteristic(characteristicUuid, properties, serviceId, peripheralAddress); >+ } >+ FakeCentralStub.prototype.removeFakeCharacteristic = function(identifier, serviceId, peripheralAddress) { >+ return this.delegate_ && this.delegate_.removeFakeCharacteristic && this.delegate_.removeFakeCharacteristic(identifier, serviceId, peripheralAddress); >+ } >+ FakeCentralStub.prototype.addFakeDescriptor = function(descriptorUuid, characteristicId, serviceId, peripheralAddress) { >+ return this.delegate_ && this.delegate_.addFakeDescriptor && this.delegate_.addFakeDescriptor(descriptorUuid, characteristicId, serviceId, peripheralAddress); >+ } >+ FakeCentralStub.prototype.removeFakeDescriptor = function(descriptorId, characteristicId, serviceId, peripheralAddress) { >+ return this.delegate_ && this.delegate_.removeFakeDescriptor && this.delegate_.removeFakeDescriptor(descriptorId, characteristicId, serviceId, peripheralAddress); >+ } >+ FakeCentralStub.prototype.setNextReadCharacteristicResponse = function(gattCode, value, characteristicId, serviceId, peripheralAddress) { >+ return this.delegate_ && this.delegate_.setNextReadCharacteristicResponse && this.delegate_.setNextReadCharacteristicResponse(gattCode, value, characteristicId, serviceId, peripheralAddress); >+ } >+ FakeCentralStub.prototype.setNextWriteCharacteristicResponse = function(gattCode, characteristicId, serviceId, peripheralAddress) { >+ return this.delegate_ && this.delegate_.setNextWriteCharacteristicResponse && this.delegate_.setNextWriteCharacteristicResponse(gattCode, characteristicId, serviceId, peripheralAddress); >+ } >+ FakeCentralStub.prototype.setNextSubscribeToNotificationsResponse = function(gattCode, characteristicId, serviceId, peripheralAddress) { >+ return this.delegate_ && this.delegate_.setNextSubscribeToNotificationsResponse && this.delegate_.setNextSubscribeToNotificationsResponse(gattCode, characteristicId, serviceId, peripheralAddress); >+ } >+ FakeCentralStub.prototype.setNextUnsubscribeFromNotificationsResponse = function(gattCode, characteristicId, serviceId, peripheralAddress) { >+ return this.delegate_ && this.delegate_.setNextUnsubscribeFromNotificationsResponse && this.delegate_.setNextUnsubscribeFromNotificationsResponse(gattCode, characteristicId, serviceId, peripheralAddress); >+ } >+ FakeCentralStub.prototype.isNotifying = function(characteristicId, serviceId, peripheralAddress) { >+ return this.delegate_ && this.delegate_.isNotifying && this.delegate_.isNotifying(characteristicId, serviceId, peripheralAddress); >+ } >+ FakeCentralStub.prototype.getLastWrittenCharacteristicValue = function(characteristicId, serviceId, peripheralAddress) { >+ return this.delegate_ && this.delegate_.getLastWrittenCharacteristicValue && this.delegate_.getLastWrittenCharacteristicValue(characteristicId, serviceId, peripheralAddress); >+ } >+ FakeCentralStub.prototype.setNextReadDescriptorResponse = function(gattCode, value, descriptorId, characteristicId, serviceId, peripheralAddress) { >+ return this.delegate_ && this.delegate_.setNextReadDescriptorResponse && this.delegate_.setNextReadDescriptorResponse(gattCode, value, descriptorId, characteristicId, serviceId, peripheralAddress); >+ } >+ FakeCentralStub.prototype.setNextWriteDescriptorResponse = function(gattCode, descriptorId, characteristicId, serviceId, peripheralAddress) { >+ return this.delegate_ && this.delegate_.setNextWriteDescriptorResponse && this.delegate_.setNextWriteDescriptorResponse(gattCode, descriptorId, characteristicId, serviceId, peripheralAddress); >+ } >+ FakeCentralStub.prototype.getLastWrittenDescriptorValue = function(descriptorId, characteristicId, serviceId, peripheralAddress) { >+ return this.delegate_ && this.delegate_.getLastWrittenDescriptorValue && this.delegate_.getLastWrittenDescriptorValue(descriptorId, characteristicId, serviceId, peripheralAddress); >+ } >+ >+ FakeCentralStub.prototype.accept = function(message) { >+ var reader = new codec.MessageReader(message); >+ switch (reader.messageName) { >+ default: >+ return false; >+ } >+ }; >+ >+ FakeCentralStub.prototype.acceptWithResponder = >+ function(message, responder) { >+ var reader = new codec.MessageReader(message); >+ switch (reader.messageName) { >+ case kFakeCentral_SimulatePreconnectedPeripheral_Name: >+ var params = reader.decodeStruct(FakeCentral_SimulatePreconnectedPeripheral_Params); >+ this.simulatePreconnectedPeripheral(params.address, params.name, params.knownServiceUuids).then(function(response) { >+ var responseParams = >+ new FakeCentral_SimulatePreconnectedPeripheral_ResponseParams(); >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SimulatePreconnectedPeripheral_Name, >+ codec.align(FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_SimulatePreconnectedPeripheral_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_SimulateAdvertisementReceived_Name: >+ var params = reader.decodeStruct(FakeCentral_SimulateAdvertisementReceived_Params); >+ this.simulateAdvertisementReceived(params.result).then(function(response) { >+ var responseParams = >+ new FakeCentral_SimulateAdvertisementReceived_ResponseParams(); >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SimulateAdvertisementReceived_Name, >+ codec.align(FakeCentral_SimulateAdvertisementReceived_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_SimulateAdvertisementReceived_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_SetNextGATTConnectionResponse_Name: >+ var params = reader.decodeStruct(FakeCentral_SetNextGATTConnectionResponse_Params); >+ this.setNextGATTConnectionResponse(params.address, params.code).then(function(response) { >+ var responseParams = >+ new FakeCentral_SetNextGATTConnectionResponse_ResponseParams(); >+ responseParams.success = response.success; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SetNextGATTConnectionResponse_Name, >+ codec.align(FakeCentral_SetNextGATTConnectionResponse_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_SetNextGATTConnectionResponse_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_SetNextGATTDiscoveryResponse_Name: >+ var params = reader.decodeStruct(FakeCentral_SetNextGATTDiscoveryResponse_Params); >+ this.setNextGATTDiscoveryResponse(params.address, params.code).then(function(response) { >+ var responseParams = >+ new FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams(); >+ responseParams.success = response.success; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SetNextGATTDiscoveryResponse_Name, >+ codec.align(FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_SimulateGATTDisconnection_Name: >+ var params = reader.decodeStruct(FakeCentral_SimulateGATTDisconnection_Params); >+ this.simulateGATTDisconnection(params.address).then(function(response) { >+ var responseParams = >+ new FakeCentral_SimulateGATTDisconnection_ResponseParams(); >+ responseParams.success = response.success; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SimulateGATTDisconnection_Name, >+ codec.align(FakeCentral_SimulateGATTDisconnection_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_SimulateGATTDisconnection_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_SimulateGATTServicesChanged_Name: >+ var params = reader.decodeStruct(FakeCentral_SimulateGATTServicesChanged_Params); >+ this.simulateGATTServicesChanged(params.address).then(function(response) { >+ var responseParams = >+ new FakeCentral_SimulateGATTServicesChanged_ResponseParams(); >+ responseParams.success = response.success; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SimulateGATTServicesChanged_Name, >+ codec.align(FakeCentral_SimulateGATTServicesChanged_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_SimulateGATTServicesChanged_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_AddFakeService_Name: >+ var params = reader.decodeStruct(FakeCentral_AddFakeService_Params); >+ this.addFakeService(params.peripheralAddress, params.serviceUuid).then(function(response) { >+ var responseParams = >+ new FakeCentral_AddFakeService_ResponseParams(); >+ responseParams.serviceId = response.serviceId; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_AddFakeService_Name, >+ codec.align(FakeCentral_AddFakeService_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_AddFakeService_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_RemoveFakeService_Name: >+ var params = reader.decodeStruct(FakeCentral_RemoveFakeService_Params); >+ this.removeFakeService(params.serviceId, params.peripheralAddress).then(function(response) { >+ var responseParams = >+ new FakeCentral_RemoveFakeService_ResponseParams(); >+ responseParams.success = response.success; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_RemoveFakeService_Name, >+ codec.align(FakeCentral_RemoveFakeService_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_RemoveFakeService_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_AddFakeCharacteristic_Name: >+ var params = reader.decodeStruct(FakeCentral_AddFakeCharacteristic_Params); >+ this.addFakeCharacteristic(params.characteristicUuid, params.properties, params.serviceId, params.peripheralAddress).then(function(response) { >+ var responseParams = >+ new FakeCentral_AddFakeCharacteristic_ResponseParams(); >+ responseParams.characteristicId = response.characteristicId; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_AddFakeCharacteristic_Name, >+ codec.align(FakeCentral_AddFakeCharacteristic_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_AddFakeCharacteristic_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_RemoveFakeCharacteristic_Name: >+ var params = reader.decodeStruct(FakeCentral_RemoveFakeCharacteristic_Params); >+ this.removeFakeCharacteristic(params.identifier, params.serviceId, params.peripheralAddress).then(function(response) { >+ var responseParams = >+ new FakeCentral_RemoveFakeCharacteristic_ResponseParams(); >+ responseParams.success = response.success; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_RemoveFakeCharacteristic_Name, >+ codec.align(FakeCentral_RemoveFakeCharacteristic_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_RemoveFakeCharacteristic_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_AddFakeDescriptor_Name: >+ var params = reader.decodeStruct(FakeCentral_AddFakeDescriptor_Params); >+ this.addFakeDescriptor(params.descriptorUuid, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) { >+ var responseParams = >+ new FakeCentral_AddFakeDescriptor_ResponseParams(); >+ responseParams.descriptorId = response.descriptorId; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_AddFakeDescriptor_Name, >+ codec.align(FakeCentral_AddFakeDescriptor_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_AddFakeDescriptor_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_RemoveFakeDescriptor_Name: >+ var params = reader.decodeStruct(FakeCentral_RemoveFakeDescriptor_Params); >+ this.removeFakeDescriptor(params.descriptorId, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) { >+ var responseParams = >+ new FakeCentral_RemoveFakeDescriptor_ResponseParams(); >+ responseParams.success = response.success; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_RemoveFakeDescriptor_Name, >+ codec.align(FakeCentral_RemoveFakeDescriptor_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_RemoveFakeDescriptor_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_SetNextReadCharacteristicResponse_Name: >+ var params = reader.decodeStruct(FakeCentral_SetNextReadCharacteristicResponse_Params); >+ this.setNextReadCharacteristicResponse(params.gattCode, params.value, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) { >+ var responseParams = >+ new FakeCentral_SetNextReadCharacteristicResponse_ResponseParams(); >+ responseParams.success = response.success; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SetNextReadCharacteristicResponse_Name, >+ codec.align(FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_SetNextReadCharacteristicResponse_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_SetNextWriteCharacteristicResponse_Name: >+ var params = reader.decodeStruct(FakeCentral_SetNextWriteCharacteristicResponse_Params); >+ this.setNextWriteCharacteristicResponse(params.gattCode, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) { >+ var responseParams = >+ new FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams(); >+ responseParams.success = response.success; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SetNextWriteCharacteristicResponse_Name, >+ codec.align(FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_SetNextSubscribeToNotificationsResponse_Name: >+ var params = reader.decodeStruct(FakeCentral_SetNextSubscribeToNotificationsResponse_Params); >+ this.setNextSubscribeToNotificationsResponse(params.gattCode, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) { >+ var responseParams = >+ new FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams(); >+ responseParams.success = response.success; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SetNextSubscribeToNotificationsResponse_Name, >+ codec.align(FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name: >+ var params = reader.decodeStruct(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params); >+ this.setNextUnsubscribeFromNotificationsResponse(params.gattCode, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) { >+ var responseParams = >+ new FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams(); >+ responseParams.success = response.success; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name, >+ codec.align(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_IsNotifying_Name: >+ var params = reader.decodeStruct(FakeCentral_IsNotifying_Params); >+ this.isNotifying(params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) { >+ var responseParams = >+ new FakeCentral_IsNotifying_ResponseParams(); >+ responseParams.success = response.success; >+ responseParams.isNotifying = response.isNotifying; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_IsNotifying_Name, >+ codec.align(FakeCentral_IsNotifying_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_IsNotifying_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_GetLastWrittenCharacteristicValue_Name: >+ var params = reader.decodeStruct(FakeCentral_GetLastWrittenCharacteristicValue_Params); >+ this.getLastWrittenCharacteristicValue(params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) { >+ var responseParams = >+ new FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams(); >+ responseParams.success = response.success; >+ responseParams.value = response.value; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_GetLastWrittenCharacteristicValue_Name, >+ codec.align(FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_SetNextReadDescriptorResponse_Name: >+ var params = reader.decodeStruct(FakeCentral_SetNextReadDescriptorResponse_Params); >+ this.setNextReadDescriptorResponse(params.gattCode, params.value, params.descriptorId, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) { >+ var responseParams = >+ new FakeCentral_SetNextReadDescriptorResponse_ResponseParams(); >+ responseParams.success = response.success; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SetNextReadDescriptorResponse_Name, >+ codec.align(FakeCentral_SetNextReadDescriptorResponse_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_SetNextReadDescriptorResponse_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_SetNextWriteDescriptorResponse_Name: >+ var params = reader.decodeStruct(FakeCentral_SetNextWriteDescriptorResponse_Params); >+ this.setNextWriteDescriptorResponse(params.gattCode, params.descriptorId, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) { >+ var responseParams = >+ new FakeCentral_SetNextWriteDescriptorResponse_ResponseParams(); >+ responseParams.success = response.success; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_SetNextWriteDescriptorResponse_Name, >+ codec.align(FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_SetNextWriteDescriptorResponse_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeCentral_GetLastWrittenDescriptorValue_Name: >+ var params = reader.decodeStruct(FakeCentral_GetLastWrittenDescriptorValue_Params); >+ this.getLastWrittenDescriptorValue(params.descriptorId, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) { >+ var responseParams = >+ new FakeCentral_GetLastWrittenDescriptorValue_ResponseParams(); >+ responseParams.success = response.success; >+ responseParams.value = response.value; >+ var builder = new codec.MessageV1Builder( >+ kFakeCentral_GetLastWrittenDescriptorValue_Name, >+ codec.align(FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeCentral_GetLastWrittenDescriptorValue_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ default: >+ return false; >+ } >+ }; >+ >+ function validateFakeCentralRequest(messageValidator) { >+ var message = messageValidator.message; >+ var paramsClass = null; >+ switch (message.getName()) { >+ case kFakeCentral_SimulatePreconnectedPeripheral_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_SimulatePreconnectedPeripheral_Params; >+ break; >+ case kFakeCentral_SimulateAdvertisementReceived_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_SimulateAdvertisementReceived_Params; >+ break; >+ case kFakeCentral_SetNextGATTConnectionResponse_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_SetNextGATTConnectionResponse_Params; >+ break; >+ case kFakeCentral_SetNextGATTDiscoveryResponse_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_SetNextGATTDiscoveryResponse_Params; >+ break; >+ case kFakeCentral_SimulateGATTDisconnection_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_SimulateGATTDisconnection_Params; >+ break; >+ case kFakeCentral_SimulateGATTServicesChanged_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_SimulateGATTServicesChanged_Params; >+ break; >+ case kFakeCentral_AddFakeService_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_AddFakeService_Params; >+ break; >+ case kFakeCentral_RemoveFakeService_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_RemoveFakeService_Params; >+ break; >+ case kFakeCentral_AddFakeCharacteristic_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_AddFakeCharacteristic_Params; >+ break; >+ case kFakeCentral_RemoveFakeCharacteristic_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_RemoveFakeCharacteristic_Params; >+ break; >+ case kFakeCentral_AddFakeDescriptor_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_AddFakeDescriptor_Params; >+ break; >+ case kFakeCentral_RemoveFakeDescriptor_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_RemoveFakeDescriptor_Params; >+ break; >+ case kFakeCentral_SetNextReadCharacteristicResponse_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_SetNextReadCharacteristicResponse_Params; >+ break; >+ case kFakeCentral_SetNextWriteCharacteristicResponse_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_SetNextWriteCharacteristicResponse_Params; >+ break; >+ case kFakeCentral_SetNextSubscribeToNotificationsResponse_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_SetNextSubscribeToNotificationsResponse_Params; >+ break; >+ case kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params; >+ break; >+ case kFakeCentral_IsNotifying_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_IsNotifying_Params; >+ break; >+ case kFakeCentral_GetLastWrittenCharacteristicValue_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_GetLastWrittenCharacteristicValue_Params; >+ break; >+ case kFakeCentral_SetNextReadDescriptorResponse_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_SetNextReadDescriptorResponse_Params; >+ break; >+ case kFakeCentral_SetNextWriteDescriptorResponse_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_SetNextWriteDescriptorResponse_Params; >+ break; >+ case kFakeCentral_GetLastWrittenDescriptorValue_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeCentral_GetLastWrittenDescriptorValue_Params; >+ break; >+ } >+ if (paramsClass === null) >+ return validator.validationError.NONE; >+ return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); >+ } >+ >+ function validateFakeCentralResponse(messageValidator) { >+ var message = messageValidator.message; >+ var paramsClass = null; >+ switch (message.getName()) { >+ case kFakeCentral_SimulatePreconnectedPeripheral_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_SimulatePreconnectedPeripheral_ResponseParams; >+ break; >+ case kFakeCentral_SimulateAdvertisementReceived_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_SimulateAdvertisementReceived_ResponseParams; >+ break; >+ case kFakeCentral_SetNextGATTConnectionResponse_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_SetNextGATTConnectionResponse_ResponseParams; >+ break; >+ case kFakeCentral_SetNextGATTDiscoveryResponse_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams; >+ break; >+ case kFakeCentral_SimulateGATTDisconnection_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_SimulateGATTDisconnection_ResponseParams; >+ break; >+ case kFakeCentral_SimulateGATTServicesChanged_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_SimulateGATTServicesChanged_ResponseParams; >+ break; >+ case kFakeCentral_AddFakeService_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_AddFakeService_ResponseParams; >+ break; >+ case kFakeCentral_RemoveFakeService_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_RemoveFakeService_ResponseParams; >+ break; >+ case kFakeCentral_AddFakeCharacteristic_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_AddFakeCharacteristic_ResponseParams; >+ break; >+ case kFakeCentral_RemoveFakeCharacteristic_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_RemoveFakeCharacteristic_ResponseParams; >+ break; >+ case kFakeCentral_AddFakeDescriptor_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_AddFakeDescriptor_ResponseParams; >+ break; >+ case kFakeCentral_RemoveFakeDescriptor_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_RemoveFakeDescriptor_ResponseParams; >+ break; >+ case kFakeCentral_SetNextReadCharacteristicResponse_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_SetNextReadCharacteristicResponse_ResponseParams; >+ break; >+ case kFakeCentral_SetNextWriteCharacteristicResponse_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams; >+ break; >+ case kFakeCentral_SetNextSubscribeToNotificationsResponse_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams; >+ break; >+ case kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams; >+ break; >+ case kFakeCentral_IsNotifying_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_IsNotifying_ResponseParams; >+ break; >+ case kFakeCentral_GetLastWrittenCharacteristicValue_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams; >+ break; >+ case kFakeCentral_SetNextReadDescriptorResponse_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_SetNextReadDescriptorResponse_ResponseParams; >+ break; >+ case kFakeCentral_SetNextWriteDescriptorResponse_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_SetNextWriteDescriptorResponse_ResponseParams; >+ break; >+ case kFakeCentral_GetLastWrittenDescriptorValue_Name: >+ if (message.isResponse()) >+ paramsClass = FakeCentral_GetLastWrittenDescriptorValue_ResponseParams; >+ break; >+ } >+ if (paramsClass === null) >+ return validator.validationError.NONE; >+ return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); >+ } >+ >+ var FakeCentral = { >+ name: 'bluetooth.mojom.FakeCentral', >+ kVersion: 0, >+ ptrClass: FakeCentralPtr, >+ proxyClass: FakeCentralProxy, >+ stubClass: FakeCentralStub, >+ validateRequest: validateFakeCentralRequest, >+ validateResponse: validateFakeCentralResponse, >+ }; >+ FakeCentralStub.prototype.validator = validateFakeCentralRequest; >+ FakeCentralProxy.prototype.validator = validateFakeCentralResponse; >+ exports.kHCISuccess = kHCISuccess; >+ exports.kHCIConnectionTimeout = kHCIConnectionTimeout; >+ exports.kGATTSuccess = kGATTSuccess; >+ exports.kGATTInvalidHandle = kGATTInvalidHandle; >+ exports.CentralState = CentralState; >+ exports.Appearance = Appearance; >+ exports.Power = Power; >+ exports.ServiceDataMap = ServiceDataMap; >+ exports.ScanRecord = ScanRecord; >+ exports.ScanResult = ScanResult; >+ exports.CharacteristicProperties = CharacteristicProperties; >+ exports.FakeBluetooth = FakeBluetooth; >+ exports.FakeBluetoothPtr = FakeBluetoothPtr; >+ exports.FakeBluetoothAssociatedPtr = FakeBluetoothAssociatedPtr; >+ exports.FakeCentral = FakeCentral; >+ exports.FakeCentralPtr = FakeCentralPtr; >+ exports.FakeCentralAssociatedPtr = FakeCentralAssociatedPtr; >+})(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/fake_bluetooth.mojom.js.headers b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/fake_bluetooth.mojom.js.headers >new file mode 100644 >index 0000000000000000000000000000000000000000..6805c323df5a975231648b830e33ce183c3cbbd3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/fake_bluetooth.mojom.js.headers >@@ -0,0 +1 @@ >+Content-Type: text/javascript; charset=utf-8 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/fake_bluetooth_chooser.mojom.js b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/fake_bluetooth_chooser.mojom.js >new file mode 100644 >index 0000000000000000000000000000000000000000..42739393c10984ad6b8890123eb4fa66671cde78 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/fake_bluetooth_chooser.mojom.js >@@ -0,0 +1,822 @@ >+// Copyright 2014 The Chromium Authors. All rights reserved. >+// Use of this source code is governed by a BSD-style license that can be >+// found in the LICENSE file. >+ >+'use strict'; >+ >+(function() { >+ var mojomId = 'content/shell/common/layout_test/fake_bluetooth_chooser.mojom'; >+ if (mojo.internal.isMojomLoaded(mojomId)) { >+ console.warn('The following mojom is loaded multiple times: ' + mojomId); >+ return; >+ } >+ mojo.internal.markMojomLoaded(mojomId); >+ var bindings = mojo; >+ var associatedBindings = mojo; >+ var codec = mojo.internal; >+ var validator = mojo.internal; >+ >+ var exports = mojo.internal.exposeNamespace('content.mojom'); >+ >+ >+ var ChooserEventType = {}; >+ ChooserEventType.CHOOSER_OPENED = 0; >+ ChooserEventType.SCAN_STARTED = ChooserEventType.CHOOSER_OPENED + 1; >+ ChooserEventType.DEVICE_UPDATE = ChooserEventType.SCAN_STARTED + 1; >+ ChooserEventType.ADAPTER_REMOVED = ChooserEventType.DEVICE_UPDATE + 1; >+ ChooserEventType.ADAPTER_DISABLED = ChooserEventType.ADAPTER_REMOVED + 1; >+ ChooserEventType.ADAPTER_ENABLED = ChooserEventType.ADAPTER_DISABLED + 1; >+ ChooserEventType.DISCOVERY_FAILED_TO_START = ChooserEventType.ADAPTER_ENABLED + 1; >+ ChooserEventType.DISCOVERING = ChooserEventType.DISCOVERY_FAILED_TO_START + 1; >+ ChooserEventType.DISCOVERY_IDLE = ChooserEventType.DISCOVERING + 1; >+ ChooserEventType.ADD_DEVICE = ChooserEventType.DISCOVERY_IDLE + 1; >+ >+ ChooserEventType.isKnownEnumValue = function(value) { >+ switch (value) { >+ case 0: >+ case 1: >+ case 2: >+ case 3: >+ case 4: >+ case 5: >+ case 6: >+ case 7: >+ case 8: >+ case 9: >+ return true; >+ } >+ return false; >+ }; >+ >+ ChooserEventType.validate = function(enumValue) { >+ var isExtensible = false; >+ if (isExtensible || this.isKnownEnumValue(enumValue)) >+ return validator.validationError.NONE; >+ >+ return validator.validationError.UNKNOWN_ENUM_VALUE; >+ }; >+ >+ function FakeBluetoothChooserEvent(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeBluetoothChooserEvent.prototype.initDefaults_ = function() { >+ this.type = 0; >+ this.origin = null; >+ this.peripheralAddress = null; >+ }; >+ FakeBluetoothChooserEvent.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeBluetoothChooserEvent.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 32} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeBluetoothChooserEvent.type >+ err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, ChooserEventType); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeBluetoothChooserEvent.origin >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, true) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeBluetoothChooserEvent.peripheralAddress >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, true) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeBluetoothChooserEvent.encodedSize = codec.kStructHeaderSize + 24; >+ >+ FakeBluetoothChooserEvent.decode = function(decoder) { >+ var packed; >+ var val = new FakeBluetoothChooserEvent(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.type = decoder.decodeStruct(codec.Int32); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ val.origin = decoder.decodeStruct(codec.NullableString); >+ val.peripheralAddress = decoder.decodeStruct(codec.NullableString); >+ return val; >+ }; >+ >+ FakeBluetoothChooserEvent.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeBluetoothChooserEvent.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.Int32, val.type); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.encodeStruct(codec.NullableString, val.origin); >+ encoder.encodeStruct(codec.NullableString, val.peripheralAddress); >+ }; >+ function FakeBluetoothChooser_WaitForEvents_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeBluetoothChooser_WaitForEvents_Params.prototype.initDefaults_ = function() { >+ this.numOfEvents = 0; >+ }; >+ FakeBluetoothChooser_WaitForEvents_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeBluetoothChooser_WaitForEvents_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeBluetoothChooser_WaitForEvents_Params.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeBluetoothChooser_WaitForEvents_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeBluetoothChooser_WaitForEvents_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.numOfEvents = decoder.decodeStruct(codec.Uint32); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ FakeBluetoothChooser_WaitForEvents_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeBluetoothChooser_WaitForEvents_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.Uint32, val.numOfEvents); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function FakeBluetoothChooser_WaitForEvents_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeBluetoothChooser_WaitForEvents_ResponseParams.prototype.initDefaults_ = function() { >+ this.events = null; >+ }; >+ FakeBluetoothChooser_WaitForEvents_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeBluetoothChooser_WaitForEvents_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeBluetoothChooser_WaitForEvents_ResponseParams.events >+ err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, new codec.PointerTo(FakeBluetoothChooserEvent), false, [0], 0); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeBluetoothChooser_WaitForEvents_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeBluetoothChooser_WaitForEvents_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeBluetoothChooser_WaitForEvents_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.events = decoder.decodeArrayPointer(new codec.PointerTo(FakeBluetoothChooserEvent)); >+ return val; >+ }; >+ >+ FakeBluetoothChooser_WaitForEvents_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeBluetoothChooser_WaitForEvents_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeArrayPointer(new codec.PointerTo(FakeBluetoothChooserEvent), val.events); >+ }; >+ function FakeBluetoothChooser_SelectPeripheral_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeBluetoothChooser_SelectPeripheral_Params.prototype.initDefaults_ = function() { >+ this.peripheralAddress = null; >+ }; >+ FakeBluetoothChooser_SelectPeripheral_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeBluetoothChooser_SelectPeripheral_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate FakeBluetoothChooser_SelectPeripheral_Params.peripheralAddress >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeBluetoothChooser_SelectPeripheral_Params.encodedSize = codec.kStructHeaderSize + 8; >+ >+ FakeBluetoothChooser_SelectPeripheral_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeBluetoothChooser_SelectPeripheral_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.peripheralAddress = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ FakeBluetoothChooser_SelectPeripheral_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeBluetoothChooser_SelectPeripheral_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.String, val.peripheralAddress); >+ }; >+ function FakeBluetoothChooser_SelectPeripheral_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeBluetoothChooser_SelectPeripheral_ResponseParams.prototype.initDefaults_ = function() { >+ }; >+ FakeBluetoothChooser_SelectPeripheral_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeBluetoothChooser_SelectPeripheral_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 8} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeBluetoothChooser_SelectPeripheral_ResponseParams.encodedSize = codec.kStructHeaderSize + 0; >+ >+ FakeBluetoothChooser_SelectPeripheral_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeBluetoothChooser_SelectPeripheral_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ return val; >+ }; >+ >+ FakeBluetoothChooser_SelectPeripheral_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeBluetoothChooser_SelectPeripheral_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ }; >+ function FakeBluetoothChooser_Cancel_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeBluetoothChooser_Cancel_Params.prototype.initDefaults_ = function() { >+ }; >+ FakeBluetoothChooser_Cancel_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeBluetoothChooser_Cancel_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 8} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeBluetoothChooser_Cancel_Params.encodedSize = codec.kStructHeaderSize + 0; >+ >+ FakeBluetoothChooser_Cancel_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeBluetoothChooser_Cancel_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ return val; >+ }; >+ >+ FakeBluetoothChooser_Cancel_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeBluetoothChooser_Cancel_Params.encodedSize); >+ encoder.writeUint32(0); >+ }; >+ function FakeBluetoothChooser_Cancel_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeBluetoothChooser_Cancel_ResponseParams.prototype.initDefaults_ = function() { >+ }; >+ FakeBluetoothChooser_Cancel_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeBluetoothChooser_Cancel_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 8} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeBluetoothChooser_Cancel_ResponseParams.encodedSize = codec.kStructHeaderSize + 0; >+ >+ FakeBluetoothChooser_Cancel_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeBluetoothChooser_Cancel_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ return val; >+ }; >+ >+ FakeBluetoothChooser_Cancel_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeBluetoothChooser_Cancel_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ }; >+ function FakeBluetoothChooser_Rescan_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeBluetoothChooser_Rescan_Params.prototype.initDefaults_ = function() { >+ }; >+ FakeBluetoothChooser_Rescan_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeBluetoothChooser_Rescan_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 8} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeBluetoothChooser_Rescan_Params.encodedSize = codec.kStructHeaderSize + 0; >+ >+ FakeBluetoothChooser_Rescan_Params.decode = function(decoder) { >+ var packed; >+ var val = new FakeBluetoothChooser_Rescan_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ return val; >+ }; >+ >+ FakeBluetoothChooser_Rescan_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeBluetoothChooser_Rescan_Params.encodedSize); >+ encoder.writeUint32(0); >+ }; >+ function FakeBluetoothChooser_Rescan_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ FakeBluetoothChooser_Rescan_ResponseParams.prototype.initDefaults_ = function() { >+ }; >+ FakeBluetoothChooser_Rescan_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ FakeBluetoothChooser_Rescan_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 8} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ FakeBluetoothChooser_Rescan_ResponseParams.encodedSize = codec.kStructHeaderSize + 0; >+ >+ FakeBluetoothChooser_Rescan_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new FakeBluetoothChooser_Rescan_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ return val; >+ }; >+ >+ FakeBluetoothChooser_Rescan_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(FakeBluetoothChooser_Rescan_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ }; >+ var kFakeBluetoothChooser_WaitForEvents_Name = 457051710; >+ var kFakeBluetoothChooser_SelectPeripheral_Name = 1924310743; >+ var kFakeBluetoothChooser_Cancel_Name = 1388880682; >+ var kFakeBluetoothChooser_Rescan_Name = 2112671529; >+ >+ function FakeBluetoothChooserPtr(handleOrPtrInfo) { >+ this.ptr = new bindings.InterfacePtrController(FakeBluetoothChooser, >+ handleOrPtrInfo); >+ } >+ >+ function FakeBluetoothChooserAssociatedPtr(associatedInterfacePtrInfo) { >+ this.ptr = new associatedBindings.AssociatedInterfacePtrController( >+ FakeBluetoothChooser, associatedInterfacePtrInfo); >+ } >+ >+ FakeBluetoothChooserAssociatedPtr.prototype = >+ Object.create(FakeBluetoothChooserPtr.prototype); >+ FakeBluetoothChooserAssociatedPtr.prototype.constructor = >+ FakeBluetoothChooserAssociatedPtr; >+ >+ function FakeBluetoothChooserProxy(receiver) { >+ this.receiver_ = receiver; >+ } >+ FakeBluetoothChooserPtr.prototype.waitForEvents = function() { >+ return FakeBluetoothChooserProxy.prototype.waitForEvents >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeBluetoothChooserProxy.prototype.waitForEvents = function(numOfEvents) { >+ var params = new FakeBluetoothChooser_WaitForEvents_Params(); >+ params.numOfEvents = numOfEvents; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeBluetoothChooser_WaitForEvents_Name, >+ codec.align(FakeBluetoothChooser_WaitForEvents_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeBluetoothChooser_WaitForEvents_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeBluetoothChooser_WaitForEvents_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeBluetoothChooserPtr.prototype.selectPeripheral = function() { >+ return FakeBluetoothChooserProxy.prototype.selectPeripheral >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeBluetoothChooserProxy.prototype.selectPeripheral = function(peripheralAddress) { >+ var params = new FakeBluetoothChooser_SelectPeripheral_Params(); >+ params.peripheralAddress = peripheralAddress; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeBluetoothChooser_SelectPeripheral_Name, >+ codec.align(FakeBluetoothChooser_SelectPeripheral_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeBluetoothChooser_SelectPeripheral_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeBluetoothChooser_SelectPeripheral_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeBluetoothChooserPtr.prototype.cancel = function() { >+ return FakeBluetoothChooserProxy.prototype.cancel >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeBluetoothChooserProxy.prototype.cancel = function() { >+ var params = new FakeBluetoothChooser_Cancel_Params(); >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeBluetoothChooser_Cancel_Name, >+ codec.align(FakeBluetoothChooser_Cancel_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeBluetoothChooser_Cancel_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeBluetoothChooser_Cancel_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ FakeBluetoothChooserPtr.prototype.rescan = function() { >+ return FakeBluetoothChooserProxy.prototype.rescan >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ FakeBluetoothChooserProxy.prototype.rescan = function() { >+ var params = new FakeBluetoothChooser_Rescan_Params(); >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kFakeBluetoothChooser_Rescan_Name, >+ codec.align(FakeBluetoothChooser_Rescan_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(FakeBluetoothChooser_Rescan_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(FakeBluetoothChooser_Rescan_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ >+ function FakeBluetoothChooserStub(delegate) { >+ this.delegate_ = delegate; >+ } >+ FakeBluetoothChooserStub.prototype.waitForEvents = function(numOfEvents) { >+ return this.delegate_ && this.delegate_.waitForEvents && this.delegate_.waitForEvents(numOfEvents); >+ } >+ FakeBluetoothChooserStub.prototype.selectPeripheral = function(peripheralAddress) { >+ return this.delegate_ && this.delegate_.selectPeripheral && this.delegate_.selectPeripheral(peripheralAddress); >+ } >+ FakeBluetoothChooserStub.prototype.cancel = function() { >+ return this.delegate_ && this.delegate_.cancel && this.delegate_.cancel(); >+ } >+ FakeBluetoothChooserStub.prototype.rescan = function() { >+ return this.delegate_ && this.delegate_.rescan && this.delegate_.rescan(); >+ } >+ >+ FakeBluetoothChooserStub.prototype.accept = function(message) { >+ var reader = new codec.MessageReader(message); >+ switch (reader.messageName) { >+ default: >+ return false; >+ } >+ }; >+ >+ FakeBluetoothChooserStub.prototype.acceptWithResponder = >+ function(message, responder) { >+ var reader = new codec.MessageReader(message); >+ switch (reader.messageName) { >+ case kFakeBluetoothChooser_WaitForEvents_Name: >+ var params = reader.decodeStruct(FakeBluetoothChooser_WaitForEvents_Params); >+ this.waitForEvents(params.numOfEvents).then(function(response) { >+ var responseParams = >+ new FakeBluetoothChooser_WaitForEvents_ResponseParams(); >+ responseParams.events = response.events; >+ var builder = new codec.MessageV1Builder( >+ kFakeBluetoothChooser_WaitForEvents_Name, >+ codec.align(FakeBluetoothChooser_WaitForEvents_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeBluetoothChooser_WaitForEvents_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeBluetoothChooser_SelectPeripheral_Name: >+ var params = reader.decodeStruct(FakeBluetoothChooser_SelectPeripheral_Params); >+ this.selectPeripheral(params.peripheralAddress).then(function(response) { >+ var responseParams = >+ new FakeBluetoothChooser_SelectPeripheral_ResponseParams(); >+ var builder = new codec.MessageV1Builder( >+ kFakeBluetoothChooser_SelectPeripheral_Name, >+ codec.align(FakeBluetoothChooser_SelectPeripheral_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeBluetoothChooser_SelectPeripheral_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeBluetoothChooser_Cancel_Name: >+ var params = reader.decodeStruct(FakeBluetoothChooser_Cancel_Params); >+ this.cancel().then(function(response) { >+ var responseParams = >+ new FakeBluetoothChooser_Cancel_ResponseParams(); >+ var builder = new codec.MessageV1Builder( >+ kFakeBluetoothChooser_Cancel_Name, >+ codec.align(FakeBluetoothChooser_Cancel_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeBluetoothChooser_Cancel_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kFakeBluetoothChooser_Rescan_Name: >+ var params = reader.decodeStruct(FakeBluetoothChooser_Rescan_Params); >+ this.rescan().then(function(response) { >+ var responseParams = >+ new FakeBluetoothChooser_Rescan_ResponseParams(); >+ var builder = new codec.MessageV1Builder( >+ kFakeBluetoothChooser_Rescan_Name, >+ codec.align(FakeBluetoothChooser_Rescan_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(FakeBluetoothChooser_Rescan_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ default: >+ return false; >+ } >+ }; >+ >+ function validateFakeBluetoothChooserRequest(messageValidator) { >+ var message = messageValidator.message; >+ var paramsClass = null; >+ switch (message.getName()) { >+ case kFakeBluetoothChooser_WaitForEvents_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeBluetoothChooser_WaitForEvents_Params; >+ break; >+ case kFakeBluetoothChooser_SelectPeripheral_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeBluetoothChooser_SelectPeripheral_Params; >+ break; >+ case kFakeBluetoothChooser_Cancel_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeBluetoothChooser_Cancel_Params; >+ break; >+ case kFakeBluetoothChooser_Rescan_Name: >+ if (message.expectsResponse()) >+ paramsClass = FakeBluetoothChooser_Rescan_Params; >+ break; >+ } >+ if (paramsClass === null) >+ return validator.validationError.NONE; >+ return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); >+ } >+ >+ function validateFakeBluetoothChooserResponse(messageValidator) { >+ var message = messageValidator.message; >+ var paramsClass = null; >+ switch (message.getName()) { >+ case kFakeBluetoothChooser_WaitForEvents_Name: >+ if (message.isResponse()) >+ paramsClass = FakeBluetoothChooser_WaitForEvents_ResponseParams; >+ break; >+ case kFakeBluetoothChooser_SelectPeripheral_Name: >+ if (message.isResponse()) >+ paramsClass = FakeBluetoothChooser_SelectPeripheral_ResponseParams; >+ break; >+ case kFakeBluetoothChooser_Cancel_Name: >+ if (message.isResponse()) >+ paramsClass = FakeBluetoothChooser_Cancel_ResponseParams; >+ break; >+ case kFakeBluetoothChooser_Rescan_Name: >+ if (message.isResponse()) >+ paramsClass = FakeBluetoothChooser_Rescan_ResponseParams; >+ break; >+ } >+ if (paramsClass === null) >+ return validator.validationError.NONE; >+ return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); >+ } >+ >+ var FakeBluetoothChooser = { >+ name: 'content.mojom.FakeBluetoothChooser', >+ kVersion: 0, >+ ptrClass: FakeBluetoothChooserPtr, >+ proxyClass: FakeBluetoothChooserProxy, >+ stubClass: FakeBluetoothChooserStub, >+ validateRequest: validateFakeBluetoothChooserRequest, >+ validateResponse: validateFakeBluetoothChooserResponse, >+ }; >+ FakeBluetoothChooserStub.prototype.validator = validateFakeBluetoothChooserRequest; >+ FakeBluetoothChooserProxy.prototype.validator = validateFakeBluetoothChooserResponse; >+ exports.ChooserEventType = ChooserEventType; >+ exports.FakeBluetoothChooserEvent = FakeBluetoothChooserEvent; >+ exports.FakeBluetoothChooser = FakeBluetoothChooser; >+ exports.FakeBluetoothChooserPtr = FakeBluetoothChooserPtr; >+ exports.FakeBluetoothChooserAssociatedPtr = FakeBluetoothChooserAssociatedPtr; >+})(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/fake_bluetooth_chooser.mojom.js.headers b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/fake_bluetooth_chooser.mojom.js.headers >new file mode 100644 >index 0000000000000000000000000000000000000000..6805c323df5a975231648b830e33ce183c3cbbd3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/fake_bluetooth_chooser.mojom.js.headers >@@ -0,0 +1 @@ >+Content-Type: text/javascript; charset=utf-8 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/generic_sensor_mocks.js b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/generic_sensor_mocks.js >new file mode 100644 >index 0000000000000000000000000000000000000000..ff3a051714622653e1f3693cfdf8bab582362d09 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/generic_sensor_mocks.js >@@ -0,0 +1,226 @@ >+'use strict'; >+ >+var GenericSensorTest = (() => { >+ // Class that mocks Sensor interface defined in >+ // https://cs.chromium.org/chromium/src/services/device/public/mojom/sensor.mojom >+ class MockSensor { >+ constructor(sensorRequest, handle, offset, size, reportingMode) { >+ this.client_ = null; >+ this.reportingMode_ = reportingMode; >+ this.sensorReadingTimerId_ = null; >+ this.requestedFrequencies_ = []; >+ let rv = handle.mapBuffer(offset, size); >+ assert_equals(rv.result, Mojo.RESULT_OK, "Failed to map shared buffer"); >+ this.buffer_ = new Float64Array(rv.buffer); >+ this.buffer_.fill(0); >+ this.binding_ = new mojo.Binding(device.mojom.Sensor, this, >+ sensorRequest); >+ this.binding_.setConnectionErrorHandler(() => { >+ this.reset(); >+ }); >+ } >+ >+ getDefaultConfiguration() { >+ return Promise.resolve({frequency: 5}); >+ } >+ >+ addConfiguration(configuration) { >+ assert_not_equals(configuration, null, "Invalid sensor configuration."); >+ >+ this.requestedFrequencies_.push(configuration.frequency); >+ // Sort using descending order. >+ this.requestedFrequencies_.sort( >+ (first, second) => { return second - first }); >+ >+ this.startReading(); >+ >+ return Promise.resolve({success: true}); >+ } >+ >+ removeConfiguration(configuration) { >+ let index = this.requestedFrequencies_.indexOf(configuration.frequency); >+ if (index == -1) >+ return; >+ >+ this.requestedFrequencies_.splice(index, 1); >+ >+ if (this.isReading) { >+ this.stopReading(); >+ if (this.requestedFrequencies_.length !== 0) >+ this.startReading(); >+ } >+ } >+ >+ suspend() { >+ this.stopReading(); >+ } >+ >+ resume() { >+ this.startReading(); >+ } >+ >+ reset() { >+ this.stopReading(); >+ this.requestedFrequencies_ = []; >+ this.buffer_.fill(0); >+ this.binding_.close(); >+ } >+ >+ startReading() { >+ if (this.isReading) { >+ console.warn("Sensor reading is already started."); >+ return; >+ } >+ >+ if (this.requestedFrequencies_.length == 0) { >+ console.warn("Sensor reading cannot be started as" + >+ "there are no configurations added."); >+ return; >+ } >+ >+ const maxFrequencyHz = this.requestedFrequencies_[0]; >+ const timeoutMs = (1 / maxFrequencyHz) * 1000; >+ this.sensorReadingTimerId_ = window.setInterval(() => { >+ // For all tests sensor reading should have monotonically >+ // increasing timestamp in seconds. >+ this.buffer_[1] = window.performance.now() * 0.001; >+ if (this.reportingMode_ === device.mojom.ReportingMode.ON_CHANGE) { >+ this.client_.sensorReadingChanged(); >+ } >+ }, timeoutMs); >+ } >+ >+ stopReading() { >+ if (this.isReading) { >+ window.clearInterval(this.sensorReadingTimerId_); >+ this.sensorReadingTimerId_ = null; >+ } >+ } >+ >+ get isReading() { >+ this.sensorReadingTimerId_ !== null; >+ } >+ } >+ >+ // Class that mocks SensorProvider interface defined in >+ // https://cs.chromium.org/chromium/src/services/device/public/mojom/sensor_provider.mojom >+ class MockSensorProvider { >+ constructor() { >+ this.readingSizeInBytes_ = >+ device.mojom.SensorInitParams.kReadBufferSizeForTests; >+ this.sharedBufferSizeInBytes_ = this.readingSizeInBytes_ * >+ device.mojom.SensorType.LAST; >+ let rv = Mojo.createSharedBuffer(this.sharedBufferSizeInBytes_); >+ assert_equals(rv.result, Mojo.RESULT_OK, "Failed to create buffer"); >+ this.sharedBufferHandle_ = rv.handle; >+ this.activeSensor_ = null; >+ this.isContinuous_ = false; >+ this.binding_ = new mojo.Binding(device.mojom.SensorProvider, this); >+ >+ this.interceptor_ = new MojoInterfaceInterceptor( >+ device.mojom.SensorProvider.name); >+ this.interceptor_.oninterfacerequest = e => { >+ this.binding_.bind(e.handle); >+ this.binding_.setConnectionErrorHandler(() => { >+ console.error("Mojo connection error"); >+ this.reset(); >+ }); >+ }; >+ this.interceptor_.start(); >+ } >+ >+ async getSensor(type) { >+ const offset = (device.mojom.SensorType.LAST - type) * >+ this.readingSizeInBytes_; >+ const reportingMode = device.mojom.ReportingMode.ON_CHANGE; >+ >+ let sensorPtr = new device.mojom.SensorPtr(); >+ if (this.activeSensor_ == null) { >+ let mockSensor = new MockSensor( >+ mojo.makeRequest(sensorPtr), this.sharedBufferHandle_, offset, >+ this.readingSizeInBytes_, reportingMode); >+ this.activeSensor_ = mockSensor; >+ this.activeSensor_.client_ = new device.mojom.SensorClientPtr(); >+ } >+ >+ let rv = this.sharedBufferHandle_.duplicateBufferHandle(); >+ >+ assert_equals(rv.result, Mojo.RESULT_OK); >+ let maxAllowedFrequencyHz = 60; >+ if (type == device.mojom.SensorType.AMBIENT_LIGHT || >+ type == device.mojom.SensorType.MAGNETOMETER) { >+ maxAllowedFrequencyHz = 10; >+ } >+ >+ let initParams = new device.mojom.SensorInitParams({ >+ sensor: sensorPtr, >+ clientRequest: mojo.makeRequest(this.activeSensor_.client_), >+ memory: rv.handle, >+ bufferOffset: offset, >+ mode: reportingMode, >+ defaultConfiguration: {frequency: 5}, >+ minimumFrequency: 1, >+ maximumFrequency: maxAllowedFrequencyHz >+ }); >+ >+ return {result: device.mojom.SensorCreationResult.SUCCESS, >+ initParams: initParams}; >+ } >+ >+ async reset() { >+ if (this.activeSensor_ !== null) { >+ this.activeSensor_.reset(); >+ this.activeSensor_ = null; >+ } >+ // Wait for an event loop iteration to let >+ // the pending mojo commands pass. >+ function schedule(func) { >+ return new Promise(resolve => { >+ setTimeout(() => { >+ func(); >+ resolve(); >+ }, 0); >+ }); >+ } >+ await schedule(this.binding_.close.bind(this.binding_)); >+ await schedule(this.interceptor_.stop.bind(this.interceptor_)); >+ } >+ } >+ >+ let testInternal = { >+ initialized: false, >+ sensorProvider: null >+ } >+ >+ class GenericSensorTestChromium { >+ constructor() { >+ Object.freeze(this); // Make it immutable. >+ } >+ >+ initialize() { >+ if (testInternal.initialized) >+ throw new Error('Call reset() before initialize().'); >+ >+ if (testRunner) { // Grant sensor permissions for Chromium testrunner. >+ ['accelerometer', 'gyroscope', >+ 'magnetometer', 'ambient-light-sensor'].forEach((entry) => { >+ testRunner.setPermission(entry, 'granted', >+ location.origin, location.origin); >+ }); >+ } >+ >+ testInternal.sensorProvider = new MockSensorProvider; >+ testInternal.initialized = true; >+ } >+ // Resets state of sensor mocks between test runs. >+ async reset() { >+ if (!testInternal.initialized) >+ throw new Error('Call initialize() before reset().'); >+ await testInternal.sensorProvider.reset(); >+ testInternal.sensorProvider = null; >+ testInternal.initialized = false; >+ } >+ } >+ >+ return GenericSensorTestChromium; >+})(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/generic_sensor_mocks.js.headers b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/generic_sensor_mocks.js.headers >new file mode 100644 >index 0000000000000000000000000000000000000000..6805c323df5a975231648b830e33ce183c3cbbd3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/generic_sensor_mocks.js.headers >@@ -0,0 +1 @@ >+Content-Type: text/javascript; charset=utf-8 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/mojo_layouttest_test.mojom.js b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/mojo_layouttest_test.mojom.js >new file mode 100644 >index 0000000000000000000000000000000000000000..babaeda156fc8c10afcc08c6652576e32a6741e1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/mojo_layouttest_test.mojom.js >@@ -0,0 +1,264 @@ >+// Copyright 2014 The Chromium Authors. All rights reserved. >+// Use of this source code is governed by a BSD-style license that can be >+// found in the LICENSE file. >+ >+'use strict'; >+ >+(function() { >+ var mojomId = 'content/test/data/mojo_layouttest_test.mojom'; >+ if (mojo.internal.isMojomLoaded(mojomId)) { >+ console.warn('The following mojom is loaded multiple times: ' + mojomId); >+ return; >+ } >+ mojo.internal.markMojomLoaded(mojomId); >+ >+ // TODO(yzshen): Define these aliases to minimize the differences between the >+ // old/new modes. Remove them when the old mode goes away. >+ var bindings = mojo; >+ var associatedBindings = mojo; >+ var codec = mojo.internal; >+ var validator = mojo.internal; >+ >+ var exports = mojo.internal.exposeNamespace('content.mojom'); >+ >+ >+ >+ function MojoLayoutTestHelper_Reverse_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ MojoLayoutTestHelper_Reverse_Params.prototype.initDefaults_ = function() { >+ this.message = null; >+ }; >+ MojoLayoutTestHelper_Reverse_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ MojoLayoutTestHelper_Reverse_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate MojoLayoutTestHelper_Reverse_Params.message >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ MojoLayoutTestHelper_Reverse_Params.encodedSize = codec.kStructHeaderSize + 8; >+ >+ MojoLayoutTestHelper_Reverse_Params.decode = function(decoder) { >+ var packed; >+ var val = new MojoLayoutTestHelper_Reverse_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.message = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ MojoLayoutTestHelper_Reverse_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(MojoLayoutTestHelper_Reverse_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.String, val.message); >+ }; >+ function MojoLayoutTestHelper_Reverse_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ MojoLayoutTestHelper_Reverse_ResponseParams.prototype.initDefaults_ = function() { >+ this.reversed = null; >+ }; >+ MojoLayoutTestHelper_Reverse_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ MojoLayoutTestHelper_Reverse_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate MojoLayoutTestHelper_Reverse_ResponseParams.reversed >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ MojoLayoutTestHelper_Reverse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ MojoLayoutTestHelper_Reverse_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new MojoLayoutTestHelper_Reverse_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.reversed = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ MojoLayoutTestHelper_Reverse_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(MojoLayoutTestHelper_Reverse_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.String, val.reversed); >+ }; >+ var kMojoLayoutTestHelper_Reverse_Name = 0; >+ >+ function MojoLayoutTestHelperPtr(handleOrPtrInfo) { >+ this.ptr = new bindings.InterfacePtrController(MojoLayoutTestHelper, >+ handleOrPtrInfo); >+ } >+ >+ function MojoLayoutTestHelperAssociatedPtr(associatedInterfacePtrInfo) { >+ this.ptr = new associatedBindings.AssociatedInterfacePtrController( >+ MojoLayoutTestHelper, associatedInterfacePtrInfo); >+ } >+ >+ MojoLayoutTestHelperAssociatedPtr.prototype = >+ Object.create(MojoLayoutTestHelperPtr.prototype); >+ MojoLayoutTestHelperAssociatedPtr.prototype.constructor = >+ MojoLayoutTestHelperAssociatedPtr; >+ >+ function MojoLayoutTestHelperProxy(receiver) { >+ this.receiver_ = receiver; >+ } >+ MojoLayoutTestHelperPtr.prototype.reverse = function() { >+ return MojoLayoutTestHelperProxy.prototype.reverse >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ MojoLayoutTestHelperProxy.prototype.reverse = function(message) { >+ var params = new MojoLayoutTestHelper_Reverse_Params(); >+ params.message = message; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kMojoLayoutTestHelper_Reverse_Name, >+ codec.align(MojoLayoutTestHelper_Reverse_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(MojoLayoutTestHelper_Reverse_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(MojoLayoutTestHelper_Reverse_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ >+ function MojoLayoutTestHelperStub(delegate) { >+ this.delegate_ = delegate; >+ } >+ MojoLayoutTestHelperStub.prototype.reverse = function(message) { >+ return this.delegate_ && this.delegate_.reverse && this.delegate_.reverse(message); >+ } >+ >+ MojoLayoutTestHelperStub.prototype.accept = function(message) { >+ var reader = new codec.MessageReader(message); >+ switch (reader.messageName) { >+ default: >+ return false; >+ } >+ }; >+ >+ MojoLayoutTestHelperStub.prototype.acceptWithResponder = >+ function(message, responder) { >+ var reader = new codec.MessageReader(message); >+ switch (reader.messageName) { >+ case kMojoLayoutTestHelper_Reverse_Name: >+ var params = reader.decodeStruct(MojoLayoutTestHelper_Reverse_Params); >+ this.reverse(params.message).then(function(response) { >+ var responseParams = >+ new MojoLayoutTestHelper_Reverse_ResponseParams(); >+ responseParams.reversed = response.reversed; >+ var builder = new codec.MessageV1Builder( >+ kMojoLayoutTestHelper_Reverse_Name, >+ codec.align(MojoLayoutTestHelper_Reverse_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(MojoLayoutTestHelper_Reverse_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ default: >+ return false; >+ } >+ }; >+ >+ function validateMojoLayoutTestHelperRequest(messageValidator) { >+ var message = messageValidator.message; >+ var paramsClass = null; >+ switch (message.getName()) { >+ case kMojoLayoutTestHelper_Reverse_Name: >+ if (message.expectsResponse()) >+ paramsClass = MojoLayoutTestHelper_Reverse_Params; >+ break; >+ } >+ if (paramsClass === null) >+ return validator.validationError.NONE; >+ return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); >+ } >+ >+ function validateMojoLayoutTestHelperResponse(messageValidator) { >+ var message = messageValidator.message; >+ var paramsClass = null; >+ switch (message.getName()) { >+ case kMojoLayoutTestHelper_Reverse_Name: >+ if (message.isResponse()) >+ paramsClass = MojoLayoutTestHelper_Reverse_ResponseParams; >+ break; >+ } >+ if (paramsClass === null) >+ return validator.validationError.NONE; >+ return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); >+ } >+ >+ var MojoLayoutTestHelper = { >+ name: 'content.mojom.MojoLayoutTestHelper', >+ kVersion: 0, >+ ptrClass: MojoLayoutTestHelperPtr, >+ proxyClass: MojoLayoutTestHelperProxy, >+ stubClass: MojoLayoutTestHelperStub, >+ validateRequest: validateMojoLayoutTestHelperRequest, >+ validateResponse: validateMojoLayoutTestHelperResponse, >+ }; >+ MojoLayoutTestHelperStub.prototype.validator = validateMojoLayoutTestHelperRequest; >+ MojoLayoutTestHelperProxy.prototype.validator = validateMojoLayoutTestHelperResponse; >+ exports.MojoLayoutTestHelper = MojoLayoutTestHelper; >+ exports.MojoLayoutTestHelperPtr = MojoLayoutTestHelperPtr; >+ exports.MojoLayoutTestHelperAssociatedPtr = MojoLayoutTestHelperAssociatedPtr; >+})(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/mojo_layouttest_test.mojom.js.headers b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/mojo_layouttest_test.mojom.js.headers >new file mode 100644 >index 0000000000000000000000000000000000000000..6805c323df5a975231648b830e33ce183c3cbbd3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/mojo_layouttest_test.mojom.js.headers >@@ -0,0 +1 @@ >+Content-Type: text/javascript; charset=utf-8 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/sensor.mojom.js b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/sensor.mojom.js >new file mode 100644 >index 0000000000000000000000000000000000000000..daa99217335fc4dec9c28119935acc28afe58dd8 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/sensor.mojom.js >@@ -0,0 +1,1072 @@ >+// Copyright 2014 The Chromium Authors. All rights reserved. >+// Use of this source code is governed by a BSD-style license that can be >+// found in the LICENSE file. >+ >+'use strict'; >+ >+(function() { >+ var mojomId = 'services/device/public/mojom/sensor.mojom'; >+ if (mojo.internal.isMojomLoaded(mojomId)) { >+ console.warn('The following mojom is loaded multiple times: ' + mojomId); >+ return; >+ } >+ mojo.internal.markMojomLoaded(mojomId); >+ var bindings = mojo; >+ var associatedBindings = mojo; >+ var codec = mojo.internal; >+ var validator = mojo.internal; >+ >+ var exports = mojo.internal.exposeNamespace('device.mojom'); >+ >+ >+ var SensorType = {}; >+ SensorType.FIRST = 1; >+ SensorType.AMBIENT_LIGHT = SensorType.FIRST; >+ SensorType.PROXIMITY = SensorType.AMBIENT_LIGHT + 1; >+ SensorType.ACCELEROMETER = SensorType.PROXIMITY + 1; >+ SensorType.LINEAR_ACCELERATION = SensorType.ACCELEROMETER + 1; >+ SensorType.GYROSCOPE = SensorType.LINEAR_ACCELERATION + 1; >+ SensorType.MAGNETOMETER = SensorType.GYROSCOPE + 1; >+ SensorType.PRESSURE = SensorType.MAGNETOMETER + 1; >+ SensorType.ABSOLUTE_ORIENTATION_EULER_ANGLES = SensorType.PRESSURE + 1; >+ SensorType.ABSOLUTE_ORIENTATION_QUATERNION = SensorType.ABSOLUTE_ORIENTATION_EULER_ANGLES + 1; >+ SensorType.RELATIVE_ORIENTATION_EULER_ANGLES = SensorType.ABSOLUTE_ORIENTATION_QUATERNION + 1; >+ SensorType.RELATIVE_ORIENTATION_QUATERNION = SensorType.RELATIVE_ORIENTATION_EULER_ANGLES + 1; >+ SensorType.LAST = SensorType.RELATIVE_ORIENTATION_QUATERNION; >+ >+ SensorType.isKnownEnumValue = function(value) { >+ switch (value) { >+ case 1: >+ case 2: >+ case 3: >+ case 4: >+ case 5: >+ case 6: >+ case 7: >+ case 8: >+ case 9: >+ case 10: >+ case 11: >+ return true; >+ } >+ return false; >+ }; >+ >+ SensorType.validate = function(enumValue) { >+ var isExtensible = false; >+ if (isExtensible || this.isKnownEnumValue(enumValue)) >+ return validator.validationError.NONE; >+ >+ return validator.validationError.UNKNOWN_ENUM_VALUE; >+ }; >+ var ReportingMode = {}; >+ ReportingMode.ON_CHANGE = 0; >+ ReportingMode.CONTINUOUS = ReportingMode.ON_CHANGE + 1; >+ >+ ReportingMode.isKnownEnumValue = function(value) { >+ switch (value) { >+ case 0: >+ case 1: >+ return true; >+ } >+ return false; >+ }; >+ >+ ReportingMode.validate = function(enumValue) { >+ var isExtensible = false; >+ if (isExtensible || this.isKnownEnumValue(enumValue)) >+ return validator.validationError.NONE; >+ >+ return validator.validationError.UNKNOWN_ENUM_VALUE; >+ }; >+ >+ function SensorConfiguration(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ SensorConfiguration.prototype.initDefaults_ = function() { >+ this.frequency = 0; >+ }; >+ SensorConfiguration.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ SensorConfiguration.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ SensorConfiguration.encodedSize = codec.kStructHeaderSize + 8; >+ >+ SensorConfiguration.decode = function(decoder) { >+ var packed; >+ var val = new SensorConfiguration(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.frequency = decoder.decodeStruct(codec.Double); >+ return val; >+ }; >+ >+ SensorConfiguration.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(SensorConfiguration.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.Double, val.frequency); >+ }; >+ function Sensor_GetDefaultConfiguration_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ Sensor_GetDefaultConfiguration_Params.prototype.initDefaults_ = function() { >+ }; >+ Sensor_GetDefaultConfiguration_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ Sensor_GetDefaultConfiguration_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 8} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ Sensor_GetDefaultConfiguration_Params.encodedSize = codec.kStructHeaderSize + 0; >+ >+ Sensor_GetDefaultConfiguration_Params.decode = function(decoder) { >+ var packed; >+ var val = new Sensor_GetDefaultConfiguration_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ return val; >+ }; >+ >+ Sensor_GetDefaultConfiguration_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(Sensor_GetDefaultConfiguration_Params.encodedSize); >+ encoder.writeUint32(0); >+ }; >+ function Sensor_GetDefaultConfiguration_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ Sensor_GetDefaultConfiguration_ResponseParams.prototype.initDefaults_ = function() { >+ this.configuration = null; >+ }; >+ Sensor_GetDefaultConfiguration_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ Sensor_GetDefaultConfiguration_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate Sensor_GetDefaultConfiguration_ResponseParams.configuration >+ err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, SensorConfiguration, false); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ Sensor_GetDefaultConfiguration_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ Sensor_GetDefaultConfiguration_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new Sensor_GetDefaultConfiguration_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.configuration = decoder.decodeStructPointer(SensorConfiguration); >+ return val; >+ }; >+ >+ Sensor_GetDefaultConfiguration_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(Sensor_GetDefaultConfiguration_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStructPointer(SensorConfiguration, val.configuration); >+ }; >+ function Sensor_AddConfiguration_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ Sensor_AddConfiguration_Params.prototype.initDefaults_ = function() { >+ this.configuration = null; >+ }; >+ Sensor_AddConfiguration_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ Sensor_AddConfiguration_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate Sensor_AddConfiguration_Params.configuration >+ err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, SensorConfiguration, false); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ Sensor_AddConfiguration_Params.encodedSize = codec.kStructHeaderSize + 8; >+ >+ Sensor_AddConfiguration_Params.decode = function(decoder) { >+ var packed; >+ var val = new Sensor_AddConfiguration_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.configuration = decoder.decodeStructPointer(SensorConfiguration); >+ return val; >+ }; >+ >+ Sensor_AddConfiguration_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(Sensor_AddConfiguration_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStructPointer(SensorConfiguration, val.configuration); >+ }; >+ function Sensor_AddConfiguration_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ Sensor_AddConfiguration_ResponseParams.prototype.initDefaults_ = function() { >+ this.success = false; >+ }; >+ Sensor_AddConfiguration_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ Sensor_AddConfiguration_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ Sensor_AddConfiguration_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; >+ >+ Sensor_AddConfiguration_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new Sensor_AddConfiguration_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.success = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ Sensor_AddConfiguration_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(Sensor_AddConfiguration_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.success & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function Sensor_RemoveConfiguration_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ Sensor_RemoveConfiguration_Params.prototype.initDefaults_ = function() { >+ this.configuration = null; >+ }; >+ Sensor_RemoveConfiguration_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ Sensor_RemoveConfiguration_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate Sensor_RemoveConfiguration_Params.configuration >+ err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, SensorConfiguration, false); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ Sensor_RemoveConfiguration_Params.encodedSize = codec.kStructHeaderSize + 8; >+ >+ Sensor_RemoveConfiguration_Params.decode = function(decoder) { >+ var packed; >+ var val = new Sensor_RemoveConfiguration_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.configuration = decoder.decodeStructPointer(SensorConfiguration); >+ return val; >+ }; >+ >+ Sensor_RemoveConfiguration_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(Sensor_RemoveConfiguration_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStructPointer(SensorConfiguration, val.configuration); >+ }; >+ function Sensor_Suspend_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ Sensor_Suspend_Params.prototype.initDefaults_ = function() { >+ }; >+ Sensor_Suspend_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ Sensor_Suspend_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 8} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ Sensor_Suspend_Params.encodedSize = codec.kStructHeaderSize + 0; >+ >+ Sensor_Suspend_Params.decode = function(decoder) { >+ var packed; >+ var val = new Sensor_Suspend_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ return val; >+ }; >+ >+ Sensor_Suspend_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(Sensor_Suspend_Params.encodedSize); >+ encoder.writeUint32(0); >+ }; >+ function Sensor_Resume_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ Sensor_Resume_Params.prototype.initDefaults_ = function() { >+ }; >+ Sensor_Resume_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ Sensor_Resume_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 8} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ Sensor_Resume_Params.encodedSize = codec.kStructHeaderSize + 0; >+ >+ Sensor_Resume_Params.decode = function(decoder) { >+ var packed; >+ var val = new Sensor_Resume_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ return val; >+ }; >+ >+ Sensor_Resume_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(Sensor_Resume_Params.encodedSize); >+ encoder.writeUint32(0); >+ }; >+ function Sensor_ConfigureReadingChangeNotifications_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ Sensor_ConfigureReadingChangeNotifications_Params.prototype.initDefaults_ = function() { >+ this.enabled = false; >+ }; >+ Sensor_ConfigureReadingChangeNotifications_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ Sensor_ConfigureReadingChangeNotifications_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ Sensor_ConfigureReadingChangeNotifications_Params.encodedSize = codec.kStructHeaderSize + 8; >+ >+ Sensor_ConfigureReadingChangeNotifications_Params.decode = function(decoder) { >+ var packed; >+ var val = new Sensor_ConfigureReadingChangeNotifications_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ packed = decoder.readUint8(); >+ val.enabled = (packed >> 0) & 1 ? true : false; >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ Sensor_ConfigureReadingChangeNotifications_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(Sensor_ConfigureReadingChangeNotifications_Params.encodedSize); >+ encoder.writeUint32(0); >+ packed = 0; >+ packed |= (val.enabled & 1) << 0 >+ encoder.writeUint8(packed); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function SensorClient_RaiseError_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ SensorClient_RaiseError_Params.prototype.initDefaults_ = function() { >+ }; >+ SensorClient_RaiseError_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ SensorClient_RaiseError_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 8} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ SensorClient_RaiseError_Params.encodedSize = codec.kStructHeaderSize + 0; >+ >+ SensorClient_RaiseError_Params.decode = function(decoder) { >+ var packed; >+ var val = new SensorClient_RaiseError_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ return val; >+ }; >+ >+ SensorClient_RaiseError_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(SensorClient_RaiseError_Params.encodedSize); >+ encoder.writeUint32(0); >+ }; >+ function SensorClient_SensorReadingChanged_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ SensorClient_SensorReadingChanged_Params.prototype.initDefaults_ = function() { >+ }; >+ SensorClient_SensorReadingChanged_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ SensorClient_SensorReadingChanged_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 8} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ SensorClient_SensorReadingChanged_Params.encodedSize = codec.kStructHeaderSize + 0; >+ >+ SensorClient_SensorReadingChanged_Params.decode = function(decoder) { >+ var packed; >+ var val = new SensorClient_SensorReadingChanged_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ return val; >+ }; >+ >+ SensorClient_SensorReadingChanged_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(SensorClient_SensorReadingChanged_Params.encodedSize); >+ encoder.writeUint32(0); >+ }; >+ var kSensor_GetDefaultConfiguration_Name = 0; >+ var kSensor_AddConfiguration_Name = 1; >+ var kSensor_RemoveConfiguration_Name = 2; >+ var kSensor_Suspend_Name = 3; >+ var kSensor_Resume_Name = 4; >+ var kSensor_ConfigureReadingChangeNotifications_Name = 5; >+ >+ function SensorPtr(handleOrPtrInfo) { >+ this.ptr = new bindings.InterfacePtrController(Sensor, >+ handleOrPtrInfo); >+ } >+ >+ function SensorAssociatedPtr(associatedInterfacePtrInfo) { >+ this.ptr = new associatedBindings.AssociatedInterfacePtrController( >+ Sensor, associatedInterfacePtrInfo); >+ } >+ >+ SensorAssociatedPtr.prototype = >+ Object.create(SensorPtr.prototype); >+ SensorAssociatedPtr.prototype.constructor = >+ SensorAssociatedPtr; >+ >+ function SensorProxy(receiver) { >+ this.receiver_ = receiver; >+ } >+ SensorPtr.prototype.getDefaultConfiguration = function() { >+ return SensorProxy.prototype.getDefaultConfiguration >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ SensorProxy.prototype.getDefaultConfiguration = function() { >+ var params = new Sensor_GetDefaultConfiguration_Params(); >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kSensor_GetDefaultConfiguration_Name, >+ codec.align(Sensor_GetDefaultConfiguration_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(Sensor_GetDefaultConfiguration_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(Sensor_GetDefaultConfiguration_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ SensorPtr.prototype.addConfiguration = function() { >+ return SensorProxy.prototype.addConfiguration >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ SensorProxy.prototype.addConfiguration = function(configuration) { >+ var params = new Sensor_AddConfiguration_Params(); >+ params.configuration = configuration; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kSensor_AddConfiguration_Name, >+ codec.align(Sensor_AddConfiguration_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(Sensor_AddConfiguration_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(Sensor_AddConfiguration_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ SensorPtr.prototype.removeConfiguration = function() { >+ return SensorProxy.prototype.removeConfiguration >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ SensorProxy.prototype.removeConfiguration = function(configuration) { >+ var params = new Sensor_RemoveConfiguration_Params(); >+ params.configuration = configuration; >+ var builder = new codec.MessageV0Builder( >+ kSensor_RemoveConfiguration_Name, >+ codec.align(Sensor_RemoveConfiguration_Params.encodedSize)); >+ builder.encodeStruct(Sensor_RemoveConfiguration_Params, params); >+ var message = builder.finish(); >+ this.receiver_.accept(message); >+ }; >+ SensorPtr.prototype.suspend = function() { >+ return SensorProxy.prototype.suspend >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ SensorProxy.prototype.suspend = function() { >+ var params = new Sensor_Suspend_Params(); >+ var builder = new codec.MessageV0Builder( >+ kSensor_Suspend_Name, >+ codec.align(Sensor_Suspend_Params.encodedSize)); >+ builder.encodeStruct(Sensor_Suspend_Params, params); >+ var message = builder.finish(); >+ this.receiver_.accept(message); >+ }; >+ SensorPtr.prototype.resume = function() { >+ return SensorProxy.prototype.resume >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ SensorProxy.prototype.resume = function() { >+ var params = new Sensor_Resume_Params(); >+ var builder = new codec.MessageV0Builder( >+ kSensor_Resume_Name, >+ codec.align(Sensor_Resume_Params.encodedSize)); >+ builder.encodeStruct(Sensor_Resume_Params, params); >+ var message = builder.finish(); >+ this.receiver_.accept(message); >+ }; >+ SensorPtr.prototype.configureReadingChangeNotifications = function() { >+ return SensorProxy.prototype.configureReadingChangeNotifications >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ SensorProxy.prototype.configureReadingChangeNotifications = function(enabled) { >+ var params = new Sensor_ConfigureReadingChangeNotifications_Params(); >+ params.enabled = enabled; >+ var builder = new codec.MessageV0Builder( >+ kSensor_ConfigureReadingChangeNotifications_Name, >+ codec.align(Sensor_ConfigureReadingChangeNotifications_Params.encodedSize)); >+ builder.encodeStruct(Sensor_ConfigureReadingChangeNotifications_Params, params); >+ var message = builder.finish(); >+ this.receiver_.accept(message); >+ }; >+ >+ function SensorStub(delegate) { >+ this.delegate_ = delegate; >+ } >+ SensorStub.prototype.getDefaultConfiguration = function() { >+ return this.delegate_ && this.delegate_.getDefaultConfiguration && this.delegate_.getDefaultConfiguration(); >+ } >+ SensorStub.prototype.addConfiguration = function(configuration) { >+ return this.delegate_ && this.delegate_.addConfiguration && this.delegate_.addConfiguration(configuration); >+ } >+ SensorStub.prototype.removeConfiguration = function(configuration) { >+ return this.delegate_ && this.delegate_.removeConfiguration && this.delegate_.removeConfiguration(configuration); >+ } >+ SensorStub.prototype.suspend = function() { >+ return this.delegate_ && this.delegate_.suspend && this.delegate_.suspend(); >+ } >+ SensorStub.prototype.resume = function() { >+ return this.delegate_ && this.delegate_.resume && this.delegate_.resume(); >+ } >+ SensorStub.prototype.configureReadingChangeNotifications = function(enabled) { >+ return this.delegate_ && this.delegate_.configureReadingChangeNotifications && this.delegate_.configureReadingChangeNotifications(enabled); >+ } >+ >+ SensorStub.prototype.accept = function(message) { >+ var reader = new codec.MessageReader(message); >+ switch (reader.messageName) { >+ case kSensor_RemoveConfiguration_Name: >+ var params = reader.decodeStruct(Sensor_RemoveConfiguration_Params); >+ this.removeConfiguration(params.configuration); >+ return true; >+ case kSensor_Suspend_Name: >+ var params = reader.decodeStruct(Sensor_Suspend_Params); >+ this.suspend(); >+ return true; >+ case kSensor_Resume_Name: >+ var params = reader.decodeStruct(Sensor_Resume_Params); >+ this.resume(); >+ return true; >+ case kSensor_ConfigureReadingChangeNotifications_Name: >+ var params = reader.decodeStruct(Sensor_ConfigureReadingChangeNotifications_Params); >+ this.configureReadingChangeNotifications(params.enabled); >+ return true; >+ default: >+ return false; >+ } >+ }; >+ >+ SensorStub.prototype.acceptWithResponder = >+ function(message, responder) { >+ var reader = new codec.MessageReader(message); >+ switch (reader.messageName) { >+ case kSensor_GetDefaultConfiguration_Name: >+ var params = reader.decodeStruct(Sensor_GetDefaultConfiguration_Params); >+ this.getDefaultConfiguration().then(function(response) { >+ var responseParams = >+ new Sensor_GetDefaultConfiguration_ResponseParams(); >+ responseParams.configuration = response.configuration; >+ var builder = new codec.MessageV1Builder( >+ kSensor_GetDefaultConfiguration_Name, >+ codec.align(Sensor_GetDefaultConfiguration_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(Sensor_GetDefaultConfiguration_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ case kSensor_AddConfiguration_Name: >+ var params = reader.decodeStruct(Sensor_AddConfiguration_Params); >+ this.addConfiguration(params.configuration).then(function(response) { >+ var responseParams = >+ new Sensor_AddConfiguration_ResponseParams(); >+ responseParams.success = response.success; >+ var builder = new codec.MessageV1Builder( >+ kSensor_AddConfiguration_Name, >+ codec.align(Sensor_AddConfiguration_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(Sensor_AddConfiguration_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ default: >+ return false; >+ } >+ }; >+ >+ function validateSensorRequest(messageValidator) { >+ var message = messageValidator.message; >+ var paramsClass = null; >+ switch (message.getName()) { >+ case kSensor_GetDefaultConfiguration_Name: >+ if (message.expectsResponse()) >+ paramsClass = Sensor_GetDefaultConfiguration_Params; >+ break; >+ case kSensor_AddConfiguration_Name: >+ if (message.expectsResponse()) >+ paramsClass = Sensor_AddConfiguration_Params; >+ break; >+ case kSensor_RemoveConfiguration_Name: >+ if (!message.expectsResponse() && !message.isResponse()) >+ paramsClass = Sensor_RemoveConfiguration_Params; >+ break; >+ case kSensor_Suspend_Name: >+ if (!message.expectsResponse() && !message.isResponse()) >+ paramsClass = Sensor_Suspend_Params; >+ break; >+ case kSensor_Resume_Name: >+ if (!message.expectsResponse() && !message.isResponse()) >+ paramsClass = Sensor_Resume_Params; >+ break; >+ case kSensor_ConfigureReadingChangeNotifications_Name: >+ if (!message.expectsResponse() && !message.isResponse()) >+ paramsClass = Sensor_ConfigureReadingChangeNotifications_Params; >+ break; >+ } >+ if (paramsClass === null) >+ return validator.validationError.NONE; >+ return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); >+ } >+ >+ function validateSensorResponse(messageValidator) { >+ var message = messageValidator.message; >+ var paramsClass = null; >+ switch (message.getName()) { >+ case kSensor_GetDefaultConfiguration_Name: >+ if (message.isResponse()) >+ paramsClass = Sensor_GetDefaultConfiguration_ResponseParams; >+ break; >+ case kSensor_AddConfiguration_Name: >+ if (message.isResponse()) >+ paramsClass = Sensor_AddConfiguration_ResponseParams; >+ break; >+ } >+ if (paramsClass === null) >+ return validator.validationError.NONE; >+ return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); >+ } >+ >+ var Sensor = { >+ name: 'device.mojom.Sensor', >+ kVersion: 0, >+ ptrClass: SensorPtr, >+ proxyClass: SensorProxy, >+ stubClass: SensorStub, >+ validateRequest: validateSensorRequest, >+ validateResponse: validateSensorResponse, >+ }; >+ SensorStub.prototype.validator = validateSensorRequest; >+ SensorProxy.prototype.validator = validateSensorResponse; >+ var kSensorClient_RaiseError_Name = 0; >+ var kSensorClient_SensorReadingChanged_Name = 1; >+ >+ function SensorClientPtr(handleOrPtrInfo) { >+ this.ptr = new bindings.InterfacePtrController(SensorClient, >+ handleOrPtrInfo); >+ } >+ >+ function SensorClientAssociatedPtr(associatedInterfacePtrInfo) { >+ this.ptr = new associatedBindings.AssociatedInterfacePtrController( >+ SensorClient, associatedInterfacePtrInfo); >+ } >+ >+ SensorClientAssociatedPtr.prototype = >+ Object.create(SensorClientPtr.prototype); >+ SensorClientAssociatedPtr.prototype.constructor = >+ SensorClientAssociatedPtr; >+ >+ function SensorClientProxy(receiver) { >+ this.receiver_ = receiver; >+ } >+ SensorClientPtr.prototype.raiseError = function() { >+ return SensorClientProxy.prototype.raiseError >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ SensorClientProxy.prototype.raiseError = function() { >+ var params = new SensorClient_RaiseError_Params(); >+ var builder = new codec.MessageV0Builder( >+ kSensorClient_RaiseError_Name, >+ codec.align(SensorClient_RaiseError_Params.encodedSize)); >+ builder.encodeStruct(SensorClient_RaiseError_Params, params); >+ var message = builder.finish(); >+ this.receiver_.accept(message); >+ }; >+ SensorClientPtr.prototype.sensorReadingChanged = function() { >+ return SensorClientProxy.prototype.sensorReadingChanged >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ SensorClientProxy.prototype.sensorReadingChanged = function() { >+ var params = new SensorClient_SensorReadingChanged_Params(); >+ var builder = new codec.MessageV0Builder( >+ kSensorClient_SensorReadingChanged_Name, >+ codec.align(SensorClient_SensorReadingChanged_Params.encodedSize)); >+ builder.encodeStruct(SensorClient_SensorReadingChanged_Params, params); >+ var message = builder.finish(); >+ this.receiver_.accept(message); >+ }; >+ >+ function SensorClientStub(delegate) { >+ this.delegate_ = delegate; >+ } >+ SensorClientStub.prototype.raiseError = function() { >+ return this.delegate_ && this.delegate_.raiseError && this.delegate_.raiseError(); >+ } >+ SensorClientStub.prototype.sensorReadingChanged = function() { >+ return this.delegate_ && this.delegate_.sensorReadingChanged && this.delegate_.sensorReadingChanged(); >+ } >+ >+ SensorClientStub.prototype.accept = function(message) { >+ var reader = new codec.MessageReader(message); >+ switch (reader.messageName) { >+ case kSensorClient_RaiseError_Name: >+ var params = reader.decodeStruct(SensorClient_RaiseError_Params); >+ this.raiseError(); >+ return true; >+ case kSensorClient_SensorReadingChanged_Name: >+ var params = reader.decodeStruct(SensorClient_SensorReadingChanged_Params); >+ this.sensorReadingChanged(); >+ return true; >+ default: >+ return false; >+ } >+ }; >+ >+ SensorClientStub.prototype.acceptWithResponder = >+ function(message, responder) { >+ var reader = new codec.MessageReader(message); >+ switch (reader.messageName) { >+ default: >+ return false; >+ } >+ }; >+ >+ function validateSensorClientRequest(messageValidator) { >+ var message = messageValidator.message; >+ var paramsClass = null; >+ switch (message.getName()) { >+ case kSensorClient_RaiseError_Name: >+ if (!message.expectsResponse() && !message.isResponse()) >+ paramsClass = SensorClient_RaiseError_Params; >+ break; >+ case kSensorClient_SensorReadingChanged_Name: >+ if (!message.expectsResponse() && !message.isResponse()) >+ paramsClass = SensorClient_SensorReadingChanged_Params; >+ break; >+ } >+ if (paramsClass === null) >+ return validator.validationError.NONE; >+ return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); >+ } >+ >+ function validateSensorClientResponse(messageValidator) { >+ return validator.validationError.NONE; >+ } >+ >+ var SensorClient = { >+ name: 'device.mojom.SensorClient', >+ kVersion: 0, >+ ptrClass: SensorClientPtr, >+ proxyClass: SensorClientProxy, >+ stubClass: SensorClientStub, >+ validateRequest: validateSensorClientRequest, >+ validateResponse: null, >+ }; >+ SensorClientStub.prototype.validator = validateSensorClientRequest; >+ SensorClientProxy.prototype.validator = null; >+ exports.SensorType = SensorType; >+ exports.ReportingMode = ReportingMode; >+ exports.SensorConfiguration = SensorConfiguration; >+ exports.Sensor = Sensor; >+ exports.SensorPtr = SensorPtr; >+ exports.SensorAssociatedPtr = SensorAssociatedPtr; >+ exports.SensorClient = SensorClient; >+ exports.SensorClientPtr = SensorClientPtr; >+ exports.SensorClientAssociatedPtr = SensorClientAssociatedPtr; >+})(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/sensor_provider.mojom.js b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/sensor_provider.mojom.js >new file mode 100644 >index 0000000000000000000000000000000000000000..d74ad97a281d90f0573924ed42af7c9f299fb30a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/sensor_provider.mojom.js >@@ -0,0 +1,429 @@ >+// Copyright 2014 The Chromium Authors. All rights reserved. >+// Use of this source code is governed by a BSD-style license that can be >+// found in the LICENSE file. >+ >+'use strict'; >+ >+(function() { >+ var mojomId = 'services/device/public/mojom/sensor_provider.mojom'; >+ if (mojo.internal.isMojomLoaded(mojomId)) { >+ console.warn('The following mojom is loaded multiple times: ' + mojomId); >+ return; >+ } >+ mojo.internal.markMojomLoaded(mojomId); >+ var bindings = mojo; >+ var associatedBindings = mojo; >+ var codec = mojo.internal; >+ var validator = mojo.internal; >+ >+ var exports = mojo.internal.exposeNamespace('device.mojom'); >+ var sensor$ = >+ mojo.internal.exposeNamespace('device.mojom'); >+ if (mojo.config.autoLoadMojomDeps) { >+ mojo.internal.loadMojomIfNecessary( >+ 'services/device/public/mojom/sensor.mojom', 'sensor.mojom.js'); >+ } >+ >+ >+ var SensorCreationResult = {}; >+ SensorCreationResult.SUCCESS = 0; >+ SensorCreationResult.ERROR_NOT_AVAILABLE = SensorCreationResult.SUCCESS + 1; >+ SensorCreationResult.ERROR_NOT_ALLOWED = SensorCreationResult.ERROR_NOT_AVAILABLE + 1; >+ >+ SensorCreationResult.isKnownEnumValue = function(value) { >+ switch (value) { >+ case 0: >+ case 1: >+ case 2: >+ return true; >+ } >+ return false; >+ }; >+ >+ SensorCreationResult.validate = function(enumValue) { >+ var isExtensible = false; >+ if (isExtensible || this.isKnownEnumValue(enumValue)) >+ return validator.validationError.NONE; >+ >+ return validator.validationError.UNKNOWN_ENUM_VALUE; >+ }; >+ >+ function SensorInitParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ SensorInitParams.kReadBufferSizeForTests = 48; >+ SensorInitParams.prototype.initDefaults_ = function() { >+ this.sensor = new sensor$.SensorPtr(); >+ this.clientRequest = new bindings.InterfaceRequest(); >+ this.memory = null; >+ this.bufferOffset = 0; >+ this.mode = 0; >+ this.defaultConfiguration = null; >+ this.maximumFrequency = 0; >+ this.minimumFrequency = 0; >+ }; >+ SensorInitParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ SensorInitParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 64} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate SensorInitParams.sensor >+ err = messageValidator.validateInterface(offset + codec.kStructHeaderSize + 0, false); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate SensorInitParams.clientRequest >+ err = messageValidator.validateInterfaceRequest(offset + codec.kStructHeaderSize + 8, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate SensorInitParams.memory >+ err = messageValidator.validateHandle(offset + codec.kStructHeaderSize + 12, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ >+ // validate SensorInitParams.mode >+ err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 24, sensor$.ReportingMode); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate SensorInitParams.defaultConfiguration >+ err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 32, sensor$.SensorConfiguration, false); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ >+ return validator.validationError.NONE; >+ }; >+ >+ SensorInitParams.encodedSize = codec.kStructHeaderSize + 56; >+ >+ SensorInitParams.decode = function(decoder) { >+ var packed; >+ var val = new SensorInitParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.sensor = decoder.decodeStruct(new codec.Interface(sensor$.SensorPtr)); >+ val.clientRequest = decoder.decodeStruct(codec.InterfaceRequest); >+ val.memory = decoder.decodeStruct(codec.Handle); >+ val.bufferOffset = decoder.decodeStruct(codec.Uint64); >+ val.mode = decoder.decodeStruct(codec.Int32); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ val.defaultConfiguration = decoder.decodeStructPointer(sensor$.SensorConfiguration); >+ val.maximumFrequency = decoder.decodeStruct(codec.Double); >+ val.minimumFrequency = decoder.decodeStruct(codec.Double); >+ return val; >+ }; >+ >+ SensorInitParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(SensorInitParams.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(new codec.Interface(sensor$.SensorPtr), val.sensor); >+ encoder.encodeStruct(codec.InterfaceRequest, val.clientRequest); >+ encoder.encodeStruct(codec.Handle, val.memory); >+ encoder.encodeStruct(codec.Uint64, val.bufferOffset); >+ encoder.encodeStruct(codec.Int32, val.mode); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.encodeStructPointer(sensor$.SensorConfiguration, val.defaultConfiguration); >+ encoder.encodeStruct(codec.Double, val.maximumFrequency); >+ encoder.encodeStruct(codec.Double, val.minimumFrequency); >+ }; >+ function SensorProvider_GetSensor_Params(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ SensorProvider_GetSensor_Params.prototype.initDefaults_ = function() { >+ this.type = 0; >+ }; >+ SensorProvider_GetSensor_Params.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ SensorProvider_GetSensor_Params.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate SensorProvider_GetSensor_Params.type >+ err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, sensor$.SensorType); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ SensorProvider_GetSensor_Params.encodedSize = codec.kStructHeaderSize + 8; >+ >+ SensorProvider_GetSensor_Params.decode = function(decoder) { >+ var packed; >+ var val = new SensorProvider_GetSensor_Params(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.type = decoder.decodeStruct(codec.Int32); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ return val; >+ }; >+ >+ SensorProvider_GetSensor_Params.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(SensorProvider_GetSensor_Params.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.Int32, val.type); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ }; >+ function SensorProvider_GetSensor_ResponseParams(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ SensorProvider_GetSensor_ResponseParams.prototype.initDefaults_ = function() { >+ this.result = 0; >+ this.initParams = null; >+ }; >+ SensorProvider_GetSensor_ResponseParams.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ SensorProvider_GetSensor_ResponseParams.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 24} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate SensorProvider_GetSensor_ResponseParams.result >+ err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, SensorCreationResult); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate SensorProvider_GetSensor_ResponseParams.initParams >+ err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, SensorInitParams, true); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ SensorProvider_GetSensor_ResponseParams.encodedSize = codec.kStructHeaderSize + 16; >+ >+ SensorProvider_GetSensor_ResponseParams.decode = function(decoder) { >+ var packed; >+ var val = new SensorProvider_GetSensor_ResponseParams(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.result = decoder.decodeStruct(codec.Int32); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ decoder.skip(1); >+ val.initParams = decoder.decodeStructPointer(SensorInitParams); >+ return val; >+ }; >+ >+ SensorProvider_GetSensor_ResponseParams.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(SensorProvider_GetSensor_ResponseParams.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.Int32, val.result); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.skip(1); >+ encoder.encodeStructPointer(SensorInitParams, val.initParams); >+ }; >+ var kSensorProvider_GetSensor_Name = 0; >+ >+ function SensorProviderPtr(handleOrPtrInfo) { >+ this.ptr = new bindings.InterfacePtrController(SensorProvider, >+ handleOrPtrInfo); >+ } >+ >+ function SensorProviderAssociatedPtr(associatedInterfacePtrInfo) { >+ this.ptr = new associatedBindings.AssociatedInterfacePtrController( >+ SensorProvider, associatedInterfacePtrInfo); >+ } >+ >+ SensorProviderAssociatedPtr.prototype = >+ Object.create(SensorProviderPtr.prototype); >+ SensorProviderAssociatedPtr.prototype.constructor = >+ SensorProviderAssociatedPtr; >+ >+ function SensorProviderProxy(receiver) { >+ this.receiver_ = receiver; >+ } >+ SensorProviderPtr.prototype.getSensor = function() { >+ return SensorProviderProxy.prototype.getSensor >+ .apply(this.ptr.getProxy(), arguments); >+ }; >+ >+ SensorProviderProxy.prototype.getSensor = function(type) { >+ var params = new SensorProvider_GetSensor_Params(); >+ params.type = type; >+ return new Promise(function(resolve, reject) { >+ var builder = new codec.MessageV1Builder( >+ kSensorProvider_GetSensor_Name, >+ codec.align(SensorProvider_GetSensor_Params.encodedSize), >+ codec.kMessageExpectsResponse, 0); >+ builder.encodeStruct(SensorProvider_GetSensor_Params, params); >+ var message = builder.finish(); >+ this.receiver_.acceptAndExpectResponse(message).then(function(message) { >+ var reader = new codec.MessageReader(message); >+ var responseParams = >+ reader.decodeStruct(SensorProvider_GetSensor_ResponseParams); >+ resolve(responseParams); >+ }).catch(function(result) { >+ reject(Error("Connection error: " + result)); >+ }); >+ }.bind(this)); >+ }; >+ >+ function SensorProviderStub(delegate) { >+ this.delegate_ = delegate; >+ } >+ SensorProviderStub.prototype.getSensor = function(type) { >+ return this.delegate_ && this.delegate_.getSensor && this.delegate_.getSensor(type); >+ } >+ >+ SensorProviderStub.prototype.accept = function(message) { >+ var reader = new codec.MessageReader(message); >+ switch (reader.messageName) { >+ default: >+ return false; >+ } >+ }; >+ >+ SensorProviderStub.prototype.acceptWithResponder = >+ function(message, responder) { >+ var reader = new codec.MessageReader(message); >+ switch (reader.messageName) { >+ case kSensorProvider_GetSensor_Name: >+ var params = reader.decodeStruct(SensorProvider_GetSensor_Params); >+ this.getSensor(params.type).then(function(response) { >+ var responseParams = >+ new SensorProvider_GetSensor_ResponseParams(); >+ responseParams.result = response.result; >+ responseParams.initParams = response.initParams; >+ var builder = new codec.MessageV1Builder( >+ kSensorProvider_GetSensor_Name, >+ codec.align(SensorProvider_GetSensor_ResponseParams.encodedSize), >+ codec.kMessageIsResponse, reader.requestID); >+ builder.encodeStruct(SensorProvider_GetSensor_ResponseParams, >+ responseParams); >+ var message = builder.finish(); >+ responder.accept(message); >+ }); >+ return true; >+ default: >+ return false; >+ } >+ }; >+ >+ function validateSensorProviderRequest(messageValidator) { >+ var message = messageValidator.message; >+ var paramsClass = null; >+ switch (message.getName()) { >+ case kSensorProvider_GetSensor_Name: >+ if (message.expectsResponse()) >+ paramsClass = SensorProvider_GetSensor_Params; >+ break; >+ } >+ if (paramsClass === null) >+ return validator.validationError.NONE; >+ return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); >+ } >+ >+ function validateSensorProviderResponse(messageValidator) { >+ var message = messageValidator.message; >+ var paramsClass = null; >+ switch (message.getName()) { >+ case kSensorProvider_GetSensor_Name: >+ if (message.isResponse()) >+ paramsClass = SensorProvider_GetSensor_ResponseParams; >+ break; >+ } >+ if (paramsClass === null) >+ return validator.validationError.NONE; >+ return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); >+ } >+ >+ var SensorProvider = { >+ name: 'device.mojom.SensorProvider', >+ kVersion: 0, >+ ptrClass: SensorProviderPtr, >+ proxyClass: SensorProviderProxy, >+ stubClass: SensorProviderStub, >+ validateRequest: validateSensorProviderRequest, >+ validateResponse: validateSensorProviderResponse, >+ }; >+ SensorProviderStub.prototype.validator = validateSensorProviderRequest; >+ SensorProviderProxy.prototype.validator = validateSensorProviderResponse; >+ exports.SensorCreationResult = SensorCreationResult; >+ exports.SensorInitParams = SensorInitParams; >+ exports.SensorProvider = SensorProvider; >+ exports.SensorProviderPtr = SensorProviderPtr; >+ exports.SensorProviderAssociatedPtr = SensorProviderAssociatedPtr; >+})(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/string16.mojom.js b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/string16.mojom.js >index 058956bf16968a31ad709bc1bbd4766490a13b90..9dbb35664fabc2c8d9ace357927960785a531287 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/string16.mojom.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/string16.mojom.js >@@ -7,7 +7,7 @@ > if ((typeof mojo !== 'undefined') && mojo.internal && mojo.config) { > > (function() { >- var mojomId = 'mojo/common/string16.mojom'; >+ var mojomId = 'mojo/public/mojom/base/string16.mojom'; > if (mojo.internal.isMojomLoaded(mojomId)) { > console.warn('The following mojom is loaded multiple times: ' + mojomId); > return; >@@ -87,7 +87,7 @@ if ((typeof mojo !== 'undefined') && mojo.internal && mojo.config) { > > if ((typeof mojo === 'undefined') || !mojo.internal || !mojo.config) { > >-define("mojo/common/string16.mojom", [ >+define("mojo/public/mojom/base/string16.mojom", [ > "mojo/public/js/associated_bindings", > "mojo/public/js/bindings", > "mojo/public/js/codec", >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/uuid.mojom.js b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/uuid.mojom.js >new file mode 100644 >index 0000000000000000000000000000000000000000..3b1b616ee3450f5ceb94f3f7e74ce5eea7af1bf9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/uuid.mojom.js >@@ -0,0 +1,79 @@ >+// Copyright 2014 The Chromium Authors. All rights reserved. >+// Use of this source code is governed by a BSD-style license that can be >+// found in the LICENSE file. >+ >+'use strict'; >+ >+(function() { >+ var mojomId = 'device/bluetooth/public/mojom/uuid.mojom'; >+ if (mojo.internal.isMojomLoaded(mojomId)) { >+ console.warn('The following mojom is loaded multiple times: ' + mojomId); >+ return; >+ } >+ mojo.internal.markMojomLoaded(mojomId); >+ var bindings = mojo; >+ var associatedBindings = mojo; >+ var codec = mojo.internal; >+ var validator = mojo.internal; >+ >+ var exports = mojo.internal.exposeNamespace('bluetooth.mojom'); >+ >+ >+ >+ function UUID(values) { >+ this.initDefaults_(); >+ this.initFields_(values); >+ } >+ >+ >+ UUID.prototype.initDefaults_ = function() { >+ this.uuid = null; >+ }; >+ UUID.prototype.initFields_ = function(fields) { >+ for(var field in fields) { >+ if (this.hasOwnProperty(field)) >+ this[field] = fields[field]; >+ } >+ }; >+ >+ UUID.validate = function(messageValidator, offset) { >+ var err; >+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ var kVersionSizes = [ >+ {version: 0, numBytes: 16} >+ ]; >+ err = messageValidator.validateStructVersion(offset, kVersionSizes); >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ >+ // validate UUID.uuid >+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) >+ if (err !== validator.validationError.NONE) >+ return err; >+ >+ return validator.validationError.NONE; >+ }; >+ >+ UUID.encodedSize = codec.kStructHeaderSize + 8; >+ >+ UUID.decode = function(decoder) { >+ var packed; >+ var val = new UUID(); >+ var numberOfBytes = decoder.readUint32(); >+ var version = decoder.readUint32(); >+ val.uuid = decoder.decodeStruct(codec.String); >+ return val; >+ }; >+ >+ UUID.encode = function(encoder, val) { >+ var packed; >+ encoder.writeUint32(UUID.encodedSize); >+ encoder.writeUint32(0); >+ encoder.encodeStruct(codec.String, val.uuid); >+ }; >+ exports.UUID = UUID; >+})(); >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/uuid.mojom.js.headers b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/uuid.mojom.js.headers >new file mode 100644 >index 0000000000000000000000000000000000000000..6805c323df5a975231648b830e33ce183c3cbbd3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/uuid.mojom.js.headers >@@ -0,0 +1 @@ >+Content-Type: text/javascript; charset=utf-8 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/w3c-import.log >index 10594d4c8fe28cdb7e2af131dd02e815a3d1fd99..3f98916fa3889fa66bfd4056ddcf435f2ca9cc58 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/w3c-import.log >@@ -21,9 +21,23 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/resources/chromium/device.mojom.js.headers > /LayoutTests/imported/w3c/web-platform-tests/resources/chromium/device_manager.mojom.js > /LayoutTests/imported/w3c/web-platform-tests/resources/chromium/device_manager.mojom.js.headers >+/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/fake_bluetooth.mojom.js >+/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/fake_bluetooth.mojom.js.headers >+/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/fake_bluetooth_chooser.mojom.js >+/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/fake_bluetooth_chooser.mojom.js.headers >+/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/generic_sensor_mocks.js >+/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/generic_sensor_mocks.js.headers > /LayoutTests/imported/w3c/web-platform-tests/resources/chromium/mojo_bindings.js > /LayoutTests/imported/w3c/web-platform-tests/resources/chromium/mojo_bindings.js.headers >+/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/mojo_layouttest_test.mojom.js >+/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/mojo_layouttest_test.mojom.js.headers >+/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/sensor.mojom.js >+/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/sensor_provider.mojom.js > /LayoutTests/imported/w3c/web-platform-tests/resources/chromium/string16.mojom.js > /LayoutTests/imported/w3c/web-platform-tests/resources/chromium/string16.mojom.js.headers >+/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/uuid.mojom.js >+/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/uuid.mojom.js.headers >+/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/web-bluetooth-test.js >+/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/web-bluetooth-test.js.headers > /LayoutTests/imported/w3c/web-platform-tests/resources/chromium/webusb-test.js > /LayoutTests/imported/w3c/web-platform-tests/resources/chromium/webusb-test.js.headers >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/web-bluetooth-test.js b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/web-bluetooth-test.js >new file mode 100644 >index 0000000000000000000000000000000000000000..f0eba0f0c6c3b6ec1b2b4ace33b957f4e23e1be2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/web-bluetooth-test.js >@@ -0,0 +1,526 @@ >+'use strict'; >+ >+function toMojoCentralState(state) { >+ switch (state) { >+ case 'absent': >+ return bluetooth.mojom.CentralState.ABSENT; >+ case 'powered-off': >+ return bluetooth.mojom.CentralState.POWERED_OFF; >+ case 'powered-on': >+ return bluetooth.mojom.CentralState.POWERED_ON; >+ default: >+ throw `Unsupported value ${state} for state.`; >+ } >+} >+ >+// Canonicalizes UUIDs and converts them to Mojo UUIDs. >+function canonicalizeAndConvertToMojoUUID(uuids) { >+ let canonicalUUIDs = uuids.map(val => ({uuid: BluetoothUUID.getService(val)})); >+ return canonicalUUIDs; >+} >+ >+// Converts WebIDL a record<DOMString, BufferSource> to a map<K, array<uint8>> to >+// use for Mojo, where the value for K is calculated using keyFn. >+function convertToMojoMap(record, keyFn) { >+ let map = new Map(); >+ for (const [key, value] of Object.entries(record)) { >+ let buffer = ArrayBuffer.isView(value) ? value.buffer : value; >+ map.set(keyFn(key), Array.from(new Uint8Array(buffer))); >+ } >+ return map; >+} >+ >+// Mapping of the property names of >+// BluetoothCharacteristicProperties defined in >+// https://webbluetoothcg.github.io/web-bluetooth/#characteristicproperties >+// to property names of the CharacteristicProperties mojo struct. >+const CHARACTERISTIC_PROPERTIES_WEB_TO_MOJO = { >+ broadcast: 'broadcast', >+ read: 'read', >+ write_without_response: 'write_without_response', >+ write: 'write', >+ notify: 'notify', >+ indicate: 'indicate', >+ authenticatedSignedWrites: 'authenticated_signed_writes', >+ extended_properties: 'extended_properties', >+}; >+ >+function ArrayToMojoCharacteristicProperties(arr) { >+ let struct = new bluetooth.mojom.CharacteristicProperties(); >+ >+ arr.forEach(val => { >+ let mojo_property = >+ CHARACTERISTIC_PROPERTIES_WEB_TO_MOJO[val]; >+ >+ if (struct.hasOwnProperty(mojo_property)) >+ struct[mojo_property] = true; >+ else >+ throw `Invalid member '${val}' for CharacteristicProperties`; >+ }); >+ >+ return struct; >+} >+ >+class FakeBluetooth { >+ constructor() { >+ this.fake_bluetooth_ptr_ = new bluetooth.mojom.FakeBluetoothPtr(); >+ Mojo.bindInterface(bluetooth.mojom.FakeBluetooth.name, >+ mojo.makeRequest(this.fake_bluetooth_ptr_).handle, 'process'); >+ } >+ >+ // Set it to indicate whether the platform supports BLE. For example, >+ // Windows 7 is a platform that doesn't support Low Energy. On the other >+ // hand Windows 10 is a platform that does support LE, even if there is no >+ // Bluetooth radio present. >+ async setLESupported(supported) { >+ if (typeof supported !== 'boolean') throw 'Type Not Supported'; >+ await this.fake_bluetooth_ptr_.setLESupported(supported); >+ } >+ >+ // Returns a promise that resolves with a FakeCentral that clients can use >+ // to simulate events that a device in the Central/Observer role would >+ // receive as well as monitor the operations performed by the device in the >+ // Central/Observer role. >+ // Calls sets LE as supported. >+ // >+ // A "Central" object would allow its clients to receive advertising events >+ // and initiate connections to peripherals i.e. operations of two roles >+ // defined by the Bluetooth Spec: Observer and Central. >+ // See Bluetooth 4.2 Vol 3 Part C 2.2.2 "Roles when Operating over an >+ // LE Physical Transport". >+ async simulateCentral({state}) { >+ await this.setLESupported(true); >+ >+ let {fakeCentral: fake_central_ptr} = >+ await this.fake_bluetooth_ptr_.simulateCentral( >+ toMojoCentralState(state)); >+ return new FakeCentral(fake_central_ptr); >+ } >+ >+ // Returns true if there are no pending responses. >+ async allResponsesConsumed() { >+ let {consumed} = await this.fake_bluetooth_ptr_.allResponsesConsumed(); >+ return consumed; >+ } >+ >+ // Returns a promise that resolves with a FakeChooser that clients can use to >+ // simulate chooser events. >+ async getManualChooser() { >+ if (typeof this.fake_chooser_ === 'undefined') { >+ this.fake_chooser_ = new FakeChooser(); >+ } >+ return this.fake_chooser_; >+ } >+} >+ >+// FakeCentral allows clients to simulate events that a device in the >+// Central/Observer role would receive as well as monitor the operations >+// performed by the device in the Central/Observer role. >+class FakeCentral { >+ constructor(fake_central_ptr) { >+ this.fake_central_ptr_ = fake_central_ptr; >+ this.peripherals_ = new Map(); >+ } >+ >+ // Simulates a peripheral with |address|, |name| and |known_service_uuids| >+ // that has already been connected to the system. If the peripheral existed >+ // already it updates its name and known UUIDs. |known_service_uuids| should >+ // be an array of BluetoothServiceUUIDs >+ // https://webbluetoothcg.github.io/web-bluetooth/#typedefdef-bluetoothserviceuuid >+ // >+ // Platforms offer methods to retrieve devices that have already been >+ // connected to the system or weren't connected through the UA e.g. a user >+ // connected a peripheral through the system's settings. This method is >+ // intended to simulate peripherals that those methods would return. >+ async simulatePreconnectedPeripheral({ >+ address, name, knownServiceUUIDs = []}) { >+ >+ await this.fake_central_ptr_.simulatePreconnectedPeripheral( >+ address, name, canonicalizeAndConvertToMojoUUID(knownServiceUUIDs)); >+ >+ return this.fetchOrCreatePeripheral_(address); >+ } >+ >+ // Simulates an advertisement packet described by |scanResult| being received >+ // from a device. If central is currently scanning, the device will appear on >+ // the list of discovered devices. >+ async simulateAdvertisementReceived(scanResult) { >+ if ('uuids' in scanResult.scanRecord) { >+ scanResult.scanRecord.uuids = >+ canonicalizeAndConvertToMojoUUID(scanResult.scanRecord.uuids); >+ } >+ >+ // Convert the optional appearance and txPower fields to the corresponding >+ // Mojo structures, since Mojo does not support optional interger values. If >+ // the fields are undefined, set the hasValue field as false and value as 0. >+ // Otherwise, set the hasValue field as true and value with the field value. >+ const has_appearance = 'appearance' in scanResult.scanRecord; >+ scanResult.scanRecord.appearance = { >+ hasValue: has_appearance, >+ value: (has_appearance ? scanResult.scanRecord.appearance : 0) >+ } >+ >+ const has_tx_power = 'txPower' in scanResult.scanRecord; >+ scanResult.scanRecord.txPower = { >+ hasValue: has_tx_power, >+ value: (has_tx_power ? scanResult.scanRecord.txPower : 0) >+ } >+ >+ // Convert manufacturerData from a record<DOMString, BufferSource> into a >+ // map<uint8, array<uint8>> for Mojo. >+ if ('manufacturerData' in scanResult.scanRecord) { >+ scanResult.scanRecord.manufacturerData = convertToMojoMap( >+ scanResult.scanRecord.manufacturerData, Number); >+ } >+ >+ // Convert serviceData from a record<DOMString, BufferSource> into a >+ // map<string, array<uint8>> for Mojo. >+ if ('serviceData' in scanResult.scanRecord) { >+ scanResult.scanRecord.serviceData.serviceData = convertToMojoMap( >+ scanResult.scanRecord.serviceData, BluetoothUUID.getService); >+ } >+ >+ await this.fake_central_ptr_.simulateAdvertisementReceived( >+ new bluetooth.mojom.ScanResult(scanResult)); >+ >+ return this.fetchOrCreatePeripheral_(scanResult.deviceAddress); >+ } >+ >+ // Create a fake_peripheral object from the given address. >+ fetchOrCreatePeripheral_(address) { >+ let peripheral = this.peripherals_.get(address); >+ if (peripheral === undefined) { >+ peripheral = new FakePeripheral(address, this.fake_central_ptr_); >+ this.peripherals_.set(address, peripheral); >+ } >+ return peripheral; >+ } >+} >+ >+class FakePeripheral { >+ constructor(address, fake_central_ptr) { >+ this.address = address; >+ this.fake_central_ptr_ = fake_central_ptr; >+ } >+ >+ // Adds a fake GATT Service with |uuid| to be discovered when discovering >+ // the peripheral's GATT Attributes. Returns a FakeRemoteGATTService >+ // corresponding to this service. |uuid| should be a BluetoothServiceUUIDs >+ // https://webbluetoothcg.github.io/web-bluetooth/#typedefdef-bluetoothserviceuuid >+ async addFakeService({uuid}) { >+ let {serviceId: service_id} = await this.fake_central_ptr_.addFakeService( >+ this.address, {uuid: BluetoothUUID.getService(uuid)}); >+ >+ if (service_id === null) throw 'addFakeService failed'; >+ >+ return new FakeRemoteGATTService( >+ service_id, this.address, this.fake_central_ptr_); >+ } >+ >+ // Sets the next GATT Connection request response to |code|. |code| could be >+ // an HCI Error Code from BT 4.2 Vol 2 Part D 1.3 List Of Error Codes or a >+ // number outside that range returned by specific platforms e.g. Android >+ // returns 0x101 to signal a GATT failure >+ // https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#GATT_FAILURE >+ async setNextGATTConnectionResponse({code}) { >+ let {success} = >+ await this.fake_central_ptr_.setNextGATTConnectionResponse( >+ this.address, code); >+ >+ if (success !== true) throw 'setNextGATTConnectionResponse failed.'; >+ } >+ >+ // Sets the next GATT Discovery request response for peripheral with >+ // |address| to |code|. |code| could be an HCI Error Code from >+ // BT 4.2 Vol 2 Part D 1.3 List Of Error Codes or a number outside that >+ // range returned by specific platforms e.g. Android returns 0x101 to signal >+ // a GATT failure >+ // https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#GATT_FAILURE >+ // >+ // The following procedures defined at BT 4.2 Vol 3 Part G Section 4. >+ // "GATT Feature Requirements" are used to discover attributes of the >+ // GATT Server: >+ // - Primary Service Discovery >+ // - Relationship Discovery >+ // - Characteristic Discovery >+ // - Characteristic Descriptor Discovery >+ // This method aims to simulate the response once all of these procedures >+ // have completed or if there was an error during any of them. >+ async setNextGATTDiscoveryResponse({code}) { >+ let {success} = >+ await this.fake_central_ptr_.setNextGATTDiscoveryResponse( >+ this.address, code); >+ >+ if (success !== true) throw 'setNextGATTDiscoveryResponse failed.'; >+ } >+ >+ // Simulates a GATT disconnection from the peripheral with |address|. >+ async simulateGATTDisconnection() { >+ let {success} = >+ await this.fake_central_ptr_.simulateGATTDisconnection(this.address); >+ >+ if (success !== true) throw 'simulateGATTDisconnection failed.'; >+ } >+ >+ // Simulates an Indication from the peripheral's GATT `Service Changed` >+ // Characteristic from BT 4.2 Vol 3 Part G 7.1. This Indication is signaled >+ // when services, characteristics, or descriptors are changed, added, or >+ // removed. >+ // >+ // The value for `Service Changed` is a range of attribute handles that have >+ // changed. However, this testing specification works at an abstracted >+ // level and does not expose setting attribute handles when adding >+ // attributes. Consequently, this simulate method should include the full >+ // range of all the peripheral's attribute handle values. >+ async simulateGATTServicesChanged() { >+ let {success} = >+ await this.fake_central_ptr_.simulateGATTServicesChanged(this.address); >+ >+ if (success !== true) throw 'simulateGATTServicesChanged failed.'; >+ } >+} >+ >+class FakeRemoteGATTService { >+ constructor(service_id, peripheral_address, fake_central_ptr) { >+ this.service_id_ = service_id; >+ this.peripheral_address_ = peripheral_address; >+ this.fake_central_ptr_ = fake_central_ptr; >+ } >+ >+ // Adds a fake GATT Characteristic with |uuid| and |properties| >+ // to this fake service. The characteristic will be found when discovering >+ // the peripheral's GATT Attributes. Returns a FakeRemoteGATTCharacteristic >+ // corresponding to the added characteristic. >+ async addFakeCharacteristic({uuid, properties}) { >+ let {characteristicId: characteristic_id} = >+ await this.fake_central_ptr_.addFakeCharacteristic( >+ {uuid: BluetoothUUID.getCharacteristic(uuid)}, >+ ArrayToMojoCharacteristicProperties(properties), >+ this.service_id_, >+ this.peripheral_address_); >+ >+ if (characteristic_id === null) throw 'addFakeCharacteristic failed'; >+ >+ return new FakeRemoteGATTCharacteristic( >+ characteristic_id, this.service_id_, >+ this.peripheral_address_, this.fake_central_ptr_); >+ } >+ >+ // Removes the fake GATT service from its fake peripheral. >+ async remove() { >+ let {success} = >+ await this.fake_central_ptr_.removeFakeService( >+ this.service_id_, >+ this.peripheral_address_); >+ >+ if (!success) throw 'remove failed'; >+ } >+} >+ >+class FakeRemoteGATTCharacteristic { >+ constructor(characteristic_id, service_id, peripheral_address, >+ fake_central_ptr) { >+ this.ids_ = [characteristic_id, service_id, peripheral_address]; >+ this.descriptors_ = []; >+ this.fake_central_ptr_ = fake_central_ptr; >+ } >+ >+ // Adds a fake GATT Descriptor with |uuid| to be discovered when >+ // discovering the peripheral's GATT Attributes. Returns a >+ // FakeRemoteGATTDescriptor corresponding to this descriptor. |uuid| should >+ // be a BluetoothDescriptorUUID >+ // https://webbluetoothcg.github.io/web-bluetooth/#typedefdef-bluetoothdescriptoruuid >+ async addFakeDescriptor({uuid}) { >+ let {descriptorId: descriptor_id} = >+ await this.fake_central_ptr_.addFakeDescriptor( >+ {uuid: BluetoothUUID.getDescriptor(uuid)}, ...this.ids_); >+ >+ if (descriptor_id === null) throw 'addFakeDescriptor failed'; >+ >+ let fake_descriptor = new FakeRemoteGATTDescriptor( >+ descriptor_id, ...this.ids_, this.fake_central_ptr_); >+ this.descriptors_.push(fake_descriptor); >+ >+ return fake_descriptor; >+ } >+ >+ // Sets the next read response for characteristic to |code| and |value|. >+ // |code| could be a GATT Error Response from >+ // BT 4.2 Vol 3 Part F 3.4.1.1 Error Response or a number outside that range >+ // returned by specific platforms e.g. Android returns 0x101 to signal a GATT >+ // failure. >+ // https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#GATT_FAILURE >+ async setNextReadResponse(gatt_code, value=null) { >+ if (gatt_code === 0 && value === null) { >+ throw '|value| can\'t be null if read should success.'; >+ } >+ if (gatt_code !== 0 && value !== null) { >+ throw '|value| must be null if read should fail.'; >+ } >+ >+ let {success} = >+ await this.fake_central_ptr_.setNextReadCharacteristicResponse( >+ gatt_code, value, ...this.ids_); >+ >+ if (!success) throw 'setNextReadCharacteristicResponse failed'; >+ } >+ >+ // Sets the next write response for this characteristic to |code|. If >+ // writing to a characteristic that only supports 'write_without_response' >+ // the set response will be ignored. >+ // |code| could be a GATT Error Response from >+ // BT 4.2 Vol 3 Part F 3.4.1.1 Error Response or a number outside that range >+ // returned by specific platforms e.g. Android returns 0x101 to signal a GATT >+ // failure. >+ async setNextWriteResponse(gatt_code) { >+ let {success} = >+ await this.fake_central_ptr_.setNextWriteCharacteristicResponse( >+ gatt_code, ...this.ids_); >+ >+ if (!success) throw 'setNextWriteCharacteristicResponse failed'; >+ } >+ >+ // Sets the next subscribe to notifications response for characteristic with >+ // |characteristic_id| in |service_id| and in |peripheral_address| to >+ // |code|. |code| could be a GATT Error Response from BT 4.2 Vol 3 Part F >+ // 3.4.1.1 Error Response or a number outside that range returned by >+ // specific platforms e.g. Android returns 0x101 to signal a GATT failure. >+ async setNextSubscribeToNotificationsResponse(gatt_code) { >+ let {success} = >+ await this.fake_central_ptr_.setNextSubscribeToNotificationsResponse( >+ gatt_code, ...this.ids_); >+ >+ if (!success) throw 'setNextSubscribeToNotificationsResponse failed'; >+ } >+ >+ // Sets the next unsubscribe to notifications response for characteristic with >+ // |characteristic_id| in |service_id| and in |peripheral_address| to >+ // |code|. |code| could be a GATT Error Response from BT 4.2 Vol 3 Part F >+ // 3.4.1.1 Error Response or a number outside that range returned by >+ // specific platforms e.g. Android returns 0x101 to signal a GATT failure. >+ async setNextUnsubscribeFromNotificationsResponse(gatt_code) { >+ let {success} = >+ await this.fake_central_ptr_.setNextUnsubscribeFromNotificationsResponse( >+ gatt_code, ...this.ids_); >+ >+ if (!success) throw 'setNextUnsubscribeToNotificationsResponse failed'; >+ } >+ >+ // Returns true if notifications from the characteristic have been subscribed >+ // to. >+ async isNotifying() { >+ let {success, isNotifying} = >+ await this.fake_central_ptr_.isNotifying(...this.ids_); >+ >+ if (!success) throw 'isNotifying failed'; >+ >+ return isNotifying; >+ } >+ >+ // Gets the last successfully written value to the characteristic. >+ // Returns null if no value has yet been written to the characteristic. >+ async getLastWrittenValue() { >+ let {success, value} = >+ await this.fake_central_ptr_.getLastWrittenCharacteristicValue( >+ ...this.ids_); >+ >+ if (!success) throw 'getLastWrittenCharacteristicValue failed'; >+ >+ return value; >+ } >+ >+ // Removes the fake GATT Characteristic from its fake service. >+ async remove() { >+ let {success} = >+ await this.fake_central_ptr_.removeFakeCharacteristic(...this.ids_); >+ >+ if (!success) throw 'remove failed'; >+ } >+} >+ >+class FakeRemoteGATTDescriptor { >+ constructor(descriptor_id, >+ characteristic_id, >+ service_id, >+ peripheral_address, >+ fake_central_ptr) { >+ this.ids_ = [ >+ descriptor_id, characteristic_id, service_id, peripheral_address]; >+ this.fake_central_ptr_ = fake_central_ptr; >+ } >+ >+ // Sets the next read response for descriptor to |code| and |value|. >+ // |code| could be a GATT Error Response from >+ // BT 4.2 Vol 3 Part F 3.4.1.1 Error Response or a number outside that range >+ // returned by specific platforms e.g. Android returns 0x101 to signal a GATT >+ // failure. >+ // https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#GATT_FAILURE >+ async setNextReadResponse(gatt_code, value=null) { >+ if (gatt_code === 0 && value === null) { >+ throw '|value| cannot be null if read should succeed.'; >+ } >+ if (gatt_code !== 0 && value !== null) { >+ throw '|value| must be null if read should fail.'; >+ } >+ >+ let {success} = >+ await this.fake_central_ptr_.setNextReadDescriptorResponse( >+ gatt_code, value, ...this.ids_); >+ >+ if (!success) throw 'setNextReadDescriptorResponse failed'; >+ } >+ >+ // Sets the next write response for this descriptor to |code|. >+ // |code| could be a GATT Error Response from >+ // BT 4.2 Vol 3 Part F 3.4.1.1 Error Response or a number outside that range >+ // returned by specific platforms e.g. Android returns 0x101 to signal a GATT >+ // failure. >+ async setNextWriteResponse(gatt_code) { >+ let {success} = >+ await this.fake_central_ptr_.setNextWriteDescriptorResponse( >+ gatt_code, ...this.ids_); >+ >+ if (!success) throw 'setNextWriteDescriptorResponse failed'; >+ } >+ >+ // Gets the last successfully written value to the descriptor. >+ // Returns null if no value has yet been written to the descriptor. >+ async getLastWrittenValue() { >+ let {success, value} = >+ await this.fake_central_ptr_.getLastWrittenDescriptorValue( >+ ...this.ids_); >+ >+ if (!success) throw 'getLastWrittenDescriptorValue failed'; >+ >+ return value; >+ } >+ >+ // Removes the fake GATT Descriptor from its fake characteristic. >+ async remove() { >+ let {success} = >+ await this.fake_central_ptr_.removeFakeDescriptor(...this.ids_); >+ >+ if (!success) throw 'remove failed'; >+ } >+} >+ >+// FakeChooser allows clients to simulate events that a user would trigger when >+// using the Bluetooth chooser, and monitor the events that are produced. >+class FakeChooser { >+ constructor() { >+ this.fake_bluetooth_chooser_ptr_ = >+ new content.mojom.FakeBluetoothChooserPtr(); >+ Mojo.bindInterface(content.mojom.FakeBluetoothChooser.name, >+ mojo.makeRequest(this.fake_bluetooth_chooser_ptr_).handle, 'process'); >+ } >+} >+ >+// If this line fails, it means that current environment does not support the >+// Web Bluetooth Test API. >+try { >+ navigator.bluetooth.test = new FakeBluetooth(); >+} catch { >+ throw 'Web Bluetooth Test API is not implemented on this ' + >+ 'environment. See the bluetooth README at ' + >+ 'https://github.com/web-platform-tests/wpt/blob/master/bluetooth/README.md#web-bluetooth-testing'; >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/web-bluetooth-test.js.headers b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/web-bluetooth-test.js.headers >new file mode 100644 >index 0000000000000000000000000000000000000000..6805c323df5a975231648b830e33ce183c3cbbd3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/web-bluetooth-test.js.headers >@@ -0,0 +1 @@ >+Content-Type: text/javascript; charset=utf-8 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/webusb-test.js b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/webusb-test.js >index 08c82547ed8944f06fdfa323232074e484642f43..630a7da945c225b1026e677c30888b0e11df9be2 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/webusb-test.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/chromium/webusb-test.js >@@ -20,12 +20,12 @@ let internal = { > }; > > // Converts an ECMAScript String object to an instance of >-// mojo.common.mojom.String16. >+// mojo_base.mojom.String16. > function mojoString16ToString(string16) { > return String.fromCharCode.apply(null, string16.data); > } > >-// Converts an instance of mojo.common.mojom.String16 to an ECMAScript String. >+// Converts an instance of mojo_base.mojom.String16 to an ECMAScript String. > function stringToMojoString16(string) { > let array = new Array(string.length); > for (var i = 0; i < string.length; ++i) { >@@ -360,15 +360,17 @@ class FakeDeviceManager { > } > > getDevice(guid, request) { >- let device = this.devicesByGuid_.get(guid); >- if (device) { >+ let retrievedDevice = this.devicesByGuid_.get(guid); >+ if (retrievedDevice) { > let binding = new mojo.Binding( >- window.device.mojom.UsbDevice, new FakeDevice(device.info), request); >+ device.mojom.UsbDevice, >+ new FakeDevice(retrievedDevice.info), >+ request); > binding.setConnectionErrorHandler(() => { >- if (device.fakeDevice.onclose) >- device.fakeDevice.onclose(); >+ if (retrievedDevice.fakeDevice.onclose) >+ retrievedDevice.fakeDevice.onclose(); > }); >- device.bindingArray.push(binding); >+ retrievedDevice.bindingArray.push(binding); > } else { > request.close(); > } >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/idlharness.js b/LayoutTests/imported/w3c/web-platform-tests/resources/idlharness.js >index c3045c49f909c9514597a6d6f8a9a3f7fe0f4df2..d00572492df7885e5ba01b32aa16d3c064f9c64e 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/idlharness.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/idlharness.js >@@ -183,11 +183,19 @@ self.IdlArray = function() > * A implements C; > * D implements E; > * >- * results in { A: ["B", "C"], D: ["E"] }. >+ * results in this["implements"] = { A: ["B", "C"], D: ["E"] }. >+ * >+ * Similarly, >+ * >+ * interface A : B {}; >+ * interface B : C {}; >+ * >+ * results in this["inheritance"] = { A: "B", B: "C" } > */ > this.partials = []; > this["implements"] = {}; > this["includes"] = {}; >+ this["inheritance"] = {}; > }; > > //@} >@@ -204,19 +212,118 @@ IdlArray.prototype.add_untested_idls = function(raw_idls, options) > { > /** Entry point. See documentation at beginning of file. */ > var parsed_idls = WebIDL2.parse(raw_idls); >- for (var i = 0; i < parsed_idls.length; i++) >- { >+ this.mark_as_untested(parsed_idls); >+ this.internal_add_idls(parsed_idls, options); >+}; >+ >+//@} >+IdlArray.prototype.mark_as_untested = function (parsed_idls) >+//@{ >+{ >+ for (var i = 0; i < parsed_idls.length; i++) { > parsed_idls[i].untested = true; >- if ("members" in parsed_idls[i]) >- { >- for (var j = 0; j < parsed_idls[i].members.length; j++) >- { >+ if ("members" in parsed_idls[i]) { >+ for (var j = 0; j < parsed_idls[i].members.length; j++) { > parsed_idls[i].members[j].untested = true; > } > } > } >- this.internal_add_idls(parsed_idls, options); > }; >+//@} >+ >+//@} >+IdlArray.prototype.is_excluded_by_options = function (name, options) >+//@{ >+{ >+ return options && >+ (options.except && options.except.includes(name) >+ || options.only && !options.only.includes(name)); >+}; >+//@} >+ >+//@} >+IdlArray.prototype.add_dependency_idls = function(raw_idls, options) >+//@{ >+{ >+ const parsed_idls = WebIDL2.parse(raw_idls); >+ const new_options = { only: [] } >+ >+ const all_deps = new Set(); >+ Object.values(this.inheritance).forEach(v => all_deps.add(v)); >+ Object.values(this.implements).forEach(v => all_deps.add(v)); >+ // NOTE: If 'A includes B' for B that we care about, then A is also a dep. >+ Object.keys(this.includes).forEach(k => { >+ all_deps.add(k); >+ this.includes[k].forEach(v => all_deps.add(v)); >+ }); >+ this.partials.map(p => p.name).forEach(v => all_deps.add(v)); >+ // Add the attribute idlTypes of all the nested members of all tested idls. >+ for (const obj of [this.members, this.partials]) { >+ const tested = Object.values(obj).filter(m => !m.untested && m.members); >+ for (const parsed of tested) { >+ for (const attr of Object.values(parsed.members).filter(m => !m.untested && m.type === 'attribute')) { >+ all_deps.add(attr.idlType.idlType); >+ } >+ } >+ } >+ >+ if (options && options.except && options.only) { >+ throw new IdlHarnessError("The only and except options can't be used together."); >+ } >+ >+ const should_skip = name => { >+ // NOTE: Deps are untested, so we're lenient, and skip re-encountered definitions. >+ // e.g. for 'idl' containing A:B, B:C, C:D >+ // array.add_idls(idl, {only: ['A','B']}). >+ // array.add_dependency_idls(idl); >+ // B would be encountered as tested, and encountered as a dep, so we ignore. >+ return name in this.members >+ || this.is_excluded_by_options(name, options); >+ } >+ // Record of skipped items, in case we later determine they are a dependency. >+ // Maps name -> [parsed_idl, ...] >+ const skipped = new Map(); >+ const process = function(parsed) { >+ let name = parsed.name >+ || parsed.type == "implements" && parsed.target >+ || parsed.type == "includes" && parsed.target; >+ if (!name || should_skip(name) || !all_deps.has(name)) { >+ name && >+ skipped.has(name) >+ ? skipped.get(name).push(parsed) >+ : skipped.set(name, [parsed]); >+ return; >+ } >+ >+ new_options.only.push(name); >+ const follow_up = []; >+ for (const dep_type of ["inheritance", "implements", "includes"]) { >+ if (parsed[dep_type]) { >+ const dep = parsed[dep_type]; >+ new_options.only.push(dep); >+ all_deps.add(dep); >+ follow_up.push(dep); >+ } >+ } >+ >+ for (const deferred of follow_up) { >+ if (skipped.has(deferred)) { >+ const next = skipped.get(deferred); >+ skipped.delete(deferred); >+ next.forEach(process); >+ } >+ } >+ } >+ for (let parsed of parsed_idls) { >+ process(parsed); >+ } >+ >+ this.mark_as_untested(parsed_idls); >+ >+ if (new_options.only.length) { >+ this.internal_add_idls(parsed_idls, new_options); >+ } >+} > > //@} > IdlArray.prototype.internal_add_idls = function(parsed_idls, options) >@@ -242,17 +349,8 @@ IdlArray.prototype.internal_add_idls = function(parsed_idls, options) > throw new IdlHarnessError("The only and except options can't be used together."); > } > >- function should_skip(name) >- { >- if (options && options.only && options.only.indexOf(name) == -1) >- { >- return true; >- } >- if (options && options.except && options.except.indexOf(name) != -1) >- { >- return true; >- } >- return false; >+ var should_skip = name => { >+ return this.is_excluded_by_options(name, options); > } > > parsed_idls.forEach(function(parsed_idl) >@@ -304,6 +402,17 @@ IdlArray.prototype.internal_add_idls = function(parsed_idls, options) > { > throw new IdlHarnessError("Duplicate identifier " + parsed_idl.name); > } >+ >+ if (parsed_idl["inheritance"]) { >+ // NOTE: Clash should be impossible (would require redefinition of parsed_idl.name). >+ if (parsed_idl.name in this["inheritance"] >+ && parsed_idl["inheritance"] != this["inheritance"][parsed_idl.name]) { >+ throw new IdlHarnessError( >+ `Inheritance for ${parsed_idl.name} was already defined`); >+ } >+ this["inheritance"][parsed_idl.name] = parsed_idl["inheritance"]; >+ } >+ > switch(parsed_idl.type) > { > case "interface": >@@ -554,8 +663,9 @@ IdlArray.prototype.is_json_type = function(type) > > function exposure_set(object, default_set) { > var exposed = object.extAttrs.filter(function(a) { return a.name == "Exposed" }); >- if (exposed.length > 1 || exposed.length < 0) { >- throw new IdlHarnessError("Unexpected Exposed extended attributes on " + memberName + ": " + exposed); >+ if (exposed.length > 1) { >+ throw new IdlHarnessError( >+ `Multiple 'Exposed' extended attributes on ${object.name}`); > } > > if (exposed.length === 0) { >@@ -683,6 +793,21 @@ IdlArray.prototype.test = function() > } > this["includes"] = {}; > >+ // Assert B defined for A : B >+ for (var member of Object.values(this.members).filter(m => m.base)) { >+ const lhs = member.name; >+ const rhs = member.base; >+ if (!(rhs in this.members)) throw new IdlHarnessError(`${lhs} inherits ${rhs}, but ${rhs} is undefined.`); >+ const lhs_is_interface = this.members[lhs] instanceof IdlInterface; >+ const rhs_is_interface = this.members[rhs] instanceof IdlInterface; >+ if (rhs_is_interface != lhs_is_interface) { >+ if (!lhs_is_interface) throw new IdlHarnessError(`${lhs} inherits ${rhs}, but ${lhs} is not an interface.`); >+ if (!rhs_is_interface) throw new IdlHarnessError(`${lhs} inherits ${rhs}, but ${rhs} is not an interface.`); >+ } >+ // Check for circular dependencies. >+ member.get_inheritance_stack(); >+ } >+ > Object.getOwnPropertyNames(this.members).forEach(function(memberName) { > var member = this.members[memberName]; > if (!(member instanceof IdlInterface)) { >@@ -762,7 +887,7 @@ IdlArray.prototype.assert_type_is = function(value, type) > return; > } > >- if (type.sequence) >+ if (type.generic === "sequence") > { > assert_true(Array.isArray(value), "should be an Array"); > if (!value.length) >@@ -1111,6 +1236,10 @@ IdlInterface.prototype.get_inheritance_stack = function() { > var base = this.array.members[idl_interface.base]; > if (!base) { > throw new Error(idl_interface.type + " " + idl_interface.base + " not found (inherited by " + idl_interface.name + ")"); >+ } else if (stack.indexOf(base) > -1) { >+ stack.push(base); >+ let dep_chain = stack.map(i => i.name).join(','); >+ throw new IdlHarnessError(`${this.name} has a circular dependency: ${dep_chain}`); > } > idl_interface = base; > stack.push(idl_interface); >@@ -1493,8 +1622,6 @@ IdlInterface.prototype.test_self = function() > // object. > // "Otherwise, if A is declared to inherit from another interface, then > // return the interface prototype object for the inherited interface. >- // "Otherwise, if A is declared with the [LegacyArrayClass] extended >- // attribute, then return %ArrayPrototype%. > // "Otherwise, return %ObjectPrototype%. > // > // "In the ECMAScript binding, the DOMException type has some additional >@@ -1517,9 +1644,6 @@ IdlInterface.prototype.test_self = function() > !this.array > .members[inherit_interface] > .has_extended_attribute("NoInterfaceObject"); >- } else if (this.has_extended_attribute('LegacyArrayClass')) { >- inherit_interface = 'Array'; >- inherit_interface_has_interface_object = true; > } else if (this.name === "DOMException") { > inherit_interface = 'Error'; > inherit_interface_has_interface_object = true; >@@ -1671,7 +1795,6 @@ IdlInterface.prototype.test_self = function() > this.name + '.prototype should not have @@unscopables'); > } > }.bind(this), this.name + ' interface: existence and properties of interface prototype object\'s @@unscopables property'); >- > }; > > //@} >@@ -2147,7 +2270,7 @@ IdlInterface.prototype.test_member_iterable = function(member) > //@{ > { > var interfaceName = this.name; >- var isPairIterator = member.idlType instanceof Array; >+ var isPairIterator = member.idlType.length === 2; > test(function() > { > var descriptor = Object.getOwnPropertyDescriptor(self[interfaceName].prototype, Symbol.iterator); >@@ -2429,6 +2552,7 @@ IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expect > } > if (!exposed_in(exposure_set(member, this.exposureSet))) { > test(function() { >+ assert_equals(exception, null, "Unexpected exception when evaluating object"); > assert_false(member.name in obj); > }.bind(this), this.name + " interface: " + desc + ' must not have property "' + member.name + '"'); > continue; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/readme.md b/LayoutTests/imported/w3c/web-platform-tests/resources/readme.md >index 8583d5f8d5b449b82d311e0e47b6e8126ce16dd5..97d2e6f92203d126ba585216c5605b581454af1e 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/readme.md >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/readme.md >@@ -1,22 +1,26 @@ >-## Introduction ## >+# Resources > >-testharness.js provides a framework for writing low-level tests of >+## `testharness.js` >+ >+`testharness.js` is a framework for writing low-level tests of > browser functionality in javascript. It provides a convenient API for > making assertions and is intended to work for both simple synchronous >-tests and for tests of asynchronous behaviour. >+tests, and tests of asynchronous behaviour. > >-## Getting Started ## >+### Getting started > >-To use testharness.js you must include two scripts, in the order given: >+To use `testharness.js` you must include two scripts, in the order given: > > ``` html >-<script src="/resources/testharness.js"></script> >-<script src="/resources/testharnessreport.js"></script> >+<script src=/resources/testharness.js></script> >+<script src=/resources/testharnessreport.js></script> > ``` > >-## Full documentation ## >+### Full documentation >+ >+For detailed API documentation please visit [https://web-platform-tests.org/writing-tests/testharness-api.html](https://web-platform-tests.org/writing-tests/testharness-api.html). > >-Full user documentation for the API is at [http://web-platform-tests.org/writing-tests/testharness-api.html](http://web-platform-tests.org/writing-tests/testharness-api.html). >+### Tutorials > >-You can also read a tutorial on >+You can also read a tutorial on > [Using testharness.js](http://darobin.github.com/test-harness-tutorial/docs/using-testharness.html). >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/README.md b/LayoutTests/imported/w3c/web-platform-tests/resources/test/README.md >index 1010516ad8ee9739a06e3d4f06cb40f8a7ed0e1f..73885247efc652264d43f95c823a990803d27e41 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/test/README.md >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/README.md >@@ -6,30 +6,32 @@ The test suite for the `testharness.js` testing framework. > > Install the following dependencies: > >-- [Python 2.7](https://www.python.org/) >+- [Python 2.7.9+](https://www.python.org/) > - [the tox Python package](https://tox.readthedocs.io/en/latest/) > - [the Mozilla Firefox web browser](https://mozilla.org/firefox) > - [the GeckoDriver server](https://github.com/mozilla/geckodriver) > >-Once these dependencies are satisfied, the tests may be run from a command line >-by executing the following command from this directory: >+Make sure `geckodriver` can be found in your `PATH`. > >- tox >+Currently, the tests should be run with the latest *Firefox Nightly*. In order to >+specify the path to Firefox Nightly, use the following command-line option: > >-Currently, the tests should be run with Firefox Nightly. >+ tox -- --binary=/path/to/FirefoxNightly > >-In order to specify the path to Firefox Nightly, use the following command-line option: >+### Automated Script > >- tox -- --binary=/path/to/FirefoxNightly >+Alternatively, you may run `tools/ci/ci_resources_unittest.sh`, which only depends on >+Python 2. The script will install other dependencies automatically and start `tox` with >+the correct arguments. > > ## Authoring Tests > >-Test cases are expressed as `.html` files located within the `tests/` >-sub-directory. Each test should include the `testharness.js` library with the >-following markup: >+Test cases are expressed as `.html` files located within the `tests/unit/` and >+`tests/funtional/` sub-directories. Each test should include the >+`testharness.js` library with the following markup: > >- <script src="../../testharness.js"></script> >- <script src="../../testharnessreport.js"></script> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> > > This should be followed by one or more `<script>` tags that interface with the > `testharness.js` API in some way. For example: >@@ -40,8 +42,25 @@ This should be followed by one or more `<script>` tags that interface with the > }, 'This test is expected to fail.'); > </script> > >-Finally, each test may include a summary of the expected results as a JSON >-string within a `<script>` tag with an `id` of `"expected"`, e.g.: >+### Unit tests >+ >+The "unit test" type allows for concisely testing the expected behavior of >+assertion methods. These tests may define any number of sub-tests; the >+acceptance criteria is simply that all tests executed pass. >+ >+### Functional tests >+ >+Thoroughly testing the behavior of the harness itself requires ensuring a >+number of considerations which cannot be verified with the "unit testing" >+strategy. These include: >+ >+- Ensuring that some tests are not run >+- Ensuring conditions that cause test failures >+- Ensuring conditions that cause harness errors >+ >+Functional tests allow for these details to be verified. Every functional test >+must include a summary of the expected results as a JSON string within a >+`<script>` tag with an `id` of `"expected"`, e.g.: > > <script type="text/json" id="expected"> > { >@@ -62,6 +81,3 @@ string within a `<script>` tag with an `id` of `"expected"`, e.g.: > "type": "complete" > } > </script> >- >-This is useful to test, for example, whether asserations that should fail or >-throw actually do. >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/config.test.json b/LayoutTests/imported/w3c/web-platform-tests/resources/test/config.test.json >deleted file mode 100644 >index df664faf44bad0696464d2ad397d123576063ff6..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/test/config.test.json >+++ /dev/null >@@ -1,27 +0,0 @@ >-{"host": "web-platform.test", >- "doc_root": null, >- "ws_doc_root": null, >- "external_host": null, >- "ports":{"http":[8000, "auto"], >- "https":[9003], >- "ws":["auto"], >- "wss":["auto"]}, >- "check_subdomains": true, >- "log_level":"debug", >- "bind_hostname": true, >- "ssl": {"type": "openssl", >- "encrypt_after_connect": false, >- "openssl": { >- "openssl_binary": "openssl", >- "base_path": "_certs", >- "force_regenerate": false, >- "base_conf_path": null >- }, >- "pregenerated": { >- "host_key_path": null, >- "host_cert_path": null >- }, >- "none": {} >- }, >- "aliases": [] >-} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/conftest.py b/LayoutTests/imported/w3c/web-platform-tests/resources/test/conftest.py >index 047ca1caed27c743adc3e9e56a65a7b130b8e39c..dc645940d6ab1d49e2b9e59f17a46d0841791880 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/test/conftest.py >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/conftest.py >@@ -17,19 +17,29 @@ def pytest_addoption(parser): > parser.addoption("--binary", action="store", default=None, help="path to browser binary") > > def pytest_collect_file(path, parent): >- if path.ext.lower() == '.html': >- return HTMLItem(str(path), parent) >+ if path.ext.lower() != '.html': >+ return >+ >+ # Tests are organized in directories by type >+ test_type = os.path.relpath(str(path), HERE).split(os.path.sep)[1] >+ >+ return HTMLItem(str(path), test_type, parent) > > def pytest_configure(config): > config.driver = webdriver.Firefox(firefox_binary=config.getoption("--binary")) > config.server = WPTServer(WPT_ROOT) > config.server.start() >- config.add_cleanup(lambda: config.server.stop()) >- config.add_cleanup(lambda: config.driver.quit()) >+ config.add_cleanup(config.server.stop) >+ config.add_cleanup(config.driver.quit) > > class HTMLItem(pytest.Item, pytest.Collector): >- def __init__(self, filename, parent): >+ def __init__(self, filename, test_type, parent): > self.filename = filename >+ self.type = test_type >+ >+ if test_type not in ('functional', 'unit'): >+ raise ValueError('Unrecognized test type: "%s"' % test_type) >+ > with io.open(filename, encoding=ENC) as f: > markup = f.read() > >@@ -47,6 +57,10 @@ class HTMLItem(pytest.Item, pytest.Collector): > > if not name: > raise ValueError('No name found in file: %s' % filename) >+ elif self.type == 'functional' and not self.expected: >+ raise ValueError('Functional tests must specify expected report data') >+ elif self.type == 'unit' and self.expected: >+ raise ValueError('Unit tests must not specify expected report data') > > super(HTMLItem, self).__init__(name, parent) > >@@ -58,6 +72,29 @@ class HTMLItem(pytest.Item, pytest.Collector): > return pytest.Collector.repr_failure(self, excinfo) > > def runtest(self): >+ if self.type == 'unit': >+ self._run_unit_test() >+ elif self.type == 'functional': >+ self._run_functional_test() >+ else: >+ raise NotImplementedError >+ >+ def _run_unit_test(self): >+ driver = self.session.config.driver >+ server = self.session.config.server >+ >+ driver.get(server.url(HARNESS)) >+ >+ actual = driver.execute_async_script('runTest("%s", "foo", arguments[0])' % server.url(str(self.filename))) >+ >+ summarized = self._summarize(actual) >+ >+ assert summarized[u'summarized_status'][u'status_string'] == u'OK', summarized[u'summarized_status'][u'message'] >+ for test in summarized[u'summarized_tests']: >+ msg = "%s\n%s" % (test[u'name'], test[u'message']) >+ assert test[u'status_string'] == u'PASS', msg >+ >+ def _run_functional_test(self): > driver = self.session.config.driver > server = self.session.config.server > >@@ -70,34 +107,30 @@ class HTMLItem(pytest.Item, pytest.Collector): > indices = [test_obj.get('index') for test_obj in actual['tests']] > self._assert_sequence(indices) > >+ summarized = self._summarize(actual) >+ >+ assert summarized == self.expected >+ >+ def _summarize(self, actual): > summarized = {} >+ > summarized[u'summarized_status'] = self._summarize_status(actual['status']) > summarized[u'summarized_tests'] = [ > self._summarize_test(test) for test in actual['tests']] > summarized[u'summarized_tests'].sort(key=lambda test_obj: test_obj.get('name')) > summarized[u'type'] = actual['type'] > >- if not self.expected: >- assert summarized[u'summarized_status'][u'status_string'] == u'OK', summarized[u'summarized_status'][u'message'] >- for test in summarized[u'summarized_tests']: >- msg = "%s\n%s:\n%s" % (test[u'name'], test[u'message'], test[u'stack']) >- assert test[u'status_string'] == u'PASS', msg >- else: >- assert summarized == self.expected >+ return summarized > > @staticmethod > def _assert_sequence(nums): >- assert nums == range(1, nums[-1] + 1) >+ if nums and len(nums) > 0: >+ assert nums == range(1, nums[-1] + 1) > > @staticmethod > def _scrub_stack(test_obj): > copy = dict(test_obj) >- >- assert 'stack' in copy >- >- if copy['stack'] is not None: >- copy['stack'] = u'(implementation-defined)' >- >+ del copy['stack'] > return copy > > @staticmethod >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/idl-helper.js b/LayoutTests/imported/w3c/web-platform-tests/resources/test/idl-helper.js >new file mode 100644 >index 0000000000000000000000000000000000000000..2b73527ff2becedfa7d191d7d82e76c1c378ff25 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/idl-helper.js >@@ -0,0 +1,24 @@ >+"use strict"; >+ >+var typedefFrom = interfaceFrom; >+var dictionaryFrom = interfaceFrom; >+function interfaceFrom(i) { >+ var idl = new IdlArray(); >+ idl.add_idls(i); >+ for (var prop in idl.members) { >+ return idl.members[prop]; >+ } >+} >+ >+function memberFrom(m) { >+ var idl = new IdlArray(); >+ idl.add_idls('interface A { ' + m + '; };'); >+ return idl.members["A"].members[0]; >+} >+ >+function typeFrom(type) { >+ var ast = WebIDL2.parse('interface Foo { ' + type + ' a(); };'); >+ ast = ast[0]; // get the first fragment >+ ast = ast.members[0]; // get the first member >+ return ast.idlType; // get the type of the first field >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/add_cleanup.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/add_cleanup.html >new file mode 100644 >index 0000000000000000000000000000000000000000..468319fdbea0044d1d8436ccf626d9778dc1e805 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/add_cleanup.html >@@ -0,0 +1,91 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Test#add_cleanup</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+</head> >+<body> >+<div id="log"></div> >+<script> >+"use strict"; >+ >+var log_sync; >+test(function(t) { >+ log_sync = ""; >+ t.add_cleanup(function() { log_sync += "1"; }); >+ t.add_cleanup(function() { log_sync += "2"; }); >+ t.add_cleanup(function() { log_sync += "3"; }); >+ t.add_cleanup(function() { log_sync += "4"; }); >+ t.add_cleanup(function() { log_sync += "5"; }); >+ log_sync += "0"; >+}, "probe synchronous"); >+ >+test(function() { >+ if (log_sync !== "012345") { >+ throw new Error("Expected: '012345'. Actual: '" + log_sync + "'."); >+ } >+}, "Cleanup methods are invoked exactly once and in the expected sequence."); >+ >+var complete, log_async; >+async_test(function(t) { >+ complete = t.step_func(function() { >+ if (log_async !== "012") { >+ throw new Error("Expected: '012'. Actual: '" + log_async + "'."); >+ } >+ >+ t.done(); >+ }); >+}, "Cleanup methods are invoked following the completion of asynchronous tests"); >+ >+async_test(function(t) { >+ log_async = ""; >+ t.add_cleanup(function() { log_async += "1"; }); >+ >+ setTimeout(t.step_func(function() { >+ t.add_cleanup(function() { >+ log_async += "2"; >+ complete(); >+ }); >+ log_async += "0"; >+ t.done(); >+ }), 0); >+}, "probe asynchronous"); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "OK", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "Cleanup methods are invoked exactly once and in the expected sequence.", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Cleanup methods are invoked following the completion of asynchronous tests", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "probe asynchronous", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "probe synchronous", >+ "properties": {}, >+ "message": null >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/add_cleanup_count.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/add_cleanup_count.html >new file mode 100644 >index 0000000000000000000000000000000000000000..75f978219183a299f4cd6dc9f238addc0c9139dc >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/add_cleanup_count.html >@@ -0,0 +1,39 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Test#add_cleanup reported count</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+</head> >+<body> >+<div id="log"></div> >+ >+<script> >+promise_test(function(t) { >+ t.add_cleanup(function() {}); >+ t.add_cleanup(function() {}); >+ t.add_cleanup(function() { throw new Error(); }); >+ new EventWatcher(t, document.body, []); >+ >+ return Promise.resolve(); >+}, 'test with 3 user-defined cleanup functions'); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "ERROR", >+ "message": "Test named 'test with 3 user-defined cleanup functions' specified 3 'cleanup' functions, and 1 failed." >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "test with 3 user-defined cleanup functions", >+ "message": null, >+ "properties": {} >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/add_cleanup_err.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/add_cleanup_err.html >new file mode 100644 >index 0000000000000000000000000000000000000000..5ec6a3fdd086230ca71b8c56b252a15b27db2734 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/add_cleanup_err.html >@@ -0,0 +1,45 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Test#add_cleanup: error</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+</head> >+<body> >+<div id="log"></div> >+<script> >+"use strict"; >+ >+test(function(t) { >+ t.add_cleanup(function() { >+ throw new Error('exception in cleanup function'); >+ }); >+}, "Exception in cleanup function causes harness failure."); >+ >+test(function() {}, "This test should not be run."); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "ERROR", >+ "message": "Test named 'Exception in cleanup function causes harness failure.' specified 1 'cleanup' function, and 1 failed." >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "Exception in cleanup function causes harness failure.", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "NOTRUN", >+ "name": "This test should not be run.", >+ "properties": {}, >+ "message": null >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/add_cleanup_err_multi.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/add_cleanup_err_multi.html >new file mode 100644 >index 0000000000000000000000000000000000000000..7556829ae09ed49d75de6af189190d4f9f850bec >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/add_cleanup_err_multi.html >@@ -0,0 +1,52 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Test#add_cleanup: multiple functions with one in error</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+</head> >+<body> >+<div id="log"></div> >+ >+<script> >+"use strict"; >+ >+test(function(t) { >+ t.add_cleanup(function() { >+ throw new Error("exception in cleanup function"); >+ }); >+ >+ // The following cleanup function defines a test so that the reported >+ // data demonstrates the intended run-time behavior, i.e. that >+ // `testharness.js` invokes all cleanup functions even when one or more >+ // throw errors. >+ t.add_cleanup(function() { >+ test(function() {}, "Verification test"); >+ }); >+ }, "Test with multiple cleanup functions"); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "ERROR", >+ "message": "Test named 'Test with multiple cleanup functions' specified 2 'cleanup' functions, and 1 failed." >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "Test with multiple cleanup functions", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "NOTRUN", >+ "name": "Verification test", >+ "properties": {}, >+ "message": null >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/api-tests-1.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/api-tests-1.html >new file mode 100644 >index 0000000000000000000000000000000000000000..4d9c774577bd2986ad434b1bd2900a32730a3571 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/api-tests-1.html >@@ -0,0 +1,427 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Sample HTML5 API Tests</title> >+<meta name="timeout" content="6000"> >+</head> >+<body onload="load_test_attr.done()"> >+<h1>Sample HTML5 API Tests</h1> >+<div id="log"></div> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+ setup_run = false; >+ setup(function() { >+ setup_run = true; >+ }); >+ test(function() {assert_true(setup_run)}, "Setup function ran"); >+ >+ // Two examples for testing events from handler and attributes >+ var load_test_event = async_test("window onload event fires when set from the handler"); >+ >+ function windowLoad() >+ { >+ load_test_event.done(); >+ } >+ on_event(window, "load", windowLoad); >+ >+ // see the body onload below >+ var load_test_attr = async_test("body element fires the onload event set from the attribute"); >+</script> >+<script> >+ function bodyElement() >+ { >+ assert_equals(document.body, document.getElementsByTagName("body")[0]); >+ } >+ test(bodyElement, "document.body should be the first body element in the document"); >+ >+ test(function() { >+ assert_equals(1,1); >+ assert_equals(NaN, NaN, "NaN case"); >+ assert_equals(0, 0, "Zero case"); >+ }, "assert_equals tests") >+ >+ test(function() { >+ assert_equals(-0, 0, "Zero case"); >+ }, "assert_equals tests expected to fail") >+ >+ test(function() { >+ assert_not_equals({}, {}, "object case"); >+ assert_not_equals(-0, 0, "Zero case"); >+ }, "assert_not_equals tests") >+ >+ function testAssertPass() >+ { >+ assert_true(true); >+ } >+ test(testAssertPass, "assert_true expected to pass"); >+ >+ function testAssertFalse() >+ { >+ assert_true(false, "false should not be true"); >+ } >+ test(testAssertFalse, "assert_true expected to fail"); >+ >+ function basicAssertArrayEquals() >+ { >+ assert_array_equals([1, NaN], [1, NaN], "[1, NaN] is equal to [1, NaN]"); >+ } >+ test(basicAssertArrayEquals, "basic assert_array_equals test"); >+ >+ function assertArrayEqualsUndefined() >+ { >+ assert_array_equals(undefined, [1], "undefined equals [1]?"); >+ } >+ test(assertArrayEqualsUndefined, "assert_array_equals with first param undefined"); >+ >+ function assertArrayEqualsTrue() >+ { >+ assert_array_equals(true, [1], "true equals [1]?"); >+ } >+ test(assertArrayEqualsTrue, "assert_array_equals with first param true"); >+ >+ function assertArrayEqualsFalse() >+ { >+ assert_array_equals(false, [1], "false equals [1]?"); >+ } >+ test(assertArrayEqualsFalse, "assert_array_equals with first param false"); >+ >+ function assertArrayEqualsNull() >+ { >+ assert_array_equals(null, [1], "null equals [1]?"); >+ } >+ test(assertArrayEqualsNull, "assert_array_equals with first param null"); >+ >+ function assertArrayEqualsNumeric() >+ { >+ assert_array_equals(1, [1], "1 equals [1]?"); >+ } >+ test(assertArrayEqualsNumeric, "assert_array_equals with first param 1"); >+ >+ function basicAssertObjectEquals() >+ { >+ assert_object_equals([1, 2, [1, 2]], { 0: 1, 1: 2, 2: { 0: 1, 1: 2} }, "array is equal to object") >+ } >+ test(basicAssertObjectEquals, "basic assert_object_equals test"); >+ >+ function basicAssertArrayApproxEquals() >+ { >+ assert_array_approx_equals([10, 11], [11, 10], 1, "[10, 11] is approximately (+/- 1) [11, 10]") >+ } >+ test(basicAssertArrayApproxEquals, "basic assert_array_approx_equals test"); >+ >+ function basicAssertApproxEquals() >+ { >+ assert_approx_equals(10, 11, 1, "10 is approximately (+/- 1) 11") >+ } >+ test(basicAssertApproxEquals, "basic assert_approx_equals test"); >+ >+ function basicAssertLessThan() >+ { >+ assert_less_than(10, 11, "10 is less than 11") >+ } >+ test(basicAssertApproxEquals, "basic assert_less_than test"); >+ >+ function basicAssertGreaterThan() >+ { >+ assert_greater_than(10, 11, "10 is not greater than 11"); >+ } >+ test(basicAssertGreaterThan, "assert_greater_than expected to fail"); >+ >+ function basicAssertGreaterThanEqual() >+ { >+ assert_greater_than_equal(10, 10, "10 is greater than or equal to 10") >+ } >+ test(basicAssertGreaterThanEqual, "basic assert_greater_than_equal test"); >+ >+ function basicAssertLessThanEqual() >+ { >+ assert_greater_than_equal('10', 10, "'10' is not a number") >+ } >+ test(basicAssertLessThanEqual, "assert_less_than_equal expected to fail"); >+ >+ function testAssertInherits() { >+ var A = function(){this.a = "a"} >+ A.prototype = {b:"b"} >+ var a = new A(); >+ assert_exists(a, "a"); >+ assert_not_exists(a, "b"); >+ assert_inherits(a, "b"); >+ } >+ test(testAssertInherits, "test for assert[_not]_exists and insert_inherits") >+ >+ test(function() >+ { >+ var a = document.createElement("a") >+ var b = document.createElement("b") >+ assert_throws("NOT_FOUND_ERR", function () {a.removeChild(b)}); >+ }, "Test throw DOM exception") >+ >+ test(function() >+ { >+ var a = document.createTextNode("a") >+ var b = document.createElement("b") >+ assert_throws("NOT_FOUND_ERR", function () {a.appendChild(b)}); >+ }, "Test throw DOM exception expected to fail") >+ >+ test(function() >+ { >+ var e = {code:0, name:"TEST_ERR", TEST_ERR:0} >+ assert_throws("TEST_ERR", function() {throw e}); >+ }, "Test assert_throws with non-DOM-exception expected to Fail"); >+ >+ var t = async_test("Test step_func") >+ setTimeout( >+ t.step_func( >+ function () { >+ assert_true(true); t.done(); >+ }), 0); >+ >+ async_test(function(t) { >+ setTimeout(t.step_func(function (){assert_true(true); t.done();}), 0); >+ }, "Test async test with callback"); >+ >+ async_test(function() { >+ setTimeout(this.step_func(function (){assert_true(true); this.done();}), 0); >+ }, "Test async test with callback and `this` obj."); >+ >+ async_test("test should timeout (fail) with the default of 2 seconds").step(function(){}); >+ >+ async_test("test should timeout (fail) with a custom set timeout value of 1 second", >+ {timeout:1000}).step(function(){}); >+ >+ async_test("async test that is never started, should have status Not Run", {timeout:1000}); >+ >+ >+ test(function(t) { >+ window.global = 1; >+ t.add_cleanup(function() {delete window.global}); >+ assert_equals(window.global, 1); >+ }, >+ "Test that defines a global and cleans it up"); >+ >+ test(function() {assert_equals(window.global, undefined)}, >+ "Test that cleanup handlers from previous test ran"); >+ >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "TIMEOUT", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "Setup function ran", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "Test assert_throws with non-DOM-exception expected to Fail", >+ "message": "Test bug: unrecognized DOMException code \"TEST_ERR\" passed to assert_throws()", >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Test async test with callback", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Test async test with callback and `this` obj.", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Test step_func", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Test that cleanup handlers from previous test ran", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Test that defines a global and cleans it up", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Test throw DOM exception", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "Test throw DOM exception expected to fail", >+ "message": "assert_throws: function \"function () {a.appendChild(b)}\" threw object \"HierarchyRequestError: Node cannot be inserted at the specified point in the hierarchy\" that is not a DOMException NOT_FOUND_ERR: property \"code\" is equal to 3, expected 8", >+ "properties": {} >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "assert_array_equals with first param 1", >+ "message": "assert_array_equals: 1 equals [1]? value is 1, expected array", >+ "properties": {} >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "assert_array_equals with first param false", >+ "message": "assert_array_equals: false equals [1]? value is false, expected array", >+ "properties": {} >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "assert_array_equals with first param null", >+ "message": "assert_array_equals: null equals [1]? value is null, expected array", >+ "properties": {} >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "assert_array_equals with first param true", >+ "message": "assert_array_equals: true equals [1]? value is true, expected array", >+ "properties": {} >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "assert_array_equals with first param undefined", >+ "message": "assert_array_equals: undefined equals [1]? value is undefined, expected array", >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "assert_equals tests", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "assert_equals tests expected to fail", >+ "message": "assert_equals: Zero case expected 0 but got -0", >+ "properties": {} >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "assert_greater_than expected to fail", >+ "message": "assert_greater_than: 10 is not greater than 11 expected a number greater than 11 but got 10", >+ "properties": {} >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "assert_less_than_equal expected to fail", >+ "message": "assert_greater_than_equal: '10' is not a number expected a number but got a \"string\"", >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "assert_not_equals tests", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "assert_true expected to fail", >+ "message": "assert_true: false should not be true expected true got false", >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "assert_true expected to pass", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "NOTRUN", >+ "name": "async test that is never started, should have status Not Run", >+ "message": null, >+ "properties": { >+ "timeout": 1000 >+ } >+ }, >+ { >+ "status_string": "PASS", >+ "name": "basic assert_approx_equals test", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "basic assert_array_approx_equals test", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "basic assert_array_equals test", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "basic assert_greater_than_equal test", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "basic assert_less_than test", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "basic assert_object_equals test", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "body element fires the onload event set from the attribute", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "document.body should be the first body element in the document", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "test for assert[_not]_exists and insert_inherits", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "TIMEOUT", >+ "name": "test should timeout (fail) with a custom set timeout value of 1 second", >+ "message": "Test timed out", >+ "properties": { >+ "timeout": 1000 >+ } >+ }, >+ { >+ "status_string": "TIMEOUT", >+ "name": "test should timeout (fail) with the default of 2 seconds", >+ "message": "Test timed out", >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "window onload event fires when set from the handler", >+ "message": null, >+ "properties": {} >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/api-tests-2.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/api-tests-2.html >new file mode 100644 >index 0000000000000000000000000000000000000000..0c269029b4fc89b170979e45b6e781d697e1bde5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/api-tests-2.html >@@ -0,0 +1,44 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Sample HTML5 API Tests</title> >+</head> >+<body> >+<h1>Sample HTML5 API Tests</h1> >+<p>There should be two results</p> >+<div id="log"></div> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+setup({explicit_done:true}) >+test(function() {assert_true(true)}, "Test defined before onload"); >+ >+onload = function() {test(function (){assert_true(true)}, "Test defined after onload"); >+done(); >+} >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "OK", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "Test defined after onload", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Test defined before onload", >+ "properties": {}, >+ "message": null >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/api-tests-3.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/api-tests-3.html >new file mode 100644 >index 0000000000000000000000000000000000000000..991fc6da670e4d55337c5f9394d1e7f9f3c4fb75 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/api-tests-3.html >@@ -0,0 +1,34 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Sample HTML5 API Tests</title> >+</head> >+<script src="/resources/testharness.js"></script> >+ >+<body> >+<h1>Sample HTML5 API Tests</h1> >+<div id="log"></div> >+<script> >+setup({explicit_timeout:true}); >+var t = async_test("This test should give a status of 'Not Run' without a delay"); >+timeout(); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "TIMEOUT", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "NOTRUN", >+ "name": "This test should give a status of 'Not Run' without a delay", >+ "properties": {}, >+ "message": null >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/force_timeout.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/force_timeout.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2058fdb8621e7d55ea2b1e22839ff0afe999f7b8 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/force_timeout.html >@@ -0,0 +1,60 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Test#force_timeout</title> >+</head> >+<body> >+<h1>Test#force_timeout</h1> >+<div id="log"></div> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+setup({ explicit_timeout: true }); >+ >+test(function(t) { >+ t.force_timeout(); >+ }, 'test (synchronous)'); >+ >+async_test(function(t) { >+ t.step_timeout(function() { >+ t.force_timeout(); >+ }, 0); >+ }, 'async_test'); >+ >+promise_test(function(t) { >+ t.force_timeout(); >+ >+ return new Promise(function() {}); >+ }, 'promise_test'); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "OK", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "TIMEOUT", >+ "name": "async_test", >+ "message": "Test timed out", >+ "properties": {} >+ }, >+ { >+ "status_string": "TIMEOUT", >+ "name": "promise_test", >+ "message": "Test timed out", >+ "properties": {} >+ }, >+ { >+ "status_string": "TIMEOUT", >+ "name": "test (synchronous)", >+ "message": "Test timed out", >+ "properties": {} >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/generate-callback.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/generate-callback.html >new file mode 100644 >index 0000000000000000000000000000000000000000..11d41743b3eaadcca3062ab937f0ff1e6cb4a1b7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/generate-callback.html >@@ -0,0 +1,153 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Sample for using generate_tests to create a series of tests that share the same callback.</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+</head> >+<body> >+<script> >+// generate_tests takes an array of arrays that define tests >+// but lets pass it an empty array and verify it does nothing. >+function null_callback() { >+ throw "null_callback should not be called."; >+} >+generate_tests(null_callback, []); >+ >+// Generate 3 tests specifying the name and one parameter >+function validate_arguments(arg1) { >+ assert_equals(arg1, 1, "Ensure that we get our expected argument"); >+} >+generate_tests(validate_arguments, [ >+ ["first test", 1], >+ ["second test", 1], >+ ["third test", 1], >+]); >+ >+// Generate a test passing in a properties object that is shared across tests. >+function validate_properties() { >+ assert_true(this.properties.sentinel, "Ensure that we got the right properties object."); >+} >+generate_tests(validate_properties, [["sentinel check 1"], ["sentinel check 2"]], {sentinel: true}); >+ >+// Generate a test passing in a properties object that is shared across tests. >+function validate_separate_properties() { >+ if (this.name === "sentinel check 1 unique properties") { >+ assert_true(this.properties.sentinel, "Ensure that we got the right properties object. Expect sentinel: true."); >+ } >+ else { >+ assert_false(this.properties.sentinel, "Ensure that we got the right properties object. Expect sentinel: false."); >+ } >+} >+generate_tests(validate_separate_properties, [["sentinel check 1 unique properties"], ["sentinel check 2 unique properties"]], [{sentinel: true}, {sentinel: false}]); >+ >+// Finally generate a complicated set of tests from another data source >+var letters = ["a", "b", "c", "d", "e", "f"]; >+var numbers = [0, 1, 2, 3, 4, 5]; >+function validate_related_arguments(arg1, arg2) { >+ assert_equals(arg1.charCodeAt(0) - "a".charCodeAt(0), arg2, "Ensure that we can map letters to numbers."); >+} >+function format_as_test(letter, index, letters) { >+ return ["Test to map " + letter + " to " + numbers[index], letter, numbers[index]]; >+} >+generate_tests(validate_related_arguments, letters.map(format_as_test)); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "OK", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "Test to map a to 0", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Test to map b to 1", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Test to map c to 2", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Test to map d to 3", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Test to map e to 4", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Test to map f to 5", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "first test", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "second test", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "sentinel check 1", >+ "properties": { >+ "sentinel": true >+ }, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "sentinel check 1 unique properties", >+ "properties": { >+ "sentinel": true >+ }, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "sentinel check 2", >+ "properties": { >+ "sentinel": true >+ }, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "sentinel check 2 unique properties", >+ "properties": { >+ "sentinel": false >+ }, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "third test", >+ "properties": {}, >+ "message": null >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/test_immutable_prototype.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/test_immutable_prototype.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ed578bce0a0dcfb8592def33bd35087bf00c8c13 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/test_immutable_prototype.html >@@ -0,0 +1,294 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+ <meta charset="utf-8"> >+ <title>idlharness: Immutable prototypes</title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/resources/WebIDLParser.js"></script> >+ <script src="/resources/idlharness.js"></script> >+</head> >+<body> >+<script> >+"use strictt"; >+ >+Object.defineProperty(window, "Foo", { >+ enumerable: false, >+ writable: true, >+ configurable: true, >+ value: function Foo() {} >+ }); >+Object.defineProperty(window.Foo, "prototype", { >+ writable: false, >+ value: window.Foo.prototype >+ }); >+Foo.prototype[Symbol.toStringTag] = "Foo"; >+ >+var idlArray = new IdlArray(); >+idlArray.add_untested_idls("interface EventTarget {};"); >+idlArray.add_idls( >+ "[Global=Window, Exposed=Window]\n" + >+ "interface Window : EventTarget {};\n" + >+ >+ "[Global=Window, Exposed=Window, Constructor()]\n" + >+ "interface Foo {};" >+ ); >+idlArray.add_objects({ >+ Foo: ["new Foo()"], >+ Window: ["window"] >+}); >+idlArray.test(); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "message": null, >+ "status_string": "OK" >+ }, >+ "summarized_tests": [ >+ { >+ "name": "Foo interface object length", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Foo interface object name", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Foo interface: existence and properties of interface object", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Foo interface: existence and properties of interface prototype object", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Foo interface: existence and properties of interface prototype object's \"constructor\" property", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Foo interface: existence and properties of interface prototype object's @@unscopables property", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Foo interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Object.setPrototypeOf should throw a TypeError", >+ "status_string": "FAIL", >+ "properties": {}, >+ "message": "assert_throws: function \"function() {\n Object.setPrototypeOf(obj, newValue);\n }\" did not throw" >+ }, >+ { >+ "name": "Foo interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Reflect.setPrototypeOf should return false", >+ "status_string": "FAIL", >+ "properties": {}, >+ "message": "assert_false: expected false got true" >+ }, >+ { >+ "name": "Foo interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via __proto__ should throw a TypeError", >+ "status_string": "FAIL", >+ "properties": {}, >+ "message": "assert_throws: function \"function() {\n obj.__proto__ = newValue;\n }\" did not throw" >+ }, >+ { >+ "name": "Foo interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Object.setPrototypeOf should not throw", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Foo interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Reflect.setPrototypeOf should return true", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Foo interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via __proto__ should not throw", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Foo interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Object.setPrototypeOf should throw a TypeError", >+ "status_string": "FAIL", >+ "properties": {}, >+ "message": "assert_throws: function \"function() {\n Object.setPrototypeOf(obj, newValue);\n }\" did not throw" >+ }, >+ { >+ "name": "Foo interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Reflect.setPrototypeOf should return false", >+ "status_string": "FAIL", >+ "properties": {}, >+ "message": "assert_false: expected false got true" >+ }, >+ { >+ "name": "Foo interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via __proto__ should throw a TypeError", >+ "status_string": "FAIL", >+ "properties": {}, >+ "message": "assert_throws: function \"function() {\n obj.__proto__ = newValue;\n }\" did not throw" >+ }, >+ { >+ "name": "Foo interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Object.setPrototypeOf should not throw", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Foo interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Reflect.setPrototypeOf should return true", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Foo interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via __proto__ should not throw", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Foo must be primary interface of new Foo()", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Stringification of new Foo()", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Stringification of window", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window interface object length", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window interface object name", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window interface: existence and properties of interface object", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window interface: existence and properties of interface prototype object", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window interface: existence and properties of interface prototype object's \"constructor\" property", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window interface: existence and properties of interface prototype object's @@unscopables property", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Object.setPrototypeOf should throw a TypeError", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Reflect.setPrototypeOf should return false", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via __proto__ should throw a TypeError", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Object.setPrototypeOf should not throw", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Reflect.setPrototypeOf should return true", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via __proto__ should not throw", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Object.setPrototypeOf should throw a TypeError", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Reflect.setPrototypeOf should return false", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via __proto__ should throw a TypeError", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Object.setPrototypeOf should not throw", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Reflect.setPrototypeOf should return true", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via __proto__ should not throw", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Window must be primary interface of window", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/test_primary_interface_of.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/test_primary_interface_of.html >new file mode 100644 >index 0000000000000000000000000000000000000000..69542f1d7d70fbb54f24393f4a91182c01e7ba7d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/test_primary_interface_of.html >@@ -0,0 +1,109 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+ <meta charset="utf-8"> >+ <title>idlharness: Primary interface</title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/resources/WebIDLParser.js"></script> >+ <script src="/resources/idlharness.js"></script> >+</head> >+<body> >+<p>Verify the series of sub-tests that are executed for "tested" interface >+objects but skipped for "untested" interface objects.</p> >+<script> >+"use strict"; >+ >+function FooParent() {} >+Object.defineProperty(window, "Foo", { >+ enumerable: false, >+ writable: true, >+ configurable: true, >+ value: function Foo() {} >+ }); >+Object.defineProperty(window.Foo, "prototype", { >+ writable: false, >+ value: new FooParent() >+ }); >+Object.defineProperty(window.Foo.prototype, "constructor", { >+ enumerable: false, >+ writable: true, >+ configurable: true, >+ value: window.Foo >+ }); >+Foo.__proto__ = FooParent; >+Foo.prototype[Symbol.toStringTag] = "Foo"; >+ >+var idlArray = new IdlArray(); >+idlArray.add_untested_idls("interface FooParent {};"); >+idlArray.add_idls( >+ "[Constructor()]\n" + >+ "interface Foo : FooParent {};" >+ ); >+idlArray.add_objects({ >+ Foo: ["new Foo()"], >+ FooParent: ["new FooParent()"] >+}); >+idlArray.test(); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "OK", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "name": "Foo interface object length", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Foo interface object name", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Foo interface: existence and properties of interface object", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Foo interface: existence and properties of interface prototype object", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Foo interface: existence and properties of interface prototype object's \"constructor\" property", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Foo interface: existence and properties of interface prototype object's @@unscopables property", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Foo must be primary interface of new Foo()", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "name": "Stringification of new Foo()", >+ "status_string": "PASS", >+ "properties": {}, >+ "message": null >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/test_to_json_operation.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/test_to_json_operation.html >new file mode 100644 >index 0000000000000000000000000000000000000000..5c60465bacbe7439e9566ddabddf088eb4cf5d6a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/test_to_json_operation.html >@@ -0,0 +1,177 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+ <meta charset="utf-8"> >+ <title>IdlInterface.prototype.test_to_json_operation()</title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/resources/WebIDLParser.js"></script> >+ <script src="/resources/idlharness.js"></script> >+ <script src="../../../../idl-helper.js"></script> >+</head> >+<body> >+<script> >+ "use strict"; >+ function wrap(member, obj) { >+ function F(obj) { >+ this._obj = obj; >+ } >+ >+ F.prototype.toJSON = function() { >+ return this._obj; >+ } >+ Object.defineProperty(F, 'name', { value: member.name }); >+ return new F(obj); >+ } >+ >+ var i, obj; >+ i = interfaceFrom("interface A { [Default] object toJSON(); attribute long foo; };"); >+ i.test_to_json_operation(wrap(i, { foo: 123 }), i.members[0]); >+ >+ // should fail (wrong type) >+ i = interfaceFrom("interface B { [Default] object toJSON(); attribute long foo; };"); >+ i.test_to_json_operation(wrap(i, { foo: "a value" }), i.members[0]); >+ >+ // should handle extraneous attributes (e.g. from an extension specification) >+ i = interfaceFrom("interface C { [Default] object toJSON(); attribute long foo; };"); >+ i.test_to_json_operation(wrap(i, { foo: 123, bar: 456 }), i.members[0]); >+ >+ // should fail (missing property) >+ i = interfaceFrom("interface D { [Default] object toJSON(); attribute long foo; };"); >+ i.test_to_json_operation(wrap(i, { }), i.members[0]); >+ >+ // should fail (should be writable) >+ obj = Object.defineProperties({}, { foo: { >+ writable: false, >+ enumerable: true, >+ configurable: true, >+ value: 123 >+ }}); >+ i = interfaceFrom("interface F { [Default] object toJSON(); attribute long foo; };"); >+ i.test_to_json_operation(wrap(i, obj), i.members[0]); >+ >+ // should fail (should be enumerable) >+ obj = Object.defineProperties({}, { foo: { >+ writable: true, >+ enumerable: false, >+ configurable: true, >+ value: 123 >+ }}); >+ i = interfaceFrom("interface G { [Default] object toJSON(); attribute long foo; };"); >+ i.test_to_json_operation(wrap(i, obj), i.members[0]); >+ >+ // should fail (should be configurable) >+ obj = Object.defineProperties({}, { foo: { >+ writable: true, >+ enumerable: true, >+ configurable: false, >+ value: 123 >+ }}); >+ i = interfaceFrom("interface H { [Default] object toJSON(); attribute long foo; };"); >+ i.test_to_json_operation(wrap(i, obj), i.members[0]); >+ >+ var idl = new IdlArray(); >+ idl.add_idls("interface I : J { [Default] object toJSON(); attribute long foo; };"); >+ idl.add_idls("interface J { [Default] object toJSON(); attribute DOMString foo;};"); >+ var i = idl.members.I; >+ i.test_to_json_operation(wrap(i, { foo: 123 }), i.members[0]); >+ >+ i = interfaceFrom("interface K { [Default] object toJSON(); };"); >+ i.test_to_json_operation(wrap(i, {}), i.members[0]); >+ >+ i = interfaceFrom("interface L { DOMString toJSON(); };"); >+ i.test_to_json_operation(wrap(i, "a string"), i.members[0]); >+ >+ // should fail (wrong output type) >+ i = interfaceFrom("interface M { DOMString toJSON(); };"); >+ i.test_to_json_operation(wrap(i, {}), i.members[0]); >+ >+ // should fail (not an IDL type) >+ i = interfaceFrom("interface N { DOMException toJSON(); };"); >+ i.test_to_json_operation(wrap(i, {}), i.members[0]); >+</script> >+<script type="text/json" id="expected"> >+ { >+ "summarized_status": { >+ "message": null, >+ "status_string": "OK" >+ }, >+ "summarized_tests": [ >+ { >+ "message": null, >+ "name": "Test default toJSON operation of A", >+ "properties": {}, >+ "status_string": "PASS" >+ }, >+ { >+ "message": "assert_equals: expected \"number\" but got \"string\"", >+ "name": "Test default toJSON operation of B", >+ "properties": {}, >+ "status_string": "FAIL" >+ }, >+ { >+ "message": null, >+ "name": "Test default toJSON operation of C", >+ "properties": {}, >+ "status_string": "PASS" >+ }, >+ { >+ "message": "assert_true: property \"foo\" should be present in the output of D.prototype.toJSON() expected true got false", >+ "name": "Test default toJSON operation of D", >+ "properties": {}, >+ "status_string": "FAIL" >+ }, >+ { >+ "message": "assert_true: property foo should be writable expected true got false", >+ "name": "Test default toJSON operation of F", >+ "properties": {}, >+ "status_string": "FAIL" >+ }, >+ { >+ "message": "assert_true: property foo should be enumerable expected true got false", >+ "name": "Test default toJSON operation of G", >+ "properties": {}, >+ "status_string": "FAIL" >+ }, >+ { >+ "message": "assert_true: property foo should be configurable expected true got false", >+ "name": "Test default toJSON operation of H", >+ "properties": {}, >+ "status_string": "FAIL" >+ }, >+ { >+ "message": null, >+ "name": "Test default toJSON operation of I", >+ "properties": {}, >+ "status_string": "PASS" >+ }, >+ { >+ "message": null, >+ "name": "Test default toJSON operation of K", >+ "properties": {}, >+ "status_string": "PASS" >+ }, >+ { >+ "message": null, >+ "name": "Test toJSON operation of L", >+ "properties": {}, >+ "status_string": "PASS" >+ }, >+ { >+ "message": "assert_equals: expected \"string\" but got \"object\"", >+ "name": "Test toJSON operation of M", >+ "properties": {}, >+ "status_string": "FAIL" >+ }, >+ { >+ "message": "assert_true: {\"type\":\"return-type\",\"sequence\":false,\"generic\":null,\"nullable\":false,\"union\":false,\"idlType\":\"DOMException\"} is not an appropriate return value for the toJSON operation of N expected true got false", >+ "name": "Test toJSON operation of N", >+ "properties": {}, >+ "status_string": "FAIL" >+ } >+ ], >+ "type": "complete" >+ } >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..53a616c63bd0e3f50357f94fe587337d7a9ab4c3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/w3c-import.log >@@ -0,0 +1,19 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/test_immutable_prototype.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/test_primary_interface_of.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/idlharness/IdlInterface/test_to_json_operation.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/iframe-callback.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/iframe-callback.html >new file mode 100644 >index 0000000000000000000000000000000000000000..f49d0aa6b80748d893c5cf40753b2f0a1cd2bac4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/iframe-callback.html >@@ -0,0 +1,116 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Example with iframe that notifies containing document via callbacks</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+</head> >+<body onload="start_test_in_iframe()"> >+<h1>Callbacks From Tests Running In An IFRAME</h1> >+<p>A test is run inside an <tt>iframe</tt> with a same origin document. The >+containing document should receive callbacks as the tests progress inside the >+<tt>iframe</tt>. A single passing test is expected in the summary below. >+<div id="log"></div> >+ >+<script> >+var callbacks = []; >+var START = 1 >+var TEST_STATE = 2 >+var RESULT = 3 >+var COMPLETION = 4 >+var test_complete = false; >+ >+setup({explicit_done: true}); >+ >+// The following callbacks are called for tests in this document as well as the >+// tests in the IFRAME. Currently, callbacks invoked from this document and any >+// child document are indistinguishable from each other. >+ >+function start_callback(properties) { >+ callbacks.push(START); >+} >+ >+function test_state_callback(test) { >+ callbacks.push(TEST_STATE); >+} >+ >+function result_callback(test) { >+ callbacks.push(RESULT); >+} >+ >+function completion_callback(tests, status) { >+ if (test_complete) { >+ return; >+ } >+ test_complete = true; >+ callbacks.push(COMPLETION); >+ verify_received_callbacks(); >+ done(); >+} >+ >+function verify_received_callbacks() { >+ var copy_of_callbacks = callbacks.slice(0); >+ >+ // Note that you can't run test assertions directly in a callback even if >+ // this is a file test. When the callback is invoked from a same-origin child >+ // page, the callstack reaches into the calling child document. Any >+ // exception thrown in a callback will be handled by the child rather than >+ // this document. >+ test( >+ function() { >+ // callbacks list should look like: >+ // START 1*(TEST_STATE) RESULT COMPLETION >+ assert_equals(copy_of_callbacks.shift(), START, >+ "The first received callback should be 'start_callback'."); >+ assert_equals(copy_of_callbacks.shift(), TEST_STATE, >+ "'test_state_callback' should be received before any " + >+ "result or completion callbacks."); >+ while(copy_of_callbacks.length > 0) { >+ var callback = copy_of_callbacks.shift(); >+ if (callback != TEST_STATE) { >+ copy_of_callbacks.unshift(callback); >+ break; >+ } >+ } >+ assert_equals(copy_of_callbacks.shift(), RESULT, >+ "'test_state_callback' should be followed by 'result_callback'."); >+ assert_equals(copy_of_callbacks.shift(), COMPLETION, >+ "Final 'result_callback' should be followed by 'completion_callback'."); >+ assert_equals(copy_of_callbacks.length, 0, >+ "'completion_callback' should be the last callback."); >+ }); >+} >+ >+function start_test_in_iframe() { >+ // This document is going to clear any received callbacks and maintain >+ // radio silence until the test in the iframe runs to completion. The >+ // completion_callback() will then complete the testing on this document. >+ callbacks.length = 0; >+ var iframe = document.createElement("iframe"); >+ // single-page-test-pass.html has a single test. >+ iframe.src = "single-page-test-pass.html"; >+ iframe.style.setProperty("display", "none"); >+ document.getElementById("target").appendChild(iframe); >+} >+</script> >+ >+<div id="target"> >+</div> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "OK", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "Example with iframe that notifies containing document via callbacks", >+ "properties": {}, >+ "message": null >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/iframe-consolidate-errors.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/iframe-consolidate-errors.html >new file mode 100644 >index 0000000000000000000000000000000000000000..67655fd64e7af73f3ac706673224949754e5df03 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/iframe-consolidate-errors.html >@@ -0,0 +1,44 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Example with iframe that consolidates errors via fetch_tests_from_window</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+var parent_test = async_test("Test executing in parent context"); >+</script> >+</head> >+<body onload="parent_test.done()"> >+<h1>Fetching Tests From a Child Context</h1> >+<p>This test demonstrates the use of <tt>fetch_tests_from_window</tt> to pull >+tests from an <tt>iframe</tt> into the primary document.</p> >+<p>The test suite is expected to fail due to an unhandled exception in the >+child context.</p> >+<div id="log"></div> >+ >+<iframe id="childContext" src="uncaught-exception-handle.html" style="display:none"></iframe> >+<!-- apisample4.html is a failing suite due to an unhandled Error. --> >+ >+<script> >+ var childContext = document.getElementById("childContext"); >+ fetch_tests_from_window(childContext.contentWindow); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "ERROR", >+ "message": "Error in remote: Error: Example Error" >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "Test executing in parent context", >+ "properties": {}, >+ "message": null >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/iframe-consolidate-tests.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/iframe-consolidate-tests.html >new file mode 100644 >index 0000000000000000000000000000000000000000..0fa1f20797d8e8c5f1d6d7b25c1cef3a69c520c3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/iframe-consolidate-tests.html >@@ -0,0 +1,86 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Example with iframe that consolidates tests via fetch_tests_from_window</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+var parent_test = async_test("Test executing in parent context"); >+</script> >+</head> >+<body onload="parent_test.done()"> >+<h1>Fetching Tests From a Child Context</h1> >+<p>This test demonstrates the use of <tt>fetch_tests_from_window</tt> to pull >+tests from an <tt>iframe</tt> into the primary document.</p> >+<p>The test suite will not complete until tests in the child context have finished >+executing</p> >+<div id="log"></div> >+ >+<iframe id="childContext" src="promise-async.html" style="display:none"></iframe> >+<!-- promise-async.html has async tests with promises --> >+ >+<script> >+ var childContext = document.getElementById("childContext"); >+ fetch_tests_from_window(childContext.contentWindow); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "OK", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "Promise rejection", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Promise resolution", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "Promises and test assertion failures (should fail)", >+ "properties": {}, >+ "message": "assert_true: This failure is expected expected true got false" >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Promises are supported in your browser", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Promises resolution chaining", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Test executing in parent context", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Use of step_func with Promises", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "Use of unreached_func with Promises (should fail)", >+ "properties": {}, >+ "message": "assert_unreached: This failure is expected Reached unreachable code" >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/iframe-msg.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/iframe-msg.html >new file mode 100644 >index 0000000000000000000000000000000000000000..283a5d98cc339011c3dd1b65111ef7bfdba5a997 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/iframe-msg.html >@@ -0,0 +1,84 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Example with iframe that notifies containing document via cross document messaging</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+</head> >+<body> >+<h1>Notifications From Tests Running In An IFRAME</h1> >+<p>A test is run inside an <tt>iframe</tt> with a same origin document. The >+containing document should receive messages via <tt>postMessage</tt>/ >+<tt>onmessage</tt> as the tests progress inside the <tt>iframe</tt>. A single >+passing test is expected in the summary below. >+</p> >+<div id="log"></div> >+ >+<script> >+var t = async_test("Containing document receives messages"); >+var start_received = false; >+var result_received = false; >+var completion_received = false; >+ >+// These are the messages that are expected to be seen while running the tests >+// in the IFRAME. >+var expected_messages = [ >+ t.step_func( >+ function(message) { >+ assert_equals(message.data.type, "start"); >+ assert_own_property(message.data, "properties"); >+ }), >+ >+ t.step_func( >+ function(message) { >+ assert_equals(message.data.type, "test_state"); >+ assert_equals(message.data.test.status, message.data.test.NOTRUN); >+ }), >+ >+ t.step_func( >+ function(message) { >+ assert_equals(message.data.type, "result"); >+ assert_equals(message.data.test.status, message.data.test.PASS); >+ }), >+ >+ t.step_func( >+ function(message) { >+ assert_equals(message.data.type, "complete"); >+ assert_equals(message.data.tests.length, 1); >+ assert_equals(message.data.tests[0].status, >+ message.data.tests[0].PASS); >+ assert_equals(message.data.status.status, message.data.status.OK); >+ t.done(); >+ }), >+ >+ t.unreached_func("Too many messages received") >+]; >+ >+on_event(window, >+ "message", >+ function(message) { >+ var handler = expected_messages.shift(); >+ handler(message); >+ }); >+</script> >+<iframe src="single-page-test-pass.html" style="display:none"> >+ <!-- single-page-test-pass.html implements a file_is_test test. --> >+</iframe> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "OK", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "Containing document receives messages", >+ "properties": {}, >+ "message": null >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/order.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/order.html >new file mode 100644 >index 0000000000000000000000000000000000000000..686383861a0a856706863f7a4880f8478902e5ac >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/order.html >@@ -0,0 +1,36 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Ordering</title> >+<meta name="timeout" content="6000"> >+</head> >+<body> >+<div id="log"></div> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+test(function() {}, 'second'); >+test(function() {}, 'first'); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "OK", >+ "message": null >+ }, >+ "summarized_tests": [{ >+ "status_string": "PASS", >+ "name": "first", >+ "message": null, >+ "properties": {} >+ }, { >+ "status_string": "PASS", >+ "name": "second", >+ "message": null, >+ "properties": {} >+ }], >+ "type": "complete" >+} >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/promise-async.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/promise-async.html >new file mode 100644 >index 0000000000000000000000000000000000000000..fa82665cf00702aabf2a2f9812ea8794142ede6c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/promise-async.html >@@ -0,0 +1,172 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Async Tests and Promises</title> >+</head> >+<body> >+<h1>Async Tests and Promises</h1> >+<p>This test assumes ECMAScript 6 Promise support. Some failures are expected.</p> >+<div id="log"></div> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+ >+test(function() { >+ var p = new Promise(function(resolve, reject) {}); >+ assert_true('then' in p); >+ assert_equals(typeof Promise.resolve, 'function'); >+ assert_equals(typeof Promise.reject, 'function'); >+}, "Promises are supported in your browser"); >+ >+(function() { >+ var t = async_test("Promise resolution"); >+ t.step(function() { >+ Promise.resolve('x').then( >+ t.step_func(function(value) { >+ assert_equals(value, 'x'); >+ t.done(); >+ }), >+ t.unreached_func('Promise should not reject') >+ ); >+ }); >+}()); >+ >+(function() { >+ var t = async_test("Promise rejection"); >+ t.step(function() { >+ Promise.reject(Error('fail')).then( >+ t.unreached_func('Promise should reject'), >+ t.step_func(function(reason) { >+ assert_true(reason instanceof Error); >+ assert_equals(reason.message, 'fail'); >+ t.done(); >+ }) >+ ); >+ }); >+}()); >+ >+(function() { >+ var t = async_test("Promises resolution chaining"); >+ t.step(function() { >+ var resolutions = []; >+ Promise.resolve('a').then( >+ t.step_func(function(value) { >+ resolutions.push(value); >+ return 'b'; >+ }) >+ ).then( >+ t.step_func(function(value) { >+ resolutions.push(value); >+ return 'c'; >+ }) >+ ).then( >+ t.step_func(function(value) { >+ resolutions.push(value); >+ >+ assert_array_equals(resolutions, ['a', 'b', 'c']); >+ t.done(); >+ }) >+ ).catch( >+ t.unreached_func('promise should not have rejected') >+ ); >+ }); >+}()); >+ >+(function() { >+ var t = async_test("Use of step_func with Promises"); >+ t.step(function() { >+ var resolutions = []; >+ Promise.resolve('x').then( >+ t.step_func_done(), >+ t.unreached_func('Promise should not have rejected') >+ ); >+ }); >+}()); >+ >+(function() { >+ var t = async_test("Promises and test assertion failures (should fail)"); >+ t.step(function() { >+ var resolutions = []; >+ Promise.resolve('x').then( >+ t.step_func(function(value) { >+ assert_true(false, 'This failure is expected'); >+ }) >+ ).then( >+ t.unreached_func('Promise should not have resolved') >+ ).catch( >+ t.unreached_func('Promise should not have rejected') >+ ); >+ }); >+}()); >+ >+(function() { >+ var t = async_test("Use of unreached_func with Promises (should fail)"); >+ t.step(function() { >+ var resolutions = []; >+ var r; >+ var p = new Promise(function(resolve, reject) { >+ // Reject instead of resolve, to demonstrate failure. >+ reject(123); >+ }); >+ p.then( >+ function(value) { >+ assert_equals(value, 123, 'This should not actually happen'); >+ }, >+ t.unreached_func('This failure is expected') >+ ); >+ }); >+}()); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "OK", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "Promise rejection", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Promise resolution", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "Promises and test assertion failures (should fail)", >+ "properties": {}, >+ "message": "assert_true: This failure is expected expected true got false" >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Promises are supported in your browser", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Promises resolution chaining", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Use of step_func with Promises", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "Use of unreached_func with Promises (should fail)", >+ "properties": {}, >+ "message": "assert_unreached: This failure is expected Reached unreachable code" >+ } >+ ], >+ "type": "complete" >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/promise.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/promise.html >new file mode 100644 >index 0000000000000000000000000000000000000000..bbda0112a6a5465babd6fbd2e202fe9ba11b6828 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/promise.html >@@ -0,0 +1,209 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Promise Tests</title> >+</head> >+<body> >+<h1>Promise Tests</h1> >+<p>This test demonstrates the use of <tt>promise_test</tt>. Assumes ECMAScript 6 >+Promise support. Some failures are expected.</p> >+<div id="log"></div> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+test( >+ function() { >+ var p = new Promise(function(resolve, reject){}); >+ assert_true("then" in p); >+ assert_equals(typeof Promise.resolve, "function"); >+ assert_equals(typeof Promise.reject, "function"); >+ }, >+ "Promises are supported in your browser"); >+ >+promise_test( >+ function() { >+ return Promise.resolve("x") >+ .then( >+ function(value) { >+ assert_equals(value, >+ "x", >+ "Fulfilled promise should pass result to " + >+ "fulfill reaction."); >+ }); >+ }, >+ "Promise fulfillment with result"); >+ >+promise_test( >+ function(t) { >+ return Promise.reject(new Error("fail")) >+ .then(t.unreached_func("Promise should reject"), >+ function(reason) { >+ assert_true( >+ reason instanceof Error, >+ "Rejected promise should pass reason to fulfill reaction."); >+ assert_equals( >+ reason.message, >+ "fail", >+ "Rejected promise should pass reason to reject reaction."); >+ }); >+ }, >+ "Promise rejection with result"); >+ >+promise_test( >+ function() { >+ var resolutions = []; >+ return Promise.resolve("a") >+ .then( >+ function(value) { >+ resolutions.push(value); >+ return "b"; >+ }) >+ .then( >+ function(value) { >+ resolutions.push(value); >+ return "c"; >+ }) >+ .then( >+ function(value) { >+ resolutions.push(value); >+ assert_array_equals(resolutions, ["a", "b", "c"]); >+ }); >+ }, >+ "Chain of promise resolutions"); >+ >+promise_test( >+ function(t) { >+ var resolutions = []; >+ return Promise.resolve("x") >+ .then( >+ function(value) { >+ assert_true(false, "Expected failure."); >+ }) >+ .then(t.unreached_func("UNEXPECTED FAILURE: Promise should not have resolved.")); >+ }, >+ "Assertion failure in a fulfill reaction (should FAIL with an expected failure)"); >+ >+promise_test( >+ function(t) { >+ return new Promise( >+ function(resolve, reject) { >+ reject(123); >+ }) >+ .then(t.unreached_func("UNEXPECTED FAILURE: Fulfill reaction reached after rejection."), >+ t.unreached_func("Expected failure.")); >+ }, >+ "unreached_func as reactor (should FAIL with an expected failure)"); >+ >+promise_test( >+ function() { >+ return true; >+ }, >+ "promise_test with function that doesn't return a Promise"); >+ >+promise_test(function(){}, >+ "promise_test with function that doesn't return anything"); >+ >+promise_test( >+ function() { >+ return Promise.reject("Expected rejection"); >+ }, >+ "promise_test with unhandled rejection (should FAIL)"); >+ >+promise_test( >+ function() { >+ return Promise.resolve(10) >+ .then( >+ function(value) { >+ throw Error("Expected exception."); >+ }); >+ }, >+ "promise_test with unhandled exception in fulfill reaction (should FAIL)"); >+ >+promise_test( >+ function(t) { >+ return Promise.reject(10) >+ .then( >+ t.unreached_func("UNEXPECTED FAILURE: Fulfill reaction reached after rejection."), >+ function(value) { >+ throw Error("Expected exception."); >+ }); >+ }, >+ "promise_test with unhandled exception in reject reaction (should FAIL)"); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "OK", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "FAIL", >+ "name": "Assertion failure in a fulfill reaction (should FAIL with an expected failure)", >+ "message": "assert_true: Expected failure. expected true got false", >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Chain of promise resolutions", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Promise fulfillment with result", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Promise rejection with result", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Promises are supported in your browser", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "PASS", >+ "name": "promise_test with function that doesn't return a Promise", >+ "message": null, >+ "properties": {} >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "promise_test with function that doesn't return anything", >+ "message": "assert_not_equals: got disallowed value undefined", >+ "properties": {} >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "promise_test with unhandled exception in fulfill reaction (should FAIL)", >+ "message": "promise_test: Unhandled rejection with value: object \"Error: Expected exception.\"", >+ "properties": {} >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "promise_test with unhandled exception in reject reaction (should FAIL)", >+ "message": "promise_test: Unhandled rejection with value: object \"Error: Expected exception.\"", >+ "properties": {} >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "promise_test with unhandled rejection (should FAIL)", >+ "message": "promise_test: Unhandled rejection with value: \"Expected rejection\"", >+ "properties": {} >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "unreached_func as reactor (should FAIL with an expected failure)", >+ "message": "assert_unreached: Expected failure. Reached unreachable code", >+ "properties": {} >+ } >+ ], >+ "type": "complete" >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/single-page-test-fail.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/single-page-test-fail.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ca90aab5adf9be9d9da4fc1fe0542ac7d04c3da7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/single-page-test-fail.html >@@ -0,0 +1,27 @@ >+<!DOCTYPE HTML> >+<title>Example with file_is_test (should fail)</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+onload = function() { >+ assert_true(false); >+ done(); >+} >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "OK", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "FAIL", >+ "name": "Example with file_is_test (should fail)", >+ "properties": {}, >+ "message": "uncaught exception: Error: assert_true: expected true got false" >+ } >+ ], >+ "type": "complete" >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/single-page-test-no-assertions.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/single-page-test-no-assertions.html >new file mode 100644 >index 0000000000000000000000000000000000000000..063a4ca514277f8bc055bd30558697bc028c3235 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/single-page-test-no-assertions.html >@@ -0,0 +1,24 @@ >+<!DOCTYPE HTML> >+<title>Example single page test with no asserts</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+done(); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "OK", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "Example single page test with no asserts", >+ "properties": {}, >+ "message": null >+ } >+ ], >+ "type": "complete" >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/single-page-test-no-body.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/single-page-test-no-body.html >new file mode 100644 >index 0000000000000000000000000000000000000000..41671b83d7c81e27a359a90a230a4c87af23f8d1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/single-page-test-no-body.html >@@ -0,0 +1,25 @@ >+<!DOCTYPE HTML> >+<title>Example single page test with no body</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+assert_true(true); >+done(); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "OK", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "Example single page test with no body", >+ "properties": {}, >+ "message": null >+ } >+ ], >+ "type": "complete" >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/single-page-test-pass.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/single-page-test-pass.html >new file mode 100644 >index 0000000000000000000000000000000000000000..1376e28b6b5bdc28c0b75b89a64b1b1df28f3d63 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/single-page-test-pass.html >@@ -0,0 +1,27 @@ >+<!DOCTYPE HTML> >+<title>Example with file_is_test</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+onload = function() { >+ assert_true(true); >+ done(); >+} >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "OK", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "Example with file_is_test", >+ "properties": {}, >+ "message": null >+ } >+ ], >+ "type": "complete" >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/uncaught-exception-handle.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/uncaught-exception-handle.html >new file mode 100644 >index 0000000000000000000000000000000000000000..764b0c4055bd83dbad2ab6a27a97d5df63587e98 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/uncaught-exception-handle.html >@@ -0,0 +1,33 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Harness Handling Uncaught Exception</title> >+</head> >+<script src="/resources/testharness.js"></script> >+ >+<body> >+<h1>Harness Handling Uncaught Exception</h1> >+<div id="log"></div> >+<script> >+var t = async_test("This should show a harness status of 'Error' and a test status of 'Not Run'"); >+throw new Error("Example Error"); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "ERROR", >+ "message": "Error: Example Error" >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "NOTRUN", >+ "name": "This should show a harness status of 'Error' and a test status of 'Not Run'", >+ "properties": {}, >+ "message": null >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/uncaught-exception-ignore.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/uncaught-exception-ignore.html >new file mode 100644 >index 0000000000000000000000000000000000000000..6bd0ddbb0d2690ede6345f276c099e955a6937e4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/uncaught-exception-ignore.html >@@ -0,0 +1,35 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Harness Ignoring Uncaught Exception</title> >+</head> >+<script src="/resources/testharness.js"></script> >+ >+<body> >+<h1>Harness Ignoring Uncaught Exception</h1> >+<div id="log"></div> >+<script> >+setup({allow_uncaught_exception:true}); >+var t = async_test("setup({allow_uncaught_exception:true}) should allow tests to pass even if there is an exception"); >+onerror = t.step_func(function() {t.done()}); >+throw new Error("Example Error"); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "OK", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "setup({allow_uncaught_exception:true}) should allow tests to pass even if there is an exception", >+ "properties": {}, >+ "message": null >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..551a4ddfe181022e0c8f67757eec90576cc57218 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/w3c-import.log >@@ -0,0 +1,43 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/add_cleanup.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/add_cleanup_count.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/add_cleanup_err.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/add_cleanup_err_multi.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/api-tests-1.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/api-tests-2.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/api-tests-3.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/force_timeout.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/generate-callback.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/iframe-callback.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/iframe-consolidate-errors.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/iframe-consolidate-tests.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/iframe-msg.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/order.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/promise-async.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/promise.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/single-page-test-fail.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/single-page-test-no-assertions.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/single-page-test-no-body.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/single-page-test-pass.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/uncaught-exception-handle.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/uncaught-exception-ignore.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker-dedicated.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker-error.js >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker-service.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker-shared.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker.js >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker-dedicated.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker-dedicated.html >new file mode 100644 >index 0000000000000000000000000000000000000000..dad467618906235316af2fb764629a4d60011773 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker-dedicated.html >@@ -0,0 +1,88 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Dedicated Worker Tests</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+</head> >+<body> >+<h1>Dedicated Web Worker Tests</h1> >+<p>Demonstrates running <tt>testharness</tt> based tests inside a dedicated web worker. >+<p>The test harness is expected to fail due to an uncaught exception in one worker.</p> >+<div id="log"></div> >+ >+<script> >+test(function(t) { >+ assert_true("Worker" in self, "Browser should support Workers"); >+ }, >+ "Browser supports Workers"); >+ >+fetch_tests_from_worker(new Worker("worker.js")); >+ >+fetch_tests_from_worker(new Worker("worker-error.js")); >+ >+test(function(t) { >+ assert_false(false, "False is false"); >+ }, >+ "Test running on main document."); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "ERROR", >+ "message": "Error: This failure is expected." >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "Browser supports Workers", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Test running on main document.", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "Untitled", >+ "properties": {}, >+ "message": "Error: This failure is expected." >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Worker async_test that completes successfully", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Worker test that completes successfully", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "NOTRUN", >+ "name": "Worker test that doesn't run ('NOT RUN')", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "Worker test that fails ('FAIL')", >+ "properties": {}, >+ "message": "assert_true: Failing test expected true got false" >+ }, >+ { >+ "status_string": "TIMEOUT", >+ "name": "Worker test that times out ('TIMEOUT')", >+ "properties": {}, >+ "message": "Test timed out" >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker-error.js b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker-error.js >new file mode 100644 >index 0000000000000000000000000000000000000000..8ef2d22d241698854c4964ad39df4b7fb0ffce16 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker-error.js >@@ -0,0 +1,3 @@ >+importScripts("/resources/testharness.js"); >+ >+throw new Error("This failure is expected."); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker-service.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker-service.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2e07746e62264d5f7a055d8ac9e297717f4471b4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker-service.html >@@ -0,0 +1,115 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Example with a service worker</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+</head> >+<body> >+<h1>Service Worker Tests</h1> >+<p>Demonstrates running <tt>testharness</tt> based tests inside a service worker. >+<p>The test harness should time out due to one of the tests inside the worker timing out. >+<p>This test assumes that the browser supports <a href="http://www.w3.org/TR/service-workers/">ServiceWorkers</a>. >+<div id="log"></div> >+ >+<script> >+test( >+ function(t) { >+ assert_true("serviceWorker" in navigator, >+ "navigator.serviceWorker exists"); >+ }, >+ "Browser supports ServiceWorker"); >+ >+promise_test( >+ function() { >+ // Since the service worker registration could be in an indeterminate >+ // state (due to, for example, a previous test run failing), we start by >+ // unregstering our service worker and then registering it again. >+ var scope = "service-worker-scope"; >+ var worker_url = "worker.js"; >+ >+ return navigator.serviceWorker.register(worker_url, {scope: scope}) >+ .then( >+ function(registration) { >+ return registration.unregister(); >+ }) >+ .then( >+ function() { >+ return navigator.serviceWorker.register(worker_url, {scope: scope}); >+ }) >+ .then( >+ function(registration) { >+ add_completion_callback( >+ function() { >+ registration.unregister(); >+ }); >+ >+ return new Promise( >+ function(resolve) { >+ registration.addEventListener("updatefound", >+ function() { >+ resolve(registration.installing); >+ }); >+ }); >+ }) >+ .then( >+ function(worker) { >+ fetch_tests_from_worker(worker); >+ }); >+ }, >+ "Register ServiceWorker"); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "TIMEOUT", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "Browser supports ServiceWorker", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Register ServiceWorker", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Worker async_test that completes successfully", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "PASS", >+ "name": "Worker test that completes successfully", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "NOTRUN", >+ "name": "Worker test that doesn't run ('NOT RUN')", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "status_string": "FAIL", >+ "name": "Worker test that fails ('FAIL')", >+ "properties": {}, >+ "message": "assert_true: Failing test expected true got false" >+ }, >+ { >+ "status_string": "TIMEOUT", >+ "name": "Worker test that times out ('TIMEOUT')", >+ "properties": {}, >+ "message": "Test timed out" >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker-shared.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker-shared.html >new file mode 100644 >index 0000000000000000000000000000000000000000..e26f17dec276642c43d6a6fd717a57b9debe1b93 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker-shared.html >@@ -0,0 +1,73 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>Example with a shared worker</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+</head> >+<body> >+<h1>Shared Web Worker Tests</h1> >+<p>Demonstrates running <tt>testharness</tt> based tests inside a shared worker. >+<p>The test harness should time out due to one of the tests in the worker timing out. >+<p>This test assumes that the browser supports <a href="http://www.w3.org/TR/workers/#shared-workers-and-the-sharedworker-interface">shared web workers</a>. >+<div id="log"></div> >+ >+<script> >+test( >+ function(t) { >+ assert_true("SharedWorker" in self, >+ "Browser should support SharedWorkers"); >+ }, >+ "Browser supports SharedWorkers"); >+ >+fetch_tests_from_worker(new SharedWorker("worker.js", >+ "My shared worker")); >+</script> >+<script type="text/json" id="expected"> >+{ >+ "summarized_status": { >+ "status_string": "TIMEOUT", >+ "message": null >+ }, >+ "summarized_tests": [ >+ { >+ "status_string": "PASS", >+ "name": "Browser supports SharedWorkers", >+ "properties": {}, >+ "message": null >+ }, >+ { >+ "message": null, >+ "name": "Worker async_test that completes successfully", >+ "properties": {}, >+ "status_string": "PASS" >+ }, >+ { >+ "message": null, >+ "name": "Worker test that completes successfully", >+ "properties": {}, >+ "status_string": "PASS" >+ }, >+ { >+ "message": null, >+ "name": "Worker test that doesn't run ('NOT RUN')", >+ "properties": {}, >+ "status_string": "NOTRUN" >+ }, >+ { >+ "message": "assert_true: Failing test expected true got false", >+ "name": "Worker test that fails ('FAIL')", >+ "properties": {}, >+ "status_string": "FAIL" >+ }, >+ { >+ "message": "Test timed out", >+ "name": "Worker test that times out ('TIMEOUT')", >+ "properties": {}, >+ "status_string": "TIMEOUT" >+ } >+ ], >+ "type": "complete" >+} >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker.js b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..a923bc2d89ecff136c1b5b5b7a2489b4ee24d688 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/functional/worker.js >@@ -0,0 +1,34 @@ >+importScripts("/resources/testharness.js"); >+ >+test( >+ function(test) { >+ assert_true(true, "True is true"); >+ }, >+ "Worker test that completes successfully"); >+ >+test( >+ function(test) { >+ assert_true(false, "Failing test"); >+ }, >+ "Worker test that fails ('FAIL')"); >+ >+async_test( >+ function(test) { >+ assert_true(true, "True is true"); >+ }, >+ "Worker test that times out ('TIMEOUT')"); >+ >+async_test("Worker test that doesn't run ('NOT RUN')"); >+ >+async_test( >+ function(test) { >+ self.setTimeout( >+ function() { >+ test.done(); >+ }, >+ 0); >+ }, >+ "Worker async_test that completes successfully"); >+ >+// An explicit done() is required for dedicated and shared web workers. >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlArray/is_json_type.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlArray/is_json_type.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d31d9173de2eda35551c54b1aab05d2cf3db5edc >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlArray/is_json_type.html >@@ -0,0 +1,194 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>IdlArray.prototype.is_json_type()</title> >+</head> >+<body> >+<div id="log"></div> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/resources/WebIDLParser.js"></script> >+<script src="/resources/idlharness.js"></script> >+<script src="../../../idl-helper.js"></script> >+<script> >+ "use strict"; >+ >+ test(function() { >+ var idl = new IdlArray(); >+ assert_true(idl.is_json_type(typeFrom("DOMString"))); >+ assert_true(idl.is_json_type(typeFrom("ByteString"))); >+ assert_true(idl.is_json_type(typeFrom("USVString"))); >+ idl.add_untested_idls('enum BarEnum { "a", "b", "c" };'); >+ assert_true(idl.is_json_type(typeFrom("BarEnum"))); >+ }, 'should return true for all string types'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ assert_false(idl.is_json_type(typeFrom("Error"))); >+ assert_false(idl.is_json_type(typeFrom("DOMException"))); >+ }, 'should return false for all exception types'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ assert_false(idl.is_json_type(typeFrom("Int8Array"))); >+ assert_false(idl.is_json_type(typeFrom("Int16Array"))); >+ assert_false(idl.is_json_type(typeFrom("Int32Array"))); >+ assert_false(idl.is_json_type(typeFrom("Uint8Array"))); >+ assert_false(idl.is_json_type(typeFrom("Uint16Array"))); >+ assert_false(idl.is_json_type(typeFrom("Uint32Array"))); >+ assert_false(idl.is_json_type(typeFrom("Uint8ClampedArray"))); >+ assert_false(idl.is_json_type(typeFrom("Float32Array"))); >+ assert_false(idl.is_json_type(typeFrom("ArrayBuffer"))); >+ assert_false(idl.is_json_type(typeFrom("DataView"))); >+ }, 'should return false for all buffer source types'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ assert_true(idl.is_json_type(typeFrom("boolean"))); >+ }, 'should return true for boolean'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ assert_true(idl.is_json_type(typeFrom("byte"))); >+ assert_true(idl.is_json_type(typeFrom("octet"))); >+ assert_true(idl.is_json_type(typeFrom("short"))); >+ assert_true(idl.is_json_type(typeFrom("unsigned short"))); >+ assert_true(idl.is_json_type(typeFrom("long"))); >+ assert_true(idl.is_json_type(typeFrom("unsigned long"))); >+ assert_true(idl.is_json_type(typeFrom("long long"))); >+ assert_true(idl.is_json_type(typeFrom("unsigned long long"))); >+ assert_true(idl.is_json_type(typeFrom("float"))); >+ assert_true(idl.is_json_type(typeFrom("unrestricted float"))); >+ assert_true(idl.is_json_type(typeFrom("double"))); >+ assert_true(idl.is_json_type(typeFrom("unrestricted double"))); >+ }, 'should return true for all numeric types'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ assert_false(idl.is_json_type(typeFrom("Promise<DOMString>"))); >+ }, 'should return false for promises'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ assert_false(idl.is_json_type(typeFrom("sequence<DOMException>"))); >+ assert_true(idl.is_json_type(typeFrom("sequence<DOMString>"))); >+ }, 'should handle sequences according to their inner types'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ assert_false(idl.is_json_type(typeFrom("FrozenArray<DOMException>"))); >+ assert_true(idl.is_json_type(typeFrom("FrozenArray<DOMString>"))); >+ }, 'should handle frozen arrays according to their inner types'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ assert_true(idl.is_json_type(typeFrom("record<DOMString, DOMString>"))); >+ assert_false(idl.is_json_type(typeFrom("record<DOMString, Error>"))); >+ }, 'should handle records according to their inner types'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ assert_true(idl.is_json_type(typeFrom("object"))); >+ }, 'should return true for object type'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ assert_false(idl.is_json_type(typeFrom("any"))); >+ }, 'should return false for any type'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ idl.add_untested_idls('dictionary Foo { DOMString foo; }; dictionary Bar : Foo { DOMString bar; };'); >+ assert_true(idl.is_json_type(typeFrom("Foo"))); >+ assert_true(idl.is_json_type(typeFrom("Bar"))); >+ }, 'should return true for dictionaries whose members are all JSON types'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ idl.add_untested_idls('dictionary Foo { };'); >+ assert_true(idl.is_json_type(typeFrom("Foo"))); >+ }, 'should return true for dictionaries which have no members'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ idl.add_untested_idls('dictionary FooBar { DOMString a; Error b; }; dictionary Baz : FooBar {};'); >+ assert_false(idl.is_json_type(typeFrom("FooBar"))); >+ assert_false(idl.is_json_type(typeFrom("Baz"))); >+ }, 'should return false for dictionaries whose members are not all JSON types'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ idl.add_untested_idls('interface Foo { DOMString toJSON(); };'); >+ assert_true(idl.is_json_type(typeFrom("Foo"))); >+ }, 'should return true for interfaces which declare a toJSON operation'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ idl.add_untested_idls('interface Foo { DOMString toJSON(); }; interface Bar : Foo { };'); >+ assert_true(idl.is_json_type(typeFrom("Bar"))); >+ }, 'should return true for interfaces which inherit from an interface which declares a toJSON operation'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ idl.add_untested_idls('interface Foo { }; interface Bar { DOMString toJSON(); }; Foo implements Bar;'); >+ assert_true(idl.is_json_type(typeFrom("Foo"))); >+ }, 'should return true for interfaces which mixin an interface which declare a toJSON operation'); >+ >+// test(function() { >+// var idl = new IdlArray(); >+// idl.add_untested_idls('interface Foo { }; interface Bar { }; interface Baz { DOMString toJSON(); }; Foo implements Bar; Bar implements Baz;'); >+// assert_true(idl.is_json_type(typeFrom("Foo"))); >+// }, 'should return true for interfaces which mixin an interface which itself mixes in an interface which declares a toJSON operation'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ idl.add_untested_idls('interface Foo { };'); >+ assert_false(idl.is_json_type(typeFrom("Foo"))); >+ }, 'should return false for interfaces which do not declare a toJSON operation'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ idl.add_untested_idls('interface Foo { object toJSON(); };'); >+ assert_true(idl.is_json_type(typeFrom("(Foo or DOMString)"))); >+ }, 'should return true for union types whose member types are JSON types'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ assert_false(idl.is_json_type(typeFrom("(DataView or DOMString)"))); >+ }, 'should return false for union types whose member types are not all JSON types'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ assert_true(idl.is_json_type(typeFrom("DOMString?"))); >+ assert_false(idl.is_json_type(typeFrom("DataView?"))); >+ }, 'should consider the inner types of nullable types'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ assert_true(idl.is_json_type(typeFrom("[XAttr] long"))); >+ assert_false(idl.is_json_type(typeFrom("[XAttr] DataView"))); >+ }, 'should consider the inner types of annotated types.'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ assert_throws(new Error(), _ => idl.is_json_type(typeFrom("Foo"))); >+ }, "should throw if it references a dictionary, enum or interface which wasn't added to the IdlArray"); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ idl.add_untested_idls('interface Foo : Bar { };'); >+ assert_throws(new Error(), _ => idl.is_json_type(typeFrom("Foo"))); >+ }, "should throw for interfaces which inherit from another interface which wasn't added to the IdlArray"); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ assert_true(idl.is_json_type(typedefFrom("typedef double DOMHighResTimeStamp;").idlType)); >+ }, 'should return true for typedefs whose source type is a JSON type'); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ assert_false(idl.is_json_type(typedefFrom("typedef DataView DOMHighResTimeStamp;").idlType)); >+ }, 'should return false for typedefs whose source type is not a JSON type'); >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlArray/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlArray/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..7ce82892ea2bca87284f384f6efcc452a63c1375 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlArray/w3c-import.log >@@ -0,0 +1,17 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlArray/is_json_type.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlDictionary/get_inheritance_stack.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlDictionary/get_inheritance_stack.html >new file mode 100644 >index 0000000000000000000000000000000000000000..1ac9e8da06fe590513bd1318c2a83a7e83803ab3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlDictionary/get_inheritance_stack.html >@@ -0,0 +1,47 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>IdlDictionary.prototype.get_inheritance_stack()</title> >+</head> >+<body> >+<div id="log"></div> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/resources/WebIDLParser.js"></script> >+<script src="/resources/idlharness.js"></script> >+<script src="../../../idl-helper.js"></script> >+<script> >+ "use strict"; >+ test(function() { >+ var stack = dictionaryFrom('dictionary A { };').get_inheritance_stack(); >+ assert_array_equals(stack.map(d => d.name), ["A"]); >+ }, 'should return an array that includes itself.'); >+ >+ test(function() { >+ var d = dictionaryFrom('dictionary A : B { };'); >+ assert_throws(new Error(), _ => d.get_inheritance_stack()); >+ }, "should throw for dictionaries which inherit from another dictionary which wasn't added to the IdlArray"); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ idl.add_idls('dictionary A : B { };'); >+ idl.add_untested_idls('dictionary B : C { }; dictionary C { };'); >+ var A = idl.members["A"]; >+ assert_array_equals(A.get_inheritance_stack().map(d => d.name), ["A", "B", "C"]); >+ }, 'should return an array of inherited dictionaries in order of inheritance, starting with itself.'); >+ >+ test(function () { >+ let i = new IdlArray(); >+ i.add_untested_idls('dictionary A : B {};'); >+ i.assert_throws(new IdlHarnessError('A inherits B, but B is undefined.'), i => i.test()); >+ }, 'A : B with B undeclared should throw IdlHarnessError'); >+ >+ test(function () { >+ let i = new IdlArray(); >+ i.add_untested_idls('dictionary A : B {};'); >+ i.add_untested_idls('interface B {};'); >+ i.assert_throws(new IdlHarnessError('A inherits B, but A is not an interface.'), i => i.test()); >+ }, 'dictionary A : B with B interface should throw IdlHarnessError'); >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlDictionary/test_partial_dictionary.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlDictionary/test_partial_dictionary.html >new file mode 100644 >index 0000000000000000000000000000000000000000..cfcea545ffac00652a8ee3ffcc9a3e9d4b8973d8 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlDictionary/test_partial_dictionary.html >@@ -0,0 +1,45 @@ >+<!DOCTYPE HTML> >+<html> >+ >+<head> >+ <meta charset="utf-8"> >+ <title>idlharness: partial dictionaries</title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/resources/WebIDLParser.js"></script> >+ <script src="/resources/idlharness.js"></script> >+ <script src="../../../idl-helper.js"></script> >+</head> >+ >+<body> >+<pre id='idl'> >+dictionary A {}; >+partial dictionary A { >+ boolean B; >+}; >+partial dictionary A { >+ boolean C; >+}; >+</pre> >+ >+<script> >+'use strict'; >+ >+test(() => { >+ let idlArray = new IdlArray(); >+ idlArray.add_idls(document.getElementById('idl').textContent); >+ idlArray.test(); >+ >+ let members = idlArray.members["A"].members.map(m => m.name); >+ assert_array_equals(members, ["B", "C"], 'A should contain B, C'); >+}, 'Partial dictionaries'); >+ >+test(() => { >+ let idlArray = new IdlArray(); >+ idlArray.add_idls('partial dictionary D {};'); >+ idlArray.assert_throws('Partial dictionary D with no original dictionary', i => i.test()); >+}, 'Partial-only dictionary definition') >+</script> >+ >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlDictionary/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlDictionary/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..8f403269949295fe16ce393162ba4052c385d7d8 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlDictionary/w3c-import.log >@@ -0,0 +1,18 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlDictionary/get_inheritance_stack.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlDictionary/test_partial_dictionary.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/default_to_json_operation.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/default_to_json_operation.html >new file mode 100644 >index 0000000000000000000000000000000000000000..4b3dcfe6898f057ad270bae908f198cf3b2e75b8 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/default_to_json_operation.html >@@ -0,0 +1,189 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>IdlDictionary.prototype.default_to_json_operation()</title> >+</head> >+<body> >+<div id="log"></div> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/resources/WebIDLParser.js"></script> >+<script src="/resources/idlharness.js"></script> >+<script src="../../../idl-helper.js"></script> >+<pre id=fragments> >+ interface A : B { >+ attribute DOMString a; >+ }; >+ >+ interface B : C { >+ [Default] object toJSON(); >+ attribute long b; >+ }; >+ >+ interface C { >+ attribute DOMString c; >+ }; >+ >+ interface D : E { >+ [Default] object toJSON(); >+ attribute float d; >+ }; >+ >+ interface E : F { >+ attribute DOMString e; >+ }; >+ >+ interface F { >+ [Default] object toJSON(); >+ attribute unrestricted double f; >+ }; >+ >+ interface G { >+ [Default] object toJSON(); >+ attribute octet g; >+ }; >+ >+ interface H { >+ [Default] object toJSON(); >+ attribute DOMString h; >+ }; >+ >+ interface I { >+ [Default] object toJSON(); >+ attribute boolean i; >+ }; >+ >+ interface J { >+ [Default] object toJSON(); >+ attribute D j; >+ }; >+ >+ A implements G; >+ A implements H; >+ B implements D; >+ E implements I; >+ H implements J; >+</pre> >+<script> >+ "use strict"; >+ test(function() { >+ var map = interfaceFrom('interface A { [Default] object toJSON(); };').default_to_json_operation(); >+ assert_equals(map.size, 0); >+ }, 'should return an empty map when there are no attributes'); >+ >+ test(function() { >+ var r = interfaceFrom('interface A { };').default_to_json_operation(); >+ assert_equals(r, null); >+ }, 'should return null when there is no toJSON method'); >+ >+ test(function() { >+ var r = interfaceFrom('interface A { DOMString toJSON(); };').default_to_json_operation(); >+ assert_equals(r, null); >+ }, 'should return null when there is a toJSON method but it does not have the [Default] extended attribute'); >+ >+ test(function() { >+ var context = new IdlArray(); >+ context.add_idls("interface A : B { DOMString toJSON(); };"); >+ context.add_idls("interface B { [Default] object toJSON(); };"); >+ var r = context.members.A.default_to_json_operation(); >+ assert_equals(r, null); >+ }, 'should return null when there is a toJSON method but it does not have the [Default] extended attribute even if this extended attribute exists on inherited interfaces'); >+ >+ test(function() { >+ var map = interfaceFrom('interface A { [Default] object toJSON(); static attribute DOMString foo; };').default_to_json_operation(); >+ assert_equals(map.size, 0); >+ }, 'should not include static attributes'); >+ >+ test(function() { >+ var map = interfaceFrom('interface A { [Default] object toJSON(); attribute Promise<DOMString> bar; };').default_to_json_operation(); >+ assert_equals(map.size, 0); >+ }, 'should not include attributes which are not JSON types'); >+ >+ test(function() { >+ var map = interfaceFrom('interface A { [Default] object toJSON(); DOMString bar(); };').default_to_json_operation(); >+ assert_equals(map.size, 0); >+ }, 'should not include operations'); >+ >+ test(function() { >+ var map = interfaceFrom('interface A { [Default] object toJSON(); attribute DOMString bar; };').default_to_json_operation(); >+ assert_equals(map.size, 1); >+ assert_true(map.has("bar")); >+ assert_equals(map.get("bar").idlType, "DOMString"); >+ }, 'should return a map whose key/value pair represent the identifier and IDL type of valid attributes'); >+ >+ test(function() { >+ var context = new IdlArray(); >+ context.add_idls("interface A : B { [Default] object toJSON(); attribute DOMString a; };"); >+ context.add_idls("interface B { [Default] object toJSON(); attribute long b; };"); >+ var map = context.members.A.default_to_json_operation(); >+ assert_array_equals([...map.keys()], ["b", "a"]); >+ assert_array_equals([...map.values()].map(v => v.idlType), ["long", "DOMString"]); >+ }, 'should return a properly ordered map that contains IDL types of valid attributes for inherited interfaces'); >+ >+ test(function() { >+ var context = new IdlArray(); >+ context.add_idls("interface A : B { attribute DOMString a; };"); >+ context.add_idls("interface B { [Default] object toJSON(); attribute long b; };"); >+ var map = context.members.A.default_to_json_operation(); >+ assert_equals(map.size, 1); >+ assert_true(map.has("b")); >+ assert_equals(map.get("b").idlType, "long"); >+ assert_array_equals([...map.keys()], ["b"]); >+ }, 'should not include attributes of the current interface when the [Default] toJSON method in inherited'); >+ >+ test(function() { >+ var context = new IdlArray(); >+ context.add_idls("interface A : B { [Default] object toJSON(); };"); >+ context.add_idls("interface B : C { [Default] object toJSON(); attribute DOMString foo; };"); >+ context.add_idls("interface C { [Default] object toJSON(); attribute long foo; };"); >+ var map = context.members.A.default_to_json_operation(); >+ assert_equals(map.size, 1); >+ assert_true(map.has("foo")); >+ assert_equals(map.get("foo").idlType, "DOMString"); >+ }, 'attributes declared further away in the inheritance hierarchy should be masked by attributes declared closer'); >+ >+ test(function() { >+ var context = new IdlArray(); >+ context.add_idls("interface A : B { [Default] object toJSON(); attribute DOMString a; };"); >+ context.add_idls("interface B { object toJSON(); attribute long b; };"); >+ var map = context.members.A.default_to_json_operation(); >+ assert_equals(map.size, 1); >+ assert_true(map.has("a")); >+ assert_false(map.has("b")); >+ assert_equals(map.get("a").idlType, "DOMString"); >+ }, 'should return an ordered map that ignores attributes of inherited interfaces which do not declare a [Default] toJSON operation.'); >+ >+ test(function() { >+ var context = new IdlArray(); >+ context.add_idls("interface A { [Default] object toJSON(); attribute DOMString a; };"); >+ context.add_idls("interface N { [Default] object toJSON(); attribute long n; };"); >+ context.add_idls("A implements N;"); >+ var map = context.members.A.default_to_json_operation(); >+ assert_array_equals([...map.keys()], ["a", "n"]); >+ assert_array_equals([...map.values()].map(v => v.idlType), ["DOMString", "long"]); >+ }, 'should return a properly ordered map that accounts for mixed-in interfaces which declare a [Default] toJSON operation.'); >+ >+ test(function() { >+ var context = new IdlArray(); >+ context.add_idls("interface A { [Default] object toJSON(); attribute DOMString a; };"); >+ context.add_idls("interface N { attribute long n; };"); >+ context.add_idls("A implements N;"); >+ var map = context.members.A.default_to_json_operation(); >+ assert_equals(map.size, 1); >+ assert_true(map.has("a")); >+ assert_false(map.has("n")); >+ assert_equals(map.get("a").idlType, "DOMString"); >+ }, 'should return a properly ordered map that ignores mixed-in interfaces which do not declare a [Default] toJSON operation.'); >+ >+ >+ test(function() { >+ var context = new IdlArray(); >+ context.add_idls(document.getElementById('fragments').textContent); >+ var map = context.members.A.default_to_json_operation(); >+ assert_array_equals([...map.keys()], ["b", "f", "i", "d", "g", "h", "j"]); >+ assert_array_equals([...map.values()].map(v => v.idlType), ["long", "unrestricted double", "boolean", "float", "octet", "DOMString", "D"]); >+ }, 'should return a properly ordered map of name/type pairs handling inherited and consequential interfaces as specified.'); >+</script> >+</body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/get_inheritance_stack.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/get_inheritance_stack.html >new file mode 100644 >index 0000000000000000000000000000000000000000..66b79afc12f2fdf139163502065a1778c63b06e2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/get_inheritance_stack.html >@@ -0,0 +1,49 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>IdlInterface.prototype.get_inheritance_stack()</title> >+</head> >+<body> >+<div id="log"></div> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/resources/WebIDLParser.js"></script> >+<script src="/resources/idlharness.js"></script> >+<script src="../../../idl-helper.js"></script> >+<script> >+ "use strict"; >+ test(function() { >+ var stack = interfaceFrom('interface A { };').get_inheritance_stack(); >+ assert_array_equals(stack.map(i => i.name), ["A"]); >+ }, 'should return an array that includes itself.'); >+ >+ test(function() { >+ var i = interfaceFrom('interface A : B { };'); >+ assert_throws(new Error(), _ => i.get_inheritance_stack()); >+ }, "should throw for interfaces which inherit from another interface which wasn't added to the IdlArray"); >+ >+ test(function() { >+ var idl = new IdlArray(); >+ idl.add_idls('interface A : B { };'); >+ idl.add_untested_idls('interface B : C { }; interface C { };'); >+ var A = idl.members["A"]; >+ assert_array_equals(A.get_inheritance_stack().map(i => i.name), ["A", "B", "C"]); >+ }, 'should return an array of inherited interfaces in order of inheritance, starting with itself.'); >+ >+ test(function () { >+ var idl = new IdlArray(); >+ idl.add_untested_idls('interface A : B { };'); >+ idl.add_untested_idls('interface B : A { };'); >+ idl.assert_throws('A has a circular dependency: A,B,A', i => i.test()); >+ }, 'should throw when inheritance is circular'); >+ >+ test(function () { >+ var idl = new IdlArray(); >+ idl.add_untested_idls('interface A : B { };'); >+ idl.assert_throws( >+ 'Duplicate identifier A', >+ i => i.add_untested_idls('interface A : C { };')); >+ }, 'should throw when multiple inheritances defined'); >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/has_default_to_json_regular_operation.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/has_default_to_json_regular_operation.html >new file mode 100644 >index 0000000000000000000000000000000000000000..b47262b72b91c692211727042f782e88064f9b40 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/has_default_to_json_regular_operation.html >@@ -0,0 +1,47 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>IdlInterface.prototype.has_default_to_json_regular_operation()</title> >+</head> >+<body> >+<div id="log"></div> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/resources/WebIDLParser.js"></script> >+<script src="/resources/idlharness.js"></script> >+<script src="../../../idl-helper.js"></script> >+<script> >+ "use strict"; >+ test(function() { >+ var i = interfaceFrom('interface A { };'); >+ assert_false(i.has_default_to_json_regular_operation()); >+ }, 'should return false when the interface declares no toJSON operation.'); >+ >+ test(function() { >+ var i = interfaceFrom('interface A { static object toJSON(); };'); >+ assert_false(i.has_default_to_json_regular_operation()); >+ }, 'should return false when the interface declares a static toJSON operation.'); >+ >+ test(function() { >+ var i = interfaceFrom('interface A { object toJSON(); };'); >+ assert_false(i.has_default_to_json_regular_operation()); >+ }, 'should return false when the interface declares a regular toJSON operation with no extended attribute.'); >+ >+ test(function() { >+ var i = interfaceFrom('interface A { [x] object toJSON(); };'); >+ assert_false(i.has_default_to_json_regular_operation()); >+ }, 'should return false when the interface declares a regular toJSON operation with another extented attribute.'); >+ >+ test(function() { >+ var i = interfaceFrom('interface A { [Default] object toJSON(); };'); >+ assert_true(i.has_default_to_json_regular_operation()); >+ }, 'should return true when the interface declares a regular toJSON operation with the [Default] extented attribute.'); >+ >+ test(function() { >+ var i = interfaceFrom('interface A { [Attr, AnotherAttr, Default] object toJSON(); };'); >+ assert_true(i.has_default_to_json_regular_operation()); >+ }, 'should return true when the interface declares a regular toJSON operation with multiple extended attributes, including [Default].'); >+</script> >+</body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/has_to_json_regular_operation.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/has_to_json_regular_operation.html >new file mode 100644 >index 0000000000000000000000000000000000000000..a1a641bd971e5a995e3965d27f3e2f8a8e834e7b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/has_to_json_regular_operation.html >@@ -0,0 +1,31 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>IdlInterface.prototype.has_to_json_regular_operation()</title> >+</head> >+<body> >+<div id="log"></div> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/resources/WebIDLParser.js"></script> >+<script src="/resources/idlharness.js"></script> >+<script src="../../../idl-helper.js"></script> >+<script> >+ "use strict"; >+ test(function() { >+ var i = interfaceFrom('interface A { };'); >+ assert_false(i.has_to_json_regular_operation()); >+ }, 'should return false when the interface declares no toJSON operation.'); >+ >+ test(function() { >+ var i = interfaceFrom('interface A { static object toJSON(); };'); >+ assert_false(i.has_to_json_regular_operation()); >+ }, 'should return false when the interface declares a static toJSON operation.'); >+ >+ test(function() { >+ var i = interfaceFrom('interface A { object toJSON(); };'); >+ assert_true(i.has_to_json_regular_operation()); >+ }, 'should return true when the interface declares a regular toJSON operation.'); >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/test_primary_interface_of_undefined.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/test_primary_interface_of_undefined.html >new file mode 100644 >index 0000000000000000000000000000000000000000..0031558ad42ce55e0cd6ee92ea9973788a9a8017 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/test_primary_interface_of_undefined.html >@@ -0,0 +1,29 @@ >+<!DOCTYPE HTML> >+<html> >+ >+<head> >+ <title>idlharness test_primary_interface_of_undefined</title> >+</head> >+ >+<body> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/WebIDLParser.js"></script> >+ <script src="/resources/idlharness.js"></script> >+ <script> >+ 'use strict'; >+ test(function () { >+ let i = new IdlArray(); >+ i.add_untested_idls('interface A : B {};'); >+ i.assert_throws(new IdlHarnessError('A inherits B, but B is undefined.'), i => i.test()); >+ }, 'A : B with B undeclared should throw IdlHarnessError'); >+ >+ test(function () { >+ let i = new IdlArray(); >+ i.add_untested_idls('interface A : B {};'); >+ i.add_untested_idls('dictionary B {};'); >+ i.assert_throws(new IdlHarnessError('A inherits B, but B is not an interface.'), i => i.test()); >+ }, 'interface A : B with B dictionary should throw IdlHarnessError'); >+ </script> >+</body> >+ >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/traverse_inherited_and_consequential_interfaces.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/traverse_inherited_and_consequential_interfaces.html >new file mode 100644 >index 0000000000000000000000000000000000000000..21817c485b95b52bffaea950b1f4b72965a9a6c2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/traverse_inherited_and_consequential_interfaces.html >@@ -0,0 +1,64 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>IdlDictionary.prototype.traverse_inherited_and_consequential_interfaces()</title> >+</head> >+<body> >+<div id="log"></div> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/resources/WebIDLParser.js"></script> >+<script src="/resources/idlharness.js"></script> >+<script src="../../../idl-helper.js"></script> >+<pre id=fragments> >+ interface A : B { }; >+ interface B : C { }; >+ interface C { }; >+ interface D : E { }; >+ interface E : F { }; >+ interface F { }; >+ interface G { }; >+ interface H { }; >+ interface I { }; >+ interface J { }; >+ >+ A implements G; >+ A implements H; >+ B implements D; >+ E implements I; >+ H implements J; >+</pre> >+<script> >+ "use strict"; >+ test(function() { >+ var interfaces = []; >+ interfaceFrom('interface A { };').traverse_inherited_and_consequential_interfaces(function(i) { >+ interfaces.push(i.name); >+ }); >+ assert_array_equals(interfaces, ["A"]); >+ }, 'should return an array that includes itself.'); >+ >+ test(function() { >+ var context = new IdlArray(); >+ context.add_idls("interface A { }; A implements B;"); >+ assert_throws(new Error(), _ => context.members["A"].traverse_inherited_and_consequential_interfaces(function() {})); >+ }, "should throw for interfaces which are extended by another interface which wasn't added to the IdlArray."); >+ >+ test(function() { >+ var context = new IdlArray(); >+ context.add_idls("interface A { };"); >+ assert_throws(new TypeError(), _ => context.members["A"].traverse_inherited_and_consequential_interfaces()); >+ }, "should throw if not passed a callback"); >+ >+ test(function() { >+ var context = new IdlArray(); >+ context.add_idls(document.getElementById('fragments').textContent); >+ var interfaces = []; >+ context.members["A"].traverse_inherited_and_consequential_interfaces(function(i) { >+ interfaces.push(i.name); >+ }); >+ assert_array_equals(interfaces, ["C", "B", "F", "E", "I", "D", "A", "G", "H", "J"]); >+ }, 'should return an array that includes the identifier of the interfaces in the correct order.'); >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..20e3a5c2ef70441296c4160541bc20a536b3d663 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/w3c-import.log >@@ -0,0 +1,22 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/default_to_json_operation.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/get_inheritance_stack.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/has_default_to_json_regular_operation.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/has_to_json_regular_operation.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/test_primary_interface_of_undefined.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterface/traverse_inherited_and_consequential_interfaces.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterfaceMember/is_to_json_regular_operation.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterfaceMember/is_to_json_regular_operation.html >new file mode 100644 >index 0000000000000000000000000000000000000000..abfa4ab800b3c8e6b5f6fd3b42a982cc2e4fe99e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterfaceMember/is_to_json_regular_operation.html >@@ -0,0 +1,42 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>IdlInterfaceMember.prototype.is_to_json_regular_operation()</title> >+</head> >+<body> >+<div id="log"></div> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/resources/WebIDLParser.js"></script> >+<script src="/resources/idlharness.js"></script> >+<script src="../../../idl-helper.js"></script> >+<script> >+ "use strict"; >+ test(function() { >+ var m = memberFrom("readonly attribute DOMString foo"); >+ assert_false(m.is_to_json_regular_operation()); >+ }, 'should return false when member is an attribute.'); >+ >+ test(function() { >+ var m = memberFrom("static void foo()"); >+ assert_false(m.is_to_json_regular_operation()); >+ }, 'should return false when member is a static operation.'); >+ >+ test(function() { >+ var m = memberFrom("static object toJSON()"); >+ assert_false(m.is_to_json_regular_operation()); >+ }, 'should return false when member is a static toJSON operation.'); >+ >+ test(function() { >+ var m = memberFrom("object toJSON()"); >+ assert_true(m.is_to_json_regular_operation()); >+ }, 'should return true when member is a regular toJSON operation.'); >+ >+ test(function() { >+ var m = memberFrom("[Foo] object toJSON()"); >+ assert_true(m.is_to_json_regular_operation()); >+ }, 'should return true when member is a regular toJSON operation with extensible attributes.'); >+</script> >+</body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterfaceMember/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterfaceMember/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..d056990e57c91197e928cf5f290a6caf59aeb25b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterfaceMember/w3c-import.log >@@ -0,0 +1,17 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/IdlInterfaceMember/is_to_json_regular_operation.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/OWNERS b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/OWNERS >new file mode 100644 >index 0000000000000000000000000000000000000000..37e8095017cda9a770580d65d8bab507aea51a31 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/OWNERS >@@ -0,0 +1 @@ >+@tobie >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/basic.html b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/basic.html >new file mode 100644 >index 0000000000000000000000000000000000000000..439c203dc95021795e2da2fd684ee4651430a4a6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/basic.html >@@ -0,0 +1,56 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<title>idlharness basic</title> >+</head> >+<body> >+<div id="log"></div> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/resources/WebIDLParser.js"></script> >+<script src="/resources/idlharness.js"></script> >+<script> >+ "use strict"; >+ test(function() { >+ assert_true("IdlArray" in window); >+ }, 'IdlArray constructor should be a global object'); >+ test(function() { >+ assert_true(new IdlArray() instanceof IdlArray); >+ }, 'IdlArray constructor should be constructible'); >+ test(function() { >+ assert_true("WebIDL2" in window); >+ }, 'WebIDL2 namespace should be a global object'); >+ test(function() { >+ assert_equals(typeof WebIDL2.parse, "function"); >+ }, 'WebIDL2 namespace should have a parse method'); >+ test(function() { >+ assert_throws(new TypeError(), function() { WebIDL2.parse("I'm a syntax error"); }); >+ }, 'WebIDL2 parse method should bail on incorrect WebIDL'); >+ test(function() { >+ assert_equals(typeof WebIDL2.parse("interface Foo {};"), "object"); >+ }, 'WebIDL2 parse method should produce an AST for correct WebIDL'); >+ for (let type of ['dictionary', 'interface']) { >+ test(function() { >+ let i = new IdlArray(); >+ i.add_untested_idls(`partial ${type} A {};`); >+ i.assert_throws(new IdlHarnessError(`Partial ${type} A with no original ${type}`), i => i.test()); >+ }, `assert_throws should handle ${type} IdlHarnessError`); >+ test(function() { >+ let i = new IdlArray(); >+ i.add_untested_idls(`partial ${type} A {};`); >+ i.assert_throws(`Partial ${type} A with no original ${type}`, i => i.test()); >+ }, `assert_throws should handle ${type} IdlHarnessError from message`); >+ test(function () { >+ try { >+ let i = new IdlArray(); >+ i.add_untested_idls(`${type} A {};`); >+ i.assert_throws(`Partial ${type} A with no original ${type}`, i => i.test()); >+ } catch (e) { >+ assert_true(e instanceof IdlHarnessError); >+ } >+ }, `assert_throws should throw if no ${type} IdlHarnessError thrown`); >+ } >+</script> >+</body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..570575ec3d3924816d623734e1ea35de2decb540 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/w3c-import.log >@@ -0,0 +1,18 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/OWNERS >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/tests/unit/basic.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tox.ini b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tox.ini >index 4f45640479f1bbb8660b935cd2db78c51d404d57..d3a30f870a1572d4423ae99f64c67d63afa345da 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/test/tox.ini >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/tox.ini >@@ -1,4 +1,6 @@ > [tox] >+# wptserve etc. are Python2-only. >+envlist = py27 > skipsdist=True > > [testenv] >@@ -9,5 +11,6 @@ deps = > pytest>=2.9 > pyvirtualdisplay > selenium >+ requests > > commands = pytest {posargs} -vv tests >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resources/test/w3c-import.log >index 26ecda0ed2f7b0db17c40ef035c763151c72bc92..bd6ca8b67382025119d6dd2422bba5f3ba470265 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/test/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/w3c-import.log >@@ -15,8 +15,8 @@ None > ------------------------------------------------------------------------ > List of files: > /LayoutTests/imported/w3c/web-platform-tests/resources/test/README.md >-/LayoutTests/imported/w3c/web-platform-tests/resources/test/config.test.json > /LayoutTests/imported/w3c/web-platform-tests/resources/test/conftest.py > /LayoutTests/imported/w3c/web-platform-tests/resources/test/harness.html >+/LayoutTests/imported/w3c/web-platform-tests/resources/test/idl-helper.js > /LayoutTests/imported/w3c/web-platform-tests/resources/test/tox.ini > /LayoutTests/imported/w3c/web-platform-tests/resources/test/wptserver.py >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/test/wptserver.py b/LayoutTests/imported/w3c/web-platform-tests/resources/test/wptserver.py >index b06f3e81745ef12561c8a172bb827b4e6828b2b6..6acad835277c4dca741bd6acda93d656024d27e7 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/test/wptserver.py >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/test/wptserver.py >@@ -1,48 +1,51 @@ >-import json >+import logging > import os >-import ssl > import subprocess >+import time >+import sys > import urllib2 > >-_CONFIG_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), >- 'config.test.json') >- >-with open(_CONFIG_FILE, 'r') as config_handle: >- config = json.loads(config_handle.read()) >- host = config["host"] >- port = config["ports"]["https"][0] > > class WPTServer(object): >- base_url = 'https://%s:%s' % (host, port) >- > def __init__(self, wpt_root): > self.wpt_root = wpt_root >+ sys.path.insert(0, os.path.join(wpt_root, "tools")) >+ from serve.serve import Config >+ config = Config() >+ self.host = config["browser_host"] >+ self.http_port = config["ports"]["http"][0] >+ self.https_port = config["ports"]["https"][0] >+ self.base_url = 'http://%s:%s' % (self.host, self.http_port) >+ self.https_base_url = 'https://%s:%s' % (self.host, self.https_port) > > def start(self): > self.devnull = open(os.devnull, 'w') >+ wptserve_cmd = [os.path.join(self.wpt_root, 'wpt'), 'serve'] >+ logging.info('Executing %s' % ' '.join(wptserve_cmd)) > self.proc = subprocess.Popen( >- [os.path.join(self.wpt_root, 'wpt'), 'serve', '--config=' + _CONFIG_FILE], >- stdout=self.devnull, >+ wptserve_cmd, > stderr=self.devnull, > cwd=self.wpt_root) >- context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) >- context.verify_mode = ssl.CERT_NONE >- context.check_hostname = False >- >- while True: >- if self.proc.poll() != None: >- raise Exception('Could not start wptserve.') > >- try: >- urllib2.urlopen(self.base_url, timeout=1, context=context) >+ for retry in range(5): >+ # Exponential backoff. >+ time.sleep(2 ** retry) >+ exit_code = self.proc.poll() >+ if exit_code != None: >+ logging.warn('Command "%s" exited with %s', ' '.join(wptserve_cmd), exit_code) > break >- except urllib2.URLError as e: >+ try: >+ urllib2.urlopen(self.base_url, timeout=1) >+ return >+ except urllib2.URLError: > pass > >+ raise Exception('Could not start wptserve on %s' % self.base_url) >+ > def stop(self): >- self.proc.kill() >+ self.proc.terminate() > self.proc.wait() > self.devnull.close() > > def url(self, abs_path): >- return self.base_url + '/' + os.path.relpath(abs_path, self.wpt_root) >+ return self.https_base_url + '/' + os.path.relpath(abs_path, self.wpt_root) >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js b/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js >new file mode 100644 >index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js.headers b/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js.headers >new file mode 100644 >index 0000000000000000000000000000000000000000..5e8f640c6659d176eaca4c71cc1798b7285540b7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js.headers >@@ -0,0 +1,2 @@ >+Content-Type: text/javascript; charset=utf-8 >+Cache-Control: max-age=3600 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver.js b/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver.js >new file mode 100644 >index 0000000000000000000000000000000000000000..6fadb8ac49470a814eefdf0ed6f82f244776cc87 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver.js >@@ -0,0 +1,173 @@ >+(function() { >+ "use strict"; >+ >+ function getInViewCenterPoint(rect) { >+ var left = Math.max(0, rect.left); >+ var right = Math.min(window.innerWidth, rect.right); >+ var top = Math.max(0, rect.top); >+ var bottom = Math.min(window.innerHeight, rect.bottom); >+ >+ var x = 0.5 * (left + right); >+ var y = 0.5 * (top + bottom); >+ >+ return [x, y]; >+ } >+ >+ function getPointerInteractablePaintTree(element) { >+ if (!window.document.contains(element)) { >+ return []; >+ } >+ >+ var rectangles = element.getClientRects(); >+ >+ if (rectangles.length === 0) { >+ return []; >+ } >+ >+ var centerPoint = getInViewCenterPoint(rectangles[0]); >+ >+ if ("elementsFromPoint" in document) { >+ return document.elementsFromPoint(centerPoint[0], centerPoint[1]); >+ } else if ("msElementsFromPoint" in document) { >+ var rv = document.msElementsFromPoint(centerPoint[0], centerPoint[1]); >+ return Array.prototype.slice.call(rv ? rv : []); >+ } else { >+ throw new Error("document.elementsFromPoint unsupported"); >+ } >+ } >+ >+ function inView(element) { >+ var pointerInteractablePaintTree = getPointerInteractablePaintTree(element); >+ return pointerInteractablePaintTree.indexOf(element) !== -1; >+ } >+ >+ >+ /** >+ * @namespace >+ */ >+ window.test_driver = { >+ /** >+ * Triggers a user-initiated click >+ * >+ * This matches the behaviour of the {@link >+ * https://w3c.github.io/webdriver/webdriver-spec.html#element-click|WebDriver >+ * Element Click command}. >+ * >+ * @param {Element} element - element to be clicked >+ * @returns {Promise} fulfilled after click occurs, or rejected in >+ * the cases the WebDriver command errors >+ */ >+ click: function(element) { >+ if (window.top !== window) { >+ return Promise.reject(new Error("can only click in top-level window")); >+ } >+ >+ if (!window.document.contains(element)) { >+ return Promise.reject(new Error("element in different document or shadow tree")); >+ } >+ >+ if (!inView(element)) { >+ element.scrollIntoView({behavior: "instant", >+ block: "end", >+ inline: "nearest"}); >+ } >+ >+ var pointerInteractablePaintTree = getPointerInteractablePaintTree(element); >+ if (pointerInteractablePaintTree.length === 0 || >+ !element.contains(pointerInteractablePaintTree[0])) { >+ return Promise.reject(new Error("element click intercepted error")); >+ } >+ >+ var rect = element.getClientRects()[0]; >+ var centerPoint = getInViewCenterPoint(rect); >+ return window.test_driver_internal.click(element, >+ {x: centerPoint[0], >+ y: centerPoint[1]}); >+ }, >+ >+ /** >+ * Send keys to an element >+ * >+ * This matches the behaviour of the {@link >+ * https://w3c.github.io/webdriver/webdriver-spec.html#element-send-keys|WebDriver >+ * Send Keys command}. >+ * >+ * @param {Element} element - element to send keys to >+ * @param {String} keys - keys to send to the element >+ * @returns {Promise} fulfilled after keys are sent, or rejected in >+ * the cases the WebDriver command errors >+ */ >+ send_keys: function(element, keys) { >+ if (window.top !== window) { >+ return Promise.reject(new Error("can only send keys in top-level window")); >+ } >+ >+ if (!window.document.contains(element)) { >+ return Promise.reject(new Error("element in different document or shadow tree")); >+ } >+ >+ if (!inView(element)) { >+ element.scrollIntoView({behavior: "instant", >+ block: "end", >+ inline: "nearest"}); >+ } >+ >+ var pointerInteractablePaintTree = getPointerInteractablePaintTree(element); >+ if (pointerInteractablePaintTree.length === 0 || >+ !element.contains(pointerInteractablePaintTree[0])) { >+ return Promise.reject(new Error("element send_keys intercepted error")); >+ } >+ >+ return window.test_driver_internal.send_keys(element, keys); >+ }, >+ >+ /** >+ * Freeze the current page >+ * >+ * The freeze function transitions the page from the HIDDEN state to >+ * the FROZEN state as described in {@link >+ * https://github.com/WICG/page-lifecycle/blob/master/README.md|Lifecycle API >+ * for Web Pages} >+ * >+ * @returns {Promise} fullfilled after the freeze request is sent, or rejected >+ * in case the WebDriver command errors >+ */ >+ freeze: function() { >+ return window.test_driver_internal.freeze(); >+ } >+ }; >+ >+ window.test_driver_internal = { >+ /** >+ * Triggers a user-initated click >+ * >+ * @param {Element} element - element to be clicked >+ * @param {{x: number, y: number} coords - viewport coordinates to click at >+ * @returns {Promise} fulfilled after click occurs or rejected if click fails >+ */ >+ click: function(element, coords) { >+ return Promise.reject(new Error("unimplemented")); >+ }, >+ >+ /** >+ * Triggers a user-initated click >+ * >+ * @param {Element} element - element to be clicked >+ * @param {String} keys - keys to send to the element >+ * @returns {Promise} fulfilled after keys are sent or rejected if click fails >+ */ >+ send_keys: function(element, keys) { >+ return Promise.reject(new Error("unimplemented")); >+ }, >+ >+ /** >+ * Freeze the current page >+ * >+ * @returns {Promise} fullfilled after freeze request is sent, otherwise >+ * it gets rejected >+ */ >+ freeze: function() { >+ return Promise.reject(new Error("unimplemented")); >+ } >+ }; >+})(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver.js.headers b/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver.js.headers >new file mode 100644 >index 0000000000000000000000000000000000000000..5e8f640c6659d176eaca4c71cc1798b7285540b7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver.js.headers >@@ -0,0 +1,2 @@ >+Content-Type: text/javascript; charset=utf-8 >+Cache-Control: max-age=3600 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/testharness.css.headers b/LayoutTests/imported/w3c/web-platform-tests/resources/testharness.css.headers >index 3d2c3342b7cd7be3f159eed225a5fe1d327b97c5..e828b629858d07afd989b80894986315bac16cc7 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/testharness.css.headers >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/testharness.css.headers >@@ -1 +1,2 @@ > Content-Type: text/css;charset=utf-8 >+Cache-Control: max-age=3600 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/testharness.js b/LayoutTests/imported/w3c/web-platform-tests/resources/testharness.js >index aa0d907559b6978cf4253b4323b1ba26dd4f1937..98897958bc427a689a3c5d7413b28d3637f2624d 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/testharness.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/testharness.js >@@ -10,10 +10,10 @@ policies and contribution forms [3]. > [3] http://www.w3.org/2004/10/27-testcases > */ > >-/* Documentation: http://web-platform-tests.org/writing-tests/testharness-api.html >+/* Documentation: https://web-platform-tests.org/writing-tests/testharness-api.html > * (../docs/_writing-tests/testharness-api.md) */ > >-(function () >+(function (global_scope) > { > var debug = false; > // default timeout is 10 seconds, test can override if needed >@@ -48,9 +48,6 @@ policies and contribution forms [3]. > * > * // Should return the test harness timeout duration in milliseconds. > * float test_timeout(); >- * >- * // Should return the global scope object. >- * object global_scope(); > * }; > */ > >@@ -248,10 +245,6 @@ policies and contribution forms [3]. > return settings.harness_timeout.normal; > }; > >- WindowTestEnvironment.prototype.global_scope = function() { >- return window; >- }; >- > /* > * Base TestEnvironment implementation for a generic web worker. > * >@@ -344,10 +337,6 @@ policies and contribution forms [3]. > return null; > }; > >- WorkerTestEnvironment.prototype.global_scope = function() { >- return self; >- }; >- > /* > * Dedicated web workers. > * https://html.spec.whatwg.org/multipage/workers.html#dedicatedworkerglobalscope >@@ -462,40 +451,88 @@ policies and contribution forms [3]. > } > }; > >+ /* >+ * JavaScript shells. >+ * >+ * This class is used as the test_environment when testharness is running >+ * inside a JavaScript shell. >+ */ >+ function ShellTestEnvironment() { >+ this.name_counter = 0; >+ this.all_loaded = false; >+ this.on_loaded_callback = null; >+ Promise.resolve().then(function() { >+ this.all_loaded = true >+ if (this.on_loaded_callback) { >+ this.on_loaded_callback(); >+ } >+ }.bind(this)); >+ this.message_list = []; >+ this.message_ports = []; >+ } >+ >+ ShellTestEnvironment.prototype.next_default_test_name = function() { >+ var suffix = this.name_counter > 0 ? " " + this.name_counter : ""; >+ this.name_counter++; >+ return "Untitled" + suffix; >+ }; >+ >+ ShellTestEnvironment.prototype.on_new_harness_properties = function() {}; >+ >+ ShellTestEnvironment.prototype.on_tests_ready = function() {}; >+ >+ ShellTestEnvironment.prototype.add_on_loaded_callback = function(callback) { >+ if (this.all_loaded) { >+ callback(); >+ } else { >+ this.on_loaded_callback = callback; >+ } >+ }; >+ >+ ShellTestEnvironment.prototype.test_timeout = function() { >+ // Tests running in a shell don't have a default timeout, so behave as >+ // if settings.explicit_timeout is true. >+ return null; >+ }; >+ > function create_test_environment() { >- if ('document' in self) { >+ if ('document' in global_scope) { > return new WindowTestEnvironment(); > } >- if ('DedicatedWorkerGlobalScope' in self && >- self instanceof DedicatedWorkerGlobalScope) { >+ if ('DedicatedWorkerGlobalScope' in global_scope && >+ global_scope instanceof DedicatedWorkerGlobalScope) { > return new DedicatedWorkerTestEnvironment(); > } >- if ('SharedWorkerGlobalScope' in self && >- self instanceof SharedWorkerGlobalScope) { >+ if ('SharedWorkerGlobalScope' in global_scope && >+ global_scope instanceof SharedWorkerGlobalScope) { > return new SharedWorkerTestEnvironment(); > } >- if ('ServiceWorkerGlobalScope' in self && >- self instanceof ServiceWorkerGlobalScope) { >+ if ('ServiceWorkerGlobalScope' in global_scope && >+ global_scope instanceof ServiceWorkerGlobalScope) { > return new ServiceWorkerTestEnvironment(); > } >- if ('WorkerGlobalScope' in self && >- self instanceof WorkerGlobalScope) { >+ if ('WorkerGlobalScope' in global_scope && >+ global_scope instanceof WorkerGlobalScope) { > return new DedicatedWorkerTestEnvironment(); > } > >+ if (!('self' in global_scope)) { >+ return new ShellTestEnvironment(); >+ } >+ > throw new Error("Unsupported test environment"); > } > > var test_environment = create_test_environment(); > > function is_shared_worker(worker) { >- return 'SharedWorker' in self && worker instanceof SharedWorker; >+ return 'SharedWorker' in global_scope && worker instanceof SharedWorker; > } > > function is_service_worker(worker) { > // The worker object may be from another execution context, > // so do not use instanceof here. >- return 'ServiceWorker' in self && >+ return 'ServiceWorker' in global_scope && > Object.prototype.toString.call(worker) == '[object ServiceWorker]'; > } > >@@ -1247,6 +1284,13 @@ policies and contribution forms [3]. > } > expose(assert_readonly, "assert_readonly"); > >+ /** >+ * Assert an Exception with the expected code is thrown. >+ * >+ * @param {object|number|string} code The expected exception code. >+ * @param {Function} func Function which should throw. >+ * @param {string} description Error description for the case that the error is not thrown. >+ */ > function assert_throws(code, func, description) > { > try { >@@ -1257,11 +1301,22 @@ policies and contribution forms [3]. > if (e instanceof AssertionError) { > throw e; > } >+ >+ assert(typeof e === "object", >+ "assert_throws", description, >+ "${func} threw ${e} with type ${type}, not an object", >+ {func:func, e:e, type:typeof e}); >+ >+ assert(e !== null, >+ "assert_throws", description, >+ "${func} threw null, not an object", >+ {func:func}); >+ > if (code === null) { > throw new AssertionError('Test bug: need to pass exception to assert_throws()'); > } > if (typeof code === "object") { >- assert(typeof e == "object" && "name" in e && e.name == code.name, >+ assert("name" in e && e.name == code.name, > "assert_throws", description, > "${func} threw ${actual} (${actual_name}) expected ${expected} (${expected_name})", > {func:func, actual:e, actual_name:e.name, >@@ -1340,8 +1395,7 @@ policies and contribution forms [3]. > var required_props = { code: name_code_map[name] }; > > if (required_props.code === 0 || >- (typeof e == "object" && >- "name" in e && >+ ("name" in e && > e.name !== e.name.toUpperCase() && > e.name !== "DOMException")) { > // New style exception: also test the name property. >@@ -1353,13 +1407,8 @@ policies and contribution forms [3]. > //in. It might be an instanceof the appropriate interface on some > //unknown other window. TODO: Work around this somehow? > >- assert(typeof e == "object", >- "assert_throws", description, >- "${func} threw ${e} with type ${type}, not an object", >- {func:func, e:e, type:typeof e}); >- > for (var prop in required_props) { >- assert(typeof e == "object" && prop in e && e[prop] == required_props[prop], >+ assert(prop in e && e[prop] == required_props[prop], > "assert_throws", description, > "${func} threw ${e} that is not a DOMException " + code + ": property ${prop} is equal to ${actual}, expected ${expected}", > {func:func, e:e, prop:prop, actual:e[prop], expected:required_props[prop]}); >@@ -1569,11 +1618,6 @@ policies and contribution forms [3]. > this._add_cleanup(callback); > }; > >- Test.prototype.force_timeout = function() { >- this.set_status(this.TIMEOUT); >- this.phase = this.phases.HAS_RESULT; >- }; >- > Test.prototype.set_timeout = function() > { > if (this.timeout_length !== null) { >@@ -1600,6 +1644,8 @@ policies and contribution forms [3]. > this.done(); > }; > >+ Test.prototype.force_timeout = Test.prototype.timeout; >+ > Test.prototype.done = function() > { > if (this.phase == this.phases.COMPLETE) { >@@ -1612,7 +1658,9 @@ policies and contribution forms [3]. > > this.phase = this.phases.COMPLETE; > >- clearTimeout(this.timeout_id); >+ if (global_scope.clearTimeout) { >+ clearTimeout(this.timeout_id); >+ } > tests.result(this); > this.cleanup(); > }; >@@ -1711,7 +1759,13 @@ policies and contribution forms [3]. > this.tests = new Array(); > > var this_obj = this; >- remote.onerror = function(error) { this_obj.remote_error(error); }; >+ // If remote context is cross origin assigning to onerror is not >+ // possible, so silently catch those errors. >+ try { >+ remote.onerror = function(error) { this_obj.remote_error(error); }; >+ } catch (e) { >+ // Ignore. >+ } > > // Keeping a reference to the remote object and the message handler until > // remote_done() is seen prevents the remote object and its message channel >@@ -1726,6 +1780,12 @@ policies and contribution forms [3]. > } > }; > >+ if (self.Promise) { >+ this.done = new Promise(function(resolve) { >+ this_obj.doneResolve = resolve; >+ }); >+ } >+ > this.message_target.addEventListener("message", this.message_handler); > } > >@@ -1775,6 +1835,10 @@ policies and contribution forms [3]. > this.running = false; > this.remote = null; > this.message_target = null; >+ if (this.doneResolve) { >+ this.doneResolve(); >+ } >+ > if (tests.all_done()) { > tests.complete(); > } >@@ -1921,12 +1985,14 @@ policies and contribution forms [3]. > }; > > Tests.prototype.set_timeout = function() { >- var this_obj = this; >- clearTimeout(this.timeout_id); >- if (this.timeout_length !== null) { >- this.timeout_id = setTimeout(function() { >- this_obj.timeout(); >- }, this.timeout_length); >+ if (global_scope.clearTimeout) { >+ var this_obj = this; >+ clearTimeout(this.timeout_id); >+ if (this.timeout_length !== null) { >+ this.timeout_id = setTimeout(function() { >+ this_obj.timeout(); >+ }, this.timeout_length); >+ } > } > }; > >@@ -2084,13 +2150,13 @@ policies and contribution forms [3]. > var message_port; > > if (is_service_worker(worker)) { >- // The ServiceWorker's implicit MessagePort is currently not >- // reliably accessible from the ServiceWorkerGlobalScope due to >- // Blink setting MessageEvent.source to null for messages sent >- // via ServiceWorker.postMessage(). Until that's resolved, >- // create an explicit MessageChannel and pass one end to the >- // worker. >- if (window.MessageChannel && !!window.chrome) { >+ if (window.MessageChannel) { >+ // The ServiceWorker's implicit MessagePort is currently not >+ // reliably accessible from the ServiceWorkerGlobalScope due to >+ // Blink setting MessageEvent.source to null for messages sent >+ // via ServiceWorker.postMessage(). Until that's resolved, >+ // create an explicit MessageChannel and pass one end to the >+ // worker. > var message_channel = new MessageChannel(); > message_port = message_channel.port1; > message_port.start(); >@@ -2131,11 +2197,13 @@ policies and contribution forms [3]. > return; > } > >- this.pending_remotes.push(this.create_remote_worker(worker)); >+ var remoteContext = this.create_remote_worker(worker); >+ this.pending_remotes.push(remoteContext); >+ return remoteContext.done; > }; > > function fetch_tests_from_worker(port) { >- tests.fetch_tests_from_worker(port); >+ return tests.fetch_tests_from_worker(port); > } > expose(fetch_tests_from_worker, 'fetch_tests_from_worker'); > >@@ -2254,12 +2322,37 @@ policies and contribution forms [3]. > } > var node = output_document.getElementById("log"); > if (!node) { >- if (!document.body || document.readyState == "loading") { >+ if (!document.readyState == "loading") { > return; > } >- node = output_document.createElement("div"); >+ node = output_document.createElementNS("http://www.w3.org/1999/xhtml", "div"); > node.id = "log"; >- output_document.body.appendChild(node); >+ if (output_document.body) { >+ output_document.body.appendChild(node); >+ } else { >+ var is_html = false; >+ var is_svg = false; >+ var output_window = output_document.defaultView; >+ if (output_window && "SVGSVGElement" in output_window) { >+ is_svg = output_document.documentElement instanceof output_window.SVGSVGElement; >+ } else if (output_window) { >+ is_html = (output_document.namespaceURI == "http://www.w3.org/1999/xhtml" && >+ output_document.localName == "html"); >+ } >+ if (is_svg) { >+ var foreignObject = output_document.createElementNS("http://www.w3.org/2000/svg", "foreignObject"); >+ foreignObject.setAttribute("width", "100%"); >+ foreignObject.setAttribute("height", "100%"); >+ output_document.documentElement.appendChild(foreignObject); >+ foreignObject.appendChild(node); >+ } else if (is_html) { >+ var body = output_document.createElementNS("http://www.w3.org/1999/xhtml", "body"); >+ output_document.documentElement.appendChild(body); >+ body.appendChild(node); >+ } else { >+ output_document.documentElement.appendChild(node); >+ } >+ } > } > this.output_document = output_document; > this.output_node = node; >@@ -2310,15 +2403,11 @@ policies and contribution forms [3]. > log.removeChild(log.lastChild); > } > >- var harness_url = get_harness_url(); >- if (harness_url !== undefined) { >- var stylesheet = output_document.createElementNS(xhtml_ns, "link"); >- stylesheet.setAttribute("rel", "stylesheet"); >- stylesheet.setAttribute("href", harness_url + "testharness.css"); >- var heads = output_document.getElementsByTagName("head"); >- if (heads.length) { >- heads[0].appendChild(stylesheet); >- } >+ var stylesheet = output_document.createElementNS(xhtml_ns, "style"); >+ stylesheet.textContent = stylesheetContent; >+ var heads = output_document.getElementsByTagName("head"); >+ if (heads.length) { >+ heads[0].appendChild(stylesheet); > } > > var status_text_harness = {}; >@@ -2784,7 +2873,7 @@ policies and contribution forms [3]. > function expose(object, name) > { > var components = name.split("."); >- var target = test_environment.global_scope(); >+ var target = global_scope; > for (var i = 0; i < components.length - 1; i++) { > if (!(components[i] in target)) { > target[components[i]] = {}; >@@ -2806,7 +2895,7 @@ policies and contribution forms [3]. > /** Returns the 'src' URL of the first <script> tag in the page to include the file 'testharness.js'. */ > function get_script_url() > { >- if (!('document' in self)) { >+ if (!('document' in global_scope)) { > return undefined; > } > >@@ -2828,16 +2917,6 @@ policies and contribution forms [3]. > return undefined; > } > >- /** Returns the URL path at which the files for testharness.js are assumed to reside (e.g., '/resources/'). >- The path is derived from inspecting the 'src' of the <script> tag that included 'testharness.js'. */ >- function get_harness_url() >- { >- var script_url = get_script_url(); >- >- // Exclude the 'testharness.js' file from the returned path, but '+ 1' to include the trailing slash. >- return script_url ? script_url.slice(0, script_url.lastIndexOf('/') + 1) : undefined; >- } >- > function supports_post_message(w) > { > var supports; >@@ -2881,38 +2960,148 @@ policies and contribution forms [3]. > > var tests = new Tests(); > >- var error_handler = function(e) { >- if (tests.tests.length === 0 && !tests.allow_uncaught_exception) { >- tests.set_file_is_test(); >- } >+ if (global_scope.addEventListener) { >+ var error_handler = function(e) { >+ if (tests.tests.length === 0 && !tests.allow_uncaught_exception) { >+ tests.set_file_is_test(); >+ } > >- var stack; >- if (e.error && e.error.stack) { >- stack = e.error.stack; >- } else { >- stack = e.filename + ":" + e.lineno + ":" + e.colno; >- } >+ var stack; >+ if (e.error && e.error.stack) { >+ stack = e.error.stack; >+ } else { >+ stack = e.filename + ":" + e.lineno + ":" + e.colno; >+ } > >- if (tests.file_is_test) { >- var test = tests.tests[0]; >- if (test.phase >= test.phases.HAS_RESULT) { >- return; >+ if (tests.file_is_test) { >+ var test = tests.tests[0]; >+ if (test.phase >= test.phases.HAS_RESULT) { >+ return; >+ } >+ test.set_status(test.FAIL, e.message, stack); >+ test.phase = test.phases.HAS_RESULT; >+ test.done(); >+ } else if (!tests.allow_uncaught_exception) { >+ tests.status.status = tests.status.ERROR; >+ tests.status.message = e.message; >+ tests.status.stack = stack; > } >- test.set_status(test.FAIL, e.message, stack); >- test.phase = test.phases.HAS_RESULT; >- test.done(); >- } else if (!tests.allow_uncaught_exception) { >- tests.status.status = tests.status.ERROR; >- tests.status.message = e.message; >- tests.status.stack = stack; >- } >- done(); >- }; >+ done(); >+ }; > >- addEventListener("error", error_handler, false); >- addEventListener("unhandledrejection", function(e){ error_handler(e.reason); }, false); >+ addEventListener("error", error_handler, false); >+ addEventListener("unhandledrejection", function(e){ error_handler(e.reason); }, false); >+ } > > test_environment.on_tests_ready(); > >-})(); >+ /** >+ * Stylesheet >+ */ >+ var stylesheetContent = "\ >+html {\ >+ font-family:DejaVu Sans, Bitstream Vera Sans, Arial, Sans;\ >+}\ >+\ >+#log .warning,\ >+#log .warning a {\ >+ color: black;\ >+ background: yellow;\ >+}\ >+\ >+#log .error,\ >+#log .error a {\ >+ color: white;\ >+ background: red;\ >+}\ >+\ >+section#summary {\ >+ margin-bottom:1em;\ >+}\ >+\ >+table#results {\ >+ border-collapse:collapse;\ >+ table-layout:fixed;\ >+ width:100%;\ >+}\ >+\ >+table#results th:first-child,\ >+table#results td:first-child {\ >+ width:4em;\ >+}\ >+\ >+table#results th:last-child,\ >+table#results td:last-child {\ >+ width:50%;\ >+}\ >+\ >+table#results.assertions th:last-child,\ >+table#results.assertions td:last-child {\ >+ width:35%;\ >+}\ >+\ >+table#results th {\ >+ padding:0;\ >+ padding-bottom:0.5em;\ >+ border-bottom:medium solid black;\ >+}\ >+\ >+table#results td {\ >+ padding:1em;\ >+ padding-bottom:0.5em;\ >+ border-bottom:thin solid black;\ >+}\ >+\ >+tr.pass > td:first-child {\ >+ color:green;\ >+}\ >+\ >+tr.fail > td:first-child {\ >+ color:red;\ >+}\ >+\ >+tr.timeout > td:first-child {\ >+ color:red;\ >+}\ >+\ >+tr.notrun > td:first-child {\ >+ color:blue;\ >+}\ >+\ >+.pass > td:first-child, .fail > td:first-child, .timeout > td:first-child, .notrun > td:first-child {\ >+ font-variant:small-caps;\ >+}\ >+\ >+table#results span {\ >+ display:block;\ >+}\ >+\ >+table#results span.expected {\ >+ font-family:DejaVu Sans Mono, Bitstream Vera Sans Mono, Monospace;\ >+ white-space:pre;\ >+}\ >+\ >+table#results span.actual {\ >+ font-family:DejaVu Sans Mono, Bitstream Vera Sans Mono, Monospace;\ >+ white-space:pre;\ >+}\ >+\ >+span.ok {\ >+ color:green;\ >+}\ >+\ >+tr.error {\ >+ color:red;\ >+}\ >+\ >+span.timeout {\ >+ color:red;\ >+}\ >+\ >+span.ok, span.timeout, span.error {\ >+ font-variant:small-caps;\ >+}\ >+"; >+ >+})(this); > // vim: set expandtab shiftwidth=4 tabstop=4: >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/testharness.js.headers b/LayoutTests/imported/w3c/web-platform-tests/resources/testharness.js.headers >index 6805c323df5a975231648b830e33ce183c3cbbd3..5e8f640c6659d176eaca4c71cc1798b7285540b7 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/testharness.js.headers >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/testharness.js.headers >@@ -1 +1,2 @@ > Content-Type: text/javascript; charset=utf-8 >+Cache-Control: max-age=3600 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/testharnessreport.js.headers b/LayoutTests/imported/w3c/web-platform-tests/resources/testharnessreport.js.headers >index 6805c323df5a975231648b830e33ce183c3cbbd3..5e8f640c6659d176eaca4c71cc1798b7285540b7 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/testharnessreport.js.headers >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/testharnessreport.js.headers >@@ -1 +1,2 @@ > Content-Type: text/javascript; charset=utf-8 >+Cache-Control: max-age=3600 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resources/w3c-import.log >index ecab68c1be8f424cae2e5f1be0b5010d99c02a6a..32a2b80a486c5f579a897c3b510071c81c275f6e 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/w3c-import.log >@@ -17,10 +17,15 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/resources/.htaccess > /LayoutTests/imported/w3c/web-platform-tests/resources/LICENSE > /LayoutTests/imported/w3c/web-platform-tests/resources/OWNERS >+/LayoutTests/imported/w3c/web-platform-tests/resources/check-layout-th.js > /LayoutTests/imported/w3c/web-platform-tests/resources/idlharness.js > /LayoutTests/imported/w3c/web-platform-tests/resources/idlharness.js.headers > /LayoutTests/imported/w3c/web-platform-tests/resources/readme.md > /LayoutTests/imported/w3c/web-platform-tests/resources/sriharness.js >+/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js >+/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js.headers >+/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver.js >+/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver.js.headers > /LayoutTests/imported/w3c/web-platform-tests/resources/testharness.css.headers > /LayoutTests/imported/w3c/web-platform-tests/resources/testharness.js > /LayoutTests/imported/w3c/web-platform-tests/resources/testharness.js.headers >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/CHANGELOG.md b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/CHANGELOG.md >new file mode 100644 >index 0000000000000000000000000000000000000000..1596d71684aa2f8ac6eca009fc6ef5dad43bc7e1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/CHANGELOG.md >@@ -0,0 +1,284 @@ >+# Change Log >+ >+## [v10.2.0](https://github.com/w3c/webidl2.js/tree/v10.2.0) (2018-01-30) >+[Full Changelog](https://github.com/w3c/webidl2.js/compare/v10.1.0...v10.2.0) >+ >+**Merged pull requests:** >+ >+- Type on union idlType [\#135](https://github.com/w3c/webidl2.js/pull/135) ([saschanaz](https://github.com/saschanaz)) >+- feat: add argument/return type [\#134](https://github.com/w3c/webidl2.js/pull/134) ([saschanaz](https://github.com/saschanaz)) >+- feat: add dictionary/typedef-type [\#133](https://github.com/w3c/webidl2.js/pull/133) ([saschanaz](https://github.com/saschanaz)) >+- feat: add const-type for idlTypes [\#132](https://github.com/w3c/webidl2.js/pull/132) ([saschanaz](https://github.com/saschanaz)) >+- feat: add types on idlTypes [\#131](https://github.com/w3c/webidl2.js/pull/131) ([saschanaz](https://github.com/saschanaz)) >+- Auto acquisition for parser result changes [\#130](https://github.com/w3c/webidl2.js/pull/130) ([saschanaz](https://github.com/saschanaz)) >+ >+## [v10.1.0](https://github.com/w3c/webidl2.js/tree/v10.1.0) (2018-01-19) >+[Full Changelog](https://github.com/w3c/webidl2.js/compare/v10.0.0...v10.1.0) >+ >+**Closed issues:** >+ >+- Support `raises` and `setraises` [\#128](https://github.com/w3c/webidl2.js/issues/128) >+- Support `legacycaller` [\#127](https://github.com/w3c/webidl2.js/issues/127) >+- Improve "No semicolon after enum" message [\#119](https://github.com/w3c/webidl2.js/issues/119) >+ >+**Merged pull requests:** >+ >+- Let error messages include the current definition name [\#129](https://github.com/w3c/webidl2.js/pull/129) ([saschanaz](https://github.com/saschanaz)) >+ >+## [v10.0.0](https://github.com/w3c/webidl2.js/tree/v10.0.0) (2017-12-20) >+[Full Changelog](https://github.com/w3c/webidl2.js/compare/v9.0.0...v10.0.0) >+ >+**Closed issues:** >+ >+- Always return an array for idlType, etc. [\#113](https://github.com/w3c/webidl2.js/issues/113) >+- Maintain writer.js or not? [\#109](https://github.com/w3c/webidl2.js/issues/109) >+ >+**Merged pull requests:** >+ >+- Remove typeExtAttrs from docs [\#124](https://github.com/w3c/webidl2.js/pull/124) ([saschanaz](https://github.com/saschanaz)) >+- Remove iterator documentation [\#123](https://github.com/w3c/webidl2.js/pull/123) ([saschanaz](https://github.com/saschanaz)) >+- Maintain writer.js [\#122](https://github.com/w3c/webidl2.js/pull/122) ([saschanaz](https://github.com/saschanaz)) >+- BREAKING CHANGE: remove deprecated iterator operation [\#121](https://github.com/w3c/webidl2.js/pull/121) ([saschanaz](https://github.com/saschanaz)) >+- Use for-of on tests [\#120](https://github.com/w3c/webidl2.js/pull/120) ([saschanaz](https://github.com/saschanaz)) >+- docs\(README\): iterables ildType is always array [\#118](https://github.com/w3c/webidl2.js/pull/118) ([marcoscaceres](https://github.com/marcoscaceres)) >+ >+## [v9.0.0](https://github.com/w3c/webidl2.js/tree/v9.0.0) (2017-11-30) >+[Full Changelog](https://github.com/w3c/webidl2.js/compare/v8.1.0...v9.0.0) >+ >+**Closed issues:** >+ >+- Code quality [\#116](https://github.com/w3c/webidl2.js/issues/116) >+- Unable to parse HTMLAllCollection interface [\#114](https://github.com/w3c/webidl2.js/issues/114) >+- Add support for mixin syntax [\#112](https://github.com/w3c/webidl2.js/issues/112) >+- Whitespace issues [\#111](https://github.com/w3c/webidl2.js/issues/111) >+ >+**Merged pull requests:** >+ >+- Consistent array type for iterable.idlType [\#117](https://github.com/w3c/webidl2.js/pull/117) ([saschanaz](https://github.com/saschanaz)) >+- Revert "chore: drop Node 6 support \(\#102\)" [\#115](https://github.com/w3c/webidl2.js/pull/115) ([TimothyGu](https://github.com/TimothyGu)) >+ >+## [v8.1.0](https://github.com/w3c/webidl2.js/tree/v8.1.0) (2017-11-03) >+[Full Changelog](https://github.com/w3c/webidl2.js/compare/v8.0.1...v8.1.0) >+ >+**Closed issues:** >+ >+- Extended Attributes `rhs` should always be there [\#96](https://github.com/w3c/webidl2.js/issues/96) >+ >+**Merged pull requests:** >+ >+- Always add rhs property [\#110](https://github.com/w3c/webidl2.js/pull/110) ([saschanaz](https://github.com/saschanaz)) >+ >+## [v8.0.1](https://github.com/w3c/webidl2.js/tree/v8.0.1) (2017-11-03) >+[Full Changelog](https://github.com/w3c/webidl2.js/compare/v8.0.0...v8.0.1) >+ >+**Fixed bugs:** >+ >+- Comment order parsing bug [\#107](https://github.com/w3c/webidl2.js/issues/107) >+ >+**Merged pull requests:** >+ >+- Remove m postfix from all\_ws\(\) [\#108](https://github.com/w3c/webidl2.js/pull/108) ([saschanaz](https://github.com/saschanaz)) >+ >+## [v8.0.0](https://github.com/w3c/webidl2.js/tree/v8.0.0) (2017-11-03) >+[Full Changelog](https://github.com/w3c/webidl2.js/compare/v7.0.0...v8.0.0) >+ >+**Closed issues:** >+ >+- Remove creators support [\#100](https://github.com/w3c/webidl2.js/issues/100) >+- Add mixin support [\#92](https://github.com/w3c/webidl2.js/issues/92) >+ >+**Merged pull requests:** >+ >+- Support mixins + includes statements [\#105](https://github.com/w3c/webidl2.js/pull/105) ([saschanaz](https://github.com/saschanaz)) >+- chore: drop Node 6 support [\#102](https://github.com/w3c/webidl2.js/pull/102) ([marcoscaceres](https://github.com/marcoscaceres)) >+- BREAKING CHANGE: drop creator support [\#101](https://github.com/w3c/webidl2.js/pull/101) ([saschanaz](https://github.com/saschanaz)) >+- Normalize some whitespace to pass wpt's lint [\#99](https://github.com/w3c/webidl2.js/pull/99) ([foolip](https://github.com/foolip)) >+ >+## [v7.0.0](https://github.com/w3c/webidl2.js/tree/v7.0.0) (2017-10-27) >+[Full Changelog](https://github.com/w3c/webidl2.js/compare/v6.1.0...v7.0.0) >+ >+**Closed issues:** >+ >+- Type conversion on default values is destructive [\#94](https://github.com/w3c/webidl2.js/issues/94) >+- extended attribute structure missing type [\#89](https://github.com/w3c/webidl2.js/issues/89) >+ >+**Merged pull requests:** >+ >+- BREAKING CHANGE: argument + default types should be string [\#95](https://github.com/w3c/webidl2.js/pull/95) ([marcoscaceres](https://github.com/marcoscaceres)) >+ >+## [v6.1.0](https://github.com/w3c/webidl2.js/tree/v6.1.0) (2017-10-23) >+[Full Changelog](https://github.com/w3c/webidl2.js/compare/v6.0.1...v6.1.0) >+ >+**Merged pull requests:** >+ >+- feat: give extended attributes a type [\#90](https://github.com/w3c/webidl2.js/pull/90) ([marcoscaceres](https://github.com/marcoscaceres)) >+ >+## [v6.0.1](https://github.com/w3c/webidl2.js/tree/v6.0.1) (2017-10-18) >+[Full Changelog](https://github.com/w3c/webidl2.js/compare/v6.0.0...v6.0.1) >+ >+**Closed issues:** >+ >+- Enum values should be objects [\#86](https://github.com/w3c/webidl2.js/issues/86) >+ >+**Merged pull requests:** >+ >+- Use ES2015 syntax for tests [\#88](https://github.com/w3c/webidl2.js/pull/88) ([saschanaz](https://github.com/saschanaz)) >+ >+## [v6.0.0](https://github.com/w3c/webidl2.js/tree/v6.0.0) (2017-10-17) >+[Full Changelog](https://github.com/w3c/webidl2.js/compare/v5.0.0...v6.0.0) >+ >+**Merged pull requests:** >+ >+- BREAKING CHANGE: ret enum value as object [\#87](https://github.com/w3c/webidl2.js/pull/87) ([marcoscaceres](https://github.com/marcoscaceres)) >+ >+## [v5.0.0](https://github.com/w3c/webidl2.js/tree/v5.0.0) (2017-10-17) >+[Full Changelog](https://github.com/w3c/webidl2.js/compare/v4.2.0...v5.0.0) >+ >+**Closed issues:** >+ >+- Unable to parse annotated types in generics [\#83](https://github.com/w3c/webidl2.js/issues/83) >+- Drop support for Node 4, move to 6 LTS [\#82](https://github.com/w3c/webidl2.js/issues/82) >+ >+**Merged pull requests:** >+ >+- BREAKING CHANGE: Use ES2015 syntax [\#84](https://github.com/w3c/webidl2.js/pull/84) ([saschanaz](https://github.com/saschanaz)) >+ >+## [v4.2.0](https://github.com/w3c/webidl2.js/tree/v4.2.0) (2017-10-16) >+[Full Changelog](https://github.com/w3c/webidl2.js/compare/v4.1.0...v4.2.0) >+ >+**Closed issues:** >+ >+- Remove legacy caller support [\#78](https://github.com/w3c/webidl2.js/issues/78) >+- Should report error for using duplicate names [\#77](https://github.com/w3c/webidl2.js/issues/77) >+ >+**Merged pull requests:** >+ >+- Check duplicated names [\#80](https://github.com/w3c/webidl2.js/pull/80) ([saschanaz](https://github.com/saschanaz)) >+- Remove legacycaller [\#79](https://github.com/w3c/webidl2.js/pull/79) ([saschanaz](https://github.com/saschanaz)) >+- Add "sequence" property to IDL Type AST definition [\#76](https://github.com/w3c/webidl2.js/pull/76) ([lerouche](https://github.com/lerouche)) >+ >+## [v4.1.0](https://github.com/w3c/webidl2.js/tree/v4.1.0) (2017-07-04) >+[Full Changelog](https://github.com/w3c/webidl2.js/compare/v4.0.0...v4.1.0) >+ >+**Closed issues:** >+ >+- Parsing error for annonated inner types of generic types [\#71](https://github.com/w3c/webidl2.js/issues/71) >+ >+**Merged pull requests:** >+ >+- Support TypeWithExtendedAttributes on generics [\#75](https://github.com/w3c/webidl2.js/pull/75) ([saschanaz](https://github.com/saschanaz)) >+ >+## [v4.0.0](https://github.com/w3c/webidl2.js/tree/v4.0.0) (2017-06-27) >+[Full Changelog](https://github.com/w3c/webidl2.js/compare/v3.0.2...v4.0.0) >+ >+**Closed issues:** >+ >+- Remove serializer-related productions [\#73](https://github.com/w3c/webidl2.js/issues/73) >+- Records don't seem to be working right [\#72](https://github.com/w3c/webidl2.js/issues/72) >+- Document namespace member output [\#59](https://github.com/w3c/webidl2.js/issues/59) >+ >+**Merged pull requests:** >+ >+- BREAKING CHANGE: remove serializers \(closes \#73\) [\#74](https://github.com/w3c/webidl2.js/pull/74) ([marcoscaceres](https://github.com/marcoscaceres)) >+- Add documentation for namespaces [\#70](https://github.com/w3c/webidl2.js/pull/70) ([saschanaz](https://github.com/saschanaz)) >+ >+## [v3.0.2](https://github.com/w3c/webidl2.js/tree/v3.0.2) (2017-05-29) >+[Full Changelog](https://github.com/w3c/webidl2.js/compare/v3.0.1...v3.0.2) >+ >+**Closed issues:** >+ >+- Whitespace issues [\#64](https://github.com/w3c/webidl2.js/issues/64) >+ >+**Merged pull requests:** >+ >+- Test for latest LTS/stable node versions [\#69](https://github.com/w3c/webidl2.js/pull/69) ([saschanaz](https://github.com/saschanaz)) >+ >+## [v3.0.1](https://github.com/w3c/webidl2.js/tree/v3.0.1) (2017-05-18) >+[Full Changelog](https://github.com/w3c/webidl2.js/compare/v2.4.0...v3.0.1) >+ >+**Closed issues:** >+ >+- Is array syntax dead? [\#66](https://github.com/w3c/webidl2.js/issues/66) >+- Remove exceptions support [\#65](https://github.com/w3c/webidl2.js/issues/65) >+ >+**Merged pull requests:** >+ >+- Fix whitespace error on parsing extended attributes [\#68](https://github.com/w3c/webidl2.js/pull/68) ([saschanaz](https://github.com/saschanaz)) >+- Remove deprecated IDL arrays and exceptions [\#67](https://github.com/w3c/webidl2.js/pull/67) ([saschanaz](https://github.com/saschanaz)) >+ >+## [v2.4.0](https://github.com/w3c/webidl2.js/tree/v2.4.0) (2017-04-12) >+[Full Changelog](https://github.com/w3c/webidl2.js/compare/v2.1.0...v2.4.0) >+ >+**Closed issues:** >+ >+- Add support for Annotated Types [\#60](https://github.com/w3c/webidl2.js/issues/60) >+- Question: Convert WebIDL -\> Javascript [\#56](https://github.com/w3c/webidl2.js/issues/56) >+- Get Robin to give us push permissions on npm [\#54](https://github.com/w3c/webidl2.js/issues/54) >+- Add support for records [\#53](https://github.com/w3c/webidl2.js/issues/53) >+- module not supported? [\#52](https://github.com/w3c/webidl2.js/issues/52) >+- Add support for namespaces [\#51](https://github.com/w3c/webidl2.js/issues/51) >+- Export is not AMD compatible [\#48](https://github.com/w3c/webidl2.js/issues/48) >+- Can't represent large constants [\#21](https://github.com/w3c/webidl2.js/issues/21) >+ >+**Merged pull requests:** >+ >+- Update webidl2.js [\#63](https://github.com/w3c/webidl2.js/pull/63) ([tqeto](https://github.com/tqeto)) >+- Remove support for MapClass \(no longer valid in WebIDL\) [\#62](https://github.com/w3c/webidl2.js/pull/62) ([dontcallmedom](https://github.com/dontcallmedom)) >+- Add support for annotated types [\#61](https://github.com/w3c/webidl2.js/pull/61) ([dontcallmedom](https://github.com/dontcallmedom)) >+- Support namespaces [\#58](https://github.com/w3c/webidl2.js/pull/58) ([saschanaz](https://github.com/saschanaz)) >+- Add support for records [\#57](https://github.com/w3c/webidl2.js/pull/57) ([TimothyGu](https://github.com/TimothyGu)) >+- Refactor [\#50](https://github.com/w3c/webidl2.js/pull/50) ([marcoscaceres](https://github.com/marcoscaceres)) >+- feat\(lib\): add AMD export support \(closes \#48\) [\#49](https://github.com/w3c/webidl2.js/pull/49) ([marcoscaceres](https://github.com/marcoscaceres)) >+ >+## [v2.1.0](https://github.com/w3c/webidl2.js/tree/v2.1.0) (2016-08-12) >+**Closed issues:** >+ >+- Exception when parsing test/syntax/idl/typedef.widl [\#46](https://github.com/w3c/webidl2.js/issues/46) >+- Wrong jsondiffpatch location [\#42](https://github.com/w3c/webidl2.js/issues/42) >+- 'npm install' fails on building microtime [\#40](https://github.com/w3c/webidl2.js/issues/40) >+- Can't represent union types in typedefs [\#38](https://github.com/w3c/webidl2.js/issues/38) >+- tokenise\(\) assumes a specific property enumeration order [\#27](https://github.com/w3c/webidl2.js/issues/27) >+- Add support for iterable\<\>, maplike\<\>, setlike\<\> declarations [\#24](https://github.com/w3c/webidl2.js/issues/24) >+- WebIDL2 fails to parse `attribute Promise\<DOMString\>\[\] baz` [\#19](https://github.com/w3c/webidl2.js/issues/19) >+- Support for ExtendedAttributeIdentList \(current editor's draft\) [\#18](https://github.com/w3c/webidl2.js/issues/18) >+- No Licensing Information [\#17](https://github.com/w3c/webidl2.js/issues/17) >+- how to regenerate w3c idl files ? [\#14](https://github.com/w3c/webidl2.js/issues/14) >+- What is lib/writer.js [\#13](https://github.com/w3c/webidl2.js/issues/13) >+- Numerous tests are failing [\#7](https://github.com/w3c/webidl2.js/issues/7) >+- Add support for missing types in ServiceWorker [\#5](https://github.com/w3c/webidl2.js/issues/5) >+- How can I parse just a function? [\#3](https://github.com/w3c/webidl2.js/issues/3) >+- Parser throws on nullable array of nullable array [\#2](https://github.com/w3c/webidl2.js/issues/2) >+- Parser throws on nullable array of any [\#1](https://github.com/w3c/webidl2.js/issues/1) >+ >+**Merged pull requests:** >+ >+- Fix "default": undefined [\#47](https://github.com/w3c/webidl2.js/pull/47) ([mkwtys](https://github.com/mkwtys)) >+- Replace expect.js with expct [\#45](https://github.com/w3c/webidl2.js/pull/45) ([halton](https://github.com/halton)) >+- Correct jsondiffpatch location. [\#44](https://github.com/w3c/webidl2.js/pull/44) ([halton](https://github.com/halton)) >+- Bump microtime to 2.1.1 [\#43](https://github.com/w3c/webidl2.js/pull/43) ([halton](https://github.com/halton)) >+- Expand writer support [\#39](https://github.com/w3c/webidl2.js/pull/39) ([markandrus](https://github.com/markandrus)) >+- Accept wider \(but still incomplete\) set of allowed syntax for extended attributes [\#37](https://github.com/w3c/webidl2.js/pull/37) ([mlogan](https://github.com/mlogan)) >+- Add test for callback with multiple arguments. [\#36](https://github.com/w3c/webidl2.js/pull/36) ([tobie](https://github.com/tobie)) >+- Iterables [\#34](https://github.com/w3c/webidl2.js/pull/34) ([motiz88](https://github.com/motiz88)) >+- Allow trailing comma in enum value lists, per spec [\#33](https://github.com/w3c/webidl2.js/pull/33) ([motiz88](https://github.com/motiz88)) >+- Allow typedefs within interfaces \(behind an opt-in flag\) [\#32](https://github.com/w3c/webidl2.js/pull/32) ([motiz88](https://github.com/motiz88)) >+- In draft [\#31](https://github.com/w3c/webidl2.js/pull/31) ([othree](https://github.com/othree)) >+- Add support for extended attributes identifier lists [\#29](https://github.com/w3c/webidl2.js/pull/29) ([tobie](https://github.com/tobie)) >+- Make `attribute Promise\<T\>\[\] attr;` work. [\#26](https://github.com/w3c/webidl2.js/pull/26) ([jyasskin](https://github.com/jyasskin)) >+- Parse required dictionary fields. [\#25](https://github.com/w3c/webidl2.js/pull/25) ([jyasskin](https://github.com/jyasskin)) >+- Define the WebIDL2 property on self rather than window. [\#23](https://github.com/w3c/webidl2.js/pull/23) ([Ms2ger](https://github.com/Ms2ger)) >+- Teach WebIDL2 to parse \[\] default values. [\#22](https://github.com/w3c/webidl2.js/pull/22) ([jyasskin](https://github.com/jyasskin)) >+- Support ID list in extended attributes [\#20](https://github.com/w3c/webidl2.js/pull/20) ([othree](https://github.com/othree)) >+- Make sure that `sequence` property of idl types is set to false if the type is actually `sequence`. [\#16](https://github.com/w3c/webidl2.js/pull/16) ([tobie](https://github.com/tobie)) >+- Parametrized [\#15](https://github.com/w3c/webidl2.js/pull/15) ([tobie](https://github.com/tobie)) >+- Add promise support [\#12](https://github.com/w3c/webidl2.js/pull/12) ([tobie](https://github.com/tobie)) >+- Remove broken coverage support from travis for now. [\#11](https://github.com/w3c/webidl2.js/pull/11) ([tobie](https://github.com/tobie)) >+- Add support for \[MapClass\(type, type\)\]. [\#10](https://github.com/w3c/webidl2.js/pull/10) ([tobie](https://github.com/tobie)) >+- Incorporate tests from widlproc\[1\] and remove dependency on said project. [\#9](https://github.com/w3c/webidl2.js/pull/9) ([tobie](https://github.com/tobie)) >+- README incorrectly recommended updating the widlproc submodule. [\#8](https://github.com/w3c/webidl2.js/pull/8) ([tobie](https://github.com/tobie)) >+- Fix bug where instrumented version of webidl2 was loaded. [\#6](https://github.com/w3c/webidl2.js/pull/6) ([tobie](https://github.com/tobie)) >+- Use https:// instead of git:// [\#4](https://github.com/w3c/webidl2.js/pull/4) ([Manishearth](https://github.com/Manishearth)) >+ >+ >+ >+\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/README.md b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/README.md >index 5d128ed27ca87cc76f15caeb63c9ceec0d8aa790..8791360d1c132d15e15a132c9ae377a14530f405 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/README.md >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/README.md >@@ -1,7 +1,7 @@ > > # WebIDL 2 > >-[](http://badge.fury.io/js/webidl2) >+[](http://badge.fury.io/js/webidl2) > > ## Purpose > >@@ -10,26 +10,6 @@ you don't know what that is, then you probably don't need it. It is meant to be > both in Node and in the browser (the parser likely works in other JS environments, but > not the test suite). > >-### What of v1? >- >-There was a previous incarnation of this project. I had written it in the most quick >-and dirty manner that was handy because I required it as a dependency in an experiment. >-As these things tend to happen, some people started using that, which then had to be >-maintained. But since it was not built on solid foundations, it was painful to keep >-up to date with the specification, which is a bit of a moving target. >- >-So I started from scratch. Compared to the previous version (which used a parser generator) >-this one is about 6x less code (which translates to 4x smaller minified or 2x smaller >-minizipped) and 4x faster. The test suite is reasonably complete (95% coverage), much more >-than previously. This version is up to date with WebIDL, rather than a couple years' behind. >-It also has *far* better error reporting. >- >-The AST you get from parsing is very similar to the one you got in v1, but some adjustments >-have been made in order to be more systematic, and to map better to what's actually in the spec >-now. If you used v1, you will need to tweak your code but the result ought to be simpler and >-you ought to be able to be a fair bit less defensive against irregularities in the way >-information is represented. >- > ## Installation > > Just the usual. For Node: >@@ -46,7 +26,6 @@ In the browser: > > ## Documentation > >- > The API to WebIDL2 is trivial: you parse a string of WebIDL and it returns a syntax tree. > > ### Parsing >@@ -103,7 +82,7 @@ The `parse()` method returns a tree object representing the parse tree of the ID > Comment and white space are not represented in the AST. > > The root of this object is always an array of definitions (where definitions are >-any of interfaces, exceptions, callbacks, etc. â anything that can occur at the root >+any of interfaces, dictionaries, callbacks, etc. â anything that can occur at the root > of the IDL). > > ### IDL Type >@@ -114,7 +93,7 @@ attached to a field called `idlType`: > > ```JS > { >- "array": false, >+ "sequence": false, > "generic": null, > "idlType": "void", > "nullable": false, >@@ -124,8 +103,7 @@ attached to a field called `idlType`: > > Where the fields are as follows: > >-* `array`: Either `false` to indicate that it is not an array, or a number for the level of >- array nesting. >+* `sequence`: Boolean indicating if it is a sequence. Same as `generic === "sequence"`. > * `generic`: String indicating the generic type (e.g. "Promise", "sequence"). `null` > otherwise. > * `idlType`: Can be different things depending on context. In most cases, this will just >@@ -136,40 +114,8 @@ Where the fields are as follows: > * `nullable`: Boolean indicating whether this is nullable or not. > * `union`: Boolean indicating whether this is a union type or not. > >-#### Interactions between `nullable` and `array` >- >-A more complex data model for our AST would likely represent `Foo[][][]` as a series of >-nested types four levels deep with three anonymous array types eventually containing a >-`Foo` type. But experience shows that such structures are cumbersome to use, and so we >-have a simpler model in which the depth of the array is specified with the `array` field. >- >-This is all fine and well, and in the vast majority of cases is actually simpler. But it >-does run afoul of cases in which it is necessary to distinguish between `Foo[][][]?`, >-`Foo?[][][]`, `Foo[][]?[]`, or even `Foo?[]?[]?[]?`. >- >-For this, when a type is an array type an additional `nullableArray` field is made available >-that captures which of the arrays contain nullable elements. It contains booleans that are >-true if the given array depth contains nullable elements, and false otherwise (mapping that to >-the syntax, and item is true if there is a `?` preceding the `[]`). These examples ought to >-clarify the model: >- >- Foo[][][]? >- -> nullable: true >- -> nullableArray: [false, false, false] >- Foo?[][][] >- -> nullable: false >- -> nullableArray: [true, false, false] >- Foo[][]?[] >- -> nullable: false >- -> nullableArray: [false, false, true] >- Foo?[]?[]?[]? >- -> nullable: true >- -> nullableArray: [true, true, true] >- >-Of particular importance, please note that the overall type is only `nullable` if there is >-a `?` at the end. >- > ### Interface >+ > Interfaces look like this: > > ```JS >@@ -193,7 +139,7 @@ Interfaces look like this: > The fields are as follows: > > * `type`: Always "interface". >-* `name`: The name of the interface >+* `name`: The name of the interface. > * `partial`: A boolean indicating whether it's a partial interface. > * `members`: An array of interface members (attributes, operations, etc.). Empty if there are none. > * `inheritance`: A string giving the name of an interface this one inherits from, `null` otherwise. >@@ -201,6 +147,56 @@ The fields are as follows: > sense. > * `extAttrs`: A list of [extended attributes](#extended-attributes). > >+### Interface mixins >+ >+Interfaces mixins look like this: >+ >+```JS >+{ >+ "type": "interface mixin", >+ "name": "Animal", >+ "partial": false, >+ "members": [...], >+ "extAttrs": [...] >+}, { >+ "type": "interface mixin", >+ "name": "Human", >+ "partial": false, >+ "members": [...], >+ "extAttrs": [...] >+} >+``` >+ >+The fields are as follows: >+ >+* `type`: Always "interface mixin". >+* `name`: The name of the interface mixin. >+* `partial`: A boolean indicating whether it's a partial interface mixin. >+* `members`: An array of interface members (attributes, operations, etc.). Empty if there are none. >+* `extAttrs`: A list of [extended attributes](#extended-attributes). >+ >+### Namespace >+ >+Namespaces look like this: >+ >+```JS >+{ >+ "type": "namespace", >+ "name": "Console", >+ "partial": false, >+ "members": [...], >+ "extAttrs": [...] >+} >+``` >+ >+The fields are as follows: >+ >+* `type`: Always "namespace". >+* `name`: The name of the namespace. >+* `partial`: A boolean indicating whether it's a partial namespace. >+* `members`: An array of namespace members (attributes and operations). Empty if there are none. >+* `extAttrs`: A list of [extended attributes](#extended-attributes). >+ > ### Callback Interfaces > > These are captured by the same structure as [Interfaces](#interface) except that >@@ -218,7 +214,6 @@ A callback looks like this: > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -252,7 +247,6 @@ A dictionary looks like this: > "sequence": false, > "generic": null, > "nullable": true, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -285,47 +279,6 @@ All the members are fields as follows: > * `extAttrs`: A list of [extended attributes](#extended-attributes). > * `default`: A [default value](#default-and-const-values), absent if there is none. > >-### Exception >- >-An exception looks like this: >- >-```JS >-{ >- "type": "exception", >- "name": "HierarchyRequestError", >- "members": [{ >- "type": "field", >- "name": "code", >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "unsigned short" >- }, >- "extAttrs": [] >- }], >- "inheritance": "DOMException", >- "extAttrs": [] >-} >-``` >- >-The fields are as follows: >- >-* `type`: Always "exception". >-* `name`: The exception name. >-* `members`: An array of members (constants or fields, where fields are described below). >-* `inheritance`: A string indicating which exception is being inherited from, `null` otherwise. >-* `extAttrs`: A list of [extended attributes](#extended-attributes). >- >-Members that aren't [constants](#constants) have the following fields: >- >-* `type`: Always "field". >-* `name`: The field's name. >-* `idlType`: An [IDL Type](#idl-type) describing what field's type. >-* `extAttrs`: A list of [extended attributes](#extended-attributes). >- > ### Enum > > An enum looks like this: >@@ -335,9 +288,9 @@ An enum looks like this: > "type": "enum", > "name": "MealType", > "values": [ >- "rice", >- "noodles", >- "other" >+ { "type": "string", "value": "rice" }, >+ { "type": "string", "value": "noodles" }, >+ { "type": "string", "value": "other" } > ], > "extAttrs": [] > } >@@ -347,7 +300,7 @@ The fields are as follows: > > * `type`: Always "enum". > * `name`: The enum's name. >-* `value`: An array of values (strings). >+* `values`: An array of values. > * `extAttrs`: A list of [extended attributes](#extended-attributes). > > ### Typedef >@@ -357,18 +310,15 @@ A typedef looks like this: > ```JS > { > "type": "typedef", >- "typeExtAttrs": [], > "idlType": { > "sequence": true, > "generic": "sequence", > "nullable": false, >- "array": false, > "union": false, > "idlType": { > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Point" > } >@@ -385,8 +335,6 @@ The fields are as follows: > * `name`: The typedef's name. > * `idlType`: An [IDL Type](#idl-type) describing what typedef's type. > * `extAttrs`: A list of [extended attributes](#extended-attributes). >-* `typeExtAttrs`: A list of [extended attributes](#extended-attributes) that apply to the >-type rather than to the typedef as a whole. > > ### Implements > >@@ -408,6 +356,26 @@ The fields are as follows: > * `implements`: The interface that is being implemented by the target. > * `extAttrs`: A list of [extended attributes](#extended-attributes). > >+### Includes >+ >+An includes definition looks like this: >+ >+```JS >+{ >+ "type": "includes", >+ "target": "Node", >+ "includes": "EventTarget", >+ "extAttrs": [] >+} >+``` >+ >+The fields are as follows: >+ >+* `type`: Always "includes". >+* `target`: The interface that includes an interface mixin. >+* `includes`: The interface mixin that is being included by the target. >+* `extAttrs`: A list of [extended attributes](#extended-attributes). >+ > ### Operation Member > > An operation looks like this: >@@ -416,16 +384,13 @@ An operation looks like this: > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -438,7 +403,6 @@ An operation looks like this: > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "long" > }, >@@ -453,9 +417,7 @@ The fields are as follows: > * `type`: Always "operation". > * `getter`: True if a getter operation. > * `setter`: True if a setter operation. >-* `creator`: True if a creator operation. > * `deleter`: True if a deleter operation. >-* `legacycaller`: True if a legacycaller operation. > * `static`: True if a static operation. > * `stringifier`: True if a stringifier operation. > * `idlType`: An [IDL Type](#idl-type) of what the operation returns. If a stringifier, may be absent. >@@ -478,7 +440,6 @@ An attribute member looks like this: > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "RegExp" > }, >@@ -525,127 +486,6 @@ The fields are as follows: > * `value`: The constant value as described by [Const Values](#default-and-const-values) > * `extAttrs`: A list of [extended attributes](#extended-attributes). > >-### Serializer Member >- >-Serializers come in many shapes, which are best understood by looking at the >-examples below that map the IDL to the produced AST. >- >-```JS >-// serializer; >-{ >- "type": "serializer", >- "extAttrs": [] >-} >- >-// serializer DOMString serialize(); >-{ >- "type": "serializer", >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "DOMString" >- }, >- "operation": { >- "name": "serialize", >- "arguments": [] >- }, >- "extAttrs": [] >-} >- >-// serializer = { from, to, amount, description }; >-{ >- "type": "serializer", >- "patternMap": true, >- "names": [ >- "from", >- "to", >- "amount", >- "description" >- ], >- "extAttrs": [] >-} >- >-// serializer = number; >-{ >- "type": "serializer", >- "name": "number", >- "extAttrs": [] >-} >- >-// serializer = [ name, number ]; >-{ >- "type": "serializer", >- "patternList": true, >- "names": [ >- "name", >- "number" >- ], >- "extAttrs": [] >-} >- >-``` >- >-The common fields are as follows: >- >-* `type`: Always "serializer". >-* `extAttrs`: A list of [extended attributes](#extended-attributes). >- >-For a simple serializer, that's all there is. If the serializer is an operation, it will >-have: >- >-* `idlType`: An [IDL Type](#idl-type) describing what the serializer returns. >-* `operation`: An object with the following fields: >- * `name`: The name of the operation. >- * `arguments`: An array of [arguments](#arguments) for the operation. >- >-If the serializer is a pattern map: >- >-* `patternMap`: Always true. >-* `names`: An array of names in the pattern map. >- >-If the serializer is a pattern list: >- >-* `patternList`: Always true. >-* `names`: An array of names in the pattern list. >- >-Finally, if the serializer is a named serializer: >- >-* `name`: The serializer's name. >- >-### Iterator Member >- >-Iterator members look like this >- >-```JS >-{ >- "type": "iterator", >- "getter": false, >- "setter": false, >- "creator": false, >- "deleter": false, >- "legacycaller": false, >- "static": false, >- "stringifier": false, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "Session2" >- }, >- "iteratorObject": "SessionIterator", >- "extAttrs": [] >-} >-``` >- >-* `type`: Always "iterator". >-* `iteratorObject`: The string on the right-hand side; absent if there isn't one. >-* the rest: same as on [operations](#operation-member). >- > ### Arguments > > The arguments (e.g. for an operation) look like this: >@@ -660,7 +500,6 @@ The arguments (e.g. for an operation) look like this: > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "long" > }, >@@ -686,6 +525,7 @@ Extended attributes are arrays of items that look like this: > "extAttrs": [{ > "name": "TreatNullAs", > "arguments": null, >+ "type": "extended-attribute", > "rhs": { > "type": "identifier", > "value": "EmptyString" >@@ -703,6 +543,7 @@ The fields are as follows: > whereas the lack thereof will yield a `null`. If there is an `rhs` field then > they are the right-hand side's arguments, otherwise they apply to the extended > attribute directly. >+* `type`: Always `"extended-attribute"`. > * `rhs`: If there is a right-hand side, this will capture its `type` (which can be > "identifier" or "identifier-list") and its `value`. > * `typePair`: If the extended attribute is a `MapClass` this will capture the >@@ -717,7 +558,7 @@ values, all of which have the following fields: > > For string, number, boolean, and sequence: > >-* `value`: The value of the given type. For sequence, the only possible value is `[]`. >+* `value`: The value of the given type, as a string. For sequence, the only possible value is `[]`. > > For Infinity: > >@@ -739,7 +580,7 @@ These appear as members of interfaces that look like this: > The fields are as follows: > > * `type`: Always one of "iterable", "legacyiterable", "maplike" or "setlike". >-* `idlType`: An [IDL Type](#idl-type) (or an array of two types) representing the declared type arguments. >+* `idlType`: An array with one or more [IDL Types](#idl-type) representing the declared type arguments. > * `readonly`: Whether the maplike or setlike is declared as read only. > * `extAttrs`: A list of [extended attributes](#extended-attributes). > >@@ -787,8 +628,3 @@ In order to test in the browser, get inside `test/web` and run `make-web-tests.j > will generate a `browser-tests.html` file that you can open in a browser. As of this > writing tests pass in the latest Firefox, Chrome, Opera, and Safari. Testing on IE > and older versions will happen progressively. >- >-## TODO >- >-* add some tests to address coverage limitations >-* add a push API for processors that need to process things like comments >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/lib/webidl2.js b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/lib/webidl2.js >index 0c9a1faacf7c7403bc5b0dbe12f524aefc9f3840..a7a61d957b55c54eb488999d8a77aabc1f1de1f2 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/lib/webidl2.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/lib/webidl2.js >@@ -1,33 +1,82 @@ > "use strict"; > > (() => { >+ // These regular expressions use the sticky flag so they will only match at >+ // the current location (ie. the offset of lastIndex). >+ const tokenRe = { >+ // This expression uses a lookahead assertion to catch false matches >+ // against integers early. >+ "float": /-?(?=[0-9]*\.|[0-9]+[eE])(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][-+]?[0-9]+)?|[0-9]+[Ee][-+]?[0-9]+)/y, >+ "integer": /-?(0([Xx][0-9A-Fa-f]+|[0-7]*)|[1-9][0-9]*)/y, >+ "identifier": /[A-Z_a-z][0-9A-Z_a-z-]*/y, >+ "string": /"[^"]*"/y, >+ "whitespace": /[\t\n\r ]+/y, >+ "comment": /((\/(\/.*|\*([^*]|\*[^\/])*\*\/)[\t\n\r ]*)+)/y, >+ "other": /[^\t\n\r 0-9A-Z_a-z]/y >+ }; >+ >+ function attemptTokenMatch(str, type, re, lastIndex, tokens) { >+ re.lastIndex = lastIndex; >+ const result = re.exec(str); >+ if (result) { >+ tokens.push({ type, value: result[0] }); >+ return re.lastIndex; >+ } >+ return -1; >+ } >+ > function tokenise(str) { > const tokens = []; >- const re = { >- "float": /^-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][-+]?[0-9]+)?|[0-9]+[Ee][-+]?[0-9]+)/, >- "integer": /^-?(0([Xx][0-9A-Fa-f]+|[0-7]*)|[1-9][0-9]*)/, >- "identifier": /^[A-Z_a-z][0-9A-Z_a-z-]*/, >- "string": /^"[^"]*"/, >- "whitespace": /^(?:[\t\n\r ]+|[\t\n\r ]*((\/\/.*|\/\*(.|\n|\r)*?\*\/)[\t\n\r ]*))+/, >- "other": /^[^\t\n\r 0-9A-Z_a-z]/ >- }; >- const types = ["float", "integer", "identifier", "string", "whitespace", "other"]; >- while (str.length > 0) { >- let matched = false; >- for (var i in types) { >- const type = types[i]; >- str = str.replace(re[type], tok => { >- tokens.push({ type, value: tok }); >- matched = true; >- return ""; >- }); >- if (matched) break; >+ let lastIndex = 0; >+ while (lastIndex < str.length) { >+ const nextChar = str.charAt(lastIndex); >+ let result = -1; >+ if (/[-0-9.]/.test(nextChar)) { >+ result = attemptTokenMatch(str, "float", tokenRe.float, lastIndex, >+ tokens); >+ if (result === -1) { >+ result = attemptTokenMatch(str, "integer", tokenRe.integer, lastIndex, >+ tokens); >+ } >+ if (result === -1) { >+ // '-' and '.' can also match "other". >+ result = attemptTokenMatch(str, "other", tokenRe.other, >+ lastIndex, tokens); >+ } >+ } else if (/[A-Z_a-z]/.test(nextChar)) { >+ result = attemptTokenMatch(str, "identifier", tokenRe.identifier, >+ lastIndex, tokens); >+ } else if (nextChar === '"') { >+ result = attemptTokenMatch(str, "string", tokenRe.string, >+ lastIndex, tokens); >+ if (result === -1) { >+ // '"' can also match "other". >+ result = attemptTokenMatch(str, "other", tokenRe.other, >+ lastIndex, tokens); >+ } >+ } else if (/[\t\n\r ]/.test(nextChar)) { >+ result = attemptTokenMatch(str, "whitespace", tokenRe.whitespace, >+ lastIndex, tokens); >+ } else if (nextChar === '/') { >+ // The parser expects comments to be labelled as "whitespace". >+ result = attemptTokenMatch(str, "whitespace", tokenRe.comment, >+ lastIndex, tokens); >+ if (result === -1) { >+ // '/' can also match "other". >+ result = attemptTokenMatch(str, "other", tokenRe.other, >+ lastIndex, tokens); >+ } >+ } else { >+ result = attemptTokenMatch(str, "other", tokenRe.other, >+ lastIndex, tokens); >+ } >+ if (result === -1) { >+ throw new Error("Token stream not progressing"); > } >- if (matched) continue; >- throw new Error("Token stream not progressing"); >+ lastIndex = result; > } > return tokens; >- }; >+ } > > class WebIDLParseError { > constructor(str, line, input, tokens) { >@@ -46,6 +95,7 @@ > let line = 1; > tokens = tokens.slice(); > const names = new Map(); >+ let current = null; > > const FLOAT = "float"; > const INT = "integer"; >@@ -58,7 +108,7 @@ > getter: false, > setter: false, > deleter: false, >- "static": false, >+ static: false, > stringifier: false > }); > >@@ -70,8 +120,18 @@ > tok += tokens[numTokens].value; > numTokens++; > } >- throw new WebIDLParseError(str, line, tok, tokens.slice(0, maxTokens)); >- }; >+ >+ let message; >+ if (current) { >+ message = `Got an error during or right after parsing \`${current.partial ? "partial " : ""}${current.type} ${current.name}\`: ${str}` >+ } >+ else { >+ // throwing before any valid definition >+ message = `Got an error before parsing any named definition: ${str}`; >+ } >+ >+ throw new WebIDLParseError(message, line, tok, tokens.slice(0, maxTokens)); >+ } > > function sanitize_name(name, type) { > if (names.has(name)) { >@@ -87,23 +147,34 @@ > if (!tokens.length || tokens[0].type !== type) return; > if (typeof value === "undefined" || tokens[0].value === value) { > last_token = tokens.shift(); >- if (type === ID) last_token.value = last_token.value.replace(/^_/, ""); >+ if (type === ID && last_token.value.startsWith('_')) >+ last_token.value = last_token.value.substring(1); > return last_token; > } >- }; >+ } >+ >+ function count(str, char) { >+ let total = 0; >+ for (let i = str.indexOf(char); i !== -1; i = str.indexOf(char, i + 1)) { >+ ++total; >+ } >+ return total; >+ } > > function ws() { > if (!tokens.length) return; > if (tokens[0].type === "whitespace") { > const t = tokens.shift(); >- t.value.replace(/\n/g, m => { >- line++; >- return m; >- }); >+ line += count(t.value, '\n'); > return t; > } >- }; >+ } > >+ const all_ws_re = { >+ "ws": /([\t\n\r ]+)/y, >+ "line-comment": /\/\/(.*)\r?\n?/y, >+ "multiline-comment": /\/\*((?:[^*]|\*[^/])*)\*\//y >+ }; > function all_ws(store, pea) { // pea == post extended attribute, tpea = same for types > const t = { type: "whitespace", value: "" }; > while (true) { >@@ -114,31 +185,30 @@ > if (t.value.length > 0) { > if (store) { > let w = t.value; >- const re = { >- "ws": /^([\t\n\r ]+)/, >- "line-comment": /^\/\/(.*)\r?\n?/, >- "multiline-comment": /^\/\*((?:.|\n|\r)*?)\*\// >- }; >- const wsTypes = []; >- for (var k in re) wsTypes.push(k); >- while (w.length) { >+ let lastIndex = 0; >+ while (lastIndex < w.length) { > let matched = false; >- for (var i in wsTypes) { >- const type = wsTypes[i]; >- w = w.replace(re[type], (tok, m1) => { >- store.push({ type: type + (pea ? ("-" + pea) : ""), value: m1 }); >+ // Servo doesn't support using "const" in this construction yet. >+ // See https://github.com/servo/servo/issues/20231. >+ // |type| can be made const once Servo supports it. >+ for (let type in all_ws_re) { >+ const re = all_ws_re[type]; >+ re.lastIndex = lastIndex; >+ const result = re.exec(w); >+ if (result) { >+ store.push({ type: type + (pea ? ("-" + pea) : ""), value: result[1] }); > matched = true; >- return ""; >- }); >- if (matched) break; >+ lastIndex = re.lastIndex; >+ break; >+ } > } >- if (matched) continue; >- throw new Error("Surprising white space construct."); // this shouldn't happen >+ if (!matched) >+ throw new Error("Surprising white space construct."); // this shouldn't happen > } > } > return t; > } >- }; >+ } > > function integer_type() { > let ret = ""; >@@ -153,7 +223,7 @@ > return ret; > } > if (ret) error("Failed to parse integer type"); >- }; >+ } > > function float_type() { > let ret = ""; >@@ -163,7 +233,7 @@ > if (consume(ID, "float")) return ret + "float"; > if (consume(ID, "double")) return ret + "double"; > if (ret) error("Failed to parse float type"); >- }; >+ } > > function primitive_type() { > const num_type = integer_type() || float_type(); >@@ -172,7 +242,7 @@ > if (consume(ID, "boolean")) return "boolean"; > if (consume(ID, "byte")) return "byte"; > if (consume(ID, "octet")) return "octet"; >- }; >+ } > > function const_value() { > if (consume(ID, "true")) return { type: "boolean", value: true }; >@@ -187,7 +257,7 @@ > if (consume(ID, "Infinity")) return { type: "Infinity", negative: true }; > else tokens.unshift(tok); > } >- }; >+ } > > function type_suffix(obj) { > while (true) { >@@ -197,11 +267,11 @@ > obj.nullable = true; > } else return; > } >- }; >+ } > >- function single_type() { >+ function single_type(typeName) { > const prim = primitive_type(); >- const ret = { sequence: false, generic: null, nullable: false, union: false }; >+ const ret = { type: typeName || null, sequence: false, generic: null, nullable: false, union: false }; > let name; > let value; > if (prim) { >@@ -219,7 +289,7 @@ > const types = []; > do { > all_ws(); >- types.push(type_with_extended_attributes() || error("Error parsing generic type " + value)); >+ types.push(type_with_extended_attributes(typeName) || error("Error parsing generic type " + value)); > all_ws(); > } > while (consume(OTHER, ",")); >@@ -248,12 +318,12 @@ > type_suffix(ret); > if (ret.nullable && ret.idlType === "any") error("Type any cannot be made nullable"); > return ret; >- }; >+ } > >- function union_type() { >+ function union_type(typeName) { > all_ws(); > if (!consume(OTHER, "(")) return; >- const ret = { sequence: false, generic: null, nullable: false, union: true, idlType: [] }; >+ const ret = { type: typeName || null, sequence: false, generic: null, nullable: false, union: true, idlType: [] }; > const fst = type_with_extended_attributes() || error("Union type with no content"); > ret.idlType.push(fst); > while (true) { >@@ -265,18 +335,18 @@ > if (!consume(OTHER, ")")) error("Unterminated union type"); > type_suffix(ret); > return ret; >- }; >+ } > >- function type() { >- return single_type() || union_type(); >- }; >+ function type(typeName) { >+ return single_type(typeName) || union_type(typeName); >+ } > >- function type_with_extended_attributes() { >+ function type_with_extended_attributes(typeName) { > const extAttrs = extended_attrs(); >- const ret = single_type() || union_type(); >+ const ret = single_type(typeName) || union_type(typeName); > if (extAttrs.length && ret) ret.extAttrs = extAttrs; > return ret; >- }; >+ } > > function argument(store) { > const ret = { optional: false, variadic: false }; >@@ -287,7 +357,7 @@ > ret.optional = true; > all_ws(); > } >- ret.idlType = type_with_extended_attributes(); >+ ret.idlType = type_with_extended_attributes("argument-type"); > if (!ret.idlType) { > if (opt_token) tokens.unshift(opt_token); > return; >@@ -322,7 +392,7 @@ > } > } > return ret; >- }; >+ } > > function argument_list(store) { > const ret = []; >@@ -335,7 +405,7 @@ > const nxt = argument(store ? ret : null) || error("Trailing comma in arguments list"); > ret.push(nxt); > } >- }; >+ } > > function simple_extended_attr(store) { > all_ws(); >@@ -386,7 +456,7 @@ > consume(OTHER, ")") || error("Unexpected token in extended attribute argument list"); > } > return ret; >- }; >+ } > > // Note: we parse something simpler than the official syntax. It's all that ever > // seems to be used >@@ -406,7 +476,7 @@ > all_ws(); > consume(OTHER, "]") || error("No end of extended attribute"); > return eas; >- }; >+ } > > function default_() { > all_ws(); >@@ -420,11 +490,11 @@ > return { type: "sequence", value: [] }; > } else { > const str = consume(STR) || error("No value for default"); >- str.value = str.value.replace(/^"/, "").replace(/"$/, ""); >+ str.value = str.value.slice(1, -1); > return str; > } > } >- }; >+ } > > function const_(store) { > all_ws(store, "pea"); >@@ -436,7 +506,7 @@ > typ = consume(ID) || error("No type for const"); > typ = typ.value; > } >- ret.idlType = typ; >+ ret.idlType = { type: "const-type", idlType: typ }; > all_ws(); > if (consume(OTHER, "?")) { > ret.nullable = true; >@@ -453,7 +523,7 @@ > all_ws(); > consume(OTHER, ";") || error("Unterminated const"); > return ret; >- }; >+ } > > function inheritance() { > all_ws(); >@@ -462,7 +532,7 @@ > const inh = consume(ID) || error("No type in inheritance"); > return inh.value; > } >- }; >+ } > > function operation_rest(ret, store) { > all_ws(); >@@ -477,7 +547,7 @@ > all_ws(); > consume(OTHER, ";") || error("Unterminated operation"); > return ret; >- }; >+ } > > function callback(store) { > all_ws(store, "pea"); >@@ -486,12 +556,11 @@ > all_ws(); > const tok = consume(ID, "interface"); > if (tok) { >- ret = interface_rest(); >- ret.type = "callback interface"; >+ ret = interface_rest(false, store, "callback interface"); > return ret; > } > const name = consume(ID) || error("No name for callback"); >- ret = { type: "callback", name: sanitize_name(name.value, "callback") }; >+ ret = current = { type: "callback", name: sanitize_name(name.value, "callback") }; > all_ws(); > consume(OTHER, "=") || error("No assignment in callback"); > all_ws(); >@@ -504,14 +573,14 @@ > all_ws(); > consume(OTHER, ";") || error("Unterminated callback"); > return ret; >- }; >+ } > > function attribute(store) { > all_ws(store, "pea"); > const grabbed = []; > const ret = { > type: "attribute", >- "static": false, >+ static: false, > stringifier: false, > inherit: false, > readonly: false >@@ -519,7 +588,7 @@ > const w = all_ws(); > if (w) grabbed.push(w); > if (consume(ID, "inherit")) { >- if (ret["static"] || ret.stringifier) error("Cannot have a static or stringifier inherit"); >+ if (ret.static || ret.stringifier) error("Cannot have a static or stringifier inherit"); > ret.inherit = true; > grabbed.push(last_token); > const w = all_ws(); >@@ -536,14 +605,14 @@ > tokens = grabbed.concat(tokens); > } > return rest; >- }; >+ } > > function attribute_rest(ret) { > if (!consume(ID, "attribute")) { > return; > } > all_ws(); >- ret.idlType = type_with_extended_attributes() || error("No type in attribute"); >+ ret.idlType = type_with_extended_attributes("attribute-type") || error("No type in attribute"); > if (ret.idlType.sequence) error("Attributes cannot accept sequence types"); > if (ret.idlType.generic === "record") error("Attributes cannot accept record types"); > all_ws(); >@@ -552,17 +621,17 @@ > all_ws(); > consume(OTHER, ";") || error("Unterminated attribute"); > return ret; >- }; >+ } > > function return_type() { >- const typ = type(); >+ const typ = type("return-type"); > if (!typ) { > if (consume(ID, "void")) { > return "void"; > } else error("No return type"); > } > return typ; >- }; >+ } > > function operation(store) { > all_ws(store, "pea"); >@@ -582,24 +651,9 @@ > } > ret.idlType = return_type(); > all_ws(); >- if (consume(ID, "iterator")) { >- all_ws(); >- ret.type = "iterator"; >- if (consume(ID, "object")) { >- ret.iteratorObject = "object"; >- } else if (consume(OTHER, "=")) { >- all_ws(); >- var name = consume(ID) || error("No right hand side in iterator"); >- ret.iteratorObject = name.value; >- } >- all_ws(); >- consume(OTHER, ";") || error("Unterminated iterator"); >- return ret; >- } else { >- operation_rest(ret, store); >- return ret; >- } >- }; >+ operation_rest(ret, store); >+ return ret; >+ } > > function static_member(store) { > all_ws(store, "pea"); >@@ -631,7 +685,7 @@ > arr.push(name.value); > } else break; > } >- }; >+ } > > function iterable_type() { > if (consume(ID, "iterable")) return "iterable"; >@@ -639,13 +693,13 @@ > else if (consume(ID, "maplike")) return "maplike"; > else if (consume(ID, "setlike")) return "setlike"; > else return; >- }; >+ } > > function readonly_iterable_type() { > if (consume(ID, "maplike")) return "maplike"; > else if (consume(ID, "setlike")) return "setlike"; > else return; >- }; >+ } > > function iterable(store) { > all_ws(store, "pea"); >@@ -672,17 +726,14 @@ > delete ret.readonly; > all_ws(); > if (consume(OTHER, "<")) { >- ret.idlType = type_with_extended_attributes() || error(`Error parsing ${ittype} declaration`); >+ ret.idlType = [type_with_extended_attributes()] || error(`Error parsing ${ittype} declaration`); > all_ws(); > if (secondTypeAllowed) { >- let type2 = null; > if (consume(OTHER, ",")) { > all_ws(); >- type2 = type_with_extended_attributes(); >+ ret.idlType.push(type_with_extended_attributes()); > all_ws(); > } >- if (type2) >- ret.idlType = [ret.idlType, type2]; > else if (secondTypeRequired) > error(`Missing second type argument in ${ittype} declaration`); > } >@@ -693,16 +744,16 @@ > error(`Error parsing ${ittype} declaration`); > > return ret; >- }; >+ } > >- function interface_rest(isPartial, store) { >+ function interface_rest(isPartial, store, typeName = "interface") { > all_ws(); > const name = consume(ID) || error("No name for interface"); > const mems = []; >- const ret = { >- type: "interface", >+ const ret = current = { >+ type: typeName, > name: isPartial ? name.value : sanitize_name(name.value, "interface"), >- partial: false, >+ partial: isPartial, > members: mems > }; > if (!isPartial) ret.inheritance = inheritance() || null; >@@ -733,7 +784,7 @@ > mem.extAttrs = ea; > ret.members.push(mem); > } >- }; >+ } > > function mixin_rest(isPartial, store) { > all_ws(); >@@ -741,10 +792,10 @@ > all_ws(); > const name = consume(ID) || error("No name for interface mixin"); > const mems = []; >- const ret = { >+ const ret = current = { > type: "interface mixin", > name: isPartial ? name.value : sanitize_name(name.value, "interface mixin"), >- partial: false, >+ partial: isPartial, > members: mems > }; > all_ws(); >@@ -787,7 +838,7 @@ > all_ws(); > const name = consume(ID) || error("No name for namespace"); > const mems = []; >- const ret = { >+ const ret = current = { > type: "namespace", > name: isPartial ? name.value : sanitize_name(name.value, "namespace"), > partial: isPartial, >@@ -817,7 +868,7 @@ > const grabbed = []; > const ret = { > type: "attribute", >- "static": false, >+ static: false, > stringifier: false, > inherit: false, > readonly: false >@@ -856,9 +907,8 @@ > interface_(true, store) || > namespace(true, store) || > error("Partial doesn't apply to anything"); >- thing.partial = true; > return thing; >- }; >+ } > > function dictionary(isPartial, store) { > all_ws(isPartial ? null : store, "pea"); >@@ -866,10 +916,10 @@ > all_ws(); > const name = consume(ID) || error("No name for dictionary"); > const mems = []; >- const ret = { >+ const ret = current = { > type: "dictionary", > name: isPartial ? name.value : sanitize_name(name.value, "dictionary"), >- partial: false, >+ partial: isPartial, > members: mems > }; > if (!isPartial) ret.inheritance = inheritance() || null; >@@ -885,7 +935,7 @@ > const ea = extended_attrs(store ? mems : null); > all_ws(store ? mems : null, "pea"); > const required = consume(ID, "required"); >- const typ = type_with_extended_attributes() || error("No type for dictionary member"); >+ const typ = type_with_extended_attributes("dictionary-type") || error("No type for dictionary member"); > all_ws(); > const name = consume(ID) || error("No name for dictionary member"); > const dflt = default_(); >@@ -904,7 +954,7 @@ > all_ws(); > consume(OTHER, ";") || error("Unterminated dictionary member"); > } >- }; >+ } > > function enum_(store) { > all_ws(store, "pea"); >@@ -912,7 +962,7 @@ > all_ws(); > const name = consume(ID) || error("No name for enum"); > const vals = []; >- const ret = { >+ const ret = current = { > type: "enum", > name: sanitize_name(name.value, "enum"), > values: vals >@@ -928,7 +978,7 @@ > return ret; > } > const val = consume(STR) || error("Unexpected value in enum"); >- val.value = val.value.replace(/"/g, ""); >+ val.value = val.value.slice(1, -1); > ret.values.push(val); > all_ws(store ? vals : null); > if (consume(OTHER, ",")) { >@@ -939,7 +989,7 @@ > saw_comma = false; > } > } >- }; >+ } > > function typedef(store) { > all_ws(store, "pea"); >@@ -948,14 +998,15 @@ > type: "typedef" > }; > all_ws(); >- ret.idlType = type_with_extended_attributes() || error("No type in typedef"); >+ ret.idlType = type_with_extended_attributes("typedef-type") || error("No type in typedef"); > all_ws(); > const name = consume(ID) || error("No name in typedef"); > ret.name = sanitize_name(name.value, "typedef"); >+ current = ret; > all_ws(); > consume(OTHER, ";") || error("Unterminated typedef"); > return ret; >- }; >+ } > > function implements_(store) { > all_ws(store, "pea"); >@@ -978,7 +1029,7 @@ > tokens.unshift(w); > tokens.unshift(target); > } >- }; >+ } > > function includes(store) { > all_ws(store, "pea"); >@@ -1001,7 +1052,7 @@ > tokens.unshift(w); > tokens.unshift(target); > } >- }; >+ } > > function definition(store) { > return callback(store) || >@@ -1013,7 +1064,7 @@ > implements_(store) || > includes(store) || > namespace(false, store); >- }; >+ } > > function definitions(store) { > if (!tokens.length) return []; >@@ -1029,11 +1080,11 @@ > defs.push(def); > } > return defs; >- }; >+ } > const res = definitions(opt.ws); > if (tokens.length) error("Unrecognised tokens"); > return res; >- }; >+ } > > const obj = { > parse(str, opt) { >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/lib/writer.js b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/lib/writer.js >index f7c79f8289358a5ba57911246440fb192f099e08..c00c0dd932221b1385b60e6e7e51dd96b0aed170 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/lib/writer.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/lib/writer.js >@@ -1,78 +1,71 @@ >-(function() { >+"use strict"; > >- var write = function(ast, opt) { >- var curPea = "", >- curTPea = "", >- opt = opt || {}, >- noop = function(str) { >- return str; }, >- optNames = "type".split(" "), >- context = []; >- for (var i = 0, n = optNames.length; i < n; i++) { >- var o = optNames[i]; >+(() => { >+ function write(ast, opt = {}) { >+ let curPea = ""; >+ let curTPea = ""; >+ const noop = str => str; >+ const optNames = "type".split(" "); >+ const context = []; >+ for (const o of optNames) { > if (!opt[o]) opt[o] = noop; > } > >- var literal = function(it) { >+ function literal(it) { > return it.value; > }; >- var wsPea = function(it) { >+ function wsPea(it) { > curPea += it.value; > return ""; > }; >- var wsTPea = function(it) { >+ function wsTPea(it) { > curTPea += it.value; > return ""; > }; >- var lineComment = function(it) { >- return "//" + it.value + "\n"; >+ function lineComment(it) { >+ return `//${it.value}\n`; > }; >- var multilineComment = function(it) { >- return "/*" + it.value + "*/"; >+ function multilineComment(it) { >+ return `/*${it.value}*/`; > }; >- var type = function(it) { >+ function type(it) { > if (typeof it === "string") return opt.type(it); // XXX should maintain some context >- if (it.union) return "(" + it.idlType.map(type).join(" or ") + ")"; >- var ret = ""; >- if (it.generic) ret += it.generic + "<"; >- else if (it.sequence) ret += "sequence<"; >- if (Array.isArray(it.idlType)) ret += it.idlType.map(type).join(", "); >- else ret += type(it.idlType); >- if (it.array || it.generic === 'Array') { >- for (var i = 0, n = it.nullableArray.length; i < n; i++) { >- var val = it.nullableArray[i]; >- if (val) ret += "?"; >- ret += "[]"; >- } >+ let ret = extended_attributes(it.extAttrs, curPea); >+ if (it.union) ret += `(${it.idlType.map(type).join(" or ")})`; >+ else { >+ if (it.generic) ret += `${it.generic}<`; >+ if (Array.isArray(it.idlType)) ret += it.idlType.map(type).join(", "); >+ else ret += type(it.idlType); >+ if (it.generic) ret += ">"; > } >- if (it.generic || it.sequence) ret += ">"; > if (it.nullable) ret += "?"; > > return ret; > }; >- var const_value = function(it) { >- var tp = it.type; >+ function const_value(it) { >+ const tp = it.type; > if (tp === "boolean") return it.value ? "true" : "false"; > else if (tp === "null") return "null"; > else if (tp === "Infinity") return (it.negative ? "-" : "") + "Infinity"; > else if (tp === "NaN") return "NaN"; > else if (tp === "number") return it.value; >- else return '"' + it.value + '"'; >+ else if (tp === "sequence") return "[]"; >+ else return `"${it.value}"`; > }; >- var argument = function(arg, pea) { >- var ret = extended_attributes(arg.extAttrs, pea); >+ function argument(arg, pea) { >+ let ret = extended_attributes(arg.extAttrs, pea); > if (arg.optional) ret += "optional "; > ret += type(arg.idlType); > if (arg.variadic) ret += "..."; >- ret += " " + arg.name; >- if (arg["default"]) ret += " = " + const_value(arg["default"]); >+ ret += ` ${arg.name}`; >+ if (arg["default"]) ret += ` = ${const_value(arg["default"])}`; > return ret; > }; >- var args = function(its) { >- var res = "", >- pea = ""; >- for (var i = 0, n = its.length; i < n; i++) { >- var arg = its[i]; >+ function args(its) { >+ let res = ""; >+ let pea = ""; >+ for (let i = 0, n = its.length; i < n; i++) { >+ const arg = its[i]; > if (arg.type === "ws") res += arg.value; > else if (arg.type === "ws-pea") pea += arg.value; > else { >@@ -83,198 +76,198 @@ > } > return res; > }; >- var make_ext_at = function(it) { >- if (it["arguments"] === null) return it.name; >+ function make_ext_at(it) { > context.unshift(it); >- var ret = it.name + "(" + (it["arguments"].length ? args(it["arguments"]) : "") + ")"; >+ let ret = it.name; >+ if (it.rhs) { >+ if (it.rhs.type === "identifier-list") ret += `=(${it.rhs.value.join(',')})`; >+ else ret += `=${it.rhs.value}`; >+ } >+ if (it.arguments) ret += `(${it["arguments"].length ? args(it["arguments"]) : ""})`; > context.shift(); // XXX need to add more contexts, but not more than needed for ReSpec > return ret; > }; >- var extended_attributes = function(eats, pea) { >+ function extended_attributes(eats, pea) { > if (!eats || !eats.length) return ""; >- return "[" + eats.map(make_ext_at).join(", ") + "]" + pea; >+ return `[${eats.map(make_ext_at).join(", ")}]${pea}`; > }; > >- var modifiers = "getter setter creator deleter legacycaller stringifier static".split(" "); >- var operation = function(it) { >- var ret = extended_attributes(it.extAttrs, curPea); >+ const modifiers = "getter setter creator deleter legacycaller stringifier static".split(" "); >+ function operation(it) { >+ let ret = extended_attributes(it.extAttrs, curPea); > curPea = ""; > if (it.stringifier && !it.idlType) return "stringifier;"; >- for (var i = 0, n = modifiers.length; i < n; i++) { >- var mod = modifiers[i]; >+ for (const mod of modifiers) { > if (it[mod]) ret += mod + " "; > } > ret += type(it.idlType) + " "; > if (it.name) ret += it.name; >- ret += "(" + args(it["arguments"]) + ");"; >+ ret += `(${args(it["arguments"])});`; > return ret; > }; > >- var attribute = function(it) { >- var ret = extended_attributes(it.extAttrs, curPea); >+ function attribute(it) { >+ let ret = extended_attributes(it.extAttrs, curPea); > curPea = ""; > if (it["static"]) ret += "static "; > if (it.stringifier) ret += "stringifier "; > if (it.readonly) ret += "readonly "; > if (it.inherit) ret += "inherit "; >- ret += "attribute " + type(it.idlType) + " " + it.name + ";"; >+ ret += `attribute ${type(it.idlType)} ${it.name};`; > return ret; > }; > >- var interface_ = function(it) { >- var ret = extended_attributes(it.extAttrs, curPea); >+ function interface_(it) { >+ let ret = extended_attributes(it.extAttrs, curPea); > curPea = ""; > if (it.partial) ret += "partial "; >- ret += "interface " + it.name + " "; >- if (it.inheritance) ret += ": " + it.inheritance + " "; >- ret += "{" + iterate(it.members) + "};"; >+ ret += `interface ${it.name} `; >+ if (it.inheritance) ret += `: ${it.inheritance} `; >+ ret += `{${iterate(it.members)}};`; > return ret; > }; > >- var dictionary = function(it) { >- var ret = extended_attributes(it.extAttrs, curPea); >+ function interface_mixin(it) { >+ let ret = extended_attributes(it.extAttrs, curPea); >+ curPea = ""; >+ if (it.partial) ret += "partial "; >+ ret += `interface mixin ${it.name} `; >+ ret += `{${iterate(it.members)}};`; >+ return ret; >+ } >+ >+ function namespace(it) { >+ let ret = extended_attributes(it.extAttrs, curPea); >+ curPea = ""; >+ if (it.partial) ret += "partial "; >+ ret += `namespace ${it.name} `; >+ ret += `{${iterate(it.members)}};`; >+ return ret; >+ } >+ >+ function dictionary(it) { >+ let ret = extended_attributes(it.extAttrs, curPea); > curPea = ""; > if (it.partial) ret += "partial "; >- ret += "dictionary " + it.name + " "; >- ret += "{" + iterate(it.members) + "};"; >+ ret += `dictionary ${it.name} `; >+ if (it.inheritance) ret += `: ${it.inheritance} `; >+ ret += `{${iterate(it.members)}};`; > return ret; > }; >- var field = function(it) { >- var ret = extended_attributes(it.extAttrs, curPea); >+ function field(it) { >+ let ret = extended_attributes(it.extAttrs, curPea); > curPea = ""; > if (it.required) ret += "required "; >- ret += type(it.idlType) + " " + it.name; >- if (it["default"]) ret += " = " + const_value(it["default"]); >+ ret += `${type(it.idlType)} ${it.name}`; >+ if (it["default"]) ret += ` = ${const_value(it["default"])}`; > ret += ";"; > return ret; > }; >- var exception = function(it) { >- var ret = extended_attributes(it.extAttrs, curPea); >+ function const_(it) { >+ const ret = extended_attributes(it.extAttrs, curPea); > curPea = ""; >- ret += "exception " + it.name + " "; >- if (it.inheritance) ret += ": " + it.inheritance + " "; >- ret += "{" + iterate(it.members) + "};"; >- return ret; >+ return `${ret}const ${type(it.idlType)}${it.nullable ? "?" : ""} ${it.name} = ${const_value(it.value)};`; > }; >- var const_ = function(it) { >- var ret = extended_attributes(it.extAttrs, curPea); >+ function typedef(it) { >+ let ret = extended_attributes(it.extAttrs, curPea); > curPea = ""; >- return ret + "const " + type(it.idlType) + " " + it.name + " = " + const_value(it.value) + ";"; >+ ret += `typedef ${extended_attributes(it.typeExtAttrs, curTPea)}`; >+ curTPea = ""; >+ return `${ret}${type(it.idlType)} ${it.name};`; > }; >- var typedef = function(it) { >- var ret = extended_attributes(it.extAttrs, curPea); >+ function implements_(it) { >+ const ret = extended_attributes(it.extAttrs, curPea); > curPea = ""; >- ret += "typedef " + extended_attributes(it.typeExtAttrs, curTPea); >- curTPea = ""; >- return ret + type(it.idlType) + " " + it.name + ";"; >+ return `${ret}${it.target} implements ${it["implements"]};`; > }; >- var implements_ = function(it) { >- var ret = extended_attributes(it.extAttrs, curPea); >+ function includes(it) { >+ const ret = extended_attributes(it.extAttrs, curPea); > curPea = ""; >- return ret + it.target + " implements " + it["implements"] + ";"; >+ return `${ret}${it.target} includes ${it.includes};`; > }; >- var callback = function(it) { >- var ret = extended_attributes(it.extAttrs, curPea); >+ function callback(it) { >+ const ret = extended_attributes(it.extAttrs, curPea); > curPea = ""; >- return ret + "callback " + it.name + " = " + type(it.idlType) + >- "(" + args(it["arguments"]) + ");"; >+ return `${ret}callback ${it.name} = ${type(it.idlType)}(${args(it["arguments"])});`; > }; >- var enum_ = function(it) { >- var ret = extended_attributes(it.extAttrs, curPea); >+ function enum_(it) { >+ let ret = extended_attributes(it.extAttrs, curPea); > curPea = ""; >- ret += "enum " + it.name + " {"; >- for (var i = 0, n = it.values.length; i < n; i++) { >- var v = it.values[i]; >- if (typeof v === "string") ret += '"' + v + '"'; >+ ret += `enum ${it.name} {`; >+ for (const v of it.values) { >+ if (v.type === "string") ret += `"${v.value}"`; > else if (v.type === "ws") ret += v.value; > else if (v.type === ",") ret += ","; > } > return ret + "};"; > }; >- var serializer = function(it) { >- var ret = "serializer"; >- if (it.name) { >- ret += " = " + it.name + ";"; >- } else if (it.patternList) { >- ret += " = [ " + it.names.join(", ") + " ];"; >- } else if (it.patternMap) { >- ret += " = { " + it.names.join(", ") + " };"; >- } else if (it.operation) { >- ret += " " + operation(it); >- } else { >- ret += ";"; >- } >- return ret; >- }; >- var iterable = function(it) { >- return "iterable<" + (it.idlType instanceof Array ? it.idlType.map(type).join(", ") : type(it.idlType)) + ">;"; >+ function iterable(it) { >+ return `iterable<${Array.isArray(it.idlType) ? it.idlType.map(type).join(", ") : type(it.idlType)}>;`; > }; >- var legacyiterable = function(it) { >- return "legacyiterable<" + (it.idlType instanceof Array ? it.idlType.map(type).join(", ") : type(it.idlType)) + ">;"; >+ function legacyiterable(it) { >+ return `legacyiterable<${Array.isArray(it.idlType) ? it.idlType.map(type).join(", ") : type(it.idlType)}>;`; > }; >- var maplike = function(it) { >- return (it.readonly ? "readonly " : "") + "maplike<" + >- it.idlType.map(type).join(", ") + ">;"; >+ function maplike(it) { >+ return `${it.readonly ? "readonly " : ""}maplike<${it.idlType.map(type).join(", ")}>;`; > }; >- var setlike = function(it) { >- return (it.readonly ? "readonly " : "") + "setlike<" + >- type(it.idlType) + ">;"; >+ function setlike(it) { >+ return `${it.readonly ? "readonly " : ""}setlike<${type(it.idlType[0])}>;`; > }; >- var callbackInterface = function(it) { >- return 'callback ' + interface_(it); >+ function callbackInterface(it) { >+ return `callback ${interface_(it)}`; > }; > >- var table = { >+ const table = { > ws: literal, > "ws-pea": wsPea, > "ws-tpea": wsTPea, > "line-comment": lineComment, > "multiline-comment": multilineComment, >- "interface": interface_, >- operation: operation, >- attribute: attribute, >- dictionary: dictionary, >- field: field, >- exception: exception, >- "const": const_, >- typedef: typedef, >- "implements": implements_, >- callback: callback, >- "enum": enum_, >- serializer: serializer, >- iterable: iterable, >- legacyiterable: legacyiterable, >- maplike: maplike, >- setlike: setlike, >+ interface: interface_, >+ "interface mixin": interface_mixin, >+ namespace, >+ operation, >+ attribute, >+ dictionary, >+ field, >+ const: const_, >+ typedef, >+ implements: implements_, >+ includes, >+ callback, >+ enum: enum_, >+ iterable, >+ legacyiterable, >+ maplike, >+ setlike, > "callback interface": callbackInterface > }; >- var dispatch = function(it) { >+ function dispatch(it) { >+ const dispatcher = table[it.type]; >+ if (!dispatcher) { >+ throw new Error(`Type "${it.type}" is unsupported`) >+ } > return table[it.type](it); > }; >- var iterate = function(things) { >+ function iterate(things) { > if (!things) return; >- var ret = ""; >- for (var i = 0, n = things.length; i < n; i++) ret += dispatch(things[i]); >+ let ret = ""; >+ for (const thing of things) ret += dispatch(thing); > return ret; > }; > return iterate(ast); > }; > > >- var obj = { >- write: function(ast, opt) { >- if (!opt) opt = {}; >- return write(ast, opt); >- } >+ const obj = { >+ write > }; > > if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { > module.exports = obj; > } else if (typeof define === 'function' && define.amd) { >- define([], function() { >- return obj; >- }); >+ define([], () => obj); > } else { > (self || window).WebIDL2Writer = obj; > } >-}()); >+})(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/package-lock.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/package-lock.json >new file mode 100644 >index 0000000000000000000000000000000000000000..a6f529d6c7f11d181f5834744170bff68e1cf882 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/package-lock.json >@@ -0,0 +1,710 @@ >+{ >+ "name": "webidl2", >+ "version": "10.2.1", >+ "lockfileVersion": 1, >+ "requires": true, >+ "dependencies": { >+ "@babel/code-frame": { >+ "version": "7.0.0-beta.40", >+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz", >+ "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==", >+ "dev": true, >+ "requires": { >+ "@babel/highlight": "7.0.0-beta.40" >+ } >+ }, >+ "@babel/highlight": { >+ "version": "7.0.0-beta.40", >+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz", >+ "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==", >+ "dev": true, >+ "requires": { >+ "chalk": "2.3.2", >+ "esutils": "2.0.2", >+ "js-tokens": "3.0.2" >+ } >+ }, >+ "ansi-regex": { >+ "version": "3.0.0", >+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", >+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", >+ "dev": true >+ }, >+ "ansi-styles": { >+ "version": "3.2.1", >+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", >+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", >+ "dev": true, >+ "requires": { >+ "color-convert": "1.9.1" >+ } >+ }, >+ "arr-diff": { >+ "version": "2.0.0", >+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", >+ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", >+ "dev": true, >+ "requires": { >+ "arr-flatten": "1.1.0" >+ } >+ }, >+ "arr-flatten": { >+ "version": "1.1.0", >+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", >+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", >+ "dev": true >+ }, >+ "array-unique": { >+ "version": "0.2.1", >+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", >+ "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", >+ "dev": true >+ }, >+ "balanced-match": { >+ "version": "1.0.0", >+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", >+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", >+ "dev": true >+ }, >+ "brace-expansion": { >+ "version": "1.1.11", >+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", >+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", >+ "dev": true, >+ "requires": { >+ "balanced-match": "1.0.0", >+ "concat-map": "0.0.1" >+ } >+ }, >+ "braces": { >+ "version": "1.8.5", >+ "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", >+ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", >+ "dev": true, >+ "requires": { >+ "expand-range": "1.8.2", >+ "preserve": "0.2.0", >+ "repeat-element": "1.1.2" >+ } >+ }, >+ "browser-stdout": { >+ "version": "1.3.1", >+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", >+ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", >+ "dev": true >+ }, >+ "chalk": { >+ "version": "2.3.2", >+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", >+ "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", >+ "dev": true, >+ "requires": { >+ "ansi-styles": "3.2.1", >+ "escape-string-regexp": "1.0.5", >+ "supports-color": "5.3.0" >+ } >+ }, >+ "color-convert": { >+ "version": "1.9.1", >+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", >+ "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", >+ "dev": true, >+ "requires": { >+ "color-name": "1.1.3" >+ } >+ }, >+ "color-name": { >+ "version": "1.1.3", >+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", >+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", >+ "dev": true >+ }, >+ "commander": { >+ "version": "2.11.0", >+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", >+ "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", >+ "dev": true >+ }, >+ "concat-map": { >+ "version": "0.0.1", >+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", >+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", >+ "dev": true >+ }, >+ "debug": { >+ "version": "3.1.0", >+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", >+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", >+ "dev": true, >+ "requires": { >+ "ms": "2.0.0" >+ } >+ }, >+ "diff": { >+ "version": "3.5.0", >+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", >+ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", >+ "dev": true >+ }, >+ "diff-match-patch": { >+ "version": "1.0.0", >+ "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.0.tgz", >+ "integrity": "sha1-HMPIOkkNZ/ldkeOfatHy4Ia2MEg=", >+ "dev": true >+ }, >+ "escape-string-regexp": { >+ "version": "1.0.5", >+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", >+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", >+ "dev": true >+ }, >+ "esutils": { >+ "version": "2.0.2", >+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", >+ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", >+ "dev": true >+ }, >+ "expand-brackets": { >+ "version": "0.1.5", >+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", >+ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", >+ "dev": true, >+ "requires": { >+ "is-posix-bracket": "0.1.1" >+ } >+ }, >+ "expand-range": { >+ "version": "1.8.2", >+ "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", >+ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", >+ "dev": true, >+ "requires": { >+ "fill-range": "2.2.3" >+ } >+ }, >+ "expect": { >+ "version": "22.4.0", >+ "resolved": "https://registry.npmjs.org/expect/-/expect-22.4.0.tgz", >+ "integrity": "sha512-Fiy862jT3qc70hwIHwwCBNISmaqBrfWKKrtqyMJ6iwZr+6KXtcnHojZFtd63TPRvRl8EQTJ+YXYy2lK6/6u+Hw==", >+ "dev": true, >+ "requires": { >+ "ansi-styles": "3.2.1", >+ "jest-diff": "22.4.0", >+ "jest-get-type": "22.1.0", >+ "jest-matcher-utils": "22.4.0", >+ "jest-message-util": "22.4.0", >+ "jest-regex-util": "22.1.0" >+ } >+ }, >+ "extglob": { >+ "version": "0.3.2", >+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", >+ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", >+ "dev": true, >+ "requires": { >+ "is-extglob": "1.0.0" >+ } >+ }, >+ "filename-regex": { >+ "version": "2.0.1", >+ "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", >+ "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", >+ "dev": true >+ }, >+ "fill-range": { >+ "version": "2.2.3", >+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", >+ "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", >+ "dev": true, >+ "requires": { >+ "is-number": "2.1.0", >+ "isobject": "2.1.0", >+ "randomatic": "1.1.7", >+ "repeat-element": "1.1.2", >+ "repeat-string": "1.6.1" >+ } >+ }, >+ "for-in": { >+ "version": "1.0.2", >+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", >+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", >+ "dev": true >+ }, >+ "for-own": { >+ "version": "0.1.5", >+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", >+ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", >+ "dev": true, >+ "requires": { >+ "for-in": "1.0.2" >+ } >+ }, >+ "fs.realpath": { >+ "version": "1.0.0", >+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", >+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", >+ "dev": true >+ }, >+ "glob": { >+ "version": "7.1.2", >+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", >+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", >+ "dev": true, >+ "requires": { >+ "fs.realpath": "1.0.0", >+ "inflight": "1.0.6", >+ "inherits": "2.0.3", >+ "minimatch": "3.0.4", >+ "once": "1.4.0", >+ "path-is-absolute": "1.0.1" >+ } >+ }, >+ "glob-base": { >+ "version": "0.3.0", >+ "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", >+ "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", >+ "dev": true, >+ "requires": { >+ "glob-parent": "2.0.0", >+ "is-glob": "2.0.1" >+ } >+ }, >+ "glob-parent": { >+ "version": "2.0.0", >+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", >+ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", >+ "dev": true, >+ "requires": { >+ "is-glob": "2.0.1" >+ } >+ }, >+ "growl": { >+ "version": "1.10.3", >+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", >+ "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", >+ "dev": true >+ }, >+ "has-flag": { >+ "version": "3.0.0", >+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", >+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", >+ "dev": true >+ }, >+ "he": { >+ "version": "1.1.1", >+ "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", >+ "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", >+ "dev": true >+ }, >+ "inflight": { >+ "version": "1.0.6", >+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", >+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", >+ "dev": true, >+ "requires": { >+ "once": "1.4.0", >+ "wrappy": "1.0.2" >+ } >+ }, >+ "inherits": { >+ "version": "2.0.3", >+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", >+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", >+ "dev": true >+ }, >+ "is-buffer": { >+ "version": "1.1.6", >+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", >+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", >+ "dev": true >+ }, >+ "is-dotfile": { >+ "version": "1.0.3", >+ "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", >+ "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", >+ "dev": true >+ }, >+ "is-equal-shallow": { >+ "version": "0.1.3", >+ "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", >+ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", >+ "dev": true, >+ "requires": { >+ "is-primitive": "2.0.0" >+ } >+ }, >+ "is-extendable": { >+ "version": "0.1.1", >+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", >+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", >+ "dev": true >+ }, >+ "is-extglob": { >+ "version": "1.0.0", >+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", >+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", >+ "dev": true >+ }, >+ "is-glob": { >+ "version": "2.0.1", >+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", >+ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", >+ "dev": true, >+ "requires": { >+ "is-extglob": "1.0.0" >+ } >+ }, >+ "is-number": { >+ "version": "2.1.0", >+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", >+ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", >+ "dev": true, >+ "requires": { >+ "kind-of": "3.2.2" >+ } >+ }, >+ "is-posix-bracket": { >+ "version": "0.1.1", >+ "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", >+ "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", >+ "dev": true >+ }, >+ "is-primitive": { >+ "version": "2.0.0", >+ "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", >+ "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", >+ "dev": true >+ }, >+ "isarray": { >+ "version": "1.0.0", >+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", >+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", >+ "dev": true >+ }, >+ "isobject": { >+ "version": "2.1.0", >+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", >+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", >+ "dev": true, >+ "requires": { >+ "isarray": "1.0.0" >+ } >+ }, >+ "jest-diff": { >+ "version": "22.4.0", >+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-22.4.0.tgz", >+ "integrity": "sha512-+/t20WmnkOkB8MOaGaPziI8zWKxquMvYw4Ub+wOzi7AUhmpFXz43buWSxVoZo4J5RnCozpGbX3/FssjJ5KV9Nw==", >+ "dev": true, >+ "requires": { >+ "chalk": "2.3.2", >+ "diff": "3.5.0", >+ "jest-get-type": "22.1.0", >+ "pretty-format": "22.4.0" >+ } >+ }, >+ "jest-get-type": { >+ "version": "22.1.0", >+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-22.1.0.tgz", >+ "integrity": "sha512-nD97IVOlNP6fjIN5i7j5XRH+hFsHL7VlauBbzRvueaaUe70uohrkz7pL/N8lx/IAwZRTJ//wOdVgh85OgM7g3w==", >+ "dev": true >+ }, >+ "jest-matcher-utils": { >+ "version": "22.4.0", >+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-22.4.0.tgz", >+ "integrity": "sha512-03m3issxUXpWMwDYTfmL8hRNewUB0yCRTeXPm+eq058rZxLHD9f5NtSSO98CWHqe4UyISIxd9Ao9iDVjHWd2qg==", >+ "dev": true, >+ "requires": { >+ "chalk": "2.3.2", >+ "jest-get-type": "22.1.0", >+ "pretty-format": "22.4.0" >+ } >+ }, >+ "jest-message-util": { >+ "version": "22.4.0", >+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-22.4.0.tgz", >+ "integrity": "sha512-eyCJB0T3hrlpFF2FqQoIB093OulP+1qvATQmD3IOgJgMGqPL6eYw8TbC5P/VCWPqKhGL51xvjIIhow5eZ2wHFw==", >+ "dev": true, >+ "requires": { >+ "@babel/code-frame": "7.0.0-beta.40", >+ "chalk": "2.3.2", >+ "micromatch": "2.3.11", >+ "slash": "1.0.0", >+ "stack-utils": "1.0.1" >+ } >+ }, >+ "jest-regex-util": { >+ "version": "22.1.0", >+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-22.1.0.tgz", >+ "integrity": "sha512-on0LqVS6Xeh69sw3d1RukVnur+lVOl3zkmb0Q54FHj9wHoq6dbtWqb3TSlnVUyx36hqjJhjgs/QLqs07Bzu72Q==", >+ "dev": true >+ }, >+ "js-tokens": { >+ "version": "3.0.2", >+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", >+ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", >+ "dev": true >+ }, >+ "jsondiffpatch": { >+ "version": "0.3.5", >+ "resolved": "https://registry.npmjs.org/jsondiffpatch/-/jsondiffpatch-0.3.5.tgz", >+ "integrity": "sha512-v7eaGLDMCHXH+fsIaZhptEUJmS8EJpunq7IM4cc4vIT/kSRAkaZ6ZF4ebiNcyUelL0znbvj6o2B5Gh9v7Og0BQ==", >+ "dev": true, >+ "requires": { >+ "chalk": "2.3.2", >+ "diff-match-patch": "1.0.0" >+ } >+ }, >+ "kind-of": { >+ "version": "3.2.2", >+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", >+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", >+ "dev": true, >+ "requires": { >+ "is-buffer": "1.1.6" >+ } >+ }, >+ "micromatch": { >+ "version": "2.3.11", >+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", >+ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", >+ "dev": true, >+ "requires": { >+ "arr-diff": "2.0.0", >+ "array-unique": "0.2.1", >+ "braces": "1.8.5", >+ "expand-brackets": "0.1.5", >+ "extglob": "0.3.2", >+ "filename-regex": "2.0.1", >+ "is-extglob": "1.0.0", >+ "is-glob": "2.0.1", >+ "kind-of": "3.2.2", >+ "normalize-path": "2.1.1", >+ "object.omit": "2.0.1", >+ "parse-glob": "3.0.4", >+ "regex-cache": "0.4.4" >+ } >+ }, >+ "minimatch": { >+ "version": "3.0.4", >+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", >+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", >+ "dev": true, >+ "requires": { >+ "brace-expansion": "1.1.11" >+ } >+ }, >+ "minimist": { >+ "version": "0.0.8", >+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", >+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", >+ "dev": true >+ }, >+ "mkdirp": { >+ "version": "0.5.1", >+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", >+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", >+ "dev": true, >+ "requires": { >+ "minimist": "0.0.8" >+ } >+ }, >+ "mocha": { >+ "version": "5.0.4", >+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.4.tgz", >+ "integrity": "sha512-nMOpAPFosU1B4Ix1jdhx5e3q7XO55ic5a8cgYvW27CequcEY+BabS0kUVL1Cw1V5PuVHZWeNRWFLmEPexo79VA==", >+ "dev": true, >+ "requires": { >+ "browser-stdout": "1.3.1", >+ "commander": "2.11.0", >+ "debug": "3.1.0", >+ "diff": "3.5.0", >+ "escape-string-regexp": "1.0.5", >+ "glob": "7.1.2", >+ "growl": "1.10.3", >+ "he": "1.1.1", >+ "mkdirp": "0.5.1", >+ "supports-color": "4.4.0" >+ }, >+ "dependencies": { >+ "has-flag": { >+ "version": "2.0.0", >+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", >+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", >+ "dev": true >+ }, >+ "supports-color": { >+ "version": "4.4.0", >+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", >+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", >+ "dev": true, >+ "requires": { >+ "has-flag": "2.0.0" >+ } >+ } >+ } >+ }, >+ "ms": { >+ "version": "2.0.0", >+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", >+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", >+ "dev": true >+ }, >+ "normalize-path": { >+ "version": "2.1.1", >+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", >+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", >+ "dev": true, >+ "requires": { >+ "remove-trailing-separator": "1.1.0" >+ } >+ }, >+ "object.omit": { >+ "version": "2.0.1", >+ "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", >+ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", >+ "dev": true, >+ "requires": { >+ "for-own": "0.1.5", >+ "is-extendable": "0.1.1" >+ } >+ }, >+ "once": { >+ "version": "1.4.0", >+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", >+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", >+ "dev": true, >+ "requires": { >+ "wrappy": "1.0.2" >+ } >+ }, >+ "parse-glob": { >+ "version": "3.0.4", >+ "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", >+ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", >+ "dev": true, >+ "requires": { >+ "glob-base": "0.3.0", >+ "is-dotfile": "1.0.3", >+ "is-extglob": "1.0.0", >+ "is-glob": "2.0.1" >+ } >+ }, >+ "path-is-absolute": { >+ "version": "1.0.1", >+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", >+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", >+ "dev": true >+ }, >+ "preserve": { >+ "version": "0.2.0", >+ "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", >+ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", >+ "dev": true >+ }, >+ "pretty-format": { >+ "version": "22.4.0", >+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-22.4.0.tgz", >+ "integrity": "sha512-pvCxP2iODIIk9adXlo4S3GRj0BrJiil68kByAa1PrgG97c1tClh9dLMgp3Z6cHFZrclaABt0UH8PIhwHuFLqYA==", >+ "dev": true, >+ "requires": { >+ "ansi-regex": "3.0.0", >+ "ansi-styles": "3.2.1" >+ } >+ }, >+ "randomatic": { >+ "version": "1.1.7", >+ "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", >+ "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", >+ "dev": true, >+ "requires": { >+ "is-number": "3.0.0", >+ "kind-of": "4.0.0" >+ }, >+ "dependencies": { >+ "is-number": { >+ "version": "3.0.0", >+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", >+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", >+ "dev": true, >+ "requires": { >+ "kind-of": "3.2.2" >+ }, >+ "dependencies": { >+ "kind-of": { >+ "version": "3.2.2", >+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", >+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", >+ "dev": true, >+ "requires": { >+ "is-buffer": "1.1.6" >+ } >+ } >+ } >+ }, >+ "kind-of": { >+ "version": "4.0.0", >+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", >+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", >+ "dev": true, >+ "requires": { >+ "is-buffer": "1.1.6" >+ } >+ } >+ } >+ }, >+ "regex-cache": { >+ "version": "0.4.4", >+ "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", >+ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", >+ "dev": true, >+ "requires": { >+ "is-equal-shallow": "0.1.3" >+ } >+ }, >+ "remove-trailing-separator": { >+ "version": "1.1.0", >+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", >+ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", >+ "dev": true >+ }, >+ "repeat-element": { >+ "version": "1.1.2", >+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", >+ "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", >+ "dev": true >+ }, >+ "repeat-string": { >+ "version": "1.6.1", >+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", >+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", >+ "dev": true >+ }, >+ "slash": { >+ "version": "1.0.0", >+ "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", >+ "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", >+ "dev": true >+ }, >+ "stack-utils": { >+ "version": "1.0.1", >+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.1.tgz", >+ "integrity": "sha1-1PM6tU6OOHeLDKXP07OvsS22hiA=", >+ "dev": true >+ }, >+ "supports-color": { >+ "version": "5.3.0", >+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", >+ "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", >+ "dev": true, >+ "requires": { >+ "has-flag": "3.0.0" >+ } >+ }, >+ "wrappy": { >+ "version": "1.0.2", >+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", >+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", >+ "dev": true >+ } >+ } >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/package.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/package.json >index 02b2a9d9b1644eb6e614fa7394ad6c0dde1fed86..ab282d189bb9e5d65703f3bd7a68399ef8f32ee6 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/package.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/package.json >@@ -1,21 +1,24 @@ > { > "name": "webidl2", > "description": "A WebIDL Parser", >- "version": "2.4.0", >- "author": "Robin Berjon <robin@berjon.com>", >- "license": "MIT", >+ "version": "10.2.1", >+ "contributors": [ >+ "Robin Berjon <robin@berjon.com> (https://berjon.com)", >+ "Marcos Caceres <marcos@marcosc.com> (https://marcosc.com)", >+ "Kagami Sascha Rosylight <saschaplas@outlook.com>", >+ "Timothy Gu <timothygu99@gmail.com>" >+ ], >+ "license": "W3C", > "dependencies": {}, > "devDependencies": { >- "mocha": "3.2.0", >- "expect": "1.20.2", >- "underscore": "1.8.3", >- "jsondiffpatch": "0.2.4", >- "benchmark": "*", >- "microtime": "2.1.3" >+ "expect": "22.4.0", >+ "jsondiffpatch": "0.3.5", >+ "mocha": "5.0.4" > }, > "scripts": { >- "test": "mocha" >+ "test": "mocha", >+ "acquire": "node test/util/acquire.js" > }, >- "repository": "git://github.com/darobin/webidl2.js", >+ "repository": "git://github.com/w3c/webidl2.js", > "main": "index" > } >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid.js b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid.js >index b8ab3a1866de0f05d23b2999f97a216e8b789c7e..19bbf006e579ef5997ae23c01decf28c0b0acb68 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid.js >@@ -1,42 +1,20 @@ >- > // NOTES: > // - the errors actually still need to be reviewed to check that they > // are fully correct interpretations of the IDLs > >-var wp = process.env.JSCOV ? require("../lib-cov/webidl2") : require("../lib/webidl2") >-, expect = require("expect") >-, pth = require("path") >-, fs = require("fs") >-; >-describe("Parses all of the invalid IDLs to check that they blow up correctly", function () { >- var dir = pth.join(__dirname, "invalid/idl") >- , skip = {} >- , idls = fs.readdirSync(dir) >- .filter(function (it) { return (/\.w?idl$/).test(it) && !skip[it]; }) >- .map(function (it) { return pth.join(dir, it); }) >- , errors = idls.map(function (it) { return pth.join(__dirname, "invalid", "json", pth.basename(it).replace(/\.w?idl/, ".json")); }) >- ; >+"use strict"; > >- for (var i = 0, n = idls.length; i < n; i++) { >- var idl = idls[i], error = JSON.parse(fs.readFileSync(errors[i], "utf8")); >- var func = (function (idl, err) { >- return function () { >- var error; >- try { >- var ast = wp.parse(fs.readFileSync(idl, "utf8")); >- console.log(JSON.stringify(ast, null, 4)); >- } >- catch (e) { >- error = e; >- } >- finally { >- expect(error).toExist(); >- expect(error.message).toEqual(err.message); >- expect(error.line).toEqual(err.line); >- } >+const { collect } = require("./util/collect"); >+const fs = require("fs"); >+const expect = require("expect"); > >- }; >- }(idl, error)); >- it("should produce the right error for " + idl, func); >- } >+describe("Parses all of the invalid IDLs to check that they blow up correctly", () => { >+ for (const test of collect("invalid", { expectError: true })) { >+ it(`should produce the right error for ${test.path}`, () => { >+ const err = test.readJSON(); >+ expect(test.error).toBeTruthy(); >+ expect(test.error.message).toEqual(err.message); >+ expect(test.error.line).toEqual(err.line); >+ }); >+ } > }); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/array.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/array.widl >new file mode 100644 >index 0000000000000000000000000000000000000000..58a8618ab648579247a8cd00ac9dc4a585faf6b8 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/array.widl >@@ -0,0 +1,6 @@ >+// Extracted from http://dev.w3.org/2006/webapi/WebIDL/ on 2011-05-06 >+// T[] is removed by https://github.com/heycam/webidl/commit/079cbb861a99e9e857a3f2a169c0beeb49cd020a >+[Constructor] >+interface LotteryResults { >+ readonly attribute unsigned short[][] numbers; >+}; >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/caller.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/caller.widl >new file mode 100644 >index 0000000000000000000000000000000000000000..26fedc33f9402c651ebd15629a8fcb7212102120 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/caller.widl >@@ -0,0 +1,7 @@ >+// Extracted from http://dev.w3.org/2006/webapi/WebIDL/ on 2011-05-06 >+// legacycallers are removed by https://github.com/heycam/webidl/pull/412 >+ >+interface NumberQuadrupler { >+ // This operation simply returns four times the given number x. >+ legacycaller float compute(float x); >+}; >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/duplicate.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/duplicate.widl >new file mode 100644 >index 0000000000000000000000000000000000000000..4916af34273d30dd7579a9be362c5f8deb65df36 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/duplicate.widl >@@ -0,0 +1,5 @@ >+typedef int Test; >+ >+interface Test { >+ void foo(); >+}; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/exception.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/exception.widl >new file mode 100644 >index 0000000000000000000000000000000000000000..a0ea2e47e20833641440b095a9b2d2d02f4504b7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/exception.widl >@@ -0,0 +1,6 @@ >+// Extracted from http://dev.w3.org/2006/webapi/WebIDL/ on 2011-05-06 >+// IDL exceptions are removed by https://github.com/heycam/webidl/commit/50e172ec079db073c3724c9beac1b576fb5dbc47 >+ >+exception SomeException { >+}; >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/iterator.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/iterator.widl >new file mode 100644 >index 0000000000000000000000000000000000000000..3bf1b36dec675656cbfd7ea4603617b3db91bfc6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/iterator.widl >@@ -0,0 +1,35 @@ >+interface SessionManager { >+ Session getSessionForUser(DOMString username); >+ readonly attribute unsigned long sessionCount; >+ >+ Session iterator; >+}; >+ >+interface Session { >+ readonly attribute DOMString username; >+ // ... >+}; >+ >+interface SessionManager2 { >+ Session2 getSessionForUser(DOMString username); >+ readonly attribute unsigned long sessionCount; >+ >+ Session2 iterator = SessionIterator; >+}; >+ >+interface Session2 { >+ readonly attribute DOMString username; >+ // ... >+}; >+ >+interface SessionIterator { >+ readonly attribute unsigned long remainingSessions; >+}; >+ >+ interface NodeList { >+ Node iterator = NodeIterator; >+ }; >+ >+ interface NodeIterator { >+ Node iterator object; >+ }; >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/maplike-1type.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/maplike-1type.widl >index 33c274b8b9a88605ed538b270ff6f5c7d0762016..efb5c14ffd626f7719277ee3892fce5fb664ec45 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/maplike-1type.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/maplike-1type.widl >@@ -1,3 +1,3 @@ > interface MapLikeOneType { >- maplike<long>; >+ maplike<long>; > } >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/no-semicolon-callback.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/no-semicolon-callback.widl >new file mode 100644 >index 0000000000000000000000000000000000000000..cb2055718e5f044a671424532eee6afe577bebc2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/no-semicolon-callback.widl >@@ -0,0 +1,7 @@ >+callback interface NoSemicolon { >+ attribute boolean noSemiColon; >+} >+ >+enum YouNeedOne { >+ "really" >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/no-semicolon.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/no-semicolon.widl >new file mode 100644 >index 0000000000000000000000000000000000000000..10bc716249b3e1fa40faacb7298ee3b1f7b673bf >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/no-semicolon.widl >@@ -0,0 +1,7 @@ >+partial interface NoSemicolon { >+ attribute boolean noSemiColon; >+} >+ >+enum YouNeedOne { >+ "really" >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/promise-with-extended-attribute.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/promise-with-extended-attribute.widl >new file mode 100644 >index 0000000000000000000000000000000000000000..0ce171fec33e72d36168ad0d731c5199adb8b08e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/promise-with-extended-attribute.widl >@@ -0,0 +1,3 @@ >+interface Foo { >+ Promise<[XAttr] DOMString> foo(any param); >+}; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/readonly-iterable.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/readonly-iterable.widl >index fc4ae2be908446e336cadd84c475cb7462b0b355..6057aa1feba64ebce61c9ec067f6250f036efa0e 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/readonly-iterable.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/readonly-iterable.widl >@@ -1,3 +1,3 @@ > interface ReadonlyIterable { >- readonly iterable<long>; >+ readonly iterable<long>; > } >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/record-key-with-extended-attribute.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/record-key-with-extended-attribute.widl >new file mode 100644 >index 0000000000000000000000000000000000000000..c11eb7414b0b8fcd9f2f6a1833bc764185b051fe >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/record-key-with-extended-attribute.widl >@@ -0,0 +1,3 @@ >+interface Foo { >+ void foo(record<[XAttr] DOMString, any> param); >+}; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/setlike-2types.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/setlike-2types.widl >index 1ecae22c0106cc9b8e5b30d6af3dfeeefb3dc22b..c2681bc75f1e8b38a2b83ce9ee5a262fbdcda762 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/setlike-2types.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/setlike-2types.widl >@@ -1,3 +1,3 @@ > interface SetLikeTwoTypes { >- setlike<long, long>; >+ setlike<long, long>; > } >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/setter-creator.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/setter-creator.widl >new file mode 100644 >index 0000000000000000000000000000000000000000..a70b26774d722f99119b8e7ce975b11627338145 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/setter-creator.widl >@@ -0,0 +1,4 @@ >+// Extracted from http://dev.w3.org/2006/webapi/WebIDL/ on 2011-05-06 >+interface OrderedMap { >+ setter creator void set(DOMString name, any value); >+}; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/special-omittable.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/special-omittable.widl >index bdfbfa709733f9faa6672ac3953b4673f283092f..dd0c1b18589979c4baba301a6e792bb1d1eca4e1 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/special-omittable.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/special-omittable.widl >@@ -1,5 +1,5 @@ > // Extracted from http://dev.w3.org/2006/webapi/WebIDL/ on 2011-05-06 >-// omittable is no longer a recognized keywoard as of 20110905 >+// omittable is no longer a recognized keyword as of 20110905 > interface Dictionary { > readonly attribute unsigned long propertyCount; > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/stray-slash.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/stray-slash.widl >new file mode 100644 >index 0000000000000000000000000000000000000000..b673aa94b01d65a0b666879f8c899c86111c7ab4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/stray-slash.widl >@@ -0,0 +1,2 @@ >+// This is a comment. >+/ This is not. >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/stringconstants.idl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/stringconstants.idl >deleted file mode 100644 >index 44fd3ff136ee5671637d02cb80964ddba092a658..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/stringconstants.idl >+++ /dev/null >@@ -1,3 +0,0 @@ >-interface Util { >- const DOMString hello = "world"; >-}; >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/stringconstants.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/stringconstants.widl >new file mode 100644 >index 0000000000000000000000000000000000000000..44fd3ff136ee5671637d02cb80964ddba092a658 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/stringconstants.widl >@@ -0,0 +1,3 @@ >+interface Util { >+ const DOMString hello = "world"; >+}; >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/typedef-nested.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/typedef-nested.widl >index 106f30b8f72ec7df496302b4a03ddddb55bf7f19..dfd377bf932b98cceeeb69755e8eacfa38417ae0 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/typedef-nested.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/typedef-nested.widl >@@ -19,4 +19,4 @@ > boolean allPointsWithinBounds(PointSequence ps); > }; > >- typedef [Clamp] octet value; >\ No newline at end of file >+ typedef [Clamp] octet value; >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/w3c-import.log >index 6a3f4930a4eb7f3dbf3a4e17fd2aea3dc26d3550..8520f366de7d4b7547c9fd7b953917dd6ab129dc 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/w3c-import.log >@@ -14,18 +14,29 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/array.widl >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/caller.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/dict-required-default.widl >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/duplicate.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/enum.widl >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/exception.widl >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/iterator.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/maplike-1type.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/module.widl >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/no-semicolon-callback.widl >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/no-semicolon.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/nonnullableany.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/nonnullableobjects.widl >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/promise-with-extended-attribute.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/raises.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/readonly-iterable.widl >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/record-key-with-extended-attribute.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/record-key.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/scopedname.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/sequenceAsAttribute.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/setlike-2types.widl >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/setter-creator.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/special-omittable.widl >-/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/stringconstants.idl >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/stray-slash.widl >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/stringconstants.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/idl/typedef-nested.widl >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/array.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/array.json >new file mode 100644 >index 0000000000000000000000000000000000000000..898b2d836bff81330d734e0ba10372e9772fd523 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/array.json >@@ -0,0 +1,4 @@ >+{ >+ "message": "Got an error during or right after parsing `interface LotteryResults`: No name in attribute", >+ "line": 5 >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/caller.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/caller.json >new file mode 100644 >index 0000000000000000000000000000000000000000..567fa3368129f9b6d54bb3bb4c0f9d4d50186525 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/caller.json >@@ -0,0 +1,4 @@ >+{ >+ "message": "Got an error during or right after parsing `interface NumberQuadrupler`: Invalid operation", >+ "line": 6 >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/dict-required-default.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/dict-required-default.json >index c5afeca85c05debc159481b3e8344aa87fd96da2..82b6b2ae42a6f61a20a32bcb67f44461ba7adae1 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/dict-required-default.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/dict-required-default.json >@@ -1,4 +1,4 @@ > { >- "message": "Required member must not have a default" >+ "message": "Got an error during or right after parsing `dictionary Dict`: Required member must not have a default" > , "line": 4 > } >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/duplicate.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/duplicate.json >new file mode 100644 >index 0000000000000000000000000000000000000000..e88a7156fe8c1c602ebe1ae8d66cbeebe69ff060 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/duplicate.json >@@ -0,0 +1,4 @@ >+{ >+ "message": "Got an error during or right after parsing `typedef Test`: The name \"Test\" of type \"typedef\" is already seen", >+ "line": 3 >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/enum.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/enum.json >index 166115801c3411b8faf7d3e9bccbe4a022a02b0e..073ff6c290cafdf614909b8f6ef27ba0a4c5829d 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/enum.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/enum.json >@@ -1,4 +1,4 @@ > { >- "message": "Unexpected value in enum" >+ "message": "Got an error during or right after parsing `enum foo`: Unexpected value in enum" > , "line": 1 > } >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/exception.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/exception.json >new file mode 100644 >index 0000000000000000000000000000000000000000..ad9fac6ca2f64e7083421516a9ceb9e6397555ec >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/exception.json >@@ -0,0 +1,4 @@ >+{ >+ "message": "Got an error before parsing any named definition: Unrecognised tokens", >+ "line": 4 >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/iterator.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/iterator.json >new file mode 100644 >index 0000000000000000000000000000000000000000..e46d653ae3c51293d584045cdadd6c0a301206fe >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/iterator.json >@@ -0,0 +1,4 @@ >+{ >+ "message": "Got an error during or right after parsing `interface SessionManager`: Invalid operation", >+ "line": 5 >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/maplike-1type.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/maplike-1type.json >index 859a820a4910cd1592dd52b31adebb013409f917..75e7a35ee256e91357994ff8a85b1828cb48112e 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/maplike-1type.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/maplike-1type.json >@@ -1,4 +1,4 @@ > { >- "message": "Missing second type argument in maplike declaration", >+ "message": "Got an error during or right after parsing `interface MapLikeOneType`: Missing second type argument in maplike declaration", > "line": 2 >-} >\ No newline at end of file >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/module.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/module.json >index 3b0984d973f45e32c56dd76d6d8b7fd6d8beb220..9c071cdd07a7a39ed18592e82100d8d50065a030 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/module.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/module.json >@@ -1,4 +1,4 @@ > { >- "message": "Unrecognised tokens" >+ "message": "Got an error before parsing any named definition: Unrecognised tokens" > , "line": 2 > } >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/no-semicolon-callback.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/no-semicolon-callback.json >new file mode 100644 >index 0000000000000000000000000000000000000000..1db9d14c8e2c51204a1e2a2d7d1e98c3066106ef >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/no-semicolon-callback.json >@@ -0,0 +1,4 @@ >+{ >+ "message": "Got an error during or right after parsing `callback interface NoSemicolon`: Missing semicolon after interface", >+ "line": 5 >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/no-semicolon.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/no-semicolon.json >new file mode 100644 >index 0000000000000000000000000000000000000000..087532a012f59276976b70b1709e927c2ddd0797 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/no-semicolon.json >@@ -0,0 +1,4 @@ >+{ >+ "message": "Got an error during or right after parsing `partial interface NoSemicolon`: Missing semicolon after interface", >+ "line": 5 >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/nonnullableany.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/nonnullableany.json >index cf5229e8e44ab096ae16c22e0b0b04c392fcb28b..8a1f90046ae4d9df8c58bf17e0c2ed6bdc7c4fd0 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/nonnullableany.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/nonnullableany.json >@@ -1,4 +1,4 @@ > { >- "message": "Type any cannot be made nullable" >+ "message": "Got an error during or right after parsing `interface NonNullable`: Type any cannot be made nullable" > , "line": 2 > } >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/nonnullableobjects.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/nonnullableobjects.json >index 23cbb3e5d180f15a898743edbd7ec400a74b32f4..52bd8dac16fe69262a0e1751bc0c2b66b215492b 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/nonnullableobjects.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/nonnullableobjects.json >@@ -1,4 +1,4 @@ > { >- "message": "Can't nullable more than once" >+ "message": "Got an error during or right after parsing `interface NonNullable`: Can't nullable more than once" > , "line": 4 > } >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/promise-with-extended-attribute.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/promise-with-extended-attribute.json >new file mode 100644 >index 0000000000000000000000000000000000000000..71212d46e3c011aed64cb6b6008a4a1b427d14bf >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/promise-with-extended-attribute.json >@@ -0,0 +1,4 @@ >+{ >+ "message": "Got an error during or right after parsing `interface Foo`: Promise type cannot have extended attribute", >+ "line": 2 >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/raises.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/raises.json >index 8b67afe4fc9702d3577aef8cf9f430662cd60119..3165b874f0c1891186b479b6460c0ae90a8533db 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/raises.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/raises.json >@@ -1,4 +1,4 @@ > { >- "message": "Unterminated attribute" >+ "message": "Got an error during or right after parsing `interface Person`: Unterminated attribute" > , "line": 5 > } >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/readonly-iterable.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/readonly-iterable.json >index c6f52a24615883eddf581aa15d215b426859c4cb..1a09264a6d0d651ecc3f22268fc6078c9cac9f96 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/readonly-iterable.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/readonly-iterable.json >@@ -1,4 +1,4 @@ > { >- "message": "Invalid operation", >+ "message": "Got an error during or right after parsing `interface ReadonlyIterable`: Invalid operation", > "line": 2 >-} >\ No newline at end of file >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/record-key-with-extended-attribute.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/record-key-with-extended-attribute.json >new file mode 100644 >index 0000000000000000000000000000000000000000..4002e7fe0155d5bc2d615d55a4e4e976e13e38a8 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/record-key-with-extended-attribute.json >@@ -0,0 +1,4 @@ >+{ >+ "message": "Got an error during or right after parsing `interface Foo`: Record key cannot have extended attribute", >+ "line": 2 >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/record-key.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/record-key.json >index 3b929b926a30a7d0b776961ee5135fae3ae57265..179d645d6a753dcebb7f9be254b51a916066fe70 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/record-key.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/record-key.json >@@ -1,4 +1,4 @@ > { >- "message": "Record key must be DOMString, USVString, or ByteString", >+ "message": "Got an error during or right after parsing `interface Foo`: Record key must be DOMString, USVString, or ByteString", > "line": 2 > } >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/scopedname.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/scopedname.json >index 8e2cd803287ef4fce3812c5ea55cfdc87c01e31f..4620d2df5fa0cc254a6d6cd3c6b75147c658b40a 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/scopedname.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/scopedname.json >@@ -1,4 +1,4 @@ > { >- "message": "No name in typedef" >+ "message": "Got an error before parsing any named definition: No name in typedef" > , "line": 2 > } >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/sequenceAsAttribute.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/sequenceAsAttribute.json >index b714f5d92434a2cc45630336b33d7645556c329c..5b4314a6de128dc602ae1dec4601a00f86c111bf 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/sequenceAsAttribute.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/sequenceAsAttribute.json >@@ -1,4 +1,4 @@ > { >- "message": "Attributes cannot accept sequence types" >+ "message": "Got an error during or right after parsing `interface sequenceAsAttribute`: Attributes cannot accept sequence types" > , "line": 2 > } >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/setlike-2types.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/setlike-2types.json >index c9e49b6756d5d900a0c1b18a440e62b4811a1d3b..2900e1bac300742cec71ee8f66977bde9b9c60ac 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/setlike-2types.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/setlike-2types.json >@@ -1,4 +1,4 @@ > { >- "message": "Unterminated setlike declaration", >+ "message": "Got an error during or right after parsing `interface SetLikeTwoTypes`: Unterminated setlike declaration", > "line": 2 >-} >\ No newline at end of file >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/setter-creator.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/setter-creator.json >new file mode 100644 >index 0000000000000000000000000000000000000000..25decb374e12fe27f05979e40d7f30647395be16 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/setter-creator.json >@@ -0,0 +1,4 @@ >+{ >+ "message": "Got an error during or right after parsing `interface OrderedMap`: Invalid operation", >+ "line": 3 >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/special-omittable.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/special-omittable.json >index 7acb08834b0e6eaf0ece877b63466eadb42a5299..c20b28e03c17d6df29e2ca1b7ee948f579ff3f27 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/special-omittable.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/special-omittable.json >@@ -1,4 +1,4 @@ > { >- "message": "Invalid operation" >+ "message": "Got an error during or right after parsing `interface Dictionary`: Invalid operation" > , "line": 6 > } >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/stray-slash.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/stray-slash.json >new file mode 100644 >index 0000000000000000000000000000000000000000..9c071cdd07a7a39ed18592e82100d8d50065a030 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/stray-slash.json >@@ -0,0 +1,4 @@ >+{ >+ "message": "Got an error before parsing any named definition: Unrecognised tokens" >+, "line": 2 >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/stringconstants.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/stringconstants.json >index d5bf1a8832c664a02c488f70df005311d30b926a..1eeb31cd3ef802b2c8f67951dd8a24fe225ebc47 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/stringconstants.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/stringconstants.json >@@ -1,4 +1,4 @@ > { >- "message": "No value for const" >+ "message": "Got an error during or right after parsing `interface Util`: No value for const" > , "line": 2 > } >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/typedef-nested.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/typedef-nested.json >index d7fb9182f86e9d3db758763f472e2ab056fcaf09..8c6081496851abcfc96073286242a19f34e5b529 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/typedef-nested.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/typedef-nested.json >@@ -1,4 +1,4 @@ > { >- "message": "Invalid operation" >+ "message": "Got an error during or right after parsing `interface Widget`: Invalid operation" > , "line": 14 >-} >\ No newline at end of file >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/w3c-import.log >index 7bc368eafaa544d2ea457f2748b2eeb4a509cec8..4d56d9f6fc3d380da4b5706c724711ef0eee775f 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/w3c-import.log >@@ -14,18 +14,29 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/array.json >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/caller.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/dict-required-default.json >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/duplicate.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/enum.json >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/exception.json >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/iterator.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/maplike-1type.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/module.json >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/no-semicolon-callback.json >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/no-semicolon.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/nonnullableany.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/nonnullableobjects.json >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/promise-with-extended-attribute.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/raises.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/readonly-iterable.json >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/record-key-with-extended-attribute.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/record-key.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/scopedname.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/sequenceAsAttribute.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/setlike-2types.json >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/setter-creator.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/special-omittable.json >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/stray-slash.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/stringconstants.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid/json/typedef-nested.json >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax.js b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax.js >index 3b343e4229d5027d9fe081418d2d5fb47d49a8f5..05d647eda103945b0633bef0b53ee789268165d3 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax.js >@@ -1,41 +1,19 @@ >+"use strict"; > >-var wp = process.env.JSCOV ? require("../lib-cov/webidl2") : require("../lib/webidl2") >-, expect = require("expect") >-, pth = require("path") >-, fs = require("fs") >-, jdp = require("jsondiffpatch") >-, debug = true >-; >-describe("Parses all of the IDLs to produce the correct ASTs", function () { >- var dir = pth.join(__dirname, "syntax/idl") >- , skip = {} // use if we have a broken test >- , idls = fs.readdirSync(dir) >- .filter(function (it) { return (/\.widl$/).test(it) && !skip[it]; }) >- .map(function (it) { return pth.join(dir, it); }) >- , jsons = idls.map(function (it) { return pth.join(__dirname, "syntax/json", pth.basename(it).replace(".widl", ".json")); }) >- ; >+const { collect } = require("./util/collect"); >+const expect = require("expect"); >+const debug = true; > >- for (var i = 0, n = idls.length; i < n; i++) { >- var idl = idls[i], json = jsons[i]; >- >- var func = (function (idl, json) { >- return function () { >- try { >- var optFile = pth.join(__dirname, "syntax/opt", pth.basename(json)); >- var opt = undefined; >- if (fs.existsSync(optFile)) >- opt = JSON.parse(fs.readFileSync(optFile, "utf8")); >- var diff = jdp.diff(JSON.parse(fs.readFileSync(json, "utf8")), >- wp.parse(fs.readFileSync(idl, "utf8"), opt)); >- if (diff && debug) console.log(JSON.stringify(diff, null, 4)); >- expect(diff).toBe(undefined); >- } >- catch (e) { >- console.log(e.toString()); >- throw e; >- } >- }; >- }(idl, json)); >- it("should produce the same AST for " + idl, func); >- } >+describe("Parses all of the IDLs to produce the correct ASTs", () => { >+ for (const test of collect("syntax")) { >+ it(`should produce the same AST for ${test.path}`, () => { >+ try { >+ expect(test.diff()).toBeFalsy(); >+ } >+ catch (e) { >+ console.log(e.toString()); >+ throw e; >+ } >+ }); >+ } > }); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/array.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/array.widl >deleted file mode 100644 >index 22e21fb6564738bd56830ce0300da389ce0574bf..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/array.widl >+++ /dev/null >@@ -1,5 +0,0 @@ >-// Extracted from http://dev.w3.org/2006/webapi/WebIDL/ on 2011-05-06 >-[Constructor] >-interface LotteryResults { >- readonly attribute unsigned short[][] numbers; >-}; >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/attributes.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/attributes.widl >index 7e1d691cbe28afdc58082a7fd81cbdb4f37cf456..1d3d5c8e83454938c691a00a7846afb423cfc4d5 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/attributes.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/attributes.widl >@@ -1,9 +1,4 @@ > // Extracted from http://dev.w3.org/2006/webapi/WebIDL/ on 2011-05-06 >-exception InvalidName { >- DOMString reason; >-}; >- >-exception NoSuchPet { }; > > interface Person { > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/caller.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/caller.widl >deleted file mode 100644 >index 92acb1c017631f04762f8d68e0462e10d3739dad..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/caller.widl >+++ /dev/null >@@ -1,5 +0,0 @@ >-// Extracted from http://dev.w3.org/2006/webapi/WebIDL/ on 2011-05-06 >-interface NumberQuadrupler { >- // This operation simply returns four times the given number x. >- legacycaller float compute(float x); >-}; >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/constants.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/constants.widl >index 5e28ae9c116a9d9262ea9e59e5b95350a1ce613f..043b022b6462eed600c8a9ceab87d1ebaef5ea18 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/constants.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/constants.widl >@@ -8,11 +8,4 @@ interface Util { > const unrestricted float sobig = Infinity; > const unrestricted double minusonedividedbyzero = -Infinity; > const short notanumber = NaN; >-}; >- >-exception Error { >- const short ERR_UNKNOWN = 0; >- const short ERR_OUT_OF_MEMORY = 1; >- >- short errorCode; > }; >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/equivalent-decl.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/equivalent-decl.widl >index 6b3e0eda284ad71f7b3ad6221a15214d4fc0fc23..6ffeb3c20a1a47209ceb2ec2441f62be3f553158 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/equivalent-decl.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/equivalent-decl.widl >@@ -7,7 +7,7 @@ interface Dictionary { > }; > > >-interface Dictionary { >+interface Dictionary2 { > readonly attribute unsigned long propertyCount; > > float getProperty(DOMString propertyName); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/exception-inheritance.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/exception-inheritance.widl >deleted file mode 100644 >index 258fdeba6f43d36a2a8d7927b695d53a5cc5d2e3..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/exception-inheritance.widl >+++ /dev/null >@@ -1,7 +0,0 @@ >-// from http://lists.w3.org/Archives/Public/public-script-coord/2010OctDec/0112.html >- exception DOMException { >- unsigned short code; >- }; >- >- exception HierarchyRequestError : DOMException { }; >- exception NoModificationAllowedError : DOMException { }; >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/exception.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/exception.widl >deleted file mode 100644 >index f4b6ae29e10ddb18ffa5fc2b6201f923cb1ad50d..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/exception.widl >+++ /dev/null >@@ -1,8 +0,0 @@ >-// Extracted from http://dev.w3.org/2006/webapi/WebIDL/ on 2011-05-06 >-interface Dahut { >- attribute DOMString type; >-}; >- >-exception SomeException { >-}; >- >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/extended-attributes.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/extended-attributes.widl >index c1df79e142d54dbf9bd4c3c298b0c270e679ffc2..57d4f97de7c3176b65e3da2aa7ed53d3db789fd9 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/extended-attributes.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/extended-attributes.widl >@@ -2,10 +2,28 @@ > > [Global=(Worker,ServiceWorker), Exposed=ServiceWorker] > interface ServiceWorkerGlobalScope : WorkerGlobalScope { >- >+ > }; > > // Conformance with ExtendedAttributeList grammar in http://www.w3.org/TR/WebIDL/#idl-extended-attributes > // Section 3.11 > [IntAttr=0, FloatAttr=3.14, StringAttr="abc"] > interface IdInterface {}; >+ >+// Extracted from http://www.w3.org/TR/2016/REC-WebIDL-1-20161215/#Constructor on 2017-5-18 with whitespace differences >+[ >+ Constructor, >+ Constructor(double radius) >+] >+interface Circle { >+ attribute double r; >+ attribute double cx; >+ attribute double cy; >+ readonly attribute double circumference; >+}; >+ >+// Extracted from https://heycam.github.io/webidl/#idl-annotated-types on 2017-12-15 >+[Exposed=Window] >+interface I { >+ attribute [XAttr] (long or Node) attrib; >+}; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/generic.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/generic.widl >index 02b64572a426abc69e4247563eb1d4797aec321e..12a1a3f62b0a6f5c32b31fd1deae39477912a48d 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/generic.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/generic.widl >@@ -1,12 +1,12 @@ > interface Foo { > Promise<ResponsePromise<sequence<DOMString?>>> bar(); >- readonly attribute Promise<DOMString>[] baz; >+ readonly attribute Promise<DOMString> baz; > }; > > // Extracted from https://slightlyoff.github.io/ServiceWorker/spec/service_worker/ on 2014-05-08 > > interface ServiceWorkerClients { >- Promise<Client[]?> getServiced(); >+ Promise<Client?> getServiced(); > Promise<any> reloadAll(); > }; > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/identifier-qualified-names.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/identifier-qualified-names.widl >index 33893d4c64498240b5cb84f19081dbd6f90e0d2a..986d0bf78c6a6f0e787c6c0b7f0b9360e478dafe 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/identifier-qualified-names.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/identifier-qualified-names.widl >@@ -3,18 +3,6 @@ > // Qualified name: "::framework::number" > typedef float number; > >- // Exception identifier: "FrameworkException" >- // Qualified name: "::framework::FrameworkException" >- exception FrameworkException { >- >- // Constant identifier: "ERR_NOT_FOUND" >- // Qualified name: "::framework::FrameworkException::ERR_NOT_FOUND" >- const long ERR_NOT_FOUND = 1; >- >- // Exception field identifier: "code" >- long code; >- }; >- > // Interface identifier: "System" > // Qualified name: "::framework::System" > interface System { >@@ -27,7 +15,7 @@ > getter DOMString (DOMString keyName); > }; > >- >+ > // Interface identifier: "TextField" > // Qualified name: "::framework::gui::TextField" > interface TextField { >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/indexed-properties.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/indexed-properties.widl >index acf0ed3bf849f06b2fc1d375cb3a82488b3bd050..4b8aa9e353fac89c05ad21fe065b455e049268e3 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/indexed-properties.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/indexed-properties.widl >@@ -7,6 +7,6 @@ interface OrderedMap { > deleter void removeByIndex(unsigned long index); > > getter any get(DOMString name); >- setter creator void set(DOMString name, any value); >+ setter void set(DOMString name, any value); > deleter void remove(DOMString name); >-}; >\ No newline at end of file >+}; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/iterable.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/iterable.widl >index c7dfafa4daa808a225a1678ba52f350555de93c6..7f726f926fdecd72600c43e328f1e0bfb36f9be1 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/iterable.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/iterable.widl >@@ -1,7 +1,11 @@ > interface IterableOne { >- iterable<long>; >+ iterable<long>; > }; > > interface IterableTwo { >- iterable<short, double?>; >+ iterable<short, double?>; >+}; >+ >+interface IterableThree { >+ iterable<[XAttr] long>; > }; >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/iterator.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/iterator.widl >deleted file mode 100644 >index 3bf1b36dec675656cbfd7ea4603617b3db91bfc6..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/iterator.widl >+++ /dev/null >@@ -1,35 +0,0 @@ >-interface SessionManager { >- Session getSessionForUser(DOMString username); >- readonly attribute unsigned long sessionCount; >- >- Session iterator; >-}; >- >-interface Session { >- readonly attribute DOMString username; >- // ... >-}; >- >-interface SessionManager2 { >- Session2 getSessionForUser(DOMString username); >- readonly attribute unsigned long sessionCount; >- >- Session2 iterator = SessionIterator; >-}; >- >-interface Session2 { >- readonly attribute DOMString username; >- // ... >-}; >- >-interface SessionIterator { >- readonly attribute unsigned long remainingSessions; >-}; >- >- interface NodeList { >- Node iterator = NodeIterator; >- }; >- >- interface NodeIterator { >- Node iterator object; >- }; >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/legacyiterable.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/legacyiterable.widl >index eafa7cf0445947efee5d58bc1ff77376d166d8f0..9e1e9c527447a2bb2013baf28c31d3faddcac6ff 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/legacyiterable.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/legacyiterable.widl >@@ -1,3 +1,3 @@ > interface LegacyIterable { >- legacyiterable<long>; >+ legacyiterable<long>; > }; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/linecomment.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/linecomment.widl >new file mode 100644 >index 0000000000000000000000000000000000000000..5d31bdb62c999e9e4644cacc7d72daeedc4bc051 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/linecomment.widl >@@ -0,0 +1,2 @@ >+/* first */ >+// second >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/maplike.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/maplike.widl >index 7b79b3888026a7693be7e46e10187290ebe2b1b4..437e381fef7673ecacc52362b5a30910c68156cd 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/maplike.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/maplike.widl >@@ -1,7 +1,13 @@ > interface MapLike { >- maplike<long, float>; >+ maplike<long, float>; > }; > > interface ReadOnlyMapLike { >- readonly maplike<long, float>; >+ readonly maplike<long, float>; >+}; >+ >+// Extracted from https://heycam.github.io/webidl/#idl-type-extended-attribute-associated-with on 2017-07-01 >+ >+interface I { >+ maplike<[XAttr2] DOMString, [XAttr3] long>; > }; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/mixin.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/mixin.widl >new file mode 100644 >index 0000000000000000000000000000000000000000..7c37a6ee4207b31ddd2c48f9e1725721679e79e2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/mixin.widl >@@ -0,0 +1,12 @@ >+// Extracted from https://heycam.github.io/webidl/#using-mixins-and-partials on 2017-11-02 >+ >+interface mixin GlobalCrypto { >+ readonly attribute Crypto crypto; >+}; >+ >+Window includes GlobalCrypto; >+WorkerGlobalScope includes GlobalCrypto; >+ >+partial interface mixin WindowOrWorkerGlobalScope { >+ readonly attribute Crypto crypto; >+}; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/overloading.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/overloading.widl >index ef1288a887763dd78947de6b8786c00539474e97..52d8d15c1a13c81397bff5981d5745d9e42ea92d 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/overloading.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/overloading.widl >@@ -12,9 +12,9 @@ interface C { > void f(B x); > }; > >-interface A { >+interface D { > /* f1 */ void f(DOMString a); > /* f2 */ void f([AllowAny] DOMString a, DOMString b, float... c); > /* f3 */ void f(); > /* f4 */ void f(long a, DOMString b, optional DOMString c, float... d); >-}; >\ No newline at end of file >+}; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/primitives.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/primitives.widl >index 92939601a1a839cf7c48c3ed748eeb93bfa3febc..a91455ee192f192187e23728c78eaa6fda8d733f 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/primitives.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/primitives.widl >@@ -9,11 +9,11 @@ interface Primitives { > attribute long long bigbig; > attribute unsigned long long bigbigpositive; > attribute float real; >- attribute double bigreal; >+ attribute double bigreal; > attribute unrestricted float realwithinfinity; >- attribute unrestricted double bigrealwithinfinity; >- attribute DOMString string; >- attribute ByteString bytes; >+ attribute unrestricted double bigrealwithinfinity; >+ attribute DOMString string; >+ attribute ByteString bytes; > attribute Date date; > attribute RegExp regexp; >-}; >\ No newline at end of file >+}; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/record.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/record.widl >index 6cdedb219bece6da8fdc98c739d341b599f71c99..c8d9343142ca256ae3695b5990139e7a145f023d 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/record.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/record.widl >@@ -6,3 +6,7 @@ interface Foo { > // Make sure record can still be registered as a type. > record baz(); > }; >+ >+interface Bar { >+ record<DOMString, [XAttr] float> bar(); >+}; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/reg-operations.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/reg-operations.widl >index 13997cb1d121ce106f49cfdcdeb9789074704842..338c8d427636fb340a00db9ec9b1ac51cfe15388 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/reg-operations.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/reg-operations.widl >@@ -4,8 +4,6 @@ interface Dimensions { > attribute unsigned long height; > }; > >-exception NoPointerDevice { }; >- > interface Button { > > // An operation that takes no arguments, returns a boolean >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/sequence.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/sequence.widl >index 6ba0d390d251a7df21c785d3c4b100ef23717cbe..d31056cf076228bec9fcb817899fd8dc7d07c06e 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/sequence.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/sequence.widl >@@ -9,4 +9,10 @@ interface Canvas { > // Make sure sequence can still be registered as a type. > interface Foo { > sequence bar(); >-}; >\ No newline at end of file >+}; >+ >+// Extracted from https://heycam.github.io/webidl/#idl-type-extended-attribute-associated-with on 2017-07-01 >+ >+interface I { >+ void f1(sequence<[XAttr] long> arg); >+}; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/serializer.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/serializer.widl >deleted file mode 100644 >index 6f6ccd0e8d59e3e057f5ad0d2f65530b16a39359..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/serializer.widl >+++ /dev/null >@@ -1,64 +0,0 @@ >-interface Transaction { >- readonly attribute Account from; >- readonly attribute Account to; >- readonly attribute float amount; >- readonly attribute DOMString description; >- readonly attribute unsigned long number; >- >- serializer; >-}; >- >-interface Account { >- attribute DOMString name; >- attribute unsigned long number; >- serializer DOMString serialize(); >-}; >- >-interface Transaction2 { >- readonly attribute Account2 from; >- readonly attribute Account2 to; >- readonly attribute float amount; >- readonly attribute DOMString description; >- readonly attribute unsigned long number; >- >- serializer = { from, to, amount, description }; >-}; >- >-interface Account2 { >- attribute DOMString name; >- attribute unsigned long number; >- serializer = number; >-}; >- >-interface Account3 { >- attribute DOMString name; >- attribute unsigned long number; >- >- serializer = { attribute }; >-}; >- >-interface Account4 { >- getter object getItem(unsigned long index); >- serializer = { getter }; >-}; >- >-interface Account5 : Account { >- attribute DOMString secondname; >- serializer = { inherit, secondname }; >-}; >- >-interface Account6 : Account { >- attribute DOMString secondname; >- serializer = { inherit, attribute }; >-}; >- >-interface Account7 { >- attribute DOMString name; >- attribute unsigned long number; >- serializer = [ name, number ]; >-}; >- >-interface Account8 { >- getter object getItem(unsigned long index); >- serializer = [ getter ]; >-}; >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/setlike.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/setlike.widl >index 890e8e5a7597dde08c2fa7cb95461baddde69bba..4512f286b59a506fcbb957befe24a081b097d73e 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/setlike.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/setlike.widl >@@ -1,7 +1,11 @@ > interface SetLike { >- setlike<long>; >+ setlike<long>; > }; > > interface ReadOnlySetLike { >- readonly setlike<long>; >+ readonly setlike<long>; >+}; >+ >+interface SetLikeExt { >+ setlike<[XAttr] long>; > }; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/stringifier.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/stringifier.widl >index 4eb483d9b53861a104f712d942af3b10566023c5..c45277ea8db3377952b4bfa8a040aadb1d1c340e 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/stringifier.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/stringifier.widl >@@ -3,6 +3,6 @@ interface A { > stringifier DOMString (); > }; > >-interface A { >+interface B { > stringifier; > }; >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/typedef-union.idl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/typedef-union.idl >deleted file mode 100644 >index 3048703e0c5541d5ca69f51870f219abf3745b44..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/typedef-union.idl >+++ /dev/null >@@ -1,4 +0,0 @@ >- typedef (ImageData or >- HTMLImageElement or >- HTMLCanvasElement or >- HTMLVideoElement) TexImageSource; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/typedef-union.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/typedef-union.widl >new file mode 100644 >index 0000000000000000000000000000000000000000..3048703e0c5541d5ca69f51870f219abf3745b44 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/typedef-union.widl >@@ -0,0 +1,4 @@ >+ typedef (ImageData or >+ HTMLImageElement or >+ HTMLCanvasElement or >+ HTMLVideoElement) TexImageSource; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/typesuffixes.widl b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/typesuffixes.widl >index 95e31c1690236ce77703c9a3ca03e88e5ba1fc06..beaaa8726009e6b1a3ffe3aafd5f89bf7cafe4bb 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/typesuffixes.widl >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/typesuffixes.widl >@@ -1,3 +1,3 @@ > interface Suffixes { >- void test(sequence<DOMString[]?>? foo); >+ void test(sequence<DOMString?>? foo); > }; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/w3c-import.log >index e800709d6a2170f8246bf8c84930b90e5d582eb4..aaeea95654540b38ebee5f0601de6e6bd97dfd27 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/w3c-import.log >@@ -15,10 +15,8 @@ None > ------------------------------------------------------------------------ > List of files: > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/allowany.widl >-/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/array.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/attributes.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/callback.widl >-/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/caller.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/constants.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/constructor.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/dictionary-inherits.widl >@@ -27,8 +25,6 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/documentation.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/enum.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/equivalent-decl.widl >-/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/exception-inheritance.widl >-/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/exception.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/extended-attributes.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/generic.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/getter-setter.widl >@@ -38,9 +34,10 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/inherits-getter.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/interface-inherits.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/iterable.widl >-/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/iterator.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/legacyiterable.widl >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/linecomment.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/maplike.widl >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/mixin.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/namedconstructor.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/namespace.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/nointerfaceobject.widl >@@ -57,7 +54,6 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/reg-operations.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/replaceable.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/sequence.widl >-/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/serializer.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/setlike.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/static.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/stringifier-attribute.widl >@@ -65,7 +61,7 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/stringifier.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/treatasnull.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/treatasundefined.widl >-/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/typedef-union.idl >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/typedef-union.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/typedef.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/typesuffixes.widl > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/idl/uniontype.widl >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/allowany.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/allowany.json >index 8abc7f9e09248acbe909c32eb007b10e75987339..cd5c6e00ac33b29bffe40d90af60b39d23908c88 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/allowany.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/allowany.json >@@ -8,16 +8,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -29,16 +27,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -49,10 +45,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "B" > }, >@@ -65,16 +61,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -86,14 +80,16 @@ > "extAttrs": [ > { > "name": "AllowAny", >- "arguments": null >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null > } > ], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -106,4 +102,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/array.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/array.json >deleted file mode 100644 >index 39afaf6c8eb20192e60be96b962d2d641cf3998e..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/array.json >+++ /dev/null >@@ -1,34 +0,0 @@ >-[ >- { >- "type": "interface", >- "name": "LotteryResults", >- "partial": false, >- "members": [ >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": true, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": 2, >- "nullableArray": [false, false], >- "union": false, >- "idlType": "unsigned short" >- }, >- "name": "numbers", >- "extAttrs": [] >- } >- ], >- "inheritance": null, >- "extAttrs": [ >- { >- "name": "Constructor", >- "arguments": null >- } >- ] >- } >-] >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/attributes.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/attributes.json >index cdf46b0ecc20f4d4326e7fb9ad8e0384ac9dcb0e..c90c70d7edc4caeb5df6f3210ba2880cbcd78869 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/attributes.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/attributes.json >@@ -1,32 +1,4 @@ > [ >- { >- "type": "exception", >- "name": "InvalidName", >- "members": [ >- { >- "type": "field", >- "name": "reason", >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "DOMString" >- }, >- "extAttrs": [] >- } >- ], >- "inheritance": null, >- "extAttrs": [] >- }, >- { >- "type": "exception", >- "name": "NoSuchPet", >- "members": [], >- "inheritance": null, >- "extAttrs": [] >- }, > { > "type": "interface", > "name": "Person", >@@ -39,10 +11,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned short" > }, >@@ -53,4 +25,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/callback.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/callback.json >index 43a517510467c6666e69356b1f540b5da0f89f4c..f31067dd25cb997c7bf4c1c80e671538366aee4a 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/callback.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/callback.json >@@ -3,10 +3,10 @@ > "type": "callback", > "name": "AsyncOperationCallback", > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -16,10 +16,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -37,16 +37,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -57,10 +55,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -77,10 +75,10 @@ > "type": "callback", > "name": "SortCallback", > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "boolean" > }, >@@ -90,10 +88,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "any" > }, >@@ -104,10 +102,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "any" > }, >@@ -116,4 +114,4 @@ > ], > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/caller.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/caller.json >deleted file mode 100644 >index a0fb5e396a5a0e87721609c16e0e98eeaf362001..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/caller.json >+++ /dev/null >@@ -1,47 +0,0 @@ >-[ >- { >- "type": "interface", >- "name": "NumberQuadrupler", >- "partial": false, >- "members": [ >- { >- "type": "operation", >- "getter": false, >- "setter": false, >- "creator": false, >- "deleter": false, >- "legacycaller": true, >- "static": false, >- "stringifier": false, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "float" >- }, >- "name": "compute", >- "arguments": [ >- { >- "optional": false, >- "variadic": false, >- "extAttrs": [], >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "float" >- }, >- "name": "x" >- } >- ], >- "extAttrs": [] >- } >- ], >- "inheritance": null, >- "extAttrs": [] >- } >-] >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/constants.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/constants.json >index 0fe6e92afc3a23571522d5a526c9f81ba538a74b..4b98751622c3391c0f19caf1b21966ac5e525acc 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/constants.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/constants.json >@@ -7,7 +7,10 @@ > { > "type": "const", > "nullable": false, >- "idlType": "boolean", >+ "idlType": { >+ "type": "const-type", >+ "idlType": "boolean" >+ }, > "name": "DEBUG", > "value": { > "type": "boolean", >@@ -18,51 +21,66 @@ > { > "type": "const", > "nullable": false, >- "idlType": "short", >+ "idlType": { >+ "type": "const-type", >+ "idlType": "short" >+ }, > "name": "negative", > "value": { > "type": "number", >- "value": -1 >+ "value": "-1" > }, > "extAttrs": [] > }, > { > "type": "const", > "nullable": false, >- "idlType": "octet", >+ "idlType": { >+ "type": "const-type", >+ "idlType": "octet" >+ }, > "name": "LF", > "value": { > "type": "number", >- "value": 10 >+ "value": "10" > }, > "extAttrs": [] > }, > { > "type": "const", > "nullable": false, >- "idlType": "unsigned long", >+ "idlType": { >+ "type": "const-type", >+ "idlType": "unsigned long" >+ }, > "name": "BIT_MASK", > "value": { > "type": "number", >- "value": 64512 >+ "value": "0x0000fc00" > }, > "extAttrs": [] > }, > { > "type": "const", > "nullable": false, >- "idlType": "float", >+ "idlType": { >+ "type": "const-type", >+ "idlType": "float" >+ }, > "name": "AVOGADRO", > "value": { > "type": "number", >- "value": 6.022e+23 >+ "value": "6.022e23" > }, > "extAttrs": [] > }, > { > "type": "const", > "nullable": false, >- "idlType": "unrestricted float", >+ "idlType": { >+ "type": "const-type", >+ "idlType": "unrestricted float" >+ }, > "name": "sobig", > "value": { > "type": "Infinity", >@@ -73,7 +91,10 @@ > { > "type": "const", > "nullable": false, >- "idlType": "unrestricted double", >+ "idlType": { >+ "type": "const-type", >+ "idlType": "unrestricted double" >+ }, > "name": "minusonedividedbyzero", > "value": { > "type": "Infinity", >@@ -84,7 +105,10 @@ > { > "type": "const", > "nullable": false, >- "idlType": "short", >+ "idlType": { >+ "type": "const-type", >+ "idlType": "short" >+ }, > "name": "notanumber", > "value": { > "type": "NaN" >@@ -94,48 +118,5 @@ > ], > "inheritance": null, > "extAttrs": [] >- }, >- { >- "type": "exception", >- "name": "Error", >- "members": [ >- { >- "type": "const", >- "nullable": false, >- "idlType": "short", >- "name": "ERR_UNKNOWN", >- "value": { >- "type": "number", >- "value": 0 >- }, >- "extAttrs": [] >- }, >- { >- "type": "const", >- "nullable": false, >- "idlType": "short", >- "name": "ERR_OUT_OF_MEMORY", >- "value": { >- "type": "number", >- "value": 1 >- }, >- "extAttrs": [] >- }, >- { >- "type": "field", >- "name": "errorCode", >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "short" >- }, >- "extAttrs": [] >- } >- ], >- "inheritance": null, >- "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/constructor.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/constructor.json >index e5944f32ee8671b13f86bed7b76a2a4d6c28bae8..292236f291bd9bdc86eba410aba6d16aaf11a667 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/constructor.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/constructor.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -28,10 +28,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -45,10 +45,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -62,10 +62,10 @@ > "inherit": false, > "readonly": true, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -77,7 +77,9 @@ > "extAttrs": [ > { > "name": "Constructor", >- "arguments": null >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null > }, > { > "name": "Constructor", >@@ -87,17 +89,19 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, > "name": "radius" > } >- ] >+ ], >+ "type": "extended-attribute", >+ "rhs": null > } > ] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/dictionary-inherits.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/dictionary-inherits.json >index fbb2338a8df82cfa5beac24ab29e5fab73673525..9b928f4f0a6f22c4328c5041c400f2039ff25518 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/dictionary-inherits.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/dictionary-inherits.json >@@ -9,10 +9,10 @@ > "name": "fillPattern", > "required": false, > "idlType": { >+ "type": "dictionary-type", > "sequence": false, > "generic": null, > "nullable": true, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -27,10 +27,10 @@ > "name": "strokePattern", > "required": false, > "idlType": { >+ "type": "dictionary-type", > "sequence": false, > "generic": null, > "nullable": true, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -44,10 +44,10 @@ > "name": "position", > "required": false, > "idlType": { >+ "type": "dictionary-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Point" > }, >@@ -67,10 +67,10 @@ > "name": "hydrometry", > "required": false, > "idlType": { >+ "type": "dictionary-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -80,4 +80,4 @@ > "inheritance": "PaintOptions", > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/dictionary.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/dictionary.json >index a7c89caab23a3f88d748cbd91f497e788ad9c6bc..f74fedc3d35b86cf86daac8cb5ececa18de3fa7f 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/dictionary.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/dictionary.json >@@ -9,10 +9,10 @@ > "name": "fillPattern", > "required": false, > "idlType": { >+ "type": "dictionary-type", > "sequence": false, > "generic": null, > "nullable": true, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -27,10 +27,10 @@ > "name": "strokePattern", > "required": false, > "idlType": { >+ "type": "dictionary-type", > "sequence": false, > "generic": null, > "nullable": true, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -44,10 +44,10 @@ > "name": "position", > "required": false, > "idlType": { >+ "type": "dictionary-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Point" > }, >@@ -58,16 +58,16 @@ > "name": "seq", > "required": false, > "idlType": { >+ "type": "dictionary-type", > "sequence": true, > "generic": "sequence", > "nullable": false, >- "array": false, > "union": false, > "idlType": { >+ "type": "dictionary-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "long" > } >@@ -83,10 +83,10 @@ > "name": "reqSeq", > "required": true, > "idlType": { >+ "type": "dictionary-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "long" > }, >@@ -106,10 +106,10 @@ > "name": "h", > "required": false, > "idlType": { >+ "type": "dictionary-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "long" > }, >@@ -120,10 +120,10 @@ > "name": "d", > "required": false, > "idlType": { >+ "type": "dictionary-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "long" > }, >@@ -132,4 +132,4 @@ > ], > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/documentation-dos.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/documentation-dos.json >index 340e039b4495d7c93522046a4408ce5fad3e1da7..baa0b5a09b5ee17b95bcdd42dba4faba25cd3733 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/documentation-dos.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/documentation-dos.json >@@ -7,4 +7,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/documentation.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/documentation.json >index 340e039b4495d7c93522046a4408ce5fad3e1da7..baa0b5a09b5ee17b95bcdd42dba4faba25cd3733 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/documentation.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/documentation.json >@@ -7,4 +7,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/enum.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/enum.json >index 196ee4e6405f27e19afeaca160c5c90afa78e54d..29d1c865b68eab6a60a46407ef4cc9665a36ad62 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/enum.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/enum.json >@@ -3,9 +3,18 @@ > "type": "enum", > "name": "MealType", > "values": [ >- "rice", >- "noodles", >- "other" >+ { >+ "type": "string", >+ "value": "rice" >+ }, >+ { >+ "type": "string", >+ "value": "noodles" >+ }, >+ { >+ "type": "string", >+ "value": "other" >+ } > ], > "extAttrs": [] > }, >@@ -21,10 +30,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "MealType" > }, >@@ -38,10 +47,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -52,16 +61,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -72,10 +79,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "MealType" > }, >@@ -86,10 +93,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -106,10 +113,19 @@ > "type": "enum", > "name": "AltMealType", > "values": [ >- "rice", >- "noodles", >- "other" >+ { >+ "type": "string", >+ "value": "rice" >+ }, >+ { >+ "type": "string", >+ "value": "noodles" >+ }, >+ { >+ "type": "string", >+ "value": "other" >+ } > ], > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/equivalent-decl.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/equivalent-decl.json >index 55a787fdcf08aa928188790abec2d236863dd53b..de8d4dbc70ba8d2984fecb2ecdcba9ec66254d3a 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/equivalent-decl.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/equivalent-decl.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": true, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -25,16 +25,14 @@ > "type": "operation", > "getter": true, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -45,10 +43,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -61,16 +59,14 @@ > "type": "operation", > "getter": false, > "setter": true, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -81,10 +77,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -95,10 +91,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -113,7 +109,7 @@ > }, > { > "type": "interface", >- "name": "Dictionary", >+ "name": "Dictionary2", > "partial": false, > "members": [ > { >@@ -123,10 +119,10 @@ > "inherit": false, > "readonly": true, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -137,16 +133,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -157,10 +151,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -173,16 +167,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -193,10 +185,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -207,10 +199,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -223,16 +215,14 @@ > "type": "operation", > "getter": true, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -243,10 +233,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -259,16 +249,14 @@ > "type": "operation", > "getter": false, > "setter": true, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -279,10 +267,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -293,10 +281,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -309,4 +297,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/exception-inheritance.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/exception-inheritance.json >index f4dc68699a6d5d3d0fe83364764c92563d2d1a43..4a76b98285697e39b3b7a284bb20e8fa0a72c1ab 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/exception-inheritance.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/exception-inheritance.json >@@ -10,7 +10,6 @@ > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned short" > }, >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/exception.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/exception.json >deleted file mode 100644 >index 3f16de828ac8927be5a8d8dd5218c436c57bd266..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/exception.json >+++ /dev/null >@@ -1,35 +0,0 @@ >-[ >- { >- "type": "interface", >- "name": "Dahut", >- "partial": false, >- "members": [ >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": false, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "DOMString" >- }, >- "name": "type", >- "extAttrs": [] >- } >- ], >- "inheritance": null, >- "extAttrs": [] >- }, >- { >- "type": "exception", >- "name": "SomeException", >- "members": [], >- "inheritance": null, >- "extAttrs": [] >- } >-] >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/extended-attributes.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/extended-attributes.json >index 3b5a3b2e22b31a9ddb322c07cfbd389df360a66b..e0dc2360f3af087b26eae9fe3dfd91f0bde6017e 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/extended-attributes.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/extended-attributes.json >@@ -9,6 +9,7 @@ > { > "name": "Global", > "arguments": null, >+ "type": "extended-attribute", > "rhs": { > "type": "identifier-list", > "value": [ >@@ -20,6 +21,7 @@ > { > "name": "Exposed", > "arguments": null, >+ "type": "extended-attribute", > "rhs": { > "type": "identifier", > "value": "ServiceWorker" >@@ -28,36 +30,205 @@ > ] > }, > { >- "type": "interface", >- "name": "IdInterface", >- "partial": false, >- "members": [], >- "inheritance": null, >- "extAttrs": [ >- { >- "name": "IntAttr", >- "arguments": null, >- "rhs": { >- "type": "integer", >- "value": "0" >- } >- }, >- { >- "name": "FloatAttr", >- "arguments": null, >- "rhs": { >- "type": "float", >- "value": "3.14" >- } >- }, >- { >- "name": "StringAttr", >- "arguments": null, >- "rhs": { >- "type": "string", >- "value": "\"abc\"" >- } >- } >- ] >+ "type": "interface", >+ "name": "IdInterface", >+ "partial": false, >+ "members": [], >+ "inheritance": null, >+ "extAttrs": [ >+ { >+ "name": "IntAttr", >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": { >+ "type": "integer", >+ "value": "0" >+ } >+ }, >+ { >+ "name": "FloatAttr", >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": { >+ "type": "float", >+ "value": "3.14" >+ } >+ }, >+ { >+ "name": "StringAttr", >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": { >+ "type": "string", >+ "value": "\"abc\"" >+ } >+ } >+ ] >+ }, >+ { >+ "type": "interface", >+ "name": "Circle", >+ "partial": false, >+ "members": [ >+ { >+ "type": "attribute", >+ "static": false, >+ "stringifier": false, >+ "inherit": false, >+ "readonly": false, >+ "idlType": { >+ "type": "attribute-type", >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "double" >+ }, >+ "name": "r", >+ "extAttrs": [] >+ }, >+ { >+ "type": "attribute", >+ "static": false, >+ "stringifier": false, >+ "inherit": false, >+ "readonly": false, >+ "idlType": { >+ "type": "attribute-type", >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "double" >+ }, >+ "name": "cx", >+ "extAttrs": [] >+ }, >+ { >+ "type": "attribute", >+ "static": false, >+ "stringifier": false, >+ "inherit": false, >+ "readonly": false, >+ "idlType": { >+ "type": "attribute-type", >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "double" >+ }, >+ "name": "cy", >+ "extAttrs": [] >+ }, >+ { >+ "type": "attribute", >+ "static": false, >+ "stringifier": false, >+ "inherit": false, >+ "readonly": true, >+ "idlType": { >+ "type": "attribute-type", >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "double" >+ }, >+ "name": "circumference", >+ "extAttrs": [] >+ } >+ ], >+ "inheritance": null, >+ "extAttrs": [ >+ { >+ "name": "Constructor", >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null >+ }, >+ { >+ "name": "Constructor", >+ "arguments": [ >+ { >+ "optional": false, >+ "variadic": false, >+ "extAttrs": [], >+ "idlType": { >+ "type": "argument-type", >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "double" >+ }, >+ "name": "radius" >+ } >+ ], >+ "type": "extended-attribute", >+ "rhs": null >+ } >+ ] >+ }, >+ { >+ "type": "interface", >+ "name": "I", >+ "partial": false, >+ "members": [ >+ { >+ "type": "attribute", >+ "static": false, >+ "stringifier": false, >+ "inherit": false, >+ "readonly": false, >+ "idlType": { >+ "type": "attribute-type", >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": true, >+ "idlType": [ >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "long" >+ }, >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "Node" >+ } >+ ], >+ "extAttrs": [ >+ { >+ "name": "XAttr", >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null >+ } >+ ] >+ }, >+ "name": "attrib", >+ "extAttrs": [] >+ } >+ ], >+ "inheritance": null, >+ "extAttrs": [ >+ { >+ "name": "Exposed", >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": { >+ "type": "identifier", >+ "value": "Window" >+ } >+ } >+ ] > } > ] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/generic.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/generic.json >index e39654ffdb2131fd0260e1a6264dbf48f74945b9..62593859fb14ce309cc752c10d74371a5cbe6cea 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/generic.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/generic.json >@@ -8,34 +8,32 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": "Promise", > "nullable": false, >- "array": false, > "union": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": "ResponsePromise", > "nullable": false, >- "array": false, > "union": false, > "idlType": { >+ "type": "return-type", > "sequence": true, > "generic": "sequence", > "nullable": false, >- "array": false, > "union": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": true, >- "array": false, > "union": false, > "idlType": "DOMString" > } >@@ -53,17 +51,16 @@ > "inherit": false, > "readonly": true, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": "Promise", > "nullable": false, >- "array": 1, >- "nullableArray": [false], > "union": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > } >@@ -84,23 +81,20 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": "Promise", > "nullable": false, >- "array": false, > "union": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": true, >- "nullableArray": [false], >- "array": 1, > "union": false, > "idlType": "Client" > } >@@ -113,22 +107,20 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": "Promise", > "nullable": false, >- "array": false, > "union": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "any" > } >@@ -150,22 +142,20 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": "ResponsePromise", > "nullable": false, >- "array": false, > "union": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "any" > } >@@ -178,4 +168,4 @@ > "inheritance": "Event", > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/getter-setter.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/getter-setter.json >index 94d20d594db15e5e2e15403930c2bd1e32a28b33..1213307f20309b3c1e32f5b56c4e58cc8289d8db 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/getter-setter.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/getter-setter.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": true, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -25,16 +25,14 @@ > "type": "operation", > "getter": true, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -45,10 +43,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -61,16 +59,14 @@ > "type": "operation", > "getter": false, > "setter": true, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -81,10 +77,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -95,10 +91,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -111,4 +107,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/identifier-qualified-names.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/identifier-qualified-names.json >index d87ea3b5f369db698e93072a1b76562a16d50fec..f4e295acd3e1209afb04ce811dfb983e0a9f47e7 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/identifier-qualified-names.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/identifier-qualified-names.json >@@ -2,48 +2,16 @@ > { > "type": "typedef", > "idlType": { >+ "type": "typedef-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, > "name": "number", > "extAttrs": [] > }, >- { >- "type": "exception", >- "name": "FrameworkException", >- "members": [ >- { >- "type": "const", >- "nullable": false, >- "idlType": "long", >- "name": "ERR_NOT_FOUND", >- "value": { >- "type": "number", >- "value": 1 >- }, >- "extAttrs": [] >- }, >- { >- "type": "field", >- "name": "code", >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "long" >- }, >- "extAttrs": [] >- } >- ], >- "inheritance": null, >- "extAttrs": [] >- }, > { > "type": "interface", > "name": "System", >@@ -53,16 +21,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "object" > }, >@@ -73,10 +39,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -89,16 +55,14 @@ > "type": "operation", > "getter": true, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -109,10 +73,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -137,10 +101,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "boolean" > }, >@@ -154,10 +118,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": true, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -177,16 +141,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -197,10 +159,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "object" > }, >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/implements.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/implements.json >index fa00e3374267b93b9d56b2ddc8b0b35e7302f481..69879d94f553d5090e5c3250077d8728d2906dbe 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/implements.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/implements.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": true, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned short" > }, >@@ -34,16 +34,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -54,10 +52,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -68,10 +66,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "EventListener" > }, >@@ -82,10 +80,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "boolean" > }, >@@ -104,4 +102,4 @@ > "implements": "EventTarget", > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/indexed-properties.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/indexed-properties.json >index 23cc4ab1023c2fedd4dab6c640a2b1307bc800af..697b595546c788e5ff38d42b4b2bc6c7f0e95425 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/indexed-properties.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/indexed-properties.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": true, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -25,16 +25,14 @@ > "type": "operation", > "getter": true, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "any" > }, >@@ -45,10 +43,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -61,16 +59,14 @@ > "type": "operation", > "getter": false, > "setter": true, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -81,10 +77,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -95,10 +91,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "any" > }, >@@ -111,16 +107,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": true, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -131,10 +125,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -147,16 +141,14 @@ > "type": "operation", > "getter": true, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "any" > }, >@@ -167,10 +159,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -183,16 +175,14 @@ > "type": "operation", > "getter": false, > "setter": true, >- "creator": true, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -203,10 +193,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -217,10 +207,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "any" > }, >@@ -233,16 +223,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": true, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -253,10 +241,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -269,4 +257,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/inherits-getter.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/inherits-getter.json >index 468e3caef711f3afab68a785805dd75f74f96ab9..818d8b6c16f8249465bf6f234ff555fe550d639c 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/inherits-getter.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/inherits-getter.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": true, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -37,10 +37,10 @@ > "inherit": false, > "readonly": true, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned short" > }, >@@ -54,10 +54,10 @@ > "inherit": true, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -68,4 +68,4 @@ > "inheritance": "Animal", > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/interface-inherits.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/interface-inherits.json >index eee07cd1dec7bb6e3691fb207a0ca45ead4a310d..74a4c39bb0ffb1deb34f1e890efa95c1f6cc6baf 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/interface-inherits.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/interface-inherits.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -37,10 +37,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Dog" > }, >@@ -63,10 +63,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Human" > }, >@@ -77,4 +77,4 @@ > "inheritance": "Animal", > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/iterable.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/iterable.json >index 3e38991dd9db21c92bc2b50769ff8b87247dacef..7126a4ea2b01b1ba99dcb9f73263c61eefe51647 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/iterable.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/iterable.json >@@ -6,14 +6,16 @@ > "members": [ > { > "type": "iterable", >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "long" >- }, >+ "idlType": [ >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "long" >+ } >+ ], > "extAttrs": [] > } > ], >@@ -29,18 +31,18 @@ > "type": "iterable", > "idlType": [ > { >+ "type": null, > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "short" > }, > { >+ "type": null, > "sequence": false, > "generic": null, > "nullable": true, >- "array": false, > "union": false, > "idlType": "double" > } >@@ -50,6 +52,36 @@ > ], > "inheritance": null, > "extAttrs": [] >+ }, >+ { >+ "type": "interface", >+ "name": "IterableThree", >+ "partial": false, >+ "members": [ >+ { >+ "type": "iterable", >+ "idlType": [ >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "long", >+ "extAttrs": [ >+ { >+ "name": "XAttr", >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null >+ } >+ ] >+ } >+ ], >+ "extAttrs": [] >+ } >+ ], >+ "inheritance": null, >+ "extAttrs": [] > } > ] >- >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/iterator.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/iterator.json >index cc3c9ec505d8e39b249121a3acdb33ea555f08d6..f9605b83450cb5dcd21ec338b82796a2a2304b08 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/iterator.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/iterator.json >@@ -8,16 +8,13 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Session" > }, >@@ -31,7 +28,6 @@ > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -50,7 +46,6 @@ > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -61,16 +56,13 @@ > "type": "iterator", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Session" > }, >@@ -95,7 +87,6 @@ > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -115,16 +106,13 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Session2" > }, >@@ -138,7 +126,6 @@ > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -157,7 +144,6 @@ > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -168,16 +154,13 @@ > "type": "iterator", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Session2" > }, >@@ -203,7 +186,6 @@ > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -229,7 +211,6 @@ > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -249,16 +230,13 @@ > "type": "iterator", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Node" > }, >@@ -278,16 +256,13 @@ > "type": "iterator", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Node" > }, >@@ -298,4 +273,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/legacyiterable.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/legacyiterable.json >index e63f99de43f43d2170867185971bd49e2b5f5587..5a1e526b50ae600c3917b419a1e2b2024eff0f91 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/legacyiterable.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/legacyiterable.json >@@ -6,14 +6,16 @@ > "members": [ > { > "type": "legacyiterable", >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "long" >- }, >+ "idlType": [ >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "long" >+ } >+ ], > "extAttrs": [] > } > ], >@@ -21,4 +23,3 @@ > "extAttrs": [] > } > ] >- >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/linecomment.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/linecomment.json >new file mode 100644 >index 0000000000000000000000000000000000000000..11fd14f494bd2026abf3769fb5b75c08f14a5fc4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/linecomment.json >@@ -0,0 +1,14 @@ >+[ >+ { >+ "type": "multiline-comment", >+ "value": " first " >+ }, >+ { >+ "type": "ws", >+ "value": "\n" >+ }, >+ { >+ "type": "line-comment", >+ "value": " second" >+ } >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/maplike.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/maplike.json >index 017d8b3f3ec2c406b25ebf904737458f8f6d1174..b86e10487c1b61f6fce1286ea9fb2e6f06fa23eb 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/maplike.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/maplike.json >@@ -8,18 +8,18 @@ > "type": "maplike", > "idlType": [ > { >+ "type": null, > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "long" > }, > { >+ "type": null, > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > } >@@ -40,18 +40,18 @@ > "type": "maplike", > "idlType": [ > { >+ "type": null, > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "long" > }, > { >+ "type": null, > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > } >@@ -62,6 +62,53 @@ > ], > "inheritance": null, > "extAttrs": [] >+ }, >+ { >+ "type": "interface", >+ "name": "I", >+ "partial": false, >+ "members": [ >+ { >+ "type": "maplike", >+ "idlType": [ >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "DOMString", >+ "extAttrs": [ >+ { >+ "name": "XAttr2", >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null >+ } >+ ] >+ }, >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "long", >+ "extAttrs": [ >+ { >+ "name": "XAttr3", >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null >+ } >+ ] >+ } >+ ], >+ "readonly": false, >+ "extAttrs": [] >+ } >+ ], >+ "inheritance": null, >+ "extAttrs": [] > } > ] >- >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/mixin.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/mixin.json >new file mode 100644 >index 0000000000000000000000000000000000000000..f0458e2b0841ca7c6d33367b49f56c86fa673a1f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/mixin.json >@@ -0,0 +1,64 @@ >+[ >+ { >+ "type": "interface mixin", >+ "name": "GlobalCrypto", >+ "partial": false, >+ "members": [ >+ { >+ "type": "attribute", >+ "static": false, >+ "stringifier": false, >+ "inherit": false, >+ "readonly": true, >+ "idlType": { >+ "type": "attribute-type", >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "Crypto" >+ }, >+ "name": "crypto", >+ "extAttrs": [] >+ } >+ ], >+ "extAttrs": [] >+ }, >+ { >+ "type": "includes", >+ "target": "Window", >+ "includes": "GlobalCrypto", >+ "extAttrs": [] >+ }, >+ { >+ "type": "includes", >+ "target": "WorkerGlobalScope", >+ "includes": "GlobalCrypto", >+ "extAttrs": [] >+ }, >+ { >+ "type": "interface mixin", >+ "name": "WindowOrWorkerGlobalScope", >+ "partial": true, >+ "members": [ >+ { >+ "type": "attribute", >+ "static": false, >+ "stringifier": false, >+ "inherit": false, >+ "readonly": true, >+ "idlType": { >+ "type": "attribute-type", >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "Crypto" >+ }, >+ "name": "crypto", >+ "extAttrs": [] >+ } >+ ], >+ "extAttrs": [] >+ } >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/namedconstructor.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/namedconstructor.json >index a947a64a4e2e3c050a4ad154826282f3b4a5fb33..f895461d15e0a53ad77d383c5019d8919fef49cf 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/namedconstructor.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/namedconstructor.json >@@ -9,6 +9,7 @@ > { > "name": "NamedConstructor", > "arguments": null, >+ "type": "extended-attribute", > "rhs": { > "type": "identifier", > "value": "Audio" >@@ -22,16 +23,17 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, > "name": "src" > } > ], >+ "type": "extended-attribute", > "rhs": { > "type": "identifier", > "value": "Audio" >@@ -39,4 +41,4 @@ > } > ] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/namespace.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/namespace.json >index 7c7ba771e1bf3ade1dc128e38a8d8bdbf02702b6..0611b710bf10d9fb6105e71a86b29619c7136727 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/namespace.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/namespace.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": true, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Vector" > }, >@@ -25,16 +25,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "double" > }, >@@ -45,10 +43,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Vector" > }, >@@ -59,10 +57,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Vector" > }, >@@ -75,16 +73,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Vector" > }, >@@ -95,10 +91,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Vector" > }, >@@ -109,10 +105,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Vector" > }, >@@ -131,4 +127,4 @@ > "members": [], > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/nointerfaceobject.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/nointerfaceobject.json >index 90f0d63c82e3f25d7f097b2f0f4cd1b0899fb1dc..03bb99442d5fe39582b4ffe2a6de9922d8a1b2b1 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/nointerfaceobject.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/nointerfaceobject.json >@@ -8,16 +8,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "any" > }, >@@ -28,10 +26,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -45,8 +43,10 @@ > "extAttrs": [ > { > "name": "NoInterfaceObject", >- "arguments": null >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null > } > ] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/nullable.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/nullable.json >index 300442f0d4661722e18af8f1e7b97940e92afe64..ae4d2aa537594cdf55387160d5de603832c09fef 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/nullable.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/nullable.json >@@ -7,7 +7,10 @@ > { > "type": "const", > "nullable": true, >- "idlType": "boolean", >+ "idlType": { >+ "type": "const-type", >+ "idlType": "boolean" >+ }, > "name": "ARE_WE_THERE_YET", > "value": { > "type": "boolean", >@@ -31,10 +34,10 @@ > "inherit": false, > "readonly": true, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": true, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -45,4 +48,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/nullableobjects.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/nullableobjects.json >index 40f7db0c1c9c8c435eb216205b239959995548a2..29d1314f1686516cb5071b2b9738916b63451eac 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/nullableobjects.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/nullableobjects.json >@@ -24,16 +24,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -44,10 +42,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": true, >- "array": false, > "union": false, > "idlType": "A" > }, >@@ -60,16 +58,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -80,10 +76,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": true, >- "array": false, > "union": false, > "idlType": "B" > }, >@@ -96,4 +92,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/operation-optional-arg.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/operation-optional-arg.json >index 6ca32576b7a41f81dcddfb7eb462508eae5d91a5..44c3a16dc2ee1aaddf02d89d6f15210f23bdfd02 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/operation-optional-arg.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/operation-optional-arg.json >@@ -8,16 +8,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "object" > }, >@@ -28,10 +26,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -42,10 +40,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -56,10 +54,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -70,17 +68,17 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, > "name": "alpha", > "default": { > "type": "number", >- "value": 3.5 >+ "value": "3.5" > } > } > ], >@@ -90,4 +88,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/overloading.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/overloading.json >index c3baa439623b09bfdb6a71b571a621a12a2e6dc5..87169e9202ba40d34f47612e5b486a55a7152d71 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/overloading.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/overloading.json >@@ -24,16 +24,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -44,10 +42,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "A" > }, >@@ -60,16 +58,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -80,10 +76,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "B" > }, >@@ -98,23 +94,21 @@ > }, > { > "type": "interface", >- "name": "A", >+ "name": "D", > "partial": false, > "members": [ > { > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -125,10 +119,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -141,16 +135,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -162,14 +154,16 @@ > "extAttrs": [ > { > "name": "AllowAny", >- "arguments": null >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null > } > ], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -180,10 +174,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -194,10 +188,10 @@ > "variadic": true, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -210,16 +204,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -231,16 +223,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -251,10 +241,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "long" > }, >@@ -265,10 +255,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -279,10 +269,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -293,10 +283,10 @@ > "variadic": true, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -309,4 +299,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/overridebuiltins.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/overridebuiltins.json >index 9e2f795e2ae175fd31eb891bd07df595cc4e7cd9..d63f8f744113ee3999515782b11f47465d16e140 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/overridebuiltins.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/overridebuiltins.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": true, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -25,16 +25,14 @@ > "type": "operation", > "getter": true, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -45,10 +43,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -62,8 +60,10 @@ > "extAttrs": [ > { > "name": "OverrideBuiltins", >- "arguments": null >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null > } > ] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/partial-interface.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/partial-interface.json >index 53c65a453bd7301863ed0fae935a10eb2aa7360f..c16c64d334dfc46f6875632ab240443f5199b290 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/partial-interface.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/partial-interface.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -37,10 +37,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -50,4 +50,4 @@ > ], > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/primitives.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/primitives.json >index 7160c2a4ce066df3284c50eaf4f4af80ef01ab90..cf965399a4ff3eb3eec8731e1c0f6c45588661ce 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/primitives.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/primitives.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "boolean" > }, >@@ -28,10 +28,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "byte" > }, >@@ -45,10 +45,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "octet" > }, >@@ -62,10 +62,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "short" > }, >@@ -79,10 +79,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned short" > }, >@@ -96,10 +96,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "long" > }, >@@ -113,10 +113,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -130,10 +130,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "long long" > }, >@@ -147,10 +147,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long long" > }, >@@ -164,10 +164,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -181,10 +181,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "double" > }, >@@ -198,10 +198,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unrestricted float" > }, >@@ -215,10 +215,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unrestricted double" > }, >@@ -232,10 +232,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -249,10 +249,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "ByteString" > }, >@@ -266,10 +266,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Date" > }, >@@ -283,10 +283,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "RegExp" > }, >@@ -297,4 +297,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/prototyperoot.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/prototyperoot.json >index 666798d94cfd272ca349d7ba549512025d4aa4f0..eda7f14dae4c5d0ba3e6f03827ecbb11f2d35337 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/prototyperoot.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/prototyperoot.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": true, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned short" > }, >@@ -26,8 +26,10 @@ > "extAttrs": [ > { > "name": "PrototypeRoot", >- "arguments": null >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null > } > ] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/putforwards.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/putforwards.json >index bd5e619cac553463e125d2489b4b282e46563ae8..4b809d2d34dcb5d0eccc4df6c2561ce4010edd82 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/putforwards.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/putforwards.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": true, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Name" > }, >@@ -23,6 +23,7 @@ > { > "name": "PutForwards", > "arguments": null, >+ "type": "extended-attribute", > "rhs": { > "type": "identifier", > "value": "full" >@@ -37,10 +38,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned short" > }, >@@ -51,4 +52,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/record.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/record.json >index d2a21a4acd99936119cd7d8a6757e361c83141cc..dd00b5df045e5c28164869333030d69eb679ee1b 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/record.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/record.json >@@ -8,16 +8,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -28,31 +26,31 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": true, > "generic": "sequence", > "nullable": false, >- "array": false, > "union": false, > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": "record", > "nullable": false, >- "array": false, > "union": false, > "idlType": [ > { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "ByteString" > }, > { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "any" > } >@@ -68,46 +66,44 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": "record", > "nullable": false, >- "array": false, > "union": false, > "idlType": [ > { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, > { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": true, >- "array": false, > "union": true, > "idlType": [ > { >+ "type": null, > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, > { >+ "type": null, > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > } >@@ -123,16 +119,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "record" > }, >@@ -151,25 +145,25 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": "record", > "nullable": false, >- "array": false, > "union": false, > "idlType": [ > { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "USVString" > }, > { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "USVString" > } >@@ -177,8 +171,63 @@ > }, > "name": "init" > } >- ] >+ ], >+ "type": "extended-attribute", >+ "rhs": null > } > ] >+ }, >+ { >+ "type": "interface", >+ "name": "Bar", >+ "partial": false, >+ "members": [ >+ { >+ "type": "operation", >+ "getter": false, >+ "setter": false, >+ "deleter": false, >+ "static": false, >+ "stringifier": false, >+ "idlType": { >+ "type": "return-type", >+ "sequence": false, >+ "generic": "record", >+ "nullable": false, >+ "union": false, >+ "idlType": [ >+ { >+ "type": "return-type", >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "DOMString" >+ }, >+ { >+ "type": "return-type", >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "float", >+ "extAttrs": [ >+ { >+ "name": "XAttr", >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null >+ } >+ ] >+ } >+ ] >+ }, >+ "name": "bar", >+ "arguments": [], >+ "extAttrs": [] >+ } >+ ], >+ "inheritance": null, >+ "extAttrs": [] > } > ] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/reg-operations.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/reg-operations.json >index c827fff03b6bf3bb4357d1aeee4170345e61437e..d696e907e0c663567614e432393c1c045f50b518 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/reg-operations.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/reg-operations.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -28,10 +28,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -42,13 +42,6 @@ > "inheritance": null, > "extAttrs": [] > }, >- { >- "type": "exception", >- "name": "NoPointerDevice", >- "members": [], >- "inheritance": null, >- "extAttrs": [] >- }, > { > "type": "interface", > "name": "Button", >@@ -58,16 +51,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "boolean" > }, >@@ -79,16 +70,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -99,10 +88,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Dimensions" > }, >@@ -115,16 +104,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -135,10 +122,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -149,10 +136,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -165,4 +152,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/replaceable.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/replaceable.json >index 4d25f3d9317e12da6d73723cefa7ff8a071be053..a10b0bfd03b022d31fdc76ec34c8132ea35f99f1 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/replaceable.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/replaceable.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": true, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -22,7 +22,9 @@ > "extAttrs": [ > { > "name": "Replaceable", >- "arguments": null >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null > } > ] > }, >@@ -30,16 +32,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -51,4 +51,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/sequence.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/sequence.json >index 7ddd402b402aee67c8b0a697d5fc006306e541b6..c2d1765bfa506d3a3cc53af5a0f61ea1c397ea06 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/sequence.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/sequence.json >@@ -8,16 +8,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -28,16 +26,16 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": true, > "generic": "sequence", > "nullable": false, >- "array": false, > "union": false, > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > } >@@ -51,22 +49,20 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": true, > "generic": "sequence", > "nullable": false, >- "array": false, > "union": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > } >@@ -84,21 +80,18 @@ > "name": "Foo", > "partial": false, > "members": [ >- > { > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "sequence" > }, >@@ -109,5 +102,63 @@ > ], > "inheritance": null, > "extAttrs": [] >- } >-] >\ No newline at end of file >+ }, >+ { >+ "type": "interface", >+ "name": "I", >+ "partial": false, >+ "members": [ >+ { >+ "type": "operation", >+ "getter": false, >+ "setter": false, >+ "deleter": false, >+ "static": false, >+ "stringifier": false, >+ "idlType": { >+ "type": "return-type", >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "void" >+ }, >+ "name": "f1", >+ "arguments": [ >+ { >+ "optional": false, >+ "variadic": false, >+ "extAttrs": [], >+ "idlType": { >+ "type": "argument-type", >+ "sequence": true, >+ "generic": "sequence", >+ "nullable": false, >+ "union": false, >+ "idlType": { >+ "type": "argument-type", >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "long", >+ "extAttrs": [ >+ { >+ "name": "XAttr", >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null >+ } >+ ] >+ } >+ }, >+ "name": "arg" >+ } >+ ], >+ "extAttrs": [] >+ } >+ ], >+ "inheritance": null, >+ "extAttrs": [] >+ } >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/serializer.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/serializer.json >deleted file mode 100644 >index 79b501fcbc4c7c492607b51d7f5f0ce41ce02bd8..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/serializer.json >+++ /dev/null >@@ -1,591 +0,0 @@ >-[ >- { >- "type": "interface", >- "name": "Transaction", >- "partial": false, >- "members": [ >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": true, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "Account" >- }, >- "name": "from", >- "extAttrs": [] >- }, >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": true, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "Account" >- }, >- "name": "to", >- "extAttrs": [] >- }, >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": true, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "float" >- }, >- "name": "amount", >- "extAttrs": [] >- }, >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": true, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "DOMString" >- }, >- "name": "description", >- "extAttrs": [] >- }, >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": true, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "unsigned long" >- }, >- "name": "number", >- "extAttrs": [] >- }, >- { >- "type": "serializer", >- "extAttrs": [] >- } >- ], >- "inheritance": null, >- "extAttrs": [] >- }, >- { >- "type": "interface", >- "name": "Account", >- "partial": false, >- "members": [ >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": false, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "DOMString" >- }, >- "name": "name", >- "extAttrs": [] >- }, >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": false, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "unsigned long" >- }, >- "name": "number", >- "extAttrs": [] >- }, >- { >- "type": "serializer", >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "DOMString" >- }, >- "operation": { >- "name": "serialize", >- "arguments": [] >- }, >- "extAttrs": [] >- } >- ], >- "inheritance": null, >- "extAttrs": [] >- }, >- { >- "type": "interface", >- "name": "Transaction2", >- "partial": false, >- "members": [ >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": true, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "Account2" >- }, >- "name": "from", >- "extAttrs": [] >- }, >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": true, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "Account2" >- }, >- "name": "to", >- "extAttrs": [] >- }, >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": true, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "float" >- }, >- "name": "amount", >- "extAttrs": [] >- }, >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": true, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "DOMString" >- }, >- "name": "description", >- "extAttrs": [] >- }, >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": true, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "unsigned long" >- }, >- "name": "number", >- "extAttrs": [] >- }, >- { >- "type": "serializer", >- "patternMap": true, >- "names": [ >- "from", >- "to", >- "amount", >- "description" >- ], >- "extAttrs": [] >- } >- ], >- "inheritance": null, >- "extAttrs": [] >- }, >- { >- "type": "interface", >- "name": "Account2", >- "partial": false, >- "members": [ >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": false, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "DOMString" >- }, >- "name": "name", >- "extAttrs": [] >- }, >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": false, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "unsigned long" >- }, >- "name": "number", >- "extAttrs": [] >- }, >- { >- "type": "serializer", >- "name": "number", >- "extAttrs": [] >- } >- ], >- "inheritance": null, >- "extAttrs": [] >- }, >- { >- "type": "interface", >- "name": "Account3", >- "partial": false, >- "members": [ >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": false, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "DOMString" >- }, >- "name": "name", >- "extAttrs": [] >- }, >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": false, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "unsigned long" >- }, >- "name": "number", >- "extAttrs": [] >- }, >- { >- "type": "serializer", >- "patternMap": true, >- "names": [ >- "attribute" >- ], >- "extAttrs": [] >- } >- ], >- "inheritance": null, >- "extAttrs": [] >- }, >- { >- "type": "interface", >- "name": "Account4", >- "partial": false, >- "members": [ >- { >- "type": "operation", >- "getter": true, >- "setter": false, >- "creator": false, >- "deleter": false, >- "legacycaller": false, >- "static": false, >- "stringifier": false, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "object" >- }, >- "name": "getItem", >- "arguments": [ >- { >- "optional": false, >- "variadic": false, >- "extAttrs": [], >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "unsigned long" >- }, >- "name": "index" >- } >- ], >- "extAttrs": [] >- }, >- { >- "type": "serializer", >- "patternMap": true, >- "names": [ >- "getter" >- ], >- "extAttrs": [] >- } >- ], >- "inheritance": null, >- "extAttrs": [] >- }, >- { >- "type": "interface", >- "name": "Account5", >- "partial": false, >- "members": [ >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": false, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "DOMString" >- }, >- "name": "secondname", >- "extAttrs": [] >- }, >- { >- "type": "serializer", >- "patternMap": true, >- "names": [ >- "inherit", >- "secondname" >- ], >- "extAttrs": [] >- } >- ], >- "inheritance": "Account", >- "extAttrs": [] >- }, >- { >- "type": "interface", >- "name": "Account6", >- "partial": false, >- "members": [ >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": false, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "DOMString" >- }, >- "name": "secondname", >- "extAttrs": [] >- }, >- { >- "type": "serializer", >- "patternMap": true, >- "names": [ >- "inherit", >- "attribute" >- ], >- "extAttrs": [] >- } >- ], >- "inheritance": "Account", >- "extAttrs": [] >- }, >- { >- "type": "interface", >- "name": "Account7", >- "partial": false, >- "members": [ >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": false, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "DOMString" >- }, >- "name": "name", >- "extAttrs": [] >- }, >- { >- "type": "attribute", >- "static": false, >- "stringifier": false, >- "inherit": false, >- "readonly": false, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "unsigned long" >- }, >- "name": "number", >- "extAttrs": [] >- }, >- { >- "type": "serializer", >- "patternList": true, >- "names": [ >- "name", >- "number" >- ], >- "extAttrs": [] >- } >- ], >- "inheritance": null, >- "extAttrs": [] >- }, >- { >- "type": "interface", >- "name": "Account8", >- "partial": false, >- "members": [ >- { >- "type": "operation", >- "getter": true, >- "setter": false, >- "creator": false, >- "deleter": false, >- "legacycaller": false, >- "static": false, >- "stringifier": false, >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "object" >- }, >- "name": "getItem", >- "arguments": [ >- { >- "optional": false, >- "variadic": false, >- "extAttrs": [], >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "unsigned long" >- }, >- "name": "index" >- } >- ], >- "extAttrs": [] >- }, >- { >- "type": "serializer", >- "patternList": true, >- "names": [ >- "getter" >- ], >- "extAttrs": [] >- } >- ], >- "inheritance": null, >- "extAttrs": [] >- } >-] >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/setlike.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/setlike.json >index d44043a944aa9bd58223a96ca7b7deeef6055091..12299a7ee0444ab0602912d4988f6c332b5a5f88 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/setlike.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/setlike.json >@@ -6,14 +6,16 @@ > "members": [ > { > "type": "setlike", >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "long" >- }, >+ "idlType": [ >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "long" >+ } >+ ], > "readonly": false, > "extAttrs": [] > } >@@ -28,20 +30,53 @@ > "members": [ > { > "type": "setlike", >- "idlType": { >- "sequence": false, >- "generic": null, >- "nullable": false, >- "array": false, >- "union": false, >- "idlType": "long" >- }, >+ "idlType": [ >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "long" >+ } >+ ], > "readonly": true, > "extAttrs": [] > } > ], > "inheritance": null, > "extAttrs": [] >+ }, >+ { >+ "type": "interface", >+ "name": "SetLikeExt", >+ "partial": false, >+ "members": [ >+ { >+ "type": "setlike", >+ "idlType": [ >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "long", >+ "extAttrs": [ >+ { >+ "name": "XAttr", >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null >+ } >+ ] >+ } >+ ], >+ "readonly": false, >+ "extAttrs": [] >+ } >+ ], >+ "inheritance": null, >+ "extAttrs": [] > } > ] >- >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/static.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/static.json >index faab12b2966cebe10cf7817cebc94e5f007a4065..0951b2acf5ff997b4104e3578f9a18dc3aa7aa49 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/static.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/static.json >@@ -19,10 +19,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -36,10 +36,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -53,10 +53,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -70,10 +70,10 @@ > "inherit": false, > "readonly": true, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "long" > }, >@@ -84,16 +84,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": true, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Point" > }, >@@ -104,10 +102,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Circle" > }, >@@ -118,10 +116,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Circle" > }, >@@ -132,10 +130,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Circle" > }, >@@ -148,4 +146,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/stringifier-attribute.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/stringifier-attribute.json >index 196ee6f1a7c07f6d17c7132bced8b38149f1c8d6..36e2b6d50ac0643998b69dfbb685b98ba8bbfbea 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/stringifier-attribute.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/stringifier-attribute.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -28,10 +28,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -43,8 +43,10 @@ > "extAttrs": [ > { > "name": "Constructor", >- "arguments": null >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null > } > ] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/stringifier-custom.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/stringifier-custom.json >index b4ab7392e5a69b871ab9545aa66a588d0c70e527..3dc3ac1758c8a2de40be0f111af8b224a406dd99 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/stringifier-custom.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/stringifier-custom.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -28,10 +28,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": true, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -45,10 +45,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -59,16 +59,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": true, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -81,8 +79,10 @@ > "extAttrs": [ > { > "name": "Constructor", >- "arguments": null >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null > } > ] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/stringifier.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/stringifier.json >index ad3abde85f4bbc610d9d806d4bde52f0801ddc97..1a702765b0a656599749784a5cb3cb32364c4412 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/stringifier.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/stringifier.json >@@ -8,16 +8,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": true, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -31,16 +29,14 @@ > }, > { > "type": "interface", >- "name": "A", >+ "name": "B", > "partial": false, > "members": [ > { > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": true, > "extAttrs": [] >@@ -49,4 +45,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/treatasnull.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/treatasnull.json >index 8bacb967acc1e1eff834532e0b266290117f6b27..611d97410439476d775304db618b2913bc5a1334 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/treatasnull.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/treatasnull.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -28,10 +28,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -42,16 +42,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "boolean" > }, >@@ -64,6 +62,7 @@ > { > "name": "TreatNullAs", > "arguments": null, >+ "type": "extended-attribute", > "rhs": { > "type": "identifier", > "value": "EmptyString" >@@ -71,10 +70,10 @@ > } > ], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -87,4 +86,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/treatasundefined.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/treatasundefined.json >index 91c4d25f5d1d2fb8f58acfe657531d3168679fba..258acdabd8593d25b57ce39bd658aa8f62d68dd5 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/treatasundefined.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/treatasundefined.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -28,10 +28,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -42,16 +42,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "boolean" > }, >@@ -64,6 +62,7 @@ > { > "name": "TreatUndefinedAs", > "arguments": null, >+ "type": "extended-attribute", > "rhs": { > "type": "identifier", > "value": "EmptyString" >@@ -71,10 +70,10 @@ > } > ], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "DOMString" > }, >@@ -87,4 +86,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/typedef-union.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/typedef-union.json >index 9c87672c8aebb1074943530d5de1edd546d3ae22..06735a807910067e791f738d1c8865f9d79fdd07 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/typedef-union.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/typedef-union.json >@@ -1,49 +1,48 @@ > [ >- { >- "type" : "typedef", >- "idlType" : { >- "nullable" : false, >- "generic" : null, >- "union" : true, >- "idlType" : [ >- { >- "union" : false, >- "generic" : null, >- "nullable" : false, >- "array" : false, >- "sequence" : false, >- "idlType" : "ImageData" >- }, >- { >- "generic" : null, >- "union" : false, >- "nullable" : false, >- "array" : false, >- "idlType" : "HTMLImageElement", >- "sequence" : false >- }, >- { >- "array" : false, >- "sequence" : false, >- "idlType" : "HTMLCanvasElement", >- "generic" : null, >- "union" : false, >- "nullable" : false >- }, >- { >- "union" : false, >- "generic" : null, >- "nullable" : false, >- "array" : false, >- "sequence" : false, >- "idlType" : "HTMLVideoElement" >- } >- ], >- "sequence" : false, >- "array" : false >- }, >- "name" : "TexImageSource", >- "extAttrs" : [], >- "typeExtAttrs" : [] >- } >+ { >+ "type": "typedef", >+ "idlType": { >+ "type": "typedef-type", >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": true, >+ "idlType": [ >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "ImageData" >+ }, >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "HTMLImageElement" >+ }, >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "HTMLCanvasElement" >+ }, >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "HTMLVideoElement" >+ } >+ ] >+ }, >+ "name": "TexImageSource", >+ "extAttrs": [] >+ } > ] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/typedef.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/typedef.json >index d0854fa3d2626855da2eed1419e32dba7f3d9cfc..5e9715da8fb2a7a884d7acd29d1d80df514ba093 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/typedef.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/typedef.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -28,10 +28,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "float" > }, >@@ -45,16 +45,16 @@ > { > "type": "typedef", > "idlType": { >+ "type": "typedef-type", > "sequence": true, > "generic": "sequence", > "nullable": false, >- "array": false, > "union": false, > "idlType": { >+ "type": "typedef-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Point" > } >@@ -74,10 +74,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Point" > }, >@@ -91,10 +91,10 @@ > "inherit": false, > "readonly": false, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Point" > }, >@@ -117,10 +117,10 @@ > "inherit": false, > "readonly": true, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Rect" > }, >@@ -131,16 +131,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "boolean" > }, >@@ -151,10 +149,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "Point" > }, >@@ -167,16 +165,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "boolean" > }, >@@ -187,10 +183,10 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "PointSequence" > }, >@@ -206,16 +202,18 @@ > { > "type": "typedef", > "idlType": { >+ "type": "typedef-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "octet", > "extAttrs": [ > { > "name": "Clamp", >- "arguments": null >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null > } > ] > }, >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/typesuffixes.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/typesuffixes.json >index 790c444ef461b05a8ff766228d9c1ced38635b39..be0b1f226827d04edc1025f838c79c8ddfd94887 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/typesuffixes.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/typesuffixes.json >@@ -8,16 +8,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -28,17 +26,16 @@ > "variadic": false, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": true, > "generic": "sequence", > "nullable": true, >- "array": false, > "union": false, > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": true, >- "array": 1, >- "nullableArray": [false], > "union": false, > "idlType": "DOMString" > } >@@ -52,4 +49,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/uniontype.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/uniontype.json >index 9da5e79f3625ef6c2b11ed204aef90742d925c61..87735c7fb6320d1ee131d034014dbb94262b6ebe 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/uniontype.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/uniontype.json >@@ -1,127 +1,129 @@ > [ >- { >- "partial": false, >- "members": [ >- { >- "idlType": { >- "idlType": [ >- { >- "array": false, >- "union": false, >- "sequence": false, >- "generic": null, >- "idlType": "float", >- "nullable": false >- }, >- { >- "idlType": [ >+ { >+ "type": "interface", >+ "name": "Union", >+ "partial": false, >+ "members": [ >+ { >+ "type": "attribute", >+ "static": false, >+ "stringifier": false, >+ "inherit": false, >+ "readonly": false, >+ "idlType": { >+ "type": "attribute-type", >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": true, >+ "idlType": [ > { >- "nullable": false, >- "idlType": "Date", >- "sequence": false, >- "generic": null, >- "union": false, >- "array": false >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "float" > }, > { >- "nullable": false, >- "idlType": "Event", >- "generic": null, >- "sequence": false, >- "array": false, >- "union": false >- } >- ], >- "nullable": false, >- "sequence": false, >- "generic": null, >- "array": false, >- "union": true >- }, >- { >- "generic": null, >- "sequence": false, >- "idlType": [ >- { >- "array": false, >- "union": false, >- "sequence": false, >- "generic": null, >- "nullable": false, >- "idlType": "Node" >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": true, >+ "idlType": [ >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "Date" >+ }, >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "Event" >+ } >+ ] > }, > { >- "nullable": false, >- "idlType": "DOMString", >- "sequence": false, >- "generic": null, >- "array": false, >- "union": false >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": true, >+ "union": true, >+ "idlType": [ >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "Node" >+ }, >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "DOMString" >+ } >+ ] > } >- ], >- "nullable": true, >- "union": true, >- "array": false >- } >- ], >- "nullable": false, >- "generic": null, >- "sequence": false, >- "union": true, >- "array": false >+ ] >+ }, >+ "name": "test", >+ "extAttrs": [] > }, >- "name": "test", >- "inherit": false, >- "type": "attribute", >- "extAttrs": [], >- "readonly": false, >- "stringifier": false, >- "static": false >- }, >- { >- "readonly": false, >- "extAttrs": [], >- "stringifier": false, >- "static": false, >- "name": "test2", >- "idlType": { >- "nullable": false, >- "idlType": [ >- { >- "extAttrs": [ >+ { >+ "type": "attribute", >+ "static": false, >+ "stringifier": false, >+ "inherit": false, >+ "readonly": false, >+ "idlType": { >+ "type": "attribute-type", >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": true, >+ "idlType": [ > { >- "name": "EnforceRange", >- "arguments": null >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "long", >+ "extAttrs": [ >+ { >+ "name": "EnforceRange", >+ "arguments": null, >+ "type": "extended-attribute", >+ "rhs": null >+ } >+ ] >+ }, >+ { >+ "type": null, >+ "sequence": false, >+ "generic": null, >+ "nullable": false, >+ "union": false, >+ "idlType": "Date" > } >- ], >- "nullable": false, >- "idlType": "long", >- "generic": null, >- "sequence": false, >- "array": false, >- "union": false >- }, >- { >- "array": false, >- "union": false, >- "sequence": false, >- "generic": null, >- "idlType": "Date", >- "nullable": false >- } >- ], >- "generic": null, >- "sequence": false, >- "union": true, >- "array": false >- }, >- "inherit": false, >- "type": "attribute" >- } >- ], >- "inheritance": null, >- "name": "Union", >- "extAttrs": [], >- "type": "interface" >- } >+ ] >+ }, >+ "name": "test2", >+ "extAttrs": [] >+ } >+ ], >+ "inheritance": null, >+ "extAttrs": [] >+ } > ] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/variadic-operations.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/variadic-operations.json >index 431ec0cb1150e0084cd8c9ac0e5f671d024a2808..53b02dfb4ccb5712894c535f25fea6f2b64c072f 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/variadic-operations.json >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/variadic-operations.json >@@ -11,10 +11,10 @@ > "inherit": false, > "readonly": true, > "idlType": { >+ "type": "attribute-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "unsigned long" > }, >@@ -25,16 +25,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -45,10 +43,10 @@ > "variadic": true, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "long" > }, >@@ -61,16 +59,14 @@ > "type": "operation", > "getter": false, > "setter": false, >- "creator": false, > "deleter": false, >- "legacycaller": false, > "static": false, > "stringifier": false, > "idlType": { >+ "type": "return-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "void" > }, >@@ -81,10 +77,10 @@ > "variadic": true, > "extAttrs": [], > "idlType": { >+ "type": "argument-type", > "sequence": false, > "generic": null, > "nullable": false, >- "array": false, > "union": false, > "idlType": "long" > }, >@@ -97,4 +93,4 @@ > "inheritance": null, > "extAttrs": [] > } >-] >\ No newline at end of file >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/w3c-import.log >index d79ee75337bedf279e72aedbf07cd15a1e740993..a84420b86ae15971906c4fa94eff8068201ad2ac 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/w3c-import.log >@@ -15,10 +15,8 @@ None > ------------------------------------------------------------------------ > List of files: > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/allowany.json >-/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/array.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/attributes.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/callback.json >-/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/caller.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/constants.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/constructor.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/dictionary-inherits.json >@@ -28,7 +26,6 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/enum.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/equivalent-decl.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/exception-inheritance.json >-/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/exception.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/extended-attributes.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/generic.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/getter-setter.json >@@ -40,7 +37,9 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/iterable.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/iterator.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/legacyiterable.json >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/linecomment.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/maplike.json >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/mixin.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/namedconstructor.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/namespace.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/nointerfaceobject.json >@@ -57,7 +56,6 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/reg-operations.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/replaceable.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/sequence.json >-/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/serializer.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/setlike.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/static.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/json/stringifier-attribute.json >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/opt/linecomment.json b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/opt/linecomment.json >new file mode 100644 >index 0000000000000000000000000000000000000000..fbcdbf4b71974b5199a86331f22515749ce95839 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/opt/linecomment.json >@@ -0,0 +1,3 @@ >+{ >+ "ws": true >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/opt/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/opt/w3c-import.log >index 2e81123b07ca7575f21ad27337d14845a717ac8e..fdf1959b975baaa8234b7b178e825a7457787cb3 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/opt/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/opt/w3c-import.log >@@ -14,4 +14,5 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/opt/linecomment.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax/opt/typedef-nested.json >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/util/acquire.js b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/util/acquire.js >new file mode 100644 >index 0000000000000000000000000000000000000000..6f37dd6083c3c75dfe561727e9a843465e3cfa6c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/util/acquire.js >@@ -0,0 +1,8 @@ >+"use strict"; >+ >+const { collect } = require("./collect"); >+const fs = require("fs"); >+ >+for (const test of collect("syntax")) { >+ fs.writeFileSync(test.jsonPath, `${JSON.stringify(test.ast, null, 4)}\n`) >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/util/collect.js b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/util/collect.js >new file mode 100644 >index 0000000000000000000000000000000000000000..7e3d9d3bf31267578c0ce2046eec3f5245c573dc >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/util/collect.js >@@ -0,0 +1,59 @@ >+"use strict"; >+ >+const wp = require("../../lib/webidl2"); >+const pth = require("path"); >+const fs = require("fs"); >+const jdp = require("jsondiffpatch"); >+ >+/** >+ * Collects test items from the specified directory >+ * @param {string} base >+ */ >+function* collect(base, { expectError } = {}) { >+ base = pth.join(__dirname, "..", base); >+ const dir = pth.join(base, "idl"); >+ const idls = fs.readdirSync(dir) >+ .filter(it => (/\.widl$/).test(it)) >+ .map(it => pth.join(dir, it)); >+ >+ for (const path of idls) { >+ const optFile = pth.join(base, "opt", pth.basename(path)).replace(".widl", ".json"); >+ let opt; >+ if (fs.existsSync(optFile)) >+ opt = JSON.parse(fs.readFileSync(optFile, "utf8")); >+ >+ try { >+ const ast = wp.parse(fs.readFileSync(path, "utf8").replace(/\r\n/g, "\n"), opt); >+ yield new TestItem({ ast, path, opt }); >+ } >+ catch (error) { >+ if (expectError) { >+ yield new TestItem({ path, error }); >+ } >+ else { >+ throw error; >+ } >+ } >+ } >+}; >+ >+ >+class TestItem { >+ constructor({ ast, path, error, opt }) { >+ this.ast = ast; >+ this.path = path; >+ this.error = error; >+ this.opt = opt; >+ this.jsonPath = pth.join(pth.dirname(path), "../json", pth.basename(path).replace(".widl", ".json")); >+ } >+ >+ readJSON() { >+ return JSON.parse(fs.readFileSync(this.jsonPath, "utf8")); >+ } >+ >+ diff(target = this.readJSON()) { >+ return jdp.diff(target, this.ast); >+ } >+} >+ >+module.exports.collect = collect; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/util/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/util/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..73c81d820fb04b5ff926acce6c5d7684fc5f1028 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/util/w3c-import.log >@@ -0,0 +1,18 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/util/acquire.js >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/util/collect.js >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/w3c-import.log >index b026795ae9999c59b96c5dda9e2c92edb6a19377..7a9f72efabcd1aafd15e62305531e6b3633180c6 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/w3c-import.log >@@ -17,3 +17,4 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/invalid.js > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/mocha.opts > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/syntax.js >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/writer.js >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/writer.js b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/writer.js >new file mode 100644 >index 0000000000000000000000000000000000000000..e84076b4f28ce38cbb41e47681ac97843df0e427 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/test/writer.js >@@ -0,0 +1,23 @@ >+"use strict"; >+ >+const { collect } = require("./util/collect"); >+const wp = require("../lib/webidl2"); >+const writer = require("../lib/writer"); >+const expect = require("expect"); >+const debug = true; >+ >+describe("Rewrite and parses all of the IDLs to produce the same ASTs", () => { >+ for (const test of collect("syntax")) { >+ it(`should produce the same AST for ${test.path}`, () => { >+ try { >+ const diff = test.diff(wp.parse(writer.write(test.ast), test.opt)); >+ if (diff && debug) console.log(JSON.stringify(diff, null, 4)); >+ expect(diff).toBe(undefined); >+ } >+ catch (e) { >+ console.log(e.toString()); >+ throw e; >+ } >+ }); >+ } >+}); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/w3c-import.log >index 7aea1e13eb5ce5a04f457bb09716c009ba7e7ff2..78b09b6a5fd3076675d3fb05760558a5596f190f 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/w3c-import.log >@@ -14,8 +14,10 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/CHANGELOG.md > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/LICENSE > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/README.md > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/coverage.html > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/index.js >+/LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/package-lock.json > /LayoutTests/imported/w3c/web-platform-tests/resources/webidl2/package.json >diff --git a/LayoutTests/imported/w3c/web-platform-tests/secure-contexts/OWNERS b/LayoutTests/imported/w3c/web-platform-tests/secure-contexts/OWNERS >new file mode 100644 >index 0000000000000000000000000000000000000000..12f907ceb41814018b7348d430d7be5bb9dc7372 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/secure-contexts/OWNERS >@@ -0,0 +1 @@ >+@mikewest >diff --git a/LayoutTests/imported/w3c/web-platform-tests/secure-contexts/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/secure-contexts/w3c-import.log >index 05a519ccafe12adc1877fc50ea4f0e84cc025f9b..4035575e5978c8b712f2be928387b92de29ea926 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/secure-contexts/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/secure-contexts/w3c-import.log >@@ -14,6 +14,7 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/secure-contexts/OWNERS > /LayoutTests/imported/w3c/web-platform-tests/secure-contexts/basic-dedicated-worker.html > /LayoutTests/imported/w3c/web-platform-tests/secure-contexts/basic-dedicated-worker.https.html > /LayoutTests/imported/w3c/web-platform-tests/secure-contexts/basic-popup-and-iframe-tests.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/server-timing/OWNERS b/LayoutTests/imported/w3c/web-platform-tests/server-timing/OWNERS >new file mode 100644 >index 0000000000000000000000000000000000000000..f1882ce94fcd500e25c3e33b7091ca265668a124 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/server-timing/OWNERS >@@ -0,0 +1 @@ >+@igrigorik >diff --git a/LayoutTests/imported/w3c/web-platform-tests/server-timing/sw.js b/LayoutTests/imported/w3c/web-platform-tests/server-timing/sw.js >index dc09808c909d6f7d31a8135c935a42c8a1a4b8f7..a6fd72ad17bc0057f63bbf65caf97b66e2cce60c 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/server-timing/sw.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/server-timing/sw.js >@@ -3,7 +3,7 @@ importScripts('/resources/testharness.js') > promise_test((test) => { > return fetch('./sw.js').then((response) => { > return new Promise((resolve, reject) => { >- setTimeout(() => { >+ step_timeout(() => { > const entry = performance.getEntriesByName(response.url)[0] > if (!entry) { > reject('no entry: ' + response.url) >diff --git a/LayoutTests/imported/w3c/web-platform-tests/server-timing/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/server-timing/w3c-import.log >index 46611a7dc61616fe49bf68144780f5ec677bdd61..3da94e5d3c1cdce91cadbb53c9d0566d003e65db 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/server-timing/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/server-timing/w3c-import.log >@@ -14,6 +14,7 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/server-timing/OWNERS > /LayoutTests/imported/w3c/web-platform-tests/server-timing/cross_origin.html > /LayoutTests/imported/w3c/web-platform-tests/server-timing/navigation_timing_idl.html > /LayoutTests/imported/w3c/web-platform-tests/server-timing/navigation_timing_idl.https.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/OWNERS b/LayoutTests/imported/w3c/web-platform-tests/service-workers/OWNERS >index f4293642c4bb1a7b15184f078cd3aeb6d936b039..7870c50f31451bee02889ed8b30d1659fd2d0b4a 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/OWNERS >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/OWNERS >@@ -1,3 +1,5 @@ >-@ehsan >+@asutherland >+@beidson > @mkruisselbrink > @mattto >+@wanderview >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/resources/cache-keys-attributes-for-service-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/resources/cache-keys-attributes-for-service-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..ee574d2cb77a76793709f25b67ac17f5f59a7121 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/resources/cache-keys-attributes-for-service-worker.js >@@ -0,0 +1,22 @@ >+self.addEventListener('fetch', (event) => { >+ const params = new URL(event.request.url).searchParams; >+ if (params.has('ignore')) { >+ return; >+ } >+ if (!params.has('name')) { >+ event.respondWith(Promise.reject(TypeError('No name is provided.'))); >+ return; >+ } >+ >+ event.respondWith(Promise.resolve().then(async () => { >+ const name = params.get('name'); >+ await caches.delete('foo'); >+ const cache = await caches.open('foo'); >+ await cache.put(event.request, new Response('hello')); >+ const keys = await cache.keys(); >+ >+ const original = event.request[name]; >+ const stored = keys[0][name]; >+ return new Response(`original: ${original}, stored: ${stored}`); >+ })); >+ }); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/resources/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/resources/w3c-import.log >index d46bdf554dadf7c85cec0c19a36f622ce823e59d..481c43e62a0a23de4dabbe987f25b604d3a9c7c7 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/resources/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/resources/w3c-import.log >@@ -15,6 +15,7 @@ None > ------------------------------------------------------------------------ > List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/resources/blank.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/resources/cache-keys-attributes-for-service-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/resources/common-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/resources/credentials-iframe.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/resources/credentials-worker.js >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/script-tests/cache-abort.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/script-tests/cache-abort.js >new file mode 100644 >index 0000000000000000000000000000000000000000..ec4130fded29e0070828092c2546dc46456d8fdc >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/script-tests/cache-abort.js >@@ -0,0 +1,81 @@ >+if (self.importScripts) { >+ importScripts('/resources/testharness.js'); >+ importScripts('../resources/test-helpers.js'); >+ importScripts('/common/utils.js'); >+} >+ >+// We perform the same tests on put, add, addAll. Parameterise the tests to >+// reduce repetition. >+const methodsToTest = { >+ put: async (cache, request) => { >+ const response = await fetch(request); >+ return cache.put(request, response); >+ }, >+ add: async (cache, request) => cache.add(request), >+ addAll: async (cache, request) => cache.addAll([request]), >+}; >+ >+for (const method in methodsToTest) { >+ const perform = methodsToTest[method]; >+ >+ cache_test(async (cache, test) => { >+ const controller = new AbortController(); >+ const signal = controller.signal; >+ controller.abort(); >+ const request = new Request('../resources/simple.txt', { signal }); >+ return promise_rejects(test, 'AbortError', perform(cache, request), >+ `${method} should reject`); >+ }, `${method}() on an already-aborted request should reject with AbortError`); >+ >+ cache_test(async (cache, test) => { >+ const controller = new AbortController(); >+ const signal = controller.signal; >+ const request = new Request('../resources/simple.txt', { signal }); >+ const promise = perform(cache, request); >+ controller.abort(); >+ return promise_rejects(test, 'AbortError', promise, >+ `${method} should reject`); >+ }, `${method}() synchronously followed by abort should reject with ` + >+ `AbortError`); >+ >+ cache_test(async (cache, test) => { >+ const controller = new AbortController(); >+ const signal = controller.signal; >+ const stateKey = token(); >+ const abortKey = token(); >+ const request = new Request( >+ `../../../fetch/api/resources/infinite-slow-response.py?stateKey=${stateKey}&abortKey=${abortKey}`, >+ { signal }); >+ >+ const promise = perform(cache, request); >+ >+ // Wait for the server to start sending the response body. >+ let opened = false; >+ do { >+ // Normally only one fetch to 'stash-take' is needed, but the fetches >+ // will be served in reverse order sometimes >+ // (i.e., 'stash-take' gets served before 'infinite-slow-response'). >+ >+ const response = >+ await fetch(`../../../fetch/api/resources/stash-take.py?key=${stateKey}`); >+ const body = await response.json(); >+ if (body === 'open') opened = true; >+ } while (!opened); >+ >+ // Sadly the above loop cannot guarantee that the browser has started >+ // processing the response body. This delay is needed to make the test >+ // failures non-flaky in Chrome version 66. My deepest apologies. >+ await new Promise(resolve => setTimeout(resolve, 250)); >+ >+ controller.abort(); >+ >+ await promise_rejects(test, 'AbortError', promise, >+ `${method} should reject`); >+ >+ // infinite-slow-response.py doesn't know when to stop. >+ return fetch(`../../../fetch/api/resources/stash-put.py?key=${abortKey}`); >+ }, `${method}() followed by abort after headers received should reject ` + >+ `with AbortError`); >+} >+ >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/script-tests/cache-match.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/script-tests/cache-match.js >index 3d00f0f04af3a16ccb7cc732e4df8ccfa0ef401c..ba359fed142cb4a3ff281a44e8a2b9ec8a7a656a 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/script-tests/cache-match.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/script-tests/cache-match.js >@@ -1,6 +1,7 @@ > if (self.importScripts) { > importScripts('/resources/testharness.js'); > importScripts('../resources/test-helpers.js'); >+ importScripts('/common/get-host-info.sub.js'); > } > > prepopulated_cache_test(simple_entries, function(cache, entries) { >@@ -318,4 +319,22 @@ cache_test(function(cache) { > }); > }, 'Cache produces large Responses that can be cloned and read correctly.'); > >+cache_test(async (cache) => { >+ const url = get_host_info().HTTPS_REMOTE_ORIGIN + >+ '/service-workers/cache-storage/resources/simple.txt?pipe=' + >+ 'header(access-control-allow-origin,*)|' + >+ 'header(access-control-expose-headers,*)|' + >+ 'header(foo,bar)|' + >+ 'header(set-cookie,X)'; >+ >+ const response = await fetch(url); >+ await cache.put(new Request(url), response); >+ const cached_response = await cache.match(url); >+ >+ const headers = cached_response.headers; >+ assert_equals(headers.get('access-control-expose-headers'), '*'); >+ assert_equals(headers.get('foo'), 'bar'); >+ assert_equals(headers.get('set-cookie'), null); >+ }, 'cors-exposed header should be stored correctly.'); >+ > done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/script-tests/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/script-tests/w3c-import.log >index 6d5781a259e450ad7fbfa719cbcd2e7a3c5ea83d..09934ce9041b95c5612f0ef7ee788618282176a9 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/script-tests/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/script-tests/w3c-import.log >@@ -14,6 +14,7 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/script-tests/cache-abort.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/script-tests/cache-add.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/script-tests/cache-delete.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/script-tests/cache-keys.js >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-abort.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-abort.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..48f1d9fd75b5b216ee32486b2c5d9a5738341dd5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-abort.https-expected.txt >@@ -0,0 +1,14 @@ >+ >+Harness Error (TIMEOUT), message = null >+ >+TIMEOUT Cache Storage: Abort Test timed out >+FAIL put() on an already-aborted request should reject with AbortError assert_unreached: Should have rejected: put should reject Reached unreachable code >+FAIL put() synchronously followed by abort should reject with AbortError assert_unreached: Should have rejected: put should reject Reached unreachable code >+TIMEOUT put() followed by abort after headers received should reject with AbortError Test timed out >+NOTRUN add() on an already-aborted request should reject with AbortError >+NOTRUN add() synchronously followed by abort should reject with AbortError >+NOTRUN add() followed by abort after headers received should reject with AbortError >+NOTRUN addAll() on an already-aborted request should reject with AbortError >+NOTRUN addAll() synchronously followed by abort should reject with AbortError >+NOTRUN addAll() followed by abort after headers received should reject with AbortError >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-abort.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-abort.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..5a8b539be81ef0e4b43f1193d4bb62972968442c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-abort.https.html >@@ -0,0 +1,10 @@ >+<!DOCTYPE html> >+<title>Cache Storage: Abort</title> >+<link rel="help" href="https://fetch.spec.whatwg.org/#request-signal"> >+<meta name="timeout" content="long"> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="../../service-worker/resources/test-helpers.sub.js"></script> >+<script> >+service_worker_test('../script-tests/cache-abort.js'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-keys-attributes-for-service-worker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-keys-attributes-for-service-worker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..9931eaacd552a04da1a6e5e89527b401817dbc3a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-keys-attributes-for-service-worker.https-expected.txt >@@ -0,0 +1,4 @@ >+ >+FAIL Request.IsReloadNavigation should persist. assert_equals: expected "original: false, stored: false" but got "original: undefined, stored: undefined" >+FAIL Request.IsHistoryNavigation should persist. assert_equals: expected "original: false, stored: false" but got "original: undefined, stored: undefined" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-keys-attributes-for-service-worker.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-keys-attributes-for-service-worker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..b6044c581b83eeb9fd9d3bfb2f936712b90d0175 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-keys-attributes-for-service-worker.https.html >@@ -0,0 +1,75 @@ >+<!DOCTYPE html> >+<title>Cache.keys (checking request attributes that can be set only on service workers)</title> >+<link rel="help" href="https://w3c.github.io/ServiceWorker/#cache-keys"> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="../../service-worker/resources/test-helpers.sub.js"></script> >+<script> >+const worker = '../resources/cache-keys-attributes-for-service-worker.js'; >+ >+function wait(ms) { >+ return new Promise(resolve => step_timeout(resolve, ms)); >+} >+ >+promise_test(async (t) => { >+ const scope = '../resources/blank.html?name=isReloadNavigation'; >+ let frame; >+ let reg; >+ >+ try { >+ reg = await service_worker_unregister_and_register(t, worker, scope); >+ await wait_for_state(t, reg.installing, 'activated'); >+ frame = await with_iframe(scope); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'original: false, stored: false'); >+ await new Promise((resolve) => { >+ frame.onload = resolve; >+ frame.contentWindow.location.reload(); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'original: true, stored: true'); >+ } finally { >+ if (frame) { >+ frame.remove(); >+ } >+ if (reg) { >+ await reg.unregister(); >+ } >+ } >+}, 'Request.IsReloadNavigation should persist.'); >+ >+promise_test(async (t) => { >+ const scope = '../resources/blank.html?name=isHistoryNavigation'; >+ let frame; >+ let reg; >+ >+ try { >+ reg = await service_worker_unregister_and_register(t, worker, scope); >+ await wait_for_state(t, reg.installing, 'activated'); >+ frame = await with_iframe(scope); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'original: false, stored: false'); >+ // Use step_timeout(0) to ensure the history entry is created for Blink >+ // and WebKit. See https://bugs.webkit.org/show_bug.cgi?id=42861. >+ await wait(0); >+ await new Promise((resolve) => { >+ frame.onload = resolve; >+ frame.src = '../resources/blank.html?ignore'; >+ }); >+ await wait(0); >+ await new Promise((resolve) => { >+ frame.onload = resolve; >+ frame.contentWindow.history.go(-1); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'original: true, stored: true'); >+ } finally { >+ if (frame) { >+ frame.remove(); >+ } >+ if (reg) { >+ await reg.unregister(); >+ } >+ } >+}, 'Request.IsHistoryNavigation should persist.'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-match.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-match.https-expected.txt >index 7195d7bdb88da55dcc438f50a1f27606ee275960..53a4a1e6425ce008ae33d8afaefc922c63c8dab6 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-match.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-match.https-expected.txt >@@ -20,4 +20,5 @@ PASS Cache.match with POST Request > PASS Cache.match with a non-2xx Response > PASS Cache.match with a network error Response > PASS Cache produces large Responses that can be cloned and read correctly. >+FAIL cors-exposed header should be stored correctly. assert_equals: expected (string) "bar" but got (object) null > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/w3c-import.log >index 174703ed246f3d6757957757b92942c108acc157..a67148d7bb9421e042611e78a2eab31ce0aa4049 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/w3c-import.log >@@ -14,8 +14,10 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-abort.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-add.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-delete.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-keys-attributes-for-service-worker.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-keys.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-match.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/cache-matchAll.https.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/cache-abort.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/cache-abort.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..5e3f2ded9ad0f3e96eeb3c1bb770afe89812ab2b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/cache-abort.https-expected.txt >@@ -0,0 +1,13 @@ >+ >+Harness Error (TIMEOUT), message = null >+ >+FAIL put() on an already-aborted request should reject with AbortError assert_unreached: Should have rejected: put should reject Reached unreachable code >+FAIL put() synchronously followed by abort should reject with AbortError assert_unreached: Should have rejected: put should reject Reached unreachable code >+TIMEOUT put() followed by abort after headers received should reject with AbortError Test timed out >+NOTRUN add() on an already-aborted request should reject with AbortError >+NOTRUN add() synchronously followed by abort should reject with AbortError >+NOTRUN add() followed by abort after headers received should reject with AbortError >+NOTRUN addAll() on an already-aborted request should reject with AbortError >+NOTRUN addAll() synchronously followed by abort should reject with AbortError >+NOTRUN addAll() followed by abort after headers received should reject with AbortError >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/cache-abort.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/cache-abort.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..405d34d665c27cee93a03f7013f087cfc0a61af7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/cache-abort.https.html >@@ -0,0 +1,9 @@ >+<!DOCTYPE html> >+<title>Cache Storage: Abort</title> >+<link rel="help" href="https://fetch.spec.whatwg.org/#request-signal"> >+<meta name="timeout" content="long"> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="../resources/test-helpers.js"></script> >+<script src="/common/utils.js"></script> >+<script src="../script-tests/cache-abort.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/cache-match.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/cache-match.https-expected.txt >index 4f52e500c8257345dd48592b79b3b17538118e5a..dff99fa824d4001660ccfeb0839e27a5c3580973 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/cache-match.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/cache-match.https-expected.txt >@@ -19,4 +19,5 @@ PASS Cache.match with POST Request > PASS Cache.match with a non-2xx Response > PASS Cache.match with a network error Response > PASS Cache produces large Responses that can be cloned and read correctly. >+FAIL cors-exposed header should be stored correctly. assert_equals: expected (string) "bar" but got (object) null > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/cache-match.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/cache-match.https.html >index ffc64984ea1b09e4c1bef459c88481cb49cf72ce..f28efad0b76b341171ad230e18d243e229153687 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/cache-match.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/cache-match.https.html >@@ -4,5 +4,6 @@ > <meta name="timeout" content="long"> > <script src="/resources/testharness.js"></script> > <script src="/resources/testharnessreport.js"></script> >+<script src="/common/get-host-info.sub.js"></script> > <script src="../resources/test-helpers.js"></script> > <script src="../script-tests/cache-match.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/w3c-import.log >index a91ec6ba8b15879d5c772205116b2f25231104aa..1361457525a0689578f9cd80ccd3936d55b8459f 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/w3c-import.log >@@ -14,6 +14,7 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/cache-abort.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/cache-add.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/cache-delete.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/window/cache-keys.https.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/worker/cache-abort.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/worker/cache-abort.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..5e3f2ded9ad0f3e96eeb3c1bb770afe89812ab2b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/worker/cache-abort.https-expected.txt >@@ -0,0 +1,13 @@ >+ >+Harness Error (TIMEOUT), message = null >+ >+FAIL put() on an already-aborted request should reject with AbortError assert_unreached: Should have rejected: put should reject Reached unreachable code >+FAIL put() synchronously followed by abort should reject with AbortError assert_unreached: Should have rejected: put should reject Reached unreachable code >+TIMEOUT put() followed by abort after headers received should reject with AbortError Test timed out >+NOTRUN add() on an already-aborted request should reject with AbortError >+NOTRUN add() synchronously followed by abort should reject with AbortError >+NOTRUN add() followed by abort after headers received should reject with AbortError >+NOTRUN addAll() on an already-aborted request should reject with AbortError >+NOTRUN addAll() synchronously followed by abort should reject with AbortError >+NOTRUN addAll() followed by abort after headers received should reject with AbortError >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/worker/cache-abort.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/worker/cache-abort.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..68bbade07d3862c883bf0f95b02a5cb6181d8e79 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/worker/cache-abort.https.html >@@ -0,0 +1,9 @@ >+<!DOCTYPE html> >+<title>>Cache Storage: Abort</title> >+<link rel="help" href="https://fetch.spec.whatwg.org/#request-signal"> >+<meta name="timeout" content="long"> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+fetch_tests_from_worker(new Worker('../script-tests/cache-abort.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/worker/cache-match.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/worker/cache-match.https-expected.txt >index 4f52e500c8257345dd48592b79b3b17538118e5a..dff99fa824d4001660ccfeb0839e27a5c3580973 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/worker/cache-match.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/worker/cache-match.https-expected.txt >@@ -19,4 +19,5 @@ PASS Cache.match with POST Request > PASS Cache.match with a non-2xx Response > PASS Cache.match with a network error Response > PASS Cache produces large Responses that can be cloned and read correctly. >+FAIL cors-exposed header should be stored correctly. assert_equals: expected (string) "bar" but got (object) null > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/worker/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/worker/w3c-import.log >index cb55ffd6b5bbd0905723fd6a645d0de8707e7b94..65dda56ffb00634ed08429fbc193e8b1303fc6f2 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/worker/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/worker/w3c-import.log >@@ -14,6 +14,7 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/worker/cache-abort.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/worker/cache-add.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/worker/cache-delete.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/worker/cache-keys.https.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/Service-Worker-Allowed-header.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/Service-Worker-Allowed-header.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..e1759e083d315515be071c1b18423b0b200ea9a4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/Service-Worker-Allowed-header.https-expected.txt >@@ -0,0 +1,10 @@ >+ >+PASS Registering within Service-Worker-Allowed path >+PASS Registering within Service-Worker-Allowed path (absolute URL) >+PASS Registering within Service-Worker-Allowed path with parent reference >+PASS Registering outside Service-Worker-Allowed path >+PASS Registering outside Service-Worker-Allowed path with parent reference >+PASS Service-Worker-Allowed is cross-origin to script, registering on a normally allowed scope >+PASS Service-Worker-Allowed is cross-origin to script, registering on a normally disallowed scope >+PASS Service-Worker-Allowed is cross-origin to page, same-origin to script >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/Service-Worker-Allowed-header.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/Service-Worker-Allowed-header.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..316067cc06679570866cd1ccf67f273cce57a15b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/Service-Worker-Allowed-header.https.html >@@ -0,0 +1,104 @@ >+<!DOCTYPE html> >+<title>Service Worker: Service-Worker-Allowed header</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/get-host-info.sub.js"></script> >+<script src="resources/test-helpers.sub.js"></script> >+<script> >+ >+const host_info = get_host_info(); >+ >+// Returns a URL for a service worker script whose Service-Worker-Allowed >+// header value is set to |allowed_path|. If |origin| is specified, that origin >+// is used. >+function build_script_url(allowed_path, origin) { >+ const script = 'resources/empty-worker.js'; >+ const url = origin ? `${origin}${base_path()}${script}` : script; >+ return `${url}?pipe=header(Service-Worker-Allowed,${allowed_path})`; >+} >+ >+promise_test(async t => { >+ const script = build_script_url('/allowed-path'); >+ const scope = '/allowed-path'; >+ const registration = await service_worker_unregister_and_register( >+ t, script, scope); >+ assert_true(registration instanceof ServiceWorkerRegistration, 'registered'); >+ assert_equals(registration.scope, normalizeURL(scope)); >+ return registration.unregister(); >+}, 'Registering within Service-Worker-Allowed path'); >+ >+promise_test(async t => { >+ const script = build_script_url(new URL('/allowed-path', document.location)); >+ const scope = '/allowed-path'; >+ const registration = await service_worker_unregister_and_register( >+ t, script, scope); >+ assert_true(registration instanceof ServiceWorkerRegistration, 'registered'); >+ assert_equals(registration.scope, normalizeURL(scope)); >+ return registration.unregister(); >+}, 'Registering within Service-Worker-Allowed path (absolute URL)'); >+ >+promise_test(async t => { >+ const script = build_script_url('../allowed-path-with-parent'); >+ const scope = 'allowed-path-with-parent'; >+ const registration = await service_worker_unregister_and_register( >+ t, script, scope); >+ assert_true(registration instanceof ServiceWorkerRegistration, 'registered'); >+ assert_equals(registration.scope, normalizeURL(scope)); >+ return registration.unregister(); >+}, 'Registering within Service-Worker-Allowed path with parent reference'); >+ >+promise_test(async t => { >+ const script = build_script_url('../allowed-path'); >+ const scope = '/disallowed-path'; >+ await service_worker_unregister(t, scope); >+ return promise_rejects(t, >+ 'SecurityError', >+ navigator.serviceWorker.register(script, {scope: scope}), >+ 'register should fail'); >+}, 'Registering outside Service-Worker-Allowed path'); >+ >+promise_test(async t => { >+ const script = build_script_url('../allowed-path-with-parent'); >+ const scope = '/allowed-path-with-parent'; >+ await service_worker_unregister(t, scope); >+ return promise_rejects(t, >+ 'SecurityError', >+ navigator.serviceWorker.register(script, {scope: scope}), >+ 'register should fail'); >+}, 'Registering outside Service-Worker-Allowed path with parent reference'); >+ >+promise_test(async t => { >+ const script = build_script_url( >+ host_info.HTTPS_REMOTE_ORIGIN + '/'); >+ const scope = 'resources/this-scope-is-normally-allowed' >+ const registration = await service_worker_unregister_and_register( >+ t, script, scope); >+ assert_true(registration instanceof ServiceWorkerRegistration, 'registered'); >+ assert_equals(registration.scope, normalizeURL(scope)); >+ return registration.unregister(); >+}, 'Service-Worker-Allowed is cross-origin to script, registering on a normally allowed scope'); >+ >+promise_test(async t => { >+ const script = build_script_url( >+ host_info.HTTPS_REMOTE_ORIGIN + '/'); >+ const scope = '/this-scope-is-normally-disallowed' >+ const registration = await service_worker_unregister_and_register( >+ t, script, scope); >+ assert_true(registration instanceof ServiceWorkerRegistration, 'registered'); >+ assert_equals(registration.scope, normalizeURL(scope)); >+ return registration.unregister(); >+}, 'Service-Worker-Allowed is cross-origin to script, registering on a normally disallowed scope'); >+ >+promise_test(async t => { >+ const script = build_script_url( >+ host_info.HTTPS_REMOTE_ORIGIN + '/cross-origin/', >+ host_info.HTTPS_REMOTE_ORIGIN); >+ const scope = '/cross-origin/'; >+ await service_worker_unregister(t, scope); >+ return promise_rejects(t, >+ 'SecurityError', >+ navigator.serviceWorker.register(script, {scope: scope}), >+ 'register should fail'); >+}, 'Service-Worker-Allowed is cross-origin to page, same-origin to script'); >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-controlling-worker.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-controlling-worker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/about-blank-replacement.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/about-blank-replacement.https-expected.txt >index 42770b42217ace6da71637929d1c642b853e1399..c50fce4ada607d59c3647530ca0d9e67cf8d8f3f 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/about-blank-replacement.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/about-blank-replacement.https-expected.txt >@@ -1,7 +1,11 @@ >+frame "<!--frame5-->" - has 1 onunload handler(s) > > > FAIL Initial about:blank is controlled, exposed to clients.matchAll(), and matches final Client. assert_false: result: failure: could not find about:blank client expected false got true > FAIL Initial about:blank modified by parent is controlled, exposed to clients.matchAll(), and matches final Client. assert_false: result: failure: could not find about:blank client expected false got true > FAIL Popup initial about:blank is controlled, exposed to clients.matchAll(), and matches final Client. assert_false: result: failure: could not find about:blank client expected false got true > PASS Initial about:blank is controlled, exposed to clients.matchAll(), and final Client is not controlled by a service worker. >+FAIL Simple about:blank is controlled and is exposed to clients.matchAll(). assert_false: result: failure: could not find about:blank client expected false got true >+FAIL Nested about:srcdoc is controlled and is exposed to clients.matchAll(). assert_false: result: failure: could not find about:srcdoc client expected false got true >+FAIL Dynamic about:blank is controlled and is exposed to clients.matchAll(). assert_false: result: failure: could not find about:blank client expected false got true > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/about-blank-replacement.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/about-blank-replacement.https.html >index 3acfe1b166a68c8750844d37c82ec98b22abe173..e1fefaf290fe521590a460942d4c3f6c0022c75f 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/about-blank-replacement.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/about-blank-replacement.https.html >@@ -58,7 +58,7 @@ function getClientIdByURL(worker, url) { > }); > } > >-async function doAsyncTest(t, scope, extraSearchParams) { >+async function doAsyncTest(t, scope) { > let reg = await service_worker_unregister_and_register(t, worker, scope); > await wait_for_state(t, reg.installing, 'activated'); > >@@ -70,20 +70,30 @@ async function doAsyncTest(t, scope, extraSearchParams) { > let initialResult = frame.contentWindow.nested().document.body.textContent; > assert_false(initialResult.startsWith('failure:'), `result: ${initialResult}`); > >+ assert_equals(frame.contentWindow.navigator.serviceWorker.controller.scriptURL, >+ frame.contentWindow.nested().navigator.serviceWorker.controller.scriptURL, >+ 'nested about:blank should have same controlling service worker'); >+ > // Next, ask the service worker to find the final client ID for the fully > // loaded nested frame. >- let nestedURL = new URL(scope, window.location); >- nestedURL.searchParams.set('nested', true); >- extraSearchParams = extraSearchParams || {}; >- for (let p in extraSearchParams) { >- nestedURL.searchParams.set(p, extraSearchParams[p]); >- } >+ let nestedURL = new URL(frame.contentWindow.nested().location); > let finalResult = await getClientIdByURL(reg.active, nestedURL); > assert_false(finalResult.startsWith('failure:'), `result: ${finalResult}`); > >- // The initial about:blank client and the final loaded client should have >- // the same ID value. >- assert_equals(initialResult, finalResult, 'client ID values should match'); >+ // If the nested frame doesn't have a URL to load, then there is no fetch >+ // event and the body should be empty. We can't verify the final client ID >+ // against anything. >+ if (nestedURL.href === 'about:blank' || >+ nestedURL.href === 'about:srcdoc') { >+ assert_equals('', initialResult, 'about:blank text content should be blank'); >+ } >+ >+ // If the nested URL is not about:blank, though, then the fetch event handler >+ // should have populated the body with the client id of the initial about:blank. >+ // Verify the final client id matches. >+ else { >+ assert_equals(initialResult, finalResult, 'client ID values should match'); >+ } > > frame.remove(); > await service_worker_unregister_and_done(t, scope); >@@ -101,8 +111,7 @@ promise_test(async function(t) { > // worker can ping the client to verify its existence. This ping-pong > // check is performed during the initial load and when verifying the > // final loaded client. >- await doAsyncTest(t, 'resources/about-blank-replacement-ping-frame.py', >- { 'ping': true }); >+ await doAsyncTest(t, 'resources/about-blank-replacement-ping-frame.py'); > }, 'Initial about:blank modified by parent is controlled, exposed to ' + > 'clients.matchAll(), and matches final Client.'); > >@@ -142,5 +151,27 @@ promise_test(async function(t) { > }, 'Initial about:blank is controlled, exposed to clients.matchAll(), and ' + > 'final Client is not controlled by a service worker.'); > >+promise_test(async function(t) { >+ // Execute a test where the nested frame is an iframe without a src >+ // attribute. This simple nested about:blank should still inherit the >+ // controller and be visible to clients.matchAll(). >+ await doAsyncTest(t, 'resources/about-blank-replacement-blank-nested-frame.html'); >+}, 'Simple about:blank is controlled and is exposed to clients.matchAll().'); >+ >+promise_test(async function(t) { >+ // Execute a test where the nested frame is an iframe using a non-empty >+ // srcdoc containing only a tag pair so its textContent is still empty. >+ // This nested iframe should still inherit the controller and be visible >+ // to clients.matchAll(). >+ await doAsyncTest(t, 'resources/about-blank-replacement-srcdoc-nested-frame.html'); >+}, 'Nested about:srcdoc is controlled and is exposed to clients.matchAll().'); >+ >+promise_test(async function(t) { >+ // Execute a test where the nested frame is dynamically added without a src >+ // attribute. This simple nested about:blank should still inherit the >+ // controller and be visible to clients.matchAll(). >+ await doAsyncTest(t, 'resources/about-blank-replacement-blank-dynamic-nested-frame.html'); >+}, 'Dynamic about:blank is controlled and is exposed to clients.matchAll().'); >+ > </script> > </body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/activation.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/activation.https.html >index 15d386ee1f236fae9991ecc3e2db1b8ab02f5be3..5755758e5716dbc608e7e773bf9b83ab3f2f7e91 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/activation.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/activation.https.html >@@ -1,29 +1,11 @@ > <!DOCTYPE html> > <meta charset="utf-8"> > <title>service worker: activation</title> >-<body> > <script src="/resources/testharness.js"></script> > <script src="/resources/testharnessreport.js"></script> > <script src="resources/test-helpers.sub.js"></script> >+<body> > <script> >-// Registers, waits for activation, then unregisters on a dummy scope. >-// >-// This helper can be used in tests that assert that activation doesn't happen. >-// It would not be sufficient to check the .waiting/.active properties once, >-// since activation could be scheduled and just hasn't happened yet. Since this >-// helper shows that activation of another registration completed, we can be >-// sure that activation really will not happen. >-function wait_for_activation_on_dummy_scope(t) { >- var dummy_scope = 'resources/there/is/no/there/there'; >- var registration; >- return navigator.serviceWorker.register('resources/empty-worker.js', >- { scope: dummy_scope }) >- .then(r => { >- registration = r; >- return wait_for_state(t, registration.installing, 'activated'); >- }) >- .then(() => registration.unregister()); >-} > // Returns {registration, iframe}, where |registration| has an active and > // waiting worker. The active worker controls |iframe| and has an inflight > // message event that can be finished by calling >@@ -67,7 +49,7 @@ function setup_activation_test(t, scope, worker_url) { > return wait_for_state(t, registration.installing, 'installed'); > }) > .then(() => { >- return wait_for_activation_on_dummy_scope(t); >+ return wait_for_activation_on_dummy_scope(t, self); > }) > .then(() => { > assert_not_equals(registration.waiting, null); >@@ -87,7 +69,7 @@ promise_test(t => { > iframe = result.iframe; > // Finish the in-flight request. > registration.active.postMessage('go'); >- return wait_for_activation_on_dummy_scope(t); >+ return wait_for_activation_on_dummy_scope(t, self); > }) > .then(() => { > // The new worker is still waiting. Remove the frame and it should >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/dedicated-worker-service-worker-interception.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/dedicated-worker-service-worker-interception.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..ebac430b988b4fc909a389fd06d103a4d48657db >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/dedicated-worker-service-worker-interception.https-expected.txt >@@ -0,0 +1,8 @@ >+CONSOLE MESSAGE: line 1: SyntaxError: Unexpected string literal './service-worker-interception-network-worker.js'. import call expects exactly one argument. >+ >+Harness Error (FAIL), message = SyntaxError: Unexpected string literal './service-worker-interception-network-worker.js'. import call expects exactly one argument. >+ >+FAIL Top-level module loading should be intercepted by a service worker. assert_equals: expected "LOADED_FROM_SERVICE_WORKER" but got "LOADED_FROM_NETWORK" >+TIMEOUT Static import should be intercepted by a service worker. Test timed out >+NOTRUN Dynamic import should be intercepted by a service worker. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/dedicated-worker-service-worker-interception.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/dedicated-worker-service-worker-interception.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2144f4827121b4902d8c56a61df823f04ee8801d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/dedicated-worker-service-worker-interception.https.html >@@ -0,0 +1,40 @@ >+<!DOCTYPE html> >+<title>DedicatedWorker: ServiceWorker interception</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/test-helpers.sub.js"></script> >+<script> >+ >+// Note that Chrome cannot pass these tests because of https://crbug.com/731599. >+ >+function service_worker_interception_test(url, description) { >+ promise_test(async t => { >+ // Register a service worker whose scope includes |url|. >+ const kServiceWorkerScriptURL = >+ 'resources/service-worker-interception-service-worker.js'; >+ const registration = await service_worker_unregister_and_register( >+ t, kServiceWorkerScriptURL, url); >+ add_result_callback(() => registration.unregister()); >+ await wait_for_state(t, registration.installing, 'activated'); >+ >+ // Start a dedicated worker for |url|. The top-level script request and any >+ // module imports should be intercepted by the service worker. >+ const worker = new Worker(url, { type: 'module' }); >+ const msg_event = await new Promise(resolve => worker.onmessage = resolve); >+ assert_equals(msg_event.data, 'LOADED_FROM_SERVICE_WORKER'); >+ }, description); >+} >+ >+service_worker_interception_test( >+ 'resources/service-worker-interception-network-worker.js', >+ 'Top-level module loading should be intercepted by a service worker.'); >+ >+service_worker_interception_test( >+ 'resources/service-worker-interception-static-import-worker.js', >+ 'Static import should be intercepted by a service worker.'); >+ >+service_worker_interception_test( >+ 'resources/service-worker-interception-dynamic-import-worker.js', >+ 'Dynamic import should be intercepted by a service worker.'); >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/detached-context.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/detached-context.https.html >index d345982343f05f1b71e89cc46a00f057eec89d8e..5ae4de8cc81e0c3650eaaf6b5656193d4a2cf8b0 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/detached-context.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/detached-context.https.html >@@ -16,6 +16,7 @@ promise_test(t => { > const scope_for_main = 'resources/' + scope_for_iframe; > const script = 'resources/empty-worker.js'; > let frame; >+ let resolvedCount = 0; > > return service_worker_unregister(t, scope_for_main) > .then(() => { >@@ -41,9 +42,23 @@ promise_test(t => { > assert_equals(r.active.state, 'activated'); > assert_equals(r.scope, normalizeURL(scope_for_main)); > r.onupdatefound = () => { /* empty */ }; >- return Promise.all([ >- promise_rejects(t, 'InvalidStateError', r.unregister()), >- promise_rejects(t, 'InvalidStateError', r.update())]); >+ >+ // We want to verify that unregister() and update() do not >+ // resolve on a detached registration. We can't check for >+ // an explicit rejection, though, because not all browsers >+ // fire rejection callbacks on detached promises. Instead >+ // we wait for a dummy scope to install, activate, and >+ // unregister before declaring that the promises did not >+ // resolve. >+ r.unregister().then(() => resolvedCount += 1, >+ () => {}); >+ r.update().then(() => resolvedCount += 1, >+ () => {}); >+ return wait_for_activation_on_dummy_scope(t, window); >+ }) >+ .then(() => { >+ assert_equals(resolvedCount, 0, >+ 'methods called on a detached registration should not resolve'); > }) > }, 'accessing a ServiceWorkerRegistration from a removed iframe'); > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/embed-and-object-are-not-intercepted.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/embed-and-object-are-not-intercepted.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..a4be0f0c2d7a2424bc576d58d008377a810b4b6a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/embed-and-object-are-not-intercepted.https-expected.txt >@@ -0,0 +1,5 @@ >+#PID UNRESPONSIVE - com.apple.WebKit.WebContent.Development (pid 44897) >+FAIL: Timed out waiting for notifyDone to be called >+ >+#EOF >+#EOF >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/embed-and-object-are-not-intercepted.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/embed-and-object-are-not-intercepted.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..34556a785aea6810243ca473fc40066d16265116 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/embed-and-object-are-not-intercepted.https.html >@@ -0,0 +1,78 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>embed and object are not intercepted</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/get-host-info.sub.js"></script> >+<script src="resources/test-helpers.sub.js?pipe=sub"></script> >+<body> >+<script> >+let registration; >+ >+const kScript = 'resources/embed-and-object-are-not-intercepted-worker.js'; >+const kScope = 'resources/'; >+ >+promise_test(t => { >+ return service_worker_unregister_and_register(t, kScript, kScope) >+ .then(registration => { >+ promise_test(() => { >+ return registration.unregister(); >+ }, 'restore global state'); >+ >+ return wait_for_state(t, registration.installing, 'activated'); >+ }) >+ }, 'initialize global state'); >+ >+promise_test(t => { >+ let frame; >+ return with_iframe('resources/embed-is-not-intercepted-iframe.html') >+ .then(f => { >+ frame = f; >+ t.add_cleanup(() => { frame.remove(); }); >+ return frame.contentWindow.test_promise; >+ }) >+ .then(result => { >+ assert_equals(result, 'request for embedded content was not intercepted'); >+ }); >+ }, 'requests for EMBED elements of embedded HTML content should not be intercepted by service workers'); >+ >+promise_test(t => { >+ let frame; >+ return with_iframe('resources/object-is-not-intercepted-iframe.html') >+ .then(f => { >+ frame = f; >+ t.add_cleanup(() => { frame.remove(); }); >+ return frame.contentWindow.test_promise; >+ }) >+ .then(result => { >+ assert_equals(result, 'request for embedded content was not intercepted'); >+ }); >+ }, 'requests for OBJECT elements of embedded HTML content should not be intercepted by service workers'); >+ >+promise_test(t => { >+ let frame; >+ return with_iframe('resources/embed-image-is-not-intercepted-iframe.html') >+ .then(f => { >+ frame = f; >+ t.add_cleanup(() => { frame.remove(); }); >+ return frame.contentWindow.test_promise; >+ }) >+ .then(result => { >+ assert_equals(result, 'request was not intercepted'); >+ }); >+ }, 'requests for EMBED elements of an image should not be intercepted by service workers'); >+ >+promise_test(t => { >+ let frame; >+ return with_iframe('resources/object-image-is-not-intercepted-iframe.html') >+ .then(f => { >+ frame = f; >+ t.add_cleanup(() => { frame.remove(); }); >+ return frame.contentWindow.test_promise; >+ }) >+ .then(result => { >+ assert_equals(result, 'request was not intercepted'); >+ }); >+ }, 'requests for OBJECT elements of an image should not be intercepted by service workers'); >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-cache.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-cache.https-expected.txt >deleted file mode 100644 >index 03c0b43f6cf7207af18c5da3d652e3aedb920ab7..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-cache.https-expected.txt >+++ /dev/null >@@ -1,41 +0,0 @@ >- >-PASS Verify canvas tainting of fetched image in a Service Worker >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&reject&cache - default >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&reject&cache - anonymous >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&reject&cache - use-credentials >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ignore&cache - default >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ignore&cache - default >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ignore&cache - anonymous >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ACAOrigin=https://localhost:9443&ignore&cache - anonymous >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ignore&cache - use-credentials >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ACAOrigin=https://localhost:9443&ignore&cache - use-credentials >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ACAOrigin=https://localhost:9443&ACACredentials=true&ignore&cache - use-credentials >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ignore&cache - default >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ignore&cache - default >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ignore&cache - anonymous >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ignore&cache - use-credentials >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ACAOrigin=https://localhost:9443&ignore&cache - use-credentials >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ACAOrigin=https://localhost:9443&ACACredentials=true&ignore&cache - use-credentials >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE&cache - default >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE&cache - anonymous >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE&cache - use-credentials >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE&cache - default >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE&cache - anonymous >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE&cache - use-credentials >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE&cache - default >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE&cache - anonymous >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE&cache - use-credentials >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE&cache - default >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE&cache - anonymous >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE&cache - use-credentials >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443&cache - default >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&credentials=same-origin&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443&cache - default >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443&cache - anonymous >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443&cache - use-credentials >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACACredentials%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443&cache - use-credentials >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443&cache - default >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&credentials=same-origin&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443&cache - default >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443&cache - anonymous >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443&cache - use-credentials >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACACredentials%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443&cache - use-credentials >- >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-cache.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-cache.https.html >deleted file mode 100644 >index e91f97e18731c50bed8103fafc7b28585495c75d..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-cache.https.html >+++ /dev/null >@@ -1,42 +0,0 @@ >-<!DOCTYPE html> >-<title>Service Worker: canvas tainting of the fetched image using cached responses</title> >-<script src="/resources/testharness.js"></script> >-<script src="/resources/testharnessreport.js"></script> >-<script src="/common/get-host-info.sub.js"></script> >-<script src="resources/test-helpers.sub.js?pipe=sub"></script> >-<body> >-<script> >-async_test(function(t) { >- var SCOPE = 'resources/fetch-canvas-tainting-iframe.html?cache'; >- var SCRIPT = 'resources/fetch-rewrite-worker.js'; >- var host_info = get_host_info(); >- >- login_https(t) >- .then(function() { >- return service_worker_unregister_and_register(t, SCRIPT, SCOPE); >- }) >- .then(function(registration) { >- return wait_for_state(t, registration.installing, 'activated'); >- }) >- .then(function() { return with_iframe(SCOPE); }) >- .then(function(frame) { >- return new Promise(function(resolve, reject) { >- var channel = new MessageChannel(); >- channel.port1.onmessage = t.step_func(function(e) { >- for (var result of e.data.results) { >- test(() => { >- assert_equals(result.result, "PASS"); >- }, result.name); >- } >- frame.remove(); >- service_worker_unregister_and_done(t, SCOPE); >- }); >- frame.contentWindow.postMessage({}, >- host_info['HTTPS_ORIGIN'], >- [channel.port2]); >- }); >- }) >- .catch(unreached_rejection(t)); >- }, 'Verify canvas tainting of fetched image in a Service Worker'); >-</script> >-</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image-cache.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image-cache.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..404cf48665d962e50996a7ed3e500a3b97e24b7a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image-cache.https-expected.txt >@@ -0,0 +1,66 @@ >+CONSOLE MESSAGE: line 26: Unable to get image data from canvas because the canvas has been tainted by cross-origin data. >+CONSOLE MESSAGE: Origin https://localhost:9443 is not allowed by Access-Control-Allow-Origin. >+CONSOLE MESSAGE: Cannot load image https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&ignore due to access control checks. >+CONSOLE MESSAGE: Origin https://localhost:9443 is not allowed by Access-Control-Allow-Origin. >+CONSOLE MESSAGE: Cannot load image https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&ignore due to access control checks. >+CONSOLE MESSAGE: Credentials flag is true, but Access-Control-Allow-Credentials is not "true". >+CONSOLE MESSAGE: Cannot load image https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&ACAOrigin=https://localhost:9443&ignore due to access control checks. >+CONSOLE MESSAGE: line 26: Unable to get image data from canvas because the canvas has been tainted by cross-origin data. >+CONSOLE MESSAGE: Blocked https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&Auth&ignore from asking for credentials because it is a cross-origin request. >+CONSOLE MESSAGE: Origin https://localhost:9443 is not allowed by Access-Control-Allow-Origin. >+CONSOLE MESSAGE: Cannot load image https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&Auth&ignore due to access control checks. >+CONSOLE MESSAGE: Origin https://localhost:9443 is not allowed by Access-Control-Allow-Origin. >+CONSOLE MESSAGE: Cannot load image https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&Auth&ignore due to access control checks. >+CONSOLE MESSAGE: Credentials flag is true, but Access-Control-Allow-Credentials is not "true". >+CONSOLE MESSAGE: Cannot load image https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&Auth&ACAOrigin=https://localhost:9443&ignore due to access control checks. >+CONSOLE MESSAGE: line 26: Unable to get image data from canvas because the canvas has been tainted by cross-origin data. >+CONSOLE MESSAGE: Response served by service worker is opaque >+CONSOLE MESSAGE: Cannot load image https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue due to access control checks. >+CONSOLE MESSAGE: Response served by service worker is opaque >+CONSOLE MESSAGE: Cannot load image https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue due to access control checks. >+CONSOLE MESSAGE: line 26: Unable to get image data from canvas because the canvas has been tainted by cross-origin data. >+ >+ >+Harness Error (TIMEOUT), message = null >+ >+PASS initialize global state >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&reject" with crossOrigin "" should be LOAD_ERROR >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&reject" with crossOrigin "anonymous" should be LOAD_ERROR >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&reject" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&ignore" with crossOrigin "" should be NOT_TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&ignore" with crossOrigin "" should be TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&ignore" with crossOrigin "anonymous" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&ACAOrigin=https://localhost:9443&ignore" with crossOrigin "anonymous" should be NOT_TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&ignore" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&ACAOrigin=https://localhost:9443&ignore" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&ACAOrigin=https://localhost:9443&ACACredentials=true&ignore" with crossOrigin "use-credentials" should be NOT_TAINTED >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&Auth&ignore" with crossOrigin "" should be NOT_TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&Auth&ignore" with crossOrigin "" should be TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&Auth&ignore" with crossOrigin "anonymous" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&Auth&ignore" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&Auth&ACAOrigin=https://localhost:9443&ignore" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&Auth&ACAOrigin=https://localhost:9443&ACACredentials=true&ignore" with crossOrigin "use-credentials" should be NOT_TAINTED >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue" with crossOrigin "" should be NOT_TAINTED >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue" with crossOrigin "anonymous" should be NOT_TAINTED >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue" with crossOrigin "use-credentials" should be NOT_TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue" with crossOrigin "" should be NOT_TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue" with crossOrigin "anonymous" should be NOT_TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue" with crossOrigin "use-credentials" should be NOT_TAINTED >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue" with crossOrigin "" should be TAINTED >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue" with crossOrigin "anonymous" should be LOAD_ERROR >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue" with crossOrigin "" should be TAINTED >+TIMEOUT url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue" with crossOrigin "anonymous" should be LOAD_ERROR Test timed out >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue" with crossOrigin "use-credentials" should be LOAD_ERROR >+NOTRUN url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "" should be LOAD_ERROR >+NOTRUN url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=cors&credentials=same-origin&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "" should be NOT_TAINTED >+NOTRUN url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "anonymous" should be NOT_TAINTED >+NOTRUN url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "use-credentials" should be LOAD_ERROR >+NOTRUN url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue%26ACACredentials%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "use-credentials" should be NOT_TAINTED >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "" should be LOAD_ERROR >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=cors&credentials=same-origin&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "" should be NOT_TAINTED >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "anonymous" should be NOT_TAINTED >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "use-credentials" should be LOAD_ERROR >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&cache=true&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26cache%3Dtrue%26ACACredentials%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "use-credentials" should be NOT_TAINTED >+NOTRUN restore global state >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image-cache.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image-cache.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..213238112257923657fe84a637ddd45cc0c038c5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image-cache.https.html >@@ -0,0 +1,16 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Service Worker: canvas tainting of the fetched image using cached responses</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/get-host-info.sub.js"></script> >+<script src="resources/test-helpers.sub.js?pipe=sub"></script> >+<script src="resources/fetch-canvas-tainting-tests.js"></script> >+<body> >+<script> >+do_canvas_tainting_tests({ >+ resource_path: base_path() + 'resources/fetch-access-control.py?PNGIMAGE', >+ cache: true >+}); >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2dbfdc83a825c13ab5fe7c681c1e91ff846f2cb9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image.https-expected.txt >@@ -0,0 +1,67 @@ >+CONSOLE MESSAGE: line 26: Unable to get image data from canvas because the canvas has been tainted by cross-origin data. >+CONSOLE MESSAGE: Origin https://localhost:9443 is not allowed by Access-Control-Allow-Origin. >+CONSOLE MESSAGE: Cannot load image https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ignore due to access control checks. >+CONSOLE MESSAGE: Origin https://localhost:9443 is not allowed by Access-Control-Allow-Origin. >+CONSOLE MESSAGE: Cannot load image https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ignore due to access control checks. >+CONSOLE MESSAGE: Credentials flag is true, but Access-Control-Allow-Credentials is not "true". >+CONSOLE MESSAGE: Cannot load image https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ACAOrigin=https://localhost:9443&ignore due to access control checks. >+CONSOLE MESSAGE: line 26: Unable to get image data from canvas because the canvas has been tainted by cross-origin data. >+CONSOLE MESSAGE: Blocked https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ignore from asking for credentials because it is a cross-origin request. >+CONSOLE MESSAGE: Origin https://localhost:9443 is not allowed by Access-Control-Allow-Origin. >+CONSOLE MESSAGE: Cannot load image https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ignore due to access control checks. >+CONSOLE MESSAGE: Origin https://localhost:9443 is not allowed by Access-Control-Allow-Origin. >+CONSOLE MESSAGE: Cannot load image https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ignore due to access control checks. >+CONSOLE MESSAGE: Credentials flag is true, but Access-Control-Allow-Credentials is not "true". >+CONSOLE MESSAGE: Cannot load image https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ACAOrigin=https://localhost:9443&ignore due to access control checks. >+CONSOLE MESSAGE: line 26: Unable to get image data from canvas because the canvas has been tainted by cross-origin data. >+CONSOLE MESSAGE: Response served by service worker is opaque >+CONSOLE MESSAGE: Cannot load image https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE due to access control checks. >+CONSOLE MESSAGE: Response served by service worker is opaque >+CONSOLE MESSAGE: Cannot load image https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE due to access control checks. >+CONSOLE MESSAGE: line 26: Unable to get image data from canvas because the canvas has been tainted by cross-origin data. >+CONSOLE MESSAGE: Response served by service worker is opaque >+CONSOLE MESSAGE: Cannot load image https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE due to access control checks. >+CONSOLE MESSAGE: Response served by service worker is opaque >+CONSOLE MESSAGE: Cannot load image https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE due to access control checks. >+ >+PASS initialize global state >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&reject" with crossOrigin "" should be LOAD_ERROR >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&reject" with crossOrigin "anonymous" should be LOAD_ERROR >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&reject" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ignore" with crossOrigin "" should be NOT_TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ignore" with crossOrigin "" should be TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ignore" with crossOrigin "anonymous" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ACAOrigin=https://localhost:9443&ignore" with crossOrigin "anonymous" should be NOT_TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ignore" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ACAOrigin=https://localhost:9443&ignore" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ACAOrigin=https://localhost:9443&ACACredentials=true&ignore" with crossOrigin "use-credentials" should be NOT_TAINTED >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ignore" with crossOrigin "" should be NOT_TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ignore" with crossOrigin "" should be TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ignore" with crossOrigin "anonymous" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ignore" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ACAOrigin=https://localhost:9443&ignore" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ACAOrigin=https://localhost:9443&ACACredentials=true&ignore" with crossOrigin "use-credentials" should be NOT_TAINTED >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE" with crossOrigin "" should be NOT_TAINTED >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE" with crossOrigin "anonymous" should be NOT_TAINTED >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE" with crossOrigin "use-credentials" should be NOT_TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE" with crossOrigin "" should be NOT_TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE" with crossOrigin "anonymous" should be NOT_TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE" with crossOrigin "use-credentials" should be NOT_TAINTED >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE" with crossOrigin "" should be TAINTED >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE" with crossOrigin "anonymous" should be LOAD_ERROR >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE" with crossOrigin "" should be TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE" with crossOrigin "anonymous" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "" should be LOAD_ERROR >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&credentials=same-origin&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "" should be NOT_TAINTED >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "anonymous" should be NOT_TAINTED >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACACredentials%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "use-credentials" should be NOT_TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&credentials=same-origin&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "" should be NOT_TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "anonymous" should be NOT_TAINTED >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACACredentials%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "use-credentials" should be NOT_TAINTED >+PASS restore global state >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..57dc7d98caa2f486cbe2dee05c8f430ad560f9e3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image.https.html >@@ -0,0 +1,16 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Service Worker: canvas tainting of the fetched image</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/get-host-info.sub.js"></script> >+<script src="resources/test-helpers.sub.js?pipe=sub"></script> >+<script src="resources/fetch-canvas-tainting-tests.js"></script> >+<body> >+<script> >+do_canvas_tainting_tests({ >+ resource_path: base_path() + 'resources/fetch-access-control.py?PNGIMAGE', >+ cache: false >+}); >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-cache.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-cache.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..60b84ced25bfba3a13bd1d3bae146b0d9c28eb2b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-cache.https-expected.txt >@@ -0,0 +1,53 @@ >+CONSOLE MESSAGE: Origin https://localhost:9443 is not allowed by Access-Control-Allow-Origin. >+CONSOLE MESSAGE: Origin https://localhost:9443 is not allowed by Access-Control-Allow-Origin. >+CONSOLE MESSAGE: Credentials flag is true, but Access-Control-Allow-Credentials is not "true". >+CONSOLE MESSAGE: Blocked https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&Auth&ignore from asking for credentials because it is a cross-origin request. >+CONSOLE MESSAGE: Origin https://localhost:9443 is not allowed by Access-Control-Allow-Origin. >+CONSOLE MESSAGE: Origin https://localhost:9443 is not allowed by Access-Control-Allow-Origin. >+CONSOLE MESSAGE: Credentials flag is true, but Access-Control-Allow-Credentials is not "true". >+CONSOLE MESSAGE: Response served by service worker is opaque >+ >+ >+Harness Error (TIMEOUT), message = null >+ >+PASS initialize global state >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&reject" with crossOrigin "" should be LOAD_ERROR >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&reject" with crossOrigin "anonymous" should be LOAD_ERROR >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&reject" with crossOrigin "use-credentials" should be LOAD_ERROR >+FAIL url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&ignore" with crossOrigin "" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&ignore" with crossOrigin "" should be TAINTED assert_equals: expected "TAINTED" but got "LOAD_ERROR" >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&ignore" with crossOrigin "anonymous" should be LOAD_ERROR >+FAIL url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&ACAOrigin=https://localhost:9443&ignore" with crossOrigin "anonymous" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&ignore" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&ACAOrigin=https://localhost:9443&ignore" with crossOrigin "use-credentials" should be LOAD_ERROR >+FAIL url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&ACAOrigin=https://localhost:9443&ACACredentials=true&ignore" with crossOrigin "use-credentials" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&Auth&ignore" with crossOrigin "" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&Auth&ignore" with crossOrigin "" should be TAINTED assert_equals: expected "TAINTED" but got "LOAD_ERROR" >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&Auth&ignore" with crossOrigin "anonymous" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&Auth&ignore" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&Auth&ACAOrigin=https://localhost:9443&ignore" with crossOrigin "use-credentials" should be LOAD_ERROR >+FAIL url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&Auth&ACAOrigin=https://localhost:9443&ACACredentials=true&ignore" with crossOrigin "use-credentials" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue" with crossOrigin "" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue" with crossOrigin "anonymous" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue" with crossOrigin "use-credentials" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue" with crossOrigin "" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue" with crossOrigin "anonymous" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue" with crossOrigin "use-credentials" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue" with crossOrigin "" should be TAINTED assert_equals: expected "TAINTED" but got "LOAD_ERROR" >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue" with crossOrigin "anonymous" should be LOAD_ERROR >+TIMEOUT url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue" with crossOrigin "use-credentials" should be LOAD_ERROR Test timed out >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue" with crossOrigin "" should be TAINTED >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue" with crossOrigin "anonymous" should be LOAD_ERROR >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue" with crossOrigin "use-credentials" should be LOAD_ERROR >+NOTRUN url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "" should be LOAD_ERROR >+NOTRUN url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=cors&credentials=same-origin&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "" should be NOT_TAINTED >+NOTRUN url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "anonymous" should be NOT_TAINTED >+NOTRUN url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "use-credentials" should be LOAD_ERROR >+NOTRUN url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue%26ACACredentials%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "use-credentials" should be NOT_TAINTED >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "" should be LOAD_ERROR >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=cors&credentials=same-origin&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "" should be NOT_TAINTED >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "anonymous" should be NOT_TAINTED >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "use-credentials" should be LOAD_ERROR >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue%26ACACredentials%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "use-credentials" should be NOT_TAINTED >+NOTRUN restore global state >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-cache.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-cache.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ef3d12bbe4982c64992b3cd0f4ed092eaa72507b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-cache.https.html >@@ -0,0 +1,16 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Service Worker: canvas tainting of the fetched video using cache responses</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/get-host-info.sub.js"></script> >+<script src="resources/test-helpers.sub.js?pipe=sub"></script> >+<script src="resources/fetch-canvas-tainting-tests.js"></script> >+<body> >+<script> >+do_canvas_tainting_tests({ >+ resource_path: base_path() + 'resources/fetch-access-control.py?VIDEO', >+ cache: true >+}); >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-with-range-request.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-with-range-request.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..b502283d8408a341cd72d080812838ac65e684af >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-with-range-request.https-expected.txt >@@ -0,0 +1,5 @@ >+#PID UNRESPONSIVE - com.apple.WebKit.WebContent.Development (pid 44974) >+FAIL: Timed out waiting for notifyDone to be called >+ >+#EOF >+#EOF >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-with-range-request.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-with-range-request.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..f1ff7ae59a7deb4117ee4c43bdafb5d3ec73fed7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-with-range-request.https.html >@@ -0,0 +1,93 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Canvas tainting due to video whose responses are fetched via a service worker including range requests</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/test-helpers.sub.js?pipe=sub"></script> >+<script src="/common/get-host-info.sub.js"></script> >+<body> >+<script> >+// These tests try to test canvas tainting due to a <video> element. The video >+// src URL is same-origin as the page, but the response is fetched via a service >+// worker that does tricky things like returning opaque responses from another >+// origin. Furthermore, this tests range requests so there are multiple >+// responses. >+// >+// We test range requests by having the server return 206 Partial Content to the >+// first request (which doesn't necessarily have a "Range" header or one with a >+// byte range). Then the <video> element automatically makes ranged requests >+// (the "Range" HTTP request header specifies a byte range). The server responds >+// to these with 206 Partial Content for the given range. >+function range_request_test(script, expected, description) { >+ promise_test(t => { >+ let frame; >+ let registration; >+ add_result_callback(() => { >+ if (frame) frame.remove(); >+ if (registration) registration.unregister(); >+ }); >+ >+ const scope = 'resources/fetch-canvas-tainting-iframe.html'; >+ return service_worker_unregister_and_register(t, script, scope) >+ .then(r => { >+ registration = r; >+ return wait_for_state(t, registration.installing, 'activated'); >+ }) >+ .then(() => { >+ return with_iframe(scope); >+ }) >+ .then(f => { >+ frame = f; >+ // Add "?VIDEO&PartialContent" to get a video resource from the >+ // server using range requests. >+ const video_url = 'fetch-access-control.py?VIDEO&PartialContent'; >+ return frame.contentWindow.create_test_case_promise(video_url); >+ }) >+ .then(result => { >+ assert_equals(result, expected); >+ }); >+ }, description); >+} >+ >+// We want to consider a number of scenarios: >+// (1) Range responses come from a single origin, the same-origin as the page. >+// The canvas should not be tainted. >+range_request_test( >+ 'resources/fetch-event-network-fallback-worker.js', >+ 'NOT_TAINTED', >+ 'range responses from single origin (same-origin)'); >+ >+// (2) Range responses come from a single origin, cross-origin from the page >+// (and without CORS sharing). This is not possible to test, since service >+// worker can't make a request with a "Range" HTTP header in no-cors mode. >+ >+// (3) Range responses come from multiple origins. The first response comes from >+// cross-origin (and without CORS sharing, so is opaque). Subsequent >+// responses come from same-origin. The canvas should be tainted (but in >+// Chrome this is a LOAD_ERROR since it disallows range responses from >+// multiple origins, period). >+range_request_test( >+ 'resources/range-request-to-different-origins-worker.js', >+ 'TAINTED', >+ 'range responses from multiple origins (cross-origin first)'); >+ >+// (4) Range responses come from multiple origins. The first response comes from >+// same-origin. Subsequent responses come from cross-origin (and without >+// CORS sharing). Like (2) this is not possible since the service worker >+// cannot make range requests cross-origin. >+ >+// (5) Range responses come from a single origin, with a mix of opaque and >+// non-opaque responses. The first request uses 'no-cors' mode to >+// receive an opaque response, and subsequent range requests use 'cors' >+// to receive non-opaque responses. The canvas should be tainted. >+range_request_test( >+ 'resources/range-request-with-different-cors-modes-worker.js', >+ 'TAINTED', >+ 'range responses from single origin with both opaque and non-opaque responses'); >+ >+// (6) Range responses come from a single origin, with a mix of opaque and >+// non-opaque responses. The first request uses 'cors' mode to >+// receive an non-opaque response, and subsequent range requests use >+// 'no-cors' to receive non-opaque responses. Like (2) this is not possible. >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..ff7f83cae27a600e4f6a558067652ddb57b3e26a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video.https-expected.txt >@@ -0,0 +1,52 @@ >+CONSOLE MESSAGE: Origin https://localhost:9443 is not allowed by Access-Control-Allow-Origin. >+CONSOLE MESSAGE: Origin https://localhost:9443 is not allowed by Access-Control-Allow-Origin. >+CONSOLE MESSAGE: Credentials flag is true, but Access-Control-Allow-Credentials is not "true". >+CONSOLE MESSAGE: Blocked https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&Auth&ignore from asking for credentials because it is a cross-origin request. >+CONSOLE MESSAGE: Origin https://localhost:9443 is not allowed by Access-Control-Allow-Origin. >+CONSOLE MESSAGE: Origin https://localhost:9443 is not allowed by Access-Control-Allow-Origin. >+CONSOLE MESSAGE: Credentials flag is true, but Access-Control-Allow-Credentials is not "true". >+ >+ >+Harness Error (TIMEOUT), message = null >+ >+PASS initialize global state >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&reject" with crossOrigin "" should be LOAD_ERROR >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&reject" with crossOrigin "anonymous" should be LOAD_ERROR >+PASS url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&reject" with crossOrigin "use-credentials" should be LOAD_ERROR >+FAIL url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&ignore" with crossOrigin "" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&ignore" with crossOrigin "" should be TAINTED assert_equals: expected "TAINTED" but got "LOAD_ERROR" >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&ignore" with crossOrigin "anonymous" should be LOAD_ERROR >+FAIL url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&ACAOrigin=https://localhost:9443&ignore" with crossOrigin "anonymous" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&ignore" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&ACAOrigin=https://localhost:9443&ignore" with crossOrigin "use-credentials" should be LOAD_ERROR >+FAIL url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&ACAOrigin=https://localhost:9443&ACACredentials=true&ignore" with crossOrigin "use-credentials" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&Auth&ignore" with crossOrigin "" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&Auth&ignore" with crossOrigin "" should be TAINTED assert_equals: expected "TAINTED" but got "LOAD_ERROR" >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&Auth&ignore" with crossOrigin "anonymous" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&Auth&ignore" with crossOrigin "use-credentials" should be LOAD_ERROR >+PASS url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&Auth&ACAOrigin=https://localhost:9443&ignore" with crossOrigin "use-credentials" should be LOAD_ERROR >+FAIL url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&Auth&ACAOrigin=https://localhost:9443&ACACredentials=true&ignore" with crossOrigin "use-credentials" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO" with crossOrigin "" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO" with crossOrigin "anonymous" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO" with crossOrigin "use-credentials" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO" with crossOrigin "" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO" with crossOrigin "anonymous" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+FAIL url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO" with crossOrigin "use-credentials" should be NOT_TAINTED assert_equals: expected "NOT_TAINTED" but got "LOAD_ERROR" >+TIMEOUT url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO" with crossOrigin "" should be TAINTED Test timed out >+NOTRUN url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO" with crossOrigin "anonymous" should be LOAD_ERROR >+NOTRUN url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO" with crossOrigin "use-credentials" should be LOAD_ERROR >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO" with crossOrigin "" should be TAINTED >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO" with crossOrigin "anonymous" should be LOAD_ERROR >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO" with crossOrigin "use-credentials" should be LOAD_ERROR >+NOTRUN url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "" should be LOAD_ERROR >+NOTRUN url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=cors&credentials=same-origin&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "" should be NOT_TAINTED >+NOTRUN url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "anonymous" should be NOT_TAINTED >+NOTRUN url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "use-credentials" should be LOAD_ERROR >+NOTRUN url "https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26ACACredentials%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "use-credentials" should be NOT_TAINTED >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "" should be LOAD_ERROR >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=cors&credentials=same-origin&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "" should be NOT_TAINTED >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "anonymous" should be NOT_TAINTED >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "use-credentials" should be LOAD_ERROR >+NOTRUN url "https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26ACACredentials%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443" with crossOrigin "use-credentials" should be NOT_TAINTED >+NOTRUN restore global state >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..577650881c15fa9a95c43dcb955bd5818ba8a8ed >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video.https.html >@@ -0,0 +1,16 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Service Worker: canvas tainting of the fetched video</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/get-host-info.sub.js"></script> >+<script src="resources/test-helpers.sub.js?pipe=sub"></script> >+<script src="resources/fetch-canvas-tainting-tests.js"></script> >+<body> >+<script> >+do_canvas_tainting_tests({ >+ resource_path: base_path() + 'resources/fetch-access-control.py?VIDEO', >+ cache: false >+}); >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting.https-expected.txt >deleted file mode 100644 >index c44be0456517e0fe9e8b29b2fdaba639b733297e..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting.https-expected.txt >+++ /dev/null >@@ -1,41 +0,0 @@ >- >-PASS Verify canvas tainting of fetched image in a Service Worker >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&reject - default >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&reject - anonymous >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&reject - use-credentials >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ignore - default >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ignore - default >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ignore - anonymous >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ACAOrigin=https://localhost:9443&ignore - anonymous >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ignore - use-credentials >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ACAOrigin=https://localhost:9443&ignore - use-credentials >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&ACAOrigin=https://localhost:9443&ACACredentials=true&ignore - use-credentials >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ignore - default >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ignore - default >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ignore - anonymous >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ignore - use-credentials >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ACAOrigin=https://localhost:9443&ignore - use-credentials >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&Auth&ACAOrigin=https://localhost:9443&ACACredentials=true&ignore - use-credentials >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE - default >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE - anonymous >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE - use-credentials >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE - default >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE - anonymous >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=same-origin&url=https%3A%2F%2Flocalhost%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE - use-credentials >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE - default >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE - anonymous >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE - use-credentials >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE - default >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE - anonymous >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=no-cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE - use-credentials >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443 - default >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&credentials=same-origin&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443 - default >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443 - anonymous >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443 - use-credentials >-PASS https://localhost:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACACredentials%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443 - use-credentials >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443 - default >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&credentials=same-origin&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443 - default >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443 - anonymous >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443 - use-credentials >-PASS https://127.0.0.1:9443/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACACredentials%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443 - use-credentials >- >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting.https.html >deleted file mode 100644 >index 393fe277d6e4f212627526bd3fdf7169981d8ac9..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting.https.html >+++ /dev/null >@@ -1,42 +0,0 @@ >-<!DOCTYPE html> >-<title>Service Worker: canvas tainting of the fetched image</title> >-<script src="/resources/testharness.js"></script> >-<script src="/resources/testharnessreport.js"></script> >-<script src="/common/get-host-info.sub.js"></script> >-<script src="resources/test-helpers.sub.js?pipe=sub"></script> >-<body> >-<script> >-async_test(function(t) { >- var SCOPE = 'resources/fetch-canvas-tainting-iframe.html'; >- var SCRIPT = 'resources/fetch-rewrite-worker.js'; >- var host_info = get_host_info(); >- >- login_https(t) >- .then(function() { >- return service_worker_unregister_and_register(t, SCRIPT, SCOPE); >- }) >- .then(function(registration) { >- return wait_for_state(t, registration.installing, 'activated'); >- }) >- .then(function() { return with_iframe(SCOPE); }) >- .then(function(frame) { >- return new Promise(function(resolve, reject) { >- var channel = new MessageChannel(); >- channel.port1.onmessage = t.step_func(function(e) { >- for (var result of e.data.results) { >- test(() => { >- assert_equals(result.result, "PASS"); >- }, result.name); >- } >- frame.remove(); >- service_worker_unregister_and_done(t, SCOPE); >- }); >- frame.contentWindow.postMessage({}, >- host_info['HTTPS_ORIGIN'], >- [channel.port2]); >- }); >- }) >- .catch(unreached_rejection(t)); >- }, 'Verify canvas tainting of fetched image in a Service Worker'); >-</script> >-</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-cors-exposed-header-names.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-cors-exposed-header-names.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..e3f07ec53f35b14a1ede1c7aa08f28e6e588bdac >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-cors-exposed-header-names.https-expected.txt >@@ -0,0 +1,4 @@ >+ >+ >+FAIL CORS-exposed header names for a response from sw assert_equals: expected (string) "bar" but got (object) null >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-cors-exposed-header-names.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-cors-exposed-header-names.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..317b02175f2f15d467d3336cd48ca0fc21b473cc >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-cors-exposed-header-names.https.html >@@ -0,0 +1,30 @@ >+<!DOCTYPE html> >+<title>Service Worker: CORS-exposed header names should be transferred correctly</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/get-host-info.sub.js"></script> >+<script src="resources/test-helpers.sub.js"></script> >+<script> >+promise_test(async function(t) { >+ const SCOPE = 'resources/simple.html'; >+ const SCRIPT = 'resources/fetch-cors-exposed-header-names-worker.js'; >+ const host_info = get_host_info(); >+ >+ const URL = get_host_info().HTTPS_REMOTE_ORIGIN + >+ '/service-workers/service-worker/resources/simple.txt?pipe=' + >+ 'header(access-control-allow-origin,*)|' + >+ 'header(access-control-expose-headers,*)|' + >+ 'header(foo,bar)|' + >+ 'header(set-cookie,X)'; >+ >+ const reg = await service_worker_unregister_and_register(t, SCRIPT, SCOPE); >+ await wait_for_state(t, reg.installing, 'activated'); >+ const frame = await with_iframe(SCOPE); >+ >+ const response = await frame.contentWindow.fetch(URL); >+ const headers = response.headers; >+ assert_equals(headers.get('foo'), 'bar'); >+ assert_equals(headers.get('set-cookie'), null); >+ assert_equals(headers.get('access-control-expose-headers'), '*'); >+ }, 'CORS-exposed header names for a response from sw'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-history-backward-navigation-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-history-backward-navigation-manual.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..3cf5922f396afe4fa4a4787917fe0ab3faa36f0d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-history-backward-navigation-manual.https.html >@@ -0,0 +1,8 @@ >+<!DOCTYPE html> >+<body> >+<p>Click <a href="resources/install-worker.html?isHistoryNavigation&script=fetch-event-test-worker.js">this link</a>. >+ Once you see "method = GET,..." in the page, go to another page, and then go back to the page using the Backward button. >+ You should see "method = GET, isHistoryNavigation = true". >+</p> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-history-forward-navigation-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-history-forward-navigation-manual.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..401939b3cb2d919a15ffd16d38cc3e0c866b43e9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-history-forward-navigation-manual.https.html >@@ -0,0 +1,8 @@ >+<!DOCTYPE html> >+<body> >+<p>Click <a href="resources/install-worker.html?isHistoryNavigation&script=fetch-event-test-worker.js">this link</a>. >+ Once you see "method = GET,..." in the page, go back to this page using the Backward button, and then go to the second page using the Forward button. >+ You should see "method = GET, isHistoryNavigation = true". >+</p> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-reload-iframe-navigation-manual.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-reload-iframe-navigation-manual.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..656dfb72a219500b025cf6f5bac59a8de4049560 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-reload-iframe-navigation-manual.https-expected.txt >@@ -0,0 +1,4 @@ >+ >+ >+FAIL FetchEvent#request.isReloadNavigation is true for manual reload. assert_equals: expected "method = GET, isReloadNavigation = false" but got "method = GET, isReloadNavigation = undefined" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-reload-iframe-navigation-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-reload-iframe-navigation-manual.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..cf1feccf6e4412e12f22a7ce1ebe55a54ba748f1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-reload-iframe-navigation-manual.https.html >@@ -0,0 +1,31 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/get-host-info.sub.js"></script> >+<script src="resources/test-helpers.sub.js"></script> >+<body> >+<script> >+const worker = 'resources/fetch-event-test-worker.js'; >+ >+promise_test(async (t) => { >+ const scope = 'resources/simple.html?isReloadNavigation'; >+ >+ const reg = await service_worker_unregister_and_register(t, worker, scope); >+ await wait_for_state(t, reg.installing, 'activated'); >+ const frame = await with_iframe(scope); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isReloadNavigation = false'); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentDocument.body.innerText = >+ 'Reload this frame manually!'; >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isReloadNavigation = true'); >+ frame.remove(); >+ await reg.unregister(); >+}, 'FetchEvent#request.isReloadNavigation is true for manual reload.'); >+ >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-reload-navigation-manual.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-reload-navigation-manual.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..a349f07c36c226e77323abda05eefec25fc3b21d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-reload-navigation-manual.https.html >@@ -0,0 +1,8 @@ >+<!DOCTYPE html> >+<body> >+<p>Click <a href="resources/install-worker.html?isReloadNavigation&script=fetch-event-test-worker.js">this link</a>. >+ Once you see "method = GET,..." in the page, reload the page. >+ You will see "method = GET, isReloadNavigation = true". >+</p> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-redirect.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-redirect.https-expected.txt >index a97cea3047151683b77cdc5ddce3b6c80f077920..dc8e5b51f76e4e6dc3f5a94fe323344077fc860a 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-redirect.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-redirect.https-expected.txt >@@ -1,9 +1,39 @@ >+CONSOLE MESSAGE: line 55: No-Cors mode requires follow redirect mode >+CONSOLE MESSAGE: line 55: Not allowed to request resource >+CONSOLE MESSAGE: line 55: Fetch API cannot load https://localhost:9443/nonav-manual-nocors-redirects-to-sameorigin-nocreds?url=redirect.py%3FRedirect%3Dhttps%253A%252F%252Flocalhost%253A9443%252Fservice-workers%252Fservice-worker%252Fresources%252Fsuccess.py&expected_type=opaqueredirect due to access control checks. >+CONSOLE MESSAGE: line 55: No-Cors mode requires follow redirect mode >+CONSOLE MESSAGE: line 55: Not allowed to request resource >+CONSOLE MESSAGE: line 55: Fetch API cannot load https://localhost:9443/nonav-manual-nocors-redirects-to-nocors-nocreds?url=redirect.py%3FRedirect%3Dhttps%253A%252F%252F127.0.0.1%253A9443%252Fservice-workers%252Fservice-worker%252Fresources%252Fsuccess.py&expected_type=opaqueredirect due to access control checks. >+CONSOLE MESSAGE: line 55: No-Cors mode requires follow redirect mode >+CONSOLE MESSAGE: line 55: Not allowed to request resource >+CONSOLE MESSAGE: line 55: Fetch API cannot load https://localhost:9443/nonav-manual-nocors-redirects-to-cors-nocreds?url=redirect.py%3FRedirect%3Dhttps%253A%252F%252F127.0.0.1%253A9443%252Fservice-workers%252Fservice-worker%252Fresources%252Fsuccess.py%253FACAOrigin%253Dhttps%25253A%25252F%25252Flocalhost%25253A9443&expected_type=opaqueredirect due to access control checks. >+CONSOLE MESSAGE: line 55: No-Cors mode requires follow redirect mode >+CONSOLE MESSAGE: line 55: Not allowed to request resource >+CONSOLE MESSAGE: line 55: Fetch API cannot load https://localhost:9443/nonav-manual-nocors-redirects-to-sameorigin-creds?url=redirect.py%3FRedirect%3Dhttps%253A%252F%252Ffoo%253Abar%2540localhost%253A9443%252Fservice-workers%252Fservice-worker%252Fresources%252Fsuccess.py&expected_type=opaqueredirect due to access control checks. >+CONSOLE MESSAGE: line 55: No-Cors mode requires follow redirect mode >+CONSOLE MESSAGE: line 55: Not allowed to request resource >+CONSOLE MESSAGE: line 55: Fetch API cannot load https://localhost:9443/nonav-manual-nocors-redirects-to-nocors-creds?url=redirect.py%3FRedirect%3Dhttps%253A%252F%252Ffoo%253Abar%2540127.0.0.1%253A9443%252Fservice-workers%252Fservice-worker%252Fresources%252Fsuccess.py&expected_type=opaqueredirect due to access control checks. >+CONSOLE MESSAGE: line 55: No-Cors mode requires follow redirect mode >+CONSOLE MESSAGE: line 55: Not allowed to request resource >+CONSOLE MESSAGE: line 55: Fetch API cannot load https://localhost:9443/nonav-manual-nocors-redirects-to-cors-creds?url=redirect.py%3FRedirect%3Dhttps%253A%252F%252Ffoo%253Abar%2540127.0.0.1%253A9443%252Fservice-workers%252Fservice-worker%252Fresources%252Fsuccess.py%253FACAOrigin%253Dhttps%25253A%25252F%25252Flocalhost%25253A9443&expected_type=opaqueredirect due to access control checks. > CONSOLE MESSAGE: line 51: No-Cors mode requires follow redirect mode > CONSOLE MESSAGE: line 51: Not allowed to request resource >-CONSOLE MESSAGE: line 51: Fetch API cannot load https://localhost:9443/nonav-manual-nocors-redirects-to-sameorigin-nocreds?url=redirect.py%3FRedirect%3Dhttps%253A%252F%252Flocalhost%253A9443%252Fservice-workers%252Fservice-worker%252Fresources%252Fsuccess.py&expected_type=opaqueredirect due to access control checks. >+CONSOLE MESSAGE: line 51: Fetch API cannot load https://localhost:9443/nonav-error-nocors-redirects-to-sameorigin-nocreds?url=redirect.py%3FRedirect%3Dhttps%253A%252F%252Flocalhost%253A9443%252Fservice-workers%252Fservice-worker%252Fresources%252Fsuccess.py due to access control checks. > CONSOLE MESSAGE: line 51: No-Cors mode requires follow redirect mode > CONSOLE MESSAGE: line 51: Not allowed to request resource >-CONSOLE MESSAGE: line 51: Fetch API cannot load https://localhost:9443/nonav-error-nocors-redirects-to-sameorigin-nocreds?url=redirect.py%3FRedirect%3Dhttps%253A%252F%252Flocalhost%253A9443%252Fservice-workers%252Fservice-worker%252Fresources%252Fsuccess.py due to access control checks. >+CONSOLE MESSAGE: line 51: Fetch API cannot load https://localhost:9443/nonav-error-nocors-redirects-to-nocors-nocreds?url=redirect.py%3FRedirect%3Dhttps%253A%252F%252F127.0.0.1%253A9443%252Fservice-workers%252Fservice-worker%252Fresources%252Fsuccess.py due to access control checks. >+CONSOLE MESSAGE: line 51: No-Cors mode requires follow redirect mode >+CONSOLE MESSAGE: line 51: Not allowed to request resource >+CONSOLE MESSAGE: line 51: Fetch API cannot load https://localhost:9443/nonav-error-nocors-redirects-to-cors-nocreds?url=redirect.py%3FRedirect%3Dhttps%253A%252F%252F127.0.0.1%253A9443%252Fservice-workers%252Fservice-worker%252Fresources%252Fsuccess.py%253FACAOrigin%253Dhttps%25253A%25252F%25252Flocalhost%25253A9443 due to access control checks. >+CONSOLE MESSAGE: line 51: No-Cors mode requires follow redirect mode >+CONSOLE MESSAGE: line 51: Not allowed to request resource >+CONSOLE MESSAGE: line 51: Fetch API cannot load https://localhost:9443/nonav-error-nocors-redirects-to-sameorigin-creds?url=redirect.py%3FRedirect%3Dhttps%253A%252F%252Ffoo%253Abar%2540localhost%253A9443%252Fservice-workers%252Fservice-worker%252Fresources%252Fsuccess.py due to access control checks. >+CONSOLE MESSAGE: line 51: No-Cors mode requires follow redirect mode >+CONSOLE MESSAGE: line 51: Not allowed to request resource >+CONSOLE MESSAGE: line 51: Fetch API cannot load https://localhost:9443/nonav-error-nocors-redirects-to-nocors-creds?url=redirect.py%3FRedirect%3Dhttps%253A%252F%252Ffoo%253Abar%2540127.0.0.1%253A9443%252Fservice-workers%252Fservice-worker%252Fresources%252Fsuccess.py due to access control checks. >+CONSOLE MESSAGE: line 51: No-Cors mode requires follow redirect mode >+CONSOLE MESSAGE: line 51: Not allowed to request resource >+CONSOLE MESSAGE: line 51: Fetch API cannot load https://localhost:9443/nonav-error-nocors-redirects-to-cors-creds?url=redirect.py%3FRedirect%3Dhttps%253A%252F%252Ffoo%253Abar%2540127.0.0.1%253A9443%252Fservice-workers%252Fservice-worker%252Fresources%252Fsuccess.py%253FACAOrigin%253Dhttps%25253A%25252F%25252Flocalhost%25253A9443 due to access control checks. > > PASS initialize global state > PASS Non-navigation, manual redirect, cors mode Request redirected to same-origin without credentials should succeed opaqueredirect interception and response should not be redirected >@@ -12,13 +42,18 @@ PASS Non-navigation, manual redirect, cors mode Request redirected to cors witho > PASS Non-navigation, manual redirect, same-origin mode Request redirected to same-origin without credentials should succeed opaqueredirect interception and response should not be redirected > PASS Non-navigation, manual redirect, same-origin mode Request redirected to no-cors without credentials should succeed opaqueredirect interception and response should not be redirected > PASS Non-navigation, manual redirect, same-origin mode Request redirected to cors without credentials should succeed opaqueredirect interception and response should not be redirected >-PASS Non-navigation, manual redirect, no-cors mode Request should fail >+FAIL Non-navigation, manual redirect, no-cors mode Request redirected to same-origin without credentials should succeed opaqueredirect interception and response should not be redirected promise_test: Unhandled rejection with value: object "TypeError: Not allowed to request resource" >+FAIL Non-navigation, manual redirect, no-cors mode Request redirected to no-cors without credentials should succeed opaqueredirect interception and response should not be redirected promise_test: Unhandled rejection with value: object "TypeError: Not allowed to request resource" >+FAIL Non-navigation, manual redirect, no-cors mode Request redirected to cors without credentials should succeed opaqueredirect interception and response should not be redirected promise_test: Unhandled rejection with value: object "TypeError: Not allowed to request resource" > PASS Non-navigation, manual redirect, cors mode Request redirected to same-origin with credentials should succeed opaqueredirect interception and response should not be redirected > PASS Non-navigation, manual redirect, cors mode Request redirected to no-cors with credentials should succeed opaqueredirect interception and response should not be redirected > PASS Non-navigation, manual redirect, cors mode Request redirected to cors with credentials should succeed opaqueredirect interception and response should not be redirected > PASS Non-navigation, manual redirect, same-origin mode Request redirected to same-origin with credentials should succeed opaqueredirect interception and response should not be redirected > PASS Non-navigation, manual redirect, same-origin mode Request redirected to no-cors with credentials should succeed opaqueredirect interception and response should not be redirected > PASS Non-navigation, manual redirect, same-origin mode Request redirected to cors with credentials should succeed opaqueredirect interception and response should not be redirected >+FAIL Non-navigation, manual redirect, no-cors mode Request redirected to same-origin with credentials should succeed opaqueredirect interception and response should not be redirected promise_test: Unhandled rejection with value: object "TypeError: Not allowed to request resource" >+FAIL Non-navigation, manual redirect, no-cors mode Request redirected to no-cors with credentials should succeed opaqueredirect interception and response should not be redirected promise_test: Unhandled rejection with value: object "TypeError: Not allowed to request resource" >+FAIL Non-navigation, manual redirect, no-cors mode Request redirected to cors with credentials should succeed opaqueredirect interception and response should not be redirected promise_test: Unhandled rejection with value: object "TypeError: Not allowed to request resource" > PASS Non-navigation, follow redirect, cors mode Request redirected to same-origin without credentials should succeed interception and response should be redirected > PASS Non-navigation, follow redirect, cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected > PASS Non-navigation, follow redirect, cors mode Request redirected to cors without credentials should succeed interception and response should be redirected >@@ -43,12 +78,17 @@ PASS Non-navigation, error redirect, cors mode Request redirected to cors withou > PASS Non-navigation, error redirect, same-origin mode Request redirected to same-origin without credentials should fail interception and response should not be redirected > PASS Non-navigation, error redirect, same-origin mode Request redirected to no-cors without credentials should fail interception and response should not be redirected > PASS Non-navigation, error redirect, same-origin mode Request redirected to cors without credentials should fail interception and response should not be redirected >-PASS Non-navigation, error redirect, no-cors mode Request should fail >+PASS Non-navigation, error redirect, no-cors mode Request redirected to same-origin without credentials should fail interception and response should not be redirected >+PASS Non-navigation, error redirect, no-cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected >+PASS Non-navigation, error redirect, no-cors mode Request redirected to cors without credentials should fail interception and response should not be redirected > PASS Non-navigation, error redirect, cors mode Request redirected to same-origin with credentials should fail interception and response should not be redirected > PASS Non-navigation, error redirect, cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected > PASS Non-navigation, error redirect, cors mode Request redirected to cors with credentials should fail interception and response should not be redirected > PASS Non-navigation, error redirect, same-origin mode Request redirected to same-origin with credentials should fail interception and response should not be redirected > PASS Non-navigation, error redirect, same-origin mode Request redirected to no-cors with credentials should fail interception and response should not be redirected > PASS Non-navigation, error redirect, same-origin mode Request redirected to cors with credentials should fail interception and response should not be redirected >+PASS Non-navigation, error redirect, no-cors mode Request redirected to same-origin with credentials should fail interception and response should not be redirected >+PASS Non-navigation, error redirect, no-cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected >+PASS Non-navigation, error redirect, no-cors mode Request redirected to cors with credentials should fail interception and response should not be redirected > PASS restore global state > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-redirect.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-redirect.https.html >index f348ca0c0d70870047cc8b3fe364fb931cb43981..c42d7f75be1e1f5a427cd62d1f3774527f99ef8d 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-redirect.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-redirect.https.html >@@ -212,9 +212,53 @@ promise_test(function(t) { > redirect: 'manual', > mode: 'no-cors' > }, >- should_reject: true >+ should_reject: false >+ }); >+}, 'Non-navigation, manual redirect, no-cors mode Request redirected to ' + >+ 'same-origin without credentials should succeed opaqueredirect interception ' + >+ 'and response should not be redirected'); >+ >+promise_test(function(t) { >+ return redirect_fetch_test(t, { >+ name: 'nonav-manual-nocors-redirects-to-nocors-nocreds', >+ redirect_dest: 'no-cors', >+ url_credentials: false, >+ expected_type: 'opaqueredirect', >+ expected_redirected: false, >+ request_init: { >+ redirect: 'manual', >+ mode: 'no-cors' >+ }, >+ // This should succeed because its redirecting from same-origin to >+ // cross-origin. Since the same-origin URL provides the location >+ // header the manual redirect mode should result in an opaqueredirect >+ // response. >+ should_reject: false > }); >-}, 'Non-navigation, manual redirect, no-cors mode Request should fail'); >+}, 'Non-navigation, manual redirect, no-cors mode Request redirected to ' + >+ 'no-cors without credentials should succeed opaqueredirect interception ' + >+ 'and response should not be redirected'); >+ >+promise_test(function(t) { >+ return redirect_fetch_test(t, { >+ name: 'nonav-manual-nocors-redirects-to-cors-nocreds', >+ redirect_dest: 'cors', >+ url_credentials: false, >+ expected_type: 'opaqueredirect', >+ expected_redirected: false, >+ request_init: { >+ redirect: 'manual', >+ mode: 'no-cors' >+ }, >+ // This should succeed because its redirecting from same-origin to >+ // cross-origin. Since the same-origin URL provides the location >+ // header the manual redirect mode should result in an opaqueredirect >+ // response. >+ should_reject: false >+ }); >+}, 'Non-navigation, manual redirect, no-cors mode Request redirected to ' + >+ 'cors without credentials should succeed opaqueredirect interception ' + >+ 'and response should not be redirected'); > > promise_test(function(t) { > return redirect_fetch_test(t, { >@@ -318,6 +362,65 @@ promise_test(function(t) { > 'cors with credentials should succeed opaqueredirect interception ' + > 'and response should not be redirected'); > >+promise_test(function(t) { >+ return redirect_fetch_test(t, { >+ name: 'nonav-manual-nocors-redirects-to-sameorigin-creds', >+ redirect_dest: 'same-origin', >+ url_credentials: true, >+ expected_type: 'opaqueredirect', >+ expected_redirected: false, >+ request_init: { >+ redirect: 'manual', >+ mode: 'no-cors' >+ }, >+ should_reject: false >+ }); >+}, 'Non-navigation, manual redirect, no-cors mode Request redirected to ' + >+ 'same-origin with credentials should succeed opaqueredirect interception ' + >+ 'and response should not be redirected'); >+ >+promise_test(function(t) { >+ return redirect_fetch_test(t, { >+ name: 'nonav-manual-nocors-redirects-to-nocors-creds', >+ redirect_dest: 'no-cors', >+ url_credentials: true, >+ expected_type: 'opaqueredirect', >+ expected_redirected: false, >+ request_init: { >+ redirect: 'manual', >+ mode: 'no-cors' >+ }, >+ // This should succeed because its redirecting from same-origin to >+ // cross-origin. Since the same-origin URL provides the location >+ // header the manual redirect mode should result in an opaqueredirect >+ // response. >+ should_reject: false >+ }); >+}, 'Non-navigation, manual redirect, no-cors mode Request redirected to ' + >+ 'no-cors with credentials should succeed opaqueredirect interception ' + >+ 'and response should not be redirected'); >+ >+promise_test(function(t) { >+ return redirect_fetch_test(t, { >+ name: 'nonav-manual-nocors-redirects-to-cors-creds', >+ redirect_dest: 'cors', >+ url_credentials: true, >+ expected_type: 'opaqueredirect', >+ expected_redirected: false, >+ request_init: { >+ redirect: 'manual', >+ mode: 'no-cors' >+ }, >+ // This should succeed because its redirecting from same-origin to >+ // cross-origin. Since the same-origin URL provides the location >+ // header the manual redirect mode should result in an opaqueredirect >+ // response. >+ should_reject: false >+ }); >+}, 'Non-navigation, manual redirect, no-cors mode Request redirected to ' + >+ 'cors with credentials should succeed opaqueredirect interception ' + >+ 'and response should not be redirected'); >+ > promise_test(function(t) { > return redirect_fetch_test(t, { > name: 'nonav-follow-cors-redirects-to-sameorigin-nocreds', >@@ -736,10 +839,47 @@ promise_test(function(t) { > redirect: 'error', > mode: 'no-cors' > }, >- // should reject because error + no-cors is not allowed. >+ // should reject because requests with 'error' RequestRedirect cannot be >+ // redirected. >+ should_reject: true >+ }); >+}, 'Non-navigation, error redirect, no-cors mode Request redirected to ' + >+ 'same-origin without credentials should fail interception ' + >+ 'and response should not be redirected'); >+ >+promise_test(function(t) { >+ return redirect_fetch_test(t, { >+ name: 'nonav-error-nocors-redirects-to-nocors-nocreds', >+ redirect_dest: 'no-cors', >+ url_credentials: false, >+ request_init: { >+ redirect: 'error', >+ mode: 'no-cors' >+ }, >+ // should reject because requests with 'error' RequestRedirect cannot be >+ // redirected. > should_reject: true > }); >-}, 'Non-navigation, error redirect, no-cors mode Request should fail'); >+}, 'Non-navigation, error redirect, no-cors mode Request redirected to ' + >+ 'no-cors without credentials should fail interception ' + >+ 'and response should not be redirected'); >+ >+promise_test(function(t) { >+ return redirect_fetch_test(t, { >+ name: 'nonav-error-nocors-redirects-to-cors-nocreds', >+ redirect_dest: 'cors', >+ url_credentials: false, >+ request_init: { >+ redirect: 'error', >+ mode: 'no-cors' >+ }, >+ // should reject because requests with 'error' RequestRedirect cannot be >+ // redirected. >+ should_reject: true >+ }); >+}, 'Non-navigation, error redirect, no-cors mode Request redirected to ' + >+ 'cors without credentials should fail interception ' + >+ 'and response should not be redirected'); > > promise_test(function(t) { > return redirect_fetch_test(t, { >@@ -842,5 +982,56 @@ promise_test(function(t) { > }, 'Non-navigation, error redirect, same-origin mode Request redirected to ' + > 'cors with credentials should fail interception ' + > 'and response should not be redirected'); >+ >+promise_test(function(t) { >+ return redirect_fetch_test(t, { >+ name: 'nonav-error-nocors-redirects-to-sameorigin-creds', >+ redirect_dest: 'same-origin', >+ url_credentials: true, >+ request_init: { >+ redirect: 'error', >+ mode: 'no-cors' >+ }, >+ // should reject because requests with 'error' RequestRedirect cannot be >+ // redirected. >+ should_reject: true >+ }); >+}, 'Non-navigation, error redirect, no-cors mode Request redirected to ' + >+ 'same-origin with credentials should fail interception ' + >+ 'and response should not be redirected'); >+ >+promise_test(function(t) { >+ return redirect_fetch_test(t, { >+ name: 'nonav-error-nocors-redirects-to-nocors-creds', >+ redirect_dest: 'no-cors', >+ url_credentials: true, >+ request_init: { >+ redirect: 'error', >+ mode: 'no-cors' >+ }, >+ // should reject because requests with 'error' RequestRedirect cannot be >+ // redirected. >+ should_reject: true >+ }); >+}, 'Non-navigation, error redirect, no-cors mode Request redirected to ' + >+ 'no-cors with credentials should fail interception ' + >+ 'and response should not be redirected'); >+ >+promise_test(function(t) { >+ return redirect_fetch_test(t, { >+ name: 'nonav-error-nocors-redirects-to-cors-creds', >+ redirect_dest: 'cors', >+ url_credentials: true, >+ request_init: { >+ redirect: 'error', >+ mode: 'no-cors' >+ }, >+ // should reject because requests with 'error' RequestRedirect cannot be >+ // redirected. >+ should_reject: true >+ }); >+}, 'Non-navigation, error redirect, no-cors mode Request redirected to ' + >+ 'cors with credentials should fail interception and response should not ' + >+ 'be redirected'); > </script> > </body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-referrer-policy.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-referrer-policy.https-expected.txt >index c33b7d9b2c37dfbf4285233ba72a28c8e27c39e5..af4d1f5d90c275377be4d252746b623b671df59b 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-referrer-policy.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-referrer-policy.https-expected.txt >@@ -1,76 +1,8 @@ >-CONSOLE MESSAGE: line 32: The page at https://localhost:9443/service-workers/service-worker/fetch-event-referrer-policy.https.html was allowed to display insecure content from http://localhost:8800/service-workers/service-worker//resources/simple.html?referrerFull. >+CONSOLE MESSAGE: line 22: [blocked] The page at https://localhost:9443/service-workers/service-worker/fetch-event-referrer-policy.https.html was not allowed to display insecure content from http://localhost:8800/service-workers/service-worker//resources/simple.html?referrerFull. > >-CONSOLE MESSAGE: line 54: The page at https://localhost:9443/service-workers/service-worker/fetch-event-referrer-policy.https.html was allowed to display insecure content from http://localhost:8800/service-workers/service-worker//resources/simple.html?referrerFull. >+CONSOLE MESSAGE: line 22: Not allowed to request resource >+CONSOLE MESSAGE: line 22: Fetch API cannot load http://localhost:8800/service-workers/service-worker//resources/simple.html?referrerFull due to access control checks. > >-CONSOLE MESSAGE: line 76: The page at https://localhost:9443/service-workers/service-worker/fetch-event-referrer-policy.https.html was allowed to display insecure content from http://localhost:8800/service-workers/service-worker//resources/simple.html?referrerFull. > >-CONSOLE MESSAGE: line 98: The page at https://localhost:9443/service-workers/service-worker/fetch-event-referrer-policy.https.html was allowed to display insecure content from http://localhost:8800/service-workers/service-worker//resources/simple.html?referrerFull. >- >-CONSOLE MESSAGE: line 120: The page at https://localhost:9443/service-workers/service-worker/fetch-event-referrer-policy.https.html was allowed to display insecure content from http://localhost:8800/service-workers/service-worker//resources/simple.html?referrerFull. >- >-CONSOLE MESSAGE: line 132: The page at https://localhost:9443/service-workers/service-worker/fetch-event-referrer-policy.https.html was allowed to display insecure content from http://localhost:8800/service-workers/service-worker//resources/simple.html?referrerFull. >- >-CONSOLE MESSAGE: line 197: The page at https://localhost:9443/service-workers/service-worker/fetch-event-referrer-policy.https.html was allowed to display insecure content from http://localhost:8800/service-workers/service-worker//resources/simple.html?referrerFull. >- >-CONSOLE MESSAGE: line 231: The page at https://localhost:9443/service-workers/service-worker/fetch-event-referrer-policy.https.html was allowed to display insecure content from http://localhost:8800/service-workers/service-worker//resources/simple.html?referrerFull. >- >-CONSOLE MESSAGE: line 32: The page at https://localhost:9443/service-workers/service-worker/fetch-event-referrer-policy.https.html was allowed to display insecure content from http://localhost:8800/service-workers/service-worker//resources/simple.html?referrerFull. >- >-CONSOLE MESSAGE: line 54: The page at https://localhost:9443/service-workers/service-worker/fetch-event-referrer-policy.https.html was allowed to display insecure content from http://localhost:8800/service-workers/service-worker//resources/simple.html?referrerFull. >- >-CONSOLE MESSAGE: line 76: The page at https://localhost:9443/service-workers/service-worker/fetch-event-referrer-policy.https.html was allowed to display insecure content from http://localhost:8800/service-workers/service-worker//resources/simple.html?referrerFull. >- >-CONSOLE MESSAGE: line 98: The page at https://localhost:9443/service-workers/service-worker/fetch-event-referrer-policy.https.html was allowed to display insecure content from http://localhost:8800/service-workers/service-worker//resources/simple.html?referrerFull. >- >-CONSOLE MESSAGE: line 120: The page at https://localhost:9443/service-workers/service-worker/fetch-event-referrer-policy.https.html was allowed to display insecure content from http://localhost:8800/service-workers/service-worker//resources/simple.html?referrerFull. >- >-CONSOLE MESSAGE: line 132: The page at https://localhost:9443/service-workers/service-worker/fetch-event-referrer-policy.https.html was allowed to display insecure content from http://localhost:8800/service-workers/service-worker//resources/simple.html?referrerFull. >- >-CONSOLE MESSAGE: line 197: The page at https://localhost:9443/service-workers/service-worker/fetch-event-referrer-policy.https.html was allowed to display insecure content from http://localhost:8800/service-workers/service-worker//resources/simple.html?referrerFull. >- >-CONSOLE MESSAGE: line 231: The page at https://localhost:9443/service-workers/service-worker/fetch-event-referrer-policy.https.html was allowed to display insecure content from http://localhost:8800/service-workers/service-worker//resources/simple.html?referrerFull. >- >- >-PASS Service Worker responds to fetch event with the referrer policy >-PASS Service Worker should respond to fetch with the default referrer policy >-PASS Service Worker should respond to fetch with the referrer URL when a member of RequestInit is present - Default Referrer >-PASS Service Worker should respond to fetch with no referrer when a member of RequestInit is present with an HTTP request - Default Referrer >-PASS Service Worker should respond to fetch with the referrer with "" - Default Referrer >-PASS Service Worker should respond to fetch with no referrer with "" - Default Referrer >-PASS Service Worker should respond to fetch with the referrer origin with "origin" and a same origin request - Default Referrer >-PASS Service Worker should respond to fetch with the referrer origin with "origin" and a cross origin request - Default Referrer >-PASS Service Worker should respond to fetch with the referrer URL with "origin-when-cross-origin" and a same origin request - Default Referrer >-PASS Service Worker should respond to fetch with the referrer origin with "origin-when-cross-origin" and a cross origin request - Default Referrer >-PASS Service Worker should respond to fetch with no referrer with "no-referrer-when-downgrade" and a same origin request - Default Referrer >-PASS Service Worker should respond to fetch with no referrer with "no-referrer-when-downgrade" and an HTTP request - Default Referrer >-PASS Service Worker should respond to fetch with no referrer with "unsafe-url" - Default Referrer >-PASS Service Worker should respond to fetch with no referrer URL with "no-referrer" - Default Referrer >-PASS Service Worker should respond to fetch with referrer URL with "same-origin" and a same origin request - Default Referrer >-PASS Service Worker should respond to fetch with no referrer with "same-origin" and cross origin request - Default Referrer >-PASS Service Worker should respond to fetch with the referrer origin with "strict-origin" and a HTTPS cross origin request - Default Referrer >-PASS Service Worker should respond to fetch with the referrer origin with "strict-origin" and a same origin request - Default Referrer >-PASS Service Worker should respond to fetch with no referrer with "strict-origin" and a HTTP request - Default Referrer >-PASS Service Worker should respond to fetch with the referrer URL with "strict-origin-when-cross-origin" and a same origin request - Default Referrer >-PASS Service Worker should respond to fetch with the referrer origin with "strict-origin-when-cross-origin" and a HTTPS cross origin request - Default Referrer >-PASS Service Worker should respond to fetch with no referrer with "strict-origin-when-cross-origin" and a HTTP request - Default Referrer >-PASS Service Worker should respond to fetch with the referrer URL when a member of RequestInit is present - Custom Referrer >-PASS Service Worker should respond to fetch with no referrer when a member of RequestInit is present with an HTTP request - Custom Referrer >-PASS Service Worker should respond to fetch with the referrer with "" - Custom Referrer >-PASS Service Worker should respond to fetch with no referrer with "" - Custom Referrer >-PASS Service Worker should respond to fetch with the referrer origin with "origin" and a same origin request - Custom Referrer >-PASS Service Worker should respond to fetch with the referrer origin with "origin" and a cross origin request - Custom Referrer >-PASS Service Worker should respond to fetch with the referrer URL with "origin-when-cross-origin" and a same origin request - Custom Referrer >-PASS Service Worker should respond to fetch with the referrer origin with "origin-when-cross-origin" and a cross origin request - Custom Referrer >-PASS Service Worker should respond to fetch with no referrer with "no-referrer-when-downgrade" and a same origin request - Custom Referrer >-PASS Service Worker should respond to fetch with no referrer with "no-referrer-when-downgrade" and an HTTP request - Custom Referrer >-PASS Service Worker should respond to fetch with no referrer with "unsafe-url" - Custom Referrer >-PASS Service Worker should respond to fetch with no referrer URL with "no-referrer" - Custom Referrer >-PASS Service Worker should respond to fetch with referrer URL with "same-origin" and a same origin request - Custom Referrer >-PASS Service Worker should respond to fetch with no referrer with "same-origin" and cross origin request - Custom Referrer >-PASS Service Worker should respond to fetch with the referrer origin with "strict-origin" and a HTTPS cross origin request - Custom Referrer >-PASS Service Worker should respond to fetch with the referrer origin with "strict-origin" and a same origin request - Custom Referrer >-PASS Service Worker should respond to fetch with no referrer with "strict-origin" and a HTTP request - Custom Referrer >-PASS Service Worker should respond to fetch with the referrer URL with "strict-origin-when-cross-origin" and a same origin request - Custom Referrer >-PASS Service Worker should respond to fetch with the referrer origin with "strict-origin-when-cross-origin" and a HTTPS cross origin request - Custom Referrer >-PASS Service Worker should respond to fetch with no referrer with "strict-origin-when-cross-origin" and a HTTP request - Custom Referrer >+FAIL Service Worker responds to fetch event with the referrer policy assert_unreached: unexpected rejection: Not allowed to request resource Reached unreachable code > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-referrer-policy.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-referrer-policy.https.html >index 15d4ed5f84c48b371c67cdcb9451ae95a1ee89dd..9b67faccac8baff81bbffd95e3c335d02ccdf216 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-referrer-policy.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-referrer-policy.https.html >@@ -7,22 +7,12 @@ > <script> > var worker = 'resources/fetch-event-test-worker.js'; > >-if (window.internals && window.internals.settings) >- internals.settings.setAllowDisplayOfInsecureContent(true); >- >-function do_test(referrer, value, expected, name) >-{ >- test(() => { >- assert_equals(value, expected); >- }, name + (referrer ? " - Custom Referrer" : " - Default Referrer")); >-} >- > function run_referrer_policy_tests(frame, referrer, href, origin) { > return frame.contentWindow.fetch('resources/simple.html?referrerFull', > {method: "GET", referrer: referrer}) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: ' + href + '\n' + > 'ReferrerPolicy: no-referrer-when-downgrade', >@@ -34,7 +24,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: \n' + > 'ReferrerPolicy: no-referrer-when-downgrade', >@@ -44,7 +34,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: ' + href + '\n' + > 'ReferrerPolicy: no-referrer-when-downgrade', >@@ -56,7 +46,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: \n' + > 'ReferrerPolicy: no-referrer-when-downgrade', >@@ -66,7 +56,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: ' + origin + '/' + '\n' + > 'ReferrerPolicy: origin', >@@ -78,7 +68,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: ' + origin + '/' + '\n' + > 'ReferrerPolicy: origin', >@@ -88,7 +78,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: ' + href + '\n' + > 'ReferrerPolicy: origin-when-cross-origin', >@@ -100,7 +90,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: ' + origin + '/' + '\n' + > 'ReferrerPolicy: origin-when-cross-origin', >@@ -110,7 +100,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: ' + href + '\n' + > 'ReferrerPolicy: no-referrer-when-downgrade', >@@ -122,7 +112,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: \n' + > 'ReferrerPolicy: no-referrer-when-downgrade', >@@ -133,7 +123,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: ' + href + '\n' + > 'ReferrerPolicy: unsafe-url', >@@ -143,7 +133,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: \n' + > 'ReferrerPolicy: no-referrer', >@@ -153,7 +143,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: ' + href + '\n' + > 'ReferrerPolicy: same-origin', >@@ -165,7 +155,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: \n' + > 'ReferrerPolicy: same-origin', >@@ -177,7 +167,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: ' + origin + '/' + '\n' + > 'ReferrerPolicy: strict-origin', >@@ -187,7 +177,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: ' + origin + '/' + '\n' + > 'ReferrerPolicy: strict-origin', >@@ -199,7 +189,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: \n' + > 'ReferrerPolicy: strict-origin', >@@ -209,7 +199,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: ' + href + '\n' + > 'ReferrerPolicy: strict-origin-when-cross-origin', >@@ -221,7 +211,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: ' + origin + '/' + '\n' + > 'ReferrerPolicy: strict-origin-when-cross-origin', >@@ -233,7 +223,7 @@ function run_referrer_policy_tests(frame, referrer, href, origin) { > }) > .then(function(response) { return response.text(); }) > .then(function(response_text) { >- do_test(referrer, >+ assert_equals( > response_text, > 'Referrer: \n' + > 'ReferrerPolicy: strict-origin-when-cross-origin', >@@ -251,16 +241,17 @@ async_test(function(t) { > .then(function() { return with_iframe(scope); }) > .then(function(f) { > frame = f; >- test(() => { >- assert_equals(frame.contentDocument.body.textContent, 'ReferrerPolicy: no-referrer-when-downgrade'); >- }, 'Service Worker should respond to fetch with the default referrer policy'); >+ assert_equals( >+ frame.contentDocument.body.textContent, >+ 'ReferrerPolicy: no-referrer-when-downgrade', >+ 'Service Worker should respond to fetch with the default referrer policy'); > // First, run the referrer policy tests without passing a referrer in RequestInit. > return run_referrer_policy_tests(frame, undefined, frame.contentDocument.location.href, > frame.contentDocument.location.origin); > }) > .then(function() { > // Now, run the referrer policy tests while passing a referrer in RequestInit. >- var referrer = get_host_info()['HTTPS_ORIGIN'] + base_path() + 'resources/fake-referrer'; >+ var referrer = get_host_info()['HTTPS_ORIGIN'] + base_path() + 'fake-referrer'; > return run_referrer_policy_tests(frame, 'fake-referrer', referrer, > frame.contentDocument.location.origin); > }) >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-custom-response.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-custom-response.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..c332e3486694699d6ee6451297732e0807cd1408 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-custom-response.https-expected.txt >@@ -0,0 +1,13 @@ >+ >+PASS Subresource built from a string >+PASS Subresource built from a blob >+PASS Subresource built from a buffer >+PASS Subresource built from a buffer-view >+FAIL Subresource built from form-data promise_test: Unhandled rejection with value: object "NotSupportedError: The operation is not supported." >+PASS Subresource built from search-params >+PASS Navigation resource built from a string >+PASS Navigation resource built from a blob >+PASS Navigation resource built from a buffer >+PASS Navigation resource built from a buffer-view >+PASS Navigation resource built from search-params >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-custom-response.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-custom-response.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..645a29c9b4f146b8c4024650c358c8325663cbac >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-custom-response.https.html >@@ -0,0 +1,82 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>respondWith with a new Response</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/test-helpers.sub.js"></script> >+<script> >+'use strict'; >+ >+const WORKER = >+ 'resources/fetch-event-respond-with-custom-response-worker.js'; >+const SCOPE = >+ 'resources/blank.html'; >+ >+// Register a service worker, then create an iframe at url. >+function iframeTest(url, callback, name) { >+ return promise_test(async t => { >+ const reg = await service_worker_unregister_and_register(t, WORKER, SCOPE); >+ add_completion_callback(() => reg.unregister()); >+ await wait_for_state(t, reg.installing, 'activated'); >+ const iframe = await with_iframe(url); >+ const iwin = iframe.contentWindow; >+ t.add_cleanup(() => iframe.remove()); >+ await callback(t, iwin); >+ }, name); >+} >+ >+iframeTest(SCOPE, async (t, iwin) => { >+ const response = await iwin.fetch('?type=string'); >+ assert_equals(await response.text(), 'PASS'); >+}, 'Subresource built from a string'); >+ >+iframeTest(SCOPE, async (t, iwin) => { >+ const response = await iwin.fetch('?type=blob'); >+ assert_equals(await response.text(), 'PASS'); >+}, 'Subresource built from a blob'); >+ >+iframeTest(SCOPE, async (t, iwin) => { >+ const response = await iwin.fetch('?type=buffer'); >+ assert_equals(await response.text(), 'PASS'); >+}, 'Subresource built from a buffer'); >+ >+iframeTest(SCOPE, async (t, iwin) => { >+ const response = await iwin.fetch('?type=buffer-view'); >+ assert_equals(await response.text(), 'PASS'); >+}, 'Subresource built from a buffer-view'); >+ >+iframeTest(SCOPE, async (t, iwin) => { >+ const response = await iwin.fetch('?type=form-data'); >+ const data = await response.formData(); >+ assert_equals(data.get('result'), 'PASS'); >+}, 'Subresource built from form-data'); >+ >+iframeTest(SCOPE, async (t, iwin) => { >+ const response = await iwin.fetch('?type=search-params'); >+ assert_equals(await response.text(), 'result=PASS'); >+}, 'Subresource built from search-params'); >+ >+// As above, but navigations >+ >+iframeTest(SCOPE + '?type=string', (t, iwin) => { >+ assert_equals(iwin.document.body.textContent, 'PASS'); >+}, 'Navigation resource built from a string'); >+ >+iframeTest(SCOPE + '?type=blob', (t, iwin) => { >+ assert_equals(iwin.document.body.textContent, 'PASS'); >+}, 'Navigation resource built from a blob'); >+ >+iframeTest(SCOPE + '?type=buffer', (t, iwin) => { >+ assert_equals(iwin.document.body.textContent, 'PASS'); >+}, 'Navigation resource built from a buffer'); >+ >+iframeTest(SCOPE + '?type=buffer-view', (t, iwin) => { >+ assert_equals(iwin.document.body.textContent, 'PASS'); >+}, 'Navigation resource built from a buffer-view'); >+ >+// Note: not testing form data for a navigation as the boundary header is lost. >+ >+iframeTest(SCOPE + '?type=search-params', (t, iwin) => { >+ assert_equals(iwin.document.body.textContent, 'result=PASS'); >+}, 'Navigation resource built from search-params'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-readable-stream.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-readable-stream.https-expected.txt >index 08211f1e5ab2d667f663fa04a3eb07bb7a00f37d..ba745966fdf0ad188aa51d0eef02f769a19efe1d 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-readable-stream.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-readable-stream.https-expected.txt >@@ -1,3 +1,8 @@ > >-PASS Respond with a Response built from a ReadableStream >+PASS Subresource built from a ReadableStream >+PASS Main resource built from a ReadableStream >+PASS Subresource built from a ReadableStream - delayed >+PASS Main resource built from a ReadableStream - delayed >+PASS Subresource built from a ReadableStream - fetch stream >+PASS Main resource built from a ReadableStream - fetch stream > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-readable-stream.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-readable-stream.https.html >index 05afb6bc0fe11e9ebcf6c464c17ea1089f0dc846..75545adbc195e8af83a8634d7626b112d01cf009 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-readable-stream.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-readable-stream.https.html >@@ -10,22 +10,45 @@ > const WORKER = > 'resources/fetch-event-respond-with-readable-stream-worker.js'; > const SCOPE = >- 'resources/fetch-event-respond-with-readable-stream-iframe.html'; >-// Called by the iframe when done. >-var done; >-var done_was_called = new Promise(resolve => done = resolve); >- >-promise_test(t => { >- return service_worker_unregister_and_register(t, WORKER, SCOPE) >- .then(reg => { >- add_completion_callback(() => reg.unregister()); >- return wait_for_state(t, reg.installing, 'activated'); >- }) >- .then(() => with_iframe(SCOPE)) >- .then(iframe => { >- t.add_cleanup(() => iframe.remove()) >- }) >- .then(() => done_was_called) >- .then(result => assert_equals(result, 'PASS')); >- }, 'Respond with a Response built from a ReadableStream'); >+ 'resources/blank.html'; >+ >+// Register a service worker, then create an iframe at url. >+function iframeTest(url, callback, name) { >+ return promise_test(async t => { >+ const reg = await service_worker_unregister_and_register(t, WORKER, SCOPE); >+ add_completion_callback(() => reg.unregister()); >+ await wait_for_state(t, reg.installing, 'activated'); >+ const iframe = await with_iframe(url); >+ const iwin = iframe.contentWindow; >+ t.add_cleanup(() => iframe.remove()); >+ await callback(t, iwin); >+ }, name); >+} >+ >+iframeTest(SCOPE, async (t, iwin) => { >+ const response = await iwin.fetch('?stream'); >+ assert_equals(await response.text(), 'PASS'); >+}, 'Subresource built from a ReadableStream'); >+ >+iframeTest(SCOPE + '?stream', (t, iwin) => { >+ assert_equals(iwin.document.body.textContent, 'PASS'); >+}, 'Main resource built from a ReadableStream'); >+ >+iframeTest(SCOPE, async (t, iwin) => { >+ const response = await iwin.fetch('?stream&delay'); >+ assert_equals(await response.text(), 'PASS'); >+}, 'Subresource built from a ReadableStream - delayed'); >+ >+iframeTest(SCOPE + '?stream&delay', (t, iwin) => { >+ assert_equals(iwin.document.body.textContent, 'PASS'); >+}, 'Main resource built from a ReadableStream - delayed'); >+ >+iframeTest(SCOPE, async (t, iwin) => { >+ const response = await iwin.fetch('?stream&use-fetch-stream'); >+ assert_equals(await response.text(), 'PASS\n'); >+}, 'Subresource built from a ReadableStream - fetch stream'); >+ >+iframeTest(SCOPE + '?stream&use-fetch-stream', (t, iwin) => { >+ assert_equals(iwin.document.body.textContent, 'PASS\n'); >+}, 'Main resource built from a ReadableStream - fetch stream'); > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event.https-expected.txt >index de4173004522026b5dfb4286436755e0ff5d1478..8c0d9a42f1b7c61ab853f14198d74e3f06526211 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event.https-expected.txt >@@ -1,7 +1,8 @@ > >- >+PASS global setup > PASS Service Worker headers in the request of a fetch event > PASS Service Worker responds to fetch event with string >+PASS Service Worker responds to fetch event using request fragment with string > PASS Service Worker responds to fetch event with blob body > PASS Service Worker responds to fetch event with the referrer URL > PASS Service Worker responds to fetch event with an existing client id >@@ -9,13 +10,28 @@ PASS Service Worker does not respond to fetch event > PASS Service Worker responds to fetch event with null response body > PASS Service Worker fetches other file in fetch event > PASS Service Worker responds to fetch event with POST form >+PASS Service Worker falls back to network in fetch event with POST form > PASS Multiple calls of respondWith must throw InvalidStateErrors > PASS Service Worker event.respondWith must set the used flag > PASS Service Worker should expose FetchEvent URL fragments. >-FAIL Service Worker responds to fetch event with the correct cache types assert_unreached: unexpected rejection: assert_equals: expected "no-cache" but got "default" Reached unreachable code >+FAIL Service Worker responds to fetch event with the correct cache types assert_equals: expected "no-cache" but got "default" > PASS Service Worker should intercept EventSource > PASS Service Worker responds to fetch event with the correct integrity_metadata > PASS FetchEvent#body is a string >+PASS FetchEvent#body is a string and is passed to network fallback > PASS FetchEvent#body is a blob >+PASS FetchEvent#body is a blob and is passed to network fallback > PASS Service Worker responds to fetch event with the correct keepalive value >+FAIL FetchEvent#request.isReloadNavigation is true (location.reload()) assert_equals: expected "method = GET, isReloadNavigation = false" but got "method = GET, isReloadNavigation = undefined" >+FAIL FetchEvent#request.isReloadNavigation is true (history.go(0)) assert_equals: expected "method = GET, isReloadNavigation = false" but got "method = GET, isReloadNavigation = undefined" >+FAIL FetchEvent#request.isReloadNavigation is true (POST + location.reload()) assert_equals: expected "method = GET, isReloadNavigation = false" but got "method = GET, isReloadNavigation = undefined" >+FAIL FetchEvent#request.isReloadNavigation is true (with history traversal) assert_equals: expected "method = GET, isReloadNavigation = false" but got "method = GET, isReloadNavigation = undefined" >+FAIL FetchEvent#request.isHistoryNavigation is true (with history.go(-1)) assert_equals: expected "method = GET, isHistoryNavigation = false" but got "method = GET, isHistoryNavigation = undefined" >+FAIL FetchEvent#request.isHistoryNavigation is true (with history.go(1)) assert_equals: expected "method = GET, isHistoryNavigation = false" but got "method = GET, isHistoryNavigation = undefined" >+FAIL FetchEvent#request.isHistoryNavigation is false (with history.go(0)) assert_equals: expected "method = GET, isHistoryNavigation = false" but got "method = GET, isHistoryNavigation = undefined" >+FAIL FetchEvent#request.isHistoryNavigation is false (with location.reload) assert_equals: expected "method = GET, isHistoryNavigation = false" but got "method = GET, isHistoryNavigation = undefined" >+FAIL FetchEvent#request.isHistoryNavigation is true (with history.go(-2)) assert_equals: expected "method = GET, isHistoryNavigation = false" but got "method = GET, isHistoryNavigation = undefined" >+FAIL FetchEvent#request.isHistoryNavigation is true (with history.go(2)) assert_equals: expected "method = GET, isHistoryNavigation = false" but got "method = GET, isHistoryNavigation = undefined" >+FAIL FetchEvent#request.isHistoryNavigation is true (POST + history.go(-1)) assert_equals: expected "method = GET, isHistoryNavigation = false" but got "method = GET, isHistoryNavigation = undefined" >+PASS restore global state > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event.https.html >index 240219b082dc7f1ca1a8affa38c006a11e8b4f4b..ecb1c14223146e469ba95cbb8dcac7333c428576 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event.https.html >@@ -6,16 +6,25 @@ > <body> > <script> > var worker = 'resources/fetch-event-test-worker.js'; >+function wait(ms) { >+ return new Promise(resolve => step_timeout(resolve, ms)); >+} > >-async_test(function(t) { >- const scope = 'resources/simple.html?headers'; >- service_worker_unregister_and_register(t, worker, scope) >- .then(function(reg) { >- return wait_for_state(t, reg.installing, 'activated'); >- }) >- .then(function() { return with_iframe(scope); }) >+promise_test(async t => { >+ const scope = 'resources/'; >+ const registration = >+ await service_worker_unregister_and_register(t, worker, scope); >+ await wait_for_state(t, registration.installing, 'activated'); >+ promise_test(t => { >+ return registration.unregister(); >+ }, 'restore global state'); >+ }, 'global setup'); >+ >+promise_test(t => { >+ const page_url = 'resources/simple.html?headers'; >+ return with_iframe(page_url) > .then(function(frame) { >- t.add_cleanup(function() { frame.remove(); }); >+ t.add_cleanup(() => { frame.remove(); }); > const headers = JSON.parse(frame.contentDocument.body.textContent); > const header_names = {}; > for (const [name, value] of headers) { >@@ -26,20 +35,14 @@ async_test(function(t) { > header_names.hasOwnProperty('accept'), > 'request includes "Accept" header as inserted by Fetch' > ); >- >- return service_worker_unregister_and_done(t, scope); >- }) >- .catch(unreached_rejection(t)); >+ }); > }, 'Service Worker headers in the request of a fetch event'); > >-async_test(function(t) { >- var scope = 'resources/simple.html?string'; >- service_worker_unregister_and_register(t, worker, scope) >- .then(function(reg) { >- return wait_for_state(t, reg.installing, 'activated'); >- }) >- .then(function() { return with_iframe(scope); }) >+promise_test(t => { >+ const page_url = 'resources/simple.html?string'; >+ return with_iframe(page_url) > .then(function(frame) { >+ t.add_cleanup(() => { frame.remove(); }); > assert_equals( > frame.contentDocument.body.textContent, > 'Test string', >@@ -52,58 +55,58 @@ async_test(function(t) { > frame.contentDocument.characterSet, > 'UTF-8', > 'The character set of the response created with a string should be UTF-8'); >- frame.remove(); >- return service_worker_unregister_and_done(t, scope); >- }) >- .catch(unreached_rejection(t)); >+ }); > }, 'Service Worker responds to fetch event with string'); > >-async_test(function(t) { >- var scope = 'resources/simple.html?blob'; >- service_worker_unregister_and_register(t, worker, scope) >- .then(function(reg) { >- return wait_for_state(t, reg.installing, 'activated'); >- }) >- .then(function() { return with_iframe(scope); }) >- .then(function(frame) { >+promise_test(t => { >+ const page_url = 'resources/simple.html?string'; >+ var frame; >+ return with_iframe(page_url) >+ .then(function(f) { >+ frame = f; >+ t.add_cleanup(() => { frame.remove(); }); >+ return frame.contentWindow.fetch(page_url + "#foo") >+ }) >+ .then(function(response) { return response.text() }) >+ .then(function(text) { >+ assert_equals( >+ text, >+ 'Test string', >+ 'Service Worker should respond to fetch with a test string'); >+ }); >+ }, 'Service Worker responds to fetch event using request fragment with string'); >+ >+promise_test(t => { >+ const page_url = 'resources/simple.html?blob'; >+ return with_iframe(page_url) >+ .then(frame => { >+ t.add_cleanup(() => { frame.remove(); }); > assert_equals( > frame.contentDocument.body.textContent, > 'Test blob', > 'Service Worker should respond to fetch with a test string'); >- frame.remove(); >- return service_worker_unregister_and_done(t, scope); >- }) >- .catch(unreached_rejection(t)); >+ }); > }, 'Service Worker responds to fetch event with blob body'); > >-async_test(function(t) { >- var scope = 'resources/simple.html?referrer'; >- service_worker_unregister_and_register(t, worker, scope) >- .then(function(reg) { >- return wait_for_state(t, reg.installing, 'activated'); >- }) >- .then(function() { return with_iframe(scope); }) >- .then(function(frame) { >+promise_test(t => { >+ const page_url = 'resources/simple.html?referrer'; >+ return with_iframe(page_url) >+ .then(frame => { >+ t.add_cleanup(() => { frame.remove(); }); > assert_equals( > frame.contentDocument.body.textContent, > 'Referrer: ' + document.location.href, > 'Service Worker should respond to fetch with the referrer URL'); >- frame.remove(); >- return service_worker_unregister_and_done(t, scope); >- }) >- .catch(unreached_rejection(t)); >+ }); > }, 'Service Worker responds to fetch event with the referrer URL'); > >-async_test(function(t) { >- var scope = 'resources/simple.html?clientId'; >+promise_test(t => { >+ const page_url = 'resources/simple.html?clientId'; > var frame; >- service_worker_unregister_and_register(t, worker, scope) >- .then(function(reg) { >- return wait_for_state(t, reg.installing, 'activated'); >- }) >- .then(function() { return with_iframe(scope); }) >+ return with_iframe(page_url) > .then(function(f) { > frame = f; >+ t.add_cleanup(() => { frame.remove(); }); > assert_equals( > frame.contentDocument.body.textContent, > 'Client ID Not Found', >@@ -117,142 +120,121 @@ async_test(function(t) { > response_text.substr(0, 15), > 'Client ID Found', > 'Service Worker should respond to fetch with an existing client id'); >- frame.remove(); >- return service_worker_unregister_and_done(t, scope); >- }) >- .catch(unreached_rejection(t)); >+ }); > }, 'Service Worker responds to fetch event with an existing client id'); > >-async_test(function(t) { >- var scope = 'resources/simple.html?ignore'; >- service_worker_unregister_and_register(t, worker, scope) >- .then(function(reg) { >- return wait_for_state(t, reg.installing, 'activated'); >- }) >- .then(function() { return with_iframe(scope); }) >+promise_test(t => { >+ const page_url = 'resources/simple.html?ignore'; >+ return with_iframe(page_url) > .then(function(frame) { >+ t.add_cleanup(() => { frame.remove(); }); > assert_equals(frame.contentDocument.body.textContent, > 'Here\'s a simple html file.\n', > 'Response should come from fallback to native fetch'); >- frame.remove(); >- return service_worker_unregister_and_done(t, scope); >- }) >- .catch(unreached_rejection(t)); >+ }); > }, 'Service Worker does not respond to fetch event'); > >-async_test(function(t) { >- var scope = 'resources/simple.html?null'; >- service_worker_unregister_and_register(t, worker, scope) >- .then(function(reg) { >- return wait_for_state(t, reg.installing, 'activated'); >- }) >- .then(function() { return with_iframe(scope); }) >+promise_test(t => { >+ const page_url = 'resources/simple.html?null'; >+ return with_iframe(page_url) > .then(function(frame) { >+ t.add_cleanup(() => { frame.remove(); }); > assert_equals(frame.contentDocument.body.textContent, > '', > 'Response should be the empty string'); >- frame.remove(); >- return service_worker_unregister_and_done(t, scope); >- }) >- .catch(unreached_rejection(t)); >+ }); > }, 'Service Worker responds to fetch event with null response body'); > >-async_test(function(t) { >- var scope = 'resources/simple.html?fetch'; >- service_worker_unregister_and_register(t, worker, scope) >- .then(function(reg) { >- return wait_for_state(t, reg.installing, 'activated'); >- }) >- .then(function() { return with_iframe(scope); }) >+promise_test(t => { >+ const page_url = 'resources/simple.html?fetch'; >+ return with_iframe(page_url) > .then(function(frame) { >+ t.add_cleanup(() => { frame.remove(); }); > assert_equals(frame.contentDocument.body.textContent, > 'Here\'s an other html file.\n', > 'Response should come from fetched other file'); >- frame.remove(); >- return service_worker_unregister_and_done(t, scope); >- }) >- .catch(unreached_rejection(t)); >+ }); > }, 'Service Worker fetches other file in fetch event'); > >-async_test(function(t) { >- var scope = 'resources/simple.html?form-post'; >- var frame_name = 'xhr-post-frame'; >- service_worker_unregister_and_register(t, worker, scope) >- .then(function(reg) { >- return wait_for_state(t, reg.installing, 'activated'); >- }) >- .then(function(sw) { >- return new Promise(function(resolve) { >- var frame = document.createElement('iframe'); >- frame.name = frame_name; >- document.body.appendChild(frame); >- var form = document.createElement('form'); >- form.target = frame_name; >- form.action = scope; >- form.method = 'post'; >- var input1 = document.createElement('input'); >- input1.type = 'text'; >- input1.value = 'testValue1'; >- input1.name = 'testName1' >- form.appendChild(input1); >- var input2 = document.createElement('input'); >- input2.type = 'text'; >- input2.value = 'testValue2'; >- input2.name = 'testName2' >- form.appendChild(input2); >- document.body.appendChild(form); >- frame.onload = function() { >- document.body.removeChild(form); >- resolve(frame); >- }; >- form.submit(); >- }); >- }) >- .then(function(frame) { >+// Creates a form and an iframe and does a form submission that navigates the >+// frame to |action_url|. Returns the frame after navigation. >+function submit_form(action_url) { >+ return new Promise(resolve => { >+ const frame = document.createElement('iframe'); >+ frame.name = 'post-frame'; >+ document.body.appendChild(frame); >+ const form = document.createElement('form'); >+ form.target = frame.name; >+ form.action = action_url; >+ form.method = 'post'; >+ const input1 = document.createElement('input'); >+ input1.type = 'text'; >+ input1.value = 'testValue1'; >+ input1.name = 'testName1' >+ form.appendChild(input1); >+ const input2 = document.createElement('input'); >+ input2.type = 'text'; >+ input2.value = 'testValue2'; >+ input2.name = 'testName2' >+ form.appendChild(input2); >+ document.body.appendChild(form); >+ frame.onload = function() { >+ form.remove(); >+ resolve(frame); >+ }; >+ form.submit(); >+ }); >+} >+ >+promise_test(t => { >+ const page_url = 'resources/simple.html?form-post'; >+ return submit_form(page_url) >+ .then(frame => { >+ t.add_cleanup(() => { frame.remove(); }); > assert_equals(frame.contentDocument.body.textContent, > 'POST:application/x-www-form-urlencoded:' + > 'testName1=testValue1&testName2=testValue2'); >- frame.remove(); >- return service_worker_unregister_and_done(t, scope); >- }) >- .catch(unreached_rejection(t)); >+ }); > }, 'Service Worker responds to fetch event with POST form'); > >-async_test(function(t) { >- var scope = 'resources/simple.html?multiple-respond-with'; >- service_worker_unregister_and_register(t, worker, scope) >- .then(function(reg) { >- return wait_for_state(t, reg.installing, 'activated'); >- }) >- .then(function() { return with_iframe(scope); }) >- .then(function(frame) { >+promise_test(t => { >+ // Add '?ignore' so the service worker falls back to network. >+ const page_url = 'resources/echo-content.py?ignore'; >+ return submit_form(page_url) >+ .then(frame => { >+ t.add_cleanup(() => { frame.remove(); }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'testName1=testValue1&testName2=testValue2'); >+ }); >+ }, 'Service Worker falls back to network in fetch event with POST form'); >+ >+promise_test(t => { >+ const page_url = 'resources/simple.html?multiple-respond-with'; >+ return with_iframe(page_url) >+ .then(frame => { >+ t.add_cleanup(() => { frame.remove(); }); > assert_equals( > frame.contentDocument.body.textContent, > '(0)(1)[InvalidStateError](2)[InvalidStateError]', > 'Multiple calls of respondWith must throw InvalidStateErrors.'); >- frame.remove(); >- return service_worker_unregister_and_done(t, scope); >- }) >- .catch(unreached_rejection(t)); >+ }); > }, 'Multiple calls of respondWith must throw InvalidStateErrors'); > >-async_test(function(t) { >- var scope = 'resources/simple.html?used-check'; >+promise_test(t => { >+ const page_url = 'resources/simple.html?used-check'; > var first_frame; >- service_worker_unregister_and_register(t, worker, scope) >- .then(function(reg) { >- return wait_for_state(t, reg.installing, 'activated'); >- }) >- .then(function() { return with_iframe(scope); }) >+ return with_iframe(page_url) > .then(function(frame) { > assert_equals(frame.contentDocument.body.textContent, > 'Here\'s an other html file.\n', > 'Response should come from fetched other file'); > first_frame = frame; >- return with_iframe(scope); >+ t.add_cleanup(() => { first_frame.remove(); }); >+ return with_iframe(page_url); > }) > .then(function(frame) { >- // When we access to the scope in the second time, the content of the >+ t.add_cleanup(() => { frame.remove(); }); >+ // When we access to the page_url in the second time, the content of the > // response is generated inside the ServiceWorker. The body contains > // the value of bodyUsed of the first response which is already > // consumed by FetchEvent.respondWith method. >@@ -260,46 +242,33 @@ async_test(function(t) { > frame.contentDocument.body.textContent, > 'bodyUsed: true', > 'event.respondWith must set the used flag.'); >- first_frame.remove(); >- frame.remove(); >- return service_worker_unregister_and_done(t, scope); >- }) >- .catch(unreached_rejection(t)); >+ }); > }, 'Service Worker event.respondWith must set the used flag'); > >-async_test(function(t) { >- var scope = 'resources/simple.html?fragment-check'; >+promise_test(t => { >+ const page_url = 'resources/simple.html?fragment-check'; > var fragment = '#/some/fragment'; > var first_frame; >- service_worker_unregister_and_register(t, worker, scope) >- .then(function(reg) { >- return wait_for_state(t, reg.installing, 'activated'); >- }) >- .then(function() { return with_iframe(scope + fragment); }) >+ return with_iframe(page_url + fragment) > .then(function(frame) { >+ t.add_cleanup(() => { frame.remove(); }); > assert_equals( > frame.contentDocument.body.textContent, > 'Fragment Found :' + fragment, > 'Service worker should expose URL fragments in request.'); >- frame.remove(); >- return service_worker_unregister_and_done(t, scope); >- }) >- .catch(unreached_rejection(t)); >+ }); > }, 'Service Worker should expose FetchEvent URL fragments.'); > >-async_test(function(t) { >- var scope = 'resources/simple.html?cache'; >+promise_test(t => { >+ const page_url = 'resources/simple.html?cache'; > var frame; > var cacheTypes = [ > undefined, 'default', 'no-store', 'reload', 'no-cache', 'force-cache', 'only-if-cached' > ]; >- service_worker_unregister_and_register(t, worker, scope) >- .then(function(reg) { >- return wait_for_state(t, reg.installing, 'activated'); >- }) >- .then(function() { return with_iframe(scope); }) >+ return with_iframe(page_url) > .then(function(f) { > frame = f; >+ t.add_cleanup(() => { frame.remove(); }); > assert_equals(frame.contentWindow.document.body.textContent, 'default'); > var tests = cacheTypes.map(function(type) { > return new Promise(function(resolve, reject) { >@@ -309,7 +278,7 @@ async_test(function(t) { > // requires the mode to be same-origin. > init.mode = 'same-origin'; > } >- return frame.contentWindow.fetch(scope + '=' + type, init) >+ return frame.contentWindow.fetch(page_url + '=' + type, init) > .then(function(response) { return response.text(); }) > .then(function(response_text) { > var expected = (type === undefined) ? 'default' : type; >@@ -336,21 +305,16 @@ async_test(function(t) { > }); > frame.contentWindow.location.reload(); > }); >- }) >- .then(function() { >- frame.remove(); >- return service_worker_unregister_and_done(t, scope); >- }) >- .catch(unreached_rejection(t)); >+ }); > }, 'Service Worker responds to fetch event with the correct cache types'); > >-async_test(function(t) { >- var scope = 'resources/simple.html?eventsource'; >+promise_test(t => { >+ const page_url = 'resources/simple.html?eventsource'; > var frame; > > function test_eventsource(opts) { > return new Promise(function(resolve, reject) { >- var eventSource = new frame.contentWindow.EventSource(scope, opts); >+ var eventSource = new frame.contentWindow.EventSource(page_url, opts); > eventSource.addEventListener('message', function(msg) { > eventSource.close(); > try { >@@ -375,73 +339,54 @@ async_test(function(t) { > }); > } > >- service_worker_unregister_and_register(t, worker, scope) >- .then(function(reg) { >- return wait_for_state(t, reg.installing, 'activated'); >- }) >- .then(function() { return with_iframe(scope); }) >+ return with_iframe(page_url) > .then(function(f) { > frame = f; >+ t.add_cleanup(() => { frame.remove(); }); > return test_eventsource({ withCredentials: false }); > }) > .then(function() { > return test_eventsource({ withCredentials: true }); >- }) >- .then(function() { >- frame.remove(); >- return service_worker_unregister_and_done(t, scope); >- }) >- .catch(unreached_rejection(t)); >+ }); > }, 'Service Worker should intercept EventSource'); > >-async_test(function(t) { >- var scope = 'resources/simple.html?integrity'; >+promise_test(t => { >+ const page_url = 'resources/simple.html?integrity'; > var frame; > var integrity_metadata = 'gs0nqru8KbsrIt5YToQqS9fYao4GQJXtcId610g7cCU='; > >- service_worker_unregister_and_register(t, worker, scope) >- .then(function(reg) { >- return wait_for_state(t, reg.installing, 'activated'); >- }) >- .then(function() { return with_iframe(scope); }) >+ return with_iframe(page_url) > .then(function(f) { > frame = f; >+ t.add_cleanup(() => { frame.remove(); }); > // A request has associated integrity metadata (a string). > // Unless stated otherwise, it is the empty string. > assert_equals( > frame.contentDocument.body.textContent, ''); > >- return frame.contentWindow.fetch(scope, {'integrity': integrity_metadata}); >+ return frame.contentWindow.fetch(page_url, {'integrity': integrity_metadata}); > }) > .then(response => { > return response.text(); > }) > .then(response_text => { > assert_equals(response_text, integrity_metadata, 'integrity'); >- frame.remove(); >- return service_worker_unregister_and_done(t, scope); >- }) >- .catch(unreached_rejection(t)); >+ }); > }, 'Service Worker responds to fetch event with the correct integrity_metadata'); > > // Test that the service worker can read FetchEvent#body when it is a string. > // It responds with request body it read. > promise_test(t => { >- // Set scope to "?ignore" so the service worker falls back to network >+ // Set page_url to "?ignore" so the service worker falls back to network > // for the main resource request, and add a suffix to avoid colliding > // with other tests. >- const scope = 'resources/simple.html?ignore-for-request-body-string'; >+ const page_url = 'resources/simple.html?ignore-for-request-body-string'; > let frame; > >- return service_worker_unregister_and_register(t, worker, scope) >- .then(reg => { >- add_completion_callback(() => { reg.unregister(); }); >- return wait_for_state(t, reg.installing, 'activated'); >- }) >- .then(() => { >- return with_iframe(scope); }) >+ return with_iframe(page_url) > .then(f => { > frame = f; >+ t.add_cleanup(() => { frame.remove(); }); > return frame.contentWindow.fetch('simple.html?request-body', { > method: 'POST', > body: 'i am the request body' >@@ -451,29 +396,54 @@ promise_test(t => { > return response.text(); > }) > .then(response_text => { >- frame.remove(); > assert_equals(response_text, 'i am the request body'); > }); > }, 'FetchEvent#body is a string'); > >+// Test that the request body is sent to network upon network fallback, >+// for a string body. >+promise_test(t => { >+ // Set page_url to "?ignore" so the service worker falls back to network >+ // for the main resource request, and add a suffix to avoid colliding >+ // with other tests. >+ const page_url = 'resources/?ignore-for-request-body-fallback-string'; >+ let frame; >+ >+ return with_iframe(page_url) >+ .then(f => { >+ frame = f; >+ t.add_cleanup(() => { frame.remove(); }); >+ // Add "?ignore" so the service worker falls back to echo-content.py. >+ const echo_url = '/fetch/api/resources/echo-content.py?ignore'; >+ return frame.contentWindow.fetch(echo_url, { >+ method: 'POST', >+ body: 'i am the request body' >+ }); >+ }) >+ .then(response => { >+ return response.text(); >+ }) >+ .then(response_text => { >+ assert_equals( >+ response_text, >+ 'i am the request body', >+ 'the network fallback request should include the request body'); >+ }); >+ }, 'FetchEvent#body is a string and is passed to network fallback'); >+ > // Test that the service worker can read FetchEvent#body when it is a blob. > // It responds with request body it read. > promise_test(t => { >- // Set scope to "?ignore" so the service worker falls back to network >+ // Set page_url to "?ignore" so the service worker falls back to network > // for the main resource request, and add a suffix to avoid colliding > // with other tests. >- const scope = 'resources/simple.html?ignore-for-request-body-blob'; >+ const page_url = 'resources/simple.html?ignore-for-request-body-blob'; > let frame; > >- return service_worker_unregister_and_register(t, worker, scope) >- .then(reg => { >- add_completion_callback(() => { reg.unregister(); }); >- return wait_for_state(t, reg.installing, 'activated'); >- }) >- .then(() => { >- return with_iframe(scope); }) >+ return with_iframe(page_url) > .then(f => { > frame = f; >+ t.add_cleanup(() => { frame.remove(); }); > const blob = new Blob(['it\'s me the blob', ' ', 'and more blob!']); > return frame.contentWindow.fetch('simple.html?request-body', { > method: 'POST', >@@ -484,23 +454,353 @@ promise_test(t => { > return response.text(); > }) > .then(response_text => { >- frame.remove(); > assert_equals(response_text, 'it\'s me the blob and more blob!'); > }); > }, 'FetchEvent#body is a blob'); > >-promise_test(async (t) => { >- const scope = 'resources/simple.html?keepalive'; >+// Test that the request body is sent to network upon network fallback, >+// for a blob body. >+promise_test(t => { >+ // Set page_url to "?ignore" so the service worker falls back to network >+ // for the main resource request, and add a suffix to avoid colliding >+ // with other tests. >+ const page_url = 'resources/simple.html?ignore-for-request-body-fallback-blob'; >+ let frame; >+ >+ return with_iframe(page_url) >+ .then(f => { >+ frame = f; >+ t.add_cleanup(() => { frame.remove(); }); >+ const blob = new Blob(['it\'s me the blob', ' ', 'and more blob!']); >+ // Add "?ignore" so the service worker falls back to echo-content.py. >+ const echo_url = '/fetch/api/resources/echo-content.py?ignore'; >+ return frame.contentWindow.fetch(echo_url, { >+ method: 'POST', >+ body: blob >+ }); >+ }) >+ .then(response => { >+ return response.text(); >+ }) >+ .then(response_text => { >+ assert_equals( >+ response_text, >+ 'it\'s me the blob and more blob!', >+ 'the network fallback request should include the request body'); >+ }); >+ }, 'FetchEvent#body is a blob and is passed to network fallback'); > >- const reg = await service_worker_unregister_and_register(t, worker, scope); >- await wait_for_state(t, reg.installing, 'activated'); >- const frame = await with_iframe(scope); >+promise_test(async (t) => { >+ const page_url = 'resources/simple.html?keepalive'; >+ const frame = await with_iframe(page_url); >+ t.add_cleanup(() => { frame.remove(); }); > assert_equals(frame.contentDocument.body.textContent, 'false'); >- const response = await frame.contentWindow.fetch(scope, {keepalive: true}); >+ const response = await frame.contentWindow.fetch(page_url, {keepalive: true}); > const text = await response.text(); > assert_equals(text, 'true'); >- frame.remove(); >- await service_worker_unregister_and_done(t, scope); > }, 'Service Worker responds to fetch event with the correct keepalive value'); >+ >+promise_test(async (t) => { >+ const page_url = 'resources/simple.html?isReloadNavigation'; >+ const frame = await with_iframe(page_url); >+ t.add_cleanup(() => { frame.remove(); }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isReloadNavigation = false'); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.location.reload(); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isReloadNavigation = true'); >+ }, 'FetchEvent#request.isReloadNavigation is true (location.reload())'); >+ >+promise_test(async (t) => { >+ const page_url = 'resources/simple.html?isReloadNavigation'; >+ const frame = await with_iframe(page_url); >+ t.add_cleanup(() => { frame.remove(); }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isReloadNavigation = false'); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.history.go(0); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isReloadNavigation = true'); >+ }, 'FetchEvent#request.isReloadNavigation is true (history.go(0))'); >+ >+promise_test(async (t) => { >+ const page_url = 'resources/simple.html?isReloadNavigation'; >+ const frame = await with_iframe(page_url); >+ t.add_cleanup(() => { frame.remove(); }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isReloadNavigation = false'); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ const form = frame.contentDocument.createElement('form'); >+ form.method = 'POST'; >+ form.name = 'form'; >+ form.action = new Request(page_url).url; >+ frame.contentDocument.body.appendChild(form); >+ form.submit(); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = POST, isReloadNavigation = false'); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.location.reload(); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = POST, isReloadNavigation = true'); >+ }, 'FetchEvent#request.isReloadNavigation is true (POST + location.reload())'); >+ >+promise_test(async (t) => { >+ const page_url = 'resources/simple.html?isReloadNavigation'; >+ const anotherUrl = new Request('resources/simple.html').url; >+ let frame = await with_iframe(page_url); >+ t.add_cleanup(() => { frame.remove(); }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isReloadNavigation = false'); >+ // Use step_timeout(0) to ensure the history entry is created for Blink >+ // and WebKit. See https://bugs.webkit.org/show_bug.cgi?id=42861. >+ await wait(0); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.src = anotherUrl; >+ }); >+ assert_equals(frame.contentDocument.body.textContent, "Here's a simple html file.\n"); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.history.go(-1); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isReloadNavigation = false'); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.history.go(0); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isReloadNavigation = true'); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.history.go(1); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, "Here's a simple html file.\n"); >+ }, 'FetchEvent#request.isReloadNavigation is true (with history traversal)'); >+ >+promise_test(async (t) => { >+ const page_url = 'resources/simple.html?isHistoryNavigation'; >+ const anotherUrl = new Request('resources/simple.html?ignore').url; >+ const frame = await with_iframe(page_url); >+ t.add_cleanup(() => { frame.remove(); }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isHistoryNavigation = false'); >+ // Use step_timeout(0) to ensure the history entry is created for Blink >+ // and WebKit. See https://bugs.webkit.org/show_bug.cgi?id=42861. >+ await wait(0); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.src = anotherUrl; >+ }); >+ assert_equals(frame.contentDocument.body.textContent, "Here's a simple html file.\n"); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.history.go(-1); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isHistoryNavigation = true'); >+ }, 'FetchEvent#request.isHistoryNavigation is true (with history.go(-1))'); >+ >+promise_test(async (t) => { >+ const page_url = 'resources/simple.html?isHistoryNavigation'; >+ const anotherUrl = new Request('resources/simple.html?ignore').url; >+ const frame = await with_iframe(anotherUrl); >+ t.add_cleanup(() => { frame.remove(); }); >+ assert_equals(frame.contentDocument.body.textContent, "Here's a simple html file.\n"); >+ // Use step_timeout(0) to ensure the history entry is created for Blink >+ // and WebKit. See https://bugs.webkit.org/show_bug.cgi?id=42861. >+ await wait(0); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.src = page_url; >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isHistoryNavigation = false'); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.history.go(-1); >+ }); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.history.go(1); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isHistoryNavigation = true'); >+ }, 'FetchEvent#request.isHistoryNavigation is true (with history.go(1))'); >+ >+promise_test(async (t) => { >+ const page_url = 'resources/simple.html?isHistoryNavigation'; >+ const anotherUrl = new Request('resources/simple.html?ignore').url; >+ const frame = await with_iframe(anotherUrl); >+ t.add_cleanup(() => { frame.remove(); }); >+ assert_equals(frame.contentDocument.body.textContent, "Here's a simple html file.\n"); >+ // Use step_timeout(0) to ensure the history entry is created for Blink >+ // and WebKit. See https://bugs.webkit.org/show_bug.cgi?id=42861. >+ await wait(0); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.src = page_url; >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isHistoryNavigation = false'); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.history.go(-1); >+ }); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.history.go(1); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isHistoryNavigation = true'); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.history.go(0); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isHistoryNavigation = false'); >+ }, 'FetchEvent#request.isHistoryNavigation is false (with history.go(0))'); >+ >+promise_test(async (t) => { >+ const page_url = 'resources/simple.html?isHistoryNavigation'; >+ const anotherUrl = new Request('resources/simple.html?ignore').url; >+ const frame = await with_iframe(anotherUrl); >+ t.add_cleanup(() => { frame.remove(); }); >+ assert_equals(frame.contentDocument.body.textContent, "Here's a simple html file.\n"); >+ // Use step_timeout(0) to ensure the history entry is created for Blink >+ // and WebKit. See https://bugs.webkit.org/show_bug.cgi?id=42861. >+ await wait(0); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.src = page_url; >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isHistoryNavigation = false'); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.history.go(-1); >+ }); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.history.go(1); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isHistoryNavigation = true'); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.location.reload(); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isHistoryNavigation = false'); >+ }, 'FetchEvent#request.isHistoryNavigation is false (with location.reload)'); >+ >+promise_test(async (t) => { >+ const page_url = 'resources/simple.html?isHistoryNavigation'; >+ const anotherUrl = new Request('resources/simple.html?ignore').url; >+ const oneAnotherUrl = new Request('resources/simple.html?ignore2').url; >+ >+ const frame = await with_iframe(page_url); >+ t.add_cleanup(() => { frame.remove(); }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isHistoryNavigation = false'); >+ // Use step_timeout(0) to ensure the history entry is created for Blink >+ // and WebKit. See https://bugs.webkit.org/show_bug.cgi?id=42861. >+ await wait(0); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.src = anotherUrl; >+ }); >+ assert_equals(frame.contentDocument.body.textContent, "Here's a simple html file.\n"); >+ await wait(0); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.src = oneAnotherUrl; >+ }); >+ assert_equals(frame.contentDocument.body.textContent, "Here's a simple html file.\n"); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.history.go(-2); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isHistoryNavigation = true'); >+ }, 'FetchEvent#request.isHistoryNavigation is true (with history.go(-2))'); >+ >+promise_test(async (t) => { >+ const page_url = 'resources/simple.html?isHistoryNavigation'; >+ const anotherUrl = new Request('resources/simple.html?ignore').url; >+ const oneAnotherUrl = new Request('resources/simple.html?ignore2').url; >+ const frame = await with_iframe(anotherUrl); >+ t.add_cleanup(() => { frame.remove(); }); >+ assert_equals(frame.contentDocument.body.textContent, "Here's a simple html file.\n"); >+ // Use step_timeout(0) to ensure the history entry is created for Blink >+ // and WebKit. See https://bugs.webkit.org/show_bug.cgi?id=42861. >+ await wait(0); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.src = oneAnotherUrl; >+ }); >+ assert_equals(frame.contentDocument.body.textContent, "Here's a simple html file.\n"); >+ await wait(0); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.src = page_url; >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isHistoryNavigation = false'); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.history.go(-2); >+ }); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.history.go(2); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isHistoryNavigation = true'); >+ }, 'FetchEvent#request.isHistoryNavigation is true (with history.go(2))'); >+ >+promise_test(async (t) => { >+ const page_url = 'resources/simple.html?isHistoryNavigation'; >+ const anotherUrl = new Request('resources/simple.html?ignore').url; >+ const frame = await with_iframe(page_url); >+ t.add_cleanup(() => { frame.remove(); }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = GET, isHistoryNavigation = false'); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ const form = frame.contentDocument.createElement('form'); >+ form.method = 'POST'; >+ form.name = 'form'; >+ form.action = new Request(page_url).url; >+ frame.contentDocument.body.appendChild(form); >+ form.submit(); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = POST, isHistoryNavigation = false'); >+ // Use step_timeout(0) to ensure the history entry is created for Blink >+ // and WebKit. See https://bugs.webkit.org/show_bug.cgi?id=42861. >+ await wait(0); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.src = anotherUrl; >+ }); >+ assert_equals(frame.contentDocument.body.textContent, "Here's a simple html file.\n"); >+ await wait(0); >+ await new Promise((resolve) => { >+ frame.addEventListener('load', resolve); >+ frame.contentWindow.history.go(-1); >+ }); >+ assert_equals(frame.contentDocument.body.textContent, >+ 'method = POST, isHistoryNavigation = true'); >+ }, 'FetchEvent#request.isHistoryNavigation is true (POST + history.go(-1))'); > </script> > </body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-css-cross-origin-mime-check.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-css-cross-origin-mime-check.https-expected.txt >deleted file mode 100644 >index 4e825ae971539a2499d0ea065006aea96492aa34..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-css-cross-origin-mime-check.https-expected.txt >+++ /dev/null >@@ -1,4 +0,0 @@ >-CONSOLE MESSAGE: Did not parse stylesheet at 'https://localhost:9443/service-workers/service-worker/resources/cross-origin-html.css' because non CSS MIME types are not allowed for cross-origin stylesheets. >- >-PASS Mime type checking of CSS files fetched via SW. >- >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-css-cross-origin-mime-check.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-css-cross-origin-mime-check.https.html >deleted file mode 100644 >index 7835f60a2ca17e203b0c5e3e76f167ed3f4aecc8..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-css-cross-origin-mime-check.https.html >+++ /dev/null >@@ -1,50 +0,0 @@ >-<!DOCTYPE html> >-<title>Service Worker: Mime type checking of CSS files fetched via SW.</title> >-<script src="/resources/testharness.js"></script> >-<script src="/resources/testharnessreport.js"></script> >-<script src="/common/get-host-info.sub.js"></script> >-<script src="resources/test-helpers.sub.js"></script> >-<script> >- >-function getElementColorInFrame(frame, id) { >- var element = frame.contentDocument.getElementById(id); >- var style = frame.contentWindow.getComputedStyle(element, ''); >- return style['color']; >-} >- >-promise_test(function(t) { >- var SCOPE = >- 'resources/fetch-request-css-cross-origin-mime-check-iframe.html'; >- var SCRIPT = >- 'resources/fetch-request-css-cross-origin-mime-check-worker.js'; >- var EXPECTED_COLOR = 'rgb(0, 0, 255)'; >- >- return service_worker_unregister_and_register(t, SCRIPT, SCOPE) >- .then(r => wait_for_state(t, r.installing, 'activated')) >- .then(_ => with_iframe(SCOPE) ) >- .then(f => { >- assert_equals( >- getElementColorInFrame(f, 'crossOriginCss'), >- EXPECTED_COLOR, >- 'The color must be overridden by cross origin CSS.'); >- assert_equals( >- getElementColorInFrame(f, 'crossOriginHtml'), >- EXPECTED_COLOR, >- 'The color must not be overridden by cross origin non CSS file.'); >- assert_equals( >- getElementColorInFrame(f, 'sameOriginCss'), >- EXPECTED_COLOR, >- 'The color must be overridden by same origin CSS.'); >- assert_equals( >- getElementColorInFrame(f, 'sameOriginHtml'), >- EXPECTED_COLOR, >- 'The color must be overridden by same origin non CSS file.'); >- assert_equals( >- getElementColorInFrame(f, 'synthetic'), >- EXPECTED_COLOR, >- 'The color must be overridden by synthetic CSS.'); >- f.remove(); >- return service_worker_unregister_and_done(t, SCOPE); >- }); >- }, 'Mime type checking of CSS files fetched via SW.'); >-</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-css-cross-origin.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-css-cross-origin.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..bc21f4f2e8bc52f28ccbea0ec0d1134a3a6d07d1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-css-cross-origin.https-expected.txt >@@ -0,0 +1,9 @@ >+CONSOLE MESSAGE: Did not parse stylesheet at 'https://localhost:9443/service-workers/service-worker/resources/cross-origin-html.css?mime=no' because non CSS MIME types are not allowed for cross-origin stylesheets. >+ >+PASS setup global state >+PASS MIME checking of CSS resources fetched via service worker when Content-Type is not set. >+FAIL Same-origin policy for access to CSS resources fetched via service worker assert_throws: function "() => { >+ f.contentDocument.styleSheets[0].cssRules[0].cssText; >+ }" threw object "TypeError: null is not an object (evaluating 'f.contentDocument.styleSheets[0].cssRules[0]')" that is not a DOMException SecurityError: property "code" is equal to undefined, expected 18 >+PASS cleanup global state >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-css-cross-origin.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-css-cross-origin.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2cdfdea996f7c55a56c4bbcd6fe94dace192a497 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-css-cross-origin.https.html >@@ -0,0 +1,81 @@ >+<!DOCTYPE html> >+<title>Service Worker: Cross-origin CSS files fetched via SW.</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/get-host-info.sub.js"></script> >+<script src="resources/test-helpers.sub.js"></script> >+<script> >+ >+function getElementColorInFrame(frame, id) { >+ var element = frame.contentDocument.getElementById(id); >+ var style = frame.contentWindow.getComputedStyle(element, ''); >+ return style['color']; >+} >+ >+promise_test(async t => { >+ var SCOPE = >+ 'resources/fetch-request-css-cross-origin'; >+ var SCRIPT = >+ 'resources/fetch-request-css-cross-origin-worker.js'; >+ let registration = await service_worker_unregister_and_register( >+ t, SCRIPT, SCOPE); >+ promise_test(async t => { >+ await registration.unregister(); >+ }, 'cleanup global state'); >+ >+ await wait_for_state(t, registration.installing, 'activated'); >+}, 'setup global state'); >+ >+promise_test(async t => { >+ const EXPECTED_COLOR = 'rgb(0, 0, 255)'; >+ const PAGE = >+ 'resources/fetch-request-css-cross-origin-mime-check-iframe.html'; >+ >+ const f = await with_iframe(PAGE); >+ t.add_cleanup(() => {f.remove(); }); >+ assert_equals( >+ getElementColorInFrame(f, 'crossOriginCss'), >+ EXPECTED_COLOR, >+ 'The color must be overridden by cross origin CSS.'); >+ assert_equals( >+ getElementColorInFrame(f, 'crossOriginHtml'), >+ EXPECTED_COLOR, >+ 'The color must not be overridden by cross origin non CSS file.'); >+ assert_equals( >+ getElementColorInFrame(f, 'sameOriginCss'), >+ EXPECTED_COLOR, >+ 'The color must be overridden by same origin CSS.'); >+ assert_equals( >+ getElementColorInFrame(f, 'sameOriginHtml'), >+ EXPECTED_COLOR, >+ 'The color must be overridden by same origin non CSS file.'); >+ assert_equals( >+ getElementColorInFrame(f, 'synthetic'), >+ EXPECTED_COLOR, >+ 'The color must be overridden by synthetic CSS.'); >+}, 'MIME checking of CSS resources fetched via service worker when Content-Type is not set.'); >+ >+promise_test(async t => { >+ const PAGE = >+ 'resources/fetch-request-css-cross-origin-read-contents.html'; >+ >+ const f = await with_iframe(PAGE); >+ t.add_cleanup(() => {f.remove(); }); >+ assert_throws('SecurityError', () => { >+ f.contentDocument.styleSheets[0].cssRules[0].cssText; >+ }); >+ assert_equals( >+ f.contentDocument.styleSheets[1].cssRules[0].cssText, >+ '#crossOriginCss { color: blue; }', >+ 'cross-origin CORS approved response'); >+ assert_equals( >+ f.contentDocument.styleSheets[2].cssRules[0].cssText, >+ '#sameOriginCss { color: blue; }', >+ 'same-origin response'); >+ assert_equals( >+ f.contentDocument.styleSheets[3].cssRules[0].cssText, >+ '#synthetic { color: blue; }', >+ 'service worker generated response'); >+ }, 'Same-origin policy for access to CSS resources fetched via service worker'); >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-no-freshness-headers.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-no-freshness-headers.https-expected.txt >index c59c5607026105f4ec5ae6655fc4be79e2824287..4bf52c92b846715ad007b5049448703a2cb892a8 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-no-freshness-headers.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-no-freshness-headers.https-expected.txt >@@ -1,3 +1,3 @@ > >-PASS The headers of FetchEvent shouldn't contain freshness headers. >+FAIL The headers of FetchEvent shouldn't contain freshness headers. assert_false: if-none-match header must not be set in the FetchEvent's request. (url = https://localhost:9443/service-workers/service-worker/resources/fetch-request-no-freshness-headers-script.py) expected false got true > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-resources.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-resources.https.html >index b0640ec985b8c40dfe6d3c2b32bc58c6904d5dd8..50421b40fbb69803f2770b0159de8706dd2fe339 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-resources.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-resources.https.html >@@ -11,9 +11,8 @@ var expected_results = {}; > function add_promise_to_test(url) > { > var expected = expected_results[url]; >- return new Promise((resolve, reject) => { >+ return new Promise((resolve) => { > expected.resolve = resolve; >- setTimeout(() => reject("test time out"), 5000); > }); > } > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-xhr-sync-on-worker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-xhr-sync-on-worker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..b43e0ced06bbb143d99d04927272abc9c849a40f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-xhr-sync-on-worker.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS Verify SyncXHR on Worker is intercepted >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-xhr-sync-on-worker.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-xhr-sync-on-worker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..9f18096aa29bb4635cfeaf0eb9fc39cff5bcc243 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-xhr-sync-on-worker.https.html >@@ -0,0 +1,41 @@ >+<!DOCTYPE html> >+<title>Service Worker: Synchronous XHR on Worker is intercepted</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/test-helpers.sub.js"></script> >+<script> >+'use strict'; >+ >+promise_test((t) => { >+ const url = 'resources/fetch-request-xhr-sync-on-worker-worker.js'; >+ const scope = 'resources/fetch-request-xhr-sync-on-worker-scope/'; >+ const non_existent_file = 'non-existent-file.txt'; >+ >+ // In Chromium, the service worker scope matching for workers is based on >+ // the URL of the parent HTML. So this test creates an iframe which is >+ // controlled by the service worker first, and creates a worker from the >+ // iframe. >+ return service_worker_unregister_and_register(t, url, scope) >+ .then((registration) => { >+ t.add_cleanup(() => registration.unregister()); >+ return wait_for_state(t, registration.installing, 'activated'); >+ }) >+ .then(() => { return with_iframe(scope + 'iframe_page'); }) >+ .then((frame) => { >+ t.add_cleanup(() => frame.remove()); >+ return frame.contentWindow.performSyncXHROnWorker(non_existent_file); >+ }) >+ .then((result) => { >+ assert_equals( >+ result.status, >+ 200, >+ 'HTTP response status code for intercepted request' >+ ); >+ assert_equals( >+ result.responseText, >+ 'Response from service worker', >+ 'HTTP response text for intercepted request' >+ ); >+ }); >+ }, 'Verify SyncXHR on Worker is intercepted'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-response-taint.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-response-taint.https-expected.txt >index fe0aab3be5112bce0151275e471f7d84fc7fdba1..ba369a313c675e911604d33acec6a2db801a8a46 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-response-taint.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-response-taint.https-expected.txt >@@ -94,9 +94,9 @@ PASS fetching url:"https://127.0.0.1:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2F > PASS url:"https://127.0.0.1:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3F&mode=no-cors&credentials=omit&" mode:"cors" credentials:"omit" should fail. > PASS url:"https://127.0.0.1:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3F&mode=no-cors&credentials=omit&" mode:"cors" credentials:"same-origin" should fail. > PASS url:"https://127.0.0.1:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3F&mode=no-cors&credentials=omit&" mode:"cors" credentials:"include" should fail. >-PASS fetching url:"https://localhost:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3D*&mode=cors&credentials=omit&" mode:"same-origin" credentials:"omit" should succeed. >-PASS fetching url:"https://localhost:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3D*&mode=cors&credentials=omit&" mode:"same-origin" credentials:"same-origin" should succeed. >-PASS fetching url:"https://localhost:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3D*&mode=cors&credentials=omit&" mode:"same-origin" credentials:"include" should succeed. >+FAIL url:"https://localhost:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3D*&mode=cors&credentials=omit&" mode:"same-origin" credentials:"omit" should fail. assert_unreached: Should have rejected: undefined Reached unreachable code >+FAIL url:"https://localhost:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3D*&mode=cors&credentials=omit&" mode:"same-origin" credentials:"same-origin" should fail. assert_unreached: Should have rejected: undefined Reached unreachable code >+FAIL url:"https://localhost:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3D*&mode=cors&credentials=omit&" mode:"same-origin" credentials:"include" should fail. assert_unreached: Should have rejected: undefined Reached unreachable code > PASS fetching url:"https://localhost:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3D*&mode=cors&credentials=omit&" mode:"no-cors" credentials:"omit" should succeed. > PASS fetching url:"https://localhost:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3D*&mode=cors&credentials=omit&" mode:"no-cors" credentials:"same-origin" should succeed. > PASS fetching url:"https://localhost:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3D*&mode=cors&credentials=omit&" mode:"no-cors" credentials:"include" should succeed. >@@ -112,9 +112,9 @@ PASS fetching url:"https://127.0.0.1:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2F > PASS fetching url:"https://127.0.0.1:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3D*&mode=cors&credentials=omit&" mode:"cors" credentials:"omit" should succeed. > PASS fetching url:"https://127.0.0.1:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3D*&mode=cors&credentials=omit&" mode:"cors" credentials:"same-origin" should succeed. > PASS fetching url:"https://127.0.0.1:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3D*&mode=cors&credentials=omit&" mode:"cors" credentials:"include" should succeed. >-PASS fetching url:"https://localhost:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443%26ACACredentials%3Dtrue&mode=cors&credentials=include&" mode:"same-origin" credentials:"omit" should succeed. >-PASS fetching url:"https://localhost:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443%26ACACredentials%3Dtrue&mode=cors&credentials=include&" mode:"same-origin" credentials:"same-origin" should succeed. >-PASS fetching url:"https://localhost:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443%26ACACredentials%3Dtrue&mode=cors&credentials=include&" mode:"same-origin" credentials:"include" should succeed. >+FAIL url:"https://localhost:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443%26ACACredentials%3Dtrue&mode=cors&credentials=include&" mode:"same-origin" credentials:"omit" should fail. assert_unreached: Should have rejected: undefined Reached unreachable code >+FAIL url:"https://localhost:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443%26ACACredentials%3Dtrue&mode=cors&credentials=include&" mode:"same-origin" credentials:"same-origin" should fail. assert_unreached: Should have rejected: undefined Reached unreachable code >+FAIL url:"https://localhost:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443%26ACACredentials%3Dtrue&mode=cors&credentials=include&" mode:"same-origin" credentials:"include" should fail. assert_unreached: Should have rejected: undefined Reached unreachable code > PASS fetching url:"https://localhost:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443%26ACACredentials%3Dtrue&mode=cors&credentials=include&" mode:"no-cors" credentials:"omit" should succeed. > PASS fetching url:"https://localhost:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443%26ACACredentials%3Dtrue&mode=cors&credentials=include&" mode:"no-cors" credentials:"same-origin" should succeed. > PASS fetching url:"https://localhost:9443/?url=https%3A%2F%2F127.0.0.1%3A9443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3Dhttps%3A%2F%2Flocalhost%3A9443%26ACACredentials%3Dtrue&mode=cors&credentials=include&" mode:"no-cors" credentials:"include" should succeed. >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-response-taint.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-response-taint.https.html >index a6e7f984ea24499d5540048faee574172aa9ec44..8ebee0c07374c37b74bc1ff79e6932d0d15b35a1 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-response-taint.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-response-taint.https.html >@@ -193,6 +193,9 @@ for_each_origin_mode_credentials(function(origin, mode, credentials) { > // Fetch to the other origin with same-origin mode should fail. > if (origin == OTHER_ORIGIN && mode == 'same-origin') { > ng_test(url, mode, credentials); >+ } else if (origin == BASE_ORIGIN && mode == 'same-origin') { >+ // Cors type response to a same-origin mode request should fail >+ ng_test(url, mode, credentials); > } else { > // The response from the SW should be cors. > ok_test(url, mode, credentials, 'cors', 'undefined'); >@@ -208,6 +211,9 @@ for_each_origin_mode_credentials(function(origin, mode, credentials) { > // Fetch to the other origin with same-origin mode should fail. > if (origin == OTHER_ORIGIN && mode == 'same-origin') { > ng_test(url, mode, credentials); >+ } else if (origin == BASE_ORIGIN && mode == 'same-origin') { >+ // Cors type response to a same-origin mode request should fail >+ ng_test(url, mode, credentials); > } else { > // The response from the SW should be cors. > ok_test(url, mode, credentials, 'cors', 'username1s'); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/import-scripts-updated-flag.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/import-scripts-updated-flag.https-expected.txt >index b829fec4072934f27145613639e55de7c258636e..6c2adbc751154e1a8442e951565376b4b4dfb4ac 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/import-scripts-updated-flag.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/import-scripts-updated-flag.https-expected.txt >@@ -2,6 +2,6 @@ > PASS initialize global state > PASS import script previously imported at worker evaluation time > PASS import script previously imported at worker install time >-FAIL import script not previously imported assert_equals: expected (string) "TypeError" but got (object) null >+FAIL import script not previously imported assert_equals: expected (string) "NetworkError" but got (object) null > PASS Tests for importScripts: import scripts updated flag > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/import-scripts-updated-flag.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/import-scripts-updated-flag.https.html >index 506827f89d5ffd55e847950d3e31e922456e6dd7..09b4496aa0ec1d28b9e101a6ba8a41a31b654540 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/import-scripts-updated-flag.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/import-scripts-updated-flag.https.html >@@ -75,7 +75,7 @@ promise_test(t => { > return post_and_wait_for_reply(worker, 'message'); > }) > .then(result => { >- assert_equals(result.error, 'TypeError'); >+ assert_equals(result.error, 'NetworkError'); > assert_equals(result.value, null); > }); > }, 'import script not previously imported'); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/interfaces-sw.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/interfaces-sw.https-expected.txt >index eabace72138b229651b443f18520bfabd1791628..4c6aa6cd9e0d4225493b764da935904bbea02508 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/interfaces-sw.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/interfaces-sw.https-expected.txt >@@ -1,249 +1,28 @@ > > PASS Interfaces and attributes in ServiceWorkerGlobalScope >-PASS test setup (cache creation) >+FAIL test setup (cache creation) promise_test: Unhandled rejection with value: object "Got an error before parsing any named definition: Unrecognised tokens, line 1 (tokens: '{"error": {') >+[ >+ { >+ "type": "other", >+ "value": "{" >+ }, >+ { >+ "type": "string", >+ "value": "\"error\"" >+ }, >+ { >+ "type": "other", >+ "value": ":" >+ }, >+ { >+ "type": "whitespace", >+ "value": " " >+ }, >+ { >+ "type": "other", >+ "value": "{" >+ } >+]" > PASS Event constructors > PASS xhr is not exposed >-PASS ServiceWorkerGlobalScope interface: existence and properties of interface object >-PASS ServiceWorkerGlobalScope interface object length >-PASS ServiceWorkerGlobalScope interface object name >-PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object >-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Object.setPrototypeOf should throw a TypeError >-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via __proto__ should throw a TypeError >-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Reflect.setPrototypeOf should return false >-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Object.setPrototypeOf should not throw >-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via __proto__ should not throw >-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Reflect.setPrototypeOf should return true >-PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object's "constructor" property >-PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object's @@unscopables property >-PASS ServiceWorkerGlobalScope interface: attribute clients >-PASS Unscopable handled correctly for clients property on ServiceWorkerGlobalScope >-PASS ServiceWorkerGlobalScope interface: attribute registration >-PASS Unscopable handled correctly for registration property on ServiceWorkerGlobalScope >-PASS ServiceWorkerGlobalScope interface: operation skipWaiting() >-PASS Unscopable handled correctly for skipWaiting() on ServiceWorkerGlobalScope >-PASS ServiceWorkerGlobalScope interface: attribute oninstall >-PASS Unscopable handled correctly for oninstall property on ServiceWorkerGlobalScope >-PASS ServiceWorkerGlobalScope interface: attribute onactivate >-PASS Unscopable handled correctly for onactivate property on ServiceWorkerGlobalScope >-PASS ServiceWorkerGlobalScope interface: attribute onfetch >-PASS Unscopable handled correctly for onfetch property on ServiceWorkerGlobalScope >-PASS ServiceWorkerGlobalScope interface: attribute onmessage >-PASS Unscopable handled correctly for onmessage property on ServiceWorkerGlobalScope >-PASS ServiceWorkerGlobalScope interface: attribute onmessageerror >-PASS Unscopable handled correctly for onmessageerror property on ServiceWorkerGlobalScope >-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Object.setPrototypeOf should throw a TypeError >-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via __proto__ should throw a TypeError >-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Reflect.setPrototypeOf should return false >-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Object.setPrototypeOf should not throw >-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via __proto__ should not throw >-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Reflect.setPrototypeOf should return true >-PASS ServiceWorkerGlobalScope must be primary interface of self >-PASS Stringification of self >-PASS ServiceWorkerGlobalScope interface: self must inherit property "clients" with the proper type >-PASS ServiceWorkerGlobalScope interface: self must inherit property "registration" with the proper type >-PASS ServiceWorkerGlobalScope interface: self must inherit property "skipWaiting()" with the proper type >-PASS ServiceWorkerGlobalScope interface: self must inherit property "oninstall" with the proper type >-PASS ServiceWorkerGlobalScope interface: self must inherit property "onactivate" with the proper type >-PASS ServiceWorkerGlobalScope interface: self must inherit property "onfetch" with the proper type >-PASS ServiceWorkerGlobalScope interface: self must inherit property "onmessage" with the proper type >-PASS ServiceWorkerGlobalScope interface: self must inherit property "onmessageerror" with the proper type >-PASS Client interface: existence and properties of interface object >-PASS Client interface object length >-PASS Client interface object name >-PASS Client interface: existence and properties of interface prototype object >-PASS Client interface: existence and properties of interface prototype object's "constructor" property >-PASS Client interface: existence and properties of interface prototype object's @@unscopables property >-PASS Client interface: attribute url >-PASS Unscopable handled correctly for url property on Client >-PASS Client interface: attribute id >-PASS Unscopable handled correctly for id property on Client >-PASS Client interface: attribute type >-PASS Unscopable handled correctly for type property on Client >-FAIL Client interface: attribute reserved assert_true: The prototype object must have a property "reserved" expected true got false >-PASS Unscopable handled correctly for reserved property on Client >-PASS Client interface: operation postMessage(any, [object Object]) >-PASS Unscopable handled correctly for postMessage(any, [object Object]) on Client >-PASS WindowClient interface: existence and properties of interface object >-PASS WindowClient interface object length >-PASS WindowClient interface object name >-PASS WindowClient interface: existence and properties of interface prototype object >-PASS WindowClient interface: existence and properties of interface prototype object's "constructor" property >-PASS WindowClient interface: existence and properties of interface prototype object's @@unscopables property >-PASS WindowClient interface: attribute visibilityState >-PASS Unscopable handled correctly for visibilityState property on WindowClient >-PASS WindowClient interface: attribute focused >-PASS Unscopable handled correctly for focused property on WindowClient >-FAIL WindowClient interface: attribute ancestorOrigins assert_true: The prototype object must have a property "ancestorOrigins" expected true got false >-PASS Unscopable handled correctly for ancestorOrigins property on WindowClient >-PASS WindowClient interface: operation focus() >-PASS Unscopable handled correctly for focus() on WindowClient >-PASS WindowClient interface: operation navigate(USVString) >-PASS Unscopable handled correctly for navigate(USVString) on WindowClient >-PASS Clients interface: existence and properties of interface object >-PASS Clients interface object length >-PASS Clients interface object name >-PASS Clients interface: existence and properties of interface prototype object >-PASS Clients interface: existence and properties of interface prototype object's "constructor" property >-PASS Clients interface: existence and properties of interface prototype object's @@unscopables property >-PASS Clients interface: operation get(DOMString) >-PASS Unscopable handled correctly for get(DOMString) on Clients >-PASS Clients interface: operation matchAll(ClientQueryOptions) >-PASS Unscopable handled correctly for matchAll(ClientQueryOptions) on Clients >-PASS Clients interface: operation openWindow(USVString) >-PASS Unscopable handled correctly for openWindow(USVString) on Clients >-PASS Clients interface: operation claim() >-PASS Unscopable handled correctly for claim() on Clients >-PASS Clients must be primary interface of self.clients >-PASS Stringification of self.clients >-PASS Clients interface: self.clients must inherit property "get(DOMString)" with the proper type >-PASS Clients interface: calling get(DOMString) on self.clients with too few arguments must throw TypeError >-PASS Clients interface: self.clients must inherit property "matchAll(ClientQueryOptions)" with the proper type >-PASS Clients interface: calling matchAll(ClientQueryOptions) on self.clients with too few arguments must throw TypeError >-PASS Clients interface: self.clients must inherit property "openWindow(USVString)" with the proper type >-PASS Clients interface: calling openWindow(USVString) on self.clients with too few arguments must throw TypeError >-PASS Clients interface: self.clients must inherit property "claim()" with the proper type >-PASS ServiceWorker interface: existence and properties of interface object >-PASS ServiceWorker interface object length >-PASS ServiceWorker interface object name >-PASS ServiceWorker interface: existence and properties of interface prototype object >-PASS ServiceWorker interface: existence and properties of interface prototype object's "constructor" property >-PASS ServiceWorker interface: existence and properties of interface prototype object's @@unscopables property >-PASS ServiceWorker interface: attribute scriptURL >-PASS Unscopable handled correctly for scriptURL property on ServiceWorker >-PASS ServiceWorker interface: attribute state >-PASS Unscopable handled correctly for state property on ServiceWorker >-PASS ServiceWorker interface: operation postMessage(any, [object Object]) >-PASS Unscopable handled correctly for postMessage(any, [object Object]) on ServiceWorker >-PASS ServiceWorker interface: attribute onstatechange >-PASS Unscopable handled correctly for onstatechange property on ServiceWorker >-PASS ServiceWorkerRegistration interface: existence and properties of interface object >-PASS ServiceWorkerRegistration interface object length >-PASS ServiceWorkerRegistration interface object name >-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object >-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property >-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's @@unscopables property >-PASS ServiceWorkerRegistration interface: attribute installing >-PASS Unscopable handled correctly for installing property on ServiceWorkerRegistration >-PASS ServiceWorkerRegistration interface: attribute waiting >-PASS Unscopable handled correctly for waiting property on ServiceWorkerRegistration >-PASS ServiceWorkerRegistration interface: attribute active >-PASS Unscopable handled correctly for active property on ServiceWorkerRegistration >-FAIL ServiceWorkerRegistration interface: attribute navigationPreload assert_true: The prototype object must have a property "navigationPreload" expected true got false >-PASS Unscopable handled correctly for navigationPreload property on ServiceWorkerRegistration >-PASS ServiceWorkerRegistration interface: attribute scope >-PASS Unscopable handled correctly for scope property on ServiceWorkerRegistration >-PASS ServiceWorkerRegistration interface: attribute updateViaCache >-PASS Unscopable handled correctly for updateViaCache property on ServiceWorkerRegistration >-PASS ServiceWorkerRegistration interface: operation update() >-PASS Unscopable handled correctly for update() on ServiceWorkerRegistration >-PASS ServiceWorkerRegistration interface: operation unregister() >-PASS Unscopable handled correctly for unregister() on ServiceWorkerRegistration >-PASS ServiceWorkerRegistration interface: attribute onupdatefound >-PASS Unscopable handled correctly for onupdatefound property on ServiceWorkerRegistration >-PASS ServiceWorkerRegistration must be primary interface of self.registration >-PASS Stringification of self.registration >-PASS ServiceWorkerRegistration interface: self.registration must inherit property "installing" with the proper type >-PASS ServiceWorkerRegistration interface: self.registration must inherit property "waiting" with the proper type >-PASS ServiceWorkerRegistration interface: self.registration must inherit property "active" with the proper type >-FAIL ServiceWorkerRegistration interface: self.registration must inherit property "navigationPreload" with the proper type assert_inherits: property "navigationPreload" not found in prototype chain >-PASS ServiceWorkerRegistration interface: self.registration must inherit property "scope" with the proper type >-PASS ServiceWorkerRegistration interface: self.registration must inherit property "updateViaCache" with the proper type >-PASS ServiceWorkerRegistration interface: self.registration must inherit property "update()" with the proper type >-PASS ServiceWorkerRegistration interface: self.registration must inherit property "unregister()" with the proper type >-PASS ServiceWorkerRegistration interface: self.registration must inherit property "onupdatefound" with the proper type >-PASS EventTarget interface: self.registration must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type >-PASS EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on self.registration with too few arguments must throw TypeError >-PASS EventTarget interface: self.registration must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type >-PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on self.registration with too few arguments must throw TypeError >-PASS EventTarget interface: self.registration must inherit property "dispatchEvent(Event)" with the proper type >-PASS EventTarget interface: calling dispatchEvent(Event) on self.registration with too few arguments must throw TypeError >-PASS EventTarget interface: existence and properties of interface object >-PASS EventTarget interface object length >-PASS EventTarget interface object name >-PASS EventTarget interface: existence and properties of interface prototype object >-PASS EventTarget interface: existence and properties of interface prototype object's "constructor" property >-PASS EventTarget interface: existence and properties of interface prototype object's @@unscopables property >-PASS EventTarget interface: operation addEventListener(DOMString, EventListener, [object Object],[object Object]) >-PASS Unscopable handled correctly for addEventListener(DOMString, EventListener, [object Object],[object Object]) on EventTarget >-PASS EventTarget interface: operation removeEventListener(DOMString, EventListener, [object Object],[object Object]) >-PASS Unscopable handled correctly for removeEventListener(DOMString, EventListener, [object Object],[object Object]) on EventTarget >-PASS EventTarget interface: operation dispatchEvent(Event) >-PASS Unscopable handled correctly for dispatchEvent(Event) on EventTarget >-FAIL NavigationPreloadManager interface: existence and properties of interface object assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-FAIL NavigationPreloadManager interface object length assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-FAIL NavigationPreloadManager interface object name assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-FAIL NavigationPreloadManager interface: existence and properties of interface prototype object assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-FAIL NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-FAIL NavigationPreloadManager interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-FAIL NavigationPreloadManager interface: operation enable() assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-PASS Unscopable handled correctly for enable() on NavigationPreloadManager >-FAIL NavigationPreloadManager interface: operation disable() assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-PASS Unscopable handled correctly for disable() on NavigationPreloadManager >-FAIL NavigationPreloadManager interface: operation setHeaderValue(ByteString) assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-PASS Unscopable handled correctly for setHeaderValue(ByteString) on NavigationPreloadManager >-FAIL NavigationPreloadManager interface: operation getState() assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-PASS Unscopable handled correctly for getState() on NavigationPreloadManager >-PASS Cache interface: existence and properties of interface object >-PASS Cache interface object length >-PASS Cache interface object name >-PASS Cache interface: existence and properties of interface prototype object >-PASS Cache interface: existence and properties of interface prototype object's "constructor" property >-PASS Cache interface: existence and properties of interface prototype object's @@unscopables property >-PASS Cache interface: operation match(RequestInfo, CacheQueryOptions) >-PASS Unscopable handled correctly for match(RequestInfo, CacheQueryOptions) on Cache >-PASS Cache interface: operation matchAll(RequestInfo, CacheQueryOptions) >-PASS Unscopable handled correctly for matchAll(RequestInfo, CacheQueryOptions) on Cache >-PASS Cache interface: operation add(RequestInfo) >-PASS Unscopable handled correctly for add(RequestInfo) on Cache >-PASS Cache interface: operation addAll([object Object]) >-PASS Unscopable handled correctly for addAll([object Object]) on Cache >-PASS Cache interface: operation put(RequestInfo, Response) >-PASS Unscopable handled correctly for put(RequestInfo, Response) on Cache >-PASS Cache interface: operation delete(RequestInfo, CacheQueryOptions) >-PASS Unscopable handled correctly for delete(RequestInfo, CacheQueryOptions) on Cache >-PASS Cache interface: operation keys(RequestInfo, CacheQueryOptions) >-PASS Unscopable handled correctly for keys(RequestInfo, CacheQueryOptions) on Cache >-PASS Cache must be primary interface of self.cacheInstance >-PASS Stringification of self.cacheInstance >-PASS Cache interface: self.cacheInstance must inherit property "match(RequestInfo, CacheQueryOptions)" with the proper type >-PASS Cache interface: calling match(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError >-PASS Cache interface: self.cacheInstance must inherit property "matchAll(RequestInfo, CacheQueryOptions)" with the proper type >-PASS Cache interface: calling matchAll(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError >-PASS Cache interface: self.cacheInstance must inherit property "add(RequestInfo)" with the proper type >-PASS Cache interface: calling add(RequestInfo) on self.cacheInstance with too few arguments must throw TypeError >-PASS Cache interface: self.cacheInstance must inherit property "addAll([object Object])" with the proper type >-PASS Cache interface: calling addAll([object Object]) on self.cacheInstance with too few arguments must throw TypeError >-PASS Cache interface: self.cacheInstance must inherit property "put(RequestInfo, Response)" with the proper type >-PASS Cache interface: calling put(RequestInfo, Response) on self.cacheInstance with too few arguments must throw TypeError >-PASS Cache interface: self.cacheInstance must inherit property "delete(RequestInfo, CacheQueryOptions)" with the proper type >-PASS Cache interface: calling delete(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError >-PASS Cache interface: self.cacheInstance must inherit property "keys(RequestInfo, CacheQueryOptions)" with the proper type >-PASS Cache interface: calling keys(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError >-PASS CacheStorage interface: existence and properties of interface object >-PASS CacheStorage interface object length >-PASS CacheStorage interface object name >-PASS CacheStorage interface: existence and properties of interface prototype object >-PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property >-PASS CacheStorage interface: existence and properties of interface prototype object's @@unscopables property >-PASS CacheStorage interface: operation match(RequestInfo, CacheQueryOptions) >-PASS Unscopable handled correctly for match(RequestInfo, CacheQueryOptions) on CacheStorage >-PASS CacheStorage interface: operation has(DOMString) >-PASS Unscopable handled correctly for has(DOMString) on CacheStorage >-PASS CacheStorage interface: operation open(DOMString) >-PASS Unscopable handled correctly for open(DOMString) on CacheStorage >-PASS CacheStorage interface: operation delete(DOMString) >-PASS Unscopable handled correctly for delete(DOMString) on CacheStorage >-PASS CacheStorage interface: operation keys() >-PASS Unscopable handled correctly for keys() on CacheStorage >-PASS CacheStorage must be primary interface of self.caches >-PASS Stringification of self.caches >-PASS CacheStorage interface: self.caches must inherit property "match(RequestInfo, CacheQueryOptions)" with the proper type >-PASS CacheStorage interface: calling match(RequestInfo, CacheQueryOptions) on self.caches with too few arguments must throw TypeError >-PASS CacheStorage interface: self.caches must inherit property "has(DOMString)" with the proper type >-PASS CacheStorage interface: calling has(DOMString) on self.caches with too few arguments must throw TypeError >-PASS CacheStorage interface: self.caches must inherit property "open(DOMString)" with the proper type >-PASS CacheStorage interface: calling open(DOMString) on self.caches with too few arguments must throw TypeError >-PASS CacheStorage interface: self.caches must inherit property "delete(DOMString)" with the proper type >-PASS CacheStorage interface: calling delete(DOMString) on self.caches with too few arguments must throw TypeError >-PASS CacheStorage interface: self.caches must inherit property "keys()" with the proper type > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/interfaces-window.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/interfaces-window.https-expected.txt >index ddc970696deaff393f69b6768af7b736ea2828dc..06675a6795bfff1089593c8360262676faa7b5a4 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/interfaces-window.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/interfaces-window.https-expected.txt >@@ -1,139 +1,26 @@ >-CONSOLE MESSAGE: line 331: callback not yet supported >+CONSOLE MESSAGE: line 440: callback not yet supported > >-PASS test setup (worker registration) >-PASS WorkerGlobalScope interface: existence and properties of interface object >-PASS ServiceWorkerGlobalScope interface: existence and properties of interface object >-PASS Client interface: existence and properties of interface object >-PASS WindowClient interface: existence and properties of interface object >-PASS Clients interface: existence and properties of interface object >-PASS ServiceWorker interface: existence and properties of interface object >-PASS ServiceWorker interface object length >-PASS ServiceWorker interface object name >-PASS ServiceWorker interface: existence and properties of interface prototype object >-PASS ServiceWorker interface: existence and properties of interface prototype object's "constructor" property >-PASS ServiceWorker interface: existence and properties of interface prototype object's @@unscopables property >-PASS ServiceWorker interface: attribute scriptURL >-PASS Unscopable handled correctly for scriptURL property on ServiceWorker >-PASS ServiceWorker interface: attribute state >-PASS Unscopable handled correctly for state property on ServiceWorker >-PASS ServiceWorker interface: operation postMessage(any, [object Object]) >-PASS Unscopable handled correctly for postMessage(any, [object Object]) on ServiceWorker >-PASS ServiceWorker interface: attribute onstatechange >-PASS Unscopable handled correctly for onstatechange property on ServiceWorker >-PASS ServiceWorker must be primary interface of window.registrationInstance.installing >-PASS Stringification of window.registrationInstance.installing >-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "scriptURL" with the proper type >-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "state" with the proper type >-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "postMessage(any, [object Object])" with the proper type >-PASS ServiceWorker interface: calling postMessage(any, [object Object]) on window.registrationInstance.installing with too few arguments must throw TypeError >-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "onstatechange" with the proper type >-PASS EventTarget interface: window.registrationInstance.installing must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type >-PASS EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance.installing with too few arguments must throw TypeError >-PASS EventTarget interface: window.registrationInstance.installing must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type >-PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance.installing with too few arguments must throw TypeError >-PASS EventTarget interface: window.registrationInstance.installing must inherit property "dispatchEvent(Event)" with the proper type >-PASS EventTarget interface: calling dispatchEvent(Event) on window.registrationInstance.installing with too few arguments must throw TypeError >-PASS ServiceWorkerRegistration interface: existence and properties of interface object >-PASS ServiceWorkerRegistration interface object length >-PASS ServiceWorkerRegistration interface object name >-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object >-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property >-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's @@unscopables property >-PASS ServiceWorkerRegistration interface: attribute installing >-PASS Unscopable handled correctly for installing property on ServiceWorkerRegistration >-PASS ServiceWorkerRegistration interface: attribute waiting >-PASS Unscopable handled correctly for waiting property on ServiceWorkerRegistration >-PASS ServiceWorkerRegistration interface: attribute active >-PASS Unscopable handled correctly for active property on ServiceWorkerRegistration >-FAIL ServiceWorkerRegistration interface: attribute navigationPreload assert_true: The prototype object must have a property "navigationPreload" expected true got false >-PASS Unscopable handled correctly for navigationPreload property on ServiceWorkerRegistration >-PASS ServiceWorkerRegistration interface: attribute scope >-PASS Unscopable handled correctly for scope property on ServiceWorkerRegistration >-PASS ServiceWorkerRegistration interface: attribute updateViaCache >-PASS Unscopable handled correctly for updateViaCache property on ServiceWorkerRegistration >-PASS ServiceWorkerRegistration interface: operation update() >-PASS Unscopable handled correctly for update() on ServiceWorkerRegistration >-PASS ServiceWorkerRegistration interface: operation unregister() >-PASS Unscopable handled correctly for unregister() on ServiceWorkerRegistration >-PASS ServiceWorkerRegistration interface: attribute onupdatefound >-PASS Unscopable handled correctly for onupdatefound property on ServiceWorkerRegistration >-PASS ServiceWorkerRegistration must be primary interface of window.registrationInstance >-PASS Stringification of window.registrationInstance >-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "installing" with the proper type >-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "waiting" with the proper type >-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "active" with the proper type >-FAIL ServiceWorkerRegistration interface: window.registrationInstance must inherit property "navigationPreload" with the proper type assert_inherits: property "navigationPreload" not found in prototype chain >-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "scope" with the proper type >-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "updateViaCache" with the proper type >-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "update()" with the proper type >-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "unregister()" with the proper type >-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "onupdatefound" with the proper type >-PASS EventTarget interface: window.registrationInstance must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type >-PASS EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance with too few arguments must throw TypeError >-PASS EventTarget interface: window.registrationInstance must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type >-PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance with too few arguments must throw TypeError >-PASS EventTarget interface: window.registrationInstance must inherit property "dispatchEvent(Event)" with the proper type >-PASS EventTarget interface: calling dispatchEvent(Event) on window.registrationInstance with too few arguments must throw TypeError >-PASS EventTarget interface: existence and properties of interface object >-PASS EventTarget interface object length >-PASS EventTarget interface object name >-PASS EventTarget interface: existence and properties of interface prototype object >-PASS EventTarget interface: existence and properties of interface prototype object's "constructor" property >-PASS EventTarget interface: existence and properties of interface prototype object's @@unscopables property >-PASS EventTarget interface: operation addEventListener(DOMString, EventListener, [object Object],[object Object]) >-PASS Unscopable handled correctly for addEventListener(DOMString, EventListener, [object Object],[object Object]) on EventTarget >-PASS EventTarget interface: operation removeEventListener(DOMString, EventListener, [object Object],[object Object]) >-PASS Unscopable handled correctly for removeEventListener(DOMString, EventListener, [object Object],[object Object]) on EventTarget >-PASS EventTarget interface: operation dispatchEvent(Event) >-PASS Unscopable handled correctly for dispatchEvent(Event) on EventTarget >-FAIL NavigationPreloadManager interface: existence and properties of interface object assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-FAIL NavigationPreloadManager interface object length assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-FAIL NavigationPreloadManager interface object name assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-FAIL NavigationPreloadManager interface: existence and properties of interface prototype object assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-FAIL NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-FAIL NavigationPreloadManager interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-FAIL NavigationPreloadManager interface: operation enable() assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-PASS Unscopable handled correctly for enable() on NavigationPreloadManager >-FAIL NavigationPreloadManager interface: operation disable() assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-PASS Unscopable handled correctly for disable() on NavigationPreloadManager >-FAIL NavigationPreloadManager interface: operation setHeaderValue(ByteString) assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-PASS Unscopable handled correctly for setHeaderValue(ByteString) on NavigationPreloadManager >-FAIL NavigationPreloadManager interface: operation getState() assert_own_property: self does not have own property "NavigationPreloadManager" expected property "NavigationPreloadManager" missing >-PASS Unscopable handled correctly for getState() on NavigationPreloadManager >-PASS Cache interface: existence and properties of interface object >-PASS Cache interface object length >-PASS Cache interface object name >-PASS Cache interface: existence and properties of interface prototype object >-PASS Cache interface: existence and properties of interface prototype object's "constructor" property >-PASS Cache interface: existence and properties of interface prototype object's @@unscopables property >-PASS Cache interface: operation match(RequestInfo, CacheQueryOptions) >-PASS Unscopable handled correctly for match(RequestInfo, CacheQueryOptions) on Cache >-PASS Cache interface: operation matchAll(RequestInfo, CacheQueryOptions) >-PASS Unscopable handled correctly for matchAll(RequestInfo, CacheQueryOptions) on Cache >-PASS Cache interface: operation add(RequestInfo) >-PASS Unscopable handled correctly for add(RequestInfo) on Cache >-PASS Cache interface: operation addAll([object Object]) >-PASS Unscopable handled correctly for addAll([object Object]) on Cache >-PASS Cache interface: operation put(RequestInfo, Response) >-PASS Unscopable handled correctly for put(RequestInfo, Response) on Cache >-PASS Cache interface: operation delete(RequestInfo, CacheQueryOptions) >-PASS Unscopable handled correctly for delete(RequestInfo, CacheQueryOptions) on Cache >-PASS Cache interface: operation keys(RequestInfo, CacheQueryOptions) >-PASS Unscopable handled correctly for keys(RequestInfo, CacheQueryOptions) on Cache >-PASS CacheStorage interface: existence and properties of interface object >-PASS CacheStorage interface object length >-PASS CacheStorage interface object name >-PASS CacheStorage interface: existence and properties of interface prototype object >-PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property >-PASS CacheStorage interface: existence and properties of interface prototype object's @@unscopables property >-PASS CacheStorage interface: operation match(RequestInfo, CacheQueryOptions) >-PASS Unscopable handled correctly for match(RequestInfo, CacheQueryOptions) on CacheStorage >-PASS CacheStorage interface: operation has(DOMString) >-PASS Unscopable handled correctly for has(DOMString) on CacheStorage >-PASS CacheStorage interface: operation open(DOMString) >-PASS Unscopable handled correctly for open(DOMString) on CacheStorage >-PASS CacheStorage interface: operation delete(DOMString) >-PASS Unscopable handled correctly for delete(DOMString) on CacheStorage >-PASS CacheStorage interface: operation keys() >-PASS Unscopable handled correctly for keys() on CacheStorage >+FAIL test setup (worker registration) promise_test: Unhandled rejection with value: object "Got an error before parsing any named definition: Unrecognised tokens, line 1 (tokens: '{"error": {') >+[ >+ { >+ "type": "other", >+ "value": "{" >+ }, >+ { >+ "type": "string", >+ "value": "\"error\"" >+ }, >+ { >+ "type": "other", >+ "value": ":" >+ }, >+ { >+ "type": "whitespace", >+ "value": " " >+ }, >+ { >+ "type": "other", >+ "value": "{" >+ } >+]" > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/interfaces-window.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/interfaces-window.https.html >index 7097df0616061e4872cf23ab04ccf97bf8f9f079..54f83f202c31319ba1c53ac049cd5eaa510bb6b2 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/interfaces-window.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/interfaces-window.https.html >@@ -9,29 +9,45 @@ > <script> > 'use strict'; > >-var idlArray = new IdlArray(); >-idlArray.add_untested_idls(idls.untested); >-idlArray.add_idls(idls.tested); >-idlArray.add_objects({ >+promise_test(async (t) => { >+ var idlArray = new IdlArray(); >+ const dom = await fetch('/interfaces/dom.idl').then(r => r.text()); >+ const serviceWorkerIdl = await fetch('/interfaces/ServiceWorker.idl').then(r => r.text()); >+ >+ idlArray.add_untested_idls(idls.untested); >+ idlArray.add_untested_idls(dom, { only: ['EventTarget'] }); >+ idlArray.add_idls(serviceWorkerIdl, { only: [ >+ 'ServiceWorkerGlobalScope', >+ 'Client', >+ 'WindowClient', >+ 'Clients', >+ 'ServiceWorker', >+ 'ServiceWorkerState', >+ 'ServiceWorkerUpdateViaCache', >+ 'ServiceWorkerRegistration', >+ 'EventTarget', >+ 'NavigationPreloadManager', >+ 'Cache', >+ 'CacheStorage', >+ ]}); >+ idlArray.add_objects({ > ServiceWorkerContainer: ['navigator.serviceWorker'] > }); >+ var scope = 'resources/scope/interfaces-and-attributes'; > >-promise_test(function(t) { >- var scope = 'resources/scope/interfaces-and-attributes'; >- >- return service_worker_unregister_and_register( >- t, 'resources/empty-worker.js', scope) >- .then(function(registration) { >- t.add_cleanup(function() { >- registration.unregister(); >- }); >+ return service_worker_unregister_and_register( >+ t, 'resources/empty-worker.js', scope) >+ .then(function(registration) { >+ t.add_cleanup(function() { >+ registration.unregister(); >+ }); > >- window.registrationInstance = registration; >- idlArray.add_objects({ >- ServiceWorkerRegistration: ['window.registrationInstance'], >- ServiceWorker: ['window.registrationInstance.installing'] >- }); >- idlArray.test(); >- }); >- }, 'test setup (worker registration)'); >+ window.registrationInstance = registration; >+ idlArray.add_objects({ >+ ServiceWorkerRegistration: ['window.registrationInstance'], >+ ServiceWorker: ['window.registrationInstance.installing'] >+ }); >+ idlArray.test(); >+ }); >+}, 'test setup (worker registration)'); > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/local-url-inherit-controller.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/local-url-inherit-controller.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..b602dc6c37b3a0e7ea075eeeae351533b1125121 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/local-url-inherit-controller.https-expected.txt >@@ -0,0 +1,10 @@ >+ >+PASS Same-origin blob URL iframe should inherit service worker controller. >+PASS Same-origin blob URL iframe should intercept fetch(). >+FAIL Same-origin blob URL worker should inherit service worker controller. assert_equals: blob URL worker should inherit controller expected (string) "https://localhost:9443/service-workers/service-worker/resources/local-url-inherit-controller-worker.js" but got (object) null >+PASS Same-origin blob URL worker should intercept fetch(). >+FAIL Data URL iframe should not inherit service worker controller. assert_equals: data URL iframe should not inherit controller expected (object) null but got (string) "https://localhost:9443/service-workers/service-worker/resources/local-url-inherit-controller-worker.js" >+FAIL Data URL iframe should not intercept fetch(). assert_equals: data URL iframe should not intercept fetch expected "" but got "intercepted" >+FAIL Data URL worker should not inherit service worker controller. promise_test: Unhandled rejection with value: object "SecurityError: The operation is insecure." >+FAIL Data URL worker should not intercept fetch(). promise_test: Unhandled rejection with value: object "SecurityError: The operation is insecure." >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/local-url-inherit-controller.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/local-url-inherit-controller.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..df25051b25748211622b26fc25f145f1c7212c8d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/local-url-inherit-controller.https.html >@@ -0,0 +1,129 @@ >+<!DOCTYPE html> >+<title>Service Worker: local URL windows and workers inherit controller</title> >+<meta name=timeout content=long> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/get-host-info.sub.js"></script> >+<script src="resources/test-helpers.sub.js"></script> >+<body> >+<script> >+ >+const SCRIPT = 'resources/local-url-inherit-controller-worker.js'; >+const SCOPE = 'resources/local-url-inherit-controller-frame.html'; >+ >+async function doAsyncTest(t, opts) { >+ let name = `${opts.scheme}-${opts.child}-${opts.check}`; >+ let scope = SCOPE + '?name=' + name; >+ let reg = await service_worker_unregister_and_register(t, SCRIPT, scope); >+ add_completion_callback(_ => reg.unregister()); >+ await wait_for_state(t, reg.installing, 'activated'); >+ >+ let frame = await with_iframe(scope); >+ add_completion_callback(_ => frame.remove()); >+ assert_not_equals(frame.contentWindow.navigator.serviceWorker.controller, null, >+ 'frame should be controlled'); >+ >+ let result = await frame.contentWindow.checkChildController(opts); >+ result = result.data; >+ >+ let expect = 'unexpected'; >+ if (opts.check === 'controller') { >+ expect = opts.expect === 'inherit' >+ ? frame.contentWindow.navigator.serviceWorker.controller.scriptURL >+ : null; >+ } else if (opts.check === 'fetch') { >+ // The service worker FetchEvent handler will provide an "intercepted" >+ // body. If the local URL ends up with an opaque origin and is not >+ // intercepted then it will get an opaque Response. In that case it >+ // should see an empty string body. >+ expect = opts.expect === 'intercept' ? 'intercepted' : ''; >+ } >+ >+ assert_equals(result, expect, >+ `${opts.scheme} URL ${opts.child} should ${opts.expect} ${opts.check}`); >+} >+ >+promise_test(function(t) { >+ return doAsyncTest(t, { >+ scheme: 'blob', >+ child: 'iframe', >+ check: 'controller', >+ expect: 'inherit', >+ }); >+}, 'Same-origin blob URL iframe should inherit service worker controller.'); >+ >+promise_test(function(t) { >+ return doAsyncTest(t, { >+ scheme: 'blob', >+ child: 'iframe', >+ check: 'fetch', >+ expect: 'intercept', >+ }); >+}, 'Same-origin blob URL iframe should intercept fetch().'); >+ >+promise_test(function(t) { >+ return doAsyncTest(t, { >+ scheme: 'blob', >+ child: 'worker', >+ check: 'controller', >+ expect: 'inherit', >+ }); >+}, 'Same-origin blob URL worker should inherit service worker controller.'); >+ >+promise_test(function(t) { >+ return doAsyncTest(t, { >+ scheme: 'blob', >+ child: 'worker', >+ check: 'fetch', >+ expect: 'intercept', >+ }); >+}, 'Same-origin blob URL worker should intercept fetch().'); >+ >+promise_test(function(t) { >+ // Data URLs should result in an opaque origin and should probably not >+ // have access to a cross-origin service worker. See: >+ // >+ // https://github.com/w3c/ServiceWorker/issues/1262 >+ // >+ return doAsyncTest(t, { >+ scheme: 'data', >+ child: 'iframe', >+ check: 'controller', >+ expect: 'not inherit', >+ }); >+}, 'Data URL iframe should not inherit service worker controller.'); >+ >+promise_test(function(t) { >+ return doAsyncTest(t, { >+ scheme: 'data', >+ child: 'iframe', >+ check: 'fetch', >+ expect: 'not intercept', >+ }); >+}, 'Data URL iframe should not intercept fetch().'); >+ >+promise_test(function(t) { >+ // Data URLs should result in an opaque origin and should probably not >+ // have access to a cross-origin service worker. See: >+ // >+ // https://github.com/w3c/ServiceWorker/issues/1262 >+ // >+ return doAsyncTest(t, { >+ scheme: 'data', >+ child: 'worker', >+ check: 'controller', >+ expect: 'not inherit', >+ }); >+}, 'Data URL worker should not inherit service worker controller.'); >+ >+promise_test(function(t) { >+ return doAsyncTest(t, { >+ scheme: 'data', >+ child: 'worker', >+ check: 'fetch', >+ expect: 'not intercept', >+ }); >+}, 'Data URL worker should not intercept fetch().'); >+ >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/multipart-image.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/multipart-image.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..9febb7db5dd224ada695a81f9c24998987c1e002 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/multipart-image.https-expected.txt >@@ -0,0 +1,11 @@ >+ >+ >+Harness Error (TIMEOUT), message = null >+ >+PASS initialize global state >+TIMEOUT same-origin multipart image via SW should be readable Test timed out >+NOTRUN cross-origin multipart image via SW with approved CORS should be readable >+NOTRUN cross-origin multipart image with no-cors via SW should not be readable >+NOTRUN cross-origin multipart image via SW with rejected CORS should fail to load >+NOTRUN restore global state >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/multipart-image.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/multipart-image.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..9bdadff21fbbac84e6150724a3a9bfdb035be38f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/multipart-image.https.html >@@ -0,0 +1,67 @@ >+<!DOCTYPE html> >+<title>Tests for cross-origin multipart image returned by service worker</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/test-helpers.sub.js"></script> >+ >+<script> >+// This tests loading a multipart image via service worker. The service worker responds with >+// an opaque or a non-opaque response. The content of opaque response should not be readable. >+ >+const script = 'resources/multipart-image-worker.js'; >+const scope = 'resources/multipart-image-iframe.html'; >+let frame; >+ >+function check_image_data(data) { >+ assert_equals(data[0], 255); >+ assert_equals(data[1], 0); >+ assert_equals(data[2], 0); >+ assert_equals(data[3], 255); >+} >+ >+promise_test(t => { >+ return service_worker_unregister_and_register(t, script, scope) >+ .then(registration => { >+ promise_test(() => { >+ if (frame) { >+ frame.remove(); >+ } >+ return registration.unregister(); >+ }, 'restore global state'); >+ >+ return wait_for_state(t, registration.installing, 'activated'); >+ }) >+ .then(() => with_iframe(scope)) >+ .then(f => { >+ frame = f; >+ }); >+ }, 'initialize global state'); >+ >+promise_test(t => { >+ return frame.contentWindow.load_multipart_image('same-origin-multipart-image') >+ .then(img => frame.contentWindow.get_image_data(img)) >+ .then(img_data => { >+ check_image_data(img_data.data); >+ }); >+ }, 'same-origin multipart image via SW should be readable'); >+ >+promise_test(t => { >+ return frame.contentWindow.load_multipart_image('cross-origin-multipart-image-with-cors-approved') >+ .then(img => frame.contentWindow.get_image_data(img)) >+ .then(img_data => { >+ check_image_data(img_data.data); >+ }); >+ }, 'cross-origin multipart image via SW with approved CORS should be readable'); >+ >+promise_test(t => { >+ return frame.contentWindow.load_multipart_image('cross-origin-multipart-image-with-no-cors') >+ .then(img => { >+ assert_throws('SecurityError', () => frame.contentWindow.get_image_data(img)); >+ }); >+ }, 'cross-origin multipart image with no-cors via SW should not be readable'); >+ >+promise_test(t => { >+ const promise = frame.contentWindow.load_multipart_image('cross-origin-multipart-image-with-cors-rejected'); >+ return promise_rejects(t, new DOMException('load failed', 'NetworkError'), promise); >+ }, 'cross-origin multipart image via SW with rejected CORS should fail to load'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigate-window.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigate-window.https.html >index 3c8533a80004702fef2db781eec5637b3ffba898..46d32a48a0ad9d98b3bc882b59e8924e45ee9ebc 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigate-window.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigate-window.https.html >@@ -94,9 +94,9 @@ function validate_window(win, url, opts) { > resultList.sort(compare_urls); > > for (var i = 0; i < resultList.length; ++i) { >- assert_equals(expected[i].url, resultList[i].url, >+ assert_equals(resultList[i].url, expected[i].url, > 'client should have expected url'); >- assert_equals(expected[i].frameType, resultList[i].frameType, >+ assert_equals(resultList[i].frameType, expected[i].frameType, > 'client should have expected frame type'); > } > return win; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/broken-chunked-encoding.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/broken-chunked-encoding.https.html >index f8b088a70da2eb0d3b36e7b9daa804131c0f9804..ec74282ac330a34b68d3e0824128ecd6703ed43d 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/broken-chunked-encoding.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/broken-chunked-encoding.https.html >@@ -18,8 +18,25 @@ promise_test(t => { > .then(frame => { > assert_equals( > frame.contentDocument.body.textContent, >- 'Done'); >+ 'PASS: preloadResponse resolved'); > }); >- }, 'Navigation Preload with broken chunked encoding must fail.'); >+ }, 'FetchEvent#preloadResponse resolves even if the body is sent with broken chunked encoding.'); >+ >+promise_test(t => { >+ var script = 'resources/broken-chunked-encoding-worker.js'; >+ var scope = 'resources/chunked-encoding-scope.py?use_broken_body'; >+ return service_worker_unregister_and_register(t, script, scope) >+ .then(registration => { >+ add_completion_callback(_ => registration.unregister()); >+ var worker = registration.installing; >+ return wait_for_state(t, worker, 'activated'); >+ }) >+ .then(_ => with_iframe(scope)) >+ .then(frame => { >+ assert_equals( >+ frame.contentDocument.body.textContent, >+ 'PASS: preloadResponse resolved'); >+ }); >+ }, 'FetchEvent#preloadResponse resolves even if the body is sent with broken chunked encoding with some delays'); > > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/resource-timing.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/resource-timing.https.html >index 5f0953c76d13abcfc56a1016783a69087cb15e3b..b4756d09a162c5e2af6a05875dcd38cddf2ea752 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/resource-timing.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/resource-timing.https.html >@@ -14,9 +14,9 @@ function check_timing_entry(entry, url, decodedBodySize, encodedBodySize) { > 'The entryType of preload response timing entry must be "resource' + > '" :' + url); > assert_equals( >- entry.initiatorType, 'other', >+ entry.initiatorType, 'navigation', > 'The initiatorType of preload response timing entry must be ' + >- '"other":' + url); >+ '"navigation":' + url); > > // If the server returns the redirect response, |decodedBodySize| is null and > // |entry.decodedBodySize| shuld be 0. Otherwise |entry.decodedBodySize| must >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/resources/broken-chunked-encoding-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/resources/broken-chunked-encoding-worker.js >index 27268e856c7551bfbe816c9a37551e9a3f26dc9c..7a453e4055f0848a2250859efb91849e24355e51 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/resources/broken-chunked-encoding-worker.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/resources/broken-chunked-encoding-worker.js >@@ -6,6 +6,6 @@ self.addEventListener('activate', event => { > self.addEventListener('fetch', event => { > event.respondWith(event.preloadResponse > .then( >- _ => new Response('Fail: got a response'), >- _ => new Response('Done'))); >+ _ => new Response('PASS: preloadResponse resolved'), >+ _ => new Response('FAIL: preloadResponse rejected'))); > }); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/resources/chunked-encoding-scope.py b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/resources/chunked-encoding-scope.py >index c0a5ddce0b18d835a185ac8704c6ad618f3e7f12..3521b64f50fb1f0e17f66c0e376ffd101dae3211 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/resources/chunked-encoding-scope.py >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/resources/chunked-encoding-scope.py >@@ -1,7 +1,7 @@ > import time > > def main(request, response): >- body = "hello\nworld\n\n" >+ use_broken_body = 'use_broken_body' in request.GET > > response.add_required_headers = False > response.writer.write_status(200) >@@ -10,7 +10,10 @@ def main(request, response): > response.writer.end_headers() > > for idx in range(10): >- response.writer.write("%s\r\n%s\r\n" % (len(str(idx)), idx)) >+ if use_broken_body: >+ response.writer.write("%s\n%s\n" % (len(str(idx)), idx)) >+ else: >+ response.writer.write("%s\r\n%s\r\n" % (len(str(idx)), idx)) > response.writer.flush() > time.sleep(0.001) > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/resources/empty-preload-response-body-scope.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/resources/empty-preload-response-body-scope.html >new file mode 100644 >index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-redirect.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-redirect.https.html >index d840666b8c6a9833e631b631b83646e8c899c53d..3f12c2fdcca5ddcb5fd0dafc79dbfc2b7e1a67bb 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-redirect.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-redirect.https.html >@@ -153,6 +153,22 @@ promise_test(function(t) { > [[SCOPE1], [], []]); > }); > }, 'Normal redirect to same-origin scope.'); >+promise_test(function(t) { >+ return setup_environment(t).then(function() { >+ return test_redirect( >+ OUT_SCOPE + 'url=' + encodeURIComponent(SCOPE1) + '#ref', >+ SCOPE1 + '#ref', >+ [[SCOPE1 + '#ref'], [], []]); >+ }); >+ }, 'Normal redirect to same-origin scope with a hash fragment.'); >+promise_test(function(t) { >+ return setup_environment(t).then(function() { >+ return test_redirect( >+ OUT_SCOPE + 'url=' + encodeURIComponent(SCOPE1 + '#ref2') + '#ref', >+ SCOPE1 + '#ref2', >+ [[SCOPE1 + '#ref2'], [], []]); >+ }); >+ }, 'Normal redirect to same-origin scope with different hash fragments.'); > promise_test(function(t) { > return setup_environment(t).then(function() { > return test_redirect( >@@ -179,6 +195,27 @@ promise_test(function(t) { > [[SCOPE1 + 'url=' + encodeURIComponent(SCOPE1), SCOPE1], [], []]); > }); > }, 'SW-fallbacked redirect to same-origin same-scope.'); >+promise_test(function(t) { >+ return setup_environment(t).then(function() { >+ return test_redirect( >+ SCOPE1 + 'url=' + encodeURIComponent(SCOPE1) + '#ref', >+ SCOPE1 + '#ref', >+ [[SCOPE1 + 'url=' + encodeURIComponent(SCOPE1) + '#ref', >+ SCOPE1 + '#ref'], >+ [], []]); >+ }); >+ }, 'SW-fallbacked redirect to same-origin same-scope with a hash fragment.'); >+promise_test(function(t) { >+ return setup_environment(t).then(function() { >+ return test_redirect( >+ SCOPE1 + 'url=' + encodeURIComponent(SCOPE1 + '#ref2') + '#ref', >+ SCOPE1 + '#ref2', >+ [[SCOPE1 + 'url=' + encodeURIComponent(SCOPE1 + '#ref2') + '#ref', >+ SCOPE1 + '#ref2'], >+ [], []]); >+ }); >+ }, 'SW-fallbacked redirect to same-origin same-scope with different hash ' + >+ 'fragments.'); > promise_test(function(t) { > return setup_environment(t).then(function() { > return test_redirect( >@@ -218,6 +255,27 @@ promise_test(function(t) { > [[SCOPE1 + 'sw=gen&url=' + encodeURIComponent(OUT_SCOPE)], [], []]); > }); > }, 'SW-generated redirect to same-origin out-scope.'); >+promise_test(function(t) { >+ return setup_environment(t).then(function() { >+ return test_redirect( >+ SCOPE1 + 'sw=gen&url=' + encodeURIComponent(OUT_SCOPE) + '#ref', >+ OUT_SCOPE + '#ref', >+ [[SCOPE1 + 'sw=gen&url=' + encodeURIComponent(OUT_SCOPE) + '#ref'], >+ [], []]); >+ }); >+ }, 'SW-generated redirect to same-origin out-scope with a hash fragment.'); >+promise_test(function(t) { >+ return setup_environment(t).then(function() { >+ return test_redirect( >+ SCOPE1 + 'sw=gen&url=' + encodeURIComponent(OUT_SCOPE + '#ref2') + >+ '#ref', >+ OUT_SCOPE + '#ref2', >+ [[SCOPE1 + 'sw=gen&url=' + encodeURIComponent(OUT_SCOPE + '#ref2') + >+ '#ref'], >+ [], []]); >+ }); >+ }, 'SW-generated redirect to same-origin out-scope with different hash' + >+ 'fragments.'); > promise_test(function(t) { > return setup_environment(t).then(function() { > return test_redirect( >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-timing.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-timing.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..1279e71e2b0840f75b1b0b41e1596e19805721ca >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-timing.https-expected.txt >@@ -0,0 +1,5 @@ >+ >+FAIL Service worker controlled navigation timing assert_unreached: unexpected rejection: undefined is not an object (evaluating 'timing[timingEventOrder[i]]') Reached unreachable code >+FAIL Service worker controlled navigation timing network fallback assert_unreached: unexpected rejection: undefined is not an object (evaluating 'timing[timingEventOrder[i]]') Reached unreachable code >+FAIL Service worker controlled navigation timing redirect assert_unreached: unexpected rejection: undefined is not an object (evaluating 'timing[timingEventOrder[i]]') Reached unreachable code >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-timing.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-timing.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ac3456e9d1a9868b11d5571862560afda0a46fef >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-timing.https.html >@@ -0,0 +1,111 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/test-helpers.sub.js"></script> >+ >+<script> >+const timingEventOrder = [ >+ 'startTime', >+ 'workerStart', >+ 'fetchStart', >+ 'requestStart', >+ 'responseStart', >+ 'responseEnd', >+]; >+ >+function verify(timing) { >+ for (let i = 0; i < timingEventOrder.length - 1; i++) { >+ assert_true(timing[timingEventOrder[i]] <= timing[timingEventOrder[i + 1]], >+ `Expected ${timingEventOrder[i]} <= ${timingEventOrder[i + 1]}`); >+ } >+} >+ >+function navigate_in_frame(frame, url) { >+ frame.contentWindow.location = url; >+ return new Promise((resolve) => { >+ frame.addEventListener('load', () => { >+ const timing = frame.contentWindow.performance.getEntriesByType('navigation')[0]; >+ resolve(timing); >+ }); >+ }); >+} >+ >+const worker_url = 'resources/navigation-timing-worker.js'; >+ >+promise_test(t => { >+ const scope = 'resources/empty.html'; >+ let frame; >+ >+ return service_worker_unregister_and_register(t, worker_url, scope) >+ .then(r => { >+ return wait_for_state(t, r.installing, 'activated'); >+ }) >+ .then(() => with_iframe(scope)) >+ .then(f => { >+ frame = f; >+ return navigate_in_frame(frame, 'resources/empty.html'); >+ }) >+ .then(timing => { >+ verify(timing); >+ }) >+ .catch(unreached_rejection(t)) >+ .then(() => { >+ if (frame) >+ frame.remove(); >+ return service_worker_unregister(t, scope); >+ }); >+}, 'Service worker controlled navigation timing'); >+ >+promise_test(t => { >+ const scope = 'resources/empty.html?network-fallback'; >+ let frame; >+ >+ return service_worker_unregister_and_register(t, worker_url, scope) >+ .then(r => { >+ return wait_for_state(t, r.installing, 'activated'); >+ }) >+ .then(() => with_iframe(scope)) >+ .then(f => { >+ frame = f; >+ return navigate_in_frame(frame, 'resources/empty.html?network-fallback'); >+ }) >+ .then(timing => { >+ verify(timing); >+ }) >+ .catch(unreached_rejection(t)) >+ .then(() => { >+ if (frame) >+ frame.remove(); >+ return service_worker_unregister(t, scope); >+ }); >+}, 'Service worker controlled navigation timing network fallback'); >+ >+promise_test(t => { >+ const scope = 'resources/redirect.py?Redirect=empty.html'; >+ let frame; >+ >+ return service_worker_unregister_and_register(t, worker_url, scope) >+ .then(r => { >+ return wait_for_state(t, r.installing, 'activated'); >+ }) >+ .then(() => with_iframe(scope)) >+ .then(f => { >+ frame = f; >+ return navigate_in_frame(frame, 'resources/redirect.py?Redirect=empty.html'); >+ }) >+ .then(timing => { >+ verify(timing); >+ // Additional checks for redirected navigation. >+ assert_true(timing.redirectStart <= timing.redirectEnd, >+ 'Expected redirectStart <= redirectEnd'); >+ assert_true(timing.redirectEnd <= timing.fetchStart, >+ 'Expected redirectEnd <= fetchStart'); >+ }) >+ .catch(unreached_rejection(t)) >+ .then(() => { >+ if (frame) >+ frame.remove(); >+ return service_worker_unregister(t, scope); >+ }); >+}, 'Service worker controlled navigation timing redirect'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/postmessage.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/postmessage.https.html >index 3a6487ea17a63d8ae7710ee6e1ddb5bc6626f919..6b2f6d78e12210647a47e2eb317c6387e8487ca2 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/postmessage.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/postmessage.https.html >@@ -13,7 +13,11 @@ promise_test(t => { > > return service_worker_unregister_and_register(t, script, scope) > .then(r => { >- t.add_cleanup(() => r.unregister()); >+ // TODO: return the Promise created by `r.unregister`once >+ // `testharness.js` has been updated to honor thenables returned by >+ // cleanup functions. >+ // See https://github.com/web-platform-tests/wpt/pull/8748 >+ t.add_cleanup(() => { r.unregister(); }); > registration = r; > worker = registration.installing; > >@@ -62,7 +66,11 @@ promise_test(t => { > > return service_worker_unregister_and_register(t, script, scope) > .then(r => { >- t.add_cleanup(() => r.unregister()); >+ // TODO: return the Promise created by `r.unregister`once >+ // `testharness.js` has been updated to honor thenables returned by >+ // cleanup functions. >+ // See https://github.com/web-platform-tests/wpt/pull/8748 >+ t.add_cleanup(() => { r.unregister(); }); > > var ab = text_encoder.encode(message); > assert_equals(ab.byteLength, message.length); >@@ -102,7 +110,11 @@ promise_test(t => { > > return service_worker_unregister_and_register(t, script, scope) > .then(r => { >- t.add_cleanup(() => r.unregister()); >+ // TODO: return the Promise created by `r.unregister`once >+ // `testharness.js` has been updated to honor thenables returned by >+ // cleanup functions. >+ // See https://github.com/web-platform-tests/wpt/pull/8748 >+ t.add_cleanup(() => { r.unregister(); }); > > var channel = new MessageChannel; > port = channel.port1; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-iframe.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-iframe.https.html >index 91756666e90b7d6b68672d0b06ffc9b06fbc0caa..ae39ddfea3e5186bdea4c6a1a5d9f0c7e6cbc212 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-iframe.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-iframe.https.html >@@ -1,10 +1,10 @@ > <!DOCTYPE html> > <meta charset="utf-8"> > <title>Service Worker: Registration for iframe</title> >-<body> > <script src="/resources/testharness.js"></script> > <script src="/resources/testharnessreport.js"></script> > <script src="resources/test-helpers.sub.js"></script> >+<body> > <script> > > // Set script url and scope url relative to the iframe's document's url. Assert >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-security-error.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-security-error.https-expected.txt >index 0eebcb2db43644b266d2c4cb6fa26e26da3eed22..d6b633a31886faa50e00bcc2415d750d23e37648 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-security-error.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-security-error.https-expected.txt >@@ -3,7 +3,7 @@ PASS Registering same scope as the script directory without the last slash > PASS Registration scope outside the script directory > PASS Registering scope outside domain > PASS Registering script outside domain >-FAIL Registering redirected script assert_throws: Registration of redirected script should fail. function "function () { throw e }" threw object "TypeError: Script URL https://localhost:9443/service-workers/service-worker/resources/redirect.py?Redirect=%2Fservice-workers%2Fservice-worker%2Fresources%2Fregistration-worker.js fetch resulted in error: Not allowed to follow a redirection while loading https://localhost:9443/service-workers/service-worker/resources/redirect.py?Redirect=%2Fservice-workers%2Fservice-worker%2Fresources%2Fregistration-worker.js" that is not a DOMException SecurityError: property "code" is equal to undefined, expected 18 >+FAIL Registering redirected script assert_throws: Registration of redirected script should fail. function "function () { throw e }" threw object "TypeError: Script URL https://localhost:9443/service-workers/service-worker/resources/redirect.py?Redirect=%2Fresources%2Fregistration-worker.js fetch resulted in error: Not allowed to follow a redirection while loading https://localhost:9443/service-workers/service-worker/resources/redirect.py?Redirect=%2Fresources%2Fregistration-worker.js" that is not a DOMException SecurityError: property "code" is equal to undefined, expected 18 > PASS Scope including parent-reference and not under the script directory > PASS Script URL including consecutive slashes > FAIL Script URL is same-origin filesystem: URL assert_throws: Registering a script which has same-origin filesystem: URL should fail with SecurityError. function "function () { throw e }" threw object "TypeError: serviceWorker.register() must be called with a script URL whose protocol is either HTTP or HTTPS" that is not a DOMException SecurityError: property "code" is equal to undefined, expected 18 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-updateviacache.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-updateviacache.https-expected.txt >index 8201a01505cbb1a3db30e4b5781012532e298a4a..67e3190f7bd180accf382b983b93bdb024776c63 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-updateviacache.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-updateviacache.https-expected.txt >@@ -1,22 +1,29 @@ > >+ >+Harness Error (TIMEOUT), message = null >+ > PASS register-with-updateViaCache-undefined > PASS register-with-updateViaCache-imports > PASS register-with-updateViaCache-all > PASS register-with-updateViaCache-none > PASS register-with-updateViaCache-undefined-then-undefined > PASS register-with-updateViaCache-undefined-then-imports >-PASS register-with-updateViaCache-undefined-then-all >-PASS register-with-updateViaCache-undefined-then-none >-PASS register-with-updateViaCache-imports-then-undefined >-PASS register-with-updateViaCache-imports-then-imports >-PASS register-with-updateViaCache-imports-then-all >-PASS register-with-updateViaCache-imports-then-none >-PASS register-with-updateViaCache-all-then-undefined >-PASS register-with-updateViaCache-all-then-imports >-PASS register-with-updateViaCache-all-then-all >-PASS register-with-updateViaCache-all-then-none >-PASS register-with-updateViaCache-none-then-undefined >-PASS register-with-updateViaCache-none-then-imports >-PASS register-with-updateViaCache-none-then-all >-PASS register-with-updateViaCache-none-then-none >+FAIL register-with-updateViaCache-undefined-then-all assert_equals: No new service worker expected null but got object "[object ServiceWorker]" >+TIMEOUT register-with-updateViaCache-undefined-then-none Test timed out >+NOTRUN register-with-updateViaCache-imports-then-undefined >+NOTRUN register-with-updateViaCache-imports-then-imports >+NOTRUN register-with-updateViaCache-imports-then-all >+NOTRUN register-with-updateViaCache-imports-then-none >+NOTRUN register-with-updateViaCache-all-then-undefined >+NOTRUN register-with-updateViaCache-all-then-imports >+NOTRUN register-with-updateViaCache-all-then-all >+NOTRUN register-with-updateViaCache-all-then-none >+NOTRUN register-with-updateViaCache-none-then-undefined >+NOTRUN register-with-updateViaCache-none-then-imports >+NOTRUN register-with-updateViaCache-none-then-all >+NOTRUN register-with-updateViaCache-none-then-none >+NOTRUN access-updateViaCache-after-unregister-undefined >+NOTRUN access-updateViaCache-after-unregister-imports >+NOTRUN access-updateViaCache-after-unregister-all >+NOTRUN access-updateViaCache-after-unregister-none > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-updateviacache.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-updateviacache.https.html >index b1fd902994f164b0874cf911da1c3befc338fd1c..64c277d94dc62e17ebb85a745b5bf0a787001d60 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-updateviacache.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-updateviacache.https.html >@@ -100,13 +100,18 @@ > await wait_for_state(t, sw, 'activated'); > const values = await getScriptTimes(sw, testName); > >+ const frame = await with_iframe(SCOPE); >+ const reg_in_frame = await frame.contentWindow.navigator.serviceWorker.getRegistration(normalizeURL(SCOPE)); >+ assert_equals(reg_in_frame.updateViaCache, updateViaCache1 || 'imports', "reg_in_frame.updateViaCache"); >+ > opts = {scope: SCOPE}; > if (updateViaCache2) opts.updateViaCache = updateViaCache2; > > await navigator.serviceWorker.register(fullScriptUrl, opts); > >- assert_equals(reg.updateViaCache, updateViaCache2 || 'imports', "reg.updateViaCache updated"); >+ const expected_updateViaCache = updateViaCache2 || 'imports'; > >+ assert_equals(reg.updateViaCache, expected_updateViaCache, "reg.updateViaCache updated"); > // If the update happens via the cache, the scripts will come back byte-identical. > // We bypass the byte-identical check if the script URL has changed, but not if > // only the updateViaCache value has changed. >@@ -138,9 +143,44 @@ > } > } > >+ // Wait for all registration related tasks on |frame| to complete. >+ await wait_for_activation_on_dummy_scope(t, frame.contentWindow); >+ // The updateViaCache change should have been propagated to all >+ // corresponding JS registration objects. >+ assert_equals(reg_in_frame.updateViaCache, expected_updateViaCache, "reg_in_frame.updateViaCache updated"); >+ frame.remove(); >+ > await cleanup(); > }, testName); > } > } > >+ // Test accessing updateViaCache of an unregistered registration. >+ for (const updateViaCache of UPDATE_VIA_CACHE_VALUES) { >+ const testName = `access-updateViaCache-after-unregister-${updateViaCache}`; >+ >+ promise_test(async t => { >+ await cleanup(); >+ >+ const opts = {scope: SCOPE}; >+ >+ if (updateViaCache) opts.updateViaCache = updateViaCache; >+ >+ const reg = await navigator.serviceWorker.register( >+ `${SCRIPT_URL}?test=${testName}`, >+ opts >+ ); >+ >+ const expected_updateViaCache = updateViaCache || 'imports'; >+ assert_equals(reg.updateViaCache, expected_updateViaCache, "reg.updateViaCache"); >+ >+ await reg.unregister(); >+ >+ // Keep the original value. >+ assert_equals(reg.updateViaCache, expected_updateViaCache, "reg.updateViaCache"); >+ >+ await cleanup(); >+ }, testName); >+ } >+ > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resource-timing-cross-origin.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resource-timing-cross-origin.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..6b12c50daeb3480c928ffa81660316bc2b690e00 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resource-timing-cross-origin.https-expected.txt >@@ -0,0 +1,4 @@ >+ >+ >+FAIL Test that timing allow check fails when service worker changes origin from same to cross origin. assert_unreached: unexpected rejection: assert_equals: decodedBodySize should be 0 in cross-origin request. expected (number) 0 but got (undefined) undefined Reached unreachable code >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resource-timing-cross-origin.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resource-timing-cross-origin.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..827688df011ea9be216a7414b161dbb730f1b975 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resource-timing-cross-origin.https.html >@@ -0,0 +1,52 @@ >+<!DOCTYPE HTML> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>This test validates Resource Timing for cross origin content fetched by Service Worker from an originally same-origin URL.</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/get-host-info.sub.js"></script> >+<script src="resources/test-helpers.sub.js"></script> >+</head> >+ >+<body> >+<script> >+async_test(function(t) { >+ const worker_url = 'resources/worker-fetching-cross-origin.js'; >+ const scope = 'resources/iframe-with-image.html'; >+ let registration; >+ service_worker_unregister_and_register(t, worker_url, scope) >+ .then(function(r) { >+ registration = r; >+ return wait_for_state(t, r.installing, 'activated'); >+ }) >+ .then(function() { >+ return with_iframe(scope); >+ }) >+ .then(function(frame) { >+ const frame_performance = frame.contentWindow.performance; >+ // Check that there is one entry for which the timing allow check algorithm failed. >+ const entries = frame_performance.getEntriesByType('resource'); >+ assert_equals(entries.length, 1); >+ const entry = entries[0]; >+ assert_equals(entry.redirectStart, 0, 'redirectStart should be 0 in cross-origin request.'); >+ assert_equals(entry.redirectEnd, 0, 'redirectEnd should be 0 in cross-origin request.'); >+ assert_equals(entry.domainLookupStart, 0, 'domainLookupStart should be 0 in cross-origin request.'); >+ assert_equals(entry.domainLookupEnd, 0, 'domainLookupEnd should be 0 in cross-origin request.'); >+ assert_equals(entry.connectStart, 0, 'connectStart should be 0 in cross-origin request.'); >+ assert_equals(entry.connectEnd, 0, 'connectEnd should be 0 in cross-origin request.'); >+ assert_equals(entry.requestStart, 0, 'requestStart should be 0 in cross-origin request.'); >+ assert_equals(entry.responseStart, 0, 'responseStart should be 0 in cross-origin request.'); >+ assert_equals(entry.secureConnectionStart, 0, 'secureConnectionStart should be 0 in cross-origin request.'); >+ assert_equals(entry.decodedBodySize, 0, 'decodedBodySize should be 0 in cross-origin request.'); >+ frame.remove(); >+ return registration.unregister(); >+ }) >+ .then(function() { >+ t.done(); >+ }) >+ .catch(unreached_rejection(t)); >+}, 'Test that timing allow check fails when service worker changes origin from same to cross origin.'); >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resource-timing.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resource-timing.https-expected.txt >index ebbcea186367b4749c8c245a31da4b21ac26d020..8c00dd205b8cc89179a8b677f45799b0ecf670c4 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resource-timing.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resource-timing.https-expected.txt >@@ -1,7 +1,9 @@ >+Blocked access to external URL https://www1.localhost:9443/service-workers/service-worker/resources/square.png > Blocked access to external URL https://www1.localhost:9443/service-workers/service-worker/resources/missing.jpg >+Blocked access to external URL https://www1.localhost:9443/service-workers/service-worker/resources/square.png > Blocked access to external URL https://www1.localhost:9443/service-workers/service-worker/resources/missing.jpg > > >-FAIL Controlled resource loads assert_unreached: unexpected rejection: assert_greater_than: Generated response expected a number greater than 0 but got 0 Reached unreachable code >+FAIL Controlled resource loads assert_greater_than: Generated response expected a number greater than 0 but got 0 > PASS Non-controlled resource loads > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resource-timing.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resource-timing.https.html >index da898e2bf6dc01a7f75c2841fd43b4b91cd71f94..123bbc87c57e857a517ab792717f1cf65b9a3a16 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resource-timing.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resource-timing.https.html >@@ -12,37 +12,45 @@ function crossOriginUrl(path) { > return get_host_info()['HTTPS_REMOTE_ORIGIN'] + base_path() + path; > } > >-function verify(performance, resource, mode, description) { >- var url = mode === 'cross-origin' ? crossOriginUrl(resource) >- : resourceUrl(resource); >- var entryList = performance.getEntries(); >- var entry = performance.getEntriesByName(url)[0]; >- assert_greater_than(entry.workerStart, 0, description); >- assert_greater_than_equal(entry.workerStart, entry.startTime, description); >- assert_less_than_equal(entry.workerStart, entry.fetchStart, description); >- if (mode === 'cross-origin') { >- assert_equals(entry.responseStart, 0, description); >- assert_greater_than_equal(entry.responseEnd, entry.fetchStart, description); >+function verify(options) { >+ const url = options.mode === 'cross-origin' ? crossOriginUrl(options.resource) >+ : resourceUrl(options.resource); >+ const entryList = options.performance.getEntriesByName(url); >+ if (options.should_no_performance_entry) { >+ // The performance timeline may not have an entry for a resource >+ // which failed to load. >+ assert_equals(entryList.length, 0, options.description); >+ return; >+ } >+ assert_equals(entryList.length, 1, options.description); >+ const entry = entryList[0]; >+ assert_equals(entry.entryType, 'resource', options.description); >+ assert_greater_than(entry.workerStart, 0, options.description); >+ assert_greater_than_equal(entry.workerStart, entry.startTime, options.description); >+ assert_less_than_equal(entry.workerStart, entry.fetchStart, options.description); >+ if (options.mode === 'cross-origin') { >+ assert_equals(entry.responseStart, 0, options.description); >+ assert_greater_than_equal(entry.responseEnd, entry.fetchStart, options.description); > } else { >- assert_greater_than_equal(entry.responseStart, entry.fetchStart, description); >- assert_greater_than_equal(entry.responseEnd, entry.responseStart, description); >+ assert_greater_than_equal(entry.responseStart, entry.fetchStart, options.description); >+ assert_greater_than_equal(entry.responseEnd, entry.responseStart, options.description); > } >- assert_greater_than(entry.responseEnd, entry.fetchStart, description); >- assert_greater_than(entry.duration, 0, description); >- if (resource.indexOf('redirect.py') != -1) { >+ assert_greater_than(entry.responseEnd, entry.fetchStart, options.description); >+ assert_greater_than(entry.duration, 0, options.description); >+ if (options.resource.indexOf('redirect.py') != -1) { > assert_less_than_equal(entry.workerStart, entry.redirectStart, >- description); >+ options.description); > } else { >- assert_equals(entry.redirectStart, 0, description); >+ assert_equals(entry.redirectStart, 0, options.description); > } > } > >-async_test(function(t) { >- var worker_url = 'resources/resource-timing-worker.js'; >- var scope = 'resources/resource-timing-iframe.sub.html'; >- var registration; >+promise_test(function(t) { >+ const worker_url = 'resources/resource-timing-worker.js'; >+ const scope = 'resources/resource-timing-iframe.sub.html'; >+ let registration; > >- service_worker_unregister_and_register(t, worker_url, scope) >+ return service_worker_unregister_and_register(t, worker_url, scope) > .then(function(r) { > registration = r; > return wait_for_state(t, r.installing, 'activated'); >@@ -51,33 +59,85 @@ async_test(function(t) { > return with_iframe(scope); > }) > .then(function(frame) { >- var performance = frame.contentWindow.performance; >- verify(performance, 'resources/dummy.js', 'same-origin', >- 'Generated response'); >- verify(performance, 'resources/empty.js', 'same-origin', >- 'Network fallback'); >- verify(performance, 'resources/redirect.py?Redirect=empty.js', >- 'same-origin', 'Redirect'); >- verify(performance, 'resources/missing.jpg', 'same-origin', >- 'Network fallback image'); >- >+ const performance = frame.contentWindow.performance; >+ verify({ >+ performance: performance, >+ resource: 'resources/dummy.js', >+ mode: 'same-origin', >+ description: 'Generated response', >+ }); >+ verify({ >+ performance: performance, >+ resource: 'resources/empty.js', >+ mode: 'same-origin', >+ description: 'Network fallback', >+ }); >+ verify({ >+ performance: performance, >+ resource: 'resources/redirect.py?Redirect=empty.js', >+ mode: 'same-origin', >+ description: 'Redirect', >+ }); >+ verify({ >+ performance: performance, >+ resource: 'resources/square.png', >+ mode: 'same-origin', >+ description: 'Network fallback image', >+ }); > // Test that worker start is available on cross-origin no-cors > // subresources. >- verify(performance, 'resources/missing.jpg', 'cross-origin', >- 'Network fallback cross-origin image'); >+ verify({ >+ performance: performance, >+ resource: 'resources/square.png', >+ mode: 'cross-origin', >+ description: 'Network fallback cross-origin image', >+ }); >+ >+ // Tests for resouces which failed to load. >+ verify({ >+ performance: performance, >+ resource: 'resources/missing.jpg', >+ mode: 'same-origin', >+ description: 'Network fallback load failure', >+ should_no_performance_entry: true, >+ }); >+ verify({ >+ performance: performance, >+ resource: 'resources/missing.jpg', >+ mode: 'cross-origin', >+ description: 'Network fallback cross-origin load failure', >+ should_no_performance_entry: true, >+ }); >+ // Tests for respondWith(fetch()). >+ verify({ >+ performance: performance, >+ resource: 'resources/missing.jpg?SWRespondsWithFetch', >+ mode: 'same-origin', >+ description: 'Resource in iframe, nonexistent but responded with fetch to another.', >+ }); >+ verify({ >+ performance: performance, >+ resource: 'resources/dummy.txt?SWFetched', >+ mode: 'same-origin', >+ description: 'Resource fetched as response from missing.jpg?SWRespondsWithFetch.', >+ should_no_performance_entry: true, >+ }); >+ // Test for a normal resource that is unaffected by the Service Worker. >+ verify({ >+ performance: performance, >+ resource: 'resources/empty-worker.js', >+ mode: 'same-origin', >+ description: 'Resource untouched by the Service Worker.', >+ }); > > frame.remove(); > return registration.unregister(); >- }) >- .then(function() { >- t.done(); >- }) >- .catch(unreached_rejection(t)); >+ }); > }, 'Controlled resource loads'); > >-test(function() { >- var url = resourceUrl('resources/test-helpers.sub.js'); >- var entry = window.performance.getEntriesByName(url)[0]; >+test(() => { >+ const url = resourceUrl('resources/test-helpers.sub.js'); >+ const entry = window.performance.getEntriesByName(url)[0]; > assert_equals(entry.workerStart, 0, 'Non-controlled'); > }, 'Non-controlled resource loads'); > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-blank-dynamic-nested-frame.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-blank-dynamic-nested-frame.html >new file mode 100644 >index 0000000000000000000000000000000000000000..1e0c6209bfc0bdf649316395c8552912aeeb143c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-blank-dynamic-nested-frame.html >@@ -0,0 +1,21 @@ >+<!doctype html> >+<html> >+<body> >+<script> >+function nestedLoaded() { >+ parent.postMessage({ type: 'NESTED_LOADED' }, '*'); >+} >+ >+// dynamically add an about:blank iframe >+var f = document.createElement('iframe'); >+f.onload = nestedLoaded; >+document.body.appendChild(f); >+ >+// Helper routine to make it slightly easier for our parent to find >+// the nested frame. >+function nested() { >+ return f.contentWindow; >+} >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-blank-nested-frame.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-blank-nested-frame.html >new file mode 100644 >index 0000000000000000000000000000000000000000..99d07a48cda5ea82abbe2be777aedfcb4d1ddbde >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-blank-nested-frame.html >@@ -0,0 +1,22 @@ >+<!doctype html> >+<html> >+<body> >+<script> >+function nestedLoaded() { >+ parent.postMessage({ type: 'NESTED_LOADED' }, '*'); >+} >+</script> >+<iframe id="nested" onload="nestedLoaded()"></iframe> >+<script> >+// Helper routine to make it slightly easier for our parent to find >+// the nested frame. >+function nested() { >+ return document.getElementById('nested').contentWindow; >+} >+ >+// NOTE: Make sure not to touch the iframe directly here. We want to >+// test the case where the initial about:blank document is not >+// directly accessed before load. >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-popup-frame.py b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-popup-frame.py >index be5294539833c76fd0ff833c67772ad945afe374..f0b8cd578e3e05e30e72cdfc343ed89f60670a7a 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-popup-frame.py >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-popup-frame.py >@@ -12,12 +12,15 @@ def main(request, response): > <script> > function nestedLoaded() { > parent.postMessage({ type: 'NESTED_LOADED' }, '*'); >- popup.close(); > } > > let popup = window.open('?nested=true'); > popup.onload = nestedLoaded; > >+addEventListener('unload', evt => { >+ popup.close(); >+}, { once: true }); >+ > // Helper routine to make it slightly easier for our parent to find > // the nested popup window. > function nested() { >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-srcdoc-nested-frame.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-srcdoc-nested-frame.html >new file mode 100644 >index 0000000000000000000000000000000000000000..0122a00aa432f9876aa3476b0650939183654382 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-srcdoc-nested-frame.html >@@ -0,0 +1,22 @@ >+<!doctype html> >+<html> >+<body> >+<script> >+function nestedLoaded() { >+ parent.postMessage({ type: 'NESTED_LOADED' }, '*'); >+} >+</script> >+<iframe id="nested" srcdoc="<div></div>" onload="nestedLoaded()"></iframe> >+<script> >+// Helper routine to make it slightly easier for our parent to find >+// the nested frame. >+function nested() { >+ return document.getElementById('nested').contentWindow; >+} >+ >+// NOTE: Make sure not to touch the iframe directly here. We want to >+// test the case where the initial about:blank document is not >+// directly accessed before load. >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/client-navigate-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/client-navigate-worker.js >index 09d11fe6181d33f43c55b0da418627142b4c646f..aff2b37ae02a0b3e3ff74db54ec4745bec427fba 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/client-navigate-worker.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/client-navigate-worker.js >@@ -5,11 +5,6 @@ importScripts("testharness-helpers.js") > > self.onfetch = function(e) { > if (e.request.url.indexOf("client-navigate-frame.html") >= 0) { >- if (e.clientId === null) { >- e.respondWith(fetch(e.request)); >- } else { >- e.respondWith(Response.error()); >- } > return; > } > e.respondWith(new Response(e.clientId)); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/clients-get-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/clients-get-worker.js >index 9f3af21abe7b2f02e0313f0566ffbc94db918570..87368ae7617575da4281aff678c27c2d37118966 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/clients-get-worker.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/clients-get-worker.js >@@ -4,13 +4,6 @@ > // the `event` object. In the case of the `onmessage` handler, it provides the > // Client instance attributes of the requested clients. > self.onfetch = function(e) { >- if (e.request.mode === 'navigate' && e.clientId !== "") { >- e.respondWith(Response.error( >- '`clientId` incorrectly set to non-empty value for request with mode `navigate`' >- )); >- return; >- } >- > if (/\/clientId$/.test(e.request.url)) { > e.respondWith(new Response(e.clientId)); > return; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/dummy-shared-worker-interceptor.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/dummy-shared-worker-interceptor.js >index 82b24459b4fe307aea80a08689e115dddbda538e..e996da6b2b7f491820ddab168e9d2f2d6f6cea35 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/dummy-shared-worker-interceptor.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/dummy-shared-worker-interceptor.js >@@ -1,7 +1,9 @@ > var worker_text = 'onconnect = function(e) { e.ports[0].postMessage("worker loading intercepted by service worker"); };'; > > self.onfetch = function(event) { >- if (event.request.url.indexOf('dummy-shared-worker.js') != -1) >- event.respondWith(new Response(worker_text)); >+ if (event.request.url.indexOf('dummy-shared-worker.js') != -1) { >+ event.respondWith(new Response( >+ worker_text, {headers: {"Content-Type": "application/javascript"}})); >+ } > }; > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/dummy-shared-worker-interceptor.js.headers b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/dummy-shared-worker-interceptor.js.headers >new file mode 100644 >index 0000000000000000000000000000000000000000..a17a9a3a12cefe883a5d4dee4d5a45bef120d050 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/dummy-shared-worker-interceptor.js.headers >@@ -0,0 +1 @@ >+Content-Type: application/javascript >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/echo-content.py b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/echo-content.py >new file mode 100644 >index 0000000000000000000000000000000000000000..c40ef0cf2bbbd435caa68fca81204342ca1dc120 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/echo-content.py >@@ -0,0 +1,14 @@ >+# This is a copy of fetch/api/resources/echo-content.py since it's more >+# convenient in this directory due to service worker's path restriction. >+def main(request, response): >+ >+ headers = [("X-Request-Method", request.method), >+ ("X-Request-Content-Length", request.headers.get("Content-Length", "NO")), >+ ("X-Request-Content-Type", request.headers.get("Content-Type", "NO")), >+ >+ # Avoid any kind of content sniffing on the response. >+ ("Content-Type", "text/plain")] >+ >+ content = request.body >+ >+ return headers, content >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embed-and-object-are-not-intercepted-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embed-and-object-are-not-intercepted-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..ffcdb7512888ffdb106e04ffa37f1b7b84b800e7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embed-and-object-are-not-intercepted-worker.js >@@ -0,0 +1,14 @@ >+// This worker intercepts a request for EMBED/OBJECT and responds with a >+// response that indicates that interception occurred. The tests expect >+// that interception does not occur. >+self.addEventListener('fetch', e => { >+ if (e.request.url.indexOf('embedded-content-from-server.html') != -1) { >+ e.respondWith(fetch('embedded-content-from-service-worker.html')); >+ return; >+ } >+ >+ if (e.request.url.indexOf('green.png') != -1) { >+ e.respondWith(Promise.reject('network error to show interception occurred')); >+ return; >+ } >+ }); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embed-image-is-not-intercepted-iframe.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embed-image-is-not-intercepted-iframe.html >new file mode 100644 >index 0000000000000000000000000000000000000000..7b8b257203a222cce158fb6d9956a186ad4661ba >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embed-image-is-not-intercepted-iframe.html >@@ -0,0 +1,21 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>iframe for embed-and-object-are-not-intercepted test</title> >+<body> >+<embed type="image/png" src="/images/green.png"></embed> >+<script> >+// Our parent (the root frame of the test) will examine this to get the result. >+var test_promise = new Promise(resolve => { >+ if (!navigator.serviceWorker.controller) >+ resolve('FAIL: this iframe is not controlled'); >+ >+ const elem = document.querySelector('embed'); >+ elem.addEventListener('load', e => { >+ resolve('request was not intercepted'); >+ }); >+ elem.addEventListener('error', e => { >+ resolve('FAIL: request was intercepted'); >+ }); >+ }); >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embed-is-not-intercepted-iframe.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embed-is-not-intercepted-iframe.html >new file mode 100644 >index 0000000000000000000000000000000000000000..39149915cc573b3f8a5e0e01a10729494aec59f1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embed-is-not-intercepted-iframe.html >@@ -0,0 +1,17 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>iframe for embed-and-object-are-not-intercepted test</title> >+<body> >+<script> >+// The EMBED element will call this with the result about whether the EMBED >+// request was intercepted by the service worker. >+var report_result; >+ >+// Our parent (the root frame of the test) will examine this to get the result. >+var test_promise = new Promise(resolve => { >+ report_result = resolve; >+ }); >+</script> >+ >+<embed src="embedded-content-from-server.html"></embed> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embedded-content-from-server.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embedded-content-from-server.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ff50a9c752690d6726d0cd6d9820947f1bc5d4b0 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embedded-content-from-server.html >@@ -0,0 +1,6 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>embed for embed-and-object-are-not-intercepted test</title> >+<script> >+window.parent.report_result('request for embedded content was not intercepted'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embedded-content-from-service-worker.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embedded-content-from-service-worker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2e2b9236082d7ae2f80c1a74fb0a84823c96d162 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embedded-content-from-service-worker.html >@@ -0,0 +1,7 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>embed for embed-and-object-are-not-intercepted test</title> >+<script> >+window.parent.report_result('request for embedded content was intercepted by service worker'); >+</script> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-access-control.py b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-access-control.py >index 93ea0e0ad66e72ec25109b3f4ce4b147f7a103c7..61b89cbd95b4b910670e4795cb2518c51abec121 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-access-control.py >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-access-control.py >@@ -1,5 +1,7 @@ > import base64 > import json >+import os >+import sys > > def main(request, response): > headers = [] >@@ -31,6 +33,43 @@ def main(request, response): > "jBoAAqMGDLwBDAwAEsoCTFWunmQAAAAASUVORK5CYII=") > return headers, body > >+ if "VIDEO" in request.GET: >+ headers.append(("Content-Type", "video/webm")) >+ body = open(os.path.join(request.doc_root, "media", "movie_5.ogv"), "rb").read() >+ length = len(body) >+ # If "PartialContent" is specified, the requestor wants to test range >+ # requests. For the initial request, respond with "206 Partial Content" >+ # and don't send the entire content. Then expect subsequent requests to >+ # have a "Range" header with a byte range. Respond with that range. >+ if "PartialContent" in request.GET: >+ if length < 1: >+ return 500, headers, "file is too small for range requests" >+ start = 0 >+ end = length - 1 >+ if "Range" in request.headers: >+ range_header = request.headers["Range"] >+ prefix = "bytes=" >+ split_header = range_header[len(prefix):].split("-") >+ # The first request might be "bytes=0-". We want to force a range >+ # request, so just return the first byte. >+ if split_header[0] == "0" and split_header[1] == "": >+ end = start >+ # Otherwise, it is a range request. Respect the values sent. >+ if split_header[0] != "": >+ start = int(split_header[0]) >+ if split_header[1] != "": >+ end = int(split_header[1]) >+ else: >+ # The request doesn't have a range. Force a range request by >+ # returning the first byte. >+ end = start >+ >+ headers.append(("Accept-Ranges", "bytes")) >+ headers.append(("Content-Length", str(end -start + 1))) >+ headers.append(("Content-Range", "bytes %d-%d/%d" % (start, end, length))) >+ chunk = body[start:(end + 1)] >+ return 206, headers, chunk >+ return headers, body > > username = request.auth.username if request.auth.username else "undefined" > password = request.auth.password if request.auth.username else "undefined" >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-canvas-tainting-iframe.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-canvas-tainting-iframe.html >index 3a73b7e77e86af53505d26fcba842565f16e8af2..a65d2501a8508addf3ec2b6d2daf00b1bdc4af2c 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-canvas-tainting-iframe.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-canvas-tainting-iframe.html >@@ -1,321 +1,69 @@ >-<script src="/common/get-host-info.sub.js"></script> >-<script src="test-helpers.sub.js?pipe=sub"></script> >+<html> >+<title>iframe for fetch canvas tainting test</title> > <script> >-var image_path = base_path() + 'fetch-access-control.py?PNGIMAGE'; >-var host_info = get_host_info(); >-var params = get_query_params(location.href); >- >-var NOT_TAINTED = 'NOT_TAINTED'; >-var TAINTED = 'TAINTED'; >-var LOAD_ERROR = 'LOAD_ERROR'; >-var TIMEOUT_ERROR = 'TIMEOUT_ERROR'; >- >-function get_query_params(url) { >- var search = (new URL(url)).search; >- if (!search) { >- return {}; >- } >- var ret = {}; >- var params = search.substring(1).split('&'); >- params.forEach(function(param) { >- var element = param.split('='); >- ret[decodeURIComponent(element[0])] = decodeURIComponent(element[1]); >- }); >- return ret; >-} >+const NOT_TAINTED = 'NOT_TAINTED'; >+const TAINTED = 'TAINTED'; >+const LOAD_ERROR = 'LOAD_ERROR'; > >+// Creates an image/video element with src=|url| and an optional |cross_origin| >+// attibute. Tries to read from the image/video using a canvas element. Returns >+// NOT_TAINTED if it could be read, TAINTED if it could not be read, and >+// LOAD_ERROR if loading the image/video failed. > function create_test_case_promise(url, cross_origin) { >- return new Promise(function(resolve) { >- var img = new Image(); >- if (cross_origin != '') { >- img.crossOrigin = cross_origin; >- } >- img.onload = function() { >- try { >- var canvas = document.createElement('canvas'); >- canvas.width = 100; >- canvas.height = 100; >- var context = canvas.getContext('2d'); >- context.drawImage(img, 0, 0); >- context.getImageData(0, 0, 100, 100); >- resolve(NOT_TAINTED); >- } catch (e) { >- resolve(TAINTED); >+ return new Promise(resolve => { >+ if (url.indexOf('PNGIMAGE') != -1) { >+ const img = document.createElement('img'); >+ if (cross_origin != '') { >+ img.crossOrigin = cross_origin; > } >- }; >- img.onerror = function() { >- resolve(LOAD_ERROR); >+ img.onload = function() { >+ try { >+ const canvas = document.createElement('canvas'); >+ canvas.width = 100; >+ canvas.height = 100; >+ const context = canvas.getContext('2d'); >+ context.drawImage(img, 0, 0); >+ context.getImageData(0, 0, 100, 100); >+ resolve(NOT_TAINTED); >+ } catch (e) { >+ resolve(TAINTED); >+ } >+ }; >+ img.onerror = function() { >+ resolve(LOAD_ERROR); >+ } >+ img.src = url; >+ return; > } >- img.src = url; >- setTimeout(() => { resolve(TIMEOUT_ERROR); }, 5000); >- }); >-} > >-var results = []; >+ if (url.indexOf('VIDEO') != -1) { >+ const video = document.createElement('video'); >+ video.autoplay = true; >+ if (cross_origin != '') { >+ video.crossOrigin = cross_origin; >+ } >+ video.onplay = function() { >+ try { >+ const canvas = document.createElement('canvas'); >+ canvas.width = 100; >+ canvas.height = 100; >+ const context = canvas.getContext('2d'); >+ context.drawImage(video, 0, 0); >+ context.getImageData(0, 0, 100, 100); >+ resolve(NOT_TAINTED); >+ } catch (e) { >+ resolve(TAINTED); >+ } >+ }; >+ video.onerror = function() { >+ resolve(LOAD_ERROR); >+ } >+ video.src = url; >+ return; >+ } > >-function create_test_promise(url, cross_origin, expected_result) { >- if (params['cache']) { >- url += "&cache"; >- } >- return create_test_case_promise(url, cross_origin).then(function(result) { >- let test_name = url + " - " + (cross_origin ? cross_origin : "default"); >- let test_result = (result == expected_result) ? 'PASS' : 'Result of url:' + url + ' ' + ' cross_origin: ' + cross_origin + ' must be ' + expected_result + ' but ' + result; >- results.push({name: test_name, result: test_result}); >- }); >+ resolve('unknown resource type'); >+ }); > } >- >-window.addEventListener('message', function(evt) { >- results = []; >- var port = evt.ports[0]; >- var image_url = host_info['HTTPS_ORIGIN'] + image_path; >- var remote_image_url = host_info['HTTPS_REMOTE_ORIGIN'] + image_path; >- // Reject tests >- create_test_promise(image_url + '&reject', '', LOAD_ERROR).then(() => { >- return create_test_promise(image_url + '&reject', 'anonymous', LOAD_ERROR) >- }).then(() => { >- return create_test_promise( >- image_url + '&reject', 'use-credentials', LOAD_ERROR) >- }).then(() => { >- // Fallback tests >- return create_test_promise( >- image_url + '&ignore', >- '', >- NOT_TAINTED) >- }).then(() => { >- return create_test_promise( >- remote_image_url + '&ignore', >- '', >- TAINTED) >- }).then(() => { >- return create_test_promise( >- remote_image_url + '&ignore', >- 'anonymous', >- LOAD_ERROR) >- }).then(() => { >- return create_test_promise( >- remote_image_url + '&ACAOrigin=' + host_info['HTTPS_ORIGIN'] + >- '&ignore', >- 'anonymous', >- NOT_TAINTED) >- }).then(() => { >- return create_test_promise( >- remote_image_url + '&ignore', >- 'use-credentials', >- LOAD_ERROR) >- }).then(() => { >- return create_test_promise( >- remote_image_url + '&ACAOrigin=' + host_info['HTTPS_ORIGIN'] + >- '&ignore', >- 'use-credentials', >- LOAD_ERROR) >- }).then(() => { >- return create_test_promise( >- remote_image_url + '&ACAOrigin=' + host_info['HTTPS_ORIGIN'] + >- '&ACACredentials=true&ignore', >- 'use-credentials', >- NOT_TAINTED) >- }).then(() => { >- >- // Credential test (fallback) >- return create_test_promise( >- image_url + '&Auth&ignore', >- '', >- NOT_TAINTED) >- }).then(() => { >- return create_test_promise( >- remote_image_url + '&Auth&ignore', >- '', >- TAINTED) >- }).then(() => { >- return create_test_promise( >- remote_image_url + '&Auth&ignore', >- 'anonymous', >- LOAD_ERROR) >- }).then(() => { >- return create_test_promise( >- remote_image_url + '&Auth&ignore', >- 'use-credentials', >- LOAD_ERROR) >- }).then(() => { >- return create_test_promise( >- remote_image_url + '&Auth&ACAOrigin=' + host_info['HTTPS_ORIGIN'] + >- '&ignore', >- 'use-credentials', >- LOAD_ERROR) >- }).then(() => { >- return create_test_promise( >- remote_image_url + '&Auth&ACAOrigin=' + host_info['HTTPS_ORIGIN'] + >- '&ACACredentials=true&ignore', >- 'use-credentials', >- NOT_TAINTED) >- }).then(() => { >- >- // Basic response >- return create_test_promise( >- image_url + >- '&mode=same-origin&url=' + encodeURIComponent(image_url), >- '', >- NOT_TAINTED) >- }).then(() => { >- return create_test_promise( >- image_url + >- '&mode=same-origin&url=' + encodeURIComponent(image_url), >- 'anonymous', >- NOT_TAINTED) >- }).then(() => { >- return create_test_promise( >- image_url + >- '&mode=same-origin&url=' + encodeURIComponent(image_url), >- 'use-credentials', >- NOT_TAINTED) >- }).then(() => { >- return create_test_promise( >- remote_image_url + >- '&mode=same-origin&url=' + encodeURIComponent(image_url), >- '', >- NOT_TAINTED) >- }).then(() => { >- return create_test_promise( >- remote_image_url + >- '&mode=same-origin&url=' + encodeURIComponent(image_url), >- 'anonymous', >- NOT_TAINTED) >- }).then(() => { >- return create_test_promise( >- remote_image_url + >- '&mode=same-origin&url=' + encodeURIComponent(image_url), >- 'use-credentials', >- NOT_TAINTED) >- }).then(() => { >- >- // Opaque response >- return create_test_promise( >- image_url + >- '&mode=no-cors&url=' + encodeURIComponent(remote_image_url), >- '', >- TAINTED) >- }).then(() => { >- return create_test_promise( >- image_url + >- '&mode=no-cors&url=' + encodeURIComponent(remote_image_url), >- 'anonymous', >- LOAD_ERROR) >- }).then(() => { >- return create_test_promise( >- image_url + >- '&mode=no-cors&url=' + encodeURIComponent(remote_image_url), >- 'use-credentials', >- LOAD_ERROR) >- }).then(() => { >- return create_test_promise( >- remote_image_url + >- '&mode=no-cors&url=' + encodeURIComponent(remote_image_url), >- '', >- TAINTED) >- }).then(() => { >- return create_test_promise( >- remote_image_url + >- '&mode=no-cors&url=' + encodeURIComponent(remote_image_url), >- 'anonymous', >- LOAD_ERROR) >- }).then(() => { >- return create_test_promise( >- remote_image_url + >- '&mode=no-cors&url=' + encodeURIComponent(remote_image_url), >- 'use-credentials', >- LOAD_ERROR) >- }).then(() => { >- >- // CORS response >- return create_test_promise( >- image_url + >- '&mode=cors&url=' + >- encodeURIComponent(remote_image_url + >- '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >- '', >- LOAD_ERROR) // We expect LOAD_ERROR since the server doesn't respond >- // with an Access-Control-Allow-Credentials header. >- }).then(() => { >- return create_test_promise( >- image_url + >- '&mode=cors&credentials=same-origin&url=' + >- encodeURIComponent(remote_image_url + >- '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >- '', >- NOT_TAINTED) >- }).then(() => { >- return create_test_promise( >- image_url + >- '&mode=cors&url=' + >- encodeURIComponent(remote_image_url + >- '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >- 'anonymous', >- NOT_TAINTED) >- }).then(() => { >- return create_test_promise( >- image_url + >- '&mode=cors&url=' + >- encodeURIComponent(remote_image_url + >- '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >- 'use-credentials', >- LOAD_ERROR) // We expect LOAD_ERROR since the server doesn't respond >- // with an Access-Control-Allow-Credentials header. >- }).then(() => { >- return create_test_promise( >- image_url + >- '&mode=cors&url=' + >- encodeURIComponent( >- remote_image_url + >- '&ACACredentials=true&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >- 'use-credentials', >- NOT_TAINTED) >- }).then(() => { >- return create_test_promise( >- remote_image_url + >- '&mode=cors&url=' + >- encodeURIComponent(remote_image_url + >- '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >- '', >- LOAD_ERROR) // We expect LOAD_ERROR since the server doesn't respond >- // with an Access-Control-Allow-Credentials header. >- }).then(() => { >- return create_test_promise( >- remote_image_url + >- '&mode=cors&credentials=same-origin&url=' + >- encodeURIComponent(remote_image_url + >- '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >- '', >- NOT_TAINTED) >- }).then(() => { >- return create_test_promise( >- remote_image_url + >- '&mode=cors&url=' + >- encodeURIComponent(remote_image_url + >- '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >- 'anonymous', >- NOT_TAINTED) >- }).then(() => { >- return create_test_promise( >- remote_image_url + >- '&mode=cors&url=' + >- encodeURIComponent(remote_image_url + >- '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >- 'use-credentials', >- LOAD_ERROR) // We expect LOAD_ERROR since the server doesn't respond >- // with an Access-Control-Allow-Credentials header. >- }).then(() => { >- return create_test_promise( >- remote_image_url + >- '&mode=cors&url=' + >- encodeURIComponent( >- remote_image_url + >- '&ACACredentials=true&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >- 'use-credentials', >- NOT_TAINTED) >- }).then(() => { >- port.postMessage({results: results}); >- }).catch(function(e) { >- port.postMessage({results: 'failure:' + e}); >- }); >- }, false); > </script> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-canvas-tainting-tests.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-canvas-tainting-tests.js >new file mode 100644 >index 0000000000000000000000000000000000000000..2aada3669eff89ef371baae2773e750b31ee37a8 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-canvas-tainting-tests.js >@@ -0,0 +1,241 @@ >+// This is the main driver of the canvas tainting tests. >+const NOT_TAINTED = 'NOT_TAINTED'; >+const TAINTED = 'TAINTED'; >+const LOAD_ERROR = 'LOAD_ERROR'; >+ >+let frame; >+ >+// Creates a single promise_test. >+function canvas_taint_test(url, cross_origin, expected_result) { >+ promise_test(t => { >+ return frame.contentWindow.create_test_case_promise(url, cross_origin) >+ .then(result => { >+ assert_equals(result, expected_result); >+ }); >+ }, 'url "' + url + '" with crossOrigin "' + cross_origin + '" should be ' + >+ expected_result); >+} >+ >+ >+// Runs all the tests. The given |params| has these properties: >+// * |resource_path|: the relative path to the (image/video) resource to test. >+// * |cache|: when true, the service worker bounces responses into >+// Cache Storage and back out before responding with them. >+function do_canvas_tainting_tests(params) { >+ const host_info = get_host_info(); >+ let resource_path = params.resource_path; >+ if (params.cache) >+ resource_path += "&cache=true"; >+ const resource_url = host_info['HTTPS_ORIGIN'] + resource_path; >+ const remote_resource_url = host_info['HTTPS_REMOTE_ORIGIN'] + resource_path; >+ >+ // Set up the service worker and the frame. >+ promise_test(function(t) { >+ const SCOPE = 'resources/fetch-canvas-tainting-iframe.html'; >+ const SCRIPT = 'resources/fetch-rewrite-worker.js'; >+ const host_info = get_host_info(); >+ >+ // login_https() is needed because some test cases use credentials. >+ return login_https(t) >+ .then(function() { >+ return service_worker_unregister_and_register(t, SCRIPT, SCOPE); >+ }) >+ .then(function(registration) { >+ promise_test(() => { >+ if (frame) >+ frame.remove(); >+ return registration.unregister(); >+ }, 'restore global state'); >+ >+ return wait_for_state(t, registration.installing, 'activated'); >+ }) >+ .then(function() { return with_iframe(SCOPE); }) >+ .then(f => { >+ frame = f; >+ }); >+ }, 'initialize global state'); >+ >+ // Reject tests. Add '&reject' so the service worker responds with a rejected promise. >+ // A load error is expected. >+ canvas_taint_test(resource_url + '&reject', '', LOAD_ERROR); >+ canvas_taint_test(resource_url + '&reject', 'anonymous', LOAD_ERROR); >+ canvas_taint_test(resource_url + '&reject', 'use-credentials', LOAD_ERROR); >+ >+ // Fallback tests. Add '&ignore' so the service worker does not respond to the fetch >+ // request, and we fall back to network. >+ canvas_taint_test(resource_url + '&ignore', '', NOT_TAINTED); >+ canvas_taint_test(remote_resource_url + '&ignore', '', TAINTED); >+ canvas_taint_test(remote_resource_url + '&ignore', 'anonymous', LOAD_ERROR); >+ canvas_taint_test( >+ remote_resource_url + '&ACAOrigin=' + host_info['HTTPS_ORIGIN'] + >+ '&ignore', >+ 'anonymous', >+ NOT_TAINTED); >+ canvas_taint_test(remote_resource_url + '&ignore', 'use-credentials', LOAD_ERROR); >+ canvas_taint_test( >+ remote_resource_url + '&ACAOrigin=' + host_info['HTTPS_ORIGIN'] + >+ '&ignore', >+ 'use-credentials', >+ LOAD_ERROR); >+ canvas_taint_test( >+ remote_resource_url + '&ACAOrigin=' + host_info['HTTPS_ORIGIN'] + >+ '&ACACredentials=true&ignore', >+ 'use-credentials', >+ NOT_TAINTED); >+ >+ // Credential tests (with fallback). Add '&Auth' so the server requires authentication. >+ // Furthermore, add '&ignore' so the service worker falls back to network. >+ canvas_taint_test(resource_url + '&Auth&ignore', '', NOT_TAINTED); >+ canvas_taint_test(remote_resource_url + '&Auth&ignore', '', TAINTED); >+ canvas_taint_test( >+ remote_resource_url + '&Auth&ignore', 'anonymous', LOAD_ERROR); >+ canvas_taint_test( >+ remote_resource_url + '&Auth&ignore', >+ 'use-credentials', >+ LOAD_ERROR); >+ canvas_taint_test( >+ remote_resource_url + '&Auth&ACAOrigin=' + host_info['HTTPS_ORIGIN'] + >+ '&ignore', >+ 'use-credentials', >+ LOAD_ERROR); >+ canvas_taint_test( >+ remote_resource_url + '&Auth&ACAOrigin=' + host_info['HTTPS_ORIGIN'] + >+ '&ACACredentials=true&ignore', >+ 'use-credentials', >+ NOT_TAINTED); >+ >+ // In the following tests, the service worker provides a response. >+ // Add '&url' so the service worker responds with fetch(url). >+ // Add '&mode' to configure the fetch request options. >+ >+ // Basic response tests. Set &url to the original url. >+ canvas_taint_test( >+ resource_url + '&mode=same-origin&url=' + encodeURIComponent(resource_url), >+ '', >+ NOT_TAINTED); >+ canvas_taint_test( >+ resource_url + '&mode=same-origin&url=' + encodeURIComponent(resource_url), >+ 'anonymous', >+ NOT_TAINTED); >+ canvas_taint_test( >+ resource_url + '&mode=same-origin&url=' + encodeURIComponent(resource_url), >+ 'use-credentials', >+ NOT_TAINTED); >+ canvas_taint_test( >+ remote_resource_url + '&mode=same-origin&url=' + >+ encodeURIComponent(resource_url), >+ '', >+ NOT_TAINTED); >+ canvas_taint_test( >+ remote_resource_url + '&mode=same-origin&url=' + >+ encodeURIComponent(resource_url), >+ 'anonymous', >+ NOT_TAINTED); >+ canvas_taint_test( >+ remote_resource_url + '&mode=same-origin&url=' + >+ encodeURIComponent(resource_url), >+ 'use-credentials', >+ NOT_TAINTED); >+ >+ // Opaque response tests. Set &url to the cross-origin URL, and &mode to >+ // 'no-cors' so we expect an opaque response. >+ canvas_taint_test( >+ resource_url + >+ '&mode=no-cors&url=' + encodeURIComponent(remote_resource_url), >+ '', >+ TAINTED); >+ canvas_taint_test( >+ resource_url + >+ '&mode=no-cors&url=' + encodeURIComponent(remote_resource_url), >+ 'anonymous', >+ LOAD_ERROR); >+ canvas_taint_test( >+ resource_url + >+ '&mode=no-cors&url=' + encodeURIComponent(remote_resource_url), >+ 'use-credentials', >+ LOAD_ERROR); >+ canvas_taint_test( >+ remote_resource_url + >+ '&mode=no-cors&url=' + encodeURIComponent(remote_resource_url), >+ '', >+ TAINTED); >+ canvas_taint_test( >+ remote_resource_url + >+ '&mode=no-cors&url=' + encodeURIComponent(remote_resource_url), >+ 'anonymous', >+ LOAD_ERROR); >+ canvas_taint_test( >+ remote_resource_url + >+ '&mode=no-cors&url=' + encodeURIComponent(remote_resource_url), >+ 'use-credentials', >+ LOAD_ERROR); >+ >+ // CORS response tests. Set &url to the cross-origin URL, and &mode >+ // to 'cors' to attempt a CORS request. >+ canvas_taint_test( >+ resource_url + '&mode=cors&url=' + >+ encodeURIComponent(remote_resource_url + >+ '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >+ '', >+ LOAD_ERROR); // We expect LOAD_ERROR since the server doesn't respond >+ // with an Access-Control-Allow-Credentials header. >+ canvas_taint_test( >+ resource_url + '&mode=cors&credentials=same-origin&url=' + >+ encodeURIComponent(remote_resource_url + >+ '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >+ '', >+ NOT_TAINTED); >+ canvas_taint_test( >+ resource_url + '&mode=cors&url=' + >+ encodeURIComponent(remote_resource_url + >+ '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >+ 'anonymous', >+ NOT_TAINTED); >+ canvas_taint_test( >+ resource_url + '&mode=cors&url=' + >+ encodeURIComponent(remote_resource_url + >+ '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >+ 'use-credentials', >+ LOAD_ERROR); // We expect LOAD_ERROR since the server doesn't respond >+ // with an Access-Control-Allow-Credentials header. >+ canvas_taint_test( >+ resource_url + '&mode=cors&url=' + >+ encodeURIComponent( >+ remote_resource_url + >+ '&ACACredentials=true&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >+ 'use-credentials', >+ NOT_TAINTED); >+ canvas_taint_test( >+ remote_resource_url + '&mode=cors&url=' + >+ encodeURIComponent(remote_resource_url + >+ '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >+ '', >+ LOAD_ERROR); // We expect LOAD_ERROR since the server doesn't respond >+ // with an Access-Control-Allow-Credentials header. >+ canvas_taint_test( >+ remote_resource_url + '&mode=cors&credentials=same-origin&url=' + >+ encodeURIComponent(remote_resource_url + >+ '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >+ '', >+ NOT_TAINTED); >+ canvas_taint_test( >+ remote_resource_url + '&mode=cors&url=' + >+ encodeURIComponent(remote_resource_url + >+ '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >+ 'anonymous', >+ NOT_TAINTED); >+ canvas_taint_test( >+ remote_resource_url + '&mode=cors&url=' + >+ encodeURIComponent(remote_resource_url + >+ '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >+ 'use-credentials', >+ LOAD_ERROR); // We expect LOAD_ERROR since the server doesn't respond >+ // with an Access-Control-Allow-Credentials header. >+ canvas_taint_test( >+ remote_resource_url + '&mode=cors&url=' + >+ encodeURIComponent( >+ remote_resource_url + >+ '&ACACredentials=true&ACAOrigin=' + host_info['HTTPS_ORIGIN']), >+ 'use-credentials', >+ NOT_TAINTED); >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-cors-exposed-header-names-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-cors-exposed-header-names-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..145952a22cf031e505412fcf7d40d59d527f75dc >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-cors-exposed-header-names-worker.js >@@ -0,0 +1,3 @@ >+self.addEventListener('fetch', (e) => { >+ e.respondWith(fetch(e.request)); >+ }); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-network-fallback-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-network-fallback-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..daa200c2badb82964cc350699832a730b52c91a4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-network-fallback-worker.js >@@ -0,0 +1,3 @@ >+self.addEventListener('fetch', () => { >+ // Do nothing. >+ }); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-custom-response-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-custom-response-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..ff24aed1282c8cf69b801cb4841594aef19db613 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-custom-response-worker.js >@@ -0,0 +1,45 @@ >+'use strict'; >+ >+addEventListener('fetch', event => { >+ const url = new URL(event.request.url); >+ const type = url.searchParams.get('type'); >+ >+ if (!type) return; >+ >+ if (type === 'string') { >+ event.respondWith(new Response('PASS')); >+ } >+ else if (type === 'blob') { >+ event.respondWith( >+ new Response(new Blob(['PASS'])) >+ ); >+ } >+ else if (type === 'buffer-view') { >+ const encoder = new TextEncoder(); >+ event.respondWith( >+ new Response(encoder.encode('PASS')) >+ ); >+ } >+ else if (type === 'buffer') { >+ const encoder = new TextEncoder(); >+ event.respondWith( >+ new Response(encoder.encode('PASS').buffer) >+ ); >+ } >+ else if (type === 'form-data') { >+ const body = new FormData(); >+ body.set('result', 'PASS'); >+ event.respondWith( >+ new Response(body) >+ ); >+ } >+ else if (type === 'search-params') { >+ const body = new URLSearchParams(); >+ body.set('result', 'PASS'); >+ event.respondWith( >+ new Response(body, { >+ headers: { 'Content-Type': 'text/plain' } >+ }) >+ ); >+ } >+}); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-iframe.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-iframe.html >deleted file mode 100644 >index 1904d75657d5781520b089261788d260d122cff6..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-iframe.html >+++ /dev/null >@@ -1,9 +0,0 @@ >-<!DOCTYPE html> >-<script> >-'use strict'; >- >-fetch('body-stream').then(resp => { >- return resp.text(); >- }).then(text => parent.done(text)) >- .catch(e => parent.done('FAIL: ' + e)); >-</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-worker.js >index ddaba55fa7ba52f93b807ad16f3578104ddb2953..aaabdc391a9e5ed426b5698c34a0907e2c61470a 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-worker.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-worker.js >@@ -1,13 +1,37 @@ > 'use strict'; >+importScripts("/resources/testharness.js"); > > self.addEventListener('fetch', event => { >- if (!event.request.url.match(/body-stream$/)) >- return; >+ const url = new URL(event.request.url); >+ if (!url.searchParams.has('stream')) return; > >- const stream = new ReadableStream({start: controller => { >- const encoder = new TextEncoder(); >+ if (url.searchParams.has('use-fetch-stream')) { >+ event.respondWith(async function() { >+ const response = await fetch('pass.txt'); >+ return new Response(response.body); >+ }()); >+ return; >+ } >+ >+ const delayEnqueue = url.searchParams.has('delay'); >+ >+ const stream = new ReadableStream({ >+ start(controller) { >+ const encoder = new TextEncoder(); >+ >+ const populate = () => { > controller.enqueue(encoder.encode('PASS')); > controller.close(); >- }}); >- event.respondWith(new Response(stream)); >+ } >+ >+ if (delayEnqueue) { >+ step_timeout(populate, 16); >+ } >+ else { >+ populate(); >+ } >+ } > }); >+ >+ event.respondWith(new Response(stream)); >+}); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-test-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-test-worker.js >index 65025d934093ae8cab30ab43b0113f01513a4510..d503a6609d695821e207217811b53f957027d118 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-test-worker.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-test-worker.js >@@ -129,6 +129,22 @@ function handleKeepalive(event) { > event.respondWith(new Response(event.request.keepalive)); > } > >+function handleIsReloadNavigation(event) { >+ const request = event.request; >+ const body = >+ `method = ${request.method}, ` + >+ `isReloadNavigation = ${request.isReloadNavigation}`; >+ event.respondWith(new Response(body)); >+} >+ >+function handleIsHistoryNavigation(event) { >+ const request = event.request; >+ const body = >+ `method = ${request.method}, ` + >+ `isHistoryNavigation = ${request.isHistoryNavigation}`; >+ event.respondWith(new Response(body)); >+} >+ > self.addEventListener('fetch', function(event) { > var url = event.request.url; > var handlers = [ >@@ -151,6 +167,8 @@ self.addEventListener('fetch', function(event) { > { pattern: '?integrity', fn: handleIntegrity }, > { pattern: '?request-body', fn: handleRequestBody }, > { pattern: '?keepalive', fn: handleKeepalive }, >+ { pattern: '?isReloadNavigation', fn: handleIsReloadNavigation }, >+ { pattern: '?isHistoryNavigation', fn: handleIsHistoryNavigation }, > ]; > > var handler = null; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-iframe.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-iframe.html >index dcb82871354e0df7c9445d4173ab99567cb7132f..9a4adedb84d466e1a7db41adae767a7a3af0a1ab 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-iframe.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-iframe.html >@@ -5,11 +5,11 @@ > #sameOriginHtml { color: red; } > #synthetic { color: red; } > </style> >-<link href="./cross-origin-css.css" rel="stylesheet" type="text/css"> >-<link href="./cross-origin-html.css" rel="stylesheet" type="text/css"> >+<link href="./cross-origin-css.css?mime=no" rel="stylesheet" type="text/css"> >+<link href="./cross-origin-html.css?mime=no" rel="stylesheet" type="text/css"> > <link href="./fetch-request-css-cross-origin-mime-check-same.css" rel="stylesheet" type="text/css"> > <link href="./fetch-request-css-cross-origin-mime-check-same.html" rel="stylesheet" type="text/css"> >-<link href="./synthetic.css" rel="stylesheet" type="text/css"> >+<link href="./synthetic.css?mime=no" rel="stylesheet" type="text/css"> > <h1 id=crossOriginCss>I should be blue</h1> > <h1 id=crossOriginHtml>I should be blue</h1> > <h1 id=sameOriginCss>I should be blue</h1> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-worker.js >deleted file mode 100644 >index 274142f5ce440016bb53b4ce8cecc44c8adb5b85..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-worker.js >+++ /dev/null >@@ -1,20 +0,0 @@ >-importScripts('/common/get-host-info.sub.js'); >-importScripts('test-helpers.sub.js'); >- >-self.addEventListener('fetch', function(event) { >- if (event.request.url.indexOf('cross-origin-css.css') != -1) { >- event.respondWith(fetch( >- get_host_info()['HTTPS_REMOTE_ORIGIN'] + base_path() + >- 'fetch-request-css-cross-origin-mime-check-cross.css', >- {mode: 'no-cors'})); >- } else if (event.request.url.indexOf('cross-origin-html.css') != -1) { >- event.respondWith(fetch( >- get_host_info()['HTTPS_REMOTE_ORIGIN'] + base_path() + >- 'fetch-request-css-cross-origin-mime-check-cross.html', >- {mode: 'no-cors'})); >- } else if (event.request.url.indexOf('synthetic.css') != -1) { >- event.respondWith(new Response("#synthetic { color: blue; }")); >- } else { >- event.respondWith(fetch(event.request)); >- } >- }); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-read-contents.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-read-contents.html >new file mode 100644 >index 0000000000000000000000000000000000000000..c902366b023accd611d52cd1c34e6b7c538f5cc6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-read-contents.html >@@ -0,0 +1,15 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>iframe: cross-origin CSS via service worker</title> >+ >+<!-- Service worker responds with a cross-origin opaque response. --> >+<link href="cross-origin-css.css" rel="stylesheet" type="text/css"> >+ >+<!-- Service worker responds with a cross-origin CORS approved response. --> >+<link href="cross-origin-css.css?cors" rel="stylesheet" type="text/css"> >+ >+<!-- Service worker falls back to network. This is a same-origin response. --> >+<link href="fetch-request-css-cross-origin-mime-check-same.css" rel="stylesheet" type="text/css"> >+ >+<!-- Service worker responds with a new Response() synthetic response. --> >+<link href="synthetic.css" rel="stylesheet" type="text/css"> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..a71e91216c10893dafb72fd01de822ef29e40e48 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-worker.js >@@ -0,0 +1,65 @@ >+importScripts('/common/get-host-info.sub.js'); >+importScripts('test-helpers.sub.js'); >+ >+const HOST_INFO = get_host_info(); >+const REMOTE_ORIGIN = HOST_INFO.HTTPS_REMOTE_ORIGIN; >+const BASE_PATH = base_path(); >+const CSS_FILE = 'fetch-request-css-cross-origin-mime-check-cross.css'; >+const HTML_FILE = 'fetch-request-css-cross-origin-mime-check-cross.html'; >+ >+function add_pipe_header(url_str, header) { >+ if (url_str.indexOf('?pipe=') == -1) { >+ url_str += '?pipe='; >+ } else { >+ url_str += '|'; >+ } >+ url_str += `header${header}`; >+ return url_str; >+} >+ >+self.addEventListener('fetch', function(event) { >+ const url = new URL(event.request.url); >+ >+ const use_mime = >+ (url.searchParams.get('mime') != 'no'); >+ const mime_header = '(Content-Type, text/css)'; >+ >+ const use_cors = >+ (url.searchParams.has('cors')); >+ const cors_header = '(Access-Control-Allow-Origin, *)'; >+ >+ const file = url.pathname.substring(url.pathname.lastIndexOf('/') + 1); >+ >+ // Respond with a cross-origin CSS resource, using CORS if desired. >+ if (file == 'cross-origin-css.css') { >+ let fetch_url = REMOTE_ORIGIN + BASE_PATH + CSS_FILE; >+ if (use_mime) >+ fetch_url = add_pipe_header(fetch_url, mime_header); >+ if (use_cors) >+ fetch_url = add_pipe_header(fetch_url, cors_header); >+ const mode = use_cors ? 'cors' : 'no-cors'; >+ event.respondWith(fetch(fetch_url, {'mode': mode})); >+ return; >+ } >+ >+ // Respond with a cross-origin CSS resource with an HTML name. This is only >+ // used in the MIME sniffing test, so MIME is never added. >+ if (file == 'cross-origin-html.css') { >+ const fetch_url = REMOTE_ORIGIN + BASE_PATH + HTML_FILE; >+ event.respondWith(fetch(fetch_url, {mode: 'no-cors'})); >+ return; >+ } >+ >+ // Respond with synthetic CSS. >+ if (file == 'synthetic.css') { >+ let headers = {}; >+ if (use_mime) { >+ headers['Content-Type'] = 'text/css'; >+ } >+ >+ event.respondWith(new Response("#synthetic { color: blue; }", {headers})); >+ return; >+ } >+ >+ // Otherwise, fallback to network. >+ }); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-iframe.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-iframe.html >index 68a1a868760bbc3c9668b62224b7f940c5dcffc3..e6e9380ba62276638ab6b771d5d59b6b632b5252 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-iframe.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-iframe.html >@@ -1 +1 @@ >-<script src="empty.js"></script> >+<script src="./fetch-request-no-freshness-headers-script.py"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-script.py b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-script.py >new file mode 100644 >index 0000000000000000000000000000000000000000..e6a392c863e33e658488e9c7a10c5a46dc4ad485 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-script.py >@@ -0,0 +1,6 @@ >+def main(request, response): >+ headers = [] >+ # Sets an ETag header to check the cache revalidation behavior. >+ headers.append(("ETag", "abc123")) >+ headers.append(("Content-Type", "text/javascript")) >+ return headers, "/* empty script */" >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-redirect-iframe.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-redirect-iframe.html >index 4c52ca9177974692098d6f233da8f4a0b50a45e1..ffd76bfc49908b9b25d10d5671c9ddb7095ea752 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-redirect-iframe.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-redirect-iframe.html >@@ -20,7 +20,6 @@ function load_image(url) { > img.onload = resolve; > img.onerror = reject; > img.src = url; >- setTimeout(() => { reject("image load timed out") }, 5000); > }); > } > >@@ -31,7 +30,6 @@ function load_audio(url) { > audio.oncanplay = resolve; > audio.onerror = reject; > audio.src = url; >- setTimeout(() => { reject("audio load timed out") }, 5000); > }); > } > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html >index ab3e2a1280b91755d4d0cf81e4079b8f4df66131..65fa5171b3d430b07accf917181033d6fcaa3df0 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html >@@ -19,24 +19,6 @@ function get_boundary(headers) { > return ''; > } > >-function create_file_system_file(file_name, data) { >- return new Promise(function(resolve, reject) { >- webkitRequestFileSystem(TEMPORARY, 1024, function(fs) { >- fs.root.getFile( >- file_name, {create: true, exclusive: true}, >- function(fileEntry) { >- fileEntry.createWriter(function(fileWriter) { >- fileWriter.onwriteend = function(e) { >- fileEntry.file(function(file) { resolve(file); }); >- }; >- var blob = new Blob([data], {type: 'text/plain'}); >- fileWriter.write(blob); >- }); >- }, function(e) { reject(e); }); >- }, function(e) { reject(e); }); >- }); >-} >- > function xhr_send(url_base, method, data, with_credentials) { > return new Promise(function(resolve, reject) { > var xhr = new XMLHttpRequest(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-sync-on-worker-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-sync-on-worker-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..0d24ffc1f33330fb59996c3a65b7530ced0f6806 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-sync-on-worker-worker.js >@@ -0,0 +1,41 @@ >+'use strict'; >+ >+self.onfetch = function(event) { >+ if (event.request.url.indexOf('non-existent-file.txt') !== -1) { >+ event.respondWith(new Response('Response from service worker')); >+ } else if (event.request.url.indexOf('/iframe_page') !== -1) { >+ event.respondWith(new Response( >+ '<!DOCTYPE html>\n' + >+ '<script>\n' + >+ 'function performSyncXHROnWorker(url) {\n' + >+ ' return new Promise((resolve) => {\n' + >+ ' var worker =\n' + >+ ' new Worker(\'./worker_script\');\n' + >+ ' worker.addEventListener(\'message\', (msg) => {\n' + >+ ' resolve(msg.data);\n' + >+ ' });\n' + >+ ' worker.postMessage({\n' + >+ ' url: url\n' + >+ ' });\n' + >+ ' });\n' + >+ '}\n' + >+ '</script>', >+ { >+ headers: [['content-type', 'text/html']] >+ })); >+ } else if (event.request.url.indexOf('/worker_script') !== -1) { >+ event.respondWith(new Response( >+ 'self.onmessage = (msg) => {' + >+ ' const syncXhr = new XMLHttpRequest();' + >+ ' syncXhr.open(\'GET\', msg.data.url, false);' + >+ ' syncXhr.send();' + >+ ' self.postMessage({' + >+ ' status: syncXhr.status,' + >+ ' responseText: syncXhr.responseText' + >+ ' });' + >+ '}', >+ { >+ headers: [['content-type', 'application/javascript']] >+ })); >+ } >+}; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-worker.js >index 8b4fd6bf91e49200aae9aaf231345b394aac4ede..91b3abb14d9c675a0bd886344a26482f36bb5770 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-worker.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-worker.js >@@ -16,7 +16,7 @@ self.addEventListener('fetch', function(event) { > credentials: event.request.credentials, > headers: headers, > body: result >- }), { headers : [["Cache-Control", "no-cache"]] } )); >+ }))); > }); > })); > }); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-rewrite-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-rewrite-worker.js >index 5d74cb39d76daf0cd29f73b919f62b895da792e6..f2d49e2706a40fb55f098f5e33dc6c17a93bf1cb 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-rewrite-worker.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-rewrite-worker.js >@@ -1,3 +1,11 @@ >+// By default, this worker responds to fetch events with >+// respondWith(fetch(request)). Additionally, if the request has a &url >+// parameter, it fetches the provided URL instead. Because it forwards fetch >+// events to this other URL, it is called the "fetch rewrite" worker. >+// >+// The worker also looks for other params on the request to do more custom >+// behavior, like falling back to network or throwing an error. >+ > function get_query_params(url) { > var search = (new URL(url)).search; > if (!search) { >@@ -125,6 +133,7 @@ self.addEventListener('fetch', function(event) { > } > } > >+ // |cache| means to bounce responses through Cache Storage and back. > if (params['cache']) { > var cacheName = "cached-fetches-" + performance.now() + "-" + > event.request.url; >@@ -137,13 +146,9 @@ self.addEventListener('fetch', function(event) { > return cache.match(request); > }).then(function(cached) { > cachedResponse = cached; >- return cache.delete(request.url); >- }).then(function() { > return self.caches.delete(cacheName); > }).then(function() { >- resolve(cachedResponse); >- }).catch((e) => { >- reject(e); >+ resolve(cachedResponse); > }); > } else { > resolve(response); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/iframe-with-image.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/iframe-with-image.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ce78840cb28310947f39232acd87fba0c0262f0b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/iframe-with-image.html >@@ -0,0 +1,2 @@ >+<!DOCTYPE html> >+<img src="square"> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/import-scripts-updated-flag-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/import-scripts-updated-flag-worker.js >index 0f5005d9af41d95c9243096478d2e35c653c9660..e01664662ef178a1dfe51c5970392d0fb66c7234 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/import-scripts-updated-flag-worker.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/import-scripts-updated-flag-worker.js >@@ -4,6 +4,7 @@ let echo_output = null; > > // Tests importing a script that sets |echo_output| to the query string. > function test_import(str) { >+ echo_output = null; > importScripts('import-scripts-echo.py?msg=' + str); > assert_equals(echo_output, str); > } >@@ -18,6 +19,7 @@ self.addEventListener('install', () => { > > self.addEventListener('message', e => { > var error = null; >+ echo_output = null; > > try { > importScripts('import-scripts-echo.py?msg=' + e.data); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/install-worker.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/install-worker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ed20cd4dca6a14e427b907a1d5147c88596bb1f0 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/install-worker.html >@@ -0,0 +1,22 @@ >+<!DOCTYPE html> >+<html> >+<body> >+<p>Loading...</p> >+<script> >+async function install() { >+ let script; >+ for (const q of location.search.slice(1).split('&')) { >+ if (q.split('=')[0] === 'script') { >+ script = q.split('=')[1]; >+ } >+ } >+ const scope = location.href; >+ const reg = await navigator.serviceWorker.register(script, {scope}); >+ await navigator.serviceWorker.ready; >+ location.reload(); >+} >+ >+install(); >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/interfaces-idls.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/interfaces-idls.js >index 9f5c5ed9675a10c1d66f39ffa27afda9db608af2..3db45c64346254983d166ba9eb94e5c342c0d653 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/interfaces-idls.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/interfaces-idls.js >@@ -12,124 +12,3 @@ interface AbstractWorker { > attribute EventHandler onerror; > }; > `; >-idls.tested = ` >-[Global=(Worker,ServiceWorker), Exposed=ServiceWorker] >-interface ServiceWorkerGlobalScope : WorkerGlobalScope { >- [SameObject] readonly attribute Clients clients; >- [SameObject] readonly attribute ServiceWorkerRegistration registration; >- >- [NewObject] Promise<void> skipWaiting(); >- >- attribute EventHandler oninstall; >- attribute EventHandler onactivate; >- attribute EventHandler onfetch; >- >- // event >- attribute EventHandler onmessage; // event.source of the message events is Client object >- attribute EventHandler onmessageerror; >-}; >- >-[Exposed=ServiceWorker] >-interface Client { >- readonly attribute USVString url; >- readonly attribute DOMString id; >- readonly attribute ClientType type; >- readonly attribute boolean reserved; >- void postMessage(any message, optional sequence<object> transfer = []); >-}; >- >-[Exposed=ServiceWorker] >-interface WindowClient : Client { >- readonly attribute VisibilityState visibilityState; >- readonly attribute boolean focused; >- [SameObject] readonly attribute FrozenArray<USVString> ancestorOrigins; >- [NewObject] Promise<WindowClient> focus(); >- [NewObject] Promise<WindowClient> navigate(USVString url); >-}; >- >-[Exposed=ServiceWorker] >-interface Clients { >- // The objects returned will be new instances every time >- [NewObject] Promise<any> get(DOMString id); >- [NewObject] Promise<sequence<Client>> matchAll(optional ClientQueryOptions options); >- [NewObject] Promise<WindowClient?> openWindow(USVString url); >- [NewObject] Promise<void> claim(); >-}; >- >-[SecureContext, Exposed=(Window,Worker)] >-interface ServiceWorker : EventTarget { >- readonly attribute USVString scriptURL; >- readonly attribute ServiceWorkerState state; >- void postMessage(any message, optional sequence<object> transfer = []); >- >- // event >- attribute EventHandler onstatechange; >-}; >-ServiceWorker implements AbstractWorker; >- >-enum ServiceWorkerState { >- "installing", >- "installed", >- "activating", >- "activated", >- "redundant" >-}; >- >-enum ServiceWorkerUpdateViaCache { >- "imports", >- "all", >- "none" >-}; >- >-[SecureContext, Exposed=(Window,Worker)] >-interface ServiceWorkerRegistration : EventTarget { >- readonly attribute ServiceWorker? installing; >- readonly attribute ServiceWorker? waiting; >- readonly attribute ServiceWorker? active; >- [SameObject] readonly attribute NavigationPreloadManager navigationPreload; >- >- readonly attribute USVString scope; >- readonly attribute ServiceWorkerUpdateViaCache updateViaCache; >- >- [NewObject] Promise<void> update(); >- [NewObject] Promise<boolean> unregister(); >- >- // event >- attribute EventHandler onupdatefound; >-}; >- >-[Constructor(), Exposed=(Window,Worker)] >-interface EventTarget { >- void addEventListener(DOMString type, EventListener? callback, optional (AddEventListenerOptions or boolean) options); >- void removeEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options); >- boolean dispatchEvent(Event event); >-}; >- >-[SecureContext, Exposed=(Window,Worker)] >-interface NavigationPreloadManager { >- Promise<void> enable(); >- Promise<void> disable(); >- Promise<void> setHeaderValue(ByteString value); >- Promise<NavigationPreloadState> getState(); >-}; >- >-[SecureContext, Exposed=(Window,Worker)] >-interface Cache { >- [NewObject] Promise<any> match(RequestInfo request, optional CacheQueryOptions options); >- [NewObject] Promise<sequence<Response>> matchAll(optional RequestInfo request, optional CacheQueryOptions options); >- [NewObject] Promise<void> add(RequestInfo request); >- [NewObject] Promise<void> addAll(sequence<RequestInfo> requests); >- [NewObject] Promise<void> put(RequestInfo request, Response response); >- [NewObject] Promise<boolean> delete(RequestInfo request, optional CacheQueryOptions options); >- [NewObject] Promise<sequence<Request>> keys(optional RequestInfo request, optional CacheQueryOptions options); >-}; >- >-[SecureContext, Exposed=(Window,Worker)] >-interface CacheStorage { >- [NewObject] Promise<any> match(RequestInfo request, optional CacheQueryOptions options); >- [NewObject] Promise<boolean> has(DOMString cacheName); >- [NewObject] Promise<Cache> open(DOMString cacheName); >- [NewObject] Promise<boolean> delete(DOMString cacheName); >- [NewObject] Promise<sequence<DOMString>> keys(); >-}; >-`; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/interfaces-worker.sub.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/interfaces-worker.sub.js >index 7bdf1016215571efd427111bd21e08416a1bf4dc..29c859bb91456a9f5ee3c98986df98c676485d93 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/interfaces-worker.sub.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/interfaces-worker.sub.js >@@ -5,10 +5,28 @@ importScripts('worker-testharness.js'); > importScripts('/resources/WebIDLParser.js'); > importScripts('/resources/idlharness.js'); > >-var idlArray = new IdlArray(); >-idlArray.add_untested_idls(idls.untested); >-idlArray.add_idls(idls.tested); >-idlArray.add_objects({ >+promise_test(async (t) => { >+ var idlArray = new IdlArray(); >+ const dom = await fetch('/interfaces/dom.idl').then(r => r.text()); >+ const serviceWorkerIdl = await fetch('/interfaces/ServiceWorker.idl').then(r => r.text()); >+ >+ idlArray.add_untested_idls(idls.untested); >+ idlArray.add_untested_idls(dom, { only: ['EventTarget'] }); >+ idlArray.add_idls(serviceWorkerIdl, { only: [ >+ 'ServiceWorkerGlobalScope', >+ 'Client', >+ 'WindowClient', >+ 'Clients', >+ 'ServiceWorker', >+ 'ServiceWorkerState', >+ 'ServiceWorkerUpdateViaCache', >+ 'ServiceWorkerRegistration', >+ 'EventTarget', >+ 'NavigationPreloadManager', >+ 'Cache', >+ 'CacheStorage', >+ ]}); >+ idlArray.add_objects({ > ServiceWorkerGlobalScope: ['self'], > Clients: ['self.clients'], > ServiceWorkerRegistration: ['self.registration'], >@@ -17,16 +35,14 @@ idlArray.add_objects({ > // Client: ['self.clientInstance'], > // WindowClient: ['self.windowClientInstance'] > }); >+ return create_temporary_cache(t) >+ .then(function(cache) { >+ self.cacheInstance = cache; > >-promise_test(function(t) { >- return create_temporary_cache(t) >- .then(function(cache) { >- self.cacheInstance = cache; >- >- idlArray.add_objects({ Cache: ['self.cacheInstance'] }); >- idlArray.test(); >- }); >- }, 'test setup (cache creation)'); >+ idlArray.add_objects({ Cache: ['self.cacheInstance'] }); >+ idlArray.test(); >+ }); >+}, 'test setup (cache creation)'); > > test(function() { > var req = new Request('http://{{host}}/', >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/local-url-inherit-controller-frame.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/local-url-inherit-controller-frame.html >new file mode 100644 >index 0000000000000000000000000000000000000000..b331f88d47179ef15d3f2634f84d6a2791001934 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/local-url-inherit-controller-frame.html >@@ -0,0 +1,130 @@ >+<!DOCTYPE html> >+<html> >+<script> >+ >+const fetchURL = new URL('dummy.txt', window.location).href; >+ >+const frameControllerText = >+`<script> >+ let t = null; >+ try { >+ if (navigator.serviceWorker.controller) { >+ t = navigator.serviceWorker.controller.scriptURL; >+ } >+ } catch (e) { >+ t = e.message; >+ } finally { >+ parent.postMessage({ data: t }, '*'); >+ } >+</` + `script>`; >+ >+const frameFetchText = >+`<script> >+ fetch('${fetchURL}', { mode: 'no-cors' }).then(response => { >+ return response.text(); >+ }).then(text => { >+ parent.postMessage({ data: text }, '*'); >+ }).catch(e => { >+ parent.postMessage({ data: e.message }, '*'); >+ }); >+</` + `script>`; >+ >+const workerControllerText = >+`let t = navigator.serviceWorker.controller >+ ? navigator.serviceWorker.controller.scriptURL >+ : null; >+self.postMessage(t);`; >+ >+const workerFetchText = >+`fetch('${fetchURL}', { mode: 'no-cors' }).then(response => { >+ return response.text(); >+}).then(text => { >+ self.postMessage(text); >+}).catch(e => { >+ self.postMessage(e.message); >+});` >+ >+function getChildText(opts) { >+ if (opts.child === 'iframe') { >+ if (opts.check === 'controller') { >+ return frameControllerText; >+ } >+ >+ if (opts.check === 'fetch') { >+ return frameFetchText; >+ } >+ >+ throw('unexpected feature to check: ' + opts.check); >+ } >+ >+ if (opts.child === 'worker') { >+ if (opts.check === 'controller') { >+ return workerControllerText; >+ } >+ >+ if (opts.check === 'fetch') { >+ return workerFetchText; >+ } >+ >+ throw('unexpected feature to check: ' + opts.check); >+ } >+ >+ throw('unexpected child type ' + opts.child); >+} >+ >+function makeURL(opts) { >+ let mimetype = opts.child === 'iframe' ? 'text/html' >+ : 'text/javascript'; >+ >+ if (opts.scheme === 'blob') { >+ let blob = new Blob([getChildText(opts)], { type: mimetype }); >+ return URL.createObjectURL(blob); >+ } >+ >+ if (opts.scheme === 'data') { >+ return `data:${mimetype},${getChildText(opts)}`; >+ } >+ >+ throw(`unexpected URL scheme ${opts.scheme}`); >+} >+ >+function testWorkerChild(url) { >+ let w = new Worker(url); >+ return new Promise((resolve, reject) => { >+ w.onmessage = resolve; >+ w.onerror = evt => { >+ reject(evt.message); >+ } >+ }); >+} >+ >+function testIframeChild(url) { >+ let frame = document.createElement('iframe'); >+ frame.src = url; >+ document.body.appendChild(frame); >+ >+ return new Promise(resolve => { >+ addEventListener('message', evt => { >+ resolve(evt.data); >+ }, { once: true }); >+ }); >+} >+ >+function testURL(opts, url) { >+ if (opts.child === 'worker') { >+ return testWorkerChild(url); >+ } >+ >+ if (opts.child === 'iframe') { >+ return testIframeChild(url); >+ } >+ >+ throw(`unexpected child type ${opts.child}`); >+} >+ >+function checkChildController(opts) { >+ let url = makeURL(opts); >+ return testURL(opts, url); >+} >+</script> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/local-url-inherit-controller-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/local-url-inherit-controller-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..9d8955f111f6f3624da8a31e033544e738ba2751 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/local-url-inherit-controller-worker.js >@@ -0,0 +1,5 @@ >+addEventListener('fetch', evt => { >+ if (evt.request.url.includes('dummy')) { >+ evt.respondWith(new Response('intercepted')); >+ } >+}); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/multipart-image-iframe.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/multipart-image-iframe.html >new file mode 100644 >index 0000000000000000000000000000000000000000..c59b95594ff505913e856377459eba28b00b8c6d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/multipart-image-iframe.html >@@ -0,0 +1,19 @@ >+<script> >+function load_multipart_image(src) { >+ return new Promise((resolve, reject) => { >+ const img = document.createElement('img'); >+ img.addEventListener('load', () => resolve(img)); >+ img.addEventListener('error', (e) => reject(new DOMException('load failed', 'NetworkError'))); >+ img.src = src; >+ }); >+} >+ >+function get_image_data(img) { >+ const canvas = document.createElement('canvas'); >+ const context = canvas.getContext('2d'); >+ context.drawImage(img, 0, 0); >+ // When |img.src| is cross origin, this should throw a SecurityError. >+ const imageData = context.getImageData(0, 0, 1, 1); >+ return imageData; >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/multipart-image-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/multipart-image-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..a38fe54d34fcb1d27bc350bcfa75007497776a01 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/multipart-image-worker.js >@@ -0,0 +1,21 @@ >+importScripts('/common/get-host-info.sub.js'); >+importScripts('test-helpers.sub.js'); >+ >+const host_info = get_host_info(); >+ >+const multipart_image_path = base_path() + 'multipart-image.py'; >+const sameorigin_url = host_info['HTTPS_ORIGIN'] + multipart_image_path; >+const cross_origin_url = host_info['HTTPS_REMOTE_ORIGIN'] + multipart_image_path; >+ >+self.addEventListener('fetch', event => { >+ const url = event.request.url; >+ if (url.indexOf('cross-origin-multipart-image-with-no-cors') >= 0) { >+ event.respondWith(fetch(cross_origin_url, {mode: 'no-cors'})); >+ } else if (url.indexOf('cross-origin-multipart-image-with-cors-rejected') >= 0) { >+ event.respondWith(fetch(cross_origin_url, {mode: 'cors'})); >+ } else if (url.indexOf('cross-origin-multipart-image-with-cors-approved') >= 0) { >+ event.respondWith(fetch(cross_origin_url + '?approvecors', {mode: 'cors'})); >+ } else if (url.indexOf('same-origin-multipart-image') >= 0) { >+ event.respondWith(fetch(sameorigin_url)); >+ } >+}); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/multipart-image.py b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/multipart-image.py >new file mode 100644 >index 0000000000000000000000000000000000000000..f94ee1c64fd9bec0be9879df8a4c166e9fa5e0f1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/multipart-image.py >@@ -0,0 +1,23 @@ >+# A request handler that serves a multipart image. >+ >+import os >+ >+ >+BOUNDARY = 'cutHere' >+ >+ >+def create_part(path): >+ with open(path, 'rb') as f: >+ return 'Content-Type: image/png\r\n\r\n' + f.read() + '--%s' % BOUNDARY >+ >+ >+def main(request, response): >+ content_type = 'multipart/x-mixed-replace; boundary=%s' % BOUNDARY >+ headers = [('Content-Type', content_type)] >+ if 'approvecors' in request.GET: >+ headers.append(('Access-Control-Allow-Origin', '*')) >+ >+ image_path = os.path.join(request.doc_root, 'images') >+ body = create_part(os.path.join(image_path, 'red.png')) >+ body = body + create_part(os.path.join(image_path, 'red-16x16.png')) >+ return headers, body >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/navigation-timing-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/navigation-timing-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..8539b40066dd91bbfaf7ef240b8104dcb2ab3b27 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/navigation-timing-worker.js >@@ -0,0 +1,15 @@ >+self.addEventListener('fetch', (event) => { >+ const url = event.request.url; >+ >+ // Network fallback. >+ if (url.indexOf('network-fallback') >= 0) { >+ return; >+ } >+ >+ // Don't intercept redirect. >+ if (url.indexOf('redirect.py') >= 0) { >+ return; >+ } >+ >+ event.respondWith(fetch(url)); >+}); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/object-image-is-not-intercepted-iframe.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/object-image-is-not-intercepted-iframe.html >new file mode 100644 >index 0000000000000000000000000000000000000000..5a20a58ab16906f42b05fd80ccf22024d59de279 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/object-image-is-not-intercepted-iframe.html >@@ -0,0 +1,21 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>iframe for embed-and-object-are-not-intercepted test</title> >+<body> >+<object type="image/png" data="/images/green.png"></embed> >+<script> >+// Our parent (the root frame of the test) will examine this to get the result. >+var test_promise = new Promise(resolve => { >+ if (!navigator.serviceWorker.controller) >+ resolve('FAIL: this iframe is not controlled'); >+ >+ const elem = document.querySelector('object'); >+ elem.addEventListener('load', e => { >+ resolve('request was not intercepted'); >+ }); >+ elem.addEventListener('error', e => { >+ resolve('FAIL: request was intercepted'); >+ }); >+ }); >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/object-is-not-intercepted-iframe.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/object-is-not-intercepted-iframe.html >new file mode 100644 >index 0000000000000000000000000000000000000000..0aeb81951ede48c62780fe723013b2ad77ffe336 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/object-is-not-intercepted-iframe.html >@@ -0,0 +1,18 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>iframe for embed-and-object-are-not-intercepted test</title> >+<body> >+<script> >+// The OBJECT element will call this with the result about whether the OBJECT >+// request was intercepted by the service worker. >+var report_result; >+ >+// Our parent (the root frame of the test) will examine this to get the result. >+var test_promise = new Promise(resolve => { >+ report_result = resolve; >+ }); >+</script> >+ >+<object data="embedded-content-from-server.html"></object> >+</body> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/pass-through-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/pass-through-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..5eaf48d5887d119e00b0db9d4adb7ada42b37855 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/pass-through-worker.js >@@ -0,0 +1,3 @@ >+addEventListener('fetch', evt => { >+ evt.respondWith(fetch(evt.request)); >+}); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/pass.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/pass.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..7ef22e9a431ad0272713b71fdc8794016c8ef12f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/pass.txt >@@ -0,0 +1 @@ >+PASS >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/range-request-to-different-origins-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/range-request-to-different-origins-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..cab6058339058f85671948e0d920ab4934367d0f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/range-request-to-different-origins-worker.js >@@ -0,0 +1,40 @@ >+// This worker is meant to test range requests where the responses come from >+// multiple origins. It forwards the first request to a cross-origin URL >+// (generating an opaque response). The server is expected to return a 206 >+// Partial Content response. Then the worker lets subsequent range requests >+// fall back to network (generating same-origin responses). The intent is to try >+// to trick the browser into treating the resource as same-origin. >+// >+// It would also be interesting to do the reverse test where the first request >+// goes to the same-origin URL, and subsequent range requests go cross-origin in >+// 'no-cors' mode to receive opaque responses. But the service worker cannot do >+// this, because in 'no-cors' mode the 'range' HTTP header is disallowed. >+ >+importScripts('/common/get-host-info.sub.js') >+ >+let initial = true; >+function is_initial_request() { >+ const old = initial; >+ initial = false; >+ return old; >+} >+ >+self.addEventListener('fetch', e => { >+ const url = new URL(e.request.url); >+ if (url.search.indexOf('VIDEO') == -1) { >+ // Fall back for non-video. >+ return; >+ } >+ >+ // Make the first request go cross-origin. >+ if (is_initial_request()) { >+ const cross_origin_url = get_host_info().HTTPS_REMOTE_ORIGIN + >+ url.pathname + url.search; >+ const cross_origin_request = new Request(cross_origin_url, >+ {mode: 'no-cors', headers: e.request.headers}); >+ e.respondWith(fetch(cross_origin_request)); >+ return; >+ } >+ >+ // Fall back to same origin for subsequent range requests. >+ }); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/range-request-with-different-cors-modes-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/range-request-with-different-cors-modes-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..7580b0b68a95e7429adec9e37e180a06b53ca15d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/range-request-with-different-cors-modes-worker.js >@@ -0,0 +1,60 @@ >+// This worker is meant to test range requests where the responses are a mix of >+// opaque ones and non-opaque ones. It forwards the first request to a >+// cross-origin URL (generating an opaque response). The server is expected to >+// return a 206 Partial Content response. Then the worker forwards subsequent >+// range requests to that URL, with CORS sharing generating a non-opaque >+// responses. The intent is to try to trick the browser into treating the >+// resource as non-opaque. >+// >+// It would also be interesting to do the reverse test where the first request >+// uses 'cors', and subsequent range requests use 'no-cors' mode. But the >+// service worker cannot do this, because in 'no-cors' mode the 'range' HTTP >+// header is disallowed. >+ >+importScripts('/common/get-host-info.sub.js') >+ >+let initial = true; >+function is_initial_request() { >+ const old = initial; >+ initial = false; >+ return old; >+} >+ >+self.addEventListener('fetch', e => { >+ const url = new URL(e.request.url); >+ if (url.search.indexOf('VIDEO') == -1) { >+ // Fall back for non-video. >+ return; >+ } >+ >+ let cross_origin_url = get_host_info().HTTPS_REMOTE_ORIGIN + >+ url.pathname + url.search; >+ >+ // The first request is no-cors. >+ if (is_initial_request()) { >+ const init = { mode: 'no-cors', headers: e.request.headers }; >+ const cross_origin_request = new Request(cross_origin_url, init); >+ e.respondWith(fetch(cross_origin_request)); >+ return; >+ } >+ >+ // Subsequent range requests are cors. >+ >+ // Copy headers needed for range requests. >+ let my_headers = new Headers; >+ if (e.request.headers.get('accept')) >+ my_headers.append('accept', e.request.headers.get('accept')); >+ if (e.request.headers.get('range')) >+ my_headers.append('range', e.request.headers.get('range')); >+ >+ // Add &ACAOrigin to allow CORS. >+ cross_origin_url += '&ACAOrigin=' + get_host_info().HTTPS_ORIGIN; >+ // Add &ACAHeaders to allow range requests. >+ cross_origin_url += '&ACAHeaders=accept,range'; >+ >+ // Make the CORS request. >+ const init = { mode: 'cors', headers: my_headers }; >+ const cross_origin_request = new Request(cross_origin_url, init); >+ e.respondWith(fetch(cross_origin_request)); >+ }); >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/registration-tests-security-error.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/registration-tests-security-error.js >index c98c4b9440b27e07483dc08669ae8cf08ded81be..c84bb66e042e1354165de3efd291f2aa2b97b9c5 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/registration-tests-security-error.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/registration-tests-security-error.js >@@ -40,7 +40,7 @@ function registration_tests_security_error(register_method, check_error_types) { > > promise_test(function(t) { > var script = 'resources/redirect.py?Redirect=' + >- encodeURIComponent('/service-workers/service-worker/resources/registration-worker.js'); >+ encodeURIComponent('/resources/registration-worker.js'); > var scope = 'resources/scope/redirect/'; > return promise_rejects(t, > check_error_types ? 'SecurityError' : null, >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/resource-timing-iframe.sub.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/resource-timing-iframe.sub.html >index c9308ea515e8d403a941ff4578804f3fbc090578..4b626576ab456eae02aa922884b0d4917caeca14 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/resource-timing-iframe.sub.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/resource-timing-iframe.sub.html >@@ -2,5 +2,9 @@ > <script src="empty.js"></script> > <script src="dummy.js"></script> > <script src="redirect.py?Redirect=empty.js"></script> >+<img src="square.png"> >+<img src="https://{{domains[www1]}}:{{ports[https][0]}}/service-workers/service-worker/resources/square.png"> > <img src="missing.jpg"> > <img src="https://{{domains[www1]}}:{{ports[https][0]}}/service-workers/service-worker/resources/missing.jpg"> >+<img src='missing.jpg?SWRespondsWithFetch'> >+<script src='empty-worker.js'></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/resource-timing-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/resource-timing-worker.js >index 452876838f5790400d25e4af9290a9f7ff7ac73c..5bc6ef34748f6de4b418fd16d2261a4276483a6a 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/resource-timing-worker.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/resource-timing-worker.js >@@ -1,9 +1,12 @@ > self.addEventListener('fetch', function(event) { >- if (event.request.url.indexOf('dummy.js') != -1) { >- event.respondWith(new Promise(resolve => { >- // Slightly delay the response so we ensure we get a non-zero >- // duration. >- setTimeout(_ => resolve(new Response()), 100); >- })); >- } >- }); >+ if (event.request.url.indexOf('dummy.js') != -1) { >+ event.respondWith(new Promise(resolve => { >+ // Slightly delay the response so we ensure we get a non-zero >+ // duration. >+ setTimeout(_ => resolve(new Response('// Empty javascript')), 50); >+ })); >+ } >+ else if (event.request.url.indexOf('missing.jpg?SWRespondsWithFetch') != -1) { >+ event.respondWith(fetch('dummy.txt?SWFetched')); >+ } >+}); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-iframe.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-iframe.html >index 155dbddb6d4c7a25956ffec1c4ab70d3745fd56b..239fa7330371bceb58567186d18095d04e4eee5b 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-iframe.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-iframe.html >@@ -1,56 +1,63 @@ > <script> > function with_iframe(url) { >- return new Promise(function(resolve) { >- var frame = document.createElement('iframe'); >- frame.src = url; >- frame.onload = function() { resolve(frame); }; >- document.body.appendChild(frame); >- }); >+ return new Promise(resolve => { >+ let frame = document.createElement('iframe'); >+ frame.src = url; >+ frame.onload = () => { resolve(frame); }; >+ document.body.appendChild(frame); >+ }); > } > > function with_sandboxed_iframe(url, sandbox) { >- return new Promise(function(resolve) { >- var frame = document.createElement('iframe'); >- frame.sandbox = sandbox; >- frame.src = url; >- frame.onload = function() { resolve(frame); }; >- document.body.appendChild(frame); >- }); >+ return new Promise(resolve => { >+ let frame = document.createElement('iframe'); >+ frame.sandbox = sandbox; >+ frame.src = url; >+ frame.onload = () => { resolve(frame); }; >+ document.body.appendChild(frame); >+ }); > } > >-function fetch_in_worker() { >- return new Promise((resolve) => { >- var blob = new Blob([ >- "fetch('" + location.href + "_workerfetch', {mode: 'no-cors'})" + >+function fetch_from_worker(url) { >+ return new Promise(resolve => { >+ let blob = new Blob([ >+ `fetch('${url}', {mode: 'no-cors'})` + > " .then(() => { self.postMessage('OK'); });"]); >- var url = URL.createObjectURL(blob); >- var worker = new Worker(url); >+ let worker_url = URL.createObjectURL(blob); >+ let worker = new Worker(worker_url); > worker.onmessage = resolve; > }); > } > >-window.onmessage = function (e) { >- var id = e.data['id']; >- fetch(location.href + "_fetch", {mode: 'no-cors'}) >- .then(function() { >- return fetch_in_worker(); >- }) >- .then(function() { >- return with_iframe(location.href + "_iframe"); >- }) >- .then(function() { >- return with_sandboxed_iframe(location.href + "_script", >- "allow-scripts"); >- }) >- .then(function() { >- return with_sandboxed_iframe(location.href + "_script-origin", >- "allow-scripts allow-same-origin"); >- }) >- .then(function() { >- window.top.postMessage({id: id, result: 'done'}, '*'); >- }) >- .catch(function(e) { >- window.top.postMessage({id: id, result: 'error: ' + e.toString()}, '*'); >- }); >+function run_test(type) { >+ const base_path = location.href; >+ switch (type) { >+ case 'fetch': >+ return fetch(`${base_path}&test=fetch`, {mode: 'no-cors'}); >+ case 'fetch-from-worker': >+ return fetch_from_worker(`${base_path}&test=fetch-from-worker`); >+ case 'iframe': >+ return with_iframe(`${base_path}&test=iframe`); >+ case 'sandboxed-iframe': >+ return with_sandboxed_iframe(`${base_path}&test=sandboxed-iframe`, >+ "allow-scripts"); >+ case 'sandboxed-iframe-same-origin': >+ return with_sandboxed_iframe( >+ `${base_path}&test=sandboxed-iframe-same-origin`, >+ "allow-scripts allow-same-origin"); >+ default: >+ return Promise.reject(`Unknown type: ${type}`); >+ } >+} >+ >+window.onmessage = event => { >+ let id = event.data['id']; >+ run_test(event.data['type']) >+ .then(() => { >+ window.top.postMessage({id: id, result: 'done'}, '*'); >+ }) >+ .catch(e => { >+ window.top.postMessage({id: id, result: 'error: ' + e.toString()}, '*'); >+ }); > }; > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-iframe.py b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-iframe.py >new file mode 100644 >index 0000000000000000000000000000000000000000..8b2244bf209455e2737482648286953eb784c2a1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-iframe.py >@@ -0,0 +1,16 @@ >+import os.path >+ >+def main(request, response): >+ header = [('Content-Type', 'text/html')] >+ if 'test' in request.GET: >+ with open(os.path.join(os.path.dirname(__file__),'blank.html'), 'r') as f: >+ body = f.read() >+ return (header, body) >+ >+ if 'sandbox' in request.GET: >+ header.append(('Content-Security-Policy', >+ 'sandbox %s' % request.GET['sandbox'])) >+ with open(os.path.join(os.path.dirname(__file__), >+ 'sandboxed-iframe-fetch-event-iframe.html'), 'r') as f: >+ body = f.read() >+ return (header, body) >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-worker.js >index ffa0abac34f251d89577d1a462e5b29e4d60d6a4..4035a8b19b902b26e868897f6e07e9bd1a27dfe6 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-worker.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-worker.js >@@ -10,6 +10,7 @@ self.addEventListener('message', function(event) { > client_urls = client_urls.sort(); > event.data.port.postMessage( > {clients: client_urls, requests: requests}); >+ requests = []; > })); > }); > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/scope1/redirect.py b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/scope1/redirect.py >new file mode 100644 >index 0000000000000000000000000000000000000000..bb4c874aacee9479bd690bfae8dc956378d1ee64 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/scope1/redirect.py >@@ -0,0 +1,6 @@ >+import os >+import imp >+# Use the file from the parent directory. >+mod = imp.load_source("_parent", os.path.join(os.path.dirname(os.path.dirname(__file__)), >+ os.path.basename(__file__))) >+main = mod.main >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/scope1/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/scope1/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..c54d51888fff3b136f9b22584e6d082073c245a6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/scope1/w3c-import.log >@@ -0,0 +1,17 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/scope1/redirect.py >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/scope2/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/scope2/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..a04ccb1d17f175764f9e1e2cf35e4f14b1bb93ab >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/scope2/w3c-import.log >@@ -0,0 +1,17 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py >new file mode 100644 >index 0000000000000000000000000000000000000000..bb4c874aacee9479bd690bfae8dc956378d1ee64 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py >@@ -0,0 +1,6 @@ >+import os >+import imp >+# Use the file from the parent directory. >+mod = imp.load_source("_parent", os.path.join(os.path.dirname(os.path.dirname(__file__)), >+ os.path.basename(__file__))) >+main = mod.main >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-header.py b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-header.py >new file mode 100644 >index 0000000000000000000000000000000000000000..2e82e78107ad4f70b3e88d700139195f8a5b029e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-header.py >@@ -0,0 +1,7 @@ >+def main(request, response): >+ service_worker_header = request.headers.get('service-worker') >+ if service_worker_header == 'script': >+ body = '// Request has `Service-Worker: script` header' >+ return 200, [('Content-Type', 'application/javascript')], body >+ else: >+ return 400, [('Content-Type', 'text/plain')], 'Bad Request' >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-interception-dynamic-import-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-interception-dynamic-import-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..680e07ff588cc70308b14595b1130826afd5c6e5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-interception-dynamic-import-worker.js >@@ -0,0 +1 @@ >+import('./service-worker-interception-network-worker.js'); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-interception-network-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-interception-network-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..5ff3900101345834aa38ebf25faca2a6cdf1bc4b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-interception-network-worker.js >@@ -0,0 +1 @@ >+postMessage('LOADED_FROM_NETWORK'); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-interception-service-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-interception-service-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..6b43a3769637dcbc3574b7010ea5c93be73d7b00 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-interception-service-worker.js >@@ -0,0 +1,9 @@ >+const kURL = '/service-worker-interception-network-worker.js'; >+const kScript = 'postMessage("LOADED_FROM_SERVICE_WORKER")'; >+const kHeaders = [['content-type', 'text/javascript']]; >+ >+self.addEventListener('fetch', e => { >+ // Serve a generated response for kURL. >+ if (e.request.url.indexOf(kURL) != -1) >+ e.respondWith(new Response(kScript, { headers: kHeaders })); >+}); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-interception-static-import-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-interception-static-import-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..e570958701db47250cf6d87a16f4722a84e626b2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-interception-static-import-worker.js >@@ -0,0 +1 @@ >+import './service-worker-interception-network-worker.js'; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/simple-intercept-worker.js.headers b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/simple-intercept-worker.js.headers >new file mode 100644 >index 0000000000000000000000000000000000000000..a17a9a3a12cefe883a5d4dee4d5a45bef120d050 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/simple-intercept-worker.js.headers >@@ -0,0 +1 @@ >+Content-Type: application/javascript >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/square.png.sub.headers b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/square.png.sub.headers >new file mode 100644 >index 0000000000000000000000000000000000000000..7341132745be2bee9e47114cda4167865e8a9699 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/square.png.sub.headers >@@ -0,0 +1,2 @@ >+Content-Type: image/png >+Access-Control-Allow-Origin: * >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/test-helpers.sub.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/test-helpers.sub.js >index 612409fbc1d55c314dab796dbf639183d767c0f6..7efde354a8f9b3b157972dca8e5a3c5b5eb4116a 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/test-helpers.sub.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/test-helpers.sub.js >@@ -46,9 +46,14 @@ function unreached_rejection(test, prefix) { > }); > } > >-// Adds an iframe to the document and returns a promise that resolves to the >-// iframe when it finishes loading. The caller is responsible for removing the >-// iframe later if needed. >+/** >+ * Adds an iframe to the document and returns a promise that resolves to the >+ * iframe when it finishes loading. The caller is responsible for removing the >+ * iframe later if needed. >+ * >+ * @param {string} url >+ * @returns {HTMLIFrameElement} >+ */ > function with_iframe(url) { > return new Promise(function(resolve) { > var frame = document.createElement('iframe'); >@@ -122,14 +127,11 @@ function wait_for_state(test, worker, state) { > } > } > >- return new Promise(test.step_func(function(resolve, reject) { >+ return new Promise(test.step_func(function(resolve) { > worker.addEventListener('statechange', test.step_func(function() { > if (worker.state === state) > resolve(state); > })); >- test.step_timeout(() => { >- reject("wait_for_state timed out, waiting for state " + state + ", worker state is " + worker.state); >- }, 10000); > })); > } > >@@ -204,16 +206,6 @@ function test_websocket(test, frame, url) { > }); > } > >-function login(test) { >- var host_info = get_host_info(); >- return test_login(test, host_info.HTTP_REMOTE_ORIGIN, >- 'username1s', 'password1s', 'cookie1') >- .then(function() { >- return test_login(test, host_info.HTTP_ORIGIN, >- 'username2s', 'password2s', 'cookie2'); >- }); >-} >- > function login_https(test) { > var host_info = get_host_info(); > return test_login(test, host_info.HTTPS_REMOTE_ORIGIN, >@@ -271,3 +263,16 @@ function with_sandboxed_iframe(url, sandbox) { > }); > } > >+// Registers, waits for activation, then unregisters on a dummy scope. >+// >+// This can be used to wait for a period of time needed to register, >+// activate, and then unregister a service worker. When checking that >+// certain behavior does *NOT* happen, this is preferable to using an >+// arbitrary delay. >+async function wait_for_activation_on_dummy_scope(t, window_or_workerglobalscope) { >+ const script = '/service-workers/service-worker/resources/empty-worker.js'; >+ const scope = 'resources/there/is/no/there/there?' + Date.now(); >+ let registration = await window_or_workerglobalscope.navigator.serviceWorker.register(script, { scope }); >+ await wait_for_state(t, registration.installing, 'activated'); >+ await registration.unregister(); >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/vtt-frame.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/vtt-frame.html >new file mode 100644 >index 0000000000000000000000000000000000000000..c3ac8034e192fcd6adca11fa638eda57b62d95bf >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/vtt-frame.html >@@ -0,0 +1,6 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Page Title</title> >+<video> >+ <track> >+</video> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/w3c-import.log >index 375f93e0cf092e2adfe5d8e69fb5de5ada125b93..f059c521f747d4281f754234d7cbba44b7998ce5 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/w3c-import.log >@@ -15,9 +15,12 @@ None > ------------------------------------------------------------------------ > List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/404.py >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-blank-dynamic-nested-frame.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-blank-nested-frame.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-frame.py > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-ping-frame.py > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-popup-frame.py >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-srcdoc-nested-frame.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-uncontrolled-nested-frame.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/about-blank-replacement-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/appcache-ordering.install.html >@@ -51,11 +54,18 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/clients-matchall-on-evaluation-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/clients-matchall-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/dummy-shared-worker-interceptor.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/dummy-shared-worker-interceptor.js.headers > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/dummy-worker-interceptor.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/dummy-worker-script.py > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/dummy.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/dummy.txt >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/echo-content.py > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/echo-message-to-source-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embed-and-object-are-not-intercepted-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embed-image-is-not-intercepted-iframe.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embed-is-not-intercepted-iframe.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embedded-content-from-server.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/embedded-content-from-service-worker.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/empty-but-slow-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/empty-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/empty.html >@@ -68,6 +78,8 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-access-control-login.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-access-control.py > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-canvas-tainting-iframe.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-canvas-tainting-tests.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-cors-exposed-header-names-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-cors-xhr-iframe.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-csp-iframe.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-csp-iframe.html.sub.headers >@@ -75,10 +87,13 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-async-respond-with-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-network-error-controllee-iframe.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-network-error-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-network-fallback-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-argument-iframe.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-argument-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-body-loaded-in-chunk-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-custom-response-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-partial-stream-worker.js >-/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-iframe.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-chunk-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-response-body-with-invalid-chunk-iframe.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-response-body-with-invalid-chunk-worker.js >@@ -97,18 +112,21 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-iframe.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-same.css > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-same.html >-/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-read-contents.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-cross-origin-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-fallback-iframe.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-fallback-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-html-imports-iframe.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-html-imports-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-iframe.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-script.py > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-redirect-iframe.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-resources-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-sync-iframe.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-sync-on-worker-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-sync-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-response-taint-iframe.html >@@ -120,6 +138,7 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-waits-for-activate-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/frame-for-getregistrations.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/http-to-https-redirect-and-register-iframe.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/iframe-with-image.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/immutable-prototype-serviceworker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/import-mime-type-worker.py > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/import-scripts-echo.py >@@ -130,6 +149,7 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/import-scripts-version.py > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/indexeddb-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/install-event-type-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/install-worker.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/interfaces-idls.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/interfaces-worker.sub.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/invalid-blobtype-iframe.https.html >@@ -142,10 +162,15 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/iso-latin1-header-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/load_worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/loaded.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/local-url-inherit-controller-frame.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/local-url-inherit-controller-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/malformed-worker.py > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/mime-sniffing-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/mime-type-worker.py > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/mint-new-worker.py >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/multipart-image-iframe.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/multipart-image-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/multipart-image.py > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/navigate-window-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-body-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-body.py >@@ -155,7 +180,10 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-scope2.py > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-to-http-iframe.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-to-http-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/navigation-timing-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/notification_icon.py >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/object-image-is-not-intercepted-iframe.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/object-is-not-intercepted-iframe.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-from-nested-event-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-then-cancel-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-then-prevent-default-worker.js >@@ -172,12 +200,16 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/opaque-response-preloaded-xhr.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/other.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/override_assert_object_equals.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/pass-through-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/pass.txt > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/performance-timeline-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/postmessage-blob-url.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/postmessage-msgport-to-client-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/postmessage-to-client-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/postmessage-transferables-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/postmessage-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/range-request-to-different-origins-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/range-request-with-different-cors-modes-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/redirect-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/redirect.py > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/referer-iframe.html >@@ -202,18 +234,26 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/respond-with-body-accessed-response-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/respond-with-body-accessed-response.jsonp > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-iframe.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-iframe.py > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/sandboxed-iframe-navigator-serviceworker-iframe.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-csp-worker.py >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-header.py >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-interception-dynamic-import-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-interception-network-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-interception-service-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/service-worker-interception-static-import-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/shared-worker-controlled.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/shared-worker-import.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/silence.oga > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/simple-intercept-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/simple-intercept-worker.js.headers > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/simple.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/simple.txt > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/skip-waiting-installed-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/skip-waiting-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/square.png >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/square.png.sub.headers > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/success.py > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/test-helpers.sub.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/testharness-helpers.js >@@ -224,10 +264,16 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/update-nocookie-worker.py > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/update-recovery-worker.py > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/update-worker.py >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/vtt-frame.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/wait-forever-in-install-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/websocket-worker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/websocket.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/windowclient-navigate-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-client-id-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-fetching-cross-origin.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-interception-iframe.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-interception-redirect-serviceworker.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-interception-redirect-webworker.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-load-interceptor.js > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-testharness.js >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker_interception_redirect_webworker.py >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-client-id-worker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-client-id-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..f592629d074bc3912ce64f325a3560a9d31c7f13 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-client-id-worker.js >@@ -0,0 +1,25 @@ >+addEventListener('fetch', evt => { >+ if (evt.request.url.includes('worker-echo-client-id.js')) { >+ evt.respondWith(new Response( >+ 'fetch("fetch-echo-client-id").then(r => r.text()).then(t => self.postMessage(t));', >+ { headers: { 'Content-Type': 'application/javascript' }})); >+ return; >+ } >+ >+ if (evt.request.url.includes('fetch-echo-client-id')) { >+ evt.respondWith(new Response(evt.clientId)); >+ return; >+ } >+ >+ if (evt.request.url.includes('frame.html')) { >+ evt.respondWith(new Response('')); >+ return; >+ } >+}); >+ >+addEventListener('message', evt => { >+ if (evt.data === 'echo-client-id') { >+ evt.ports[0].postMessage(evt.source.id); >+ return; >+ } >+}); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-fetching-cross-origin.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-fetching-cross-origin.js >new file mode 100644 >index 0000000000000000000000000000000000000000..79f08991174cb50735f8bc0631876c22b3359be1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-fetching-cross-origin.js >@@ -0,0 +1,10 @@ >+importScripts('/common/get-host-info.sub.js'); >+importScripts('test-helpers.sub.js'); >+ >+self.addEventListener('fetch', event => { >+ const host_info = get_host_info(); >+ // The sneaky Service Worker changes the same-origin 'square' request for a cross-origin image. >+ if (event.request.url.indexOf('square') != -1) { >+ event.respondWith(fetch(host_info['HTTPS_REMOTE_ORIGIN'] + base_path() + 'square.png', {mode: 'cors'})); >+ } >+}); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-interception-redirect-serviceworker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-interception-redirect-serviceworker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..f5ba5a38df5a7893dca3e2db47b4395c5360db2c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-interception-redirect-serviceworker.js >@@ -0,0 +1,48 @@ >+let name; >+if (self.registration.scope.indexOf('scope1') != -1) >+ name = 'sw1'; >+if (self.registration.scope.indexOf('scope2') != -1) >+ name = 'sw2'; >+ >+ >+self.addEventListener('fetch', evt => { >+ // There are three types of requests this service worker handles. >+ >+ // (1) The first request for the worker, which will redirect elsewhere. >+ // "redirect.py" means to test network redirect, so let network handle it. >+ if (evt.request.url.indexOf('redirect.py') != -1) { >+ return; >+ } >+ // "sw-redirect" means to test service worker redirect, so respond with a >+ // redirect. >+ if (evt.request.url.indexOf('sw-redirect') != -1) { >+ const url = new URL(evt.request.url); >+ const redirect_to = url.searchParams.get('Redirect'); >+ evt.respondWith(Response.redirect(redirect_to)); >+ return; >+ } >+ >+ // (2) After redirect, the request is for a "webworker.py" URL. >+ // Add a search parameter to indicate this service worker handled the >+ // final request for the worker. >+ if (evt.request.url.indexOf('webworker.py') != -1) { >+ const greeting = encodeURIComponent(`${name} saw the request for the worker script`); >+ evt.respondWith(fetch(`worker_interception_redirect_webworker.py?greeting=${greeting}`)); >+ return; >+ } >+ >+ // (3) The worker does an importScripts() to import-scripts-echo.py. Indicate >+ // that this service worker handled the request. >+ if (evt.request.url.indexOf('import-scripts-echo.py') != -1) { >+ const msg = encodeURIComponent(`${name} saw importScripts from the worker`); >+ evt.respondWith(fetch(`import-scripts-echo.py?msg=${msg}`)); >+ return; >+ } >+ >+ // (4) The worker does a fetch() to simple.txt. Indicate that this service >+ // worker handled the request. >+ if (evt.request.url.indexOf('simple.txt') != -1) { >+ evt.respondWith(new Response(`${name} saw the fetch from the worker`)); >+ return; >+ } >+}); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-interception-redirect-webworker.js b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-interception-redirect-webworker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..d602f230f08abb1cfff0902a1727bab2a13b9faf >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker-interception-redirect-webworker.js >@@ -0,0 +1,42 @@ >+// This is the (shared or dedicated) worker file for the >+// worker-interception-redirect test. It should be served by the corresponding >+// .py file instead of being served directly. >+// >+// This file is served from both resources/*webworker.py and >+// resources/scope2/*webworker.py, hence some of the complexity >+// below about paths. >+const resources_url = new URL("/service-workers/service-worker/resources/", >+ self.location); >+ >+// This greeting text is meant to be injected by the Python script that serves >+// this file, to indicate how the script was served (from network or from >+// service worker). >+// >+// We can't just use a sub pipe and name this file .sub.js since we want >+// to serve the file from multiple URLs (see above). >+let greeting = '%GREETING_TEXT%'; >+if (!greeting) >+ greeting = 'the shared worker script was served from network'; >+ >+// Call importScripts() which fills |echo_output| with a string indicating >+// whether a service worker intercepted the importScripts() request. >+let echo_output; >+const import_scripts_msg = encodeURIComponent( >+ 'importScripts: served from network'); >+const import_scripts_url = >+ new URL(`import-scripts-echo.py?msg=${import_scripts_msg}`, resources_url); >+importScripts(import_scripts_url); >+const import_scripts_greeting = echo_output; >+ >+self.onconnect = async function(e) { >+ const port = e.ports[0]; >+ port.start(); >+ port.postMessage(greeting); >+ >+ port.postMessage(import_scripts_greeting); >+ >+ const fetch_url = new URL('simple.txt', resources_url); >+ const response = await fetch(fetch_url); >+ const text = await response.text(); >+ port.postMessage('fetch(): ' + text); >+}; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker_interception_redirect_webworker.py b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker_interception_redirect_webworker.py >new file mode 100644 >index 0000000000000000000000000000000000000000..e388e461448f64d37d747b26830f4e869a2c6528 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/worker_interception_redirect_webworker.py >@@ -0,0 +1,19 @@ >+# This serves the worker JavaScript file. It takes a |greeting| request >+# parameter to inject into the JavaScript to indicate how the request >+# reached the server. >+import os >+import sys >+ >+def main(request, response): >+ path = os.path.join(os.path.dirname(__file__), >+ "worker-interception-redirect-webworker.js") >+ body = open(path, "rb").read() >+ if "greeting" in request.GET: >+ body = body.replace("%GREETING_TEXT%", request.GET["greeting"]) >+ else: >+ body = body.replace("%GREETING_TEXT%", "") >+ >+ headers = [] >+ headers.append(("Content-Type", "text/javascript")) >+ >+ return headers, body >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/sandboxed-iframe-fetch-event.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/sandboxed-iframe-fetch-event.https.html >index 8b361bd25df7cc0e05062d88e8142e54870ff343..e08b71645325cd8fe94f1001bc778ed325571a98 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/sandboxed-iframe-fetch-event.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/sandboxed-iframe-fetch-event.https.html >@@ -7,210 +7,529 @@ > <script> > var lastCallbackId = 0; > var callbacks = {}; >-function postMessageAndWaitResult(frame) { >+function doTest(frame, type) { > return new Promise(function(resolve) { > var id = ++lastCallbackId; > callbacks[id] = resolve; >- frame.contentWindow.postMessage({id:id}, '*'); >+ frame.contentWindow.postMessage({id: id, type: type}, '*'); >+ }); >+} >+ >+// Asks the service worker for data about requests and clients seen. The >+// worker posts a message back with |data| where: >+// |data.requests|: the requests the worker received FetchEvents for >+// |data.clients|: the URLs of all the worker's clients >+// The worker clears its data after responding. >+function getResultsFromWorker(worker) { >+ return new Promise(resolve => { >+ let channel = new MessageChannel(); >+ channel.port1.onmessage = msg => { >+ resolve(msg.data); >+ }; >+ worker.postMessage({port: channel.port2}, [channel.port2]); > }); > } > > window.onmessage = function (e) { > message = e.data; > var id = message['id']; >- var calback = callbacks[id]; >+ var callback = callbacks[id]; > delete callbacks[id]; >- calback(message['result']); >+ callback(message['result']); > }; > >-promise_test(function(t) { >- var SCOPE = 'resources/sandboxed-iframe-fetch-event-iframe.html'; >- var SCRIPT = 'resources/sandboxed-iframe-fetch-event-worker.js'; >- var frames = []; >- var worker; >- return service_worker_unregister_and_register(t, SCRIPT, SCOPE) >- .then(function(registration) { >- worker = registration.installing; >- return wait_for_state(t, registration.installing, 'activated'); >- }) >- .then(function() { >- return with_iframe(SCOPE + '?iframe'); >- }) >- .then(function(frame) { >- frames.push(frame); >- return postMessageAndWaitResult(frame); >- }) >- .then(function(result) { >- assert_equals(result, 'done'); >- return with_sandboxed_iframe(SCOPE + '?script', 'allow-scripts'); >- }) >- .then(function(frame) { >- frames.push(frame); >- return postMessageAndWaitResult(frame); >- }) >- .then(function(result) { >- assert_equals(result, 'done'); >- return with_sandboxed_iframe(SCOPE + '?script-origin', >- 'allow-scripts allow-same-origin'); >- }) >- .then(function(frame) { >- frames.push(frame); >- return postMessageAndWaitResult(frame); >- }) >- .then(function(result) { >- assert_equals(result, 'done'); >- return new Promise(function(resolve) { >- var channel = new MessageChannel(); >- channel.port1.onmessage = function(msg) { >- resolve(msg); >- }; >- worker.postMessage({port: channel.port2}, [channel.port2]); >- }); >- }) >- .then(function(msg) { >- for (var frame of frames) { >- frame.remove(); >- } >- var expected_base_url = new URL(SCOPE, location.href).href; >- var request_set = {}; >- for (var request of msg.data.requests) { >- request_set[request] = true; >- } >- assert_true( >- expected_base_url + '?iframe' in request_set, >- 'The request for normal iframe should be handled by SW.'); >- assert_true( >- expected_base_url + '?iframe_fetch' in request_set, >- 'The fetch request from normal iframe should be handled by SW.'); >- assert_true( >- expected_base_url + '?iframe_workerfetch' in request_set, >- 'The fetch request from worker in normal iframe should be ' + >- 'handled by SW.'); >- assert_true( >- expected_base_url + '?iframe_iframe' in request_set, >- 'The request for normal iframe inside normal iframe should be ' + >- 'handled by SW.'); >- assert_false( >- expected_base_url + '?iframe_script' in request_set, >- 'The request for sandboxed iframe with allow-scripts flag ' + >- 'inside normal iframe should not be handled by SW.'); >- assert_true( >- expected_base_url + '?iframe_script-origin' in request_set, >- 'The request for sandboxed iframe with allow-scripts and ' + >- 'allow-same-origin flag inside normal iframe should be handled ' + >- 'by SW.'); >- assert_false( >- expected_base_url + '?script' in request_set, >- 'The request for sandboxed iframe with allow-scripts flag ' + >- 'should not be handled by SW.'); >- assert_false( >- expected_base_url + '?script_fetch' in request_set, >- 'The fetch request from sandboxed iframe with allow-scripts ' + >- 'flag should not be handled by SW.'); >- assert_false( >- expected_base_url + '?script_workerfetch' in request_set, >- 'The fetch request from worker from sandboxed iframe with ' + >- 'allow-scripts flag should not be handled by SW.'); >- assert_false( >- expected_base_url + '?script_iframe' in request_set, >- 'The request for normal iframe inside sandboxed iframe with ' + >- 'allow-scripts flag should not be handled by SW.'); >- assert_false( >- expected_base_url + '?script_script' in request_set, >- 'The request for sandboxed iframe with allow-scripts flag ' + >- 'inside sandboxed iframe with allow-scripts flag should not be ' + >- 'handled by SW.'); >- assert_false( >- expected_base_url + '?script_script-origin' in request_set, >- 'The request for sandboxed iframe with allow-scripts and ' + >- 'allow-same-origin flag inside sandboxed iframe with ' + >- 'allow-scripts flag should not be handled by SW.'); >- assert_true( >- expected_base_url + '?script-origin' in request_set, >- 'The request for sandboxed iframe with allow-scripts and ' + >- 'allow-same-origin flag should be handled by SW.'); >- assert_true( >- expected_base_url + '?script-origin_fetch' in request_set, >- 'The fetch request from sandboxed iframe with allow-scripts ' + >- 'and allow-same-origin flag should be handled by SW.'); >- assert_true( >- expected_base_url + '?script-origin_workerfetch' in request_set, >- 'The fetch request from worker in sandboxed iframe with ' + >- 'allow-scripts and allow-same-origin flag should be handled ' + >- 'by SW.'); >- assert_true( >- expected_base_url + '?script-origin_iframe' in request_set, >- 'The request for normal iframe inside sandboxed iframe with ' + >- 'allow-scripts and allow-same-origin flag should be handled by' + >- 'SW.'); >- assert_false( >- expected_base_url + '?script-origin_script' in request_set, >- 'The request for sandboxed iframe with allow-scripts flag ' + >- 'inside sandboxed iframe with allow-scripts and ' + >- 'allow-same-origin flag should be handled by SW.'); >- assert_true( >- expected_base_url + '?script-origin_script-origin' in request_set, >- 'The request for sandboxed iframe with allow-scripts and' + >- 'allow-same-origin flag inside sandboxed iframe with ' + >- 'allow-scripts and allow-same-origin flag should be handled by' + >- 'SW.'); >- >- var client_set = {}; >- for (var client of msg.data.clients) { >- client_set[client] = true; >- } >- assert_true( >- expected_base_url + '?iframe' in client_set, >- 'The normal iframe should be controlled by SW.'); >- assert_true( >- expected_base_url + '?iframe_iframe' in client_set, >- 'The normal iframe inside normal iframe should be controlled ' + >- 'by SW.'); >- assert_false( >- expected_base_url + '?iframe_script' in client_set, >- 'The sandboxed iframe with allow-scripts flag inside normal ' + >- 'iframe should not be controlled by SW.'); >- assert_true( >- expected_base_url + '?iframe_script-origin' in client_set, >- 'The sandboxed iframe with allow-scripts and allow-same-origin' + >- 'flag inside normal iframe should be controlled by SW.'); >- assert_false( >- expected_base_url + '?script' in client_set, >- 'The sandboxed iframe with allow-scripts flag should not be ' + >- 'controlled by SW.'); >- assert_false( >- expected_base_url + '?script_iframe' in client_set, >- 'The normal iframe inside sandboxed iframe with allow-scripts' + >- 'flag should not be controlled by SW.'); >- assert_false( >- expected_base_url + '?script_script' in client_set, >- 'The sandboxed iframe with allow-scripts flag inside sandboxed ' + >- 'iframe with allow-scripts flag should not be controlled by SW.'); >- assert_false( >- expected_base_url + '?script_script-origin' in client_set, >- 'The sandboxed iframe with allow-scripts and allow-same-origin ' + >- 'flag inside sandboxed iframe with allow-scripts flag should ' + >- 'not be controlled by SW.'); >- assert_true( >- expected_base_url + '?script-origin' in client_set, >- 'The sandboxed iframe with allow-scripts and allow-same-origin ' + >- 'flag should be controlled by SW.'); >- assert_true( >- expected_base_url + '?script-origin_iframe' in client_set, >- 'The normal iframe inside sandboxed iframe with allow-scripts ' + >- 'and allow-same-origin flag should be controlled by SW.'); >- assert_false( >- expected_base_url + '?script-origin_script' in client_set, >- 'The sandboxed iframe with allow-scripts flag inside sandboxed ' + >- 'iframe with allow-scripts and allow-same-origin flag should ' + >- 'be controlled by SW.'); >- assert_true( >- expected_base_url + '?script-origin_script-origin' in client_set, >- 'The sandboxed iframe with allow-scripts and allow-same-origin ' + >- 'flag inside sandboxed iframe with allow-scripts and ' + >- 'allow-same-origin flag should be controlled by SW.'); >- return service_worker_unregister_and_done(t, SCOPE); >- }); >- }, 'ServiceWorker FetchEvent for sandboxed iframe.'); >+const SCOPE = 'resources/sandboxed-iframe-fetch-event-iframe.py'; >+const SCRIPT = 'resources/sandboxed-iframe-fetch-event-worker.js'; >+const expected_base_url = new URL(SCOPE, location.href); >+// Service worker controlling |SCOPE|. >+let worker; >+// A normal iframe. >+// This should be controlled by a service worker. >+let normal_frame; >+// An iframe created by <iframe sandbox='allow-scripts'>. >+// This should NOT be controlled by a service worker. >+let sandboxed_frame; >+// An iframe created by <iframe sandbox='allow-scripts allow-same-origin'>. >+// This should be controlled by a service worker. >+let sandboxed_same_origin_frame; >+// An iframe whose response header has >+// 'Content-Security-Policy: allow-scripts'. >+// This should NOT be controlled by a service worker. >+let sandboxed_frame_by_header; >+// An iframe whose response header has >+// 'Content-Security-Policy: allow-scripts allow-same-origin'. >+// This should be controlled by a service worker. >+let sandboxed_same_origin_frame_by_header; >+ >+promise_test(t => { >+ return service_worker_unregister_and_register(t, SCRIPT, SCOPE) >+ .then(function(registration) { >+ add_completion_callback(() => registration.unregister()); >+ worker = registration.installing; >+ return wait_for_state(t, registration.installing, 'activated'); >+ }); >+}, 'Prepare a service worker.'); >+ >+promise_test(t => { >+ return with_iframe(SCOPE + '?iframe') >+ .then(f => { >+ normal_frame = f; >+ add_completion_callback(() => f.remove()); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ let requests = data.requests; >+ assert_equals(requests.length, 1); >+ assert_equals(requests[0], expected_base_url + '?iframe'); >+ assert_true(data.clients.includes(expected_base_url + '?iframe')); >+ }); >+}, 'Prepare a normal iframe.'); >+ >+promise_test(t => { >+ return with_sandboxed_iframe(SCOPE + '?sandboxed-iframe', 'allow-scripts') >+ .then(f => { >+ sandboxed_frame = f; >+ add_completion_callback(() => f.remove()); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ assert_equals(data.requests.length, 0); >+ assert_false(data.clients.includes(expected_base_url + >+ '?sandboxed-iframe')); >+ }); >+}, 'Prepare an iframe sandboxed by <iframe sandbox="allow-scripts">.'); >+ >+promise_test(t => { >+ return with_sandboxed_iframe(SCOPE + '?sandboxed-iframe-same-origin', >+ 'allow-scripts allow-same-origin') >+ .then(f => { >+ sandboxed_same_origin_frame = f; >+ add_completion_callback(() => f.remove()); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ let requests = data.requests; >+ assert_equals(requests.length, 1); >+ assert_equals(requests[0], >+ expected_base_url + '?sandboxed-iframe-same-origin'); >+ assert_true(data.clients.includes( >+ expected_base_url + '?sandboxed-iframe-same-origin')); >+ }) >+}, 'Prepare an iframe sandboxed by ' + >+ '<iframe sandbox="allow-scripts allow-same-origin">.'); >+ >+promise_test(t => { >+ const iframe_full_url = expected_base_url + '?sandbox=allow-scripts&' + >+ 'sandboxed-frame-by-header'; >+ return with_iframe(iframe_full_url) >+ .then(f => { >+ sandboxed_frame_by_header = f; >+ add_completion_callback(() => f.remove()); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ let requests = data.requests; >+ assert_equals(requests.length, 1, >+ 'Service worker should provide the response'); >+ assert_equals(requests[0], iframe_full_url); >+ assert_false(data.clients.includes(iframe_full_url), >+ 'Service worker should NOT control the sandboxed page'); >+ }); >+}, 'Prepare an iframe sandboxed by CSP HTTP header with allow-scripts.'); >+ >+promise_test(t => { >+ const iframe_full_url = >+ expected_base_url + '?sandbox=allow-scripts%20allow-same-origin&' + >+ 'sandboxed-iframe-same-origin-by-header'; >+ return with_iframe(iframe_full_url) >+ .then(f => { >+ sandboxed_same_origin_frame_by_header = f; >+ add_completion_callback(() => f.remove()); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ let requests = data.requests; >+ assert_equals(requests.length, 1); >+ assert_equals(requests[0], iframe_full_url); >+ assert_true(data.clients.includes(iframe_full_url)); >+ }) >+}, 'Prepare an iframe sandboxed by CSP HTTP header with allow-scripts and ' + >+ 'allow-same-origin.'); >+ >+promise_test(t => { >+ let frame = normal_frame; >+ return doTest(frame, 'fetch') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ let requests = data.requests; >+ assert_equals(requests.length, 1, >+ 'The fetch request should be handled by SW.'); >+ assert_equals(requests[0], frame.src + '&test=fetch'); >+ }); >+}, 'Fetch request from a normal iframe'); >+ >+promise_test(t => { >+ let frame = normal_frame; >+ return doTest(frame, 'fetch-from-worker') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ let requests = data.requests; >+ assert_equals(requests.length, 1, >+ 'The fetch request should be handled by SW.'); >+ assert_equals(requests[0], frame.src + '&test=fetch-from-worker'); >+ }); >+}, 'Fetch request from a worker in a normal iframe'); >+ >+promise_test(t => { >+ let frame = normal_frame; >+ return doTest(frame, 'iframe') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ let requests = data.requests; >+ assert_equals(requests.length, 1, >+ 'The request should be handled by SW.'); >+ assert_equals(requests[0], frame.src + '&test=iframe'); >+ assert_true(data.clients.includes(frame.src + '&test=iframe')); >+ >+ }); >+}, 'Request for an iframe in the normal iframe'); >+ >+promise_test(t => { >+ let frame = normal_frame; >+ return doTest(frame, 'sandboxed-iframe') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ assert_equals(data.requests.length, 0, >+ 'The request should NOT be handled by SW.'); >+ assert_false(data.clients.includes( >+ frame.src + '&test=sandboxed-iframe')); >+ }); >+}, 'Request for an sandboxed iframe with allow-scripts flag in the normal ' + >+ 'iframe'); >+ >+promise_test(t => { >+ let frame = normal_frame; >+ return doTest(frame, 'sandboxed-iframe-same-origin') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ let requests = data.requests; >+ assert_equals(requests.length, 1, >+ 'The request should be handled by SW.'); >+ assert_equals(requests[0], >+ frame.src + '&test=sandboxed-iframe-same-origin'); >+ assert_true(data.clients.includes( >+ frame.src + '&test=sandboxed-iframe-same-origin')); >+ }); >+}, 'Request for an sandboxed iframe with allow-scripts and ' + >+ 'allow-same-origin flag in the normal iframe'); >+ >+promise_test(t => { >+ let frame = sandboxed_frame; >+ return doTest(frame, 'fetch') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ assert_equals(data.requests.length, 0, >+ 'The fetch request should NOT be handled by SW.'); >+ }); >+}, 'Fetch request from iframe sandboxed by an attribute with allow-scripts ' + >+ 'flag'); >+ >+promise_test(t => { >+ let frame = sandboxed_frame; >+ return doTest(frame, 'fetch-from-worker') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ assert_equals(data.requests.length, 0, >+ 'The fetch request should NOT be handled by SW.'); >+ }); >+}, 'Fetch request from a worker in iframe sandboxed by an attribute with ' + >+ 'allow-scripts flag'); >+ >+promise_test(t => { >+ let frame = sandboxed_frame; >+ return doTest(frame, 'iframe') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ assert_equals(data.requests.length, 0, >+ 'The request should NOT be handled by SW.'); >+ assert_false(data.clients.includes(frame.src + '&test=iframe')); >+ }); >+}, 'Request for an iframe in the iframe sandboxed by an attribute with ' + >+ 'allow-scripts flag'); >+ >+promise_test(t => { >+ let frame = sandboxed_frame; >+ return doTest(frame, 'sandboxed-iframe') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ assert_equals(data.requests.length, 0, >+ 'The request should NOT be handled by SW.'); >+ assert_false(data.clients.includes( >+ frame.src + '&test=sandboxed-iframe')); >+ }); >+}, 'Request for an sandboxed iframe with allow-scripts flag in the iframe ' + >+ 'sandboxed by an attribute with allow-scripts flag'); >+ >+promise_test(t => { >+ let frame = sandboxed_frame; >+ return doTest(frame, 'sandboxed-iframe-same-origin') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ assert_equals(data.requests.length, 0, >+ 'The request should NOT be handled by SW.'); >+ assert_false(data.clients.includes( >+ frame.src + '&test=sandboxed-iframe-same-origin')); >+ }); >+}, 'Request for an sandboxed iframe with allow-scripts and ' + >+ 'allow-same-origin flag in the iframe sandboxed by an attribute with ' + >+ 'allow-scripts flag'); >+ >+promise_test(t => { >+ let frame = sandboxed_same_origin_frame; >+ return doTest(frame, 'fetch') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ let requests = data.requests; >+ assert_equals(requests.length, 1, >+ 'The fetch request should be handled by SW.'); >+ assert_equals(requests[0], frame.src + '&test=fetch'); >+ }); >+}, 'Fetch request from iframe sandboxed by an attribute with allow-scripts ' + >+ 'and allow-same-origin flag'); >+ >+promise_test(t => { >+ let frame = sandboxed_same_origin_frame; >+ return doTest(frame, 'fetch-from-worker') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ let requests = data.requests; >+ assert_equals(requests.length, 1, >+ 'The fetch request should be handled by SW.'); >+ assert_equals(requests[0], >+ frame.src + '&test=fetch-from-worker'); >+ }); >+}, 'Fetch request from a worker in iframe sandboxed by an attribute with ' + >+ 'allow-scripts and allow-same-origin flag'); >+ >+promise_test(t => { >+ let frame = sandboxed_same_origin_frame; >+ return doTest(frame, 'iframe') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ let requests = data.requests; >+ assert_equals(requests.length, 1, >+ 'The request should be handled by SW.'); >+ assert_equals(requests[0], frame.src + '&test=iframe'); >+ assert_true(data.clients.includes(frame.src + '&test=iframe')); >+ }); >+}, 'Request for an iframe in the iframe sandboxed by an attribute with ' + >+ 'allow-scripts and allow-same-origin flag'); >+ >+promise_test(t => { >+ let frame = sandboxed_same_origin_frame; >+ return doTest(frame, 'sandboxed-iframe') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ assert_equals(data.requests.length, 0, >+ 'The request should NOT be handled by SW.'); >+ assert_false(data.clients.includes( >+ frame.src + '&test=sandboxed-iframe')); >+ }); >+}, 'Request for an sandboxed iframe with allow-scripts flag in the iframe ' + >+ 'sandboxed by attribute with allow-scripts and allow-same-origin flag'); >+ >+promise_test(t => { >+ let frame = sandboxed_same_origin_frame; >+ return doTest(frame, 'sandboxed-iframe-same-origin') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ let requests = data.requests; >+ assert_equals(requests.length, 1, >+ 'The request should be handled by SW.'); >+ assert_equals(requests[0], >+ frame.src + '&test=sandboxed-iframe-same-origin'); >+ assert_true(data.clients.includes( >+ frame.src + '&test=sandboxed-iframe-same-origin')); >+ }); >+}, 'Request for an sandboxed iframe with allow-scripts and ' + >+ 'allow-same-origin flag in the iframe sandboxed by attribute with ' + >+ 'allow-scripts and allow-same-origin flag'); >+ >+promise_test(t => { >+ let frame = sandboxed_frame_by_header; >+ return doTest(frame, 'fetch') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ assert_equals(data.requests.length, 0, >+ 'The request should NOT be handled by SW.'); >+ }); >+}, 'Fetch request from iframe sandboxed by CSP HTTP header with ' + >+ 'allow-scripts flag'); >+ >+promise_test(t => { >+ let frame = sandboxed_frame_by_header; >+ return doTest(frame, 'iframe') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ assert_equals(data.requests.length, 0, >+ 'The request should NOT be handled by SW.'); >+ assert_false(data.clients.includes(frame.src + '&test=iframe')); >+ }); >+}, 'Request for an iframe in the iframe sandboxed by CSP HTTP header with ' + >+ 'allow-scripts flag'); >+ >+promise_test(t => { >+ let frame = sandboxed_frame_by_header; >+ return doTest(frame, 'sandboxed-iframe') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ assert_equals(data.requests.length, 0, >+ 'The request should NOT be handled by SW.'); >+ assert_false(data.clients.includes( >+ frame.src + '&test=sandboxed-iframe')); >+ }); >+}, 'Request for an sandboxed iframe with allow-scripts flag in the iframe ' + >+ 'sandboxed by CSP HTTP header with allow-scripts flag'); >+ >+promise_test(t => { >+ let frame = sandboxed_frame_by_header; >+ return doTest(frame, 'sandboxed-iframe-same-origin') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ assert_equals(data.requests.length, 0, >+ 'The request should NOT be handled by SW.'); >+ assert_false(data.clients.includes( >+ frame.src + '&test=sandboxed-iframe-same-origin')); >+ }); >+}, 'Request for an sandboxed iframe with allow-scripts and ' + >+ 'allow-same-origin flag in the iframe sandboxed by CSP HTTP header with ' + >+ 'allow-scripts flag'); >+ >+promise_test(t => { >+ let frame = sandboxed_same_origin_frame_by_header; >+ return doTest(frame, 'fetch') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ let requests = data.requests; >+ assert_equals(requests.length, 1, >+ 'The request should be handled by SW.'); >+ assert_equals(requests[0], frame.src + '&test=fetch'); >+ }); >+}, 'Fetch request from iframe sandboxed by CSP HTTP header with ' + >+ 'allow-scripts and allow-same-origin flag'); >+ >+promise_test(t => { >+ let frame = sandboxed_same_origin_frame_by_header; >+ return doTest(frame, 'iframe') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ let requests = data.requests; >+ assert_equals(requests.length, 1, >+ 'The request should be handled by SW.'); >+ assert_equals(requests[0], frame.src + '&test=iframe'); >+ assert_true(data.clients.includes(frame.src + '&test=iframe')); >+ }); >+}, 'Request for an iframe in the iframe sandboxed by CSP HTTP header with ' + >+ 'allow-scripts and allow-same-origin flag'); >+ >+promise_test(t => { >+ let frame = sandboxed_same_origin_frame_by_header; >+ return doTest(frame, 'sandboxed-iframe') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ assert_equals(data.requests.length, 0, >+ 'The request should NOT be handled by SW.'); >+ assert_false( >+ data.clients.includes(frame.src + '&test=sandboxed-iframe')); >+ }); >+}, 'Request for an sandboxed iframe with allow-scripts flag in the ' + >+ 'iframe sandboxed by CSP HTTP header with allow-scripts and ' + >+ 'allow-same-origin flag'); >+ >+promise_test(t => { >+ let frame = sandboxed_same_origin_frame_by_header; >+ return doTest(frame, 'sandboxed-iframe-same-origin') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ let requests = data.requests; >+ assert_equals(requests.length, 1, >+ 'The request should be handled by SW.'); >+ assert_equals(requests[0], >+ frame.src + '&test=sandboxed-iframe-same-origin'); >+ assert_true(data.clients.includes( >+ frame.src + '&test=sandboxed-iframe-same-origin')); >+ }); >+}, 'Request for an sandboxed iframe with allow-scripts and ' + >+ 'allow-same-origin flag in the iframe sandboxed by CSP HTTP header with ' + >+ 'allow-scripts and allow-same-origin flag'); > </script> > </body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/service-worker-header.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/service-worker-header.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..7463264ba4a7f9c20cfc0e9345432d543ac44054 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/service-worker-header.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS A request to fetch service worker script should have Service-Worker header >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/service-worker-header.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/service-worker-header.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2584485c65ab60e8b429c3db66fc43a8157a8ed5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/service-worker-header.https.html >@@ -0,0 +1,18 @@ >+<!DOCTYPE html> >+<title>Service Worker: Service-Worker header</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/test-helpers.sub.js"></script> >+<script> >+ >+promise_test(t => { >+ const script = 'resources/service-worker-header.py'; >+ const scope = 'resources/service-worker-header'; >+ return service_worker_unregister_and_register(t, script, scope) >+ .then(registration => { >+ assert_true(registration instanceof ServiceWorkerRegistration); >+ return registration.unregister(); >+ }); >+}, 'A request to fetch service worker script should have Service-Worker header'); >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https-expected.txt >index 38d3d0943920e2bf69a1f172cfe453d9c09fd2d4..3ad1f7acbafe2cb172e468b023ab28a8b857002e 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https-expected.txt >@@ -1,4 +1,5 @@ > >+Harness Error (TIMEOUT), message = null >+ > PASS Test skipWaiting while a client is using the registration >-PASS skipWaiting > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https.html >index c265b03e02190425c781dae2b351c760bd61e965..a9c398a260676d976f0aac0ca495aa1a6c94e631 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https.html >@@ -50,6 +50,9 @@ promise_test(function(t) { > }) > .then(function(registration) { > sw_registration = registration; >+ t.add_cleanup(function() { >+ registration.unregister(); >+ }); > return saw_controllerchanged; > }) > .then(function() { >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https-expected.txt >index 0ea9d5875786a829a36285079452ccddf05ea475..f74be6b65da58e219decf56ad6bcc3c75e294121 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https-expected.txt >@@ -1,4 +1,5 @@ > >+Harness Error (TIMEOUT), message = null >+ > PASS Test skipWaiting while a client is not being controlled >-PASS skipWaiting > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https.html >index da1e33411e54459104416d1c7e526a06c8f47710..dbe2bde78d3c0b4bd68967188d668c455714121f 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https.html >@@ -26,6 +26,9 @@ promise_test(function(t) { > }) > .then(function(registration) { > sw_registration = registration; >+ t.add_cleanup(function() { >+ registration.unregister(); >+ }); > return wait_for_state(t, registration.installing, 'activated'); > }) > .then(function() { >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/svg-target-reftest.https-expected.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/svg-target-reftest.https-expected.html >new file mode 100644 >index 0000000000000000000000000000000000000000..9a93d3b37047560a1b686266932c039968683fce >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/svg-target-reftest.https-expected.html >@@ -0,0 +1,5 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Green svg box reference file</title> >+<p>Pass if you see a green box below.</p> >+<iframe src="svg-target-reftest-001-frame.html"> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/svg-target-reftest.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/svg-target-reftest.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..3710ee61d85fe5f7272e949e33622f3592e65436 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/svg-target-reftest.https.html >@@ -0,0 +1,28 @@ >+<!DOCTYPE html> >+<html class="reftest-wait"> >+<meta charset="utf-8"> >+<title>Service worker interception does not break SVG fragment targets</title> >+<meta name="assert" content="SVG with link fragment should render correctly when intercepted by a service worker."> >+<script src="resources/test-helpers.sub.js"></script> >+<link rel="match" href="resources/svg-target-reftest-001.html"> >+<p>Pass if you see a green box below.</p> >+<script> >+// We want to use utility functions designed for testharness.js where >+// there is a test object. We don't have a test object in reftests >+// so fake one for now. >+const fake_test = { step_func: f => f }; >+ >+async function runTest() { >+ const script = './resources/pass-through-worker.js'; >+ const scope = './resources/svg-target-reftest-frame.html'; >+ let reg = await navigator.serviceWorker.register(script, { scope }); >+ await wait_for_state(fake_test, reg.installing, 'activated'); >+ let f = await with_iframe(scope); >+ document.documentElement.classList.remove('reftest-wait'); >+ await reg.unregister(); >+ // Note, we cannot remove the frame explicitly because we can't >+ // tell when the reftest completes. >+} >+runTest(); >+</script> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/unregister-then-register-new-script.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/unregister-then-register-new-script.https-expected.txt >index 8e42bee4bedcc81fc6f9af5ab79e8c594c387399..90b7cae31c86e31044fe30ec9487272692237996 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/unregister-then-register-new-script.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/unregister-then-register-new-script.https-expected.txt >@@ -1,5 +1,5 @@ > > PASS Registering a new script URL while an unregistered registration is in use >-PASS Registering a new script URL that 404s does not resurrect an unregistered registration >-PASS Registering a new script URL that fails to install does not resurrect an unregistered registration >+PASS Registering a new script URL that 404s does resurrect an unregistered registration >+PASS Registering a new script URL that fails to install does resurrect an unregistered registration > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/unregister-then-register-new-script.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/unregister-then-register-new-script.https.html >index 385430c2d8e6c875a1dbbc3ff14c80500f049a39..582132a742fc9bb0fba62ee025356f983938da1b 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/unregister-then-register-new-script.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/unregister-then-register-new-script.https.html >@@ -90,9 +90,12 @@ async_test(function(t) { > return registration.unregister(); > }) > .then(function() { >+ // Step 5.1 of Register clears the uninstall flag before fetching >+ // the script: >+ // >+ // https://w3c.github.io/ServiceWorker/#register-algorithm > var promise = navigator.serviceWorker.register('this-will-404', > { scope: scope }); >- iframe.remove(); > return promise; > }) > .then( >@@ -100,17 +103,28 @@ async_test(function(t) { > assert_unreached('register should reject the promise'); > }, > function() { >+ assert_equals(registration.installing, null, >+ 'registration.installing'); >+ assert_equals(registration.waiting, null, >+ 'registration.waiting'); >+ assert_equals(registration.active.scriptURL, normalizeURL(worker_url), >+ 'registration.active'); >+ iframe.remove(); > return with_iframe(scope); > }) > .then(function(frame) { >- assert_equals(frame.contentWindow.navigator.serviceWorker.controller, >- null, >- 'document should not load with a controller'); >+ assert_equals( >+ frame.contentWindow.navigator.serviceWorker.controller.scriptURL, >+ normalizeURL(worker_url), >+ 'the original worker should control a new document'); > frame.remove(); >+ return registration.unregister(); >+ }) >+ .then(function() { > t.done(); > }) > .catch(unreached_rejection(t)); >-}, 'Registering a new script URL that 404s does not resurrect an ' + >+}, 'Registering a new script URL that 404s does resurrect an ' + > 'unregistered registration'); > > async_test(function(t) { >@@ -131,9 +145,12 @@ async_test(function(t) { > return registration.unregister(); > }) > .then(function() { >+ // Step 5.1 of Register clears the uninstall flag before firing >+ // the install event: >+ // >+ // https://w3c.github.io/ServiceWorker/#register-algorithm > var promise = navigator.serviceWorker.register( > 'resources/reject-install-worker.js', { scope: scope }); >- iframe.remove(); > return promise; > }) > .then(function(r) { >@@ -141,12 +158,20 @@ async_test(function(t) { > return wait_for_state(t, r.installing, 'redundant'); > }) > .then(function() { >+ assert_equals(registration.installing, null, >+ 'registration.installing'); >+ assert_equals(registration.waiting, null, >+ 'registration.waiting'); >+ assert_equals(registration.active.scriptURL, normalizeURL(worker_url), >+ 'registration.active'); >+ iframe.remove(); > return with_iframe(scope); > }) > .then(function(frame) { >- assert_equals(frame.contentWindow.navigator.serviceWorker.controller, >- null, >- 'document should not load with a controller'); >+ assert_equals( >+ frame.contentWindow.navigator.serviceWorker.controller.scriptURL, >+ normalizeURL(worker_url), >+ 'the original worker should control a new document'); > frame.remove(); > return registration.unregister(); > }) >@@ -154,6 +179,6 @@ async_test(function(t) { > t.done(); > }) > .catch(unreached_rejection(t)); >- }, 'Registering a new script URL that fails to install does not resurrect ' + >+ }, 'Registering a new script URL that fails to install does resurrect ' + > 'an unregistered registration'); > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/update-result.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/update-result.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..c9e94489445a05e1c14b98da160cbebde0c59f75 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/update-result.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS ServiceWorkerRegistration.update() should resolve a registration object >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/update-result.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/update-result.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d8ed94f776650c8a40ba82df9ca5e909b460bb79 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/update-result.https.html >@@ -0,0 +1,23 @@ >+<!DOCTYPE html> >+<title>Service Worker: update() should resolve a ServiceWorkerRegistration</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/test-helpers.sub.js"></script> >+<body> >+<script> >+ >+promise_test(async function(t) { >+ const script = './resources/empty.js'; >+ const scope = './resources/empty.html?update-result'; >+ >+ let reg = await navigator.serviceWorker.register(script, { scope }); >+ t.add_cleanup(async _ => await reg.unregister()); >+ await wait_for_state(t, reg.installing, 'activated'); >+ >+ let result = await reg.update(); >+ assert_true(result instanceof ServiceWorkerRegistration, >+ 'update() should resolve a ServiceWorkerRegistration'); >+}, 'ServiceWorkerRegistration.update() should resolve a registration object'); >+ >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/w3c-import.log >index 2a8d014bf06ae0919b3bf418a353cde8c3000a63..8c2ac9aee8c7d8830d1680e78ca087316c1f07df 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/w3c-import.log >@@ -14,6 +14,7 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/Service-Worker-Allowed-header.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/about-blank-replacement.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/activate-event-after-install-state-change.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/activation-after-registration.https.html >@@ -41,20 +42,33 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/controller-on-disconnect.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/controller-on-load.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/controller-on-reload.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/dedicated-worker-service-worker-interception.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/detached-context.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/embed-and-object-are-not-intercepted.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/extendable-event-async-waituntil.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/extendable-event-waituntil.https.html >-/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-cache.https.html >-/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image-cache.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-cache.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video-with-range-request.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-video.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-cors-exposed-header-names.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-cors-xhr.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-csp.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-after-navigation-within-page.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-async-respond-with.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-history-backward-navigation-manual.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-history-forward-navigation-manual.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-reload-iframe-navigation-manual.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-reload-navigation-manual.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-network-error.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-redirect.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-referrer-policy.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-argument.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-body-loaded-in-chunk.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-custom-response.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-partial-stream.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-readable-stream-chunk.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-readable-stream.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-response-body-with-invalid-chunk.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-stops-propagation.https.html >@@ -67,13 +81,14 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-mixed-content-to-inscope.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-mixed-content-to-outscope.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-css-base-url.https.html >-/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-css-cross-origin-mime-check.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-css-cross-origin.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-css-images.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-fallback.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-html-imports.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-no-freshness-headers.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-redirect.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-resources.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-xhr-sync-on-worker.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-xhr-sync.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-xhr.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-response-taint.https.html >@@ -94,13 +109,16 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/invalid-blobtype.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/invalid-header.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/iso-latin1-header.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/local-url-inherit-controller.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/mime-sniffing.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/multipart-image.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/multiple-register.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/multiple-update.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigate-window.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-redirect-body.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-redirect-to-http.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-redirect.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-timing.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/onactivate-script-error.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/oninstall-script-error.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/opaque-response-preloaded.https.html >@@ -131,6 +149,7 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-updateviacache.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/rejections.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/request-end-to-end.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resource-timing-cross-origin.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resource-timing.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/respond-with-body-accessed-response.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/sandboxed-iframe-fetch-event.https.html >@@ -138,6 +157,7 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/service-worker-csp-connect.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/service-worker-csp-default.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/service-worker-csp-script.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/service-worker-header.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/serviceworker-message-event-historical.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/serviceworkerobject-scripturl.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/shared-worker-controlled.https.html >@@ -147,6 +167,8 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/state.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/svg-target-reftest.https-expected.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/svg-target-reftest.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/synced-state.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/uncontrolled-page.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/unregister-controller.https.html >@@ -157,9 +179,14 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/update-after-oneday.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/update-bytecheck.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/update-recovery.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/update-result.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/update.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/waiting.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/websocket-in-service-worker.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/websocket.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/webvtt-cross-origin.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/windowclient-navigate.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-client-id.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https.html >+/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-interception-redirect.https.html > /LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-interception.https.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/webvtt-cross-origin.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/webvtt-cross-origin.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d3bdc23647f6d8ff4791cee5a70cb649c2e95ce2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/webvtt-cross-origin.https-expected.txt >@@ -0,0 +1,12 @@ >+ >+PASS initialize global state >+PASS same-origin text track should load >+FAIL cross-origin text track with no-cors request should not load assert_equals: expected "error event" but got "load event" >+PASS cross-origin text track with rejected cors request should not load >+PASS cross-origin text track with approved cors request should load >+PASS same-origin text track that redirects same-origin should load >+FAIL same-origin text track that redirects cross-origin should not load assert_equals: expected "error event" but got "load event" >+PASS same-origin text track that redirects to a cross-origin text track with rejected cors should not load >+PASS same-origin text track that redirects to a cross-origin text track with approved cors should load >+PASS restore global state >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/webvtt-cross-origin.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/webvtt-cross-origin.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..637f494e4c1e69dac48535a14128b9bc0d5615b6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/webvtt-cross-origin.https.html >@@ -0,0 +1,172 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>cross-origin webvtt returned by service worker is detected</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/get-host-info.sub.js"></script> >+<script src="resources/test-helpers.sub.js?pipe=sub"></script> >+<body> >+<script> >+// This file tests opaque responses for WebVTT text track. It creates >+// an iframe with a <track> element, controlled by a service worker. >+// Each test tries to load a text track, the service worker intercepts the >+// requests and responds with opaque or non-opaque responses. The opaque >+// responses should result in load errors. >+ >+const host_info = get_host_info(); >+const kScript = 'resources/fetch-rewrite-worker.js'; >+// Add '?ignore' so the service worker falls back for the navigation. >+const kScope = 'resources/vtt-frame.html?ignore'; >+let frame; >+ >+function load_track(url) { >+ const track = frame.contentDocument.querySelector('track'); >+ const result = new Promise((resolve, reject) => { >+ track.onload = (e => { >+ resolve('load event'); >+ }); >+ track.onerror = (e => { >+ resolve('error event'); >+ }); >+ }); >+ >+ track.src = url; >+ // Setting mode to hidden seems needed, or else the text track requests don't >+ // occur. >+ track.track.mode = 'hidden'; >+ return result; >+} >+ >+promise_test(t => { >+ return service_worker_unregister_and_register(t, kScript, kScope) >+ .then(registration => { >+ promise_test(() => { >+ frame.remove(); >+ return registration.unregister(); >+ }, 'restore global state'); >+ >+ return wait_for_state(t, registration.installing, 'activated'); >+ }) >+ .then(() => { >+ return with_iframe(kScope); >+ }) >+ .then(f => { >+ frame = f; >+ }) >+ }, 'initialize global state'); >+ >+promise_test(t => { >+ let url = '/media/foo.vtt'; >+ // Add '?url' and tell the service worker to fetch a same-origin URL. >+ url += '?url=' + host_info.HTTPS_ORIGIN + '/media/foo.vtt'; >+ return load_track(url) >+ .then(result => { >+ assert_equals(result, 'load event'); >+ }); >+ }, 'same-origin text track should load'); >+ >+promise_test(t => { >+ let url = '/media/foo.vtt'; >+ // Add '?url' and tell the service worker to fetch a cross-origin URL. >+ url += '?url=' + get_host_info().HTTPS_REMOTE_ORIGIN + '/media/foo.vtt'; >+ return load_track(url) >+ .then(result => { >+ assert_equals(result, 'error event'); >+ }); >+ }, 'cross-origin text track with no-cors request should not load'); >+ >+promise_test(t => { >+ let url = '/media/foo.vtt'; >+ // Add '?url' and tell the service worker to fetch a cross-origin URL that >+ // doesn't support CORS. >+ url += '?url=' + get_host_info().HTTPS_REMOTE_ORIGIN + >+ '/media/foo-no-cors.vtt'; >+ // Add '&mode' to tell the service worker to do a CORS request. >+ url += '&mode=cors'; >+ return load_track(url) >+ .then(result => { >+ assert_equals(result, 'error event'); >+ }); >+ }, 'cross-origin text track with rejected cors request should not load'); >+ >+promise_test(t => { >+ let url = '/media/foo.vtt'; >+ // Add '?url' and tell the service worker to fetch a cross-origin URL. >+ url += '?url=' + get_host_info().HTTPS_REMOTE_ORIGIN + '/media/foo.vtt'; >+ // Add '&mode' to tell the service worker to do a CORS request. >+ url += '&mode=cors'; >+ // Add '&credentials=same-origin' to allow Access-Control-Allow-Origin=* so >+ // that CORS will succeed if the service approves it. >+ url += '&credentials=same-origin'; >+ return load_track(url) >+ .then(result => { >+ assert_equals(result, 'load event'); >+ }); >+ }, 'cross-origin text track with approved cors request should load'); >+ >+// Redirect tests. >+ >+promise_test(t => { >+ let url = '/media/foo.vtt'; >+ // Add '?url' and tell the service worker to fetch a same-origin URL that redirects... >+ redirector_url = host_info.HTTPS_ORIGIN + base_path() + 'resources/redirect.py?Redirect='; >+ // ... to a same-origin URL. >+ redirect_target = host_info.HTTPS_ORIGIN + '/media/foo.vtt'; >+ url += '?url=' + encodeURIComponent(redirector_url + encodeURIComponent(redirect_target)); >+ return load_track(url) >+ .then(result => { >+ assert_equals(result, 'load event'); >+ }); >+ }, 'same-origin text track that redirects same-origin should load'); >+ >+promise_test(t => { >+ let url = '/media/foo.vtt'; >+ // Add '?url' and tell the service worker to fetch a same-origin URL that redirects... >+ redirector_url = host_info.HTTPS_ORIGIN + base_path() + 'resources/redirect.py?Redirect='; >+ // ... to a cross-origin URL. >+ redirect_target = host_info.HTTPS_REMOTE_ORIGIN + '/media/foo.vtt'; >+ url += '?url=' + encodeURIComponent(redirector_url + encodeURIComponent(redirect_target)); >+ return load_track(url) >+ .then(result => { >+ assert_equals(result, 'error event'); >+ }); >+ }, 'same-origin text track that redirects cross-origin should not load'); >+ >+ >+promise_test(t => { >+ let url = '/media/foo.vtt'; >+ // Add '?url' and tell the service worker to fetch a same-origin URL that redirects... >+ redirector_url = host_info.HTTPS_ORIGIN + base_path() + 'resources/redirect.py?Redirect='; >+ // ... to a cross-origin URL. >+ redirect_target = host_info.HTTPS_REMOTE_ORIGIN + '/media/foo-no-cors.vtt'; >+ url += '?url=' + encodeURIComponent(redirector_url + encodeURIComponent(redirect_target)); >+ // Add '&mode' to tell the service worker to do a CORS request. >+ url += '&mode=cors'; >+ // Add '&credentials=same-origin' to allow Access-Control-Allow-Origin=* so >+ // that CORS will succeed if the server approves it. >+ url += '&credentials=same-origin'; >+ return load_track(url) >+ .then(result => { >+ assert_equals(result, 'error event'); >+ }); >+ }, 'same-origin text track that redirects to a cross-origin text track with rejected cors should not load'); >+ >+promise_test(t => { >+ let url = '/media/foo.vtt'; >+ // Add '?url' and tell the service worker to fetch a same-origin URL that redirects... >+ redirector_url = host_info.HTTPS_ORIGIN + base_path() + 'resources/redirect.py?Redirect='; >+ // ... to a cross-origin URL. >+ redirect_target = host_info.HTTPS_REMOTE_ORIGIN + '/media/foo.vtt'; >+ url += '?url=' + encodeURIComponent(redirector_url + encodeURIComponent(redirect_target)); >+ // Add '&mode' to tell the service worker to do a CORS request. >+ url += '&mode=cors'; >+ // Add '&credentials=same-origin' to allow Access-Control-Allow-Origin=* so >+ // that CORS will succeed if the server approves it. >+ url += '&credentials=same-origin'; >+ return load_track(url) >+ .then(result => { >+ assert_equals(result, 'load event'); >+ }); >+ }, 'same-origin text track that redirects to a cross-origin text track with approved cors should load'); >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/windowclient-navigate.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/windowclient-navigate.https.html >index 8fb467a3f9bf81be9af270857a8fedc392492aa4..8ea279ef075e5e6c8904966b005f0baf0d75bca9 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/windowclient-navigate.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/windowclient-navigate.https.html >@@ -166,7 +166,7 @@ function navigate_test(override_parameters) { > // executes. `Test#add_cleanup` cannot be used for this purpose because the > // operation is asynchronous, and `add_cleanup` does not support > // asynchronous operations at the time of this writing. See >- // https://github.com/w3c/web-platform-tests/issues/6075 >+ // https://github.com/web-platform-tests/wpt/issues/6075 > // Ensure also that test failure is not hidden by successful cleanup > // operation. > return test_body >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-client-id.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-client-id.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..42a9e1322c045eaa049be140af06b545d3697bf0 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-client-id.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+FAIL Verify workers have a unique client id separate from their owning documents window assert_not_equals: frame and worker client ids should be different got disallowed value "1-5" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-client-id.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-client-id.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..4e4d31660bd56add3f3559fce5e884b0c7e1f0e2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-client-id.https.html >@@ -0,0 +1,58 @@ >+<!DOCTYPE html> >+<title>Service Worker: Workers should have their own unique client Id</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/test-helpers.sub.js"></script> >+<body> >+<script> >+ >+// Get the iframe client ID by calling postMessage() on its controlling >+// worker. This will cause the service worker to post back the >+// MessageEvent.source.id value. >+function getFrameClientId(frame) { >+ return new Promise(resolve => { >+ let mc = new MessageChannel(); >+ frame.contentWindow.navigator.serviceWorker.controller.postMessage( >+ 'echo-client-id', [mc.port2]); >+ mc.port1.onmessage = evt => { >+ resolve(evt.data); >+ }; >+ }); >+} >+ >+// Get the worker client ID by creating a worker that performs an intercepted >+// fetch(). The synthetic fetch() response will contain the FetchEvent.clientId >+// value. This is then posted back to here. >+function getWorkerClientId(frame) { >+ return new Promise(resolve => { >+ let w = new frame.contentWindow.Worker('worker-echo-client-id.js'); >+ w.onmessage = evt => { >+ resolve(evt.data); >+ }; >+ }); >+} >+ >+promise_test(async function(t) { >+ const script = './resources/worker-client-id-worker.js'; >+ const scope = './resources/worker-client-id'; >+ const frame = scope + '/frame.html'; >+ >+ let reg = await navigator.serviceWorker.register(script, { scope }); >+ t.add_cleanup(async _ => await reg.unregister()); >+ await wait_for_state(t, reg.installing, 'activated'); >+ >+ let f = await with_iframe(frame); >+ t.add_cleanup(_ => f.remove()); >+ >+ let frameClientId = await getFrameClientId(f); >+ assert_not_equals(frameClientId, null, 'frame client id should exist'); >+ >+ let workerClientId = await getWorkerClientId(f); >+ assert_not_equals(workerClientId, null, 'worker client id should exist'); >+ >+ assert_not_equals(frameClientId, workerClientId, >+ 'frame and worker client ids should be different'); >+}, 'Verify workers have a unique client id separate from their owning documents window'); >+ >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..647e131936d478bbfd707a1304611ca99732cacf >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https-expected.txt >@@ -0,0 +1,13 @@ >+CONSOLE MESSAGE: line 27: [blocked] The page at https://localhost:9443/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https.html was not allowed to display insecure content from blob:null/45cf614b-61af-4ace-b36a-5755e2a1e0e0. >+ >+CONSOLE MESSAGE: line 27: Not allowed to request resource >+CONSOLE MESSAGE: line 27: Cannot load blob:null/45cf614b-61af-4ace-b36a-5755e2a1e0e0 due to access control checks. >+ >+Harness Error (TIMEOUT), message = null >+ >+PASS Prepare a service worker. >+FAIL Prepare an iframe sandboxed by CSP HTTP header with allow-scripts. assert_false: Service worker should NOT control the sandboxed page expected false got true >+PASS Prepare an iframe sandboxed by CSP HTTP header with allow-scripts and allow-same-origin. >+TIMEOUT Fetch request from a worker in iframe sandboxed by CSP HTTP header allow-scripts flag Test timed out >+NOTRUN Fetch request from a worker in iframe sandboxed by CSP HTTP header with allow-scripts and allow-same-origin flag >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..c8480bf1be003903383404fa90ff28af668f6533 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https.html >@@ -0,0 +1,132 @@ >+<!DOCTYPE html> >+<title>ServiceWorker FetchEvent issued from workers in an iframe sandboxed via CSP HTTP response header.</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/test-helpers.sub.js"></script> >+<body> >+<script> >+let lastCallbackId = 0; >+let callbacks = {}; >+function doTest(frame, type) { >+ return new Promise(function(resolve) { >+ var id = ++lastCallbackId; >+ callbacks[id] = resolve; >+ frame.contentWindow.postMessage({id: id, type: type}, '*'); >+ }); >+} >+ >+// Asks the service worker for data about requests and clients seen. The >+// worker posts a message back with |data| where: >+// |data.requests|: the requests the worker received FetchEvents for >+// |data.clients|: the URLs of all the worker's clients >+// The worker clears its data after responding. >+function getResultsFromWorker(worker) { >+ return new Promise(resolve => { >+ let channel = new MessageChannel(); >+ channel.port1.onmessage = msg => { >+ resolve(msg.data); >+ }; >+ worker.postMessage({port: channel.port2}, [channel.port2]); >+ }); >+} >+ >+window.onmessage = function (e) { >+ message = e.data; >+ let id = message['id']; >+ let callback = callbacks[id]; >+ delete callbacks[id]; >+ callback(message['result']); >+}; >+ >+const SCOPE = 'resources/sandboxed-iframe-fetch-event-iframe.py'; >+const SCRIPT = 'resources/sandboxed-iframe-fetch-event-worker.js'; >+const expected_base_url = new URL(SCOPE, location.href); >+// A service worker controlling |SCOPE|. >+let worker; >+// An iframe whose response header has >+// 'Content-Security-Policy: allow-scripts'. >+// This should NOT be controlled by a service worker. >+let sandboxed_frame_by_header; >+// An iframe whose response header has >+// 'Content-Security-Policy: allow-scripts allow-same-origin'. >+// This should be controlled by a service worker. >+let sandboxed_same_origin_frame_by_header; >+ >+promise_test(t => { >+ return service_worker_unregister_and_register(t, SCRIPT, SCOPE) >+ .then(function(registration) { >+ add_completion_callback(() => registration.unregister()); >+ worker = registration.installing; >+ return wait_for_state(t, registration.installing, 'activated'); >+ }); >+}, 'Prepare a service worker.'); >+ >+promise_test(t => { >+ const iframe_full_url = expected_base_url + '?sandbox=allow-scripts&' + >+ 'sandboxed-frame-by-header'; >+ return with_iframe(iframe_full_url) >+ .then(f => { >+ sandboxed_frame_by_header = f; >+ add_completion_callback(() => f.remove()); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ let requests = data.requests; >+ assert_equals(requests.length, 1, >+ 'Service worker should provide the response'); >+ assert_equals(requests[0], iframe_full_url); >+ assert_false(data.clients.includes(iframe_full_url), >+ 'Service worker should NOT control the sandboxed page'); >+ }); >+}, 'Prepare an iframe sandboxed by CSP HTTP header with allow-scripts.'); >+ >+promise_test(t => { >+ const iframe_full_url = >+ expected_base_url + '?sandbox=allow-scripts%20allow-same-origin&' + >+ 'sandboxed-iframe-same-origin-by-header'; >+ return with_iframe(iframe_full_url) >+ .then(f => { >+ sandboxed_same_origin_frame_by_header = f; >+ add_completion_callback(() => f.remove()); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ let requests = data.requests; >+ assert_equals(requests.length, 1); >+ assert_equals(requests[0], iframe_full_url); >+ assert_true(data.clients.includes(iframe_full_url)); >+ }) >+}, 'Prepare an iframe sandboxed by CSP HTTP header with allow-scripts and ' + >+ 'allow-same-origin.'); >+ >+promise_test(t => { >+ let frame = sandboxed_frame_by_header; >+ return doTest(frame, 'fetch-from-worker') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ assert_equals(data.requests.length, 0, >+ 'The request should NOT be handled by SW.'); >+ }); >+}, 'Fetch request from a worker in iframe sandboxed by CSP HTTP header ' + >+ 'allow-scripts flag'); >+ >+promise_test(t => { >+ let frame = sandboxed_same_origin_frame_by_header; >+ return doTest(frame, 'fetch-from-worker') >+ .then(result => { >+ assert_equals(result, 'done'); >+ return getResultsFromWorker(worker); >+ }) >+ .then(data => { >+ let requests = data.requests; >+ assert_equals(requests.length, 1, >+ 'The request should be handled by SW.'); >+ assert_equals(requests[0], frame.src + '&test=fetch-from-worker'); >+ }); >+}, 'Fetch request from a worker in iframe sandboxed by CSP HTTP header ' + >+ 'with allow-scripts and allow-same-origin flag'); >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-interception-redirect.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-interception-redirect.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..1b3cd2082e27e494899c849ce5154049bd15f55f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-interception-redirect.https-expected.txt >@@ -0,0 +1,8 @@ >+ >+PASS initialize global state >+FAIL request to sw1 scope gets network redirect to sw2 scope promise_test: Unhandled rejection with value: object "TypeError: undefined is not a constructor (evaluating 'new frame.contentWindow.SharedWorker(worker_url)')" >+FAIL request to sw1 scope gets network redirect to out-of-scope promise_test: Unhandled rejection with value: object "TypeError: undefined is not a constructor (evaluating 'new frame.contentWindow.SharedWorker(worker_url)')" >+FAIL request to sw1 scope gets service-worker redirect to sw2 scope promise_test: Unhandled rejection with value: object "TypeError: undefined is not a constructor (evaluating 'new frame.contentWindow.SharedWorker(worker_url)')" >+FAIL request to sw1 scope gets service-worker redirect to out-of-scope promise_test: Unhandled rejection with value: object "TypeError: undefined is not a constructor (evaluating 'new frame.contentWindow.SharedWorker(worker_url)')" >+PASS cleanup global state >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-interception-redirect.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-interception-redirect.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..654495fe4c3bb8d0006ce556106fee070b534af8 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-interception-redirect.https.html >@@ -0,0 +1,171 @@ >+<!DOCTYPE html> >+<title>Service Worker: controlling a SharedWorker</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/test-helpers.sub.js"></script> >+<body> >+<script> >+// This tests service worker interception for worker clients, when the request >+// for the worker script goes through redirects. For example, a request can go >+// through a chain of URLs like A -> B -> C -> D and each URL might fall in the >+// scope of a different service worker, if any. >+// The two key questions are: >+// 1. Upon a redirect from A -> B, should a service worker for scope B >+// intercept the request? >+// 2. After the final response, which service worker controls the resulting >+// client? >+// >+// The standard prescribes the following: >+// 1. The service worker for scope B intercepts the redirect. *However*, once a >+// request falls back to network (i.e., a service worker did not call >+// respondWith()) and a redirect is then received from network, no service >+// worker should intercept that redirect or any subsequent redirects. >+// 2. The final service worker that got a fetch event (or would have, in the >+// case of a non-fetch-event worker) becomes the controller of the client. >+// >+// The standard may change later, see: >+// https://github.com/w3c/ServiceWorker/issues/1289 >+// >+// The basic test setup is: >+// 1. Page registers service workers for scope1 and scope2. >+// 2. Page requests a worker from scope1. >+// 3. The request is redirected to scope2 or out-of-scope. >+// 4. The worker posts message to the page describing where the final response >+// was served from (service worker or network). >+// 5. The worker does an importScripts() and fetch(), and posts back the >+// responses, which describe where the responses where served from. >+// >+// Currently this only tests shared worker but dedicated worker tests should be >+// added in a future patch. >+ >+// Globals for easier cleanup. >+const scope1 = 'resources/scope1'; >+const scope2 = 'resources/scope2'; >+let frame; >+ >+function get_message_from_worker(worker) { >+ return new Promise(resolve => { >+ worker.port.onmessage = evt => { >+ resolve(evt.data); >+ } >+ }); >+} >+ >+async function cleanup() { >+ if (frame) >+ frame.remove(); >+ >+ const reg1 = await navigator.serviceWorker.getRegistration(scope1); >+ if (reg1) >+ await reg1.unregister(); >+ const reg2 = await navigator.serviceWorker.getRegistration(scope2); >+ if (reg2) >+ await reg2.unregister(); >+} >+ >+// Builds the worker script URL, which encodes information about where >+// to redirect to. The URL falls in sw1's scope. >+// >+// - |redirector| is "network" or "serviceworker". If "serviceworker", sw1 will >+// respondWith() a redirect. Otherwise, it falls back to network and the server >+// responds with a redirect. >+// - |redirect_location| is "scope2" or "out-of-scope". If "scope2", the >+// redirect ends up in sw2's scope2. Otherwise it's out of scope. >+function build_worker_url(redirector, redirect_location) { >+ let redirect_path; >+ // Set path to redirect.py, a file on the server that serves >+ // a redirect. When sw1 sees this URL, it falls back to network. >+ if (redirector == 'network') >+ redirector_path = 'redirect.py'; >+ // Set path to 'sw-redirect', to tell the service worker >+ // to respond with redirect. >+ else if (redirector == 'serviceworker') >+ redirector_path = 'sw-redirect'; >+ >+ let redirect_to = base_path() + 'resources/'; >+ // Append "scope2/" to redirect_to, so the redirect falls in scope2. >+ // Otherwise no change is needed, as the parent "resources/" directory is >+ // used, and is out-of-scope. >+ if (redirect_location == 'scope2') >+ redirect_to += 'scope2/'; >+ // Append the name of the file which serves the worker script. >+ redirect_to += 'worker_interception_redirect_webworker.py'; >+ >+ return `scope1/${redirector_path}?Redirect=${redirect_to}` >+} >+ >+promise_test(async t => { >+ await cleanup(); >+ const service_worker = 'resources/worker-interception-redirect-serviceworker.js'; >+ const registration1 = await navigator.serviceWorker.register(service_worker, {scope: scope1}); >+ await wait_for_state(t, registration1.installing, 'activated'); >+ const registration2 = await navigator.serviceWorker.register(service_worker, {scope: scope2}); >+ await wait_for_state(t, registration2.installing, 'activated'); >+ >+ promise_test(t => { >+ return cleanup(); >+ }, 'cleanup global state'); >+}, 'initialize global state'); >+ >+function worker_redirect_test(worker_url, >+ expected_main_resource_message, >+ expected_import_scripts_message, >+ expected_fetch_message, >+ description) { >+ promise_test(async t => { >+ // Create a frame to load the worker from. This way we can remove the frame >+ // to destroy the worker client when the test is done. >+ frame = await with_iframe('resources/blank.html'); >+ t.add_cleanup(() => { frame.remove(); }); >+ >+ // Start the worker. >+ const w = new frame.contentWindow.SharedWorker(worker_url); >+ w.port.start(); >+ >+ // Expect a message from the worker indicating which service worker >+ // provided the response for the worker script request, if any. >+ const data = await get_message_from_worker(w); >+ assert_equals(data, expected_main_resource_message); >+ >+ // The worker does an importScripts(). Expect a message from the worker >+ // indicating which service worker provided the response for the >+ // importScripts(), if any. >+ const import_scripts_message = await get_message_from_worker(w); >+ assert_equals(import_scripts_message, expected_import_scripts_message); >+ >+ // The worker does a fetch(). Expect a message from the worker indicating >+ // which service worker provided the response for the fetch(), if any. >+ const fetch_message = await get_message_from_worker(w); >+ assert_equals(fetch_message, expected_fetch_message); >+ }, description); >+} >+ >+worker_redirect_test( >+ build_worker_url('network', 'scope2'), >+ 'the shared worker script was served from network', >+ 'sw1 saw importScripts from the worker', >+ 'fetch(): sw1 saw the fetch from the worker', >+ 'request to sw1 scope gets network redirect to sw2 scope'); >+ >+worker_redirect_test( >+ build_worker_url('network', 'out-scope'), >+ 'the shared worker script was served from network', >+ 'sw1 saw importScripts from the worker', >+ 'fetch(): sw1 saw the fetch from the worker', >+ 'request to sw1 scope gets network redirect to out-of-scope'); >+ >+worker_redirect_test( >+ build_worker_url('serviceworker', 'scope2'), >+ 'sw2 saw the request for the worker script', >+ 'sw2 saw importScripts from the worker', >+ 'fetch(): sw2 saw the fetch from the worker', >+ 'request to sw1 scope gets service-worker redirect to sw2 scope'); >+ >+worker_redirect_test( >+ build_worker_url('serviceworker', 'out-scope'), >+ 'the shared worker script was served from network', >+ 'sw1 saw importScripts from the worker', >+ 'fetch(): sw1 saw the fetch from the worker', >+ 'request to sw1 scope gets service-worker redirect to out-of-scope'); >+</script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-interception.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-interception.https-expected.txt >index d1d4f894793fcfebcc2600848a3b2ac34d275200..45e229e7281ce0e10ad376e8d5ce2e4820759209 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-interception.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-interception.https-expected.txt >@@ -2,7 +2,7 @@ > > FAIL Verify worker script from uncontrolled document is intercepted by Service Worker promise_test: Unhandled rejection with value: undefined > FAIL Verify worker script intercepted by same-origin response succeeds promise_test: Unhandled rejection with value: undefined >-FAIL Verify worker script intercepted by cors response succeeds promise_test: Unhandled rejection with value: undefined >+PASS Verify worker script intercepted by cors response fails > PASS Verify worker script intercepted by no-cors cross-origin response fails > PASS Verify worker loads from controlled document are intercepted by Service Worker > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-interception.https.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-interception.https.html >index 3ec66a54b6e1e536d781eaf00c9f8a47f0029c41..4f14746d917f9e8f41dfca85e1669dde50d568c4 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-interception.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/worker-interception.https.html >@@ -81,10 +81,16 @@ promise_test(function(t) { > }); > }) > .then(function(data) { >- assert_equals(data, 'dummy-worker-script loaded'); >+ assert_unreached('intercepted cors response to a same-origin mode ' + >+ 'worker load should fail'); > service_worker_unregister_and_done(t, scope); >- }); >- }, 'Verify worker script intercepted by cors response succeeds'); >+ }) >+ .catch(function(e) { >+ assert_true(true, 'intercepted cors response to a same-origin mode ' + >+ 'worker load should fail'); >+ service_worker_unregister_and_done(t, scope); >+ }); >+ }, 'Verify worker script intercepted by cors response fails'); > > promise_test(function(t) { > var worker_url = 'resources/dummy-no-cors-worker.js'; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1-service-worker-obj-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1-service-worker-obj-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..6a53d3ec00c64f8a9d058fc114e4cb0fa1039d94 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1-service-worker-obj-expected.txt >@@ -0,0 +1,29 @@ >+CONSOLE MESSAGE: line 830: TypeError: this.members[name].test_object is not a function. (In 'this.members[name].test_object(str)', 'this.members[name].test_object' is undefined) >+ >+Harness Error (FAIL), message = TypeError: this.members[name].test_object is not a function. (In 'this.members[name].test_object(str)', 'this.members[name].test_object' is undefined) >+ >+FAIL ServiceWorker interface: existence and properties of interface object assert_equals: prototype of ServiceWorker is not Worker expected function "function Worker() { >+ [native code] >+}" but got function "function EventTarget() { >+ [native code] >+}" >+PASS ServiceWorker interface object length >+PASS ServiceWorker interface object name >+FAIL ServiceWorker interface: existence and properties of interface prototype object assert_equals: prototype of ServiceWorker.prototype is not Worker.prototype expected object "[object WorkerPrototype]" but got object "[object EventTargetPrototype]" >+PASS ServiceWorker interface: existence and properties of interface prototype object's "constructor" property >+PASS ServiceWorker interface: existence and properties of interface prototype object's @@unscopables property >+FAIL ServiceWorker interface: attribute scope assert_true: The prototype object must have a property "scope" expected true got false >+PASS Unscopable handled correctly for scope property on ServiceWorker >+FAIL ServiceWorker interface: attribute url assert_true: The prototype object must have a property "url" expected true got false >+PASS Unscopable handled correctly for url property on ServiceWorker >+PASS ServiceWorker interface: attribute state >+PASS Unscopable handled correctly for state property on ServiceWorker >+PASS ServiceWorker interface: attribute onstatechange >+PASS Unscopable handled correctly for onstatechange property on ServiceWorker >+FAIL ServiceWorker must be primary interface of throw new Error ('No object defined for the ServiceWorker interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the ServiceWorker interface" >+FAIL Stringification of throw new Error ('No object defined for the ServiceWorker interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the ServiceWorker interface" >+FAIL ServiceWorker interface: throw new Error ('No object defined for the ServiceWorker interface') must inherit property "scope" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the ServiceWorker interface" >+FAIL ServiceWorker interface: throw new Error ('No object defined for the ServiceWorker interface') must inherit property "url" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the ServiceWorker interface" >+FAIL ServiceWorker interface: throw new Error ('No object defined for the ServiceWorker interface') must inherit property "state" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the ServiceWorker interface" >+FAIL ServiceWorker interface: throw new Error ('No object defined for the ServiceWorker interface') must inherit property "onstatechange" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the ServiceWorker interface" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1-service-worker-obj.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1-service-worker-obj.html >new file mode 100644 >index 0000000000000000000000000000000000000000..99c2cbe8597d7391defdd2057ef466a2445cec73 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1-service-worker-obj.html >@@ -0,0 +1,63 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: ServiceWorker</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#service-worker-obj"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ <script src=/resources/WebIDLParser.js></script> >+ <script src=/resources/idlharness.js></script> >+ >+ </head> >+ <body> >+ >+<script type=text/plain id="idl_0"> >+[Constructor()] // no-op constructor >+interface ServiceWorker : Worker { >+ readonly attribute DOMString scope; >+ readonly attribute DOMString url; >+ readonly attribute ServiceWorkerState state; >+ >+ // event >+ attribute EventHandler onstatechange; >+}; >+ >+enum ServiceWorkerState { >+ "installing", >+ "installed", >+ "activating", >+ "activated", >+ "redundant" >+}; >+</script> >+ >+<!-- >+The `ServiceWorker` interface represents the document-side view of a Service >+Worker. This object provides a no-op constructor. Callers should note that only >+`ServiceWorker` objects created by the user agent (see >+`navigator.serviceWorker.installing`, `navigator.serviceWorker.waiting`, >+`navigator.serviceWorker.active` and `navigator.serviceWorker.controller`) will >+provide meaningful functionality. >+--> >+ >+ >+ <script type=text/plain id="untested_idls"> >+ interface EventHandler {}; >+ interface Worker {}; >+ </script> >+ >+ <script> >+ var idl_array = new IdlArray(); >+ idl_array.add_untested_idls(document.getElementById("untested_idls").textContent); >+ idl_array.add_idls(document.getElementById("idl_0").textContent); >+ idl_array.add_objects({ >+ ServiceWorker: ["throw new Error ('No object defined for the ServiceWorker interface')"], >+ ServiceWorkerState: ["throw new Error ('No object defined for the ServiceWorkerState enum')"] >+ }); >+ idl_array.test(); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.1-service-worker-scope-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.1-service-worker-scope-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..1101e195972a92286379a9fbd4bdfd4cd788e0fc >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.1-service-worker-scope-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section scope so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.1-service-worker-scope.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.1-service-worker-scope.html >new file mode 100644 >index 0000000000000000000000000000000000000000..8c75c608297a3dcf14d03d60ebc624ea233b6427 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.1-service-worker-scope.html >@@ -0,0 +1,46 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: scope</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#service-worker-scope"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+The `scope` of a `ServiceWorker` object reflects the [URL scope][1] of the >+associated Service Worker [registration][2]. The `scope` attribute must return >+the [serialization][3] of the URL representing the [URL scope][1] of the >+associated Service Worker [registration][2]. >+ >+For example, consider a document created by a navigation to >+`https://example.com/app.html` which [matches][4] via the following >+registration call which has been previously executed: >+// Script on the page https://example.com/app.html >+navigator.serviceWorker.register("/service_worker.js", { scope: "/*" }); >+The value of `navigator.serviceWorker.controller.scope` will be >+`"https://example.com/*"`. >+ >+ >+ >+[1]: #url-scope >+[2]: #registration >+[3]: http://url.spec.whatwg.org/#concept-url-serializer >+[4]: #on-fetch-request-algorithm >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section scope so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.2-service-worker-url-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.2-service-worker-url-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..87e9123f47441138acdfa8eab5f05f2ac23f8f67 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.2-service-worker-url-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section url so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.2-service-worker-url.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.2-service-worker-url.html >new file mode 100644 >index 0000000000000000000000000000000000000000..5674df7fc8d9ac493251a6c51a3d7ca34674a71d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.2-service-worker-url.html >@@ -0,0 +1,43 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: url</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#service-worker-url"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+The `url` attribute must return the [serialization][1] of the URL of the script >+of the Service Worker, identified by its [URL scope][2], that is associated >+with the [ServiceWorkerGlobalScope][3] object. The `url` attribute is always an >+[absolute URL][4] corresponding to the script file which the Service Worker >+evaluates. >+ >+In the example in section 3.1.1, the value of >+`navigator.serviceWorker.controller.url` will be >+`"https://example.com/service_worker.js"`. >+ >+ >+ >+[1]: http://url.spec.whatwg.org/#concept-url-serializer >+[2]: #url-scope >+[3]: #service-worker-global-scope-interface >+[4]: http://url.spec.whatwg.org/#concept-absolute-url >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section url so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.3-service-worker-state-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.3-service-worker-state-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d9ecc612fb690ac9d52ce70c329e5d3ae5e721b3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.3-service-worker-state-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section state so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.3-service-worker-state.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.3-service-worker-state.html >new file mode 100644 >index 0000000000000000000000000000000000000000..8e729baf89f5e786e715ecadd071b06b00a43eaf >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.3-service-worker-state.html >@@ -0,0 +1,76 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: state</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#service-worker-state"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+The [ServiceWorker][1] object can be in several states. The `state` attribute >+must return the current state, which must be one of the following values >+defined in the [ServiceWorkerState][2] enumeration: >+ >+`"installing"`: >+ The Service Worker represented by the [ServiceWorker][1] object has entered >+ and is running the steps in the [installation process][3]. During this >+ state, `e.waitUntil(p)` can be called inside the `oninstall` event handler >+ of the associcated [ServiceWorkerGloberScope][4] object to extend the life >+ of the [installing worker][5] until the passed [Promise][6] resolves >+ successfully. This is primarily used to ensure that the Service Worker is >+ not active until all of the core caches are populated. >+`"installed"`: >+ The Service Worker represented by the [ServiceWorker][1] object has >+ completed the steps in the [installation process][3]. The Service Worker in >+ this state is considered the [worker in waiting][7]. >+`"activating"`: >+ The Service Worker represented by the [ServiceWorker][1] object has entered >+ and is running the steps in the [activation process][8]. During this state, >+ `e.waitUntil(p)` can be called inside the `onactivate` event handler of the >+ associated [ServiceWorkerGloberScope][9] object to extend the life of the >+ activating [active worker][10] until the passed [Promise][6] resolves >+ successfully. Note that no [functional events][11] are dispatched until the >+ state becomes `"activated"`. >+`"activated"`: >+ The Service Worker represented by the [ServiceWorker][1] object has >+ completed the steps in the [activation process][8]. The Service Worker in >+ this state is considered the [active worker][10] ready to [control][12] the >+ documents in matching scope upon subsequence [navigation][13]. >+`"redundant"`: >+ A newly created Service Worker [registration][14] is replacing the current >+ [registration][14] of the Service Worker. >+ >+ >+ >+[1]: #service-worker-interface >+[2]: #service-worker-state-enum >+[3]: #installation-process >+[4]: #service-worker-glober-scope-interface >+[5]: #installing-worker >+[6]: http://goo.gl/3TobQS >+[7]: #worker-in-waiting >+[8]: #activation-process >+[9]: #service-worker-global-scope-interface >+[10]: #active-worker >+[11]: #functional-events >+[12]: #document-control >+[13]: http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html#navigate >+[14]: #registration >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section state so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.4-service-worker-on-state-change-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.4-service-worker-on-state-change-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..b526845145e4072f38fa1684f3c4afa878c11ffa >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.4-service-worker-on-state-change-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section onstatechange so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.4-service-worker-on-state-change.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.4-service-worker-on-state-change.html >new file mode 100644 >index 0000000000000000000000000000000000000000..c87dce60163242a8d271bbc61f61d1c985afcb5d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.1.4-service-worker-on-state-change.html >@@ -0,0 +1,35 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: onstatechange</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#service-worker-on-state-change"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`onstatechange` is the [event handler][1] that must be supported as attribute >+by the `[ServiceWorker][2]` object. A `statechange` event using the >+`[Event][3]` interface is dispatched on `[ServiceWorker][2]` object when the >+`state` attribute of the `ServiceWorker` object is changed. >+ >+[1]: http://goo.gl/rBfiz0 >+[2]: #service-worker-interface >+[3]: http://goo.gl/Mzv7Dv >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section onstatechange so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2-navigator-service-worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2-navigator-service-worker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..143ada076500c092c900c58932522ab369fe49dc >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2-navigator-service-worker-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 746: Partial interface Navigator with no original interface >+ >+FAIL Service Workers: navigator.serviceWorker Partial interface Navigator with no original interface >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2-navigator-service-worker.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2-navigator-service-worker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d5b51475aa8c19f4e747fc39fbef3315ddb8c6c9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2-navigator-service-worker.html >@@ -0,0 +1,84 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: navigator.serviceWorker</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#navigator-service-worker"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ <script src=/resources/WebIDLParser.js></script> >+ <script src=/resources/idlharness.js></script> >+ >+ </head> >+ <body> >+ >+<!-- >+The `serviceWorker` attribute of the [Navigator][1] interface must return an >+instance of the `ServiceWorkerContainer` interface, which provides access to >+registration, removal, upgrade, and communication with Service Workers that are >+(or will become) active for the current document. Communication with these >+workers is provided via standard [HTML5 messaging APIs][2], and [messaging >+occurs as per usual with Web Workers][3]. >+--> >+<script type=text/plain id="idl_0"> >+partial interface Navigator { >+ readonly attribute ServiceWorkerContainer serviceWorker; >+}; >+ >+interface ServiceWorkerContainer : EventTarget { >+ [Unforgeable] readonly attribute ServiceWorker? installing; >+ [Unforgeable] readonly attribute ServiceWorker? waiting; >+ [Unforgeable] readonly attribute ServiceWorker? active; >+ [Unforgeable] readonly attribute ServiceWorker? controller; >+ readonly attribute Promise<ServiceWorker> ready; >+ >+ Promise<sequence<ServiceWorker>?> getAll(); >+ Promise<ServiceWorker> register(DOMString url, optional RegistrationOptionList options); >+ Promise<any> unregister(DOMString? scope); >+ >+ // events >+ attribute EventHandler onupdatefound; >+ attribute EventHandler oncontrollerchange; >+ attribute EventHandler onreloadpage; >+ attribute EventHandler onerror; >+}; >+ >+dictionary RegistrationOptionList { >+ DOMString scope = "/*"; >+}; >+ >+interface ReloadPageEvent : Event { >+ void waitUntil(Promise<any> f); >+}; >+</script> >+ >+<!-- >+[1]: http://goo.gl/I7WAhg >+[2]: http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html >+[3]: http://www.w3.org/TR/workers/#dom-worker-postmessage >+--> >+ >+ >+ <script type=text/plain id="untested_idls"> >+ interface ServiceWorker {}; >+ interface EventHandler {}; >+ interface EventTarget {}; >+ interface Event {}; >+ </script> >+ >+ <script> >+ var idl_array = new IdlArray(); >+ idl_array.add_untested_idls(document.getElementById("untested_idls").textContent); >+ idl_array.add_idls(document.getElementById("idl_0").textContent); >+ idl_array.add_objects({ >+ Navigator: ["throw new Error ('No object defined for the Navigator interface')"], >+ ServiceWorkerContainer: ["throw new Error ('No object defined for the ServiceWorkerContainer interface')"], >+ RegistrationOptionList: ["throw new Error ('No object defined for the RegistrationOptionList dictionary')"], >+ ReloadPageEvent: ["throw new Error ('No object defined for the ReloadPageEvent interface')"] >+ }); >+ idl_array.test(); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.1-navigator-service-worker-installing-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.1-navigator-service-worker-installing-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..6a4d8d20a9ff21035e7c45a9f1a4e2ef3f6103e7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.1-navigator-service-worker-installing-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section installing so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.1-navigator-service-worker-installing.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.1-navigator-service-worker-installing.html >new file mode 100644 >index 0000000000000000000000000000000000000000..59e4f3d6a0d3bfa3c928c921fdcc8f756d314c90 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.1-navigator-service-worker-installing.html >@@ -0,0 +1,43 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: installing</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#navigator-service-worker-installing"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`navigator.serviceWorker.installing` must return a [ServiceWorker][1] object >+representing the [installing worker][2] that is currently undergoing the >+installation process (from step 1 to step 7 of the [_Installation >+algorithm][3]) for the given [URL scope][4] in which the document may be >+[controlled][5] when the Service Worker becomes the [active worker][6]. >+`navigator.serviceWorker.installing` returns `null` if no Service Worker >+[registration][7] is in the [installation process][8]. >+ >+[1]: #service-worker-interface >+[2]: #installing-worker >+[3]: #installation-algorithm >+[4]: #url-scope >+[5]: #document-control >+[6]: #active-worker >+[7]: #service-worker-registration-internal-interface >+[8]: #installation-process >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section installing so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.10-navigator-service-worker-oncontrollerchange-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.10-navigator-service-worker-oncontrollerchange-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..18cbe63c743aa3acc8623abbbb540790532fc46d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.10-navigator-service-worker-oncontrollerchange-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section oncontrollerchange so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.10-navigator-service-worker-oncontrollerchange.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.10-navigator-service-worker-oncontrollerchange.html >new file mode 100644 >index 0000000000000000000000000000000000000000..478860146dcecb174bfb4b59d6c9db8d05315a01 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.10-navigator-service-worker-oncontrollerchange.html >@@ -0,0 +1,45 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: oncontrollerchange</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#navigator-service-worker-oncontrollerchange"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`navigator.serviceWorker.oncontrollerchange` is the [event handler][1] that >+must be supported as attribute by the `[ServiceWorkerContainer][2]` object. A >+`controllerchange` event using the `[Event][3]` interface is dispatched on >+`[ServiceWorkerContainer][2]` object (See step 7 of the [_Activation >+algorithm][4]) when the associated Service Worker [registration][5] for the >+document enters the [activation process][6]. When the [activation process][6] >+is triggered by `replace()` method call within the event handler of the >+`install` event, `navigator.serviceWorker.controller` immediately reflects the >+[active worker][7] as the Service Worker that [controls][8] the document. >+ >+[1]: http://goo.gl/rBfiz0 >+[2]: #service-worker-container-interface >+[3]: http://goo.gl/Mzv7Dv >+[4]: #activation-algorithm >+[5]: #registration >+[6]: #activation-process >+[7]: #active-worker >+[8]: #document-control >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section oncontrollerchange so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.11-navigator-service-worker-onreloadpage-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.11-navigator-service-worker-onreloadpage-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..6640e72dc880391f3e3dc88e088668cac9b0df23 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.11-navigator-service-worker-onreloadpage-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section onreloadpage so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.11-navigator-service-worker-onreloadpage.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.11-navigator-service-worker-onreloadpage.html >new file mode 100644 >index 0000000000000000000000000000000000000000..e2207db100a21a8f8f53c72a2cd8f86ae7f510a1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.11-navigator-service-worker-onreloadpage.html >@@ -0,0 +1,41 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: onreloadpage</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#navigator-service-worker-onreloadpage"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`navigator.serviceWorker.onreloadpage` is the [event handler][1] that must be >+supported as attribute by the `[ServiceWorkerContainer][2]` object. An event >+named `reloadpage` using the `[ReloadPageEvent][3]` interface is dispatched on >+`[ServiceWorkerContainer][2]` object when the page reload is triggered by the >+`[self.clients.reloadAll()][4]` method call from the [active worker][5], >+represented by its associated [ServiceWorkerGlobalScope][6] object, for the >+document. >+ >+[1]: http://goo.gl/rBfiz0 >+[2]: #service-worker-container-interface >+[3]: #reload-page-event-interface >+[4]: #reloadall-method >+[5]: #active-worker >+[6]: #service-worker-global-scope-interface >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section onreloadpage so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.12-navigator-service-worker-onerror-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.12-navigator-service-worker-onerror-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..c74517df266e09225ee949795f882da335476319 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.12-navigator-service-worker-onerror-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section onerror so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.12-navigator-service-worker-onerror.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.12-navigator-service-worker-onerror.html >new file mode 100644 >index 0000000000000000000000000000000000000000..313f0bdfcd500a725bfaf5a59045ec7721f8c674 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.12-navigator-service-worker-onerror.html >@@ -0,0 +1,37 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: onerror</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#navigator-service-worker-onerror"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`navigator.serviceWorker.onerror` is the [event handler][1] that must be >+supported as attribute by the `[ServiceWorkerContainer][2]` object. An event >+named `error` using the `[ErrorEvent][3]` interface is dispatched on >+`[ServiceWorkerContainer][2]` object for any error from the associated >+`[ServiceWorker][4]` objects. >+ >+[1]: http://goo.gl/rBfiz0 >+[2]: #service-worker-container-interface >+[3]: http://goo.gl/FKuWgu >+[4]: #service-worker-interface >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section onerror so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.2-navigator-service-worker-waiting-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.2-navigator-service-worker-waiting-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..45bce087a995171ded2c55374e430c6950b713c9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.2-navigator-service-worker-waiting-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section waiting so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.2-navigator-service-worker-waiting.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.2-navigator-service-worker-waiting.html >new file mode 100644 >index 0000000000000000000000000000000000000000..663ce82f9685858451bea7129106376b054b6fba >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.2-navigator-service-worker-waiting.html >@@ -0,0 +1,34 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: waiting</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#navigator-service-worker-waiting"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`navigator.serviceWorker.waiting` must return a [ServiceWorker][1] object >+representing the waiting Service Worker that is considered the [worker in >+waiting][2] for the document. `navigator.serviceWorker.waiting` returns `null` >+if there is no [worker in waiting][2] for the document. >+ >+[1]: #service-worker-interface >+[2]: #worker-in-waiting >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section waiting so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.3-navigator-service-worker-active-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.3-navigator-service-worker-active-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..ebd1abae969860ac002e2a556c74580ab2d7386f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.3-navigator-service-worker-active-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section active so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.3-navigator-service-worker-active.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.3-navigator-service-worker-active.html >new file mode 100644 >index 0000000000000000000000000000000000000000..f7406f59012fc8e197177e1c37e43d045a1fd70b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.3-navigator-service-worker-active.html >@@ -0,0 +1,40 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: active</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#navigator-service-worker-active"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`navigator.serviceWorker.active` must return a [ServiceWorker][1] object >+representing the [active worker][2] that is currently undergoing or completed >+the activation process (from step 4 to step 9 of the [_Activation >+algorithm][3]) for the given [URL scope][4] in which the document is controlled >+(or to be controlled). `navigator.serviceWorker.active` returns `null` if no >+Service Worker [registration][5] is in the [activation process][6]. >+ >+[1]: #service-worker-interface >+[2]: #active-worker >+[3]: #activation-algorithm >+[4]: #url-scope >+[5]: #service-worker-registration-internal-interface >+[6]: #activation-process >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section active so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.4-navigator-service-worker-controller-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.4-navigator-service-worker-controller-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..970fbe926fef41f6c9ab2e3d4af53318503c2b7f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.4-navigator-service-worker-controller-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section controller so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.4-navigator-service-worker-controller.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.4-navigator-service-worker-controller.html >new file mode 100644 >index 0000000000000000000000000000000000000000..1a26cce6d4edc2c9130f28069e4d9664bf8a6d9d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.4-navigator-service-worker-controller.html >@@ -0,0 +1,37 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: controller</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#navigator-service-worker-controller"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`navigator.serviceWorker.controller` must return a [ServiceWorker][1] object >+representing the [active worker][2] that currently handles resource requests >+for the document. `navigator.serviceWorker.controller` returns `null` if the >+current document was not [created under a Service Worker][3] (See step 6-1 of >+[_OnFetchRequest][3] algorithm) or the request is a force refresh >+(shift+refresh). >+ >+[1]: #service-worker-interface >+[2]: #active-worker >+[3]: #on-fetch-request-algorithm >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section controller so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.5-navigator-service-worker-ready-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.5-navigator-service-worker-ready-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..58f0b73d2fb9c51bce7fce8d1bae171440888c70 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.5-navigator-service-worker-ready-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section ready so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.5-navigator-service-worker-ready.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.5-navigator-service-worker-ready.html >new file mode 100644 >index 0000000000000000000000000000000000000000..67a690ddc5b2d40c1c21a0bf021a49fbddb0c760 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.5-navigator-service-worker-ready.html >@@ -0,0 +1,67 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: ready</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#navigator-service-worker-ready"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`navigator.serviceWorker.ready` attribute must return the result of running >+these steps: >+ >+1. Let `promise` be a newly-created [promise][1]. >+2. Return `promise`. >+3. Run the following steps asynchronously: >+ 1. Let `registration` be the result of running [_ScopeMatch >+ algorithm][2] with document's url as its argument. >+ 2. If `registration` is null, then: >+ 1. Wait for the document to have a matching [registration][3]. >+ 3. If the [registration][3], represented by `registration`, for the >+ document has an [active worker][4], then: >+ 1. Resolve `promise` with the [ServiceWorker][5] object associated >+ with the [active worker][4]. >+ 2. Abort these steps. >+ 4. If the [registration][3], represented by `registration`, for the >+ document has a [worker in waiting][6], then: >+ 1. Resolve `promise` with the [ServiceWorker][5] object associated >+ with the [worker in waiting][6]. >+ 2. Abort these steps. >+ 5. Wait until the [registration][3], represented by `registration`, >+ for the document acquires a [worker in waiting][6] through a new >+ [installation process][7]. >+ 6. Resolve `promise` with the [ServiceWorker][5] object associated >+ with the [worker in waiting][6]. >+Note that `ready` attribute is desinged in a way that the returned [promise][1] >+will never reject. Instead, it waits until the [promise][1] resolves with a >+newly installed [worker in waiting][6]. Hence, the `state` of the acquired >+[`ServiceWorker`][8] object is either `installed`, `activating` or `activated`. >+ >+ >+ >+[1]: http://goo.gl/3TobQS >+[2]: #scope-match-algorithm >+[3]: #registration >+[4]: #active-worker >+[5]: #service-worker-interface >+[6]: #worker-in-waiting >+[7]: #installation-process >+[8]: #service-worker >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section ready so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.6-navigator-service-worker-getAll-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.6-navigator-service-worker-getAll-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..008c23e8e24fe207e0867da7ed0e3d026e3ce9f0 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.6-navigator-service-worker-getAll-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section getAll() so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.6-navigator-service-worker-getAll.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.6-navigator-service-worker-getAll.html >new file mode 100644 >index 0000000000000000000000000000000000000000..3c2afe99cbb492554522912c265f243902f74134 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.6-navigator-service-worker-getAll.html >@@ -0,0 +1,30 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: getAll()</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#navigator-service-worker-getAll"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`navigator.serviceWorker.getAll()` method must return a promise that resolves >+with the array of the ServiceWorker objects in `installing`, `installed`, >+`activating` and `activated` states. >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section getAll() so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.7-navigator-service-worker-register-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.7-navigator-service-worker-register-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..6ded38b1a3982823a0a77d6e524a0eeebe7a31ab >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.7-navigator-service-worker-register-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section register() so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.7-navigator-service-worker-register.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.7-navigator-service-worker-register.html >new file mode 100644 >index 0000000000000000000000000000000000000000..df469de42af5ea5868de91df77164dbf5af28a3e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.7-navigator-service-worker-register.html >@@ -0,0 +1,32 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: register()</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#navigator-service-worker-register"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`navigator.serviceWorker.register(url, options)` method must run the >+[Registration algorithm][1] passing `url` and `options`.`scope` as the >+arguments. >+ >+[1]: #registration-algorithm >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section register() so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.8-navigator-service-worker-unregister-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.8-navigator-service-worker-unregister-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..581e5e6638f0102938f07350c83c8f6a220e22db >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.8-navigator-service-worker-unregister-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section unregister() so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.8-navigator-service-worker-unregister.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.8-navigator-service-worker-unregister.html >new file mode 100644 >index 0000000000000000000000000000000000000000..6f1b43b6bdee80d5da06b4f3786f068c8a7648f9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.8-navigator-service-worker-unregister.html >@@ -0,0 +1,31 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: unregister()</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#navigator-service-worker-unregister"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`navigator.serviceWorker.unregister(scope)` method must run the [Unregistration >+algorithm][1] passing `scope` as the argument. >+ >+[1]: #unregistration-algorithm >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section unregister() so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.9-navigator-service-worker-onupdatefound-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.9-navigator-service-worker-onupdatefound-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..1db9ccbdad60b506fb08cbcfdb423efa8c244b74 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.9-navigator-service-worker-onupdatefound-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section onupdatefound so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.9-navigator-service-worker-onupdatefound.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.9-navigator-service-worker-onupdatefound.html >new file mode 100644 >index 0000000000000000000000000000000000000000..7babe7c245681870c3559baca65d976aaa437723 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-3.2.9-navigator-service-worker-onupdatefound.html >@@ -0,0 +1,42 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: onupdatefound</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#navigator-service-worker-onupdatefound"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`navigator.serviceWorker.onupdatefound` is the [event handler][1] that must be >+supported as attribute by the `[ServiceWorkerContainer][2]` object. An >+`updatefound` event using the `[Event][3]` interface is dispatched on >+`[ServiceWorkerContainer][2]` object (See step 4 of the [_Installation >+algorithm][4]) when the associated Service Worker [registration][5] for the >+document enters the [installation process][6] such that >+`navigator.serviceWorker.installing` becomes the new [installing worker][7]. >+ >+[1]: http://goo.gl/rBfiz0 >+[2]: #service-worker-container-interface >+[3]: http://goo.gl/Mzv7Dv >+[4]: #installation-algorithm >+[5]: #registration >+[6]: #installation-process >+[7]: #installing-worker >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section onupdatefound so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1-service-worker-global-scope-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1-service-worker-global-scope-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..174f532d674f16ac9fe8d93e8c375b2669919ab4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1-service-worker-global-scope-expected.txt >@@ -0,0 +1,9 @@ >+CONSOLE MESSAGE: line 1699: TypeError: undefined is not an object (evaluating 'self[this.name].prototype') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'self[this.name].prototype') >+ >+FAIL ServiceWorkerGlobalScope interface: existence and properties of interface object assert_own_property: self does not have own property "ServiceWorkerGlobalScope" expected property "ServiceWorkerGlobalScope" missing >+FAIL ServiceWorkerGlobalScope interface object length assert_own_property: self does not have own property "ServiceWorkerGlobalScope" expected property "ServiceWorkerGlobalScope" missing >+FAIL ServiceWorkerGlobalScope interface object name assert_own_property: self does not have own property "ServiceWorkerGlobalScope" expected property "ServiceWorkerGlobalScope" missing >+FAIL ServiceWorkerGlobalScope interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ServiceWorkerGlobalScope" expected property "ServiceWorkerGlobalScope" missing >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1-service-worker-global-scope.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1-service-worker-global-scope.html >new file mode 100644 >index 0000000000000000000000000000000000000000..c11feaca4c832bb90562868a6d78d4ac0ee017fc >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1-service-worker-global-scope.html >@@ -0,0 +1,75 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: ServiceWorkerGlobalScope</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#service-worker-global-scope"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ <script src=/resources/WebIDLParser.js></script> >+ <script src=/resources/idlharness.js></script> >+ >+ </head> >+ <body> >+ >+<script type=text/plain id="idl_0"> >+[Global] >+interface ServiceWorkerGlobalScope : WorkerGlobalScope { >+ readonly attribute CacheStorage caches; >+ // A container for a list of window objects, identifiable by ID, that >+ // correspond to windows (or workers) that are "controlled" by this SW >+ readonly attribute ServiceWorkerClients clients; >+ [Unforgeable] readonly attribute DOMString scope; >+ >+ Promise<any> fetch((Request or ScalarValueString) request); >+ >+ void update(); >+ void unregister(); >+ >+ attribute EventHandler oninstall; >+ attribute EventHandler onactivate; >+ attribute EventHandler onfetch; >+ attribute EventHandler onbeforeevicted; >+ attribute EventHandler onevicted; >+ >+ // The event.source of these MessageEvents are instances of Client >+ attribute EventHandler onmessage; >+ >+ // close() method inherited from WorkerGlobalScope is not exposed. >+}; >+</script> >+ >+<!-- >+The `ServiceWorkerGlobalScope` interface represents the global execution >+context of a Service Worker. `ServiceWorkerGlobalScope` object provides >+generic, event-driven, time-limited script execution contexts that run at an >+origin. Once successfully [registered][1], a Service Worker is started, kept >+alive and killed by their relationship to events, not documents. Any type of >+synchronous requests MUST NOT be initiated inside of a Service Worker. >+ >+[1]: #navigator-service-worker-register >+--> >+ >+ >+ <script type=text/plain id="untested_idls"> >+ interface CacheStorage {}; >+ interface ServiceWorkerClients {}; >+ interface Request {}; >+ interface ScalarValueString {}; >+ interface EventHandler {}; >+ interface WorkerGlobalScope {}; >+ </script> >+ >+ <script> >+ var idl_array = new IdlArray(); >+ idl_array.add_untested_idls(document.getElementById("untested_idls").textContent); >+ idl_array.add_idls(document.getElementById("idl_0").textContent); >+ idl_array.add_objects({ >+ ServiceWorkerGlobalScope: ["throw new Error ('No object defined for the ServiceWorkerGlobalScope interface')"] >+ }); >+ idl_array.test(); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.1-service-worker-global-scope-caches-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.1-service-worker-global-scope-caches-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..337bd358baf4b38e0ee453505f9c029cb0467622 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.1-service-worker-global-scope-caches-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section caches so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.1-service-worker-global-scope-caches.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.1-service-worker-global-scope-caches.html >new file mode 100644 >index 0000000000000000000000000000000000000000..f1fce5036a100e4e0fa324d647502a67e5d00a2b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.1-service-worker-global-scope-caches.html >@@ -0,0 +1,36 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: caches</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#service-worker-global-scope-caches"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`self.caches` must return the `[CacheStorage][1]` object that is the global >+asynchronous map object for the `[ServiceWorkerGlobalScope][2]` execution >+context containing the cache objects keyed by the name of the caches. Caches >+are always enumerable via `self.caches` in insertion order (per [ECMAScript 6 >+Map objects][3].) >+ >+[1]: #cache-storage-interface >+[2]: #service-worker-global-scope-interface >+[3]: http://goo.gl/gNnDPO >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section caches so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.2-service-worker-global-scope-clients-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.2-service-worker-global-scope-clients-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..f2660a26e23943f43b096257e16a376628bd6e79 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.2-service-worker-global-scope-clients-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section clients so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.2-service-worker-global-scope-clients.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.2-service-worker-global-scope-clients.html >new file mode 100644 >index 0000000000000000000000000000000000000000..cd5d28353a29634d75ed951316d740989582c98b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.2-service-worker-global-scope-clients.html >@@ -0,0 +1,33 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: clients</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#service-worker-global-scope-clients"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`self.clients` must return the `[ServiceWorkerClients][1]` object containing a >+list of client objects, identifiable by ID, that correspond to windows or >+workers that are [controlled][2] by this Service Worker. >+ >+[1]: #service-worker-clients-interface >+[2]: #document-control >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section clients so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.3-service-worker-global-scope-scope-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.3-service-worker-global-scope-scope-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..1101e195972a92286379a9fbd4bdfd4cd788e0fc >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.3-service-worker-global-scope-scope-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section scope so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.3-service-worker-global-scope-scope.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.3-service-worker-global-scope-scope.html >new file mode 100644 >index 0000000000000000000000000000000000000000..7b6ce78fa909730fe80c4b8c6c93825962d23ba7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.3-service-worker-global-scope-scope.html >@@ -0,0 +1,36 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: scope</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#service-worker-global-scope-scope"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+The `scope` attribute of a [ServiceWorkerGlobalScope][1] object reflects the >+[URL scope][2] of the associated Service Worker [registration][3]. The `scope` >+attribute must return the [serialization][4] of the URL representing the [URL >+scope][2] of the associated Service Worker [registration][3]. >+ >+[1]: #service-worker-global-scope-interface >+[2]: #url-scope >+[3]: #registration >+[4]: http://url.spec.whatwg.org/#concept-url-serializer >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section scope so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.4-service-worker-global-scope-fetch-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.4-service-worker-global-scope-fetch-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..04e834141fdaea6a737fa9d3ebdcbcf0cf978109 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.4-service-worker-global-scope-fetch-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section fetch(request) so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.4-service-worker-global-scope-fetch.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.4-service-worker-global-scope-fetch.html >new file mode 100644 >index 0000000000000000000000000000000000000000..98345471f3b8f708850d019e897f7baf277cf793 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.4-service-worker-global-scope-fetch.html >@@ -0,0 +1,55 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: fetch(request)</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#service-worker-global-scope-fetch"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`self.fetch(request)` method must run these steps: >+ >+1. Let `request` be a [request][1] represented by `request`. >+2. Set [`client`][2] of `request` to the [JavaScript global >+ environment][3] represented by `self` object. >+3. Let `promise` be a newly-created [promise][4]. >+4. Return `promise.` >+5. Run the following steps asynchronously: >+ 1. Let `response` be the result of running [fetch algorithm][5] with >+ `request` as its argument. >+ 2. If `response` is a [network error][6], then: >+ 1. Reject `promise` with a new [DOMException][7] whose name is >+ "[NetworkError][8]". >+ 3. Else, >+ 1. Resolve `promise` with a new [Response][9] object associated >+ with `response`. >+ >+ >+ >+[1]: http://goo.gl/ucOuXl >+[2]: http://goo.gl/Oxj4xQ >+[3]: http://goo.gl/ifwwCC >+[4]: http://goo.gl/3TobQS >+[5]: http://goo.gl/fGMifs >+[6]: http://goo.gl/jprjjc >+[7]: http://goo.gl/A0U8qC >+[8]: http://goo.gl/lud5HB >+[9]: http://goo.gl/Deazjv >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section fetch(request) so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.5-service-worker-global-scope-update-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.5-service-worker-global-scope-update-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..363963b9a4b778cc25fa375d429afcc14dde9573 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.5-service-worker-global-scope-update-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section update() so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.5-service-worker-global-scope-update.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.5-service-worker-global-scope-update.html >new file mode 100644 >index 0000000000000000000000000000000000000000..26e255dd4a0209f9492bfd327183f6915359ca36 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.5-service-worker-global-scope-update.html >@@ -0,0 +1,36 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: update()</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#service-worker-global-scope-update"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`update()` pings the server for an updated version of this script without >+consulting caches. `self.update()` method must run the [_SoftUpdate >+algorithm][1] passing its serviceWorkerRegistration object as the argument >+which is the result of running the [_GetRegistration algorithm][2] with >+`self.scope` as the argument. (This is conceptually the same operation that UA >+does maximum once per every 24 hours.) >+ >+[1]: #soft-update-algorithm >+[2]: #get-registration-algorithm >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section update() so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.6-service-worker-global-scope-unregister-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.6-service-worker-global-scope-unregister-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..581e5e6638f0102938f07350c83c8f6a220e22db >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.6-service-worker-global-scope-unregister-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section unregister() so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.6-service-worker-global-scope-unregister.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.6-service-worker-global-scope-unregister.html >new file mode 100644 >index 0000000000000000000000000000000000000000..de1d64a6e45c45480a7eab230ddb33ba7f006444 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.6-service-worker-global-scope-unregister.html >@@ -0,0 +1,31 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: unregister()</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#service-worker-global-scope-unregister"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`self.unregister()` method must run the [Unregistration algorithm][1] >+implicitly passing `self.scope` as the argument. >+ >+[1]: #unregistration-algorithm >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section unregister() so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.7-service-worker-global-scope-onmessage-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.7-service-worker-global-scope-onmessage-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..da7648b5619c70c6ad28eeae9d5e93ff81b3e6a6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.7-service-worker-global-scope-onmessage-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section onmessage so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.7-service-worker-global-scope-onmessage.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.7-service-worker-global-scope-onmessage.html >new file mode 100644 >index 0000000000000000000000000000000000000000..b930439486efab516cd33807064d907a535fafde >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.1.7-service-worker-global-scope-onmessage.html >@@ -0,0 +1,45 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: onmessage</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#service-worker-global-scope-onmessage"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`self.onmessage` is the [event handler][1] that must be supported as attribute >+by the `ServiceWorkerGlobalScope` object. `ServiceWorkerGlobalScope` objects >+act as if they had an implicit `[MessagePort][2]` associated with them. This >+port is part of a channel that is set up when the worker is created, but it is >+not exposed. This object must never be garbage collected before the >+`ServiceWorkerGlobalScope` object. >+ >+All messages received by that port must immediately be retargeted at the >+`ServiceWorkerGlobalScope` object. That is, an event named `message` using the >+`[MessageEvent][3]` interface is dispatched on ServiceWorkerGlobalScope object. >+The `event.source` of these `[MessageEvent][3]`s are instances of `[Client][4]`. >+ >+ >+ >+[1]: http://goo.gl/rBfiz0 >+[2]: http://goo.gl/tHBrI6 >+[3]: http://goo.gl/S5e0b6 >+[4]: #client-interface >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section onmessage so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.2-client-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.2-client-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..00d12959c71458ac7db726a34b5cb36d42c3628b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.2-client-expected.txt >@@ -0,0 +1,17 @@ >+ >+FAIL Client interface: existence and properties of interface object assert_own_property: self does not have own property "Client" expected property "Client" missing >+FAIL Client interface object length assert_own_property: self does not have own property "Client" expected property "Client" missing >+FAIL Client interface object name assert_own_property: self does not have own property "Client" expected property "Client" missing >+FAIL Client interface: existence and properties of interface prototype object assert_own_property: self does not have own property "Client" expected property "Client" missing >+FAIL Client interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "Client" expected property "Client" missing >+FAIL Client interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "Client" expected property "Client" missing >+FAIL Client interface: attribute id assert_own_property: self does not have own property "Client" expected property "Client" missing >+PASS Unscopable handled correctly for id property on Client >+FAIL Client interface: operation postMessage(any, DOMString, [object Object]) assert_own_property: self does not have own property "Client" expected property "Client" missing >+PASS Unscopable handled correctly for postMessage(any, DOMString, [object Object]) on Client >+FAIL Client must be primary interface of throw new Error ('No object defined for the Client interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Client interface" >+FAIL Stringification of throw new Error ('No object defined for the Client interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Client interface" >+FAIL Client interface: throw new Error ('No object defined for the Client interface') must inherit property "id" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Client interface" >+FAIL Client interface: throw new Error ('No object defined for the Client interface') must inherit property "postMessage(any, DOMString, [object Object])" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Client interface" >+FAIL Client interface: calling postMessage(any, DOMString, [object Object]) on throw new Error ('No object defined for the Client interface') with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Client interface" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.2-client.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.2-client.html >new file mode 100644 >index 0000000000000000000000000000000000000000..fda0e298f5e7f1c55a619e3858682d850844b5ef >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.2-client.html >@@ -0,0 +1,61 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: Client</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#client"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ <script src=/resources/WebIDLParser.js></script> >+ <script src=/resources/idlharness.js></script> >+ >+ </head> >+ <body> >+ >+<script type=text/plain id="idl_0"> >+[Constructor()] // no-op constructor >+interface Client { >+ readonly attribute unsigned long id; >+ void postMessage(any message, DOMString targetOrigin, >+ optional sequence<Transferable> transfer); >+}; >+</script> >+ >+<!-- >+The `Client` interface represents the window or the worker (defined as client) >+that is [controlled][1] by the Service Worker. This object provides a no-op >+constructor. Callers should note that only `Client` objects created by the user >+agent (see [`this.clients.getServiced()`][2]) will provide meaningful >+functionality. >+ >+The `id` of a `Client` identifies the specific client object from the list of >+client objects serviced by the Service Worker. The `postMessage(message, >+targetOrigin, transfer)` method of a `[Client][3]`, when called, causes a >+`[MessageEvent][4]` to be dispatched at the client object. >+ >+ >+ >+[1]: #document-control >+[2]: #get-serviced-method >+[3]: #client-interface >+[4]: http://goo.gl/4SLWiH >+--> >+ >+ >+ <script type=text/plain id="untested_idls"> >+ interface Transferable {}; >+ </script> >+ >+ <script> >+ var idl_array = new IdlArray(); >+ idl_array.add_untested_idls(document.getElementById("untested_idls").textContent); >+ idl_array.add_idls(document.getElementById("idl_0").textContent); >+ idl_array.add_objects({ >+ Client: ["throw new Error ('No object defined for the Client interface')"] >+ }); >+ idl_array.test(); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.3-service-worker-clients-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.3-service-worker-clients-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..5a05ff40dacfd445e544432346033802d3cb2d4c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.3-service-worker-clients-expected.txt >@@ -0,0 +1,16 @@ >+ >+FAIL ServiceWorkerClients interface: existence and properties of interface object assert_own_property: self does not have own property "ServiceWorkerClients" expected property "ServiceWorkerClients" missing >+FAIL ServiceWorkerClients interface object length assert_own_property: self does not have own property "ServiceWorkerClients" expected property "ServiceWorkerClients" missing >+FAIL ServiceWorkerClients interface object name assert_own_property: self does not have own property "ServiceWorkerClients" expected property "ServiceWorkerClients" missing >+FAIL ServiceWorkerClients interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ServiceWorkerClients" expected property "ServiceWorkerClients" missing >+FAIL ServiceWorkerClients interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ServiceWorkerClients" expected property "ServiceWorkerClients" missing >+FAIL ServiceWorkerClients interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ServiceWorkerClients" expected property "ServiceWorkerClients" missing >+FAIL ServiceWorkerClients interface: operation getServiced() assert_own_property: self does not have own property "ServiceWorkerClients" expected property "ServiceWorkerClients" missing >+PASS Unscopable handled correctly for getServiced() on ServiceWorkerClients >+FAIL ServiceWorkerClients interface: operation reloadAll() assert_own_property: self does not have own property "ServiceWorkerClients" expected property "ServiceWorkerClients" missing >+PASS Unscopable handled correctly for reloadAll() on ServiceWorkerClients >+FAIL ServiceWorkerClients must be primary interface of throw new Error ('No object defined for the ServiceWorkerClients interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the ServiceWorkerClients interface" >+FAIL Stringification of throw new Error ('No object defined for the ServiceWorkerClients interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the ServiceWorkerClients interface" >+FAIL ServiceWorkerClients interface: throw new Error ('No object defined for the ServiceWorkerClients interface') must inherit property "getServiced()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the ServiceWorkerClients interface" >+FAIL ServiceWorkerClients interface: throw new Error ('No object defined for the ServiceWorkerClients interface') must inherit property "reloadAll()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the ServiceWorkerClients interface" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.3-service-worker-clients.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.3-service-worker-clients.html >new file mode 100644 >index 0000000000000000000000000000000000000000..475df1952fba671b5a4f8a3b3a05d8dcc39c4f6c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.3-service-worker-clients.html >@@ -0,0 +1,48 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: ServiceWorkerClients</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#service-worker-clients"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ <script src=/resources/WebIDLParser.js></script> >+ <script src=/resources/idlharness.js></script> >+ >+ </head> >+ <body> >+ >+<script type=text/plain id="idl_0"> >+interface ServiceWorkerClients { >+ // A list of client objects, identifiable by ID, that correspond to windows >+ // (or workers) that are "controlled" by this SW >+ Promise<sequence<Client>?> getServiced(); >+ Promise<any> reloadAll(); >+}; >+</script> >+ >+<!-- >+The `ServiceWorkerClients` interface represents a container for a list of >+`[Client][1]` objects. >+ >+[1]: #client-interface >+--> >+ >+ >+ <script type=text/plain id="untested_idls"> >+ interface Client {}; >+ </script> >+ >+ <script> >+ var idl_array = new IdlArray(); >+ idl_array.add_untested_idls(document.getElementById("untested_idls").textContent); >+ idl_array.add_idls(document.getElementById("idl_0").textContent); >+ idl_array.add_objects({ >+ ServiceWorkerClients: ["throw new Error ('No object defined for the ServiceWorkerClients interface')"] >+ }); >+ idl_array.test(); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.3.1-get-serviced-method-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.3.1-get-serviced-method-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..ffc41b03551f39b693b10887292a366d4db15184 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.3.1-get-serviced-method-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section getServiced() so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.3.1-get-serviced-method.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.3.1-get-serviced-method.html >new file mode 100644 >index 0000000000000000000000000000000000000000..b3cd06fdf278f4f4d6a87b3bf97648f0e52528a1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.3.1-get-serviced-method.html >@@ -0,0 +1,34 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: getServiced()</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#get-serviced-method"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+The `getServiced()` method of a `ServiceWorkerClients`, when called, returns a >+[Promise][1] that will resolve with a list of `[Client][2]` objects that are >+[controlled][3] by this Service Worker. >+ >+[1]: http://goo.gl/3TobQS >+[2]: #client-interface >+[3]: #document-control >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section getServiced() so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.3.2-reloadall-method-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.3.2-reloadall-method-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..9477d2c968850ccd4455f5cdef4460c979b30db5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.3.2-reloadall-method-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section reloadAll() so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.3.2-reloadall-method.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.3.2-reloadall-method.html >new file mode 100644 >index 0000000000000000000000000000000000000000..c5a9dd45404a52c8175967e340ae04095964c127 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.3.2-reloadall-method.html >@@ -0,0 +1,37 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: reloadAll()</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#reloadall-method"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`reloadAll()` provides a mechanism for the worker to request synchronized >+re-fetch of all documents whose URLs match the registration's [URL scope][1]. >+An event named `reloadpage` is dispatched on the `navigator.serviceWorker` >+object of each document. The in-document handlers may allow the event to >+continue, request an extension (via [`e.waitUntil()`][2]), or cancel the >+collective reload by calling [`e.preventDefault()`][3]. >+ >+[1]: #url-scope >+[2]: #wait-until-method >+[3]: http://goo.gl/2zH6ie >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section reloadAll() so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.4-request-objects-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.4-request-objects-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..65346d7c56620a26412bcf3cb7dc52f4502ae97e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.4-request-objects-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 59: TypeError: null is not an object (evaluating 'document.getElementById("untested_idls").textContent') >+ >+FAIL Service Workers: Request Objects TypeError: null is not an object (evaluating 'document.getElementById("untested_idls").textContent') >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.4-request-objects.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.4-request-objects.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2f471f80f6074a6a6ce27dde1d88199eb01d8bff >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.4-request-objects.html >@@ -0,0 +1,72 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: Request Objects</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#request-objects"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ <script src=/resources/WebIDLParser.js></script> >+ <script src=/resources/idlharness.js></script> >+ >+ </head> >+ <body> >+ >+<script type=text/plain id="idl_0"> >+[Constructor(optional RequestInit init)] >+interface Request { >+ attribute unsigned long timeout; >+ attribute DOMString url; >+ attribute ByteString method; >+ readonly attribute DOMString origin; >+ readonly attribute Mode mode; >+ attribute boolean synchronous; >+ attribute boolean forcePreflight; >+ attribute boolean omitCredentials; >+ readonly attribute DOMString referrer; >+ readonly attribute HeaderMap headers; // alternative: sequence<Header> headers; >+ attribute any body; >+}; >+ >+dictionary RequestInit { >+ unsigned long timeout = 0; >+ DOMString url; >+ boolean synchronous = false; >+ boolean forcePreflight = false; >+ boolean omitCredentials = false; >+ ByteString method = "GET"; >+ HeaderMap headers; >+ any body; >+}; >+ >+enum Mode { >+ "same origin", >+ "tainted cross-origin", >+ "CORS", >+ "CORS-with-forced-preflight" >+}; >+ >+[MapClass(DOMString, DOMString)] >+interface HeaderMap { >+}; >+</script> >+ >+ >+ >+ >+ <script> >+ var idl_array = new IdlArray(); >+ idl_array.add_untested_idls(document.getElementById("untested_idls").textContent); >+ idl_array.add_idls(document.getElementById("idl_0").textContent); >+ idl_array.add_objects({ >+ Request: ["throw new Error ('No object defined for the Request interface')"], >+ RequestInit: ["throw new Error ('No object defined for the RequestInit dictionary')"], >+ Mode: ["throw new Error ('No object defined for the Mode enum')"], >+ HeaderMap: ["throw new Error ('No object defined for the HeaderMap interface')"] >+ }); >+ idl_array.test(); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.5-response-objects-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.5-response-objects-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..93bf196d1a943f646b407234ba9038a720de412c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.5-response-objects-expected.txt >@@ -0,0 +1,72 @@ >+CONSOLE MESSAGE: line 830: TypeError: this.members[name].test_object is not a function. (In 'this.members[name].test_object(str)', 'this.members[name].test_object' is undefined) >+ >+Harness Error (FAIL), message = TypeError: this.members[name].test_object is not a function. (In 'this.members[name].test_object(str)', 'this.members[name].test_object' is undefined) >+ >+FAIL AbstractResponse interface: existence and properties of interface object assert_own_property: self does not have own property "AbstractResponse" expected property "AbstractResponse" missing >+FAIL AbstractResponse interface object length assert_own_property: self does not have own property "AbstractResponse" expected property "AbstractResponse" missing >+FAIL AbstractResponse interface object name assert_own_property: self does not have own property "AbstractResponse" expected property "AbstractResponse" missing >+FAIL AbstractResponse interface: existence and properties of interface prototype object assert_own_property: self does not have own property "AbstractResponse" expected property "AbstractResponse" missing >+FAIL AbstractResponse interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "AbstractResponse" expected property "AbstractResponse" missing >+FAIL AbstractResponse interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "AbstractResponse" expected property "AbstractResponse" missing >+FAIL AbstractResponse must be primary interface of throw new Error ('No object defined for the AbstractResponse interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the AbstractResponse interface" >+FAIL Stringification of throw new Error ('No object defined for the AbstractResponse interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the AbstractResponse interface" >+FAIL OpaqueResponse interface: existence and properties of interface object assert_own_property: self does not have own property "OpaqueResponse" expected property "OpaqueResponse" missing >+FAIL OpaqueResponse interface object length assert_own_property: self does not have own property "OpaqueResponse" expected property "OpaqueResponse" missing >+FAIL OpaqueResponse interface object name assert_own_property: self does not have own property "OpaqueResponse" expected property "OpaqueResponse" missing >+FAIL OpaqueResponse interface: existence and properties of interface prototype object assert_own_property: self does not have own property "OpaqueResponse" expected property "OpaqueResponse" missing >+FAIL OpaqueResponse interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "OpaqueResponse" expected property "OpaqueResponse" missing >+FAIL OpaqueResponse interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "OpaqueResponse" expected property "OpaqueResponse" missing >+FAIL OpaqueResponse interface: attribute status assert_own_property: self does not have own property "OpaqueResponse" expected property "OpaqueResponse" missing >+PASS Unscopable handled correctly for status property on OpaqueResponse >+FAIL OpaqueResponse interface: attribute statusText assert_own_property: self does not have own property "OpaqueResponse" expected property "OpaqueResponse" missing >+PASS Unscopable handled correctly for statusText property on OpaqueResponse >+FAIL OpaqueResponse interface: attribute headers assert_own_property: self does not have own property "OpaqueResponse" expected property "OpaqueResponse" missing >+PASS Unscopable handled correctly for headers property on OpaqueResponse >+FAIL OpaqueResponse interface: attribute url assert_own_property: self does not have own property "OpaqueResponse" expected property "OpaqueResponse" missing >+PASS Unscopable handled correctly for url property on OpaqueResponse >+FAIL OpaqueResponse must be primary interface of throw new Error ('No object defined for the OpaqueResponse interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the OpaqueResponse interface" >+FAIL Stringification of throw new Error ('No object defined for the OpaqueResponse interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the OpaqueResponse interface" >+FAIL OpaqueResponse interface: throw new Error ('No object defined for the OpaqueResponse interface') must inherit property "status" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the OpaqueResponse interface" >+FAIL OpaqueResponse interface: throw new Error ('No object defined for the OpaqueResponse interface') must inherit property "statusText" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the OpaqueResponse interface" >+FAIL OpaqueResponse interface: throw new Error ('No object defined for the OpaqueResponse interface') must inherit property "headers" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the OpaqueResponse interface" >+FAIL OpaqueResponse interface: throw new Error ('No object defined for the OpaqueResponse interface') must inherit property "url" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the OpaqueResponse interface" >+FAIL CORSResponse interface: existence and properties of interface object assert_own_property: self does not have own property "CORSResponse" expected property "CORSResponse" missing >+FAIL CORSResponse interface object length assert_own_property: self does not have own property "CORSResponse" expected property "CORSResponse" missing >+FAIL CORSResponse interface object name assert_own_property: self does not have own property "CORSResponse" expected property "CORSResponse" missing >+FAIL CORSResponse interface: existence and properties of interface prototype object assert_own_property: self does not have own property "CORSResponse" expected property "CORSResponse" missing >+FAIL CORSResponse interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "CORSResponse" expected property "CORSResponse" missing >+FAIL CORSResponse interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "CORSResponse" expected property "CORSResponse" missing >+FAIL CORSResponse interface: attribute headers assert_own_property: self does not have own property "CORSResponse" expected property "CORSResponse" missing >+PASS Unscopable handled correctly for headers property on CORSResponse >+FAIL CORSResponse must be primary interface of throw new Error ('No object defined for the CORSResponse interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CORSResponse interface" >+FAIL Stringification of throw new Error ('No object defined for the CORSResponse interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CORSResponse interface" >+FAIL CORSResponse interface: throw new Error ('No object defined for the CORSResponse interface') must inherit property "headers" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CORSResponse interface" >+FAIL Response interface: throw new Error ('No object defined for the CORSResponse interface') must inherit property "status" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CORSResponse interface" >+FAIL Response interface: throw new Error ('No object defined for the CORSResponse interface') must inherit property "statusText" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CORSResponse interface" >+FAIL Response interface: throw new Error ('No object defined for the CORSResponse interface') must inherit property "headers" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CORSResponse interface" >+FAIL Response interface: throw new Error ('No object defined for the CORSResponse interface') must inherit property "url" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CORSResponse interface" >+FAIL Response interface: throw new Error ('No object defined for the CORSResponse interface') must inherit property "toBlob()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CORSResponse interface" >+FAIL Response interface: existence and properties of interface object assert_own_property: should inherit from AbstractResponse, but self has no such property expected property "AbstractResponse" missing >+PASS Response interface object length >+PASS Response interface object name >+FAIL Response interface: existence and properties of interface prototype object assert_own_property: should inherit from AbstractResponse, but self has no such property expected property "AbstractResponse" missing >+PASS Response interface: existence and properties of interface prototype object's "constructor" property >+PASS Response interface: existence and properties of interface prototype object's @@unscopables property >+FAIL Response interface: attribute status assert_equals: setter must be function for PutForwards, Replaceable, or non-readonly attributes expected "function" but got "undefined" >+PASS Unscopable handled correctly for status property on Response >+FAIL Response interface: attribute statusText assert_equals: setter must be function for PutForwards, Replaceable, or non-readonly attributes expected "function" but got "undefined" >+PASS Unscopable handled correctly for statusText property on Response >+PASS Response interface: attribute headers >+PASS Unscopable handled correctly for headers property on Response >+FAIL Response interface: attribute url assert_equals: setter must be function for PutForwards, Replaceable, or non-readonly attributes expected "function" but got "undefined" >+PASS Unscopable handled correctly for url property on Response >+FAIL Response interface: operation toBlob() assert_own_property: interface prototype object missing non-static operation expected property "toBlob" missing >+PASS Unscopable handled correctly for toBlob() on Response >+FAIL Response must be primary interface of throw new Error ('No object defined for the Response interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Response interface" >+FAIL Stringification of throw new Error ('No object defined for the Response interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Response interface" >+FAIL Response interface: throw new Error ('No object defined for the Response interface') must inherit property "status" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Response interface" >+FAIL Response interface: throw new Error ('No object defined for the Response interface') must inherit property "statusText" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Response interface" >+FAIL Response interface: throw new Error ('No object defined for the Response interface') must inherit property "headers" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Response interface" >+FAIL Response interface: throw new Error ('No object defined for the Response interface') must inherit property "url" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Response interface" >+FAIL Response interface: throw new Error ('No object defined for the Response interface') must inherit property "toBlob()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Response interface" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.5-response-objects.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.5-response-objects.html >new file mode 100644 >index 0000000000000000000000000000000000000000..445982f51a3ab083ddb579d96f104452c149af51 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.5-response-objects.html >@@ -0,0 +1,75 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: Response Objects</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#response-objects"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ <script src=/resources/WebIDLParser.js></script> >+ <script src=/resources/idlharness.js></script> >+ >+ </head> >+ <body> >+ >+<!-- >+`Response` objects model HTTP responses. >+--> >+<script type=text/plain id="idl_0"> >+[Constructor] >+interface AbstractResponse { >+}; >+ >+interface OpaqueResponse : AbstractResponse { >+ readonly attribute unsigned short status; >+ readonly attribute ByteString statusText; >+ // Returns a filtered list of headers. See prose for details. >+ readonly attribute HeaderMap headers; >+ // No setter for headers >+ readonly attribute DOMString url; >+}; >+ >+interface CORSResponse : Response { >+ readonly attribute HeaderMap headers; >+}; >+ >+[Constructor(optional ResponseInit responseInitDict)] >+interface Response : AbstractResponse { >+ attribute unsigned short status; >+ attribute ByteString statusText; >+ readonly attribute HeaderMap headers; >+ attribute DOMString url; >+ Promise<Blob> toBlob(); >+}; >+ >+dictionary ResponseInit { >+ unsigned short status = 200; >+ ByteString statusText = "OK"; >+ HeaderMap headers; >+}; >+</script> >+ >+ >+ >+ <script type=text/plain id="untested_idls"> >+ interface HeaderMap {}; >+ interface Blob {}; >+ </script> >+ >+ <script> >+ var idl_array = new IdlArray(); >+ idl_array.add_untested_idls(document.getElementById("untested_idls").textContent); >+ idl_array.add_idls(document.getElementById("idl_0").textContent); >+ idl_array.add_objects({ >+ AbstractResponse: ["throw new Error ('No object defined for the AbstractResponse interface')"], >+ OpaqueResponse: ["throw new Error ('No object defined for the OpaqueResponse interface')"], >+ CORSResponse: ["throw new Error ('No object defined for the CORSResponse interface')"], >+ Response: ["throw new Error ('No object defined for the Response interface')"], >+ ResponseInit: ["throw new Error ('No object defined for the ResponseInit dictionary')"] >+ }); >+ idl_array.test(); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.5.2-response-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.5.2-response-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..832c7e36d295de78327f8065d068b8a0f9719109 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.5.2-response-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section Response so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.5.2-response.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.5.2-response.html >new file mode 100644 >index 0000000000000000000000000000000000000000..fbc72f30ad77c1d5591fcf359b4e4a7eb0263274 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.5.2-response.html >@@ -0,0 +1,36 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: Response</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#response"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`Response` objects are mutable and constructable. They model HTTP responses. >+The `fetch()` API returns this type for same-origin responses. >+ >+It may be possible to set the `Location` header of a `Response` object to >+someplace not in the current origin but this is not a security issue. >+Cross-origin response bodies are opaque to script, and since only same-origin >+documents will encounter these responses, the only systems the Service Worker >+can "lie to" are same-origin (and therefore safe from the perspective of other >+origins). >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section Response so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.5.4-opaque-response-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.5.4-opaque-response-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..5fabdd78893ba95ce7b714b0332704f3040ad094 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.5.4-opaque-response-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section OpaqueResponse so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.5.4-opaque-response.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.5.4-opaque-response.html >new file mode 100644 >index 0000000000000000000000000000000000000000..a91306f4c3c85d1b3181e5bb62016157b71e3e14 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.5.4-opaque-response.html >@@ -0,0 +1,36 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: OpaqueResponse</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#opaque-response"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`OpaqueResponse` objects are immutable but constructable. The `fetch()` API >+returns this type for cross-origin responses. >+ >+Their role is to encapsulate the security properties of the web platform. As >+such, their `body` attribute will always be `undefined` and the list of >+readable `headers` is heavily filtered. >+ >+`OpaqueResponse` objects may be forwarded on to rendering documents in exactly >+the same way as mutable `Response` objects. >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section OpaqueResponse so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6-cache-objects-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6-cache-objects-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..ab9a5058e8de2a761b3c64433b8c2f12f10fd32f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6-cache-objects-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section Caches so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6-cache-objects.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6-cache-objects.html >new file mode 100644 >index 0000000000000000000000000000000000000000..befd67cb378b0ea3e0f8d45cad3e344a4e2f9610 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6-cache-objects.html >@@ -0,0 +1,37 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: Caches</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#cache-objects"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+To allow authors to fully manage their content caches for offline use, the >+`[ServiceWorkerGlobalScope][1]` execution context provides the caching methods >+largely conforming to [ECMAScript 6 Map objects][2] with additional convenience >+methods. A domain can have multiple, named `[Cache][3]` objects, whose contents >+are entirely under the control of scripts. Caches are not shared across >+domains, and they are completely isolated from the browser's HTTP cache. >+ >+[1]: #service-worker-global-scope-interface >+[2]: http://goo.gl/gNnDPO >+[3]: #cache-interface >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section Caches so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6.1-cache-lifetimes-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6.1-cache-lifetimes-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..aa13b400aeb7806229404328ebca1d85dc8a4518 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6.1-cache-lifetimes-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section Understanding Cache Lifetimes so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6.1-cache-lifetimes.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6.1-cache-lifetimes.html >new file mode 100644 >index 0000000000000000000000000000000000000000..f6c9ecbd1919553af81429f1e16a6637ccc902f3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6.1-cache-lifetimes.html >@@ -0,0 +1,38 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: Understanding Cache Lifetimes</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#cache-lifetimes"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+The `[Cache][1]` instances are not part of the browser's HTTP cache. The >+`[Cache][1]` objects are exactly what authors have to manage themselves. The >+`[Cache][1]` objects do not get updated unless authors explicitly request them >+to be. The `[Cache][1]` objects do not expire unless authors delete the >+entries. The `[Cache][1]` objects do not disappear just because the Service >+Worker script is updated. That is, caches are not updated automatically. >+Updates must be manually managed. This implies that authors should version >+their caches by name and make sure to use the caches only from the version of >+the ServiceWorker that can safely operate on. >+ >+[1]: #cache-interface >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section Understanding Cache Lifetimes so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6.2-cache-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6.2-cache-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..34e2b9bd39b9957cc32e2e77df9ae58b4beb7d9f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6.2-cache-expected.txt >@@ -0,0 +1,38 @@ >+ >+PASS Cache interface: existence and properties of interface object >+PASS Cache interface object length >+PASS Cache interface object name >+PASS Cache interface: existence and properties of interface prototype object >+PASS Cache interface: existence and properties of interface prototype object's "constructor" property >+PASS Cache interface: existence and properties of interface prototype object's @@unscopables property >+PASS Cache interface: operation match(RequestInfo, CacheQueryOptions) >+PASS Unscopable handled correctly for match(RequestInfo, CacheQueryOptions) on Cache >+PASS Cache interface: operation matchAll(RequestInfo, CacheQueryOptions) >+PASS Unscopable handled correctly for matchAll(RequestInfo, CacheQueryOptions) on Cache >+PASS Cache interface: operation add(RequestInfo) >+PASS Unscopable handled correctly for add(RequestInfo) on Cache >+PASS Cache interface: operation addAll([object Object]) >+PASS Unscopable handled correctly for addAll([object Object]) on Cache >+PASS Cache interface: operation put(RequestInfo, Response) >+PASS Unscopable handled correctly for put(RequestInfo, Response) on Cache >+PASS Cache interface: operation delete(RequestInfo, CacheQueryOptions) >+PASS Unscopable handled correctly for delete(RequestInfo, CacheQueryOptions) on Cache >+PASS Cache interface: operation keys(RequestInfo, CacheQueryOptions) >+PASS Unscopable handled correctly for keys(RequestInfo, CacheQueryOptions) on Cache >+FAIL Cache must be primary interface of throw new Error ('No object defined for the Cache interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Cache interface" >+FAIL Stringification of throw new Error ('No object defined for the Cache interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Cache interface" >+FAIL Cache interface: throw new Error ('No object defined for the Cache interface') must inherit property "match(RequestInfo, CacheQueryOptions)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Cache interface" >+FAIL Cache interface: calling match(RequestInfo, CacheQueryOptions) on throw new Error ('No object defined for the Cache interface') with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Cache interface" >+FAIL Cache interface: throw new Error ('No object defined for the Cache interface') must inherit property "matchAll(RequestInfo, CacheQueryOptions)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Cache interface" >+FAIL Cache interface: calling matchAll(RequestInfo, CacheQueryOptions) on throw new Error ('No object defined for the Cache interface') with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Cache interface" >+FAIL Cache interface: throw new Error ('No object defined for the Cache interface') must inherit property "add(RequestInfo)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Cache interface" >+FAIL Cache interface: calling add(RequestInfo) on throw new Error ('No object defined for the Cache interface') with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Cache interface" >+FAIL Cache interface: throw new Error ('No object defined for the Cache interface') must inherit property "addAll([object Object])" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Cache interface" >+FAIL Cache interface: calling addAll([object Object]) on throw new Error ('No object defined for the Cache interface') with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Cache interface" >+FAIL Cache interface: throw new Error ('No object defined for the Cache interface') must inherit property "put(RequestInfo, Response)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Cache interface" >+FAIL Cache interface: calling put(RequestInfo, Response) on throw new Error ('No object defined for the Cache interface') with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Cache interface" >+FAIL Cache interface: throw new Error ('No object defined for the Cache interface') must inherit property "delete(RequestInfo, CacheQueryOptions)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Cache interface" >+FAIL Cache interface: calling delete(RequestInfo, CacheQueryOptions) on throw new Error ('No object defined for the Cache interface') with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Cache interface" >+FAIL Cache interface: throw new Error ('No object defined for the Cache interface') must inherit property "keys(RequestInfo, CacheQueryOptions)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Cache interface" >+FAIL Cache interface: calling keys(RequestInfo, CacheQueryOptions) on throw new Error ('No object defined for the Cache interface') with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the Cache interface" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6.2-cache.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6.2-cache.html >new file mode 100644 >index 0000000000000000000000000000000000000000..9270481d1837fb5c2c242de41e6653a26601cc3d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6.2-cache.html >@@ -0,0 +1,64 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: Cache</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#cache"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ <script src=/resources/WebIDLParser.js></script> >+ <script src=/resources/idlharness.js></script> >+ >+ </head> >+ <body> >+ >+<script type=text/plain id="idl_0"> >+[Exposed=(Window,Worker)] >+interface Cache { >+ Promise<Response> match(RequestInfo request, optional CacheQueryOptions options); >+ Promise<sequence<Response>> matchAll(optional RequestInfo request, optional CacheQueryOptions options); >+ Promise<void> add(RequestInfo request); >+ Promise<void> addAll(sequence<RequestInfo> requests); >+ Promise<void> put(RequestInfo request, Response response); >+ Promise<boolean> delete(RequestInfo request, optional CacheQueryOptions options); >+ Promise<sequence<Request>> keys(optional RequestInfo request, optional CacheQueryOptions options); >+}; >+ >+dictionary CacheQueryOptions { >+ boolean ignoreSearch = false; >+ boolean ignoreMethod = false; >+ boolean ignoreVary = false; >+ DOMString cacheName; >+}; >+ >+dictionary CacheBatchOperation { >+ DOMString type; >+ Request request; >+ Response response; >+ CacheQueryOptions options; >+}; >+</script> >+ >+ >+ >+ <script type=text/plain id="untested_idls"> >+ interface AbstractResponse {}; >+ interface Request {}; >+ interface ScalarValueString {}; >+ </script> >+ >+ <script> >+ var idl_array = new IdlArray(); >+ idl_array.add_untested_idls(document.getElementById("untested_idls").textContent); >+ idl_array.add_idls(document.getElementById("idl_0").textContent); >+ idl_array.add_objects({ >+ Cache: ["throw new Error ('No object defined for the Cache interface')"], >+ QueryParams: ["throw new Error ('No object defined for the QueryParams dictionary')"], >+ CacheIterationCallback: ["throw new Error ('No object defined for the CacheIterationCallback callback')"] >+ }); >+ idl_array.test(); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6.3-cache-storage-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6.3-cache-storage-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..11f2ca2a2e4106294da4145b4100b63b9d834cff >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6.3-cache-storage-expected.txt >@@ -0,0 +1,50 @@ >+CONSOLE MESSAGE: line 440: callback not yet supported >+ >+PASS CacheStorage interface: existence and properties of interface object >+FAIL CacheStorage interface object length assert_equals: wrong value for CacheStorage.length expected 1 but got 0 >+PASS CacheStorage interface object name >+PASS CacheStorage interface: existence and properties of interface prototype object >+PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property >+PASS CacheStorage interface: existence and properties of interface prototype object's @@unscopables property >+PASS CacheStorage interface: operation match(ScalarValueString, DOMString) >+PASS Unscopable handled correctly for match(ScalarValueString, DOMString) on CacheStorage >+FAIL CacheStorage interface: operation get(DOMString) assert_own_property: interface prototype object missing non-static operation expected property "get" missing >+PASS Unscopable handled correctly for get(DOMString) on CacheStorage >+PASS CacheStorage interface: operation has(DOMString) >+PASS Unscopable handled correctly for has(DOMString) on CacheStorage >+FAIL CacheStorage interface: operation set(DOMString, Cache) assert_own_property: interface prototype object missing non-static operation expected property "set" missing >+PASS Unscopable handled correctly for set(DOMString, Cache) on CacheStorage >+FAIL CacheStorage interface: operation clear() assert_own_property: interface prototype object missing non-static operation expected property "clear" missing >+PASS Unscopable handled correctly for clear() on CacheStorage >+PASS CacheStorage interface: operation delete(DOMString) >+PASS Unscopable handled correctly for delete(DOMString) on CacheStorage >+FAIL CacheStorage interface: operation forEach(CacheStorageIterationCallback, object) assert_own_property: interface prototype object missing non-static operation expected property "forEach" missing >+PASS Unscopable handled correctly for forEach(CacheStorageIterationCallback, object) on CacheStorage >+FAIL CacheStorage interface: operation entries() assert_own_property: interface prototype object missing non-static operation expected property "entries" missing >+PASS Unscopable handled correctly for entries() on CacheStorage >+PASS CacheStorage interface: operation keys() >+PASS Unscopable handled correctly for keys() on CacheStorage >+FAIL CacheStorage interface: operation values() assert_own_property: interface prototype object missing non-static operation expected property "values" missing >+PASS Unscopable handled correctly for values() on CacheStorage >+FAIL CacheStorage interface: operation size() assert_own_property: interface prototype object missing non-static operation expected property "size" missing >+PASS Unscopable handled correctly for size() on CacheStorage >+FAIL CacheStorage must be primary interface of throw new Error ('No object defined for the CacheStorage interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+FAIL Stringification of throw new Error ('No object defined for the CacheStorage interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+FAIL CacheStorage interface: throw new Error ('No object defined for the CacheStorage interface') must inherit property "match(ScalarValueString, DOMString)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+FAIL CacheStorage interface: calling match(ScalarValueString, DOMString) on throw new Error ('No object defined for the CacheStorage interface') with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+FAIL CacheStorage interface: throw new Error ('No object defined for the CacheStorage interface') must inherit property "get(DOMString)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+FAIL CacheStorage interface: calling get(DOMString) on throw new Error ('No object defined for the CacheStorage interface') with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+FAIL CacheStorage interface: throw new Error ('No object defined for the CacheStorage interface') must inherit property "has(DOMString)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+FAIL CacheStorage interface: calling has(DOMString) on throw new Error ('No object defined for the CacheStorage interface') with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+FAIL CacheStorage interface: throw new Error ('No object defined for the CacheStorage interface') must inherit property "set(DOMString, Cache)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+FAIL CacheStorage interface: calling set(DOMString, Cache) on throw new Error ('No object defined for the CacheStorage interface') with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+FAIL CacheStorage interface: throw new Error ('No object defined for the CacheStorage interface') must inherit property "clear()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+FAIL CacheStorage interface: throw new Error ('No object defined for the CacheStorage interface') must inherit property "delete(DOMString)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+FAIL CacheStorage interface: calling delete(DOMString) on throw new Error ('No object defined for the CacheStorage interface') with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+FAIL CacheStorage interface: throw new Error ('No object defined for the CacheStorage interface') must inherit property "forEach(CacheStorageIterationCallback, object)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+FAIL CacheStorage interface: calling forEach(CacheStorageIterationCallback, object) on throw new Error ('No object defined for the CacheStorage interface') with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+FAIL CacheStorage interface: throw new Error ('No object defined for the CacheStorage interface') must inherit property "entries()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+FAIL CacheStorage interface: throw new Error ('No object defined for the CacheStorage interface') must inherit property "keys()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+FAIL CacheStorage interface: throw new Error ('No object defined for the CacheStorage interface') must inherit property "values()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+FAIL CacheStorage interface: throw new Error ('No object defined for the CacheStorage interface') must inherit property "size()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the CacheStorage interface" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6.3-cache-storage.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6.3-cache-storage.html >new file mode 100644 >index 0000000000000000000000000000000000000000..29666d837fc05c0315043c97e7ab4f30efad0771 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.6.3-cache-storage.html >@@ -0,0 +1,62 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: CacheStorage</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#cache-storage"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ <script src=/resources/WebIDLParser.js></script> >+ <script src=/resources/idlharness.js></script> >+ >+ </head> >+ <body> >+ >+<script type=text/plain id="idl_0"> >+[Constructor(sequence<any> iterable)] >+interface CacheStorage { >+ Promise<any> match(ScalarValueString url, optional DOMString cacheName); >+ Promise<Cache> get(DOMString key); >+ Promise<boolean> has(DOMString key); >+ Promise<any> set(DOMString key, Cache val); >+ Promise<any> clear(); >+ Promise<any> delete(DOMString key); >+ void forEach(CacheStorageIterationCallback callback, optional object thisArg); >+ Promise<sequence<any>> entries(); >+ Promise<sequence<DOMString>> keys(); >+ Promise<sequence<Cache>> values(); >+ Promise<unsigned long> size(); >+}; >+ >+callback CacheStorageIterationCallback = void (Cache value, DOMString key, CacheStorage map); >+</script> >+ >+<!-- >+**Note**:[CacheStorage][1]interface is designed to largely conform >+to[ECMAScript 6 Map objects][2]but entirely async, and with additional >+convenience methods. >+ >+[1]: #cache-storage-interface >+[2]: http://goo.gl/gNnDPO >+--> >+ >+ >+ <script type=text/plain id="untested_idls"> >+ interface ScalarValueString {}; >+ interface Cache {}; >+ </script> >+ >+ <script> >+ var idl_array = new IdlArray(); >+ idl_array.add_untested_idls(document.getElementById("untested_idls").textContent); >+ idl_array.add_idls(document.getElementById("idl_0").textContent); >+ idl_array.add_objects({ >+ CacheStorage: ["throw new Error ('No object defined for the CacheStorage interface')"], >+ CacheStorageIterationCallback: ["throw new Error ('No object defined for the CacheStorageIterationCallback callback')"] >+ }); >+ idl_array.test(); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.1-install-phase-event-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.1-install-phase-event-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..7ae0e5d732a2643e4329265ad9e0622b31dd9613 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.1-install-phase-event-expected.txt >@@ -0,0 +1,14 @@ >+ >+FAIL InstallPhaseEvent interface: existence and properties of interface object assert_own_property: self does not have own property "InstallPhaseEvent" expected property "InstallPhaseEvent" missing >+FAIL InstallPhaseEvent interface object length assert_own_property: self does not have own property "InstallPhaseEvent" expected property "InstallPhaseEvent" missing >+FAIL InstallPhaseEvent interface object name assert_own_property: self does not have own property "InstallPhaseEvent" expected property "InstallPhaseEvent" missing >+FAIL InstallPhaseEvent interface: existence and properties of interface prototype object assert_own_property: self does not have own property "InstallPhaseEvent" expected property "InstallPhaseEvent" missing >+FAIL InstallPhaseEvent interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "InstallPhaseEvent" expected property "InstallPhaseEvent" missing >+FAIL InstallPhaseEvent interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "InstallPhaseEvent" expected property "InstallPhaseEvent" missing >+FAIL InstallPhaseEvent interface: operation waitUntil([object Object]) assert_own_property: self does not have own property "InstallPhaseEvent" expected property "InstallPhaseEvent" missing >+PASS Unscopable handled correctly for waitUntil([object Object]) on InstallPhaseEvent >+FAIL InstallPhaseEvent must be primary interface of throw new Error ('No object defined for the InstallPhaseEvent interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the InstallPhaseEvent interface" >+FAIL Stringification of throw new Error ('No object defined for the InstallPhaseEvent interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the InstallPhaseEvent interface" >+FAIL InstallPhaseEvent interface: throw new Error ('No object defined for the InstallPhaseEvent interface') must inherit property "waitUntil([object Object])" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the InstallPhaseEvent interface" >+FAIL InstallPhaseEvent interface: calling waitUntil([object Object]) on throw new Error ('No object defined for the InstallPhaseEvent interface') with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the InstallPhaseEvent interface" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.1-install-phase-event.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.1-install-phase-event.html >new file mode 100644 >index 0000000000000000000000000000000000000000..8b7ab81c5eff4a5ce03cb6939d75a1e38d5290d6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.1-install-phase-event.html >@@ -0,0 +1,51 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: InstallPhaseEvent</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#install-phase-event"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ <script src=/resources/WebIDLParser.js></script> >+ <script src=/resources/idlharness.js></script> >+ >+ </head> >+ <body> >+ >+<script type=text/plain id="idl_0"> >+interface InstallPhaseEvent : Event { >+ Promise<any> waitUntil(Promise<any> f); >+}; >+</script> >+ >+<!-- >+Service Workers have two [Lifecycle events][1], `[install][2]` and >+`[activate][3]`. Service Workers use the `[InstallPhaseEvent][4]` interface for >+`[activate][3]` event and the `[InstallEvent][5]` interface, which inherits >+from the `[InstallPhaseEvent][4]` interface, for `[install][2]` event. >+ >+[1]: #lifecycle-events >+[2]: #install-event >+[3]: #activate-event >+[4]: #install-phase-event-interface >+[5]: #install-event-interface >+--> >+ >+ >+ <script type=text/plain id="untested_idls"> >+ interface Event {}; >+ </script> >+ >+ <script> >+ var idl_array = new IdlArray(); >+ idl_array.add_untested_idls(document.getElementById("untested_idls").textContent); >+ idl_array.add_idls(document.getElementById("idl_0").textContent); >+ idl_array.add_objects({ >+ InstallPhaseEvent: ["throw new Error ('No object defined for the InstallPhaseEvent interface')"] >+ }); >+ idl_array.test(); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.1.1-wait-until-method-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.1.1-wait-until-method-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..6857b57d00b94da04c3aadcda9c7b376b7622027 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.1.1-wait-until-method-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section event.waitUntil(f) so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.1.1-wait-until-method.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.1.1-wait-until-method.html >new file mode 100644 >index 0000000000000000000000000000000000000000..318318b13940cd9f5f8ebab8b93b6ec371ffb3ff >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.1.1-wait-until-method.html >@@ -0,0 +1,39 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: event.waitUntil(f)</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#wait-until-method"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`event.waitUntil(f)` method, when called in `oninstall` or `onactivate`, >+extends the lifetime of the event. When called in `oninstall`, it delays >+treating the installing worker until the passed [Promise][1] resolves >+successfully. This is primarily used to ensure that a `ServiceWorker` is not >+active until all of the core caches it depends on are populated. When called in >+`onactivate`, it delays treating the activating worker until the passed >+[Promise][1] resolves successfully. This is primarily used to ensure that any >+[Functional events][2] are not dispatched to the `ServiceWorker` until it >+upgrades database schemas and deletes the outdated cache entries. >+ >+[1]: http://goo.gl/3TobQS >+[2]: #functional-events >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section event.waitUntil(f) so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.2-install-event-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.2-install-event-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..e176016a7228e377d813dfc544ae276d50ed2e0d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.2-install-event-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section install Event so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.2-install-event.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.2-install-event.html >new file mode 100644 >index 0000000000000000000000000000000000000000..77702ed02833c762b3cb12d3144c39844f5f8713 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.2-install-event.html >@@ -0,0 +1,35 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: install Event</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#install-event"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+An event named `[install][1]` using the `[InstallEvent][2]` interface is >+dispatched on `ServiceWorkerGlobalScope` object when the state of the >+associated `ServiceWorker` changes its value to `installing`. (See step 3 of >+[_Installation algorithm][3]) >+ >+[1]: #install-event >+[2]: #install-event-interface >+[3]: #installation-algorithm >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section install Event so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.2.1-install-event-section-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.2.1-install-event-section-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..0d896ccc5680725edecd48a89f4a9812747b300e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.2.1-install-event-section-expected.txt >@@ -0,0 +1,16 @@ >+ >+FAIL InstallEvent interface: existence and properties of interface object assert_own_property: self does not have own property "InstallEvent" expected property "InstallEvent" missing >+FAIL InstallEvent interface object length assert_own_property: self does not have own property "InstallEvent" expected property "InstallEvent" missing >+FAIL InstallEvent interface object name assert_own_property: self does not have own property "InstallEvent" expected property "InstallEvent" missing >+FAIL InstallEvent interface: existence and properties of interface prototype object assert_own_property: self does not have own property "InstallEvent" expected property "InstallEvent" missing >+FAIL InstallEvent interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "InstallEvent" expected property "InstallEvent" missing >+FAIL InstallEvent interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "InstallEvent" expected property "InstallEvent" missing >+FAIL InstallEvent interface: attribute activeWorker assert_own_property: self does not have own property "InstallEvent" expected property "InstallEvent" missing >+PASS Unscopable handled correctly for activeWorker property on InstallEvent >+FAIL InstallEvent interface: operation replace() assert_own_property: self does not have own property "InstallEvent" expected property "InstallEvent" missing >+PASS Unscopable handled correctly for replace() on InstallEvent >+FAIL InstallEvent must be primary interface of throw new Error ('No object defined for the InstallEvent interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the InstallEvent interface" >+FAIL Stringification of throw new Error ('No object defined for the InstallEvent interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the InstallEvent interface" >+FAIL InstallEvent interface: throw new Error ('No object defined for the InstallEvent interface') must inherit property "activeWorker" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the InstallEvent interface" >+FAIL InstallEvent interface: throw new Error ('No object defined for the InstallEvent interface') must inherit property "replace()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the InstallEvent interface" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.2.1-install-event-section.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.2.1-install-event-section.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d9b47e195af2b35f8d4f803caacd23e00e74f155 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.2.1-install-event-section.html >@@ -0,0 +1,47 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: InstallEvent</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#install-event-section"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ <script src=/resources/WebIDLParser.js></script> >+ <script src=/resources/idlharness.js></script> >+ >+ </head> >+ <body> >+ >+<script type=text/plain id="idl_0"> >+interface InstallEvent : InstallPhaseEvent { >+ readonly attribute ServiceWorker? activeWorker; >+ void replace(); >+}; >+</script> >+ >+<!-- >+Service Workers use the `[InstallEvent][1]` interface for `[install][2]` event. >+ >+[1]: #install-event-interface >+[2]: #install-event >+--> >+ >+ >+ <script type=text/plain id="untested_idls"> >+ interface ServiceWorker {}; >+ interface InstallPhaseEvent {}; >+ </script> >+ >+ <script> >+ var idl_array = new IdlArray(); >+ idl_array.add_untested_idls(document.getElementById("untested_idls").textContent); >+ idl_array.add_idls(document.getElementById("idl_0").textContent); >+ idl_array.add_objects({ >+ InstallEvent: ["throw new Error ('No object defined for the InstallEvent interface')"] >+ }); >+ idl_array.test(); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.2.2-replace-method-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.2.2-replace-method-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..70e56ddb02ff76d4053cd81382dd73c1ff8a5969 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.2.2-replace-method-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section event.replace() so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.2.2-replace-method.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.2.2-replace-method.html >new file mode 100644 >index 0000000000000000000000000000000000000000..6981d3079c3e108d6f4c96a69db719e206d09c75 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.2.2-replace-method.html >@@ -0,0 +1,38 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: event.replace()</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#replace-method"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`replace()` interacts with `waitUntil` method in the following way: >+ >+- Successful installation can be delayed by `waitUntil`, perhaps by >+ subsequent event handlers. >+- Replacement only happens upon successful installation >+- Therefore, replacement of the [active worker][1] (if any) is not >+ immediate, however it may occur as soon as the end of the current turn. >+ >+ >+ >+[1]: #navigator-service-worker-active >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section event.replace() so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.3-activate-event-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.3-activate-event-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..3bf3f0dc50870ebcf095cadb326f1e33307e2e8d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.3-activate-event-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section activate Event so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.3-activate-event.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.3-activate-event.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2a0162e5fd3eb48db2905bee9982fbe65e399793 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.3-activate-event.html >@@ -0,0 +1,41 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: activate Event</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#activate-event"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+An event named `[activate][1]` using the `[InstallPhaseEvent][2]` interface is >+dispatched on `ServiceWorkerGlobalScope` object when the state of the >+associated `ServiceWorker` changes its value to `activating`. (See step 6 of >+[_Activation algorithm][3]) >+ >+Service Workers use the `[InstallPhaseEvent][4]` interface for `[activate][1]` >+event. >+ >+ >+ >+[1]: #activate-event >+[2]: #install-phase-event >+[3]: #activation-algorithm >+[4]: #install-phase-event-interface >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section activate Event so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.1-fetch-event-section-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.1-fetch-event-section-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..c2878b0bb21d2805d9f96210a29b2343146184cc >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.1-fetch-event-section-expected.txt >@@ -0,0 +1,36 @@ >+CONSOLE MESSAGE: line 830: TypeError: this.members[name].test_object is not a function. (In 'this.members[name].test_object(str)', 'this.members[name].test_object' is undefined) >+ >+Harness Error (FAIL), message = TypeError: this.members[name].test_object is not a function. (In 'this.members[name].test_object(str)', 'this.members[name].test_object' is undefined) >+ >+FAIL FetchEvent interface: existence and properties of interface object assert_own_property: self does not have own property "FetchEvent" expected property "FetchEvent" missing >+FAIL FetchEvent interface object length assert_own_property: self does not have own property "FetchEvent" expected property "FetchEvent" missing >+FAIL FetchEvent interface object name assert_own_property: self does not have own property "FetchEvent" expected property "FetchEvent" missing >+FAIL FetchEvent interface: existence and properties of interface prototype object assert_own_property: self does not have own property "FetchEvent" expected property "FetchEvent" missing >+FAIL FetchEvent interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "FetchEvent" expected property "FetchEvent" missing >+FAIL FetchEvent interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "FetchEvent" expected property "FetchEvent" missing >+FAIL FetchEvent interface: attribute request assert_own_property: self does not have own property "FetchEvent" expected property "FetchEvent" missing >+PASS Unscopable handled correctly for request property on FetchEvent >+FAIL FetchEvent interface: attribute client assert_own_property: self does not have own property "FetchEvent" expected property "FetchEvent" missing >+PASS Unscopable handled correctly for client property on FetchEvent >+FAIL FetchEvent interface: attribute context assert_own_property: self does not have own property "FetchEvent" expected property "FetchEvent" missing >+PASS Unscopable handled correctly for context property on FetchEvent >+FAIL FetchEvent interface: attribute isReload assert_own_property: self does not have own property "FetchEvent" expected property "FetchEvent" missing >+PASS Unscopable handled correctly for isReload property on FetchEvent >+FAIL FetchEvent interface: operation respondWith([object Object]) assert_own_property: self does not have own property "FetchEvent" expected property "FetchEvent" missing >+PASS Unscopable handled correctly for respondWith([object Object]) on FetchEvent >+FAIL FetchEvent interface: operation forwardTo(ScalarValueString) assert_own_property: self does not have own property "FetchEvent" expected property "FetchEvent" missing >+PASS Unscopable handled correctly for forwardTo(ScalarValueString) on FetchEvent >+FAIL FetchEvent interface: operation default() assert_own_property: self does not have own property "FetchEvent" expected property "FetchEvent" missing >+PASS Unscopable handled correctly for default() on FetchEvent >+FAIL FetchEvent must be primary interface of throw new Error ('No object defined for the FetchEvent interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the FetchEvent interface" >+FAIL Stringification of throw new Error ('No object defined for the FetchEvent interface') assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the FetchEvent interface" >+FAIL FetchEvent interface: throw new Error ('No object defined for the FetchEvent interface') must inherit property "request" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the FetchEvent interface" >+FAIL FetchEvent interface: throw new Error ('No object defined for the FetchEvent interface') must inherit property "client" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the FetchEvent interface" >+FAIL FetchEvent interface: throw new Error ('No object defined for the FetchEvent interface') must inherit property "context" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the FetchEvent interface" >+FAIL FetchEvent interface: throw new Error ('No object defined for the FetchEvent interface') must inherit property "isReload" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the FetchEvent interface" >+FAIL FetchEvent interface: throw new Error ('No object defined for the FetchEvent interface') must inherit property "respondWith([object Object])" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the FetchEvent interface" >+FAIL FetchEvent interface: calling respondWith([object Object]) on throw new Error ('No object defined for the FetchEvent interface') with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the FetchEvent interface" >+FAIL FetchEvent interface: throw new Error ('No object defined for the FetchEvent interface') must inherit property "forwardTo(ScalarValueString)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the FetchEvent interface" >+FAIL FetchEvent interface: calling forwardTo(ScalarValueString) on throw new Error ('No object defined for the FetchEvent interface') with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the FetchEvent interface" >+FAIL FetchEvent interface: throw new Error ('No object defined for the FetchEvent interface') must inherit property "default()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "Error: No object defined for the FetchEvent interface" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.1-fetch-event-section.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.1-fetch-event-section.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ace71967bdf868b11b2cca58e8893523b9121894 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.1-fetch-event-section.html >@@ -0,0 +1,71 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: FetchEvent</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#fetch-event-section"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ <script src=/resources/WebIDLParser.js></script> >+ <script src=/resources/idlharness.js></script> >+ >+ </head> >+ <body> >+ >+<script type=text/plain id="idl_0"> >+[Constructor] >+interface FetchEvent : Event { >+ readonly attribute Request request; >+ readonly attribute Client client; // The window issuing the request. >+ readonly attribute Context context; >+ readonly attribute boolean isReload; >+ >+ void respondWith(Promise<AbstractResponse> r); >+ Promise<any> forwardTo(ScalarValueString url); >+ Promise<any> default(); >+}; >+ >+enum Context { >+ "connect", >+ "font", >+ "img", >+ "object", >+ "script", >+ "style", >+ "worker", >+ "popup", >+ "child", >+ "navigate" >+}; >+</script> >+ >+<!-- >+Service Workers use the `[FetchEvent][1]` interface for `[fetch][2]` event. >+ >+[1]: #fetch-event-interface >+[2]: #fetch-event >+--> >+ >+ >+ <script type=text/plain id="untested_idls"> >+ interface Request {}; >+ interface Client {}; >+ interface AbstractResponse {}; >+ interface ScalarValueString {}; >+ interface Event {}; >+ </script> >+ >+ <script> >+ var idl_array = new IdlArray(); >+ idl_array.add_untested_idls(document.getElementById("untested_idls").textContent); >+ idl_array.add_idls(document.getElementById("idl_0").textContent); >+ idl_array.add_objects({ >+ FetchEvent: ["throw new Error ('No object defined for the FetchEvent interface')"], >+ Context: ["throw new Error ('No object defined for the Context enum')"] >+ }); >+ idl_array.test(); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.2-respond-with-method-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.2-respond-with-method-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..9f460c6c94409cca151f11290ea7b0314e4db176 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.2-respond-with-method-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section event.respondWith(r) so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.2-respond-with-method.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.2-respond-with-method.html >new file mode 100644 >index 0000000000000000000000000000000000000000..416b8ef517a85692348058595b27baeae9abe04d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.2-respond-with-method.html >@@ -0,0 +1,46 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: event.respondWith(r)</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#respond-with-method"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`event.respondWith(r)` method must run the steps, from step 10 to step 15, >+defined in the [_OnFetchRequest algorithm][1]. >+ >+The `r` argument must resolve with a [AbstractResponse][2], else a >+[NetworkError][3] is thrown. If the request is a top-level navigation and the >+return value is a [OpaqueResponse][4] (an opaque response body), a >+[NetworkError][3] is thrown. The final URL of all successful (non >+network-error) responses is the [requested][5] URL. Renderer-side security >+checks about tainting for cross-origin content are tied to the transparency (or >+opacity) of the [Response][6] body, not URLs. >+ >+ >+ >+[1]: #on-fetch-request-algorithm >+[2]: #abstract-response-interface >+[3]: http://w3c.github.io/dom/#networkerror >+[4]: #opaque-response-interface >+[5]: #request-objects >+[6]: #response-interface >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section event.respondWith(r) so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.3-default-method-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.3-default-method-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..1c7728fa5fad8e5801dfb9382514da1dc68833fb >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.3-default-method-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section event.default() so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.3-default-method.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.3-default-method.html >new file mode 100644 >index 0000000000000000000000000000000000000000..deff7ac4238eac47b82833814fe6f8babf941b5d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.3-default-method.html >@@ -0,0 +1,52 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: event.default()</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#default-method"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+`event.default()` method must run these steps: >+ >+1. Let `promise` be a newly-created [promise][1]. >+2. Return `promise.` >+3. Run the following steps asynchronously: >+ 1. Let `request` be `event`'s `request`. >+ 2. Set `request`'s [skip service worker flag][2]. >+ 3. Let `response` be the result of running [fetch algorithm][3] with >+ `request` as its argument. >+ 4. If `response` is a [network error][4], then: >+ 1. Reject `promise` with a new [DOMException][5] whose name is >+ "[NetworkError][6]". >+ 5. Else, >+ 1. Resolve `promise` with a new [Response][7] object associated >+ with `response`. >+ >+ >+ >+[1]: http://goo.gl/3TobQS >+[2]: http://goo.gl/gP7IWW >+[3]: http://goo.gl/fGMifs >+[4]: http://goo.gl/jprjjc >+[5]: http://goo.gl/A0U8qC >+[6]: http://goo.gl/lud5HB >+[7]: http://goo.gl/Deazjv >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section event.default() so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.4-is-reload-attribute-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.4-is-reload-attribute-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..f43f970eab3078e7b7fe79fe36d862a7c9e978be >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.4-is-reload-attribute-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section event.isReload so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.4-is-reload-attribute.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.4-is-reload-attribute.html >new file mode 100644 >index 0000000000000000000000000000000000000000..fffe5d5b29f1cd0bb46f2a2cd3a98a67bcedefd4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-4.7.4.4-is-reload-attribute.html >@@ -0,0 +1,32 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: event.isReload</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#is-reload-attribute"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+Returns true if `event` was dispatched with the user's intention for the page >+reload, and false otherwise. Pressing the refresh button should be considered a >+reload while clicking a link and pressing the back button should not. The >+behavior of the `Ctrl+l enter` is left to the implementations of the user >+agents. >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section event.isReload so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-5.1-origin-relativity-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-5.1-origin-relativity-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..5d6e1df58a133579dd18bb8b5d23eca422569d6d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-5.1-origin-relativity-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section Origin Relativity so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-5.1-origin-relativity.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-5.1-origin-relativity.html >new file mode 100644 >index 0000000000000000000000000000000000000000..469ce2975cd5263829e2f9195b366db1c0268471 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-5.1-origin-relativity.html >@@ -0,0 +1,35 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: Origin Relativity</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#origin-relativity"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+One of the advanced concerns that major applications would encounter is whether >+they can be hosted from a CDN. By definition, these are servers in other >+places, often on other domains. Therefore, Service Workers cannot be hosted on >+CDNs. But they can include resources via [importScripts()][1]. The reason for >+this restriction is that Service Workers create the opportunity for a bad actor >+to turn a bad day into a bad eternity. >+ >+[1]: http://goo.gl/Owcfs2 >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section Origin Relativity so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-5.2-cross-origin-resources-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-5.2-cross-origin-resources-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..1ac71d562e4950358f38b525b7b084cba646bbfd >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-5.2-cross-origin-resources-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS There are no tests for section Cross-Origin Resources & CORS so far. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-5.2-cross-origin-resources.html b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-5.2-cross-origin-resources.html >new file mode 100644 >index 0000000000000000000000000000000000000000..42c685b1d5525be8c3ed68a9112b2d546e78bcf6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/stub-5.2-cross-origin-resources.html >@@ -0,0 +1,48 @@ >+<!DOCTYPE html> >+<html> >+<title>Service Workers: Cross-Origin Resources & CORS</title> >+ <head> >+ <link rel="help" href="https://w3c.github.io/ServiceWorker/#cross-origin-resources"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ >+ </head> >+ <body> >+ >+<!-- >+ >+Applications tend to cache items that come from a CDN or other domain. It is >+possible to request many of them directly using <script>, <img>, <video> and >+<link> elements. It would be hugely limiting if this sort of runtime >+collaboration broke when offline. Similarly, it is possible to XHR many sorts >+of off-domain resources when appropriate CORS headers are set. >+ >+ServiceWorkers enable this by allowing `Cache`s to fetch and cache off-origin >+items. Some restrictions apply, however. First, unlike same-origin resources >+which are managed in the `Cache` as `[Promise][1]`s for `Response` instances, >+the objects stored are `[Promise][1]`s for `OpaqueResponse` instances. >+`OpaqueResponse` provides a much less expressive API than `Response`; the >+bodies and headers cannot be read or set, nor many of the other aspects of >+their content inspected. They can be passed to `respondWith()` and >+`forwardTo()` in the same manner as `Response`s, but cannot be meaningfully >+created programmatically. These limitations are necessary to preserve the >+security invariants of the platform. Allowing `Cache`s to store them allows >+applications to avoid re-architecting in most cases. >+ >+ >+ >+[1]: http://goo.gl/3TobQS >+ >+--> >+ >+ >+ >+ <script> >+ test(function() { >+ // not_implemented(); >+ }, "There are no tests for section Cross-Origin Resources & CORS so far."); >+ </script> >+ >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/tools/blink-import.py b/LayoutTests/imported/w3c/web-platform-tests/service-workers/tools/blink-import.py >index 355df07960c42663d99648f19d9e31c384d12c94..552fdc054cc766f13ffe660b1f105b2c9b8c106c 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/tools/blink-import.py >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/tools/blink-import.py >@@ -1,3 +1,5 @@ >+from __future__ import print_function >+ > import os > import re > import shutil >@@ -184,7 +186,7 @@ def main(): > > for k, v in path_changes.iteritems(): > if os.path.basename(k) in filename_changes: >- print "Got duplicate name:" + os.path.basename(k) >+ print("Got duplicate name:" + os.path.basename(k)) > filename_changes[os.path.basename(k)] = os.path.basename(v) > > for path in source_paths(work_path): >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Document-prototype-currentScript-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Document-prototype-currentScript-expected.txt >index 002e3c89ecbc6a27de528069a8da7d5ac50678a8..0088aa2048d10ddefa7d7ece665c4dacbb172449 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Document-prototype-currentScript-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Document-prototype-currentScript-expected.txt >@@ -1,10 +1,8 @@ > >-Harness Error (FAIL), message = 1 duplicate test name: "document.currentScript must be set to a script element that loads an external script in a document tree" >- > PASS document.currentScript must not to be set to a script element in a shadow tree in open mode > PASS document.currentScript must not to be set to a script element in a shadow tree in closed mode > PASS document.currentScript must be set to a script element that loads an external script in a document tree >-PASS document.currentScript must be set to a script element that loads an external script in a document tree >+PASS document.currentScript must be set to a script element that loads an external script in a document tree (2) > PASS document.currentScript must not be set to a script element that loads an external script in an open shadow tree > PASS document.currentScript must not be set to a script element that loads an external script in a closed shadow tree > PASS document.currentScript must be set to a script element that loads an external script that was in an open shadow tree and then removed >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Document-prototype-currentScript.html b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Document-prototype-currentScript.html >index 867cea9795e09a17017fac8cd1730f605adf39b4..ff0344fe49367a5e2af292f2911a3f025697c86a 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Document-prototype-currentScript.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Document-prototype-currentScript.html >@@ -40,10 +40,11 @@ var testedScriptElement = null; > function executeNextTest() > { > var testCase = asyncScriptTests.shift(); >- var mode = testCase.mode; > if (!testCase) > return; > >+ var mode = testCase.mode; >+ > testCase.test.step(function () { > testedScriptElement = document.createElement('script'); > testedScriptElement.src = 'resources/Document-prototype-currentScript-helper.js'; >@@ -75,7 +76,7 @@ var asyncScriptTests = [ > test: async_test('document.currentScript must be set to a script element that loads an external script in a document tree'), > mode: null, remove: false, expected: function () { return testedScriptElement; }}, > { >- test: async_test('document.currentScript must be set to a script element that loads an external script in a document tree'), >+ test: async_test('document.currentScript must be set to a script element that loads an external script in a document tree (2)'), > mode: null, remove: true, expected: function () { return testedScriptElement; }}, > { > test: async_test('document.currentScript must not be set to a script element that loads an external script in an open shadow tree'), >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/DocumentOrShadowRoot-prototype-elementFromPoint-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/DocumentOrShadowRoot-prototype-elementFromPoint-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..3183a0e016f2b7c3d939428fb3b84b42e180b567 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/DocumentOrShadowRoot-prototype-elementFromPoint-expected.txt >@@ -0,0 +1,41 @@ >+ >+PASS document.elementFromPoint and shadow.ElementFromPoint must return the shadow host of the hit-tested text node when the hit-tested text node is a direct child of the root and the host has display: inline >+PASS document.elementFromPoint and shadow.ElementFromPoint must return the shadow host of the hit-tested text node when the hit-tested text node is a direct child of the root and the host has display: block >+PASS document.elementFromPoint and shadow.ElementFromPoint must return the shadow host of the hit-tested text node when the hit-tested text node is a direct child of the root and the host has display: inline-block >+FAIL document.elementFromPoint and shadowRoot.elementFromPoint must return the shadow host when the hit-tested text node is assigned to a slot and the host has display: inline assert_equals: expected Element node <test-element style="display: inline;">text</test-element> but got Element node <slot></slot> >+FAIL document.elementFromPoint and shadowRoot.elementFromPoint must return the shadow host when the hit-tested text node is assigned to a slot and the host has display: block assert_equals: expected Element node <test-element style="display: block;">text</test-element> but got Element node <slot></slot> >+FAIL document.elementFromPoint and shadowRoot.elementFromPoint must return the shadow host when the hit-tested text node is assigned to a slot and the host has display: inline-block assert_equals: expected Element node <test-element style="display: inline-block;">text</test-e... but got Element node <slot></slot> >+PASS document.elementFromPoint and shadowRoot.elementFromPoint must return the element assigned to a slot when hit-tested text node under an element is assigned to a slot in the shadow tree and the shadow host of the slot has display: inline >+PASS document.elementFromPoint and shadowRoot.elementFromPoint must return the element assigned to a slot when hit-tested text node under an element is assigned to a slot in the shadow tree and the shadow host of the slot has display: block >+PASS document.elementFromPoint and shadowRoot.elementFromPoint must return the element assigned to a slot when hit-tested text node under an element is assigned to a slot in the shadow tree and the shadow host of the slot has display: inline-block >+PASS document.elementFromPoint must return the shadow host of the hit-tested element under a shadow root and shadowRoot.elementFromPoint must return the element parent of the hit-tested text node under the point when the shadow host has display: inline >+PASS document.elementFromPoint must return the shadow host of the hit-tested element under a shadow root and shadowRoot.elementFromPoint must return the element parent of the hit-tested text node under the point when the shadow host has display: block >+PASS document.elementFromPoint must return the shadow host of the hit-tested element under a shadow root and shadowRoot.elementFromPoint must return the element parent of the hit-tested text node under the point when the shadow host has display: inline-block >+PASS document.elementFromPoint must return the shadow host and shadowRoot.elementFromPoint must return the slot parent of the fallback text when the hit-tested text node is a fallback content and the host has display: inline >+PASS document.elementFromPoint must return the shadow host and shadowRoot.elementFromPoint must return the slot parent of the fallback text when the hit-tested text node is a fallback content and the host has display: block >+PASS document.elementFromPoint must return the shadow host and shadowRoot.elementFromPoint must return the slot parent of the fallback text when the hit-tested text node is a fallback content and the host has display: inline-block >+FAIL document.elementFromPoint, shadowRoot.elementFromPoint, innerShadow.elementFromPoint must return a child element assigned to a slot when the hit-tested text node is assigned to a slot in the shadow tree of the child element and the outer shadow host has display: inline assert_equals: expected Element node <inner-host>hello</inner-host> but got Element node <slot></slot> >+FAIL document.elementFromPoint, shadowRoot.elementFromPoint, innerShadow.elementFromPoint must return a child element assigned to a slot when the hit-tested text node is assigned to a slot in the shadow tree of the child element and the outer shadow host has display: block assert_equals: expected Element node <inner-host>hello</inner-host> but got Element node <slot></slot> >+FAIL document.elementFromPoint, shadowRoot.elementFromPoint, innerShadow.elementFromPoint must return a child element assigned to a slot when the hit-tested text node is assigned to a slot in the shadow tree of the child element and the outer shadow host has display: inline-block assert_equals: expected Element node <inner-host>hello</inner-host> but got Element node <slot></slot> >+PASS document.elementFromPoint, shadowRoot.elementFromPoint, innerShadow.elementFromPoint must return a child element with its own shadow tree assigned to a slot when the hit-tested text node is its direct child and the outer shadow host has display: inline >+PASS document.elementFromPoint, shadowRoot.elementFromPoint, innerShadow.elementFromPoint must return a child element with its own shadow tree assigned to a slot when the hit-tested text node is its direct child and the outer shadow host has display: block >+PASS document.elementFromPoint, shadowRoot.elementFromPoint, innerShadow.elementFromPoint must return a child element with its own shadow tree assigned to a slot when the hit-tested text node is its direct child and the outer shadow host has display: inline-block >+PASS document.elementFromPoint, shadowRoot.elementFromPoint must return a child element with its own shadow tree assigned to a slot when the hit-tested text node is a child of another element and innerShadow.elementFromPoint must return the parent element of the hit-tested text node under it when the outer shadow host has display: inline >+PASS document.elementFromPoint, shadowRoot.elementFromPoint must return a child element with its own shadow tree assigned to a slot when the hit-tested text node is a child of another element and innerShadow.elementFromPoint must return the parent element of the hit-tested text node under it when the outer shadow host has display: block >+PASS document.elementFromPoint, shadowRoot.elementFromPoint must return a child element with its own shadow tree assigned to a slot when the hit-tested text node is a child of another element and innerShadow.elementFromPoint must return the parent element of the hit-tested text node under it when the outer shadow host has display: inline-block >+PASS document.elementsFromPoint and shadow.elementsFromPoint must return the shadow host and its ancestors of the hit-tested text node when the hit-tested text node is a direct child of the root and the host has display: inline >+PASS document.elementsFromPoint and shadow.elementsFromPoint must return the shadow host and its ancestors of the hit-tested text node when the hit-tested text node is a direct child of the root and the host has display: block >+PASS document.elementsFromPoint and shadow.elementsFromPoint must return the shadow host and its ancestors of the hit-tested text node when the hit-tested text node is a direct child of the root and the host has display: inline-block >+FAIL document.elementsFromPoint and shadowRoot.elementsFromPoint must return the shadow host and its ancestors when the hit-tested text node is assigned to a slot and the host has display: inline assert_array_equals: property 0, expected Element node <test-element style="display: inline;">text</test-element> but got Element node <slot></slot> >+FAIL document.elementsFromPoint and shadowRoot.elementsFromPoint must return the shadow host and its ancestors when the hit-tested text node is assigned to a slot and the host has display: block assert_array_equals: lengths differ, expected 4 got 5 >+FAIL document.elementsFromPoint and shadowRoot.elementsFromPoint must return the shadow host and its ancestors when the hit-tested text node is assigned to a slot and the host has display: inline-block assert_array_equals: lengths differ, expected 4 got 5 >+PASS document.elementsFromPoint and shadowRoot.elementsFromPoint must return the element assigned to a slot and its non-shadow ancestors when hit-tested text node under an element is assigned to a slot in the shadow tree and the shadow host of the slot has display: inline >+PASS document.elementsFromPoint and shadowRoot.elementsFromPoint must return the element assigned to a slot and its non-shadow ancestors when hit-tested text node under an element is assigned to a slot in the shadow tree and the shadow host of the slot has display: block >+PASS document.elementsFromPoint and shadowRoot.elementsFromPoint must return the element assigned to a slot and its non-shadow ancestors when hit-tested text node under an element is assigned to a slot in the shadow tree and the shadow host of the slot has display: inline-block >+FAIL document.elementsFromPoint must return the shadow host and its ancestors of the hit-tested element under a shadow root andshadowRoot.elementsFromPoint must return the element parent and its non-shadow ancestors of the hit-tested text node under the point when the shadow host has display: inline assert_array_equals: lengths differ, expected 5 got 4 >+PASS document.elementsFromPoint must return the shadow host and its ancestors of the hit-tested element under a shadow root andshadowRoot.elementsFromPoint must return the element parent and its non-shadow ancestors of the hit-tested text node under the point when the shadow host has display: block >+PASS document.elementsFromPoint must return the shadow host and its ancestors of the hit-tested element under a shadow root andshadowRoot.elementsFromPoint must return the element parent and its non-shadow ancestors of the hit-tested text node under the point when the shadow host has display: inline-block >+PASS document.elementsFromPoint must return the shadow host and its ancestors and shadowRoot.elementsFromPoint must return the slot parent of the fallback text and its non-shadow ancestors when the hit-tested text node is a fallback content and the host has display: inline >+PASS document.elementsFromPoint must return the shadow host and its ancestors and shadowRoot.elementsFromPoint must return the slot parent of the fallback text and its non-shadow ancestors when the hit-tested text node is a fallback content and the host has display: block >+PASS document.elementsFromPoint must return the shadow host and its ancestors and shadowRoot.elementsFromPoint must return the slot parent of the fallback text and its non-shadow ancestors when the hit-tested text node is a fallback content and the host has display: inline-block >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/DocumentOrShadowRoot-prototype-elementFromPoint.html b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/DocumentOrShadowRoot-prototype-elementFromPoint.html >new file mode 100644 >index 0000000000000000000000000000000000000000..8cefa41ae35b9e0b8b7b18ffca098c5a147d2dfd >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/DocumentOrShadowRoot-prototype-elementFromPoint.html >@@ -0,0 +1,236 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title>Shadow DOM and CSSOM View: Document.prototype.elementFromPoint</title> >+ <meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"> >+ <meta name="assert" content="DocumentOrShadowRoot must have elementFromPoint and must return retarget the result against the context object."> >+ <link rel="help" href="https://www.w3.org/TR/cssom-view-1/#dom-document-elementfrompoint"> >+ <link rel="help" href="https://www.w3.org/TR/shadow-dom/#extensions-to-the-documentorshadowroot-mixin"> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ </head> >+ <body> >+ <div id="container"></div> >+ <style> >+test-element { display: block; width: 100px; height: 100px; } >+ </style> >+ <script> >+ >+function pointInElement(node) { >+ let x = 5; >+ let y = 5; >+ do { >+ x += node.offsetLeft; >+ y += node.offsetTop; >+ node = node.offsetParent; >+ } while (node); >+ return [x, y]; >+} >+ >+const displayValues = ['inline', 'block', 'inline-block']; >+var container = document.getElementById('container'); >+ >+displayValues.forEach(function (displayValue) { >+ test(function () { >+ container.innerHTML = ''; >+ let host = document.createElement('test-element'); >+ host.style.display = displayValue; >+ let shadow = host.attachShadow({mode: 'closed'}); >+ shadow.innerHTML = 'hello'; >+ container.appendChild(host); >+ assert_equals(document.elementFromPoint(...pointInElement(host)), host); >+ assert_equals(shadow.elementFromPoint(...pointInElement(host)), host); >+ }, 'document.elementFromPoint and shadow.ElementFromPoint must return the shadow host of the hit-tested text node when the hit-tested text node is a direct child of the root and the host has display: ' + displayValue); >+}); >+ >+displayValues.forEach(function (displayValue) { >+ test(function () { >+ container.innerHTML = ''; >+ let host = document.createElement('test-element'); >+ host.style.display = displayValue; >+ let shadow = host.attachShadow({mode: 'closed'}); >+ shadow.innerHTML = '<slot></slot>'; >+ host.innerHTML = 'text'; >+ container.appendChild(host); >+ assert_equals(document.elementFromPoint(...pointInElement(host)), host); >+ assert_equals(shadow.elementFromPoint(...pointInElement(host)), host); >+ }, 'document.elementFromPoint and shadowRoot.elementFromPoint must return the shadow host when the hit-tested text node is assigned to a slot and the host has display: ' + displayValue); >+}); >+ >+displayValues.forEach(function (displayValue) { >+ test(function () { >+ container.innerHTML = ''; >+ let host = document.createElement('test-element'); >+ host.style.display = displayValue; >+ let shadow = host.attachShadow({mode: 'closed'}); >+ shadow.innerHTML = '<slot></slot>'; >+ host.innerHTML = '<span>text</span>'; >+ container.appendChild(host); >+ assert_equals(document.elementFromPoint(...pointInElement(host)), host.querySelector('span')); >+ assert_equals(shadow.elementFromPoint(...pointInElement(host)), host.querySelector('span')); >+ }, 'document.elementFromPoint and shadowRoot.elementFromPoint must return the element assigned to a slot when hit-tested text node under an element is assigned to a slot in the shadow tree and the shadow host of the slot has display: ' + displayValue); >+}); >+ >+displayValues.forEach(function (displayValue) { >+ test(function () { >+ container.innerHTML = ''; >+ let host = document.createElement('test-element'); >+ host.style.display = displayValue; >+ let shadow = host.attachShadow({mode: 'closed'}); >+ shadow.innerHTML = '<span>text</span>'; >+ container.appendChild(host); >+ assert_equals(document.elementFromPoint(...pointInElement(host)), host); >+ assert_equals(shadow.elementFromPoint(...pointInElement(host)), shadow.querySelector('span')); >+ }, 'document.elementFromPoint must return the shadow host of the hit-tested element under a shadow root and shadowRoot.elementFromPoint must return the element parent of the hit-tested text node under the point when the shadow host has display: ' + displayValue); >+}); >+ >+displayValues.forEach(function (displayValue) { >+ test(function () { >+ container.innerHTML = ''; >+ let host = document.createElement('test-element'); >+ host.style.display = displayValue; >+ let shadow = host.attachShadow({mode: 'closed'}); >+ shadow.innerHTML = '<slot>fallback</slot>'; >+ container.appendChild(host); >+ assert_equals(document.elementFromPoint(...pointInElement(host)), host); >+ assert_equals(shadow.elementFromPoint(...pointInElement(host)), shadow.querySelector('slot')); >+ }, 'document.elementFromPoint must return the shadow host and shadowRoot.elementFromPoint must return the slot parent of the fallback text when the hit-tested text node is a fallback content and the host has display: ' + displayValue); >+}); >+ >+ >+ >+displayValues.forEach(function (displayValue) { >+ test(function () { >+ container.innerHTML = ''; >+ let host = document.createElement('test-element'); >+ host.style.display = displayValue; >+ let shadow = host.attachShadow({mode: 'closed'}); >+ shadow.innerHTML = '<slot></slot>'; >+ host.innerHTML = '<inner-host>hello</inner-host>'; >+ container.appendChild(host); >+ >+ let innerHost = host.querySelector('inner-host'); >+ let innerShadow = innerHost.attachShadow({mode: 'closed'}); >+ innerShadow.innerHTML = '<slot></slot>'; >+ assert_equals(document.elementFromPoint(...pointInElement(host)), innerHost); >+ assert_equals(shadow.elementFromPoint(...pointInElement(host)), innerHost); >+ assert_equals(innerShadow.elementFromPoint(...pointInElement(host)), innerHost); >+ }, 'document.elementFromPoint, shadowRoot.elementFromPoint, innerShadow.elementFromPoint must return a child element assigned to a slot' >+ + ' when the hit-tested text node is assigned to a slot in the shadow tree of the child element and the outer shadow host has display: ' + displayValue); >+}); >+ >+displayValues.forEach(function (displayValue) { >+ test(function () { >+ container.innerHTML = ''; >+ let host = document.createElement('test-element'); >+ host.style.display = displayValue; >+ let shadow = host.attachShadow({mode: 'closed'}); >+ shadow.innerHTML = '<slot></slot>'; >+ host.innerHTML = '<inner-host></inner-host>'; >+ container.appendChild(host); >+ >+ let innerHost = host.querySelector('inner-host'); >+ let innerShadow = innerHost.attachShadow({mode: 'closed'}); >+ innerShadow.innerHTML = 'hello'; >+ assert_equals(document.elementFromPoint(...pointInElement(host)), innerHost); >+ assert_equals(shadow.elementFromPoint(...pointInElement(host)), innerHost); >+ assert_equals(innerShadow.elementFromPoint(...pointInElement(host)), innerHost); >+ }, 'document.elementFromPoint, shadowRoot.elementFromPoint, innerShadow.elementFromPoint must return a child element with its own shadow tree assigned to a slot' >+ + ' when the hit-tested text node is its direct child and the outer shadow host has display: ' + displayValue); >+}); >+ >+displayValues.forEach(function (displayValue) { >+ test(function () { >+ container.innerHTML = ''; >+ let host = document.createElement('test-element'); >+ host.style.display = displayValue; >+ let shadow = host.attachShadow({mode: 'closed'}); >+ shadow.innerHTML = '<slot></slot>'; >+ host.innerHTML = '<inner-host></inner-host>'; >+ container.appendChild(host); >+ >+ let innerHost = host.querySelector('inner-host'); >+ let innerShadow = innerHost.attachShadow({mode: 'closed'}); >+ innerShadow.innerHTML = '<span>hello</span>'; >+ >+ assert_equals(document.elementFromPoint(...pointInElement(host)), innerHost); >+ assert_equals(shadow.elementFromPoint(...pointInElement(host)), innerHost); >+ assert_equals(innerShadow.elementFromPoint(...pointInElement(host)), innerShadow.querySelector('span')); >+ }, 'document.elementFromPoint, shadowRoot.elementFromPoint must return a child element with its own shadow tree assigned to a slot' >+ + ' when the hit-tested text node is a child of another element and innerShadow.elementFromPoint must return the parent element of the hit-tested text node under it when the outer shadow host has display: ' + displayValue); >+}); >+ >+displayValues.forEach(function (displayValue) { >+ test(function () { >+ container.innerHTML = ''; >+ let host = document.createElement('test-element'); >+ host.style.display = displayValue; >+ let shadow = host.attachShadow({mode: 'closed'}); >+ shadow.innerHTML = 'hello'; >+ container.appendChild(host); >+ assert_array_equals(document.elementsFromPoint(...pointInElement(host)), [host, container, document.body, document.documentElement]); >+ assert_array_equals(shadow.elementsFromPoint(...pointInElement(host)), [host, container, document.body, document.documentElement]); >+ }, 'document.elementsFromPoint and shadow.elementsFromPoint must return the shadow host and its ancestors of the hit-tested text node when the hit-tested text node is a direct child of the root and the host has display: ' + displayValue); >+}); >+ >+displayValues.forEach(function (displayValue) { >+ test(function () { >+ container.innerHTML = ''; >+ let host = document.createElement('test-element'); >+ host.style.display = displayValue; >+ let shadow = host.attachShadow({mode: 'closed'}); >+ shadow.innerHTML = '<slot></slot>'; >+ host.innerHTML = 'text'; >+ container.appendChild(host); >+ assert_array_equals(document.elementsFromPoint(...pointInElement(host)), [host, container, document.body, document.documentElement]); >+ assert_array_equals(shadow.elementsFromPoint(...pointInElement(host)), [host, container, document.body, document.documentElement]); >+ },'document.elementsFromPoint and shadowRoot.elementsFromPoint must return the shadow host and its ancestors when the hit-tested text node is assigned to a slot and the host has display: ' + displayValue); >+}); >+ >+displayValues.forEach(function (displayValue) { >+ test(function () { >+ container.innerHTML = ''; >+ let host = document.createElement('test-element'); >+ host.style.display = displayValue; >+ let shadow = host.attachShadow({mode: 'closed'}); >+ shadow.innerHTML = '<div><slot></slot></div>'; >+ host.innerHTML = '<span>text</span>'; >+ container.appendChild(host); >+ assert_array_equals(document.elementsFromPoint(...pointInElement(host)), [host.querySelector('span'), host, container, document.body, document.documentElement]); >+ assert_array_equals(shadow.elementsFromPoint(...pointInElement(host)), [host.querySelector('span'), shadow.querySelector('div'), host, container, document.body, document.documentElement]); >+ }, 'document.elementsFromPoint and shadowRoot.elementsFromPoint must return the element assigned to a slot and its non-shadow ancestors when hit-tested text node under an element is assigned to a slot in the shadow tree and the shadow host of the slot has display: ' + displayValue); >+}); >+ >+displayValues.forEach(function (displayValue) { >+ test(function () { >+ container.innerHTML = ''; >+ let host = document.createElement('test-element'); >+ host.style.display = displayValue; >+ let shadow = host.attachShadow({mode: 'closed'}); >+ shadow.innerHTML = '<span>text</span>'; >+ container.appendChild(host); >+ assert_array_equals(document.elementsFromPoint(...pointInElement(host)), [host, container, document.body, document.documentElement]); >+ assert_array_equals(shadow.elementsFromPoint(...pointInElement(host)), [shadow.querySelector('span'), host, container, document.body, document.documentElement]); >+ }, 'document.elementsFromPoint must return the shadow host and its ancestors of the hit-tested element under a shadow root and' >+ + 'shadowRoot.elementsFromPoint must return the element parent and its non-shadow ancestors of the hit-tested text node under the point when the shadow host has display: ' + displayValue); >+}); >+ >+displayValues.forEach(function (displayValue) { >+ test(function () { >+ container.innerHTML = ''; >+ let host = document.createElement('test-element'); >+ host.style.display = displayValue; >+ let shadow = host.attachShadow({mode: 'closed'}); >+ shadow.innerHTML = '<div><slot>fallback</slot></div>'; >+ container.appendChild(host); >+ assert_array_equals(document.elementsFromPoint(...pointInElement(host)), [host, container, document.body, document.documentElement]); >+ assert_array_equals(shadow.elementsFromPoint(...pointInElement(host)), [shadow.querySelector('slot'), shadow.querySelector('div'), host, container, document.body, document.documentElement]); >+ }, 'document.elementsFromPoint must return the shadow host and its ancestors and shadowRoot.elementsFromPoint must return the slot parent of the fallback text and its non-shadow ancestors when the hit-tested text node is a fallback content and the host has display: ' + displayValue); >+}); >+ >+container.innerHTML = ''; >+ >+ </script> >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Element-interface-attachShadow-custom-element-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Element-interface-attachShadow-custom-element-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..3ebd606875d35a1fe70dfde3e6fc7bd6bb7b2dfd >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Element-interface-attachShadow-custom-element-expected.txt >@@ -0,0 +1,4 @@ >+ >+PASS Element.attachShadow must create an instance of ShadowRoot for autonomous custom elements >+PASS Element.attachShadow must throw a NotSupportedError for customized built-in elements >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Element-interface-attachShadow-custom-element.html b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Element-interface-attachShadow-custom-element.html >new file mode 100644 >index 0000000000000000000000000000000000000000..b59460e17b97353154ddfb083f9abe118100ad11 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Element-interface-attachShadow-custom-element.html >@@ -0,0 +1,29 @@ >+<!DOCTYPE html> >+<title>Shadow DOM: Attaching a ShadowRoot for custom elements</title> >+<meta name="author" title="Hayato Ito" href="mailto:hayato@chromium.org"> >+<link rel="help" href="https://dom.spec.whatwg.org/#dom-element-attachshadow"> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+class MyAutonomousCustomElement extends HTMLElement { >+} >+ >+customElements.define('my-custom', MyAutonomousCustomElement); >+ >+test(() => { >+ assert_true(document.createElement('my-custom').attachShadow({mode: "open"}) instanceof ShadowRoot); >+}, 'Element.attachShadow must create an instance of ShadowRoot for autonomous custom elements'); >+ >+class MyCustomizedBuiltinElement extends HTMLInputElement { >+} >+ >+customElements.define('my-input', MyCustomizedBuiltinElement, { extends: 'input' }); >+ >+test(() => { >+ assert_throws({'name': 'NotSupportedError'}, () => { >+ document.createElement('input', {is: 'my-input'}).attachShadow({mode: "open"}); >+ }); >+}, 'Element.attachShadow must throw a NotSupportedError for customized built-in elements'); >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Extensions-to-Event-Interface-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Extensions-to-Event-Interface-expected.txt >index bf7d58dc76bdec49669f6dcbf40aceb1a0d8003a..ac15308bc491bcb332e5e1bad0e870127b1dc9aa 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Extensions-to-Event-Interface-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Extensions-to-Event-Interface-expected.txt >@@ -1,8 +1,6 @@ > >-PASS composedPath() must exist on Event > PASS composedPath() must return an empty array when the event has not been dispatched > PASS composedPath() must return an empty array when the event is no longer dispatched >-PASS composed must exist on Event > PASS composed on EventInit must default to false > PASS composed on EventInit must set the composed flag > FAIL The event must propagate out of open mode shadow boundaries when the composed flag is set assert_array_equals: value is 5, expected array >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Extensions-to-Event-Interface.html b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Extensions-to-Event-Interface.html >index 37d07a777cde4cd13ce2f115b81a89f7f9bad901..52cda0b6bb863cf5f09d9752874165656bfc3fe3 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Extensions-to-Event-Interface.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Extensions-to-Event-Interface.html >@@ -13,11 +13,6 @@ > <div id="log"></div> > <script> > >-test(function () { >- assert_true('composedPath' in Event.prototype); >- assert_true('composedPath' in new Event('my-event')); >-}, 'composedPath() must exist on Event'); >- > test(function () { > var event = new Event('my-event'); > assert_array_equals(event.composedPath(), []); >@@ -29,11 +24,6 @@ test(function () { > assert_array_equals(event.composedPath(), []); > }, 'composedPath() must return an empty array when the event is no longer dispatched'); > >-test(function () { >- assert_true('composed' in Event.prototype); >- assert_true('composed' in new Event('my-event')); >-}, 'composed must exist on Event'); >- > test(function () { > var event = new Event('my-event'); > assert_false(event.composed); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/event-composed-path-after-dom-mutation-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/event-composed-path-after-dom-mutation-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..ed42c8e7a9a17dab78739989989621522b83308b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/event-composed-path-after-dom-mutation-expected.txt >@@ -0,0 +1,4 @@ >+ >+FAIL Event.composedPath() should return the same result even if DOM is mutated (1/2) assert_array_equals: lengths differ, expected 3 got 2 >+FAIL Event.composedPath() should return the same result even if DOM is mutated (2/2) assert_array_equals: lengths differ, expected 5 got 2 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/event-composed-path-after-dom-mutation.html b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/event-composed-path-after-dom-mutation.html >new file mode 100644 >index 0000000000000000000000000000000000000000..fd129e036af711b1fa4f9a42fabcc344200fc2d6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/event-composed-path-after-dom-mutation.html >@@ -0,0 +1,59 @@ >+<!DOCTYPE html> >+<title>Shadow DOM: Event.composedPath() should return the same result even if DOM is mutated</title> >+<meta name="author" title="Hayato Ito" href="mailto:hayato@google.com"> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/shadow-dom.js"></script> >+ >+<div id="test1"> >+ <div id="host"> >+ <template id="sr" data-mode="closed"> >+ <div id="target"></div> >+ </template> >+ </div> >+</div> >+ >+<script> >+async_test((t) => { >+ const n = createTestTree(document.querySelector('#test1')); >+ n.host.addEventListener('my-event', t.step_func((e) => { >+ const path_before = e.composedPath(); >+ // Move the target out of a closed shadow tree >+ n.host.append(n.target); >+ const path_after = e.composedPath(); >+ assert_array_equals(path_before, path_after); >+ t.done(); >+ })); >+ const event = new Event('my-event', { bubbles: true, composed: true }); >+ n.target.dispatchEvent(event); >+}, 'Event.composedPath() should return the same result even if DOM is mutated (1/2)'); >+</script> >+ >+<div id="test2"> >+ <div id="host1"> >+ <template id="sr1" data-mode="closed"> >+ <div id="host2"> >+ <template id="sr2" data-mode="open"> >+ <div id="target"></div> >+ </template> >+ </div> >+ </template> >+ </div> >+</div> >+ >+<script> >+async_test((t) => { >+ const n = createTestTree(document.querySelector('#test2')); >+ n.host1.addEventListener('my-event', t.step_func((e) => { >+ const path_before = e.composedPath(); >+ // Move nodes out of a closed shadow tree >+ n.host1.append(n.host2); >+ n.host1.append(n.target); >+ const path_after = e.composedPath(); >+ assert_array_equals(path_before, path_after); >+ t.done(); >+ })); >+ const event = new Event('my-event', { bubbles: true, composed: true }); >+ n.target.dispatchEvent(event); >+}, 'Event.composedPath() should return the same result even if DOM is mutated (2/2)'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/form-control-form-attribute-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/form-control-form-attribute-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..6583e246e1ec78c2b11e9c1c3cb94bb32448fcf4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/form-control-form-attribute-expected.txt >@@ -0,0 +1,7 @@ >+form >+ >+ >+PASS Form control's form attribute should point to the form element. >+FAIL Shadow form control's form attribute should work also in shadow DOM. assert_equals: expected null but got Element node <form id="form">form</form> >+PASS Form element as form control's ancestor should work also in shadow DOM. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/form-control-form-attribute.html b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/form-control-form-attribute.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2e782b2587d8dc6b71deee7d229ed4e8a996703c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/form-control-form-attribute.html >@@ -0,0 +1,80 @@ >+<!doctype html> >+<meta charset=utf-8> >+<title>Form controls' form attribute</title> >+<script src=/resources/testharness.js></script> >+<script src=/resources/testharnessreport.js></script> >+<div id="testcontent"> >+ <form id="form">form</form> >+ <input id="input" form="form"> >+</div> >+ >+<script> >+ >+test(() => { >+ assert_equals(document.getElementById('input').form, >+ document.getElementById('form')); >+}, "Form control's form attribute should point to the form element."); >+ >+test(() => { >+ var testcontent = document.getElementById("testcontent"); >+ var host = document.createElement("div"); >+ var sr = host.attachShadow({mode: "open"}); >+ sr.innerHTML = testcontent.innerHTML; >+ var input = sr.getElementById("input"); >+ var form = sr.getElementById("form"); >+ >+ // Should have null form when shadow DOM isn't connected. >+ assert_equals(input.form, null); >+ >+ testcontent.appendChild(host); >+ assert_equals(input.form, form); >+ >+ host.remove(); >+ assert_equals(input.form, null); >+ >+ testcontent.appendChild(host); >+ assert_equals(input.form, form); >+ >+ input.remove(); >+ assert_equals(input.form, null); >+ >+ sr.appendChild(input); >+ assert_equals(input.form, form); >+ >+ form.id = "foobar"; >+ assert_equals(input.form, null); >+ >+ form.id = "form"; >+ assert_equals(input.form, form); >+ >+ form.remove(); >+ assert_equals(input.form, null); >+ >+ sr.appendChild(form); >+ assert_equals(input.form, form); >+ >+ host.remove(); >+}, "Shadow form control's form attribute should work also in shadow DOM."); >+ >+test(() => { >+ var testcontent = document.getElementById("testcontent"); >+ var host = document.createElement("div"); >+ var sr = host.attachShadow({mode: "open"}); >+ sr.innerHTML = "<form id='form'><input id='input'></form>"; >+ var input = sr.getElementById("input"); >+ var form = sr.getElementById("form"); >+ >+ assert_equals(input.form, form); >+ >+ input.remove(); >+ assert_equals(input.form, null); >+ >+ form.appendChild(input); >+ assert_equals(input.form, form); >+ >+ form.remove(); >+ assert_equals(input.form, form); >+ >+ host.remove(); >+}, "Form element as form control's ancestor should work also in shadow DOM."); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/input-element-list-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/input-element-list-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..978159e5341c9905f522561459254e433d582f69 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/input-element-list-expected.txt >@@ -0,0 +1,5 @@ >+ >+ >+FAIL Input element's list attribute should point to the datalist element. assert_equals: expected (object) null but got (undefined) undefined >+FAIL Input element's list attribute should point to the datalist element in Shadow DOM. assert_equals: expected (object) null but got (undefined) undefined >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/input-element-list.html b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/input-element-list.html >new file mode 100644 >index 0000000000000000000000000000000000000000..b571534eb0d6f3f57cfbec3e706648b19848b6d6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/input-element-list.html >@@ -0,0 +1,39 @@ >+<!doctype html> >+<meta charset=utf-8> >+<title>Input.list</title> >+<script src=/resources/testharness.js></script> >+<script src=/resources/testharnessreport.js></script> >+<div id="testcontent"> >+ <input id="input" list="datalist"> >+</div> >+<script> >+ >+test(() => { >+ assert_equals(document.getElementById('input').list, null); >+ var dl = document.createElement("datalist"); >+ dl.id = "datalist"; >+ document.getElementById("testcontent").appendChild(dl); >+ assert_equals(document.getElementById('input').list, dl); >+}, "Input element's list attribute should point to the datalist element."); >+ >+ >+test(() => { >+ var host = document.createElement("div"); >+ document.getElementById("testcontent").appendChild(host); >+ var sr = host.attachShadow({mode: "open"}); >+ var input = document.createElement("input"); >+ input.setAttribute("list", "datalist"); >+ sr.appendChild(input); >+ assert_equals(input.list, null); >+ >+ var dl = document.createElement("datalist"); >+ dl.id = "datalist"; >+ sr.appendChild(dl); >+ assert_equals(input.list, dl); >+ >+ dl.remove(); >+ assert_equals(input.list, null); >+}, "Input element's list attribute should point to the datalist element in Shadow DOM."); >+ >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/layout-slot-no-longer-assigned-expected.html b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/layout-slot-no-longer-assigned-expected.html >new file mode 100644 >index 0000000000000000000000000000000000000000..0e76edd65b7baf5316fc9d0c4da59a3502e4c27a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/layout-slot-no-longer-assigned-expected.html >@@ -0,0 +1 @@ >+<!DOCTYPE html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/layout-slot-no-longer-assigned.html b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/layout-slot-no-longer-assigned.html >new file mode 100644 >index 0000000000000000000000000000000000000000..dfcac99da023ec2bbd94835f71efaef952a62341 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/layout-slot-no-longer-assigned.html >@@ -0,0 +1,15 @@ >+<!DOCTYPE html> >+<title>Layout using slot elements</title> >+<link rel="author" title="Hayato Ito" href="mailto:hayato@google.com"/> >+<link rel="help" href="https://dom.spec.whatwg.org/#shadow-tree-slots"> >+<link rel="match" href="reference/empty.html"/> >+<div id="host"></div> >+<script> >+const host = document.querySelector('#host'); >+const sr = host.attachShadow({ mode: 'open' }); >+sr.innerHTML = '<slot name=s1></slot>' >+host.innerHTML = '<div id=d1 slot=s1></div>'; >+ >+document.body.offsetLeft; >+document.querySelector('#d1').setAttribute('slot', 's2'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/layout-slot-no-longer-fallback-expected.html b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/layout-slot-no-longer-fallback-expected.html >new file mode 100644 >index 0000000000000000000000000000000000000000..0e76edd65b7baf5316fc9d0c4da59a3502e4c27a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/layout-slot-no-longer-fallback-expected.html >@@ -0,0 +1 @@ >+<!DOCTYPE html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/layout-slot-no-longer-fallback.html b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/layout-slot-no-longer-fallback.html >new file mode 100644 >index 0000000000000000000000000000000000000000..7507f11ac18e6590367a147acbc78834b0d19afd >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/layout-slot-no-longer-fallback.html >@@ -0,0 +1,15 @@ >+<!DOCTYPE html> >+<title>Layout using slot elements</title> >+<link rel="author" title="Hayato Ito" href="mailto:hayato@google.com"/> >+<link rel="help" href="https://dom.spec.whatwg.org/#shadow-tree-slots"> >+<link rel="match" href="reference/empty.html"/> >+<div id="host"></div> >+<script> >+const host = document.querySelector('#host'); >+const sr = host.attachShadow({ mode: 'open' }); >+ >+sr.innerHTML = '<slot><div id="fallback">Should not be displayed</div></slot>' >+ >+document.body.offsetLeft; >+host.appendChild(document.createElement('div')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/resources/event-path-test-helpers.js b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/resources/event-path-test-helpers.js >index 17d6fff662b9f9d80a693767809c49e16643dcf4..f0e8ec33ff7162169c00e877f9aba3bba45aebac 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/resources/event-path-test-helpers.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/resources/event-path-test-helpers.js >@@ -16,9 +16,6 @@ function dispatchEventWithEventLog(shadow, target, event) { > eventPath.push(this.label); > relatedTargets.push(event.relatedTarget ? event.relatedTarget.label : null); > >- if (!event.composedPath) // Don't fail all tests just for the lack of composedPath. >- return; >- > pathAtTargets.push(event.composedPath().map(function (node) { return node.label; })); > targets.push(event.target); > }).bind(node)); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/slotchange-event-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/slotchange-event-expected.txt >index 9c31efce7f29bf4f5c6e17950879163cf6bc34dd..972fd9c9fe10aaa33ddb57e218c326ea64595777 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/slotchange-event-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/slotchange-event-expected.txt >@@ -1,7 +1,7 @@ >-CONSOLE MESSAGE: line 2659: Error: assert_equals: slotchange must not be fired on a slot element if the assigned nodes changed after the slot was removed expected 2 but got 0 >-CONSOLE MESSAGE: line 2659: Error: assert_equals: slotchange must not be fired on a slot element if the assigned nodes changed after the slot was removed expected 2 but got 0 >-CONSOLE MESSAGE: line 2659: Error: assert_equals: slotchange must not be fired on a slot element if the assigned nodes changed after the slot was removed expected 2 but got 0 >-CONSOLE MESSAGE: line 2659: Error: assert_equals: slotchange must not be fired on a slot element if the assigned nodes changed after the slot was removed expected 2 but got 0 >+CONSOLE MESSAGE: line 2748: Error: assert_equals: slotchange must not be fired on a slot element if the assigned nodes changed after the slot was removed expected 2 but got 0 >+CONSOLE MESSAGE: line 2748: Error: assert_equals: slotchange must not be fired on a slot element if the assigned nodes changed after the slot was removed expected 2 but got 0 >+CONSOLE MESSAGE: line 2748: Error: assert_equals: slotchange must not be fired on a slot element if the assigned nodes changed after the slot was removed expected 2 but got 0 >+CONSOLE MESSAGE: line 2748: Error: assert_equals: slotchange must not be fired on a slot element if the assigned nodes changed after the slot was removed expected 2 but got 0 > > Harness Error (FAIL), message = Error: assert_equals: slotchange must not be fired on a slot element if the assigned nodes changed after the slot was removed expected 2 but got 0 > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/w3c-import.log >index b7026b1275667020d2c806669756d296134b62cd..9aafc495e918984e3fdcc543e777e3a367620129 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/w3c-import.log >@@ -17,6 +17,8 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Document-prototype-adoptNode.html > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Document-prototype-currentScript.html > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Document-prototype-importNode.html >+/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/DocumentOrShadowRoot-prototype-elementFromPoint.html >+/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Element-interface-attachShadow-custom-element.html > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Element-interface-attachShadow.html > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Element-interface-shadowRoot-attribute.html > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Extensions-to-Event-Interface.html >@@ -27,6 +29,7 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Range-prototype-insertNode.html > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/ShadowRoot-interface.html > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/Slotable-interface.html >+/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/event-composed-path-after-dom-mutation.html > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/event-composed-path-with-related-target.html > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/event-composed-path.html > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/event-composed.html >@@ -34,7 +37,13 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/event-inside-slotted-node.html > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/event-post-dispatch.html > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/event-with-related-target.html >+/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/form-control-form-attribute.html > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/historical.html >+/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/input-element-list.html >+/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/layout-slot-no-longer-assigned-expected.html >+/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/layout-slot-no-longer-assigned.html >+/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/layout-slot-no-longer-fallback-expected.html >+/LayoutTests/imported/w3c/web-platform-tests/shadow-dom/layout-slot-no-longer-fallback.html > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/scroll-to-the-fragment-in-shadow-tree.html > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/slotchange-customelements.html > /LayoutTests/imported/w3c/web-platform-tests/shadow-dom/slotchange-event.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/generate-test-wrappers.js b/LayoutTests/imported/w3c/web-platform-tests/streams/generate-test-wrappers.js >index 4a406fe75c2ee37b689b3a7c8a3fa7f1ed18230b..22e5c786bbc4d755805f35eb0bdc957dad1c90db 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/streams/generate-test-wrappers.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/generate-test-wrappers.js >@@ -8,7 +8,7 @@ > // > // It will turn any importScripts inside the .js file into <script>s in the browser context wrapper. > // >-// This could become obsolete if https://github.com/w3c/web-platform-tests/issues/4210 gets fixed, >+// This could become obsolete if https://github.com/web-platform-tests/wpt/issues/4210 gets fixed, > // allowing .any.js to work with all four contexts. > > const fs = require("fs"); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/general-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/general-expected.txt >index 1d91127e666218804eeee661a65f2788f1909c8d..8e102745fb8ec4e276aa0aee4390709c924e9ff9 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/general-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/general-expected.txt >@@ -1,14 +1,14 @@ > CONSOLE MESSAGE: line 16: Unhandled Promise Rejection: TypeError: The WritableStream.ready getter can only be used on instances of WritableStream >-CONSOLE MESSAGE: line 2890: TypeError: undefined is not an object (evaluating 'e.error') >+CONSOLE MESSAGE: line 2970: TypeError: undefined is not an object (evaluating 'e.error') > CONSOLE MESSAGE: Unhandled Promise Rejection: undefined >-CONSOLE MESSAGE: line 2890: TypeError: undefined is not an object (evaluating 'e.error') >+CONSOLE MESSAGE: line 2970: TypeError: undefined is not an object (evaluating 'e.error') > CONSOLE MESSAGE: Unhandled Promise Rejection: undefined > CONSOLE MESSAGE: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream >-CONSOLE MESSAGE: line 2890: TypeError: undefined is not an object (evaluating 'e.error') >+CONSOLE MESSAGE: line 2970: TypeError: undefined is not an object (evaluating 'e.error') > CONSOLE MESSAGE: Unhandled Promise Rejection: undefined >-CONSOLE MESSAGE: line 2890: TypeError: undefined is not an object (evaluating 'e.error') >+CONSOLE MESSAGE: line 2970: TypeError: undefined is not an object (evaluating 'e.error') > CONSOLE MESSAGE: Unhandled Promise Rejection: undefined >-CONSOLE MESSAGE: line 2890: TypeError: undefined is not an object (evaluating 'e.error') >+CONSOLE MESSAGE: line 2970: TypeError: undefined is not an object (evaluating 'e.error') > CONSOLE MESSAGE: Unhandled Promise Rejection: undefined > > Harness Error (FAIL), message = The WritableStream.ready getter can only be used on instances of WritableStream >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..f4f8083ee8ffec8cef11b76ba2b22f7d3c10cb4e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request-expected.txt >@@ -0,0 +1,18 @@ >+ >+PASS ReadableStreamBYOBRequest constructor should throw when passed a undefined ReadableByteStreamController and a undefined view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a undefined ReadableByteStreamController and a null view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a undefined ReadableByteStreamController and a fake view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a undefined ReadableByteStreamController and a real view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a null ReadableByteStreamController and a undefined view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a null ReadableByteStreamController and a null view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a null ReadableByteStreamController and a fake view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a null ReadableByteStreamController and a real view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a fake ReadableByteStreamController and a undefined view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a fake ReadableByteStreamController and a null view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a fake ReadableByteStreamController and a fake view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a fake ReadableByteStreamController and a real view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a real ReadableByteStreamController and a undefined view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a real ReadableByteStreamController and a null view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a real ReadableByteStreamController and a fake view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a real ReadableByteStreamController and a real view >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.dedicatedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.dedicatedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..f4f8083ee8ffec8cef11b76ba2b22f7d3c10cb4e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.dedicatedworker-expected.txt >@@ -0,0 +1,18 @@ >+ >+PASS ReadableStreamBYOBRequest constructor should throw when passed a undefined ReadableByteStreamController and a undefined view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a undefined ReadableByteStreamController and a null view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a undefined ReadableByteStreamController and a fake view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a undefined ReadableByteStreamController and a real view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a null ReadableByteStreamController and a undefined view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a null ReadableByteStreamController and a null view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a null ReadableByteStreamController and a fake view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a null ReadableByteStreamController and a real view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a fake ReadableByteStreamController and a undefined view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a fake ReadableByteStreamController and a null view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a fake ReadableByteStreamController and a fake view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a fake ReadableByteStreamController and a real view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a real ReadableByteStreamController and a undefined view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a real ReadableByteStreamController and a null view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a real ReadableByteStreamController and a fake view >+PASS ReadableStreamBYOBRequest constructor should throw when passed a real ReadableByteStreamController and a real view >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.dedicatedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.dedicatedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..887e3343d210bb20628eac80822e05b0833e2b32 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.dedicatedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>construct-byob-request.js dedicated worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new Worker('construct-byob-request.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.html >new file mode 100644 >index 0000000000000000000000000000000000000000..4e071e70c56600f8828a9772a6858cbb054e2301 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.html >@@ -0,0 +1,10 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>construct-byob-request.js browser context wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script src="../resources/rs-utils.js"></script> >+ >+<script src="construct-byob-request.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.js b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.js >new file mode 100644 >index 0000000000000000000000000000000000000000..29fdac5baa9c8715868b74b4e4cecde2459a2467 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.js >@@ -0,0 +1,82 @@ >+'use strict'; >+ >+// Prior to whatwg/stream#870 it was possible to construct a ReadableStreamBYOBRequest directly. This made it possible >+// to construct requests that were out-of-sync with the state of the ReadableStream. They could then be used to call >+// internal operations, resulting in asserts or bad behaviour. This file contains regression tests for the change. >+ >+if (self.importScripts) { >+ self.importScripts('../resources/rs-utils.js'); >+ self.importScripts('/resources/testharness.js'); >+} >+ >+function getRealByteStreamController() { >+ let controller; >+ new ReadableStream({ >+ start(c) { >+ controller = c; >+ }, >+ type: 'bytes' >+ }); >+ return controller; >+} >+ >+const ReadableByteStreamController = getRealByteStreamController().constructor; >+ >+// Create an object pretending to have prototype |prototype|, of type |type|. |type| is one of "undefined", "null", >+// "fake", or "real". "real" will call the realObjectCreator function to get a real instance of the object. >+function createDummyObject(prototype, type, realObjectCreator) { >+ switch (type) { >+ case 'undefined': >+ return undefined; >+ >+ case 'null': >+ return null; >+ >+ case 'fake': >+ return Object.create(prototype); >+ >+ case 'real': >+ return realObjectCreator(); >+ } >+ >+ throw new Error('not reached'); >+} >+ >+const dummyTypes = ['undefined', 'null', 'fake', 'real']; >+ >+function runTests(ReadableStreamBYOBRequest) { >+ for (const controllerType of dummyTypes) { >+ const controller = createDummyObject(ReadableByteStreamController.prototype, controllerType, >+ getRealByteStreamController); >+ for (const viewType of dummyTypes) { >+ const view = createDummyObject(Uint8Array.prototype, viewType, () => new Uint8Array(16)); >+ test(() => { >+ assert_throws(new TypeError(), () => new ReadableStreamBYOBRequest(controller, view), >+ 'constructor should throw'); >+ }, `ReadableStreamBYOBRequest constructor should throw when passed a ${controllerType} ` + >+ `ReadableByteStreamController and a ${viewType} view`); >+ } >+ } >+} >+ >+function getConstructorAndRunTests() { >+ let ReadableStreamBYOBRequest; >+ const rs = new ReadableStream({ >+ pull(controller) { >+ const byobRequest = controller.byobRequest; >+ ReadableStreamBYOBRequest = byobRequest.constructor; >+ byobRequest.respond(4); >+ }, >+ type: 'bytes' >+ }); >+ rs.getReader({ mode: 'byob' }).read(new Uint8Array(8)).then(() => { >+ runTests(ReadableStreamBYOBRequest); >+ done(); >+ }); >+} >+ >+// We can only get at the ReadableStreamBYOBRequest constructor asynchronously, so we need to make the test harness wait >+// for us to explicitly tell it all our tests have run. >+setup({ explicit_done: true }); >+ >+getConstructorAndRunTests(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.serviceworker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.serviceworker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d8697d4e7645406841019be5aa83eb2df00e396d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.serviceworker.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+FAIL Service worker test setup assert_unreached: unregister and register should not fail: TypeError: ReadableByteStreamController is not implemented Reached unreachable code >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.serviceworker.https.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.serviceworker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..abf70cbf643b16ee73e24d092e3abfb2621ded11 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.serviceworker.https.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>construct-byob-request.js service worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> >+ >+<script> >+'use strict'; >+service_worker_test('construct-byob-request.js', 'Service worker test setup'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.sharedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.sharedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..e156ac515eb234236c32cae8df0c2552727b1843 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.sharedworker-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 10: ReferenceError: Can't find variable: SharedWorker >+ >+FAIL construct-byob-request.js shared worker wrapper file ReferenceError: Can't find variable: SharedWorker >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.sharedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.sharedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..6f7ef5ca59f6b8881389bb57e100903e793b01eb >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.sharedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>construct-byob-request.js shared worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new SharedWorker('construct-byob-request.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2b32ba61a286fc01e7b0b786217ba403f9cff507 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor-expected.txt >@@ -0,0 +1,18 @@ >+ >+FAIL ReadableStream constructor should stop after get on size fails assert_equals: operations should be performed in the right order expected "get on size" but got "get on type,get on highWaterMark,get on size" >+FAIL ReadableStream constructor should stop after get on highWaterMark fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark" but got "get on type,get on highWaterMark" >+FAIL ReadableStream constructor should stop after get on type fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type" but got "get on type" >+FAIL ReadableStream constructor should stop after validate on type fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type" but got "get on type" >+FAIL ReadableStream constructor should stop after validate on size fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type" but got "get on type,get on highWaterMark,get on size" >+FAIL ReadableStream constructor should stop after tonumber on highWaterMark fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark" >+FAIL ReadableStream constructor should stop after validate on highWaterMark fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark" >+FAIL ReadableStream constructor should stop after get on pull fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize,get on start" >+FAIL ReadableStream constructor should stop after validate on pull fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize,get on start" >+FAIL ReadableStream constructor should stop after get on cancel fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize,get on start" >+FAIL ReadableStream constructor should stop after validate on cancel fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize,get on start" >+FAIL ReadableStream constructor should stop after get on autoAllocateChunkSize fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on autoAllocateChunkSize" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on autoAllocateChunkSize" >+FAIL ReadableStream constructor should stop after tonumber on autoAllocateChunkSize fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize" >+FAIL ReadableStream constructor should stop after validate on autoAllocateChunkSize fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize" >+FAIL ReadableStream constructor should stop after get on start fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize,get on start" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize,get on start" >+FAIL ReadableStream constructor should stop after validate on start fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize,get on start" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize,get on start" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.dedicatedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.dedicatedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2b32ba61a286fc01e7b0b786217ba403f9cff507 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.dedicatedworker-expected.txt >@@ -0,0 +1,18 @@ >+ >+FAIL ReadableStream constructor should stop after get on size fails assert_equals: operations should be performed in the right order expected "get on size" but got "get on type,get on highWaterMark,get on size" >+FAIL ReadableStream constructor should stop after get on highWaterMark fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark" but got "get on type,get on highWaterMark" >+FAIL ReadableStream constructor should stop after get on type fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type" but got "get on type" >+FAIL ReadableStream constructor should stop after validate on type fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type" but got "get on type" >+FAIL ReadableStream constructor should stop after validate on size fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type" but got "get on type,get on highWaterMark,get on size" >+FAIL ReadableStream constructor should stop after tonumber on highWaterMark fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark" >+FAIL ReadableStream constructor should stop after validate on highWaterMark fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark" >+FAIL ReadableStream constructor should stop after get on pull fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize,get on start" >+FAIL ReadableStream constructor should stop after validate on pull fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize,get on start" >+FAIL ReadableStream constructor should stop after get on cancel fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize,get on start" >+FAIL ReadableStream constructor should stop after validate on cancel fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize,get on start" >+FAIL ReadableStream constructor should stop after get on autoAllocateChunkSize fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on autoAllocateChunkSize" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on autoAllocateChunkSize" >+FAIL ReadableStream constructor should stop after tonumber on autoAllocateChunkSize fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize" >+FAIL ReadableStream constructor should stop after validate on autoAllocateChunkSize fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize" >+FAIL ReadableStream constructor should stop after get on start fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize,get on start" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize,get on start" >+FAIL ReadableStream constructor should stop after validate on start fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize,get on start" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize,get on start" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.dedicatedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.dedicatedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..aebe97ef88a3dc6726756e37ece747d6a68ae498 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.dedicatedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>constructor.js dedicated worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new Worker('constructor.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.html >new file mode 100644 >index 0000000000000000000000000000000000000000..a548e088685affc72c67c5584d9ffac0a1f6e18a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.html >@@ -0,0 +1,10 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>constructor.js browser context wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script src="../resources/constructor-ordering.js"></script> >+ >+<script src="constructor.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.js b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.js >new file mode 100644 >index 0000000000000000000000000000000000000000..3405e23878c9ad8bafe17173e94f128145eda196 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.js >@@ -0,0 +1,53 @@ >+'use strict'; >+ >+if (self.importScripts) { >+ self.importScripts('/resources/testharness.js'); >+ self.importScripts('../resources/constructor-ordering.js'); >+} >+ >+const operations = [ >+ op('get', 'size'), >+ op('get', 'highWaterMark'), >+ op('get', 'type'), >+ op('validate', 'type'), >+ op('validate', 'size'), >+ op('tonumber', 'highWaterMark'), >+ op('validate', 'highWaterMark'), >+ op('get', 'pull'), >+ op('validate', 'pull'), >+ op('get', 'cancel'), >+ op('validate', 'cancel'), >+ op('get', 'autoAllocateChunkSize'), >+ op('tonumber', 'autoAllocateChunkSize'), >+ op('validate', 'autoAllocateChunkSize'), >+ op('get', 'start'), >+ op('validate', 'start') >+]; >+ >+for (const failureOp of operations) { >+ test(() => { >+ const record = new OpRecorder(failureOp); >+ const underlyingSource = createRecordingObjectWithProperties(record, ['start', 'pull', 'cancel']); >+ >+ // The valid value for "type" is "bytes", so set it separately. >+ defineCheckedProperty(record, underlyingSource, 'type', () => record.check('type') ? 'invalid' : 'bytes'); >+ >+ // autoAllocateChunkSize is a special case because it has a tonumber step. >+ defineCheckedProperty(record, underlyingSource, 'autoAllocateChunkSize', >+ () => createRecordingNumberObject(record, 'autoAllocateChunkSize')); >+ >+ const strategy = createRecordingStrategy(record); >+ >+ try { >+ new ReadableStream(underlyingSource, strategy); >+ assert_unreached('constructor should throw'); >+ } catch (e) { >+ assert_equals(typeof e, 'object', 'e should be an object'); >+ } >+ >+ assert_equals(record.actual(), expectedAsString(operations, failureOp), >+ 'operations should be performed in the right order'); >+ }, `ReadableStream constructor should stop after ${failureOp} fails`); >+} >+ >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.serviceworker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.serviceworker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..30139b0ab9fda6c547bf2aa5d612eee3426dcb5f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.serviceworker.https-expected.txt >@@ -0,0 +1,19 @@ >+ >+PASS Service worker test setup >+FAIL ReadableStream constructor should stop after get on size fails assert_equals: operations should be performed in the right order expected "get on size" but got "get on type" >+FAIL ReadableStream constructor should stop after get on highWaterMark fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark" but got "get on type" >+FAIL ReadableStream constructor should stop after get on type fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type" but got "get on type" >+FAIL ReadableStream constructor should stop after validate on type fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type" but got "get on type" >+FAIL ReadableStream constructor should stop after validate on size fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type" but got "get on type" >+FAIL ReadableStream constructor should stop after tonumber on highWaterMark fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark" but got "get on type" >+FAIL ReadableStream constructor should stop after validate on highWaterMark fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark" but got "get on type" >+FAIL ReadableStream constructor should stop after get on pull fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull" but got "get on type" >+FAIL ReadableStream constructor should stop after validate on pull fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull" but got "get on type" >+FAIL ReadableStream constructor should stop after get on cancel fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel" but got "get on type" >+FAIL ReadableStream constructor should stop after validate on cancel fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel" but got "get on type" >+FAIL ReadableStream constructor should stop after get on autoAllocateChunkSize fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on autoAllocateChunkSize" but got "get on type" >+FAIL ReadableStream constructor should stop after tonumber on autoAllocateChunkSize fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize" but got "get on type" >+FAIL ReadableStream constructor should stop after validate on autoAllocateChunkSize fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize" but got "get on type" >+FAIL ReadableStream constructor should stop after get on start fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize,get on start" but got "get on type" >+FAIL ReadableStream constructor should stop after validate on start fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on autoAllocateChunkSize,tonumber on autoAllocateChunkSize,get on start" but got "get on type" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.serviceworker.https.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.serviceworker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ddddf06652427a3f0c579e0c66518729a6820f36 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.serviceworker.https.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>constructor.js service worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> >+ >+<script> >+'use strict'; >+service_worker_test('constructor.js', 'Service worker test setup'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.sharedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.sharedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2e2954f1ccd19f38dd0318dbdef3b16aa374ea2c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.sharedworker-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 10: ReferenceError: Can't find variable: SharedWorker >+ >+FAIL constructor.js shared worker wrapper file ReferenceError: Can't find variable: SharedWorker >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.sharedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.sharedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..52b1a5daf99e8511dbca8335b05ed7dff9e270b7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.sharedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>constructor.js shared worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new SharedWorker('constructor.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/w3c-import.log >index 8937bbbb24cbf985ccb5150dd1e3419dd3b2a381..2fb645be481fa61b6f536aba7fc356c0a2c6282b 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/w3c-import.log >@@ -19,6 +19,16 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/brand-checks.js > /LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/brand-checks.serviceworker.https.html > /LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/brand-checks.sharedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.dedicatedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.js >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.serviceworker.https.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.sharedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.dedicatedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.js >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.serviceworker.https.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/constructor.sharedworker.html > /LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/detached-buffers.dedicatedworker.html > /LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/detached-buffers.html > /LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/detached-buffers.js >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..a0f194b8b1419ed697fe3e045e116df026e38532 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor-expected.txt >@@ -0,0 +1,15 @@ >+ >+FAIL ReadableStream constructor should stop after get on size fails assert_equals: operations should be performed in the right order expected "get on size" but got "get on type,get on highWaterMark,get on size" >+FAIL ReadableStream constructor should stop after get on highWaterMark fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark" but got "get on type,get on highWaterMark" >+FAIL ReadableStream constructor should stop after get on type fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type" but got "get on type" >+FAIL ReadableStream constructor should stop after validate on type fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type" but got "get on type" >+FAIL ReadableStream constructor should stop after validate on size fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type" but got "get on type,get on highWaterMark,get on size,get on highWaterMark" >+FAIL ReadableStream constructor should stop after tonumber on highWaterMark fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark" >+FAIL ReadableStream constructor should stop after validate on highWaterMark fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark" >+FAIL ReadableStream constructor should stop after get on pull fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on start" >+FAIL ReadableStream constructor should stop after validate on pull fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on start" >+FAIL ReadableStream constructor should stop after get on cancel fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on start" >+FAIL ReadableStream constructor should stop after validate on cancel fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on start" >+FAIL ReadableStream constructor should stop after get on start fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on start" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on start" >+FAIL ReadableStream constructor should stop after validate on start fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on start" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on start" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.dedicatedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.dedicatedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..a0f194b8b1419ed697fe3e045e116df026e38532 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.dedicatedworker-expected.txt >@@ -0,0 +1,15 @@ >+ >+FAIL ReadableStream constructor should stop after get on size fails assert_equals: operations should be performed in the right order expected "get on size" but got "get on type,get on highWaterMark,get on size" >+FAIL ReadableStream constructor should stop after get on highWaterMark fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark" but got "get on type,get on highWaterMark" >+FAIL ReadableStream constructor should stop after get on type fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type" but got "get on type" >+FAIL ReadableStream constructor should stop after validate on type fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type" but got "get on type" >+FAIL ReadableStream constructor should stop after validate on size fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type" but got "get on type,get on highWaterMark,get on size,get on highWaterMark" >+FAIL ReadableStream constructor should stop after tonumber on highWaterMark fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark" >+FAIL ReadableStream constructor should stop after validate on highWaterMark fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark" >+FAIL ReadableStream constructor should stop after get on pull fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on start" >+FAIL ReadableStream constructor should stop after validate on pull fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on start" >+FAIL ReadableStream constructor should stop after get on cancel fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on start" >+FAIL ReadableStream constructor should stop after validate on cancel fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on start" >+FAIL ReadableStream constructor should stop after get on start fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on start" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on start" >+FAIL ReadableStream constructor should stop after validate on start fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on start" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on start" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.dedicatedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.dedicatedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..aebe97ef88a3dc6726756e37ece747d6a68ae498 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.dedicatedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>constructor.js dedicated worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new Worker('constructor.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.html >new file mode 100644 >index 0000000000000000000000000000000000000000..a548e088685affc72c67c5584d9ffac0a1f6e18a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.html >@@ -0,0 +1,10 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>constructor.js browser context wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script src="../resources/constructor-ordering.js"></script> >+ >+<script src="constructor.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.js b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.js >new file mode 100644 >index 0000000000000000000000000000000000000000..c202f3b082c51b5ba1f841a8074d8edcfbdf1321 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.js >@@ -0,0 +1,42 @@ >+'use strict'; >+ >+if (self.importScripts) { >+ self.importScripts('/resources/testharness.js'); >+ self.importScripts('../resources/constructor-ordering.js'); >+} >+ >+const operations = [ >+ op('get', 'size'), >+ op('get', 'highWaterMark'), >+ op('get', 'type'), >+ op('validate', 'type'), >+ op('validate', 'size'), >+ op('tonumber', 'highWaterMark'), >+ op('validate', 'highWaterMark'), >+ op('get', 'pull'), >+ op('validate', 'pull'), >+ op('get', 'cancel'), >+ op('validate', 'cancel'), >+ op('get', 'start'), >+ op('validate', 'start') >+]; >+ >+for (const failureOp of operations) { >+ test(() => { >+ const record = new OpRecorder(failureOp); >+ const underlyingSource = createRecordingObjectWithProperties(record, ['type', 'start', 'pull', 'cancel']); >+ const strategy = createRecordingStrategy(record); >+ >+ try { >+ new ReadableStream(underlyingSource, strategy); >+ assert_unreached('constructor should throw'); >+ } catch (e) { >+ assert_equals(typeof e, 'object', 'e should be an object'); >+ } >+ >+ assert_equals(record.actual(), expectedAsString(operations, failureOp), >+ 'operations should be performed in the right order'); >+ }, `ReadableStream constructor should stop after ${failureOp} fails`); >+} >+ >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.serviceworker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.serviceworker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..0239f624dfe0524e4544904e199d6aeb7164ec97 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.serviceworker.https-expected.txt >@@ -0,0 +1,16 @@ >+ >+PASS Service worker test setup >+FAIL ReadableStream constructor should stop after get on size fails assert_equals: operations should be performed in the right order expected "get on size" but got "get on type,get on highWaterMark,get on size" >+FAIL ReadableStream constructor should stop after get on highWaterMark fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark" but got "get on type,get on highWaterMark" >+FAIL ReadableStream constructor should stop after get on type fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type" but got "get on type" >+FAIL ReadableStream constructor should stop after validate on type fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type" but got "get on type" >+FAIL ReadableStream constructor should stop after validate on size fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type" but got "get on type,get on highWaterMark,get on size,get on highWaterMark" >+FAIL ReadableStream constructor should stop after tonumber on highWaterMark fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark" >+FAIL ReadableStream constructor should stop after validate on highWaterMark fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark" >+FAIL ReadableStream constructor should stop after get on pull fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on start" >+FAIL ReadableStream constructor should stop after validate on pull fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on start" >+FAIL ReadableStream constructor should stop after get on cancel fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on start" >+FAIL ReadableStream constructor should stop after validate on cancel fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on start" >+FAIL ReadableStream constructor should stop after get on start fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on start" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on start" >+FAIL ReadableStream constructor should stop after validate on start fails assert_equals: operations should be performed in the right order expected "get on size,get on highWaterMark,get on type,tonumber on highWaterMark,get on pull,get on cancel,get on start" but got "get on type,get on highWaterMark,get on size,get on highWaterMark,tonumber on highWaterMark,get on start" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.serviceworker.https.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.serviceworker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ddddf06652427a3f0c579e0c66518729a6820f36 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.serviceworker.https.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>constructor.js service worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> >+ >+<script> >+'use strict'; >+service_worker_test('constructor.js', 'Service worker test setup'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.sharedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.sharedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2e2954f1ccd19f38dd0318dbdef3b16aa374ea2c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.sharedworker-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 10: ReferenceError: Can't find variable: SharedWorker >+ >+FAIL constructor.js shared worker wrapper file ReferenceError: Can't find variable: SharedWorker >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.sharedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.sharedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..52b1a5daf99e8511dbca8335b05ed7dff9e270b7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.sharedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>constructor.js shared worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new SharedWorker('constructor.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..328ec215bfdbf49f66dc633b64585b2ed95b70ef >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global-expected.txt >@@ -0,0 +1,4 @@ >+ >+FAIL ReadableStream tee() should not touch Object.prototype properties type getter called >+PASS ReadableStream tee() should not call the global ReadableStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.dedicatedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.dedicatedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..328ec215bfdbf49f66dc633b64585b2ed95b70ef >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.dedicatedworker-expected.txt >@@ -0,0 +1,4 @@ >+ >+FAIL ReadableStream tee() should not touch Object.prototype properties type getter called >+PASS ReadableStream tee() should not call the global ReadableStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.dedicatedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.dedicatedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..327bc92f75d4732e76330f1105d0e5b409c03b22 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.dedicatedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>patched-global.js dedicated worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new Worker('patched-global.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.html >new file mode 100644 >index 0000000000000000000000000000000000000000..869e9109e025e5e2391d51d336f03e6df335fd69 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.html >@@ -0,0 +1,10 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>patched-global.js browser context wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+ >+ >+<script src="patched-global.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.js b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.js >new file mode 100644 >index 0000000000000000000000000000000000000000..e8117c480484a3b6a83ecf10d1b9c8c61c5d02ca >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.js >@@ -0,0 +1,67 @@ >+'use strict'; >+ >+// Tests which patch the global environment are kept separate to avoid >+// interfering with other tests. >+ >+if (self.importScripts) { >+ self.importScripts('/resources/testharness.js'); >+} >+ >+const ReadableStream_prototype_locked_get = >+ Object.getOwnPropertyDescriptor(ReadableStream.prototype, 'locked').get; >+ >+// Verify that |rs| passes the brand check as a readable stream. >+function isReadableStream(rs) { >+ try { >+ ReadableStream_prototype_locked_get.call(rs); >+ return true; >+ } catch (e) { >+ return false; >+ } >+} >+ >+test(t => { >+ const rs = new ReadableStream(); >+ >+ const trappedProperties = ['highWaterMark', 'size', 'start', 'type', 'mode']; >+ for (const property of trappedProperties) { >+ // eslint-disable-next-line no-extend-native, accessor-pairs >+ Object.defineProperty(Object.prototype, property, { >+ get() { throw new Error(`${property} getter called`); }, >+ configurable: true >+ }); >+ } >+ t.add_cleanup(() => { >+ for (const property of trappedProperties) { >+ delete Object.prototype[property]; >+ } >+ }); >+ >+ const [branch1, branch2] = rs.tee(); >+ assert_true(isReadableStream(branch1), 'branch1 should be a ReadableStream'); >+ assert_true(isReadableStream(branch2), 'branch2 should be a ReadableStream'); >+}, 'ReadableStream tee() should not touch Object.prototype properties'); >+ >+test(t => { >+ const rs = new ReadableStream(); >+ >+ const oldReadableStream = self.ReadableStream; >+ >+ /* eslint-disable no-native-reassign */ >+ self.ReadableStream = function() { >+ throw new Error('ReadableStream called on global object'); >+ }; >+ >+ t.add_cleanup(() => { >+ self.ReadableStream = oldReadableStream; >+ }); >+ >+ const [branch1, branch2] = rs.tee(); >+ >+ assert_true(isReadableStream(branch1), 'branch1 should be a ReadableStream'); >+ assert_true(isReadableStream(branch2), 'branch2 should be a ReadableStream'); >+ >+ /* eslint-enable no-native-reassign */ >+}, 'ReadableStream tee() should not call the global ReadableStream'); >+ >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.serviceworker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.serviceworker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..92554bf51fa9e8965db3ab1f336bb614c6d39ea4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.serviceworker.https-expected.txt >@@ -0,0 +1,5 @@ >+ >+PASS Service worker test setup >+FAIL ReadableStream tee() should not touch Object.prototype properties type getter called >+PASS ReadableStream tee() should not call the global ReadableStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.serviceworker.https.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.serviceworker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..addb438ba6fe407662232f97bb6c2583f3f17cf4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.serviceworker.https.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>patched-global.js service worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> >+ >+<script> >+'use strict'; >+service_worker_test('patched-global.js', 'Service worker test setup'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.sharedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.sharedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..5293962394bdf646b647bd5ec050645f3ce59269 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.sharedworker-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 10: ReferenceError: Can't find variable: SharedWorker >+ >+FAIL patched-global.js shared worker wrapper file ReferenceError: Can't find variable: SharedWorker >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.sharedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.sharedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..6dba52fa67f53c4c0437ebd4ad7166ca5ceb1d7d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.sharedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>patched-global.js shared worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new SharedWorker('patched-global.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..1fa4220c650b010491e7855e245778ad3daa5127 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies-expected.txt >@@ -0,0 +1,12 @@ >+ >+PASS enqueue() inside size() should work >+PASS close() inside size() should not crash >+PASS close request inside size() should work >+PASS error() inside size() should work >+PASS desiredSize inside size() should work >+PASS cancel() inside size() should work >+PASS pipeTo() inside size() should behave as expected >+PASS read() inside of size() should behave as expected >+PASS getReader() inside size() should work >+PASS tee() inside size() should work >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.dedicatedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.dedicatedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..864e81a786d0d976ddd969d78df232c45089757f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.dedicatedworker-expected.txt >@@ -0,0 +1,12 @@ >+ >+PASS enqueue() inside size() should work >+PASS close() inside size() should not crash >+PASS close request inside size() should work >+PASS error() inside size() should work >+PASS desiredSize inside size() should work >+PASS cancel() inside size() should work >+FAIL pipeTo() inside size() should behave as expected Can't find variable: WritableStream >+PASS read() inside of size() should behave as expected >+PASS getReader() inside size() should work >+PASS tee() inside size() should work >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.dedicatedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.dedicatedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..300dc8518753892694eb7b7f6afc08a2c2ee516c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.dedicatedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>reentrant-strategies.js dedicated worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new Worker('reentrant-strategies.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.html >new file mode 100644 >index 0000000000000000000000000000000000000000..e2a6406bd469cda4c474253998b98640d6693dc5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>reentrant-strategies.js browser context wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script src="../resources/recording-streams.js"></script> >+<script src="../resources/rs-utils.js"></script> >+<script src="../resources/test-utils.js"></script> >+ >+<script src="reentrant-strategies.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.js b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.js >new file mode 100644 >index 0000000000000000000000000000000000000000..47dd3bf3c7debff96a87fbe56550200d226d8170 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.js >@@ -0,0 +1,269 @@ >+'use strict'; >+ >+// The size() function of the readable strategy can re-entrantly call back into the ReadableStream implementation. This >+// makes it risky to cache state across the call to ReadableStreamDefaultControllerEnqueue. These tests attempt to catch >+// such errors. They are separated from the other strategy tests because no real user code should ever do anything like >+// this. >+ >+if (self.importScripts) { >+ self.importScripts('/resources/testharness.js'); >+ self.importScripts('../resources/recording-streams.js'); >+ self.importScripts('../resources/rs-utils.js'); >+ self.importScripts('../resources/test-utils.js'); >+} >+ >+const error1 = new Error('error1'); >+error1.name = 'error1'; >+ >+promise_test(() => { >+ let controller; >+ let calls = 0; >+ const rs = new ReadableStream({ >+ start(c) { >+ controller = c; >+ } >+ }, { >+ size() { >+ ++calls; >+ if (calls < 2) { >+ controller.enqueue('b'); >+ } >+ return 1; >+ } >+ }); >+ controller.enqueue('a'); >+ controller.close(); >+ return readableStreamToArray(rs) >+ .then(array => assert_array_equals(array, ['b', 'a'], 'array should contain two chunks')); >+}, 'enqueue() inside size() should work'); >+ >+promise_test(() => { >+ let controller; >+ const rs = new ReadableStream({ >+ start(c) { >+ controller = c; >+ } >+ }, { >+ size() { >+ // The queue is empty. >+ controller.close(); >+ // The state has gone from "readable" to "closed". >+ return 1; >+ // This chunk will be enqueued, but will be impossible to read because the state is already "closed". >+ } >+ }); >+ controller.enqueue('a'); >+ return readableStreamToArray(rs) >+ .then(array => assert_array_equals(array, [], 'array should contain no chunks')); >+ // The chunk 'a' is still in rs's queue. It is closed so 'a' cannot be read. >+}, 'close() inside size() should not crash'); >+ >+promise_test(() => { >+ let controller; >+ let calls = 0; >+ const rs = new ReadableStream({ >+ start(c) { >+ controller = c; >+ } >+ }, { >+ size() { >+ ++calls; >+ if (calls === 2) { >+ // The queue contains one chunk. >+ controller.close(); >+ // The state is still "readable", but closeRequest is now true. >+ } >+ return 1; >+ } >+ }); >+ controller.enqueue('a'); >+ controller.enqueue('b'); >+ return readableStreamToArray(rs) >+ .then(array => assert_array_equals(array, ['a', 'b'], 'array should contain two chunks')); >+}, 'close request inside size() should work'); >+ >+promise_test(t => { >+ let controller; >+ const rs = new ReadableStream({ >+ start(c) { >+ controller = c; >+ } >+ }, { >+ size() { >+ controller.error(error1); >+ return 1; >+ } >+ }); >+ controller.enqueue('a'); >+ return promise_rejects(t, error1, rs.getReader().read(), 'read() should reject'); >+}, 'error() inside size() should work'); >+ >+promise_test(() => { >+ let controller; >+ const rs = new ReadableStream({ >+ start(c) { >+ controller = c; >+ } >+ }, { >+ size() { >+ assert_equals(controller.desiredSize, 1, 'desiredSize should be 1'); >+ return 1; >+ }, >+ highWaterMark: 1 >+ }); >+ controller.enqueue('a'); >+ controller.close(); >+ return readableStreamToArray(rs) >+ .then(array => assert_array_equals(array, ['a'], 'array should contain one chunk')); >+}, 'desiredSize inside size() should work'); >+ >+promise_test(t => { >+ let cancelPromise; >+ let controller; >+ const rs = new ReadableStream({ >+ start(c) { >+ controller = c; >+ }, >+ cancel: t.step_func(reason => { >+ assert_equals(reason, error1, 'reason should be error1'); >+ assert_throws(new TypeError(), () => controller.enqueue(), 'enqueue() should throw'); >+ }) >+ }, { >+ size() { >+ cancelPromise = rs.cancel(error1); >+ return 1; >+ }, >+ highWaterMark: Infinity >+ }); >+ controller.enqueue('a'); >+ const reader = rs.getReader(); >+ return Promise.all([ >+ reader.closed, >+ cancelPromise >+ ]); >+}, 'cancel() inside size() should work'); >+ >+promise_test(() => { >+ let controller; >+ let pipeToPromise; >+ const ws = recordingWritableStream(); >+ const rs = new ReadableStream({ >+ start(c) { >+ controller = c; >+ } >+ }, { >+ size() { >+ if (!pipeToPromise) { >+ pipeToPromise = rs.pipeTo(ws); >+ } >+ return 1; >+ }, >+ highWaterMark: 1 >+ }); >+ controller.enqueue('a'); >+ assert_not_equals(pipeToPromise, undefined); >+ >+ // Some pipeTo() implementations need an additional chunk enqueued in order for the first one to be processed. See >+ // https://github.com/whatwg/streams/issues/794 for background. >+ controller.enqueue('a'); >+ >+ // Give pipeTo() a chance to process the queued chunks. >+ return delay(0).then(() => { >+ assert_array_equals(ws.events, ['write', 'a', 'write', 'a'], 'ws should contain two chunks'); >+ controller.close(); >+ return pipeToPromise; >+ }).then(() => { >+ assert_array_equals(ws.events, ['write', 'a', 'write', 'a', 'close'], 'target should have been closed'); >+ }); >+}, 'pipeTo() inside size() should behave as expected'); >+ >+promise_test(() => { >+ let controller; >+ let readPromise; >+ let calls = 0; >+ let readResolved = false; >+ let reader; >+ const rs = new ReadableStream({ >+ start(c) { >+ controller = c; >+ } >+ }, { >+ size() { >+ // This is triggered by controller.enqueue(). The queue is empty and there are no pending reads. This read is >+ // added to the list of pending reads. >+ readPromise = reader.read(); >+ ++calls; >+ return 1; >+ }, >+ highWaterMark: 0 >+ }); >+ reader = rs.getReader(); >+ controller.enqueue('a'); >+ readPromise.then(() => { >+ readResolved = true; >+ }); >+ return flushAsyncEvents().then(() => { >+ assert_false(readResolved); >+ controller.enqueue('b'); >+ assert_equals(calls, 1, 'size() should have been called once'); >+ return delay(0); >+ }).then(() => { >+ assert_true(readResolved); >+ assert_equals(calls, 1, 'size() should only be called once'); >+ return readPromise; >+ }).then(({ value, done }) => { >+ assert_false(done, 'done should be false'); >+ // See https://github.com/whatwg/streams/issues/794 for why this chunk is not 'a'. >+ assert_equals(value, 'b', 'chunk should have been read'); >+ assert_equals(calls, 1, 'calls should still be 1'); >+ return reader.read(); >+ }).then(({ value, done }) => { >+ assert_false(done, 'done should be false again'); >+ assert_equals(value, 'a', 'chunk a should come after b'); >+ }); >+}, 'read() inside of size() should behave as expected'); >+ >+promise_test(() => { >+ let controller; >+ let reader; >+ const rs = new ReadableStream({ >+ start(c) { >+ controller = c; >+ } >+ }, { >+ size() { >+ reader = rs.getReader(); >+ return 1; >+ } >+ }); >+ controller.enqueue('a'); >+ return reader.read().then(({ value, done }) => { >+ assert_false(done, 'done should be false'); >+ assert_equals(value, 'a', 'value should be a'); >+ }); >+}, 'getReader() inside size() should work'); >+ >+promise_test(() => { >+ let controller; >+ let branch1; >+ let branch2; >+ const rs = new ReadableStream({ >+ start(c) { >+ controller = c; >+ } >+ }, { >+ size() { >+ [branch1, branch2] = rs.tee(); >+ return 1; >+ } >+ }); >+ controller.enqueue('a'); >+ assert_true(rs.locked, 'rs should be locked'); >+ controller.close(); >+ return Promise.all([ >+ readableStreamToArray(branch1).then(array => assert_array_equals(array, ['a'], 'branch1 should have one chunk')), >+ readableStreamToArray(branch2).then(array => assert_array_equals(array, ['a'], 'branch2 should have one chunk')) >+ ]); >+}, 'tee() inside size() should work'); >+ >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.serviceworker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.serviceworker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..339a7a2c51e784b95e3315584859e33b4744144e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.serviceworker.https-expected.txt >@@ -0,0 +1,13 @@ >+ >+PASS Service worker test setup >+PASS enqueue() inside size() should work >+PASS close() inside size() should not crash >+PASS close request inside size() should work >+PASS error() inside size() should work >+PASS desiredSize inside size() should work >+PASS cancel() inside size() should work >+FAIL pipeTo() inside size() should behave as expected Can't find variable: WritableStream >+PASS read() inside of size() should behave as expected >+PASS getReader() inside size() should work >+PASS tee() inside size() should work >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.serviceworker.https.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.serviceworker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..6c1813d13853a6d826affc95dcba5a5ad5d9768a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.serviceworker.https.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>reentrant-strategies.js service worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> >+ >+<script> >+'use strict'; >+service_worker_test('reentrant-strategies.js', 'Service worker test setup'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.sharedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.sharedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..e984787443687813d38bcd0823a800d3a0711f25 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.sharedworker-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 10: ReferenceError: Can't find variable: SharedWorker >+ >+FAIL reentrant-strategies.js shared worker wrapper file ReferenceError: Can't find variable: SharedWorker >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.sharedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.sharedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..4415a3fb9b35ae2422fa06d98b1dce1264b9e0ea >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.sharedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>reentrant-strategies.js shared worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new SharedWorker('reentrant-strategies.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/w3c-import.log >index 043534e50f4573eac1f28d55455e9972ebece6ba..0ff784949d2876db5b15ddfe6a8e413863104c6d 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/w3c-import.log >@@ -34,6 +34,11 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/cancel.js > /LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/cancel.serviceworker.https.html > /LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/cancel.sharedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.dedicatedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.js >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.serviceworker.https.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.sharedworker.html > /LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/count-queuing-strategy-integration.dedicatedworker.html > /LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/count-queuing-strategy-integration.html > /LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/count-queuing-strategy-integration.js >@@ -59,6 +64,16 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general.js > /LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general.serviceworker.https.html > /LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general.sharedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.dedicatedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.js >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.serviceworker.https.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.sharedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.dedicatedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.js >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.serviceworker.https.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.sharedworker.html > /LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.dedicatedworker.html > /LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.html > /LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.js >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/constructor-ordering.js b/LayoutTests/imported/w3c/web-platform-tests/streams/resources/constructor-ordering.js >new file mode 100644 >index 0000000000000000000000000000000000000000..79862e044c079f0695d1083f261bbb449fc26eff >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/resources/constructor-ordering.js >@@ -0,0 +1,129 @@ >+'use strict'; >+ >+// Helpers for tests that constructors perform getting and validation of properties in the standard order. >+// See ../readable-streams/constructor.js for an example of how to use them. >+ >+// Describes an operation on a property. |type| is "get", "validate" or "tonumber". |name| is the name of the property >+// in question. |side| is usually undefined, but is used by TransformStream to distinguish between the readable and >+// writable strategies. >+class Op { >+ constructor(type, name, side) { >+ this.type = type; >+ this.name = name; >+ this.side = side; >+ } >+ >+ toString() { >+ return this.side === undefined ? `${this.type} on ${this.name}` : `${this.type} on ${this.name} (${this.side})`; >+ } >+ >+ equals(otherOp) { >+ return this.type === otherOp.type && this.name === otherOp.name && this.side === otherOp.side; >+ } >+} >+ >+// Provides a concise syntax to create an Op object. |side| is used by TransformStream to distinguish between the two >+// strategies. >+function op(type, name, side = undefined) { >+ return new Op(type, name, side); >+} >+ >+// Records a sequence of operations. Also checks each operation against |failureOp| to see if it should fail. >+class OpRecorder { >+ constructor(failureOp) { >+ this.ops = []; >+ this.failureOp = failureOp; >+ this.matched = false; >+ } >+ >+ // Record an operation. Returns true if this operation should fail. >+ recordAndCheck(type, name, side = undefined) { >+ const recordedOp = op(type, name, side); >+ this.ops.push(recordedOp); >+ return this.failureOp.equals(recordedOp); >+ } >+ >+ // Returns true if validation of this property should fail. >+ check(name, side = undefined) { >+ return this.failureOp.equals(op('validate', name, side)); >+ } >+ >+ // Returns the sequence of recorded operations as a string. >+ actual() { >+ return this.ops.toString(); >+ } >+} >+ >+// Creates an object with the list of properties named in |properties|. Every property access will be recorded in >+// |record|, which will also be used to determine whether a particular property access should fail, or whether it should >+// return an invalid value that will fail validation. >+function createRecordingObjectWithProperties(record, properties) { >+ const recordingObject = {}; >+ for (const property of properties) { >+ defineCheckedProperty(record, recordingObject, property, () => record.check(property) ? 'invalid' : undefined); >+ } >+ return recordingObject; >+} >+ >+// Add a getter to |object| named |property| which throws if op('get', property) should fail, and otherwise calls >+// getter() to get the return value. >+function defineCheckedProperty(record, object, property, getter) { >+ Object.defineProperty(object, property, { >+ get() { >+ if (record.recordAndCheck('get', property)) { >+ throw new Error(`intentional failure of get ${property}`); >+ } >+ return getter(); >+ } >+ }); >+} >+ >+// Similar to createRecordingObjectWithProperties(), but with specific functionality for "highWaterMark" so that numeric >+// conversion can be recorded. Permits |side| to be specified so that TransformStream can distinguish between its two >+// strategies. >+function createRecordingStrategy(record, side = undefined) { >+ return { >+ get size() { >+ if (record.recordAndCheck('get', 'size', side)) { >+ throw new Error(`intentional failure of get size`); >+ } >+ return record.check('size', side) ? 'invalid' : undefined; >+ }, >+ get highWaterMark() { >+ if (record.recordAndCheck('get', 'highWaterMark', side)) { >+ throw new Error(`intentional failure of get highWaterMark`); >+ } >+ return createRecordingNumberObject(record, 'highWaterMark', side); >+ } >+ }; >+} >+ >+// Creates an object which will record when it is converted to a number. It will assert if the conversion is to some >+// other type, and will fail if op('tonumber', property, side) is set as the failure step. The object will convert to -1 >+// if 'validate' is set as the failure step, and 1 otherwise. >+function createRecordingNumberObject(record, property, side = undefined) { >+ return { >+ [Symbol.toPrimitive](hint) { >+ assert_equals(hint, 'number', `hint for ${property} should be 'number'`); >+ if (record.recordAndCheck('tonumber', property, side)) { >+ throw new Error(`intentional failure of ${op('tonumber', property, side)}`); >+ } >+ return record.check(property, side) ? -1 : 1; >+ } >+ }; >+} >+ >+// Creates a string from everything in |operations| up to and including |failureOp|. "validate" steps are excluded from >+// the output, as we cannot record them except by making them fail. >+function expectedAsString(operations, failureOp) { >+ const expected = []; >+ for (const step of operations) { >+ if (step.type !== 'validate') { >+ expected.push(step); >+ } >+ if (step.equals(failureOp)) { >+ break; >+ } >+ } >+ return expected.toString(); >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/streams/resources/w3c-import.log >index 72220d15edb7eb8d52d364056291f3f8659f4c07..38f810d7d415e009ec64d81080fa8801420f2261 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/resources/w3c-import.log >@@ -14,6 +14,7 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/streams/resources/constructor-ordering.js > /LayoutTests/imported/w3c/web-platform-tests/streams/resources/recording-streams.js > /LayoutTests/imported/w3c/web-platform-tests/streams/resources/rs-test-templates.js > /LayoutTests/imported/w3c/web-platform-tests/streams/resources/rs-utils.js >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..ec07c7b972851dd9c7d26885f155826979c5a971 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure-expected.txt >@@ -0,0 +1,16 @@ >+ >+FAIL backpressure allows no transforms with a default identity transform and no reader Can't find variable: TransformStream >+FAIL backpressure only allows one transform() with a identity transform with a readable HWM of 1 and no reader Can't find variable: TransformStream >+FAIL transform() should keep being called as long as there is no backpressure Can't find variable: TransformStream >+FAIL writes should resolve as soon as transform completes Can't find variable: TransformStream >+FAIL calling pull() before the first write() with backpressure should work Can't find variable: TransformStream >+FAIL transform() should be able to read the chunk it just enqueued Can't find variable: TransformStream >+FAIL blocking transform() should cause backpressure Can't find variable: TransformStream >+FAIL writer.closed should resolve after readable is canceled during start Can't find variable: TransformStream >+FAIL writer.closed should resolve after readable is canceled with backpressure Can't find variable: TransformStream >+FAIL writer.closed should resolve after readable is canceled with no backpressure Can't find variable: TransformStream >+FAIL cancelling the readable should cause a pending write to resolve Can't find variable: TransformStream >+FAIL cancelling the readable side of a TransformStream should abort an empty pipe Can't find variable: TransformStream >+FAIL cancelling the readable side of a TransformStream should abort an empty pipe after startup Can't find variable: TransformStream >+FAIL cancelling the readable side of a TransformStream should abort a full pipe Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.dedicatedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.dedicatedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..ec07c7b972851dd9c7d26885f155826979c5a971 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.dedicatedworker-expected.txt >@@ -0,0 +1,16 @@ >+ >+FAIL backpressure allows no transforms with a default identity transform and no reader Can't find variable: TransformStream >+FAIL backpressure only allows one transform() with a identity transform with a readable HWM of 1 and no reader Can't find variable: TransformStream >+FAIL transform() should keep being called as long as there is no backpressure Can't find variable: TransformStream >+FAIL writes should resolve as soon as transform completes Can't find variable: TransformStream >+FAIL calling pull() before the first write() with backpressure should work Can't find variable: TransformStream >+FAIL transform() should be able to read the chunk it just enqueued Can't find variable: TransformStream >+FAIL blocking transform() should cause backpressure Can't find variable: TransformStream >+FAIL writer.closed should resolve after readable is canceled during start Can't find variable: TransformStream >+FAIL writer.closed should resolve after readable is canceled with backpressure Can't find variable: TransformStream >+FAIL writer.closed should resolve after readable is canceled with no backpressure Can't find variable: TransformStream >+FAIL cancelling the readable should cause a pending write to resolve Can't find variable: TransformStream >+FAIL cancelling the readable side of a TransformStream should abort an empty pipe Can't find variable: TransformStream >+FAIL cancelling the readable side of a TransformStream should abort an empty pipe after startup Can't find variable: TransformStream >+FAIL cancelling the readable side of a TransformStream should abort a full pipe Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.dedicatedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.dedicatedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..36d10f505f973a27306a508e2275811f5fc2e27e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.dedicatedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>backpressure.js dedicated worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new Worker('backpressure.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.html >new file mode 100644 >index 0000000000000000000000000000000000000000..65f056f58058df40bdd7aa156c8018918cc18c48 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>backpressure.js browser context wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script src="../resources/recording-streams.js"></script> >+<script src="../resources/test-utils.js"></script> >+ >+<script src="backpressure.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.js b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.js >new file mode 100644 >index 0000000000000000000000000000000000000000..7446b770901622fe1f70400122f8c038cb4c675b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.js >@@ -0,0 +1,200 @@ >+'use strict'; >+ >+if (self.importScripts) { >+ self.importScripts('/resources/testharness.js'); >+ self.importScripts('../resources/recording-streams.js'); >+ self.importScripts('../resources/test-utils.js'); >+} >+ >+const error1 = new Error('error1 message'); >+error1.name = 'error1'; >+ >+promise_test(() => { >+ const ts = recordingTransformStream(); >+ const writer = ts.writable.getWriter(); >+ // This call never resolves. >+ writer.write('a'); >+ return flushAsyncEvents().then(() => { >+ assert_array_equals(ts.events, [], 'transform should not be called'); >+ }); >+}, 'backpressure allows no transforms with a default identity transform and no reader'); >+ >+promise_test(() => { >+ const ts = recordingTransformStream({}, undefined, { highWaterMark: 1 }); >+ const writer = ts.writable.getWriter(); >+ // This call to write() resolves asynchronously. >+ writer.write('a'); >+ // This call to write() waits for backpressure that is never relieved and never calls transform(). >+ writer.write('b'); >+ return flushAsyncEvents().then(() => { >+ assert_array_equals(ts.events, ['transform', 'a'], 'transform should be called once'); >+ }); >+}, 'backpressure only allows one transform() with a identity transform with a readable HWM of 1 and no reader'); >+ >+promise_test(() => { >+ // Without a transform() implementation, recordingTransformStream() never enqueues anything. >+ const ts = recordingTransformStream({ >+ transform() { >+ // Discard all chunks. As a result, the readable side is never full enough to exert backpressure and transform() >+ // keeps being called. >+ } >+ }, undefined, { highWaterMark: 1 }); >+ const writer = ts.writable.getWriter(); >+ const writePromises = []; >+ for (let i = 0; i < 4; ++i) { >+ writePromises.push(writer.write(i)); >+ } >+ return Promise.all(writePromises).then(() => { >+ assert_array_equals(ts.events, ['transform', 0, 'transform', 1, 'transform', 2, 'transform', 3], >+ 'all 4 events should be transformed'); >+ }); >+}, 'transform() should keep being called as long as there is no backpressure'); >+ >+promise_test(() => { >+ const ts = new TransformStream({}, undefined, { highWaterMark: 1 }); >+ const writer = ts.writable.getWriter(); >+ const reader = ts.readable.getReader(); >+ const events = []; >+ const writerPromises = [ >+ writer.write('a').then(() => events.push('a')), >+ writer.write('b').then(() => events.push('b')), >+ writer.close().then(() => events.push('closed'))]; >+ return delay(0).then(() => { >+ assert_array_equals(events, ['a'], 'the first write should have resolved'); >+ return reader.read(); >+ }).then(({ value, done }) => { >+ assert_false(done, 'done should not be true'); >+ assert_equals('a', value, 'value should be "a"'); >+ return delay(0); >+ }).then(() => { >+ assert_array_equals(events, ['a', 'b', 'closed'], 'both writes and close() should have resolved'); >+ return reader.read(); >+ }).then(({ value, done }) => { >+ assert_false(done, 'done should still not be true'); >+ assert_equals('b', value, 'value should be "b"'); >+ return reader.read(); >+ }).then(({ done }) => { >+ assert_true(done, 'done should be true'); >+ return writerPromises; >+ }); >+}, 'writes should resolve as soon as transform completes'); >+ >+promise_test(() => { >+ const ts = new TransformStream(undefined, undefined, { highWaterMark: 0 }); >+ const writer = ts.writable.getWriter(); >+ const reader = ts.readable.getReader(); >+ const readPromise = reader.read(); >+ writer.write('a'); >+ return readPromise.then(({ value, done }) => { >+ assert_false(done, 'not done'); >+ assert_equals(value, 'a', 'value should be "a"'); >+ }); >+}, 'calling pull() before the first write() with backpressure should work'); >+ >+promise_test(() => { >+ let reader; >+ const ts = recordingTransformStream({ >+ transform(chunk, controller) { >+ controller.enqueue(chunk); >+ return reader.read(); >+ } >+ }, undefined, { highWaterMark: 1 }); >+ const writer = ts.writable.getWriter(); >+ reader = ts.readable.getReader(); >+ return writer.write('a'); >+}, 'transform() should be able to read the chunk it just enqueued'); >+ >+promise_test(() => { >+ let resolveTransform; >+ const transformPromise = new Promise(resolve => { >+ resolveTransform = resolve; >+ }); >+ const ts = recordingTransformStream({ >+ transform() { >+ return transformPromise; >+ } >+ }, undefined, new CountQueuingStrategy({ highWaterMark: Infinity })); >+ const writer = ts.writable.getWriter(); >+ assert_equals(writer.desiredSize, 1, 'desiredSize should be 1'); >+ return delay(0).then(() => { >+ writer.write('a'); >+ assert_array_equals(ts.events, ['transform', 'a']); >+ assert_equals(writer.desiredSize, 0, 'desiredSize should be 0'); >+ return flushAsyncEvents(); >+ }).then(() => { >+ assert_equals(writer.desiredSize, 0, 'desiredSize should still be 0'); >+ resolveTransform(); >+ return delay(0); >+ }).then(() => { >+ assert_equals(writer.desiredSize, 1, 'desiredSize should be 1'); >+ }); >+}, 'blocking transform() should cause backpressure'); >+ >+promise_test(t => { >+ const ts = new TransformStream(); >+ ts.readable.cancel(error1); >+ return promise_rejects(t, error1, ts.writable.getWriter().closed, 'closed should reject'); >+}, 'writer.closed should resolve after readable is canceled during start'); >+ >+promise_test(t => { >+ const ts = new TransformStream({}, undefined, { highWaterMark: 0 }); >+ return delay(0).then(() => { >+ ts.readable.cancel(error1); >+ return promise_rejects(t, error1, ts.writable.getWriter().closed, 'closed should reject'); >+ }); >+}, 'writer.closed should resolve after readable is canceled with backpressure'); >+ >+promise_test(t => { >+ const ts = new TransformStream({}, undefined, { highWaterMark: 1 }); >+ return delay(0).then(() => { >+ ts.readable.cancel(error1); >+ return promise_rejects(t, error1, ts.writable.getWriter().closed, 'closed should reject'); >+ }); >+}, 'writer.closed should resolve after readable is canceled with no backpressure'); >+ >+promise_test(() => { >+ const ts = new TransformStream({}, undefined, { highWaterMark: 1 }); >+ const writer = ts.writable.getWriter(); >+ return delay(0).then(() => { >+ const writePromise = writer.write('a'); >+ ts.readable.cancel(error1); >+ return writePromise; >+ }); >+}, 'cancelling the readable should cause a pending write to resolve'); >+ >+promise_test(t => { >+ const rs = new ReadableStream(); >+ const ts = new TransformStream(); >+ const pipePromise = rs.pipeTo(ts.writable); >+ ts.readable.cancel(error1); >+ return promise_rejects(t, error1, pipePromise, 'promise returned from pipeTo() should be rejected'); >+}, 'cancelling the readable side of a TransformStream should abort an empty pipe'); >+ >+promise_test(t => { >+ const rs = new ReadableStream(); >+ const ts = new TransformStream(); >+ const pipePromise = rs.pipeTo(ts.writable); >+ return delay(0).then(() => { >+ ts.readable.cancel(error1); >+ return promise_rejects(t, error1, pipePromise, 'promise returned from pipeTo() should be rejected'); >+ }); >+}, 'cancelling the readable side of a TransformStream should abort an empty pipe after startup'); >+ >+promise_test(t => { >+ const rs = new ReadableStream({ >+ start(controller) { >+ controller.enqueue('a'); >+ controller.enqueue('b'); >+ controller.enqueue('c'); >+ } >+ }); >+ const ts = new TransformStream(); >+ const pipePromise = rs.pipeTo(ts.writable); >+ // Allow data to flow into the pipe. >+ return delay(0).then(() => { >+ ts.readable.cancel(error1); >+ return promise_rejects(t, error1, pipePromise, 'promise returned from pipeTo() should be rejected'); >+ }); >+}, 'cancelling the readable side of a TransformStream should abort a full pipe'); >+ >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.serviceworker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.serviceworker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..ffd096b9730a5ee067374147fc44084d6a2a8a20 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.serviceworker.https-expected.txt >@@ -0,0 +1,17 @@ >+ >+PASS Service worker test setup >+FAIL backpressure allows no transforms with a default identity transform and no reader Can't find variable: TransformStream >+FAIL backpressure only allows one transform() with a identity transform with a readable HWM of 1 and no reader Can't find variable: TransformStream >+FAIL transform() should keep being called as long as there is no backpressure Can't find variable: TransformStream >+FAIL writes should resolve as soon as transform completes Can't find variable: TransformStream >+FAIL calling pull() before the first write() with backpressure should work Can't find variable: TransformStream >+FAIL transform() should be able to read the chunk it just enqueued Can't find variable: TransformStream >+FAIL blocking transform() should cause backpressure Can't find variable: TransformStream >+FAIL writer.closed should resolve after readable is canceled during start Can't find variable: TransformStream >+FAIL writer.closed should resolve after readable is canceled with backpressure Can't find variable: TransformStream >+FAIL writer.closed should resolve after readable is canceled with no backpressure Can't find variable: TransformStream >+FAIL cancelling the readable should cause a pending write to resolve Can't find variable: TransformStream >+FAIL cancelling the readable side of a TransformStream should abort an empty pipe Can't find variable: TransformStream >+FAIL cancelling the readable side of a TransformStream should abort an empty pipe after startup Can't find variable: TransformStream >+FAIL cancelling the readable side of a TransformStream should abort a full pipe Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.serviceworker.https.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.serviceworker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..493feaa69ff63b23fb2c58cfb88aec4f308bbce9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.serviceworker.https.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>backpressure.js service worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> >+ >+<script> >+'use strict'; >+service_worker_test('backpressure.js', 'Service worker test setup'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.sharedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.sharedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2a4abd45dd6ef29ef9c7e3ca86557b26ee214eab >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.sharedworker-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 10: ReferenceError: Can't find variable: SharedWorker >+ >+FAIL backpressure.js shared worker wrapper file ReferenceError: Can't find variable: SharedWorker >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.sharedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.sharedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..0a16b99ee908e808312711852e8610e6afbeb38e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.sharedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>backpressure.js shared worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new SharedWorker('backpressure.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..a586e0e3f316635c33d6365864bcb7c8f98d8e05 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 36: ReferenceError: Can't find variable: TransformStream >+ >+FAIL brand-checks.js browser context wrapper file ReferenceError: Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.dedicatedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.dedicatedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..7ed6340bb1cc3d7a4c22a19f7e9d683a4d1bbcec >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.dedicatedworker-expected.txt >@@ -0,0 +1,5 @@ >+CONSOLE MESSAGE: line 1834: TypeError: null is not an object (evaluating 'this.message_target.removeEventListener') >+CONSOLE MESSAGE: line 36: ReferenceError: Can't find variable: TransformStream >+ >+FAIL Untitled ReferenceError: Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.dedicatedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.dedicatedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..bb3f11a90e281b96aab4695d7cab04cc436e8f07 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.dedicatedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>brand-checks.js dedicated worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new Worker('brand-checks.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.html >new file mode 100644 >index 0000000000000000000000000000000000000000..98d2e281ffaf6f0b4046b30296b2d09fb1f3de9f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.html >@@ -0,0 +1,10 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>brand-checks.js browser context wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script src="../resources/test-utils.js"></script> >+ >+<script src="brand-checks.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.js b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.js >new file mode 100644 >index 0000000000000000000000000000000000000000..0dd0d91b318223ea5a4a3b3f58141d405d24d2cb >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.js >@@ -0,0 +1,79 @@ >+'use strict'; >+ >+if (self.importScripts) { >+ self.importScripts('/resources/testharness.js'); >+ self.importScripts('../resources/test-utils.js'); >+} >+ >+const TransformStreamDefaultController = getTransformStreamDefaultControllerConstructor(); >+ >+function getTransformStreamDefaultControllerConstructor() { >+ return realTSDefaultController().constructor; >+} >+ >+function fakeTS() { >+ return Object.setPrototypeOf({ >+ get readable() { return new ReadableStream(); }, >+ get writable() { return new WritableStream(); } >+ }, TransformStream.prototype); >+} >+ >+function realTS() { >+ return new TransformStream(); >+} >+ >+function fakeTSDefaultController() { >+ return Object.setPrototypeOf({ >+ get desiredSize() { return 1; }, >+ enqueue() { }, >+ close() { }, >+ error() { } >+ }, TransformStreamDefaultController.prototype); >+} >+ >+function realTSDefaultController() { >+ let controller; >+ new TransformStream({ >+ start(c) { >+ controller = c; >+ } >+ }); >+ return controller; >+} >+ >+test(() => { >+ getterThrowsForAll(TransformStream.prototype, 'readable', >+ [fakeTS(), realTSDefaultController(), undefined, null]); >+}, 'TransformStream.prototype.readable enforces a brand check'); >+ >+test(() => { >+ getterThrowsForAll(TransformStream.prototype, 'writable', >+ [fakeTS(), realTSDefaultController(), undefined, null]); >+}, 'TransformStream.prototype.writable enforces a brand check'); >+ >+test(() => { >+ constructorThrowsForAll(TransformStreamDefaultController, >+ [fakeTS(), realTS(), realTSDefaultController(), undefined, null]); >+}, 'TransformStreamDefaultConstructor enforces a brand check and doesn\'t permit independent construction'); >+ >+test(() => { >+ getterThrowsForAll(TransformStreamDefaultController.prototype, 'desiredSize', >+ [fakeTSDefaultController(), realTS(), undefined, null]); >+}, 'TransformStreamDefaultController.prototype.desiredSize enforces a brand check'); >+ >+test(() => { >+ methodThrowsForAll(TransformStreamDefaultController.prototype, 'enqueue', >+ [fakeTSDefaultController(), realTS(), undefined, null]); >+}, 'TransformStreamDefaultController.prototype.enqueue enforces a brand check'); >+ >+test(() => { >+ methodThrowsForAll(TransformStreamDefaultController.prototype, 'terminate', >+ [fakeTSDefaultController(), realTS(), undefined, null]); >+}, 'TransformStreamDefaultController.prototype.terminate enforces a brand check'); >+ >+test(() => { >+ methodThrowsForAll(TransformStreamDefaultController.prototype, 'error', >+ [fakeTSDefaultController(), realTS(), undefined, null]); >+}, 'TransformStreamDefaultController.prototype.error enforces a brand check'); >+ >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.serviceworker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.serviceworker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..bc972a5067b668e2945d1f673e3e9f18112e83fa >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.serviceworker.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+FAIL Service worker test setup assert_unreached: unregister and register should not fail: ReferenceError: Can't find variable: TransformStream Reached unreachable code >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.serviceworker.https.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.serviceworker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2439cdb95e989b7e7427562ce627ad17c82cb975 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.serviceworker.https.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>brand-checks.js service worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> >+ >+<script> >+'use strict'; >+service_worker_test('brand-checks.js', 'Service worker test setup'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.sharedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.sharedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..71ffc85f978e57bb9b4ea605d508bdcc71852d6f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.sharedworker-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 10: ReferenceError: Can't find variable: SharedWorker >+ >+FAIL brand-checks.js shared worker wrapper file ReferenceError: Can't find variable: SharedWorker >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.sharedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.sharedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..cff72eca46341fdd6663ec139d871e1b81344b20 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.sharedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>brand-checks.js shared worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new SharedWorker('brand-checks.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..c06f8f80cce5bcee8303910c1d3c8c3f35ebbee3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor-expected.txt >@@ -0,0 +1,22 @@ >+ >+FAIL TransformStream constructor should stop after get on size (writable) fails assert_equals: operations should be performed in the right order expected "get on size (writable)" but got "" >+FAIL TransformStream constructor should stop after get on highWaterMark (writable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable)" but got "" >+FAIL TransformStream constructor should stop after get on size (readable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable)" but got "" >+FAIL TransformStream constructor should stop after get on highWaterMark (readable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable)" but got "" >+FAIL TransformStream constructor should stop after get on writableType fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType" but got "" >+FAIL TransformStream constructor should stop after validate on writableType fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType" but got "" >+FAIL TransformStream constructor should stop after validate on size (writable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType" but got "" >+FAIL TransformStream constructor should stop after tonumber on highWaterMark (writable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable)" but got "" >+FAIL TransformStream constructor should stop after validate on highWaterMark (writable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable)" but got "" >+FAIL TransformStream constructor should stop after get on readableType fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType" but got "" >+FAIL TransformStream constructor should stop after validate on readableType fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType" but got "" >+FAIL TransformStream constructor should stop after validate on size (readable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType" but got "" >+FAIL TransformStream constructor should stop after tonumber on highWaterMark (readable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable)" but got "" >+FAIL TransformStream constructor should stop after validate on highWaterMark (readable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable)" but got "" >+FAIL TransformStream constructor should stop after get on transform fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable),get on transform" but got "" >+FAIL TransformStream constructor should stop after validate on transform fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable),get on transform" but got "" >+FAIL TransformStream constructor should stop after get on flush fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable),get on transform,get on flush" but got "" >+FAIL TransformStream constructor should stop after validate on flush fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable),get on transform,get on flush" but got "" >+FAIL TransformStream constructor should stop after get on start fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable),get on transform,get on flush,get on start" but got "" >+FAIL TransformStream constructor should stop after validate on start fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable),get on transform,get on flush,get on start" but got "" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.dedicatedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.dedicatedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..c06f8f80cce5bcee8303910c1d3c8c3f35ebbee3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.dedicatedworker-expected.txt >@@ -0,0 +1,22 @@ >+ >+FAIL TransformStream constructor should stop after get on size (writable) fails assert_equals: operations should be performed in the right order expected "get on size (writable)" but got "" >+FAIL TransformStream constructor should stop after get on highWaterMark (writable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable)" but got "" >+FAIL TransformStream constructor should stop after get on size (readable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable)" but got "" >+FAIL TransformStream constructor should stop after get on highWaterMark (readable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable)" but got "" >+FAIL TransformStream constructor should stop after get on writableType fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType" but got "" >+FAIL TransformStream constructor should stop after validate on writableType fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType" but got "" >+FAIL TransformStream constructor should stop after validate on size (writable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType" but got "" >+FAIL TransformStream constructor should stop after tonumber on highWaterMark (writable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable)" but got "" >+FAIL TransformStream constructor should stop after validate on highWaterMark (writable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable)" but got "" >+FAIL TransformStream constructor should stop after get on readableType fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType" but got "" >+FAIL TransformStream constructor should stop after validate on readableType fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType" but got "" >+FAIL TransformStream constructor should stop after validate on size (readable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType" but got "" >+FAIL TransformStream constructor should stop after tonumber on highWaterMark (readable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable)" but got "" >+FAIL TransformStream constructor should stop after validate on highWaterMark (readable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable)" but got "" >+FAIL TransformStream constructor should stop after get on transform fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable),get on transform" but got "" >+FAIL TransformStream constructor should stop after validate on transform fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable),get on transform" but got "" >+FAIL TransformStream constructor should stop after get on flush fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable),get on transform,get on flush" but got "" >+FAIL TransformStream constructor should stop after validate on flush fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable),get on transform,get on flush" but got "" >+FAIL TransformStream constructor should stop after get on start fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable),get on transform,get on flush,get on start" but got "" >+FAIL TransformStream constructor should stop after validate on start fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable),get on transform,get on flush,get on start" but got "" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.dedicatedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.dedicatedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..aebe97ef88a3dc6726756e37ece747d6a68ae498 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.dedicatedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>constructor.js dedicated worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new Worker('constructor.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.html >new file mode 100644 >index 0000000000000000000000000000000000000000..a548e088685affc72c67c5584d9ffac0a1f6e18a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.html >@@ -0,0 +1,10 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>constructor.js browser context wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script src="../resources/constructor-ordering.js"></script> >+ >+<script src="constructor.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.js b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.js >new file mode 100644 >index 0000000000000000000000000000000000000000..62770031184842a2257cd7c63674cfe6fc5b2420 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.js >@@ -0,0 +1,51 @@ >+'use strict'; >+ >+if (self.importScripts) { >+ self.importScripts('/resources/testharness.js'); >+ self.importScripts('../resources/constructor-ordering.js'); >+} >+ >+const operations = [ >+ op('get', 'size', 'writable'), >+ op('get', 'highWaterMark', 'writable'), >+ op('get', 'size', 'readable'), >+ op('get', 'highWaterMark', 'readable'), >+ op('get', 'writableType'), >+ op('validate', 'writableType'), >+ op('validate', 'size', 'writable'), >+ op('tonumber', 'highWaterMark', 'writable'), >+ op('validate', 'highWaterMark', 'writable'), >+ op('get', 'readableType'), >+ op('validate', 'readableType'), >+ op('validate', 'size', 'readable'), >+ op('tonumber', 'highWaterMark', 'readable'), >+ op('validate', 'highWaterMark', 'readable'), >+ op('get', 'transform'), >+ op('validate', 'transform'), >+ op('get', 'flush'), >+ op('validate', 'flush'), >+ op('get', 'start'), >+ op('validate', 'start') >+]; >+ >+for (const failureOp of operations) { >+ test(() => { >+ const record = new OpRecorder(failureOp); >+ const transformer = createRecordingObjectWithProperties( >+ record, ['readableType', 'writableType', 'start', 'transform', 'flush']); >+ const writableStrategy = createRecordingStrategy(record, 'writable'); >+ const readableStrategy = createRecordingStrategy(record, 'readable'); >+ >+ try { >+ new TransformStream(transformer, writableStrategy, readableStrategy); >+ assert_unreached('constructor should throw'); >+ } catch (e) { >+ assert_equals(typeof e, 'object', 'e should be an object'); >+ } >+ >+ assert_equals(record.actual(), expectedAsString(operations, failureOp), >+ 'operations should be performed in the right order'); >+ }, `TransformStream constructor should stop after ${failureOp} fails`); >+} >+ >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.serviceworker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.serviceworker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..edf70de31f4733fd9b4eea06995854b915fa868d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.serviceworker.https-expected.txt >@@ -0,0 +1,23 @@ >+ >+PASS Service worker test setup >+FAIL TransformStream constructor should stop after get on size (writable) fails assert_equals: operations should be performed in the right order expected "get on size (writable)" but got "" >+FAIL TransformStream constructor should stop after get on highWaterMark (writable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable)" but got "" >+FAIL TransformStream constructor should stop after get on size (readable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable)" but got "" >+FAIL TransformStream constructor should stop after get on highWaterMark (readable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable)" but got "" >+FAIL TransformStream constructor should stop after get on writableType fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType" but got "" >+FAIL TransformStream constructor should stop after validate on writableType fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType" but got "" >+FAIL TransformStream constructor should stop after validate on size (writable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType" but got "" >+FAIL TransformStream constructor should stop after tonumber on highWaterMark (writable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable)" but got "" >+FAIL TransformStream constructor should stop after validate on highWaterMark (writable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable)" but got "" >+FAIL TransformStream constructor should stop after get on readableType fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType" but got "" >+FAIL TransformStream constructor should stop after validate on readableType fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType" but got "" >+FAIL TransformStream constructor should stop after validate on size (readable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType" but got "" >+FAIL TransformStream constructor should stop after tonumber on highWaterMark (readable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable)" but got "" >+FAIL TransformStream constructor should stop after validate on highWaterMark (readable) fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable)" but got "" >+FAIL TransformStream constructor should stop after get on transform fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable),get on transform" but got "" >+FAIL TransformStream constructor should stop after validate on transform fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable),get on transform" but got "" >+FAIL TransformStream constructor should stop after get on flush fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable),get on transform,get on flush" but got "" >+FAIL TransformStream constructor should stop after validate on flush fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable),get on transform,get on flush" but got "" >+FAIL TransformStream constructor should stop after get on start fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable),get on transform,get on flush,get on start" but got "" >+FAIL TransformStream constructor should stop after validate on start fails assert_equals: operations should be performed in the right order expected "get on size (writable),get on highWaterMark (writable),get on size (readable),get on highWaterMark (readable),get on writableType,tonumber on highWaterMark (writable),get on readableType,tonumber on highWaterMark (readable),get on transform,get on flush,get on start" but got "" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.serviceworker.https.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.serviceworker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ddddf06652427a3f0c579e0c66518729a6820f36 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.serviceworker.https.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>constructor.js service worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> >+ >+<script> >+'use strict'; >+service_worker_test('constructor.js', 'Service worker test setup'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.sharedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.sharedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2e2954f1ccd19f38dd0318dbdef3b16aa374ea2c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.sharedworker-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 10: ReferenceError: Can't find variable: SharedWorker >+ >+FAIL constructor.js shared worker wrapper file ReferenceError: Can't find variable: SharedWorker >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.sharedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.sharedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..52b1a5daf99e8511dbca8335b05ed7dff9e270b7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.sharedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>constructor.js shared worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new SharedWorker('constructor.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..1df6bba508710ef5ce51feddf2c27bf33b08f65a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors-expected.txt >@@ -0,0 +1,36 @@ >+ >+FAIL TransformStream errors thrown in transform put the writable and readable in an errored state Can't find variable: TransformStream >+FAIL TransformStream errors thrown in flush put the writable and readable in an errored state Can't find variable: TransformStream >+FAIL errored TransformStream should not enqueue new chunks Can't find variable: TransformStream >+FAIL TransformStream transformer.start() rejected promise should error the stream Can't find variable: TransformStream >+FAIL when controller.error is followed by a rejection, the error reason should come from controller.error Can't find variable: TransformStream >+FAIL TransformStream constructor should throw when start does assert_throws: constructor should throw function "() => new TransformStream({ >+ start() { throw new URIError('start thrown error'); }, >+ transform() {} >+ })" threw object "ReferenceError: Can't find variable: TransformStream" ("ReferenceError") expected object "URIError" ("URIError") >+FAIL when strategy.size throws inside start(), the constructor should throw the same error assert_throws: constructor should throw the same error strategy.size throws function "() => new TransformStream({ >+ start(c) { >+ c.enqueue('a'); >+ }, >+ transform() {} >+ }, undefined, strategy)" threw object "ReferenceError: Can't find variable: TransformStream" ("ReferenceError") expected object "URIError" ("URIError") >+FAIL when strategy.size calls controller.error() then throws, the constructor should throw the first error assert_throws: the first error should be thrown function "() => new TransformStream({ >+ start(c) { >+ controller = c; >+ c.enqueue('a'); >+ }, >+ transform() {} >+ }, undefined, strategy)" threw object "ReferenceError: Can't find variable: TransformStream" ("ReferenceError") expected object "URIError" ("URIError") >+FAIL cancelling the readable side should error the writable Can't find variable: TransformStream >+FAIL it should be possible to error the readable between close requested and complete Can't find variable: TransformStream >+FAIL an exception from transform() should error the stream if terminate has been requested but not completed Can't find variable: TransformStream >+FAIL abort should set the close reason for the writable when it happens before cancel during start, but cancel should still succeed Can't find variable: TransformStream >+FAIL abort should set the close reason for the writable when it happens before cancel during underlying sink write, but cancel should still succeed Can't find variable: TransformStream >+FAIL controller.error() should do nothing the second time it is called Can't find variable: TransformStream >+FAIL controller.error() should do nothing after readable.cancel() Can't find variable: TransformStream >+FAIL controller.error() should do nothing after writable.abort() has completed Can't find variable: TransformStream >+FAIL controller.error() should do nothing after a transformer method has thrown an exception Can't find variable: TransformStream >+FAIL erroring during write with backpressure should result in the write failing Can't find variable: TransformStream >+FAIL a write() that was waiting for backpressure should reject if the writable is aborted Can't find variable: TransformStream >+FAIL the readable should be errored with the reason passed to the writable abort() method Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.dedicatedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.dedicatedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..1df6bba508710ef5ce51feddf2c27bf33b08f65a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.dedicatedworker-expected.txt >@@ -0,0 +1,36 @@ >+ >+FAIL TransformStream errors thrown in transform put the writable and readable in an errored state Can't find variable: TransformStream >+FAIL TransformStream errors thrown in flush put the writable and readable in an errored state Can't find variable: TransformStream >+FAIL errored TransformStream should not enqueue new chunks Can't find variable: TransformStream >+FAIL TransformStream transformer.start() rejected promise should error the stream Can't find variable: TransformStream >+FAIL when controller.error is followed by a rejection, the error reason should come from controller.error Can't find variable: TransformStream >+FAIL TransformStream constructor should throw when start does assert_throws: constructor should throw function "() => new TransformStream({ >+ start() { throw new URIError('start thrown error'); }, >+ transform() {} >+ })" threw object "ReferenceError: Can't find variable: TransformStream" ("ReferenceError") expected object "URIError" ("URIError") >+FAIL when strategy.size throws inside start(), the constructor should throw the same error assert_throws: constructor should throw the same error strategy.size throws function "() => new TransformStream({ >+ start(c) { >+ c.enqueue('a'); >+ }, >+ transform() {} >+ }, undefined, strategy)" threw object "ReferenceError: Can't find variable: TransformStream" ("ReferenceError") expected object "URIError" ("URIError") >+FAIL when strategy.size calls controller.error() then throws, the constructor should throw the first error assert_throws: the first error should be thrown function "() => new TransformStream({ >+ start(c) { >+ controller = c; >+ c.enqueue('a'); >+ }, >+ transform() {} >+ }, undefined, strategy)" threw object "ReferenceError: Can't find variable: TransformStream" ("ReferenceError") expected object "URIError" ("URIError") >+FAIL cancelling the readable side should error the writable Can't find variable: TransformStream >+FAIL it should be possible to error the readable between close requested and complete Can't find variable: TransformStream >+FAIL an exception from transform() should error the stream if terminate has been requested but not completed Can't find variable: TransformStream >+FAIL abort should set the close reason for the writable when it happens before cancel during start, but cancel should still succeed Can't find variable: TransformStream >+FAIL abort should set the close reason for the writable when it happens before cancel during underlying sink write, but cancel should still succeed Can't find variable: TransformStream >+FAIL controller.error() should do nothing the second time it is called Can't find variable: TransformStream >+FAIL controller.error() should do nothing after readable.cancel() Can't find variable: TransformStream >+FAIL controller.error() should do nothing after writable.abort() has completed Can't find variable: TransformStream >+FAIL controller.error() should do nothing after a transformer method has thrown an exception Can't find variable: TransformStream >+FAIL erroring during write with backpressure should result in the write failing Can't find variable: TransformStream >+FAIL a write() that was waiting for backpressure should reject if the writable is aborted Can't find variable: TransformStream >+FAIL the readable should be errored with the reason passed to the writable abort() method Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.dedicatedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.dedicatedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..078591779a81981c5696d3d904dbe8ddfa23c037 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.dedicatedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>errors.js dedicated worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new Worker('errors.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.html >new file mode 100644 >index 0000000000000000000000000000000000000000..3a07b47e2cf851705b1ba8ff6364b2c9b925444d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.html >@@ -0,0 +1,10 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>errors.js browser context wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script src="../resources/test-utils.js"></script> >+ >+<script src="errors.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.js b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.js >new file mode 100644 >index 0000000000000000000000000000000000000000..fdb2154554696ad651f5fec49531fdc6aa050698 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.js >@@ -0,0 +1,346 @@ >+'use strict'; >+ >+if (self.importScripts) { >+ self.importScripts('/resources/testharness.js'); >+ self.importScripts('../resources/test-utils.js'); >+} >+ >+const thrownError = new Error('bad things are happening!'); >+thrownError.name = 'error1'; >+ >+promise_test(t => { >+ const ts = new TransformStream({ >+ transform() { >+ throw thrownError; >+ } >+ }); >+ >+ const reader = ts.readable.getReader(); >+ >+ const writer = ts.writable.getWriter(); >+ >+ return Promise.all([ >+ promise_rejects(t, thrownError, writer.write('a'), >+ 'writable\'s write should reject with the thrown error'), >+ promise_rejects(t, thrownError, reader.read(), >+ 'readable\'s read should reject with the thrown error'), >+ promise_rejects(t, thrownError, reader.closed, >+ 'readable\'s closed should be rejected with the thrown error'), >+ promise_rejects(t, thrownError, writer.closed, >+ 'writable\'s closed should be rejected with the thrown error') >+ ]); >+}, 'TransformStream errors thrown in transform put the writable and readable in an errored state'); >+ >+promise_test(t => { >+ const ts = new TransformStream({ >+ transform() { >+ }, >+ flush() { >+ throw thrownError; >+ } >+ }); >+ >+ const reader = ts.readable.getReader(); >+ >+ const writer = ts.writable.getWriter(); >+ >+ return Promise.all([ >+ writer.write('a'), >+ promise_rejects(t, thrownError, writer.close(), >+ 'writable\'s close should reject with the thrown error'), >+ promise_rejects(t, thrownError, reader.read(), >+ 'readable\'s read should reject with the thrown error'), >+ promise_rejects(t, thrownError, reader.closed, >+ 'readable\'s closed should be rejected with the thrown error'), >+ promise_rejects(t, thrownError, writer.closed, >+ 'writable\'s closed should be rejected with the thrown error') >+ ]); >+}, 'TransformStream errors thrown in flush put the writable and readable in an errored state'); >+ >+test(() => { >+ new TransformStream({ >+ start(c) { >+ c.enqueue('a'); >+ c.error(new Error('generic error')); >+ assert_throws(new TypeError(), () => c.enqueue('b'), 'enqueue() should throw'); >+ } >+ }); >+}, 'errored TransformStream should not enqueue new chunks'); >+ >+promise_test(t => { >+ const ts = new TransformStream({ >+ start() { >+ return flushAsyncEvents().then(() => { >+ throw thrownError; >+ }); >+ }, >+ transform: t.unreached_func('transform should not be called'), >+ flush: t.unreached_func('flush should not be called') >+ }); >+ >+ const writer = ts.writable.getWriter(); >+ const reader = ts.readable.getReader(); >+ return Promise.all([ >+ promise_rejects(t, thrownError, writer.write('a'), 'writer should reject with thrownError'), >+ promise_rejects(t, thrownError, writer.close(), 'close() should reject with thrownError'), >+ promise_rejects(t, thrownError, reader.read(), 'reader should reject with thrownError') >+ ]); >+}, 'TransformStream transformer.start() rejected promise should error the stream'); >+ >+promise_test(t => { >+ const controllerError = new Error('start failure'); >+ controllerError.name = 'controllerError'; >+ const ts = new TransformStream({ >+ start(c) { >+ return flushAsyncEvents() >+ .then(() => { >+ c.error(controllerError); >+ throw new Error('ignored error'); >+ }); >+ }, >+ transform: t.unreached_func('transform should never be called if start() fails'), >+ flush: t.unreached_func('flush should never be called if start() fails') >+ }); >+ >+ const writer = ts.writable.getWriter(); >+ const reader = ts.readable.getReader(); >+ return Promise.all([ >+ promise_rejects(t, controllerError, writer.write('a'), 'writer should reject with controllerError'), >+ promise_rejects(t, controllerError, writer.close(), 'close should reject with same error'), >+ promise_rejects(t, controllerError, reader.read(), 'reader should reject with same error') >+ ]); >+}, 'when controller.error is followed by a rejection, the error reason should come from controller.error'); >+ >+test(() => { >+ assert_throws(new URIError(), () => new TransformStream({ >+ start() { throw new URIError('start thrown error'); }, >+ transform() {} >+ }), 'constructor should throw'); >+}, 'TransformStream constructor should throw when start does'); >+ >+test(() => { >+ const strategy = { >+ size() { throw new URIError('size thrown error'); } >+ }; >+ >+ assert_throws(new URIError(), () => new TransformStream({ >+ start(c) { >+ c.enqueue('a'); >+ }, >+ transform() {} >+ }, undefined, strategy), 'constructor should throw the same error strategy.size throws'); >+}, 'when strategy.size throws inside start(), the constructor should throw the same error'); >+ >+test(() => { >+ const controllerError = new URIError('controller.error'); >+ >+ let controller; >+ const strategy = { >+ size() { >+ controller.error(controllerError); >+ throw new Error('redundant error'); >+ } >+ }; >+ >+ assert_throws(new URIError(), () => new TransformStream({ >+ start(c) { >+ controller = c; >+ c.enqueue('a'); >+ }, >+ transform() {} >+ }, undefined, strategy), 'the first error should be thrown'); >+}, 'when strategy.size calls controller.error() then throws, the constructor should throw the first error'); >+ >+promise_test(t => { >+ const ts = new TransformStream(); >+ const writer = ts.writable.getWriter(); >+ const closedPromise = writer.closed; >+ return Promise.all([ >+ ts.readable.cancel(thrownError), >+ promise_rejects(t, thrownError, closedPromise, 'closed should throw a TypeError') >+ ]); >+}, 'cancelling the readable side should error the writable'); >+ >+promise_test(t => { >+ let controller; >+ const ts = new TransformStream({ >+ start(c) { >+ controller = c; >+ } >+ }); >+ const writer = ts.writable.getWriter(); >+ const reader = ts.readable.getReader(); >+ const writePromise = writer.write('a'); >+ const closePromise = writer.close(); >+ controller.error(thrownError); >+ return Promise.all([ >+ promise_rejects(t, thrownError, reader.closed, 'reader.closed should reject'), >+ promise_rejects(t, thrownError, writePromise, 'writePromise should reject'), >+ promise_rejects(t, thrownError, closePromise, 'closePromise should reject')]); >+}, 'it should be possible to error the readable between close requested and complete'); >+ >+promise_test(t => { >+ const ts = new TransformStream({ >+ transform(chunk, controller) { >+ controller.enqueue(chunk); >+ controller.terminate(); >+ throw thrownError; >+ } >+ }, undefined, { highWaterMark: 1 }); >+ const writePromise = ts.writable.getWriter().write('a'); >+ const closedPromise = ts.readable.getReader().closed; >+ return Promise.all([ >+ promise_rejects(t, thrownError, writePromise, 'write() should reject'), >+ promise_rejects(t, thrownError, closedPromise, 'reader.closed should reject') >+ ]); >+}, 'an exception from transform() should error the stream if terminate has been requested but not completed'); >+ >+promise_test(t => { >+ const ts = new TransformStream(); >+ const writer = ts.writable.getWriter(); >+ // The microtask following transformer.start() hasn't completed yet, so the abort is queued and not notified to the >+ // TransformStream yet. >+ const abortPromise = writer.abort(thrownError); >+ const cancelPromise = ts.readable.cancel(new Error('cancel reason')); >+ return Promise.all([ >+ abortPromise, >+ cancelPromise, >+ promise_rejects(t, thrownError, writer.closed, 'writer.closed should reject with thrownError')]); >+}, 'abort should set the close reason for the writable when it happens before cancel during start, but cancel should ' + >+ 'still succeed'); >+ >+promise_test(t => { >+ let resolveTransform; >+ const transformPromise = new Promise(resolve => { >+ resolveTransform = resolve; >+ }); >+ const ts = new TransformStream({ >+ transform() { >+ return transformPromise; >+ } >+ }, undefined, { highWaterMark: 2 }); >+ const writer = ts.writable.getWriter(); >+ return delay(0).then(() => { >+ const writePromise = writer.write(); >+ const abortPromise = writer.abort(thrownError); >+ const cancelPromise = ts.readable.cancel(new Error('cancel reason')); >+ resolveTransform(); >+ return Promise.all([ >+ writePromise, >+ abortPromise, >+ cancelPromise, >+ promise_rejects(t, thrownError, writer.closed, 'writer.closed should reject with thrownError')]); >+ }); >+}, 'abort should set the close reason for the writable when it happens before cancel during underlying sink write, ' + >+ 'but cancel should still succeed'); >+ >+const ignoredError = new Error('ignoredError'); >+ignoredError.name = 'ignoredError'; >+ >+promise_test(t => { >+ const ts = new TransformStream({ >+ start(controller) { >+ controller.error(thrownError); >+ controller.error(ignoredError); >+ } >+ }); >+ return promise_rejects(t, thrownError, ts.writable.abort(), 'abort() should reject with thrownError'); >+}, 'controller.error() should do nothing the second time it is called'); >+ >+promise_test(t => { >+ let controller; >+ const ts = new TransformStream({ >+ start(c) { >+ controller = c; >+ } >+ }); >+ const cancelPromise = ts.readable.cancel(thrownError); >+ controller.error(ignoredError); >+ return Promise.all([ >+ cancelPromise, >+ promise_rejects(t, thrownError, ts.writable.getWriter().closed, 'closed should reject with thrownError') >+ ]); >+}, 'controller.error() should do nothing after readable.cancel()'); >+ >+promise_test(t => { >+ let controller; >+ const ts = new TransformStream({ >+ start(c) { >+ controller = c; >+ } >+ }); >+ return ts.writable.abort(thrownError).then(() => { >+ controller.error(ignoredError); >+ return promise_rejects(t, thrownError, ts.writable.getWriter().closed, 'closed should reject with thrownError'); >+ }); >+}, 'controller.error() should do nothing after writable.abort() has completed'); >+ >+promise_test(t => { >+ let controller; >+ const ts = new TransformStream({ >+ start(c) { >+ controller = c; >+ }, >+ transform() { >+ throw thrownError; >+ } >+ }, undefined, { highWaterMark: Infinity }); >+ const writer = ts.writable.getWriter(); >+ return promise_rejects(t, thrownError, writer.write(), 'write() should reject').then(() => { >+ controller.error(); >+ return promise_rejects(t, thrownError, writer.closed, 'closed should reject with thrownError'); >+ }); >+}, 'controller.error() should do nothing after a transformer method has thrown an exception'); >+ >+promise_test(t => { >+ let controller; >+ let calls = 0; >+ const ts = new TransformStream({ >+ start(c) { >+ controller = c; >+ }, >+ transform() { >+ ++calls; >+ } >+ }, undefined, { highWaterMark: 1 }); >+ return delay(0).then(() => { >+ // Create backpressure. >+ controller.enqueue('a'); >+ const writer = ts.writable.getWriter(); >+ // transform() will not be called until backpressure is relieved. >+ const writePromise = writer.write('b'); >+ assert_equals(calls, 0, 'transform() should not have been called'); >+ controller.error(thrownError); >+ // Now backpressure has been relieved and the write can proceed. >+ return promise_rejects(t, thrownError, writePromise, 'write() should reject').then(() => { >+ assert_equals(calls, 0, 'transform() should not be called'); >+ }); >+ }); >+}, 'erroring during write with backpressure should result in the write failing'); >+ >+promise_test(t => { >+ const ts = new TransformStream({}, undefined, { highWaterMark: 0 }); >+ return delay(0).then(() => { >+ const writer = ts.writable.getWriter(); >+ // write should start synchronously >+ const writePromise = writer.write(0); >+ // The underlying sink's abort() is not called until the write() completes. >+ const abortPromise = writer.abort(thrownError); >+ // Perform a read to relieve backpressure and permit the write() to complete. >+ const readPromise = ts.readable.getReader().read(); >+ return Promise.all([ >+ promise_rejects(t, thrownError, readPromise, 'read() should reject'), >+ promise_rejects(t, thrownError, writePromise, 'write() should reject'), >+ abortPromise >+ ]); >+ }); >+}, 'a write() that was waiting for backpressure should reject if the writable is aborted'); >+ >+promise_test(t => { >+ const ts = new TransformStream(); >+ ts.writable.abort(thrownError); >+ const reader = ts.readable.getReader(); >+ return promise_rejects(t, thrownError, reader.read(), 'read() should reject with thrownError'); >+}, 'the readable should be errored with the reason passed to the writable abort() method'); >+ >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.serviceworker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.serviceworker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..76562822314aa2ad995b836c6622fb996559dab6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.serviceworker.https-expected.txt >@@ -0,0 +1,37 @@ >+ >+PASS Service worker test setup >+FAIL TransformStream errors thrown in transform put the writable and readable in an errored state Can't find variable: TransformStream >+FAIL TransformStream errors thrown in flush put the writable and readable in an errored state Can't find variable: TransformStream >+FAIL errored TransformStream should not enqueue new chunks Can't find variable: TransformStream >+FAIL TransformStream transformer.start() rejected promise should error the stream Can't find variable: TransformStream >+FAIL when controller.error is followed by a rejection, the error reason should come from controller.error Can't find variable: TransformStream >+FAIL TransformStream constructor should throw when start does assert_throws: constructor should throw function "() => new TransformStream({ >+ start() { throw new URIError('start thrown error'); }, >+ transform() {} >+ })" threw object "ReferenceError: Can't find variable: TransformStream" ("ReferenceError") expected object "URIError" ("URIError") >+FAIL when strategy.size throws inside start(), the constructor should throw the same error assert_throws: constructor should throw the same error strategy.size throws function "() => new TransformStream({ >+ start(c) { >+ c.enqueue('a'); >+ }, >+ transform() {} >+ }, undefined, strategy)" threw object "ReferenceError: Can't find variable: TransformStream" ("ReferenceError") expected object "URIError" ("URIError") >+FAIL when strategy.size calls controller.error() then throws, the constructor should throw the first error assert_throws: the first error should be thrown function "() => new TransformStream({ >+ start(c) { >+ controller = c; >+ c.enqueue('a'); >+ }, >+ transform() {} >+ }, undefined, strategy)" threw object "ReferenceError: Can't find variable: TransformStream" ("ReferenceError") expected object "URIError" ("URIError") >+FAIL cancelling the readable side should error the writable Can't find variable: TransformStream >+FAIL it should be possible to error the readable between close requested and complete Can't find variable: TransformStream >+FAIL an exception from transform() should error the stream if terminate has been requested but not completed Can't find variable: TransformStream >+FAIL abort should set the close reason for the writable when it happens before cancel during start, but cancel should still succeed Can't find variable: TransformStream >+FAIL abort should set the close reason for the writable when it happens before cancel during underlying sink write, but cancel should still succeed Can't find variable: TransformStream >+FAIL controller.error() should do nothing the second time it is called Can't find variable: TransformStream >+FAIL controller.error() should do nothing after readable.cancel() Can't find variable: TransformStream >+FAIL controller.error() should do nothing after writable.abort() has completed Can't find variable: TransformStream >+FAIL controller.error() should do nothing after a transformer method has thrown an exception Can't find variable: TransformStream >+FAIL erroring during write with backpressure should result in the write failing Can't find variable: TransformStream >+FAIL a write() that was waiting for backpressure should reject if the writable is aborted Can't find variable: TransformStream >+FAIL the readable should be errored with the reason passed to the writable abort() method Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.serviceworker.https.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.serviceworker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..85707ebb8ce5d3d6004db95471dba7b6caf742ee >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.serviceworker.https.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>errors.js service worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> >+ >+<script> >+'use strict'; >+service_worker_test('errors.js', 'Service worker test setup'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.sharedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.sharedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..02d43acf78145fbc3d9239aa5cd429ff79570c6a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.sharedworker-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 10: ReferenceError: Can't find variable: SharedWorker >+ >+FAIL errors.js shared worker wrapper file ReferenceError: Can't find variable: SharedWorker >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.sharedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.sharedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..011d843ffa2301a9c96da494cb925fa08c69c20e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.sharedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>errors.js shared worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new SharedWorker('errors.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..8ded81a19445f7aab02be6441196ae8833c4753b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush-expected.txt >@@ -0,0 +1,7 @@ >+ >+FAIL TransformStream flush is called immediately when the writable is closed, if no writes are queued Can't find variable: TransformStream >+FAIL TransformStream flush is called after all queued writes finish, once the writable is closed Can't find variable: TransformStream >+FAIL TransformStream flush gets a chance to enqueue more into the readable Can't find variable: TransformStream >+FAIL TransformStream flush gets a chance to enqueue more into the readable, and can then async close Can't find variable: TransformStream >+FAIL error() during flush should cause writer.close() to reject Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.dedicatedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.dedicatedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..8ded81a19445f7aab02be6441196ae8833c4753b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.dedicatedworker-expected.txt >@@ -0,0 +1,7 @@ >+ >+FAIL TransformStream flush is called immediately when the writable is closed, if no writes are queued Can't find variable: TransformStream >+FAIL TransformStream flush is called after all queued writes finish, once the writable is closed Can't find variable: TransformStream >+FAIL TransformStream flush gets a chance to enqueue more into the readable Can't find variable: TransformStream >+FAIL TransformStream flush gets a chance to enqueue more into the readable, and can then async close Can't find variable: TransformStream >+FAIL error() during flush should cause writer.close() to reject Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.dedicatedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.dedicatedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..4633c1e3180852bc4af4d2abdde89380e1b301a2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.dedicatedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>flush.js dedicated worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new Worker('flush.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.html >new file mode 100644 >index 0000000000000000000000000000000000000000..af437b44e03e00e8c84dc859f3e527cacd920c51 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.html >@@ -0,0 +1,10 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>flush.js browser context wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script src="../resources/test-utils.js"></script> >+ >+<script src="flush.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.js b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.js >new file mode 100644 >index 0000000000000000000000000000000000000000..1e9909a7041779b878b4258fb37de20e80212d1c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.js >@@ -0,0 +1,136 @@ >+'use strict'; >+ >+if (self.importScripts) { >+ self.importScripts('../resources/test-utils.js'); >+ self.importScripts('/resources/testharness.js'); >+} >+ >+promise_test(() => { >+ let flushCalled = false; >+ const ts = new TransformStream({ >+ transform() { }, >+ flush() { >+ flushCalled = true; >+ } >+ }); >+ >+ return ts.writable.getWriter().close().then(() => { >+ return assert_true(flushCalled, 'closing the writable triggers the transform flush immediately'); >+ }); >+}, 'TransformStream flush is called immediately when the writable is closed, if no writes are queued'); >+ >+promise_test(() => { >+ let flushCalled = false; >+ let resolveTransform; >+ const ts = new TransformStream({ >+ transform() { >+ return new Promise(resolve => { >+ resolveTransform = resolve; >+ }); >+ }, >+ flush() { >+ flushCalled = true; >+ return new Promise(() => {}); // never resolves >+ } >+ }, undefined, { highWaterMark: 1 }); >+ >+ const writer = ts.writable.getWriter(); >+ writer.write('a'); >+ writer.close(); >+ assert_false(flushCalled, 'closing the writable does not immediately call flush if writes are not finished'); >+ >+ let rsClosed = false; >+ ts.readable.getReader().closed.then(() => { >+ rsClosed = true; >+ }); >+ >+ return delay(0).then(() => { >+ assert_false(flushCalled, 'closing the writable does not asynchronously call flush if writes are not finished'); >+ resolveTransform(); >+ return delay(0); >+ }).then(() => { >+ assert_true(flushCalled, 'flush is eventually called'); >+ assert_false(rsClosed, 'if flushPromise does not resolve, the readable does not become closed'); >+ }); >+}, 'TransformStream flush is called after all queued writes finish, once the writable is closed'); >+ >+promise_test(() => { >+ let c; >+ const ts = new TransformStream({ >+ start(controller) { >+ c = controller; >+ }, >+ transform() { >+ }, >+ flush() { >+ c.enqueue('x'); >+ c.enqueue('y'); >+ } >+ }); >+ >+ const reader = ts.readable.getReader(); >+ >+ const writer = ts.writable.getWriter(); >+ writer.write('a'); >+ writer.close(); >+ return reader.read().then(result1 => { >+ assert_equals(result1.value, 'x', 'the first chunk read is the first one enqueued in flush'); >+ assert_equals(result1.done, false, 'the first chunk read is the first one enqueued in flush'); >+ >+ return reader.read().then(result2 => { >+ assert_equals(result2.value, 'y', 'the second chunk read is the second one enqueued in flush'); >+ assert_equals(result2.done, false, 'the second chunk read is the second one enqueued in flush'); >+ }); >+ }); >+}, 'TransformStream flush gets a chance to enqueue more into the readable'); >+ >+promise_test(() => { >+ let c; >+ const ts = new TransformStream({ >+ start(controller) { >+ c = controller; >+ }, >+ transform() { >+ }, >+ flush() { >+ c.enqueue('x'); >+ c.enqueue('y'); >+ return delay(0); >+ } >+ }); >+ >+ const reader = ts.readable.getReader(); >+ >+ const writer = ts.writable.getWriter(); >+ writer.write('a'); >+ writer.close(); >+ >+ return Promise.all([ >+ reader.read().then(result1 => { >+ assert_equals(result1.value, 'x', 'the first chunk read is the first one enqueued in flush'); >+ assert_equals(result1.done, false, 'the first chunk read is the first one enqueued in flush'); >+ >+ return reader.read().then(result2 => { >+ assert_equals(result2.value, 'y', 'the second chunk read is the second one enqueued in flush'); >+ assert_equals(result2.done, false, 'the second chunk read is the second one enqueued in flush'); >+ }); >+ }), >+ reader.closed.then(() => { >+ assert_true(true, 'readable reader becomes closed'); >+ }) >+ ]); >+}, 'TransformStream flush gets a chance to enqueue more into the readable, and can then async close'); >+ >+const error1 = new Error('error1'); >+error1.name = 'error1'; >+ >+promise_test(t => { >+ const ts = new TransformStream({ >+ flush(controller) { >+ controller.error(error1); >+ } >+ }); >+ return promise_rejects(t, error1, ts.writable.getWriter().close(), 'close() should reject'); >+}, 'error() during flush should cause writer.close() to reject'); >+ >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.serviceworker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.serviceworker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d2d1c20724ad5a1e4fec65ef597aebace1163043 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.serviceworker.https-expected.txt >@@ -0,0 +1,8 @@ >+ >+PASS Service worker test setup >+FAIL TransformStream flush is called immediately when the writable is closed, if no writes are queued Can't find variable: TransformStream >+FAIL TransformStream flush is called after all queued writes finish, once the writable is closed Can't find variable: TransformStream >+FAIL TransformStream flush gets a chance to enqueue more into the readable Can't find variable: TransformStream >+FAIL TransformStream flush gets a chance to enqueue more into the readable, and can then async close Can't find variable: TransformStream >+FAIL error() during flush should cause writer.close() to reject Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.serviceworker.https.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.serviceworker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..37d067a5084e4d641123614eb06e48030ee534db >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.serviceworker.https.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>flush.js service worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> >+ >+<script> >+'use strict'; >+service_worker_test('flush.js', 'Service worker test setup'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.sharedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.sharedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..0228866881b0cf89168baf3ec0ebfde34c143c40 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.sharedworker-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 10: ReferenceError: Can't find variable: SharedWorker >+ >+FAIL flush.js shared worker wrapper file ReferenceError: Can't find variable: SharedWorker >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.sharedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.sharedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d57bb81b358cb4222350ff1aa25954004a58b0a9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.sharedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>flush.js shared worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new SharedWorker('flush.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..b3cf1a66227850338adc0288f803a34f3154332f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general-expected.txt >@@ -0,0 +1,27 @@ >+ >+FAIL TransformStream can be constructed with a transform function Can't find variable: TransformStream >+FAIL TransformStream can be constructed with no transform function Can't find variable: TransformStream >+FAIL TransformStream instances must have writable and readable properties of the correct types Can't find variable: TransformStream >+FAIL TransformStream writable starts in the writable state Can't find variable: TransformStream >+FAIL Identity TransformStream: can read from readable what is put into writable Can't find variable: TransformStream >+FAIL Uppercaser sync TransformStream: can read from readable transformed version of what is put into writable Can't find variable: TransformStream >+FAIL Uppercaser-doubler sync TransformStream: can read both chunks put into the readable Can't find variable: TransformStream >+FAIL Uppercaser async TransformStream: can read from readable transformed version of what is put into writable Can't find variable: TransformStream >+FAIL Uppercaser-doubler async TransformStream: can read both chunks put into the readable Can't find variable: TransformStream >+FAIL TransformStream: by default, closing the writable closes the readable (when there are no queued writes) Can't find variable: TransformStream >+FAIL TransformStream: by default, closing the writable waits for transforms to finish before closing both Can't find variable: TransformStream >+FAIL TransformStream: by default, closing the writable closes the readable after sync enqueues and async done Can't find variable: TransformStream >+FAIL TransformStream: by default, closing the writable closes the readable after async enqueues and async done Can't find variable: TransformStream >+FAIL Transform stream should call transformer methods as methods Can't find variable: TransformStream >+FAIL methods should not not have .apply() or .call() called Can't find variable: TransformStream >+FAIL TransformStream start, transform, and flush should be strictly ordered Can't find variable: TransformStream >+FAIL it should be possible to call transform() synchronously Can't find variable: TransformStream >+FAIL closing the writable should close the readable when there are no queued chunks, even with backpressure Can't find variable: TransformStream >+FAIL enqueue() should throw after controller.terminate() Can't find variable: TransformStream >+FAIL enqueue() should throw after readable.cancel() Can't find variable: TransformStream >+FAIL controller.terminate() should do nothing the second time it is called Can't find variable: TransformStream >+FAIL terminate() should do nothing after readable.cancel() Can't find variable: TransformStream >+FAIL start() should not be called twice Can't find variable: TransformStream >+FAIL specifying a defined readableType should throw assert_throws: constructor should throw function "() => new TransformStream({ readableType: 'bytes' })" threw object "ReferenceError: Can't find variable: TransformStream" ("ReferenceError") expected object "RangeError" ("RangeError") >+FAIL specifying a defined writableType should throw assert_throws: constructor should throw function "() => new TransformStream({ writableType: 'bytes' })" threw object "ReferenceError: Can't find variable: TransformStream" ("ReferenceError") expected object "RangeError" ("RangeError") >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.dedicatedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.dedicatedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..b3cf1a66227850338adc0288f803a34f3154332f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.dedicatedworker-expected.txt >@@ -0,0 +1,27 @@ >+ >+FAIL TransformStream can be constructed with a transform function Can't find variable: TransformStream >+FAIL TransformStream can be constructed with no transform function Can't find variable: TransformStream >+FAIL TransformStream instances must have writable and readable properties of the correct types Can't find variable: TransformStream >+FAIL TransformStream writable starts in the writable state Can't find variable: TransformStream >+FAIL Identity TransformStream: can read from readable what is put into writable Can't find variable: TransformStream >+FAIL Uppercaser sync TransformStream: can read from readable transformed version of what is put into writable Can't find variable: TransformStream >+FAIL Uppercaser-doubler sync TransformStream: can read both chunks put into the readable Can't find variable: TransformStream >+FAIL Uppercaser async TransformStream: can read from readable transformed version of what is put into writable Can't find variable: TransformStream >+FAIL Uppercaser-doubler async TransformStream: can read both chunks put into the readable Can't find variable: TransformStream >+FAIL TransformStream: by default, closing the writable closes the readable (when there are no queued writes) Can't find variable: TransformStream >+FAIL TransformStream: by default, closing the writable waits for transforms to finish before closing both Can't find variable: TransformStream >+FAIL TransformStream: by default, closing the writable closes the readable after sync enqueues and async done Can't find variable: TransformStream >+FAIL TransformStream: by default, closing the writable closes the readable after async enqueues and async done Can't find variable: TransformStream >+FAIL Transform stream should call transformer methods as methods Can't find variable: TransformStream >+FAIL methods should not not have .apply() or .call() called Can't find variable: TransformStream >+FAIL TransformStream start, transform, and flush should be strictly ordered Can't find variable: TransformStream >+FAIL it should be possible to call transform() synchronously Can't find variable: TransformStream >+FAIL closing the writable should close the readable when there are no queued chunks, even with backpressure Can't find variable: TransformStream >+FAIL enqueue() should throw after controller.terminate() Can't find variable: TransformStream >+FAIL enqueue() should throw after readable.cancel() Can't find variable: TransformStream >+FAIL controller.terminate() should do nothing the second time it is called Can't find variable: TransformStream >+FAIL terminate() should do nothing after readable.cancel() Can't find variable: TransformStream >+FAIL start() should not be called twice Can't find variable: TransformStream >+FAIL specifying a defined readableType should throw assert_throws: constructor should throw function "() => new TransformStream({ readableType: 'bytes' })" threw object "ReferenceError: Can't find variable: TransformStream" ("ReferenceError") expected object "RangeError" ("RangeError") >+FAIL specifying a defined writableType should throw assert_throws: constructor should throw function "() => new TransformStream({ writableType: 'bytes' })" threw object "ReferenceError: Can't find variable: TransformStream" ("ReferenceError") expected object "RangeError" ("RangeError") >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.dedicatedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.dedicatedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..86e480139e89172cccd2a08f1417dd3398f5328a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.dedicatedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>general.js dedicated worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new Worker('general.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.html >new file mode 100644 >index 0000000000000000000000000000000000000000..975cd009fd184e300d711397b014ba2abde67f8a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>general.js browser context wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script src="../resources/test-utils.js"></script> >+<script src="../resources/rs-utils.js"></script> >+ >+<script src="general.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.js b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.js >new file mode 100644 >index 0000000000000000000000000000000000000000..02614c495c2c232d88d74764e2db8e54addb8b1b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.js >@@ -0,0 +1,444 @@ >+'use strict'; >+ >+if (self.importScripts) { >+ self.importScripts('/resources/testharness.js'); >+ self.importScripts('../resources/test-utils.js'); >+ self.importScripts('../resources/rs-utils.js'); >+} >+ >+test(() => { >+ new TransformStream({ transform() { } }); >+}, 'TransformStream can be constructed with a transform function'); >+ >+test(() => { >+ new TransformStream(); >+ new TransformStream({}); >+}, 'TransformStream can be constructed with no transform function'); >+ >+test(() => { >+ const ts = new TransformStream({ transform() { } }); >+ const proto = Object.getPrototypeOf(ts); >+ >+ const writableStream = Object.getOwnPropertyDescriptor(proto, 'writable'); >+ assert_true(writableStream !== undefined, 'it has a writable property'); >+ assert_false(writableStream.enumerable, 'writable should be non-enumerable'); >+ assert_equals(typeof writableStream.get, 'function', 'writable should have a getter'); >+ assert_equals(writableStream.set, undefined, 'writable should not have a setter'); >+ assert_true(writableStream.configurable, 'writable should be configurable'); >+ assert_true(ts.writable instanceof WritableStream, 'writable is an instance of WritableStream'); >+ assert_not_equals(WritableStream.prototype.getWriter.call(ts.writable), undefined, >+ 'writable should pass WritableStream brand check'); >+ >+ const readableStream = Object.getOwnPropertyDescriptor(proto, 'readable'); >+ assert_true(readableStream !== undefined, 'it has a readable property'); >+ assert_false(readableStream.enumerable, 'readable should be non-enumerable'); >+ assert_equals(typeof readableStream.get, 'function', 'readable should have a getter'); >+ assert_equals(readableStream.set, undefined, 'readable should not have a setter'); >+ assert_true(readableStream.configurable, 'readable should be configurable'); >+ assert_true(ts.readable instanceof ReadableStream, 'readable is an instance of ReadableStream'); >+ assert_not_equals(ReadableStream.prototype.getReader.call(ts.readable), undefined, >+ 'readable should pass ReadableStream brand check'); >+}, 'TransformStream instances must have writable and readable properties of the correct types'); >+ >+test(() => { >+ const ts = new TransformStream({ transform() { } }); >+ >+ const writer = ts.writable.getWriter(); >+ assert_equals(writer.desiredSize, 1, 'writer.desiredSize should be 1'); >+}, 'TransformStream writable starts in the writable state'); >+ >+ >+promise_test(() => { >+ const ts = new TransformStream(); >+ >+ const writer = ts.writable.getWriter(); >+ writer.write('a'); >+ assert_equals(writer.desiredSize, 0, 'writer.desiredSize should be 0 after write()'); >+ >+ return ts.readable.getReader().read().then(result => { >+ assert_equals(result.value, 'a', >+ 'result from reading the readable is the same as was written to writable'); >+ assert_false(result.done, 'stream should not be done'); >+ >+ return delay(0).then(() => assert_equals(writer.desiredSize, 1, 'desiredSize should be 1 again')); >+ }); >+}, 'Identity TransformStream: can read from readable what is put into writable'); >+ >+promise_test(() => { >+ let c; >+ const ts = new TransformStream({ >+ start(controller) { >+ c = controller; >+ }, >+ transform(chunk) { >+ c.enqueue(chunk.toUpperCase()); >+ } >+ }); >+ >+ const writer = ts.writable.getWriter(); >+ writer.write('a'); >+ >+ return ts.readable.getReader().read().then(result => { >+ assert_equals(result.value, 'A', >+ 'result from reading the readable is the transformation of what was written to writable'); >+ assert_false(result.done, 'stream should not be done'); >+ }); >+}, 'Uppercaser sync TransformStream: can read from readable transformed version of what is put into writable'); >+ >+promise_test(() => { >+ let c; >+ const ts = new TransformStream({ >+ start(controller) { >+ c = controller; >+ }, >+ transform(chunk) { >+ c.enqueue(chunk.toUpperCase()); >+ c.enqueue(chunk.toUpperCase()); >+ } >+ }); >+ >+ const writer = ts.writable.getWriter(); >+ writer.write('a'); >+ >+ const reader = ts.readable.getReader(); >+ >+ return reader.read().then(result1 => { >+ assert_equals(result1.value, 'A', >+ 'the first chunk read is the transformation of the single chunk written'); >+ assert_false(result1.done, 'stream should not be done'); >+ >+ return reader.read().then(result2 => { >+ assert_equals(result2.value, 'A', >+ 'the second chunk read is also the transformation of the single chunk written'); >+ assert_false(result2.done, 'stream should not be done'); >+ }); >+ }); >+}, 'Uppercaser-doubler sync TransformStream: can read both chunks put into the readable'); >+ >+promise_test(() => { >+ let c; >+ const ts = new TransformStream({ >+ start(controller) { >+ c = controller; >+ }, >+ transform(chunk) { >+ return delay(0).then(() => c.enqueue(chunk.toUpperCase())); >+ } >+ }); >+ >+ const writer = ts.writable.getWriter(); >+ writer.write('a'); >+ >+ return ts.readable.getReader().read().then(result => { >+ assert_equals(result.value, 'A', >+ 'result from reading the readable is the transformation of what was written to writable'); >+ assert_false(result.done, 'stream should not be done'); >+ }); >+}, 'Uppercaser async TransformStream: can read from readable transformed version of what is put into writable'); >+ >+promise_test(() => { >+ let doSecondEnqueue; >+ let returnFromTransform; >+ const ts = new TransformStream({ >+ transform(chunk, controller) { >+ delay(0).then(() => controller.enqueue(chunk.toUpperCase())); >+ doSecondEnqueue = () => controller.enqueue(chunk.toUpperCase()); >+ return new Promise(resolve => { >+ returnFromTransform = resolve; >+ }); >+ } >+ }); >+ >+ const reader = ts.readable.getReader(); >+ >+ const writer = ts.writable.getWriter(); >+ writer.write('a'); >+ >+ return reader.read().then(result1 => { >+ assert_equals(result1.value, 'A', >+ 'the first chunk read is the transformation of the single chunk written'); >+ assert_false(result1.done, 'stream should not be done'); >+ doSecondEnqueue(); >+ >+ return reader.read().then(result2 => { >+ assert_equals(result2.value, 'A', >+ 'the second chunk read is also the transformation of the single chunk written'); >+ assert_false(result2.done, 'stream should not be done'); >+ returnFromTransform(); >+ }); >+ }); >+}, 'Uppercaser-doubler async TransformStream: can read both chunks put into the readable'); >+ >+promise_test(() => { >+ const ts = new TransformStream({ transform() { } }); >+ >+ const writer = ts.writable.getWriter(); >+ writer.close(); >+ >+ return Promise.all([writer.closed, ts.readable.getReader().closed]); >+}, 'TransformStream: by default, closing the writable closes the readable (when there are no queued writes)'); >+ >+promise_test(() => { >+ let transformResolve; >+ const transformPromise = new Promise(resolve => { >+ transformResolve = resolve; >+ }); >+ const ts = new TransformStream({ >+ transform() { >+ return transformPromise; >+ } >+ }, undefined, { highWaterMark: 1 }); >+ >+ const writer = ts.writable.getWriter(); >+ writer.write('a'); >+ writer.close(); >+ >+ let rsClosed = false; >+ ts.readable.getReader().closed.then(() => { >+ rsClosed = true; >+ }); >+ >+ return delay(0).then(() => { >+ assert_equals(rsClosed, false, 'readable is not closed after a tick'); >+ transformResolve(); >+ >+ return writer.closed.then(() => { >+ // TODO: Is this expectation correct? >+ assert_equals(rsClosed, true, 'readable is closed at that point'); >+ }); >+ }); >+}, 'TransformStream: by default, closing the writable waits for transforms to finish before closing both'); >+ >+promise_test(() => { >+ let c; >+ const ts = new TransformStream({ >+ start(controller) { >+ c = controller; >+ }, >+ transform() { >+ c.enqueue('x'); >+ c.enqueue('y'); >+ return delay(0); >+ } >+ }); >+ >+ const writer = ts.writable.getWriter(); >+ writer.write('a'); >+ writer.close(); >+ >+ const readableChunks = readableStreamToArray(ts.readable); >+ >+ return writer.closed.then(() => { >+ return readableChunks.then(chunks => { >+ assert_array_equals(chunks, ['x', 'y'], 'both enqueued chunks can be read from the readable'); >+ }); >+ }); >+}, 'TransformStream: by default, closing the writable closes the readable after sync enqueues and async done'); >+ >+promise_test(() => { >+ let c; >+ const ts = new TransformStream({ >+ start(controller) { >+ c = controller; >+ }, >+ transform() { >+ return delay(0) >+ .then(() => c.enqueue('x')) >+ .then(() => c.enqueue('y')) >+ .then(() => delay(0)); >+ } >+ }); >+ >+ const writer = ts.writable.getWriter(); >+ writer.write('a'); >+ writer.close(); >+ >+ const readableChunks = readableStreamToArray(ts.readable); >+ >+ return writer.closed.then(() => { >+ return readableChunks.then(chunks => { >+ assert_array_equals(chunks, ['x', 'y'], 'both enqueued chunks can be read from the readable'); >+ }); >+ }); >+}, 'TransformStream: by default, closing the writable closes the readable after async enqueues and async done'); >+ >+promise_test(() => { >+ let c; >+ const ts = new TransformStream({ >+ suffix: '-suffix', >+ >+ start(controller) { >+ c = controller; >+ c.enqueue('start' + this.suffix); >+ }, >+ >+ transform(chunk) { >+ c.enqueue(chunk + this.suffix); >+ }, >+ >+ flush() { >+ c.enqueue('flushed' + this.suffix); >+ } >+ }); >+ >+ const writer = ts.writable.getWriter(); >+ writer.write('a'); >+ writer.close(); >+ >+ const readableChunks = readableStreamToArray(ts.readable); >+ >+ return writer.closed.then(() => { >+ return readableChunks.then(chunks => { >+ assert_array_equals(chunks, ['start-suffix', 'a-suffix', 'flushed-suffix'], 'all enqueued chunks have suffixes'); >+ }); >+ }); >+}, 'Transform stream should call transformer methods as methods'); >+ >+promise_test(() => { >+ function functionWithOverloads() {} >+ functionWithOverloads.apply = () => assert_unreached('apply() should not be called'); >+ functionWithOverloads.call = () => assert_unreached('call() should not be called'); >+ const ts = new TransformStream({ >+ start: functionWithOverloads, >+ transform: functionWithOverloads, >+ flush: functionWithOverloads >+ }); >+ const writer = ts.writable.getWriter(); >+ writer.write('a'); >+ writer.close(); >+ >+ return readableStreamToArray(ts.readable); >+}, 'methods should not not have .apply() or .call() called'); >+ >+promise_test(t => { >+ let startCalled = false; >+ let startDone = false; >+ let transformDone = false; >+ let flushDone = false; >+ const ts = new TransformStream({ >+ start() { >+ startCalled = true; >+ return flushAsyncEvents().then(() => { >+ startDone = true; >+ }); >+ }, >+ transform() { >+ return t.step(() => { >+ assert_true(startDone, 'transform() should not be called until the promise returned from start() has resolved'); >+ return flushAsyncEvents().then(() => { >+ transformDone = true; >+ }); >+ }); >+ }, >+ flush() { >+ return t.step(() => { >+ assert_true(transformDone, >+ 'flush() should not be called until the promise returned from transform() has resolved'); >+ return flushAsyncEvents().then(() => { >+ flushDone = true; >+ }); >+ }); >+ } >+ }, undefined, { highWaterMark: 1 }); >+ >+ assert_true(startCalled, 'start() should be called synchronously'); >+ >+ const writer = ts.writable.getWriter(); >+ const writePromise = writer.write('a'); >+ return writer.close().then(() => { >+ assert_true(flushDone, 'promise returned from flush() should have resolved'); >+ return writePromise; >+ }); >+}, 'TransformStream start, transform, and flush should be strictly ordered'); >+ >+promise_test(() => { >+ let transformCalled = false; >+ const ts = new TransformStream({ >+ transform() { >+ transformCalled = true; >+ } >+ }, undefined, { highWaterMark: Infinity }); >+ // transform() is only called synchronously when there is no backpressure and all microtasks have run. >+ return delay(0).then(() => { >+ const writePromise = ts.writable.getWriter().write(); >+ assert_true(transformCalled, 'transform() should have been called'); >+ return writePromise; >+ }); >+}, 'it should be possible to call transform() synchronously'); >+ >+promise_test(() => { >+ const ts = new TransformStream({}, undefined, { highWaterMark: 0 }); >+ >+ const writer = ts.writable.getWriter(); >+ writer.close(); >+ >+ return Promise.all([writer.closed, ts.readable.getReader().closed]); >+}, 'closing the writable should close the readable when there are no queued chunks, even with backpressure'); >+ >+test(() => { >+ new TransformStream({ >+ start(controller) { >+ controller.terminate(); >+ assert_throws(new TypeError(), () => controller.enqueue(), 'enqueue should throw'); >+ } >+ }); >+}, 'enqueue() should throw after controller.terminate()'); >+ >+promise_test(() => { >+ let controller; >+ const ts = new TransformStream({ >+ start(c) { >+ controller = c; >+ } >+ }); >+ const cancelPromise = ts.readable.cancel(); >+ assert_throws(new TypeError(), () => controller.enqueue(), 'enqueue should throw'); >+ return cancelPromise; >+}, 'enqueue() should throw after readable.cancel()'); >+ >+test(() => { >+ new TransformStream({ >+ start(controller) { >+ controller.terminate(); >+ controller.terminate(); >+ } >+ }); >+}, 'controller.terminate() should do nothing the second time it is called'); >+ >+promise_test(t => { >+ let controller; >+ const ts = new TransformStream({ >+ start(c) { >+ controller = c; >+ } >+ }); >+ const cancelReason = { name: 'cancelReason' }; >+ const cancelPromise = ts.readable.cancel(cancelReason); >+ controller.terminate(); >+ return Promise.all([ >+ cancelPromise, >+ promise_rejects(t, cancelReason, ts.writable.getWriter().closed, 'closed should reject with cancelReason') >+ ]); >+}, 'terminate() should do nothing after readable.cancel()'); >+ >+promise_test(() => { >+ let calls = 0; >+ new TransformStream({ >+ start() { >+ ++calls; >+ } >+ }); >+ return flushAsyncEvents().then(() => { >+ assert_equals(calls, 1, 'start() should have been called exactly once'); >+ }); >+}, 'start() should not be called twice'); >+ >+test(() => { >+ assert_throws(new RangeError(), () => new TransformStream({ readableType: 'bytes' }), 'constructor should throw'); >+}, 'specifying a defined readableType should throw'); >+ >+test(() => { >+ assert_throws(new RangeError(), () => new TransformStream({ writableType: 'bytes' }), 'constructor should throw'); >+}, 'specifying a defined writableType should throw'); >+ >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.serviceworker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.serviceworker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..be6e97febe6247a66d9d7191100e938f58d09230 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.serviceworker.https-expected.txt >@@ -0,0 +1,28 @@ >+ >+PASS Service worker test setup >+FAIL TransformStream can be constructed with a transform function Can't find variable: TransformStream >+FAIL TransformStream can be constructed with no transform function Can't find variable: TransformStream >+FAIL TransformStream instances must have writable and readable properties of the correct types Can't find variable: TransformStream >+FAIL TransformStream writable starts in the writable state Can't find variable: TransformStream >+FAIL Identity TransformStream: can read from readable what is put into writable Can't find variable: TransformStream >+FAIL Uppercaser sync TransformStream: can read from readable transformed version of what is put into writable Can't find variable: TransformStream >+FAIL Uppercaser-doubler sync TransformStream: can read both chunks put into the readable Can't find variable: TransformStream >+FAIL Uppercaser async TransformStream: can read from readable transformed version of what is put into writable Can't find variable: TransformStream >+FAIL Uppercaser-doubler async TransformStream: can read both chunks put into the readable Can't find variable: TransformStream >+FAIL TransformStream: by default, closing the writable closes the readable (when there are no queued writes) Can't find variable: TransformStream >+FAIL TransformStream: by default, closing the writable waits for transforms to finish before closing both Can't find variable: TransformStream >+FAIL TransformStream: by default, closing the writable closes the readable after sync enqueues and async done Can't find variable: TransformStream >+FAIL TransformStream: by default, closing the writable closes the readable after async enqueues and async done Can't find variable: TransformStream >+FAIL Transform stream should call transformer methods as methods Can't find variable: TransformStream >+FAIL methods should not not have .apply() or .call() called Can't find variable: TransformStream >+FAIL TransformStream start, transform, and flush should be strictly ordered Can't find variable: TransformStream >+FAIL it should be possible to call transform() synchronously Can't find variable: TransformStream >+FAIL closing the writable should close the readable when there are no queued chunks, even with backpressure Can't find variable: TransformStream >+FAIL enqueue() should throw after controller.terminate() Can't find variable: TransformStream >+FAIL enqueue() should throw after readable.cancel() Can't find variable: TransformStream >+FAIL controller.terminate() should do nothing the second time it is called Can't find variable: TransformStream >+FAIL terminate() should do nothing after readable.cancel() Can't find variable: TransformStream >+FAIL start() should not be called twice Can't find variable: TransformStream >+FAIL specifying a defined readableType should throw assert_throws: constructor should throw function "() => new TransformStream({ readableType: 'bytes' })" threw object "ReferenceError: Can't find variable: TransformStream" ("ReferenceError") expected object "RangeError" ("RangeError") >+FAIL specifying a defined writableType should throw assert_throws: constructor should throw function "() => new TransformStream({ writableType: 'bytes' })" threw object "ReferenceError: Can't find variable: TransformStream" ("ReferenceError") expected object "RangeError" ("RangeError") >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.serviceworker.https.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.serviceworker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d1de7c342c03d6861e53bfb735edb4249fdcfc72 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.serviceworker.https.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>general.js service worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> >+ >+<script> >+'use strict'; >+service_worker_test('general.js', 'Service worker test setup'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.sharedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.sharedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..4f101a2b2225b92fb0b894e74eb3d9541be80dc5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.sharedworker-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 10: ReferenceError: Can't find variable: SharedWorker >+ >+FAIL general.js shared worker wrapper file ReferenceError: Can't find variable: SharedWorker >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.sharedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.sharedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..dceea8ac8b9f00c9d0cca37bf137be453e714511 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.sharedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>general.js shared worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new SharedWorker('general.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d060a711ab547dbd330a7fb5d3a788574798303b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz-expected.txt >@@ -0,0 +1,22 @@ >+ >+FAIL testing "" (length 1) Can't find variable: TransformStream >+FAIL testing "" (length 0) Can't find variable: TransformStream >+FAIL testing "{{in1}}" (length 1) Can't find variable: TransformStream >+FAIL testing "z{{in1}}" (length 1) Can't find variable: TransformStream >+FAIL testing "{{in1}}q" (length 1) Can't find variable: TransformStream >+FAIL testing "{{in1}}{{in1}" (length 1) Can't find variable: TransformStream >+FAIL testing "{{in1}}{{in1},}" (length 2) Can't find variable: TransformStream >+FAIL testing "{{in1,}}" (length 2) Can't find variable: TransformStream >+FAIL testing "{{,in1}}" (length 2) Can't find variable: TransformStream >+FAIL testing "{,{in1}}" (length 2) Can't find variable: TransformStream >+FAIL testing "{{,in1}" (length 2) Can't find variable: TransformStream >+FAIL testing "{" (length 1) Can't find variable: TransformStream >+FAIL testing "{," (length 2) Can't find variable: TransformStream >+FAIL testing "{,{,i,n,1,},}" (length 7) Can't find variable: TransformStream >+FAIL testing "{{in1}}{{in2}}{{in1}}" (length 1) Can't find variable: TransformStream >+FAIL testing "{{wrong}}" (length 1) Can't find variable: TransformStream >+FAIL testing "{{wron,g}}" (length 2) Can't find variable: TransformStream >+FAIL testing "{{quine}}" (length 1) Can't find variable: TransformStream >+FAIL testing "{{bogusPartial}}" (length 1) Can't find variable: TransformStream >+FAIL testing "{{bogusPartial}}}" (length 1) Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.dedicatedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.dedicatedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d060a711ab547dbd330a7fb5d3a788574798303b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.dedicatedworker-expected.txt >@@ -0,0 +1,22 @@ >+ >+FAIL testing "" (length 1) Can't find variable: TransformStream >+FAIL testing "" (length 0) Can't find variable: TransformStream >+FAIL testing "{{in1}}" (length 1) Can't find variable: TransformStream >+FAIL testing "z{{in1}}" (length 1) Can't find variable: TransformStream >+FAIL testing "{{in1}}q" (length 1) Can't find variable: TransformStream >+FAIL testing "{{in1}}{{in1}" (length 1) Can't find variable: TransformStream >+FAIL testing "{{in1}}{{in1},}" (length 2) Can't find variable: TransformStream >+FAIL testing "{{in1,}}" (length 2) Can't find variable: TransformStream >+FAIL testing "{{,in1}}" (length 2) Can't find variable: TransformStream >+FAIL testing "{,{in1}}" (length 2) Can't find variable: TransformStream >+FAIL testing "{{,in1}" (length 2) Can't find variable: TransformStream >+FAIL testing "{" (length 1) Can't find variable: TransformStream >+FAIL testing "{," (length 2) Can't find variable: TransformStream >+FAIL testing "{,{,i,n,1,},}" (length 7) Can't find variable: TransformStream >+FAIL testing "{{in1}}{{in2}}{{in1}}" (length 1) Can't find variable: TransformStream >+FAIL testing "{{wrong}}" (length 1) Can't find variable: TransformStream >+FAIL testing "{{wron,g}}" (length 2) Can't find variable: TransformStream >+FAIL testing "{{quine}}" (length 1) Can't find variable: TransformStream >+FAIL testing "{{bogusPartial}}" (length 1) Can't find variable: TransformStream >+FAIL testing "{{bogusPartial}}}" (length 1) Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.dedicatedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.dedicatedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..6352938dc1b16750ebcbc5130ec7cb0ca687cdca >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.dedicatedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>lipfuzz.js dedicated worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new Worker('lipfuzz.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.html >new file mode 100644 >index 0000000000000000000000000000000000000000..5003375f30fa05d5fdba4d89320e55f51ea3392a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.html >@@ -0,0 +1,10 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>lipfuzz.js browser context wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+ >+ >+<script src="lipfuzz.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.js b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.js >new file mode 100644 >index 0000000000000000000000000000000000000000..5c33e1549c43a73b421d49f14d342cc17e729de6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.js >@@ -0,0 +1,168 @@ >+'use strict'; >+ >+if (self.importScripts) { >+ self.importScripts('/resources/testharness.js'); >+} >+ >+class LipFuzzTransformer { >+ constructor(substitutions) { >+ this.substitutions = substitutions; >+ this.partialChunk = ''; >+ this.lastIndex = undefined; >+ } >+ >+ transform(chunk, controller) { >+ chunk = this.partialChunk + chunk; >+ this.partialChunk = ''; >+ // lastIndex is the index of the first character after the last substitution. >+ this.lastIndex = 0; >+ chunk = chunk.replace(/\{\{([a-zA-Z0-9_-]+)\}\}/g, this.replaceTag.bind(this)); >+ // Regular expression for an incomplete template at the end of a string. >+ const partialAtEndRegexp = /\{(\{([a-zA-Z0-9_-]+(\})?)?)?$/g; >+ // Avoid looking at any characters that have already been substituted. >+ partialAtEndRegexp.lastIndex = this.lastIndex; >+ this.lastIndex = undefined; >+ const match = partialAtEndRegexp.exec(chunk); >+ if (match) { >+ this.partialChunk = chunk.substring(match.index); >+ chunk = chunk.substring(0, match.index); >+ } >+ controller.enqueue(chunk); >+ } >+ >+ flush(controller) { >+ if (this.partialChunk.length > 0) { >+ controller.enqueue(this.partialChunk); >+ } >+ } >+ >+ replaceTag(match, p1, offset) { >+ let replacement = this.substitutions[p1]; >+ if (replacement === undefined) { >+ replacement = ''; >+ } >+ this.lastIndex = offset + replacement.length; >+ return replacement; >+ } >+} >+ >+const substitutions = { >+ in1: 'out1', >+ in2: 'out2', >+ quine: '{{quine}}', >+ bogusPartial: '{{incompleteResult}' >+}; >+ >+const cases = [ >+ { >+ input: [''], >+ output: [''] >+ }, >+ { >+ input: [], >+ output: [] >+ }, >+ { >+ input: ['{{in1}}'], >+ output: ['out1'] >+ }, >+ { >+ input: ['z{{in1}}'], >+ output: ['zout1'] >+ }, >+ { >+ input: ['{{in1}}q'], >+ output: ['out1q'] >+ }, >+ { >+ input: ['{{in1}}{{in1}'], >+ output: ['out1', '{{in1}'] >+ }, >+ { >+ input: ['{{in1}}{{in1}', '}'], >+ output: ['out1', 'out1'] >+ }, >+ { >+ input: ['{{in1', '}}'], >+ output: ['', 'out1'] >+ }, >+ { >+ input: ['{{', 'in1}}'], >+ output: ['', 'out1'] >+ }, >+ { >+ input: ['{', '{in1}}'], >+ output: ['', 'out1'] >+ }, >+ { >+ input: ['{{', 'in1}'], >+ output: ['', '', '{{in1}'] >+ }, >+ { >+ input: ['{'], >+ output: ['', '{'] >+ }, >+ { >+ input: ['{', ''], >+ output: ['', '', '{'] >+ }, >+ { >+ input: ['{', '{', 'i', 'n', '1', '}', '}'], >+ output: ['', '', '', '', '', '', 'out1'] >+ }, >+ { >+ input: ['{{in1}}{{in2}}{{in1}}'], >+ output: ['out1out2out1'] >+ }, >+ { >+ input: ['{{wrong}}'], >+ output: [''] >+ }, >+ { >+ input: ['{{wron', 'g}}'], >+ output: ['', ''] >+ }, >+ { >+ input: ['{{quine}}'], >+ output: ['{{quine}}'] >+ }, >+ { >+ input: ['{{bogusPartial}}'], >+ output: ['{{incompleteResult}'] >+ }, >+ { >+ input: ['{{bogusPartial}}}'], >+ output: ['{{incompleteResult}}'] >+ } >+]; >+ >+for (const testCase of cases) { >+ const inputChunks = testCase.input; >+ const outputChunks = testCase.output; >+ promise_test(() => { >+ const lft = new TransformStream(new LipFuzzTransformer(substitutions)); >+ const writer = lft.writable.getWriter(); >+ const promises = []; >+ for (const inputChunk of inputChunks) { >+ promises.push(writer.write(inputChunk)); >+ } >+ promises.push(writer.close()); >+ const reader = lft.readable.getReader(); >+ let readerChain = Promise.resolve(); >+ for (const outputChunk of outputChunks) { >+ readerChain = readerChain.then(() => { >+ return reader.read().then(({ value, done }) => { >+ assert_false(done, `done should be false when reading ${outputChunk}`); >+ assert_equals(value, outputChunk, `value should match outputChunk`); >+ }); >+ }); >+ } >+ readerChain = readerChain.then(() => { >+ return reader.read().then(({ done }) => assert_true(done, `done should be true`)); >+ }); >+ promises.push(readerChain); >+ return Promise.all(promises); >+ }, `testing "${inputChunks}" (length ${inputChunks.length})`); >+} >+ >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.serviceworker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.serviceworker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..3b92fcf2eea40a9b299161a7a1c111b2b26700b7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.serviceworker.https-expected.txt >@@ -0,0 +1,23 @@ >+ >+PASS Service worker test setup >+FAIL testing "" (length 1) Can't find variable: TransformStream >+FAIL testing "" (length 0) Can't find variable: TransformStream >+FAIL testing "{{in1}}" (length 1) Can't find variable: TransformStream >+FAIL testing "z{{in1}}" (length 1) Can't find variable: TransformStream >+FAIL testing "{{in1}}q" (length 1) Can't find variable: TransformStream >+FAIL testing "{{in1}}{{in1}" (length 1) Can't find variable: TransformStream >+FAIL testing "{{in1}}{{in1},}" (length 2) Can't find variable: TransformStream >+FAIL testing "{{in1,}}" (length 2) Can't find variable: TransformStream >+FAIL testing "{{,in1}}" (length 2) Can't find variable: TransformStream >+FAIL testing "{,{in1}}" (length 2) Can't find variable: TransformStream >+FAIL testing "{{,in1}" (length 2) Can't find variable: TransformStream >+FAIL testing "{" (length 1) Can't find variable: TransformStream >+FAIL testing "{," (length 2) Can't find variable: TransformStream >+FAIL testing "{,{,i,n,1,},}" (length 7) Can't find variable: TransformStream >+FAIL testing "{{in1}}{{in2}}{{in1}}" (length 1) Can't find variable: TransformStream >+FAIL testing "{{wrong}}" (length 1) Can't find variable: TransformStream >+FAIL testing "{{wron,g}}" (length 2) Can't find variable: TransformStream >+FAIL testing "{{quine}}" (length 1) Can't find variable: TransformStream >+FAIL testing "{{bogusPartial}}" (length 1) Can't find variable: TransformStream >+FAIL testing "{{bogusPartial}}}" (length 1) Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.serviceworker.https.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.serviceworker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..8af3b5f65126ef6b8f979a2bd55624004086a86d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.serviceworker.https.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>lipfuzz.js service worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> >+ >+<script> >+'use strict'; >+service_worker_test('lipfuzz.js', 'Service worker test setup'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.sharedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.sharedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..268a5f78a672923adb76331d6ca4654a69bb4e8a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.sharedworker-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 10: ReferenceError: Can't find variable: SharedWorker >+ >+FAIL lipfuzz.js shared worker wrapper file ReferenceError: Can't find variable: SharedWorker >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.sharedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.sharedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..9536ed1c14c693ac343ec71f774ed9f9291d8bc5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.sharedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>lipfuzz.js shared worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new SharedWorker('lipfuzz.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..8e6dd75e4bd6ba88a632b7b354bc747d2694c431 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global-expected.txt >@@ -0,0 +1,4 @@ >+ >+FAIL TransformStream constructor should not call setters for highWaterMark or size Can't find variable: TransformStream >+FAIL TransformStream should use the original value of ReadableStream and WritableStream Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.dedicatedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.dedicatedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..459681a84ad9c6dc187f92aefcf3c9693e42db35 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.dedicatedworker-expected.txt >@@ -0,0 +1,4 @@ >+ >+FAIL TransformStream constructor should not call setters for highWaterMark or size Can't find variable: TransformStream >+FAIL TransformStream should use the original value of ReadableStream and WritableStream Can't find variable: WritableStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.dedicatedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.dedicatedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..327bc92f75d4732e76330f1105d0e5b409c03b22 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.dedicatedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>patched-global.js dedicated worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new Worker('patched-global.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.html >new file mode 100644 >index 0000000000000000000000000000000000000000..869e9109e025e5e2391d51d336f03e6df335fd69 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.html >@@ -0,0 +1,10 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>patched-global.js browser context wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+ >+ >+<script src="patched-global.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.js b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.js >new file mode 100644 >index 0000000000000000000000000000000000000000..d27b9cdd119edad098120f2b867cf9229f575af5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.js >@@ -0,0 +1,53 @@ >+'use strict'; >+ >+// Tests which patch the global environment are kept separate to avoid interfering with other tests. >+ >+if (self.importScripts) { >+ self.importScripts('/resources/testharness.js'); >+} >+ >+// eslint-disable-next-line no-extend-native, accessor-pairs >+Object.defineProperty(Object.prototype, 'highWaterMark', { >+ set() { throw new Error('highWaterMark setter called'); } >+}); >+ >+// eslint-disable-next-line no-extend-native, accessor-pairs >+Object.defineProperty(Object.prototype, 'size', { >+ set() { throw new Error('size setter called'); } >+}); >+ >+test(() => { >+ assert_not_equals(new TransformStream(), null, 'constructor should work'); >+}, 'TransformStream constructor should not call setters for highWaterMark or size'); >+ >+test(t => { >+ /* eslint-disable no-native-reassign */ >+ >+ const oldReadableStream = ReadableStream; >+ const oldWritableStream = WritableStream; >+ const getReader = ReadableStream.prototype.getReader; >+ const getWriter = WritableStream.prototype.getWriter; >+ >+ // Replace ReadableStream and WritableStream with broken versions. >+ ReadableStream = function () { >+ throw new Error('Called the global ReadableStream constructor'); >+ }; >+ WritableStream = function () { >+ throw new Error('Called the global WritableStream constructor'); >+ }; >+ t.add_cleanup(() => { >+ ReadableStream = oldReadableStream; >+ WritableStream = oldWritableStream; >+ }); >+ >+ const ts = new TransformStream(); >+ >+ // Just to be sure, ensure the readable and writable pass brand checks. >+ assert_not_equals(getReader.call(ts.readable), undefined, >+ 'getReader should work when called on ts.readable'); >+ assert_not_equals(getWriter.call(ts.writable), undefined, >+ 'getWriter should work when called on ts.writable'); >+ /* eslint-enable no-native-reassign */ >+}, 'TransformStream should use the original value of ReadableStream and WritableStream'); >+ >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.serviceworker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.serviceworker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..44220822eadadaea0c915d3b6f2f85c736e91eb6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.serviceworker.https-expected.txt >@@ -0,0 +1,5 @@ >+ >+PASS Service worker test setup >+FAIL TransformStream constructor should not call setters for highWaterMark or size Can't find variable: TransformStream >+FAIL TransformStream should use the original value of ReadableStream and WritableStream Can't find variable: WritableStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.serviceworker.https.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.serviceworker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..addb438ba6fe407662232f97bb6c2583f3f17cf4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.serviceworker.https.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>patched-global.js service worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> >+ >+<script> >+'use strict'; >+service_worker_test('patched-global.js', 'Service worker test setup'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.sharedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.sharedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..5293962394bdf646b647bd5ec050645f3ce59269 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.sharedworker-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 10: ReferenceError: Can't find variable: SharedWorker >+ >+FAIL patched-global.js shared worker wrapper file ReferenceError: Can't find variable: SharedWorker >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.sharedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.sharedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..6dba52fa67f53c4c0437ebd4ad7166ca5ceb1d7d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.sharedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>patched-global.js shared worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new SharedWorker('patched-global.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..ffac2c0de32228db53fea849462be053f46f8a48 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties-expected.txt >@@ -0,0 +1,6 @@ >+CONSOLE MESSAGE: line 28: ReferenceError: Can't find variable: TransformStream >+ >+Harness Error (FAIL), message = ReferenceError: Can't find variable: TransformStream >+ >+PASS TransformStreamDefaultController should not be exported on the global object >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.dedicatedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.dedicatedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..15f74f33e62a9cb4f486544139a6342fbd5b6cd2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.dedicatedworker-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 1834: TypeError: null is not an object (evaluating 'this.message_target.removeEventListener') >+CONSOLE MESSAGE: line 28: ReferenceError: Can't find variable: TransformStream >+ >+Harness Error (FAIL), message = ReferenceError: Can't find variable: TransformStream >+ >+PASS TransformStreamDefaultController should not be exported on the global object >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.dedicatedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.dedicatedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..50d63ed0edb2ba052daaf89df23c9320fc82c9dc >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.dedicatedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>properties.js dedicated worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new Worker('properties.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ad410a53c8251685610cc0014699eaaaceea35d2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.html >@@ -0,0 +1,10 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>properties.js browser context wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+ >+ >+<script src="properties.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.js b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.js >new file mode 100644 >index 0000000000000000000000000000000000000000..f8d8face2d44f207d99c6c91589b0dbf98356e34 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.js >@@ -0,0 +1,194 @@ >+'use strict'; >+ >+if (self.importScripts) { >+ self.importScripts('/resources/testharness.js'); >+} >+ >+// The purpose of this file is to test for objects, attributes and arguments that should not exist. >+// The test cases are generated from data tables to reduce duplication. >+ >+// Courtesy of André Bargull. Source is https://esdiscuss.org/topic/isconstructor#content-11. >+function IsConstructor(o) { >+ try { >+ new new Proxy(o, { construct: () => ({}) })(); >+ return true; >+ } catch (e) { >+ return false; >+ } >+} >+ >+test(() => { >+ assert_equals(self['TransformStreamDefaultController'], undefined, >+ `TransformStreamDefaultController should not be defined`); >+}, `TransformStreamDefaultController should not be exported on the global object`); >+ >+// Now get hold of the symbol so we can test its properties. >+self.TransformStreamDefaultController = (() => { >+ let controller; >+ new TransformStream({ >+ start(c) { >+ controller = c; >+ } >+ }); >+ return controller.constructor; >+})(); >+ >+const expected = { >+ TransformStream: { >+ constructor: { >+ type: 'constructor', >+ length: 0 >+ }, >+ readable: { >+ type: 'getter' >+ }, >+ writable: { >+ type: 'getter' >+ } >+ }, >+ TransformStreamDefaultController: { >+ constructor: { >+ type: 'constructor', >+ length: 0 >+ }, >+ desiredSize: { >+ type: 'getter' >+ }, >+ enqueue: { >+ type: 'method', >+ length: 1 >+ }, >+ error: { >+ type: 'method', >+ length: 1 >+ }, >+ terminate: { >+ type: 'method', >+ length: 0 >+ } >+ } >+}; >+ >+for (const c in expected) { >+ const properties = expected[c]; >+ const prototype = self[c].prototype; >+ for (const name in properties) { >+ const fullName = `${c}.prototype.${name}`; >+ const descriptor = Object.getOwnPropertyDescriptor(prototype, name); >+ test(() => { >+ const { configurable, enumerable } = descriptor; >+ assert_true(configurable, `${name} should be configurable`); >+ assert_false(enumerable, `${name} should not be enumerable`); >+ }, `${fullName} should have standard properties`); >+ const type = properties[name].type; >+ switch (type) { >+ case 'getter': >+ test(() => { >+ const { writable, get, set } = descriptor; >+ assert_equals(writable, undefined, `${name} should not be a data descriptor`); >+ assert_equals(typeof get, 'function', `${name} should have a getter`); >+ assert_equals(set, undefined, `${name} should not have a setter`); >+ }, `${fullName} should be a getter`); >+ break; >+ >+ case 'constructor': >+ case 'method': >+ test(() => { >+ assert_true(descriptor.writable, `${name} should be writable`); >+ assert_equals(typeof prototype[name], 'function', `${name} should be a function`); >+ assert_equals(prototype[name].length, properties[name].length, >+ `${name} should take ${properties[name].length} arguments`); >+ if (type === 'constructor') { >+ assert_true(IsConstructor(prototype[name]), `${name} should be a constructor`); >+ assert_equals(prototype[name].name, c, `${name}.name should be '${c}'`); >+ } else { >+ assert_false(IsConstructor(prototype[name]), `${name} should not be a constructor`); >+ assert_equals(prototype[name].name, name, `${name}.name should be '${name}`); >+ } >+ }, `${fullName} should be a ${type}`); >+ break; >+ } >+ } >+ test(() => { >+ const expectedPropertyNames = Object.keys(properties).sort(); >+ const actualPropertyNames = Object.getOwnPropertyNames(prototype).sort(); >+ assert_array_equals(actualPropertyNames, expectedPropertyNames, >+ `${c} properties should match expected properties`); >+ }, `${c}.prototype should have exactly the expected properties`); >+} >+ >+const transformerMethods = { >+ start: { >+ length: 1, >+ trigger: () => Promise.resolve() >+ }, >+ transform: { >+ length: 2, >+ trigger: ts => ts.writable.getWriter().write() >+ }, >+ flush: { >+ length: 1, >+ trigger: ts => ts.writable.getWriter().close() >+ } >+}; >+ >+for (const method in transformerMethods) { >+ const { length, trigger } = transformerMethods[method]; >+ >+ // Some semantic tests of how transformer methods are called can be found in general.js, as well as in the test files >+ // specific to each method. >+ promise_test(() => { >+ let argCount; >+ const ts = new TransformStream({ >+ [method](...args) { >+ argCount = args.length; >+ } >+ }, undefined, { highWaterMark: Infinity }); >+ return Promise.resolve(trigger(ts)).then(() => { >+ assert_equals(argCount, length, `${method} should be called with ${length} arguments`); >+ }); >+ }, `transformer method ${method} should be called with the right number of arguments`); >+ >+ promise_test(() => { >+ let methodWasCalled = false; >+ function Transformer() {} >+ Transformer.prototype = { >+ [method]() { >+ methodWasCalled = true; >+ } >+ }; >+ const ts = new TransformStream(new Transformer(), undefined, { highWaterMark: Infinity }); >+ return Promise.resolve(trigger(ts)).then(() => { >+ assert_true(methodWasCalled, `${method} should be called`); >+ }); >+ }, `transformer method ${method} should be called even when it's located on the prototype chain`); >+ >+ promise_test(t => { >+ const unreachedTraps = ['getPrototypeOf', 'setPrototypeOf', 'isExtensible', 'preventExtensions', >+ 'getOwnPropertyDescriptor', 'defineProperty', 'has', 'set', 'deleteProperty', 'ownKeys', >+ 'apply', 'construct']; >+ const touchedProperties = []; >+ const handler = { >+ get: t.step_func((target, property) => { >+ touchedProperties.push(property); >+ if (property === 'readableType' || property === 'writableType') { >+ return undefined; >+ } >+ return () => Promise.resolve(); >+ }) >+ }; >+ for (const trap of unreachedTraps) { >+ handler[trap] = t.unreached_func(`${trap} should not be trapped`); >+ } >+ const transformer = new Proxy({}, handler); >+ const ts = new TransformStream(transformer, undefined, { highWaterMark: Infinity }); >+ assert_array_equals(touchedProperties, ['writableType', 'readableType', 'transform', 'flush', 'start'], >+ 'expected properties should be got'); >+ return trigger(ts).then(() => { >+ assert_array_equals(touchedProperties, ['writableType', 'readableType', 'transform', 'flush', 'start'], >+ 'no properties should be accessed on method call'); >+ }); >+ }, `unexpected properties should not be accessed when calling transformer method ${method}`); >+} >+ >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.serviceworker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.serviceworker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..bc972a5067b668e2945d1f673e3e9f18112e83fa >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.serviceworker.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+FAIL Service worker test setup assert_unreached: unregister and register should not fail: ReferenceError: Can't find variable: TransformStream Reached unreachable code >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.serviceworker.https.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.serviceworker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ba5c5135f2f7fc903b66bce883c10661d73eba33 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.serviceworker.https.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>properties.js service worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> >+ >+<script> >+'use strict'; >+service_worker_test('properties.js', 'Service worker test setup'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.sharedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.sharedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..5766f7596730bb52df03d7815fb7d8b39b63a51c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.sharedworker-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 10: ReferenceError: Can't find variable: SharedWorker >+ >+FAIL properties.js shared worker wrapper file ReferenceError: Can't find variable: SharedWorker >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.sharedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.sharedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..42fb3e5ebc0a03123c5338b025be6ef85e4b2873 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.sharedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>properties.js shared worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new SharedWorker('properties.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2b59317a761758f018683bf296d4eb6551e38482 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies-expected.txt >@@ -0,0 +1,13 @@ >+ >+FAIL enqueue() inside size() should work Can't find variable: TransformStream >+FAIL terminate() inside size() should work Can't find variable: TransformStream >+FAIL error() inside size() should work Can't find variable: TransformStream >+FAIL desiredSize inside size() should work Can't find variable: TransformStream >+FAIL readable cancel() inside size() should work Can't find variable: TransformStream >+FAIL pipeTo() inside size() should work Can't find variable: TransformStream >+FAIL read() inside of size() should work Can't find variable: TransformStream >+FAIL writer.write() inside size() should work Can't find variable: TransformStream >+FAIL synchronous writer.write() inside size() should work Can't find variable: TransformStream >+FAIL writer.close() inside size() should work Can't find variable: TransformStream >+FAIL writer.abort() inside size() should work Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.dedicatedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.dedicatedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..72b71e42c236d01e1e64b3f428a81fb56f56e05d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.dedicatedworker-expected.txt >@@ -0,0 +1,13 @@ >+ >+FAIL enqueue() inside size() should work Can't find variable: TransformStream >+FAIL terminate() inside size() should work Can't find variable: TransformStream >+FAIL error() inside size() should work Can't find variable: TransformStream >+FAIL desiredSize inside size() should work Can't find variable: TransformStream >+FAIL readable cancel() inside size() should work Can't find variable: TransformStream >+FAIL pipeTo() inside size() should work Can't find variable: WritableStream >+FAIL read() inside of size() should work Can't find variable: TransformStream >+FAIL writer.write() inside size() should work Can't find variable: TransformStream >+FAIL synchronous writer.write() inside size() should work Can't find variable: TransformStream >+FAIL writer.close() inside size() should work Can't find variable: TransformStream >+FAIL writer.abort() inside size() should work Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.dedicatedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.dedicatedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..300dc8518753892694eb7b7f6afc08a2c2ee516c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.dedicatedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>reentrant-strategies.js dedicated worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new Worker('reentrant-strategies.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.html >new file mode 100644 >index 0000000000000000000000000000000000000000..e2a6406bd469cda4c474253998b98640d6693dc5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>reentrant-strategies.js browser context wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script src="../resources/recording-streams.js"></script> >+<script src="../resources/rs-utils.js"></script> >+<script src="../resources/test-utils.js"></script> >+ >+<script src="reentrant-strategies.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.js b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.js >new file mode 100644 >index 0000000000000000000000000000000000000000..50285bbbcd97a1c454000cc48c110b4e12e60b73 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.js >@@ -0,0 +1,324 @@ >+'use strict'; >+ >+// The size() function of readableStrategy can re-entrantly call back into the TransformStream implementation. This >+// makes it risky to cache state across the call to ReadableStreamDefaultControllerEnqueue. These tests attempt to catch >+// such errors. They are separated from the other strategy tests because no real user code should ever do anything like >+// this. >+// >+// There is no such issue with writableStrategy size() because it is never called from within TransformStream >+// algorithms. >+ >+if (self.importScripts) { >+ self.importScripts('/resources/testharness.js'); >+ self.importScripts('../resources/recording-streams.js'); >+ self.importScripts('../resources/rs-utils.js'); >+ self.importScripts('../resources/test-utils.js'); >+} >+ >+const error1 = new Error('error1'); >+error1.name = 'error1'; >+ >+promise_test(() => { >+ let controller; >+ let calls = 0; >+ const ts = new TransformStream({ >+ start(c) { >+ controller = c; >+ } >+ }, undefined, { >+ size() { >+ ++calls; >+ if (calls < 2) { >+ controller.enqueue('b'); >+ } >+ return 1; >+ }, >+ highWaterMark: Infinity >+ }); >+ const writer = ts.writable.getWriter(); >+ return Promise.all([writer.write('a'), writer.close()]) >+ .then(() => readableStreamToArray(ts.readable)) >+ .then(array => assert_array_equals(array, ['b', 'a'], 'array should contain two chunks')); >+}, 'enqueue() inside size() should work'); >+ >+promise_test(() => { >+ let controller; >+ const ts = new TransformStream({ >+ start(c) { >+ controller = c; >+ } >+ }, undefined, { >+ size() { >+ // The readable queue is empty. >+ controller.terminate(); >+ // The readable state has gone from "readable" to "closed". >+ return 1; >+ // This chunk will be enqueued, but will be impossible to read because the state is already "closed". >+ }, >+ highWaterMark: Infinity >+ }); >+ const writer = ts.writable.getWriter(); >+ return writer.write('a') >+ .then(() => readableStreamToArray(ts.readable)) >+ .then(array => assert_array_equals(array, [], 'array should contain no chunks')); >+ // The chunk 'a' is still in readable's queue. readable is closed so 'a' cannot be read. writable's queue is empty and >+ // it is still writable. >+}, 'terminate() inside size() should work'); >+ >+promise_test(t => { >+ let controller; >+ const ts = new TransformStream({ >+ start(c) { >+ controller = c; >+ } >+ }, undefined, { >+ size() { >+ controller.error(error1); >+ return 1; >+ }, >+ highWaterMark: Infinity >+ }); >+ const writer = ts.writable.getWriter(); >+ return writer.write('a') >+ .then(() => promise_rejects(t, error1, ts.readable.getReader().read(), 'read() should reject')); >+}, 'error() inside size() should work'); >+ >+promise_test(() => { >+ let controller; >+ const ts = new TransformStream({ >+ start(c) { >+ controller = c; >+ } >+ }, undefined, { >+ size() { >+ assert_equals(controller.desiredSize, 1, 'desiredSize should be 1'); >+ return 1; >+ }, >+ highWaterMark: 1 >+ }); >+ const writer = ts.writable.getWriter(); >+ return Promise.all([writer.write('a'), writer.close()]) >+ .then(() => readableStreamToArray(ts.readable)) >+ .then(array => assert_array_equals(array, ['a'], 'array should contain one chunk')); >+}, 'desiredSize inside size() should work'); >+ >+promise_test(t => { >+ let cancelPromise; >+ const ts = new TransformStream({}, undefined, { >+ size() { >+ cancelPromise = ts.readable.cancel(error1); >+ return 1; >+ }, >+ highWaterMark: Infinity >+ }); >+ const writer = ts.writable.getWriter(); >+ return writer.write('a') >+ .then(() => { >+ promise_rejects(t, error1, writer.closed, 'writer.closed should reject'); >+ return cancelPromise; >+ }); >+}, 'readable cancel() inside size() should work'); >+ >+promise_test(() => { >+ let controller; >+ let pipeToPromise; >+ const ws = recordingWritableStream(); >+ const ts = new TransformStream({ >+ start(c) { >+ controller = c; >+ } >+ }, undefined, { >+ size() { >+ if (!pipeToPromise) { >+ pipeToPromise = ts.readable.pipeTo(ws); >+ } >+ return 1; >+ }, >+ highWaterMark: 1 >+ }); >+ // Allow promise returned by start() to resolve so that enqueue() will happen synchronously. >+ return delay(0).then(() => { >+ controller.enqueue('a'); >+ assert_not_equals(pipeToPromise, undefined); >+ >+ // Some pipeTo() implementations need an additional chunk enqueued in order for the first one to be processed. See >+ // https://github.com/whatwg/streams/issues/794 for background. >+ controller.enqueue('a'); >+ >+ // Give pipeTo() a chance to process the queued chunks. >+ return delay(0); >+ }).then(() => { >+ assert_array_equals(ws.events, ['write', 'a', 'write', 'a'], 'ws should contain two chunks'); >+ controller.terminate(); >+ return pipeToPromise; >+ }).then(() => { >+ assert_array_equals(ws.events, ['write', 'a', 'write', 'a', 'close'], 'target should have been closed'); >+ }); >+}, 'pipeTo() inside size() should work'); >+ >+promise_test(() => { >+ let controller; >+ let readPromise; >+ let calls = 0; >+ let reader; >+ const ts = new TransformStream({ >+ start(c) { >+ controller = c; >+ } >+ }, undefined, { >+ size() { >+ // This is triggered by controller.enqueue(). The queue is empty and there are no pending reads. pull() is called >+ // synchronously, allowing transform() to proceed asynchronously. This results in a second call to enqueue(), >+ // which resolves this pending read() without calling size() again. >+ readPromise = reader.read(); >+ ++calls; >+ return 1; >+ }, >+ highWaterMark: 0 >+ }); >+ reader = ts.readable.getReader(); >+ const writer = ts.writable.getWriter(); >+ let writeResolved = false; >+ const writePromise = writer.write('b').then(() => { >+ writeResolved = true; >+ }); >+ return flushAsyncEvents().then(() => { >+ assert_false(writeResolved); >+ controller.enqueue('a'); >+ assert_equals(calls, 1, 'size() should have been called once'); >+ return delay(0); >+ }).then(() => { >+ assert_true(writeResolved); >+ assert_equals(calls, 1, 'size() should only be called once'); >+ return readPromise; >+ }).then(({ value, done }) => { >+ assert_false(done, 'done should be false'); >+ // See https://github.com/whatwg/streams/issues/794 for why this chunk is not 'a'. >+ assert_equals(value, 'b', 'chunk should have been read'); >+ assert_equals(calls, 1, 'calls should still be 1'); >+ return writePromise; >+ }); >+}, 'read() inside of size() should work'); >+ >+promise_test(() => { >+ let writer; >+ let writePromise1; >+ let calls = 0; >+ const ts = new TransformStream({}, undefined, { >+ size() { >+ ++calls; >+ if (calls < 2) { >+ writePromise1 = writer.write('a'); >+ } >+ return 1; >+ }, >+ highWaterMark: Infinity >+ }); >+ writer = ts.writable.getWriter(); >+ // Give pull() a chance to be called. >+ return delay(0).then(() => { >+ // This write results in a synchronous call to transform(), enqueue(), and size(). >+ const writePromise2 = writer.write('b'); >+ assert_equals(calls, 1, 'size() should have been called once'); >+ return Promise.all([writePromise1, writePromise2, writer.close()]); >+ }).then(() => { >+ assert_equals(calls, 2, 'size() should have been called twice'); >+ return readableStreamToArray(ts.readable); >+ }).then(array => { >+ assert_array_equals(array, ['b', 'a'], 'both chunks should have been enqueued'); >+ assert_equals(calls, 2, 'calls should still be 2'); >+ }); >+}, 'writer.write() inside size() should work'); >+ >+promise_test(() => { >+ let controller; >+ let writer; >+ let writePromise; >+ let calls = 0; >+ const ts = new TransformStream({ >+ start(c) { >+ controller = c; >+ } >+ }, undefined, { >+ size() { >+ ++calls; >+ if (calls < 2) { >+ writePromise = writer.write('a'); >+ } >+ return 1; >+ }, >+ highWaterMark: Infinity >+ }); >+ writer = ts.writable.getWriter(); >+ // Give pull() a chance to be called. >+ return delay(0).then(() => { >+ // This enqueue results in synchronous calls to size(), write(), transform() and enqueue(). >+ controller.enqueue('b'); >+ assert_equals(calls, 2, 'size() should have been called twice'); >+ return Promise.all([writePromise, writer.close()]); >+ }).then(() => { >+ return readableStreamToArray(ts.readable); >+ }).then(array => { >+ // Because one call to enqueue() is nested inside the other, they finish in the opposite order that they were >+ // called, so the chunks end up reverse order. >+ assert_array_equals(array, ['a', 'b'], 'both chunks should have been enqueued'); >+ assert_equals(calls, 2, 'calls should still be 2'); >+ }); >+}, 'synchronous writer.write() inside size() should work'); >+ >+promise_test(() => { >+ let writer; >+ let closePromise; >+ let controller; >+ const ts = new TransformStream({ >+ start(c) { >+ controller = c; >+ } >+ }, undefined, { >+ size() { >+ closePromise = writer.close(); >+ return 1; >+ }, >+ highWaterMark: 1 >+ }); >+ writer = ts.writable.getWriter(); >+ const reader = ts.readable.getReader(); >+ // Wait for the promise returned by start() to be resolved so that the call to close() will result in a synchronous >+ // call to TransformStreamDefaultSink. >+ return delay(0).then(() => { >+ controller.enqueue('a'); >+ return reader.read(); >+ }).then(({ value, done }) => { >+ assert_false(done, 'done should be false'); >+ assert_equals(value, 'a', 'value should be correct'); >+ return reader.read(); >+ }).then(({ done }) => { >+ assert_true(done, 'done should be true'); >+ return closePromise; >+ }); >+}, 'writer.close() inside size() should work'); >+ >+promise_test(t => { >+ let abortPromise; >+ let controller; >+ const ts = new TransformStream({ >+ start(c) { >+ controller = c; >+ } >+ }, undefined, { >+ size() { >+ abortPromise = ts.writable.abort(error1); >+ return 1; >+ }, >+ highWaterMark: 1 >+ }); >+ const reader = ts.readable.getReader(); >+ // Wait for the promise returned by start() to be resolved so that the call to abort() will result in a synchronous >+ // call to TransformStreamDefaultSink. >+ return delay(0).then(() => { >+ controller.enqueue('a'); >+ return Promise.all([promise_rejects(t, error1, reader.read(), 'read() should reject'), abortPromise]); >+ }); >+}, 'writer.abort() inside size() should work'); >+ >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.serviceworker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.serviceworker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..09606901f4b94e92f3a2816dbfe97043f0364673 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.serviceworker.https-expected.txt >@@ -0,0 +1,14 @@ >+ >+PASS Service worker test setup >+FAIL enqueue() inside size() should work Can't find variable: TransformStream >+FAIL terminate() inside size() should work Can't find variable: TransformStream >+FAIL error() inside size() should work Can't find variable: TransformStream >+FAIL desiredSize inside size() should work Can't find variable: TransformStream >+FAIL readable cancel() inside size() should work Can't find variable: TransformStream >+FAIL pipeTo() inside size() should work Can't find variable: WritableStream >+FAIL read() inside of size() should work Can't find variable: TransformStream >+FAIL writer.write() inside size() should work Can't find variable: TransformStream >+FAIL synchronous writer.write() inside size() should work Can't find variable: TransformStream >+FAIL writer.close() inside size() should work Can't find variable: TransformStream >+FAIL writer.abort() inside size() should work Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.serviceworker.https.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.serviceworker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..6c1813d13853a6d826affc95dcba5a5ad5d9768a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.serviceworker.https.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>reentrant-strategies.js service worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> >+ >+<script> >+'use strict'; >+service_worker_test('reentrant-strategies.js', 'Service worker test setup'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.sharedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.sharedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..e984787443687813d38bcd0823a800d3a0711f25 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.sharedworker-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 10: ReferenceError: Can't find variable: SharedWorker >+ >+FAIL reentrant-strategies.js shared worker wrapper file ReferenceError: Can't find variable: SharedWorker >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.sharedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.sharedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..4415a3fb9b35ae2422fa06d98b1dce1264b9e0ea >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.sharedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>reentrant-strategies.js shared worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new SharedWorker('reentrant-strategies.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..bab30eea36a3403d073ada97c6f6e246680f4b8b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies-expected.txt >@@ -0,0 +1,12 @@ >+ >+FAIL writableStrategy highWaterMark should work Can't find variable: TransformStream >+FAIL readableStrategy highWaterMark should work Can't find variable: TransformStream >+FAIL writable should have the correct size() function Can't find variable: TransformStream >+FAIL default writable strategy should be equivalent to { highWaterMark: 1 } Can't find variable: TransformStream >+FAIL default readable strategy should be equivalent to { highWaterMark: 0 } Can't find variable: TransformStream >+FAIL a RangeError should be thrown for an invalid highWaterMark assert_throws: should throw RangeError for negative writableHighWaterMark function "() => new TransformStream(undefined, { highWaterMark: -1 })" threw object "ReferenceError: Can't find variable: TransformStream" ("ReferenceError") expected object "RangeError" ("RangeError") >+FAIL writableStrategy highWaterMark should be converted to a number Can't find variable: TransformStream >+FAIL readableStrategy highWaterMark should be converted to a number Can't find variable: TransformStream >+FAIL a bad readableStrategy size function should cause writer.write() to reject on an identity transform Can't find variable: TransformStream >+FAIL a bad readableStrategy size function should error the stream on enqueue even when transformer.transform() catches the exception Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.dedicatedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.dedicatedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..bab30eea36a3403d073ada97c6f6e246680f4b8b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.dedicatedworker-expected.txt >@@ -0,0 +1,12 @@ >+ >+FAIL writableStrategy highWaterMark should work Can't find variable: TransformStream >+FAIL readableStrategy highWaterMark should work Can't find variable: TransformStream >+FAIL writable should have the correct size() function Can't find variable: TransformStream >+FAIL default writable strategy should be equivalent to { highWaterMark: 1 } Can't find variable: TransformStream >+FAIL default readable strategy should be equivalent to { highWaterMark: 0 } Can't find variable: TransformStream >+FAIL a RangeError should be thrown for an invalid highWaterMark assert_throws: should throw RangeError for negative writableHighWaterMark function "() => new TransformStream(undefined, { highWaterMark: -1 })" threw object "ReferenceError: Can't find variable: TransformStream" ("ReferenceError") expected object "RangeError" ("RangeError") >+FAIL writableStrategy highWaterMark should be converted to a number Can't find variable: TransformStream >+FAIL readableStrategy highWaterMark should be converted to a number Can't find variable: TransformStream >+FAIL a bad readableStrategy size function should cause writer.write() to reject on an identity transform Can't find variable: TransformStream >+FAIL a bad readableStrategy size function should error the stream on enqueue even when transformer.transform() catches the exception Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.dedicatedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.dedicatedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..9dba120fea864ed97d3658f604e68cc1015fdaa1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.dedicatedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>strategies.js dedicated worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new Worker('strategies.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.html >new file mode 100644 >index 0000000000000000000000000000000000000000..b445963bd9b187377f49ed4b36dbcc0037f29b58 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>strategies.js browser context wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script src="../resources/recording-streams.js"></script> >+<script src="../resources/test-utils.js"></script> >+ >+<script src="strategies.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.js b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.js >new file mode 100644 >index 0000000000000000000000000000000000000000..1775b7fa170dc375d3c0ca2845609b5dd7a871a4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.js >@@ -0,0 +1,155 @@ >+'use strict'; >+ >+// Here we just test that the strategies are correctly passed to the readable and writable sides. We assume that >+// ReadableStream and WritableStream will correctly apply the strategies when they are being used by a TransformStream >+// and so it isn't necessary to repeat their tests here. >+ >+if (self.importScripts) { >+ self.importScripts('/resources/testharness.js'); >+ self.importScripts('../resources/recording-streams.js'); >+ self.importScripts('../resources/test-utils.js'); >+} >+ >+test(() => { >+ const ts = new TransformStream({}, { highWaterMark: 17 }); >+ assert_equals(ts.writable.getWriter().desiredSize, 17, 'desiredSize should be 17'); >+}, 'writableStrategy highWaterMark should work'); >+ >+promise_test(() => { >+ const ts = recordingTransformStream({}, undefined, { highWaterMark: 9 }); >+ const writer = ts.writable.getWriter(); >+ for (let i = 0; i < 10; ++i) { >+ writer.write(i); >+ } >+ return delay(0).then(() => { >+ assert_array_equals(ts.events, [ >+ 'transform', 0, 'transform', 1, 'transform', 2, 'transform', 3, 'transform', 4, >+ 'transform', 5, 'transform', 6, 'transform', 7, 'transform', 8], >+ 'transform() should have been called 9 times'); >+ }); >+}, 'readableStrategy highWaterMark should work'); >+ >+promise_test(t => { >+ let writableSizeCalled = false; >+ let readableSizeCalled = false; >+ let transformCalled = false; >+ const ts = new TransformStream( >+ { >+ transform(chunk, controller) { >+ t.step(() => { >+ transformCalled = true; >+ assert_true(writableSizeCalled, 'writableStrategy.size() should have been called'); >+ assert_false(readableSizeCalled, 'readableStrategy.size() should not have been called'); >+ controller.enqueue(chunk); >+ assert_true(readableSizeCalled, 'readableStrategy.size() should have been called'); >+ }); >+ } >+ }, >+ { >+ size() { >+ writableSizeCalled = true; >+ return 1; >+ } >+ }, >+ { >+ size() { >+ readableSizeCalled = true; >+ return 1; >+ }, >+ highWaterMark: Infinity >+ }); >+ return ts.writable.getWriter().write().then(() => { >+ assert_true(transformCalled, 'transform() should be called'); >+ }); >+}, 'writable should have the correct size() function'); >+ >+test(() => { >+ const ts = new TransformStream(); >+ const writer = ts.writable.getWriter(); >+ assert_equals(writer.desiredSize, 1, 'default writable HWM is 1'); >+ writer.write(undefined); >+ assert_equals(writer.desiredSize, 0, 'default chunk size is 1'); >+}, 'default writable strategy should be equivalent to { highWaterMark: 1 }'); >+ >+promise_test(t => { >+ const ts = new TransformStream({ >+ transform(chunk, controller) { >+ return t.step(() => { >+ assert_equals(controller.desiredSize, 0, 'desiredSize should be 0'); >+ controller.enqueue(undefined); >+ // The first chunk enqueued is consumed by the pending read(). >+ assert_equals(controller.desiredSize, 0, 'desiredSize should still be 0'); >+ controller.enqueue(undefined); >+ assert_equals(controller.desiredSize, -1, 'desiredSize should be -1'); >+ }); >+ } >+ }); >+ const writePromise = ts.writable.getWriter().write(); >+ return ts.readable.getReader().read().then(() => writePromise); >+}, 'default readable strategy should be equivalent to { highWaterMark: 0 }'); >+ >+test(() => { >+ assert_throws(new RangeError(), () => new TransformStream(undefined, { highWaterMark: -1 }), >+ 'should throw RangeError for negative writableHighWaterMark'); >+ assert_throws(new RangeError(), () => new TransformStream(undefined, undefined, { highWaterMark: -1 }), >+ 'should throw RangeError for negative readableHighWaterMark'); >+ assert_throws(new RangeError(), () => new TransformStream(undefined, { highWaterMark: NaN }), >+ 'should throw RangeError for NaN writableHighWaterMark'); >+ assert_throws(new RangeError(), () => new TransformStream(undefined, undefined, { highWaterMark: NaN }), >+ 'should throw RangeError for NaN readableHighWaterMark'); >+}, 'a RangeError should be thrown for an invalid highWaterMark'); >+ >+const objectThatConvertsTo42 = { >+ toString() { >+ return '42'; >+ } >+}; >+ >+test(() => { >+ const ts = new TransformStream(undefined, { highWaterMark: objectThatConvertsTo42 }); >+ const writer = ts.writable.getWriter(); >+ assert_equals(writer.desiredSize, 42, 'writable HWM is 42'); >+}, 'writableStrategy highWaterMark should be converted to a number'); >+ >+test(() => { >+ const ts = new TransformStream({ >+ start(controller) { >+ assert_equals(controller.desiredSize, 42, 'desiredSize should be 42'); >+ } >+ }, undefined, { highWaterMark: objectThatConvertsTo42 }); >+}, 'readableStrategy highWaterMark should be converted to a number'); >+ >+promise_test(t => { >+ const ts = new TransformStream(undefined, undefined, { >+ size() { return NaN; }, >+ highWaterMark: 1 >+ }); >+ const writer = ts.writable.getWriter(); >+ return promise_rejects(t, new RangeError(), writer.write(), 'write should reject'); >+}, 'a bad readableStrategy size function should cause writer.write() to reject on an identity transform'); >+ >+promise_test(t => { >+ const ts = new TransformStream({ >+ transform(chunk, controller) { >+ // This assert has the important side-effect of catching the error, so transform() does not throw. >+ assert_throws(new RangeError(), () => controller.enqueue(chunk), 'enqueue should throw'); >+ } >+ }, undefined, { >+ size() { >+ return -1; >+ }, >+ highWaterMark: 1 >+ }); >+ >+ const writer = ts.writable.getWriter(); >+ return writer.write().then(() => { >+ return Promise.all([ >+ promise_rejects(t, new RangeError(), writer.ready, 'ready should reject'), >+ promise_rejects(t, new RangeError(), writer.closed, 'closed should reject'), >+ promise_rejects(t, new RangeError(), ts.readable.getReader().closed, 'readable closed should reject') >+ ]); >+ }); >+}, 'a bad readableStrategy size function should error the stream on enqueue even when transformer.transform() ' + >+ 'catches the exception'); >+ >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.serviceworker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.serviceworker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..7186b0b7e6732cf12f654947fa4e92199106b230 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.serviceworker.https-expected.txt >@@ -0,0 +1,13 @@ >+ >+PASS Service worker test setup >+FAIL writableStrategy highWaterMark should work Can't find variable: TransformStream >+FAIL readableStrategy highWaterMark should work Can't find variable: TransformStream >+FAIL writable should have the correct size() function Can't find variable: TransformStream >+FAIL default writable strategy should be equivalent to { highWaterMark: 1 } Can't find variable: TransformStream >+FAIL default readable strategy should be equivalent to { highWaterMark: 0 } Can't find variable: TransformStream >+FAIL a RangeError should be thrown for an invalid highWaterMark assert_throws: should throw RangeError for negative writableHighWaterMark function "() => new TransformStream(undefined, { highWaterMark: -1 })" threw object "ReferenceError: Can't find variable: TransformStream" ("ReferenceError") expected object "RangeError" ("RangeError") >+FAIL writableStrategy highWaterMark should be converted to a number Can't find variable: TransformStream >+FAIL readableStrategy highWaterMark should be converted to a number Can't find variable: TransformStream >+FAIL a bad readableStrategy size function should cause writer.write() to reject on an identity transform Can't find variable: TransformStream >+FAIL a bad readableStrategy size function should error the stream on enqueue even when transformer.transform() catches the exception Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.serviceworker.https.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.serviceworker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..f0a9f213f192bfda0385c4bfdae88abfe14df1ff >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.serviceworker.https.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>strategies.js service worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> >+ >+<script> >+'use strict'; >+service_worker_test('strategies.js', 'Service worker test setup'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.sharedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.sharedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..eed91603813bf903ba3fefdf2e27f68568eeebd5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.sharedworker-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 10: ReferenceError: Can't find variable: SharedWorker >+ >+FAIL strategies.js shared worker wrapper file ReferenceError: Can't find variable: SharedWorker >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.sharedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.sharedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..cd0b2be708cc374b1f6404e7ad9ade2cd389a1b2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.sharedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>strategies.js shared worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new SharedWorker('strategies.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..5b8a5ba963d2e99591960b43acd65b1ea3d9ad10 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate-expected.txt >@@ -0,0 +1,8 @@ >+ >+FAIL controller.terminate() should error pipeTo() Can't find variable: TransformStream >+FAIL controller.terminate() should prevent remaining chunks from being processed Can't find variable: TransformStream >+FAIL controller.enqueue() should throw after controller.terminate() Can't find variable: TransformStream >+FAIL controller.error() after controller.terminate() with queued chunk should error the readable Can't find variable: TransformStream >+FAIL controller.error() after controller.terminate() without queued chunk should do nothing Can't find variable: TransformStream >+FAIL controller.terminate() inside flush() should not prevent writer.close() from succeeding Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.dedicatedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.dedicatedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..5b8a5ba963d2e99591960b43acd65b1ea3d9ad10 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.dedicatedworker-expected.txt >@@ -0,0 +1,8 @@ >+ >+FAIL controller.terminate() should error pipeTo() Can't find variable: TransformStream >+FAIL controller.terminate() should prevent remaining chunks from being processed Can't find variable: TransformStream >+FAIL controller.enqueue() should throw after controller.terminate() Can't find variable: TransformStream >+FAIL controller.error() after controller.terminate() with queued chunk should error the readable Can't find variable: TransformStream >+FAIL controller.error() after controller.terminate() without queued chunk should do nothing Can't find variable: TransformStream >+FAIL controller.terminate() inside flush() should not prevent writer.close() from succeeding Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.dedicatedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.dedicatedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..403e3bf8cceabfff48e02426b20ccadd14e7f3ef >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.dedicatedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>terminate.js dedicated worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new Worker('terminate.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.html >new file mode 100644 >index 0000000000000000000000000000000000000000..c75136e1e54dbe71497a41383eaa94d5975c19a0 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>terminate.js browser context wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script src="../resources/recording-streams.js"></script> >+<script src="../resources/test-utils.js"></script> >+ >+<script src="terminate.js"></script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.js b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.js >new file mode 100644 >index 0000000000000000000000000000000000000000..36c6fbd379b1e2081c1b7545f02dde59fe96c809 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.js >@@ -0,0 +1,105 @@ >+'use strict'; >+ >+if (self.importScripts) { >+ self.importScripts('/resources/testharness.js'); >+ self.importScripts('../resources/recording-streams.js'); >+ self.importScripts('../resources/test-utils.js'); >+} >+ >+promise_test(t => { >+ const ts = recordingTransformStream({}, undefined, { highWaterMark: 0 }); >+ const rs = new ReadableStream({ >+ start(controller) { >+ controller.enqueue(0); >+ } >+ }); >+ let pipeToRejected = false; >+ const pipeToPromise = promise_rejects(t, new TypeError(), rs.pipeTo(ts.writable), 'pipeTo should reject').then(() => { >+ pipeToRejected = true; >+ }); >+ return delay(0).then(() => { >+ assert_array_equals(ts.events, [], 'transform() should have seen no chunks'); >+ assert_false(pipeToRejected, 'pipeTo() should not have rejected yet'); >+ ts.controller.terminate(); >+ return pipeToPromise; >+ }).then(() => { >+ assert_array_equals(ts.events, [], 'transform() should still have seen no chunks'); >+ assert_true(pipeToRejected, 'pipeToRejected must be true'); >+ }); >+}, 'controller.terminate() should error pipeTo()'); >+ >+promise_test(t => { >+ const ts = recordingTransformStream({}, undefined, { highWaterMark: 1 }); >+ const rs = new ReadableStream({ >+ start(controller) { >+ controller.enqueue(0); >+ controller.enqueue(1); >+ } >+ }); >+ const pipeToPromise = rs.pipeTo(ts.writable); >+ return delay(0).then(() => { >+ assert_array_equals(ts.events, ['transform', 0], 'transform() should have seen one chunk'); >+ ts.controller.terminate(); >+ return promise_rejects(t, new TypeError(), pipeToPromise, 'pipeTo() should reject'); >+ }).then(() => { >+ assert_array_equals(ts.events, ['transform', 0], 'transform() should still have seen only one chunk'); >+ }); >+}, 'controller.terminate() should prevent remaining chunks from being processed'); >+ >+test(() => { >+ new TransformStream({ >+ start(controller) { >+ controller.enqueue(0); >+ controller.terminate(); >+ assert_throws(new TypeError(), () => controller.enqueue(1), 'enqueue should throw'); >+ } >+ }); >+}, 'controller.enqueue() should throw after controller.terminate()'); >+ >+const error1 = new Error('error1'); >+error1.name = 'error1'; >+ >+promise_test(t => { >+ const ts = new TransformStream({ >+ start(controller) { >+ controller.enqueue(0); >+ controller.terminate(); >+ controller.error(error1); >+ } >+ }); >+ return Promise.all([ >+ promise_rejects(t, new TypeError(), ts.writable.abort(), 'abort() should reject with a TypeError'), >+ promise_rejects(t, error1, ts.readable.cancel(), 'cancel() should reject with error1'), >+ promise_rejects(t, error1, ts.readable.getReader().closed, 'closed should reject with error1') >+ ]); >+}, 'controller.error() after controller.terminate() with queued chunk should error the readable'); >+ >+promise_test(t => { >+ const ts = new TransformStream({ >+ start(controller) { >+ controller.terminate(); >+ controller.error(error1); >+ } >+ }); >+ return Promise.all([ >+ promise_rejects(t, new TypeError(), ts.writable.abort(), 'abort() should reject with a TypeError'), >+ ts.readable.cancel(), >+ ts.readable.getReader().closed >+ ]); >+}, 'controller.error() after controller.terminate() without queued chunk should do nothing'); >+ >+promise_test(() => { >+ const ts = new TransformStream({ >+ flush(controller) { >+ controller.terminate(); >+ } >+ }); >+ const writer = ts.writable.getWriter(); >+ return Promise.all([ >+ writer.close(), >+ writer.closed, >+ ts.readable.getReader().closed >+ ]); >+}, 'controller.terminate() inside flush() should not prevent writer.close() from succeeding'); >+ >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.serviceworker.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.serviceworker.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..1e7d78f83b49fc6ff8f618dedce16c8445eae12a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.serviceworker.https-expected.txt >@@ -0,0 +1,9 @@ >+ >+PASS Service worker test setup >+FAIL controller.terminate() should error pipeTo() Can't find variable: TransformStream >+FAIL controller.terminate() should prevent remaining chunks from being processed Can't find variable: TransformStream >+FAIL controller.enqueue() should throw after controller.terminate() Can't find variable: TransformStream >+FAIL controller.error() after controller.terminate() with queued chunk should error the readable Can't find variable: TransformStream >+FAIL controller.error() after controller.terminate() without queued chunk should do nothing Can't find variable: TransformStream >+FAIL controller.terminate() inside flush() should not prevent writer.close() from succeeding Can't find variable: TransformStream >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.serviceworker.https.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.serviceworker.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..f5715f6fd01d849747d67498453a629da100f913 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.serviceworker.https.html >@@ -0,0 +1,12 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>terminate.js service worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> >+ >+<script> >+'use strict'; >+service_worker_test('terminate.js', 'Service worker test setup'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.sharedworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.sharedworker-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..0cb6e7c8e39fe3ee341111028494210a202f922e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.sharedworker-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 10: ReferenceError: Can't find variable: SharedWorker >+ >+FAIL terminate.js shared worker wrapper file ReferenceError: Can't find variable: SharedWorker >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.sharedworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.sharedworker.html >new file mode 100644 >index 0000000000000000000000000000000000000000..3af58a1c14330919cbc126918d842d7c97926e32 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.sharedworker.html >@@ -0,0 +1,11 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>terminate.js shared worker wrapper file</title> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+'use strict'; >+fetch_tests_from_worker(new SharedWorker('terminate.js')); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..f5606e384db7b938590cb236f76f89cd9641ff8e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/w3c-import.log >@@ -0,0 +1,76 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.dedicatedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.js >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.serviceworker.https.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.sharedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.dedicatedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.js >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.serviceworker.https.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/brand-checks.sharedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.dedicatedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.js >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.serviceworker.https.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/constructor.sharedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.dedicatedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.js >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.serviceworker.https.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.sharedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.dedicatedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.js >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.serviceworker.https.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.sharedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.dedicatedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.js >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.serviceworker.https.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.sharedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.dedicatedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.js >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.serviceworker.https.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.sharedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.dedicatedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.js >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.serviceworker.https.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.sharedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.dedicatedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.js >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.serviceworker.https.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.sharedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.dedicatedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.js >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.serviceworker.https.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.sharedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.dedicatedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.js >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.serviceworker.https.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.sharedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.dedicatedworker.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.js >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.serviceworker.https.html >+/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.sharedworker.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/touch-events/create-touch-touchlist-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/touch-events/create-touch-touchlist-expected.txt >deleted file mode 100644 >index c6846c853c8f84148af480daceb634ecd0324a5e..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/touch-events/create-touch-touchlist-expected.txt >+++ /dev/null >@@ -1,6 +0,0 @@ >- >-PASS document.createTouch exists and creates a Touch object with requested properties >-PASS document.createTouchList exists and correctly creates a TouchList from zero Touch objects >-FAIL document.createTouchList exists and correctly creates a TouchList from a single Touch assert_true: radiusX attribute in Touch object expected true got false >-FAIL document.createTouchList exists and correctly creates a TouchList from two Touch objects assert_true: radiusX attribute in Touch object expected true got false >- >diff --git a/LayoutTests/imported/w3c/web-platform-tests/touch-events/create-touch-touchlist.html b/LayoutTests/imported/w3c/web-platform-tests/touch-events/create-touch-touchlist.html >deleted file mode 100644 >index abd0f4835c5285981d19fe74504ffc975274ec6c..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/touch-events/create-touch-touchlist.html >+++ /dev/null >@@ -1,50 +0,0 @@ >-<!DOCTYPE HTML> >-<html> >-<head> >-<title>document.createTouch and document.createTouchList Tests</title> >-<script src="/resources/testharness.js"></script> >-<script src="/resources/testharnessreport.js"></script> >-<script src="touch-support.js"></script> >-<body> >-<div id="target0"></div> >-<script> >-test(function() { >- var testTarget = document.getElementById('target0'); >- var touch1 = document.createTouch(window, testTarget, 42, 15, 20, 35, 40); >- assert_equals(touch1.target, testTarget, "touch.target is target0"); >- assert_equals(touch1.identifier, 42, "touch.identifier is requested value"); >- assert_equals(touch1.pageX, 15, "touch.pageX is requested value"); >- assert_equals(touch1.pageY, 20, "touch.pageY is requested value"); >- assert_equals(touch1.screenX, 35, "touch.screenX is requested value"); >- assert_equals(touch1.screenY, 40, "touch.screenY is requested value"); >-}, "document.createTouch exists and creates a Touch object with requested properties"); >- >-test(function() { >- var touchList = document.createTouchList(); >- assert_equals(touchList.length, 0, "touchList.length is 0"); >- check_TouchList_object(touchList); >-}, "document.createTouchList exists and correctly creates a TouchList from zero Touch objects"); >- >-test(function() { >- var testTarget = document.getElementById('target0'); >- var touch1 = document.createTouch(window, testTarget, 42, 15, 20, 35, 40); >- var touchList = document.createTouchList(touch1); >- assert_equals(touchList.length, 1, "touchList.length is 1"); >- assert_equals(touchList.item(0), touch1, "touchList.item(0) is touch1"); >- check_TouchList_object(touchList); >-}, "document.createTouchList exists and correctly creates a TouchList from a single Touch"); >- >-test(function() { >- var testTarget = document.getElementById('target0'); >- var touch1 = document.createTouch(window, testTarget, 42, 15, 20, 35, 40); >- var touch2 = document.createTouch(window, target0, 44, 25, 30, 45, 50); >- var touchList = document.createTouchList(touch1, touch2); >- assert_equals(touchList.length, 2, "touchList.length is 2"); >- assert_equals(touchList.item(0), touch1, "touchList.item(0) is touch1"); >- assert_equals(touchList.item(1), touch2, "touchList.item(1) is touch2"); >- check_TouchList_object(touchList); >-}, "document.createTouchList exists and correctly creates a TouchList from two Touch objects"); >-</script> >-</head> >-</body> >-</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/touch-events/historical.html b/LayoutTests/imported/w3c/web-platform-tests/touch-events/historical.html >index 7d1e323c4d568532347d8033e59200de37c5281f..27cc88d8ce0f7889cb60b8d0b7ba9f759745637c 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/touch-events/historical.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/touch-events/historical.html >@@ -16,7 +16,7 @@ > assert_false(name in Touch.prototype, > "Should not be supported on the prototype"); > >- var touch = document.createTouch(window, window, 0, 0, 0, 0, 0); >+ var touch = new Touch({identifier: 12341, target:document.body}); > assert_false(name in touch, > "Should not be supported on the instance"); > }, "Touch::" + name); >@@ -26,7 +26,8 @@ test(function() { > assert_false("identifiedTouch" in TouchList.prototype, > "Should not be supported on the prototype"); > >- var touchList = document.createTouchList(); >+ var touchevent = new TouchEvent("touchstart", {}); >+ var touchList = touchevent.touches; > assert_false("identifiedTouch" in touchList, > "Should not be supported on the instance"); > }, "TouchList::identifiedTouch"); >@@ -39,4 +40,20 @@ test(function() { > assert_false("initTouchEvent" in touchEvent, > "Should not be supported on the instance"); > }, "TouchEvent::initTouchEvent"); >+ >+test(function() { >+ assert_false("createTouch" in Document.prototype, >+ "Should not be supported on the prototype"); >+ >+ assert_false("createTouch" in document, >+ "Should not be supported on the instance"); >+}, "Document::createTouch"); >+ >+test(function() { >+ assert_false("createTouchList" in Document.prototype, >+ "Should not be supported on the prototype"); >+ >+ assert_false("createTouchList" in document, >+ "Should not be supported on the instance"); >+}, "Document::createTouchList"); > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/touch-events/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/touch-events/w3c-import.log >index ff0159075280c1005dec78f298f76e84ec068542..8ec21cc6df2755783283504d5c60e43c20408614 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/touch-events/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/touch-events/w3c-import.log >@@ -15,7 +15,6 @@ None > ------------------------------------------------------------------------ > List of files: > /LayoutTests/imported/w3c/web-platform-tests/touch-events/OWNERS >-/LayoutTests/imported/w3c/web-platform-tests/touch-events/create-touch-touchlist.html > /LayoutTests/imported/w3c/web-platform-tests/touch-events/historical.html > /LayoutTests/imported/w3c/web-platform-tests/touch-events/multi-touch-interactions.js > /LayoutTests/imported/w3c/web-platform-tests/touch-events/touch-globaleventhandler-interface.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/update-built-tests.sh b/LayoutTests/imported/w3c/web-platform-tests/update-built-tests.sh >index 63722f4b1d0e03705c05c2e893e388a8b677e457..34e4fd5100e3baa1bbcceeacbbf77713f1355274 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/update-built-tests.sh >+++ b/LayoutTests/imported/w3c/web-platform-tests/update-built-tests.sh >@@ -5,3 +5,7 @@ set -ex > infrastructure/assumptions/tools/build.sh > html/tools/build.sh > offscreen-canvas/tools/build.sh >+python mimesniff/mime-types/resources/generated-mime-types.py >+ >+# Infrastucture >+python wpt make-tasks >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/README.md b/LayoutTests/imported/w3c/web-platform-tests/url/README.md >index 4cb3c00d61c44e268a898acb3466df7be601944f..667951d680fcdae240661f6cb3a1747f2ec545ec 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/README.md >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/README.md >@@ -1,10 +1,12 @@ >+## urltestdata.json >+ > These tests are for browsers, but the data for >-`a-element.html`, `url-constructor.html`, and `a-element-xhtml.xhtml` >-is in `urltestdata.json` and can be re-used by non-browser implementations. >+`a-element.html`, `url-constructor.html`, `a-element-xhtml.xhtml`, and `failure.html` >+is in `resources/urltestdata.json` and can be re-used by non-browser implementations. > This file contains a JSON array of comments as strings and test cases as objects. > The keys for each test case are: > >-* `base`: an absolute URL as a string whose [parsing] without a base of its own should succeed. >+* `base`: an absolute URL as a string whose [parsing] without a base of its own must succeed. > This key is always present, > and may have a value like `"about:blank"` when `input` is an absolute URL. > * `input`: an URL as a string to be [parsed][parsing] with `base` as its base URL. >@@ -19,5 +21,28 @@ The keys for each test case are: > The `origin` key may be missing. > In that case, the APIâs `origin` attribute is not tested. > >+In addition to testing that parsing `input` against `base` gives the result, a test harness for the >+`URL` constructor (or similar APIs) should additionally test the following pattern: if `failure` is >+true, parsing `about:blank` against `input` must give failure. This tests that the logic for >+converting base URLs into strings properly fails the whole parsing algorithm if the base URL cannot >+be parsed. >+ >+## setters_tests.json >+ >+`resources/setters_tests.json` is self-documented. >+ >+## toascii.json >+ >+`resources/toascii.json` is a JSON resource containing an array where each item is an object >+consisting of an optional `comment` field and mandatory `input` and `output` fields. `input` is the >+domain to be parsed according to the rules of UTS #46 (as stipulated by the URL Standard). `output` >+gives the expected output of the parser after serialization. An `output` of `null` means parsing is >+expected to fail. >+ >+## URL parser's encoding argument >+ >+Tests in `/encoding` and `/html/infrastructure/urls/resolving-urls/query-encoding/` cover the >+encoding argument to the URL parser. >+ > [parsing]: https://url.spec.whatwg.org/#concept-basic-url-parser > [API]: https://url.spec.whatwg.org/#api >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/a-element-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/url/a-element-expected.txt >index f6edc09dff98c38f345da7355e4a1cc8d6fe983f..e646ca50c8568eb148144fe5a438836252a9abf9 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/a-element-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/a-element-expected.txt >@@ -512,13 +512,13 @@ PASS Parsing: <http://example.org/test?%23%23> against <about:blank> > PASS Parsing: <http://example.org/test?%GH> against <about:blank> > PASS Parsing: <http://example.org/test?a#%EF> against <about:blank> > PASS Parsing: <http://example.org/test?a#%GH> against <about:blank> >-FAIL Parsing: <test-a.html> against <a> assert_unreached: Expected URL to fail parsing Reached unreachable code >-FAIL Parsing: <test-a-slash.html> against <a/> assert_unreached: Expected URL to fail parsing Reached unreachable code >-FAIL Parsing: <test-a-slash-slash.html> against <a//> assert_unreached: Expected URL to fail parsing Reached unreachable code >+PASS Parsing: <a> against <about:blank> >+PASS Parsing: <a/> against <about:blank> >+PASS Parsing: <a//> against <about:blank> > PASS Parsing: <test-a-colon.html> against <a:> >+PASS Parsing: <test-a-colon-b.html> against <a:b> > PASS Parsing: <test-a-colon-slash.html> against <a:/> > FAIL Parsing: <test-a-colon-slash-slash.html> against <a://> assert_equals: href expected "a:///test-a-colon-slash-slash.html" but got "a://test-a-colon-slash-slash.html" >-PASS Parsing: <test-a-colon-b.html> against <a:b> > PASS Parsing: <test-a-colon-slash-b.html> against <a:/b> > PASS Parsing: <test-a-colon-slash-slash-b.html> against <a://b> > FAIL Parsing: <http://example.org/test?a#b\0c> against <about:blank> assert_equals: href expected "http://example.org/test?a#bc" but got "http://example.org/test?a#b%00c" >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/a-element-origin-xhtml.xhtml b/LayoutTests/imported/w3c/web-platform-tests/url/a-element-origin-xhtml.xhtml >index 3d0d72efcb4c4dc3cbf35f08711a2c8d25da9900..effcf04bee3fb0def0b32bd92df5008fbd27e063 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/a-element-origin-xhtml.xhtml >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/a-element-origin-xhtml.xhtml >@@ -9,7 +9,7 @@ > </head> > <body> > <div id="log"></div> >- <script src="a-element-origin.js"></script> >+ <script src="resources/a-element-origin.js"></script> > </body> > </html> >-<!-- Other dependencies: urltestdata.json --> >+<!-- Other dependencies: resources/urltestdata.json --> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/a-element-origin.html b/LayoutTests/imported/w3c/web-platform-tests/url/a-element-origin.html >index 28ef696b4c1a8dc9977a773982484fde11a0c37b..9cc8e94cbed06056fe4529b74499d8ae94dc8523 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/a-element-origin.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/a-element-origin.html >@@ -4,5 +4,5 @@ > <script src=/resources/testharnessreport.js></script> > <base id=base> > <div id=log></div> >-<script src=a-element-origin.js></script> >-<!-- Other dependencies: urltestdata.json --> >+<script src=resources/a-element-origin.js></script> >+<!-- Other dependencies: resources/urltestdata.json --> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/a-element-origin.js b/LayoutTests/imported/w3c/web-platform-tests/url/a-element-origin.js >deleted file mode 100644 >index a1202db5bde49cf96609f056af5cb2b85b9e1697..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/a-element-origin.js >+++ /dev/null >@@ -1,35 +0,0 @@ >-var setup = async_test("Loading dataâ¦") >-setup.step(function() { >- var request = new XMLHttpRequest() >- request.open("GET", "urltestdata.json") >- request.send() >- request.responseType = "json" >- request.onload = setup.step_func(function() { >- runURLTests(request.response) >- setup.done() >- }) >-}) >- >-function setBase(base) { >- document.getElementById("base").href = base >-} >- >-function bURL(url, base) { >- base = base || "about:blank" >- setBase(base) >- var a = document.createElement("a") >- a.setAttribute("href", url) >- return a >-} >- >-function runURLTests(urltests) { >- for(var i = 0, l = urltests.length; i < l; i++) { >- var expected = urltests[i] >- if (typeof expected === "string" || !("origin" in expected)) continue >- >- test(function() { >- var url = bURL(expected.input, expected.base) >- assert_equals(url.origin, expected.origin, "origin") >- }, "Parsing origin: <" + expected.input + "> against <" + expected.base + ">") >- } >-} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/a-element-xhtml-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/url/a-element-xhtml-expected.txt >index f6edc09dff98c38f345da7355e4a1cc8d6fe983f..e646ca50c8568eb148144fe5a438836252a9abf9 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/a-element-xhtml-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/a-element-xhtml-expected.txt >@@ -512,13 +512,13 @@ PASS Parsing: <http://example.org/test?%23%23> against <about:blank> > PASS Parsing: <http://example.org/test?%GH> against <about:blank> > PASS Parsing: <http://example.org/test?a#%EF> against <about:blank> > PASS Parsing: <http://example.org/test?a#%GH> against <about:blank> >-FAIL Parsing: <test-a.html> against <a> assert_unreached: Expected URL to fail parsing Reached unreachable code >-FAIL Parsing: <test-a-slash.html> against <a/> assert_unreached: Expected URL to fail parsing Reached unreachable code >-FAIL Parsing: <test-a-slash-slash.html> against <a//> assert_unreached: Expected URL to fail parsing Reached unreachable code >+PASS Parsing: <a> against <about:blank> >+PASS Parsing: <a/> against <about:blank> >+PASS Parsing: <a//> against <about:blank> > PASS Parsing: <test-a-colon.html> against <a:> >+PASS Parsing: <test-a-colon-b.html> against <a:b> > PASS Parsing: <test-a-colon-slash.html> against <a:/> > FAIL Parsing: <test-a-colon-slash-slash.html> against <a://> assert_equals: href expected "a:///test-a-colon-slash-slash.html" but got "a://test-a-colon-slash-slash.html" >-PASS Parsing: <test-a-colon-b.html> against <a:b> > PASS Parsing: <test-a-colon-slash-b.html> against <a:/b> > PASS Parsing: <test-a-colon-slash-slash-b.html> against <a://b> > FAIL Parsing: <http://example.org/test?a#b\0c> against <about:blank> assert_equals: href expected "http://example.org/test?a#bc" but got "http://example.org/test?a#b%00c" >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/a-element-xhtml.xhtml b/LayoutTests/imported/w3c/web-platform-tests/url/a-element-xhtml.xhtml >index fda4c3604ef6c60fb9915455aebc762d34127715..c6c67cf3ce619bb5abb7522e621ff1371a957619 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/a-element-xhtml.xhtml >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/a-element-xhtml.xhtml >@@ -9,7 +9,7 @@ > </head> > <body> > <div id="log"></div> >- <script src="a-element.js"></script> >+ <script src="resources/a-element.js"></script> > </body> > </html> >-<!-- Other dependencies: urltestdata.json --> >+<!-- Other dependencies: resources/urltestdata.json --> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/a-element.html b/LayoutTests/imported/w3c/web-platform-tests/url/a-element.html >index 1b7e2fdd3fa1781bd341eb23c54dc1b89b841458..05c37f30b71e12eee71f6941d33e712aafa080f3 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/a-element.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/a-element.html >@@ -4,5 +4,5 @@ > <script src=/resources/testharnessreport.js></script> > <base id=base> > <div id=log></div> >-<script src=a-element.js></script> >-<!-- Other dependencies: urltestdata.json --> >+<script src=resources/a-element.js></script> >+<!-- Other dependencies: resources/urltestdata.json --> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/a-element.js b/LayoutTests/imported/w3c/web-platform-tests/url/a-element.js >deleted file mode 100644 >index a3d78139b16a010e1381bff09cdbc228444b9553..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/a-element.js >+++ /dev/null >@@ -1,52 +0,0 @@ >-var setup = async_test("Loading dataâ¦") >-setup.step(function() { >- var request = new XMLHttpRequest() >- request.open("GET", "urltestdata.json") >- request.send() >- request.responseType = "json" >- request.onload = setup.step_func(function() { >- runURLTests(request.response) >- setup.done() >- }) >-}) >- >-function setBase(base) { >- document.getElementById("base").href = base >-} >- >-function bURL(url, base) { >- base = base || "about:blank" >- setBase(base) >- var a = document.createElement("a") >- a.setAttribute("href", url) >- return a >-} >- >-function runURLTests(urltests) { >- for(var i = 0, l = urltests.length; i < l; i++) { >- var expected = urltests[i] >- if (typeof expected === "string") continue // skip comments >- >- test(function() { >- var url = bURL(expected.input, expected.base) >- if(expected.failure) { >- if(url.protocol !== ':') { >- assert_unreached("Expected URL to fail parsing") >- } >- assert_equals(url.href, expected.input, "failure should set href to input") >- return >- } >- >- assert_equals(url.href, expected.href, "href") >- assert_equals(url.protocol, expected.protocol, "protocol") >- assert_equals(url.username, expected.username, "username") >- assert_equals(url.password, expected.password, "password") >- assert_equals(url.host, expected.host, "host") >- assert_equals(url.hostname, expected.hostname, "hostname") >- assert_equals(url.port, expected.port, "port") >- assert_equals(url.pathname, expected.pathname, "pathname") >- assert_equals(url.search, expected.search, "search") >- assert_equals(url.hash, expected.hash, "hash") >- }, "Parsing: <" + expected.input + "> against <" + expected.base + ">") >- } >-} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/data-uri-fragment-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/url/data-uri-fragment-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d41137a3896d6a5ad617066647b562ceb5750861 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/data-uri-fragment-expected.txt >@@ -0,0 +1,4 @@ >+ >+ >+FAIL Data URI parsing of fragments assert_equals: expected "<p id=\"foo\">This should be the only visible text.</p>" but got "<p id=\"foo\">This should be the only visible text.</p>#foo" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/data-uri-fragment.html b/LayoutTests/imported/w3c/web-platform-tests/url/data-uri-fragment.html >new file mode 100644 >index 0000000000000000000000000000000000000000..e77d96f03d821d4fdcd8cfa17f05ebe1b8237fe7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/data-uri-fragment.html >@@ -0,0 +1,34 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Data URI parsing of fragments</title> >+<link rel="help" href="https://url.spec.whatwg.org/"> >+<meta name="assert" content="Fragments should not be included as part of a data URI's body"> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<iframe id="iframe"></iframe> >+ >+<script> >+const IFRAME_DATA_SRC = `data:text/html, >+ <style>:target { color: green; }<\/style> >+ <script>window.addEventListener('load', function() { >+ const data = { >+ foo_matches_target_selector: document.getElementById('foo').matches(':target'), >+ body_html: document.body.innerHTML, >+ }; >+ parent.postMessage(data, '*'); >+ });<\/script> >+ <p id="foo">This should be the only visible text.</p>#foo`.replace('\n', ''); >+ >+async_test(function(t) { >+ window.addEventListener("message", t.step_func_done(function(event) { >+ assert_true(event.data.foo_matches_target_selector); >+ assert_equals(event.data.body_html, >+ '<p id="foo">This should be the only visible text.</p>'); >+ })); >+ >+ const iframe = document.getElementById("iframe"); >+ iframe.src = IFRAME_DATA_SRC; >+}); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/failure.html b/LayoutTests/imported/w3c/web-platform-tests/url/failure.html >index d097d4e35100967900e22b128698cc91af54742a..13a90cc8d097c1631022d9cc1ec636fca19b256d 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/failure.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/failure.html >@@ -6,7 +6,7 @@ > <div id=log></div> > <iframe></iframe> > <script> >-promise_test(() => fetch("urltestdata.json").then(res => res.json()).then(runTests), "Loading dataâ¦") >+promise_test(() => fetch("resources/urltestdata.json").then(res => res.json()).then(runTests), "Loading dataâ¦") > > function runTests(testData) { > for(const test of testData) { >@@ -16,7 +16,13 @@ function runTests(testData) { > > const name = test.input + " should throw" > >- self.test(() => { // new URL itself is already tested by url-constructor.html >+ self.test(() => { // URL's constructor's first argument is tested by url-constructor.html >+ // If a URL fails to parse with any valid base, it must also fail to parse with no base, i.e. >+ // when used as a base URL itself. >+ assert_throws(new TypeError(), () => new URL("about:blank", test.input)); >+ }, "URL's constructor's base argument: " + name) >+ >+ self.test(() => { > const url = new URL("about:blank") > assert_throws(new TypeError, () => url.href = test.input) > }, "URL's href: " + name) >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/resources/a-element-origin.js b/LayoutTests/imported/w3c/web-platform-tests/url/resources/a-element-origin.js >new file mode 100644 >index 0000000000000000000000000000000000000000..3b8cb1cbbe7c75a7d64442b59f2ad4888cef2f68 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/resources/a-element-origin.js >@@ -0,0 +1,25 @@ >+promise_test(() => fetch("resources/urltestdata.json").then(res => res.json()).then(runURLTests), "Loading dataâ¦"); >+ >+function setBase(base) { >+ document.getElementById("base").href = base >+} >+ >+function bURL(url, base) { >+ base = base || "about:blank" >+ setBase(base) >+ var a = document.createElement("a") >+ a.setAttribute("href", url) >+ return a >+} >+ >+function runURLTests(urltests) { >+ for(var i = 0, l = urltests.length; i < l; i++) { >+ var expected = urltests[i] >+ if (typeof expected === "string" || !("origin" in expected)) continue >+ >+ test(function() { >+ var url = bURL(expected.input, expected.base) >+ assert_equals(url.origin, expected.origin, "origin") >+ }, "Parsing origin: <" + expected.input + "> against <" + expected.base + ">") >+ } >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/resources/a-element.js b/LayoutTests/imported/w3c/web-platform-tests/url/resources/a-element.js >new file mode 100644 >index 0000000000000000000000000000000000000000..f64531bc8bd5285ae9f2c35cd38f8a739ee39e72 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/resources/a-element.js >@@ -0,0 +1,42 @@ >+promise_test(() => fetch("resources/urltestdata.json").then(res => res.json()).then(runURLTests), "Loading dataâ¦"); >+ >+function setBase(base) { >+ document.getElementById("base").href = base >+} >+ >+function bURL(url, base) { >+ base = base || "about:blank" >+ setBase(base) >+ var a = document.createElement("a") >+ a.setAttribute("href", url) >+ return a >+} >+ >+function runURLTests(urltests) { >+ for(var i = 0, l = urltests.length; i < l; i++) { >+ var expected = urltests[i] >+ if (typeof expected === "string") continue // skip comments >+ >+ test(function() { >+ var url = bURL(expected.input, expected.base) >+ if(expected.failure) { >+ if(url.protocol !== ':') { >+ assert_unreached("Expected URL to fail parsing") >+ } >+ assert_equals(url.href, expected.input, "failure should set href to input") >+ return >+ } >+ >+ assert_equals(url.href, expected.href, "href") >+ assert_equals(url.protocol, expected.protocol, "protocol") >+ assert_equals(url.username, expected.username, "username") >+ assert_equals(url.password, expected.password, "password") >+ assert_equals(url.host, expected.host, "host") >+ assert_equals(url.hostname, expected.hostname, "hostname") >+ assert_equals(url.port, expected.port, "port") >+ assert_equals(url.pathname, expected.pathname, "pathname") >+ assert_equals(url.search, expected.search, "search") >+ assert_equals(url.hash, expected.hash, "hash") >+ }, "Parsing: <" + expected.input + "> against <" + expected.base + ">") >+ } >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/resources/setters_tests.json b/LayoutTests/imported/w3c/web-platform-tests/url/resources/setters_tests.json >new file mode 100644 >index 0000000000000000000000000000000000000000..db23d9247328009772b3cdc9eb161f9787304857 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/resources/setters_tests.json >@@ -0,0 +1,1866 @@ >+{ >+ "comment": [ >+ "## Tests for setters of https://url.spec.whatwg.org/#urlutils-members", >+ "", >+ "This file contains a JSON object.", >+ "Other than 'comment', each key is an attribute of the `URL` interface", >+ "defined in WHATWGâs URL Standard.", >+ "The values are arrays of test case objects for that attribute.", >+ "", >+ "To run a test case for the attribute `attr`:", >+ "", >+ "* Create a new `URL` object with the value for the 'href' key", >+ " the constructor single parameter. (Without a base URL.)", >+ " This must not throw.", >+ "* Set the attribute `attr` to (invoke its setter with)", >+ " with the value of for 'new_value' key.", >+ "* The value for the 'expected' key is another object.", >+ " For each `key` / `value` pair of that object,", >+ " get the attribute `key` (invoke its getter).", >+ " The returned string must be equal to `value`.", >+ "", >+ "Note: the 'href' setter is already covered by urltestdata.json." >+ ], >+ "protocol": [ >+ { >+ "comment": "The empty string is not a valid scheme. Setter leaves the URL unchanged.", >+ "href": "a://example.net", >+ "new_value": "", >+ "expected": { >+ "href": "a://example.net", >+ "protocol": "a:" >+ } >+ }, >+ { >+ "href": "a://example.net", >+ "new_value": "b", >+ "expected": { >+ "href": "b://example.net", >+ "protocol": "b:" >+ } >+ }, >+ { >+ "href": "javascript:alert(1)", >+ "new_value": "defuse", >+ "expected": { >+ "href": "defuse:alert(1)", >+ "protocol": "defuse:" >+ } >+ }, >+ { >+ "comment": "Upper-case ASCII is lower-cased", >+ "href": "a://example.net", >+ "new_value": "B", >+ "expected": { >+ "href": "b://example.net", >+ "protocol": "b:" >+ } >+ }, >+ { >+ "comment": "Non-ASCII is rejected", >+ "href": "a://example.net", >+ "new_value": "é", >+ "expected": { >+ "href": "a://example.net", >+ "protocol": "a:" >+ } >+ }, >+ { >+ "comment": "No leading digit", >+ "href": "a://example.net", >+ "new_value": "0b", >+ "expected": { >+ "href": "a://example.net", >+ "protocol": "a:" >+ } >+ }, >+ { >+ "comment": "No leading punctuation", >+ "href": "a://example.net", >+ "new_value": "+b", >+ "expected": { >+ "href": "a://example.net", >+ "protocol": "a:" >+ } >+ }, >+ { >+ "href": "a://example.net", >+ "new_value": "bC0+-.", >+ "expected": { >+ "href": "bc0+-.://example.net", >+ "protocol": "bc0+-.:" >+ } >+ }, >+ { >+ "comment": "Only some punctuation is acceptable", >+ "href": "a://example.net", >+ "new_value": "b,c", >+ "expected": { >+ "href": "a://example.net", >+ "protocol": "a:" >+ } >+ }, >+ { >+ "comment": "Non-ASCII is rejected", >+ "href": "a://example.net", >+ "new_value": "bé", >+ "expected": { >+ "href": "a://example.net", >+ "protocol": "a:" >+ } >+ }, >+ { >+ "comment": "Canât switch from URL containing username/password/port to file", >+ "href": "http://test@example.net", >+ "new_value": "file", >+ "expected": { >+ "href": "http://test@example.net/", >+ "protocol": "http:" >+ } >+ }, >+ { >+ "href": "gopher://example.net:1234", >+ "new_value": "file", >+ "expected": { >+ "href": "gopher://example.net:1234/", >+ "protocol": "gopher:" >+ } >+ }, >+ { >+ "href": "wss://x:x@example.net:1234", >+ "new_value": "file", >+ "expected": { >+ "href": "wss://x:x@example.net:1234/", >+ "protocol": "wss:" >+ } >+ }, >+ { >+ "comment": "Canât switch from file URL with no host", >+ "href": "file://localhost/", >+ "new_value": "http", >+ "expected": { >+ "href": "file:///", >+ "protocol": "file:" >+ } >+ }, >+ { >+ "href": "file:///test", >+ "new_value": "gopher", >+ "expected": { >+ "href": "file:///test", >+ "protocol": "file:" >+ } >+ }, >+ { >+ "href": "file:", >+ "new_value": "wss", >+ "expected": { >+ "href": "file:///", >+ "protocol": "file:" >+ } >+ }, >+ { >+ "comment": "Canât switch from special scheme to non-special", >+ "href": "http://example.net", >+ "new_value": "b", >+ "expected": { >+ "href": "http://example.net/", >+ "protocol": "http:" >+ } >+ }, >+ { >+ "href": "file://hi/path", >+ "new_value": "s", >+ "expected": { >+ "href": "file://hi/path", >+ "protocol": "file:" >+ } >+ }, >+ { >+ "href": "https://example.net", >+ "new_value": "s", >+ "expected": { >+ "href": "https://example.net/", >+ "protocol": "https:" >+ } >+ }, >+ { >+ "href": "ftp://example.net", >+ "new_value": "test", >+ "expected": { >+ "href": "ftp://example.net/", >+ "protocol": "ftp:" >+ } >+ }, >+ { >+ "comment": "Cannot-be-a-base URL doesnât have a host, but URL in a special scheme must.", >+ "href": "mailto:me@example.net", >+ "new_value": "http", >+ "expected": { >+ "href": "mailto:me@example.net", >+ "protocol": "mailto:" >+ } >+ }, >+ { >+ "comment": "Canât switch from non-special scheme to special", >+ "href": "ssh://me@example.net", >+ "new_value": "http", >+ "expected": { >+ "href": "ssh://me@example.net", >+ "protocol": "ssh:" >+ } >+ }, >+ { >+ "href": "ssh://me@example.net", >+ "new_value": "gopher", >+ "expected": { >+ "href": "ssh://me@example.net", >+ "protocol": "ssh:" >+ } >+ }, >+ { >+ "href": "ssh://me@example.net", >+ "new_value": "file", >+ "expected": { >+ "href": "ssh://me@example.net", >+ "protocol": "ssh:" >+ } >+ }, >+ { >+ "href": "ssh://example.net", >+ "new_value": "file", >+ "expected": { >+ "href": "ssh://example.net", >+ "protocol": "ssh:" >+ } >+ }, >+ { >+ "href": "nonsense:///test", >+ "new_value": "https", >+ "expected": { >+ "href": "nonsense:///test", >+ "protocol": "nonsense:" >+ } >+ }, >+ { >+ "comment": "Stuff after the first ':' is ignored", >+ "href": "http://example.net", >+ "new_value": "https:foo : bar", >+ "expected": { >+ "href": "https://example.net/", >+ "protocol": "https:" >+ } >+ }, >+ { >+ "comment": "Stuff after the first ':' is ignored", >+ "href": "data:text/html,<p>Test", >+ "new_value": "view-source+data:foo : bar", >+ "expected": { >+ "href": "view-source+data:text/html,<p>Test", >+ "protocol": "view-source+data:" >+ } >+ }, >+ { >+ "comment": "Port is set to null if it is the default for new scheme.", >+ "href": "http://foo.com:443/", >+ "new_value": "https", >+ "expected": { >+ "href": "https://foo.com/", >+ "protocol": "https:", >+ "port": "" >+ } >+ } >+ ], >+ "username": [ >+ { >+ "comment": "No host means no username", >+ "href": "file:///home/you/index.html", >+ "new_value": "me", >+ "expected": { >+ "href": "file:///home/you/index.html", >+ "username": "" >+ } >+ }, >+ { >+ "comment": "No host means no username", >+ "href": "unix:/run/foo.socket", >+ "new_value": "me", >+ "expected": { >+ "href": "unix:/run/foo.socket", >+ "username": "" >+ } >+ }, >+ { >+ "comment": "Cannot-be-a-base means no username", >+ "href": "mailto:you@example.net", >+ "new_value": "me", >+ "expected": { >+ "href": "mailto:you@example.net", >+ "username": "" >+ } >+ }, >+ { >+ "href": "javascript:alert(1)", >+ "new_value": "wario", >+ "expected": { >+ "href": "javascript:alert(1)", >+ "username": "" >+ } >+ }, >+ { >+ "href": "http://example.net", >+ "new_value": "me", >+ "expected": { >+ "href": "http://me@example.net/", >+ "username": "me" >+ } >+ }, >+ { >+ "href": "http://:secret@example.net", >+ "new_value": "me", >+ "expected": { >+ "href": "http://me:secret@example.net/", >+ "username": "me" >+ } >+ }, >+ { >+ "href": "http://me@example.net", >+ "new_value": "", >+ "expected": { >+ "href": "http://example.net/", >+ "username": "" >+ } >+ }, >+ { >+ "href": "http://me:secret@example.net", >+ "new_value": "", >+ "expected": { >+ "href": "http://:secret@example.net/", >+ "username": "" >+ } >+ }, >+ { >+ "comment": "UTF-8 percent encoding with the userinfo encode set.", >+ "href": "http://example.net", >+ "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Ãé", >+ "expected": { >+ "href": "http://%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9@example.net/", >+ "username": "%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9" >+ } >+ }, >+ { >+ "comment": "Bytes already percent-encoded are left as-is.", >+ "href": "http://example.net", >+ "new_value": "%c3%89té", >+ "expected": { >+ "href": "http://%c3%89t%C3%A9@example.net/", >+ "username": "%c3%89t%C3%A9" >+ } >+ }, >+ { >+ "href": "sc:///", >+ "new_value": "x", >+ "expected": { >+ "href": "sc:///", >+ "username": "" >+ } >+ }, >+ { >+ "href": "javascript://x/", >+ "new_value": "wario", >+ "expected": { >+ "href": "javascript://wario@x/", >+ "username": "wario" >+ } >+ }, >+ { >+ "href": "file://test/", >+ "new_value": "test", >+ "expected": { >+ "href": "file://test/", >+ "username": "" >+ } >+ } >+ ], >+ "password": [ >+ { >+ "comment": "No host means no password", >+ "href": "file:///home/me/index.html", >+ "new_value": "secret", >+ "expected": { >+ "href": "file:///home/me/index.html", >+ "password": "" >+ } >+ }, >+ { >+ "comment": "No host means no password", >+ "href": "unix:/run/foo.socket", >+ "new_value": "secret", >+ "expected": { >+ "href": "unix:/run/foo.socket", >+ "password": "" >+ } >+ }, >+ { >+ "comment": "Cannot-be-a-base means no password", >+ "href": "mailto:me@example.net", >+ "new_value": "secret", >+ "expected": { >+ "href": "mailto:me@example.net", >+ "password": "" >+ } >+ }, >+ { >+ "href": "http://example.net", >+ "new_value": "secret", >+ "expected": { >+ "href": "http://:secret@example.net/", >+ "password": "secret" >+ } >+ }, >+ { >+ "href": "http://me@example.net", >+ "new_value": "secret", >+ "expected": { >+ "href": "http://me:secret@example.net/", >+ "password": "secret" >+ } >+ }, >+ { >+ "href": "http://:secret@example.net", >+ "new_value": "", >+ "expected": { >+ "href": "http://example.net/", >+ "password": "" >+ } >+ }, >+ { >+ "href": "http://me:secret@example.net", >+ "new_value": "", >+ "expected": { >+ "href": "http://me@example.net/", >+ "password": "" >+ } >+ }, >+ { >+ "comment": "UTF-8 percent encoding with the userinfo encode set.", >+ "href": "http://example.net", >+ "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Ãé", >+ "expected": { >+ "href": "http://:%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9@example.net/", >+ "password": "%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9" >+ } >+ }, >+ { >+ "comment": "Bytes already percent-encoded are left as-is.", >+ "href": "http://example.net", >+ "new_value": "%c3%89té", >+ "expected": { >+ "href": "http://:%c3%89t%C3%A9@example.net/", >+ "password": "%c3%89t%C3%A9" >+ } >+ }, >+ { >+ "href": "sc:///", >+ "new_value": "x", >+ "expected": { >+ "href": "sc:///", >+ "password": "" >+ } >+ }, >+ { >+ "href": "javascript://x/", >+ "new_value": "bowser", >+ "expected": { >+ "href": "javascript://:bowser@x/", >+ "password": "bowser" >+ } >+ }, >+ { >+ "href": "file://test/", >+ "new_value": "test", >+ "expected": { >+ "href": "file://test/", >+ "password": "" >+ } >+ } >+ ], >+ "host": [ >+ { >+ "comment": "Non-special scheme", >+ "href": "sc://x/", >+ "new_value": "\u0000", >+ "expected": { >+ "href": "sc://x/", >+ "host": "x", >+ "hostname": "x" >+ } >+ }, >+ { >+ "href": "sc://x/", >+ "new_value": "\u0009", >+ "expected": { >+ "href": "sc:///", >+ "host": "", >+ "hostname": "" >+ } >+ }, >+ { >+ "href": "sc://x/", >+ "new_value": "\u000A", >+ "expected": { >+ "href": "sc:///", >+ "host": "", >+ "hostname": "" >+ } >+ }, >+ { >+ "href": "sc://x/", >+ "new_value": "\u000D", >+ "expected": { >+ "href": "sc:///", >+ "host": "", >+ "hostname": "" >+ } >+ }, >+ { >+ "href": "sc://x/", >+ "new_value": " ", >+ "expected": { >+ "href": "sc://x/", >+ "host": "x", >+ "hostname": "x" >+ } >+ }, >+ { >+ "href": "sc://x/", >+ "new_value": "#", >+ "expected": { >+ "href": "sc:///", >+ "host": "", >+ "hostname": "" >+ } >+ }, >+ { >+ "href": "sc://x/", >+ "new_value": "/", >+ "expected": { >+ "href": "sc:///", >+ "host": "", >+ "hostname": "" >+ } >+ }, >+ { >+ "href": "sc://x/", >+ "new_value": "?", >+ "expected": { >+ "href": "sc:///", >+ "host": "", >+ "hostname": "" >+ } >+ }, >+ { >+ "href": "sc://x/", >+ "new_value": "@", >+ "expected": { >+ "href": "sc://x/", >+ "host": "x", >+ "hostname": "x" >+ } >+ }, >+ { >+ "href": "sc://x/", >+ "new_value": "Ã", >+ "expected": { >+ "href": "sc://%C3%9F/", >+ "host": "%C3%9F", >+ "hostname": "%C3%9F" >+ } >+ }, >+ { >+ "comment": "IDNA Nontransitional_Processing", >+ "href": "https://x/", >+ "new_value": "Ã", >+ "expected": { >+ "href": "https://xn--zca/", >+ "host": "xn--zca", >+ "hostname": "xn--zca" >+ } >+ }, >+ { >+ "comment": "Cannot-be-a-base means no host", >+ "href": "mailto:me@example.net", >+ "new_value": "example.com", >+ "expected": { >+ "href": "mailto:me@example.net", >+ "host": "" >+ } >+ }, >+ { >+ "comment": "Cannot-be-a-base means no password", >+ "href": "data:text/plain,Stuff", >+ "new_value": "example.net", >+ "expected": { >+ "href": "data:text/plain,Stuff", >+ "host": "" >+ } >+ }, >+ { >+ "href": "http://example.net", >+ "new_value": "example.com:8080", >+ "expected": { >+ "href": "http://example.com:8080/", >+ "host": "example.com:8080", >+ "hostname": "example.com", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "Port number is unchanged if not specified in the new value", >+ "href": "http://example.net:8080", >+ "new_value": "example.com", >+ "expected": { >+ "href": "http://example.com:8080/", >+ "host": "example.com:8080", >+ "hostname": "example.com", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "Port number is unchanged if not specified", >+ "href": "http://example.net:8080", >+ "new_value": "example.com:", >+ "expected": { >+ "href": "http://example.com:8080/", >+ "host": "example.com:8080", >+ "hostname": "example.com", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "The empty host is not valid for special schemes", >+ "href": "http://example.net", >+ "new_value": "", >+ "expected": { >+ "href": "http://example.net/", >+ "host": "example.net" >+ } >+ }, >+ { >+ "comment": "The empty host is OK for non-special schemes", >+ "href": "view-source+http://example.net/foo", >+ "new_value": "", >+ "expected": { >+ "href": "view-source+http:///foo", >+ "host": "" >+ } >+ }, >+ { >+ "comment": "Path-only URLs can gain a host", >+ "href": "a:/foo", >+ "new_value": "example.net", >+ "expected": { >+ "href": "a://example.net/foo", >+ "host": "example.net" >+ } >+ }, >+ { >+ "comment": "IPv4 address syntax is normalized", >+ "href": "http://example.net", >+ "new_value": "0x7F000001:8080", >+ "expected": { >+ "href": "http://127.0.0.1:8080/", >+ "host": "127.0.0.1:8080", >+ "hostname": "127.0.0.1", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "IPv6 address syntax is normalized", >+ "href": "http://example.net", >+ "new_value": "[::0:01]:2", >+ "expected": { >+ "href": "http://[::1]:2/", >+ "host": "[::1]:2", >+ "hostname": "[::1]", >+ "port": "2" >+ } >+ }, >+ { >+ "comment": "Default port number is removed", >+ "href": "http://example.net", >+ "new_value": "example.com:80", >+ "expected": { >+ "href": "http://example.com/", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "Default port number is removed", >+ "href": "https://example.net", >+ "new_value": "example.com:443", >+ "expected": { >+ "href": "https://example.com/", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "Default port number is only removed for the relevant scheme", >+ "href": "https://example.net", >+ "new_value": "example.com:80", >+ "expected": { >+ "href": "https://example.com:80/", >+ "host": "example.com:80", >+ "hostname": "example.com", >+ "port": "80" >+ } >+ }, >+ { >+ "comment": "Port number is removed if new port is scheme default and existing URL has a non-default port", >+ "href": "http://example.net:8080", >+ "new_value": "example.com:80", >+ "expected": { >+ "href": "http://example.com/", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "Stuff after a / delimiter is ignored", >+ "href": "http://example.net/path", >+ "new_value": "example.com/stuff", >+ "expected": { >+ "href": "http://example.com/path", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "Stuff after a / delimiter is ignored", >+ "href": "http://example.net/path", >+ "new_value": "example.com:8080/stuff", >+ "expected": { >+ "href": "http://example.com:8080/path", >+ "host": "example.com:8080", >+ "hostname": "example.com", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "Stuff after a ? delimiter is ignored", >+ "href": "http://example.net/path", >+ "new_value": "example.com?stuff", >+ "expected": { >+ "href": "http://example.com/path", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "Stuff after a ? delimiter is ignored", >+ "href": "http://example.net/path", >+ "new_value": "example.com:8080?stuff", >+ "expected": { >+ "href": "http://example.com:8080/path", >+ "host": "example.com:8080", >+ "hostname": "example.com", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "Stuff after a # delimiter is ignored", >+ "href": "http://example.net/path", >+ "new_value": "example.com#stuff", >+ "expected": { >+ "href": "http://example.com/path", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "Stuff after a # delimiter is ignored", >+ "href": "http://example.net/path", >+ "new_value": "example.com:8080#stuff", >+ "expected": { >+ "href": "http://example.com:8080/path", >+ "host": "example.com:8080", >+ "hostname": "example.com", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "Stuff after a \\ delimiter is ignored for special schemes", >+ "href": "http://example.net/path", >+ "new_value": "example.com\\stuff", >+ "expected": { >+ "href": "http://example.com/path", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "Stuff after a \\ delimiter is ignored for special schemes", >+ "href": "http://example.net/path", >+ "new_value": "example.com:8080\\stuff", >+ "expected": { >+ "href": "http://example.com:8080/path", >+ "host": "example.com:8080", >+ "hostname": "example.com", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "\\ is not a delimiter for non-special schemes, but still forbidden in hosts", >+ "href": "view-source+http://example.net/path", >+ "new_value": "example.com\\stuff", >+ "expected": { >+ "href": "view-source+http://example.net/path", >+ "host": "example.net", >+ "hostname": "example.net", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", >+ "href": "view-source+http://example.net/path", >+ "new_value": "example.com:8080stuff2", >+ "expected": { >+ "href": "view-source+http://example.com:8080/path", >+ "host": "example.com:8080", >+ "hostname": "example.com", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", >+ "href": "http://example.net/path", >+ "new_value": "example.com:8080stuff2", >+ "expected": { >+ "href": "http://example.com:8080/path", >+ "host": "example.com:8080", >+ "hostname": "example.com", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", >+ "href": "http://example.net/path", >+ "new_value": "example.com:8080+2", >+ "expected": { >+ "href": "http://example.com:8080/path", >+ "host": "example.com:8080", >+ "hostname": "example.com", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "Port numbers are 16 bit integers", >+ "href": "http://example.net/path", >+ "new_value": "example.com:65535", >+ "expected": { >+ "href": "http://example.com:65535/path", >+ "host": "example.com:65535", >+ "hostname": "example.com", >+ "port": "65535" >+ } >+ }, >+ { >+ "comment": "Port numbers are 16 bit integers, overflowing is an error. Hostname is still set, though.", >+ "href": "http://example.net/path", >+ "new_value": "example.com:65536", >+ "expected": { >+ "href": "http://example.com/path", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "Broken IPv6", >+ "href": "http://example.net/", >+ "new_value": "[google.com]", >+ "expected": { >+ "href": "http://example.net/", >+ "host": "example.net", >+ "hostname": "example.net" >+ } >+ }, >+ { >+ "href": "http://example.net/", >+ "new_value": "[::1.2.3.4x]", >+ "expected": { >+ "href": "http://example.net/", >+ "host": "example.net", >+ "hostname": "example.net" >+ } >+ }, >+ { >+ "href": "http://example.net/", >+ "new_value": "[::1.2.3.]", >+ "expected": { >+ "href": "http://example.net/", >+ "host": "example.net", >+ "hostname": "example.net" >+ } >+ }, >+ { >+ "href": "http://example.net/", >+ "new_value": "[::1.2.]", >+ "expected": { >+ "href": "http://example.net/", >+ "host": "example.net", >+ "hostname": "example.net" >+ } >+ }, >+ { >+ "href": "http://example.net/", >+ "new_value": "[::1.]", >+ "expected": { >+ "href": "http://example.net/", >+ "host": "example.net", >+ "hostname": "example.net" >+ } >+ }, >+ { >+ "href": "file://y/", >+ "new_value": "x:123", >+ "expected": { >+ "href": "file://y/", >+ "host": "y", >+ "hostname": "y", >+ "port": "" >+ } >+ }, >+ { >+ "href": "file://y/", >+ "new_value": "loc%41lhost", >+ "expected": { >+ "href": "file:///", >+ "host": "", >+ "hostname": "", >+ "port": "" >+ } >+ }, >+ { >+ "href": "file://hi/x", >+ "new_value": "", >+ "expected": { >+ "href": "file:///x", >+ "host": "", >+ "hostname": "", >+ "port": "" >+ } >+ }, >+ { >+ "href": "sc://test@test/", >+ "new_value": "", >+ "expected": { >+ "href": "sc://test@test/", >+ "host": "test", >+ "hostname": "test", >+ "username": "test" >+ } >+ }, >+ { >+ "href": "sc://test:12/", >+ "new_value": "", >+ "expected": { >+ "href": "sc://test:12/", >+ "host": "test:12", >+ "hostname": "test", >+ "port": "12" >+ } >+ } >+ ], >+ "hostname": [ >+ { >+ "comment": "Non-special scheme", >+ "href": "sc://x/", >+ "new_value": "\u0000", >+ "expected": { >+ "href": "sc://x/", >+ "host": "x", >+ "hostname": "x" >+ } >+ }, >+ { >+ "href": "sc://x/", >+ "new_value": "\u0009", >+ "expected": { >+ "href": "sc:///", >+ "host": "", >+ "hostname": "" >+ } >+ }, >+ { >+ "href": "sc://x/", >+ "new_value": "\u000A", >+ "expected": { >+ "href": "sc:///", >+ "host": "", >+ "hostname": "" >+ } >+ }, >+ { >+ "href": "sc://x/", >+ "new_value": "\u000D", >+ "expected": { >+ "href": "sc:///", >+ "host": "", >+ "hostname": "" >+ } >+ }, >+ { >+ "href": "sc://x/", >+ "new_value": " ", >+ "expected": { >+ "href": "sc://x/", >+ "host": "x", >+ "hostname": "x" >+ } >+ }, >+ { >+ "href": "sc://x/", >+ "new_value": "#", >+ "expected": { >+ "href": "sc:///", >+ "host": "", >+ "hostname": "" >+ } >+ }, >+ { >+ "href": "sc://x/", >+ "new_value": "/", >+ "expected": { >+ "href": "sc:///", >+ "host": "", >+ "hostname": "" >+ } >+ }, >+ { >+ "href": "sc://x/", >+ "new_value": "?", >+ "expected": { >+ "href": "sc:///", >+ "host": "", >+ "hostname": "" >+ } >+ }, >+ { >+ "href": "sc://x/", >+ "new_value": "@", >+ "expected": { >+ "href": "sc://x/", >+ "host": "x", >+ "hostname": "x" >+ } >+ }, >+ { >+ "comment": "Cannot-be-a-base means no host", >+ "href": "mailto:me@example.net", >+ "new_value": "example.com", >+ "expected": { >+ "href": "mailto:me@example.net", >+ "host": "" >+ } >+ }, >+ { >+ "comment": "Cannot-be-a-base means no password", >+ "href": "data:text/plain,Stuff", >+ "new_value": "example.net", >+ "expected": { >+ "href": "data:text/plain,Stuff", >+ "host": "" >+ } >+ }, >+ { >+ "href": "http://example.net:8080", >+ "new_value": "example.com", >+ "expected": { >+ "href": "http://example.com:8080/", >+ "host": "example.com:8080", >+ "hostname": "example.com", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "The empty host is not valid for special schemes", >+ "href": "http://example.net", >+ "new_value": "", >+ "expected": { >+ "href": "http://example.net/", >+ "host": "example.net" >+ } >+ }, >+ { >+ "comment": "The empty host is OK for non-special schemes", >+ "href": "view-source+http://example.net/foo", >+ "new_value": "", >+ "expected": { >+ "href": "view-source+http:///foo", >+ "host": "" >+ } >+ }, >+ { >+ "comment": "Path-only URLs can gain a host", >+ "href": "a:/foo", >+ "new_value": "example.net", >+ "expected": { >+ "href": "a://example.net/foo", >+ "host": "example.net" >+ } >+ }, >+ { >+ "comment": "IPv4 address syntax is normalized", >+ "href": "http://example.net:8080", >+ "new_value": "0x7F000001", >+ "expected": { >+ "href": "http://127.0.0.1:8080/", >+ "host": "127.0.0.1:8080", >+ "hostname": "127.0.0.1", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "IPv6 address syntax is normalized", >+ "href": "http://example.net", >+ "new_value": "[::0:01]", >+ "expected": { >+ "href": "http://[::1]/", >+ "host": "[::1]", >+ "hostname": "[::1]", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "Stuff after a : delimiter is ignored", >+ "href": "http://example.net/path", >+ "new_value": "example.com:8080", >+ "expected": { >+ "href": "http://example.com/path", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "Stuff after a : delimiter is ignored", >+ "href": "http://example.net:8080/path", >+ "new_value": "example.com:", >+ "expected": { >+ "href": "http://example.com:8080/path", >+ "host": "example.com:8080", >+ "hostname": "example.com", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "Stuff after a / delimiter is ignored", >+ "href": "http://example.net/path", >+ "new_value": "example.com/stuff", >+ "expected": { >+ "href": "http://example.com/path", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "Stuff after a ? delimiter is ignored", >+ "href": "http://example.net/path", >+ "new_value": "example.com?stuff", >+ "expected": { >+ "href": "http://example.com/path", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "Stuff after a # delimiter is ignored", >+ "href": "http://example.net/path", >+ "new_value": "example.com#stuff", >+ "expected": { >+ "href": "http://example.com/path", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "Stuff after a \\ delimiter is ignored for special schemes", >+ "href": "http://example.net/path", >+ "new_value": "example.com\\stuff", >+ "expected": { >+ "href": "http://example.com/path", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "\\ is not a delimiter for non-special schemes, but still forbidden in hosts", >+ "href": "view-source+http://example.net/path", >+ "new_value": "example.com\\stuff", >+ "expected": { >+ "href": "view-source+http://example.net/path", >+ "host": "example.net", >+ "hostname": "example.net", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "Broken IPv6", >+ "href": "http://example.net/", >+ "new_value": "[google.com]", >+ "expected": { >+ "href": "http://example.net/", >+ "host": "example.net", >+ "hostname": "example.net" >+ } >+ }, >+ { >+ "href": "http://example.net/", >+ "new_value": "[::1.2.3.4x]", >+ "expected": { >+ "href": "http://example.net/", >+ "host": "example.net", >+ "hostname": "example.net" >+ } >+ }, >+ { >+ "href": "http://example.net/", >+ "new_value": "[::1.2.3.]", >+ "expected": { >+ "href": "http://example.net/", >+ "host": "example.net", >+ "hostname": "example.net" >+ } >+ }, >+ { >+ "href": "http://example.net/", >+ "new_value": "[::1.2.]", >+ "expected": { >+ "href": "http://example.net/", >+ "host": "example.net", >+ "hostname": "example.net" >+ } >+ }, >+ { >+ "href": "http://example.net/", >+ "new_value": "[::1.]", >+ "expected": { >+ "href": "http://example.net/", >+ "host": "example.net", >+ "hostname": "example.net" >+ } >+ }, >+ { >+ "href": "file://y/", >+ "new_value": "x:123", >+ "expected": { >+ "href": "file://y/", >+ "host": "y", >+ "hostname": "y", >+ "port": "" >+ } >+ }, >+ { >+ "href": "file://y/", >+ "new_value": "loc%41lhost", >+ "expected": { >+ "href": "file:///", >+ "host": "", >+ "hostname": "", >+ "port": "" >+ } >+ }, >+ { >+ "href": "file://hi/x", >+ "new_value": "", >+ "expected": { >+ "href": "file:///x", >+ "host": "", >+ "hostname": "", >+ "port": "" >+ } >+ }, >+ { >+ "href": "sc://test@test/", >+ "new_value": "", >+ "expected": { >+ "href": "sc://test@test/", >+ "host": "test", >+ "hostname": "test", >+ "username": "test" >+ } >+ }, >+ { >+ "href": "sc://test:12/", >+ "new_value": "", >+ "expected": { >+ "href": "sc://test:12/", >+ "host": "test:12", >+ "hostname": "test", >+ "port": "12" >+ } >+ } >+ ], >+ "port": [ >+ { >+ "href": "http://example.net", >+ "new_value": "8080", >+ "expected": { >+ "href": "http://example.net:8080/", >+ "host": "example.net:8080", >+ "hostname": "example.net", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "Port number is removed if empty is the new value", >+ "href": "http://example.net:8080", >+ "new_value": "", >+ "expected": { >+ "href": "http://example.net/", >+ "host": "example.net", >+ "hostname": "example.net", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "Default port number is removed", >+ "href": "http://example.net:8080", >+ "new_value": "80", >+ "expected": { >+ "href": "http://example.net/", >+ "host": "example.net", >+ "hostname": "example.net", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "Default port number is removed", >+ "href": "https://example.net:4433", >+ "new_value": "443", >+ "expected": { >+ "href": "https://example.net/", >+ "host": "example.net", >+ "hostname": "example.net", >+ "port": "" >+ } >+ }, >+ { >+ "comment": "Default port number is only removed for the relevant scheme", >+ "href": "https://example.net", >+ "new_value": "80", >+ "expected": { >+ "href": "https://example.net:80/", >+ "host": "example.net:80", >+ "hostname": "example.net", >+ "port": "80" >+ } >+ }, >+ { >+ "comment": "Stuff after a / delimiter is ignored", >+ "href": "http://example.net/path", >+ "new_value": "8080/stuff", >+ "expected": { >+ "href": "http://example.net:8080/path", >+ "host": "example.net:8080", >+ "hostname": "example.net", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "Stuff after a ? delimiter is ignored", >+ "href": "http://example.net/path", >+ "new_value": "8080?stuff", >+ "expected": { >+ "href": "http://example.net:8080/path", >+ "host": "example.net:8080", >+ "hostname": "example.net", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "Stuff after a # delimiter is ignored", >+ "href": "http://example.net/path", >+ "new_value": "8080#stuff", >+ "expected": { >+ "href": "http://example.net:8080/path", >+ "host": "example.net:8080", >+ "hostname": "example.net", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "Stuff after a \\ delimiter is ignored for special schemes", >+ "href": "http://example.net/path", >+ "new_value": "8080\\stuff", >+ "expected": { >+ "href": "http://example.net:8080/path", >+ "host": "example.net:8080", >+ "hostname": "example.net", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", >+ "href": "view-source+http://example.net/path", >+ "new_value": "8080stuff2", >+ "expected": { >+ "href": "view-source+http://example.net:8080/path", >+ "host": "example.net:8080", >+ "hostname": "example.net", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", >+ "href": "http://example.net/path", >+ "new_value": "8080stuff2", >+ "expected": { >+ "href": "http://example.net:8080/path", >+ "host": "example.net:8080", >+ "hostname": "example.net", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", >+ "href": "http://example.net/path", >+ "new_value": "8080+2", >+ "expected": { >+ "href": "http://example.net:8080/path", >+ "host": "example.net:8080", >+ "hostname": "example.net", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "Port numbers are 16 bit integers", >+ "href": "http://example.net/path", >+ "new_value": "65535", >+ "expected": { >+ "href": "http://example.net:65535/path", >+ "host": "example.net:65535", >+ "hostname": "example.net", >+ "port": "65535" >+ } >+ }, >+ { >+ "comment": "Port numbers are 16 bit integers, overflowing is an error", >+ "href": "http://example.net:8080/path", >+ "new_value": "65536", >+ "expected": { >+ "href": "http://example.net:8080/path", >+ "host": "example.net:8080", >+ "hostname": "example.net", >+ "port": "8080" >+ } >+ }, >+ { >+ "comment": "Port numbers are 16 bit integers, overflowing is an error", >+ "href": "non-special://example.net:8080/path", >+ "new_value": "65536", >+ "expected": { >+ "href": "non-special://example.net:8080/path", >+ "host": "example.net:8080", >+ "hostname": "example.net", >+ "port": "8080" >+ } >+ }, >+ { >+ "href": "file://test/", >+ "new_value": "12", >+ "expected": { >+ "href": "file://test/", >+ "port": "" >+ } >+ }, >+ { >+ "href": "file://localhost/", >+ "new_value": "12", >+ "expected": { >+ "href": "file:///", >+ "port": "" >+ } >+ }, >+ { >+ "href": "non-base:value", >+ "new_value": "12", >+ "expected": { >+ "href": "non-base:value", >+ "port": "" >+ } >+ }, >+ { >+ "href": "sc:///", >+ "new_value": "12", >+ "expected": { >+ "href": "sc:///", >+ "port": "" >+ } >+ }, >+ { >+ "href": "sc://x/", >+ "new_value": "12", >+ "expected": { >+ "href": "sc://x:12/", >+ "port": "12" >+ } >+ }, >+ { >+ "href": "javascript://x/", >+ "new_value": "12", >+ "expected": { >+ "href": "javascript://x:12/", >+ "port": "12" >+ } >+ } >+ ], >+ "pathname": [ >+ { >+ "comment": "Cannot-be-a-base donât have a path", >+ "href": "mailto:me@example.net", >+ "new_value": "/foo", >+ "expected": { >+ "href": "mailto:me@example.net", >+ "pathname": "me@example.net" >+ } >+ }, >+ { >+ "href": "unix:/run/foo.socket?timeout=10", >+ "new_value": "/var/log/../run/bar.socket", >+ "expected": { >+ "href": "unix:/var/run/bar.socket?timeout=10", >+ "pathname": "/var/run/bar.socket" >+ } >+ }, >+ { >+ "href": "https://example.net#nav", >+ "new_value": "home", >+ "expected": { >+ "href": "https://example.net/home#nav", >+ "pathname": "/home" >+ } >+ }, >+ { >+ "href": "https://example.net#nav", >+ "new_value": "../home", >+ "expected": { >+ "href": "https://example.net/home#nav", >+ "pathname": "/home" >+ } >+ }, >+ { >+ "comment": "\\ is a segment delimiter for 'special' URLs", >+ "href": "http://example.net/home?lang=fr#nav", >+ "new_value": "\\a\\%2E\\b\\%2e.\\c", >+ "expected": { >+ "href": "http://example.net/a/c?lang=fr#nav", >+ "pathname": "/a/c" >+ } >+ }, >+ { >+ "comment": "\\ is *not* a segment delimiter for non-'special' URLs", >+ "href": "view-source+http://example.net/home?lang=fr#nav", >+ "new_value": "\\a\\%2E\\b\\%2e.\\c", >+ "expected": { >+ "href": "view-source+http://example.net/\\a\\%2E\\b\\%2e.\\c?lang=fr#nav", >+ "pathname": "/\\a\\%2E\\b\\%2e.\\c" >+ } >+ }, >+ { >+ "comment": "UTF-8 percent encoding with the default encode set. Tabs and newlines are removed.", >+ "href": "a:/", >+ "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Ãé", >+ "expected": { >+ "href": "a:/%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E%3F@AZ[\\]^_%60az%7B|%7D~%7F%C2%80%C2%81%C3%89%C3%A9", >+ "pathname": "/%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E%3F@AZ[\\]^_%60az%7B|%7D~%7F%C2%80%C2%81%C3%89%C3%A9" >+ } >+ }, >+ { >+ "comment": "Bytes already percent-encoded are left as-is, including %2E outside dotted segments.", >+ "href": "http://example.net", >+ "new_value": "%2e%2E%c3%89té", >+ "expected": { >+ "href": "http://example.net/%2e%2E%c3%89t%C3%A9", >+ "pathname": "/%2e%2E%c3%89t%C3%A9" >+ } >+ }, >+ { >+ "comment": "? needs to be encoded", >+ "href": "http://example.net", >+ "new_value": "?", >+ "expected": { >+ "href": "http://example.net/%3F", >+ "pathname": "/%3F" >+ } >+ }, >+ { >+ "comment": "# needs to be encoded", >+ "href": "http://example.net", >+ "new_value": "#", >+ "expected": { >+ "href": "http://example.net/%23", >+ "pathname": "/%23" >+ } >+ }, >+ { >+ "comment": "? needs to be encoded, non-special scheme", >+ "href": "sc://example.net", >+ "new_value": "?", >+ "expected": { >+ "href": "sc://example.net/%3F", >+ "pathname": "/%3F" >+ } >+ }, >+ { >+ "comment": "# needs to be encoded, non-special scheme", >+ "href": "sc://example.net", >+ "new_value": "#", >+ "expected": { >+ "href": "sc://example.net/%23", >+ "pathname": "/%23" >+ } >+ }, >+ { >+ "comment": "File URLs and (back)slashes", >+ "href": "file://monkey/", >+ "new_value": "\\\\", >+ "expected": { >+ "href": "file://monkey/", >+ "pathname": "/" >+ } >+ }, >+ { >+ "comment": "File URLs and (back)slashes", >+ "href": "file:///unicorn", >+ "new_value": "//\\/", >+ "expected": { >+ "href": "file:///", >+ "pathname": "/" >+ } >+ }, >+ { >+ "comment": "File URLs and (back)slashes", >+ "href": "file:///unicorn", >+ "new_value": "//monkey/..//", >+ "expected": { >+ "href": "file:///", >+ "pathname": "/" >+ } >+ } >+ ], >+ "search": [ >+ { >+ "href": "https://example.net#nav", >+ "new_value": "lang=fr", >+ "expected": { >+ "href": "https://example.net/?lang=fr#nav", >+ "search": "?lang=fr" >+ } >+ }, >+ { >+ "href": "https://example.net?lang=en-US#nav", >+ "new_value": "lang=fr", >+ "expected": { >+ "href": "https://example.net/?lang=fr#nav", >+ "search": "?lang=fr" >+ } >+ }, >+ { >+ "href": "https://example.net?lang=en-US#nav", >+ "new_value": "?lang=fr", >+ "expected": { >+ "href": "https://example.net/?lang=fr#nav", >+ "search": "?lang=fr" >+ } >+ }, >+ { >+ "href": "https://example.net?lang=en-US#nav", >+ "new_value": "??lang=fr", >+ "expected": { >+ "href": "https://example.net/??lang=fr#nav", >+ "search": "??lang=fr" >+ } >+ }, >+ { >+ "href": "https://example.net?lang=en-US#nav", >+ "new_value": "?", >+ "expected": { >+ "href": "https://example.net/?#nav", >+ "search": "" >+ } >+ }, >+ { >+ "href": "https://example.net?lang=en-US#nav", >+ "new_value": "", >+ "expected": { >+ "href": "https://example.net/#nav", >+ "search": "" >+ } >+ }, >+ { >+ "href": "https://example.net?lang=en-US", >+ "new_value": "", >+ "expected": { >+ "href": "https://example.net/", >+ "search": "" >+ } >+ }, >+ { >+ "href": "https://example.net", >+ "new_value": "", >+ "expected": { >+ "href": "https://example.net/", >+ "search": "" >+ } >+ }, >+ { >+ "comment": "UTF-8 percent encoding with the query encode set. Tabs and newlines are removed.", >+ "href": "a:/", >+ "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Ãé", >+ "expected": { >+ "href": "a:/?%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_`az{|}~%7F%C2%80%C2%81%C3%89%C3%A9", >+ "search": "?%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_`az{|}~%7F%C2%80%C2%81%C3%89%C3%A9" >+ } >+ }, >+ { >+ "comment": "Bytes already percent-encoded are left as-is", >+ "href": "http://example.net", >+ "new_value": "%c3%89té", >+ "expected": { >+ "href": "http://example.net/?%c3%89t%C3%A9", >+ "search": "?%c3%89t%C3%A9" >+ } >+ } >+ ], >+ "hash": [ >+ { >+ "href": "https://example.net", >+ "new_value": "main", >+ "expected": { >+ "href": "https://example.net/#main", >+ "hash": "#main" >+ } >+ }, >+ { >+ "href": "https://example.net#nav", >+ "new_value": "main", >+ "expected": { >+ "href": "https://example.net/#main", >+ "hash": "#main" >+ } >+ }, >+ { >+ "href": "https://example.net?lang=en-US", >+ "new_value": "##nav", >+ "expected": { >+ "href": "https://example.net/?lang=en-US##nav", >+ "hash": "##nav" >+ } >+ }, >+ { >+ "href": "https://example.net?lang=en-US#nav", >+ "new_value": "#main", >+ "expected": { >+ "href": "https://example.net/?lang=en-US#main", >+ "hash": "#main" >+ } >+ }, >+ { >+ "href": "https://example.net?lang=en-US#nav", >+ "new_value": "#", >+ "expected": { >+ "href": "https://example.net/?lang=en-US#", >+ "hash": "" >+ } >+ }, >+ { >+ "href": "https://example.net?lang=en-US#nav", >+ "new_value": "", >+ "expected": { >+ "href": "https://example.net/?lang=en-US", >+ "hash": "" >+ } >+ }, >+ { >+ "href": "http://example.net", >+ "new_value": "#foo bar", >+ "expected": { >+ "href": "http://example.net/#foo%20bar", >+ "hash": "#foo%20bar" >+ } >+ }, >+ { >+ "href": "http://example.net", >+ "new_value": "#foo\"bar", >+ "expected": { >+ "href": "http://example.net/#foo%22bar", >+ "hash": "#foo%22bar" >+ } >+ }, >+ { >+ "href": "http://example.net", >+ "new_value": "#foo<bar", >+ "expected": { >+ "href": "http://example.net/#foo%3Cbar", >+ "hash": "#foo%3Cbar" >+ } >+ }, >+ { >+ "href": "http://example.net", >+ "new_value": "#foo>bar", >+ "expected": { >+ "href": "http://example.net/#foo%3Ebar", >+ "hash": "#foo%3Ebar" >+ } >+ }, >+ { >+ "href": "http://example.net", >+ "new_value": "#foo`bar", >+ "expected": { >+ "href": "http://example.net/#foo%60bar", >+ "hash": "#foo%60bar" >+ } >+ }, >+ { >+ "comment": "Simple percent-encoding; nuls, tabs, and newlines are removed", >+ "href": "a:/", >+ "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Ãé", >+ "expected": { >+ "href": "a:/#%01%1F%20!%22#$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_%60az{|}~%7F%C2%80%C2%81%C3%89%C3%A9", >+ "hash": "#%01%1F%20!%22#$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_%60az{|}~%7F%C2%80%C2%81%C3%89%C3%A9" >+ } >+ }, >+ { >+ "comment": "Bytes already percent-encoded are left as-is", >+ "href": "http://example.net", >+ "new_value": "%c3%89té", >+ "expected": { >+ "href": "http://example.net/#%c3%89t%C3%A9", >+ "hash": "#%c3%89t%C3%A9" >+ } >+ }, >+ { >+ "href": "javascript:alert(1)", >+ "new_value": "castle", >+ "expected": { >+ "href": "javascript:alert(1)#castle", >+ "hash": "#castle" >+ } >+ } >+ ] >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/resources/toascii.json b/LayoutTests/imported/w3c/web-platform-tests/url/resources/toascii.json >new file mode 100644 >index 0000000000000000000000000000000000000000..814f06e794866d4d2a817418ad368bf4f5ff446a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/resources/toascii.json >@@ -0,0 +1,149 @@ >+[ >+ "This resource is focused on highlighting issues with UTS #46 ToASCII", >+ { >+ "comment": "Label with hyphens in 3rd and 4th position", >+ "input": "aa--", >+ "output": "aa--" >+ }, >+ { >+ "input": "aâ --", >+ "output": "xn--a---kp0a" >+ }, >+ { >+ "input": "ab--c", >+ "output": "ab--c" >+ }, >+ { >+ "comment": "Label with leading hyphen", >+ "input": "-x", >+ "output": "-x" >+ }, >+ { >+ "input": "-â ", >+ "output": "xn----xhn" >+ }, >+ { >+ "input": "-x.xn--nxa", >+ "output": "-x.xn--nxa" >+ }, >+ { >+ "input": "-x.β", >+ "output": "-x.xn--nxa" >+ }, >+ { >+ "comment": "Label with trailing hyphen", >+ "input": "x-.xn--nxa", >+ "output": "x-.xn--nxa" >+ }, >+ { >+ "input": "x-.β", >+ "output": "x-.xn--nxa" >+ }, >+ { >+ "comment": "Empty labels", >+ "input": "x..xn--nxa", >+ "output": "x..xn--nxa" >+ }, >+ { >+ "input": "x..β", >+ "output": "x..xn--nxa" >+ }, >+ { >+ "comment": "Invalid Punycode", >+ "input": "xn--a", >+ "output": null >+ }, >+ { >+ "input": "xn--a.xn--nxa", >+ "output": null >+ }, >+ { >+ "input": "xn--a.β", >+ "output": null >+ }, >+ { >+ "comment": "Valid Punycode", >+ "input": "xn--nxa.xn--nxa", >+ "output": "xn--nxa.xn--nxa" >+ }, >+ { >+ "comment": "Mixed", >+ "input": "xn--nxa.β", >+ "output": "xn--nxa.xn--nxa" >+ }, >+ { >+ "input": "ab--c.xn--nxa", >+ "output": "ab--c.xn--nxa" >+ }, >+ { >+ "input": "ab--c.β", >+ "output": "ab--c.xn--nxa" >+ }, >+ { >+ "comment": "CheckJoiners is true", >+ "input": "\u200D.example", >+ "output": null >+ }, >+ { >+ "input": "xn--1ug.example", >+ "output": null >+ }, >+ { >+ "comment": "CheckBidi is true", >+ "input": "Ùa", >+ "output": null >+ }, >+ { >+ "input": "xn--a-yoc", >+ "output": null >+ }, >+ { >+ "comment": "processing_option is Nontransitional_Processing", >+ "input": "à·à·âà¶»à·", >+ "output": "xn--10cl1a0b660p" >+ }, >+ { >+ "input": "ÙØ§Ù ÙâØ§Û", >+ "output": "xn--mgba3gch31f060k" >+ }, >+ { >+ "comment": "U+FFFD", >+ "input": "\uFFFD.com", >+ "output": null >+ }, >+ { >+ "comment": "U+FFFD character encoded in Punycode", >+ "input": "xn--zn7c.com", >+ "output": null >+ }, >+ { >+ "comment": "Label longer than 63 code points", >+ "input": "x01234567890123456789012345678901234567890123456789012345678901x", >+ "output": "x01234567890123456789012345678901234567890123456789012345678901x" >+ }, >+ { >+ "input": "x01234567890123456789012345678901234567890123456789012345678901â ", >+ "output": "xn--x01234567890123456789012345678901234567890123456789012345678901-6963b" >+ }, >+ { >+ "input": "x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa", >+ "output": "x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa" >+ }, >+ { >+ "input": "x01234567890123456789012345678901234567890123456789012345678901x.β", >+ "output": "x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa" >+ }, >+ { >+ "comment": "Domain excluding TLD longer than 253 code points", >+ "input": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.x", >+ "output": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.x" >+ }, >+ { >+ "input": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa", >+ "output": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa" >+ }, >+ { >+ "input": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β", >+ "output": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa" >+ } >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/resources/urltestdata.json b/LayoutTests/imported/w3c/web-platform-tests/url/resources/urltestdata.json >new file mode 100644 >index 0000000000000000000000000000000000000000..8c87da2bf5dfee4f204574c2d421d7c6de787522 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/resources/urltestdata.json >@@ -0,0 +1,6623 @@ >+[ >+ "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/script-tests/segments.js", >+ { >+ "input": "http://example\t.\norg", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://user:pass@foo:21/bar;par?b#c", >+ "base": "http://example.org/foo/bar", >+ "href": "http://user:pass@foo:21/bar;par?b#c", >+ "origin": "http://foo:21", >+ "protocol": "http:", >+ "username": "user", >+ "password": "pass", >+ "host": "foo:21", >+ "hostname": "foo", >+ "port": "21", >+ "pathname": "/bar;par", >+ "search": "?b", >+ "hash": "#c" >+ }, >+ { >+ "input": "https://test:@test", >+ "base": "about:blank", >+ "href": "https://test@test/", >+ "origin": "https://test", >+ "protocol": "https:", >+ "username": "test", >+ "password": "", >+ "host": "test", >+ "hostname": "test", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "https://:@test", >+ "base": "about:blank", >+ "href": "https://test/", >+ "origin": "https://test", >+ "protocol": "https:", >+ "username": "", >+ "password": "", >+ "host": "test", >+ "hostname": "test", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "non-special://test:@test/x", >+ "base": "about:blank", >+ "href": "non-special://test@test/x", >+ "origin": "null", >+ "protocol": "non-special:", >+ "username": "test", >+ "password": "", >+ "host": "test", >+ "hostname": "test", >+ "port": "", >+ "pathname": "/x", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "non-special://:@test/x", >+ "base": "about:blank", >+ "href": "non-special://test/x", >+ "origin": "null", >+ "protocol": "non-special:", >+ "username": "", >+ "password": "", >+ "host": "test", >+ "hostname": "test", >+ "port": "", >+ "pathname": "/x", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http:foo.com", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/foo.com", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/foo.com", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "\t :foo.com \n", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/:foo.com", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/:foo.com", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": " foo.com ", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/foo.com", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/foo.com", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "a:\t foo.com", >+ "base": "http://example.org/foo/bar", >+ "href": "a: foo.com", >+ "origin": "null", >+ "protocol": "a:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": " foo.com", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://f:21/ b ? d # e ", >+ "base": "http://example.org/foo/bar", >+ "href": "http://f:21/%20b%20?%20d%20#%20e", >+ "origin": "http://f:21", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "f:21", >+ "hostname": "f", >+ "port": "21", >+ "pathname": "/%20b%20", >+ "search": "?%20d%20", >+ "hash": "#%20e" >+ }, >+ { >+ "input": "lolscheme:x x#x x", >+ "base": "about:blank", >+ "href": "lolscheme:x x#x%20x", >+ "protocol": "lolscheme:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "x x", >+ "search": "", >+ "hash": "#x%20x" >+ }, >+ { >+ "input": "http://f:/c", >+ "base": "http://example.org/foo/bar", >+ "href": "http://f/c", >+ "origin": "http://f", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "f", >+ "hostname": "f", >+ "port": "", >+ "pathname": "/c", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://f:0/c", >+ "base": "http://example.org/foo/bar", >+ "href": "http://f:0/c", >+ "origin": "http://f:0", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "f:0", >+ "hostname": "f", >+ "port": "0", >+ "pathname": "/c", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://f:00000000000000/c", >+ "base": "http://example.org/foo/bar", >+ "href": "http://f:0/c", >+ "origin": "http://f:0", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "f:0", >+ "hostname": "f", >+ "port": "0", >+ "pathname": "/c", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://f:00000000000000000000080/c", >+ "base": "http://example.org/foo/bar", >+ "href": "http://f/c", >+ "origin": "http://f", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "f", >+ "hostname": "f", >+ "port": "", >+ "pathname": "/c", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://f:b/c", >+ "base": "http://example.org/foo/bar", >+ "failure": true >+ }, >+ { >+ "input": "http://f: /c", >+ "base": "http://example.org/foo/bar", >+ "failure": true >+ }, >+ { >+ "input": "http://f:\n/c", >+ "base": "http://example.org/foo/bar", >+ "href": "http://f/c", >+ "origin": "http://f", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "f", >+ "hostname": "f", >+ "port": "", >+ "pathname": "/c", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://f:fifty-two/c", >+ "base": "http://example.org/foo/bar", >+ "failure": true >+ }, >+ { >+ "input": "http://f:999999/c", >+ "base": "http://example.org/foo/bar", >+ "failure": true >+ }, >+ { >+ "input": "non-special://f:999999/c", >+ "base": "http://example.org/foo/bar", >+ "failure": true >+ }, >+ { >+ "input": "http://f: 21 / b ? d # e ", >+ "base": "http://example.org/foo/bar", >+ "failure": true >+ }, >+ { >+ "input": "", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/bar", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/bar", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": " \t", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/bar", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/bar", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": ":foo.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/:foo.com/", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/:foo.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": ":foo.com\\", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/:foo.com/", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/:foo.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": ":", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/:", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/:", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": ":a", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/:a", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/:a", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": ":/", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/:/", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/:/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": ":\\", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/:/", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/:/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": ":#", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/:#", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/:", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "#", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/bar#", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/bar", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "#/", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/bar#/", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/bar", >+ "search": "", >+ "hash": "#/" >+ }, >+ { >+ "input": "#\\", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/bar#\\", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/bar", >+ "search": "", >+ "hash": "#\\" >+ }, >+ { >+ "input": "#;?", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/bar#;?", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/bar", >+ "search": "", >+ "hash": "#;?" >+ }, >+ { >+ "input": "?", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/bar?", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/bar", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "/", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": ":23", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/:23", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/:23", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "/:23", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/:23", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/:23", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "::", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/::", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/::", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "::23", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/::23", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/::23", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "foo://", >+ "base": "http://example.org/foo/bar", >+ "href": "foo://", >+ "origin": "null", >+ "protocol": "foo:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://a:b@c:29/d", >+ "base": "http://example.org/foo/bar", >+ "href": "http://a:b@c:29/d", >+ "origin": "http://c:29", >+ "protocol": "http:", >+ "username": "a", >+ "password": "b", >+ "host": "c:29", >+ "hostname": "c", >+ "port": "29", >+ "pathname": "/d", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http::@c:29", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/:@c:29", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/:@c:29", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://&a:foo(b]c@d:2/", >+ "base": "http://example.org/foo/bar", >+ "href": "http://&a:foo(b%5Dc@d:2/", >+ "origin": "http://d:2", >+ "protocol": "http:", >+ "username": "&a", >+ "password": "foo(b%5Dc", >+ "host": "d:2", >+ "hostname": "d", >+ "port": "2", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://::@c@d:2", >+ "base": "http://example.org/foo/bar", >+ "href": "http://:%3A%40c@d:2/", >+ "origin": "http://d:2", >+ "protocol": "http:", >+ "username": "", >+ "password": "%3A%40c", >+ "host": "d:2", >+ "hostname": "d", >+ "port": "2", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://foo.com:b@d/", >+ "base": "http://example.org/foo/bar", >+ "href": "http://foo.com:b@d/", >+ "origin": "http://d", >+ "protocol": "http:", >+ "username": "foo.com", >+ "password": "b", >+ "host": "d", >+ "hostname": "d", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://foo.com/\\@", >+ "base": "http://example.org/foo/bar", >+ "href": "http://foo.com//@", >+ "origin": "http://foo.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "foo.com", >+ "hostname": "foo.com", >+ "port": "", >+ "pathname": "//@", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http:\\\\foo.com\\", >+ "base": "http://example.org/foo/bar", >+ "href": "http://foo.com/", >+ "origin": "http://foo.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "foo.com", >+ "hostname": "foo.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http:\\\\a\\b:c\\d@foo.com\\", >+ "base": "http://example.org/foo/bar", >+ "href": "http://a/b:c/d@foo.com/", >+ "origin": "http://a", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "a", >+ "hostname": "a", >+ "port": "", >+ "pathname": "/b:c/d@foo.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "foo:/", >+ "base": "http://example.org/foo/bar", >+ "href": "foo:/", >+ "origin": "null", >+ "protocol": "foo:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "foo:/bar.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "foo:/bar.com/", >+ "origin": "null", >+ "protocol": "foo:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/bar.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "foo://///////", >+ "base": "http://example.org/foo/bar", >+ "href": "foo://///////", >+ "origin": "null", >+ "protocol": "foo:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "///////", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "foo://///////bar.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "foo://///////bar.com/", >+ "origin": "null", >+ "protocol": "foo:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "///////bar.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "foo:////://///", >+ "base": "http://example.org/foo/bar", >+ "href": "foo:////://///", >+ "origin": "null", >+ "protocol": "foo:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "//://///", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "c:/foo", >+ "base": "http://example.org/foo/bar", >+ "href": "c:/foo", >+ "origin": "null", >+ "protocol": "c:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/foo", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "//foo/bar", >+ "base": "http://example.org/foo/bar", >+ "href": "http://foo/bar", >+ "origin": "http://foo", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "foo", >+ "hostname": "foo", >+ "port": "", >+ "pathname": "/bar", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://foo/path;a??e#f#g", >+ "base": "http://example.org/foo/bar", >+ "href": "http://foo/path;a??e#f#g", >+ "origin": "http://foo", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "foo", >+ "hostname": "foo", >+ "port": "", >+ "pathname": "/path;a", >+ "search": "??e", >+ "hash": "#f#g" >+ }, >+ { >+ "input": "http://foo/abcd?efgh?ijkl", >+ "base": "http://example.org/foo/bar", >+ "href": "http://foo/abcd?efgh?ijkl", >+ "origin": "http://foo", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "foo", >+ "hostname": "foo", >+ "port": "", >+ "pathname": "/abcd", >+ "search": "?efgh?ijkl", >+ "hash": "" >+ }, >+ { >+ "input": "http://foo/abcd#foo?bar", >+ "base": "http://example.org/foo/bar", >+ "href": "http://foo/abcd#foo?bar", >+ "origin": "http://foo", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "foo", >+ "hostname": "foo", >+ "port": "", >+ "pathname": "/abcd", >+ "search": "", >+ "hash": "#foo?bar" >+ }, >+ { >+ "input": "[61:24:74]:98", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/[61:24:74]:98", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/[61:24:74]:98", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http:[61:27]/:foo", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/[61:27]/:foo", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/[61:27]/:foo", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://[1::2]:3:4", >+ "base": "http://example.org/foo/bar", >+ "failure": true >+ }, >+ { >+ "input": "http://2001::1", >+ "base": "http://example.org/foo/bar", >+ "failure": true >+ }, >+ { >+ "input": "http://2001::1]", >+ "base": "http://example.org/foo/bar", >+ "failure": true >+ }, >+ { >+ "input": "http://2001::1]:80", >+ "base": "http://example.org/foo/bar", >+ "failure": true >+ }, >+ { >+ "input": "http://[2001::1]", >+ "base": "http://example.org/foo/bar", >+ "href": "http://[2001::1]/", >+ "origin": "http://[2001::1]", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "[2001::1]", >+ "hostname": "[2001::1]", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://[::127.0.0.1]", >+ "base": "http://example.org/foo/bar", >+ "href": "http://[::7f00:1]/", >+ "origin": "http://[::7f00:1]", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "[::7f00:1]", >+ "hostname": "[::7f00:1]", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://[0:0:0:0:0:0:13.1.68.3]", >+ "base": "http://example.org/foo/bar", >+ "href": "http://[::d01:4403]/", >+ "origin": "http://[::d01:4403]", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "[::d01:4403]", >+ "hostname": "[::d01:4403]", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://[2001::1]:80", >+ "base": "http://example.org/foo/bar", >+ "href": "http://[2001::1]/", >+ "origin": "http://[2001::1]", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "[2001::1]", >+ "hostname": "[2001::1]", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http:/example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/example.com/", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ftp:/example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "ftp://example.com/", >+ "origin": "ftp://example.com", >+ "protocol": "ftp:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "https:/example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "https://example.com/", >+ "origin": "https://example.com", >+ "protocol": "https:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "madeupscheme:/example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "madeupscheme:/example.com/", >+ "origin": "null", >+ "protocol": "madeupscheme:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file:/example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "file:///example.com/", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file://example:1/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "file://example:test/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "file://example%/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "file://[example]/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "ftps:/example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "ftps:/example.com/", >+ "origin": "null", >+ "protocol": "ftps:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "gopher:/example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "gopher://example.com/", >+ "origin": "gopher://example.com", >+ "protocol": "gopher:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ws:/example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "ws://example.com/", >+ "origin": "ws://example.com", >+ "protocol": "ws:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "wss:/example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "wss://example.com/", >+ "origin": "wss://example.com", >+ "protocol": "wss:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "data:/example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "data:/example.com/", >+ "origin": "null", >+ "protocol": "data:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "javascript:/example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "javascript:/example.com/", >+ "origin": "null", >+ "protocol": "javascript:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "mailto:/example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "mailto:/example.com/", >+ "origin": "null", >+ "protocol": "mailto:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http:example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/example.com/", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ftp:example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "ftp://example.com/", >+ "origin": "ftp://example.com", >+ "protocol": "ftp:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "https:example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "https://example.com/", >+ "origin": "https://example.com", >+ "protocol": "https:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "madeupscheme:example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "madeupscheme:example.com/", >+ "origin": "null", >+ "protocol": "madeupscheme:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ftps:example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "ftps:example.com/", >+ "origin": "null", >+ "protocol": "ftps:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "gopher:example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "gopher://example.com/", >+ "origin": "gopher://example.com", >+ "protocol": "gopher:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ws:example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "ws://example.com/", >+ "origin": "ws://example.com", >+ "protocol": "ws:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "wss:example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "wss://example.com/", >+ "origin": "wss://example.com", >+ "protocol": "wss:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "data:example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "data:example.com/", >+ "origin": "null", >+ "protocol": "data:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "javascript:example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "javascript:example.com/", >+ "origin": "null", >+ "protocol": "javascript:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "mailto:example.com/", >+ "base": "http://example.org/foo/bar", >+ "href": "mailto:example.com/", >+ "origin": "null", >+ "protocol": "mailto:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "/a/b/c", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/a/b/c", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/a/b/c", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "/a/ /c", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/a/%20/c", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/a/%20/c", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "/a%2fc", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/a%2fc", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/a%2fc", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "/a/%2f/c", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/a/%2f/c", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/a/%2f/c", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "#β", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/bar#%CE%B2", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/bar", >+ "search": "", >+ "hash": "#%CE%B2" >+ }, >+ { >+ "input": "data:text/html,test#test", >+ "base": "http://example.org/foo/bar", >+ "href": "data:text/html,test#test", >+ "origin": "null", >+ "protocol": "data:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "text/html,test", >+ "search": "", >+ "hash": "#test" >+ }, >+ { >+ "input": "tel:1234567890", >+ "base": "http://example.org/foo/bar", >+ "href": "tel:1234567890", >+ "origin": "null", >+ "protocol": "tel:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "1234567890", >+ "search": "", >+ "hash": "" >+ }, >+ "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/file.html", >+ { >+ "input": "file:c:\\foo\\bar.html", >+ "base": "file:///tmp/mock/path", >+ "href": "file:///c:/foo/bar.html", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/c:/foo/bar.html", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": " File:c|////foo\\bar.html", >+ "base": "file:///tmp/mock/path", >+ "href": "file:///c:////foo/bar.html", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/c:////foo/bar.html", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "C|/foo/bar", >+ "base": "file:///tmp/mock/path", >+ "href": "file:///C:/foo/bar", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C:/foo/bar", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "/C|\\foo\\bar", >+ "base": "file:///tmp/mock/path", >+ "href": "file:///C:/foo/bar", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C:/foo/bar", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "//C|/foo/bar", >+ "base": "file:///tmp/mock/path", >+ "href": "file:///C:/foo/bar", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C:/foo/bar", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "//server/file", >+ "base": "file:///tmp/mock/path", >+ "href": "file://server/file", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "server", >+ "hostname": "server", >+ "port": "", >+ "pathname": "/file", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "\\\\server\\file", >+ "base": "file:///tmp/mock/path", >+ "href": "file://server/file", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "server", >+ "hostname": "server", >+ "port": "", >+ "pathname": "/file", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "/\\server/file", >+ "base": "file:///tmp/mock/path", >+ "href": "file://server/file", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "server", >+ "hostname": "server", >+ "port": "", >+ "pathname": "/file", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file:///foo/bar.txt", >+ "base": "file:///tmp/mock/path", >+ "href": "file:///foo/bar.txt", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/foo/bar.txt", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file:///home/me", >+ "base": "file:///tmp/mock/path", >+ "href": "file:///home/me", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/home/me", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "//", >+ "base": "file:///tmp/mock/path", >+ "href": "file:///", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "///", >+ "base": "file:///tmp/mock/path", >+ "href": "file:///", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "///test", >+ "base": "file:///tmp/mock/path", >+ "href": "file:///test", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/test", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file://test", >+ "base": "file:///tmp/mock/path", >+ "href": "file://test/", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "test", >+ "hostname": "test", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file://localhost", >+ "base": "file:///tmp/mock/path", >+ "href": "file:///", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file://localhost/", >+ "base": "file:///tmp/mock/path", >+ "href": "file:///", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file://localhost/test", >+ "base": "file:///tmp/mock/path", >+ "href": "file:///test", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/test", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "test", >+ "base": "file:///tmp/mock/path", >+ "href": "file:///tmp/mock/test", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/tmp/mock/test", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file:test", >+ "base": "file:///tmp/mock/path", >+ "href": "file:///tmp/mock/test", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/tmp/mock/test", >+ "search": "", >+ "hash": "" >+ }, >+ "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/script-tests/path.js", >+ { >+ "input": "http://example.com/././foo", >+ "base": "about:blank", >+ "href": "http://example.com/foo", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/./.foo", >+ "base": "about:blank", >+ "href": "http://example.com/.foo", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/.foo", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo/.", >+ "base": "about:blank", >+ "href": "http://example.com/foo/", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo/./", >+ "base": "about:blank", >+ "href": "http://example.com/foo/", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo/bar/..", >+ "base": "about:blank", >+ "href": "http://example.com/foo/", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo/bar/../", >+ "base": "about:blank", >+ "href": "http://example.com/foo/", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo/..bar", >+ "base": "about:blank", >+ "href": "http://example.com/foo/..bar", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo/..bar", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo/bar/../ton", >+ "base": "about:blank", >+ "href": "http://example.com/foo/ton", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo/ton", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo/bar/../ton/../../a", >+ "base": "about:blank", >+ "href": "http://example.com/a", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/a", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo/../../..", >+ "base": "about:blank", >+ "href": "http://example.com/", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo/../../../ton", >+ "base": "about:blank", >+ "href": "http://example.com/ton", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/ton", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo/%2e", >+ "base": "about:blank", >+ "href": "http://example.com/foo/", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo/%2e%2", >+ "base": "about:blank", >+ "href": "http://example.com/foo/%2e%2", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo/%2e%2", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar", >+ "base": "about:blank", >+ "href": "http://example.com/%2e.bar", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/%2e.bar", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com////../..", >+ "base": "about:blank", >+ "href": "http://example.com//", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "//", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo/bar//../..", >+ "base": "about:blank", >+ "href": "http://example.com/foo/", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo/bar//..", >+ "base": "about:blank", >+ "href": "http://example.com/foo/bar/", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo/bar/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo", >+ "base": "about:blank", >+ "href": "http://example.com/foo", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/%20foo", >+ "base": "about:blank", >+ "href": "http://example.com/%20foo", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/%20foo", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo%", >+ "base": "about:blank", >+ "href": "http://example.com/foo%", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo%", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo%2", >+ "base": "about:blank", >+ "href": "http://example.com/foo%2", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo%2", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo%2zbar", >+ "base": "about:blank", >+ "href": "http://example.com/foo%2zbar", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo%2zbar", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo%2ézbar", >+ "base": "about:blank", >+ "href": "http://example.com/foo%2%C3%82%C2%A9zbar", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo%2%C3%82%C2%A9zbar", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo%41%7a", >+ "base": "about:blank", >+ "href": "http://example.com/foo%41%7a", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo%41%7a", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo\t\u0091%91", >+ "base": "about:blank", >+ "href": "http://example.com/foo%C2%91%91", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo%C2%91%91", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo%00%51", >+ "base": "about:blank", >+ "href": "http://example.com/foo%00%51", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foo%00%51", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/(%28:%3A%29)", >+ "base": "about:blank", >+ "href": "http://example.com/(%28:%3A%29)", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/(%28:%3A%29)", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/%3A%3a%3C%3c", >+ "base": "about:blank", >+ "href": "http://example.com/%3A%3a%3C%3c", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/%3A%3a%3C%3c", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/foo\tbar", >+ "base": "about:blank", >+ "href": "http://example.com/foobar", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/foobar", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com\\\\foo\\\\bar", >+ "base": "about:blank", >+ "href": "http://example.com//foo//bar", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "//foo//bar", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/%7Ffp3%3Eju%3Dduvgw%3Dd", >+ "base": "about:blank", >+ "href": "http://example.com/%7Ffp3%3Eju%3Dduvgw%3Dd", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/%7Ffp3%3Eju%3Dduvgw%3Dd", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/@asdf%40", >+ "base": "about:blank", >+ "href": "http://example.com/@asdf%40", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/@asdf%40", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/ä½ å¥½ä½ å¥½", >+ "base": "about:blank", >+ "href": "http://example.com/%E4%BD%A0%E5%A5%BD%E4%BD%A0%E5%A5%BD", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/%E4%BD%A0%E5%A5%BD%E4%BD%A0%E5%A5%BD", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/â¥/foo", >+ "base": "about:blank", >+ "href": "http://example.com/%E2%80%A5/foo", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/%E2%80%A5/foo", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com//foo", >+ "base": "about:blank", >+ "href": "http://example.com/%EF%BB%BF/foo", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/%EF%BB%BF/foo", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.com/â®/foo/â/bar", >+ "base": "about:blank", >+ "href": "http://example.com/%E2%80%AE/foo/%E2%80%AD/bar", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/%E2%80%AE/foo/%E2%80%AD/bar", >+ "search": "", >+ "hash": "" >+ }, >+ "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/script-tests/relative.js", >+ { >+ "input": "http://www.google.com/foo?bar=baz#", >+ "base": "about:blank", >+ "href": "http://www.google.com/foo?bar=baz#", >+ "origin": "http://www.google.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.google.com", >+ "hostname": "www.google.com", >+ "port": "", >+ "pathname": "/foo", >+ "search": "?bar=baz", >+ "hash": "" >+ }, >+ { >+ "input": "http://www.google.com/foo?bar=baz# »", >+ "base": "about:blank", >+ "href": "http://www.google.com/foo?bar=baz#%20%C2%BB", >+ "origin": "http://www.google.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.google.com", >+ "hostname": "www.google.com", >+ "port": "", >+ "pathname": "/foo", >+ "search": "?bar=baz", >+ "hash": "#%20%C2%BB" >+ }, >+ { >+ "input": "data:test# »", >+ "base": "about:blank", >+ "href": "data:test#%20%C2%BB", >+ "origin": "null", >+ "protocol": "data:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "test", >+ "search": "", >+ "hash": "#%20%C2%BB" >+ }, >+ { >+ "input": "http://www.google.com", >+ "base": "about:blank", >+ "href": "http://www.google.com/", >+ "origin": "http://www.google.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.google.com", >+ "hostname": "www.google.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://192.0x00A80001", >+ "base": "about:blank", >+ "href": "http://192.168.0.1/", >+ "origin": "http://192.168.0.1", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "192.168.0.1", >+ "hostname": "192.168.0.1", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://www/foo%2Ehtml", >+ "base": "about:blank", >+ "href": "http://www/foo%2Ehtml", >+ "origin": "http://www", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www", >+ "hostname": "www", >+ "port": "", >+ "pathname": "/foo%2Ehtml", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://www/foo/%2E/html", >+ "base": "about:blank", >+ "href": "http://www/foo/html", >+ "origin": "http://www", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www", >+ "hostname": "www", >+ "port": "", >+ "pathname": "/foo/html", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://user:pass@/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "http://%25DOMAIN:foobar@foodomain.com/", >+ "base": "about:blank", >+ "href": "http://%25DOMAIN:foobar@foodomain.com/", >+ "origin": "http://foodomain.com", >+ "protocol": "http:", >+ "username": "%25DOMAIN", >+ "password": "foobar", >+ "host": "foodomain.com", >+ "hostname": "foodomain.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http:\\\\www.google.com\\foo", >+ "base": "about:blank", >+ "href": "http://www.google.com/foo", >+ "origin": "http://www.google.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.google.com", >+ "hostname": "www.google.com", >+ "port": "", >+ "pathname": "/foo", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://foo:80/", >+ "base": "about:blank", >+ "href": "http://foo/", >+ "origin": "http://foo", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "foo", >+ "hostname": "foo", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://foo:81/", >+ "base": "about:blank", >+ "href": "http://foo:81/", >+ "origin": "http://foo:81", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "foo:81", >+ "hostname": "foo", >+ "port": "81", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "httpa://foo:80/", >+ "base": "about:blank", >+ "href": "httpa://foo:80/", >+ "origin": "null", >+ "protocol": "httpa:", >+ "username": "", >+ "password": "", >+ "host": "foo:80", >+ "hostname": "foo", >+ "port": "80", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://foo:-80/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "https://foo:443/", >+ "base": "about:blank", >+ "href": "https://foo/", >+ "origin": "https://foo", >+ "protocol": "https:", >+ "username": "", >+ "password": "", >+ "host": "foo", >+ "hostname": "foo", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "https://foo:80/", >+ "base": "about:blank", >+ "href": "https://foo:80/", >+ "origin": "https://foo:80", >+ "protocol": "https:", >+ "username": "", >+ "password": "", >+ "host": "foo:80", >+ "hostname": "foo", >+ "port": "80", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ftp://foo:21/", >+ "base": "about:blank", >+ "href": "ftp://foo/", >+ "origin": "ftp://foo", >+ "protocol": "ftp:", >+ "username": "", >+ "password": "", >+ "host": "foo", >+ "hostname": "foo", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ftp://foo:80/", >+ "base": "about:blank", >+ "href": "ftp://foo:80/", >+ "origin": "ftp://foo:80", >+ "protocol": "ftp:", >+ "username": "", >+ "password": "", >+ "host": "foo:80", >+ "hostname": "foo", >+ "port": "80", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "gopher://foo:70/", >+ "base": "about:blank", >+ "href": "gopher://foo/", >+ "origin": "gopher://foo", >+ "protocol": "gopher:", >+ "username": "", >+ "password": "", >+ "host": "foo", >+ "hostname": "foo", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "gopher://foo:443/", >+ "base": "about:blank", >+ "href": "gopher://foo:443/", >+ "origin": "gopher://foo:443", >+ "protocol": "gopher:", >+ "username": "", >+ "password": "", >+ "host": "foo:443", >+ "hostname": "foo", >+ "port": "443", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ws://foo:80/", >+ "base": "about:blank", >+ "href": "ws://foo/", >+ "origin": "ws://foo", >+ "protocol": "ws:", >+ "username": "", >+ "password": "", >+ "host": "foo", >+ "hostname": "foo", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ws://foo:81/", >+ "base": "about:blank", >+ "href": "ws://foo:81/", >+ "origin": "ws://foo:81", >+ "protocol": "ws:", >+ "username": "", >+ "password": "", >+ "host": "foo:81", >+ "hostname": "foo", >+ "port": "81", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ws://foo:443/", >+ "base": "about:blank", >+ "href": "ws://foo:443/", >+ "origin": "ws://foo:443", >+ "protocol": "ws:", >+ "username": "", >+ "password": "", >+ "host": "foo:443", >+ "hostname": "foo", >+ "port": "443", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ws://foo:815/", >+ "base": "about:blank", >+ "href": "ws://foo:815/", >+ "origin": "ws://foo:815", >+ "protocol": "ws:", >+ "username": "", >+ "password": "", >+ "host": "foo:815", >+ "hostname": "foo", >+ "port": "815", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "wss://foo:80/", >+ "base": "about:blank", >+ "href": "wss://foo:80/", >+ "origin": "wss://foo:80", >+ "protocol": "wss:", >+ "username": "", >+ "password": "", >+ "host": "foo:80", >+ "hostname": "foo", >+ "port": "80", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "wss://foo:81/", >+ "base": "about:blank", >+ "href": "wss://foo:81/", >+ "origin": "wss://foo:81", >+ "protocol": "wss:", >+ "username": "", >+ "password": "", >+ "host": "foo:81", >+ "hostname": "foo", >+ "port": "81", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "wss://foo:443/", >+ "base": "about:blank", >+ "href": "wss://foo/", >+ "origin": "wss://foo", >+ "protocol": "wss:", >+ "username": "", >+ "password": "", >+ "host": "foo", >+ "hostname": "foo", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "wss://foo:815/", >+ "base": "about:blank", >+ "href": "wss://foo:815/", >+ "origin": "wss://foo:815", >+ "protocol": "wss:", >+ "username": "", >+ "password": "", >+ "host": "foo:815", >+ "hostname": "foo", >+ "port": "815", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http:/example.com/", >+ "base": "about:blank", >+ "href": "http://example.com/", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ftp:/example.com/", >+ "base": "about:blank", >+ "href": "ftp://example.com/", >+ "origin": "ftp://example.com", >+ "protocol": "ftp:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "https:/example.com/", >+ "base": "about:blank", >+ "href": "https://example.com/", >+ "origin": "https://example.com", >+ "protocol": "https:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "madeupscheme:/example.com/", >+ "base": "about:blank", >+ "href": "madeupscheme:/example.com/", >+ "origin": "null", >+ "protocol": "madeupscheme:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file:/example.com/", >+ "base": "about:blank", >+ "href": "file:///example.com/", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ftps:/example.com/", >+ "base": "about:blank", >+ "href": "ftps:/example.com/", >+ "origin": "null", >+ "protocol": "ftps:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "gopher:/example.com/", >+ "base": "about:blank", >+ "href": "gopher://example.com/", >+ "origin": "gopher://example.com", >+ "protocol": "gopher:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ws:/example.com/", >+ "base": "about:blank", >+ "href": "ws://example.com/", >+ "origin": "ws://example.com", >+ "protocol": "ws:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "wss:/example.com/", >+ "base": "about:blank", >+ "href": "wss://example.com/", >+ "origin": "wss://example.com", >+ "protocol": "wss:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "data:/example.com/", >+ "base": "about:blank", >+ "href": "data:/example.com/", >+ "origin": "null", >+ "protocol": "data:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "javascript:/example.com/", >+ "base": "about:blank", >+ "href": "javascript:/example.com/", >+ "origin": "null", >+ "protocol": "javascript:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "mailto:/example.com/", >+ "base": "about:blank", >+ "href": "mailto:/example.com/", >+ "origin": "null", >+ "protocol": "mailto:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http:example.com/", >+ "base": "about:blank", >+ "href": "http://example.com/", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ftp:example.com/", >+ "base": "about:blank", >+ "href": "ftp://example.com/", >+ "origin": "ftp://example.com", >+ "protocol": "ftp:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "https:example.com/", >+ "base": "about:blank", >+ "href": "https://example.com/", >+ "origin": "https://example.com", >+ "protocol": "https:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "madeupscheme:example.com/", >+ "base": "about:blank", >+ "href": "madeupscheme:example.com/", >+ "origin": "null", >+ "protocol": "madeupscheme:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ftps:example.com/", >+ "base": "about:blank", >+ "href": "ftps:example.com/", >+ "origin": "null", >+ "protocol": "ftps:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "gopher:example.com/", >+ "base": "about:blank", >+ "href": "gopher://example.com/", >+ "origin": "gopher://example.com", >+ "protocol": "gopher:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ws:example.com/", >+ "base": "about:blank", >+ "href": "ws://example.com/", >+ "origin": "ws://example.com", >+ "protocol": "ws:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "wss:example.com/", >+ "base": "about:blank", >+ "href": "wss://example.com/", >+ "origin": "wss://example.com", >+ "protocol": "wss:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "data:example.com/", >+ "base": "about:blank", >+ "href": "data:example.com/", >+ "origin": "null", >+ "protocol": "data:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "javascript:example.com/", >+ "base": "about:blank", >+ "href": "javascript:example.com/", >+ "origin": "null", >+ "protocol": "javascript:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "mailto:example.com/", >+ "base": "about:blank", >+ "href": "mailto:example.com/", >+ "origin": "null", >+ "protocol": "mailto:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "example.com/", >+ "search": "", >+ "hash": "" >+ }, >+ "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/segments-userinfo-vs-host.html", >+ { >+ "input": "http:@www.example.com", >+ "base": "about:blank", >+ "href": "http://www.example.com/", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http:/@www.example.com", >+ "base": "about:blank", >+ "href": "http://www.example.com/", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://@www.example.com", >+ "base": "about:blank", >+ "href": "http://www.example.com/", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http:a:b@www.example.com", >+ "base": "about:blank", >+ "href": "http://a:b@www.example.com/", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "a", >+ "password": "b", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http:/a:b@www.example.com", >+ "base": "about:blank", >+ "href": "http://a:b@www.example.com/", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "a", >+ "password": "b", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://a:b@www.example.com", >+ "base": "about:blank", >+ "href": "http://a:b@www.example.com/", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "a", >+ "password": "b", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://@pple.com", >+ "base": "about:blank", >+ "href": "http://pple.com/", >+ "origin": "http://pple.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "pple.com", >+ "hostname": "pple.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http::b@www.example.com", >+ "base": "about:blank", >+ "href": "http://:b@www.example.com/", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "b", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http:/:b@www.example.com", >+ "base": "about:blank", >+ "href": "http://:b@www.example.com/", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "b", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://:b@www.example.com", >+ "base": "about:blank", >+ "href": "http://:b@www.example.com/", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "b", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http:/:@/www.example.com", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "http://user@/www.example.com", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "http:@/www.example.com", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "http:/@/www.example.com", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "http://@/www.example.com", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "https:@/www.example.com", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "http:a:b@/www.example.com", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "http:/a:b@/www.example.com", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "http://a:b@/www.example.com", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "http::@/www.example.com", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "http:a:@www.example.com", >+ "base": "about:blank", >+ "href": "http://a@www.example.com/", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "a", >+ "password": "", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http:/a:@www.example.com", >+ "base": "about:blank", >+ "href": "http://a@www.example.com/", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "a", >+ "password": "", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://a:@www.example.com", >+ "base": "about:blank", >+ "href": "http://a@www.example.com/", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "a", >+ "password": "", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://www.@pple.com", >+ "base": "about:blank", >+ "href": "http://www.@pple.com/", >+ "origin": "http://pple.com", >+ "protocol": "http:", >+ "username": "www.", >+ "password": "", >+ "host": "pple.com", >+ "hostname": "pple.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http:@:www.example.com", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "http:/@:www.example.com", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "http://@:www.example.com", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "http://:@www.example.com", >+ "base": "about:blank", >+ "href": "http://www.example.com/", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ "# Others", >+ { >+ "input": "/", >+ "base": "http://www.example.com/test", >+ "href": "http://www.example.com/", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "/test.txt", >+ "base": "http://www.example.com/test", >+ "href": "http://www.example.com/test.txt", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/test.txt", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": ".", >+ "base": "http://www.example.com/test", >+ "href": "http://www.example.com/", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "..", >+ "base": "http://www.example.com/test", >+ "href": "http://www.example.com/", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "test.txt", >+ "base": "http://www.example.com/test", >+ "href": "http://www.example.com/test.txt", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/test.txt", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "./test.txt", >+ "base": "http://www.example.com/test", >+ "href": "http://www.example.com/test.txt", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/test.txt", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "../test.txt", >+ "base": "http://www.example.com/test", >+ "href": "http://www.example.com/test.txt", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/test.txt", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "../aaa/test.txt", >+ "base": "http://www.example.com/test", >+ "href": "http://www.example.com/aaa/test.txt", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/aaa/test.txt", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "../../test.txt", >+ "base": "http://www.example.com/test", >+ "href": "http://www.example.com/test.txt", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/test.txt", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ä¸/test.txt", >+ "base": "http://www.example.com/test", >+ "href": "http://www.example.com/%E4%B8%AD/test.txt", >+ "origin": "http://www.example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.example.com", >+ "hostname": "www.example.com", >+ "port": "", >+ "pathname": "/%E4%B8%AD/test.txt", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://www.example2.com", >+ "base": "http://www.example.com/test", >+ "href": "http://www.example2.com/", >+ "origin": "http://www.example2.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.example2.com", >+ "hostname": "www.example2.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "//www.example2.com", >+ "base": "http://www.example.com/test", >+ "href": "http://www.example2.com/", >+ "origin": "http://www.example2.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.example2.com", >+ "hostname": "www.example2.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file:...", >+ "base": "http://www.example.com/test", >+ "href": "file:///...", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/...", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file:..", >+ "base": "http://www.example.com/test", >+ "href": "file:///", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file:a", >+ "base": "http://www.example.com/test", >+ "href": "file:///a", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/a", >+ "search": "", >+ "hash": "" >+ }, >+ "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/host.html", >+ "Basic canonicalization, uppercase should be converted to lowercase", >+ { >+ "input": "http://ExAmPlE.CoM", >+ "base": "http://other.com/", >+ "href": "http://example.com/", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example example.com", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ { >+ "input": "http://Goo%20 goo%7C|.com", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ { >+ "input": "http://[]", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ { >+ "input": "http://[:]", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ "U+3000 is mapped to U+0020 (space) which is disallowed", >+ { >+ "input": "http://GOO\u00a0\u3000goo.com", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ "Other types of space (no-break, zero-width, zero-width-no-break) are name-prepped away to nothing. U+200B, U+2060, and U+FEFF, are ignored", >+ { >+ "input": "http://GOO\u200b\u2060\ufeffgoo.com", >+ "base": "http://other.com/", >+ "href": "http://googoo.com/", >+ "origin": "http://googoo.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "googoo.com", >+ "hostname": "googoo.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ "Leading and trailing C0 control or space", >+ { >+ "input": "\u0000\u001b\u0004\u0012 http://example.com/\u001f \u000d ", >+ "base": "about:blank", >+ "href": "http://example.com/", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ "Ideographic full stop (full-width period for Chinese, etc.) should be treated as a dot. U+3002 is mapped to U+002E (dot)", >+ { >+ "input": "http://www.fooãbar.com", >+ "base": "http://other.com/", >+ "href": "http://www.foo.bar.com/", >+ "origin": "http://www.foo.bar.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "www.foo.bar.com", >+ "hostname": "www.foo.bar.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ "Invalid unicode characters should fail... U+FDD0 is disallowed; %ef%b7%90 is U+FDD0", >+ { >+ "input": "http://\ufdd0zyx.com", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ "This is the same as previous but escaped", >+ { >+ "input": "http://%ef%b7%90zyx.com", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ "U+FFFD", >+ { >+ "input": "https://\ufffd", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "https://%EF%BF%BD", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "https://x/\ufffd?\ufffd#\ufffd", >+ "base": "about:blank", >+ "href": "https://x/%EF%BF%BD?%EF%BF%BD#%EF%BF%BD", >+ "origin": "https://x", >+ "protocol": "https:", >+ "username": "", >+ "password": "", >+ "host": "x", >+ "hostname": "x", >+ "port": "", >+ "pathname": "/%EF%BF%BD", >+ "search": "?%EF%BF%BD", >+ "hash": "#%EF%BF%BD" >+ }, >+ "Test name prepping, fullwidth input should be converted to ASCII and NOT IDN-ized. This is 'Go' in fullwidth UTF-8/UTF-16.", >+ { >+ "input": "http://ï¼§ï½.com", >+ "base": "http://other.com/", >+ "href": "http://go.com/", >+ "origin": "http://go.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "go.com", >+ "hostname": "go.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ "URL spec forbids the following. https://www.w3.org/Bugs/Public/show_bug.cgi?id=24257", >+ { >+ "input": "http://ï¼ ï¼ï¼.com", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ { >+ "input": "http://%ef%bc%85%ef%bc%94%ef%bc%91.com", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ "...%00 in fullwidth should fail (also as escaped UTF-8 input)", >+ { >+ "input": "http://ï¼ ï¼ï¼.com", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ { >+ "input": "http://%ef%bc%85%ef%bc%90%ef%bc%90.com", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ "Basic IDN support, UTF-8 and UTF-16 input should be converted to IDN", >+ { >+ "input": "http://ä½ å¥½ä½ å¥½", >+ "base": "http://other.com/", >+ "href": "http://xn--6qqa088eba/", >+ "origin": "http://xn--6qqa088eba", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "xn--6qqa088eba", >+ "hostname": "xn--6qqa088eba", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "https://faÃ.ExAmPlE/", >+ "base": "about:blank", >+ "href": "https://xn--fa-hia.example/", >+ "origin": "https://xn--fa-hia.example", >+ "protocol": "https:", >+ "username": "", >+ "password": "", >+ "host": "xn--fa-hia.example", >+ "hostname": "xn--fa-hia.example", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "sc://faÃ.ExAmPlE/", >+ "base": "about:blank", >+ "href": "sc://fa%C3%9F.ExAmPlE/", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "fa%C3%9F.ExAmPlE", >+ "hostname": "fa%C3%9F.ExAmPlE", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ "Invalid escaped characters should fail and the percents should be escaped. https://www.w3.org/Bugs/Public/show_bug.cgi?id=24191", >+ { >+ "input": "http://%zz%66%a.com", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ "If we get an invalid character that has been escaped.", >+ { >+ "input": "http://%25", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ { >+ "input": "http://hello%00", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ "Escaped numbers should be treated like IP addresses if they are.", >+ { >+ "input": "http://%30%78%63%30%2e%30%32%35%30.01", >+ "base": "http://other.com/", >+ "href": "http://192.168.0.1/", >+ "origin": "http://192.168.0.1", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "192.168.0.1", >+ "hostname": "192.168.0.1", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://%30%78%63%30%2e%30%32%35%30.01%2e", >+ "base": "http://other.com/", >+ "href": "http://192.168.0.1/", >+ "origin": "http://192.168.0.1", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "192.168.0.1", >+ "hostname": "192.168.0.1", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://192.168.0.257", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ "Invalid escaping in hosts causes failure", >+ { >+ "input": "http://%3g%78%63%30%2e%30%32%35%30%2E.01", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ "A space in a host causes failure", >+ { >+ "input": "http://192.168.0.1 hello", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ { >+ "input": "https://x x:12", >+ "base": "about:blank", >+ "failure": true >+ }, >+ "Fullwidth and escaped UTF-8 fullwidth should still be treated as IP", >+ { >+ "input": "http://ï¼ï¼¸ï½ï¼ï¼ï¼ï¼ï¼ï¼ï¼ï¼ï¼", >+ "base": "http://other.com/", >+ "href": "http://192.168.0.1/", >+ "origin": "http://192.168.0.1", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "192.168.0.1", >+ "hostname": "192.168.0.1", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ "Domains with empty labels", >+ { >+ "input": "http://./", >+ "base": "about:blank", >+ "href": "http://./", >+ "origin": "http://.", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": ".", >+ "hostname": ".", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://../", >+ "base": "about:blank", >+ "href": "http://../", >+ "origin": "http://..", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "..", >+ "hostname": "..", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://0..0x300/", >+ "base": "about:blank", >+ "href": "http://0..0x300/", >+ "origin": "http://0..0x300", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "0..0x300", >+ "hostname": "0..0x300", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ "Broken IPv6", >+ { >+ "input": "http://[www.google.com]/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "http://[google.com]", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ { >+ "input": "http://[::1.2.3.4x]", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ { >+ "input": "http://[::1.2.3.]", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ { >+ "input": "http://[::1.2.]", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ { >+ "input": "http://[::1.]", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ "Misc Unicode", >+ { >+ "input": "http://foo:ð©@example.com/bar", >+ "base": "http://other.com/", >+ "href": "http://foo:%F0%9F%92%A9@example.com/bar", >+ "origin": "http://example.com", >+ "protocol": "http:", >+ "username": "foo", >+ "password": "%F0%9F%92%A9", >+ "host": "example.com", >+ "hostname": "example.com", >+ "port": "", >+ "pathname": "/bar", >+ "search": "", >+ "hash": "" >+ }, >+ "# resolving a fragment against any scheme succeeds", >+ { >+ "input": "#", >+ "base": "test:test", >+ "href": "test:test#", >+ "origin": "null", >+ "protocol": "test:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "test", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "#x", >+ "base": "mailto:x@x.com", >+ "href": "mailto:x@x.com#x", >+ "origin": "null", >+ "protocol": "mailto:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "x@x.com", >+ "search": "", >+ "hash": "#x" >+ }, >+ { >+ "input": "#x", >+ "base": "data:,", >+ "href": "data:,#x", >+ "origin": "null", >+ "protocol": "data:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": ",", >+ "search": "", >+ "hash": "#x" >+ }, >+ { >+ "input": "#x", >+ "base": "about:blank", >+ "href": "about:blank#x", >+ "origin": "null", >+ "protocol": "about:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "blank", >+ "search": "", >+ "hash": "#x" >+ }, >+ { >+ "input": "#", >+ "base": "test:test?test", >+ "href": "test:test?test#", >+ "origin": "null", >+ "protocol": "test:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "test", >+ "search": "?test", >+ "hash": "" >+ }, >+ "# multiple @ in authority state", >+ { >+ "input": "https://@test@test@example:800/", >+ "base": "http://doesnotmatter/", >+ "href": "https://%40test%40test@example:800/", >+ "origin": "https://example:800", >+ "protocol": "https:", >+ "username": "%40test%40test", >+ "password": "", >+ "host": "example:800", >+ "hostname": "example", >+ "port": "800", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "https://@@@example", >+ "base": "http://doesnotmatter/", >+ "href": "https://%40%40@example/", >+ "origin": "https://example", >+ "protocol": "https:", >+ "username": "%40%40", >+ "password": "", >+ "host": "example", >+ "hostname": "example", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ "non-az-09 characters", >+ { >+ "input": "http://`{}:`{}@h/`{}?`{}", >+ "base": "http://doesnotmatter/", >+ "href": "http://%60%7B%7D:%60%7B%7D@h/%60%7B%7D?`{}", >+ "origin": "http://h", >+ "protocol": "http:", >+ "username": "%60%7B%7D", >+ "password": "%60%7B%7D", >+ "host": "h", >+ "hostname": "h", >+ "port": "", >+ "pathname": "/%60%7B%7D", >+ "search": "?`{}", >+ "hash": "" >+ }, >+ "# Credentials in base", >+ { >+ "input": "/some/path", >+ "base": "http://user@example.org/smth", >+ "href": "http://user@example.org/some/path", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "user", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/some/path", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "", >+ "base": "http://user:pass@example.org:21/smth", >+ "href": "http://user:pass@example.org:21/smth", >+ "origin": "http://example.org:21", >+ "protocol": "http:", >+ "username": "user", >+ "password": "pass", >+ "host": "example.org:21", >+ "hostname": "example.org", >+ "port": "21", >+ "pathname": "/smth", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "/some/path", >+ "base": "http://user:pass@example.org:21/smth", >+ "href": "http://user:pass@example.org:21/some/path", >+ "origin": "http://example.org:21", >+ "protocol": "http:", >+ "username": "user", >+ "password": "pass", >+ "host": "example.org:21", >+ "hostname": "example.org", >+ "port": "21", >+ "pathname": "/some/path", >+ "search": "", >+ "hash": "" >+ }, >+ "# a set of tests designed by zcorpan for relative URLs with unknown schemes", >+ { >+ "input": "i", >+ "base": "sc:sd", >+ "failure": true >+ }, >+ { >+ "input": "i", >+ "base": "sc:sd/sd", >+ "failure": true >+ }, >+ { >+ "input": "i", >+ "base": "sc:/pa/pa", >+ "href": "sc:/pa/i", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/pa/i", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "i", >+ "base": "sc://ho/pa", >+ "href": "sc://ho/i", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "ho", >+ "hostname": "ho", >+ "port": "", >+ "pathname": "/i", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "i", >+ "base": "sc:///pa/pa", >+ "href": "sc:///pa/i", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/pa/i", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "../i", >+ "base": "sc:sd", >+ "failure": true >+ }, >+ { >+ "input": "../i", >+ "base": "sc:sd/sd", >+ "failure": true >+ }, >+ { >+ "input": "../i", >+ "base": "sc:/pa/pa", >+ "href": "sc:/i", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/i", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "../i", >+ "base": "sc://ho/pa", >+ "href": "sc://ho/i", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "ho", >+ "hostname": "ho", >+ "port": "", >+ "pathname": "/i", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "../i", >+ "base": "sc:///pa/pa", >+ "href": "sc:///i", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/i", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "/i", >+ "base": "sc:sd", >+ "failure": true >+ }, >+ { >+ "input": "/i", >+ "base": "sc:sd/sd", >+ "failure": true >+ }, >+ { >+ "input": "/i", >+ "base": "sc:/pa/pa", >+ "href": "sc:/i", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/i", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "/i", >+ "base": "sc://ho/pa", >+ "href": "sc://ho/i", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "ho", >+ "hostname": "ho", >+ "port": "", >+ "pathname": "/i", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "/i", >+ "base": "sc:///pa/pa", >+ "href": "sc:///i", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/i", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "?i", >+ "base": "sc:sd", >+ "failure": true >+ }, >+ { >+ "input": "?i", >+ "base": "sc:sd/sd", >+ "failure": true >+ }, >+ { >+ "input": "?i", >+ "base": "sc:/pa/pa", >+ "href": "sc:/pa/pa?i", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/pa/pa", >+ "search": "?i", >+ "hash": "" >+ }, >+ { >+ "input": "?i", >+ "base": "sc://ho/pa", >+ "href": "sc://ho/pa?i", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "ho", >+ "hostname": "ho", >+ "port": "", >+ "pathname": "/pa", >+ "search": "?i", >+ "hash": "" >+ }, >+ { >+ "input": "?i", >+ "base": "sc:///pa/pa", >+ "href": "sc:///pa/pa?i", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/pa/pa", >+ "search": "?i", >+ "hash": "" >+ }, >+ { >+ "input": "#i", >+ "base": "sc:sd", >+ "href": "sc:sd#i", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "sd", >+ "search": "", >+ "hash": "#i" >+ }, >+ { >+ "input": "#i", >+ "base": "sc:sd/sd", >+ "href": "sc:sd/sd#i", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "sd/sd", >+ "search": "", >+ "hash": "#i" >+ }, >+ { >+ "input": "#i", >+ "base": "sc:/pa/pa", >+ "href": "sc:/pa/pa#i", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/pa/pa", >+ "search": "", >+ "hash": "#i" >+ }, >+ { >+ "input": "#i", >+ "base": "sc://ho/pa", >+ "href": "sc://ho/pa#i", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "ho", >+ "hostname": "ho", >+ "port": "", >+ "pathname": "/pa", >+ "search": "", >+ "hash": "#i" >+ }, >+ { >+ "input": "#i", >+ "base": "sc:///pa/pa", >+ "href": "sc:///pa/pa#i", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/pa/pa", >+ "search": "", >+ "hash": "#i" >+ }, >+ "# make sure that relative URL logic works on known typically non-relative schemes too", >+ { >+ "input": "about:/../", >+ "base": "about:blank", >+ "href": "about:/", >+ "origin": "null", >+ "protocol": "about:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "data:/../", >+ "base": "about:blank", >+ "href": "data:/", >+ "origin": "null", >+ "protocol": "data:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "javascript:/../", >+ "base": "about:blank", >+ "href": "javascript:/", >+ "origin": "null", >+ "protocol": "javascript:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "mailto:/../", >+ "base": "about:blank", >+ "href": "mailto:/", >+ "origin": "null", >+ "protocol": "mailto:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ "# unknown schemes and their hosts", >+ { >+ "input": "sc://ñ.test/", >+ "base": "about:blank", >+ "href": "sc://%C3%B1.test/", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "%C3%B1.test", >+ "hostname": "%C3%B1.test", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "sc://\u001F!\"$&'()*+,-.;<=>^_`{|}~/", >+ "base": "about:blank", >+ "href": "sc://%1F!\"$&'()*+,-.;<=>^_`{|}~/", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "%1F!\"$&'()*+,-.;<=>^_`{|}~", >+ "hostname": "%1F!\"$&'()*+,-.;<=>^_`{|}~", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "sc://\u0000/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "sc:// /", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "sc://%/", >+ "base": "about:blank", >+ "href": "sc://%/", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "%", >+ "hostname": "%", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "sc://@/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "sc://te@s:t@/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "sc://:/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "sc://:12/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "sc://[/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "sc://\\/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "sc://]/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "x", >+ "base": "sc://ñ", >+ "href": "sc://%C3%B1/x", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "%C3%B1", >+ "hostname": "%C3%B1", >+ "port": "", >+ "pathname": "/x", >+ "search": "", >+ "hash": "" >+ }, >+ "# unknown schemes and backslashes", >+ { >+ "input": "sc:\\../", >+ "base": "about:blank", >+ "href": "sc:\\../", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "\\../", >+ "search": "", >+ "hash": "" >+ }, >+ "# unknown scheme with path looking like a password", >+ { >+ "input": "sc::a@example.net", >+ "base": "about:blank", >+ "href": "sc::a@example.net", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": ":a@example.net", >+ "search": "", >+ "hash": "" >+ }, >+ "# unknown scheme with bogus percent-encoding", >+ { >+ "input": "wow:%NBD", >+ "base": "about:blank", >+ "href": "wow:%NBD", >+ "origin": "null", >+ "protocol": "wow:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "%NBD", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "wow:%1G", >+ "base": "about:blank", >+ "href": "wow:%1G", >+ "origin": "null", >+ "protocol": "wow:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "%1G", >+ "search": "", >+ "hash": "" >+ }, >+ "# Hosts and percent-encoding", >+ { >+ "input": "ftp://example.com%80/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "ftp://example.com%A0/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "https://example.com%80/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "https://example.com%A0/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "ftp://%e2%98%83", >+ "base": "about:blank", >+ "href": "ftp://xn--n3h/", >+ "origin": "ftp://xn--n3h", >+ "protocol": "ftp:", >+ "username": "", >+ "password": "", >+ "host": "xn--n3h", >+ "hostname": "xn--n3h", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "https://%e2%98%83", >+ "base": "about:blank", >+ "href": "https://xn--n3h/", >+ "origin": "https://xn--n3h", >+ "protocol": "https:", >+ "username": "", >+ "password": "", >+ "host": "xn--n3h", >+ "hostname": "xn--n3h", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ "# tests from jsdom/whatwg-url designed for code coverage", >+ { >+ "input": "http://127.0.0.1:10100/relative_import.html", >+ "base": "about:blank", >+ "href": "http://127.0.0.1:10100/relative_import.html", >+ "origin": "http://127.0.0.1:10100", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "127.0.0.1:10100", >+ "hostname": "127.0.0.1", >+ "port": "10100", >+ "pathname": "/relative_import.html", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://facebook.com/?foo=%7B%22abc%22", >+ "base": "about:blank", >+ "href": "http://facebook.com/?foo=%7B%22abc%22", >+ "origin": "http://facebook.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "facebook.com", >+ "hostname": "facebook.com", >+ "port": "", >+ "pathname": "/", >+ "search": "?foo=%7B%22abc%22", >+ "hash": "" >+ }, >+ { >+ "input": "https://localhost:3000/jqueryui@1.2.3", >+ "base": "about:blank", >+ "href": "https://localhost:3000/jqueryui@1.2.3", >+ "origin": "https://localhost:3000", >+ "protocol": "https:", >+ "username": "", >+ "password": "", >+ "host": "localhost:3000", >+ "hostname": "localhost", >+ "port": "3000", >+ "pathname": "/jqueryui@1.2.3", >+ "search": "", >+ "hash": "" >+ }, >+ "# tab/LF/CR", >+ { >+ "input": "h\tt\nt\rp://h\to\ns\rt:9\t0\n0\r0/p\ta\nt\rh?q\tu\ne\rry#f\tr\na\rg", >+ "base": "about:blank", >+ "href": "http://host:9000/path?query#frag", >+ "origin": "http://host:9000", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "host:9000", >+ "hostname": "host", >+ "port": "9000", >+ "pathname": "/path", >+ "search": "?query", >+ "hash": "#frag" >+ }, >+ "# Stringification of URL.searchParams", >+ { >+ "input": "?a=b&c=d", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/bar?a=b&c=d", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/bar", >+ "search": "?a=b&c=d", >+ "searchParams": "a=b&c=d", >+ "hash": "" >+ }, >+ { >+ "input": "??a=b&c=d", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/bar??a=b&c=d", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/bar", >+ "search": "??a=b&c=d", >+ "searchParams": "%3Fa=b&c=d", >+ "hash": "" >+ }, >+ "# Scheme only", >+ { >+ "input": "http:", >+ "base": "http://example.org/foo/bar", >+ "href": "http://example.org/foo/bar", >+ "origin": "http://example.org", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/foo/bar", >+ "search": "", >+ "searchParams": "", >+ "hash": "" >+ }, >+ { >+ "input": "http:", >+ "base": "https://example.org/foo/bar", >+ "failure": true >+ }, >+ { >+ "input": "sc:", >+ "base": "https://example.org/foo/bar", >+ "href": "sc:", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "", >+ "search": "", >+ "searchParams": "", >+ "hash": "" >+ }, >+ "# Percent encoding of fragments", >+ { >+ "input": "http://foo.bar/baz?qux#foo\bbar", >+ "base": "about:blank", >+ "href": "http://foo.bar/baz?qux#foo%08bar", >+ "origin": "http://foo.bar", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "foo.bar", >+ "hostname": "foo.bar", >+ "port": "", >+ "pathname": "/baz", >+ "search": "?qux", >+ "searchParams": "qux=", >+ "hash": "#foo%08bar" >+ }, >+ { >+ "input": "http://foo.bar/baz?qux#foo\"bar", >+ "base": "about:blank", >+ "href": "http://foo.bar/baz?qux#foo%22bar", >+ "origin": "http://foo.bar", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "foo.bar", >+ "hostname": "foo.bar", >+ "port": "", >+ "pathname": "/baz", >+ "search": "?qux", >+ "searchParams": "qux=", >+ "hash": "#foo%22bar" >+ }, >+ { >+ "input": "http://foo.bar/baz?qux#foo<bar", >+ "base": "about:blank", >+ "href": "http://foo.bar/baz?qux#foo%3Cbar", >+ "origin": "http://foo.bar", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "foo.bar", >+ "hostname": "foo.bar", >+ "port": "", >+ "pathname": "/baz", >+ "search": "?qux", >+ "searchParams": "qux=", >+ "hash": "#foo%3Cbar" >+ }, >+ { >+ "input": "http://foo.bar/baz?qux#foo>bar", >+ "base": "about:blank", >+ "href": "http://foo.bar/baz?qux#foo%3Ebar", >+ "origin": "http://foo.bar", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "foo.bar", >+ "hostname": "foo.bar", >+ "port": "", >+ "pathname": "/baz", >+ "search": "?qux", >+ "searchParams": "qux=", >+ "hash": "#foo%3Ebar" >+ }, >+ { >+ "input": "http://foo.bar/baz?qux#foo`bar", >+ "base": "about:blank", >+ "href": "http://foo.bar/baz?qux#foo%60bar", >+ "origin": "http://foo.bar", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "foo.bar", >+ "hostname": "foo.bar", >+ "port": "", >+ "pathname": "/baz", >+ "search": "?qux", >+ "searchParams": "qux=", >+ "hash": "#foo%60bar" >+ }, >+ "# IPv4 parsing (via https://github.com/nodejs/node/pull/10317)", >+ { >+ "input": "http://192.168.257", >+ "base": "http://other.com/", >+ "href": "http://192.168.1.1/", >+ "origin": "http://192.168.1.1", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "192.168.1.1", >+ "hostname": "192.168.1.1", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://192.168.257.com", >+ "base": "http://other.com/", >+ "href": "http://192.168.257.com/", >+ "origin": "http://192.168.257.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "192.168.257.com", >+ "hostname": "192.168.257.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://256", >+ "base": "http://other.com/", >+ "href": "http://0.0.1.0/", >+ "origin": "http://0.0.1.0", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "0.0.1.0", >+ "hostname": "0.0.1.0", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://256.com", >+ "base": "http://other.com/", >+ "href": "http://256.com/", >+ "origin": "http://256.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "256.com", >+ "hostname": "256.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://999999999", >+ "base": "http://other.com/", >+ "href": "http://59.154.201.255/", >+ "origin": "http://59.154.201.255", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "59.154.201.255", >+ "hostname": "59.154.201.255", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://999999999.com", >+ "base": "http://other.com/", >+ "href": "http://999999999.com/", >+ "origin": "http://999999999.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "999999999.com", >+ "hostname": "999999999.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://10000000000", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ { >+ "input": "http://10000000000.com", >+ "base": "http://other.com/", >+ "href": "http://10000000000.com/", >+ "origin": "http://10000000000.com", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "10000000000.com", >+ "hostname": "10000000000.com", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://4294967295", >+ "base": "http://other.com/", >+ "href": "http://255.255.255.255/", >+ "origin": "http://255.255.255.255", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "255.255.255.255", >+ "hostname": "255.255.255.255", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://4294967296", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ { >+ "input": "http://0xffffffff", >+ "base": "http://other.com/", >+ "href": "http://255.255.255.255/", >+ "origin": "http://255.255.255.255", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "255.255.255.255", >+ "hostname": "255.255.255.255", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://0xffffffff1", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ { >+ "input": "http://256.256.256.256", >+ "base": "http://other.com/", >+ "failure": true >+ }, >+ { >+ "input": "http://256.256.256.256.256", >+ "base": "http://other.com/", >+ "href": "http://256.256.256.256.256/", >+ "origin": "http://256.256.256.256.256", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "256.256.256.256.256", >+ "hostname": "256.256.256.256.256", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "https://0x.0x.0", >+ "base": "about:blank", >+ "href": "https://0.0.0.0/", >+ "origin": "https://0.0.0.0", >+ "protocol": "https:", >+ "username": "", >+ "password": "", >+ "host": "0.0.0.0", >+ "hostname": "0.0.0.0", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ "More IPv4 parsing (via https://github.com/jsdom/whatwg-url/issues/92)", >+ { >+ "input": "https://0x100000000/test", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "https://256.0.0.1/test", >+ "base": "about:blank", >+ "failure": true >+ }, >+ "# file URLs containing percent-encoded Windows drive letters (shouldn't work)", >+ { >+ "input": "file:///C%3A/", >+ "base": "about:blank", >+ "href": "file:///C%3A/", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C%3A/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file:///C%7C/", >+ "base": "about:blank", >+ "href": "file:///C%7C/", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C%7C/", >+ "search": "", >+ "hash": "" >+ }, >+ "# file URLs relative to other file URLs (via https://github.com/jsdom/whatwg-url/pull/60)", >+ { >+ "input": "pix/submit.gif", >+ "base": "file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/anchor.html", >+ "href": "file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/pix/submit.gif", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/pix/submit.gif", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "..", >+ "base": "file:///C:/", >+ "href": "file:///C:/", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C:/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "..", >+ "base": "file:///", >+ "href": "file:///", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ "# More file URL tests by zcorpan and annevk", >+ { >+ "input": "/", >+ "base": "file:///C:/a/b", >+ "href": "file:///C:/", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C:/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "//d:", >+ "base": "file:///C:/a/b", >+ "href": "file:///d:", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/d:", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "//d:/..", >+ "base": "file:///C:/a/b", >+ "href": "file:///d:/", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/d:/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "..", >+ "base": "file:///ab:/", >+ "href": "file:///", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "..", >+ "base": "file:///1:/", >+ "href": "file:///", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "", >+ "base": "file:///test?test#test", >+ "href": "file:///test?test", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/test", >+ "search": "?test", >+ "hash": "" >+ }, >+ { >+ "input": "file:", >+ "base": "file:///test?test#test", >+ "href": "file:///test?test", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/test", >+ "search": "?test", >+ "hash": "" >+ }, >+ { >+ "input": "?x", >+ "base": "file:///test?test#test", >+ "href": "file:///test?x", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/test", >+ "search": "?x", >+ "hash": "" >+ }, >+ { >+ "input": "file:?x", >+ "base": "file:///test?test#test", >+ "href": "file:///test?x", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/test", >+ "search": "?x", >+ "hash": "" >+ }, >+ { >+ "input": "#x", >+ "base": "file:///test?test#test", >+ "href": "file:///test?test#x", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/test", >+ "search": "?test", >+ "hash": "#x" >+ }, >+ { >+ "input": "file:#x", >+ "base": "file:///test?test#test", >+ "href": "file:///test?test#x", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/test", >+ "search": "?test", >+ "hash": "#x" >+ }, >+ "# File URLs and many (back)slashes", >+ { >+ "input": "file:\\\\//", >+ "base": "about:blank", >+ "href": "file:///", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file:\\\\\\\\", >+ "base": "about:blank", >+ "href": "file:///", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file:\\\\\\\\?fox", >+ "base": "about:blank", >+ "href": "file:///?fox", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "?fox", >+ "hash": "" >+ }, >+ { >+ "input": "file:\\\\\\\\#guppy", >+ "base": "about:blank", >+ "href": "file:///#guppy", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "#guppy" >+ }, >+ { >+ "input": "file://spider///", >+ "base": "about:blank", >+ "href": "file://spider/", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "spider", >+ "hostname": "spider", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file:\\\\localhost//", >+ "base": "about:blank", >+ "href": "file:///", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file:///localhost//cat", >+ "base": "about:blank", >+ "href": "file:///localhost//cat", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/localhost//cat", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file://\\/localhost//cat", >+ "base": "about:blank", >+ "href": "file:///localhost//cat", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/localhost//cat", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file://localhost//a//../..//", >+ "base": "about:blank", >+ "href": "file:///", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "/////mouse", >+ "base": "file:///elephant", >+ "href": "file:///mouse", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/mouse", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "\\//pig", >+ "base": "file://lion/", >+ "href": "file:///pig", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/pig", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "\\/localhost//pig", >+ "base": "file://lion/", >+ "href": "file:///pig", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/pig", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "//localhost//pig", >+ "base": "file://lion/", >+ "href": "file:///pig", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/pig", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "/..//localhost//pig", >+ "base": "file://lion/", >+ "href": "file://lion/localhost//pig", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "lion", >+ "hostname": "lion", >+ "port": "", >+ "pathname": "/localhost//pig", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file://", >+ "base": "file://ape/", >+ "href": "file:///", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ "# File URLs with non-empty hosts", >+ { >+ "input": "/rooibos", >+ "base": "file://tea/", >+ "href": "file://tea/rooibos", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "tea", >+ "hostname": "tea", >+ "port": "", >+ "pathname": "/rooibos", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "/?chai", >+ "base": "file://tea/", >+ "href": "file://tea/?chai", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "tea", >+ "hostname": "tea", >+ "port": "", >+ "pathname": "/", >+ "search": "?chai", >+ "hash": "" >+ }, >+ "# Windows drive letter handling with the 'file:' base URL", >+ { >+ "input": "C|", >+ "base": "file://host/dir/file", >+ "href": "file:///C:", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C:", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "C|#", >+ "base": "file://host/dir/file", >+ "href": "file:///C:#", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C:", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "C|?", >+ "base": "file://host/dir/file", >+ "href": "file:///C:?", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C:", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "C|/", >+ "base": "file://host/dir/file", >+ "href": "file:///C:/", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C:/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "C|\n/", >+ "base": "file://host/dir/file", >+ "href": "file:///C:/", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C:/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "C|\\", >+ "base": "file://host/dir/file", >+ "href": "file:///C:/", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C:/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "C", >+ "base": "file://host/dir/file", >+ "href": "file://host/dir/C", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "host", >+ "hostname": "host", >+ "port": "", >+ "pathname": "/dir/C", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "C|a", >+ "base": "file://host/dir/file", >+ "href": "file://host/dir/C|a", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "host", >+ "hostname": "host", >+ "port": "", >+ "pathname": "/dir/C|a", >+ "search": "", >+ "hash": "" >+ }, >+ "# Windows drive letter quirk in the file slash state", >+ { >+ "input": "/c:/foo/bar", >+ "base": "file:///c:/baz/qux", >+ "href": "file:///c:/foo/bar", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/c:/foo/bar", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "/c|/foo/bar", >+ "base": "file:///c:/baz/qux", >+ "href": "file:///c:/foo/bar", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/c:/foo/bar", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file:\\c:\\foo\\bar", >+ "base": "file:///c:/baz/qux", >+ "href": "file:///c:/foo/bar", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/c:/foo/bar", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "/c:/foo/bar", >+ "base": "file://host/path", >+ "href": "file:///c:/foo/bar", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/c:/foo/bar", >+ "search": "", >+ "hash": "" >+ }, >+ "# Windows drive letter quirk with not empty host", >+ { >+ "input": "file://example.net/C:/", >+ "base": "about:blank", >+ "href": "file:///C:/", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C:/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file://1.2.3.4/C:/", >+ "base": "about:blank", >+ "href": "file:///C:/", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C:/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file://[1::8]/C:/", >+ "base": "about:blank", >+ "href": "file:///C:/", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C:/", >+ "search": "", >+ "hash": "" >+ }, >+ "# Windows drive letter quirk (no host)", >+ { >+ "input": "file:/C|/", >+ "base": "about:blank", >+ "href": "file:///C:/", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C:/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file://C|/", >+ "base": "about:blank", >+ "href": "file:///C:/", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/C:/", >+ "search": "", >+ "hash": "" >+ }, >+ "# file URLs without base URL by Rimas MiseviÄius", >+ { >+ "input": "file:", >+ "base": "about:blank", >+ "href": "file:///", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "file:?q=v", >+ "base": "about:blank", >+ "href": "file:///?q=v", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "?q=v", >+ "hash": "" >+ }, >+ { >+ "input": "file:#frag", >+ "base": "about:blank", >+ "href": "file:///#frag", >+ "protocol": "file:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "#frag" >+ }, >+ "# IPv6 tests", >+ { >+ "input": "http://[1:0::]", >+ "base": "http://example.net/", >+ "href": "http://[1::]/", >+ "origin": "http://[1::]", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "[1::]", >+ "hostname": "[1::]", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://[0:1:2:3:4:5:6:7:8]", >+ "base": "http://example.net/", >+ "failure": true >+ }, >+ { >+ "input": "https://[0::0::0]", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "https://[0:.0]", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "https://[0:0:]", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "https://[0:1:2:3:4:5:6:7.0.0.0.1]", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "https://[0:1.00.0.0.0]", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "https://[0:1.290.0.0.0]", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "https://[0:1.23.23]", >+ "base": "about:blank", >+ "failure": true >+ }, >+ "# Empty host", >+ { >+ "input": "http://?", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "http://#", >+ "base": "about:blank", >+ "failure": true >+ }, >+ "Port overflow (2^32 + 81)", >+ { >+ "input": "http://f:4294967377/c", >+ "base": "http://example.org/", >+ "failure": true >+ }, >+ "Port overflow (2^64 + 81)", >+ { >+ "input": "http://f:18446744073709551697/c", >+ "base": "http://example.org/", >+ "failure": true >+ }, >+ "Port overflow (2^128 + 81)", >+ { >+ "input": "http://f:340282366920938463463374607431768211537/c", >+ "base": "http://example.org/", >+ "failure": true >+ }, >+ "# Non-special-URL path tests", >+ { >+ "input": "sc://ñ", >+ "base": "about:blank", >+ "href": "sc://%C3%B1", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "%C3%B1", >+ "hostname": "%C3%B1", >+ "port": "", >+ "pathname": "", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "sc://ñ?x", >+ "base": "about:blank", >+ "href": "sc://%C3%B1?x", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "%C3%B1", >+ "hostname": "%C3%B1", >+ "port": "", >+ "pathname": "", >+ "search": "?x", >+ "hash": "" >+ }, >+ { >+ "input": "sc://ñ#x", >+ "base": "about:blank", >+ "href": "sc://%C3%B1#x", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "%C3%B1", >+ "hostname": "%C3%B1", >+ "port": "", >+ "pathname": "", >+ "search": "", >+ "hash": "#x" >+ }, >+ { >+ "input": "#x", >+ "base": "sc://ñ", >+ "href": "sc://%C3%B1#x", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "%C3%B1", >+ "hostname": "%C3%B1", >+ "port": "", >+ "pathname": "", >+ "search": "", >+ "hash": "#x" >+ }, >+ { >+ "input": "?x", >+ "base": "sc://ñ", >+ "href": "sc://%C3%B1?x", >+ "origin": "null", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "%C3%B1", >+ "hostname": "%C3%B1", >+ "port": "", >+ "pathname": "", >+ "search": "?x", >+ "hash": "" >+ }, >+ { >+ "input": "sc://?", >+ "base": "about:blank", >+ "href": "sc://?", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "sc://#", >+ "base": "about:blank", >+ "href": "sc://#", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "///", >+ "base": "sc://x/", >+ "href": "sc:///", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "////", >+ "base": "sc://x/", >+ "href": "sc:////", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "//", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "////x/", >+ "base": "sc://x/", >+ "href": "sc:////x/", >+ "protocol": "sc:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "//x/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "tftp://foobar.com/someconfig;mode=netascii", >+ "base": "about:blank", >+ "href": "tftp://foobar.com/someconfig;mode=netascii", >+ "origin": "null", >+ "protocol": "tftp:", >+ "username": "", >+ "password": "", >+ "host": "foobar.com", >+ "hostname": "foobar.com", >+ "port": "", >+ "pathname": "/someconfig;mode=netascii", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "telnet://user:pass@foobar.com:23/", >+ "base": "about:blank", >+ "href": "telnet://user:pass@foobar.com:23/", >+ "origin": "null", >+ "protocol": "telnet:", >+ "username": "user", >+ "password": "pass", >+ "host": "foobar.com:23", >+ "hostname": "foobar.com", >+ "port": "23", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "ut2004://10.10.10.10:7777/Index.ut2", >+ "base": "about:blank", >+ "href": "ut2004://10.10.10.10:7777/Index.ut2", >+ "origin": "null", >+ "protocol": "ut2004:", >+ "username": "", >+ "password": "", >+ "host": "10.10.10.10:7777", >+ "hostname": "10.10.10.10", >+ "port": "7777", >+ "pathname": "/Index.ut2", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "redis://foo:bar@somehost:6379/0?baz=bam&qux=baz", >+ "base": "about:blank", >+ "href": "redis://foo:bar@somehost:6379/0?baz=bam&qux=baz", >+ "origin": "null", >+ "protocol": "redis:", >+ "username": "foo", >+ "password": "bar", >+ "host": "somehost:6379", >+ "hostname": "somehost", >+ "port": "6379", >+ "pathname": "/0", >+ "search": "?baz=bam&qux=baz", >+ "hash": "" >+ }, >+ { >+ "input": "rsync://foo@host:911/sup", >+ "base": "about:blank", >+ "href": "rsync://foo@host:911/sup", >+ "origin": "null", >+ "protocol": "rsync:", >+ "username": "foo", >+ "password": "", >+ "host": "host:911", >+ "hostname": "host", >+ "port": "911", >+ "pathname": "/sup", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "git://github.com/foo/bar.git", >+ "base": "about:blank", >+ "href": "git://github.com/foo/bar.git", >+ "origin": "null", >+ "protocol": "git:", >+ "username": "", >+ "password": "", >+ "host": "github.com", >+ "hostname": "github.com", >+ "port": "", >+ "pathname": "/foo/bar.git", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "irc://myserver.com:6999/channel?passwd", >+ "base": "about:blank", >+ "href": "irc://myserver.com:6999/channel?passwd", >+ "origin": "null", >+ "protocol": "irc:", >+ "username": "", >+ "password": "", >+ "host": "myserver.com:6999", >+ "hostname": "myserver.com", >+ "port": "6999", >+ "pathname": "/channel", >+ "search": "?passwd", >+ "hash": "" >+ }, >+ { >+ "input": "dns://fw.example.org:9999/foo.bar.org?type=TXT", >+ "base": "about:blank", >+ "href": "dns://fw.example.org:9999/foo.bar.org?type=TXT", >+ "origin": "null", >+ "protocol": "dns:", >+ "username": "", >+ "password": "", >+ "host": "fw.example.org:9999", >+ "hostname": "fw.example.org", >+ "port": "9999", >+ "pathname": "/foo.bar.org", >+ "search": "?type=TXT", >+ "hash": "" >+ }, >+ { >+ "input": "ldap://localhost:389/ou=People,o=JNDITutorial", >+ "base": "about:blank", >+ "href": "ldap://localhost:389/ou=People,o=JNDITutorial", >+ "origin": "null", >+ "protocol": "ldap:", >+ "username": "", >+ "password": "", >+ "host": "localhost:389", >+ "hostname": "localhost", >+ "port": "389", >+ "pathname": "/ou=People,o=JNDITutorial", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "git+https://github.com/foo/bar", >+ "base": "about:blank", >+ "href": "git+https://github.com/foo/bar", >+ "origin": "null", >+ "protocol": "git+https:", >+ "username": "", >+ "password": "", >+ "host": "github.com", >+ "hostname": "github.com", >+ "port": "", >+ "pathname": "/foo/bar", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "urn:ietf:rfc:2648", >+ "base": "about:blank", >+ "href": "urn:ietf:rfc:2648", >+ "origin": "null", >+ "protocol": "urn:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "ietf:rfc:2648", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "tag:joe@example.org,2001:foo/bar", >+ "base": "about:blank", >+ "href": "tag:joe@example.org,2001:foo/bar", >+ "origin": "null", >+ "protocol": "tag:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "joe@example.org,2001:foo/bar", >+ "search": "", >+ "hash": "" >+ }, >+ "# percent encoded hosts in non-special-URLs", >+ { >+ "input": "non-special://%E2%80%A0/", >+ "base": "about:blank", >+ "href": "non-special://%E2%80%A0/", >+ "protocol": "non-special:", >+ "username": "", >+ "password": "", >+ "host": "%E2%80%A0", >+ "hostname": "%E2%80%A0", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "non-special://H%4fSt/path", >+ "base": "about:blank", >+ "href": "non-special://H%4fSt/path", >+ "protocol": "non-special:", >+ "username": "", >+ "password": "", >+ "host": "H%4fSt", >+ "hostname": "H%4fSt", >+ "port": "", >+ "pathname": "/path", >+ "search": "", >+ "hash": "" >+ }, >+ "# IPv6 in non-special-URLs", >+ { >+ "input": "non-special://[1:2:0:0:5:0:0:0]/", >+ "base": "about:blank", >+ "href": "non-special://[1:2:0:0:5::]/", >+ "protocol": "non-special:", >+ "username": "", >+ "password": "", >+ "host": "[1:2:0:0:5::]", >+ "hostname": "[1:2:0:0:5::]", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "non-special://[1:2:0:0:0:0:0:3]/", >+ "base": "about:blank", >+ "href": "non-special://[1:2::3]/", >+ "protocol": "non-special:", >+ "username": "", >+ "password": "", >+ "host": "[1:2::3]", >+ "hostname": "[1:2::3]", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "non-special://[1:2::3]:80/", >+ "base": "about:blank", >+ "href": "non-special://[1:2::3]:80/", >+ "protocol": "non-special:", >+ "username": "", >+ "password": "", >+ "host": "[1:2::3]:80", >+ "hostname": "[1:2::3]", >+ "port": "80", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "non-special://[:80/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "blob:https://example.com:443/", >+ "base": "about:blank", >+ "href": "blob:https://example.com:443/", >+ "protocol": "blob:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "https://example.com:443/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "blob:d3958f5c-0777-0845-9dcf-2cb28783acaf", >+ "base": "about:blank", >+ "href": "blob:d3958f5c-0777-0845-9dcf-2cb28783acaf", >+ "protocol": "blob:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "d3958f5c-0777-0845-9dcf-2cb28783acaf", >+ "search": "", >+ "hash": "" >+ }, >+ "Invalid IPv4 radix digits", >+ { >+ "input": "http://0177.0.0.0189", >+ "base": "about:blank", >+ "href": "http://0177.0.0.0189/", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "0177.0.0.0189", >+ "hostname": "0177.0.0.0189", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://0x7f.0.0.0x7g", >+ "base": "about:blank", >+ "href": "http://0x7f.0.0.0x7g/", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "0x7f.0.0.0x7g", >+ "hostname": "0x7f.0.0.0x7g", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://0X7F.0.0.0X7G", >+ "base": "about:blank", >+ "href": "http://0x7f.0.0.0x7g/", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "0x7f.0.0.0x7g", >+ "hostname": "0x7f.0.0.0x7g", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ "Invalid IPv4 portion of IPv6 address", >+ { >+ "input": "http://[::127.0.0.0.1]", >+ "base": "about:blank", >+ "failure": true >+ }, >+ "Uncompressed IPv6 addresses with 0", >+ { >+ "input": "http://[0:1:0:1:0:1:0:1]", >+ "base": "about:blank", >+ "href": "http://[0:1:0:1:0:1:0:1]/", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "[0:1:0:1:0:1:0:1]", >+ "hostname": "[0:1:0:1:0:1:0:1]", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://[1:0:1:0:1:0:1:0]", >+ "base": "about:blank", >+ "href": "http://[1:0:1:0:1:0:1:0]/", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "[1:0:1:0:1:0:1:0]", >+ "hostname": "[1:0:1:0:1:0:1:0]", >+ "port": "", >+ "pathname": "/", >+ "search": "", >+ "hash": "" >+ }, >+ "Percent-encoded query and fragment", >+ { >+ "input": "http://example.org/test?\u0022", >+ "base": "about:blank", >+ "href": "http://example.org/test?%22", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/test", >+ "search": "?%22", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.org/test?\u0023", >+ "base": "about:blank", >+ "href": "http://example.org/test?#", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/test", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.org/test?\u003C", >+ "base": "about:blank", >+ "href": "http://example.org/test?%3C", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/test", >+ "search": "?%3C", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.org/test?\u003E", >+ "base": "about:blank", >+ "href": "http://example.org/test?%3E", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/test", >+ "search": "?%3E", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.org/test?\u2323", >+ "base": "about:blank", >+ "href": "http://example.org/test?%E2%8C%A3", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/test", >+ "search": "?%E2%8C%A3", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.org/test?%23%23", >+ "base": "about:blank", >+ "href": "http://example.org/test?%23%23", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/test", >+ "search": "?%23%23", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.org/test?%GH", >+ "base": "about:blank", >+ "href": "http://example.org/test?%GH", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/test", >+ "search": "?%GH", >+ "hash": "" >+ }, >+ { >+ "input": "http://example.org/test?a#%EF", >+ "base": "about:blank", >+ "href": "http://example.org/test?a#%EF", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/test", >+ "search": "?a", >+ "hash": "#%EF" >+ }, >+ { >+ "input": "http://example.org/test?a#%GH", >+ "base": "about:blank", >+ "href": "http://example.org/test?a#%GH", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/test", >+ "search": "?a", >+ "hash": "#%GH" >+ }, >+ "URLs that require a non-about:blank base. (Also serve as invalid base tests.)", >+ { >+ "input": "a", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "a/", >+ "base": "about:blank", >+ "failure": true >+ }, >+ { >+ "input": "a//", >+ "base": "about:blank", >+ "failure": true >+ }, >+ "Bases that don't fail to parse but fail to be bases", >+ { >+ "input": "test-a-colon.html", >+ "base": "a:", >+ "failure": true >+ }, >+ { >+ "input": "test-a-colon-b.html", >+ "base": "a:b", >+ "failure": true >+ }, >+ "Other base URL tests, that must succeed", >+ { >+ "input": "test-a-colon-slash.html", >+ "base": "a:/", >+ "href": "a:/test-a-colon-slash.html", >+ "protocol": "a:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/test-a-colon-slash.html", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "test-a-colon-slash-slash.html", >+ "base": "a://", >+ "href": "a:///test-a-colon-slash-slash.html", >+ "protocol": "a:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/test-a-colon-slash-slash.html", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "test-a-colon-slash-b.html", >+ "base": "a:/b", >+ "href": "a:/test-a-colon-slash-b.html", >+ "protocol": "a:", >+ "username": "", >+ "password": "", >+ "host": "", >+ "hostname": "", >+ "port": "", >+ "pathname": "/test-a-colon-slash-b.html", >+ "search": "", >+ "hash": "" >+ }, >+ { >+ "input": "test-a-colon-slash-slash-b.html", >+ "base": "a://b", >+ "href": "a://b/test-a-colon-slash-slash-b.html", >+ "protocol": "a:", >+ "username": "", >+ "password": "", >+ "host": "b", >+ "hostname": "b", >+ "port": "", >+ "pathname": "/test-a-colon-slash-slash-b.html", >+ "search": "", >+ "hash": "" >+ }, >+ "Null code point in fragment", >+ { >+ "input": "http://example.org/test?a#b\u0000c", >+ "base": "about:blank", >+ "href": "http://example.org/test?a#bc", >+ "protocol": "http:", >+ "username": "", >+ "password": "", >+ "host": "example.org", >+ "hostname": "example.org", >+ "port": "", >+ "pathname": "/test", >+ "search": "?a", >+ "hash": "#bc" >+ } >+] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/resources/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/url/resources/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..76f7a6206de286d7a36365aaf3d961a762d8e88a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/resources/w3c-import.log >@@ -0,0 +1,21 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/url/resources/a-element-origin.js >+/LayoutTests/imported/w3c/web-platform-tests/url/resources/a-element.js >+/LayoutTests/imported/w3c/web-platform-tests/url/resources/setters_tests.json >+/LayoutTests/imported/w3c/web-platform-tests/url/resources/toascii.json >+/LayoutTests/imported/w3c/web-platform-tests/url/resources/urltestdata.json >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/setters_tests.json b/LayoutTests/imported/w3c/web-platform-tests/url/setters_tests.json >deleted file mode 100644 >index 714bd5e7ce234ac914fd5813f2dfffdfde1fae02..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/setters_tests.json >+++ /dev/null >@@ -1,1855 +0,0 @@ >-{ >- "comment": [ >- "## Tests for setters of https://url.spec.whatwg.org/#urlutils-members", >- "", >- "This file contains a JSON object.", >- "Other than 'comment', each key is an attribute of the `URL` interface", >- "defined in WHATWGâs URL Standard.", >- "The values are arrays of test case objects for that attribute.", >- "", >- "To run a test case for the attribute `attr`:", >- "", >- "* Create a new `URL` object with the value for the 'href' key", >- " the constructor single parameter. (Without a base URL.)", >- " This must not throw.", >- "* Set the attribute `attr` to (invoke its setter with)", >- " with the value of for 'new_value' key.", >- "* The value for the 'expected' key is another object.", >- " For each `key` / `value` pair of that object,", >- " get the attribute `key` (invoke its getter).", >- " The returned string must be equal to `value`.", >- "", >- "Note: the 'href' setter is already covered by urltestdata.json." >- ], >- "protocol": [ >- { >- "comment": "The empty string is not a valid scheme. Setter leaves the URL unchanged.", >- "href": "a://example.net", >- "new_value": "", >- "expected": { >- "href": "a://example.net", >- "protocol": "a:" >- } >- }, >- { >- "href": "a://example.net", >- "new_value": "b", >- "expected": { >- "href": "b://example.net", >- "protocol": "b:" >- } >- }, >- { >- "href": "javascript:alert(1)", >- "new_value": "defuse", >- "expected": { >- "href": "defuse:alert(1)", >- "protocol": "defuse:" >- } >- }, >- { >- "comment": "Upper-case ASCII is lower-cased", >- "href": "a://example.net", >- "new_value": "B", >- "expected": { >- "href": "b://example.net", >- "protocol": "b:" >- } >- }, >- { >- "comment": "Non-ASCII is rejected", >- "href": "a://example.net", >- "new_value": "é", >- "expected": { >- "href": "a://example.net", >- "protocol": "a:" >- } >- }, >- { >- "comment": "No leading digit", >- "href": "a://example.net", >- "new_value": "0b", >- "expected": { >- "href": "a://example.net", >- "protocol": "a:" >- } >- }, >- { >- "comment": "No leading punctuation", >- "href": "a://example.net", >- "new_value": "+b", >- "expected": { >- "href": "a://example.net", >- "protocol": "a:" >- } >- }, >- { >- "href": "a://example.net", >- "new_value": "bC0+-.", >- "expected": { >- "href": "bc0+-.://example.net", >- "protocol": "bc0+-.:" >- } >- }, >- { >- "comment": "Only some punctuation is acceptable", >- "href": "a://example.net", >- "new_value": "b,c", >- "expected": { >- "href": "a://example.net", >- "protocol": "a:" >- } >- }, >- { >- "comment": "Non-ASCII is rejected", >- "href": "a://example.net", >- "new_value": "bé", >- "expected": { >- "href": "a://example.net", >- "protocol": "a:" >- } >- }, >- { >- "comment": "Canât switch from URL containing username/password/port to file", >- "href": "http://test@example.net", >- "new_value": "file", >- "expected": { >- "href": "http://test@example.net/", >- "protocol": "http:" >- } >- }, >- { >- "href": "gopher://example.net:1234", >- "new_value": "file", >- "expected": { >- "href": "gopher://example.net:1234/", >- "protocol": "gopher:" >- } >- }, >- { >- "href": "wss://x:x@example.net:1234", >- "new_value": "file", >- "expected": { >- "href": "wss://x:x@example.net:1234/", >- "protocol": "wss:" >- } >- }, >- { >- "comment": "Canât switch from file URL with no host", >- "href": "file://localhost/", >- "new_value": "http", >- "expected": { >- "href": "file:///", >- "protocol": "file:" >- } >- }, >- { >- "href": "file:///test", >- "new_value": "gopher", >- "expected": { >- "href": "file:///test", >- "protocol": "file:" >- } >- }, >- { >- "href": "file:", >- "new_value": "wss", >- "expected": { >- "href": "file:///", >- "protocol": "file:" >- } >- }, >- { >- "comment": "Canât switch from special scheme to non-special", >- "href": "http://example.net", >- "new_value": "b", >- "expected": { >- "href": "http://example.net/", >- "protocol": "http:" >- } >- }, >- { >- "href": "file://hi/path", >- "new_value": "s", >- "expected": { >- "href": "file://hi/path", >- "protocol": "file:" >- } >- }, >- { >- "href": "https://example.net", >- "new_value": "s", >- "expected": { >- "href": "https://example.net/", >- "protocol": "https:" >- } >- }, >- { >- "href": "ftp://example.net", >- "new_value": "test", >- "expected": { >- "href": "ftp://example.net/", >- "protocol": "ftp:" >- } >- }, >- { >- "comment": "Cannot-be-a-base URL doesnât have a host, but URL in a special scheme must.", >- "href": "mailto:me@example.net", >- "new_value": "http", >- "expected": { >- "href": "mailto:me@example.net", >- "protocol": "mailto:" >- } >- }, >- { >- "comment": "Canât switch from non-special scheme to special", >- "href": "ssh://me@example.net", >- "new_value": "http", >- "expected": { >- "href": "ssh://me@example.net", >- "protocol": "ssh:" >- } >- }, >- { >- "href": "ssh://me@example.net", >- "new_value": "gopher", >- "expected": { >- "href": "ssh://me@example.net", >- "protocol": "ssh:" >- } >- }, >- { >- "href": "ssh://me@example.net", >- "new_value": "file", >- "expected": { >- "href": "ssh://me@example.net", >- "protocol": "ssh:" >- } >- }, >- { >- "href": "ssh://example.net", >- "new_value": "file", >- "expected": { >- "href": "ssh://example.net", >- "protocol": "ssh:" >- } >- }, >- { >- "href": "nonsense:///test", >- "new_value": "https", >- "expected": { >- "href": "nonsense:///test", >- "protocol": "nonsense:" >- } >- }, >- { >- "comment": "Stuff after the first ':' is ignored", >- "href": "http://example.net", >- "new_value": "https:foo : bar", >- "expected": { >- "href": "https://example.net/", >- "protocol": "https:" >- } >- }, >- { >- "comment": "Stuff after the first ':' is ignored", >- "href": "data:text/html,<p>Test", >- "new_value": "view-source+data:foo : bar", >- "expected": { >- "href": "view-source+data:text/html,<p>Test", >- "protocol": "view-source+data:" >- } >- }, >- { >- "comment": "Port is set to null if it is the default for new scheme.", >- "href": "http://foo.com:443/", >- "new_value": "https", >- "expected": { >- "href": "https://foo.com/", >- "protocol": "https:", >- "port": "" >- } >- } >- ], >- "username": [ >- { >- "comment": "No host means no username", >- "href": "file:///home/you/index.html", >- "new_value": "me", >- "expected": { >- "href": "file:///home/you/index.html", >- "username": "" >- } >- }, >- { >- "comment": "No host means no username", >- "href": "unix:/run/foo.socket", >- "new_value": "me", >- "expected": { >- "href": "unix:/run/foo.socket", >- "username": "" >- } >- }, >- { >- "comment": "Cannot-be-a-base means no username", >- "href": "mailto:you@example.net", >- "new_value": "me", >- "expected": { >- "href": "mailto:you@example.net", >- "username": "" >- } >- }, >- { >- "href": "javascript:alert(1)", >- "new_value": "wario", >- "expected": { >- "href": "javascript:alert(1)", >- "username": "" >- } >- }, >- { >- "href": "http://example.net", >- "new_value": "me", >- "expected": { >- "href": "http://me@example.net/", >- "username": "me" >- } >- }, >- { >- "href": "http://:secret@example.net", >- "new_value": "me", >- "expected": { >- "href": "http://me:secret@example.net/", >- "username": "me" >- } >- }, >- { >- "href": "http://me@example.net", >- "new_value": "", >- "expected": { >- "href": "http://example.net/", >- "username": "" >- } >- }, >- { >- "href": "http://me:secret@example.net", >- "new_value": "", >- "expected": { >- "href": "http://:secret@example.net/", >- "username": "" >- } >- }, >- { >- "comment": "UTF-8 percent encoding with the userinfo encode set.", >- "href": "http://example.net", >- "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Ãé", >- "expected": { >- "href": "http://%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9@example.net/", >- "username": "%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9" >- } >- }, >- { >- "comment": "Bytes already percent-encoded are left as-is.", >- "href": "http://example.net", >- "new_value": "%c3%89té", >- "expected": { >- "href": "http://%c3%89t%C3%A9@example.net/", >- "username": "%c3%89t%C3%A9" >- } >- }, >- { >- "href": "sc:///", >- "new_value": "x", >- "expected": { >- "href": "sc:///", >- "username": "" >- } >- }, >- { >- "href": "javascript://x/", >- "new_value": "wario", >- "expected": { >- "href": "javascript://wario@x/", >- "username": "wario" >- } >- }, >- { >- "href": "file://test/", >- "new_value": "test", >- "expected": { >- "href": "file://test/", >- "username": "" >- } >- } >- ], >- "password": [ >- { >- "comment": "No host means no password", >- "href": "file:///home/me/index.html", >- "new_value": "secret", >- "expected": { >- "href": "file:///home/me/index.html", >- "password": "" >- } >- }, >- { >- "comment": "No host means no password", >- "href": "unix:/run/foo.socket", >- "new_value": "secret", >- "expected": { >- "href": "unix:/run/foo.socket", >- "password": "" >- } >- }, >- { >- "comment": "Cannot-be-a-base means no password", >- "href": "mailto:me@example.net", >- "new_value": "secret", >- "expected": { >- "href": "mailto:me@example.net", >- "password": "" >- } >- }, >- { >- "href": "http://example.net", >- "new_value": "secret", >- "expected": { >- "href": "http://:secret@example.net/", >- "password": "secret" >- } >- }, >- { >- "href": "http://me@example.net", >- "new_value": "secret", >- "expected": { >- "href": "http://me:secret@example.net/", >- "password": "secret" >- } >- }, >- { >- "href": "http://:secret@example.net", >- "new_value": "", >- "expected": { >- "href": "http://example.net/", >- "password": "" >- } >- }, >- { >- "href": "http://me:secret@example.net", >- "new_value": "", >- "expected": { >- "href": "http://me@example.net/", >- "password": "" >- } >- }, >- { >- "comment": "UTF-8 percent encoding with the userinfo encode set.", >- "href": "http://example.net", >- "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Ãé", >- "expected": { >- "href": "http://:%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9@example.net/", >- "password": "%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9" >- } >- }, >- { >- "comment": "Bytes already percent-encoded are left as-is.", >- "href": "http://example.net", >- "new_value": "%c3%89té", >- "expected": { >- "href": "http://:%c3%89t%C3%A9@example.net/", >- "password": "%c3%89t%C3%A9" >- } >- }, >- { >- "href": "sc:///", >- "new_value": "x", >- "expected": { >- "href": "sc:///", >- "password": "" >- } >- }, >- { >- "href": "javascript://x/", >- "new_value": "bowser", >- "expected": { >- "href": "javascript://:bowser@x/", >- "password": "bowser" >- } >- }, >- { >- "href": "file://test/", >- "new_value": "test", >- "expected": { >- "href": "file://test/", >- "password": "" >- } >- } >- ], >- "host": [ >- { >- "comment": "Non-special scheme", >- "href": "sc://x/", >- "new_value": "\u0000", >- "expected": { >- "href": "sc://x/", >- "host": "x", >- "hostname": "x" >- } >- }, >- { >- "href": "sc://x/", >- "new_value": "\u0009", >- "expected": { >- "href": "sc:///", >- "host": "", >- "hostname": "" >- } >- }, >- { >- "href": "sc://x/", >- "new_value": "\u000A", >- "expected": { >- "href": "sc:///", >- "host": "", >- "hostname": "" >- } >- }, >- { >- "href": "sc://x/", >- "new_value": "\u000D", >- "expected": { >- "href": "sc:///", >- "host": "", >- "hostname": "" >- } >- }, >- { >- "href": "sc://x/", >- "new_value": " ", >- "expected": { >- "href": "sc://x/", >- "host": "x", >- "hostname": "x" >- } >- }, >- { >- "href": "sc://x/", >- "new_value": "#", >- "expected": { >- "href": "sc:///", >- "host": "", >- "hostname": "" >- } >- }, >- { >- "href": "sc://x/", >- "new_value": "/", >- "expected": { >- "href": "sc:///", >- "host": "", >- "hostname": "" >- } >- }, >- { >- "href": "sc://x/", >- "new_value": "?", >- "expected": { >- "href": "sc:///", >- "host": "", >- "hostname": "" >- } >- }, >- { >- "href": "sc://x/", >- "new_value": "@", >- "expected": { >- "href": "sc://x/", >- "host": "x", >- "hostname": "x" >- } >- }, >- { >- "href": "sc://x/", >- "new_value": "Ã", >- "expected": { >- "href": "sc://%C3%9F/", >- "host": "%C3%9F", >- "hostname": "%C3%9F" >- } >- }, >- { >- "comment": "IDNA Nontransitional_Processing", >- "href": "https://x/", >- "new_value": "Ã", >- "expected": { >- "href": "https://xn--zca/", >- "host": "xn--zca", >- "hostname": "xn--zca" >- } >- }, >- { >- "comment": "Cannot-be-a-base means no host", >- "href": "mailto:me@example.net", >- "new_value": "example.com", >- "expected": { >- "href": "mailto:me@example.net", >- "host": "" >- } >- }, >- { >- "comment": "Cannot-be-a-base means no password", >- "href": "data:text/plain,Stuff", >- "new_value": "example.net", >- "expected": { >- "href": "data:text/plain,Stuff", >- "host": "" >- } >- }, >- { >- "href": "http://example.net", >- "new_value": "example.com:8080", >- "expected": { >- "href": "http://example.com:8080/", >- "host": "example.com:8080", >- "hostname": "example.com", >- "port": "8080" >- } >- }, >- { >- "comment": "Port number is unchanged if not specified in the new value", >- "href": "http://example.net:8080", >- "new_value": "example.com", >- "expected": { >- "href": "http://example.com:8080/", >- "host": "example.com:8080", >- "hostname": "example.com", >- "port": "8080" >- } >- }, >- { >- "comment": "Port number is unchanged if not specified", >- "href": "http://example.net:8080", >- "new_value": "example.com:", >- "expected": { >- "href": "http://example.com:8080/", >- "host": "example.com:8080", >- "hostname": "example.com", >- "port": "8080" >- } >- }, >- { >- "comment": "The empty host is not valid for special schemes", >- "href": "http://example.net", >- "new_value": "", >- "expected": { >- "href": "http://example.net/", >- "host": "example.net" >- } >- }, >- { >- "comment": "The empty host is OK for non-special schemes", >- "href": "view-source+http://example.net/foo", >- "new_value": "", >- "expected": { >- "href": "view-source+http:///foo", >- "host": "" >- } >- }, >- { >- "comment": "Path-only URLs can gain a host", >- "href": "a:/foo", >- "new_value": "example.net", >- "expected": { >- "href": "a://example.net/foo", >- "host": "example.net" >- } >- }, >- { >- "comment": "IPv4 address syntax is normalized", >- "href": "http://example.net", >- "new_value": "0x7F000001:8080", >- "expected": { >- "href": "http://127.0.0.1:8080/", >- "host": "127.0.0.1:8080", >- "hostname": "127.0.0.1", >- "port": "8080" >- } >- }, >- { >- "comment": "IPv6 address syntax is normalized", >- "href": "http://example.net", >- "new_value": "[::0:01]:2", >- "expected": { >- "href": "http://[::1]:2/", >- "host": "[::1]:2", >- "hostname": "[::1]", >- "port": "2" >- } >- }, >- { >- "comment": "Default port number is removed", >- "href": "http://example.net", >- "new_value": "example.com:80", >- "expected": { >- "href": "http://example.com/", >- "host": "example.com", >- "hostname": "example.com", >- "port": "" >- } >- }, >- { >- "comment": "Default port number is removed", >- "href": "https://example.net", >- "new_value": "example.com:443", >- "expected": { >- "href": "https://example.com/", >- "host": "example.com", >- "hostname": "example.com", >- "port": "" >- } >- }, >- { >- "comment": "Default port number is only removed for the relevant scheme", >- "href": "https://example.net", >- "new_value": "example.com:80", >- "expected": { >- "href": "https://example.com:80/", >- "host": "example.com:80", >- "hostname": "example.com", >- "port": "80" >- } >- }, >- { >- "comment": "Stuff after a / delimiter is ignored", >- "href": "http://example.net/path", >- "new_value": "example.com/stuff", >- "expected": { >- "href": "http://example.com/path", >- "host": "example.com", >- "hostname": "example.com", >- "port": "" >- } >- }, >- { >- "comment": "Stuff after a / delimiter is ignored", >- "href": "http://example.net/path", >- "new_value": "example.com:8080/stuff", >- "expected": { >- "href": "http://example.com:8080/path", >- "host": "example.com:8080", >- "hostname": "example.com", >- "port": "8080" >- } >- }, >- { >- "comment": "Stuff after a ? delimiter is ignored", >- "href": "http://example.net/path", >- "new_value": "example.com?stuff", >- "expected": { >- "href": "http://example.com/path", >- "host": "example.com", >- "hostname": "example.com", >- "port": "" >- } >- }, >- { >- "comment": "Stuff after a ? delimiter is ignored", >- "href": "http://example.net/path", >- "new_value": "example.com:8080?stuff", >- "expected": { >- "href": "http://example.com:8080/path", >- "host": "example.com:8080", >- "hostname": "example.com", >- "port": "8080" >- } >- }, >- { >- "comment": "Stuff after a # delimiter is ignored", >- "href": "http://example.net/path", >- "new_value": "example.com#stuff", >- "expected": { >- "href": "http://example.com/path", >- "host": "example.com", >- "hostname": "example.com", >- "port": "" >- } >- }, >- { >- "comment": "Stuff after a # delimiter is ignored", >- "href": "http://example.net/path", >- "new_value": "example.com:8080#stuff", >- "expected": { >- "href": "http://example.com:8080/path", >- "host": "example.com:8080", >- "hostname": "example.com", >- "port": "8080" >- } >- }, >- { >- "comment": "Stuff after a \\ delimiter is ignored for special schemes", >- "href": "http://example.net/path", >- "new_value": "example.com\\stuff", >- "expected": { >- "href": "http://example.com/path", >- "host": "example.com", >- "hostname": "example.com", >- "port": "" >- } >- }, >- { >- "comment": "Stuff after a \\ delimiter is ignored for special schemes", >- "href": "http://example.net/path", >- "new_value": "example.com:8080\\stuff", >- "expected": { >- "href": "http://example.com:8080/path", >- "host": "example.com:8080", >- "hostname": "example.com", >- "port": "8080" >- } >- }, >- { >- "comment": "\\ is not a delimiter for non-special schemes, but still forbidden in hosts", >- "href": "view-source+http://example.net/path", >- "new_value": "example.com\\stuff", >- "expected": { >- "href": "view-source+http://example.net/path", >- "host": "example.net", >- "hostname": "example.net", >- "port": "" >- } >- }, >- { >- "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", >- "href": "view-source+http://example.net/path", >- "new_value": "example.com:8080stuff2", >- "expected": { >- "href": "view-source+http://example.com:8080/path", >- "host": "example.com:8080", >- "hostname": "example.com", >- "port": "8080" >- } >- }, >- { >- "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", >- "href": "http://example.net/path", >- "new_value": "example.com:8080stuff2", >- "expected": { >- "href": "http://example.com:8080/path", >- "host": "example.com:8080", >- "hostname": "example.com", >- "port": "8080" >- } >- }, >- { >- "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", >- "href": "http://example.net/path", >- "new_value": "example.com:8080+2", >- "expected": { >- "href": "http://example.com:8080/path", >- "host": "example.com:8080", >- "hostname": "example.com", >- "port": "8080" >- } >- }, >- { >- "comment": "Port numbers are 16 bit integers", >- "href": "http://example.net/path", >- "new_value": "example.com:65535", >- "expected": { >- "href": "http://example.com:65535/path", >- "host": "example.com:65535", >- "hostname": "example.com", >- "port": "65535" >- } >- }, >- { >- "comment": "Port numbers are 16 bit integers, overflowing is an error. Hostname is still set, though.", >- "href": "http://example.net/path", >- "new_value": "example.com:65536", >- "expected": { >- "href": "http://example.com/path", >- "host": "example.com", >- "hostname": "example.com", >- "port": "" >- } >- }, >- { >- "comment": "Broken IPv6", >- "href": "http://example.net/", >- "new_value": "[google.com]", >- "expected": { >- "href": "http://example.net/", >- "host": "example.net", >- "hostname": "example.net" >- } >- }, >- { >- "href": "http://example.net/", >- "new_value": "[::1.2.3.4x]", >- "expected": { >- "href": "http://example.net/", >- "host": "example.net", >- "hostname": "example.net" >- } >- }, >- { >- "href": "http://example.net/", >- "new_value": "[::1.2.3.]", >- "expected": { >- "href": "http://example.net/", >- "host": "example.net", >- "hostname": "example.net" >- } >- }, >- { >- "href": "http://example.net/", >- "new_value": "[::1.2.]", >- "expected": { >- "href": "http://example.net/", >- "host": "example.net", >- "hostname": "example.net" >- } >- }, >- { >- "href": "http://example.net/", >- "new_value": "[::1.]", >- "expected": { >- "href": "http://example.net/", >- "host": "example.net", >- "hostname": "example.net" >- } >- }, >- { >- "href": "file://y/", >- "new_value": "x:123", >- "expected": { >- "href": "file://y/", >- "host": "y", >- "hostname": "y", >- "port": "" >- } >- }, >- { >- "href": "file://y/", >- "new_value": "loc%41lhost", >- "expected": { >- "href": "file:///", >- "host": "", >- "hostname": "", >- "port": "" >- } >- }, >- { >- "href": "file://hi/x", >- "new_value": "", >- "expected": { >- "href": "file:///x", >- "host": "", >- "hostname": "", >- "port": "" >- } >- }, >- { >- "href": "sc://test@test/", >- "new_value": "", >- "expected": { >- "href": "sc://test@test/", >- "host": "test", >- "hostname": "test", >- "username": "test" >- } >- }, >- { >- "href": "sc://test:12/", >- "new_value": "", >- "expected": { >- "href": "sc://test:12/", >- "host": "test:12", >- "hostname": "test", >- "port": "12" >- } >- } >- ], >- "hostname": [ >- { >- "comment": "Non-special scheme", >- "href": "sc://x/", >- "new_value": "\u0000", >- "expected": { >- "href": "sc://x/", >- "host": "x", >- "hostname": "x" >- } >- }, >- { >- "href": "sc://x/", >- "new_value": "\u0009", >- "expected": { >- "href": "sc:///", >- "host": "", >- "hostname": "" >- } >- }, >- { >- "href": "sc://x/", >- "new_value": "\u000A", >- "expected": { >- "href": "sc:///", >- "host": "", >- "hostname": "" >- } >- }, >- { >- "href": "sc://x/", >- "new_value": "\u000D", >- "expected": { >- "href": "sc:///", >- "host": "", >- "hostname": "" >- } >- }, >- { >- "href": "sc://x/", >- "new_value": " ", >- "expected": { >- "href": "sc://x/", >- "host": "x", >- "hostname": "x" >- } >- }, >- { >- "href": "sc://x/", >- "new_value": "#", >- "expected": { >- "href": "sc:///", >- "host": "", >- "hostname": "" >- } >- }, >- { >- "href": "sc://x/", >- "new_value": "/", >- "expected": { >- "href": "sc:///", >- "host": "", >- "hostname": "" >- } >- }, >- { >- "href": "sc://x/", >- "new_value": "?", >- "expected": { >- "href": "sc:///", >- "host": "", >- "hostname": "" >- } >- }, >- { >- "href": "sc://x/", >- "new_value": "@", >- "expected": { >- "href": "sc://x/", >- "host": "x", >- "hostname": "x" >- } >- }, >- { >- "comment": "Cannot-be-a-base means no host", >- "href": "mailto:me@example.net", >- "new_value": "example.com", >- "expected": { >- "href": "mailto:me@example.net", >- "host": "" >- } >- }, >- { >- "comment": "Cannot-be-a-base means no password", >- "href": "data:text/plain,Stuff", >- "new_value": "example.net", >- "expected": { >- "href": "data:text/plain,Stuff", >- "host": "" >- } >- }, >- { >- "href": "http://example.net:8080", >- "new_value": "example.com", >- "expected": { >- "href": "http://example.com:8080/", >- "host": "example.com:8080", >- "hostname": "example.com", >- "port": "8080" >- } >- }, >- { >- "comment": "The empty host is not valid for special schemes", >- "href": "http://example.net", >- "new_value": "", >- "expected": { >- "href": "http://example.net/", >- "host": "example.net" >- } >- }, >- { >- "comment": "The empty host is OK for non-special schemes", >- "href": "view-source+http://example.net/foo", >- "new_value": "", >- "expected": { >- "href": "view-source+http:///foo", >- "host": "" >- } >- }, >- { >- "comment": "Path-only URLs can gain a host", >- "href": "a:/foo", >- "new_value": "example.net", >- "expected": { >- "href": "a://example.net/foo", >- "host": "example.net" >- } >- }, >- { >- "comment": "IPv4 address syntax is normalized", >- "href": "http://example.net:8080", >- "new_value": "0x7F000001", >- "expected": { >- "href": "http://127.0.0.1:8080/", >- "host": "127.0.0.1:8080", >- "hostname": "127.0.0.1", >- "port": "8080" >- } >- }, >- { >- "comment": "IPv6 address syntax is normalized", >- "href": "http://example.net", >- "new_value": "[::0:01]", >- "expected": { >- "href": "http://[::1]/", >- "host": "[::1]", >- "hostname": "[::1]", >- "port": "" >- } >- }, >- { >- "comment": "Stuff after a : delimiter is ignored", >- "href": "http://example.net/path", >- "new_value": "example.com:8080", >- "expected": { >- "href": "http://example.com/path", >- "host": "example.com", >- "hostname": "example.com", >- "port": "" >- } >- }, >- { >- "comment": "Stuff after a : delimiter is ignored", >- "href": "http://example.net:8080/path", >- "new_value": "example.com:", >- "expected": { >- "href": "http://example.com:8080/path", >- "host": "example.com:8080", >- "hostname": "example.com", >- "port": "8080" >- } >- }, >- { >- "comment": "Stuff after a / delimiter is ignored", >- "href": "http://example.net/path", >- "new_value": "example.com/stuff", >- "expected": { >- "href": "http://example.com/path", >- "host": "example.com", >- "hostname": "example.com", >- "port": "" >- } >- }, >- { >- "comment": "Stuff after a ? delimiter is ignored", >- "href": "http://example.net/path", >- "new_value": "example.com?stuff", >- "expected": { >- "href": "http://example.com/path", >- "host": "example.com", >- "hostname": "example.com", >- "port": "" >- } >- }, >- { >- "comment": "Stuff after a # delimiter is ignored", >- "href": "http://example.net/path", >- "new_value": "example.com#stuff", >- "expected": { >- "href": "http://example.com/path", >- "host": "example.com", >- "hostname": "example.com", >- "port": "" >- } >- }, >- { >- "comment": "Stuff after a \\ delimiter is ignored for special schemes", >- "href": "http://example.net/path", >- "new_value": "example.com\\stuff", >- "expected": { >- "href": "http://example.com/path", >- "host": "example.com", >- "hostname": "example.com", >- "port": "" >- } >- }, >- { >- "comment": "\\ is not a delimiter for non-special schemes, but still forbidden in hosts", >- "href": "view-source+http://example.net/path", >- "new_value": "example.com\\stuff", >- "expected": { >- "href": "view-source+http://example.net/path", >- "host": "example.net", >- "hostname": "example.net", >- "port": "" >- } >- }, >- { >- "comment": "Broken IPv6", >- "href": "http://example.net/", >- "new_value": "[google.com]", >- "expected": { >- "href": "http://example.net/", >- "host": "example.net", >- "hostname": "example.net" >- } >- }, >- { >- "href": "http://example.net/", >- "new_value": "[::1.2.3.4x]", >- "expected": { >- "href": "http://example.net/", >- "host": "example.net", >- "hostname": "example.net" >- } >- }, >- { >- "href": "http://example.net/", >- "new_value": "[::1.2.3.]", >- "expected": { >- "href": "http://example.net/", >- "host": "example.net", >- "hostname": "example.net" >- } >- }, >- { >- "href": "http://example.net/", >- "new_value": "[::1.2.]", >- "expected": { >- "href": "http://example.net/", >- "host": "example.net", >- "hostname": "example.net" >- } >- }, >- { >- "href": "http://example.net/", >- "new_value": "[::1.]", >- "expected": { >- "href": "http://example.net/", >- "host": "example.net", >- "hostname": "example.net" >- } >- }, >- { >- "href": "file://y/", >- "new_value": "x:123", >- "expected": { >- "href": "file://y/", >- "host": "y", >- "hostname": "y", >- "port": "" >- } >- }, >- { >- "href": "file://y/", >- "new_value": "loc%41lhost", >- "expected": { >- "href": "file:///", >- "host": "", >- "hostname": "", >- "port": "" >- } >- }, >- { >- "href": "file://hi/x", >- "new_value": "", >- "expected": { >- "href": "file:///x", >- "host": "", >- "hostname": "", >- "port": "" >- } >- }, >- { >- "href": "sc://test@test/", >- "new_value": "", >- "expected": { >- "href": "sc://test@test/", >- "host": "test", >- "hostname": "test", >- "username": "test" >- } >- }, >- { >- "href": "sc://test:12/", >- "new_value": "", >- "expected": { >- "href": "sc://test:12/", >- "host": "test:12", >- "hostname": "test", >- "port": "12" >- } >- } >- ], >- "port": [ >- { >- "href": "http://example.net", >- "new_value": "8080", >- "expected": { >- "href": "http://example.net:8080/", >- "host": "example.net:8080", >- "hostname": "example.net", >- "port": "8080" >- } >- }, >- { >- "comment": "Port number is removed if empty is the new value", >- "href": "http://example.net:8080", >- "new_value": "", >- "expected": { >- "href": "http://example.net/", >- "host": "example.net", >- "hostname": "example.net", >- "port": "" >- } >- }, >- { >- "comment": "Default port number is removed", >- "href": "http://example.net:8080", >- "new_value": "80", >- "expected": { >- "href": "http://example.net/", >- "host": "example.net", >- "hostname": "example.net", >- "port": "" >- } >- }, >- { >- "comment": "Default port number is removed", >- "href": "https://example.net:4433", >- "new_value": "443", >- "expected": { >- "href": "https://example.net/", >- "host": "example.net", >- "hostname": "example.net", >- "port": "" >- } >- }, >- { >- "comment": "Default port number is only removed for the relevant scheme", >- "href": "https://example.net", >- "new_value": "80", >- "expected": { >- "href": "https://example.net:80/", >- "host": "example.net:80", >- "hostname": "example.net", >- "port": "80" >- } >- }, >- { >- "comment": "Stuff after a / delimiter is ignored", >- "href": "http://example.net/path", >- "new_value": "8080/stuff", >- "expected": { >- "href": "http://example.net:8080/path", >- "host": "example.net:8080", >- "hostname": "example.net", >- "port": "8080" >- } >- }, >- { >- "comment": "Stuff after a ? delimiter is ignored", >- "href": "http://example.net/path", >- "new_value": "8080?stuff", >- "expected": { >- "href": "http://example.net:8080/path", >- "host": "example.net:8080", >- "hostname": "example.net", >- "port": "8080" >- } >- }, >- { >- "comment": "Stuff after a # delimiter is ignored", >- "href": "http://example.net/path", >- "new_value": "8080#stuff", >- "expected": { >- "href": "http://example.net:8080/path", >- "host": "example.net:8080", >- "hostname": "example.net", >- "port": "8080" >- } >- }, >- { >- "comment": "Stuff after a \\ delimiter is ignored for special schemes", >- "href": "http://example.net/path", >- "new_value": "8080\\stuff", >- "expected": { >- "href": "http://example.net:8080/path", >- "host": "example.net:8080", >- "hostname": "example.net", >- "port": "8080" >- } >- }, >- { >- "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", >- "href": "view-source+http://example.net/path", >- "new_value": "8080stuff2", >- "expected": { >- "href": "view-source+http://example.net:8080/path", >- "host": "example.net:8080", >- "hostname": "example.net", >- "port": "8080" >- } >- }, >- { >- "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", >- "href": "http://example.net/path", >- "new_value": "8080stuff2", >- "expected": { >- "href": "http://example.net:8080/path", >- "host": "example.net:8080", >- "hostname": "example.net", >- "port": "8080" >- } >- }, >- { >- "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", >- "href": "http://example.net/path", >- "new_value": "8080+2", >- "expected": { >- "href": "http://example.net:8080/path", >- "host": "example.net:8080", >- "hostname": "example.net", >- "port": "8080" >- } >- }, >- { >- "comment": "Port numbers are 16 bit integers", >- "href": "http://example.net/path", >- "new_value": "65535", >- "expected": { >- "href": "http://example.net:65535/path", >- "host": "example.net:65535", >- "hostname": "example.net", >- "port": "65535" >- } >- }, >- { >- "comment": "Port numbers are 16 bit integers, overflowing is an error", >- "href": "http://example.net:8080/path", >- "new_value": "65536", >- "expected": { >- "href": "http://example.net:8080/path", >- "host": "example.net:8080", >- "hostname": "example.net", >- "port": "8080" >- } >- }, >- { >- "comment": "Port numbers are 16 bit integers, overflowing is an error", >- "href": "non-special://example.net:8080/path", >- "new_value": "65536", >- "expected": { >- "href": "non-special://example.net:8080/path", >- "host": "example.net:8080", >- "hostname": "example.net", >- "port": "8080" >- } >- }, >- { >- "href": "file://test/", >- "new_value": "12", >- "expected": { >- "href": "file://test/", >- "port": "" >- } >- }, >- { >- "href": "file://localhost/", >- "new_value": "12", >- "expected": { >- "href": "file:///", >- "port": "" >- } >- }, >- { >- "href": "non-base:value", >- "new_value": "12", >- "expected": { >- "href": "non-base:value", >- "port": "" >- } >- }, >- { >- "href": "sc:///", >- "new_value": "12", >- "expected": { >- "href": "sc:///", >- "port": "" >- } >- }, >- { >- "href": "sc://x/", >- "new_value": "12", >- "expected": { >- "href": "sc://x:12/", >- "port": "12" >- } >- }, >- { >- "href": "javascript://x/", >- "new_value": "12", >- "expected": { >- "href": "javascript://x:12/", >- "port": "12" >- } >- } >- ], >- "pathname": [ >- { >- "comment": "Cannot-be-a-base donât have a path", >- "href": "mailto:me@example.net", >- "new_value": "/foo", >- "expected": { >- "href": "mailto:me@example.net", >- "pathname": "me@example.net" >- } >- }, >- { >- "href": "unix:/run/foo.socket?timeout=10", >- "new_value": "/var/log/../run/bar.socket", >- "expected": { >- "href": "unix:/var/run/bar.socket?timeout=10", >- "pathname": "/var/run/bar.socket" >- } >- }, >- { >- "href": "https://example.net#nav", >- "new_value": "home", >- "expected": { >- "href": "https://example.net/home#nav", >- "pathname": "/home" >- } >- }, >- { >- "href": "https://example.net#nav", >- "new_value": "../home", >- "expected": { >- "href": "https://example.net/home#nav", >- "pathname": "/home" >- } >- }, >- { >- "comment": "\\ is a segment delimiter for 'special' URLs", >- "href": "http://example.net/home?lang=fr#nav", >- "new_value": "\\a\\%2E\\b\\%2e.\\c", >- "expected": { >- "href": "http://example.net/a/c?lang=fr#nav", >- "pathname": "/a/c" >- } >- }, >- { >- "comment": "\\ is *not* a segment delimiter for non-'special' URLs", >- "href": "view-source+http://example.net/home?lang=fr#nav", >- "new_value": "\\a\\%2E\\b\\%2e.\\c", >- "expected": { >- "href": "view-source+http://example.net/\\a\\%2E\\b\\%2e.\\c?lang=fr#nav", >- "pathname": "/\\a\\%2E\\b\\%2e.\\c" >- } >- }, >- { >- "comment": "UTF-8 percent encoding with the default encode set. Tabs and newlines are removed.", >- "href": "a:/", >- "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Ãé", >- "expected": { >- "href": "a:/%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E%3F@AZ[\\]^_%60az%7B|%7D~%7F%C2%80%C2%81%C3%89%C3%A9", >- "pathname": "/%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E%3F@AZ[\\]^_%60az%7B|%7D~%7F%C2%80%C2%81%C3%89%C3%A9" >- } >- }, >- { >- "comment": "Bytes already percent-encoded are left as-is, including %2E outside dotted segments.", >- "href": "http://example.net", >- "new_value": "%2e%2E%c3%89té", >- "expected": { >- "href": "http://example.net/%2e%2E%c3%89t%C3%A9", >- "pathname": "/%2e%2E%c3%89t%C3%A9" >- } >- }, >- { >- "comment": "? needs to be encoded", >- "href": "http://example.net", >- "new_value": "?", >- "expected": { >- "href": "http://example.net/%3F", >- "pathname": "/%3F" >- } >- }, >- { >- "comment": "# needs to be encoded", >- "href": "http://example.net", >- "new_value": "#", >- "expected": { >- "href": "http://example.net/%23", >- "pathname": "/%23" >- } >- }, >- { >- "comment": "? needs to be encoded, non-special scheme", >- "href": "sc://example.net", >- "new_value": "?", >- "expected": { >- "href": "sc://example.net/%3F", >- "pathname": "/%3F" >- } >- }, >- { >- "comment": "# needs to be encoded, non-special scheme", >- "href": "sc://example.net", >- "new_value": "#", >- "expected": { >- "href": "sc://example.net/%23", >- "pathname": "/%23" >- } >- }, >- { >- "comment": "File URLs and (back)slashes", >- "href": "file://monkey/", >- "new_value": "\\\\", >- "expected": { >- "href": "file://monkey/", >- "pathname": "/" >- } >- }, >- { >- "comment": "File URLs and (back)slashes", >- "href": "file:///unicorn", >- "new_value": "//\\/", >- "expected": { >- "href": "file:///", >- "pathname": "/" >- } >- }, >- { >- "comment": "File URLs and (back)slashes", >- "href": "file:///unicorn", >- "new_value": "//monkey/..//", >- "expected": { >- "href": "file:///", >- "pathname": "/" >- } >- } >- ], >- "search": [ >- { >- "href": "https://example.net#nav", >- "new_value": "lang=fr", >- "expected": { >- "href": "https://example.net/?lang=fr#nav", >- "search": "?lang=fr" >- } >- }, >- { >- "href": "https://example.net?lang=en-US#nav", >- "new_value": "lang=fr", >- "expected": { >- "href": "https://example.net/?lang=fr#nav", >- "search": "?lang=fr" >- } >- }, >- { >- "href": "https://example.net?lang=en-US#nav", >- "new_value": "?lang=fr", >- "expected": { >- "href": "https://example.net/?lang=fr#nav", >- "search": "?lang=fr" >- } >- }, >- { >- "href": "https://example.net?lang=en-US#nav", >- "new_value": "??lang=fr", >- "expected": { >- "href": "https://example.net/??lang=fr#nav", >- "search": "??lang=fr" >- } >- }, >- { >- "href": "https://example.net?lang=en-US#nav", >- "new_value": "?", >- "expected": { >- "href": "https://example.net/?#nav", >- "search": "" >- } >- }, >- { >- "href": "https://example.net?lang=en-US#nav", >- "new_value": "", >- "expected": { >- "href": "https://example.net/#nav", >- "search": "" >- } >- }, >- { >- "href": "https://example.net?lang=en-US", >- "new_value": "", >- "expected": { >- "href": "https://example.net/", >- "search": "" >- } >- }, >- { >- "href": "https://example.net", >- "new_value": "", >- "expected": { >- "href": "https://example.net/", >- "search": "" >- } >- }, >- { >- "comment": "UTF-8 percent encoding with the query encode set. Tabs and newlines are removed.", >- "href": "a:/", >- "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Ãé", >- "expected": { >- "href": "a:/?%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_`az{|}~%7F%C2%80%C2%81%C3%89%C3%A9", >- "search": "?%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_`az{|}~%7F%C2%80%C2%81%C3%89%C3%A9" >- } >- }, >- { >- "comment": "Bytes already percent-encoded are left as-is", >- "href": "http://example.net", >- "new_value": "%c3%89té", >- "expected": { >- "href": "http://example.net/?%c3%89t%C3%A9", >- "search": "?%c3%89t%C3%A9" >- } >- } >- ], >- "hash": [ >- { >- "href": "https://example.net", >- "new_value": "main", >- "expected": { >- "href": "https://example.net/#main", >- "hash": "#main" >- } >- }, >- { >- "href": "https://example.net#nav", >- "new_value": "main", >- "expected": { >- "href": "https://example.net/#main", >- "hash": "#main" >- } >- }, >- { >- "href": "https://example.net?lang=en-US", >- "new_value": "##nav", >- "expected": { >- "href": "https://example.net/?lang=en-US##nav", >- "hash": "##nav" >- } >- }, >- { >- "href": "https://example.net?lang=en-US#nav", >- "new_value": "#main", >- "expected": { >- "href": "https://example.net/?lang=en-US#main", >- "hash": "#main" >- } >- }, >- { >- "href": "https://example.net?lang=en-US#nav", >- "new_value": "#", >- "expected": { >- "href": "https://example.net/?lang=en-US#", >- "hash": "" >- } >- }, >- { >- "href": "https://example.net?lang=en-US#nav", >- "new_value": "", >- "expected": { >- "href": "https://example.net/?lang=en-US", >- "hash": "" >- } >- }, >- { >- "href": "http://example.net", >- "new_value": "#foo bar", >- "expected": { >- "href": "http://example.net/#foo%20bar", >- "hash": "#foo%20bar" >- } >- }, >- { >- "href": "http://example.net", >- "new_value": "#foo\"bar", >- "expected": { >- "href": "http://example.net/#foo%22bar", >- "hash": "#foo%22bar" >- } >- }, >- { >- "href": "http://example.net", >- "new_value": "#foo<bar", >- "expected": { >- "href": "http://example.net/#foo%3Cbar", >- "hash": "#foo%3Cbar" >- } >- }, >- { >- "href": "http://example.net", >- "new_value": "#foo>bar", >- "expected": { >- "href": "http://example.net/#foo%3Ebar", >- "hash": "#foo%3Ebar" >- } >- }, >- { >- "href": "http://example.net", >- "new_value": "#foo`bar", >- "expected": { >- "href": "http://example.net/#foo%60bar", >- "hash": "#foo%60bar" >- } >- }, >- { >- "comment": "Simple percent-encoding; nuls, tabs, and newlines are removed", >- "href": "a:/", >- "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Ãé", >- "expected": { >- "href": "a:/#%01%1F%20!%22#$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_%60az{|}~%7F%C2%80%C2%81%C3%89%C3%A9", >- "hash": "#%01%1F%20!%22#$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_%60az{|}~%7F%C2%80%C2%81%C3%89%C3%A9" >- } >- }, >- { >- "comment": "Bytes already percent-encoded are left as-is", >- "href": "http://example.net", >- "new_value": "%c3%89té", >- "expected": { >- "href": "http://example.net/#%c3%89t%C3%A9", >- "hash": "#%c3%89t%C3%A9" >- } >- }, >- { >- "href": "javascript:alert(1)", >- "new_value": "castle", >- "expected": { >- "href": "javascript:alert(1)#castle", >- "hash": "#castle" >- } >- } >- ] >-} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/toascii.json b/LayoutTests/imported/w3c/web-platform-tests/url/toascii.json >deleted file mode 100644 >index 814f06e794866d4d2a817418ad368bf4f5ff446a..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/toascii.json >+++ /dev/null >@@ -1,149 +0,0 @@ >-[ >- "This resource is focused on highlighting issues with UTS #46 ToASCII", >- { >- "comment": "Label with hyphens in 3rd and 4th position", >- "input": "aa--", >- "output": "aa--" >- }, >- { >- "input": "aâ --", >- "output": "xn--a---kp0a" >- }, >- { >- "input": "ab--c", >- "output": "ab--c" >- }, >- { >- "comment": "Label with leading hyphen", >- "input": "-x", >- "output": "-x" >- }, >- { >- "input": "-â ", >- "output": "xn----xhn" >- }, >- { >- "input": "-x.xn--nxa", >- "output": "-x.xn--nxa" >- }, >- { >- "input": "-x.β", >- "output": "-x.xn--nxa" >- }, >- { >- "comment": "Label with trailing hyphen", >- "input": "x-.xn--nxa", >- "output": "x-.xn--nxa" >- }, >- { >- "input": "x-.β", >- "output": "x-.xn--nxa" >- }, >- { >- "comment": "Empty labels", >- "input": "x..xn--nxa", >- "output": "x..xn--nxa" >- }, >- { >- "input": "x..β", >- "output": "x..xn--nxa" >- }, >- { >- "comment": "Invalid Punycode", >- "input": "xn--a", >- "output": null >- }, >- { >- "input": "xn--a.xn--nxa", >- "output": null >- }, >- { >- "input": "xn--a.β", >- "output": null >- }, >- { >- "comment": "Valid Punycode", >- "input": "xn--nxa.xn--nxa", >- "output": "xn--nxa.xn--nxa" >- }, >- { >- "comment": "Mixed", >- "input": "xn--nxa.β", >- "output": "xn--nxa.xn--nxa" >- }, >- { >- "input": "ab--c.xn--nxa", >- "output": "ab--c.xn--nxa" >- }, >- { >- "input": "ab--c.β", >- "output": "ab--c.xn--nxa" >- }, >- { >- "comment": "CheckJoiners is true", >- "input": "\u200D.example", >- "output": null >- }, >- { >- "input": "xn--1ug.example", >- "output": null >- }, >- { >- "comment": "CheckBidi is true", >- "input": "Ùa", >- "output": null >- }, >- { >- "input": "xn--a-yoc", >- "output": null >- }, >- { >- "comment": "processing_option is Nontransitional_Processing", >- "input": "à·à·âà¶»à·", >- "output": "xn--10cl1a0b660p" >- }, >- { >- "input": "ÙØ§Ù ÙâØ§Û", >- "output": "xn--mgba3gch31f060k" >- }, >- { >- "comment": "U+FFFD", >- "input": "\uFFFD.com", >- "output": null >- }, >- { >- "comment": "U+FFFD character encoded in Punycode", >- "input": "xn--zn7c.com", >- "output": null >- }, >- { >- "comment": "Label longer than 63 code points", >- "input": "x01234567890123456789012345678901234567890123456789012345678901x", >- "output": "x01234567890123456789012345678901234567890123456789012345678901x" >- }, >- { >- "input": "x01234567890123456789012345678901234567890123456789012345678901â ", >- "output": "xn--x01234567890123456789012345678901234567890123456789012345678901-6963b" >- }, >- { >- "input": "x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa", >- "output": "x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa" >- }, >- { >- "input": "x01234567890123456789012345678901234567890123456789012345678901x.β", >- "output": "x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa" >- }, >- { >- "comment": "Domain excluding TLD longer than 253 code points", >- "input": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.x", >- "output": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.x" >- }, >- { >- "input": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa", >- "output": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa" >- }, >- { >- "input": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β", >- "output": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa" >- } >-] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/toascii.window.js b/LayoutTests/imported/w3c/web-platform-tests/url/toascii.window.js >index b49ef20b7713ecebf1563fafe812f3b13c51cf66..b28c664479a26aafddef076ce73ab448418d91fc 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/toascii.window.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/toascii.window.js >@@ -1,12 +1,4 @@ >-async_test(t => { >- const request = new XMLHttpRequest() >- request.open("GET", "toascii.json") >- request.send() >- request.responseType = "json" >- request.onload = t.step_func_done(() => { >- runTests(request.response) >- }) >-}, "Loading dataâ¦") >+promise_test(() => fetch("resources/toascii.json").then(res => res.json()).then(runTests), "Loading dataâ¦"); > > function makeURL(type, input) { > input = "https://" + input + "/x" >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/url-constructor-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/url/url-constructor-expected.txt >index 6f1d71a2c1ed7f9eb144191e367317c24885e666..117766c882014242b2ccaa810919bbc509f07238 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/url-constructor-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/url-constructor-expected.txt >@@ -520,13 +520,13 @@ PASS Parsing: <http://example.org/test?%23%23> against <about:blank> > PASS Parsing: <http://example.org/test?%GH> against <about:blank> > PASS Parsing: <http://example.org/test?a#%EF> against <about:blank> > PASS Parsing: <http://example.org/test?a#%GH> against <about:blank> >-PASS Parsing: <test-a.html> against <a> >-PASS Parsing: <test-a-slash.html> against <a/> >-PASS Parsing: <test-a-slash-slash.html> against <a//> >+PASS Parsing: <a> against <about:blank> >+PASS Parsing: <a/> against <about:blank> >+PASS Parsing: <a//> against <about:blank> > PASS Parsing: <test-a-colon.html> against <a:> >+PASS Parsing: <test-a-colon-b.html> against <a:b> > PASS Parsing: <test-a-colon-slash.html> against <a:/> > FAIL Parsing: <test-a-colon-slash-slash.html> against <a://> assert_equals: href expected "a:///test-a-colon-slash-slash.html" but got "a://test-a-colon-slash-slash.html" >-PASS Parsing: <test-a-colon-b.html> against <a:b> > PASS Parsing: <test-a-colon-slash-b.html> against <a:/b> > PASS Parsing: <test-a-colon-slash-slash-b.html> against <a://b> > FAIL Parsing: <http://example.org/test?a#b\0c> against <about:blank> assert_equals: href expected "http://example.org/test?a#bc" but got "http://example.org/test?a#b%00c" >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/url-constructor.html b/LayoutTests/imported/w3c/web-platform-tests/url/url-constructor.html >index 490917c4f2f7215fbd72860a9f761a4e3cdba549..6d7c2d64dbd8c5e3f632c86436a9f0bb9b500b22 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/url-constructor.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/url-constructor.html >@@ -4,20 +4,6 @@ > <script src=/resources/testharnessreport.js></script> > <div id=log></div> > <script> >-function runURLConstructorTests() { >- var setup = async_test("Loading dataâ¦") >- setup.step(function() { >- var request = new XMLHttpRequest() >- request.open("GET", "urltestdata.json") >- request.send() >- request.responseType = "json" >- request.onload = setup.step_func(function() { >- runURLTests(request.response) >- setup.done() >- }) >- }) >-} >- > function bURL(url, base) { > return new URL(url, base || "about:blank") > } >@@ -122,5 +108,5 @@ function runURLSearchParamTests() { > }, 'URL.searchParams and URL.search setters, update propagation') > } > runURLSearchParamTests() >-runURLConstructorTests() >+promise_test(() => fetch("resources/urltestdata.json").then(res => res.json()).then(runURLTests), "Loading dataâ¦"); > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/url-origin.html b/LayoutTests/imported/w3c/web-platform-tests/url/url-origin.html >index f9d4b3d821dfe8e8a3c091ff8b4d51218c192eb7..fccb643ed6c8069cc61fee276fbf5c69b3828850 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/url-origin.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/url-origin.html >@@ -4,19 +4,7 @@ > <script src=/resources/testharnessreport.js></script> > <div id=log></div> > <script> >-function runURLOriginTests() { >- var setup = async_test("Loading dataâ¦") >- setup.step(function() { >- var request = new XMLHttpRequest() >- request.open("GET", "urltestdata.json") >- request.send() >- request.responseType = "json" >- request.onload = setup.step_func(function() { >- runURLTests(request.response) >- setup.done() >- }) >- }) >-} >+promise_test(() => fetch("resources/urltestdata.json").then(res => res.json()).then(runURLTests), "Loading dataâ¦"); > > function bURL(url, base) { > return new URL(url, base || "about:blank") >@@ -33,5 +21,4 @@ function runURLTests(urltests) { > }, "Origin parsing: <" + expected.input + "> against <" + expected.base + ">") > } > } >-runURLOriginTests() > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/url-setters-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/url/url-setters-expected.txt >index fbd5c5b9f52de5afc95d6461c4f9b8c409cf496b..8124948c86916a4bceab96903fdaf8bf9fd01465 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/url-setters-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/url-setters-expected.txt >@@ -243,6 +243,9 @@ PASS <area>: Setting <https://example.net>.host = 'example.com:443' Default port > PASS URL: Setting <https://example.net>.host = 'example.com:80' Default port number is only removed for the relevant scheme > PASS <a>: Setting <https://example.net>.host = 'example.com:80' Default port number is only removed for the relevant scheme > PASS <area>: Setting <https://example.net>.host = 'example.com:80' Default port number is only removed for the relevant scheme >+PASS URL: Setting <http://example.net:8080>.host = 'example.com:80' Port number is removed if new port is scheme default and existing URL has a non-default port >+PASS <a>: Setting <http://example.net:8080>.host = 'example.com:80' Port number is removed if new port is scheme default and existing URL has a non-default port >+PASS <area>: Setting <http://example.net:8080>.host = 'example.com:80' Port number is removed if new port is scheme default and existing URL has a non-default port > FAIL URL: Setting <http://example.net/path>.host = 'example.com/stuff' Stuff after a / delimiter is ignored assert_equals: expected "http://example.com/path" but got "http://example.com/stuff/path" > FAIL <a>: Setting <http://example.net/path>.host = 'example.com/stuff' Stuff after a / delimiter is ignored assert_equals: expected "http://example.com/path" but got "http://example.com/stuff/path" > FAIL <area>: Setting <http://example.net/path>.host = 'example.com/stuff' Stuff after a / delimiter is ignored assert_equals: expected "http://example.com/path" but got "http://example.com/stuff/path" >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/url-setters.html b/LayoutTests/imported/w3c/web-platform-tests/url/url-setters.html >index b8b8ee5c7692c4e049efbe1c1745613ac9f33490..db30cf0774da445a18d9a6755b97ad1e13083b99 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/url-setters.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/url-setters.html >@@ -4,19 +4,7 @@ > <script src=/resources/testharnessreport.js></script> > <div id=log></div> > <script> >-function startURLSettersTests() { >- var setup = async_test("Loading dataâ¦") >- setup.step(function() { >- var request = new XMLHttpRequest() >- request.open("GET", "setters_tests.json") >- request.send() >- request.responseType = "json" >- request.onload = setup.step_func(function() { >- runURLSettersTests(request.response) >- setup.done() >- }) >- }) >-} >+promise_test(() => fetch("resources/setters_tests.json").then(res => res.json()).then(runURLSettersTests), "Loading dataâ¦"); > > function runURLSettersTests(all_test_cases) { > for (var attribute_to_be_set in all_test_cases) { >@@ -57,6 +45,4 @@ function runURLSettersTests(all_test_cases) { > } > } > } >- >-startURLSettersTests() > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/urlsearchparams-foreach-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/url/urlsearchparams-foreach-expected.txt >index 3675c00099f9c566cbb670d5737dc0cea9b791ed..b12dc3eed84b0341dc358a4c215c759db0c39994 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/urlsearchparams-foreach-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/urlsearchparams-foreach-expected.txt >@@ -2,4 +2,7 @@ > PASS ForEach Check > PASS For-of Check > PASS empty >+PASS delete next param during iteration >+PASS delete current param during iteration >+PASS delete every param seen during iteration > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/urlsearchparams-foreach.html b/LayoutTests/imported/w3c/web-platform-tests/url/urlsearchparams-foreach.html >index faa699cae1f25eb03eccc6fcc1df24ee0affa963..29c0ee802fde38c7d04b0a94152dc74a19c67111 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/urlsearchparams-foreach.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/urlsearchparams-foreach.html >@@ -36,4 +36,48 @@ test(function() { > assert_unreached(i); > } > }, "empty"); >+ >+test(function() { >+ const url = new URL("http://localhost/query?param0=0¶m1=1¶m2=2"); >+ const searchParams = url.searchParams; >+ const seen = []; >+ for (param of searchParams) { >+ if (param[0] === 'param0') { >+ searchParams.delete('param1'); >+ } >+ seen.push(param); >+ } >+ >+ assert_array_equals(seen[0], ["param0", "0"]); >+ assert_array_equals(seen[1], ["param2", "2"]); >+}, "delete next param during iteration"); >+ >+test(function() { >+ const url = new URL("http://localhost/query?param0=0¶m1=1¶m2=2"); >+ const searchParams = url.searchParams; >+ const seen = []; >+ for (param of searchParams) { >+ if (param[0] === 'param0') { >+ searchParams.delete('param0'); >+ // 'param1=1' is now in the first slot, so the next iteration will see 'param2=2'. >+ } else { >+ seen.push(param); >+ } >+ } >+ >+ assert_array_equals(seen[0], ["param2", "2"]); >+}, "delete current param during iteration"); >+ >+test(function() { >+ const url = new URL("http://localhost/query?param0=0¶m1=1¶m2=2"); >+ const searchParams = url.searchParams; >+ const seen = []; >+ for (param of searchParams) { >+ seen.push(param[0]); >+ searchParams.delete(param[0]); >+ } >+ >+ assert_array_equals(seen, ["param0", "param2"], "param1 should not have been seen by the loop"); >+ assert_equals(String(searchParams), "param1=1", "param1 should remain"); >+}, "delete every param seen during iteration"); > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/urltestdata.json b/LayoutTests/imported/w3c/web-platform-tests/url/urltestdata.json >deleted file mode 100644 >index 867056619b4cf7f695e4d39502b706d5b2467233..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/urltestdata.json >+++ /dev/null >@@ -1,6621 +0,0 @@ >-[ >- "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/script-tests/segments.js", >- { >- "input": "http://example\t.\norg", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://user:pass@foo:21/bar;par?b#c", >- "base": "http://example.org/foo/bar", >- "href": "http://user:pass@foo:21/bar;par?b#c", >- "origin": "http://foo:21", >- "protocol": "http:", >- "username": "user", >- "password": "pass", >- "host": "foo:21", >- "hostname": "foo", >- "port": "21", >- "pathname": "/bar;par", >- "search": "?b", >- "hash": "#c" >- }, >- { >- "input": "https://test:@test", >- "base": "about:blank", >- "href": "https://test@test/", >- "origin": "https://test", >- "protocol": "https:", >- "username": "test", >- "password": "", >- "host": "test", >- "hostname": "test", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "https://:@test", >- "base": "about:blank", >- "href": "https://test/", >- "origin": "https://test", >- "protocol": "https:", >- "username": "", >- "password": "", >- "host": "test", >- "hostname": "test", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "non-special://test:@test/x", >- "base": "about:blank", >- "href": "non-special://test@test/x", >- "origin": "null", >- "protocol": "non-special:", >- "username": "test", >- "password": "", >- "host": "test", >- "hostname": "test", >- "port": "", >- "pathname": "/x", >- "search": "", >- "hash": "" >- }, >- { >- "input": "non-special://:@test/x", >- "base": "about:blank", >- "href": "non-special://test/x", >- "origin": "null", >- "protocol": "non-special:", >- "username": "", >- "password": "", >- "host": "test", >- "hostname": "test", >- "port": "", >- "pathname": "/x", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http:foo.com", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/foo.com", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/foo.com", >- "search": "", >- "hash": "" >- }, >- { >- "input": "\t :foo.com \n", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/:foo.com", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/:foo.com", >- "search": "", >- "hash": "" >- }, >- { >- "input": " foo.com ", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/foo.com", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/foo.com", >- "search": "", >- "hash": "" >- }, >- { >- "input": "a:\t foo.com", >- "base": "http://example.org/foo/bar", >- "href": "a: foo.com", >- "origin": "null", >- "protocol": "a:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": " foo.com", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://f:21/ b ? d # e ", >- "base": "http://example.org/foo/bar", >- "href": "http://f:21/%20b%20?%20d%20#%20e", >- "origin": "http://f:21", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "f:21", >- "hostname": "f", >- "port": "21", >- "pathname": "/%20b%20", >- "search": "?%20d%20", >- "hash": "#%20e" >- }, >- { >- "input": "lolscheme:x x#x x", >- "base": "about:blank", >- "href": "lolscheme:x x#x%20x", >- "protocol": "lolscheme:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "x x", >- "search": "", >- "hash": "#x%20x" >- }, >- { >- "input": "http://f:/c", >- "base": "http://example.org/foo/bar", >- "href": "http://f/c", >- "origin": "http://f", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "f", >- "hostname": "f", >- "port": "", >- "pathname": "/c", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://f:0/c", >- "base": "http://example.org/foo/bar", >- "href": "http://f:0/c", >- "origin": "http://f:0", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "f:0", >- "hostname": "f", >- "port": "0", >- "pathname": "/c", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://f:00000000000000/c", >- "base": "http://example.org/foo/bar", >- "href": "http://f:0/c", >- "origin": "http://f:0", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "f:0", >- "hostname": "f", >- "port": "0", >- "pathname": "/c", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://f:00000000000000000000080/c", >- "base": "http://example.org/foo/bar", >- "href": "http://f/c", >- "origin": "http://f", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "f", >- "hostname": "f", >- "port": "", >- "pathname": "/c", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://f:b/c", >- "base": "http://example.org/foo/bar", >- "failure": true >- }, >- { >- "input": "http://f: /c", >- "base": "http://example.org/foo/bar", >- "failure": true >- }, >- { >- "input": "http://f:\n/c", >- "base": "http://example.org/foo/bar", >- "href": "http://f/c", >- "origin": "http://f", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "f", >- "hostname": "f", >- "port": "", >- "pathname": "/c", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://f:fifty-two/c", >- "base": "http://example.org/foo/bar", >- "failure": true >- }, >- { >- "input": "http://f:999999/c", >- "base": "http://example.org/foo/bar", >- "failure": true >- }, >- { >- "input": "non-special://f:999999/c", >- "base": "http://example.org/foo/bar", >- "failure": true >- }, >- { >- "input": "http://f: 21 / b ? d # e ", >- "base": "http://example.org/foo/bar", >- "failure": true >- }, >- { >- "input": "", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/bar", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/bar", >- "search": "", >- "hash": "" >- }, >- { >- "input": " \t", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/bar", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/bar", >- "search": "", >- "hash": "" >- }, >- { >- "input": ":foo.com/", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/:foo.com/", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/:foo.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": ":foo.com\\", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/:foo.com/", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/:foo.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": ":", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/:", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/:", >- "search": "", >- "hash": "" >- }, >- { >- "input": ":a", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/:a", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/:a", >- "search": "", >- "hash": "" >- }, >- { >- "input": ":/", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/:/", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/:/", >- "search": "", >- "hash": "" >- }, >- { >- "input": ":\\", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/:/", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/:/", >- "search": "", >- "hash": "" >- }, >- { >- "input": ":#", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/:#", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/:", >- "search": "", >- "hash": "" >- }, >- { >- "input": "#", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/bar#", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/bar", >- "search": "", >- "hash": "" >- }, >- { >- "input": "#/", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/bar#/", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/bar", >- "search": "", >- "hash": "#/" >- }, >- { >- "input": "#\\", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/bar#\\", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/bar", >- "search": "", >- "hash": "#\\" >- }, >- { >- "input": "#;?", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/bar#;?", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/bar", >- "search": "", >- "hash": "#;?" >- }, >- { >- "input": "?", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/bar?", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/bar", >- "search": "", >- "hash": "" >- }, >- { >- "input": "/", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": ":23", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/:23", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/:23", >- "search": "", >- "hash": "" >- }, >- { >- "input": "/:23", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/:23", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/:23", >- "search": "", >- "hash": "" >- }, >- { >- "input": "::", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/::", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/::", >- "search": "", >- "hash": "" >- }, >- { >- "input": "::23", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/::23", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/::23", >- "search": "", >- "hash": "" >- }, >- { >- "input": "foo://", >- "base": "http://example.org/foo/bar", >- "href": "foo://", >- "origin": "null", >- "protocol": "foo:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://a:b@c:29/d", >- "base": "http://example.org/foo/bar", >- "href": "http://a:b@c:29/d", >- "origin": "http://c:29", >- "protocol": "http:", >- "username": "a", >- "password": "b", >- "host": "c:29", >- "hostname": "c", >- "port": "29", >- "pathname": "/d", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http::@c:29", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/:@c:29", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/:@c:29", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://&a:foo(b]c@d:2/", >- "base": "http://example.org/foo/bar", >- "href": "http://&a:foo(b%5Dc@d:2/", >- "origin": "http://d:2", >- "protocol": "http:", >- "username": "&a", >- "password": "foo(b%5Dc", >- "host": "d:2", >- "hostname": "d", >- "port": "2", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://::@c@d:2", >- "base": "http://example.org/foo/bar", >- "href": "http://:%3A%40c@d:2/", >- "origin": "http://d:2", >- "protocol": "http:", >- "username": "", >- "password": "%3A%40c", >- "host": "d:2", >- "hostname": "d", >- "port": "2", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://foo.com:b@d/", >- "base": "http://example.org/foo/bar", >- "href": "http://foo.com:b@d/", >- "origin": "http://d", >- "protocol": "http:", >- "username": "foo.com", >- "password": "b", >- "host": "d", >- "hostname": "d", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://foo.com/\\@", >- "base": "http://example.org/foo/bar", >- "href": "http://foo.com//@", >- "origin": "http://foo.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "foo.com", >- "hostname": "foo.com", >- "port": "", >- "pathname": "//@", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http:\\\\foo.com\\", >- "base": "http://example.org/foo/bar", >- "href": "http://foo.com/", >- "origin": "http://foo.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "foo.com", >- "hostname": "foo.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http:\\\\a\\b:c\\d@foo.com\\", >- "base": "http://example.org/foo/bar", >- "href": "http://a/b:c/d@foo.com/", >- "origin": "http://a", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "a", >- "hostname": "a", >- "port": "", >- "pathname": "/b:c/d@foo.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "foo:/", >- "base": "http://example.org/foo/bar", >- "href": "foo:/", >- "origin": "null", >- "protocol": "foo:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "foo:/bar.com/", >- "base": "http://example.org/foo/bar", >- "href": "foo:/bar.com/", >- "origin": "null", >- "protocol": "foo:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/bar.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "foo://///////", >- "base": "http://example.org/foo/bar", >- "href": "foo://///////", >- "origin": "null", >- "protocol": "foo:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "///////", >- "search": "", >- "hash": "" >- }, >- { >- "input": "foo://///////bar.com/", >- "base": "http://example.org/foo/bar", >- "href": "foo://///////bar.com/", >- "origin": "null", >- "protocol": "foo:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "///////bar.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "foo:////://///", >- "base": "http://example.org/foo/bar", >- "href": "foo:////://///", >- "origin": "null", >- "protocol": "foo:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "//://///", >- "search": "", >- "hash": "" >- }, >- { >- "input": "c:/foo", >- "base": "http://example.org/foo/bar", >- "href": "c:/foo", >- "origin": "null", >- "protocol": "c:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/foo", >- "search": "", >- "hash": "" >- }, >- { >- "input": "//foo/bar", >- "base": "http://example.org/foo/bar", >- "href": "http://foo/bar", >- "origin": "http://foo", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "foo", >- "hostname": "foo", >- "port": "", >- "pathname": "/bar", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://foo/path;a??e#f#g", >- "base": "http://example.org/foo/bar", >- "href": "http://foo/path;a??e#f#g", >- "origin": "http://foo", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "foo", >- "hostname": "foo", >- "port": "", >- "pathname": "/path;a", >- "search": "??e", >- "hash": "#f#g" >- }, >- { >- "input": "http://foo/abcd?efgh?ijkl", >- "base": "http://example.org/foo/bar", >- "href": "http://foo/abcd?efgh?ijkl", >- "origin": "http://foo", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "foo", >- "hostname": "foo", >- "port": "", >- "pathname": "/abcd", >- "search": "?efgh?ijkl", >- "hash": "" >- }, >- { >- "input": "http://foo/abcd#foo?bar", >- "base": "http://example.org/foo/bar", >- "href": "http://foo/abcd#foo?bar", >- "origin": "http://foo", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "foo", >- "hostname": "foo", >- "port": "", >- "pathname": "/abcd", >- "search": "", >- "hash": "#foo?bar" >- }, >- { >- "input": "[61:24:74]:98", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/[61:24:74]:98", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/[61:24:74]:98", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http:[61:27]/:foo", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/[61:27]/:foo", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/[61:27]/:foo", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://[1::2]:3:4", >- "base": "http://example.org/foo/bar", >- "failure": true >- }, >- { >- "input": "http://2001::1", >- "base": "http://example.org/foo/bar", >- "failure": true >- }, >- { >- "input": "http://2001::1]", >- "base": "http://example.org/foo/bar", >- "failure": true >- }, >- { >- "input": "http://2001::1]:80", >- "base": "http://example.org/foo/bar", >- "failure": true >- }, >- { >- "input": "http://[2001::1]", >- "base": "http://example.org/foo/bar", >- "href": "http://[2001::1]/", >- "origin": "http://[2001::1]", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "[2001::1]", >- "hostname": "[2001::1]", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://[::127.0.0.1]", >- "base": "http://example.org/foo/bar", >- "href": "http://[::7f00:1]/", >- "origin": "http://[::7f00:1]", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "[::7f00:1]", >- "hostname": "[::7f00:1]", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://[0:0:0:0:0:0:13.1.68.3]", >- "base": "http://example.org/foo/bar", >- "href": "http://[::d01:4403]/", >- "origin": "http://[::d01:4403]", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "[::d01:4403]", >- "hostname": "[::d01:4403]", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://[2001::1]:80", >- "base": "http://example.org/foo/bar", >- "href": "http://[2001::1]/", >- "origin": "http://[2001::1]", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "[2001::1]", >- "hostname": "[2001::1]", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http:/example.com/", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/example.com/", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ftp:/example.com/", >- "base": "http://example.org/foo/bar", >- "href": "ftp://example.com/", >- "origin": "ftp://example.com", >- "protocol": "ftp:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "https:/example.com/", >- "base": "http://example.org/foo/bar", >- "href": "https://example.com/", >- "origin": "https://example.com", >- "protocol": "https:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "madeupscheme:/example.com/", >- "base": "http://example.org/foo/bar", >- "href": "madeupscheme:/example.com/", >- "origin": "null", >- "protocol": "madeupscheme:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file:/example.com/", >- "base": "http://example.org/foo/bar", >- "href": "file:///example.com/", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file://example:1/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "file://example:test/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "file://example%/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "file://[example]/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "ftps:/example.com/", >- "base": "http://example.org/foo/bar", >- "href": "ftps:/example.com/", >- "origin": "null", >- "protocol": "ftps:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "gopher:/example.com/", >- "base": "http://example.org/foo/bar", >- "href": "gopher://example.com/", >- "origin": "gopher://example.com", >- "protocol": "gopher:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ws:/example.com/", >- "base": "http://example.org/foo/bar", >- "href": "ws://example.com/", >- "origin": "ws://example.com", >- "protocol": "ws:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "wss:/example.com/", >- "base": "http://example.org/foo/bar", >- "href": "wss://example.com/", >- "origin": "wss://example.com", >- "protocol": "wss:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "data:/example.com/", >- "base": "http://example.org/foo/bar", >- "href": "data:/example.com/", >- "origin": "null", >- "protocol": "data:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "javascript:/example.com/", >- "base": "http://example.org/foo/bar", >- "href": "javascript:/example.com/", >- "origin": "null", >- "protocol": "javascript:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "mailto:/example.com/", >- "base": "http://example.org/foo/bar", >- "href": "mailto:/example.com/", >- "origin": "null", >- "protocol": "mailto:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http:example.com/", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/example.com/", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ftp:example.com/", >- "base": "http://example.org/foo/bar", >- "href": "ftp://example.com/", >- "origin": "ftp://example.com", >- "protocol": "ftp:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "https:example.com/", >- "base": "http://example.org/foo/bar", >- "href": "https://example.com/", >- "origin": "https://example.com", >- "protocol": "https:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "madeupscheme:example.com/", >- "base": "http://example.org/foo/bar", >- "href": "madeupscheme:example.com/", >- "origin": "null", >- "protocol": "madeupscheme:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ftps:example.com/", >- "base": "http://example.org/foo/bar", >- "href": "ftps:example.com/", >- "origin": "null", >- "protocol": "ftps:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "gopher:example.com/", >- "base": "http://example.org/foo/bar", >- "href": "gopher://example.com/", >- "origin": "gopher://example.com", >- "protocol": "gopher:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ws:example.com/", >- "base": "http://example.org/foo/bar", >- "href": "ws://example.com/", >- "origin": "ws://example.com", >- "protocol": "ws:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "wss:example.com/", >- "base": "http://example.org/foo/bar", >- "href": "wss://example.com/", >- "origin": "wss://example.com", >- "protocol": "wss:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "data:example.com/", >- "base": "http://example.org/foo/bar", >- "href": "data:example.com/", >- "origin": "null", >- "protocol": "data:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "javascript:example.com/", >- "base": "http://example.org/foo/bar", >- "href": "javascript:example.com/", >- "origin": "null", >- "protocol": "javascript:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "mailto:example.com/", >- "base": "http://example.org/foo/bar", >- "href": "mailto:example.com/", >- "origin": "null", >- "protocol": "mailto:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "/a/b/c", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/a/b/c", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/a/b/c", >- "search": "", >- "hash": "" >- }, >- { >- "input": "/a/ /c", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/a/%20/c", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/a/%20/c", >- "search": "", >- "hash": "" >- }, >- { >- "input": "/a%2fc", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/a%2fc", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/a%2fc", >- "search": "", >- "hash": "" >- }, >- { >- "input": "/a/%2f/c", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/a/%2f/c", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/a/%2f/c", >- "search": "", >- "hash": "" >- }, >- { >- "input": "#β", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/bar#%CE%B2", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/bar", >- "search": "", >- "hash": "#%CE%B2" >- }, >- { >- "input": "data:text/html,test#test", >- "base": "http://example.org/foo/bar", >- "href": "data:text/html,test#test", >- "origin": "null", >- "protocol": "data:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "text/html,test", >- "search": "", >- "hash": "#test" >- }, >- { >- "input": "tel:1234567890", >- "base": "http://example.org/foo/bar", >- "href": "tel:1234567890", >- "origin": "null", >- "protocol": "tel:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "1234567890", >- "search": "", >- "hash": "" >- }, >- "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/file.html", >- { >- "input": "file:c:\\foo\\bar.html", >- "base": "file:///tmp/mock/path", >- "href": "file:///c:/foo/bar.html", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/c:/foo/bar.html", >- "search": "", >- "hash": "" >- }, >- { >- "input": " File:c|////foo\\bar.html", >- "base": "file:///tmp/mock/path", >- "href": "file:///c:////foo/bar.html", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/c:////foo/bar.html", >- "search": "", >- "hash": "" >- }, >- { >- "input": "C|/foo/bar", >- "base": "file:///tmp/mock/path", >- "href": "file:///C:/foo/bar", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C:/foo/bar", >- "search": "", >- "hash": "" >- }, >- { >- "input": "/C|\\foo\\bar", >- "base": "file:///tmp/mock/path", >- "href": "file:///C:/foo/bar", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C:/foo/bar", >- "search": "", >- "hash": "" >- }, >- { >- "input": "//C|/foo/bar", >- "base": "file:///tmp/mock/path", >- "href": "file:///C:/foo/bar", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C:/foo/bar", >- "search": "", >- "hash": "" >- }, >- { >- "input": "//server/file", >- "base": "file:///tmp/mock/path", >- "href": "file://server/file", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "server", >- "hostname": "server", >- "port": "", >- "pathname": "/file", >- "search": "", >- "hash": "" >- }, >- { >- "input": "\\\\server\\file", >- "base": "file:///tmp/mock/path", >- "href": "file://server/file", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "server", >- "hostname": "server", >- "port": "", >- "pathname": "/file", >- "search": "", >- "hash": "" >- }, >- { >- "input": "/\\server/file", >- "base": "file:///tmp/mock/path", >- "href": "file://server/file", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "server", >- "hostname": "server", >- "port": "", >- "pathname": "/file", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file:///foo/bar.txt", >- "base": "file:///tmp/mock/path", >- "href": "file:///foo/bar.txt", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/foo/bar.txt", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file:///home/me", >- "base": "file:///tmp/mock/path", >- "href": "file:///home/me", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/home/me", >- "search": "", >- "hash": "" >- }, >- { >- "input": "//", >- "base": "file:///tmp/mock/path", >- "href": "file:///", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "///", >- "base": "file:///tmp/mock/path", >- "href": "file:///", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "///test", >- "base": "file:///tmp/mock/path", >- "href": "file:///test", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/test", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file://test", >- "base": "file:///tmp/mock/path", >- "href": "file://test/", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "test", >- "hostname": "test", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file://localhost", >- "base": "file:///tmp/mock/path", >- "href": "file:///", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file://localhost/", >- "base": "file:///tmp/mock/path", >- "href": "file:///", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file://localhost/test", >- "base": "file:///tmp/mock/path", >- "href": "file:///test", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/test", >- "search": "", >- "hash": "" >- }, >- { >- "input": "test", >- "base": "file:///tmp/mock/path", >- "href": "file:///tmp/mock/test", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/tmp/mock/test", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file:test", >- "base": "file:///tmp/mock/path", >- "href": "file:///tmp/mock/test", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/tmp/mock/test", >- "search": "", >- "hash": "" >- }, >- "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/script-tests/path.js", >- { >- "input": "http://example.com/././foo", >- "base": "about:blank", >- "href": "http://example.com/foo", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/./.foo", >- "base": "about:blank", >- "href": "http://example.com/.foo", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/.foo", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo/.", >- "base": "about:blank", >- "href": "http://example.com/foo/", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo/./", >- "base": "about:blank", >- "href": "http://example.com/foo/", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo/bar/..", >- "base": "about:blank", >- "href": "http://example.com/foo/", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo/bar/../", >- "base": "about:blank", >- "href": "http://example.com/foo/", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo/..bar", >- "base": "about:blank", >- "href": "http://example.com/foo/..bar", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo/..bar", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo/bar/../ton", >- "base": "about:blank", >- "href": "http://example.com/foo/ton", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo/ton", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo/bar/../ton/../../a", >- "base": "about:blank", >- "href": "http://example.com/a", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/a", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo/../../..", >- "base": "about:blank", >- "href": "http://example.com/", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo/../../../ton", >- "base": "about:blank", >- "href": "http://example.com/ton", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/ton", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo/%2e", >- "base": "about:blank", >- "href": "http://example.com/foo/", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo/%2e%2", >- "base": "about:blank", >- "href": "http://example.com/foo/%2e%2", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo/%2e%2", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar", >- "base": "about:blank", >- "href": "http://example.com/%2e.bar", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/%2e.bar", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com////../..", >- "base": "about:blank", >- "href": "http://example.com//", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "//", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo/bar//../..", >- "base": "about:blank", >- "href": "http://example.com/foo/", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo/bar//..", >- "base": "about:blank", >- "href": "http://example.com/foo/bar/", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo/bar/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo", >- "base": "about:blank", >- "href": "http://example.com/foo", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/%20foo", >- "base": "about:blank", >- "href": "http://example.com/%20foo", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/%20foo", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo%", >- "base": "about:blank", >- "href": "http://example.com/foo%", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo%", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo%2", >- "base": "about:blank", >- "href": "http://example.com/foo%2", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo%2", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo%2zbar", >- "base": "about:blank", >- "href": "http://example.com/foo%2zbar", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo%2zbar", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo%2ézbar", >- "base": "about:blank", >- "href": "http://example.com/foo%2%C3%82%C2%A9zbar", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo%2%C3%82%C2%A9zbar", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo%41%7a", >- "base": "about:blank", >- "href": "http://example.com/foo%41%7a", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo%41%7a", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo\t\u0091%91", >- "base": "about:blank", >- "href": "http://example.com/foo%C2%91%91", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo%C2%91%91", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo%00%51", >- "base": "about:blank", >- "href": "http://example.com/foo%00%51", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foo%00%51", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/(%28:%3A%29)", >- "base": "about:blank", >- "href": "http://example.com/(%28:%3A%29)", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/(%28:%3A%29)", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/%3A%3a%3C%3c", >- "base": "about:blank", >- "href": "http://example.com/%3A%3a%3C%3c", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/%3A%3a%3C%3c", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/foo\tbar", >- "base": "about:blank", >- "href": "http://example.com/foobar", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/foobar", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com\\\\foo\\\\bar", >- "base": "about:blank", >- "href": "http://example.com//foo//bar", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "//foo//bar", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/%7Ffp3%3Eju%3Dduvgw%3Dd", >- "base": "about:blank", >- "href": "http://example.com/%7Ffp3%3Eju%3Dduvgw%3Dd", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/%7Ffp3%3Eju%3Dduvgw%3Dd", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/@asdf%40", >- "base": "about:blank", >- "href": "http://example.com/@asdf%40", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/@asdf%40", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/ä½ å¥½ä½ å¥½", >- "base": "about:blank", >- "href": "http://example.com/%E4%BD%A0%E5%A5%BD%E4%BD%A0%E5%A5%BD", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/%E4%BD%A0%E5%A5%BD%E4%BD%A0%E5%A5%BD", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/â¥/foo", >- "base": "about:blank", >- "href": "http://example.com/%E2%80%A5/foo", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/%E2%80%A5/foo", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com//foo", >- "base": "about:blank", >- "href": "http://example.com/%EF%BB%BF/foo", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/%EF%BB%BF/foo", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.com/â®/foo/â/bar", >- "base": "about:blank", >- "href": "http://example.com/%E2%80%AE/foo/%E2%80%AD/bar", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/%E2%80%AE/foo/%E2%80%AD/bar", >- "search": "", >- "hash": "" >- }, >- "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/script-tests/relative.js", >- { >- "input": "http://www.google.com/foo?bar=baz#", >- "base": "about:blank", >- "href": "http://www.google.com/foo?bar=baz#", >- "origin": "http://www.google.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.google.com", >- "hostname": "www.google.com", >- "port": "", >- "pathname": "/foo", >- "search": "?bar=baz", >- "hash": "" >- }, >- { >- "input": "http://www.google.com/foo?bar=baz# »", >- "base": "about:blank", >- "href": "http://www.google.com/foo?bar=baz#%20%C2%BB", >- "origin": "http://www.google.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.google.com", >- "hostname": "www.google.com", >- "port": "", >- "pathname": "/foo", >- "search": "?bar=baz", >- "hash": "#%20%C2%BB" >- }, >- { >- "input": "data:test# »", >- "base": "about:blank", >- "href": "data:test#%20%C2%BB", >- "origin": "null", >- "protocol": "data:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "test", >- "search": "", >- "hash": "#%20%C2%BB" >- }, >- { >- "input": "http://www.google.com", >- "base": "about:blank", >- "href": "http://www.google.com/", >- "origin": "http://www.google.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.google.com", >- "hostname": "www.google.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://192.0x00A80001", >- "base": "about:blank", >- "href": "http://192.168.0.1/", >- "origin": "http://192.168.0.1", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "192.168.0.1", >- "hostname": "192.168.0.1", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://www/foo%2Ehtml", >- "base": "about:blank", >- "href": "http://www/foo%2Ehtml", >- "origin": "http://www", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www", >- "hostname": "www", >- "port": "", >- "pathname": "/foo%2Ehtml", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://www/foo/%2E/html", >- "base": "about:blank", >- "href": "http://www/foo/html", >- "origin": "http://www", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www", >- "hostname": "www", >- "port": "", >- "pathname": "/foo/html", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://user:pass@/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "http://%25DOMAIN:foobar@foodomain.com/", >- "base": "about:blank", >- "href": "http://%25DOMAIN:foobar@foodomain.com/", >- "origin": "http://foodomain.com", >- "protocol": "http:", >- "username": "%25DOMAIN", >- "password": "foobar", >- "host": "foodomain.com", >- "hostname": "foodomain.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http:\\\\www.google.com\\foo", >- "base": "about:blank", >- "href": "http://www.google.com/foo", >- "origin": "http://www.google.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.google.com", >- "hostname": "www.google.com", >- "port": "", >- "pathname": "/foo", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://foo:80/", >- "base": "about:blank", >- "href": "http://foo/", >- "origin": "http://foo", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "foo", >- "hostname": "foo", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://foo:81/", >- "base": "about:blank", >- "href": "http://foo:81/", >- "origin": "http://foo:81", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "foo:81", >- "hostname": "foo", >- "port": "81", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "httpa://foo:80/", >- "base": "about:blank", >- "href": "httpa://foo:80/", >- "origin": "null", >- "protocol": "httpa:", >- "username": "", >- "password": "", >- "host": "foo:80", >- "hostname": "foo", >- "port": "80", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://foo:-80/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "https://foo:443/", >- "base": "about:blank", >- "href": "https://foo/", >- "origin": "https://foo", >- "protocol": "https:", >- "username": "", >- "password": "", >- "host": "foo", >- "hostname": "foo", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "https://foo:80/", >- "base": "about:blank", >- "href": "https://foo:80/", >- "origin": "https://foo:80", >- "protocol": "https:", >- "username": "", >- "password": "", >- "host": "foo:80", >- "hostname": "foo", >- "port": "80", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ftp://foo:21/", >- "base": "about:blank", >- "href": "ftp://foo/", >- "origin": "ftp://foo", >- "protocol": "ftp:", >- "username": "", >- "password": "", >- "host": "foo", >- "hostname": "foo", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ftp://foo:80/", >- "base": "about:blank", >- "href": "ftp://foo:80/", >- "origin": "ftp://foo:80", >- "protocol": "ftp:", >- "username": "", >- "password": "", >- "host": "foo:80", >- "hostname": "foo", >- "port": "80", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "gopher://foo:70/", >- "base": "about:blank", >- "href": "gopher://foo/", >- "origin": "gopher://foo", >- "protocol": "gopher:", >- "username": "", >- "password": "", >- "host": "foo", >- "hostname": "foo", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "gopher://foo:443/", >- "base": "about:blank", >- "href": "gopher://foo:443/", >- "origin": "gopher://foo:443", >- "protocol": "gopher:", >- "username": "", >- "password": "", >- "host": "foo:443", >- "hostname": "foo", >- "port": "443", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ws://foo:80/", >- "base": "about:blank", >- "href": "ws://foo/", >- "origin": "ws://foo", >- "protocol": "ws:", >- "username": "", >- "password": "", >- "host": "foo", >- "hostname": "foo", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ws://foo:81/", >- "base": "about:blank", >- "href": "ws://foo:81/", >- "origin": "ws://foo:81", >- "protocol": "ws:", >- "username": "", >- "password": "", >- "host": "foo:81", >- "hostname": "foo", >- "port": "81", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ws://foo:443/", >- "base": "about:blank", >- "href": "ws://foo:443/", >- "origin": "ws://foo:443", >- "protocol": "ws:", >- "username": "", >- "password": "", >- "host": "foo:443", >- "hostname": "foo", >- "port": "443", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ws://foo:815/", >- "base": "about:blank", >- "href": "ws://foo:815/", >- "origin": "ws://foo:815", >- "protocol": "ws:", >- "username": "", >- "password": "", >- "host": "foo:815", >- "hostname": "foo", >- "port": "815", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "wss://foo:80/", >- "base": "about:blank", >- "href": "wss://foo:80/", >- "origin": "wss://foo:80", >- "protocol": "wss:", >- "username": "", >- "password": "", >- "host": "foo:80", >- "hostname": "foo", >- "port": "80", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "wss://foo:81/", >- "base": "about:blank", >- "href": "wss://foo:81/", >- "origin": "wss://foo:81", >- "protocol": "wss:", >- "username": "", >- "password": "", >- "host": "foo:81", >- "hostname": "foo", >- "port": "81", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "wss://foo:443/", >- "base": "about:blank", >- "href": "wss://foo/", >- "origin": "wss://foo", >- "protocol": "wss:", >- "username": "", >- "password": "", >- "host": "foo", >- "hostname": "foo", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "wss://foo:815/", >- "base": "about:blank", >- "href": "wss://foo:815/", >- "origin": "wss://foo:815", >- "protocol": "wss:", >- "username": "", >- "password": "", >- "host": "foo:815", >- "hostname": "foo", >- "port": "815", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http:/example.com/", >- "base": "about:blank", >- "href": "http://example.com/", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ftp:/example.com/", >- "base": "about:blank", >- "href": "ftp://example.com/", >- "origin": "ftp://example.com", >- "protocol": "ftp:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "https:/example.com/", >- "base": "about:blank", >- "href": "https://example.com/", >- "origin": "https://example.com", >- "protocol": "https:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "madeupscheme:/example.com/", >- "base": "about:blank", >- "href": "madeupscheme:/example.com/", >- "origin": "null", >- "protocol": "madeupscheme:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file:/example.com/", >- "base": "about:blank", >- "href": "file:///example.com/", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ftps:/example.com/", >- "base": "about:blank", >- "href": "ftps:/example.com/", >- "origin": "null", >- "protocol": "ftps:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "gopher:/example.com/", >- "base": "about:blank", >- "href": "gopher://example.com/", >- "origin": "gopher://example.com", >- "protocol": "gopher:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ws:/example.com/", >- "base": "about:blank", >- "href": "ws://example.com/", >- "origin": "ws://example.com", >- "protocol": "ws:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "wss:/example.com/", >- "base": "about:blank", >- "href": "wss://example.com/", >- "origin": "wss://example.com", >- "protocol": "wss:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "data:/example.com/", >- "base": "about:blank", >- "href": "data:/example.com/", >- "origin": "null", >- "protocol": "data:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "javascript:/example.com/", >- "base": "about:blank", >- "href": "javascript:/example.com/", >- "origin": "null", >- "protocol": "javascript:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "mailto:/example.com/", >- "base": "about:blank", >- "href": "mailto:/example.com/", >- "origin": "null", >- "protocol": "mailto:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http:example.com/", >- "base": "about:blank", >- "href": "http://example.com/", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ftp:example.com/", >- "base": "about:blank", >- "href": "ftp://example.com/", >- "origin": "ftp://example.com", >- "protocol": "ftp:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "https:example.com/", >- "base": "about:blank", >- "href": "https://example.com/", >- "origin": "https://example.com", >- "protocol": "https:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "madeupscheme:example.com/", >- "base": "about:blank", >- "href": "madeupscheme:example.com/", >- "origin": "null", >- "protocol": "madeupscheme:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ftps:example.com/", >- "base": "about:blank", >- "href": "ftps:example.com/", >- "origin": "null", >- "protocol": "ftps:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "gopher:example.com/", >- "base": "about:blank", >- "href": "gopher://example.com/", >- "origin": "gopher://example.com", >- "protocol": "gopher:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ws:example.com/", >- "base": "about:blank", >- "href": "ws://example.com/", >- "origin": "ws://example.com", >- "protocol": "ws:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "wss:example.com/", >- "base": "about:blank", >- "href": "wss://example.com/", >- "origin": "wss://example.com", >- "protocol": "wss:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "data:example.com/", >- "base": "about:blank", >- "href": "data:example.com/", >- "origin": "null", >- "protocol": "data:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "javascript:example.com/", >- "base": "about:blank", >- "href": "javascript:example.com/", >- "origin": "null", >- "protocol": "javascript:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "example.com/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "mailto:example.com/", >- "base": "about:blank", >- "href": "mailto:example.com/", >- "origin": "null", >- "protocol": "mailto:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "example.com/", >- "search": "", >- "hash": "" >- }, >- "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/segments-userinfo-vs-host.html", >- { >- "input": "http:@www.example.com", >- "base": "about:blank", >- "href": "http://www.example.com/", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http:/@www.example.com", >- "base": "about:blank", >- "href": "http://www.example.com/", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://@www.example.com", >- "base": "about:blank", >- "href": "http://www.example.com/", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http:a:b@www.example.com", >- "base": "about:blank", >- "href": "http://a:b@www.example.com/", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "a", >- "password": "b", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http:/a:b@www.example.com", >- "base": "about:blank", >- "href": "http://a:b@www.example.com/", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "a", >- "password": "b", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://a:b@www.example.com", >- "base": "about:blank", >- "href": "http://a:b@www.example.com/", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "a", >- "password": "b", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://@pple.com", >- "base": "about:blank", >- "href": "http://pple.com/", >- "origin": "http://pple.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "pple.com", >- "hostname": "pple.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http::b@www.example.com", >- "base": "about:blank", >- "href": "http://:b@www.example.com/", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "", >- "password": "b", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http:/:b@www.example.com", >- "base": "about:blank", >- "href": "http://:b@www.example.com/", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "", >- "password": "b", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://:b@www.example.com", >- "base": "about:blank", >- "href": "http://:b@www.example.com/", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "", >- "password": "b", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http:/:@/www.example.com", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "http://user@/www.example.com", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "http:@/www.example.com", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "http:/@/www.example.com", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "http://@/www.example.com", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "https:@/www.example.com", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "http:a:b@/www.example.com", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "http:/a:b@/www.example.com", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "http://a:b@/www.example.com", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "http::@/www.example.com", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "http:a:@www.example.com", >- "base": "about:blank", >- "href": "http://a@www.example.com/", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "a", >- "password": "", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http:/a:@www.example.com", >- "base": "about:blank", >- "href": "http://a@www.example.com/", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "a", >- "password": "", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://a:@www.example.com", >- "base": "about:blank", >- "href": "http://a@www.example.com/", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "a", >- "password": "", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://www.@pple.com", >- "base": "about:blank", >- "href": "http://www.@pple.com/", >- "origin": "http://pple.com", >- "protocol": "http:", >- "username": "www.", >- "password": "", >- "host": "pple.com", >- "hostname": "pple.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http:@:www.example.com", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "http:/@:www.example.com", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "http://@:www.example.com", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "http://:@www.example.com", >- "base": "about:blank", >- "href": "http://www.example.com/", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- "# Others", >- { >- "input": "/", >- "base": "http://www.example.com/test", >- "href": "http://www.example.com/", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "/test.txt", >- "base": "http://www.example.com/test", >- "href": "http://www.example.com/test.txt", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/test.txt", >- "search": "", >- "hash": "" >- }, >- { >- "input": ".", >- "base": "http://www.example.com/test", >- "href": "http://www.example.com/", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "..", >- "base": "http://www.example.com/test", >- "href": "http://www.example.com/", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "test.txt", >- "base": "http://www.example.com/test", >- "href": "http://www.example.com/test.txt", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/test.txt", >- "search": "", >- "hash": "" >- }, >- { >- "input": "./test.txt", >- "base": "http://www.example.com/test", >- "href": "http://www.example.com/test.txt", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/test.txt", >- "search": "", >- "hash": "" >- }, >- { >- "input": "../test.txt", >- "base": "http://www.example.com/test", >- "href": "http://www.example.com/test.txt", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/test.txt", >- "search": "", >- "hash": "" >- }, >- { >- "input": "../aaa/test.txt", >- "base": "http://www.example.com/test", >- "href": "http://www.example.com/aaa/test.txt", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/aaa/test.txt", >- "search": "", >- "hash": "" >- }, >- { >- "input": "../../test.txt", >- "base": "http://www.example.com/test", >- "href": "http://www.example.com/test.txt", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/test.txt", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ä¸/test.txt", >- "base": "http://www.example.com/test", >- "href": "http://www.example.com/%E4%B8%AD/test.txt", >- "origin": "http://www.example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.example.com", >- "hostname": "www.example.com", >- "port": "", >- "pathname": "/%E4%B8%AD/test.txt", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://www.example2.com", >- "base": "http://www.example.com/test", >- "href": "http://www.example2.com/", >- "origin": "http://www.example2.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.example2.com", >- "hostname": "www.example2.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "//www.example2.com", >- "base": "http://www.example.com/test", >- "href": "http://www.example2.com/", >- "origin": "http://www.example2.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.example2.com", >- "hostname": "www.example2.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file:...", >- "base": "http://www.example.com/test", >- "href": "file:///...", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/...", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file:..", >- "base": "http://www.example.com/test", >- "href": "file:///", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file:a", >- "base": "http://www.example.com/test", >- "href": "file:///a", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/a", >- "search": "", >- "hash": "" >- }, >- "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/host.html", >- "Basic canonicalization, uppercase should be converted to lowercase", >- { >- "input": "http://ExAmPlE.CoM", >- "base": "http://other.com/", >- "href": "http://example.com/", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example example.com", >- "base": "http://other.com/", >- "failure": true >- }, >- { >- "input": "http://Goo%20 goo%7C|.com", >- "base": "http://other.com/", >- "failure": true >- }, >- { >- "input": "http://[]", >- "base": "http://other.com/", >- "failure": true >- }, >- { >- "input": "http://[:]", >- "base": "http://other.com/", >- "failure": true >- }, >- "U+3000 is mapped to U+0020 (space) which is disallowed", >- { >- "input": "http://GOO\u00a0\u3000goo.com", >- "base": "http://other.com/", >- "failure": true >- }, >- "Other types of space (no-break, zero-width, zero-width-no-break) are name-prepped away to nothing. U+200B, U+2060, and U+FEFF, are ignored", >- { >- "input": "http://GOO\u200b\u2060\ufeffgoo.com", >- "base": "http://other.com/", >- "href": "http://googoo.com/", >- "origin": "http://googoo.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "googoo.com", >- "hostname": "googoo.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- "Leading and trailing C0 control or space", >- { >- "input": "\u0000\u001b\u0004\u0012 http://example.com/\u001f \u000d ", >- "base": "about:blank", >- "href": "http://example.com/", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- "Ideographic full stop (full-width period for Chinese, etc.) should be treated as a dot. U+3002 is mapped to U+002E (dot)", >- { >- "input": "http://www.fooãbar.com", >- "base": "http://other.com/", >- "href": "http://www.foo.bar.com/", >- "origin": "http://www.foo.bar.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "www.foo.bar.com", >- "hostname": "www.foo.bar.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- "Invalid unicode characters should fail... U+FDD0 is disallowed; %ef%b7%90 is U+FDD0", >- { >- "input": "http://\ufdd0zyx.com", >- "base": "http://other.com/", >- "failure": true >- }, >- "This is the same as previous but escaped", >- { >- "input": "http://%ef%b7%90zyx.com", >- "base": "http://other.com/", >- "failure": true >- }, >- "U+FFFD", >- { >- "input": "https://\ufffd", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "https://%EF%BF%BD", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "https://x/\ufffd?\ufffd#\ufffd", >- "base": "about:blank", >- "href": "https://x/%EF%BF%BD?%EF%BF%BD#%EF%BF%BD", >- "origin": "https://x", >- "protocol": "https:", >- "username": "", >- "password": "", >- "host": "x", >- "hostname": "x", >- "port": "", >- "pathname": "/%EF%BF%BD", >- "search": "?%EF%BF%BD", >- "hash": "#%EF%BF%BD" >- }, >- "Test name prepping, fullwidth input should be converted to ASCII and NOT IDN-ized. This is 'Go' in fullwidth UTF-8/UTF-16.", >- { >- "input": "http://ï¼§ï½.com", >- "base": "http://other.com/", >- "href": "http://go.com/", >- "origin": "http://go.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "go.com", >- "hostname": "go.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- "URL spec forbids the following. https://www.w3.org/Bugs/Public/show_bug.cgi?id=24257", >- { >- "input": "http://ï¼ ï¼ï¼.com", >- "base": "http://other.com/", >- "failure": true >- }, >- { >- "input": "http://%ef%bc%85%ef%bc%94%ef%bc%91.com", >- "base": "http://other.com/", >- "failure": true >- }, >- "...%00 in fullwidth should fail (also as escaped UTF-8 input)", >- { >- "input": "http://ï¼ ï¼ï¼.com", >- "base": "http://other.com/", >- "failure": true >- }, >- { >- "input": "http://%ef%bc%85%ef%bc%90%ef%bc%90.com", >- "base": "http://other.com/", >- "failure": true >- }, >- "Basic IDN support, UTF-8 and UTF-16 input should be converted to IDN", >- { >- "input": "http://ä½ å¥½ä½ å¥½", >- "base": "http://other.com/", >- "href": "http://xn--6qqa088eba/", >- "origin": "http://xn--6qqa088eba", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "xn--6qqa088eba", >- "hostname": "xn--6qqa088eba", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "https://faÃ.ExAmPlE/", >- "base": "about:blank", >- "href": "https://xn--fa-hia.example/", >- "origin": "https://xn--fa-hia.example", >- "protocol": "https:", >- "username": "", >- "password": "", >- "host": "xn--fa-hia.example", >- "hostname": "xn--fa-hia.example", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "sc://faÃ.ExAmPlE/", >- "base": "about:blank", >- "href": "sc://fa%C3%9F.ExAmPlE/", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "fa%C3%9F.ExAmPlE", >- "hostname": "fa%C3%9F.ExAmPlE", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- "Invalid escaped characters should fail and the percents should be escaped. https://www.w3.org/Bugs/Public/show_bug.cgi?id=24191", >- { >- "input": "http://%zz%66%a.com", >- "base": "http://other.com/", >- "failure": true >- }, >- "If we get an invalid character that has been escaped.", >- { >- "input": "http://%25", >- "base": "http://other.com/", >- "failure": true >- }, >- { >- "input": "http://hello%00", >- "base": "http://other.com/", >- "failure": true >- }, >- "Escaped numbers should be treated like IP addresses if they are.", >- { >- "input": "http://%30%78%63%30%2e%30%32%35%30.01", >- "base": "http://other.com/", >- "href": "http://192.168.0.1/", >- "origin": "http://192.168.0.1", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "192.168.0.1", >- "hostname": "192.168.0.1", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://%30%78%63%30%2e%30%32%35%30.01%2e", >- "base": "http://other.com/", >- "href": "http://192.168.0.1/", >- "origin": "http://192.168.0.1", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "192.168.0.1", >- "hostname": "192.168.0.1", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://192.168.0.257", >- "base": "http://other.com/", >- "failure": true >- }, >- "Invalid escaping in hosts causes failure", >- { >- "input": "http://%3g%78%63%30%2e%30%32%35%30%2E.01", >- "base": "http://other.com/", >- "failure": true >- }, >- "A space in a host causes failure", >- { >- "input": "http://192.168.0.1 hello", >- "base": "http://other.com/", >- "failure": true >- }, >- { >- "input": "https://x x:12", >- "base": "about:blank", >- "failure": true >- }, >- "Fullwidth and escaped UTF-8 fullwidth should still be treated as IP", >- { >- "input": "http://ï¼ï¼¸ï½ï¼ï¼ï¼ï¼ï¼ï¼ï¼ï¼ï¼", >- "base": "http://other.com/", >- "href": "http://192.168.0.1/", >- "origin": "http://192.168.0.1", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "192.168.0.1", >- "hostname": "192.168.0.1", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- "Domains with empty labels", >- { >- "input": "http://./", >- "base": "about:blank", >- "href": "http://./", >- "origin": "http://.", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": ".", >- "hostname": ".", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://../", >- "base": "about:blank", >- "href": "http://../", >- "origin": "http://..", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "..", >- "hostname": "..", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://0..0x300/", >- "base": "about:blank", >- "href": "http://0..0x300/", >- "origin": "http://0..0x300", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "0..0x300", >- "hostname": "0..0x300", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- "Broken IPv6", >- { >- "input": "http://[www.google.com]/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "http://[google.com]", >- "base": "http://other.com/", >- "failure": true >- }, >- { >- "input": "http://[::1.2.3.4x]", >- "base": "http://other.com/", >- "failure": true >- }, >- { >- "input": "http://[::1.2.3.]", >- "base": "http://other.com/", >- "failure": true >- }, >- { >- "input": "http://[::1.2.]", >- "base": "http://other.com/", >- "failure": true >- }, >- { >- "input": "http://[::1.]", >- "base": "http://other.com/", >- "failure": true >- }, >- "Misc Unicode", >- { >- "input": "http://foo:ð©@example.com/bar", >- "base": "http://other.com/", >- "href": "http://foo:%F0%9F%92%A9@example.com/bar", >- "origin": "http://example.com", >- "protocol": "http:", >- "username": "foo", >- "password": "%F0%9F%92%A9", >- "host": "example.com", >- "hostname": "example.com", >- "port": "", >- "pathname": "/bar", >- "search": "", >- "hash": "" >- }, >- "# resolving a fragment against any scheme succeeds", >- { >- "input": "#", >- "base": "test:test", >- "href": "test:test#", >- "origin": "null", >- "protocol": "test:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "test", >- "search": "", >- "hash": "" >- }, >- { >- "input": "#x", >- "base": "mailto:x@x.com", >- "href": "mailto:x@x.com#x", >- "origin": "null", >- "protocol": "mailto:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "x@x.com", >- "search": "", >- "hash": "#x" >- }, >- { >- "input": "#x", >- "base": "data:,", >- "href": "data:,#x", >- "origin": "null", >- "protocol": "data:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": ",", >- "search": "", >- "hash": "#x" >- }, >- { >- "input": "#x", >- "base": "about:blank", >- "href": "about:blank#x", >- "origin": "null", >- "protocol": "about:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "blank", >- "search": "", >- "hash": "#x" >- }, >- { >- "input": "#", >- "base": "test:test?test", >- "href": "test:test?test#", >- "origin": "null", >- "protocol": "test:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "test", >- "search": "?test", >- "hash": "" >- }, >- "# multiple @ in authority state", >- { >- "input": "https://@test@test@example:800/", >- "base": "http://doesnotmatter/", >- "href": "https://%40test%40test@example:800/", >- "origin": "https://example:800", >- "protocol": "https:", >- "username": "%40test%40test", >- "password": "", >- "host": "example:800", >- "hostname": "example", >- "port": "800", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "https://@@@example", >- "base": "http://doesnotmatter/", >- "href": "https://%40%40@example/", >- "origin": "https://example", >- "protocol": "https:", >- "username": "%40%40", >- "password": "", >- "host": "example", >- "hostname": "example", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- "non-az-09 characters", >- { >- "input": "http://`{}:`{}@h/`{}?`{}", >- "base": "http://doesnotmatter/", >- "href": "http://%60%7B%7D:%60%7B%7D@h/%60%7B%7D?`{}", >- "origin": "http://h", >- "protocol": "http:", >- "username": "%60%7B%7D", >- "password": "%60%7B%7D", >- "host": "h", >- "hostname": "h", >- "port": "", >- "pathname": "/%60%7B%7D", >- "search": "?`{}", >- "hash": "" >- }, >- "# Credentials in base", >- { >- "input": "/some/path", >- "base": "http://user@example.org/smth", >- "href": "http://user@example.org/some/path", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "user", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/some/path", >- "search": "", >- "hash": "" >- }, >- { >- "input": "", >- "base": "http://user:pass@example.org:21/smth", >- "href": "http://user:pass@example.org:21/smth", >- "origin": "http://example.org:21", >- "protocol": "http:", >- "username": "user", >- "password": "pass", >- "host": "example.org:21", >- "hostname": "example.org", >- "port": "21", >- "pathname": "/smth", >- "search": "", >- "hash": "" >- }, >- { >- "input": "/some/path", >- "base": "http://user:pass@example.org:21/smth", >- "href": "http://user:pass@example.org:21/some/path", >- "origin": "http://example.org:21", >- "protocol": "http:", >- "username": "user", >- "password": "pass", >- "host": "example.org:21", >- "hostname": "example.org", >- "port": "21", >- "pathname": "/some/path", >- "search": "", >- "hash": "" >- }, >- "# a set of tests designed by zcorpan for relative URLs with unknown schemes", >- { >- "input": "i", >- "base": "sc:sd", >- "failure": true >- }, >- { >- "input": "i", >- "base": "sc:sd/sd", >- "failure": true >- }, >- { >- "input": "i", >- "base": "sc:/pa/pa", >- "href": "sc:/pa/i", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/pa/i", >- "search": "", >- "hash": "" >- }, >- { >- "input": "i", >- "base": "sc://ho/pa", >- "href": "sc://ho/i", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "ho", >- "hostname": "ho", >- "port": "", >- "pathname": "/i", >- "search": "", >- "hash": "" >- }, >- { >- "input": "i", >- "base": "sc:///pa/pa", >- "href": "sc:///pa/i", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/pa/i", >- "search": "", >- "hash": "" >- }, >- { >- "input": "../i", >- "base": "sc:sd", >- "failure": true >- }, >- { >- "input": "../i", >- "base": "sc:sd/sd", >- "failure": true >- }, >- { >- "input": "../i", >- "base": "sc:/pa/pa", >- "href": "sc:/i", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/i", >- "search": "", >- "hash": "" >- }, >- { >- "input": "../i", >- "base": "sc://ho/pa", >- "href": "sc://ho/i", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "ho", >- "hostname": "ho", >- "port": "", >- "pathname": "/i", >- "search": "", >- "hash": "" >- }, >- { >- "input": "../i", >- "base": "sc:///pa/pa", >- "href": "sc:///i", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/i", >- "search": "", >- "hash": "" >- }, >- { >- "input": "/i", >- "base": "sc:sd", >- "failure": true >- }, >- { >- "input": "/i", >- "base": "sc:sd/sd", >- "failure": true >- }, >- { >- "input": "/i", >- "base": "sc:/pa/pa", >- "href": "sc:/i", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/i", >- "search": "", >- "hash": "" >- }, >- { >- "input": "/i", >- "base": "sc://ho/pa", >- "href": "sc://ho/i", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "ho", >- "hostname": "ho", >- "port": "", >- "pathname": "/i", >- "search": "", >- "hash": "" >- }, >- { >- "input": "/i", >- "base": "sc:///pa/pa", >- "href": "sc:///i", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/i", >- "search": "", >- "hash": "" >- }, >- { >- "input": "?i", >- "base": "sc:sd", >- "failure": true >- }, >- { >- "input": "?i", >- "base": "sc:sd/sd", >- "failure": true >- }, >- { >- "input": "?i", >- "base": "sc:/pa/pa", >- "href": "sc:/pa/pa?i", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/pa/pa", >- "search": "?i", >- "hash": "" >- }, >- { >- "input": "?i", >- "base": "sc://ho/pa", >- "href": "sc://ho/pa?i", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "ho", >- "hostname": "ho", >- "port": "", >- "pathname": "/pa", >- "search": "?i", >- "hash": "" >- }, >- { >- "input": "?i", >- "base": "sc:///pa/pa", >- "href": "sc:///pa/pa?i", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/pa/pa", >- "search": "?i", >- "hash": "" >- }, >- { >- "input": "#i", >- "base": "sc:sd", >- "href": "sc:sd#i", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "sd", >- "search": "", >- "hash": "#i" >- }, >- { >- "input": "#i", >- "base": "sc:sd/sd", >- "href": "sc:sd/sd#i", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "sd/sd", >- "search": "", >- "hash": "#i" >- }, >- { >- "input": "#i", >- "base": "sc:/pa/pa", >- "href": "sc:/pa/pa#i", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/pa/pa", >- "search": "", >- "hash": "#i" >- }, >- { >- "input": "#i", >- "base": "sc://ho/pa", >- "href": "sc://ho/pa#i", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "ho", >- "hostname": "ho", >- "port": "", >- "pathname": "/pa", >- "search": "", >- "hash": "#i" >- }, >- { >- "input": "#i", >- "base": "sc:///pa/pa", >- "href": "sc:///pa/pa#i", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/pa/pa", >- "search": "", >- "hash": "#i" >- }, >- "# make sure that relative URL logic works on known typically non-relative schemes too", >- { >- "input": "about:/../", >- "base": "about:blank", >- "href": "about:/", >- "origin": "null", >- "protocol": "about:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "data:/../", >- "base": "about:blank", >- "href": "data:/", >- "origin": "null", >- "protocol": "data:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "javascript:/../", >- "base": "about:blank", >- "href": "javascript:/", >- "origin": "null", >- "protocol": "javascript:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "mailto:/../", >- "base": "about:blank", >- "href": "mailto:/", >- "origin": "null", >- "protocol": "mailto:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- "# unknown schemes and their hosts", >- { >- "input": "sc://ñ.test/", >- "base": "about:blank", >- "href": "sc://%C3%B1.test/", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "%C3%B1.test", >- "hostname": "%C3%B1.test", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "sc://\u001F!\"$&'()*+,-.;<=>^_`{|}~/", >- "base": "about:blank", >- "href": "sc://%1F!\"$&'()*+,-.;<=>^_`{|}~/", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "%1F!\"$&'()*+,-.;<=>^_`{|}~", >- "hostname": "%1F!\"$&'()*+,-.;<=>^_`{|}~", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "sc://\u0000/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "sc:// /", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "sc://%/", >- "base": "about:blank", >- "href": "sc://%/", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "%", >- "hostname": "%", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "sc://@/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "sc://te@s:t@/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "sc://:/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "sc://:12/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "sc://[/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "sc://\\/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "sc://]/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "x", >- "base": "sc://ñ", >- "href": "sc://%C3%B1/x", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "%C3%B1", >- "hostname": "%C3%B1", >- "port": "", >- "pathname": "/x", >- "search": "", >- "hash": "" >- }, >- "# unknown schemes and backslashes", >- { >- "input": "sc:\\../", >- "base": "about:blank", >- "href": "sc:\\../", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "\\../", >- "search": "", >- "hash": "" >- }, >- "# unknown scheme with path looking like a password", >- { >- "input": "sc::a@example.net", >- "base": "about:blank", >- "href": "sc::a@example.net", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": ":a@example.net", >- "search": "", >- "hash": "" >- }, >- "# unknown scheme with bogus percent-encoding", >- { >- "input": "wow:%NBD", >- "base": "about:blank", >- "href": "wow:%NBD", >- "origin": "null", >- "protocol": "wow:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "%NBD", >- "search": "", >- "hash": "" >- }, >- { >- "input": "wow:%1G", >- "base": "about:blank", >- "href": "wow:%1G", >- "origin": "null", >- "protocol": "wow:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "%1G", >- "search": "", >- "hash": "" >- }, >- "# Hosts and percent-encoding", >- { >- "input": "ftp://example.com%80/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "ftp://example.com%A0/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "https://example.com%80/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "https://example.com%A0/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "ftp://%e2%98%83", >- "base": "about:blank", >- "href": "ftp://xn--n3h/", >- "origin": "ftp://xn--n3h", >- "protocol": "ftp:", >- "username": "", >- "password": "", >- "host": "xn--n3h", >- "hostname": "xn--n3h", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "https://%e2%98%83", >- "base": "about:blank", >- "href": "https://xn--n3h/", >- "origin": "https://xn--n3h", >- "protocol": "https:", >- "username": "", >- "password": "", >- "host": "xn--n3h", >- "hostname": "xn--n3h", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- "# tests from jsdom/whatwg-url designed for code coverage", >- { >- "input": "http://127.0.0.1:10100/relative_import.html", >- "base": "about:blank", >- "href": "http://127.0.0.1:10100/relative_import.html", >- "origin": "http://127.0.0.1:10100", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "127.0.0.1:10100", >- "hostname": "127.0.0.1", >- "port": "10100", >- "pathname": "/relative_import.html", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://facebook.com/?foo=%7B%22abc%22", >- "base": "about:blank", >- "href": "http://facebook.com/?foo=%7B%22abc%22", >- "origin": "http://facebook.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "facebook.com", >- "hostname": "facebook.com", >- "port": "", >- "pathname": "/", >- "search": "?foo=%7B%22abc%22", >- "hash": "" >- }, >- { >- "input": "https://localhost:3000/jqueryui@1.2.3", >- "base": "about:blank", >- "href": "https://localhost:3000/jqueryui@1.2.3", >- "origin": "https://localhost:3000", >- "protocol": "https:", >- "username": "", >- "password": "", >- "host": "localhost:3000", >- "hostname": "localhost", >- "port": "3000", >- "pathname": "/jqueryui@1.2.3", >- "search": "", >- "hash": "" >- }, >- "# tab/LF/CR", >- { >- "input": "h\tt\nt\rp://h\to\ns\rt:9\t0\n0\r0/p\ta\nt\rh?q\tu\ne\rry#f\tr\na\rg", >- "base": "about:blank", >- "href": "http://host:9000/path?query#frag", >- "origin": "http://host:9000", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "host:9000", >- "hostname": "host", >- "port": "9000", >- "pathname": "/path", >- "search": "?query", >- "hash": "#frag" >- }, >- "# Stringification of URL.searchParams", >- { >- "input": "?a=b&c=d", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/bar?a=b&c=d", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/bar", >- "search": "?a=b&c=d", >- "searchParams": "a=b&c=d", >- "hash": "" >- }, >- { >- "input": "??a=b&c=d", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/bar??a=b&c=d", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/bar", >- "search": "??a=b&c=d", >- "searchParams": "%3Fa=b&c=d", >- "hash": "" >- }, >- "# Scheme only", >- { >- "input": "http:", >- "base": "http://example.org/foo/bar", >- "href": "http://example.org/foo/bar", >- "origin": "http://example.org", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/foo/bar", >- "search": "", >- "searchParams": "", >- "hash": "" >- }, >- { >- "input": "http:", >- "base": "https://example.org/foo/bar", >- "failure": true >- }, >- { >- "input": "sc:", >- "base": "https://example.org/foo/bar", >- "href": "sc:", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "", >- "search": "", >- "searchParams": "", >- "hash": "" >- }, >- "# Percent encoding of fragments", >- { >- "input": "http://foo.bar/baz?qux#foo\bbar", >- "base": "about:blank", >- "href": "http://foo.bar/baz?qux#foo%08bar", >- "origin": "http://foo.bar", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "foo.bar", >- "hostname": "foo.bar", >- "port": "", >- "pathname": "/baz", >- "search": "?qux", >- "searchParams": "qux=", >- "hash": "#foo%08bar" >- }, >- { >- "input": "http://foo.bar/baz?qux#foo\"bar", >- "base": "about:blank", >- "href": "http://foo.bar/baz?qux#foo%22bar", >- "origin": "http://foo.bar", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "foo.bar", >- "hostname": "foo.bar", >- "port": "", >- "pathname": "/baz", >- "search": "?qux", >- "searchParams": "qux=", >- "hash": "#foo%22bar" >- }, >- { >- "input": "http://foo.bar/baz?qux#foo<bar", >- "base": "about:blank", >- "href": "http://foo.bar/baz?qux#foo%3Cbar", >- "origin": "http://foo.bar", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "foo.bar", >- "hostname": "foo.bar", >- "port": "", >- "pathname": "/baz", >- "search": "?qux", >- "searchParams": "qux=", >- "hash": "#foo%3Cbar" >- }, >- { >- "input": "http://foo.bar/baz?qux#foo>bar", >- "base": "about:blank", >- "href": "http://foo.bar/baz?qux#foo%3Ebar", >- "origin": "http://foo.bar", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "foo.bar", >- "hostname": "foo.bar", >- "port": "", >- "pathname": "/baz", >- "search": "?qux", >- "searchParams": "qux=", >- "hash": "#foo%3Ebar" >- }, >- { >- "input": "http://foo.bar/baz?qux#foo`bar", >- "base": "about:blank", >- "href": "http://foo.bar/baz?qux#foo%60bar", >- "origin": "http://foo.bar", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "foo.bar", >- "hostname": "foo.bar", >- "port": "", >- "pathname": "/baz", >- "search": "?qux", >- "searchParams": "qux=", >- "hash": "#foo%60bar" >- }, >- "# IPv4 parsing (via https://github.com/nodejs/node/pull/10317)", >- { >- "input": "http://192.168.257", >- "base": "http://other.com/", >- "href": "http://192.168.1.1/", >- "origin": "http://192.168.1.1", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "192.168.1.1", >- "hostname": "192.168.1.1", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://192.168.257.com", >- "base": "http://other.com/", >- "href": "http://192.168.257.com/", >- "origin": "http://192.168.257.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "192.168.257.com", >- "hostname": "192.168.257.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://256", >- "base": "http://other.com/", >- "href": "http://0.0.1.0/", >- "origin": "http://0.0.1.0", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "0.0.1.0", >- "hostname": "0.0.1.0", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://256.com", >- "base": "http://other.com/", >- "href": "http://256.com/", >- "origin": "http://256.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "256.com", >- "hostname": "256.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://999999999", >- "base": "http://other.com/", >- "href": "http://59.154.201.255/", >- "origin": "http://59.154.201.255", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "59.154.201.255", >- "hostname": "59.154.201.255", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://999999999.com", >- "base": "http://other.com/", >- "href": "http://999999999.com/", >- "origin": "http://999999999.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "999999999.com", >- "hostname": "999999999.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://10000000000", >- "base": "http://other.com/", >- "failure": true >- }, >- { >- "input": "http://10000000000.com", >- "base": "http://other.com/", >- "href": "http://10000000000.com/", >- "origin": "http://10000000000.com", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "10000000000.com", >- "hostname": "10000000000.com", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://4294967295", >- "base": "http://other.com/", >- "href": "http://255.255.255.255/", >- "origin": "http://255.255.255.255", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "255.255.255.255", >- "hostname": "255.255.255.255", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://4294967296", >- "base": "http://other.com/", >- "failure": true >- }, >- { >- "input": "http://0xffffffff", >- "base": "http://other.com/", >- "href": "http://255.255.255.255/", >- "origin": "http://255.255.255.255", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "255.255.255.255", >- "hostname": "255.255.255.255", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://0xffffffff1", >- "base": "http://other.com/", >- "failure": true >- }, >- { >- "input": "http://256.256.256.256", >- "base": "http://other.com/", >- "failure": true >- }, >- { >- "input": "http://256.256.256.256.256", >- "base": "http://other.com/", >- "href": "http://256.256.256.256.256/", >- "origin": "http://256.256.256.256.256", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "256.256.256.256.256", >- "hostname": "256.256.256.256.256", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "https://0x.0x.0", >- "base": "about:blank", >- "href": "https://0.0.0.0/", >- "origin": "https://0.0.0.0", >- "protocol": "https:", >- "username": "", >- "password": "", >- "host": "0.0.0.0", >- "hostname": "0.0.0.0", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- "More IPv4 parsing (via https://github.com/jsdom/whatwg-url/issues/92)", >- { >- "input": "https://0x100000000/test", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "https://256.0.0.1/test", >- "base": "about:blank", >- "failure": true >- }, >- "# file URLs containing percent-encoded Windows drive letters (shouldn't work)", >- { >- "input": "file:///C%3A/", >- "base": "about:blank", >- "href": "file:///C%3A/", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C%3A/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file:///C%7C/", >- "base": "about:blank", >- "href": "file:///C%7C/", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C%7C/", >- "search": "", >- "hash": "" >- }, >- "# file URLs relative to other file URLs (via https://github.com/jsdom/whatwg-url/pull/60)", >- { >- "input": "pix/submit.gif", >- "base": "file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/anchor.html", >- "href": "file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/pix/submit.gif", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/pix/submit.gif", >- "search": "", >- "hash": "" >- }, >- { >- "input": "..", >- "base": "file:///C:/", >- "href": "file:///C:/", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C:/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "..", >- "base": "file:///", >- "href": "file:///", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- "# More file URL tests by zcorpan and annevk", >- { >- "input": "/", >- "base": "file:///C:/a/b", >- "href": "file:///C:/", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C:/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "//d:", >- "base": "file:///C:/a/b", >- "href": "file:///d:", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/d:", >- "search": "", >- "hash": "" >- }, >- { >- "input": "//d:/..", >- "base": "file:///C:/a/b", >- "href": "file:///d:/", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/d:/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "..", >- "base": "file:///ab:/", >- "href": "file:///", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "..", >- "base": "file:///1:/", >- "href": "file:///", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "", >- "base": "file:///test?test#test", >- "href": "file:///test?test", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/test", >- "search": "?test", >- "hash": "" >- }, >- { >- "input": "file:", >- "base": "file:///test?test#test", >- "href": "file:///test?test", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/test", >- "search": "?test", >- "hash": "" >- }, >- { >- "input": "?x", >- "base": "file:///test?test#test", >- "href": "file:///test?x", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/test", >- "search": "?x", >- "hash": "" >- }, >- { >- "input": "file:?x", >- "base": "file:///test?test#test", >- "href": "file:///test?x", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/test", >- "search": "?x", >- "hash": "" >- }, >- { >- "input": "#x", >- "base": "file:///test?test#test", >- "href": "file:///test?test#x", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/test", >- "search": "?test", >- "hash": "#x" >- }, >- { >- "input": "file:#x", >- "base": "file:///test?test#test", >- "href": "file:///test?test#x", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/test", >- "search": "?test", >- "hash": "#x" >- }, >- "# File URLs and many (back)slashes", >- { >- "input": "file:\\\\//", >- "base": "about:blank", >- "href": "file:///", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file:\\\\\\\\", >- "base": "about:blank", >- "href": "file:///", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file:\\\\\\\\?fox", >- "base": "about:blank", >- "href": "file:///?fox", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "?fox", >- "hash": "" >- }, >- { >- "input": "file:\\\\\\\\#guppy", >- "base": "about:blank", >- "href": "file:///#guppy", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "#guppy" >- }, >- { >- "input": "file://spider///", >- "base": "about:blank", >- "href": "file://spider/", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "spider", >- "hostname": "spider", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file:\\\\localhost//", >- "base": "about:blank", >- "href": "file:///", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file:///localhost//cat", >- "base": "about:blank", >- "href": "file:///localhost//cat", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/localhost//cat", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file://\\/localhost//cat", >- "base": "about:blank", >- "href": "file:///localhost//cat", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/localhost//cat", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file://localhost//a//../..//", >- "base": "about:blank", >- "href": "file:///", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "/////mouse", >- "base": "file:///elephant", >- "href": "file:///mouse", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/mouse", >- "search": "", >- "hash": "" >- }, >- { >- "input": "\\//pig", >- "base": "file://lion/", >- "href": "file:///pig", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/pig", >- "search": "", >- "hash": "" >- }, >- { >- "input": "\\/localhost//pig", >- "base": "file://lion/", >- "href": "file:///pig", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/pig", >- "search": "", >- "hash": "" >- }, >- { >- "input": "//localhost//pig", >- "base": "file://lion/", >- "href": "file:///pig", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/pig", >- "search": "", >- "hash": "" >- }, >- { >- "input": "/..//localhost//pig", >- "base": "file://lion/", >- "href": "file://lion/localhost//pig", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "lion", >- "hostname": "lion", >- "port": "", >- "pathname": "/localhost//pig", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file://", >- "base": "file://ape/", >- "href": "file:///", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- "# File URLs with non-empty hosts", >- { >- "input": "/rooibos", >- "base": "file://tea/", >- "href": "file://tea/rooibos", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "tea", >- "hostname": "tea", >- "port": "", >- "pathname": "/rooibos", >- "search": "", >- "hash": "" >- }, >- { >- "input": "/?chai", >- "base": "file://tea/", >- "href": "file://tea/?chai", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "tea", >- "hostname": "tea", >- "port": "", >- "pathname": "/", >- "search": "?chai", >- "hash": "" >- }, >- "# Windows drive letter handling with the 'file:' base URL", >- { >- "input": "C|", >- "base": "file://host/dir/file", >- "href": "file:///C:", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C:", >- "search": "", >- "hash": "" >- }, >- { >- "input": "C|#", >- "base": "file://host/dir/file", >- "href": "file:///C:#", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C:", >- "search": "", >- "hash": "" >- }, >- { >- "input": "C|?", >- "base": "file://host/dir/file", >- "href": "file:///C:?", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C:", >- "search": "", >- "hash": "" >- }, >- { >- "input": "C|/", >- "base": "file://host/dir/file", >- "href": "file:///C:/", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C:/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "C|\n/", >- "base": "file://host/dir/file", >- "href": "file:///C:/", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C:/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "C|\\", >- "base": "file://host/dir/file", >- "href": "file:///C:/", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C:/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "C", >- "base": "file://host/dir/file", >- "href": "file://host/dir/C", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "host", >- "hostname": "host", >- "port": "", >- "pathname": "/dir/C", >- "search": "", >- "hash": "" >- }, >- { >- "input": "C|a", >- "base": "file://host/dir/file", >- "href": "file://host/dir/C|a", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "host", >- "hostname": "host", >- "port": "", >- "pathname": "/dir/C|a", >- "search": "", >- "hash": "" >- }, >- "# Windows drive letter quirk in the file slash state", >- { >- "input": "/c:/foo/bar", >- "base": "file:///c:/baz/qux", >- "href": "file:///c:/foo/bar", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/c:/foo/bar", >- "search": "", >- "hash": "" >- }, >- { >- "input": "/c|/foo/bar", >- "base": "file:///c:/baz/qux", >- "href": "file:///c:/foo/bar", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/c:/foo/bar", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file:\\c:\\foo\\bar", >- "base": "file:///c:/baz/qux", >- "href": "file:///c:/foo/bar", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/c:/foo/bar", >- "search": "", >- "hash": "" >- }, >- { >- "input": "/c:/foo/bar", >- "base": "file://host/path", >- "href": "file:///c:/foo/bar", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/c:/foo/bar", >- "search": "", >- "hash": "" >- }, >- "# Windows drive letter quirk with not empty host", >- { >- "input": "file://example.net/C:/", >- "base": "about:blank", >- "href": "file:///C:/", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C:/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file://1.2.3.4/C:/", >- "base": "about:blank", >- "href": "file:///C:/", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C:/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file://[1::8]/C:/", >- "base": "about:blank", >- "href": "file:///C:/", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C:/", >- "search": "", >- "hash": "" >- }, >- "# Windows drive letter quirk (no host)", >- { >- "input": "file:/C|/", >- "base": "about:blank", >- "href": "file:///C:/", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C:/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file://C|/", >- "base": "about:blank", >- "href": "file:///C:/", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/C:/", >- "search": "", >- "hash": "" >- }, >- "# file URLs without base URL by Rimas MiseviÄius", >- { >- "input": "file:", >- "base": "about:blank", >- "href": "file:///", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "file:?q=v", >- "base": "about:blank", >- "href": "file:///?q=v", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "?q=v", >- "hash": "" >- }, >- { >- "input": "file:#frag", >- "base": "about:blank", >- "href": "file:///#frag", >- "protocol": "file:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "#frag" >- }, >- "# IPv6 tests", >- { >- "input": "http://[1:0::]", >- "base": "http://example.net/", >- "href": "http://[1::]/", >- "origin": "http://[1::]", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "[1::]", >- "hostname": "[1::]", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://[0:1:2:3:4:5:6:7:8]", >- "base": "http://example.net/", >- "failure": true >- }, >- { >- "input": "https://[0::0::0]", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "https://[0:.0]", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "https://[0:0:]", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "https://[0:1:2:3:4:5:6:7.0.0.0.1]", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "https://[0:1.00.0.0.0]", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "https://[0:1.290.0.0.0]", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "https://[0:1.23.23]", >- "base": "about:blank", >- "failure": true >- }, >- "# Empty host", >- { >- "input": "http://?", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "http://#", >- "base": "about:blank", >- "failure": true >- }, >- "Port overflow (2^32 + 81)", >- { >- "input": "http://f:4294967377/c", >- "base": "http://example.org/", >- "failure": true >- }, >- "Port overflow (2^64 + 81)", >- { >- "input": "http://f:18446744073709551697/c", >- "base": "http://example.org/", >- "failure": true >- }, >- "Port overflow (2^128 + 81)", >- { >- "input": "http://f:340282366920938463463374607431768211537/c", >- "base": "http://example.org/", >- "failure": true >- }, >- "# Non-special-URL path tests", >- { >- "input": "sc://ñ", >- "base": "about:blank", >- "href": "sc://%C3%B1", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "%C3%B1", >- "hostname": "%C3%B1", >- "port": "", >- "pathname": "", >- "search": "", >- "hash": "" >- }, >- { >- "input": "sc://ñ?x", >- "base": "about:blank", >- "href": "sc://%C3%B1?x", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "%C3%B1", >- "hostname": "%C3%B1", >- "port": "", >- "pathname": "", >- "search": "?x", >- "hash": "" >- }, >- { >- "input": "sc://ñ#x", >- "base": "about:blank", >- "href": "sc://%C3%B1#x", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "%C3%B1", >- "hostname": "%C3%B1", >- "port": "", >- "pathname": "", >- "search": "", >- "hash": "#x" >- }, >- { >- "input": "#x", >- "base": "sc://ñ", >- "href": "sc://%C3%B1#x", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "%C3%B1", >- "hostname": "%C3%B1", >- "port": "", >- "pathname": "", >- "search": "", >- "hash": "#x" >- }, >- { >- "input": "?x", >- "base": "sc://ñ", >- "href": "sc://%C3%B1?x", >- "origin": "null", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "%C3%B1", >- "hostname": "%C3%B1", >- "port": "", >- "pathname": "", >- "search": "?x", >- "hash": "" >- }, >- { >- "input": "sc://?", >- "base": "about:blank", >- "href": "sc://?", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "", >- "search": "", >- "hash": "" >- }, >- { >- "input": "sc://#", >- "base": "about:blank", >- "href": "sc://#", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "", >- "search": "", >- "hash": "" >- }, >- { >- "input": "///", >- "base": "sc://x/", >- "href": "sc:///", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "////", >- "base": "sc://x/", >- "href": "sc:////", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "//", >- "search": "", >- "hash": "" >- }, >- { >- "input": "////x/", >- "base": "sc://x/", >- "href": "sc:////x/", >- "protocol": "sc:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "//x/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "tftp://foobar.com/someconfig;mode=netascii", >- "base": "about:blank", >- "href": "tftp://foobar.com/someconfig;mode=netascii", >- "origin": "null", >- "protocol": "tftp:", >- "username": "", >- "password": "", >- "host": "foobar.com", >- "hostname": "foobar.com", >- "port": "", >- "pathname": "/someconfig;mode=netascii", >- "search": "", >- "hash": "" >- }, >- { >- "input": "telnet://user:pass@foobar.com:23/", >- "base": "about:blank", >- "href": "telnet://user:pass@foobar.com:23/", >- "origin": "null", >- "protocol": "telnet:", >- "username": "user", >- "password": "pass", >- "host": "foobar.com:23", >- "hostname": "foobar.com", >- "port": "23", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "ut2004://10.10.10.10:7777/Index.ut2", >- "base": "about:blank", >- "href": "ut2004://10.10.10.10:7777/Index.ut2", >- "origin": "null", >- "protocol": "ut2004:", >- "username": "", >- "password": "", >- "host": "10.10.10.10:7777", >- "hostname": "10.10.10.10", >- "port": "7777", >- "pathname": "/Index.ut2", >- "search": "", >- "hash": "" >- }, >- { >- "input": "redis://foo:bar@somehost:6379/0?baz=bam&qux=baz", >- "base": "about:blank", >- "href": "redis://foo:bar@somehost:6379/0?baz=bam&qux=baz", >- "origin": "null", >- "protocol": "redis:", >- "username": "foo", >- "password": "bar", >- "host": "somehost:6379", >- "hostname": "somehost", >- "port": "6379", >- "pathname": "/0", >- "search": "?baz=bam&qux=baz", >- "hash": "" >- }, >- { >- "input": "rsync://foo@host:911/sup", >- "base": "about:blank", >- "href": "rsync://foo@host:911/sup", >- "origin": "null", >- "protocol": "rsync:", >- "username": "foo", >- "password": "", >- "host": "host:911", >- "hostname": "host", >- "port": "911", >- "pathname": "/sup", >- "search": "", >- "hash": "" >- }, >- { >- "input": "git://github.com/foo/bar.git", >- "base": "about:blank", >- "href": "git://github.com/foo/bar.git", >- "origin": "null", >- "protocol": "git:", >- "username": "", >- "password": "", >- "host": "github.com", >- "hostname": "github.com", >- "port": "", >- "pathname": "/foo/bar.git", >- "search": "", >- "hash": "" >- }, >- { >- "input": "irc://myserver.com:6999/channel?passwd", >- "base": "about:blank", >- "href": "irc://myserver.com:6999/channel?passwd", >- "origin": "null", >- "protocol": "irc:", >- "username": "", >- "password": "", >- "host": "myserver.com:6999", >- "hostname": "myserver.com", >- "port": "6999", >- "pathname": "/channel", >- "search": "?passwd", >- "hash": "" >- }, >- { >- "input": "dns://fw.example.org:9999/foo.bar.org?type=TXT", >- "base": "about:blank", >- "href": "dns://fw.example.org:9999/foo.bar.org?type=TXT", >- "origin": "null", >- "protocol": "dns:", >- "username": "", >- "password": "", >- "host": "fw.example.org:9999", >- "hostname": "fw.example.org", >- "port": "9999", >- "pathname": "/foo.bar.org", >- "search": "?type=TXT", >- "hash": "" >- }, >- { >- "input": "ldap://localhost:389/ou=People,o=JNDITutorial", >- "base": "about:blank", >- "href": "ldap://localhost:389/ou=People,o=JNDITutorial", >- "origin": "null", >- "protocol": "ldap:", >- "username": "", >- "password": "", >- "host": "localhost:389", >- "hostname": "localhost", >- "port": "389", >- "pathname": "/ou=People,o=JNDITutorial", >- "search": "", >- "hash": "" >- }, >- { >- "input": "git+https://github.com/foo/bar", >- "base": "about:blank", >- "href": "git+https://github.com/foo/bar", >- "origin": "null", >- "protocol": "git+https:", >- "username": "", >- "password": "", >- "host": "github.com", >- "hostname": "github.com", >- "port": "", >- "pathname": "/foo/bar", >- "search": "", >- "hash": "" >- }, >- { >- "input": "urn:ietf:rfc:2648", >- "base": "about:blank", >- "href": "urn:ietf:rfc:2648", >- "origin": "null", >- "protocol": "urn:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "ietf:rfc:2648", >- "search": "", >- "hash": "" >- }, >- { >- "input": "tag:joe@example.org,2001:foo/bar", >- "base": "about:blank", >- "href": "tag:joe@example.org,2001:foo/bar", >- "origin": "null", >- "protocol": "tag:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "joe@example.org,2001:foo/bar", >- "search": "", >- "hash": "" >- }, >- "# percent encoded hosts in non-special-URLs", >- { >- "input": "non-special://%E2%80%A0/", >- "base": "about:blank", >- "href": "non-special://%E2%80%A0/", >- "protocol": "non-special:", >- "username": "", >- "password": "", >- "host": "%E2%80%A0", >- "hostname": "%E2%80%A0", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "non-special://H%4fSt/path", >- "base": "about:blank", >- "href": "non-special://H%4fSt/path", >- "protocol": "non-special:", >- "username": "", >- "password": "", >- "host": "H%4fSt", >- "hostname": "H%4fSt", >- "port": "", >- "pathname": "/path", >- "search": "", >- "hash": "" >- }, >- "# IPv6 in non-special-URLs", >- { >- "input": "non-special://[1:2:0:0:5:0:0:0]/", >- "base": "about:blank", >- "href": "non-special://[1:2:0:0:5::]/", >- "protocol": "non-special:", >- "username": "", >- "password": "", >- "host": "[1:2:0:0:5::]", >- "hostname": "[1:2:0:0:5::]", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "non-special://[1:2:0:0:0:0:0:3]/", >- "base": "about:blank", >- "href": "non-special://[1:2::3]/", >- "protocol": "non-special:", >- "username": "", >- "password": "", >- "host": "[1:2::3]", >- "hostname": "[1:2::3]", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "non-special://[1:2::3]:80/", >- "base": "about:blank", >- "href": "non-special://[1:2::3]:80/", >- "protocol": "non-special:", >- "username": "", >- "password": "", >- "host": "[1:2::3]:80", >- "hostname": "[1:2::3]", >- "port": "80", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "non-special://[:80/", >- "base": "about:blank", >- "failure": true >- }, >- { >- "input": "blob:https://example.com:443/", >- "base": "about:blank", >- "href": "blob:https://example.com:443/", >- "protocol": "blob:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "https://example.com:443/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "blob:d3958f5c-0777-0845-9dcf-2cb28783acaf", >- "base": "about:blank", >- "href": "blob:d3958f5c-0777-0845-9dcf-2cb28783acaf", >- "protocol": "blob:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "d3958f5c-0777-0845-9dcf-2cb28783acaf", >- "search": "", >- "hash": "" >- }, >- "Invalid IPv4 radix digits", >- { >- "input": "http://0177.0.0.0189", >- "base": "about:blank", >- "href": "http://0177.0.0.0189/", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "0177.0.0.0189", >- "hostname": "0177.0.0.0189", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://0x7f.0.0.0x7g", >- "base": "about:blank", >- "href": "http://0x7f.0.0.0x7g/", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "0x7f.0.0.0x7g", >- "hostname": "0x7f.0.0.0x7g", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://0X7F.0.0.0X7G", >- "base": "about:blank", >- "href": "http://0x7f.0.0.0x7g/", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "0x7f.0.0.0x7g", >- "hostname": "0x7f.0.0.0x7g", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- "Invalid IPv4 portion of IPv6 address", >- { >- "input": "http://[::127.0.0.0.1]", >- "base": "about:blank", >- "failure": true >- }, >- "Uncompressed IPv6 addresses with 0", >- { >- "input": "http://[0:1:0:1:0:1:0:1]", >- "base": "about:blank", >- "href": "http://[0:1:0:1:0:1:0:1]/", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "[0:1:0:1:0:1:0:1]", >- "hostname": "[0:1:0:1:0:1:0:1]", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://[1:0:1:0:1:0:1:0]", >- "base": "about:blank", >- "href": "http://[1:0:1:0:1:0:1:0]/", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "[1:0:1:0:1:0:1:0]", >- "hostname": "[1:0:1:0:1:0:1:0]", >- "port": "", >- "pathname": "/", >- "search": "", >- "hash": "" >- }, >- "Percent-encoded query and fragment", >- { >- "input": "http://example.org/test?\u0022", >- "base": "about:blank", >- "href": "http://example.org/test?%22", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/test", >- "search": "?%22", >- "hash": "" >- }, >- { >- "input": "http://example.org/test?\u0023", >- "base": "about:blank", >- "href": "http://example.org/test?#", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/test", >- "search": "", >- "hash": "" >- }, >- { >- "input": "http://example.org/test?\u003C", >- "base": "about:blank", >- "href": "http://example.org/test?%3C", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/test", >- "search": "?%3C", >- "hash": "" >- }, >- { >- "input": "http://example.org/test?\u003E", >- "base": "about:blank", >- "href": "http://example.org/test?%3E", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/test", >- "search": "?%3E", >- "hash": "" >- }, >- { >- "input": "http://example.org/test?\u2323", >- "base": "about:blank", >- "href": "http://example.org/test?%E2%8C%A3", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/test", >- "search": "?%E2%8C%A3", >- "hash": "" >- }, >- { >- "input": "http://example.org/test?%23%23", >- "base": "about:blank", >- "href": "http://example.org/test?%23%23", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/test", >- "search": "?%23%23", >- "hash": "" >- }, >- { >- "input": "http://example.org/test?%GH", >- "base": "about:blank", >- "href": "http://example.org/test?%GH", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/test", >- "search": "?%GH", >- "hash": "" >- }, >- { >- "input": "http://example.org/test?a#%EF", >- "base": "about:blank", >- "href": "http://example.org/test?a#%EF", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/test", >- "search": "?a", >- "hash": "#%EF" >- }, >- { >- "input": "http://example.org/test?a#%GH", >- "base": "about:blank", >- "href": "http://example.org/test?a#%GH", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/test", >- "search": "?a", >- "hash": "#%GH" >- }, >- "Bad bases", >- { >- "input": "test-a.html", >- "base": "a", >- "failure": true >- }, >- { >- "input": "test-a-slash.html", >- "base": "a/", >- "failure": true >- }, >- { >- "input": "test-a-slash-slash.html", >- "base": "a//", >- "failure": true >- }, >- { >- "input": "test-a-colon.html", >- "base": "a:", >- "failure": true >- }, >- { >- "input": "test-a-colon-slash.html", >- "base": "a:/", >- "href": "a:/test-a-colon-slash.html", >- "protocol": "a:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/test-a-colon-slash.html", >- "search": "", >- "hash": "" >- }, >- { >- "input": "test-a-colon-slash-slash.html", >- "base": "a://", >- "href": "a:///test-a-colon-slash-slash.html", >- "protocol": "a:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/test-a-colon-slash-slash.html", >- "search": "", >- "hash": "" >- }, >- { >- "input": "test-a-colon-b.html", >- "base": "a:b", >- "failure": true >- }, >- { >- "input": "test-a-colon-slash-b.html", >- "base": "a:/b", >- "href": "a:/test-a-colon-slash-b.html", >- "protocol": "a:", >- "username": "", >- "password": "", >- "host": "", >- "hostname": "", >- "port": "", >- "pathname": "/test-a-colon-slash-b.html", >- "search": "", >- "hash": "" >- }, >- { >- "input": "test-a-colon-slash-slash-b.html", >- "base": "a://b", >- "href": "a://b/test-a-colon-slash-slash-b.html", >- "protocol": "a:", >- "username": "", >- "password": "", >- "host": "b", >- "hostname": "b", >- "port": "", >- "pathname": "/test-a-colon-slash-slash-b.html", >- "search": "", >- "hash": "" >- }, >- "Null code point in fragment", >- { >- "input": "http://example.org/test?a#b\u0000c", >- "base": "about:blank", >- "href": "http://example.org/test?a#bc", >- "protocol": "http:", >- "username": "", >- "password": "", >- "host": "example.org", >- "hostname": "example.org", >- "port": "", >- "pathname": "/test", >- "search": "?a", >- "hash": "#bc" >- } >-] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/url/w3c-import.log >index 47d0bf85cba152708379edf1d99acc53b5e42b39..7cc93274f567647cb2316e4386c47fec06dbed09 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/url/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/url/w3c-import.log >@@ -18,15 +18,12 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/url/README.md > /LayoutTests/imported/w3c/web-platform-tests/url/a-element-origin-xhtml.xhtml > /LayoutTests/imported/w3c/web-platform-tests/url/a-element-origin.html >-/LayoutTests/imported/w3c/web-platform-tests/url/a-element-origin.js > /LayoutTests/imported/w3c/web-platform-tests/url/a-element-xhtml.xhtml > /LayoutTests/imported/w3c/web-platform-tests/url/a-element.html >-/LayoutTests/imported/w3c/web-platform-tests/url/a-element.js >+/LayoutTests/imported/w3c/web-platform-tests/url/data-uri-fragment.html > /LayoutTests/imported/w3c/web-platform-tests/url/failure.html > /LayoutTests/imported/w3c/web-platform-tests/url/historical.any.js > /LayoutTests/imported/w3c/web-platform-tests/url/interfaces.any.js >-/LayoutTests/imported/w3c/web-platform-tests/url/setters_tests.json >-/LayoutTests/imported/w3c/web-platform-tests/url/toascii.json > /LayoutTests/imported/w3c/web-platform-tests/url/toascii.window.js > /LayoutTests/imported/w3c/web-platform-tests/url/url-constructor.html > /LayoutTests/imported/w3c/web-platform-tests/url/url-origin.html >@@ -43,4 +40,3 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/url/urlsearchparams-set.html > /LayoutTests/imported/w3c/web-platform-tests/url/urlsearchparams-sort.html > /LayoutTests/imported/w3c/web-platform-tests/url/urlsearchparams-stringifier.html >-/LayoutTests/imported/w3c/web-platform-tests/url/urltestdata.json >diff --git a/LayoutTests/imported/w3c/web-platform-tests/user-timing/clearMarks-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/user-timing/clearMarks-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..89c73812b240e5ebf7dba02f663e94d04ed0b52a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/user-timing/clearMarks-expected.txt >@@ -0,0 +1,63 @@ >+Description >+ >+This test validates functionality of the interface window.performance.clearMarks. >+ >+ >+PASS First loop: checking entries after removing "". There should be 2 entries. >+PASS First loop: checking entries after removing "". Entries in entrylist should be in order. >+PASS First loop: checking entries after removing "". Entry_list 0. Entry "1" should be one that we have set. >+PASS First loop: checking entries after removing "". Entry_list 0. entryType should be "mark". >+PASS First loop: checking entries after removing "". Entry_list 0. startTime should greater than 0. >+PASS First loop: checking entries after removing "". Entry_list 0. duration of mark should be 0. >+PASS First loop: checking entries after removing "". Entry_list 1. Entry "abc" should be one that we have set. >+PASS First loop: checking entries after removing "". Entry_list 1. entryType should be "mark". >+PASS First loop: checking entries after removing "". Entry_list 1. startTime should greater than 0. >+PASS First loop: checking entries after removing "". Entry_list 1. duration of mark should be 0. >+PASS First loop: marks that we cleared for "" should not exist anymore. >+PASS First loop: checking entries after removing "1". There should be 1 entries. >+PASS First loop: checking entries after removing "1". Entries in entrylist should be in order. >+PASS First loop: checking entries after removing "1". Entry_list 0. Entry "abc" should be one that we have set. >+PASS First loop: checking entries after removing "1". Entry_list 0. entryType should be "mark". >+PASS First loop: checking entries after removing "1". Entry_list 0. startTime should greater than 0. >+PASS First loop: checking entries after removing "1". Entry_list 0. duration of mark should be 0. >+PASS First loop: marks that we cleared for "1" should not exist anymore. >+PASS First loop: checking entries after removing "abc". There should be 0 entries. >+PASS First loop: checking entries after removing "abc". Entries in entrylist should be in order. >+PASS First loop: marks that we cleared for "abc" should not exist anymore. >+PASS No marks should exist after we clear all. >+PASS Second loop: checking entries after removing "". There should be 4 entries. >+PASS Second loop: checking entries after removing "". Entries in entrylist should be in order. >+PASS Second loop: checking entries after removing "". Entry_list 0. Entry "1" should be one that we have set. >+PASS Second loop: checking entries after removing "". Entry_list 0. entryType should be "mark". >+PASS Second loop: checking entries after removing "". Entry_list 0. startTime should greater than 0. >+PASS Second loop: checking entries after removing "". Entry_list 0. duration of mark should be 0. >+PASS Second loop: checking entries after removing "". Entry_list 1. Entry "1" should be one that we have set. >+PASS Second loop: checking entries after removing "". Entry_list 1. entryType should be "mark". >+PASS Second loop: checking entries after removing "". Entry_list 1. startTime should greater than 0. >+PASS Second loop: checking entries after removing "". Entry_list 1. duration of mark should be 0. >+PASS Second loop: checking entries after removing "". Entry_list 2. Entry "abc" should be one that we have set. >+PASS Second loop: checking entries after removing "". Entry_list 2. entryType should be "mark". >+PASS Second loop: checking entries after removing "". Entry_list 2. startTime should greater than 0. >+PASS Second loop: checking entries after removing "". Entry_list 2. duration of mark should be 0. >+PASS Second loop: checking entries after removing "". Entry_list 3. Entry "abc" should be one that we have set. >+PASS Second loop: checking entries after removing "". Entry_list 3. entryType should be "mark". >+PASS Second loop: checking entries after removing "". Entry_list 3. startTime should greater than 0. >+PASS Second loop: checking entries after removing "". Entry_list 3. duration of mark should be 0. >+PASS Second loop: marks that we cleared for "" should not exist anymore. >+PASS Second loop: checking entries after removing "1". There should be 2 entries. >+PASS Second loop: checking entries after removing "1". Entries in entrylist should be in order. >+PASS Second loop: checking entries after removing "1". Entry_list 0. Entry "abc" should be one that we have set. >+PASS Second loop: checking entries after removing "1". Entry_list 0. entryType should be "mark". >+PASS Second loop: checking entries after removing "1". Entry_list 0. startTime should greater than 0. >+PASS Second loop: checking entries after removing "1". Entry_list 0. duration of mark should be 0. >+PASS Second loop: checking entries after removing "1". Entry_list 1. Entry "abc" should be one that we have set. >+PASS Second loop: checking entries after removing "1". Entry_list 1. entryType should be "mark". >+PASS Second loop: checking entries after removing "1". Entry_list 1. startTime should greater than 0. >+PASS Second loop: checking entries after removing "1". Entry_list 1. duration of mark should be 0. >+PASS Second loop: marks that we cleared for "1" should not exist anymore. >+PASS Second loop: checking entries after removing "abc". There should be 0 entries. >+PASS Second loop: checking entries after removing "abc". Entries in entrylist should be in order. >+PASS Second loop: marks that we cleared for "abc" should not exist anymore. >+PASS Nothing should happen if we clear a non-exist mark. >+PASS No marks should exist when we clear all. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/user-timing/clearMarks.html b/LayoutTests/imported/w3c/web-platform-tests/user-timing/clearMarks.html >new file mode 100644 >index 0000000000000000000000000000000000000000..22d67262c3d76698862e46756a793267423cb5b1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/user-timing/clearMarks.html >@@ -0,0 +1,72 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>functionality test of window.performance.clearMarks</title> >+<link rel="author" title="Intel" href="http://www.intel.com/" /> >+<link rel="help" href="http://www.w3.org/TR/user-timing/#extensions-performance-interface"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/performance-timeline-utils.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+<script> >+setup({ explicit_done: true }); >+ >+function onload_test() >+{ >+ const entrylist_checker = new performance_entrylist_checker('mark'); >+ const string_mark_names = mark_names.map(function (x) { return String(x)}); >+ mark_names.forEach(performance.mark, performance); >+ >+ for (let i = 0; i < mark_names.length; ++i) >+ { >+ performance.clearMarks(mark_names[i]); >+ const retained_entries = performance.getEntriesByType('mark'); >+ const non_retained_entries = performance.getEntriesByName(mark_names[i], 'mark'); >+ entrylist_checker.entrylist_check(retained_entries, mark_names.length - i - 1, string_mark_names, >+ 'First loop: checking entries after removing "' + mark_names[i] + '". '); >+ test_equals(non_retained_entries.length, 0, >+ 'First loop: marks that we cleared for "' + mark_names[i] + '" should not exist anymore.'); >+ } >+ >+ mark_names.forEach(performance.mark, performance); >+ performance.clearMarks(); >+ test_equals(performance.getEntriesByType('mark').length, 0, 'No marks should exist after we clear all.'); >+ >+ // Following cases test clear existed mark name that is tied for two times. >+ mark_names.forEach(performance.mark, performance); >+ mark_names.forEach(performance.mark, performance); >+ >+ for (let i = 0; i < mark_names.length; ++i) >+ { >+ performance.clearMarks(mark_names[i]); >+ const retained_entries = performance.getEntriesByType('mark'); >+ const non_retained_entries = performance.getEntriesByName(mark_names[i], 'mark'); >+ entrylist_checker.entrylist_check(retained_entries, (mark_names.length - i - 1) * 2, string_mark_names, >+ 'Second loop: checking entries after removing "' + mark_names[i] + '". '); >+ test_equals(non_retained_entries.length, 0, >+ 'Second loop: marks that we cleared for "' + mark_names[i] + '" should not exist anymore.'); >+ } >+ >+ // Following cases test clear functionality when mark names are tied for two times. >+ mark_names.forEach(performance.mark, performance); >+ mark_names.forEach(performance.mark, performance); >+ var entry_number_before_useless_clear = performance.getEntriesByType('Mark').length; >+ performance.clearMarks('NonExist'); >+ var entry_number_after_useless_clear = performance.getEntriesByType('Mark').length; >+ test_equals(entry_number_before_useless_clear, entry_number_after_useless_clear, 'Nothing should happen if we clear a non-exist mark.'); >+ >+ performance.clearMarks(); >+ test_equals(performance.getEntriesByType('mark').length, 0, 'No marks should exist when we clear all.'); >+ >+ done(); >+} >+</script> >+</head> >+<body onload=onload_test()> >+ <h1>Description</h1> >+ <p>This test validates functionality of the interface window.performance.clearMarks.</p> >+ <div id="log"></div> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/user-timing/clearMeasures-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/user-timing/clearMeasures-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..7b62a2db7c8ed4174820c716911512ec3f45b56c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/user-timing/clearMeasures-expected.txt >@@ -0,0 +1,63 @@ >+Description >+ >+This test validates functionality of the interface window.performance.clearMeasures. >+ >+ >+PASS First loop: checking entries after removing "". There should be 2 entries. >+PASS First loop: checking entries after removing "". Entries in entrylist should be in order. >+PASS First loop: checking entries after removing "". Entry_list 0. Entry "aaa" should be one that we have set. >+PASS First loop: checking entries after removing "". Entry_list 0. entryType should be "measure". >+PASS First loop: checking entries after removing "". Entry_list 0. startTime should be a number. >+PASS First loop: checking entries after removing "". Entry_list 0. duration should be a number. >+PASS First loop: checking entries after removing "". Entry_list 1. Entry "2" should be one that we have set. >+PASS First loop: checking entries after removing "". Entry_list 1. entryType should be "measure". >+PASS First loop: checking entries after removing "". Entry_list 1. startTime should be a number. >+PASS First loop: checking entries after removing "". Entry_list 1. duration should be a number. >+PASS First loop: measure "" should not exist anymore after we cleared it. >+PASS First loop: checking entries after removing "2". There should be 1 entries. >+PASS First loop: checking entries after removing "2". Entries in entrylist should be in order. >+PASS First loop: checking entries after removing "2". Entry_list 0. Entry "aaa" should be one that we have set. >+PASS First loop: checking entries after removing "2". Entry_list 0. entryType should be "measure". >+PASS First loop: checking entries after removing "2". Entry_list 0. startTime should be a number. >+PASS First loop: checking entries after removing "2". Entry_list 0. duration should be a number. >+PASS First loop: measure "2" should not exist anymore after we cleared it. >+PASS First loop: checking entries after removing "aaa". There should be 0 entries. >+PASS First loop: checking entries after removing "aaa". Entries in entrylist should be in order. >+PASS First loop: measure "aaa" should not exist anymore after we cleared it. >+PASS No measures should exist after we clear all (after first loop). >+PASS Second loop: checking entries after removing "". There should be 4 entries. >+PASS Second loop: checking entries after removing "". Entries in entrylist should be in order. >+PASS Second loop: checking entries after removing "". Entry_list 0. Entry "aaa" should be one that we have set. >+PASS Second loop: checking entries after removing "". Entry_list 0. entryType should be "measure". >+PASS Second loop: checking entries after removing "". Entry_list 0. startTime should be a number. >+PASS Second loop: checking entries after removing "". Entry_list 0. duration should be a number. >+PASS Second loop: checking entries after removing "". Entry_list 1. Entry "aaa" should be one that we have set. >+PASS Second loop: checking entries after removing "". Entry_list 1. entryType should be "measure". >+PASS Second loop: checking entries after removing "". Entry_list 1. startTime should be a number. >+PASS Second loop: checking entries after removing "". Entry_list 1. duration should be a number. >+PASS Second loop: checking entries after removing "". Entry_list 2. Entry "2" should be one that we have set. >+PASS Second loop: checking entries after removing "". Entry_list 2. entryType should be "measure". >+PASS Second loop: checking entries after removing "". Entry_list 2. startTime should be a number. >+PASS Second loop: checking entries after removing "". Entry_list 2. duration should be a number. >+PASS Second loop: checking entries after removing "". Entry_list 3. Entry "2" should be one that we have set. >+PASS Second loop: checking entries after removing "". Entry_list 3. entryType should be "measure". >+PASS Second loop: checking entries after removing "". Entry_list 3. startTime should be a number. >+PASS Second loop: checking entries after removing "". Entry_list 3. duration should be a number. >+PASS Second loop: measure "" should not exist anymore after we cleared it. >+PASS Second loop: checking entries after removing "2". There should be 2 entries. >+PASS Second loop: checking entries after removing "2". Entries in entrylist should be in order. >+PASS Second loop: checking entries after removing "2". Entry_list 0. Entry "aaa" should be one that we have set. >+PASS Second loop: checking entries after removing "2". Entry_list 0. entryType should be "measure". >+PASS Second loop: checking entries after removing "2". Entry_list 0. startTime should be a number. >+PASS Second loop: checking entries after removing "2". Entry_list 0. duration should be a number. >+PASS Second loop: checking entries after removing "2". Entry_list 1. Entry "aaa" should be one that we have set. >+PASS Second loop: checking entries after removing "2". Entry_list 1. entryType should be "measure". >+PASS Second loop: checking entries after removing "2". Entry_list 1. startTime should be a number. >+PASS Second loop: checking entries after removing "2". Entry_list 1. duration should be a number. >+PASS Second loop: measure "2" should not exist anymore after we cleared it. >+PASS Second loop: checking entries after removing "aaa". There should be 0 entries. >+PASS Second loop: checking entries after removing "aaa". Entries in entrylist should be in order. >+PASS Second loop: measure "aaa" should not exist anymore after we cleared it. >+PASS Nothing should happen if we clear a non-exist measure >+PASS No measures should exist when we clear all (after second loop). >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/user-timing/clearMeasures.html b/LayoutTests/imported/w3c/web-platform-tests/user-timing/clearMeasures.html >new file mode 100644 >index 0000000000000000000000000000000000000000..488bece373365ba78246b33bed4e8869370abdbd >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/user-timing/clearMeasures.html >@@ -0,0 +1,73 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>functionality test of window.performance.clearMeasures</title> >+<link rel="author" title="Intel" href="http://www.intel.com/" /> >+<link rel="help" href="http://www.w3.org/TR/user-timing/#extensions-performance-interface"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/performance-timeline-utils.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+<script> >+setup({ explicit_done: true }); >+ >+function onload_test() >+{ >+ const context = new PerformanceContext(window.performance); >+ const entrylist_checker = new performance_entrylist_checker('measure'); >+ const measure_names = measures.map(function(x) {return x[0];}); >+ >+ mark_names.forEach(context.mark, context); >+ measures.forEach(context.initialMeasures, context); >+ for (let i = 0; i < measures.length; ++i) >+ { >+ context.clearMeasures(measures[i][0]); >+ const retained_entries = context.getEntriesByType('measure'); >+ const non_retained_entries = context.getEntriesByName(measures[i][0], 'measure'); >+ entrylist_checker.entrylist_check(retained_entries, measures.length - i - 1, measure_names, >+ 'First loop: checking entries after removing "' + measures[i][0] + '". '); >+ test_equals(non_retained_entries.length, 0, >+ 'First loop: measure "' + measures[i][0] + '" should not exist anymore after we cleared it.'); >+ } >+ >+ measures.forEach(context.initialMeasures, context); >+ context.clearMeasures(); >+ test_equals(context.getEntriesByType('measure').length, 0, 'No measures should exist after we clear all (after first loop).'); >+ >+ // Following cases test clear existed measure name that is tied twice. >+ measures.forEach(context.initialMeasures, context); >+ mark_names.forEach(context.mark, context); >+ measures.forEach(context.initialMeasures, context); >+ for (let i = 0; i < measures.length; ++i) >+ { >+ context.clearMeasures(measures[i][0]); >+ const retained_entries = context.getEntriesByType('measure'); >+ const non_retained_entries = context.getEntriesByName(measures[i][0], 'measure'); >+ entrylist_checker.entrylist_check(retained_entries, (measures.length - i - 1) * 2, measure_names, >+ 'Second loop: checking entries after removing "' + measures[i][0] + '". '); >+ test_equals(non_retained_entries.length, 0, >+ 'Second loop: measure "' + measures[i][0] +'" should not exist anymore after we cleared it.'); >+ } >+ >+ // Following cases test clear functionality when measure names are tied twice. >+ measures.forEach(context.initialMeasures, context); >+ measures.forEach(context.initialMeasures, context); >+ const entry_number_before_useless_clear = context.getEntriesByType('measure').length; >+ context.clearMeasures('NonExist'); >+ const entry_number_after_useless_clear = context.getEntriesByType('measure').length; >+ test_equals(entry_number_before_useless_clear, entry_number_after_useless_clear, 'Nothing should happen if we clear a non-exist measure'); >+ context.clearMeasures(); >+ test_equals(context.getEntriesByType('measure').length, 0, 'No measures should exist when we clear all (after second loop).'); >+ >+ done(); >+} >+</script> >+</head> >+<body onload=onload_test()> >+ <h1>Description</h1> >+ <p>This test validates functionality of the interface window.performance.clearMeasures.</p> >+ <div id="log"></div> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..3ce73b699c4a236c1daf41fbadc0ee8b58881e84 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-expected.txt >@@ -0,0 +1,125 @@ >+Description >+ >+This test validates functionality of the interface window.performance.mark. >+ >+ >+PASS There should be 0 marks >+PASS Checking all entries.There should be 3 entries. >+PASS Checking all entries.Entries in entrylist should be in order. >+PASS Checking all entries.Entry_list 0. Entry "1" should be one that we have set. >+PASS Checking all entries.Entry_list 0. entryType should be "mark". >+PASS Checking all entries.Entry_list 0. startTime should greater than 0. >+PASS Checking all entries.Entry_list 0. duration of mark should be 0. >+PASS Checking all entries.Entry_list 1. Entry "abc" should be one that we have set. >+PASS Checking all entries.Entry_list 1. entryType should be "mark". >+PASS Checking all entries.Entry_list 1. startTime should greater than 0. >+PASS Checking all entries.Entry_list 1. duration of mark should be 0. >+PASS Checking all entries.Entry_list 2. Entry "" should be one that we have set. >+PASS Checking all entries.Entry_list 2. entryType should be "mark". >+PASS Checking all entries.Entry_list 2. startTime should greater than 0. >+PASS Checking all entries.Entry_list 2. duration of mark should be 0. >+PASS First loop: checking entry of name "1".There should be 1 entries. >+PASS First loop: checking entry of name "1".Entries in entrylist should be in order. >+PASS First loop: checking entry of name "1".Entry_list 0. Entry "1" should be one that we have set. >+PASS First loop: checking entry of name "1".Entry_list 0. entryType should be "mark". >+PASS First loop: checking entry of name "1".Entry_list 0. startTime should greater than 0. >+PASS First loop: checking entry of name "1".Entry_list 0. duration of mark should be 0. >+PASS First loop: checking entry of name "abc".There should be 1 entries. >+PASS First loop: checking entry of name "abc".Entries in entrylist should be in order. >+PASS First loop: checking entry of name "abc".Entry_list 0. Entry "abc" should be one that we have set. >+PASS First loop: checking entry of name "abc".Entry_list 0. entryType should be "mark". >+PASS First loop: checking entry of name "abc".Entry_list 0. startTime should greater than 0. >+PASS First loop: checking entry of name "abc".Entry_list 0. duration of mark should be 0. >+PASS First loop: checking entry of name "".There should be 1 entries. >+PASS First loop: checking entry of name "".Entries in entrylist should be in order. >+PASS First loop: checking entry of name "".Entry_list 0. Entry "" should be one that we have set. >+PASS First loop: checking entry of name "".Entry_list 0. entryType should be "mark". >+PASS First loop: checking entry of name "".Entry_list 0. startTime should greater than 0. >+PASS First loop: checking entry of name "".Entry_list 0. duration of mark should be 0. >+PASS Checking all doubly marked entries.There should be 6 entries. >+PASS Checking all doubly marked entries.Entries in entrylist should be in order. >+PASS Checking all doubly marked entries.Entry_list 0. Entry "1" should be one that we have set. >+PASS Checking all doubly marked entries.Entry_list 0. entryType should be "mark". >+PASS Checking all doubly marked entries.Entry_list 0. startTime should greater than 0. >+PASS Checking all doubly marked entries.Entry_list 0. duration of mark should be 0. >+PASS Checking all doubly marked entries.Entry_list 1. Entry "abc" should be one that we have set. >+PASS Checking all doubly marked entries.Entry_list 1. entryType should be "mark". >+PASS Checking all doubly marked entries.Entry_list 1. startTime should greater than 0. >+PASS Checking all doubly marked entries.Entry_list 1. duration of mark should be 0. >+PASS Checking all doubly marked entries.Entry_list 2. Entry "" should be one that we have set. >+PASS Checking all doubly marked entries.Entry_list 2. entryType should be "mark". >+PASS Checking all doubly marked entries.Entry_list 2. startTime should greater than 0. >+PASS Checking all doubly marked entries.Entry_list 2. duration of mark should be 0. >+PASS Checking all doubly marked entries.Entry_list 3. Entry "1" should be one that we have set. >+PASS Checking all doubly marked entries.Entry_list 3. entryType should be "mark". >+PASS Checking all doubly marked entries.Entry_list 3. startTime should greater than 0. >+PASS Checking all doubly marked entries.Entry_list 3. duration of mark should be 0. >+PASS Checking all doubly marked entries.Entry_list 4. Entry "abc" should be one that we have set. >+PASS Checking all doubly marked entries.Entry_list 4. entryType should be "mark". >+PASS Checking all doubly marked entries.Entry_list 4. startTime should greater than 0. >+PASS Checking all doubly marked entries.Entry_list 4. duration of mark should be 0. >+PASS Checking all doubly marked entries.Entry_list 5. Entry "" should be one that we have set. >+PASS Checking all doubly marked entries.Entry_list 5. entryType should be "mark". >+PASS Checking all doubly marked entries.Entry_list 5. startTime should greater than 0. >+PASS Checking all doubly marked entries.Entry_list 5. duration of mark should be 0. >+PASS Second loop step 0: checking entries of name "1".There should be 2 entries. >+PASS Second loop step 0: checking entries of name "1".Entries in entrylist should be in order. >+PASS Second loop step 0: checking entries of name "1".Entry_list 0. Entry "1" should be one that we have set. >+PASS Second loop step 0: checking entries of name "1".Entry_list 0. entryType should be "mark". >+PASS Second loop step 0: checking entries of name "1".Entry_list 0. startTime should greater than 0. >+PASS Second loop step 0: checking entries of name "1".Entry_list 0. duration of mark should be 0. >+PASS Second loop step 0: checking entries of name "1".Entry_list 1. Entry "1" should be one that we have set. >+PASS Second loop step 0: checking entries of name "1".Entry_list 1. entryType should be "mark". >+PASS Second loop step 0: checking entries of name "1".Entry_list 1. startTime should greater than 0. >+PASS Second loop step 0: checking entries of name "1".Entry_list 1. duration of mark should be 0. >+PASS Second loop step 1: checking entries of name "abc".There should be 2 entries. >+PASS Second loop step 1: checking entries of name "abc".Entries in entrylist should be in order. >+PASS Second loop step 1: checking entries of name "abc".Entry_list 0. Entry "abc" should be one that we have set. >+PASS Second loop step 1: checking entries of name "abc".Entry_list 0. entryType should be "mark". >+PASS Second loop step 1: checking entries of name "abc".Entry_list 0. startTime should greater than 0. >+PASS Second loop step 1: checking entries of name "abc".Entry_list 0. duration of mark should be 0. >+PASS Second loop step 1: checking entries of name "abc".Entry_list 1. Entry "abc" should be one that we have set. >+PASS Second loop step 1: checking entries of name "abc".Entry_list 1. entryType should be "mark". >+PASS Second loop step 1: checking entries of name "abc".Entry_list 1. startTime should greater than 0. >+PASS Second loop step 1: checking entries of name "abc".Entry_list 1. duration of mark should be 0. >+PASS Second loop step 2: checking entries of name "".There should be 2 entries. >+PASS Second loop step 2: checking entries of name "".Entries in entrylist should be in order. >+PASS Second loop step 2: checking entries of name "".Entry_list 0. Entry "" should be one that we have set. >+PASS Second loop step 2: checking entries of name "".Entry_list 0. entryType should be "mark". >+PASS Second loop step 2: checking entries of name "".Entry_list 0. startTime should greater than 0. >+PASS Second loop step 2: checking entries of name "".Entry_list 0. duration of mark should be 0. >+PASS Second loop step 2: checking entries of name "".Entry_list 1. Entry "" should be one that we have set. >+PASS Second loop step 2: checking entries of name "".Entry_list 1. entryType should be "mark". >+PASS Second loop step 2: checking entries of name "".Entry_list 1. startTime should greater than 0. >+PASS Second loop step 2: checking entries of name "".Entry_list 1. duration of mark should be 0. >+PASS Second loop step 3: checking entries of name "1".There should be 2 entries. >+PASS Second loop step 3: checking entries of name "1".Entries in entrylist should be in order. >+PASS Second loop step 3: checking entries of name "1".Entry_list 0. Entry "1" should be one that we have set. >+PASS Second loop step 3: checking entries of name "1".Entry_list 0. entryType should be "mark". >+PASS Second loop step 3: checking entries of name "1".Entry_list 0. startTime should greater than 0. >+PASS Second loop step 3: checking entries of name "1".Entry_list 0. duration of mark should be 0. >+PASS Second loop step 3: checking entries of name "1".Entry_list 1. Entry "1" should be one that we have set. >+PASS Second loop step 3: checking entries of name "1".Entry_list 1. entryType should be "mark". >+PASS Second loop step 3: checking entries of name "1".Entry_list 1. startTime should greater than 0. >+PASS Second loop step 3: checking entries of name "1".Entry_list 1. duration of mark should be 0. >+PASS Second loop step 4: checking entries of name "abc".There should be 2 entries. >+PASS Second loop step 4: checking entries of name "abc".Entries in entrylist should be in order. >+PASS Second loop step 4: checking entries of name "abc".Entry_list 0. Entry "abc" should be one that we have set. >+PASS Second loop step 4: checking entries of name "abc".Entry_list 0. entryType should be "mark". >+PASS Second loop step 4: checking entries of name "abc".Entry_list 0. startTime should greater than 0. >+PASS Second loop step 4: checking entries of name "abc".Entry_list 0. duration of mark should be 0. >+PASS Second loop step 4: checking entries of name "abc".Entry_list 1. Entry "abc" should be one that we have set. >+PASS Second loop step 4: checking entries of name "abc".Entry_list 1. entryType should be "mark". >+PASS Second loop step 4: checking entries of name "abc".Entry_list 1. startTime should greater than 0. >+PASS Second loop step 4: checking entries of name "abc".Entry_list 1. duration of mark should be 0. >+PASS Second loop step 5: checking entries of name "".There should be 2 entries. >+PASS Second loop step 5: checking entries of name "".Entries in entrylist should be in order. >+PASS Second loop step 5: checking entries of name "".Entry_list 0. Entry "" should be one that we have set. >+PASS Second loop step 5: checking entries of name "".Entry_list 0. entryType should be "mark". >+PASS Second loop step 5: checking entries of name "".Entry_list 0. startTime should greater than 0. >+PASS Second loop step 5: checking entries of name "".Entry_list 0. duration of mark should be 0. >+PASS Second loop step 5: checking entries of name "".Entry_list 1. Entry "" should be one that we have set. >+PASS Second loop step 5: checking entries of name "".Entry_list 1. entryType should be "mark". >+PASS Second loop step 5: checking entries of name "".Entry_list 1. startTime should greater than 0. >+PASS Second loop step 5: checking entries of name "".Entry_list 1. duration of mark should be 0. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark.html b/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark.html >new file mode 100644 >index 0000000000000000000000000000000000000000..a7074f1efdb261298bd9260d944e51db02a42e93 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark.html >@@ -0,0 +1,54 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>functionality test of window.performance.mark</title> >+<link rel="author" title="Intel" href="http://www.intel.com/" /> >+<link rel="help" href="http://www.w3.org/TR/user-timing/#extensions-performance-interface"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/performance-timeline-utils.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+<script> >+setup({ explicit_done: true }); >+ >+function onload_test() >+{ >+ const entrylist_checker = new performance_entrylist_checker('mark'); >+ const string_mark_names = mark_names.map(function (x) { return String(x)}); >+ >+ test_equals(performance.getEntriesByType("mark").length, 0, 'There should be ' + 0 + ' marks'); >+ mark_names.forEach(performance.mark, performance); >+ let mark_entrylist = performance.getEntriesByType('mark'); >+ >+ entrylist_checker.entrylist_check(mark_entrylist, mark_names.length, string_mark_names, 'Checking all entries.'); >+ >+ for (let i = 0; i < mark_entrylist.length; ++i) >+ { >+ const mark_entrylist_by_name = performance.getEntriesByName(mark_entrylist[i].name, 'mark'); >+ entrylist_checker.entrylist_check(mark_entrylist_by_name, 1, string_mark_names, >+ 'First loop: checking entry of name "' + mark_entrylist[i].name + '".'); >+ } >+ >+ mark_names.forEach(performance.mark, performance); >+ mark_entrylist = performance.getEntriesByType('mark'); >+ entrylist_checker.entrylist_check(mark_entrylist, mark_names.length * 2, string_mark_names, 'Checking all doubly marked entries.'); >+ >+ for (let i = 0; i < mark_entrylist.length; ++i) >+ { >+ const mark_entrylist_by_name = performance.getEntriesByName(mark_entrylist[i].name, 'mark'); >+ entrylist_checker.entrylist_check(mark_entrylist_by_name, 2, string_mark_names, >+ 'Second loop step ' + i + ': checking entries of name "' + mark_entrylist[i].name + '".'); >+ } >+ >+ done(); >+} >+</script> >+</head> >+<body onload=onload_test()> >+ <h1>Description</h1> >+ <p>This test validates functionality of the interface window.performance.mark.</p> >+ <div id="log"></div> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark_exceptions-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark_exceptions-expected.txt >index 30714bc9f43f36a534aab3bb0ab87f76949b9bed..5a5327ec91b66f0b05b4f80578847ab4da79e72f 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark_exceptions-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark_exceptions-expected.txt >@@ -3,6 +3,7 @@ Description > This test validates that the performance.mark() method throws a SYNTAX_ERR exception whenever a navigation timing attribute is provided for the name parameter. > > >+PASS window.performance.mark() throws a TypeError exception. > PASS window.performance.mark("navigationStart") throws a SyntaxError exception. > PASS window.performance.mark("unloadEventStart") throws a SyntaxError exception. > PASS window.performance.mark("unloadEventEnd") throws a SyntaxError exception. >diff --git a/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark_exceptions.html b/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark_exceptions.html >index 477b3fabbba70eb424174f24a636c28f5273ebe0..e1f4c4e0f49484cedd8b6025bbe854c0503c94c1 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark_exceptions.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark_exceptions.html >@@ -18,6 +18,12 @@ function test_exception(attrName) { > }, "window.performance.mark(\"" + attrName + "\") throws a SyntaxError exception."); > } > >+test(() => { >+ assert_throws(new TypeError(), function() { >+ window.performance.mark(); >+ }); >+}, 'window.performance.mark() throws a TypeError exception.') >+ > // loop through mark scenarios > for (var i in timingAttributes) { > test_exception(timingAttributes[i]); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_associated_with_navigation_timing-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_associated_with_navigation_timing-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2cd367618732a4aaf48115d0d10422291e3cbe3d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_associated_with_navigation_timing-expected.txt >@@ -0,0 +1,14 @@ >+Description >+ >+This test validates functionality of the interface window.performance.measure using keywords from the Navigation Timing spec. >+ >+ >+PASS Measure of navigationStart to now should be positive value. >+PASS Measure of navigationStart to loadEventEnd should be positive value. >+PASS Measure of current mark to navigationStart should be negative value. >+PASS loadTime plus loadEventEnd to a mark "a" should equal to navigationStart to "a". >+PASS Second measure of current mark to navigationStart should be negative value. >+PASS Measures of loadTime should have same duration. >+PASS Measure from domComplete event to most recent mark "a" should have longer duration. >+PASS Measure from most recent mark to navigationStart should have longer duration. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_associated_with_navigation_timing.html b/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_associated_with_navigation_timing.html >new file mode 100644 >index 0000000000000000000000000000000000000000..9fd4664b9e9a5f1e974b469d6e67ff6dc0194bea >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_associated_with_navigation_timing.html >@@ -0,0 +1,53 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>functionality test of window.performance.measure</title> >+<link rel="author" title="Intel" href="http://www.intel.com/" /> >+<link rel="help" href="http://www.w3.org/TR/user-timing/#extensions-performance-interface"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/performance-timeline-utils.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+<script> >+setup({ explicit_done: true }); >+ >+function onload_test() >+{ >+ const measures_for_timing_order = [ >+ ['nav2now', 'navigationStart'], >+ ['loadTime', 'navigationStart', 'loadEventEnd'], >+ ['loadEventEnd2a', 'loadEventEnd', 'abc'], >+ ['nav2a', 'navigationStart', 'abc'], >+ ['domComplete2a', 'domComplete', 'abc'], >+ ['negativeValue', 1, 'navigationStart'], >+ ]; >+ const context = new PerformanceContext(window.performance); >+ >+ mark_names.forEach(context.mark, context); >+ measures_for_timing_order.forEach(context.initialMeasures, context); >+ test_greater_than(context.getEntriesByName('nav2now', 'measure')[0].duration, 0, 'Measure of navigationStart to now should be positive value.'); >+ test_greater_than(context.getEntriesByName('loadTime', 'measure')[0].duration, 0, 'Measure of navigationStart to loadEventEnd should be positive value.'); >+ test_greater_than(0, context.getEntriesByName('negativeValue', 'measure')[0].duration, 'Measure of current mark to navigationStart should be negative value.'); >+ test_equals(context.getEntriesByName('loadTime', 'measure')[0].duration + context.getEntriesByName('loadEventEnd2a', 'measure')[0].duration, context.getEntriesByName('nav2a', 'measure')[0].duration, 'loadTime plus loadEventEnd to a mark "a" should equal to navigationStart to "a".'); >+ >+ // Following cases test for scenarios that measure names are tied twice. >+ mark_names.forEach(context.mark, context); >+ measures_for_timing_order.forEach(context.initialMeasures, context); >+ >+ test_greater_than(context.getEntriesByName('nav2now', 'measure')[1].duration, context.getEntriesByName('nav2now', 'measure')[0].duration, 'Second measure of current mark to navigationStart should be negative value.'); >+ test_equals(context.getEntriesByName('loadTime', 'measure')[0].duration, context.getEntriesByName('loadTime', 'measure')[1].duration, 'Measures of loadTime should have same duration.'); >+ test_greater_than(context.getEntriesByName('domComplete2a', 'measure')[1].duration, context.getEntriesByName('domComplete2a', 'measure')[0].duration, 'Measure from domComplete event to most recent mark "a" should have longer duration.'); >+ test_greater_than(context.getEntriesByName('negativeValue', 'measure')[0].duration, context.getEntriesByName('negativeValue', 'measure')[1].duration, 'Measure from most recent mark to navigationStart should have longer duration.'); >+ >+ done(); >+} >+</script> >+</head> >+<body onload="setTimeout(onload_test,0)"> >+ <h1>Description</h1> >+ <p>This test validates functionality of the interface window.performance.measure using keywords from the Navigation Timing spec.</p> >+ <div id="log"></div> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_exception-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_exception-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..843161c781c89515c3ee6962f1b75e1b151ee355 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_exception-expected.txt >@@ -0,0 +1,14 @@ >+Description >+ >+This test validates all exception scenarios of method window.performance.measure in User Timing API >+ >+ >+PASS Invocation of performance.measure() should throw TypeError Exception. >+PASS Invocation of performance.measure("Exception1", "NonExistMark1") should throw SYNTAX_ERR Exception. >+PASS Invocation of performance.measure("Exception2", "NonExistMark1", "navigationStart") should throw SYNTAX_ERR Exception. >+PASS Invocation of performance.measure("Exception3", "navigationStart", "NonExistMark1") should throw SYNTAX_ERR Exception. >+PASS Invocation of performance.measure("Exception4", "NonExistMark1", "ExistMark") should throw SYNTAX_ERR Exception. >+PASS Invocation of performance.measure("Exception5", "ExistMark", "NonExistMark1") should throw SYNTAX_ERR Exception. >+PASS Invocation of performance.measure("Exception6", "NonExistMark1", "NonExistMark2") should throw SYNTAX_ERR Exception. >+PASS Invocation of performance.measure("Exception7", "redirectStart") should throw INVALID_ACCESS_ERR Exception. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_exception.html b/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_exception.html >new file mode 100644 >index 0000000000000000000000000000000000000000..8783ff7e22671309eda54962903a1610c352285d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_exception.html >@@ -0,0 +1,32 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>exception test of window.performance.measure</title> >+<link rel="author" title="Intel" href="http://www.intel.com/" /> >+<link rel="help" href="http://www.w3.org/TR/user-timing/#extensions-performance-interface"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/performance-timeline-utils.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+</head> >+ >+<body> >+<h1>Description</h1> >+<p>This test validates all exception scenarios of method window.performance.measure in User Timing API</p> >+ >+<div id="log"></div> >+<script> >+performance.mark('ExistMark'); >+test_method_throw_exception('performance.measure()', TypeError()); >+test_method_throw_exception('performance.measure("Exception1", "NonExistMark1")', 'SYNTAX_ERR'); >+test_method_throw_exception('performance.measure("Exception2", "NonExistMark1", "navigationStart")', 'SYNTAX_ERR'); >+test_method_throw_exception('performance.measure("Exception3", "navigationStart", "NonExistMark1")', 'SYNTAX_ERR'); >+test_method_throw_exception('performance.measure("Exception4", "NonExistMark1", "ExistMark")', 'SYNTAX_ERR'); >+test_method_throw_exception('performance.measure("Exception5", "ExistMark", "NonExistMark1")', 'SYNTAX_ERR'); >+test_method_throw_exception('performance.measure("Exception6", "NonExistMark1", "NonExistMark2")', 'SYNTAX_ERR'); >+test_method_throw_exception('performance.measure("Exception7", "redirectStart")', 'INVALID_ACCESS_ERR'); >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/user-timing/measures-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/user-timing/measures-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..df3bd1fbbb22161ccef06122016ef058eacb4ef7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/user-timing/measures-expected.txt >@@ -0,0 +1,125 @@ >+Description >+ >+This test validates functionality of the interface window.performance.measure. >+ >+ >+PASS There should be 0 entries returned. >+PASS Checking all entries.There should be 3 entries. >+PASS Checking all entries.Entries in entrylist should be in order. >+PASS Checking all entries.Entry_list 0. Entry "aaa" should be one that we have set. >+PASS Checking all entries.Entry_list 0. entryType should be "measure". >+PASS Checking all entries.Entry_list 0. startTime should be a number. >+PASS Checking all entries.Entry_list 0. duration should be a number. >+PASS Checking all entries.Entry_list 1. Entry "" should be one that we have set. >+PASS Checking all entries.Entry_list 1. entryType should be "measure". >+PASS Checking all entries.Entry_list 1. startTime should be a number. >+PASS Checking all entries.Entry_list 1. duration should be a number. >+PASS Checking all entries.Entry_list 2. Entry "2" should be one that we have set. >+PASS Checking all entries.Entry_list 2. entryType should be "measure". >+PASS Checking all entries.Entry_list 2. startTime should be a number. >+PASS Checking all entries.Entry_list 2. duration should be a number. >+PASS First loop: checking entry of name "aaa".There should be 1 entries. >+PASS First loop: checking entry of name "aaa".Entries in entrylist should be in order. >+PASS First loop: checking entry of name "aaa".Entry_list 0. Entry "aaa" should be one that we have set. >+PASS First loop: checking entry of name "aaa".Entry_list 0. entryType should be "measure". >+PASS First loop: checking entry of name "aaa".Entry_list 0. startTime should be a number. >+PASS First loop: checking entry of name "aaa".Entry_list 0. duration should be a number. >+PASS First loop: checking entry of name "".There should be 1 entries. >+PASS First loop: checking entry of name "".Entries in entrylist should be in order. >+PASS First loop: checking entry of name "".Entry_list 0. Entry "" should be one that we have set. >+PASS First loop: checking entry of name "".Entry_list 0. entryType should be "measure". >+PASS First loop: checking entry of name "".Entry_list 0. startTime should be a number. >+PASS First loop: checking entry of name "".Entry_list 0. duration should be a number. >+PASS First loop: checking entry of name "2".There should be 1 entries. >+PASS First loop: checking entry of name "2".Entries in entrylist should be in order. >+PASS First loop: checking entry of name "2".Entry_list 0. Entry "2" should be one that we have set. >+PASS First loop: checking entry of name "2".Entry_list 0. entryType should be "measure". >+PASS First loop: checking entry of name "2".Entry_list 0. startTime should be a number. >+PASS First loop: checking entry of name "2".Entry_list 0. duration should be a number. >+PASS Checking all doubly measured entries.There should be 6 entries. >+PASS Checking all doubly measured entries.Entries in entrylist should be in order. >+PASS Checking all doubly measured entries.Entry_list 0. Entry "aaa" should be one that we have set. >+PASS Checking all doubly measured entries.Entry_list 0. entryType should be "measure". >+PASS Checking all doubly measured entries.Entry_list 0. startTime should be a number. >+PASS Checking all doubly measured entries.Entry_list 0. duration should be a number. >+PASS Checking all doubly measured entries.Entry_list 1. Entry "aaa" should be one that we have set. >+PASS Checking all doubly measured entries.Entry_list 1. entryType should be "measure". >+PASS Checking all doubly measured entries.Entry_list 1. startTime should be a number. >+PASS Checking all doubly measured entries.Entry_list 1. duration should be a number. >+PASS Checking all doubly measured entries.Entry_list 2. Entry "" should be one that we have set. >+PASS Checking all doubly measured entries.Entry_list 2. entryType should be "measure". >+PASS Checking all doubly measured entries.Entry_list 2. startTime should be a number. >+PASS Checking all doubly measured entries.Entry_list 2. duration should be a number. >+PASS Checking all doubly measured entries.Entry_list 3. Entry "" should be one that we have set. >+PASS Checking all doubly measured entries.Entry_list 3. entryType should be "measure". >+PASS Checking all doubly measured entries.Entry_list 3. startTime should be a number. >+PASS Checking all doubly measured entries.Entry_list 3. duration should be a number. >+PASS Checking all doubly measured entries.Entry_list 4. Entry "2" should be one that we have set. >+PASS Checking all doubly measured entries.Entry_list 4. entryType should be "measure". >+PASS Checking all doubly measured entries.Entry_list 4. startTime should be a number. >+PASS Checking all doubly measured entries.Entry_list 4. duration should be a number. >+PASS Checking all doubly measured entries.Entry_list 5. Entry "2" should be one that we have set. >+PASS Checking all doubly measured entries.Entry_list 5. entryType should be "measure". >+PASS Checking all doubly measured entries.Entry_list 5. startTime should be a number. >+PASS Checking all doubly measured entries.Entry_list 5. duration should be a number. >+PASS Second loop step 0: checking entry of name "aaa".There should be 2 entries. >+PASS Second loop step 0: checking entry of name "aaa".Entries in entrylist should be in order. >+PASS Second loop step 0: checking entry of name "aaa".Entry_list 0. Entry "aaa" should be one that we have set. >+PASS Second loop step 0: checking entry of name "aaa".Entry_list 0. entryType should be "measure". >+PASS Second loop step 0: checking entry of name "aaa".Entry_list 0. startTime should be a number. >+PASS Second loop step 0: checking entry of name "aaa".Entry_list 0. duration should be a number. >+PASS Second loop step 0: checking entry of name "aaa".Entry_list 1. Entry "aaa" should be one that we have set. >+PASS Second loop step 0: checking entry of name "aaa".Entry_list 1. entryType should be "measure". >+PASS Second loop step 0: checking entry of name "aaa".Entry_list 1. startTime should be a number. >+PASS Second loop step 0: checking entry of name "aaa".Entry_list 1. duration should be a number. >+PASS Second loop step 1: checking entry of name "aaa".There should be 2 entries. >+PASS Second loop step 1: checking entry of name "aaa".Entries in entrylist should be in order. >+PASS Second loop step 1: checking entry of name "aaa".Entry_list 0. Entry "aaa" should be one that we have set. >+PASS Second loop step 1: checking entry of name "aaa".Entry_list 0. entryType should be "measure". >+PASS Second loop step 1: checking entry of name "aaa".Entry_list 0. startTime should be a number. >+PASS Second loop step 1: checking entry of name "aaa".Entry_list 0. duration should be a number. >+PASS Second loop step 1: checking entry of name "aaa".Entry_list 1. Entry "aaa" should be one that we have set. >+PASS Second loop step 1: checking entry of name "aaa".Entry_list 1. entryType should be "measure". >+PASS Second loop step 1: checking entry of name "aaa".Entry_list 1. startTime should be a number. >+PASS Second loop step 1: checking entry of name "aaa".Entry_list 1. duration should be a number. >+PASS Second loop step 2: checking entry of name "".There should be 2 entries. >+PASS Second loop step 2: checking entry of name "".Entries in entrylist should be in order. >+PASS Second loop step 2: checking entry of name "".Entry_list 0. Entry "" should be one that we have set. >+PASS Second loop step 2: checking entry of name "".Entry_list 0. entryType should be "measure". >+PASS Second loop step 2: checking entry of name "".Entry_list 0. startTime should be a number. >+PASS Second loop step 2: checking entry of name "".Entry_list 0. duration should be a number. >+PASS Second loop step 2: checking entry of name "".Entry_list 1. Entry "" should be one that we have set. >+PASS Second loop step 2: checking entry of name "".Entry_list 1. entryType should be "measure". >+PASS Second loop step 2: checking entry of name "".Entry_list 1. startTime should be a number. >+PASS Second loop step 2: checking entry of name "".Entry_list 1. duration should be a number. >+PASS Second loop step 3: checking entry of name "".There should be 2 entries. >+PASS Second loop step 3: checking entry of name "".Entries in entrylist should be in order. >+PASS Second loop step 3: checking entry of name "".Entry_list 0. Entry "" should be one that we have set. >+PASS Second loop step 3: checking entry of name "".Entry_list 0. entryType should be "measure". >+PASS Second loop step 3: checking entry of name "".Entry_list 0. startTime should be a number. >+PASS Second loop step 3: checking entry of name "".Entry_list 0. duration should be a number. >+PASS Second loop step 3: checking entry of name "".Entry_list 1. Entry "" should be one that we have set. >+PASS Second loop step 3: checking entry of name "".Entry_list 1. entryType should be "measure". >+PASS Second loop step 3: checking entry of name "".Entry_list 1. startTime should be a number. >+PASS Second loop step 3: checking entry of name "".Entry_list 1. duration should be a number. >+PASS Second loop step 4: checking entry of name "2".There should be 2 entries. >+PASS Second loop step 4: checking entry of name "2".Entries in entrylist should be in order. >+PASS Second loop step 4: checking entry of name "2".Entry_list 0. Entry "2" should be one that we have set. >+PASS Second loop step 4: checking entry of name "2".Entry_list 0. entryType should be "measure". >+PASS Second loop step 4: checking entry of name "2".Entry_list 0. startTime should be a number. >+PASS Second loop step 4: checking entry of name "2".Entry_list 0. duration should be a number. >+PASS Second loop step 4: checking entry of name "2".Entry_list 1. Entry "2" should be one that we have set. >+PASS Second loop step 4: checking entry of name "2".Entry_list 1. entryType should be "measure". >+PASS Second loop step 4: checking entry of name "2".Entry_list 1. startTime should be a number. >+PASS Second loop step 4: checking entry of name "2".Entry_list 1. duration should be a number. >+PASS Second loop step 5: checking entry of name "2".There should be 2 entries. >+PASS Second loop step 5: checking entry of name "2".Entries in entrylist should be in order. >+PASS Second loop step 5: checking entry of name "2".Entry_list 0. Entry "2" should be one that we have set. >+PASS Second loop step 5: checking entry of name "2".Entry_list 0. entryType should be "measure". >+PASS Second loop step 5: checking entry of name "2".Entry_list 0. startTime should be a number. >+PASS Second loop step 5: checking entry of name "2".Entry_list 0. duration should be a number. >+PASS Second loop step 5: checking entry of name "2".Entry_list 1. Entry "2" should be one that we have set. >+PASS Second loop step 5: checking entry of name "2".Entry_list 1. entryType should be "measure". >+PASS Second loop step 5: checking entry of name "2".Entry_list 1. startTime should be a number. >+PASS Second loop step 5: checking entry of name "2".Entry_list 1. duration should be a number. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/user-timing/measures.html b/LayoutTests/imported/w3c/web-platform-tests/user-timing/measures.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d0ab11e39aeff5b51f9294396c037744682b4bf9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/user-timing/measures.html >@@ -0,0 +1,62 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<meta charset="utf-8" /> >+<title>functionality test of window.performance.measure</title> >+<link rel="author" title="Intel" href="http://www.intel.com/" /> >+<link rel="help" href="http://www.w3.org/TR/user-timing/#extensions-performance-interface"/> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/common/performance-timeline-utils.js"></script> >+<script src="resources/webperftestharness.js"></script> >+<script src="resources/webperftestharnessextension.js"></script> >+<script> >+setup({ explicit_done: true }); >+ >+function onload_test() >+{ >+ const context = new PerformanceContext(window.performance); >+ const entrylist_checker = new performance_entrylist_checker('measure'); >+ const measure_names = measures.map(function(x) {return x[0];}); >+ >+ test_equals(context.getEntriesByType('measure').length, 0, 'There should be ' + 0 + ' entries returned.'); >+ >+ mark_names.forEach(context.mark, context); >+ measures.forEach(context.initialMeasures, context); >+ >+ let measure_entrylist = context.getEntriesByType('measure'); >+ entrylist_checker.entrylist_check(measure_entrylist, measures.length, measure_names, >+ 'Checking all entries.'); >+ >+ for (let i = 0; i < measure_entrylist.length; ++i) >+ { >+ const measure_entrylist_by_name = context.getEntriesByName(measure_entrylist[i].name, 'measure'); >+ entrylist_checker.entrylist_check(measure_entrylist_by_name, 1, measure_names, >+ 'First loop: checking entry of name "' + measure_entrylist[i].name + '".'); >+ } >+ >+ // Following cases test for scenarios that measure names are tied for two times >+ mark_names.forEach(context.mark, context); >+ measures.forEach(context.initialMeasures, context); >+ >+ measure_entrylist = context.getEntriesByType('measure'); >+ entrylist_checker.entrylist_check(measure_entrylist, measures.length * 2, measure_names, >+ 'Checking all doubly measured entries.'); >+ >+ for (let i = 0; i < measure_entrylist.length; ++i) >+ { >+ const measure_entrylist_by_name = context.getEntriesByName(measure_entrylist[i].name, 'measure'); >+ entrylist_checker.entrylist_check(measure_entrylist_by_name, 2, measure_names, >+ 'Second loop step ' + i + ': checking entry of name "' + measure_entrylist[i].name + '".'); >+ } >+ >+ done(); >+} >+</script> >+</head> >+<body onload=onload_test()> >+ <h1>Description</h1> >+ <p>This test validates functionality of the interface window.performance.measure.</p> >+ <div id="log"></div> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/user-timing/resources/webperftestharnessextension.js b/LayoutTests/imported/w3c/web-platform-tests/user-timing/resources/webperftestharnessextension.js >index 579ee9096aa4b392525da9b371821a3c4bdb6420..822376be24c2fc7e45441e47a1a3f09d341e7bac 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/user-timing/resources/webperftestharnessextension.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/user-timing/resources/webperftestharnessextension.js >@@ -88,28 +88,29 @@ function test_resource_entries(entries, expected_entries) > } > } > } >+ > function performance_entrylist_checker(type) > { >- var entryType = type; >+ const entryType = type; > >- function entry_check(entry, expectedNames) >+ function entry_check(entry, expectedNames, testDescription = '') > { >- var msg = 'Entry \"' + entry.name + '\" should be one that we have set.'; >+ const msg = testDescription + 'Entry \"' + entry.name + '\" should be one that we have set.'; > wp_test(function() { assert_in_array(entry.name, expectedNames, msg); }, msg); >- test_equals(entry.entryType, entryType, 'entryType should be \"' + entryType + '\".'); >+ test_equals(entry.entryType, entryType, testDescription + 'entryType should be \"' + entryType + '\".'); > if (type === "measure") { >- test_true(isFinite(entry.startTime), 'startTime should be a number.'); >- test_true(isFinite(entry.duration), 'duration should be a number.'); >+ test_true(isFinite(entry.startTime), testDescription + 'startTime should be a number.'); >+ test_true(isFinite(entry.duration), testDescription + 'duration should be a number.'); > } else if (type === "mark") { >- test_greater_than(entry.startTime, 0, 'startTime should greater than 0.'); >- test_equals(entry.duration, 0, 'duration of mark should be 0.'); >+ test_greater_than(entry.startTime, 0, testDescription + 'startTime should greater than 0.'); >+ test_equals(entry.duration, 0, testDescription + 'duration of mark should be 0.'); > } > } > > function entrylist_order_check(entryList) > { >- var inOrder = true; >- for (var i = 0; i < entryList.length - 1; ++i) >+ let inOrder = true; >+ for (let i = 0; i < entryList.length - 1; ++i) > { > if (entryList[i + 1].startTime < entryList[i].startTime) { > inOrder = false; >@@ -119,13 +120,13 @@ function performance_entrylist_checker(type) > return inOrder; > } > >- function entrylist_check(entryList, expectedLength, expectedNames) >+ function entrylist_check(entryList, expectedLength, expectedNames, testDescription = '') > { >- test_equals(entryList.length, expectedLength, 'There should be ' + expectedLength + ' entries.'); >- test_true(entrylist_order_check(entryList), 'Entries in entrylist should be in order.'); >- for (var i = 0; i < entryList.length; ++i) >+ test_equals(entryList.length, expectedLength, testDescription + 'There should be ' + expectedLength + ' entries.'); >+ test_true(entrylist_order_check(entryList), testDescription + 'Entries in entrylist should be in order.'); >+ for (let i = 0; i < entryList.length; ++i) > { >- entry_check(entryList[i], expectedNames); >+ entry_check(entryList[i], expectedNames, testDescription + 'Entry_list ' + i + '. '); > } > } > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/user-timing/user-timing-tojson-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/user-timing/user-timing-tojson-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..92448fae54cff98e3d5e46a4d88ab8f667164315 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/user-timing/user-timing-tojson-expected.txt >@@ -0,0 +1,4 @@ >+ >+PASS Test toJSON() in PerformanceMark >+PASS Test toJSON() in PerformanceMeasure >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/user-timing/user-timing-tojson.html b/LayoutTests/imported/w3c/web-platform-tests/user-timing/user-timing-tojson.html >new file mode 100644 >index 0000000000000000000000000000000000000000..6aef7fa904ab958a4c3f8600ea592fac418d0522 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/user-timing/user-timing-tojson.html >@@ -0,0 +1,44 @@ >+<!doctype html> >+<html> >+<head> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+</head> >+<body> >+<script> >+const keys = [ >+ 'name', >+ 'entryType', >+ 'startTime', >+ 'duration', >+]; >+test(() => { >+ performance.mark('a'); >+ const markEntries = performance.getEntriesByType('mark'); >+ assert_equals(1, markEntries.length); >+ const markEntry = markEntries[0]; >+ assert_equals(markEntry.entryType, 'mark'); >+ assert_equals(typeof(markEntry.toJSON), 'function'); >+ const markJSON = markEntry.toJSON(); >+ assert_equals(typeof(markJSON), 'object'); >+ for (const key of keys) { >+ assert_equals(markJSON[key], markEntry[key], `PerformanceMark ${key} entry does not match its toJSON value`); >+ } >+}, 'Test toJSON() in PerformanceMark'); >+ >+test(() => { >+ performance.measure('m'); >+ const measureEntries = performance.getEntriesByType('measure'); >+ assert_equals(1, measureEntries.length); >+ const measureEntry = measureEntries[0]; >+ assert_equals(measureEntry.entryType, 'measure'); >+ assert_equals(typeof(measureEntry.toJSON), 'function'); >+ const measureJSON = measureEntry.toJSON(); >+ assert_equals(typeof(measureJSON), 'object'); >+ for (const key of keys) { >+ assert_equals(measureJSON[key], measureEntry[key], `PerformanceMeasure ${key} entry does not match its toJSON value`); >+ } >+}, 'Test toJSON() in PerformanceMeasure'); >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/user-timing/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/user-timing/w3c-import.log >index 32703cdabf1575d8200db40112c96b3a6f83125e..65710b46977ac2d2db6a57323f33e085a9a0aa2e 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/user-timing/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/user-timing/w3c-import.log >@@ -15,6 +15,8 @@ None > ------------------------------------------------------------------------ > List of files: > /LayoutTests/imported/w3c/web-platform-tests/user-timing/OWNERS >+/LayoutTests/imported/w3c/web-platform-tests/user-timing/clearMarks.html >+/LayoutTests/imported/w3c/web-platform-tests/user-timing/clearMeasures.html > /LayoutTests/imported/w3c/web-platform-tests/user-timing/clear_all_marks.any.js > /LayoutTests/imported/w3c/web-platform-tests/user-timing/clear_all_measures.any.js > /LayoutTests/imported/w3c/web-platform-tests/user-timing/clear_non_existent_mark.any.js >@@ -27,9 +29,14 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/user-timing/invoke_with_timing_attributes.worker.js > /LayoutTests/imported/w3c/web-platform-tests/user-timing/invoke_without_parameter.html > /LayoutTests/imported/w3c/web-platform-tests/user-timing/mark.any.js >+/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark.html > /LayoutTests/imported/w3c/web-platform-tests/user-timing/mark_exceptions.html > /LayoutTests/imported/w3c/web-platform-tests/user-timing/measure.html >+/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_associated_with_navigation_timing.html >+/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_exception.html > /LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_exceptions_navigation_timing.html > /LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_navigation_timing.html > /LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_syntax_err.any.js >+/LayoutTests/imported/w3c/web-platform-tests/user-timing/measures.html >+/LayoutTests/imported/w3c/web-platform-tests/user-timing/user-timing-tojson.html > /LayoutTests/imported/w3c/web-platform-tests/user-timing/user_timing_exists.any.js >diff --git a/LayoutTests/imported/w3c/web-platform-tests/visual-viewport/OWNERS b/LayoutTests/imported/w3c/web-platform-tests/visual-viewport/OWNERS >new file mode 100644 >index 0000000000000000000000000000000000000000..d1e9918656623253f1a5cad2a1ad5e4fc1d18d01 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/visual-viewport/OWNERS >@@ -0,0 +1 @@ >+@bokand >diff --git a/LayoutTests/imported/w3c/web-platform-tests/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/w3c-import.log >index d45b103be57b10cd5305838e0da817a9cd2f3a3a..fd74882a3d0352fdc3a4f3146a742681d30aba45 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/w3c-import.log >@@ -14,11 +14,11 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/CODEOWNERS > /LayoutTests/imported/w3c/web-platform-tests/CONTRIBUTING.md > /LayoutTests/imported/w3c/web-platform-tests/LICENSE.md > /LayoutTests/imported/w3c/web-platform-tests/README.md > /LayoutTests/imported/w3c/web-platform-tests/check_stability.ini >-/LayoutTests/imported/w3c/web-platform-tests/config.default.json > /LayoutTests/imported/w3c/web-platform-tests/lint.whitelist > /LayoutTests/imported/w3c/web-platform-tests/serve.py > /LayoutTests/imported/w3c/web-platform-tests/server-side.md >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/js/helpers.js b/LayoutTests/imported/w3c/web-platform-tests/webaudio/js/helpers.js >index 650d25c2ad6601b343e4110b6543bb784e4706a2..fbbfc8e00444dce1440fdbe8e28e11c5b064ce3d 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/js/helpers.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/js/helpers.js >@@ -5,7 +5,7 @@ > function trimEmptyElements(array) { > var start = 0; > var end = array.length; >- >+ > while (start < array.length) { > if (array[start] !== 0) { > break; >@@ -115,7 +115,7 @@ function compareBuffers(got, expected) { > * + skipOfflineContextTests: optional. when true, skips running tests on an offline > * context by circumventing testOnOfflineContext. > * >- * [0]: http://web-platform-tests.org/writing-tests/testharness-api.html#single-page-tests >+ * [0]: https://web-platform-tests.org/writing-tests/testharness-api.html#single-page-tests > */ > function runTest(name) > { >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/audio-param.js b/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/audio-param.js >new file mode 100644 >index 0000000000000000000000000000000000000000..bc33fe8a21f5e7fcbe4e3d2d2a4c4c3b840d3072 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/audio-param.js >@@ -0,0 +1,44 @@ >+// Define functions that implement the formulas for AudioParam automations. >+ >+// AudioParam linearRamp value at time t for a linear ramp between (t0, v0) and >+// (t1, v1). It is assumed that t0 <= t. Results are undefined otherwise. >+function audioParamLinearRamp(t, v0, t0, v1, t1) { >+ if (t >= t1) >+ return v1; >+ return (v0 + (v1 - v0) * (t - t0) / (t1 - t0)) >+} >+ >+// AudioParam exponentialRamp value at time t for an exponential ramp between >+// (t0, v0) and (t1, v1). It is assumed that t0 <= t. Results are undefined >+// otherwise. >+function audioParamExponentialRamp(t, v0, t0, v1, t1) { >+ if (t >= t1) >+ return v1; >+ return v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0)); >+} >+ >+// AudioParam setTarget value at time t for a setTarget curve starting at (t0, >+// v0) with a final value of vFainal and a time constant of timeConstant. It is >+// assumed that t0 <= t. Results are undefined otherwise. >+function audioParamSetTarget(t, v0, t0, vFinal, timeConstant) { >+ return vFinal + (v0 - vFinal) * Math.exp(-(t - t0) / timeConstant); >+} >+ >+// AudioParam setValueCurve value at time t for a setValueCurve starting at time >+// t0 with curve, curve, and duration duration. The sample rate is sampleRate. >+// It is assumed that t0 <= t. >+function audioParamSetValueCurve(t, curve, t0, duration) { >+ if (t > t0 + duration) >+ return curve[curve.length - 1]; >+ >+ let curvePointsPerSecond = (curve.length - 1) / duration; >+ >+ let virtualIndex = (t - t0) * curvePointsPerSecond; >+ let index = Math.floor(virtualIndex); >+ >+ let delta = virtualIndex - index; >+ >+ let c0 = curve[index]; >+ let c1 = curve[Math.min(index + 1, curve.length - 1)]; >+ return c0 + (c1 - c0) * delta; >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/audionodeoptions.js b/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/audionodeoptions.js >new file mode 100644 >index 0000000000000000000000000000000000000000..293e8e0d9c8370a4015f3eaf2cfc4d2eb90df011 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/audionodeoptions.js >@@ -0,0 +1,251 @@ >+// Test that constructor for the node with name |nodeName| handles the >+// various possible values for channelCount, channelCountMode, and >+// channelInterpretation. >+ >+// The |should| parameter is the test function from new |Audit|. >+function testAudioNodeOptions(should, context, nodeName, expectedNodeOptions) { >+ if (expectedNodeOptions === undefined) >+ expectedNodeOptions = {}; >+ let node; >+ >+ // Test that we can set channelCount and that errors are thrown for >+ // invalid values >+ let testChannelCount = 17; >+ if (expectedNodeOptions.channelCount) { >+ testChannelCount = expectedNodeOptions.channelCount.value; >+ } >+ should( >+ () => { >+ node = new window[nodeName]( >+ context, Object.assign({}, expectedNodeOptions.additionalOptions, { >+ channelCount: testChannelCount >+ })); >+ }, >+ 'new ' + nodeName + '(c, {channelCount: ' + testChannelCount + '}}') >+ .notThrow(); >+ should(node.channelCount, 'node.channelCount').beEqualTo(testChannelCount); >+ >+ if (expectedNodeOptions.channelCount && >+ expectedNodeOptions.channelCount.isFixed) { >+ // The channel count is fixed. Verify that we throw an error if >+ // we try to change it. Arbitrarily set the count to be one more >+ // than the expected value. >+ testChannelCount = expectedNodeOptions.channelCount.value + 1; >+ should( >+ () => { >+ node = new window[nodeName]( >+ context, >+ Object.assign( >+ {}, expectedNodeOptions.additionalOptions, >+ {channelCount: testChannelCount})); >+ }, >+ 'new ' + nodeName + '(c, {channelCount: ' + testChannelCount + '}}') >+ .throw(expectedNodeOptions.channelCount.errorType || 'TypeError'); >+ } else { >+ // The channel count is not fixed. Try to set the count to invalid >+ // values and make sure an error is thrown. >+ let errorType = 'NotSupportedError'; >+ >+ [0, 99].forEach(testValue => { >+ should(() => { >+ node = new window[nodeName]( >+ context, Object.assign({}, expectedNodeOptions.additionalOptions, { >+ channelCount: testValue >+ })); >+ }, `new ${nodeName}(c, {channelCount: ${testValue}})`).throw(errorType); >+ }); >+ } >+ >+ // Test channelCountMode >+ let testChannelCountMode = 'max'; >+ if (expectedNodeOptions.channelCountMode) { >+ testChannelCountMode = expectedNodeOptions.channelCountMode.value; >+ } >+ should( >+ () => { >+ node = new window[nodeName]( >+ context, Object.assign({}, expectedNodeOptions.additionalOptions, { >+ channelCountMode: testChannelCountMode >+ })); >+ }, >+ 'new ' + nodeName + '(c, {channelCountMode: "' + testChannelCountMode + >+ '"}') >+ .notThrow(); >+ should(node.channelCountMode, 'node.channelCountMode') >+ .beEqualTo(testChannelCountMode); >+ >+ if (expectedNodeOptions.channelCountMode && >+ expectedNodeOptions.channelCountMode.isFixed) { >+ // Channel count mode is fixed. Test setting to something else throws. >+ ['max', 'clamped-max', 'explicit'].forEach(testValue => { >+ if (testValue !== expectedNodeOptions.channelCountMode.value) { >+ should( >+ () => { >+ node = new window[nodeName]( >+ context, >+ Object.assign( >+ {}, expectedNodeOptions.additionalOptions, >+ {channelCountMode: testValue})); >+ }, >+ `new ${nodeName}(c, {channelCountMode: "${testValue}"})`) >+ .throw(expectedNodeOptions.channelCountMode.errorType); >+ } >+ }); >+ } else { >+ // Mode is not fixed. Verify that we can set the mode to all valid >+ // values, and that we throw for invalid values. >+ >+ let testValues = ['max', 'clamped-max', 'explicit']; >+ >+ testValues.forEach(testValue => { >+ should(() => { >+ node = new window[nodeName]( >+ context, Object.assign({}, expectedNodeOptions.additionalOptions, { >+ channelCountMode: testValue >+ })); >+ }, `new ${nodeName}(c, {channelCountMode: "${testValue}"})`).notThrow(); >+ should( >+ node.channelCountMode, 'node.channelCountMode after valid setter') >+ .beEqualTo(testValue); >+ >+ }); >+ >+ should( >+ () => { >+ node = new window[nodeName]( >+ context, >+ Object.assign( >+ {}, expectedNodeOptions.additionalOptions, >+ {channelCountMode: 'foobar'})); >+ }, >+ 'new ' + nodeName + '(c, {channelCountMode: "foobar"}') >+ .throw('TypeError'); >+ should(node.channelCountMode, 'node.channelCountMode after invalid setter') >+ .beEqualTo(testValues[testValues.length - 1]); >+ } >+ >+ // Test channelInterpretation >+ if (expectedNodeOptions.channelInterpretation && >+ expectedNodeOptions.channelInterpretation.isFixed) { >+ // The channel interpretation is fixed. Verify that we throw an >+ // error if we try to change it. >+ ['speakers', 'discrete'].forEach(testValue => { >+ if (testValue !== expectedNodeOptions.channelInterpretation.value) { >+ should( >+ () => { >+ node = new window[nodeName]( >+ context, >+ Object.assign( >+ {}, expectedNodeOptions.additionOptions, >+ {channelInterpretation: testValue})); >+ }, >+ `new ${nodeName}(c, {channelInterpretation: "${testValue}"})`) >+ .throw(expectedNodeOptions.channelInterpretation.errorType); >+ } >+ }); >+ } else { >+ // Channel interpretation is not fixed. Verify that we can set it >+ // to all possible values. >+ should( >+ () => { >+ node = new window[nodeName]( >+ context, >+ Object.assign( >+ {}, expectedNodeOptions.additionalOptions, >+ {channelInterpretation: 'speakers'})); >+ }, >+ 'new ' + nodeName + '(c, {channelInterpretation: "speakers"})') >+ .notThrow(); >+ should(node.channelInterpretation, 'node.channelInterpretation') >+ .beEqualTo('speakers'); >+ >+ should( >+ () => { >+ node = new window[nodeName]( >+ context, >+ Object.assign( >+ {}, expectedNodeOptions.additionalOptions, >+ {channelInterpretation: 'discrete'})); >+ }, >+ 'new ' + nodeName + '(c, {channelInterpretation: "discrete"})') >+ .notThrow(); >+ should(node.channelInterpretation, 'node.channelInterpretation') >+ .beEqualTo('discrete'); >+ >+ should( >+ () => { >+ node = new window[nodeName]( >+ context, >+ Object.assign( >+ {}, expectedNodeOptions.additionalOptions, >+ {channelInterpretation: 'foobar'})); >+ }, >+ 'new ' + nodeName + '(c, {channelInterpretation: "foobar"})') >+ .throw('TypeError'); >+ should( >+ node.channelInterpretation, >+ 'node.channelInterpretation after invalid setter') >+ .beEqualTo('discrete'); >+ } >+} >+ >+function initializeContext(should) { >+ let c; >+ should(() => { >+ c = new OfflineAudioContext(1, 1, 48000); >+ }, 'context = new OfflineAudioContext(...)').notThrow(); >+ >+ return c; >+} >+ >+function testInvalidConstructor(should, name, context) { >+ should(() => { >+ new window[name](); >+ }, 'new ' + name + '()').throw('TypeError'); >+ should(() => { >+ new window[name](1); >+ }, 'new ' + name + '(1)').throw('TypeError'); >+ should(() => { >+ new window[name](context, 42); >+ }, 'new ' + name + '(context, 42)').throw('TypeError'); >+} >+ >+function testDefaultConstructor(should, name, context, options) { >+ let node; >+ >+ let message = options.prefix + ' = new ' + name + '(context'; >+ if (options.constructorOptions) >+ message += ', ' + JSON.stringify(options.constructorOptions); >+ message += ')' >+ >+ should(() => { >+ node = new window[name](context, options.constructorOptions); >+ }, message).notThrow(); >+ >+ should(node instanceof window[name], options.prefix + ' instanceof ' + name) >+ .beEqualTo(true); >+ should(node.numberOfInputs, options.prefix + '.numberOfInputs') >+ .beEqualTo(options.numberOfInputs); >+ should(node.numberOfOutputs, options.prefix + '.numberOfOutputs') >+ .beEqualTo(options.numberOfOutputs); >+ should(node.channelCount, options.prefix + '.channelCount') >+ .beEqualTo(options.channelCount); >+ should(node.channelCountMode, options.prefix + '.channelCountMode') >+ .beEqualTo(options.channelCountMode); >+ should(node.channelInterpretation, options.prefix + '.channelInterpretation') >+ .beEqualTo(options.channelInterpretation); >+ >+ return node; >+} >+ >+function testDefaultAttributes(should, node, prefix, items) { >+ items.forEach((item) => { >+ let attr = node[item.name]; >+ if (attr instanceof AudioParam) { >+ should(attr.value, prefix + '.' + item.name + '.value') >+ .beEqualTo(item.value); >+ } else { >+ should(attr, prefix + '.' + item.name).beEqualTo(item.value); >+ } >+ }); >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/biquad-testing.js b/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/biquad-testing.js >new file mode 100644 >index 0000000000000000000000000000000000000000..7a0b6e6c1f8a3d616620425731603f0b43c5ff84 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/biquad-testing.js >@@ -0,0 +1,171 @@ >+// Globals, to make testing and debugging easier. >+let context; >+let filter; >+let signal; >+let renderedBuffer; >+let renderedData; >+ >+let sampleRate = 44100.0; >+let pulseLengthFrames = .1 * sampleRate; >+ >+// Maximum allowed error for the test to succeed. Experimentally determined. >+let maxAllowedError = 5.9e-8; >+ >+// This must be large enough so that the filtered result is >+// essentially zero. See comments for createTestAndRun. >+let timeStep = .1; >+ >+// Maximum number of filters we can process (mostly for setting the >+// render length correctly.) >+let maxFilters = 5; >+ >+// How long to render. Must be long enough for all of the filters we >+// want to test. >+let renderLengthSeconds = timeStep * (maxFilters + 1); >+ >+let renderLengthSamples = Math.round(renderLengthSeconds * sampleRate); >+ >+// Number of filters that will be processed. >+let nFilters; >+ >+function createImpulseBuffer(context, length) { >+ let impulse = context.createBuffer(1, length, context.sampleRate); >+ let data = impulse.getChannelData(0); >+ for (let k = 1; k < data.length; ++k) { >+ data[k] = 0; >+ } >+ data[0] = 1; >+ >+ return impulse; >+} >+ >+ >+function createTestAndRun(context, filterType, testParameters) { >+ // To test the filters, we apply a signal (an impulse) to each of >+ // the specified filters, with each signal starting at a different >+ // time. The output of the filters is summed together at the >+ // output. Thus for filter k, the signal input to the filter >+ // starts at time k * timeStep. For this to work well, timeStep >+ // must be large enough for the output of each filter to have >+ // decayed to zero with timeStep seconds. That way the filter >+ // outputs don't interfere with each other. >+ >+ let filterParameters = testParameters.filterParameters; >+ nFilters = Math.min(filterParameters.length, maxFilters); >+ >+ signal = new Array(nFilters); >+ filter = new Array(nFilters); >+ >+ impulse = createImpulseBuffer(context, pulseLengthFrames); >+ >+ // Create all of the signal sources and filters that we need. >+ for (let k = 0; k < nFilters; ++k) { >+ signal[k] = context.createBufferSource(); >+ signal[k].buffer = impulse; >+ >+ filter[k] = context.createBiquadFilter(); >+ filter[k].type = filterType; >+ filter[k].frequency.value = >+ context.sampleRate / 2 * filterParameters[k].cutoff; >+ filter[k].detune.value = (filterParameters[k].detune === undefined) ? >+ 0 : >+ filterParameters[k].detune; >+ filter[k].Q.value = filterParameters[k].q; >+ filter[k].gain.value = filterParameters[k].gain; >+ >+ signal[k].connect(filter[k]); >+ filter[k].connect(context.destination); >+ >+ signal[k].start(timeStep * k); >+ } >+ >+ return context.startRendering().then(buffer => { >+ checkFilterResponse(buffer, filterType, testParameters); >+ }); >+} >+ >+function addSignal(dest, src, destOffset) { >+ // Add src to dest at the given dest offset. >+ for (let k = destOffset, j = 0; k < dest.length, j < src.length; ++k, ++j) { >+ dest[k] += src[j]; >+ } >+} >+ >+function generateReference(filterType, filterParameters) { >+ let result = new Array(renderLengthSamples); >+ let data = new Array(renderLengthSamples); >+ // Initialize the result array and data. >+ for (let k = 0; k < result.length; ++k) { >+ result[k] = 0; >+ data[k] = 0; >+ } >+ // Make data an impulse. >+ data[0] = 1; >+ >+ for (let k = 0; k < nFilters; ++k) { >+ // Filter an impulse >+ let detune = (filterParameters[k].detune === undefined) ? >+ 0 : >+ filterParameters[k].detune; >+ let frequency = filterParameters[k].cutoff * >+ Math.pow(2, detune / 1200); // Apply detune, converting from Cents. >+ >+ let filterCoef = createFilter( >+ filterType, frequency, filterParameters[k].q, filterParameters[k].gain); >+ let y = filterData(filterCoef, data, renderLengthSamples); >+ >+ // Accumulate this filtered data into the final output at the desired >+ // offset. >+ addSignal(result, y, timeToSampleFrame(timeStep * k, sampleRate)); >+ } >+ >+ return result; >+} >+ >+function checkFilterResponse(renderedBuffer, filterType, testParameters) { >+ let filterParameters = testParameters.filterParameters; >+ let maxAllowedError = testParameters.threshold; >+ let should = testParameters.should; >+ >+ renderedData = renderedBuffer.getChannelData(0); >+ >+ reference = generateReference(filterType, filterParameters); >+ >+ let len = Math.min(renderedData.length, reference.length); >+ >+ let success = true; >+ >+ // Maximum error between rendered data and expected data >+ let maxError = 0; >+ >+ // Sample offset where the maximum error occurred. >+ let maxPosition = 0; >+ >+ // Number of infinities or NaNs that occurred in the rendered data. >+ let invalidNumberCount = 0; >+ >+ should(nFilters, 'Number of filters tested') >+ .beEqualTo(filterParameters.length); >+ >+ // Compare the rendered signal with our reference, keeping >+ // track of the maximum difference (and the offset of the max >+ // difference.) Check for bad numbers in the rendered output >+ // too. There shouldn't be any. >+ for (let k = 0; k < len; ++k) { >+ let err = Math.abs(renderedData[k] - reference[k]); >+ if (err > maxError) { >+ maxError = err; >+ maxPosition = k; >+ } >+ if (!isValidNumber(renderedData[k])) { >+ ++invalidNumberCount; >+ } >+ } >+ >+ should( >+ invalidNumberCount, 'Number of non-finite values in the rendered output') >+ .beEqualTo(0); >+ >+ should(maxError, 'Max error in ' + filterTypeName[filterType] + ' response') >+ .beLessThanOrEqualTo(maxAllowedError); >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/mix-testing.js b/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/mix-testing.js >new file mode 100644 >index 0000000000000000000000000000000000000000..63c8e1aca61b27b405a2475d180dbd47e79c9501 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/mix-testing.js >@@ -0,0 +1,23 @@ >+let toneLengthSeconds = 1; >+ >+// Create a buffer with multiple channels. >+// The signal frequency in each channel is the multiple of that in the first >+// channel. >+function createToneBuffer(context, frequency, duration, numberOfChannels) { >+ let sampleRate = context.sampleRate; >+ let sampleFrameLength = duration * sampleRate; >+ >+ let audioBuffer = >+ context.createBuffer(numberOfChannels, sampleFrameLength, sampleRate); >+ >+ let n = audioBuffer.length; >+ >+ for (let k = 0; k < numberOfChannels; ++k) { >+ let data = audioBuffer.getChannelData(k); >+ >+ for (let i = 0; i < n; ++i) >+ data[i] = Math.sin(frequency * (k + 1) * 2.0 * Math.PI * i / sampleRate); >+ } >+ >+ return audioBuffer; >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/mixing-rules.js b/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/mixing-rules.js >new file mode 100644 >index 0000000000000000000000000000000000000000..e06a1468a3b8eea60c4f603b05bf474e8d6cbe9d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/mixing-rules.js >@@ -0,0 +1,350 @@ >+// Utilities for mixing rule testing. >+// http://webaudio.github.io/web-audio-api/#channel-up-mixing-and-down-mixing >+ >+ >+/** >+ * Create an n-channel buffer, with all sample data zero except for a shifted >+ * impulse. The impulse position depends on the channel index. For example, for >+ * a 4-channel buffer: >+ * channel 0: 1 0 0 0 0 0 0 0 >+ * channel 1: 0 1 0 0 0 0 0 0 >+ * channel 2: 0 0 1 0 0 0 0 0 >+ * channel 3: 0 0 0 1 0 0 0 0 >+ * @param {AudioContext} context Associated AudioContext. >+ * @param {Number} numberOfChannels Number of channels of test buffer. >+ * @param {Number} frameLength Buffer length in frames. >+ * @return {AudioBuffer} >+ */ >+function createShiftedImpulseBuffer(context, numberOfChannels, frameLength) { >+ let shiftedImpulseBuffer = >+ context.createBuffer(numberOfChannels, frameLength, context.sampleRate); >+ for (let channel = 0; channel < numberOfChannels; ++channel) { >+ let data = shiftedImpulseBuffer.getChannelData(channel); >+ data[channel] = 1; >+ } >+ >+ return shiftedImpulseBuffer; >+} >+ >+/** >+ * Create a string that displays the content of AudioBuffer. >+ * @param {AudioBuffer} audioBuffer AudioBuffer object to stringify. >+ * @param {Number} frameLength Number of frames to be printed. >+ * @param {Number} frameOffset Starting frame position for printing. >+ * @return {String} >+ */ >+function stringifyBuffer(audioBuffer, frameLength, frameOffset) { >+ frameOffset = (frameOffset || 0); >+ >+ let stringifiedBuffer = ''; >+ for (let channel = 0; channel < audioBuffer.numberOfChannels; ++channel) { >+ let channelData = audioBuffer.getChannelData(channel); >+ for (let i = 0; i < frameLength; ++i) >+ stringifiedBuffer += channelData[i + frameOffset] + ' '; >+ stringifiedBuffer += '\n'; >+ } >+ >+ return stringifiedBuffer; >+} >+ >+/** >+ * Compute number of channels from the connection. >+ * http://webaudio.github.io/web-audio-api/#dfn-computednumberofchannels >+ * @param {String} connections A string specifies the connection. For >+ * example, the string "128" means 3 >+ * connections, having 1, 2, and 8 channels >+ * respectively. >+ * @param {Number} channelCount Channel count. >+ * @param {String} channelCountMode Channel count mode. >+ * @return {Number} Computed number of channels. >+ */ >+function computeNumberOfChannels(connections, channelCount, channelCountMode) { >+ if (channelCountMode == 'explicit') >+ return channelCount; >+ >+ // Must have at least one channel. >+ let computedNumberOfChannels = 1; >+ >+ // Compute "computedNumberOfChannels" based on all the connections. >+ for (let i = 0; i < connections.length; ++i) { >+ let connectionNumberOfChannels = parseInt(connections[i]); >+ computedNumberOfChannels = >+ Math.max(computedNumberOfChannels, connectionNumberOfChannels); >+ } >+ >+ if (channelCountMode == 'clamped-max') >+ computedNumberOfChannels = Math.min(computedNumberOfChannels, channelCount); >+ >+ return computedNumberOfChannels; >+} >+ >+/** >+ * Apply up/down-mixing (in-place summing) based on 'speaker' interpretation. >+ * @param {AudioBuffer} input Input audio buffer. >+ * @param {AudioBuffer} output Output audio buffer. >+ */ >+function speakersSum(input, output) { >+ if (input.length != output.length) { >+ throw '[mixing-rules.js] speakerSum(): buffer lengths mismatch (input: ' + >+ input.length + ', output: ' + output.length + ')'; >+ } >+ >+ if (input.numberOfChannels === output.numberOfChannels) { >+ for (let channel = 0; channel < output.numberOfChannels; ++channel) { >+ let inputChannel = input.getChannelData(channel); >+ let outputChannel = output.getChannelData(channel); >+ for (let i = 0; i < outputChannel.length; i++) >+ outputChannel[i] += inputChannel[i]; >+ } >+ } else if (input.numberOfChannels < output.numberOfChannels) { >+ processUpMix(input, output); >+ } else { >+ processDownMix(input, output); >+ } >+} >+ >+/** >+ * In-place summing to |output| based on 'discrete' channel interpretation. >+ * @param {AudioBuffer} input Input audio buffer. >+ * @param {AudioBuffer} output Output audio buffer. >+ */ >+function discreteSum(input, output) { >+ if (input.length != output.length) { >+ throw '[mixing-rules.js] speakerSum(): buffer lengths mismatch (input: ' + >+ input.length + ', output: ' + output.length + ')'; >+ } >+ >+ let numberOfChannels = >+ Math.min(input.numberOfChannels, output.numberOfChannels) >+ >+ for (let channel = 0; channel < numberOfChannels; ++channel) { >+ let inputChannel = input.getChannelData(channel); >+ let outputChannel = output.getChannelData(channel); >+ for (let i = 0; i < outputChannel.length; i++) >+ outputChannel[i] += inputChannel[i]; >+ } >+} >+ >+/** >+ * Perform up-mix by in-place summing to |output| buffer. >+ * @param {AudioBuffer} input Input audio buffer. >+ * @param {AudioBuffer} output Output audio buffer. >+ */ >+function processUpMix(input, output) { >+ let numberOfInputChannels = input.numberOfChannels; >+ let numberOfOutputChannels = output.numberOfChannels; >+ let i, length = output.length; >+ >+ // Up-mixing: 1 -> 2, 1 -> 4 >+ // output.L += input >+ // output.R += input >+ // output.SL += 0 (in the case of 1 -> 4) >+ // output.SR += 0 (in the case of 1 -> 4) >+ if ((numberOfInputChannels === 1 && numberOfOutputChannels === 2) || >+ (numberOfInputChannels === 1 && numberOfOutputChannels === 4)) { >+ let inputChannel = input.getChannelData(0); >+ let outputChannel0 = output.getChannelData(0); >+ let outputChannel1 = output.getChannelData(1); >+ for (i = 0; i < length; i++) { >+ outputChannel0[i] += inputChannel[i]; >+ outputChannel1[i] += inputChannel[i]; >+ } >+ >+ return; >+ } >+ >+ // Up-mixing: 1 -> 5.1 >+ // output.L += 0 >+ // output.R += 0 >+ // output.C += input >+ // output.LFE += 0 >+ // output.SL += 0 >+ // output.SR += 0 >+ if (numberOfInputChannels == 1 && numberOfOutputChannels == 6) { >+ let inputChannel = input.getChannelData(0); >+ let outputChannel2 = output.getChannelData(2); >+ for (i = 0; i < length; i++) >+ outputChannel2[i] += inputChannel[i]; >+ >+ return; >+ } >+ >+ // Up-mixing: 2 -> 4, 2 -> 5.1 >+ // output.L += input.L >+ // output.R += input.R >+ // output.C += 0 (in the case of 2 -> 5.1) >+ // output.LFE += 0 (in the case of 2 -> 5.1) >+ // output.SL += 0 >+ // output.SR += 0 >+ if ((numberOfInputChannels === 2 && numberOfOutputChannels === 4) || >+ (numberOfInputChannels === 2 && numberOfOutputChannels === 6)) { >+ let inputChannel0 = input.getChannelData(0); >+ let inputChannel1 = input.getChannelData(1); >+ let outputChannel0 = output.getChannelData(0); >+ let outputChannel1 = output.getChannelData(1); >+ for (i = 0; i < length; i++) { >+ outputChannel0[i] += inputChannel0[i]; >+ outputChannel1[i] += inputChannel1[i]; >+ } >+ >+ return; >+ } >+ >+ // Up-mixing: 4 -> 5.1 >+ // output.L += input.L >+ // output.R += input.R >+ // output.C += 0 >+ // output.LFE += 0 >+ // output.SL += input.SL >+ // output.SR += input.SR >+ if (numberOfInputChannels === 4 && numberOfOutputChannels === 6) { >+ let inputChannel0 = input.getChannelData(0); // input.L >+ let inputChannel1 = input.getChannelData(1); // input.R >+ let inputChannel2 = input.getChannelData(2); // input.SL >+ let inputChannel3 = input.getChannelData(3); // input.SR >+ let outputChannel0 = output.getChannelData(0); // output.L >+ let outputChannel1 = output.getChannelData(1); // output.R >+ let outputChannel4 = output.getChannelData(4); // output.SL >+ let outputChannel5 = output.getChannelData(5); // output.SR >+ for (i = 0; i < length; i++) { >+ outputChannel0[i] += inputChannel0[i]; >+ outputChannel1[i] += inputChannel1[i]; >+ outputChannel4[i] += inputChannel2[i]; >+ outputChannel5[i] += inputChannel3[i]; >+ } >+ >+ return; >+ } >+ >+ // All other cases, fall back to the discrete sum. >+ discreteSum(input, output); >+} >+ >+/** >+ * Perform down-mix by in-place summing to |output| buffer. >+ * @param {AudioBuffer} input Input audio buffer. >+ * @param {AudioBuffer} output Output audio buffer. >+ */ >+function processDownMix(input, output) { >+ let numberOfInputChannels = input.numberOfChannels; >+ let numberOfOutputChannels = output.numberOfChannels; >+ let i, length = output.length; >+ >+ // Down-mixing: 2 -> 1 >+ // output += 0.5 * (input.L + input.R) >+ if (numberOfInputChannels === 2 && numberOfOutputChannels === 1) { >+ let inputChannel0 = input.getChannelData(0); // input.L >+ let inputChannel1 = input.getChannelData(1); // input.R >+ let outputChannel0 = output.getChannelData(0); >+ for (i = 0; i < length; i++) >+ outputChannel0[i] += 0.5 * (inputChannel0[i] + inputChannel1[i]); >+ >+ return; >+ } >+ >+ // Down-mixing: 4 -> 1 >+ // output += 0.25 * (input.L + input.R + input.SL + input.SR) >+ if (numberOfInputChannels === 4 && numberOfOutputChannels === 1) { >+ let inputChannel0 = input.getChannelData(0); // input.L >+ let inputChannel1 = input.getChannelData(1); // input.R >+ let inputChannel2 = input.getChannelData(2); // input.SL >+ let inputChannel3 = input.getChannelData(3); // input.SR >+ let outputChannel0 = output.getChannelData(0); >+ for (i = 0; i < length; i++) { >+ outputChannel0[i] += 0.25 * >+ (inputChannel0[i] + inputChannel1[i] + inputChannel2[i] + >+ inputChannel3[i]); >+ } >+ >+ return; >+ } >+ >+ // Down-mixing: 5.1 -> 1 >+ // output += sqrt(1/2) * (input.L + input.R) + input.C >+ // + 0.5 * (input.SL + input.SR) >+ if (numberOfInputChannels === 6 && numberOfOutputChannels === 1) { >+ let inputChannel0 = input.getChannelData(0); // input.L >+ let inputChannel1 = input.getChannelData(1); // input.R >+ let inputChannel2 = input.getChannelData(2); // input.C >+ let inputChannel4 = input.getChannelData(4); // input.SL >+ let inputChannel5 = input.getChannelData(5); // input.SR >+ let outputChannel0 = output.getChannelData(0); >+ let scaleSqrtHalf = Math.sqrt(0.5); >+ for (i = 0; i < length; i++) { >+ outputChannel0[i] += >+ scaleSqrtHalf * (inputChannel0[i] + inputChannel1[i]) + >+ inputChannel2[i] + 0.5 * (inputChannel4[i] + inputChannel5[i]); >+ } >+ >+ return; >+ } >+ >+ // Down-mixing: 4 -> 2 >+ // output.L += 0.5 * (input.L + input.SL) >+ // output.R += 0.5 * (input.R + input.SR) >+ if (numberOfInputChannels == 4 && numberOfOutputChannels == 2) { >+ let inputChannel0 = input.getChannelData(0); // input.L >+ let inputChannel1 = input.getChannelData(1); // input.R >+ let inputChannel2 = input.getChannelData(2); // input.SL >+ let inputChannel3 = input.getChannelData(3); // input.SR >+ let outputChannel0 = output.getChannelData(0); // output.L >+ let outputChannel1 = output.getChannelData(1); // output.R >+ for (i = 0; i < length; i++) { >+ outputChannel0[i] += 0.5 * (inputChannel0[i] + inputChannel2[i]); >+ outputChannel1[i] += 0.5 * (inputChannel1[i] + inputChannel3[i]); >+ } >+ >+ return; >+ } >+ >+ // Down-mixing: 5.1 -> 2 >+ // output.L += input.L + sqrt(1/2) * (input.C + input.SL) >+ // output.R += input.R + sqrt(1/2) * (input.C + input.SR) >+ if (numberOfInputChannels == 6 && numberOfOutputChannels == 2) { >+ let inputChannel0 = input.getChannelData(0); // input.L >+ let inputChannel1 = input.getChannelData(1); // input.R >+ let inputChannel2 = input.getChannelData(2); // input.C >+ let inputChannel4 = input.getChannelData(4); // input.SL >+ let inputChannel5 = input.getChannelData(5); // input.SR >+ let outputChannel0 = output.getChannelData(0); // output.L >+ let outputChannel1 = output.getChannelData(1); // output.R >+ let scaleSqrtHalf = Math.sqrt(0.5); >+ for (i = 0; i < length; i++) { >+ outputChannel0[i] += inputChannel0[i] + >+ scaleSqrtHalf * (inputChannel2[i] + inputChannel4[i]); >+ outputChannel1[i] += inputChannel1[i] + >+ scaleSqrtHalf * (inputChannel2[i] + inputChannel5[i]); >+ } >+ >+ return; >+ } >+ >+ // Down-mixing: 5.1 -> 4 >+ // output.L += input.L + sqrt(1/2) * input.C >+ // output.R += input.R + sqrt(1/2) * input.C >+ // output.SL += input.SL >+ // output.SR += input.SR >+ if (numberOfInputChannels === 6 && numberOfOutputChannels === 4) { >+ let inputChannel0 = input.getChannelData(0); // input.L >+ let inputChannel1 = input.getChannelData(1); // input.R >+ let inputChannel2 = input.getChannelData(2); // input.C >+ let inputChannel4 = input.getChannelData(4); // input.SL >+ let inputChannel5 = input.getChannelData(5); // input.SR >+ let outputChannel0 = output.getChannelData(0); // output.L >+ let outputChannel1 = output.getChannelData(1); // output.R >+ let outputChannel2 = output.getChannelData(2); // output.SL >+ let outputChannel3 = output.getChannelData(3); // output.SR >+ let scaleSqrtHalf = Math.sqrt(0.5); >+ for (i = 0; i < length; i++) { >+ outputChannel0[i] += inputChannel0[i] + scaleSqrtHalf * inputChannel2[i]; >+ outputChannel1[i] += inputChannel1[i] + scaleSqrtHalf * inputChannel2[i]; >+ outputChannel2[i] += inputChannel4[i]; >+ outputChannel3[i] += inputChannel5[i]; >+ } >+ >+ return; >+ } >+ >+ // All other cases, fall back to the discrete sum. >+ discreteSum(input, output); >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/w3c-import.log >index 3152710e145059ddb5150d6076b2bcbda0e63bb6..85a3e5204d5c6ad90b4453015b352dafa44a5d84 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/w3c-import.log >@@ -14,14 +14,19 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/audio-param.js >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/audionodeoptions.js > /LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/audioparam-testing.js > /LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/audit-util.js > /LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/audit.js > /LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/biquad-filters.js >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/biquad-testing.js > /LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/convolution-testing.js > /LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/delay-testing.js > /LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/distance-model-testing.js > /LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/merger-testing.js >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/mix-testing.js >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/mixing-rules.js > /LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/panner-formulas.js > /LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/panner-model-testing.js > /LayoutTests/imported/w3c/web-platform-tests/webaudio/resources/sin_440Hz_-6dBFS_1s.wav >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..0127d3976e64eb597825f281160a5a482d509a32 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser-expected.txt >@@ -0,0 +1,17 @@ >+CONSOLE MESSAGE: line 227: TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+PASS context = new OfflineAudioContext(...) did not throw an exception. >+PASS < [initialize] All assertions passed. (total 1 assertions) >+PASS > [invalid constructor] >+PASS new AnalyserNode() threw TypeError: "function is not a constructor (evaluating 'new window[name]()')". >+PASS new AnalyserNode(1) threw TypeError: "function is not a constructor (evaluating 'new window[name](1)')". >+PASS new AnalyserNode(context, 42) threw TypeError: "function is not a constructor (evaluating 'new window[name](context, 42)')". >+PASS < [invalid constructor] All assertions passed. (total 3 assertions) >+PASS > [default constructor] >+FAIL X node0 = new AnalyserNode(context) incorrectly threw TypeError: "function is not a constructor (evaluating 'new window[name](context, options.constructorOptions)')". assert_true: expected true got false >+FAIL X node0 instanceof AnalyserNode is not equal to true. Got false. assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2112edeeffcf5688357d98b5161e6c3ab2d761ad >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser.html >@@ -0,0 +1,183 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Constructor: AnalyserNode >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audionodeoptions.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let context; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('initialize', (task, should) => { >+ context = initializeContext(should); >+ task.done(); >+ }); >+ >+ audit.define('invalid constructor', (task, should) => { >+ testInvalidConstructor(should, 'AnalyserNode', context); >+ task.done(); >+ }); >+ >+ audit.define('default constructor', (task, should) => { >+ let prefix = 'node0'; >+ let node = testDefaultConstructor(should, 'AnalyserNode', context, { >+ prefix: prefix, >+ numberOfInputs: 1, >+ numberOfOutputs: 1, >+ channelCount: 1, >+ channelCountMode: 'max', >+ channelInterpretation: 'speakers' >+ }); >+ >+ testDefaultAttributes(should, node, prefix, [ >+ {name: 'fftSize', value: 2048}, >+ {name: 'frequencyBinCount', value: 1024}, >+ {name: 'minDecibels', value: -100}, {name: 'maxDecibels', value: -30}, >+ {name: 'smoothingTimeConstant', value: 0.8} >+ ]); >+ >+ task.done(); >+ }); >+ >+ audit.define('test AudioNodeOptions', (task, should) => { >+ testAudioNodeOptions(should, context, 'AnalyserNode'); >+ task.done(); >+ }); >+ >+ audit.define('constructor with options', (task, should) => { >+ let options = { >+ fftSize: 32, >+ maxDecibels: 1, >+ minDecibels: -13, >+ // Choose a value that can be represented the same as a float and as a >+ // double. >+ smoothingTimeConstant: 0.125 >+ }; >+ >+ let node; >+ should( >+ () => { >+ node = new AnalyserNode(context, options); >+ }, >+ 'node1 = new AnalyserNode(c, ' + JSON.stringify(options) + ')') >+ .notThrow(); >+ >+ should(node instanceof AnalyserNode, 'node1 instanceof AnalyserNode') >+ .beEqualTo(true); >+ should(node.fftSize, 'node1.fftSize').beEqualTo(options.fftSize); >+ should(node.maxDecibels, 'node1.maxDecibels') >+ .beEqualTo(options.maxDecibels); >+ should(node.minDecibels, 'node1.minDecibels') >+ .beEqualTo(options.minDecibels); >+ should(node.smoothingTimeConstant, 'node1.smoothingTimeConstant') >+ .beEqualTo(options.smoothingTimeConstant); >+ >+ task.done(); >+ }); >+ >+ audit.define('construct invalid options', (task, should) => { >+ let node; >+ >+ should( >+ () => { >+ node = new AnalyserNode(context, {fftSize: 33}); >+ }, >+ 'node = new AnalyserNode(c, { fftSize: 33 })') >+ .throw('IndexSizeError'); >+ should( >+ () => { >+ node = new AnalyserNode(context, {maxDecibels: -500}); >+ }, >+ 'node = new AnalyserNode(c, { maxDecibels: -500 })') >+ .throw('IndexSizeError'); >+ should( >+ () => { >+ node = new AnalyserNode(context, {minDecibels: -10}); >+ }, >+ 'node = new AnalyserNode(c, { minDecibels: -10 })') >+ .throw('IndexSizeError'); >+ should( >+ () => { >+ node = new AnalyserNode(context, {smoothingTimeConstant: 2}); >+ }, >+ 'node = new AnalyserNode(c, { smoothingTimeConstant: 2 })') >+ .throw('IndexSizeError'); >+ should(function() { >+ node = new AnalyserNode(context, {frequencyBinCount: 33}); >+ }, 'node = new AnalyserNode(c, { frequencyBinCount: 33 })').notThrow(); >+ should(node.frequencyBinCount, 'node.frequencyBinCount') >+ .beEqualTo(1024); >+ >+ task.done(); >+ }); >+ >+ audit.define('setting min/max', (task, should) => { >+ let node; >+ >+ // Recall the default values of minDecibels and maxDecibels are -100, >+ // and -30, respectively. Setting both values in the constructor should >+ // not signal an error in any of the following cases. >+ let options = {minDecibels: -10, maxDecibels: 20}; >+ should( >+ () => { >+ node = new AnalyserNode(context, options); >+ }, >+ 'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')') >+ .notThrow(); >+ >+ options = {maxDecibels: 20, minDecibels: -10}; >+ should( >+ () => { >+ node = new AnalyserNode(context, options); >+ }, >+ 'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')') >+ .notThrow(); >+ >+ options = {minDecibels: -200, maxDecibels: -150}; >+ should( >+ () => { >+ node = new AnalyserNode(context, options); >+ }, >+ 'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')') >+ .notThrow(); >+ >+ options = {maxDecibels: -150, minDecibels: -200}; >+ should( >+ () => { >+ node = new AnalyserNode(context, options); >+ }, >+ 'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')') >+ .notThrow(); >+ >+ // But these should signal because minDecibel > maxDecibel >+ options = {maxDecibels: -150, minDecibels: -10}; >+ should( >+ () => { >+ node = new AnalyserNode(context, options); >+ }, >+ 'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')') >+ .throw('IndexSizeError'); >+ >+ options = {minDecibels: -10, maxDecibels: -150}; >+ should( >+ () => { >+ node = new AnalyserNode(context, options); >+ }, >+ 'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')') >+ .throw('IndexSizeError'); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-basic-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-basic-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..08e0598bcbbace87de240b7125f272912cc723c0 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-basic-expected.txt >@@ -0,0 +1,13 @@ >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [Basic AnalyserNode test] >+PASS Number of inputs for AnalyserNode is equal to 1. >+PASS Number of outputs for AnalyserNode is equal to 1. >+PASS Default minDecibels value is equal to -100. >+PASS Default maxDecibels value is equal to -30. >+PASS Default smoothingTimeConstant value is equal to 0.8. >+PASS node.minDecibels = -50.333333333333336 is equal to -50.333333333333336. >+PASS node.maxDecibels = -40.333333333333336 is equal to -40.333333333333336. >+PASS < [Basic AnalyserNode test] All assertions passed. (total 7 assertions) >+PASS # AUDIT TASK RUNNER FINISHED: 1 tasks ran successfully. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-basic.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-basic.html >new file mode 100644 >index 0000000000000000000000000000000000000000..e176d6111e81fbff6ce75d63bec563bede61de6b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-basic.html >@@ -0,0 +1,57 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ realtimeanalyser-basic.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let context = 0; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('Basic AnalyserNode test', function(task, should) { >+ context = new AudioContext(); >+ let analyser = context.createAnalyser(); >+ >+ should(analyser.numberOfInputs, 'Number of inputs for AnalyserNode') >+ .beEqualTo(1); >+ >+ should(analyser.numberOfOutputs, 'Number of outputs for AnalyserNode') >+ .beEqualTo(1); >+ >+ should(analyser.minDecibels, 'Default minDecibels value') >+ .beEqualTo(-100); >+ >+ should(analyser.maxDecibels, 'Default maxDecibels value') >+ .beEqualTo(-30); >+ >+ should( >+ analyser.smoothingTimeConstant, >+ 'Default smoothingTimeConstant value') >+ .beEqualTo(0.8); >+ >+ let expectedValue = -50 - (1 / 3); >+ analyser.minDecibels = expectedValue; >+ >+ should(analyser.minDecibels, 'node.minDecibels = ' + expectedValue) >+ .beEqualTo(expectedValue); >+ >+ expectedValue = -40 - (1 / 3); >+ analyser.maxDecibels = expectedValue; >+ >+ should(analyser.maxDecibels, 'node.maxDecibels = ' + expectedValue) >+ .beEqualTo(expectedValue); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..38e9aea61a67e667c922b76f59cb8e58c147d573 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 105: TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [FFT scaling tests] Test Scaling of FFT in AnalyserNode >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling.html >new file mode 100644 >index 0000000000000000000000000000000000000000..6a0ab7d06eda5a67ca4262ea1ded49b03cc356b9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling.html >@@ -0,0 +1,113 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ realtimeanalyser-fft-scaling.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <div id="description"></div> >+ <div id="console"></div> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ // The number of analysers. We have analysers from size for each of the >+ // possible sizes of 2^5 to 2^15 for a total of 11. >+ let numberOfAnalysers = 11; >+ let sampleRate = 44100; >+ let nyquistFrequency = sampleRate / 2; >+ >+ // Frequency of the sine wave test signal. Should be high enough so that >+ // we get at least one full cycle for the 32-point FFT. This should also >+ // be such that the frequency should be exactly in one of the FFT bins for >+ // each of the possible FFT sizes. >+ let oscFrequency = nyquistFrequency / 16; >+ >+ // The actual peak values from each analyser. Useful for examining the >+ // actual peak values. >+ let peakValue = new Array(numberOfAnalysers); >+ >+ // For a 0dBFS sine wave, we would expect the FFT magnitude to be 0dB as >+ // well, but the analyzer node applies a Blackman window (to smooth the >+ // estimate). This reduces the energy of the signal so the FFT peak is >+ // less than 0dB. The threshold value given here was determined >+ // experimentally. >+ // >+ // See https://code.google.com/p/chromium/issues/detail?id=341596. >+ let peakThreshold = [ >+ -14.43, -13.56, -13.56, -13.56, -13.56, -13.56, -13.56, -13.56, -13.56, >+ -13.56, -13.56 >+ ]; >+ >+ function checkResult(order, analyser, should) { >+ return function() { >+ let index = order - 5; >+ let fftSize = 1 << order; >+ let fftData = new Float32Array(fftSize); >+ analyser.getFloatFrequencyData(fftData); >+ >+ // Compute the frequency bin that should contain the peak. >+ let expectedBin = >+ analyser.frequencyBinCount * (oscFrequency / nyquistFrequency); >+ >+ // Find the actual bin by finding the bin containing the peak. >+ let actualBin = 0; >+ peakValue[index] = -1000; >+ for (k = 0; k < analyser.frequencyBinCount; ++k) { >+ if (fftData[k] > peakValue[index]) { >+ actualBin = k; >+ peakValue[index] = fftData[k]; >+ } >+ } >+ >+ should(actualBin, (1 << order) + '-point FFT peak position') >+ .beEqualTo(expectedBin); >+ >+ should( >+ peakValue[index], (1 << order) + '-point FFT peak value in dBFS') >+ .beGreaterThanOrEqualTo(peakThreshold[index]); >+ } >+ } >+ >+ audit.define( >+ { >+ label: 'FFT scaling tests', >+ description: 'Test Scaling of FFT in AnalyserNode' >+ }, >+ function(task, should) { >+ let tests = []; >+ for (let k = 5; k <= 15; ++k) >+ tests.push(runTest(k, should)); >+ >+ // The order in which the tests finish is not important. >+ Promise.all(tests).then(task.done.bind(task)); >+ }); >+ >+ function runTest(order, should) { >+ let context = new OfflineAudioContext(1, 1 << order, sampleRate); >+ // Use a sine wave oscillator as the reference source signal. >+ let osc = context.createOscillator(); >+ osc.type = 'sine'; >+ osc.frequency.value = oscFrequency; >+ osc.connect(context.destination); >+ >+ let analyser = context.createAnalyser(); >+ // No smoothing to simplify the analysis of the result. >+ analyser.smoothingTimeConstant = 0; >+ analyser.fftSize = 1 << order; >+ osc.connect(analyser); >+ >+ osc.start(); >+ return context.startRendering().then(() => { >+ checkResult(order, analyser, should)(); >+ }); >+ } >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-sizing-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-sizing-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..e8920bc03a0630ec5c1b1464e4696e66d6a5e24d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-sizing-expected.txt >@@ -0,0 +1,43 @@ >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [FFT size test] Test that re-sizing the FFT arrays does not fail. >+PASS Setting fftSize to -1 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 0 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 1 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 2 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 3 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 4 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 5 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 8 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 9 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 16 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 17 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 32 did not throw an exception. >+PASS Setting fftSize to 33 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 64 did not throw an exception. >+PASS Setting fftSize to 65 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 128 did not throw an exception. >+PASS Setting fftSize to 129 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 256 did not throw an exception. >+PASS Setting fftSize to 257 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 512 did not throw an exception. >+PASS Setting fftSize to 513 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 1024 did not throw an exception. >+PASS Setting fftSize to 1025 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 2048 did not throw an exception. >+PASS Setting fftSize to 2049 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 4096 did not throw an exception. >+PASS Setting fftSize to 4097 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 8192 did not throw an exception. >+PASS Setting fftSize to 8193 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 16384 did not throw an exception. >+PASS Setting fftSize to 16385 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 32768 did not throw an exception. >+PASS Setting fftSize to 32769 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 65536 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 65537 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 131072 threw IndexSizeError: "The index is not in the allowed range.". >+PASS Setting fftSize to 131073 threw IndexSizeError: "The index is not in the allowed range.". >+PASS < [FFT size test] All assertions passed. (total 37 assertions) >+PASS # AUDIT TASK RUNNER FINISHED: 1 tasks ran successfully. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-sizing.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-sizing.html >new file mode 100644 >index 0000000000000000000000000000000000000000..b3de37f119f167469a4337d520345f820a6c4165 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-sizing.html >@@ -0,0 +1,54 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ realtimeanalyser-fft-sizing.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ function doTest(fftSize, illegal, should) { >+ let c = new OfflineAudioContext(1, 1000, 44100); >+ let a = c.createAnalyser(); >+ let message = 'Setting fftSize to ' + fftSize; >+ let tester = function() { >+ a.fftSize = fftSize; >+ }; >+ >+ if (illegal) { >+ should(tester, message).throw('IndexSizeError'); >+ } else { >+ should(tester, message).notThrow(); >+ } >+ } >+ >+ audit.define( >+ { >+ label: 'FFT size test', >+ description: 'Test that re-sizing the FFT arrays does not fail.' >+ }, >+ function(task, should) { >+ doTest(-1, true, should); >+ doTest(0, true, should); >+ doTest(1, true, should); >+ for (let i = 2; i <= 0x20000; i *= 2) { >+ if (i >= 32 && i <= 32768) >+ doTest(i, false, should); >+ else >+ doTest(i, true, should); >+ doTest(i + 1, true, should); >+ } >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/w3c-import.log >index 33c72b7317498d3301ce173f0051621cd55b8132..ae0fec443be5e53fe99753cc6d40f061f9c5d518 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/w3c-import.log >@@ -14,6 +14,10 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-basic.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-sizing.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-gain.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-minimum.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-output.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..3cced8341d7b5ba5cdf94a1ab4a991b5bdaa51b4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel-expected.txt >@@ -0,0 +1,31 @@ >+CONSOLE MESSAGE: line 236: TypeError: buffer.copyFromChannel is not a function. (In 'buffer.copyFromChannel(dst8, c)', 'buffer.copyFromChannel' is undefined) >+ >+Harness Error (FAIL), message = TypeError: buffer.copyFromChannel is not a function. (In 'buffer.copyFromChannel(dst8, c)', 'buffer.copyFromChannel' is undefined) >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+PASS Initialized values contains only the constant -1. >+PASS < [initialize] All assertions passed. (total 1 assertions) >+PASS > [copyFrom-exceptions] >+FAIL X AudioBuffer.prototype.copyFromChannel does not exist. Got undefined. assert_true: expected true got false >+PASS 0: buffer = context.createBuffer(3, 16, context.sampleRate) did not throw an exception. >+PASS 1: buffer.copyFromChannel(null, 0) threw TypeError: "buffer.copyFromChannel is not a function. (In 'buffer.copyFromChannel(null, 0)', 'buffer.copyFromChannel' is undefined)". >+PASS 2: buffer.copyFromChannel(context, 0) threw TypeError: "buffer.copyFromChannel is not a function. (In 'buffer.copyFromChannel(context, 0)', 'buffer.copyFromChannel' is undefined)". >+FAIL X 3: buffer.copyFromChannel(x, -1) threw "TypeError" instead of IndexSizeError. assert_true: expected true got false >+FAIL X 4: buffer.copyFromChannel(x, 3) threw "TypeError" instead of IndexSizeError. assert_true: expected true got false >+FAIL X 5: buffer.copyFromChannel(x, 0, -1) threw "TypeError" instead of IndexSizeError. assert_true: expected true got false >+FAIL X 6: buffer.copyFromChannel(x, 0, 16) threw "TypeError" instead of IndexSizeError. assert_true: expected true got false >+FAIL X 7: buffer.copyFromChannel(x, 3) threw "TypeError" instead of IndexSizeError. assert_true: expected true got false >+FAIL < [copyFrom-exceptions] 6 out of 9 assertions were failed. assert_true: expected true got false >+PASS > [copyTo-exceptions] >+FAIL X AudioBuffer.prototype.copyToChannel does not exist. Got undefined. assert_true: expected true got false >+PASS 0: buffer.copyToChannel(null, 0) threw TypeError: "buffer.copyToChannel is not a function. (In 'buffer.copyToChannel(null, 0)', 'buffer.copyToChannel' is undefined)". >+PASS 1: buffer.copyToChannel(context, 0) threw TypeError: "buffer.copyToChannel is not a function. (In 'buffer.copyToChannel(context, 0)', 'buffer.copyToChannel' is undefined)". >+FAIL X 2: buffer.copyToChannel(x, -1) threw "TypeError" instead of IndexSizeError. assert_true: expected true got false >+FAIL X 3: buffer.copyToChannel(x, 3) threw "TypeError" instead of IndexSizeError. assert_true: expected true got false >+FAIL X 4: buffer.copyToChannel(x, 0, -1) threw "TypeError" instead of IndexSizeError. assert_true: expected true got false >+FAIL X 5: buffer.copyToChannel(x, 0, 16) threw "TypeError" instead of IndexSizeError. assert_true: expected true got false >+FAIL X 6: buffer.copyToChannel(x, 3) threw "TypeError" instead of IndexSizeError. assert_true: expected true got false >+FAIL < [copyTo-exceptions] 6 out of 8 assertions were failed. assert_true: expected true got false >+PASS > [copyFrom-validate] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel.html >new file mode 100644 >index 0000000000000000000000000000000000000000..7d0af70df625ba7e2471091efe8d04e7e36f1165 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel.html >@@ -0,0 +1,331 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Basic Functionality of AudioBuffer.copyFromChannel and >+ AudioBuffer.copyToChannel >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ // Define utility routines. >+ >+ // Initialize the AudioBuffer |buffer| with a ramp signal on each channel. >+ // The ramp starts at channel number + 1. >+ function initializeAudioBufferRamp(buffer) { >+ for (let c = 0; c < buffer.numberOfChannels; ++c) { >+ let d = buffer.getChannelData(c); >+ for (let k = 0; k < d.length; ++k) { >+ d[k] = k + c + 1; >+ } >+ } >+ } >+ >+ // Create a Float32Array of length |length| and initialize the array to >+ // -1. >+ function createInitializedF32Array(length) { >+ let x = new Float32Array(length); >+ for (let k = 0; k < length; ++k) { >+ x[k] = -1; >+ } >+ return x; >+ } >+ >+ // Create a Float32Array of length |length| that is initialized to be a >+ // ramp starting at 1. >+ function createFloat32RampArray(length) { >+ let x = new Float32Array(length); >+ for (let k = 0; k < x.length; ++k) { >+ x[k] = k + 1; >+ } >+ >+ return x; >+ } >+ >+ // Test that the array |x| is a ramp starting at value |start| of length >+ // |length|, starting at |startIndex| in the array. |startIndex| is >+ // optional and defaults to 0. Any other values must be -1. >+ function shouldBeRamp( >+ should, testName, x, startValue, length, startIndex) { >+ let k; >+ let startingIndex = startIndex || 0; >+ let expected = Array(x.length); >+ >+ // Fill the expected array with the correct results. >+ >+ // The initial part (if any) must be -1. >+ for (k = 0; k < startingIndex; ++k) { >+ expected[k] = -1; >+ } >+ >+ // The second part should be a ramp starting with |startValue| >+ for (; k < startingIndex + length; ++k) { >+ expected[k] = startValue + k - startingIndex; >+ } >+ >+ // The last part (if any) should be -1. >+ for (; k < x.length; ++k) { >+ expected[k] = -1; >+ } >+ >+ should(x, testName, {numberOfArrayLog: 32}).beEqualToArray(expected); >+ } >+ >+ let audit = Audit.createTaskRunner(); >+ >+ let context = new AudioContext(); >+ // Temp array for testing exceptions for copyToChannel/copyFromChannel. >+ // The length is arbitrary. >+ let x = new Float32Array(8); >+ >+ // Number of frames in the AudioBuffer for testing. This is pretty >+ // arbitrary so choose a fairly small value. >+ let bufferLength = 16; >+ >+ // Number of channels in the AudioBuffer. Also arbitrary, but it should >+ // be greater than 1 for test coverage. >+ let numberOfChannels = 3; >+ >+ // AudioBuffer that will be used for testing copyFrom and copyTo. >+ let buffer = context.createBuffer( >+ numberOfChannels, bufferLength, context.sampleRate); >+ >+ let initialValues = Array(numberOfChannels); >+ >+ // Initialize things >+ audit.define('initialize', (task, should) => { >+ // Initialize to -1. >+ initialValues.fill(-1); >+ should(initialValues, 'Initialized values').beConstantValueOf(-1) >+ task.done(); >+ }); >+ >+ // Test that expected exceptions are signaled for copyFrom. >+ audit.define('copyFrom-exceptions', (task, should) => { >+ should( >+ AudioBuffer.prototype.copyFromChannel, >+ 'AudioBuffer.prototype.copyFromChannel') >+ .exist(); >+ >+ should( >+ () => { >+ buffer = context.createBuffer( >+ numberOfChannels, bufferLength, context.sampleRate); >+ }, >+ '0: buffer = context.createBuffer(' + numberOfChannels + ', ' + >+ bufferLength + ', context.sampleRate)') >+ .notThrow(); >+ should(() => { >+ buffer.copyFromChannel(null, 0); >+ }, '1: buffer.copyFromChannel(null, 0)').throw('TypeError'); >+ should(() => { >+ buffer.copyFromChannel(context, 0); >+ }, '2: buffer.copyFromChannel(context, 0)').throw('TypeError'); >+ should(() => { >+ buffer.copyFromChannel(x, -1); >+ }, '3: buffer.copyFromChannel(x, -1)').throw('IndexSizeError'); >+ should( >+ () => { >+ buffer.copyFromChannel(x, numberOfChannels); >+ }, >+ '4: buffer.copyFromChannel(x, ' + numberOfChannels + ')') >+ .throw('IndexSizeError'); >+ ; >+ should(() => { >+ buffer.copyFromChannel(x, 0, -1); >+ }, '5: buffer.copyFromChannel(x, 0, -1)').throw('IndexSizeError'); >+ should( >+ () => { >+ buffer.copyFromChannel(x, 0, bufferLength); >+ }, >+ '6: buffer.copyFromChannel(x, 0, ' + bufferLength + ')') >+ .throw('IndexSizeError'); >+ >+ should(() => { >+ buffer.copyFromChannel(x, 3); >+ }, '7: buffer.copyFromChannel(x, 3)').throw('IndexSizeError'); >+ >+ if (window.SharedArrayBuffer) { >+ let shared_buffer = new Float32Array(new SharedArrayBuffer(32)); >+ should( >+ () => { >+ buffer.copyFromChannel(shared_buffer, 0); >+ }, >+ '8: buffer.copyFromChannel(SharedArrayBuffer view, 0)') >+ .throw('TypeError'); >+ >+ should( >+ () => { >+ buffer.copyFromChannel(shared_buffer, 0, 0); >+ }, >+ '9: buffer.copyFromChannel(SharedArrayBuffer view, 0, 0)') >+ .throw('TypeError'); >+ } >+ >+ task.done(); >+ }); >+ >+ // Test that expected exceptions are signaled for copyTo. >+ audit.define('copyTo-exceptions', (task, should) => { >+ should( >+ AudioBuffer.prototype.copyToChannel, >+ 'AudioBuffer.prototype.copyToChannel') >+ .exist(); >+ should(() => { >+ buffer.copyToChannel(null, 0); >+ }, '0: buffer.copyToChannel(null, 0)').throw('TypeError'); >+ should(() => { >+ buffer.copyToChannel(context, 0); >+ }, '1: buffer.copyToChannel(context, 0)').throw('TypeError'); >+ should(() => { >+ buffer.copyToChannel(x, -1); >+ }, '2: buffer.copyToChannel(x, -1)').throw('IndexSizeError'); >+ should( >+ () => { >+ buffer.copyToChannel(x, numberOfChannels); >+ }, >+ '3: buffer.copyToChannel(x, ' + numberOfChannels + ')') >+ .throw('IndexSizeError'); >+ should(() => { >+ buffer.copyToChannel(x, 0, -1); >+ }, '4: buffer.copyToChannel(x, 0, -1)').throw('IndexSizeError'); >+ should( >+ () => { >+ buffer.copyToChannel(x, 0, bufferLength); >+ }, >+ '5: buffer.copyToChannel(x, 0, ' + bufferLength + ')') >+ .throw('IndexSizeError'); >+ >+ should(() => { >+ buffer.copyToChannel(x, 3); >+ }, '6: buffer.copyToChannel(x, 3)').throw('IndexSizeError'); >+ >+ if (window.SharedArrayBuffer) { >+ let shared_buffer = new Float32Array(new SharedArrayBuffer(32)); >+ should( >+ () => { >+ buffer.copyToChannel(shared_buffer, 0); >+ }, >+ '7: buffer.copyToChannel(SharedArrayBuffer view, 0)') >+ .throw('TypeError'); >+ >+ should( >+ () => { >+ buffer.copyToChannel(shared_buffer, 0, 0); >+ }, >+ '8: buffer.copyToChannel(SharedArrayBuffer view, 0, 0)') >+ .throw('TypeError'); >+ } >+ >+ task.done(); >+ }); >+ >+ // Test copyFromChannel >+ audit.define('copyFrom-validate', (task, should) => { >+ // Initialize the AudioBuffer to a ramp for testing copyFrom. >+ initializeAudioBufferRamp(buffer); >+ >+ // Test copyFrom operation with a short destination array, filling the >+ // destination completely. >+ for (let c = 0; c < numberOfChannels; ++c) { >+ let dst8 = createInitializedF32Array(8); >+ buffer.copyFromChannel(dst8, c); >+ shouldBeRamp( >+ should, 'buffer.copyFromChannel(dst8, ' + c + ')', dst8, c + 1, 8) >+ } >+ >+ // Test copyFrom operation with a short destination array using a >+ // non-zero start index that still fills the destination completely. >+ for (let c = 0; c < numberOfChannels; ++c) { >+ let dst8 = createInitializedF32Array(8); >+ buffer.copyFromChannel(dst8, c, 1); >+ shouldBeRamp( >+ should, 'buffer.copyFromChannel(dst8, ' + c + ', 1)', dst8, c + 2, >+ 8) >+ } >+ >+ // Test copyFrom operation with a short destination array using a >+ // non-zero start index that does not fill the destinatiom completely. >+ // The extra elements should be unchanged. >+ for (let c = 0; c < numberOfChannels; ++c) { >+ let dst8 = createInitializedF32Array(8); >+ let startInChannel = bufferLength - 5; >+ buffer.copyFromChannel(dst8, c, startInChannel); >+ shouldBeRamp( >+ should, >+ 'buffer.copyFromChannel(dst8, ' + c + ', ' + startInChannel + ')', >+ dst8, c + 1 + startInChannel, bufferLength - startInChannel); >+ } >+ >+ // Copy operation with the destination longer than the buffer, leaving >+ // the trailing elements of the destination untouched. >+ for (let c = 0; c < numberOfChannels; ++c) { >+ let dst26 = createInitializedF32Array(bufferLength + 10); >+ buffer.copyFromChannel(dst26, c); >+ shouldBeRamp( >+ should, 'buffer.copyFromChannel(dst26, ' + c + ')', dst26, c + 1, >+ bufferLength); >+ } >+ >+ task.done(); >+ }); >+ >+ // Test copyTo >+ audit.define('copyTo-validate', (task, should) => { >+ // Create a source consisting of a ramp starting at 1, longer than the >+ // AudioBuffer >+ let src = createFloat32RampArray(bufferLength + 10); >+ >+ // Test copyTo with AudioBuffer shorter than Float32Array. The >+ // AudioBuffer should be completely filled with the Float32Array. >+ should( >+ () => { >+ buffer = >+ createConstantBuffer(context, bufferLength, initialValues); >+ }, >+ 'buffer = createConstantBuffer(context, ' + bufferLength + ', [' + >+ initialValues + '])') >+ .notThrow(); >+ >+ for (let c = 0; c < numberOfChannels; ++c) { >+ buffer.copyToChannel(src, c); >+ shouldBeRamp( >+ should, 'buffer.copyToChannel(src, ' + c + ')', >+ buffer.getChannelData(c), 1, bufferLength); >+ } >+ >+ // Test copyTo with AudioBuffer longer than the Float32Array. The tail >+ // of the AudioBuffer should be unchanged. >+ buffer = createConstantBuffer(context, bufferLength, initialValues); >+ let src10 = createFloat32RampArray(10); >+ for (let c = 0; c < numberOfChannels; ++c) { >+ buffer.copyToChannel(src10, c); >+ shouldBeRamp( >+ should, 'buffer.copyToChannel(src10, ' + c + ')', >+ buffer.getChannelData(c), 1, 10); >+ } >+ >+ // Test copyTo with non-default startInChannel. Part of the AudioBuffer >+ // should filled with the beginning and end sections untouched. >+ buffer = createConstantBuffer(context, bufferLength, initialValues); >+ for (let c = 0; c < numberOfChannels; ++c) { >+ let startInChannel = 5; >+ buffer.copyToChannel(src10, c, startInChannel); >+ >+ shouldBeRamp( >+ should, >+ 'buffer.copyToChannel(src10, ' + c + ', ' + startInChannel + ')', >+ buffer.getChannelData(c), 1, src10.length, startInChannel); >+ } >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..e92717eccf64d86756da34c81a5fb7accfe352b4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-expected.txt >@@ -0,0 +1,17 @@ >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [Basic tests for AudioBuffer] >+PASS buffer = context.createBuffer(4, 88200, 44100) is true. >+PASS buffer.sampleRate is equal to 44100. >+PASS buffer.length is equal to 88200. >+PASS buffer.duration is equal to 2. >+PASS buffer.numberOfChannels is equal to 4. >+PASS buffer.getChannelData(0) instanceof window.Float32Array is true. >+PASS buffer.getChannelData(1) instanceof window.Float32Array is true. >+PASS buffer.getChannelData(2) instanceof window.Float32Array is true. >+PASS buffer.getChannelData(3) instanceof window.Float32Array is true. >+FAIL X buffer.getChannelData(4) threw "SyntaxError" instead of IndexSizeError. assert_true: expected true got false >+FAIL X context.createBuffer(1, 1000, 24576).duration is not equal to 0.040690104166666664. Got 0.0406901054084301. assert_true: expected true got false >+FAIL < [Basic tests for AudioBuffer] 2 out of 11 assertions were failed. assert_true: expected true got false >+FAIL # AUDIT TASK RUNNER FINISHED: 1 out of 1 tasks were failed. assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-getChannelData-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-getChannelData-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..f213f32d227d499f1146ed590a847087f7977b69 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-getChannelData-expected.txt >@@ -0,0 +1,12 @@ >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [buffer-eq] >+FAIL X buffer.getChannelData(0) === buffer.getChannelData(0) is not equal to true. Got false. assert_true: expected true got false >+FAIL X buffer.getChannelData(1) === buffer.getChannelData(1) is not equal to true. Got false. assert_true: expected true got false >+FAIL < [buffer-eq] 2 out of 2 assertions were failed. assert_true: expected true got false >+PASS > [buffer-not-eq] >+PASS buffer1.getChannelData(0) === buffer2.getChannelData(0) is equal to false. >+PASS buffer1.getChannelData(1) === buffer2.getChannelData(1) is equal to false. >+PASS < [buffer-not-eq] All assertions passed. (total 2 assertions) >+FAIL # AUDIT TASK RUNNER FINISHED: 1 out of 2 tasks were failed. assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-getChannelData.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-getChannelData.html >new file mode 100644 >index 0000000000000000000000000000000000000000..612a91cf4ef60f6f1d441d27e2ab86f32b94f0fd >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-getChannelData.html >@@ -0,0 +1,66 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test AudioBuffer.getChannelData() Returns the Same Object >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audioparam-testing.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let sampleRate = 48000; >+ let renderDuration = 0.5; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('buffer-eq', (task, should) => { >+ // Verify that successive calls to getChannelData return the same >+ // buffer. >+ let context = new AudioContext(); >+ let channelCount = 2; >+ let frameLength = 1000; >+ let buffer = >+ context.createBuffer(channelCount, frameLength, context.sampleRate); >+ >+ for (let c = 0; c < channelCount; ++c) { >+ let a = buffer.getChannelData(c); >+ let b = buffer.getChannelData(c); >+ >+ let message = 'buffer.getChannelData(' + c + ')'; >+ should(a === b, message + ' === ' + message).beEqualTo(true); >+ } >+ >+ task.done(); >+ }); >+ >+ audit.define('buffer-not-eq', (task, should) => { >+ let context = new AudioContext(); >+ let channelCount = 2; >+ let frameLength = 1000; >+ let buffer1 = >+ context.createBuffer(channelCount, frameLength, context.sampleRate); >+ let buffer2 = >+ context.createBuffer(channelCount, frameLength, context.sampleRate); >+ let success = true; >+ >+ for (let c = 0; c < channelCount; ++c) { >+ let a = buffer1.getChannelData(c); >+ let b = buffer2.getChannelData(c); >+ >+ let message = 'getChannelData(' + c + ')'; >+ should(a === b, 'buffer1.' + message + ' === buffer2.' + message) >+ .beEqualTo(false) && >+ success; >+ } >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer.html >new file mode 100644 >index 0000000000000000000000000000000000000000..07a34f07c185f4bc9dcf1b325bb51067610b430a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer.html >@@ -0,0 +1,71 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ audiobuffer.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let sampleRate = 44100.0 >+ let lengthInSeconds = 2; >+ let numberOfChannels = 4; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('Basic tests for AudioBuffer', function(task, should) { >+ let context = new AudioContext(); >+ let buffer = context.createBuffer( >+ numberOfChannels, sampleRate * lengthInSeconds, sampleRate); >+ >+ // Just for printing out a message describing what "buffer" is in the >+ // following tests. >+ should( >+ true, >+ 'buffer = context.createBuffer(' + numberOfChannels + ', ' + >+ (sampleRate * lengthInSeconds) + ', ' + sampleRate + ')') >+ .beTrue(); >+ >+ should(buffer.sampleRate, 'buffer.sampleRate').beEqualTo(sampleRate); >+ >+ should(buffer.length, 'buffer.length') >+ .beEqualTo(sampleRate * lengthInSeconds); >+ >+ should(buffer.duration, 'buffer.duration').beEqualTo(lengthInSeconds); >+ >+ should(buffer.numberOfChannels, 'buffer.numberOfChannels') >+ .beEqualTo(numberOfChannels); >+ >+ for (let index = 0; index < buffer.numberOfChannels; ++index) { >+ should( >+ buffer.getChannelData(index) instanceof window.Float32Array, >+ 'buffer.getChannelData(' + index + >+ ') instanceof window.Float32Array') >+ .beTrue(); >+ } >+ >+ should( >+ function() { >+ buffer.getChannelData(buffer.numberOfChannels); >+ }, >+ 'buffer.getChannelData(' + buffer.numberOfChannels + ')') >+ .throw('IndexSizeError'); >+ >+ let buffer2 = context.createBuffer(1, 1000, 24576); >+ let expectedDuration = 1000 / 24576; >+ >+ should( >+ buffer2.duration, 'context.createBuffer(1, 1000, 24576).duration') >+ .beEqualTo(expectedDuration); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/ctor-audiobuffer-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/ctor-audiobuffer-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..28e01b02852e4e0b2e50e5da295d0bb73f96edce >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/ctor-audiobuffer-expected.txt >@@ -0,0 +1,20 @@ >+CONSOLE MESSAGE: line 69: TypeError: undefined is not an object (evaluating 'buffer.numberOfChannels') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'buffer.numberOfChannels') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+PASS context = new OfflineAudioContext(...) did not throw an exception. >+PASS < [initialize] All assertions passed. (total 1 assertions) >+PASS > [invalid constructor] >+PASS new AudioBuffer() threw TypeError: "function is not a constructor (evaluating 'new AudioBuffer()')". >+PASS new AudioBuffer(1) threw TypeError: "function is not a constructor (evaluating 'new AudioBuffer(1)')". >+PASS new AudioBuffer(Date, 42) threw TypeError: "function is not a constructor (evaluating 'new AudioBuffer(Date, 42)')". >+PASS < [invalid constructor] All assertions passed. (total 3 assertions) >+PASS > [required options] >+PASS buffer = new AudioBuffer({}) threw TypeError: "function is not a constructor (evaluating 'new AudioBuffer({})')". >+PASS buffer = new AudioBuffer({length: 1}) threw TypeError: "function is not a constructor (evaluating 'new AudioBuffer({length: 1})')". >+PASS buffer = new AudioBuffer({sampleRate: 48000}) threw TypeError: "function is not a constructor (evaluating 'new AudioBuffer({sampleRate: 48000})')". >+PASS buffer = new AudioBuffer({numberOfChannels: 1} threw TypeError: "function is not a constructor (evaluating 'new AudioBuffer({numberOfChannels: 1})')". >+FAIL X buffer0 = new AudioBuffer({length: 21, sampleRate: 48000} incorrectly threw TypeError: "function is not a constructor (evaluating 'new AudioBuffer({length: 21, sampleRate: context.sampleRate})')". assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/ctor-audiobuffer.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/ctor-audiobuffer.html >new file mode 100644 >index 0000000000000000000000000000000000000000..f6032f29431b744905e7b33d8bdf65cadab328cf >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/ctor-audiobuffer.html >@@ -0,0 +1,234 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Constructor: AudioBuffer >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audionodeoptions.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let context; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('initialize', (task, should) => { >+ context = initializeContext(should); >+ task.done(); >+ }); >+ >+ audit.define('invalid constructor', (task, should) => { >+ should(() => { >+ new AudioBuffer(); >+ }, 'new AudioBuffer()').throw('TypeError'); >+ should(() => { >+ new AudioBuffer(1); >+ }, 'new AudioBuffer(1)').throw('TypeError'); >+ should(() => { >+ new AudioBuffer(Date, 42); >+ }, 'new AudioBuffer(Date, 42)').throw('TypeError'); >+ >+ task.done(); >+ }); >+ >+ audit.define('required options', (task, should) => { >+ let buffer; >+ >+ // The length and sampleRate attributes are required; all others are >+ // optional. >+ should(() => { >+ new AudioBuffer({}); >+ }, 'buffer = new AudioBuffer({})').throw('TypeError'); >+ >+ should(() => { >+ new AudioBuffer({length: 1}); >+ }, 'buffer = new AudioBuffer({length: 1})').throw('TypeError'); >+ >+ should(() => { >+ new AudioBuffer({sampleRate: 48000}); >+ }, 'buffer = new AudioBuffer({sampleRate: 48000})').throw('TypeError'); >+ >+ should(() => { >+ buffer = new AudioBuffer({numberOfChannels: 1}); >+ }, 'buffer = new AudioBuffer({numberOfChannels: 1}').throw('TypeError'); >+ >+ // Length and sampleRate are required, but others are optional. >+ should( >+ () => { >+ buffer = >+ new AudioBuffer({length: 21, sampleRate: context.sampleRate}); >+ }, >+ 'buffer0 = new AudioBuffer({length: 21, sampleRate: ' + >+ context.sampleRate + '}') >+ .notThrow(); >+ // Verify the buffer has the correct values. >+ should(buffer.numberOfChannels, 'buffer0.numberOfChannels') >+ .beEqualTo(1); >+ should(buffer.length, 'buffer0.length').beEqualTo(21); >+ should(buffer.sampleRate, 'buffer0.sampleRate') >+ .beEqualTo(context.sampleRate); >+ >+ should( >+ () => { >+ buffer = new AudioBuffer( >+ {numberOfChannels: 3, length: 1, sampleRate: 48000}); >+ }, >+ 'buffer1 = new AudioBuffer(' + >+ '{numberOfChannels: 3, length: 1, sampleRate: 48000})') >+ .notThrow(); >+ // Verify the buffer has the correct values. >+ should(buffer.numberOfChannels, 'buffer1.numberOfChannels') >+ .beEqualTo(3); >+ should(buffer.length, 'buffer1.length').beEqualTo(1); >+ should(buffer.sampleRate, 'buffer1.sampleRate').beEqualTo(48000); >+ >+ task.done(); >+ }); >+ >+ audit.define('invalid option values', (task, should) => { >+ let options = {numberOfChannels: 0, length: 1, sampleRate: 16000}; >+ should( >+ () => { >+ let buffer = new AudioBuffer(options); >+ }, >+ 'new AudioBuffer(' + JSON.stringify(options) + ')') >+ .throw('NotSupportedError'); >+ >+ options = {numberOfChannels: 99, length: 0, sampleRate: 16000}; >+ should( >+ () => { >+ let buffer = new AudioBuffer(options); >+ }, >+ 'new AudioBuffer(' + JSON.stringify(options) + ')') >+ .throw('NotSupportedError'); >+ >+ options = {numberOfChannels: 1, length: 0, sampleRate: 16000}; >+ should( >+ () => { >+ let buffer = new AudioBuffer(options); >+ }, >+ 'new AudioBuffer(' + JSON.stringify(options) + ')') >+ .throw('NotSupportedError'); >+ >+ options = {numberOfChannels: 1, length: 1, sampleRate: 100}; >+ should( >+ () => { >+ let buffer = new AudioBuffer(options); >+ }, >+ 'new AudioBuffer(' + JSON.stringify(options) + ')') >+ .throw('NotSupportedError'); >+ >+ task.done(); >+ }); >+ >+ audit.define('default constructor', (task, should) => { >+ let buffer; >+ >+ let options = {numberOfChannels: 5, length: 17, sampleRate: 16000}; >+ should( >+ () => { >+ buffer = new AudioBuffer(options); >+ }, >+ 'buffer = new AudioBuffer(' + JSON.stringify(options) + ')') >+ .notThrow(); >+ >+ should(buffer.numberOfChannels, 'buffer.numberOfChannels') >+ .beEqualTo(options.numberOfChannels); >+ should(buffer.length, 'buffer.length').beEqualTo(options.length); >+ should(buffer.sampleRate, 'buffer.sampleRate').beEqualTo(16000); >+ >+ task.done(); >+ }); >+ >+ audit.define('valid constructor', (task, should) => { >+ let buffer; >+ >+ let options = {numberOfChannels: 3, length: 42, sampleRate: 54321}; >+ >+ let message = 'new AudioBuffer(' + JSON.stringify(options) + ')'; >+ should(() => { >+ buffer = new AudioBuffer(options); >+ }, message).notThrow(); >+ >+ should(buffer.numberOfChannels, 'buffer.numberOfChannels') >+ .beEqualTo(options.numberOfChannels); >+ >+ should(buffer.length, 'buffer.length').beEqualTo(options.length); >+ >+ should(buffer.sampleRate, 'buffer.sampleRate') >+ .beEqualTo(options.sampleRate); >+ >+ // Verify that we actually got the right number of channels >+ for (let k = 0; k < options.numberOfChannels; ++k) { >+ let data; >+ let message = 'buffer.getChannelData(' + k + ')'; >+ should(() => { >+ data = buffer.getChannelData(k); >+ }, message).notThrow(); >+ >+ should(data.length, message + ' length').beEqualTo(options.length); >+ } >+ >+ should( >+ () => { >+ buffer.getChannelData(options.numberOfChannels); >+ }, >+ 'buffer.getChannelData(' + options.numberOfChannels + ')') >+ .throw('IndexSizeError'); >+ >+ task.done(); >+ }); >+ >+ audit.define('multiple contexts', (task, should) => { >+ // Test that an AudioBuffer can be used for different contexts. >+ let buffer = >+ new AudioBuffer({length: 128, sampleRate: context.sampleRate}); >+ >+ // Don't use getChannelData here because we want to be able to use >+ // |data| to compare the final results of playing out this buffer. (If >+ // we did, |data| gets detached when the sources play.) >+ let data = new Float32Array(buffer.length); >+ for (let k = 0; k < data.length; ++k) >+ data[k] = 1 + k; >+ buffer.copyToChannel(data, 0); >+ >+ let c1 = new OfflineAudioContext(1, 128, context.sampleRate); >+ let c2 = new OfflineAudioContext(1, 128, context.sampleRate); >+ >+ let s1 = new AudioBufferSourceNode(c1, {buffer: buffer}); >+ let s2 = new AudioBufferSourceNode(c2, {buffer: buffer}); >+ >+ s1.connect(c1.destination); >+ s2.connect(c2.destination); >+ >+ s1.start(); >+ s2.start(); >+ >+ Promise >+ .all([ >+ c1.startRendering().then(function(resultBuffer) { >+ return should(resultBuffer.getChannelData(0), 'c1 result') >+ .beEqualToArray(data); >+ }), >+ c2.startRendering().then(function(resultBuffer) { >+ return should(resultBuffer.getChannelData(0), 'c2 result') >+ .beEqualToArray(data); >+ }), >+ ]) >+ .then(returnValues => { >+ should( >+ returnValues[0] && returnValues[1], >+ 'AudioBuffer shared between two different contexts') >+ .message('correctly', 'incorrectly'); >+ task.done(); >+ }); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/idl-test-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/idl-test-expected.txt >index 0fc08231ef32d3e15df81244d8f72a0bbb092aee..0c8f00fd17aa91a70e1991c6f534993100c1828e 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/idl-test-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/idl-test-expected.txt >@@ -1,5 +1,5 @@ >-CONSOLE MESSAGE: line 331: callback not yet supported >-CONSOLE MESSAGE: line 331: callback not yet supported >+CONSOLE MESSAGE: line 440: callback not yet supported >+CONSOLE MESSAGE: line 440: callback not yet supported > dictionary AudioBufferOptions { > unsigned long numberOfChannels = 1; > required unsigned long length; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/w3c-import.log >index 7a4f456e29c3e1ad932eba630e785ad4f2170888..4cfb04126bacf14388b8f3f4a04680f8e00aaa3c 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/w3c-import.log >@@ -14,4 +14,8 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-getChannelData.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/ctor-audiobuffer.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/idl-test.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..09be433cf1018fa750d05632ba1c8cfdcef0793e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource-expected.txt >@@ -0,0 +1,17 @@ >+CONSOLE MESSAGE: line 227: TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+PASS context = new OfflineAudioContext(...) did not throw an exception. >+PASS < [initialize] All assertions passed. (total 1 assertions) >+PASS > [invalid constructor] >+PASS new AudioBufferSourceNode() threw TypeError: "function is not a constructor (evaluating 'new window[name]()')". >+PASS new AudioBufferSourceNode(1) threw TypeError: "function is not a constructor (evaluating 'new window[name](1)')". >+PASS new AudioBufferSourceNode(context, 42) threw TypeError: "function is not a constructor (evaluating 'new window[name](context, 42)')". >+PASS < [invalid constructor] All assertions passed. (total 3 assertions) >+PASS > [default constructor] >+FAIL X node0 = new AudioBufferSourceNode(context) incorrectly threw TypeError: "function is not a constructor (evaluating 'new window[name](context, options.constructorOptions)')". assert_true: expected true got false >+FAIL X node0 instanceof AudioBufferSourceNode is not equal to true. Got false. assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource.html >new file mode 100644 >index 0000000000000000000000000000000000000000..c1c3203451e62587b1aa864e85c63617c36c2a3d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource.html >@@ -0,0 +1,116 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Constructor: AudioBufferSource >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audionodeoptions.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let context; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('initialize', (task, should) => { >+ context = initializeContext(should); >+ task.done(); >+ }); >+ >+ audit.define('invalid constructor', (task, should) => { >+ testInvalidConstructor(should, 'AudioBufferSourceNode', context); >+ task.done(); >+ }); >+ >+ audit.define('default constructor', (task, should) => { >+ let prefix = 'node0'; >+ let node = >+ testDefaultConstructor(should, 'AudioBufferSourceNode', context, { >+ prefix: prefix, >+ numberOfInputs: 0, >+ numberOfOutputs: 1, >+ channelCount: 2, >+ channelCountMode: 'max', >+ channelInterpretation: 'speakers' >+ }); >+ >+ testDefaultAttributes(should, node, prefix, [ >+ {name: 'buffer', value: null}, >+ {name: 'detune', value: 0}, >+ {name: 'loop', value: false}, >+ {name: 'loopEnd', value: 0.0}, >+ {name: 'loopStart', value: 0.0}, >+ {name: 'playbackRate', value: 1.0}, >+ ]); >+ >+ task.done(); >+ }); >+ >+ audit.define('nullable buffer', (task, should) => { >+ let node; >+ let options = {buffer: null}; >+ >+ should( >+ () => { >+ node = new AudioBufferSourceNode(context, options); >+ }, >+ 'node1 = new AudioBufferSourceNode(c, ' + JSON.stringify(options)) >+ .notThrow(); >+ >+ should(node.buffer, 'node1.buffer').beEqualTo(null); >+ >+ task.done(); >+ }); >+ >+ audit.define('constructor options', (task, should) => { >+ let node; >+ let buffer = context.createBuffer(2, 1000, context.sampleRate); >+ >+ let options = { >+ buffer: buffer, >+ detune: .5, >+ loop: true, >+ loopEnd: (buffer.length / 2) / context.sampleRate, >+ loopStart: 5 / context.sampleRate, >+ playbackRate: .75 >+ }; >+ >+ let message = 'node = new AudioBufferSourceNode(c, ' + >+ JSON.stringify(options) + ')'; >+ >+ should(() => { >+ node = new AudioBufferSourceNode(context, options); >+ }, message).notThrow(); >+ >+ // Use the factory method to create an equivalent node and compare the >+ // results from the constructor against this node. >+ let factoryNode = context.createBufferSource(); >+ factoryNode.buffer = options.buffer; >+ factoryNode.detune.value = options.detune; >+ factoryNode.loop = options.loop; >+ factoryNode.loopEnd = options.loopEnd; >+ factoryNode.loopStart = options.loopStart; >+ factoryNode.playbackRate.value = options.playbackRate; >+ >+ should(node.buffer === buffer, 'node2.buffer === buffer') >+ .beEqualTo(true); >+ should(node.detune.value, 'node2.detune.value') >+ .beEqualTo(factoryNode.detune.value); >+ should(node.loop, 'node2.loop').beEqualTo(factoryNode.loop); >+ should(node.loopEnd, 'node2.loopEnd').beEqualTo(factoryNode.loopEnd); >+ should(node.loopStart, 'node2.loopStart') >+ .beEqualTo(factoryNode.loopStart); >+ should(node.playbackRate.value, 'node2.playbackRate.value') >+ .beEqualTo(factoryNode.playbackRate.value); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..9509b7223c9b5d60ed16ed26be6e185430a28e18 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/w3c-import.log >@@ -0,0 +1,17 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-getoutputtimestamp-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-getoutputtimestamp-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..c5e819cedc723664da0bd092ef78d1c15e894862 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-getoutputtimestamp-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 17: TypeError: context.getOutputTimestamp is not a function. (In 'context.getOutputTimestamp()', 'context.getOutputTimestamp' is undefined) >+ >+Harness Error (FAIL), message = TypeError: context.getOutputTimestamp is not a function. (In 'context.getOutputTimestamp()', 'context.getOutputTimestamp' is undefined) >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [getoutputtimestamp-initial-values] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-getoutputtimestamp.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-getoutputtimestamp.html >new file mode 100644 >index 0000000000000000000000000000000000000000..cd09696e6890a251d34f2e6be379061a01f6ba25 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-getoutputtimestamp.html >@@ -0,0 +1,32 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Testing AudioContext.getOutputTimestamp() method >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('getoutputtimestamp-initial-values', function(task, should) { >+ let context = new AudioContext; >+ let timestamp = context.getOutputTimestamp(); >+ >+ should(timestamp.contextTime, 'timestamp.contextTime').exist(); >+ should(timestamp.performanceTime, 'timestamp.performanceTime').exist(); >+ >+ should(timestamp.contextTime, 'timestamp.contextTime').beEqualTo(0); >+ should(timestamp.performanceTime, 'timestamp.performanceTime') >+ .beEqualTo(0); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-suspend-resume-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-suspend-resume-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..9bb826e08265679e18da70b54be8e12db6a37e43 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-suspend-resume-expected.txt >@@ -0,0 +1,21 @@ >+CONSOLE MESSAGE: line 106: Unhandled Promise Rejection: TypeError: undefined is not an object (evaluating 'p3.then') >+ >+Harness Error (FAIL), message = undefined is not an object (evaluating 'p3.then') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test-suspend] Test suspend() for offline context >+PASS offlineContext = new OfflineAudioContext(1, 44100, 44100) did not throw an exception. >+PASS offlineContext.state is equal to suspended. >+PASS p1 = offlineContext.suspend() did not throw an exception. >+PASS p1 instanceof Promise is true. >+PASS p1 rejected correctly with InvalidStateError: The object is in an invalid state.. >+PASS < [test-suspend] All assertions passed. (total 5 assertions) >+PASS > [test-resume] Test resume() for offline context >+PASS p2 = offlineContext.resume() did not throw an exception. >+PASS p2 instanceof Promise is true. >+PASS After resume, offlineContext.state is equal to suspended. >+PASS p2 rejected correctly with InvalidStateError: The object is in an invalid state.. >+PASS < [test-resume] All assertions passed. (total 4 assertions) >+PASS > [test-after-close] Test state after context closed >+PASS p3 = offlineContext.startRendering() did not throw an exception. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-suspend-resume.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-suspend-resume.html >new file mode 100644 >index 0000000000000000000000000000000000000000..48506d65ac9cf82e8e81841832193ac1f1f3cb56 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-suspend-resume.html >@@ -0,0 +1,145 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test AudioContext.suspend() and AudioContext.resume() >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let offlineContext; >+ let osc; >+ let p1; >+ let p2; >+ let p3; >+ >+ let sampleRate = 44100; >+ let durationInSeconds = 1; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ // Task: test suspend(). >+ audit.define( >+ { >+ label: 'test-suspend', >+ description: 'Test suspend() for offline context' >+ }, >+ function(task, should) { >+ // Test suspend/resume. Ideally this test is best with a online >+ // AudioContext, but content shell doesn't really have a working >+ // online AudioContext. Hence, use an OfflineAudioContext. Not all >+ // possible scenarios can be easily checked with an offline context >+ // instead of an online context. >+ >+ // Create an audio context with an oscillator. >+ should( >+ () => { >+ offlineContext = new OfflineAudioContext( >+ 1, durationInSeconds * sampleRate, sampleRate); >+ }, >+ 'offlineContext = new OfflineAudioContext(1, ' + >+ (durationInSeconds * sampleRate) + ', ' + sampleRate + ')') >+ .notThrow(); >+ osc = offlineContext.createOscillator(); >+ osc.connect(offlineContext.destination); >+ >+ // Verify the state. >+ should(offlineContext.state, 'offlineContext.state') >+ .beEqualTo('suspended'); >+ >+ // Multiple calls to suspend() should not be a problem. But we can't >+ // test that on an offline context. Thus, check that suspend() on >+ // an OfflineAudioContext rejects the promise. >+ should( >+ () => p1 = offlineContext.suspend(), >+ 'p1 = offlineContext.suspend()') >+ .notThrow(); >+ should(p1 instanceof Promise, 'p1 instanceof Promise').beTrue(); >+ >+ should(p1, 'p1').beRejected().then(task.done.bind(task)); >+ }); >+ >+ >+ // Task: test resume(). >+ audit.define( >+ { >+ label: 'test-resume', >+ description: 'Test resume() for offline context' >+ }, >+ function(task, should) { >+ // Multiple calls to resume should not be a problem. But we can't >+ // test that on an offline context. Thus, check that resume() on an >+ // OfflineAudioContext rejects the promise. >+ should( >+ () => p2 = offlineContext.resume(), >+ 'p2 = offlineContext.resume()') >+ .notThrow(); >+ should(p2 instanceof Promise, 'p2 instanceof Promise').beTrue(); >+ >+ // Resume doesn't actually resume an offline context >+ should(offlineContext.state, 'After resume, offlineContext.state') >+ .beEqualTo('suspended'); >+ should(p2, 'p2').beRejected().then(task.done.bind(task)); >+ }); >+ >+ // Task: test the state after context closed. >+ audit.define( >+ { >+ label: 'test-after-close', >+ description: 'Test state after context closed' >+ }, >+ function(task, should) { >+ // Render the offline context. >+ osc.start(); >+ >+ // Test suspend/resume in tested promise pattern. We don't care >+ // about the actual result of the offline rendering. >+ should( >+ () => p3 = offlineContext.startRendering(), >+ 'p3 = offlineContext.startRendering()') >+ .notThrow(); >+ >+ p3.then(() => { >+ should(offlineContext.state, 'After close, offlineContext.state') >+ .beEqualTo('closed'); >+ >+ // suspend() should be rejected on a closed context. >+ should(offlineContext.suspend(), 'offlineContext.suspend()') >+ .beRejected() >+ .then(() => { >+ // resume() should be rejected on closed context. >+ should(offlineContext.resume(), 'offlineContext.resume()') >+ .beRejected() >+ .then(task.done.bind(task)); >+ }) >+ }); >+ }); >+ >+ audit.define( >+ { >+ label: 'resume-running-context', >+ description: 'Test resuming a running context' >+ }, >+ (task, should) => { >+ let context; >+ should(() => context = new AudioContext(), 'Create online context') >+ .notThrow(); >+ >+ should(context.state, 'context.state').beEqualTo('running'); >+ should(context.resume(), 'context.resume') >+ .beResolved() >+ .then(() => { >+ should(context.state, 'context.state after resume') >+ .beEqualTo('running'); >+ }) >+ .then(() => task.done()); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..9f32c8a37264e831066a95883cdf2354ed126e47 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions-expected.txt >@@ -0,0 +1,27 @@ >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test-audiocontextoptions-latencyHint-basic] Test creating contexts with basic latencyHint types. >+PASS context = new AudioContext() did not throw an exception. >+PASS context.sampleRate (48000 Hz) is greater than 0. >+FAIL X default baseLatency is not greater than 0. Got undefined. assert_true: expected true got false >+PASS context = new AudioContext({'latencyHint': 'interactive'}) did not throw an exception. >+PASS interactive baseLatency is equal to undefined. >+PASS context = new AudioContext({'latencyHint': 'balanced'}) did not throw an exception. >+FAIL X balanced baseLatency is not greater than or equal to undefined. Got undefined. assert_true: expected true got false >+PASS context = new AudioContext({'latencyHint': 'playback'}) did not throw an exception. >+FAIL X playback baseLatency is not greater than or equal to undefined. Got undefined. assert_true: expected true got false >+FAIL < [test-audiocontextoptions-latencyHint-basic] 3 out of 9 assertions were failed. assert_true: expected true got false >+PASS > [test-audiocontextoptions-latencyHint-double] Test creating contexts with explicit latencyHint values. >+PASS context = new AudioContext({'latencyHint': interactiveLatency/2}) did not throw an exception. >+FAIL X double-constructor baseLatency small is not less than or equal to undefined. Got undefined. assert_true: expected true got false >+PASS context = new AudioContext({'latencyHint': validLatency}) did not throw an exception. >+FAIL X double-constructor baseLatency inrange 1 is not greater than or equal to undefined. Got undefined. assert_true: expected true got false >+FAIL X double-constructor baseLatency inrange 2 is not less than or equal to undefined. Got undefined. assert_true: expected true got false >+PASS creating two high latency contexts did not throw an exception. >+PASS high latency context baseLatency is equal to undefined. >+FAIL X high latency context baseLatency is not greater than undefined. Got undefined. assert_true: expected true got false >+FAIL X context = new AudioContext({'latencyHint': 'foo'}) did not throw an exception. assert_true: expected true got false >+FAIL X context = new AudioContext('latencyHint') did not throw an exception. assert_true: expected true got false >+FAIL < [test-audiocontextoptions-latencyHint-double] 6 out of 10 assertions were failed. assert_true: expected true got false >+FAIL # AUDIT TASK RUNNER FINISHED: 2 out of 2 tasks were failed. assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions.html >new file mode 100644 >index 0000000000000000000000000000000000000000..295cd5a5db1183a1ab7968adbc7922de9db158d1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions.html >@@ -0,0 +1,162 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test AudioContextOptions >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let context; >+ let defaultLatency; >+ let interactiveLatency; >+ let balancedLatency; >+ let playbackLatency; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define( >+ { >+ label: 'test-audiocontextoptions-latencyHint-basic', >+ description: 'Test creating contexts with basic latencyHint types.' >+ }, >+ function(task, should) { >+ let closingPromises = []; >+ >+ // Verify that an AudioContext can be created with default options. >+ should(function() { >+ context = new AudioContext() >+ }, 'context = new AudioContext()').notThrow(); >+ >+ should(context.sampleRate, >+ `context.sampleRate (${context.sampleRate} Hz)`).beGreaterThan(0); >+ >+ defaultLatency = context.baseLatency; >+ should(defaultLatency, 'default baseLatency').beGreaterThan(0); >+ >+ // Verify that an AudioContext can be created with the expected >+ // latency types. >+ should( >+ function() { >+ context = new AudioContext({'latencyHint': 'interactive'}) >+ }, >+ 'context = new AudioContext({\'latencyHint\': \'interactive\'})') >+ .notThrow(); >+ >+ interactiveLatency = context.baseLatency; >+ should(interactiveLatency, 'interactive baseLatency') >+ .beEqualTo(defaultLatency); >+ closingPromises.push(context.close()); >+ >+ should( >+ function() { >+ context = new AudioContext({'latencyHint': 'balanced'}) >+ }, >+ 'context = new AudioContext({\'latencyHint\': \'balanced\'})') >+ .notThrow(); >+ >+ balancedLatency = context.baseLatency; >+ should(balancedLatency, 'balanced baseLatency') >+ .beGreaterThanOrEqualTo(interactiveLatency); >+ closingPromises.push(context.close()); >+ >+ should( >+ function() { >+ context = new AudioContext({'latencyHint': 'playback'}) >+ }, >+ 'context = new AudioContext({\'latencyHint\': \'playback\'})') >+ .notThrow(); >+ >+ playbackLatency = context.baseLatency; >+ should(playbackLatency, 'playback baseLatency') >+ .beGreaterThanOrEqualTo(balancedLatency); >+ closingPromises.push(context.close()); >+ >+ Promise.all(closingPromises).then(function() { >+ task.done(); >+ }); >+ }); >+ >+ audit.define( >+ { >+ label: 'test-audiocontextoptions-latencyHint-double', >+ description: >+ 'Test creating contexts with explicit latencyHint values.' >+ }, >+ function(task, should) { >+ let closingPromises = []; >+ >+ // Verify too small exact latency clamped to 'interactive' >+ should( >+ function() { >+ context = >+ new AudioContext({'latencyHint': interactiveLatency / 2}) >+ }, >+ 'context = new AudioContext({\'latencyHint\': ' + >+ 'interactiveLatency/2})') >+ .notThrow(); >+ should(context.baseLatency, 'double-constructor baseLatency small') >+ .beLessThanOrEqualTo(interactiveLatency); >+ closingPromises.push(context.close()); >+ >+ // Verify that exact latency in range works as expected >+ let validLatency = (interactiveLatency + playbackLatency) / 2; >+ should( >+ function() { >+ context = new AudioContext({'latencyHint': validLatency}) >+ }, >+ 'context = new AudioContext({\'latencyHint\': validLatency})') >+ .notThrow(); >+ should( >+ context.baseLatency, 'double-constructor baseLatency inrange 1') >+ .beGreaterThanOrEqualTo(interactiveLatency); >+ should( >+ context.baseLatency, 'double-constructor baseLatency inrange 2') >+ .beLessThanOrEqualTo(playbackLatency); >+ closingPromises.push(context.close()); >+ >+ // Verify too big exact latency clamped to some value >+ let context1; >+ let context2; >+ should(function() { >+ context1 = >+ new AudioContext({'latencyHint': playbackLatency * 10}); >+ context2 = >+ new AudioContext({'latencyHint': playbackLatency * 20}); >+ }, 'creating two high latency contexts').notThrow(); >+ should(context1.baseLatency, 'high latency context baseLatency') >+ .beEqualTo(context2.baseLatency); >+ should(context1.baseLatency, 'high latency context baseLatency') >+ .beGreaterThan(interactiveLatency); >+ closingPromises.push(context1.close()); >+ closingPromises.push(context2.close()); >+ >+ // Verify that invalid latencyHint values are rejected. >+ should( >+ function() { >+ context = new AudioContext({'latencyHint': 'foo'}) >+ }, >+ 'context = new AudioContext({\'latencyHint\': \'foo\'})') >+ .throw('TypeError'); >+ >+ // Verify that no extra options can be passed into the >+ // AudioContextOptions. >+ should( >+ function() { >+ context = new AudioContext('latencyHint') >+ }, >+ 'context = new AudioContext(\'latencyHint\')') >+ .throw('TypeError'); >+ >+ Promise.all(closingPromises).then(function() { >+ task.done(); >+ }); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..20dafbdc483bc8e743c427b236c49282595ae781 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/w3c-import.log >@@ -0,0 +1,19 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-getoutputtimestamp.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-suspend-resume.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiodestinationnode-interface/idl-test-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiodestinationnode-interface/idl-test-expected.txt >index 54ddc222c4a88ed1d217a77b4ea8cf9275744ddf..85a431380276010052fa3eb9b11b54ecac938793 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiodestinationnode-interface/idl-test-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiodestinationnode-interface/idl-test-expected.txt >@@ -1,5 +1,5 @@ >-CONSOLE MESSAGE: line 331: callback not yet supported >-CONSOLE MESSAGE: line 331: callback not yet supported >+CONSOLE MESSAGE: line 440: callback not yet supported >+CONSOLE MESSAGE: line 440: callback not yet supported > interface AudioDestinationNode : AudioNode { > > readonly attribute unsigned long maxChannelCount; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-channel-rules-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-channel-rules-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..55cccda8a9bbd5cde55ad46e2ced6f9cec2e0b4f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-channel-rules-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 267: TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] Channel mixing rules for AudioNodes >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-channel-rules.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-channel-rules.html >new file mode 100644 >index 0000000000000000000000000000000000000000..a1c3273cc3fef597eff30e13c6074bd99ddb7acf >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-channel-rules.html >@@ -0,0 +1,277 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ audionode-channel-rules.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/mixing-rules.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ let context = 0; >+ let sampleRate = 44100; >+ let renderNumberOfChannels = 8; >+ let singleTestFrameLength = 8; >+ let testBuffers; >+ >+ // A list of connections to an AudioNode input, each of which is to be >+ // used in one or more specific test cases. Each element in the list is a >+ // string, with the number of connections corresponding to the length of >+ // the string, and each character in the string is from '1' to '8' >+ // representing a 1 to 8 channel connection (from an AudioNode output). >+ >+ // For example, the string "128" means 3 connections, having 1, 2, and 8 >+ // channels respectively. >+ >+ let connectionsList = [ >+ '1', '2', '3', '4', '5', '6', '7', '8', '11', '12', '14', '18', '111', >+ '122', '123', '124', '128' >+ ]; >+ >+ // A list of mixing rules, each of which will be tested against all of the >+ // connections in connectionsList. >+ let mixingRulesList = [ >+ { >+ channelCount: 2, >+ channelCountMode: 'max', >+ channelInterpretation: 'speakers' >+ }, >+ { >+ channelCount: 4, >+ channelCountMode: 'clamped-max', >+ channelInterpretation: 'speakers' >+ }, >+ >+ // Test up-down-mix to some explicit speaker layouts. >+ { >+ channelCount: 1, >+ channelCountMode: 'explicit', >+ channelInterpretation: 'speakers' >+ }, >+ { >+ channelCount: 2, >+ channelCountMode: 'explicit', >+ channelInterpretation: 'speakers' >+ }, >+ { >+ channelCount: 4, >+ channelCountMode: 'explicit', >+ channelInterpretation: 'speakers' >+ }, >+ { >+ channelCount: 6, >+ channelCountMode: 'explicit', >+ channelInterpretation: 'speakers' >+ }, >+ >+ { >+ channelCount: 2, >+ channelCountMode: 'max', >+ channelInterpretation: 'discrete' >+ }, >+ { >+ channelCount: 4, >+ channelCountMode: 'clamped-max', >+ channelInterpretation: 'discrete' >+ }, >+ { >+ channelCount: 4, >+ channelCountMode: 'explicit', >+ channelInterpretation: 'discrete' >+ }, >+ { >+ channelCount: 8, >+ channelCountMode: 'explicit', >+ channelInterpretation: 'discrete' >+ }, >+ ]; >+ >+ let numberOfTests = mixingRulesList.length * connectionsList.length; >+ >+ // Print out the information for an individual test case. >+ function printTestInformation( >+ testNumber, actualBuffer, expectedBuffer, frameLength, frameOffset) { >+ let actual = stringifyBuffer(actualBuffer, frameLength); >+ let expected = >+ stringifyBuffer(expectedBuffer, frameLength, frameOffset); >+ debug('TEST CASE #' + testNumber + '\n'); >+ debug('actual channels:\n' + actual); >+ debug('expected channels:\n' + expected); >+ } >+ >+ function scheduleTest( >+ testNumber, connections, channelCount, channelCountMode, >+ channelInterpretation) { >+ let mixNode = context.createGain(); >+ mixNode.channelCount = channelCount; >+ mixNode.channelCountMode = channelCountMode; >+ mixNode.channelInterpretation = channelInterpretation; >+ mixNode.connect(context.destination); >+ >+ for (let i = 0; i < connections.length; ++i) { >+ let connectionNumberOfChannels = >+ connections.charCodeAt(i) - '0'.charCodeAt(0); >+ >+ let source = context.createBufferSource(); >+ // Get a buffer with the right number of channels, converting from >+ // 1-based to 0-based index. >+ let buffer = testBuffers[connectionNumberOfChannels - 1]; >+ source.buffer = buffer; >+ source.connect(mixNode); >+ >+ // Start at the right offset. >+ let sampleFrameOffset = testNumber * singleTestFrameLength; >+ let time = sampleFrameOffset / sampleRate; >+ source.start(time); >+ } >+ } >+ >+ function checkTestResult( >+ renderedBuffer, testNumber, connections, channelCount, >+ channelCountMode, channelInterpretation, should) { >+ let s = 'connections: ' + connections + ', ' + channelCountMode; >+ >+ // channelCount is ignored in "max" mode. >+ if (channelCountMode == 'clamped-max' || >+ channelCountMode == 'explicit') { >+ s += '(' + channelCount + ')'; >+ } >+ >+ s += ', ' + channelInterpretation; >+ >+ let computedNumberOfChannels = computeNumberOfChannels( >+ connections, channelCount, channelCountMode); >+ >+ // Create a zero-initialized silent AudioBuffer with >+ // computedNumberOfChannels. >+ let destBuffer = context.createBuffer( >+ computedNumberOfChannels, singleTestFrameLength, >+ context.sampleRate); >+ >+ // Mix all of the connections into the destination buffer. >+ for (let i = 0; i < connections.length; ++i) { >+ let connectionNumberOfChannels = >+ connections.charCodeAt(i) - '0'.charCodeAt(0); >+ let sourceBuffer = >+ testBuffers[connectionNumberOfChannels - 1]; // convert from >+ // 1-based to >+ // 0-based index >+ >+ if (channelInterpretation == 'speakers') { >+ speakersSum(sourceBuffer, destBuffer); >+ } else if (channelInterpretation == 'discrete') { >+ discreteSum(sourceBuffer, destBuffer); >+ } else { >+ alert('Invalid channel interpretation!'); >+ } >+ } >+ >+ // Use this when debugging mixing rules. >+ // printTestInformation(testNumber, renderedBuffer, destBuffer, >+ // singleTestFrameLength, sampleFrameOffset); >+ >+ // Validate that destBuffer matches the rendered output. We need to >+ // check the rendered output at a specific sample-frame-offset >+ // corresponding to the specific test case we're checking for based on >+ // testNumber. >+ >+ let sampleFrameOffset = testNumber * singleTestFrameLength; >+ for (let c = 0; c < renderNumberOfChannels; ++c) { >+ let renderedData = renderedBuffer.getChannelData(c); >+ for (let frame = 0; frame < singleTestFrameLength; ++frame) { >+ let renderedValue = renderedData[frame + sampleFrameOffset]; >+ >+ let expectedValue = 0; >+ if (c < destBuffer.numberOfChannels) { >+ let expectedData = destBuffer.getChannelData(c); >+ expectedValue = expectedData[frame]; >+ } >+ >+ // We may need to add an epsilon in the comparison if we add more >+ // test vectors. >+ if (renderedValue != expectedValue) { >+ let message = s + 'rendered: ' + renderedValue + >+ ' expected: ' + expectedValue + ' channel: ' + c + >+ ' frame: ' + frame; >+ // testFailed(s); >+ should(renderedValue, s).beEqualTo(expectedValue); >+ return; >+ } >+ } >+ } >+ >+ should(true, s).beTrue(); >+ } >+ >+ function checkResult(buffer, should) { >+ // Sanity check result. >+ should(buffer.length, 'Rendered number of frames') >+ .beEqualTo(numberOfTests * singleTestFrameLength); >+ should(buffer.numberOfChannels, 'Rendered number of channels') >+ .beEqualTo(renderNumberOfChannels); >+ >+ // Check all the tests. >+ let testNumber = 0; >+ for (let m = 0; m < mixingRulesList.length; ++m) { >+ let mixingRules = mixingRulesList[m]; >+ for (let i = 0; i < connectionsList.length; ++i, ++testNumber) { >+ checkTestResult( >+ buffer, testNumber, connectionsList[i], >+ mixingRules.channelCount, mixingRules.channelCountMode, >+ mixingRules.channelInterpretation, should); >+ } >+ } >+ } >+ >+ audit.define( >+ {label: 'test', description: 'Channel mixing rules for AudioNodes'}, >+ function(task, should) { >+ >+ // Create 8-channel offline audio context. Each test will render 8 >+ // sample-frames starting at sample-frame position testNumber * 8. >+ let totalFrameLength = numberOfTests * singleTestFrameLength; >+ context = new OfflineAudioContext( >+ renderNumberOfChannels, totalFrameLength, sampleRate); >+ >+ // Set destination to discrete mixing. >+ context.destination.channelCount = renderNumberOfChannels; >+ context.destination.channelCountMode = 'explicit'; >+ context.destination.channelInterpretation = 'discrete'; >+ >+ // Create test buffers from 1 to 8 channels. >+ testBuffers = new Array(); >+ for (let i = 0; i < renderNumberOfChannels; ++i) { >+ testBuffers[i] = createShiftedImpulseBuffer( >+ context, i + 1, singleTestFrameLength); >+ } >+ >+ // Schedule all the tests. >+ let testNumber = 0; >+ for (let m = 0; m < mixingRulesList.length; ++m) { >+ let mixingRules = mixingRulesList[m]; >+ for (let i = 0; i < connectionsList.length; ++i, ++testNumber) { >+ scheduleTest( >+ testNumber, connectionsList[i], mixingRules.channelCount, >+ mixingRules.channelCountMode, >+ mixingRules.channelInterpretation); >+ } >+ } >+ >+ // Render then check results. >+ // context.oncomplete = checkResult; >+ context.startRendering().then(buffer => { >+ checkResult(buffer, should); >+ task.done(); >+ }); >+ ; >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..4bdb7c754dd7ae2d3f7365e1fca3f7784edc5e78 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 30: TypeError: undefined is not an object (evaluating 'config.returned.constructor') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'config.returned.constructor') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [from-dictionary] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining.html >new file mode 100644 >index 0000000000000000000000000000000000000000..0a8c73160e543d6f9d382b536e5c41f7d29c6e9a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining.html >@@ -0,0 +1,164 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ audionode-connect-method-chaining.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ // AudioNode dictionary with associated arguments. >+ let nodeDictionary = [ >+ {name: 'Analyser'}, {name: 'BiquadFilter'}, {name: 'BufferSource'}, >+ {name: 'ChannelMerger', args: [6]}, >+ {name: 'ChannelSplitter', args: [6]}, {name: 'Convolver'}, >+ {name: 'Delay', args: []}, {name: 'DynamicsCompressor'}, {name: 'Gain'}, >+ {name: 'Oscillator'}, {name: 'Panner'}, >+ {name: 'ScriptProcessor', args: [512, 1, 1]}, {name: 'StereoPanner'}, >+ {name: 'WaveShaper'} >+ ]; >+ >+ >+ function verifyReturnedNode(should, config) { >+ should( >+ config.destination === config.returned, >+ 'The return value of ' + config.desc + ' matches the destination ' + >+ config.returned.constructor.name) >+ .beEqualTo(true); >+ } >+ >+ // Test utility for batch method checking: in order to test 3 method >+ // signatures, so we create 3 dummy destinations. >+ // 1) .connect(GainNode) >+ // 2) .connect(BiquadFilterNode, output) >+ // 3) .connect(ChannelMergerNode, output, input) >+ function testConnectMethod(context, should, options) { >+ let source = >+ context['create' + options.name].apply(context, options.args); >+ let sourceName = source.constructor.name; >+ >+ let destination1 = context.createGain(); >+ verifyReturnedNode(should, { >+ source: source, >+ destination: destination1, >+ returned: source.connect(destination1), >+ desc: sourceName + '.connect(' + destination1.constructor.name + ')' >+ }); >+ >+ let destination2 = context.createBiquadFilter(); >+ verifyReturnedNode(should, { >+ source: source, >+ destination: destination2, >+ returned: source.connect(destination2, 0), >+ desc: >+ sourceName + '.connect(' + destination2.constructor.name + ', 0)' >+ }); >+ >+ let destination3 = context.createChannelMerger(); >+ verifyReturnedNode(should, { >+ source: source, >+ destination: destination3, >+ returned: source.connect(destination3, 0, 1), >+ desc: sourceName + '.connect(' + destination3.constructor.name + >+ ', 0, 1)' >+ }); >+ } >+ >+ >+ let audit = Audit.createTaskRunner(); >+ >+ // Task: testing entries from the dictionary. >+ audit.define('from-dictionary', (task, should) => { >+ let context = new AudioContext(); >+ >+ for (let i = 0; i < nodeDictionary.length; i++) >+ testConnectMethod(context, should, nodeDictionary[i]); >+ >+ task.done(); >+ }); >+ >+ // Task: testing Media* nodes. >+ audit.define('media-group', (task, should) => { >+ let context = new AudioContext(); >+ >+ // Test MediaElementSourceNode needs an <audio> element. >+ let mediaElement = document.createElement('audio'); >+ testConnectMethod( >+ context, should, >+ {name: 'MediaElementSource', args: [mediaElement]}); >+ >+ testConnectMethod(context, should, {name: 'MediaStreamDestination'}); >+ >+ // MediaStreamSourceNode requires 'stream' object to be constructed, >+ // which is a part of MediaStreamDestinationNode. >+ let streamDestination = context.createMediaStreamDestination(); >+ let stream = streamDestination.stream; >+ testConnectMethod( >+ context, should, {name: 'MediaStreamSource', args: [stream]}); >+ >+ task.done(); >+ }); >+ >+ // Task: test the exception thrown by invalid operation. >+ audit.define('invalid-operation', (task, should) => { >+ let contextA = new AudioContext(); >+ let contextB = new AudioContext(); >+ let gain1 = contextA.createGain(); >+ let gain2 = contextA.createGain(); >+ >+ // Test if the first connection throws correctly. The first gain node >+ // does not have the second output, so it should throw. >+ should(function() { >+ gain1.connect(gain2, 1).connect(contextA.destination); >+ }, 'Connecting with an invalid output').throw('IndexSizeError'); >+ >+ // Test if the second connection throws correctly. The contextB's >+ // destination is not compatible with the nodes from contextA, thus the >+ // first connection succeeds but the second one should throw. >+ should( >+ function() { >+ gain1.connect(gain2).connect(contextB.destination); >+ }, >+ 'Connecting to a node from the different context') >+ .throw('InvalidAccessError'); >+ >+ task.done(); >+ }); >+ >+ // Task: verify if the method chaining actually works. >+ audit.define('verification', (task, should) => { >+ // We pick the lowest sample rate allowed to run the test efficiently. >+ let context = new OfflineAudioContext(1, 128, 3000); >+ >+ let constantBuffer = createConstantBuffer(context, 1, 1.0); >+ >+ let source = context.createBufferSource(); >+ source.buffer = constantBuffer; >+ source.loop = true; >+ >+ let gain1 = context.createGain(); >+ gain1.gain.value = 0.5; >+ let gain2 = context.createGain(); >+ gain2.gain.value = 0.25; >+ >+ source.connect(gain1).connect(gain2).connect(context.destination); >+ source.start(); >+ >+ context.startRendering() >+ .then(function(buffer) { >+ should( >+ buffer.getChannelData(0), >+ 'The output of chained connection of gain nodes') >+ .beConstantValueOf(0.125); >+ }) >+ .then(() => task.done()); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-order-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-order-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..737345fc7a03c9fce2378fbc50092cadec5dea54 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-order-expected.txt >@@ -0,0 +1,8 @@ >+CONSOLE MESSAGE: line 361: TypeError: undefined is not an object (evaluating 'this._actual.then') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'this._actual.then') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [Test connections] AudioNode connection order doesn't trigger assertion errors >+PASS Connecting nodes did not throw an exception. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-order.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-order.html >new file mode 100644 >index 0000000000000000000000000000000000000000..eca15dedfa0fdcd7b575fb45ad0804c3fc636ada >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-order.html >@@ -0,0 +1,77 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ audionode-connect-order.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ let sampleRate = 44100.0; >+ let renderLengthSeconds = 0.125; >+ let delayTimeSeconds = 0.1; >+ >+ function createSinWaveBuffer(context, lengthInSeconds, frequency) { >+ let audioBuffer = >+ context.createBuffer(1, lengthInSeconds * sampleRate, sampleRate); >+ >+ let n = audioBuffer.length; >+ let data = audioBuffer.getChannelData(0); >+ >+ for (let i = 0; i < n; ++i) { >+ data[i] = Math.sin(frequency * 2 * Math.PI * i / sampleRate); >+ } >+ >+ return audioBuffer; >+ } >+ >+ audit.define( >+ { >+ label: 'Test connections', >+ description: >+ 'AudioNode connection order doesn\'t trigger assertion errors' >+ }, >+ function(task, should) { >+ // Create offline audio context. >+ let context = new OfflineAudioContext( >+ 1, sampleRate * renderLengthSeconds, sampleRate); >+ let toneBuffer = >+ createSinWaveBuffer(context, renderLengthSeconds, 880); >+ >+ let bufferSource = context.createBufferSource(); >+ bufferSource.buffer = toneBuffer; >+ bufferSource.connect(context.destination); >+ >+ let delay = context.createDelay(); >+ delay.delayTime.value = delayTimeSeconds; >+ >+ // We connect delay node to gain node before anything is connected >+ // to delay node itself. We do this because we try to trigger the >+ // ASSERT which might be fired due to AudioNode connection order, >+ // especially when gain node and delay node is involved e.g. >+ // https://bugs.webkit.org/show_bug.cgi?id=76685. >+ >+ should(() => { >+ let gain = context.createGain(); >+ gain.connect(context.destination); >+ delay.connect(gain); >+ }, 'Connecting nodes').notThrow(); >+ >+ bufferSource.start(0); >+ >+ let promise = context.startRendering(); >+ >+ should(promise, 'OfflineContext startRendering()') >+ .beResolved() >+ .then(task.done.bind(task)); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..3eb265b2cf78773ed88b44ce2597bc69a706dfd1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam-expected.txt >@@ -0,0 +1,9 @@ >+CONSOLE MESSAGE: line 82: TypeError: undefined is not an object (evaluating 'context.startRendering() >+ .then') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'context.startRendering() >+ .then') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [disconnect(AudioParam)] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html >new file mode 100644 >index 0000000000000000000000000000000000000000..c3d3fae2155602bbae7494e0e1439ea1a477b054 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html >@@ -0,0 +1,214 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ audionode-disconnect-audioparam.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let renderQuantum = 128; >+ >+ let sampleRate = 44100; >+ let renderDuration = 0.5; >+ let disconnectTime = 0.5 * renderDuration; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ // Calculate the index for disconnection. >+ function getDisconnectIndex(disconnectTime) { >+ let disconnectIndex = disconnectTime * sampleRate; >+ return disconnectIndex -= (disconnectIndex) % renderQuantum; >+ } >+ >+ // Get the index of value change. >+ function getValueChangeIndex(array, targetValue) { >+ return array.findIndex(function(element, index) { >+ if (element === targetValue) >+ return true; >+ }); >+ } >+ >+ // Task 1: test disconnect(AudioParam) method. >+ audit.define('disconnect(AudioParam)', (task, should) => { >+ >+ // Creates a buffer source with value [1] and then connect it to two >+ // gain nodes in series. The output of the buffer source is lowered by >+ // half >+ // (* 0.5) and then connected to two |.gain| AudioParams in each gain >+ // node. >+ // >+ // (1) bufferSource => gain1 => gain2 >+ // (2) bufferSource => half => gain1.gain >+ // (3) half => gain2.gain >+ // >+ // This graph should produce the output of 2.25 (= 1 * 1.5 * 1.5). After >+ // disconnecting (3), it should produce 1.5. >+ let context = >+ new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate); >+ let source = context.createBufferSource(); >+ let buffer1ch = createConstantBuffer(context, 1, 1); >+ let half = context.createGain(); >+ let gain1 = context.createGain(); >+ let gain2 = context.createGain(); >+ >+ source.buffer = buffer1ch; >+ source.loop = true; >+ half.gain.value = 0.5; >+ >+ source.connect(gain1); >+ gain1.connect(gain2); >+ gain2.connect(context.destination); >+ source.connect(half); >+ >+ // Connecting |half| to both |gain1.gain| and |gain2.gain| amplifies the >+ // signal by 2.25 (= 1.5 * 1.5) because each gain node amplifies the >+ // signal by 1.5 (= 1.0 + 0.5). >+ half.connect(gain1.gain); >+ half.connect(gain2.gain); >+ >+ source.start(); >+ >+ // Schedule the disconnection at the half of render duration. >+ context.suspend(disconnectTime).then(function() { >+ half.disconnect(gain2.gain); >+ context.resume(); >+ }); >+ >+ context.startRendering() >+ .then(function(buffer) { >+ let channelData = buffer.getChannelData(0); >+ let disconnectIndex = getDisconnectIndex(disconnectTime); >+ let valueChangeIndex = getValueChangeIndex(channelData, 1.5); >+ >+ // Expected values are: 1 * 1.5 * 1.5 -> 1 * 1.5 = [2.25, 1.5] >+ should(channelData, 'Channel #0').containValues([2.25, 1.5]); >+ should(valueChangeIndex, 'The index of value change') >+ .beEqualTo(disconnectIndex); >+ >+ }) >+ .then(() => task.done()); >+ }); >+ >+ // Task 2: test disconnect(AudioParam, output) method. >+ audit.define('disconnect(AudioParam, output)', (task, should) => { >+ >+ // Create a 2-channel buffer source with [1, 2] in each channel and >+ // make a serial connection through gain1 and gain 2. The make the >+ // buffer source half with a gain node and connect it to a 2-output >+ // splitter. Connect each output to 2 gain AudioParams respectively. >+ // >+ // (1) bufferSource => gain1 => gain2 >+ // (2) bufferSource => half => splitter(2) >+ // (3) splitter#0 => gain1.gain >+ // (4) splitter#1 => gain2.gain >+ // >+ // This graph should produce 3 (= 1 * 1.5 * 2) and 6 (= 2 * 1.5 * 2) for >+ // each channel. After disconnecting (4), it should output 1.5 and 3. >+ let context = >+ new OfflineAudioContext(2, renderDuration * sampleRate, sampleRate); >+ let source = context.createBufferSource(); >+ let buffer2ch = createConstantBuffer(context, 1, [1, 2]); >+ let splitter = context.createChannelSplitter(2); >+ let half = context.createGain(); >+ let gain1 = context.createGain(); >+ let gain2 = context.createGain(); >+ >+ source.buffer = buffer2ch; >+ source.loop = true; >+ half.gain.value = 0.5; >+ >+ source.connect(gain1); >+ gain1.connect(gain2); >+ gain2.connect(context.destination); >+ >+ // |source| originally is [1, 2] but it becomes [0.5, 1] after 0.5 gain. >+ // Each splitter's output will be applied to |gain1.gain| and >+ // |gain2.gain| respectively in an additive fashion. >+ source.connect(half); >+ half.connect(splitter); >+ >+ // This amplifies the signal by 1.5. (= 1.0 + 0.5) >+ splitter.connect(gain1.gain, 0); >+ >+ // This amplifies the signal by 2. (= 1.0 + 1.0) >+ splitter.connect(gain2.gain, 1); >+ >+ source.start(); >+ >+ // Schedule the disconnection at the half of render duration. >+ context.suspend(disconnectTime).then(function() { >+ splitter.disconnect(gain2.gain, 1); >+ context.resume(); >+ }); >+ >+ context.startRendering() >+ .then(function(buffer) { >+ let channelData0 = buffer.getChannelData(0); >+ let channelData1 = buffer.getChannelData(1); >+ >+ let disconnectIndex = getDisconnectIndex(disconnectTime); >+ let valueChangeIndexCh0 = getValueChangeIndex(channelData0, 1.5); >+ let valueChangeIndexCh1 = getValueChangeIndex(channelData1, 3); >+ >+ // Expected values are: 1 * 1.5 * 2 -> 1 * 1.5 = [3, 1.5] >+ should(channelData0, 'Channel #0').containValues([3, 1.5]); >+ should( >+ valueChangeIndexCh0, >+ 'The index of value change in channel #0') >+ .beEqualTo(disconnectIndex); >+ >+ // Expected values are: 2 * 1.5 * 2 -> 2 * 1.5 = [6, 3] >+ should(channelData1, 'Channel #1').containValues([6, 3]); >+ should( >+ valueChangeIndexCh1, >+ 'The index of value change in channel #1') >+ .beEqualTo(disconnectIndex); >+ >+ }) >+ .then(() => task.done()); >+ }); >+ >+ // Task 3: exception checks. >+ audit.define('exceptions', (task, should) => { >+ let context = new AudioContext(); >+ let gain1 = context.createGain(); >+ let splitter = context.createChannelSplitter(2); >+ let gain2 = context.createGain(); >+ let gain3 = context.createGain(); >+ >+ // Connect a splitter to gain nodes and merger so we can test the >+ // possible ways of disconnecting the nodes to verify that appropriate >+ // exceptions are thrown. >+ gain1.connect(splitter); >+ splitter.connect(gain2.gain, 0); >+ splitter.connect(gain3.gain, 1); >+ gain2.connect(gain3); >+ gain3.connect(context.destination); >+ >+ // gain1 is not connected to gain3.gain. Exception should be thrown. >+ should(function() { >+ gain1.disconnect(gain3.gain); >+ }, 'gain1.disconnect(gain3.gain)').throw('InvalidAccessError'); >+ >+ // When the output index is good but the destination is invalid. >+ should(function() { >+ splitter.disconnect(gain1.gain, 1); >+ }, 'splitter.disconnect(gain1.gain, 1)').throw('InvalidAccessError'); >+ >+ // When both arguments are wrong, throw IndexSizeError first. >+ should(function() { >+ splitter.disconnect(gain1.gain, 2); >+ }, 'splitter.disconnect(gain1.gain, 2)').throw('IndexSizeError'); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..07a1484117fd699cd650c5bba7481191e08eec20 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-expected.txt >@@ -0,0 +1,9 @@ >+CONSOLE MESSAGE: line 42: TypeError: undefined is not an object (evaluating 'context.startRendering() >+ .then') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'context.startRendering() >+ .then') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [disconnect()] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect.html >new file mode 100644 >index 0000000000000000000000000000000000000000..b29c09d395fc2815ee5441fdb06320ad02f2f3f5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect.html >@@ -0,0 +1,298 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ audionode-disconnect.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ // Task 1: test disconnect() method. >+ audit.define('disconnect()', (task, should) => { >+ >+ // Connect a source to multiple gain nodes, each connected to the >+ // destination. Then disconnect the source. The expected output should >+ // be all zeros since the source was disconnected. >+ let context = new OfflineAudioContext(1, 128, 44100); >+ let source = context.createBufferSource(); >+ let buffer1ch = createConstantBuffer(context, 128, [1]); >+ let gain1 = context.createGain(); >+ let gain2 = context.createGain(); >+ let gain3 = context.createGain(); >+ >+ source.buffer = buffer1ch; >+ >+ source.connect(gain1); >+ source.connect(gain2); >+ source.connect(gain3); >+ gain1.connect(context.destination); >+ gain2.connect(context.destination); >+ gain3.connect(context.destination); >+ source.start(); >+ >+ // This disconnects everything. >+ source.disconnect(); >+ >+ context.startRendering() >+ .then(function(buffer) { >+ >+ // With everything disconnected, the result should be zero. >+ should(buffer.getChannelData(0), 'Channel #0') >+ .beConstantValueOf(0); >+ >+ }) >+ .then(() => task.done()); >+ }); >+ >+ // Task 2: test disconnect(output) method. >+ audit.define('disconnect(output)', (task, should) => { >+ >+ // Create multiple connections from each output of a ChannelSplitter >+ // to a gain node. Then test if disconnecting a single output of >+ // splitter is actually disconnected. >+ let context = new OfflineAudioContext(1, 128, 44100); >+ let source = context.createBufferSource(); >+ let buffer3ch = createConstantBuffer(context, 128, [1, 2, 3]); >+ let splitter = context.createChannelSplitter(3); >+ let sum = context.createGain(); >+ >+ source.buffer = buffer3ch; >+ >+ source.connect(splitter); >+ splitter.connect(sum, 0); >+ splitter.connect(sum, 1); >+ splitter.connect(sum, 2); >+ sum.connect(context.destination); >+ source.start(); >+ >+ // This disconnects the second output. >+ splitter.disconnect(1); >+ >+ context.startRendering() >+ .then(function(buffer) { >+ >+ // The rendered channel should contain 4. (= 1 + 0 + 3) >+ should(buffer.getChannelData(0), 'Channel #0') >+ .beConstantValueOf(4); >+ >+ }) >+ .then(() => task.done()); >+ }); >+ >+ // Task 3: test disconnect(AudioNode) method. >+ audit.define('disconnect(AudioNode)', (task, should) => { >+ >+ // Connect a source to multiple gain nodes. Then test if disconnecting a >+ // single destination selectively works correctly. >+ let context = new OfflineAudioContext(1, 128, 44100); >+ let source = context.createBufferSource(); >+ let buffer1ch = createConstantBuffer(context, 128, [1]); >+ let gain1 = context.createGain(); >+ let gain2 = context.createGain(); >+ let gain3 = context.createGain(); >+ let orphan = context.createGain(); >+ >+ source.buffer = buffer1ch; >+ >+ source.connect(gain1); >+ source.connect(gain2); >+ source.connect(gain3); >+ gain1.connect(context.destination); >+ gain2.connect(context.destination); >+ gain3.connect(context.destination); >+ source.start(); >+ >+ source.disconnect(gain2); >+ >+ context.startRendering() >+ .then(function(buffer) { >+ >+ // The |sum| gain node should produce value 2. (1 + 0 + 1 = 2) >+ should(buffer.getChannelData(0), 'Channel #0') >+ .beConstantValueOf(2); >+ >+ }) >+ .then(() => task.done()); >+ }); >+ >+ // Task 4: test disconnect(AudioNode, output) method. >+ audit.define('disconnect(AudioNode, output)', (task, should) => { >+ >+ // Connect a buffer with 2 channels with each containing 1 and 2 >+ // respectively to a ChannelSplitter, then connect the splitter to 2 >+ // gain nodes as shown below: >+ // (1) splitter#0 => gain1 >+ // (2) splitter#0 => gain2 >+ // (3) splitter#1 => gain2 >+ // Then disconnect (2) and verify if the selective disconnection on a >+ // specified output of the destination node works correctly. >+ let context = new OfflineAudioContext(1, 128, 44100); >+ let source = context.createBufferSource(); >+ let buffer2ch = createConstantBuffer(context, 128, [1, 2]); >+ let splitter = context.createChannelSplitter(2); >+ let gain1 = context.createGain(); >+ let gain2 = context.createGain(); >+ >+ source.buffer = buffer2ch; >+ >+ source.connect(splitter); >+ splitter.connect(gain1, 0); // gain1 gets channel 0. >+ splitter.connect(gain2, 0); // gain2 sums channel 0 and 1. >+ splitter.connect(gain2, 1); >+ gain1.connect(context.destination); >+ gain2.connect(context.destination); >+ source.start(); >+ >+ splitter.disconnect(gain2, 0); // Now gain2 gets [2] >+ >+ context.startRendering() >+ .then(function(buffer) { >+ >+ // The sum of gain1 and gain2 should produce value 3. (= 1 + 2) >+ should(buffer.getChannelData(0), 'Channel #0') >+ .beConstantValueOf(3); >+ >+ }) >+ .then(() => task.done()); >+ }); >+ >+ // Task 5: test disconnect(AudioNode, output, input) method. >+ audit.define('disconnect(AudioNode, output, input)', (task, should) => { >+ >+ // Create a 3-channel buffer with [1, 2, 3] in each channel and then >+ // pass it through a splitter and a merger. Each input/output of the >+ // splitter and the merger is connected in a sequential order as shown >+ // below. >+ // (1) splitter#0 => merger#0 >+ // (2) splitter#1 => merger#1 >+ // (3) splitter#2 => merger#2 >+ // Then disconnect (3) and verify if each channel contains [1] and [2] >+ // respectively. >+ let context = new OfflineAudioContext(3, 128, 44100); >+ let source = context.createBufferSource(); >+ let buffer3ch = createConstantBuffer(context, 128, [1, 2, 3]); >+ let splitter = context.createChannelSplitter(3); >+ let merger = context.createChannelMerger(3); >+ >+ source.buffer = buffer3ch; >+ >+ source.connect(splitter); >+ splitter.connect(merger, 0, 0); >+ splitter.connect(merger, 1, 1); >+ splitter.connect(merger, 2, 2); >+ merger.connect(context.destination); >+ source.start(); >+ >+ splitter.disconnect(merger, 2, 2); >+ >+ context.startRendering() >+ .then(function(buffer) { >+ >+ // Each channel should have 1, 2, and 0 respectively. >+ should(buffer.getChannelData(0), 'Channel #0') >+ .beConstantValueOf(1); >+ should(buffer.getChannelData(1), 'Channel #1') >+ .beConstantValueOf(2); >+ should(buffer.getChannelData(2), 'Channel #2') >+ .beConstantValueOf(0); >+ >+ }) >+ .then(() => task.done()); >+ }); >+ >+ // Task 6: exception checks. >+ audit.define('exceptions', (task, should) => { >+ let context = new OfflineAudioContext(2, 128, 44100); >+ let gain1 = context.createGain(); >+ let splitter = context.createChannelSplitter(2); >+ let merger = context.createChannelMerger(2); >+ let gain2 = context.createGain(); >+ let gain3 = context.createGain(); >+ >+ // Connect a splitter to gain nodes and merger so we can test the >+ // possible ways of disconnecting the nodes to verify that appropriate >+ // exceptions are thrown. >+ gain1.connect(splitter); >+ splitter.connect(gain2, 0); >+ splitter.connect(gain3, 1); >+ splitter.connect(merger, 0, 0); >+ splitter.connect(merger, 1, 1); >+ gain2.connect(gain3); >+ gain3.connect(context.destination); >+ merger.connect(context.destination); >+ >+ // There is no output #2. An exception should be thrown. >+ should(function() { >+ splitter.disconnect(2); >+ }, 'splitter.disconnect(2)').throw('IndexSizeError'); >+ >+ // Disconnecting the output already disconnected should not throw. >+ should(function() { >+ splitter.disconnect(1); >+ splitter.disconnect(1); >+ }, 'Disconnecting a connection twice').notThrow(); >+ >+ // gain1 is not connected gain2. An exception should be thrown. >+ should(function() { >+ gain1.disconnect(gain2); >+ }, 'gain1.disconnect(gain2)').throw('InvalidAccessError'); >+ >+ // gain1 and gain3 are not connected. An exception should be thrown. >+ should(function() { >+ gain1.disconnect(gain3); >+ }, 'gain1.disconnect(gain3)').throw('InvalidAccessError'); >+ >+ // There is no output #2 in the splitter. An exception should be thrown. >+ should(function() { >+ splitter.disconnect(gain2, 2); >+ }, 'splitter.disconnect(gain2, 2)').throw('IndexSizeError'); >+ >+ // The splitter and gain1 are not connected. An exception should be >+ // thrown. >+ should(function() { >+ splitter.disconnect(gain1, 0); >+ }, 'splitter.disconnect(gain1, 0)').throw('InvalidAccessError'); >+ >+ // The splitter output #0 and the gain3 output #0 are not connected. An >+ // exception should be thrown. >+ should(function() { >+ splitter.disconnect(gain3, 0, 0); >+ }, 'splitter.disconnect(gain3, 0, 0)').throw('InvalidAccessError'); >+ >+ // The output index is out of bound. An exception should be thrown. >+ should(function() { >+ splitter.disconnect(merger, 3, 0); >+ }, 'splitter.disconnect(merger, 3, 0)').throw('IndexSizeError'); >+ >+ task.done(); >+ }); >+ >+ audit.define('disabled-outputs', (task, should) => { >+ // See crbug.com/656652 >+ let context = new OfflineAudioContext(2, 1024, 44100); >+ let g1 = context.createGain(); >+ let g2 = context.createGain(); >+ g1.connect(g2); >+ g1.disconnect(g2); >+ let g3 = context.createGain(); >+ g2.connect(g3); >+ g1.connect(g2); >+ context.startRendering() >+ .then(function() { >+ // If we make it here, we passed. >+ should(true, 'Disabled outputs handled') >+ .message('correctly', 'inccorrectly'); >+ }) >+ .then(() => task.done()); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..58fb3a474d3be9b884a1b572357a1b98f5e1e85f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-expected.txt >@@ -0,0 +1,18 @@ >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] Basic tests for AudioNode API. >+PASS AudioBufferSource.numberOfInputs is equal to 0. >+PASS AudioBufferSource.numberOfOutputs is equal to 1. >+PASS AudioContext.destination.numberOfInputs is equal to 1. >+PASS AudioContext.destination.numberOfOutputs is equal to 0. >+PASS audioNode.connect(0, 0, 0) threw TypeError: "Argument 1 ('destination') to AudioNode.connect must be an instance of AudioNode". >+PASS audioNode.connect(null, 0, 0) threw TypeError: "Argument 1 ('destination') to AudioNode.connect must be an instance of AudioNode". >+PASS audioNode.connect(context.destination, 5, 0) threw IndexSizeError: "The index is not in the allowed range.". >+PASS audioNode.connect(context.destination, 0, 5) threw IndexSizeError: "The index is not in the allowed range.". >+PASS audioNode.connect(context.destination, 0, 0) did not throw an exception. >+FAIL X Connecting a node to a different context threw "SyntaxError" instead of InvalidAccessError. assert_true: expected true got false >+FAIL X context3 = new AudioContext(1, 44100, 44100) did not throw an exception. assert_true: expected true got false >+PASS AudioNode is an EventTarget is true. >+FAIL < [test] 2 out of 12 assertions were failed. assert_true: expected true got false >+FAIL # AUDIT TASK RUNNER FINISHED: 1 out of 1 tasks were failed. assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode.html >new file mode 100644 >index 0000000000000000000000000000000000000000..b75cd0b5c0e035602f30751787dff3b0bcd94d9e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode.html >@@ -0,0 +1,93 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ audionode.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <div id="description"></div> >+ <div id="console"></div> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ let context = 0; >+ let context2 = 0; >+ let context3 = 0; >+ >+ audit.define( >+ {label: 'test', description: 'Basic tests for AudioNode API.'}, >+ function(task, should) { >+ >+ context = new AudioContext(); >+ window.audioNode = context.createBufferSource(); >+ >+ // Check input and output numbers of AudioSourceNode. >+ should(audioNode.numberOfInputs, 'AudioBufferSource.numberOfInputs') >+ .beEqualTo(0); >+ should( >+ audioNode.numberOfOutputs, 'AudioBufferSource.numberOfOutputs') >+ .beEqualTo(1); >+ >+ // Check input and output numbers of AudioDestinationNode >+ should( >+ context.destination.numberOfInputs, >+ 'AudioContext.destination.numberOfInputs') >+ .beEqualTo(1); >+ should( >+ context.destination.numberOfOutputs, >+ 'AudioContext.destination.numberOfOutputs') >+ .beEqualTo(0); >+ >+ // Try calling connect() method with illegal values. >+ should( >+ () => audioNode.connect(0, 0, 0), 'audioNode.connect(0, 0, 0)') >+ .throw('TypeError'); >+ should( >+ () => audioNode.connect(null, 0, 0), >+ 'audioNode.connect(null, 0, 0)') >+ .throw('TypeError'); >+ should( >+ () => audioNode.connect(context.destination, 5, 0), >+ 'audioNode.connect(context.destination, 5, 0)') >+ .throw('IndexSizeError'); >+ should( >+ () => audioNode.connect(context.destination, 0, 5), >+ 'audioNode.connect(context.destination, 0, 5)') >+ .throw('IndexSizeError'); >+ >+ should( >+ () => audioNode.connect(context.destination, 0, 0), >+ 'audioNode.connect(context.destination, 0, 0)') >+ .notThrow(); >+ >+ // Create a new context and try to connect the other context's node >+ // to this one. >+ context2 = new AudioContext(); >+ should( >+ () => window.audioNode.connect(context2.destination), >+ 'Connecting a node to a different context') >+ .throw('InvalidAccessError'); >+ >+ // 3-arg AudioContext doesn't create an offline context anymore. >+ should( >+ () => context3 = new AudioContext(1, 44100, 44100), >+ 'context3 = new AudioContext(1, 44100, 44100)') >+ .throw('TypeError'); >+ >+ // Ensure it is an EventTarget >+ should( >+ audioNode instanceof EventTarget, 'AudioNode is an EventTarget') >+ .beTrue(); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/channel-mode-interp-basic-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/channel-mode-interp-basic-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..df26e115bb883ca4c147f9a122ff708ff4357525 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/channel-mode-interp-basic-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 22: SyntaxError: The string did not match the expected pattern. >+ >+Harness Error (FAIL), message = SyntaxError: The string did not match the expected pattern. >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [interp] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/channel-mode-interp-basic.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/channel-mode-interp-basic.html >new file mode 100644 >index 0000000000000000000000000000000000000000..35cfca8e4eec6809832845aa48388d0a30c602fb >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/channel-mode-interp-basic.html >@@ -0,0 +1,66 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Setting of channelCountMode and channelInterpretation >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ // Fairly arbitrary sample rate and number of frames, except the number of >+ // frames should be more than a few render quantums. >+ let sampleRate = 16000; >+ let renderFrames = 10 * 128; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('interp', (task, should) => { >+ let context = new OfflineAudioContext(1, renderFrames, sampleRate); >+ let node = context.createGain(); >+ >+ // Set a new interpretation and verify that it changed. >+ node.channelInterpretation = 'discrete'; >+ let value = node.channelInterpretation; >+ should(value, 'node.channelInterpretation').beEqualTo('discrete'); >+ node.connect(context.destination); >+ >+ context.startRendering() >+ .then(function(buffer) { >+ // After rendering, the value should have been changed. >+ should( >+ node.channelInterpretation, >+ 'After rendering node.channelInterpretation') >+ .beEqualTo('discrete'); >+ }) >+ .then(() => task.done()); >+ }); >+ >+ audit.define('mode', (task, should) => { >+ let context = new OfflineAudioContext(1, renderFrames, sampleRate); >+ let node = context.createGain(); >+ >+ // Set a new mode and verify that it changed. >+ node.channelCountMode = 'explicit'; >+ let value = node.channelCountMode; >+ should(value, 'node.channelCountMode').beEqualTo('explicit'); >+ node.connect(context.destination); >+ >+ context.startRendering() >+ .then(function(buffer) { >+ // After rendering, the value should have been changed. >+ should( >+ node.channelCountMode, >+ 'After rendering node.channelCountMode') >+ .beEqualTo('explicit'); >+ }) >+ .then(() => task.done()); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/w3c-import.log >index d88e2f96d28fe23fe43a0d71c244d41433be971c..fb4bc1252663a350dae3348aa942d5740b75e5f5 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/w3c-import.log >@@ -14,4 +14,11 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-channel-rules.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-order.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-return-value.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/channel-mode-interp-basic.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-connect-audioratesignal-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-connect-audioratesignal-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..f1774f5fcc14479b301765e3db7cc66081712635 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-connect-audioratesignal-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 94: TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-connect-audioratesignal.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-connect-audioratesignal.html >new file mode 100644 >index 0000000000000000000000000000000000000000..517d64f3dbb69e610a5ed17475c45f530f749a42 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-connect-audioratesignal.html >@@ -0,0 +1,103 @@ >+<!DOCTYPE html> >+<!-- >+Tests that an audio-rate signal (AudioNode output) can be connected to an >+AudioParam. Specifically, this tests that an audio-rate signal coming from an >+AudioBufferSourceNode playing an AudioBuffer containing a specific curve can be >+connected to an AudioGainNode's .gain attribute (an AudioParam). Another >+AudioBufferSourceNode will be the audio source having its gain changed. We load >+this one with an AudioBuffer containing a constant value of 1. Thus it's easy >+to check that the resultant signal should be equal to the gain-scaling curve. >+--> >+<html> >+ <head> >+ <title> >+ audioparam-connect-audioratesignal.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ let sampleRate = 44100.0; >+ let lengthInSeconds = 1; >+ >+ let context = 0; >+ let constantOneBuffer = 0; >+ let linearRampBuffer = 0; >+ >+ function checkResult(renderedBuffer, should) { >+ let renderedData = renderedBuffer.getChannelData(0); >+ let expectedData = linearRampBuffer.getChannelData(0); >+ let n = renderedBuffer.length; >+ >+ should(n, 'Rendered signal length').beEqualTo(linearRampBuffer.length); >+ >+ // Check that the rendered result exactly matches the buffer used to >+ // control gain. This is because we're changing the gain of a signal >+ // having constant value 1. >+ let success = true; >+ for (let i = 0; i < n; ++i) { >+ if (renderedData[i] != expectedData[i]) { >+ success = false; >+ break; >+ } >+ } >+ >+ should( >+ success, >+ 'Rendered signal exactly matches the audio-rate gain changing signal') >+ .beTrue(); >+ } >+ >+ audit.define('test', function(task, should) { >+ let sampleFrameLength = sampleRate * lengthInSeconds; >+ >+ // Create offline audio context. >+ context = new OfflineAudioContext(1, sampleFrameLength, sampleRate); >+ >+ // Create buffer used by the source which will have its gain controlled. >+ constantOneBuffer = createConstantBuffer(context, sampleFrameLength, 1); >+ >+ // Create buffer used to control gain. >+ linearRampBuffer = createLinearRampBuffer(context, sampleFrameLength); >+ >+ // Create the two sources. >+ >+ let constantSource = context.createBufferSource(); >+ constantSource.buffer = constantOneBuffer; >+ >+ let gainChangingSource = context.createBufferSource(); >+ gainChangingSource.buffer = linearRampBuffer; >+ >+ // Create a gain node controlling the gain of constantSource and make >+ // the connections. >+ let gainNode = context.createGain(); >+ >+ // Intrinsic baseline gain of zero. >+ gainNode.gain.value = 0; >+ >+ constantSource.connect(gainNode); >+ gainNode.connect(context.destination); >+ >+ // Connect an audio-rate signal to control the .gain AudioParam. >+ // This is the heart of what is being tested. >+ gainChangingSource.connect(gainNode.gain); >+ >+ // Start both sources at time 0. >+ constantSource.start(0); >+ gainChangingSource.start(0); >+ >+ context.startRendering().then(buffer => { >+ checkResult(buffer, should); >+ task.done(); >+ }); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exceptional-values-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exceptional-values-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..81c278043df741a27910bbacf6053c499966f9d7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exceptional-values-expected.txt >@@ -0,0 +1,10 @@ >+CONSOLE MESSAGE: line 41: TypeError: undefined is not an object (evaluating 'context.createGain') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'context.createGain') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+FAIL X Creating context for testing incorrectly threw SyntaxError: "The string did not match the expected pattern.". assert_true: expected true got false >+FAIL < [initialize] 1 out of 1 assertions were failed. assert_true: expected true got false >+PASS > [test value] Test non-finite arguments for AudioParam value >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exceptional-values.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exceptional-values.html >new file mode 100644 >index 0000000000000000000000000000000000000000..c2d18de2170843564f01e47cef420332ba251272 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exceptional-values.html >@@ -0,0 +1,235 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ audioparam-exceptional-values.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ // Context to use for all of the tests. The context isn't used for any >+ // processing; just need one for creating a gain node, which is used for >+ // all the tests. >+ let context; >+ >+ // For these values, AudioParam methods should throw a Typeerror because >+ // they are not finite values. >+ let nonFiniteValues = [Infinity, -Infinity, NaN]; >+ >+ audit.define('initialize', (task, should) => { >+ should(() => { >+ // Context for testing. Rendering isn't done, so any valid values can >+ // be used here so might as well make them small. >+ context = new OfflineAudioContext(1, 1, 8000); >+ }, 'Creating context for testing').notThrow(); >+ >+ task.done(); >+ }); >+ >+ audit.define( >+ { >+ label: 'test value', >+ description: 'Test non-finite arguments for AudioParam value' >+ }, >+ (task, should) => { >+ let gain = context.createGain(); >+ >+ // Default method for generating the arguments for an automation >+ // method for testing the value of the automation. >+ let defaultFuncArg = (value) => [value, 1]; >+ >+ // Test the value parameter >+ doTests(should, gain, 'TypeError', nonFiniteValues, [ >+ {automationName: 'setValueAtTime', funcArg: defaultFuncArg}, { >+ automationName: 'linearRampToValueAtTime', >+ funcArg: defaultFuncArg >+ }, >+ { >+ automationName: 'exponentialRampToValueAtTime', >+ funcArg: defaultFuncArg >+ }, >+ { >+ automationName: 'setTargetAtTime', >+ funcArg: (value) => [value, 1, 1] >+ } >+ ]); >+ task.done(); >+ }); >+ >+ audit.define( >+ { >+ label: 'test time', >+ description: 'Test non-finite arguments for AudioParam time' >+ }, >+ (task, should) => { >+ let gain = context.createGain(); >+ >+ // Default method for generating the arguments for an automation >+ // method for testing the time parameter of the automation. >+ let defaultFuncArg = (startTime) => [1, startTime]; >+ >+ // Test the time parameter >+ doTests(should, gain, 'TypeError', nonFiniteValues, [ >+ {automationName: 'setValueAtTime', funcArg: defaultFuncArg}, >+ { >+ automationName: 'linearRampToValueAtTime', >+ funcArg: defaultFuncArg >+ }, >+ { >+ automationName: 'exponentialRampToValueAtTime', >+ funcArg: defaultFuncArg >+ }, >+ // Test start time for setTarget >+ { >+ automationName: 'setTargetAtTime', >+ funcArg: (startTime) => [1, startTime, 1] >+ }, >+ // Test time constant for setTarget >+ { >+ automationName: 'setTargetAtTime', >+ funcArg: (timeConstant) => [1, 1, timeConstant] >+ }, >+ ]); >+ >+ task.done(); >+ }); >+ >+ audit.define( >+ { >+ label: 'test setValueCurve', >+ description: 'Test non-finite arguments for setValueCurveAtTime' >+ }, >+ (task, should) => { >+ let gain = context.createGain(); >+ >+ // Just an array for use by setValueCurveAtTime. The length and >+ // contents of the array are not important. >+ let curve = new Float32Array(3); >+ >+ doTests(should, gain, 'TypeError', nonFiniteValues, [ >+ { >+ automationName: 'setValueCurveAtTime', >+ funcArg: (startTime) => [curve, startTime, 1] >+ }, >+ ]); >+ >+ // Non-finite values for the curve should signal an error >+ doTests( >+ should, gain, 'TypeError', >+ [[1, 2, Infinity, 3], [1, NaN, 2, 3]], [{ >+ automationName: 'setValueCurveAtTime', >+ funcArg: (c) => [c, 1, 1] >+ }]); >+ >+ task.done(); >+ }); >+ >+ audit.define( >+ { >+ label: 'special cases 1', >+ description: 'Test exceptions for finite values' >+ }, >+ (task, should) => { >+ let gain = context.createGain(); >+ >+ // Default method for generating the arguments for an automation >+ // method for testing the time parameter of the automation. >+ let defaultFuncArg = (startTime) => [1, startTime]; >+ >+ // Test the time parameter >+ let curve = new Float32Array(3); >+ doTests(should, gain, 'RangeError', [-1], [ >+ {automationName: 'setValueAtTime', funcArg: defaultFuncArg}, >+ { >+ automationName: 'linearRampToValueAtTime', >+ funcArg: defaultFuncArg >+ }, >+ { >+ automationName: 'exponentialRampToValueAtTime', >+ funcArg: defaultFuncArg >+ }, >+ { >+ automationName: 'setTargetAtTime', >+ funcArg: (startTime) => [1, startTime, 1] >+ }, >+ // Test time constant >+ { >+ automationName: 'setTargetAtTime', >+ funcArg: (timeConstant) => [1, 1, timeConstant] >+ }, >+ // startTime and duration for setValueCurve >+ { >+ automationName: 'setValueCurveAtTime', >+ funcArg: (startTime) => [curve, startTime, 1] >+ }, >+ { >+ automationName: 'setValueCurveAtTime', >+ funcArg: (duration) => [curve, 1, duration] >+ }, >+ ]); >+ >+ // One final test for setValueCurve: duration can't be 0. >+ should( >+ () => gain.gain.setValueCurveAtTime(curve, 1, 0), >+ 'gain.gain.setValueCurveAtTime(curve, 1, 0)') >+ .throw('RangeError'); >+ >+ task.done(); >+ }); >+ >+ audit.define( >+ { >+ label: 'special cases 2', >+ description: 'Test special cases for expeonentialRamp' >+ }, >+ (task, should) => { >+ let gain = context.createGain(); >+ >+ doTests(should, gain, 'RangeError', [0, -1e-100, 1e-100], [{ >+ automationName: 'exponentialRampToValueAtTime', >+ funcArg: (value) => [value, 1] >+ }]); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ >+ // Run test over the set of values in |testValues| for all of the >+ // automation methods in |testMethods|. The expected error type is >+ // |errorName|. |testMethods| is an array of dictionaries with attributes >+ // |automationName| giving the name of the automation method to be tested >+ // and |funcArg| being a function of one parameter that produces an array >+ // that will be used as the argument to the automation method. >+ function doTests(should, node, errorName, testValues, testMethods) { >+ testValues.forEach(value => { >+ testMethods.forEach(method => { >+ let args = method.funcArg(value); >+ let message = 'gain.gain.' + method.automationName + '(' + >+ argString(args) + ')'; >+ should(() => node.gain[method.automationName](...args), message) >+ .throw(errorName); >+ }); >+ }); >+ } >+ >+ // Specialized printer for automation arguments so that messages make >+ // sense. We assume the first element is either a number or an array. If >+ // it's an array, there are always three elements, and we want to print >+ // out the brackets for the array argument. >+ function argString(arg) { >+ if (typeof(arg[0]) === 'number') { >+ return arg.toString(); >+ } >+ >+ return '[' + arg[0] + '],' + arg[1] + ',' + arg[2]; >+ } >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exponentialRampToValueAtTime-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exponentialRampToValueAtTime-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..ede4fd1465e713aa1780d599b74ceb7e5c208a95 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exponentialRampToValueAtTime-expected.txt >@@ -0,0 +1,108 @@ >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] AudioParam exponentialRampToValueAtTime() functionality >+PASS Number of tests started and ended at the correct time is equal to 100. >+PASS Max error for test 0 at offset 126 is less than or equal to 0.00001222. >+PASS Max error for test 1 at offset 1535 is less than or equal to 0.00001222. >+PASS Max error for test 2 at offset 3967 is less than or equal to 0.00001222. >+PASS Max error for test 3 at offset 5247 is less than or equal to 0.00001222. >+PASS Max error for test 4 at offset 5503 is less than or equal to 0.00001222. >+PASS Max error for test 5 at offset 7679 is less than or equal to 0.00001222. >+PASS Max error for test 6 at offset 8063 is less than or equal to 0.00001222. >+PASS Max error for test 7 at offset 9471 is less than or equal to 0.00001222. >+PASS Max error for test 8 at offset 11902 is less than or equal to 0.00001222. >+PASS Max error for test 9 at offset 13183 is less than or equal to 0.00001222. >+PASS Max error for test 10 at offset 14462 is less than or equal to 0.00001222. >+PASS Max error for test 11 at offset 14719 is less than or equal to 0.00001222. >+PASS Max error for test 12 at offset 15999 is less than or equal to 0.00001222. >+PASS Max error for test 13 at offset 17919 is less than or equal to 0.00001222. >+PASS Max error for test 14 at offset 18686 is less than or equal to 0.00001222. >+PASS Max error for test 15 at offset 21119 is less than or equal to 0.00001222. >+PASS Max error for test 16 at offset 21375 is less than or equal to 0.00001222. >+PASS Max error for test 17 at offset 23807 is less than or equal to 0.00001222. >+PASS Max error for test 18 at offset 23935 is less than or equal to 0.00001222. >+PASS Max error for test 19 at offset 26367 is less than or equal to 0.00001222. >+PASS Max error for test 20 at offset 26623 is less than or equal to 0.00001222. >+PASS Max error for test 21 at offset 29055 is less than or equal to 0.00001222. >+PASS Max error for test 22 at offset 29311 is less than or equal to 0.00001222. >+PASS Max error for test 23 at offset 31743 is less than or equal to 0.00001222. >+PASS Max error for test 24 at offset 31998 is less than or equal to 0.00001222. >+PASS Max error for test 25 at offset 34175 is less than or equal to 0.00001222. >+PASS Max error for test 26 at offset 34558 is less than or equal to 0.00001222. >+PASS Max error for test 27 at offset 36351 is less than or equal to 0.00001222. >+PASS Max error for test 28 at offset 37247 is less than or equal to 0.00001222. >+PASS Max error for test 29 at offset 39679 is less than or equal to 0.00001222. >+PASS Max error for test 30 at offset 40703 is less than or equal to 0.00001222. >+PASS Max error for test 31 at offset 41599 is less than or equal to 0.00001222. >+PASS Max error for test 32 at offset 43646 is less than or equal to 0.00001222. >+PASS Max error for test 33 at offset 44415 is less than or equal to 0.00001222. >+PASS Max error for test 34 at offset 45183 is less than or equal to 0.00001222. >+PASS Max error for test 35 at offset 47103 is less than or equal to 0.00001222. >+PASS Max error for test 36 at offset 48895 is less than or equal to 0.00001222. >+PASS Max error for test 37 at offset 49151 is less than or equal to 0.00001222. >+PASS Max error for test 38 at offset 51583 is less than or equal to 0.00001222. >+PASS Max error for test 39 at offset 52735 is less than or equal to 0.00001222. >+PASS Max error for test 40 at offset 53247 is less than or equal to 0.00001222. >+PASS Max error for test 41 at offset 54527 is less than or equal to 0.00001222. >+PASS Max error for test 42 at offset 56447 is less than or equal to 0.00001222. >+PASS Max error for test 43 at offset 57215 is less than or equal to 0.00001222. >+PASS Max error for test 44 at offset 58879 is less than or equal to 0.00001222. >+PASS Max error for test 45 at offset 59775 is less than or equal to 0.00001222. >+PASS Max error for test 46 at offset 61695 is less than or equal to 0.00001222. >+PASS Max error for test 47 at offset 62335 is less than or equal to 0.00001222. >+PASS Max error for test 48 at offset 64255 is less than or equal to 0.00001222. >+PASS Max error for test 49 at offset 65151 is less than or equal to 0.00001222. >+PASS Max error for test 50 at offset 67455 is less than or equal to 0.00001222. >+PASS Max error for test 51 at offset 67711 is less than or equal to 0.00001222. >+PASS Max error for test 52 at offset 69630 is less than or equal to 0.00001222. >+PASS Max error for test 53 at offset 70527 is less than or equal to 0.00001222. >+PASS Max error for test 54 at offset 72063 is less than or equal to 0.00001222. >+PASS Max error for test 55 at offset 73087 is less than or equal to 0.00001222. >+PASS Max error for test 56 at offset 74879 is less than or equal to 0.00001222. >+PASS Max error for test 57 at offset 76671 is less than or equal to 0.00001222. >+PASS Max error for test 58 at offset 77935 is less than or equal to 0.00001222. >+PASS Max error for test 59 at offset 78463 is less than or equal to 0.00001222. >+PASS Max error for test 60 at offset 80382 is less than or equal to 0.00001222. >+PASS Max error for test 61 at offset 81151 is less than or equal to 0.00001222. >+PASS Max error for test 62 at offset 82175 is less than or equal to 0.00001222. >+PASS Max error for test 63 at offset 83839 is less than or equal to 0.00001222. >+PASS Max error for test 64 at offset 85247 is less than or equal to 0.00001222. >+PASS Max error for test 65 at offset 86143 is less than or equal to 0.00001222. >+PASS Max error for test 66 at offset 88063 is less than or equal to 0.00001222. >+PASS Max error for test 67 at offset 89087 is less than or equal to 0.00001222. >+PASS Max error for test 68 at offset 91262 is less than or equal to 0.00001222. >+PASS Max error for test 69 at offset 92287 is less than or equal to 0.00001222. >+PASS Max error for test 70 at offset 93822 is less than or equal to 0.00001222. >+PASS Max error for test 71 at offset 94975 is less than or equal to 0.00001222. >+PASS Max error for test 72 at offset 96510 is less than or equal to 0.00001222. >+PASS Max error for test 73 at offset 96891 is less than or equal to 0.00001222. >+PASS Max error for test 74 at offset 98687 is less than or equal to 0.00001222. >+PASS Max error for test 75 at offset 99839 is less than or equal to 0.00001222. >+PASS Max error for test 76 at offset 100990 is less than or equal to 0.00001222. >+PASS Max error for test 77 at offset 102782 is less than or equal to 0.00001222. >+PASS Max error for test 78 at offset 104447 is less than or equal to 0.00001222. >+PASS Max error for test 79 at offset 105710 is less than or equal to 0.00001222. >+PASS Max error for test 80 at offset 107132 is less than or equal to 0.00001222. >+PASS Max error for test 81 at offset 107363 is less than or equal to 0.00001222. >+PASS Max error for test 82 at offset 108799 is less than or equal to 0.00001222. >+PASS Max error for test 83 at offset 110438 is less than or equal to 0.00001222. >+PASS Max error for test 84 at offset 112112 is less than or equal to 0.00001222. >+PASS Max error for test 85 at offset 113596 is less than or equal to 0.00001222. >+PASS Max error for test 86 at offset 115071 is less than or equal to 0.00001222. >+PASS Max error for test 87 at offset 116351 is less than or equal to 0.00001222. >+PASS Max error for test 88 at offset 117375 is less than or equal to 0.00001222. >+PASS Max error for test 89 at offset 118902 is less than or equal to 0.00001222. >+PASS Max error for test 90 at offset 120188 is less than or equal to 0.00001222. >+PASS Max error for test 91 at offset 121701 is less than or equal to 0.00001222. >+PASS Max error for test 92 at offset 123007 is less than or equal to 0.00001222. >+PASS Max error for test 93 at offset 124159 is less than or equal to 0.00001222. >+PASS Max error for test 94 at offset 124923 is less than or equal to 0.00001222. >+PASS Max error for test 95 at offset 126999 is less than or equal to 0.00001222. >+PASS Max error for test 96 at offset 127861 is less than or equal to 0.00001222. >+PASS Max error for test 97 at offset 129532 is less than or equal to 0.00001222. >+PASS Max error for test 98 at offset 130551 is less than or equal to 0.00001222. >+PASS Max error for test 99 at offset 132093 is less than or equal to 0.00001222. >+PASS Number of failed tests with an acceptable relative tolerance of 0.00001222 is equal to 0. >+PASS < [test] All assertions passed. (total 102 assertions) >+PASS # AUDIT TASK RUNNER FINISHED: 1 tasks ran successfully. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exponentialRampToValueAtTime.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exponentialRampToValueAtTime.html >new file mode 100644 >index 0000000000000000000000000000000000000000..bec4c1286b4aaf7ba1b7aa7209ff41dad6c02dbd >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exponentialRampToValueAtTime.html >@@ -0,0 +1,63 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test AudioParam.exponentialRampToValueAtTime >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audioparam-testing.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ // Play a long DC signal out through an AudioGainNode, and call >+ // setValueAtTime() and exponentialRampToValueAtTime() at regular >+ // intervals to set the starting and ending values for an exponential >+ // ramp. Each time interval has a ramp with a different starting and >+ // ending value so that there is a discontinuity at each time interval >+ // boundary. The discontinuity is for testing timing. Also, we alternate >+ // between an increasing and decreasing ramp for each interval. >+ >+ // Number of tests to run. >+ let numberOfTests = 100; >+ >+ // Max allowed difference between the rendered data and the expected >+ // result. >+ let maxAllowedError = 1.222e-5; >+ >+ // The AudioGainNode starts with this value instead of the default value. >+ let initialValue = 100; >+ >+ // Set the gain node value to the specified value at the specified time. >+ function setValue(value, time) { >+ gainNode.gain.setValueAtTime(value, time); >+ } >+ >+ // Generate an exponential ramp ending at time |endTime| with an ending >+ // value of |value|. >+ function generateRamp(value, startTime, endTime){ >+ // |startTime| is ignored because the exponential ramp >+ // uses the value from the setValueAtTime() call above. >+ gainNode.gain.exponentialRampToValueAtTime(value, endTime)} >+ >+ audit.define( >+ { >+ label: 'test', >+ description: >+ 'AudioParam exponentialRampToValueAtTime() functionality' >+ }, >+ function(task, should) { >+ createAudioGraphAndTest( >+ task, should, numberOfTests, initialValue, setValue, >+ generateRamp, 'exponentialRampToValueAtTime()', maxAllowedError, >+ createExponentialRampArray); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-large-endtime-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-large-endtime-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..47611533408a9eb53a77f65e618db432870126dc >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-large-endtime-expected.txt >@@ -0,0 +1,9 @@ >+CONSOLE MESSAGE: line 33: TypeError: undefined is not an object (evaluating 'graph.context.startRendering() >+ .then') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'graph.context.startRendering() >+ .then') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [linearRamp] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-large-endtime.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-large-endtime.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d8f38eeba0857a352badbdbeef3eca8bf9a6f087 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-large-endtime.html >@@ -0,0 +1,73 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ AudioParam with Huge End Time >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let sampleRate = 48000; >+ // Render for some small (but fairly arbitrary) time. >+ let renderDuration = 0.125; >+ // Any huge time value that won't fit in a size_t (2^64 on a 64-bit >+ // machine). >+ let largeTime = 1e300; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ // See crbug.com/582701. Create an audioparam with a huge end time and >+ // verify that to automation is run. We don't care about the actual >+ // results, just that it runs. >+ >+ // Test linear ramp with huge end time >+ audit.define('linearRamp', (task, should) => { >+ let graph = createGraph(); >+ graph.gain.gain.linearRampToValueAtTime(0.1, largeTime); >+ >+ graph.source.start(); >+ graph.context.startRendering() >+ .then(function(buffer) { >+ should(true, 'linearRampToValue(0.1, ' + largeTime + ')') >+ .message('successfully rendered', 'unsuccessfully rendered'); >+ }) >+ .then(() => task.done()); >+ }); >+ >+ // Test exponential ramp with huge end time >+ audit.define('exponentialRamp', (task, should) => { >+ let graph = createGraph(); >+ graph.gain.gain.exponentialRampToValueAtTime(.1, largeTime); >+ >+ graph.source.start(); >+ graph.context.startRendering() >+ .then(function(buffer) { >+ should(true, 'exponentialRampToValue(0.1, ' + largeTime + ')') >+ .message('successfully rendered', 'unsuccessfully rendered'); >+ }) >+ .then(() => task.done()); >+ }); >+ >+ audit.run(); >+ >+ // Create the graph and return the context, the source, and the gain node. >+ function createGraph() { >+ let context = >+ new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate); >+ let src = context.createBufferSource(); >+ src.buffer = createConstantBuffer(context, 1, 1); >+ src.loop = true; >+ let gain = context.createGain(); >+ src.connect(gain); >+ gain.connect(context.destination); >+ gain.gain.setValueAtTime(1, 0.1 / sampleRate); >+ >+ return {context: context, gain: gain, source: src}; >+ } >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-linearRampToValueAtTime-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-linearRampToValueAtTime-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..487c40af45383f7897aada8554998474a57b0a00 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-linearRampToValueAtTime-expected.txt >@@ -0,0 +1,108 @@ >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] AudioParam linearRampToValueAtTime() functionality >+PASS Number of tests started and ended at the correct time is equal to 100. >+PASS Max error for test 0 at offset 657 is less than or equal to 0.000001865. >+PASS Max error for test 1 at offset 1553 is less than or equal to 0.000001865. >+PASS Max error for test 2 at offset 2982 is less than or equal to 0.000001865. >+PASS Max error for test 3 at offset 4556 is less than or equal to 0.000001865. >+PASS Max error for test 4 at offset 6231 is less than or equal to 0.000001865. >+PASS Max error for test 5 at offset 7111 is less than or equal to 0.000001865. >+PASS Max error for test 6 at offset 8479 is less than or equal to 0.000001865. >+PASS Max error for test 7 at offset 9900 is less than or equal to 0.000001865. >+PASS Max error for test 8 at offset 11046 is less than or equal to 0.000001865. >+PASS Max error for test 9 at offset 12344 is less than or equal to 0.000001865. >+PASS Max error for test 10 at offset 13766 is less than or equal to 0.000001865. >+PASS Max error for test 11 at offset 14710 is less than or equal to 0.000001865. >+PASS Max error for test 12 at offset 16419 is less than or equal to 0.000001865. >+PASS Max error for test 13 at offset 17678 is less than or equal to 0.000001865. >+PASS Max error for test 14 at offset 18679 is less than or equal to 0.000001865. >+PASS Max error for test 15 at offset 20112 is less than or equal to 0.000001865. >+PASS Max error for test 16 at offset 21444 is less than or equal to 0.000001865. >+PASS Max error for test 17 at offset 22734 is less than or equal to 0.000001865. >+PASS Max error for test 18 at offset 24352 is less than or equal to 0.000001865. >+PASS Max error for test 19 at offset 25557 is less than or equal to 0.000001865. >+PASS Max error for test 20 at offset 26885 is less than or equal to 0.000001865. >+PASS Max error for test 21 at offset 28311 is less than or equal to 0.000001865. >+PASS Max error for test 22 at offset 29259 is less than or equal to 0.000001865. >+PASS Max error for test 23 at offset 30879 is less than or equal to 0.000001865. >+PASS Max error for test 24 at offset 32157 is less than or equal to 0.000001865. >+PASS Max error for test 25 at offset 33495 is less than or equal to 0.000001865. >+PASS Max error for test 26 at offset 34412 is less than or equal to 0.000001865. >+PASS Max error for test 27 at offset 35867 is less than or equal to 0.000001865. >+PASS Max error for test 28 at offset 37319 is less than or equal to 0.000001865. >+PASS Max error for test 29 at offset 38731 is less than or equal to 0.000001865. >+PASS Max error for test 30 at offset 40033 is less than or equal to 0.000001865. >+PASS Max error for test 31 at offset 41212 is less than or equal to 0.000001865. >+PASS Max error for test 32 at offset 42508 is less than or equal to 0.000001865. >+PASS Max error for test 33 at offset 43790 is less than or equal to 0.000001865. >+PASS Max error for test 34 at offset 45329 is less than or equal to 0.000001865. >+PASS Max error for test 35 at offset 46364 is less than or equal to 0.000001865. >+PASS Max error for test 36 at offset 48151 is less than or equal to 0.000001865. >+PASS Max error for test 37 at offset 49522 is less than or equal to 0.000001865. >+PASS Max error for test 38 at offset 50899 is less than or equal to 0.000001865. >+PASS Max error for test 39 at offset 52255 is less than or equal to 0.000001865. >+PASS Max error for test 40 at offset 52932 is less than or equal to 0.000001865. >+PASS Max error for test 41 at offset 54381 is less than or equal to 0.000001865. >+PASS Max error for test 42 at offset 56219 is less than or equal to 0.000001865. >+PASS Max error for test 43 at offset 57014 is less than or equal to 0.000001865. >+PASS Max error for test 44 at offset 58224 is less than or equal to 0.000001865. >+PASS Max error for test 45 at offset 60171 is less than or equal to 0.000001865. >+PASS Max error for test 46 at offset 61235 is less than or equal to 0.000001865. >+PASS Max error for test 47 at offset 62220 is less than or equal to 0.000001865. >+PASS Max error for test 48 at offset 63879 is less than or equal to 0.000001865. >+PASS Max error for test 49 at offset 64884 is less than or equal to 0.000001865. >+PASS Max error for test 50 at offset 67468 is less than or equal to 0.000001865. >+PASS Max error for test 51 at offset 67844 is less than or equal to 0.000001865. >+PASS Max error for test 52 at offset 69211 is less than or equal to 0.000001865. >+PASS Max error for test 53 at offset 70605 is less than or equal to 0.000001865. >+PASS Max error for test 54 at offset 71998 is less than or equal to 0.000001865. >+PASS Max error for test 55 at offset 73295 is less than or equal to 0.000001865. >+PASS Max error for test 56 at offset 74554 is less than or equal to 0.000001865. >+PASS Max error for test 57 at offset 75896 is less than or equal to 0.000001865. >+PASS Max error for test 58 at offset 76861 is less than or equal to 0.000001865. >+PASS Max error for test 59 at offset 78458 is less than or equal to 0.000001865. >+PASS Max error for test 60 at offset 79798 is less than or equal to 0.000001865. >+PASS Max error for test 61 at offset 81256 is less than or equal to 0.000001865. >+PASS Max error for test 62 at offset 82464 is less than or equal to 0.000001865. >+PASS Max error for test 63 at offset 83954 is less than or equal to 0.000001865. >+PASS Max error for test 64 at offset 84701 is less than or equal to 0.000001865. >+PASS Max error for test 65 at offset 86343 is less than or equal to 0.000001865. >+PASS Max error for test 66 at offset 87335 is less than or equal to 0.000001865. >+PASS Max error for test 67 at offset 89890 is less than or equal to 0.000001865. >+PASS Max error for test 68 at offset 90044 is less than or equal to 0.000001865. >+PASS Max error for test 69 at offset 91455 is less than or equal to 0.000001865. >+PASS Max error for test 70 at offset 92629 is less than or equal to 0.000001865. >+PASS Max error for test 71 at offset 94073 is less than or equal to 0.000001865. >+PASS Max error for test 72 at offset 95912 is less than or equal to 0.000001865. >+PASS Max error for test 73 at offset 96674 is less than or equal to 0.000001865. >+PASS Max error for test 74 at offset 97949 is less than or equal to 0.000001865. >+PASS Max error for test 75 at offset 99861 is less than or equal to 0.000001865. >+PASS Max error for test 76 at offset 101168 is less than or equal to 0.000001865. >+PASS Max error for test 77 at offset 103175 is less than or equal to 0.000001865. >+PASS Max error for test 78 at offset 103711 is less than or equal to 0.000001865. >+PASS Max error for test 79 at offset 104680 is less than or equal to 0.000001865. >+PASS Max error for test 80 at offset 106251 is less than or equal to 0.000001865. >+PASS Max error for test 81 at offset 107716 is less than or equal to 0.000001865. >+PASS Max error for test 82 at offset 108818 is less than or equal to 0.000001865. >+PASS Max error for test 83 at offset 109989 is less than or equal to 0.000001865. >+PASS Max error for test 84 at offset 112153 is less than or equal to 0.000001865. >+PASS Max error for test 85 at offset 113772 is less than or equal to 0.000001865. >+PASS Max error for test 86 at offset 114376 is less than or equal to 0.000001865. >+PASS Max error for test 87 at offset 115112 is less than or equal to 0.000001865. >+PASS Max error for test 88 at offset 116572 is less than or equal to 0.000001865. >+PASS Max error for test 89 at offset 117924 is less than or equal to 0.000001865. >+PASS Max error for test 90 at offset 119326 is less than or equal to 0.000001865. >+PASS Max error for test 91 at offset 120516 is less than or equal to 0.000001865. >+PASS Max error for test 92 at offset 122758 is less than or equal to 0.000001865. >+PASS Max error for test 93 at offset 124309 is less than or equal to 0.000001865. >+PASS Max error for test 94 at offset 125673 is less than or equal to 0.000001865. >+PASS Max error for test 95 at offset 127006 is less than or equal to 0.000001865. >+PASS Max error for test 96 at offset 127202 is less than or equal to 0.000001865. >+PASS Max error for test 97 at offset 128579 is less than or equal to 0.000001865. >+PASS Max error for test 98 at offset 129679 is less than or equal to 0.000001865. >+PASS Max error for test 99 at offset 131112 is less than or equal to 0.000001865. >+PASS Number of failed tests with an acceptable relative tolerance of 0.000001865 is equal to 0. >+PASS < [test] All assertions passed. (total 102 assertions) >+PASS # AUDIT TASK RUNNER FINISHED: 1 tasks ran successfully. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-linearRampToValueAtTime.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-linearRampToValueAtTime.html >new file mode 100644 >index 0000000000000000000000000000000000000000..509c254d92d891a1f4e6820760e757b03d02366f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-linearRampToValueAtTime.html >@@ -0,0 +1,60 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test AudioParam.linearRampToValueAtTime >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audioparam-testing.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ // Play a long DC signal out through an AudioGainNode, and call >+ // setValueAtTime() and linearRampToValueAtTime() at regular intervals to >+ // set the starting and ending values for a linear ramp. Each time >+ // interval has a ramp with a different starting and ending value so that >+ // there is a discontinuity at each time interval boundary. The >+ // discontinuity is for testing timing. Also, we alternate between an >+ // increasing and decreasing ramp for each interval. >+ >+ // Number of tests to run. >+ let numberOfTests = 100; >+ >+ // Max allowed difference between the rendered data and the expected >+ // result. >+ let maxAllowedError = 1.865e-6; >+ >+ // Set the gain node value to the specified value at the specified time. >+ function setValue(value, time) { >+ gainNode.gain.setValueAtTime(value, time); >+ } >+ >+ // Generate a linear ramp ending at time |endTime| with an ending value of >+ // |value|. >+ function generateRamp(value, startTime, endTime){ >+ // |startTime| is ignored because the linear ramp uses the value from >+ // the >+ // setValueAtTime() call above. >+ gainNode.gain.linearRampToValueAtTime(value, endTime)} >+ >+ audit.define( >+ { >+ label: 'test', >+ description: 'AudioParam linearRampToValueAtTime() functionality' >+ }, >+ function(task, should) { >+ createAudioGraphAndTest( >+ task, should, numberOfTests, 1, setValue, generateRamp, >+ 'linearRampToValueAtTime()', maxAllowedError, >+ createLinearRampArray); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-method-chaining-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-method-chaining-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..42d15f04c3638006a34608cb7c9ebf01b7e2450e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-method-chaining-expected.txt >@@ -0,0 +1,15 @@ >+CONSOLE MESSAGE: line 52: SyntaxError: The string did not match the expected pattern. >+ >+Harness Error (FAIL), message = SyntaxError: The string did not match the expected pattern. >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [from-dictionary] >+FAIL X The return value of AudioParam.setValueAtTime() matches the source AudioParam is not equal to true. Got false. assert_true: expected true got false >+FAIL X The return value of AudioParam.linearRampToValueAtTime() matches the source AudioParam is not equal to true. Got false. assert_true: expected true got false >+FAIL X The return value of AudioParam.exponentialRampToValueAtTime() matches the source AudioParam is not equal to true. Got false. assert_true: expected true got false >+FAIL X The return value of AudioParam.setTargetAtTime() matches the source AudioParam is not equal to true. Got false. assert_true: expected true got false >+FAIL X The return value of AudioParam.setValueCurveAtTime() matches the source AudioParam is not equal to true. Got false. assert_true: expected true got false >+FAIL X The return value of AudioParam.cancelScheduledValues() matches the source AudioParam is not equal to true. Got false. assert_true: expected true got false >+FAIL < [from-dictionary] 6 out of 6 assertions were failed. assert_true: expected true got false >+PASS > [invalid-operation] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-method-chaining.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-method-chaining.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ed25a0193b5ebdb40b2758cb9e9efc10b4c9bef2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-method-chaining.html >@@ -0,0 +1,143 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ audioparam-method-chaining.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audioparam-testing.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let sampleRate = 8000; >+ >+ // Create a dummy array for setValueCurveAtTime method. >+ let curveArray = new Float32Array([5.0, 6.0]); >+ >+ // AudioNode dictionary with associated dummy arguments. >+ let methodDictionary = [ >+ {name: 'setValueAtTime', args: [1.0, 0.0]}, >+ {name: 'linearRampToValueAtTime', args: [2.0, 1.0]}, >+ {name: 'exponentialRampToValueAtTime', args: [3.0, 2.0]}, >+ {name: 'setTargetAtTime', args: [4.0, 2.0, 0.5]}, >+ {name: 'setValueCurveAtTime', args: [curveArray, 5.0, 1.0]}, >+ {name: 'cancelScheduledValues', args: [6.0]} >+ ]; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ // Task: testing entries from the dictionary. >+ audit.define('from-dictionary', (task, should) => { >+ let context = new AudioContext(); >+ >+ methodDictionary.forEach(function(method) { >+ let sourceParam = context.createGain().gain; >+ should( >+ sourceParam === sourceParam[method.name](...method.args), >+ 'The return value of ' + sourceParam.constructor.name + '.' + >+ method.name + '()' + >+ ' matches the source AudioParam') >+ .beEqualTo(true); >+ >+ }); >+ >+ task.done(); >+ }); >+ >+ // Task: test method chaining with invalid operation. >+ audit.define('invalid-operation', (task, should) => { >+ let context = new OfflineAudioContext(1, sampleRate, sampleRate); >+ let osc = context.createOscillator(); >+ let amp1 = context.createGain(); >+ let amp2 = context.createGain(); >+ >+ osc.connect(amp1); >+ osc.connect(amp2); >+ amp1.connect(context.destination); >+ amp2.connect(context.destination); >+ >+ // The first operation fails with an exception, thus the second one >+ // should not have effect on the parameter value. Instead, it should >+ // maintain the default value of 1.0. >+ should( >+ function() { >+ amp1.gain.setValueAtTime(0.25, -1.0) >+ .linearRampToValueAtTime(2.0, 1.0); >+ }, >+ 'Calling setValueAtTime() with a negative end time') >+ .throw('RangeError'); >+ >+ // The first operation succeeds but the second fails due to zero target >+ // value for the exponential ramp. Thus only the first should have >+ // effect on the parameter value, setting the value to 0.5. >+ should( >+ function() { >+ amp2.gain.setValueAtTime(0.5, 0.0).exponentialRampToValueAtTime( >+ 0.0, 1.0); >+ }, >+ 'Calling exponentialRampToValueAtTime() with a zero target value') >+ .throw('RangeError'); >+ >+ osc.start(); >+ osc.stop(1.0); >+ >+ context.startRendering() >+ .then(function(buffer) { >+ should(amp1.gain.value, 'The gain value of the first gain node') >+ .beEqualTo(1.0); >+ should(amp2.gain.value, 'The gain value of the second gain node') >+ .beEqualTo(0.5); >+ }) >+ .then(() => task.done()); >+ }); >+ >+ // Task: verify if the method chaining actually works. Create an arbitrary >+ // envelope and compare the result with the expected one created by JS >+ // code. >+ audit.define('verification', (task, should) => { >+ let context = new OfflineAudioContext(1, sampleRate * 4, sampleRate); >+ let constantBuffer = createConstantBuffer(context, 1, 1.0); >+ >+ let source = context.createBufferSource(); >+ source.buffer = constantBuffer; >+ source.loop = true; >+ >+ let envelope = context.createGain(); >+ >+ source.connect(envelope); >+ envelope.connect(context.destination); >+ >+ envelope.gain.setValueAtTime(0.0, 0.0) >+ .linearRampToValueAtTime(1.0, 1.0) >+ .exponentialRampToValueAtTime(0.5, 2.0) >+ .setTargetAtTime(0.001, 2.0, 0.5); >+ >+ source.start(); >+ >+ context.startRendering() >+ .then(function(buffer) { >+ let expectedEnvelope = >+ createLinearRampArray(0.0, 1.0, 0.0, 1.0, sampleRate); >+ expectedEnvelope.push(...createExponentialRampArray( >+ 1.0, 2.0, 1.0, 0.5, sampleRate)); >+ expectedEnvelope.push(...createExponentialApproachArray( >+ 2.0, 4.0, 0.5, 0.001, sampleRate, 0.5)); >+ >+ // There are slight differences between JS implementation of >+ // AudioParam envelope and the internal implementation. (i.e. >+ // double/float and rounding up) The error threshold is adjusted >+ // empirically through the local testing. >+ should(buffer.getChannelData(0), 'The rendered envelope') >+ .beCloseToArray( >+ expectedEnvelope, {absoluteThreshold: 4.0532e-6}); >+ }) >+ .then(() => task.done()); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setTargetAtTime-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setTargetAtTime-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..fc0960b11b5fa9126b1b0522d827952ad2b8dd0f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setTargetAtTime-expected.txt >@@ -0,0 +1,108 @@ >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] AudioParam setTargetAtTime() functionality. >+PASS Number of tests started and ended at the correct time is equal to 100. >+PASS Max error for test 0 at offset 1289 is less than or equal to 0.00065683. >+PASS Max error for test 1 at offset 2612 is less than or equal to 0.00065683. >+PASS Max error for test 2 at offset 3935 is less than or equal to 0.00065683. >+PASS Max error for test 3 at offset 5258 is less than or equal to 0.00065683. >+PASS Max error for test 4 at offset 6581 is less than or equal to 0.00065683. >+PASS Max error for test 5 at offset 7904 is less than or equal to 0.00065683. >+PASS Max error for test 6 at offset 9227 is less than or equal to 0.00065683. >+PASS Max error for test 7 at offset 10550 is less than or equal to 0.00065683. >+PASS Max error for test 8 at offset 11873 is less than or equal to 0.00065683. >+PASS Max error for test 9 at offset 13196 is less than or equal to 0.00065683. >+PASS Max error for test 10 at offset 14519 is less than or equal to 0.00065683. >+PASS Max error for test 11 at offset 15842 is less than or equal to 0.00065683. >+PASS Max error for test 12 at offset 17165 is less than or equal to 0.00065683. >+PASS Max error for test 13 at offset 18488 is less than or equal to 0.00065683. >+PASS Max error for test 14 at offset 19811 is less than or equal to 0.00065683. >+PASS Max error for test 15 at offset 21134 is less than or equal to 0.00065683. >+PASS Max error for test 16 at offset 22457 is less than or equal to 0.00065683. >+PASS Max error for test 17 at offset 23780 is less than or equal to 0.00065683. >+PASS Max error for test 18 at offset 25103 is less than or equal to 0.00065683. >+PASS Max error for test 19 at offset 26426 is less than or equal to 0.00065683. >+PASS Max error for test 20 at offset 27749 is less than or equal to 0.00065683. >+PASS Max error for test 21 at offset 29072 is less than or equal to 0.00065683. >+PASS Max error for test 22 at offset 30395 is less than or equal to 0.00065683. >+PASS Max error for test 23 at offset 31718 is less than or equal to 0.00065683. >+PASS Max error for test 24 at offset 33041 is less than or equal to 0.00065683. >+PASS Max error for test 25 at offset 34364 is less than or equal to 0.00065683. >+PASS Max error for test 26 at offset 35687 is less than or equal to 0.00065683. >+PASS Max error for test 27 at offset 37010 is less than or equal to 0.00065683. >+PASS Max error for test 28 at offset 38333 is less than or equal to 0.00065683. >+PASS Max error for test 29 at offset 39656 is less than or equal to 0.00065683. >+PASS Max error for test 30 at offset 40979 is less than or equal to 0.00065683. >+PASS Max error for test 31 at offset 42302 is less than or equal to 0.00065683. >+PASS Max error for test 32 at offset 43625 is less than or equal to 0.00065683. >+PASS Max error for test 33 at offset 44948 is less than or equal to 0.00065683. >+PASS Max error for test 34 at offset 46271 is less than or equal to 0.00065683. >+PASS Max error for test 35 at offset 47594 is less than or equal to 0.00065683. >+PASS Max error for test 36 at offset 48917 is less than or equal to 0.00065683. >+PASS Max error for test 37 at offset 49099 is less than or equal to 0.00065683. >+PASS Max error for test 38 at offset 50422 is less than or equal to 0.00065683. >+PASS Max error for test 39 at offset 51745 is less than or equal to 0.00065683. >+PASS Max error for test 40 at offset 53068 is less than or equal to 0.00065683. >+PASS Max error for test 41 at offset 54391 is less than or equal to 0.00065683. >+PASS Max error for test 42 at offset 55714 is less than or equal to 0.00065683. >+PASS Max error for test 43 at offset 57037 is less than or equal to 0.00065683. >+PASS Max error for test 44 at offset 58360 is less than or equal to 0.00065683. >+PASS Max error for test 45 at offset 59683 is less than or equal to 0.00065683. >+PASS Max error for test 46 at offset 61006 is less than or equal to 0.00065683. >+PASS Max error for test 47 at offset 62329 is less than or equal to 0.00065683. >+PASS Max error for test 48 at offset 63652 is less than or equal to 0.00065683. >+PASS Max error for test 49 at offset 64975 is less than or equal to 0.00065683. >+PASS Max error for test 50 at offset 66298 is less than or equal to 0.00065683. >+PASS Max error for test 51 at offset 67621 is less than or equal to 0.00065683. >+PASS Max error for test 52 at offset 68944 is less than or equal to 0.00065683. >+PASS Max error for test 53 at offset 70267 is less than or equal to 0.00065683. >+PASS Max error for test 54 at offset 71590 is less than or equal to 0.00065683. >+PASS Max error for test 55 at offset 72913 is less than or equal to 0.00065683. >+PASS Max error for test 56 at offset 74236 is less than or equal to 0.00065683. >+PASS Max error for test 57 at offset 75559 is less than or equal to 0.00065683. >+PASS Max error for test 58 at offset 76882 is less than or equal to 0.00065683. >+PASS Max error for test 59 at offset 78205 is less than or equal to 0.00065683. >+PASS Max error for test 60 at offset 79528 is less than or equal to 0.00065683. >+PASS Max error for test 61 at offset 80851 is less than or equal to 0.00065683. >+PASS Max error for test 62 at offset 82174 is less than or equal to 0.00065683. >+PASS Max error for test 63 at offset 83497 is less than or equal to 0.00065683. >+PASS Max error for test 64 at offset 84820 is less than or equal to 0.00065683. >+PASS Max error for test 65 at offset 86143 is less than or equal to 0.00065683. >+PASS Max error for test 66 at offset 87466 is less than or equal to 0.00065683. >+PASS Max error for test 67 at offset 88789 is less than or equal to 0.00065683. >+PASS Max error for test 68 at offset 90112 is less than or equal to 0.00065683. >+PASS Max error for test 69 at offset 91436 is less than or equal to 0.00065683. >+PASS Max error for test 70 at offset 92759 is less than or equal to 0.00065683. >+PASS Max error for test 71 at offset 94082 is less than or equal to 0.00065683. >+PASS Max error for test 72 at offset 95405 is less than or equal to 0.00065683. >+PASS Max error for test 73 at offset 96728 is less than or equal to 0.00065683. >+PASS Max error for test 74 at offset 98051 is less than or equal to 0.00065683. >+PASS Max error for test 75 at offset 99374 is less than or equal to 0.00065683. >+PASS Max error for test 76 at offset 100697 is less than or equal to 0.00065683. >+PASS Max error for test 77 at offset 102020 is less than or equal to 0.00065683. >+PASS Max error for test 78 at offset 103343 is less than or equal to 0.00065683. >+PASS Max error for test 79 at offset 104666 is less than or equal to 0.00065683. >+PASS Max error for test 80 at offset 105989 is less than or equal to 0.00065683. >+PASS Max error for test 81 at offset 107312 is less than or equal to 0.00065683. >+PASS Max error for test 82 at offset 108635 is less than or equal to 0.00065683. >+PASS Max error for test 83 at offset 109958 is less than or equal to 0.00065683. >+PASS Max error for test 84 at offset 111281 is less than or equal to 0.00065683. >+PASS Max error for test 85 at offset 112595 is less than or equal to 0.00065683. >+PASS Max error for test 86 at offset 113918 is less than or equal to 0.00065683. >+PASS Max error for test 87 at offset 115241 is less than or equal to 0.00065683. >+PASS Max error for test 88 at offset 116564 is less than or equal to 0.00065683. >+PASS Max error for test 89 at offset 117887 is less than or equal to 0.00065683. >+PASS Max error for test 90 at offset 119210 is less than or equal to 0.00065683. >+PASS Max error for test 91 at offset 120533 is less than or equal to 0.00065683. >+PASS Max error for test 92 at offset 121856 is less than or equal to 0.00065683. >+PASS Max error for test 93 at offset 123803 is less than or equal to 0.00065683. >+PASS Max error for test 94 at offset 125126 is less than or equal to 0.00065683. >+PASS Max error for test 95 at offset 126449 is less than or equal to 0.00065683. >+PASS Max error for test 96 at offset 127772 is less than or equal to 0.00065683. >+PASS Max error for test 97 at offset 129396 is less than or equal to 0.00065683. >+PASS Max error for test 98 at offset 130719 is less than or equal to 0.00065683. >+PASS Max error for test 99 at offset 132162 is less than or equal to 0.00065683. >+PASS Number of failed tests with an acceptable relative tolerance of 0.00065683 is equal to 0. >+PASS < [test] All assertions passed. (total 102 assertions) >+PASS # AUDIT TASK RUNNER FINISHED: 1 tasks ran successfully. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setTargetAtTime.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setTargetAtTime.html >new file mode 100644 >index 0000000000000000000000000000000000000000..faf00c007b375a365bbb6b00e4051d44852d0fdc >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setTargetAtTime.html >@@ -0,0 +1,61 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test AudioParam.setTargetAtTime >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audioparam-testing.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ // Play a long DC signal out through an AudioGainNode, and call >+ // setValueAtTime() and setTargetAtTime at regular intervals to set the >+ // starting value and the target value. Each time interval has a ramp with >+ // a different starting and target value so that there is a discontinuity >+ // at each time interval boundary. The discontinuity is for testing >+ // timing. Also, we alternate between an increasing and decreasing ramp >+ // for each interval. >+ >+ // Number of tests to run. >+ let numberOfTests = 100; >+ >+ // Max allowed difference between the rendered data and the expected >+ // result. >+ let maxAllowedError = 6.5683e-4 >+ >+ // The AudioGainNode starts with this value instead of the default value. >+ let initialValue = 100; >+ >+ // Set the gain node value to the specified value at the specified time. >+ function setValue(value, time) { >+ gainNode.gain.setValueAtTime(value, time); >+ } >+ >+ // Generate an exponential approach starting at |startTime| with a target >+ // value of |value|. >+ function automation(value, startTime, endTime){ >+ // endTime is not used for setTargetAtTime. >+ gainNode.gain.setTargetAtTime(value, startTime, timeConstant)} >+ >+ audit.define( >+ { >+ label: 'test', >+ description: 'AudioParam setTargetAtTime() functionality.' >+ }, >+ function(task, should) { >+ createAudioGraphAndTest( >+ task, should, numberOfTests, initialValue, setValue, automation, >+ 'setTargetAtTime()', maxAllowedError, >+ createExponentialApproachArray); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueAtTime-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueAtTime-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..e558a5c447c5be8a8c7bbf4a1d91e9b213878c7f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueAtTime-expected.txt >@@ -0,0 +1,108 @@ >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] AudioParam setValueAtTime() functionality. >+PASS Number of tests started and ended at the correct time is equal to 100. >+PASS Max error for test 0 at offset 0 is less than or equal to 6e-8. >+PASS Max error for test 1 at offset 1323 is less than or equal to 6e-8. >+PASS Max error for test 2 at offset 2646 is less than or equal to 6e-8. >+PASS Max error for test 3 at offset 3969 is less than or equal to 6e-8. >+PASS Max error for test 4 at offset 5292 is less than or equal to 6e-8. >+PASS Max error for test 5 at offset 6615 is less than or equal to 6e-8. >+PASS Max error for test 6 at offset 7938 is less than or equal to 6e-8. >+PASS Max error for test 7 at offset 9261 is less than or equal to 6e-8. >+PASS Max error for test 8 at offset 10584 is less than or equal to 6e-8. >+PASS Max error for test 9 at offset 11907 is less than or equal to 6e-8. >+PASS Max error for test 10 at offset 13230 is less than or equal to 6e-8. >+PASS Max error for test 11 at offset 14553 is less than or equal to 6e-8. >+PASS Max error for test 12 at offset 15876 is less than or equal to 6e-8. >+PASS Max error for test 13 at offset 17199 is less than or equal to 6e-8. >+PASS Max error for test 14 at offset 18522 is less than or equal to 6e-8. >+PASS Max error for test 15 at offset 19845 is less than or equal to 6e-8. >+PASS Max error for test 16 at offset 21168 is less than or equal to 6e-8. >+PASS Max error for test 17 at offset 22491 is less than or equal to 6e-8. >+PASS Max error for test 18 at offset 23814 is less than or equal to 6e-8. >+PASS Max error for test 19 at offset 25137 is less than or equal to 6e-8. >+PASS Max error for test 20 at offset 26460 is less than or equal to 6e-8. >+PASS Max error for test 21 at offset 27783 is less than or equal to 6e-8. >+PASS Max error for test 22 at offset 29106 is less than or equal to 6e-8. >+PASS Max error for test 23 at offset 30429 is less than or equal to 6e-8. >+PASS Max error for test 24 at offset 31752 is less than or equal to 6e-8. >+PASS Max error for test 25 at offset 33075 is less than or equal to 6e-8. >+PASS Max error for test 26 at offset 34398 is less than or equal to 6e-8. >+PASS Max error for test 27 at offset 35721 is less than or equal to 6e-8. >+PASS Max error for test 28 at offset 37044 is less than or equal to 6e-8. >+PASS Max error for test 29 at offset 38367 is less than or equal to 6e-8. >+PASS Max error for test 30 at offset 39690 is less than or equal to 6e-8. >+PASS Max error for test 31 at offset 41013 is less than or equal to 6e-8. >+PASS Max error for test 32 at offset 42336 is less than or equal to 6e-8. >+PASS Max error for test 33 at offset 43659 is less than or equal to 6e-8. >+PASS Max error for test 34 at offset 44982 is less than or equal to 6e-8. >+PASS Max error for test 35 at offset 46305 is less than or equal to 6e-8. >+PASS Max error for test 36 at offset 47628 is less than or equal to 6e-8. >+PASS Max error for test 37 at offset 48951 is less than or equal to 6e-8. >+PASS Max error for test 38 at offset 50274 is less than or equal to 6e-8. >+PASS Max error for test 39 at offset 51597 is less than or equal to 6e-8. >+PASS Max error for test 40 at offset 52920 is less than or equal to 6e-8. >+PASS Max error for test 41 at offset 54243 is less than or equal to 6e-8. >+PASS Max error for test 42 at offset 55566 is less than or equal to 6e-8. >+PASS Max error for test 43 at offset 56889 is less than or equal to 6e-8. >+PASS Max error for test 44 at offset 58212 is less than or equal to 6e-8. >+PASS Max error for test 45 at offset 59535 is less than or equal to 6e-8. >+PASS Max error for test 46 at offset 60858 is less than or equal to 6e-8. >+PASS Max error for test 47 at offset 62181 is less than or equal to 6e-8. >+PASS Max error for test 48 at offset 63504 is less than or equal to 6e-8. >+PASS Max error for test 49 at offset 64827 is less than or equal to 6e-8. >+PASS Max error for test 50 at offset 66150 is less than or equal to 6e-8. >+PASS Max error for test 51 at offset 67473 is less than or equal to 6e-8. >+PASS Max error for test 52 at offset 68796 is less than or equal to 6e-8. >+PASS Max error for test 53 at offset 70119 is less than or equal to 6e-8. >+PASS Max error for test 54 at offset 71442 is less than or equal to 6e-8. >+PASS Max error for test 55 at offset 72765 is less than or equal to 6e-8. >+PASS Max error for test 56 at offset 74088 is less than or equal to 6e-8. >+PASS Max error for test 57 at offset 75411 is less than or equal to 6e-8. >+PASS Max error for test 58 at offset 76734 is less than or equal to 6e-8. >+PASS Max error for test 59 at offset 78057 is less than or equal to 6e-8. >+PASS Max error for test 60 at offset 79380 is less than or equal to 6e-8. >+PASS Max error for test 61 at offset 80703 is less than or equal to 6e-8. >+PASS Max error for test 62 at offset 82026 is less than or equal to 6e-8. >+PASS Max error for test 63 at offset 83349 is less than or equal to 6e-8. >+PASS Max error for test 64 at offset 84672 is less than or equal to 6e-8. >+PASS Max error for test 65 at offset 85995 is less than or equal to 6e-8. >+PASS Max error for test 66 at offset 87318 is less than or equal to 6e-8. >+PASS Max error for test 67 at offset 88641 is less than or equal to 6e-8. >+PASS Max error for test 68 at offset 89964 is less than or equal to 6e-8. >+PASS Max error for test 69 at offset 91287 is less than or equal to 6e-8. >+PASS Max error for test 70 at offset 92610 is less than or equal to 6e-8. >+PASS Max error for test 71 at offset 93933 is less than or equal to 6e-8. >+PASS Max error for test 72 at offset 95256 is less than or equal to 6e-8. >+PASS Max error for test 73 at offset 96579 is less than or equal to 6e-8. >+PASS Max error for test 74 at offset 97902 is less than or equal to 6e-8. >+PASS Max error for test 75 at offset 99225 is less than or equal to 6e-8. >+PASS Max error for test 76 at offset 100548 is less than or equal to 6e-8. >+PASS Max error for test 77 at offset 101871 is less than or equal to 6e-8. >+PASS Max error for test 78 at offset 103194 is less than or equal to 6e-8. >+PASS Max error for test 79 at offset 104517 is less than or equal to 6e-8. >+PASS Max error for test 80 at offset 105840 is less than or equal to 6e-8. >+PASS Max error for test 81 at offset 107163 is less than or equal to 6e-8. >+PASS Max error for test 82 at offset 108486 is less than or equal to 6e-8. >+PASS Max error for test 83 at offset 109809 is less than or equal to 6e-8. >+PASS Max error for test 84 at offset 111132 is less than or equal to 6e-8. >+PASS Max error for test 85 at offset 112455 is less than or equal to 6e-8. >+PASS Max error for test 86 at offset 113778 is less than or equal to 6e-8. >+PASS Max error for test 87 at offset 115101 is less than or equal to 6e-8. >+PASS Max error for test 88 at offset 116424 is less than or equal to 6e-8. >+PASS Max error for test 89 at offset 117747 is less than or equal to 6e-8. >+PASS Max error for test 90 at offset 119070 is less than or equal to 6e-8. >+PASS Max error for test 91 at offset 120393 is less than or equal to 6e-8. >+PASS Max error for test 92 at offset 121716 is less than or equal to 6e-8. >+PASS Max error for test 93 at offset 123039 is less than or equal to 6e-8. >+PASS Max error for test 94 at offset 124362 is less than or equal to 6e-8. >+PASS Max error for test 95 at offset 125685 is less than or equal to 6e-8. >+PASS Max error for test 96 at offset 127008 is less than or equal to 6e-8. >+PASS Max error for test 97 at offset 128331 is less than or equal to 6e-8. >+PASS Max error for test 98 at offset 129654 is less than or equal to 6e-8. >+PASS Max error for test 99 at offset 130977 is less than or equal to 6e-8. >+PASS Number of failed tests with an acceptable relative tolerance of 6e-8 is equal to 0. >+PASS < [test] All assertions passed. (total 102 assertions) >+PASS # AUDIT TASK RUNNER FINISHED: 1 tasks ran successfully. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueAtTime.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueAtTime.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ab2edfd009f1320fdb8e0a49dffb984baed36f05 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueAtTime.html >@@ -0,0 +1,57 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ audioparam-setValueAtTime.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audioparam-testing.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ // Play a long DC signal out through an AudioGainNode, and call >+ // setValueAtTime() at regular intervals to set the value for the duration >+ // of the interval. Each time interval has different value so that there >+ // is a discontinuity at each time interval boundary. The discontinuity >+ // is for testing timing. >+ >+ // Number of tests to run. >+ let numberOfTests = 100; >+ >+ // Max allowed difference between the rendered data and the expected >+ // result. >+ let maxAllowedError = 6e-8; >+ >+ // Set the gain node value to the specified value at the specified time. >+ function setValue(value, time) { >+ gainNode.gain.setValueAtTime(value, time); >+ } >+ >+ // For testing setValueAtTime(), we don't need to do anything for >+ // automation. because the value at the beginning of the interval is set >+ // by setValue and it remains constant for the duration, which is what we >+ // want. >+ function automation(value, startTime, endTime) { >+ // Do nothing. >+ } >+ >+ audit.define( >+ { >+ label: 'test', >+ description: 'AudioParam setValueAtTime() functionality.' >+ }, >+ function(task, should) { >+ createAudioGraphAndTest( >+ task, should, numberOfTests, 1, setValue, automation, >+ 'setValueAtTime()', maxAllowedError, createConstantArray); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..7db516c675f62007fe8d2afe368f30570a528996 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions-expected.txt >@@ -0,0 +1,32 @@ >+CONSOLE MESSAGE: line 201: TypeError: undefined is not an object (evaluating 'context.startRendering() >+ .then') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'context.startRendering() >+ .then') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [setValueCurve] >+PASS setValueCurveAtTime(curve, 0.0125, 0.0125) did not throw an exception. >+FAIL X setValueAtTime(1, 0.018750000000000003) did not throw an exception. assert_true: expected true got false >+FAIL X linearRampToValueAtTime(1, 0.018750000000000003) did not throw an exception. assert_true: expected true got false >+FAIL X exponentialRampToValueAtTime(1, 0.018750000000000003) did not throw an exception. assert_true: expected true got false >+FAIL X setTargetAtTime(1, 0.018750000000000003, 1) did not throw an exception. assert_true: expected true got false >+PASS setValueAtTime(1, 0.026250000000000002) did not throw an exception. >+FAIL < [setValueCurve] 4 out of 6 assertions were failed. assert_true: expected true got false >+PASS > [automations] >+PASS linearRampToValueAtTime(1, 0.0125) did not throw an exception. >+PASS exponentialRampToValueAtTime(1, 0.025) did not throw an exception. >+PASS setTargetAtTime(1, 0.037500000000000006, 0.1) did not throw an exception. >+PASS setValueCurveAtTime(curve, 0.05, 0.1) did not throw an exception. >+FAIL X setValueCurveAtTime(curve, 0.00625, 0.01) did not throw an exception. assert_true: expected true got false >+FAIL X setValueCurveAtTime(curve, 0.018750000000000003, 0.01) did not throw an exception. assert_true: expected true got false >+FAIL X setValueCurveAtTime(curve, 0.03125, 0.01) did not throw an exception. assert_true: expected true got false >+FAIL X setValueCurveAtTime(curve, 0.043750000000000004, 0.01) did not throw an exception. assert_true: expected true got false >+FAIL X setValueCurveAtTime([NaN, NaN], 0.043750000000000004, 0.01) did not throw an exception. assert_true: expected true got false >+FAIL X setValueCurveAtTime([1, Infinity], 0.043750000000000004, 0.01) did not throw an exception. assert_true: expected true got false >+PASS delayTime.setValueCurveAtTime([1, 5], 0.043750000000000004, 0.01) did not throw an exception. >+FAIL X delayTime.setValueCurveAtTime([1, 5, Infinity], 0.043750000000000004, 0.01) did not throw an exception. assert_true: expected true got false >+FAIL X setValueCurveAtTime(curve, 0.031415926535897934, 0.01) did not throw an exception. assert_true: expected true got false >+FAIL < [automations] 8 out of 13 assertions were failed. assert_true: expected true got false >+PASS > [catch-exception] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions.html >new file mode 100644 >index 0000000000000000000000000000000000000000..590dcbd5a29be09b3be88cae1b89d545df7fe5c6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions.html >@@ -0,0 +1,320 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Exceptions from setValueCurveAtTime >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let sampleRate = 48000; >+ // Some short duration because we don't need to run the test for very >+ // long. >+ let testDurationSec = 0.125; >+ let testDurationFrames = testDurationSec * sampleRate; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('setValueCurve', (task, should) => { >+ let success = true; >+ let context = >+ new OfflineAudioContext(1, testDurationFrames, sampleRate); >+ let g = context.createGain(); >+ let curve = new Float32Array(2); >+ >+ // Start time and duration for setValueCurveAtTime >+ let curveStartTime = 0.1 * testDurationSec; >+ let duration = 0.1 * testDurationSec; >+ >+ // Some time that is known to during the setValueCurveTime interval. >+ let automationTime = curveStartTime + duration / 2; >+ >+ should( >+ () => { >+ g.gain.setValueCurveAtTime(curve, curveStartTime, duration); >+ }, >+ 'setValueCurveAtTime(curve, ' + curveStartTime + ', ' + duration + >+ ')') >+ .notThrow(); >+ >+ should( >+ function() { >+ g.gain.setValueAtTime(1, automationTime); >+ }, >+ 'setValueAtTime(1, ' + automationTime + ')') >+ .throw('NotSupportedError'); >+ >+ should( >+ function() { >+ g.gain.linearRampToValueAtTime(1, automationTime); >+ }, >+ 'linearRampToValueAtTime(1, ' + automationTime + ')') >+ .throw('NotSupportedError'); >+ >+ should( >+ function() { >+ g.gain.exponentialRampToValueAtTime(1, automationTime); >+ }, >+ 'exponentialRampToValueAtTime(1, ' + automationTime + ')') >+ .throw('NotSupportedError'); >+ >+ should( >+ function() { >+ g.gain.setTargetAtTime(1, automationTime, 1); >+ }, >+ 'setTargetAtTime(1, ' + automationTime + ', 1)') >+ .throw('NotSupportedError'); >+ >+ should( >+ function() { >+ g.gain.setValueAtTime(1, curveStartTime + 1.1 * duration); >+ }, >+ 'setValueAtTime(1, ' + (curveStartTime + 1.1 * duration) + ')') >+ .notThrow(); >+ >+ task.done(); >+ }); >+ >+ audit.define('automations', (task, should) => { >+ let context = >+ new OfflineAudioContext(1, testDurationFrames, sampleRate); >+ let g = context.createGain(); >+ >+ let curve = new Float32Array(2); >+ // Start time and duration for setValueCurveAtTime >+ let startTime = 0; >+ let timeInterval = testDurationSec / 10; >+ let time; >+ >+ startTime += timeInterval; >+ should(() => { >+ g.gain.linearRampToValueAtTime(1, startTime); >+ }, 'linearRampToValueAtTime(1, ' + startTime + ')').notThrow(); >+ >+ startTime += timeInterval; >+ should(() => { >+ g.gain.exponentialRampToValueAtTime(1, startTime); >+ }, 'exponentialRampToValueAtTime(1, ' + startTime + ')').notThrow(); >+ >+ startTime += timeInterval; >+ should(() => { >+ g.gain.setTargetAtTime(1, startTime, 0.1); >+ }, 'setTargetAtTime(1, ' + startTime + ', 0.1)').notThrow(); >+ >+ startTime += timeInterval; >+ should(() => { >+ g.gain.setValueCurveAtTime(curve, startTime, 0.1); >+ }, 'setValueCurveAtTime(curve, ' + startTime + ', 0.1)').notThrow(); >+ >+ // Now try to setValueCurve that overlaps each of the above automations >+ startTime = timeInterval / 2; >+ >+ for (let k = 0; k < 4; ++k) { >+ time = startTime + timeInterval * k; >+ should( >+ () => { >+ g.gain.setValueCurveAtTime(curve, time, 0.01); >+ }, >+ 'setValueCurveAtTime(curve, ' + time + ', 0.01)') >+ .throw('NotSupportedError'); >+ } >+ >+ // Elements of setValueCurve should be finite. >+ should( >+ () => { >+ g.gain.setValueCurveAtTime( >+ Float32Array.from([NaN, NaN]), time, 0.01); >+ }, >+ 'setValueCurveAtTime([NaN, NaN], ' + time + ', 0.01)') >+ .throw('TypeError'); >+ >+ should( >+ () => { >+ g.gain.setValueCurveAtTime( >+ Float32Array.from([1, Infinity]), time, 0.01); >+ }, >+ 'setValueCurveAtTime([1, Infinity], ' + time + ', 0.01)') >+ .throw('TypeError'); >+ >+ let d = context.createDelay(); >+ // Check that we get warnings for out-of-range values and also throw for >+ // non-finite values. >+ should( >+ () => { >+ d.delayTime.setValueCurveAtTime( >+ Float32Array.from([1, 5]), time, 0.01); >+ }, >+ 'delayTime.setValueCurveAtTime([1, 5], ' + time + ', 0.01)') >+ .notThrow(); >+ >+ should( >+ () => { >+ d.delayTime.setValueCurveAtTime( >+ Float32Array.from([1, 5, Infinity]), time, 0.01); >+ }, >+ 'delayTime.setValueCurveAtTime([1, 5, Infinity], ' + time + >+ ', 0.01)') >+ .throw('TypeError'); >+ >+ // One last test that prints out lots of digits for the time. >+ time = Math.PI / 100; >+ should( >+ () => { >+ g.gain.setValueCurveAtTime(curve, time, 0.01); >+ }, >+ 'setValueCurveAtTime(curve, ' + time + ', 0.01)') >+ .throw('NotSupportedError'); >+ >+ task.done(); >+ }); >+ >+ audit.define('catch-exception', (task, should) => { >+ // Verify that the curve isn't inserted into the time line even if we >+ // catch the exception. >+ let success = true; >+ let context = >+ new OfflineAudioContext(1, testDurationFrames, sampleRate); >+ let gain = context.createGain(); >+ let source = context.createBufferSource(); >+ let buffer = context.createBuffer(1, 1, context.sampleRate); >+ buffer.getChannelData(0)[0] = 1; >+ source.buffer = buffer; >+ source.loop = true; >+ >+ source.connect(gain); >+ gain.connect(context.destination); >+ >+ gain.gain.setValueAtTime(1, 0); >+ try { >+ // The value curve has an invalid element. This automation shouldn't >+ // be inserted into the timeline at all. >+ gain.gain.setValueCurveAtTime( >+ Float32Array.from([0, NaN]), 128 / context.sampleRate, .5); >+ } catch (e) { >+ }; >+ source.start(); >+ >+ context.startRendering() >+ .then(function(resultBuffer) { >+ // Since the setValueCurve wasn't inserted, the output should be >+ // exactly 1 for the entire duration. >+ should( >+ resultBuffer.getChannelData(0), >+ 'Handled setValueCurve exception so output') >+ .beConstantValueOf(1); >+ >+ }) >+ .then(() => task.done()); >+ }); >+ >+ audit.define('start-end', (task, should) => { >+ let context = >+ new OfflineAudioContext(1, testDurationFrames, sampleRate); >+ let g = context.createGain(); >+ let curve = new Float32Array(2); >+ >+ // Verify that a setValueCurve can start at the end of an automation. >+ let time = 0; >+ let timeInterval = testDurationSec / 50; >+ should(() => { >+ g.gain.setValueAtTime(1, time); >+ }, 'setValueAtTime(1, ' + time + ')').notThrow(); >+ >+ time += timeInterval; >+ should(() => { >+ g.gain.linearRampToValueAtTime(0, time); >+ }, 'linearRampToValueAtTime(0, ' + time + ')').notThrow(); >+ >+ // setValueCurve starts at the end of the linear ramp. This should be >+ // fine. >+ should( >+ () => { >+ g.gain.setValueCurveAtTime(curve, time, timeInterval); >+ }, >+ 'setValueCurveAtTime(..., ' + time + ', ' + timeInterval + ')') >+ .notThrow(); >+ >+ // exponentialRamp ending one interval past the setValueCurve should be >+ // fine. >+ time += 2 * timeInterval; >+ should(() => { >+ g.gain.exponentialRampToValueAtTime(1, time); >+ }, 'exponentialRampToValueAtTime(1, ' + time + ')').notThrow(); >+ >+ // setValueCurve starts at the end of the exponential ramp. This should >+ // be fine. >+ should( >+ () => { >+ g.gain.setValueCurveAtTime(curve, time, timeInterval); >+ }, >+ 'setValueCurveAtTime(..., ' + time + ', ' + timeInterval + ')') >+ .notThrow(); >+ >+ // setValueCurve at the end of the setValueCurve should be fine. >+ time += timeInterval; >+ should( >+ () => { >+ g.gain.setValueCurveAtTime(curve, time, timeInterval); >+ }, >+ 'setValueCurveAtTime(..., ' + time + ', ' + timeInterval + ')') >+ .notThrow(); >+ >+ // setValueAtTime at the end of setValueCurve should be fine. >+ time += timeInterval; >+ should(() => { >+ g.gain.setValueAtTime(0, time); >+ }, 'setValueAtTime(0, ' + time + ')').notThrow(); >+ >+ // setValueCurve at the end of setValueAtTime should be fine. >+ should( >+ () => { >+ g.gain.setValueCurveAtTime(curve, time, timeInterval); >+ }, >+ 'setValueCurveAtTime(..., ' + time + ', ' + timeInterval + ')') >+ .notThrow(); >+ >+ // setTarget starting at the end of setValueCurve should be fine. >+ time += timeInterval; >+ should(() => { >+ g.gain.setTargetAtTime(1, time, 1); >+ }, 'setTargetAtTime(1, ' + time + ', 1)').notThrow(); >+ >+ task.done(); >+ }); >+ >+ audit.define('curve lengths', (task, should) => { >+ let context = >+ new OfflineAudioContext(1, testDurationFrames, sampleRate); >+ let g = context.createGain(); >+ let time = 0; >+ >+ // Check for invalid curve lengths >+ should( >+ () => { >+ g.gain.setValueCurveAtTime(Float32Array.from([]), time, 0.01); >+ }, >+ 'setValueCurveAtTime([], ' + time + ', 0.01)') >+ .throw('InvalidStateError'); >+ >+ should( >+ () => { >+ g.gain.setValueCurveAtTime(Float32Array.from([1]), time, 0.01); >+ }, >+ 'setValueCurveAtTime([1], ' + time + ', 0.01)') >+ .throw('InvalidStateError'); >+ >+ should(() => { >+ g.gain.setValueCurveAtTime(Float32Array.from([1, 2]), time, 0.01); >+ }, 'setValueCurveAtTime([1,2], ' + time + ', 0.01)').notThrow(); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurveAtTime-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurveAtTime-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..e0cd64b3ab998f3930f8b9344194601cb348c6a7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurveAtTime-expected.txt >@@ -0,0 +1,28 @@ >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] AudioParam setValueCurveAtTime() functionality. >+PASS Number of tests started and ended at the correct time is equal to 20. >+FAIL X Max error for test 0 at offset 1304 is not less than or equal to 0.0000037194. Got 0.030871472751557993. assert_true: expected true got false >+FAIL X Max error for test 1 at offset 2627 is not less than or equal to 0.0000037194. Got 0.030871472751557993. assert_true: expected true got false >+FAIL X Max error for test 2 at offset 3950 is not less than or equal to 0.0000037194. Got 0.030871472751543783. assert_true: expected true got false >+FAIL X Max error for test 3 at offset 5273 is not less than or equal to 0.0000037194. Got 0.030871472751543783. assert_true: expected true got false >+FAIL X Max error for test 4 at offset 6596 is not less than or equal to 0.0000037194. Got 0.030871472751543783. assert_true: expected true got false >+FAIL X Max error for test 5 at offset 7919 is not less than or equal to 0.0000037194. Got 0.030871472751543783. assert_true: expected true got false >+FAIL X Max error for test 6 at offset 9242 is not less than or equal to 0.0000037194. Got 0.030871472751543783. assert_true: expected true got false >+FAIL X Max error for test 7 at offset 10565 is not less than or equal to 0.0000037194. Got 0.030871472751543783. assert_true: expected true got false >+FAIL X Max error for test 8 at offset 11888 is not less than or equal to 0.0000037194. Got 0.030871472751586526. assert_true: expected true got false >+FAIL X Max error for test 9 at offset 13211 is not less than or equal to 0.0000037194. Got 0.03087147275151525. assert_true: expected true got false >+FAIL X Max error for test 10 at offset 14534 is not less than or equal to 0.0000037194. Got 0.03087147275151525. assert_true: expected true got false >+FAIL X Max error for test 11 at offset 15857 is not less than or equal to 0.0000037194. Got 0.030871472751508144. assert_true: expected true got false >+FAIL X Max error for test 12 at offset 17180 is not less than or equal to 0.0000037194. Got 0.030871472751586526. assert_true: expected true got false >+FAIL X Max error for test 13 at offset 18503 is not less than or equal to 0.0000037194. Got 0.03087147275151525. assert_true: expected true got false >+FAIL X Max error for test 14 at offset 19826 is not less than or equal to 0.0000037194. Got 0.03087147275151525. assert_true: expected true got false >+FAIL X Max error for test 15 at offset 21149 is not less than or equal to 0.0000037194. Got 0.030871472751508144. assert_true: expected true got false >+FAIL X Max error for test 16 at offset 22472 is not less than or equal to 0.0000037194. Got 0.030871472751586526. assert_true: expected true got false >+FAIL X Max error for test 17 at offset 23795 is not less than or equal to 0.0000037194. Got 0.030871472751586526. assert_true: expected true got false >+FAIL X Max error for test 18 at offset 25118 is not less than or equal to 0.0000037194. Got 0.03087147275143698. assert_true: expected true got false >+FAIL X Max error for test 19 at offset 26441 is not less than or equal to 0.0000037194. Got 0.030871472751586526. assert_true: expected true got false >+PASS Number of failed tests with an acceptable relative tolerance of 0.0000037194 is equal to 0. >+FAIL < [test] 20 out of 22 assertions were failed. assert_true: expected true got false >+FAIL # AUDIT TASK RUNNER FINISHED: 1 out of 1 tasks were failed. assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurveAtTime.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurveAtTime.html >new file mode 100644 >index 0000000000000000000000000000000000000000..de8406244bc386981c0527629e3685f250c6a659 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurveAtTime.html >@@ -0,0 +1,71 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test AudioParam.setValueCurveAtTime >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audioparam-testing.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ // Play a long DC signal out through an AudioGainNode and for each time >+ // interval call setValueCurveAtTime() to set the values for the duration >+ // of the interval. Each curve is a sine wave, and we assume that the >+ // time interval is not an exact multiple of the period. This causes a >+ // discontinuity between time intervals which is used to test timing. >+ >+ // Number of tests to run. >+ let numberOfTests = 20; >+ >+ // Max allowed difference between the rendered data and the expected >+ // result. Because of the linear interpolation, the rendered curve isn't >+ // exactly the same as the reference. This value is experimentally >+ // determined. >+ let maxAllowedError = 3.7194e-6; >+ >+ // The amplitude of the sine wave. >+ let sineAmplitude = 1; >+ >+ // Frequency of the sine wave. >+ let freqHz = 440; >+ >+ // Curve to use for setValueCurveAtTime(). >+ let curve; >+ >+ // Sets the curve data for the entire time interval. >+ function automation(value, startTime, endTime) { >+ gainNode.gain.setValueCurveAtTime( >+ curve, startTime, endTime - startTime); >+ } >+ >+ audit.define( >+ { >+ label: 'test', >+ description: 'AudioParam setValueCurveAtTime() functionality.' >+ }, >+ function(task, should) { >+ // The curve of values to use. >+ curve = createSineWaveArray( >+ timeInterval, freqHz, sineAmplitude, sampleRate); >+ >+ createAudioGraphAndTest( >+ task, should, numberOfTests, sineAmplitude, >+ function(k) { >+ // Don't need to set the value. >+ }, >+ automation, 'setValueCurveAtTime()', maxAllowedError, >+ createReferenceSineArray, >+ 2 * Math.PI * sineAmplitude * freqHz / sampleRate, >+ differenceErrorMetric); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-summingjunction-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-summingjunction-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..f9ab1812fc5e4d97a92ec16250103b5e717f8f8e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-summingjunction-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 111: TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-summingjunction.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-summingjunction.html >new file mode 100644 >index 0000000000000000000000000000000000000000..9084942f7032cd00d9d57b8d4d1f6ba2742ab57f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-summingjunction.html >@@ -0,0 +1,120 @@ >+<!DOCTYPE html> >+<!-- >+Tests that multiple audio-rate signals (AudioNode outputs) can be connected to an AudioParam >+and that these signals are summed, along with the AudioParams intrinsic value. >+--> >+<html> >+ <head> >+ <title> >+ audioparam-summingjunction.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/mix-testing.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ let sampleRate = 44100.0; >+ let lengthInSeconds = 1; >+ >+ let context = 0; >+ >+ // Buffers used by the two gain controlling sources. >+ let linearRampBuffer; >+ let toneBuffer; >+ let toneFrequency = 440; >+ >+ // Arbitrary non-zero value. >+ let baselineGain = 5; >+ >+ // Allow for a small round-off error. >+ let maxAllowedError = 1e-6; >+ >+ function checkResult(renderedBuffer, should) { >+ let renderedData = renderedBuffer.getChannelData(0); >+ >+ // Get buffer data from the two sources used to control gain. >+ let linearRampData = linearRampBuffer.getChannelData(0); >+ let toneData = toneBuffer.getChannelData(0); >+ >+ let n = renderedBuffer.length; >+ >+ should(n, 'Rendered signal length').beEqualTo(linearRampBuffer.length); >+ >+ // Check that the rendered result exactly matches the sum of the >+ // intrinsic gain plus the two sources used to control gain. This is >+ // because we're changing the gain of a signal having constant value 1. >+ let success = true; >+ for (let i = 0; i < n; ++i) { >+ let expectedValue = baselineGain + linearRampData[i] + toneData[i]; >+ let error = Math.abs(expectedValue - renderedData[i]); >+ >+ if (error > maxAllowedError) { >+ success = false; >+ break; >+ } >+ } >+ >+ should( >+ success, >+ 'Rendered signal matches sum of two audio-rate gain changing signals plus baseline gain') >+ .beTrue(); >+ } >+ >+ audit.define('test', function(task, should) { >+ let sampleFrameLength = sampleRate * lengthInSeconds; >+ >+ // Create offline audio context. >+ context = new OfflineAudioContext(1, sampleFrameLength, sampleRate); >+ >+ // Create buffer used by the source which will have its gain controlled. >+ let constantOneBuffer = >+ createConstantBuffer(context, sampleFrameLength, 1); >+ let constantSource = context.createBufferSource(); >+ constantSource.buffer = constantOneBuffer; >+ >+ // Create 1st buffer used to control gain (a linear ramp). >+ linearRampBuffer = createLinearRampBuffer(context, sampleFrameLength); >+ let gainSource1 = context.createBufferSource(); >+ gainSource1.buffer = linearRampBuffer; >+ >+ // Create 2st buffer used to control gain (a simple sine wave tone). >+ toneBuffer = >+ createToneBuffer(context, toneFrequency, lengthInSeconds, 1); >+ let gainSource2 = context.createBufferSource(); >+ gainSource2.buffer = toneBuffer; >+ >+ // Create a gain node controlling the gain of constantSource and make >+ // the connections. >+ let gainNode = context.createGain(); >+ >+ // Intrinsic baseline gain. >+ // This gain value should be summed with gainSource1 and gainSource2. >+ gainNode.gain.value = baselineGain; >+ >+ constantSource.connect(gainNode); >+ gainNode.connect(context.destination); >+ >+ // Connect two audio-rate signals to control the .gain AudioParam. >+ gainSource1.connect(gainNode.gain); >+ gainSource2.connect(gainNode.gain); >+ >+ // Start all sources at time 0. >+ constantSource.start(0); >+ gainSource1.start(0); >+ gainSource2.start(0); >+ >+ context.startRendering().then(buffer => { >+ checkResult(buffer, should); >+ task.done(); >+ }); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..52d6e4b8d0585bf5604ffb6df20f927889f7ccdf >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 94: TypeError: Not enough arguments >+ >+Harness Error (FAIL), message = TypeError: Not enough arguments >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [AudioBufferSourceNode] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate-testing.js b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate-testing.js >new file mode 100644 >index 0000000000000000000000000000000000000000..46d9d4a6e0c2fbe460b0398ab806450a9d5798ef >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate-testing.js >@@ -0,0 +1,117 @@ >+// Test k-rate vs a-rate AudioParams. >+// >+// |options| describes how the testing of the AudioParam should be done: >+// >+// nodeName: name of the AudioNode to be tested >+// nodeOptions: options to be used in the AudioNode constructor >+// >+// prefix: Prefix for all output messages (to make them unique for >+// testharness) >+// >+// rateSettings: A vector of dictionaries specifying how to set the automation >+// rate(s): >+// name: Name of the AudioParam >+// value: The automation rate for the AudioParam given by |name|. >+// >+// automations: A vector of dictionaries specifying how to automate each >+// AudioParam: >+// name: Name of the AudioParam >+// >+// methods: A vector of dictionaries specifying the automation methods to >+// be used for testing: >+// name: Automation method to call >+// options: Arguments for the automation method >+// >+// Testing is somewhat rudimentary. We create two nodes of the same type. One >+// node uses the default automation rates for each AudioParam (expecting them to >+// be a-rate). The second node sets the automation rate of AudioParams to >+// "k-rate". The set is speciified by |options.rateSettings|. >+// >+// For both of these nodes, the same set of automation methods (given by >+// |options.automations|) is applied. A simple oscillator is connected to each >+// node which in turn are connected to different channels of an offline context. >+// Channel 0 is the k-rate node output; channel 1, the a-rate output; and >+// channel 3, the difference between the outputs. >+// >+// Success is declared if the difference signal is not exactly zero. This means >+// the the automations did different things, as expected. >+// >+// The promise from |startRendering| is returned. >+function doTest(context, should, options) { >+ let merger = new ChannelMergerNode( >+ context, {numberOfInputs: context.destination.numberOfChannels}); >+ merger.connect(context.destination); >+ >+ let src = new OscillatorNode(context); >+ let kRateNode = new window[options.nodeName](context, options.nodeOptions); >+ let aRateNode = new window[options.nodeName](context, options.nodeOptions); >+ let inverter = new GainNode(context, {gain: -1}); >+ >+ // Set kRateNode filter to use k-rate params. >+ options.rateSettings.forEach(setting => { >+ kRateNode[setting.name].automationRate = setting.value; >+ // Mostly for documentation in the output. These should always >+ // pass. >+ should( >+ kRateNode[setting.name].automationRate, >+ `${options.prefix}: Setting ${ >+ setting.name >+ }.automationRate to "${setting.value}"`) >+ .beEqualTo(setting.value); >+ }); >+ >+ // Run through all automations for each node separately. (Mostly to keep >+ // output of automations together.) >+ options.automations.forEach(param => { >+ param.methods.forEach(method => { >+ // Most for documentation in the output. These should never throw. >+ let message = `${param.name}.${method.name}(${method.options})` >+ should(() => { >+ kRateNode[param.name][method.name](...method.options); >+ }, options.prefix + ': k-rate node: ' + message).notThrow(); >+ }); >+ }); >+ options.automations.forEach(param => { >+ param.methods.forEach(method => { >+ // Most for documentation in the output. These should never throw. >+ let message = `${param.name}.${method.name}(${method.options})` >+ should(() => { >+ aRateNode[param.name][method.name](...method.options); >+ }, options.prefix + ': a-rate node:' + message).notThrow(); >+ }); >+ }); >+ >+ // The k-rate result is channel 0, and the a-rate result is channel 1. >+ src.connect(kRateNode).connect(merger, 0, 0); >+ src.connect(aRateNode).connect(merger, 0, 1); >+ >+ // Compute the difference between the a-rate and k-rate results and send >+ // that to channel 2. >+ kRateNode.connect(merger, 0, 2); >+ aRateNode.connect(inverter).connect(merger, 0, 2); >+ >+ src.start(); >+ return context.startRendering().then(renderedBuffer => { >+ let kRateOutput = renderedBuffer.getChannelData(0); >+ let aRateOutput = renderedBuffer.getChannelData(1); >+ let diff = renderedBuffer.getChannelData(2); >+ >+ // Some informative messages to print out values of the k-rate and >+ // a-rate outputs. These should always pass. >+ should( >+ kRateOutput, `${options.prefix}: Output of k-rate ${options.nodeName}`) >+ .beEqualToArray(kRateOutput); >+ should( >+ aRateOutput, `${options.prefix}: Output of a-rate ${options.nodeName}`) >+ .beEqualToArray(aRateOutput); >+ >+ // The real test. If k-rate AudioParam is working correctly, the >+ // k-rate result MUST differ from the a-rate result. >+ should( >+ diff, >+ `${ >+ options.prefix >+ }: Difference between a-rate and k-rate ${options.nodeName}`) >+ .notBeConstantValueOf(0); >+ }); >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate.html >new file mode 100644 >index 0000000000000000000000000000000000000000..a3c789e2f2cbdb31e540bf5cc58850786b4ed73b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate.html >@@ -0,0 +1,167 @@ >+<!doctype html> >+<html> >+ <head> >+ <title>AudioParam.automationRate tests</title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ >+ <body> >+ <script> >+ // For each node that has an AudioParam, verify that the default >+ // |automationRate| has the expected value and that we can change it or >+ // throw an error if it can't be changed. >+ >+ // Any valid sample rate is fine; we don't actually render anything in the >+ // tests. >+ let sampleRate = 8000; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ // Array of tests. Each test is a dictonary consisting of the name of the >+ // node and an array specifying the AudioParam's of the node. This array >+ // in turn gives the name of the AudioParam, the default value for the >+ // |automationRate|, and whether it is fixed (isFixed). >+ const tests = [ >+ { >+ nodeName: 'AudioBufferSourceNode', >+ audioParams: [ >+ {name: 'detune', defaultRate: 'k-rate', isFixed: true}, >+ {name: 'playbackRate', defaultRate: 'k-rate', isFixed: true} >+ ] >+ }, >+ { >+ nodeName: 'BiquadFilterNode', >+ audioParams: [ >+ {name: 'frequency', defaultRate: 'a-rate', isFixed: false}, >+ {name: 'detune', defaultRate: 'a-rate', isFixed: false}, >+ {name: 'Q', defaultRate: 'a-rate', isFixed: false}, >+ {name: 'gain', defaultRate: 'a-rate', isFixed: false}, >+ ] >+ }, >+ { >+ nodeName: 'ConstantSourceNode', >+ audioParams: [{name: 'offset', defaultRate: 'a-rate', isFixed: false}] >+ }, >+ { >+ nodeName: 'DelayNode', >+ audioParams: >+ [{name: 'delayTime', defaultRate: 'a-rate', isFixed: false}] >+ }, >+ { >+ nodeName: 'DynamicsCompressorNode', >+ audioParams: [ >+ {name: 'threshold', defaultRate: 'k-rate', isFixed: true}, >+ {name: 'knee', defaultRate: 'k-rate', isFixed: true}, >+ {name: 'ratio', defaultRate: 'k-rate', isFixed: true}, >+ {name: 'attack', defaultRate: 'k-rate', isFixed: true}, >+ {name: 'release', defaultRate: 'k-rate', isFixed: true} >+ ] >+ }, >+ { >+ nodeName: 'GainNode', >+ audioParams: [{name: 'gain', defaultRate: 'a-rate', isFixed: false}] >+ }, >+ { >+ nodeName: 'OscillatorNode', >+ audioParams: [ >+ {name: 'frequency', defaultRate: 'a-rate', isFixed: false}, >+ {name: 'detune', defaultRate: 'a-rate', isFixed: false} >+ ] >+ }, >+ { >+ nodeName: 'PannerNode', >+ audioParams: [ >+ {name: 'positionX', defaultRate: 'a-rate', isFixed: false}, >+ {name: 'positionY', defaultRate: 'a-rate', isFixed: false}, >+ {name: 'positionZ', defaultRate: 'a-rate', isFixed: false}, >+ {name: 'orientationX', defaultRate: 'a-rate', isFixed: false}, >+ {name: 'orientationY', defaultRate: 'a-rate', isFixed: false}, >+ {name: 'orientationZ', defaultRate: 'a-rate', isFixed: false}, >+ ] >+ }, >+ { >+ nodeName: 'StereoPannerNode', >+ audioParams: [{name: 'pan', defaultRate: 'a-rate', isFixed: false}] >+ }, >+ ]; >+ >+ tests.forEach(test => { >+ // Define a separate test for each test entry. >+ audit.define(test.nodeName, (task, should) => { >+ let context = new OfflineAudioContext( >+ {length: sampleRate, sampleRate: sampleRate}); >+ // Construct the node and test each AudioParam of the node. >+ let node = new window[test.nodeName](context); >+ test.audioParams.forEach(param => { >+ testAudioParam( >+ should, {nodeName: test.nodeName, node: node, param: param}); >+ }); >+ >+ task.done(); >+ }); >+ }); >+ >+ // AudioListener needs it's own special test since it's not a node. >+ audit.define('AudioListener', (task, should) => { >+ let context = new OfflineAudioContext( >+ {length: sampleRate, sampleRate: sampleRate}); >+ >+ [{name: 'positionX', defaultRate: 'a-rate', isFixed: false}, >+ {name: 'positionY', defaultRate: 'a-rate', isFixed: false}, >+ {name: 'positionZ', defaultRate: 'a-rate', isFixed: false}, >+ {name: 'forwardX', defaultRate: 'a-rate', isFixed: false}, >+ {name: 'forwardY', defaultRate: 'a-rate', isFixed: false}, >+ {name: 'forwardZ', defaultRate: 'a-rate', isFixed: false}, >+ {name: 'upX', defaultRate: 'a-rate', isFixed: false}, >+ {name: 'upY', defaultRate: 'a-rate', isFixed: false}, >+ {name: 'upZ', defaultRate: 'a-rate', isFixed: false}, >+ ].forEach(param => { >+ testAudioParam(should, { >+ nodeName: 'AudioListener', >+ node: context.listener, >+ param: param >+ }); >+ }); >+ task.done(); >+ }); >+ >+ audit.run(); >+ >+ function testAudioParam(should, options) { >+ let param = options.param; >+ let audioParam = options.node[param.name]; >+ let defaultRate = param.defaultRate; >+ >+ // Verify that the default value is correct. >+ should( >+ audioParam.automationRate, >+ `Default ${options.nodeName}.${param.name}.automationRate`) >+ .beEqualTo(defaultRate); >+ >+ // Try setting the rate to a different rate. If the |automationRate| >+ // is fixed, expect an error. Otherwise, expect no error and expect >+ // the value is changed to the new value. >+ let newRate = defaultRate === 'a-rate' ? 'k-rate' : 'a-rate'; >+ let setMessage = `Set ${ >+ options.nodeName >+ }.${param.name}.automationRate to "${newRate}"` >+ >+ if (param.isFixed) { >+ should(() => audioParam.automationRate = newRate, setMessage) >+ .throw('InvalidStateError'); >+ } >+ else { >+ should(() => audioParam.automationRate = newRate, setMessage) >+ .notThrow(); >+ should( >+ audioParam.automationRate, >+ `${options.nodeName}.${param.name}.automationRate`) >+ .beEqualTo(newRate); >+ } >+ } >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..33d9944619560512b7587e2c02088071056c2177 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 24: TypeError: Not enough arguments >+ >+Harness Error (FAIL), message = TypeError: Not enough arguments >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [Insert same event at same time] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html >new file mode 100644 >index 0000000000000000000000000000000000000000..eab77c494d1161083f1fe73376492b177355995f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html >@@ -0,0 +1,314 @@ >+<!doctype html> >+<html> >+ <head> >+ <title> >+ Test Handling of Event Insertion >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audio-param.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ // Use a power of two for the sample rate so there's no round-off in >+ // computing time from frame. >+ let sampleRate = 16384; >+ >+ audit.define( >+ {label: 'Insert same event at same time'}, (task, should) => { >+ // Context for testing. >+ let context = new OfflineAudioContext( >+ {length: 16384, sampleRate: sampleRate}); >+ >+ // The source node to use. Automations will be scheduled here. >+ let src = new ConstantSourceNode(context, {offset: 0}); >+ src.connect(context.destination); >+ >+ // An array of tests to be done. Each entry specifies the event >+ // type and the event time. The events are inserted in the order >+ // given (in |values|), and the second event should replace the >+ // first, as required by the spec. >+ let testCases = [ >+ { >+ event: 'setValueAtTime', >+ frame: RENDER_QUANTUM_FRAMES, >+ values: [99, 1], >+ outputTestFrame: RENDER_QUANTUM_FRAMES, >+ expectedOutputValue: 1 >+ }, >+ { >+ event: 'linearRampToValueAtTime', >+ frame: 2 * RENDER_QUANTUM_FRAMES, >+ values: [99, 2], >+ outputTestFrame: 2 * RENDER_QUANTUM_FRAMES, >+ expectedOutputValue: 2 >+ }, >+ { >+ event: 'exponentialRampToValueAtTime', >+ frame: 3 * RENDER_QUANTUM_FRAMES, >+ values: [99, 3], >+ outputTestFrame: 3 * RENDER_QUANTUM_FRAMES, >+ expectedOutputValue: 3 >+ }, >+ { >+ event: 'setValueCurveAtTime', >+ frame: 3 * RENDER_QUANTUM_FRAMES, >+ values: [[98, 99], [3, 4]], >+ extraArgs: RENDER_QUANTUM_FRAMES / context.sampleRate, >+ outputTestFrame: 4 * RENDER_QUANTUM_FRAMES, >+ expectedOutputValue: 4 >+ } >+ ]; >+ >+ testCases.forEach(entry => { >+ entry.values.forEach(value => { >+ let eventTime = entry.frame / context.sampleRate; >+ let message = eventToString( >+ entry.event, value, eventTime, entry.extraArgs); >+ // This is mostly to print out the event that is getting >+ // inserted. It should never ever throw. >+ should(() => { >+ src.offset[entry.event](value, eventTime, entry.extraArgs); >+ }, message).notThrow(); >+ }); >+ }); >+ >+ src.start(); >+ >+ context.startRendering() >+ .then(audioBuffer => { >+ let audio = audioBuffer.getChannelData(0); >+ >+ // Look through the test cases to figure out what the correct >+ // output values should be. >+ testCases.forEach(entry => { >+ let expected = entry.expectedOutputValue; >+ let frame = entry.outputTestFrame; >+ let time = frame / context.sampleRate; >+ should( >+ audio[frame], `Output at frame ${frame} (time ${time})`) >+ .beEqualTo(expected); >+ }); >+ }) >+ .then(() => task.done()); >+ }); >+ >+ audit.define( >+ { >+ label: 'Linear + Expo', >+ description: 'Different events at same time' >+ }, >+ (task, should) => { >+ // Should be a linear ramp up to the event time, and after a >+ // constant value because the exponential ramp has ended. >+ let testCase = [ >+ {event: 'linearRampToValueAtTime', value: 2, relError: 0}, >+ {event: 'setValueAtTime', value: 99}, >+ {event: 'exponentialRampToValueAtTime', value: 3}, >+ ]; >+ let eventFrame = 2 * RENDER_QUANTUM_FRAMES; >+ let prefix = 'Linear+Expo: '; >+ >+ testEventInsertion(prefix, should, eventFrame, testCase) >+ .then(expectConstant(prefix, should, eventFrame, testCase)) >+ .then(() => task.done()); >+ }); >+ >+ audit.define( >+ { >+ label: 'Expo + Linear', >+ description: 'Different events at same time', >+ }, >+ (task, should) => { >+ // Should be an exponential ramp up to the event time, and after a >+ // constant value because the linear ramp has ended. >+ let testCase = [ >+ { >+ event: 'exponentialRampToValueAtTime', >+ value: 3, >+ relError: 4.2533e-6 >+ }, >+ {event: 'setValueAtTime', value: 99}, >+ {event: 'linearRampToValueAtTime', value: 2}, >+ ]; >+ let eventFrame = 2 * RENDER_QUANTUM_FRAMES; >+ let prefix = 'Expo+Linear: '; >+ >+ testEventInsertion(prefix, should, eventFrame, testCase) >+ .then(expectConstant(prefix, should, eventFrame, testCase)) >+ .then(() => task.done()); >+ }); >+ >+ audit.define( >+ { >+ label: 'Linear + SetTarget', >+ description: 'Different events at same time', >+ }, >+ (task, should) => { >+ // Should be a linear ramp up to the event time, and then a >+ // decaying value. >+ let testCase = [ >+ {event: 'linearRampToValueAtTime', value: 3, relError: 0}, >+ {event: 'setValueAtTime', value: 100}, >+ {event: 'setTargetAtTime', value: 0, extraArgs: 0.1}, >+ ]; >+ let eventFrame = 2 * RENDER_QUANTUM_FRAMES; >+ let prefix = 'Linear+SetTarget: '; >+ >+ testEventInsertion(prefix, should, eventFrame, testCase) >+ .then(audioBuffer => { >+ let audio = audioBuffer.getChannelData(0); >+ let prefix = 'Linear+SetTarget: '; >+ let eventTime = eventFrame / sampleRate; >+ let expectedValue = methodMap[testCase[0].event]( >+ (eventFrame - 1) / sampleRate, 1, 0, testCase[0].value, >+ eventTime); >+ should( >+ audio[eventFrame - 1], >+ prefix + >+ `At time ${ >+ (eventFrame - 1) / sampleRate >+ } (frame ${eventFrame - 1}) output`) >+ .beCloseTo( >+ expectedValue, >+ {threshold: testCase[0].relError || 0}); >+ >+ // The setValue should have taken effect >+ should( >+ audio[eventFrame], >+ prefix + >+ `At time ${eventTime} (frame ${eventFrame}) output`) >+ .beEqualTo(testCase[1].value); >+ >+ // The final event is setTarget. Compute the expected output. >+ let actual = audio.slice(eventFrame); >+ let expected = new Float32Array(actual.length); >+ for (let k = 0; k < expected.length; ++k) { >+ let t = (eventFrame + k) / sampleRate; >+ expected[k] = audioParamSetTarget( >+ t, testCase[1].value, eventTime, testCase[2].value, >+ testCase[2].extraArgs); >+ } >+ should( >+ actual, >+ prefix + >+ `At time ${eventTime} (frame ${ >+ eventFrame >+ }) and later`) >+ .beCloseToArray(expected, {relativeThreshold: 1.7807e-7}); >+ }) >+ .then(() => task.done()); >+ }); >+ >+ >+ audit.run(); >+ >+ // Takes a list of |testCases| consisting of automation methods and >+ // schedules them to occur at |eventFrame|. |prefix| is a prefix for >+ // messages produced by |should|. >+ // >+ // Each item in |testCases| is a dictionary with members: >+ // event - the name of automation method to be inserted, >+ // value - the value for the event, >+ // extraArgs - extra arguments if the event needs more than the value >+ // and time (such as setTargetAtTime). >+ function testEventInsertion(prefix, should, eventFrame, testCases) { >+ let context = new OfflineAudioContext( >+ {length: 4 * RENDER_QUANTUM_FRAMES, sampleRate: sampleRate}); >+ >+ // The source node to use. Automations will be scheduled here. >+ let src = new ConstantSourceNode(context, {offset: 0}); >+ src.connect(context.destination); >+ >+ // Initialize value to 1 at the beginning. >+ src.offset.setValueAtTime(1, 0); >+ >+ // Test automations have this event time. >+ let eventTime = eventFrame / context.sampleRate; >+ >+ // Sanity check that context is long enough for the test >+ should( >+ eventFrame < context.length, >+ prefix + 'Context length is long enough for the test') >+ .beTrue(); >+ >+ // Automations to be tested. The first event should be the actual >+ // output up to the event time. The last event should be the final >+ // output from the event time and onwards. >+ testCases.forEach(entry => { >+ should( >+ () => { >+ src.offset[entry.event]( >+ entry.value, eventTime, entry.extraArgs); >+ }, >+ prefix + >+ eventToString( >+ entry.event, entry.value, eventTime, entry.extraArgs)) >+ .notThrow(); >+ }); >+ >+ src.start(); >+ >+ return context.startRendering(); >+ } >+ >+ // Verify output of test where the final value of the automation is >+ // expected to be constant. >+ function expectConstant(prefix, should, eventFrame, testCases) { >+ return audioBuffer => { >+ let audio = audioBuffer.getChannelData(0); >+ >+ let eventTime = eventFrame / sampleRate; >+ >+ // Compute the expected value of the first automation one frame before >+ // the event time. This is a quick check that the correct automation >+ // was done. >+ let expectedValue = methodMap[testCases[0].event]( >+ (eventFrame - 1) / sampleRate, 1, 0, testCases[0].value, >+ eventTime); >+ should( >+ audio[eventFrame - 1], >+ prefix + >+ `At time ${ >+ (eventFrame - 1) / sampleRate >+ } (frame ${eventFrame - 1}) output`) >+ .beCloseTo(expectedValue, {threshold: testCases[0].relError}); >+ >+ // The last event scheduled is expected to set the value for all >+ // future times. Verify that the output has the expected value. >+ should( >+ audio.slice(eventFrame), >+ prefix + >+ `At time ${eventTime} (frame ${ >+ eventFrame >+ }) and later, output`) >+ .beConstantValueOf(testCases[testCases.length - 1].value); >+ }; >+ } >+ >+ // Convert an automation method to a string for printing. >+ function eventToString(method, value, time, extras) { >+ let string = method + '('; >+ string += (value instanceof Array) ? `[${value}]` : value; >+ string += ', ' + time; >+ if (extras) { >+ string += ', ' + extras; >+ } >+ string += ')'; >+ return string; >+ } >+ >+ // Map between the automation method name and a function that computes the >+ // output value of the automation method. >+ const methodMap = { >+ linearRampToValueAtTime: audioParamLinearRamp, >+ exponentialRampToValueAtTime: audioParamExponentialRamp, >+ setValueAtTime: (t, v) => v >+ }; >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-audioworklet.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-audioworklet.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..02c641ef2d90ff9aa00f489d1f09363e8df8587b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-audioworklet.https-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 30: TypeError: Not enough arguments >+ >+Harness Error (FAIL), message = TypeError: Not enough arguments >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [Create Test Worklet] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-audioworklet.https.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-audioworklet.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..e891da6da2b02924aac74b9e850677dc080b57b0 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-audioworklet.https.html >@@ -0,0 +1,79 @@ >+<!doctype html> >+<html> >+ <head> >+ <title>Test k-rate AudioParam of AudioWorkletNode</title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ >+ <body> >+ <script> >+ const audit = Audit.createTaskRunner(); >+ >+ // Use the worklet gain node to test k-rate parameters. >+ const filePath = >+ '../the-audioworklet-interface/processors/gain-processor.js'; >+ >+ // Context for testing >+ let context; >+ >+ audit.define('Create Test Worklet', (task, should) => { >+ >+ // Arbitrary sample rate and duration. >+ const sampleRate = 8000; >+ >+ // Only new a few render quanta to verify things are working. >+ const testDuration = 4 * 128 / sampleRate; >+ >+ context = new OfflineAudioContext({ >+ numberOfChannels: 3, >+ sampleRate: sampleRate, >+ length: testDuration * sampleRate >+ }); >+ >+ should( >+ context.audioWorklet.addModule(filePath), >+ 'Construction of AudioWorklet') >+ .beResolved() >+ .then(() => task.done()); >+ }); >+ >+ audit.define('AudioWorklet k-rate AudioParam', (task, should) => { >+ let src = new ConstantSourceNode(context); >+ >+ let kRateNode = new AudioWorkletNode(context, 'gain'); >+ >+ src.connect(kRateNode).connect(context.destination); >+ >+ let kRateParam = kRateNode.parameters.get('gain'); >+ kRateParam.automationRate = 'k-rate'; >+ >+ // Automate the gain >+ kRateParam.setValueAtTime(0, 0); >+ kRateParam.linearRampToValueAtTime( >+ 10, context.length / context.sampleRate); >+ >+ src.start(); >+ >+ context.startRendering() >+ .then(audioBuffer => { >+ let output = audioBuffer.getChannelData(0); >+ >+ // Verify that the output from the worklet is step-wise >+ // constant. >+ for (let k = 0; k < output.length; k += 128) { >+ should( >+ output.slice(k, k + 128), >+ ` k-rate output [${k}: ${k + 127}]`) >+ .beConstantValueOf(output[k]); >+ } >+ }) >+ .then(() => task.done()); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-biquad-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-biquad-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..b73074698614568b5d65a9909a2e85aa939e3d70 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-biquad-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 22: TypeError: Not enough arguments >+ >+Harness Error (FAIL), message = TypeError: Not enough arguments >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [Biquad k-rate AudioParams (all)] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-biquad.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-biquad.html >new file mode 100644 >index 0000000000000000000000000000000000000000..85ae4f175fe182a4bf993443163dea14f00fa203 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-biquad.html >@@ -0,0 +1,111 @@ >+<!doctype html> >+<html> >+ <head> >+ <title>Test k-rate AudioParams of BiquadFilterNode</title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="automation-rate-testing.js"></script> >+ </head> >+ >+ <body> >+ <script> >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define( >+ {task: 'BiquadFilter-0', label: 'Biquad k-rate AudioParams (all)'}, >+ (task, should) => { >+ // Arbitrary sample rate and duration. >+ let sampleRate = 8000; >+ let testDuration = 1; >+ let context = new OfflineAudioContext({ >+ numberOfChannels: 3, >+ sampleRate: sampleRate, >+ length: testDuration * sampleRate >+ }); >+ >+ doTest(context, should, { >+ nodeName: 'BiquadFilterNode', >+ nodeOptions: {type: 'lowpass'}, >+ prefix: 'All k-rate params', >+ // Set all AudioParams to k-rate >+ rateSettings: [ >+ {name: 'Q', value: 'k-rate'}, >+ {name: 'detune', value: 'k-rate'}, >+ {name: 'frequency', value: 'k-rate'}, >+ {name: 'gain', value: 'k-rate'}, >+ ], >+ // Automate just the frequency >+ automations: [{ >+ name: 'frequency', >+ methods: [ >+ {name: 'setValueAtTime', options: [350, 0]}, { >+ name: 'linearRampToValueAtTime', >+ options: [0, testDuration] >+ } >+ ] >+ }] >+ }).then(() => task.done()); >+ }); >+ >+ // Define a test where we verify that a k-rate audio param produces >+ // different results from an a-rate audio param for each of the audio >+ // params of a biquad. >+ // >+ // Each entry gives the name of the AudioParam, an initial value to be >+ // used with setValueAtTime, and a final value to be used with >+ // linearRampToValueAtTime. (See |doTest| for details as well.) >+ >+ [{name: 'Q', >+ initial: 1, >+ final: 10 >+ }, >+ {name: 'detune', >+ initial: 0, >+ final: 1200 >+ }, >+ {name: 'frequency', >+ initial: 350, >+ final: 0 >+ }, >+ {name: 'gain', >+ initial: 10, >+ final: 0 >+ }].forEach(paramProperty => { >+ audit.define('Biquad k-rate ' + paramProperty.name, (task, should) => { >+ // Arbitrary sample rate and duration. >+ let sampleRate = 8000; >+ let testDuration = 1; >+ let context = new OfflineAudioContext({ >+ numberOfChannels: 3, >+ sampleRate: sampleRate, >+ length: testDuration * sampleRate >+ }); >+ >+ doTest(context, should, { >+ nodeName: 'BiquadFilterNode', >+ nodeOptions: {type: 'peaking', Q: 1, gain: 10}, >+ prefix: `k-rate ${paramProperty.name}`, >+ // Just set the frequency to k-rate >+ rateSettings: [ >+ {name: paramProperty.name, value: 'k-rate'}, >+ ], >+ // Automate just the given AudioParam >+ automations: [{ >+ name: paramProperty.name, >+ methods: [ >+ {name: 'setValueAtTime', options: [paramProperty.initial, 0]}, { >+ name: 'linearRampToValueAtTime', >+ options: [paramProperty.final, testDuration] >+ } >+ ] >+ }] >+ }).then(() => task.done()); >+ }); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-constant-source-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-constant-source-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..88174b07155cd4574829917098c3d000a3441f91 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-constant-source-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 22: TypeError: Not enough arguments >+ >+Harness Error (FAIL), message = TypeError: Not enough arguments >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [ConstantSource k-rate offset] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-constant-source.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-constant-source.html >new file mode 100644 >index 0000000000000000000000000000000000000000..5c421d0bc42f8981446f82ad606e49baa93f65a5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-constant-source.html >@@ -0,0 +1,81 @@ >+<!doctype html> >+<html> >+ <head> >+ <title>Test k-rate AudioParam of ConstantSourceNode</title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ >+ <body> >+ <script> >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('ConstantSource k-rate offset', (task, should) => { >+ // Arbitrary sample rate and duration. >+ let sampleRate = 8000; >+ >+ // Only new a few render quanta to verify things are working. >+ let testDuration = 4 * 128 / sampleRate; >+ >+ let context = new OfflineAudioContext({ >+ numberOfChannels: 3, >+ sampleRate: sampleRate, >+ length: testDuration * sampleRate >+ }); >+ >+ let merger = new ChannelMergerNode( >+ context, {numberOfInputs: context.numberOfChannels}); >+ merger.connect(context.destination); >+ let inverter = new GainNode(context, {gain: -1}); >+ inverter.connect(merger, 0, 2); >+ >+ let kRateNode = new ConstantSourceNode(context); >+ let aRateNode = new ConstantSourceNode(context); >+ >+ kRateNode.connect(merger, 0, 0); >+ aRateNode.connect(merger, 0, 1); >+ >+ kRateNode.connect(merger, 0, 2); >+ aRateNode.connect(inverter); >+ >+ // Set the rate >+ kRateNode.offset.automationRate = 'k-rate'; >+ >+ // Automate the offset >+ kRateNode.offset.setValueAtTime(0, 0); >+ kRateNode.offset.linearRampToValueAtTime(10, testDuration); >+ >+ aRateNode.offset.setValueAtTime(0, 0); >+ aRateNode.offset.linearRampToValueAtTime(10, testDuration); >+ >+ kRateNode.start(); >+ aRateNode.start(); >+ >+ context.startRendering() >+ .then(audioBuffer => { >+ let kRateOut = audioBuffer.getChannelData(0); >+ let aRateOut = audioBuffer.getChannelData(1); >+ let diff = audioBuffer.getChannelData(2); >+ >+ // Verify that the outputs are different. >+ should(diff, 'Difference between a-rate and k-rate outputs') >+ .notBeConstantValueOf(0); >+ >+ // Verify that the constant source node output is step-wise >+ // constant. >+ for (let k = 0; k < kRateOut.length; k += 128) { >+ should( >+ kRateOut.slice(k, k + 128), >+ `k-rate output [${k}: ${k + 127}]`) >+ .beConstantValueOf(kRateOut[k]); >+ } >+ }) >+ .then(() => task.done()); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-delay-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-delay-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..e0f7370d5ec82357507821c97a24b9e705b03e92 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-delay-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 20: TypeError: Not enough arguments >+ >+Harness Error (FAIL), message = TypeError: Not enough arguments >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [Test k-rate DelayNode] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-delay.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-delay.html >new file mode 100644 >index 0000000000000000000000000000000000000000..5465c3943089e36b7dc95f65454904115beda55f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-delay.html >@@ -0,0 +1,49 @@ >+<!doctype html> >+<html> >+ <head> >+ <title>Test k-rate AudioParam of DelayNode</title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="automation-rate-testing.js"></script> >+ </head> >+ >+ <body> >+ <script> >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('Test k-rate DelayNode', (task, should) => { >+ // Arbitrary sample rate and duration. >+ let sampleRate = 8000; >+ let testDuration = 1; >+ let context = new OfflineAudioContext({ >+ numberOfChannels: 3, >+ sampleRate: sampleRate, >+ length: testDuration * sampleRate >+ }); >+ >+ >+ doTest(context, should, { >+ nodeName: 'DelayNode', >+ nodeOptions: null, >+ prefix: 'DelayNode', >+ // Set all AudioParams to k-rate >+ rateSettings: [{name: 'delayTime', value: 'k-rate'}], >+ // Automate just the frequency >+ automations: [{ >+ name: 'delayTime', >+ methods: [ >+ {name: 'setValueAtTime', options: [0, 0]}, { >+ name: 'linearRampToValueAtTime', >+ options: [.5, testDuration] >+ } >+ ] >+ }] >+ }).then(() => task.done()); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-gain-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-gain-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..a9bcba9c329d03c54c278bf23d266c1c6e380c6f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-gain-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 20: TypeError: Not enough arguments >+ >+Harness Error (FAIL), message = TypeError: Not enough arguments >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [Test k-rate GainNode] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-gain.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-gain.html >new file mode 100644 >index 0000000000000000000000000000000000000000..887d9f78db8a79b0aae96b9cdf818cde7b33aa6c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-gain.html >@@ -0,0 +1,47 @@ >+<!doctype html> >+<html> >+ <head> >+ <title>Test k-rate AudioParam of GainNode</title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="automation-rate-testing.js"></script> >+ </head> >+ >+ <body> >+ <script> >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('Test k-rate GainNode', (task, should) => { >+ // Arbitrary sample rate and duration. >+ let sampleRate = 8000; >+ let testDuration = 1; >+ let context = new OfflineAudioContext({ >+ numberOfChannels: 3, >+ sampleRate: sampleRate, >+ length: testDuration * sampleRate >+ }); >+ >+ >+ doTest(context, should, { >+ nodeName: 'GainNode', >+ nodeOptions: null, >+ prefix: 'GainNode', >+ // Set AudioParam to k-rate >+ rateSettings: [{name: 'gain', value: 'k-rate'}], >+ // Automate >+ automations: [{ >+ name: 'gain', >+ methods: [ >+ {name: 'setValueAtTime', options: [1, 0]}, >+ {name: 'linearRampToValueAtTime', options: [0, testDuration]} >+ ] >+ }] >+ }).then(() => task.done()); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-oscillator-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-oscillator-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..9bfc0b371244922b2e1493be6017cf452372f7a7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-oscillator-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 28: TypeError: Not enough arguments >+ >+Harness Error (FAIL), message = TypeError: Not enough arguments >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [Oscillator k-rate detune] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-oscillator.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-oscillator.html >new file mode 100644 >index 0000000000000000000000000000000000000000..1672f0d975f2b2e2fd0c127663b403745b669265 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-oscillator.html >@@ -0,0 +1,88 @@ >+<!doctype html> >+<html> >+ <head> >+ <title>Test k-rate AudioParams of OscillatorNode</title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ >+ <body> >+ <script> >+ let audit = Audit.createTaskRunner(); >+ >+ // Arbitrary sample rate and duration. >+ let sampleRate = 8000; >+ >+ // Only new a few render quanta to verify things are working. >+ let testDuration = 4 * 128 / sampleRate; >+ >+ [{name: 'detune', initial: 0, final: 1200}, { >+ name: 'frequency', >+ initial: 440, >+ final: sampleRate / 2 >+ }].forEach(paramProperty => { >+ audit.define( >+ 'Oscillator k-rate ' + paramProperty.name, (task, should) => { >+ let context = new OfflineAudioContext({ >+ numberOfChannels: 3, >+ sampleRate: sampleRate, >+ length: testDuration * sampleRate >+ }); >+ >+ let merger = new ChannelMergerNode( >+ context, {numberOfInputs: context.numberOfChannels}); >+ merger.connect(context.destination); >+ let inverter = new GainNode(context, {gain: -1}); >+ inverter.connect(merger, 0, 2); >+ >+ let kRateNode = new OscillatorNode(context); >+ let aRateNode = new OscillatorNode(context); >+ >+ kRateNode.connect(merger, 0, 0); >+ aRateNode.connect(merger, 0, 1); >+ >+ kRateNode.connect(merger, 0, 2); >+ aRateNode.connect(inverter); >+ >+ // Set the rate >+ kRateNode[paramProperty.name].automationRate = 'k-rate'; >+ >+ // Automate the offset >+ kRateNode[paramProperty.name].setValueAtTime( >+ paramProperty.initial, 0); >+ kRateNode[paramProperty.name].linearRampToValueAtTime( >+ paramProperty.final, testDuration); >+ >+ aRateNode[paramProperty.name].setValueAtTime( >+ paramProperty.initial, 0); >+ aRateNode[paramProperty.name].linearRampToValueAtTime( >+ paramProperty.final, testDuration); >+ >+ kRateNode.start(); >+ aRateNode.start(); >+ >+ context.startRendering() >+ .then(audioBuffer => { >+ let kRateOut = audioBuffer.getChannelData(0); >+ let aRateOut = audioBuffer.getChannelData(1); >+ let diff = audioBuffer.getChannelData(2); >+ >+ // Verify that the outputs are different. >+ should( >+ diff, >+ 'k-rate ' + paramProperty.name + >+ ': Difference between a-rate and k-rate outputs') >+ .notBeConstantValueOf(0); >+ >+ }) >+ .then(() => task.done()); >+ }); >+ }); >+ >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-panner-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-panner-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..a300317fb1a0d3b9e4d073359f20311f5507c945 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-panner-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 34: TypeError: Not enough arguments >+ >+Harness Error (FAIL), message = TypeError: Not enough arguments >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [Panner k-rate positionX] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-panner.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-panner.html >new file mode 100644 >index 0000000000000000000000000000000000000000..1e9e900adb1151453f1c9dc3e3c5326aef9eb211 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-panner.html >@@ -0,0 +1,172 @@ >+<!doctype html> >+<html> >+ <head> >+ <title>Test k-rate AudioParams of PannerNode</title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="automation-rate-testing.js"></script> >+ </head> >+ >+ <body> >+ <script> >+ let audit = Audit.createTaskRunner(); >+ >+ // Define a test where we verify that a k-rate audio param produces >+ // different results from an a-rate audio param for each of the audio >+ // params of a biquad. >+ // >+ // Each entry gives the name of the AudioParam, an initial value to be >+ // used with setValueAtTime, and a final value to be used with >+ // linearRampToValueAtTime. (See |doTest| for details as well.) >+ >+ [{name: 'positionX', initial: 0, final: 1000}, >+ {name: 'positionY', initial: 0, final: 1000}, >+ {name: 'orientationX', initial: .1, final: 1000}, >+ {name: 'orientationY', initial: .1, final: 1000}, >+ {name: 'orientationZ', initial: .1, final: 1000}, >+ ].forEach(paramProperty => { >+ audit.define('Panner k-rate ' + paramProperty.name, (task, should) => { >+ // Arbitrary sample rate and duration. >+ let sampleRate = 8000; >+ let testDuration = 1; >+ let context = new OfflineAudioContext({ >+ numberOfChannels: 3, >+ sampleRate: sampleRate, >+ length: testDuration * sampleRate >+ }); >+ >+ doTest(context, should, { >+ nodeName: 'PannerNode', >+ // Make the source directional so orientation matters, and set some >+ // defaults for the position and orientation so that we're not on an >+ // axis where the azimuth and elevation might be constant when >+ // moving one of the AudioParams. >+ nodeOptions: { >+ distanceModel: 'inverse', >+ coneOuterAngle: 360, >+ coneInnerAngle: 10, >+ positionX: 10, >+ positionY: 10, >+ positionZ: 10, >+ orientationX: 1, >+ orientationY: 1, >+ orientationZ: 1 >+ }, >+ prefix: `k-rate ${paramProperty.name}`, >+ // Just set the frequency to k-rate >+ rateSettings: [ >+ {name: paramProperty.name, value: 'k-rate'}, >+ ], >+ // Automate just the given AudioParam >+ automations: [{ >+ name: paramProperty.name, >+ methods: [ >+ {name: 'setValueAtTime', options: [paramProperty.initial, 0]}, { >+ name: 'linearRampToValueAtTime', >+ options: [paramProperty.final, testDuration] >+ } >+ ] >+ }] >+ }).then(() => task.done()); >+ }); >+ }); >+ >+ // Test k-rate automation of the listener. The intial and final >+ // automation values are pretty arbitrary, except that they should be such >+ // that the panner and listener produces non-constant output. >+ [{name: 'positionX', initial: [1, 0], final: [1000, 1]}, >+ {name: 'positionY', initial: [1, 0], final: [1000, 1]}, >+ {name: 'positionZ', initial: [1, 0], final: [1000, 1]}, >+ {name: 'forwardX', initial: [-1, 0], final: [1, 1]}, >+ {name: 'forwardY', initial: [-1, 0], final: [1, 1]}, >+ {name: 'forwardZ', initial: [-1, 0], final: [1, 1]}, >+ {name: 'upX', initial: [-1, 0], final: [1000, 1]}, >+ {name: 'upY', initial: [-1, 0], final: [1000, 1]}, >+ {name: 'upZ', initial: [-1, 0], final: [1000, 1]}, >+ ].forEach(paramProperty => { >+ audit.define( >+ 'Listener k-rate ' + paramProperty.name, (task, should) => { >+ // Arbitrary sample rate and duration. >+ let sampleRate = 8000; >+ let testDuration = 5 * 128 / sampleRate; >+ let context = new OfflineAudioContext({ >+ numberOfChannels: 1, >+ sampleRate: sampleRate, >+ length: testDuration * sampleRate >+ }); >+ >+ doListenerTest(context, should, { >+ param: paramProperty.name, >+ initial: paramProperty.initial, >+ final: paramProperty.final >+ }).then(() => task.done()); >+ }); >+ }); >+ >+ audit.run(); >+ >+ function doListenerTest(context, should, options) { >+ let src = new ConstantSourceNode(context); >+ let panner = new PannerNode(context, { >+ distanceModel: 'inverse', >+ coneOuterAngle: 360, >+ coneInnerAngle: 10, >+ positionX: 10, >+ positionY: 10, >+ positionZ: 10, >+ orientationX: 1, >+ orientationY: 1, >+ orientationZ: 1 >+ }); >+ >+ src.connect(panner).connect(context.destination); >+ >+ src.start(); >+ >+ let listener = context.listener; >+ >+ // Set listener properties to "random" values so that motion on one of >+ // the attributes actually changes things relative to the panner >+ // location. >+ listener.positionX.value = -1; >+ listener.positionY.value = 1; >+ listener.positionZ.value = -1; >+ listener.forwardX.value = -1; >+ listener.forwardY.value = 1; >+ listener.forwardZ.value = -1; >+ listener.upX.value = 1; >+ listener.upY.value = 1; >+ listener.upZ.value = 1; >+ >+ let audioParam = listener[options.param]; >+ audioParam.automationRate = 'k-rate'; >+ >+ let prefix = `Listener ${options.param}`; >+ should(audioParam.automationRate, prefix + '.automationRate') >+ .beEqualTo('k-rate'); >+ should(() => { >+ audioParam.setValueAtTime(...options.initial); >+ }, prefix + `.setValueAtTime(${options.initial})`).notThrow(); >+ should(() => { >+ audioParam.linearRampToValueAtTime(...options.final); >+ }, prefix + `.linearRampToValueAtTime(${options.final})`).notThrow(); >+ >+ return context.startRendering().then(renderedBuffer => { >+ let prefix = `Listener k-rate ${options.param}: `; >+ let output = renderedBuffer.getChannelData(0); >+ // Sanity check that the output isn't constant. >+ should(output, prefix + `Output`).notBeConstantValueOf(output[0]); >+ >+ // Verify that the output is constant over each render quantum >+ for (let k = 0; k < output.length; k += 128) { >+ should( >+ output.slice(k, k + 128), prefix + `Output [${k}, ${k + 127}]`) >+ .beConstantValueOf(output[k]); >+ } >+ }); >+ } >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-stereo-panner-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-stereo-panner-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..878703e976153d4f9bf296e916a0bcde18a8d07e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-stereo-panner-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 20: TypeError: Not enough arguments >+ >+Harness Error (FAIL), message = TypeError: Not enough arguments >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [Test k-rate StereoPannerNode] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-stereo-panner.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-stereo-panner.html >new file mode 100644 >index 0000000000000000000000000000000000000000..06905b89c31884ca9f5ec012a2263d68840d043f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-stereo-panner.html >@@ -0,0 +1,48 @@ >+<!doctype html> >+<html> >+ <head> >+ <title>Test k-rate AudioParam of StereoPannerNode</title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="automation-rate-testing.js"></script> >+ </head> >+ >+ <body> >+ <script> >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('Test k-rate StereoPannerNode', (task, should) => { >+ // Arbitrary sample rate and duration. >+ let sampleRate = 8000; >+ let testDuration = 1; >+ let context = new OfflineAudioContext({ >+ numberOfChannels: 3, >+ sampleRate: sampleRate, >+ length: testDuration * sampleRate >+ }); >+ >+ doTest(context, should, { >+ nodeName: 'StereoPannerNode', >+ nodeOptions: null, >+ prefix: 'StereoPannerNode', >+ // Set all AudioParams to k-rate. >+ rateSettings: [{name: 'pan', value: 'k-rate'}], >+ // Automate just the frequency. >+ automations: [{ >+ name: 'pan', >+ methods: [ >+ {name: 'setValueAtTime', options: [0, 0]}, { >+ name: 'linearRampToValueAtTime', >+ options: [.5, testDuration] >+ } >+ ] >+ }] >+ }).then(() => task.done()); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/w3c-import.log >index a45e33457fd6725863ce235c036a01032b1733be..472b239f4e98c87cfadb5d2deda20ca568cdfbd2 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/w3c-import.log >@@ -14,7 +14,29 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-connect-audioratesignal.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exceptional-values.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exponentialRampToValueAtTime.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-large-endtime.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-linearRampToValueAtTime.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-method-chaining.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setTargetAtTime.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueAtTime.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurveAtTime.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-summingjunction.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate-testing.js >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/idl-test.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-audioworklet.https.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-biquad.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-constant-source.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-delay.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-gain.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-oscillator.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-panner.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/k-rate-stereo-panner.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/retrospective-exponentialRampToValueAtTime.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/retrospective-linearRampToValueAtTime.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/retrospective-setTargetAtTime.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-automatic-pull.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-automatic-pull.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..49369b38932a5ef98221a08167374e6db0fefffd >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-automatic-pull.https-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 30: TypeError: undefined is not an object (evaluating 'context.audioWorklet.addModule') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'context.audioWorklet.addModule') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [setup-worklet] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-automatic-pull.https.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-automatic-pull.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..330b359f7d9c4dbe24056a763ef3473389839192 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-automatic-pull.https.html >@@ -0,0 +1,73 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test AudioWorkletNode's automatic pull feature >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ const audit = Audit.createTaskRunner(); >+ >+ // Arbitrary sample rate. Anything should work. >+ const sampleRate = 48000; >+ const renderLength = RENDER_QUANTUM_FRAMES * 2; >+ const channelCount = 1; >+ const filePath = 'processors/zero-output-processor.js'; >+ >+ const sourceOffset = 0.5; >+ >+ // Connect a constant source node to the zero-output AudioWorkletNode. >+ // Then verify if it captures the data correctly. >+ audit.define('setup-worklet', (task, should) => { >+ const context = >+ new OfflineAudioContext(channelCount, renderLength, sampleRate); >+ >+ context.audioWorklet.addModule(filePath).then(() => { >+ let testSource = >+ new ConstantSourceNode(context, { offset: sourceOffset }); >+ let zeroOutputWorkletNode = >+ new AudioWorkletNode(context, 'zero-output-processor', { >+ numberOfInputs: 1, >+ numberOfOutputs: 0, >+ processorOptions: { >+ bufferLength: renderLength, >+ channeCount: channelCount >+ } >+ }); >+ >+ // Start the source and stop at the first render quantum. >+ testSource.connect(zeroOutputWorkletNode); >+ testSource.start(); >+ testSource.stop(RENDER_QUANTUM_FRAMES/sampleRate); >+ >+ zeroOutputWorkletNode.port.onmessage = (event) => { >+ // The |capturedBuffer| can be multichannel. Iterate through it. >+ for (let i = 0; i < event.data.capturedBuffer.length; ++i) { >+ let buffer = event.data.capturedBuffer[i]; >+ // Split the captured buffer in half for the easier test. >+ should(buffer.subarray(0, RENDER_QUANTUM_FRAMES), >+ 'The first half of the captured buffer') >+ .beConstantValueOf(sourceOffset); >+ should(buffer.subarray(RENDER_QUANTUM_FRAMES, renderLength), >+ 'The second half of the captured buffer') >+ .beConstantValueOf(0); >+ } >+ task.done(); >+ }; >+ >+ // Starts the rendering, but we don't need the rendered buffer from >+ // the context. >+ context.startRendering(); >+ }); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/w3c-import.log >index 04051112ec0dbd423f3b26e71629fea69b37ae5f..d47b6ae26d701cb897ea7017eae685baa54dec1a 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/w3c-import.log >@@ -22,3 +22,4 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/option-test-processor.js > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/port-processor.js > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/timing-info-processor.js >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/zero-output-processor.js >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/zero-output-processor.js b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/zero-output-processor.js >new file mode 100644 >index 0000000000000000000000000000000000000000..b97ed6e115132e7fe9679812788d252b01090c4c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/zero-output-processor.js >@@ -0,0 +1,42 @@ >+/** >+ * @class ZeroOutputProcessor >+ * @extends AudioWorkletProcessor >+ * >+ * This processor accumulates the incoming buffer and send the buffered data >+ * to the main thread when it reaches the specified frame length. The processor >+ * only supports the single input. >+ */ >+ >+const kRenderQuantumFrames = 128; >+ >+class ZeroOuttputProcessor extends AudioWorkletProcessor { >+ constructor(options) { >+ super(); >+ >+ this._framesRequested = options.processorOptions.bufferLength; >+ this._framesCaptured = 0; >+ this._buffer = []; >+ for (let i = 0; i < options.processorOptions.channeCount; ++i) { >+ this._buffer[i] = new Float32Array(this._framesRequested); >+ } >+ } >+ >+ process(inputs) { >+ let input = inputs[0]; >+ let startIndex = this._framesCaptured; >+ let endIndex = startIndex + kRenderQuantumFrames; >+ for (let i = 0; i < this._buffer.length; ++i) { >+ this._buffer[i].subarray(startIndex, endIndex).set(input[i]); >+ } >+ this._framesCaptured = endIndex; >+ >+ if (this._framesCaptured >= this._framesRequested) { >+ this.port.postMessage({ capturedBuffer: this._buffer }); >+ return false; >+ } else { >+ return true; >+ } >+ } >+} >+ >+registerProcessor('zero-output-processor', ZeroOuttputProcessor); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/w3c-import.log >index 84e67027c23e4703c9c3bd09887fcc4648349195..1d93c5d7ebc1deea9fd450b28c57e5cfa99085f7 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/w3c-import.log >@@ -19,6 +19,7 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-messageport.https.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletglobalscope-sample-rate.https.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletglobalscope-timing-info.https.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-automatic-pull.https.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-channel-count.https.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-construction.https.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-constructor-options.https.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-allpass-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-allpass-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..be3335e35857ee76c651162be87d426ab2c5845f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-allpass-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 82: TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] Biquad allpass filter >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-allpass.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-allpass.html >new file mode 100644 >index 0000000000000000000000000000000000000000..86618f9e46dbc1b5462f949cadf703ac59993577 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-allpass.html >@@ -0,0 +1,42 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ biquad-allpass.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/biquad-filters.js"></script> >+ <script src="/webaudio/resources/biquad-testing.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define( >+ {label: 'test', description: 'Biquad allpass filter'}, >+ function(task, should) { >+ >+ // Create offline audio context. >+ let context = new OfflineAudioContext( >+ 2, sampleRate * renderLengthSeconds, sampleRate); >+ >+ let filterParameters = [ >+ {cutoff: 0, q: 10, gain: 1}, >+ {cutoff: 1, q: 10, gain: 1}, >+ {cutoff: .5, q: 0, gain: 1}, >+ {cutoff: 0.25, q: 10, gain: 1}, >+ ]; >+ createTestAndRun(context, 'allpass', { >+ should: should, >+ threshold: 3.9337e-8, >+ filterParameters: filterParameters >+ }).then(task.done.bind(task)); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2a92d815aa33251acf8ca3266c356590c1a510b0 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 161: SyntaxError: The string did not match the expected pattern. >+ >+Harness Error (FAIL), message = SyntaxError: The string did not match the expected pattern. >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [automate-freq] >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation.html >new file mode 100644 >index 0000000000000000000000000000000000000000..54b2142cea250cdbfe084df6fb9e1d42eac96cd2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation.html >@@ -0,0 +1,406 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Biquad Automation Test >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/biquad-filters.js"></script> >+ <script src="/webaudio/resources/audioparam-testing.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ // Don't need to run these tests at high sampling rate, so just use a low >+ // one to reduce memory usage and complexity. >+ let sampleRate = 16000; >+ >+ // How long to render for each test. >+ let renderDuration = 0.25; >+ // Where to end the automations. Fairly arbitrary, but must end before >+ // the renderDuration. >+ let automationEndTime = renderDuration / 2; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ // The definition of the linear ramp automation function. >+ function linearRamp(t, v0, v1, t0, t1) { >+ return v0 + (v1 - v0) * (t - t0) / (t1 - t0); >+ } >+ >+ // Generate the filter coefficients for the specified filter using the >+ // given parameters for the given duration. |filterTypeFunction| is a >+ // function that returns the filter coefficients for one set of >+ // parameters. |parameters| is a property bag that contains the start and >+ // end values (as an array) for each of the biquad attributes. The >+ // properties are |freq|, |Q|, |gain|, and |detune|. |duration| is the >+ // number of seconds for which the coefficients are generated. >+ // >+ // A property bag with properties |b0|, |b1|, |b2|, |a1|, |a2|. Each >+ // propery is an array consisting of the coefficients for the time-varying >+ // biquad filter. >+ function generateFilterCoefficients( >+ filterTypeFunction, parameters, duration) { >+ let renderEndFrame = Math.ceil(renderDuration * sampleRate); >+ let endFrame = Math.ceil(duration * sampleRate); >+ let nCoef = renderEndFrame; >+ let b0 = new Float64Array(nCoef); >+ let b1 = new Float64Array(nCoef); >+ let b2 = new Float64Array(nCoef); >+ let a1 = new Float64Array(nCoef); >+ let a2 = new Float64Array(nCoef); >+ >+ let k = 0; >+ // If the property is not given, use the defaults. >+ let freqs = parameters.freq || [350, 350]; >+ let qs = parameters.Q || [1, 1]; >+ let gains = parameters.gain || [0, 0]; >+ let detunes = parameters.detune || [0, 0]; >+ >+ for (let frame = 0; frame <= endFrame; ++frame) { >+ // Apply linear ramp at frame |frame|. >+ let f = >+ linearRamp(frame / sampleRate, freqs[0], freqs[1], 0, duration); >+ let q = linearRamp(frame / sampleRate, qs[0], qs[1], 0, duration); >+ let g = >+ linearRamp(frame / sampleRate, gains[0], gains[1], 0, duration); >+ let d = linearRamp( >+ frame / sampleRate, detunes[0], detunes[1], 0, duration); >+ >+ // Compute actual frequency parameter >+ f = f * Math.pow(2, d / 1200); >+ >+ // Compute filter coefficients >+ let coef = filterTypeFunction(f / (sampleRate / 2), q, g); >+ b0[k] = coef.b0; >+ b1[k] = coef.b1; >+ b2[k] = coef.b2; >+ a1[k] = coef.a1; >+ a2[k] = coef.a2; >+ ++k; >+ } >+ >+ // Fill the rest of the arrays with the constant value to the end of >+ // the rendering duration. >+ b0.fill(b0[endFrame], endFrame + 1); >+ b1.fill(b1[endFrame], endFrame + 1); >+ b2.fill(b2[endFrame], endFrame + 1); >+ a1.fill(a1[endFrame], endFrame + 1); >+ a2.fill(a2[endFrame], endFrame + 1); >+ >+ return {b0: b0, b1: b1, b2: b2, a1: a1, a2: a2}; >+ } >+ >+ // Apply the given time-varying biquad filter to the given signal, >+ // |signal|. |coef| should be the time-varying coefficients of the >+ // filter, as returned by |generateFilterCoefficients|. >+ function timeVaryingFilter(signal, coef) { >+ let length = signal.length; >+ // Use double precision for the internal computations. >+ let y = new Float64Array(length); >+ >+ // Prime the pump. (Assumes the signal has length >= 2!) >+ y[0] = coef.b0[0] * signal[0]; >+ y[1] = >+ coef.b0[1] * signal[1] + coef.b1[1] * signal[0] - coef.a1[1] * y[0]; >+ >+ for (let n = 2; n < length; ++n) { >+ y[n] = coef.b0[n] * signal[n] + coef.b1[n] * signal[n - 1] + >+ coef.b2[n] * signal[n - 2]; >+ y[n] -= coef.a1[n] * y[n - 1] + coef.a2[n] * y[n - 2]; >+ } >+ >+ // But convert the result to single precision for comparison. >+ return y.map(Math.fround); >+ } >+ >+ // Configure the audio graph using |context|. Returns the biquad filter >+ // node and the AudioBuffer used for the source. >+ function configureGraph(context, toneFrequency) { >+ // The source is just a simple sine wave. >+ let src = context.createBufferSource(); >+ let b = >+ context.createBuffer(1, renderDuration * sampleRate, sampleRate); >+ let data = b.getChannelData(0); >+ let omega = 2 * Math.PI * toneFrequency / sampleRate; >+ for (let k = 0; k < data.length; ++k) { >+ data[k] = Math.sin(omega * k); >+ } >+ src.buffer = b; >+ let f = context.createBiquadFilter(); >+ src.connect(f); >+ f.connect(context.destination); >+ >+ src.start(); >+ >+ return {filter: f, source: b}; >+ } >+ >+ function createFilterVerifier( >+ should, filterCreator, threshold, parameters, input, message) { >+ return function(resultBuffer) { >+ let actual = resultBuffer.getChannelData(0); >+ let coefs = generateFilterCoefficients( >+ filterCreator, parameters, automationEndTime); >+ >+ reference = timeVaryingFilter(input, coefs); >+ >+ should(actual, message).beCloseToArray(reference, { >+ absoluteThreshold: threshold >+ }); >+ }; >+ } >+ >+ // Automate just the frequency parameter. A bandpass filter is used where >+ // the center frequency is swept across the source (which is a simple >+ // tone). >+ audit.define('automate-freq', (task, should) => { >+ let context = >+ new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate); >+ >+ // Center frequency of bandpass filter and also the frequency of the >+ // test tone. >+ let centerFreq = 10 * 440; >+ >+ // Sweep the frequency +/- 5*440 Hz from the center. This should cause >+ // the output to be low at the beginning and end of the test where the >+ // tone is outside the pass band of the filter, but high in the middle >+ // of the automation time where the tone is near the center of the pass >+ // band. Make sure the frequency sweep stays inside the Nyquist >+ // frequency. >+ let parameters = {freq: [centerFreq - 5 * 440, centerFreq + 5 * 440]}; >+ let graph = configureGraph(context, centerFreq); >+ let f = graph.filter; >+ let b = graph.source; >+ >+ f.type = 'bandpass'; >+ f.frequency.setValueAtTime(parameters.freq[0], 0); >+ f.frequency.linearRampToValueAtTime( >+ parameters.freq[1], automationEndTime); >+ >+ context.startRendering() >+ .then(createFilterVerifier( >+ should, createBandpassFilter, 4.6455e-6, parameters, >+ b.getChannelData(0), >+ 'Output of bandpass filter with frequency automation')) >+ .then(() => task.done()); >+ }); >+ >+ // Automate just the Q parameter. A bandpass filter is used where the Q >+ // of the filter is swept. >+ audit.define('automate-q', (task, should) => { >+ let context = >+ new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate); >+ >+ // The frequency of the test tone. >+ let centerFreq = 440; >+ >+ // Sweep the Q paramter between 1 and 200. This will cause the output >+ // of the filter to pass most of the tone at the beginning to passing >+ // less of the tone at the end. This is because we set center frequency >+ // of the bandpass filter to be slightly off from the actual tone. >+ let parameters = { >+ Q: [1, 200], >+ // Center frequency of the bandpass filter is just 25 Hz above the >+ // tone frequency. >+ freq: [centerFreq + 25, centerFreq + 25] >+ }; >+ let graph = configureGraph(context, centerFreq); >+ let f = graph.filter; >+ let b = graph.source; >+ >+ f.type = 'bandpass'; >+ f.frequency.value = parameters.freq[0]; >+ f.Q.setValueAtTime(parameters.Q[0], 0); >+ f.Q.linearRampToValueAtTime(parameters.Q[1], automationEndTime); >+ >+ context.startRendering() >+ .then(createFilterVerifier( >+ should, createBandpassFilter, 9.8348e-7, parameters, >+ b.getChannelData(0), >+ 'Output of bandpass filter with Q automation')) >+ .then(() => task.done()); >+ }); >+ >+ // Automate just the gain of the lowshelf filter. A test tone will be in >+ // the lowshelf part of the filter. The output will vary as the gain of >+ // the lowshelf is changed. >+ audit.define('automate-gain', (task, should) => { >+ let context = >+ new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate); >+ >+ // Frequency of the test tone. >+ let centerFreq = 440; >+ >+ // Set the cutoff frequency of the lowshelf to be significantly higher >+ // than the test tone. Sweep the gain from 20 dB to -20 dB. (We go from >+ // 20 to -20 to easily verify that the filter didn't go unstable.) >+ let parameters = {freq: [3500, 3500], gain: [20, -20]}; >+ let graph = configureGraph(context, centerFreq); >+ let f = graph.filter; >+ let b = graph.source; >+ >+ f.type = 'lowshelf'; >+ f.frequency.value = parameters.freq[0]; >+ f.gain.setValueAtTime(parameters.gain[0], 0); >+ f.gain.linearRampToValueAtTime(parameters.gain[1], automationEndTime); >+ >+ context.startRendering() >+ .then(createFilterVerifier( >+ should, createLowShelfFilter, 2.7657e-5, parameters, >+ b.getChannelData(0), >+ 'Output of lowshelf filter with gain automation')) >+ .then(() => task.done()); >+ }); >+ >+ // Automate just the detune parameter. Basically the same test as for the >+ // frequncy parameter but we just use the detune parameter to modulate the >+ // frequency parameter. >+ audit.define('automate-detune', (task, should) => { >+ let context = >+ new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate); >+ let centerFreq = 10 * 440; >+ let parameters = { >+ freq: [centerFreq, centerFreq], >+ detune: [-10 * 1200, 10 * 1200] >+ }; >+ let graph = configureGraph(context, centerFreq); >+ let f = graph.filter; >+ let b = graph.source; >+ >+ f.type = 'bandpass'; >+ f.frequency.value = parameters.freq[0]; >+ f.detune.setValueAtTime(parameters.detune[0], 0); >+ f.detune.linearRampToValueAtTime( >+ parameters.detune[1], automationEndTime); >+ >+ context.startRendering() >+ .then(createFilterVerifier( >+ should, createBandpassFilter, 3.1471e-5, parameters, >+ b.getChannelData(0), >+ 'Output of bandpass filter with detune automation')) >+ .then(() => task.done()); >+ }); >+ >+ // Automate all of the filter parameters at once. This is a basic check >+ // that everything is working. A peaking filter is used because it uses >+ // all of the parameters. >+ audit.define('automate-all', (task, should) => { >+ let context = >+ new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate); >+ let graph = configureGraph(context, 10 * 440); >+ let f = graph.filter; >+ let b = graph.source; >+ >+ // Sweep all of the filter parameters. These are pretty much arbitrary. >+ let parameters = { >+ freq: [8000, 100], >+ Q: [f.Q.value, .0001], >+ gain: [f.gain.value, 20], >+ detune: [2400, -2400] >+ }; >+ >+ f.type = 'peaking'; >+ // Set starting points for all parameters of the filter. Start at 10 >+ // kHz for the center frequency, and the defaults for Q and gain. >+ f.frequency.setValueAtTime(parameters.freq[0], 0); >+ f.Q.setValueAtTime(parameters.Q[0], 0); >+ f.gain.setValueAtTime(parameters.gain[0], 0); >+ f.detune.setValueAtTime(parameters.detune[0], 0); >+ >+ // Linear ramp each parameter >+ f.frequency.linearRampToValueAtTime( >+ parameters.freq[1], automationEndTime); >+ f.Q.linearRampToValueAtTime(parameters.Q[1], automationEndTime); >+ f.gain.linearRampToValueAtTime(parameters.gain[1], automationEndTime); >+ f.detune.linearRampToValueAtTime( >+ parameters.detune[1], automationEndTime); >+ >+ context.startRendering() >+ .then(createFilterVerifier( >+ should, createPeakingFilter, 6.2907e-4, parameters, >+ b.getChannelData(0), >+ 'Output of peaking filter with automation of all parameters')) >+ .then(() => task.done()); >+ }); >+ >+ // Test that modulation of the frequency parameter of the filter works. A >+ // sinusoid of 440 Hz is the test signal that is applied to a bandpass >+ // biquad filter. The frequency parameter of the filter is modulated by a >+ // sinusoid at 103 Hz, and the frequency modulation varies from 116 to 412 >+ // Hz. (This test was taken from the description in >+ // https://github.com/WebAudio/web-audio-api/issues/509#issuecomment-94731355) >+ audit.define('modulation', (task, should) => { >+ let context = >+ new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate); >+ >+ // Create a graph with the sinusoidal source at 440 Hz as the input to a >+ // biquad filter. >+ let graph = configureGraph(context, 440); >+ let f = graph.filter; >+ let b = graph.source; >+ >+ f.type = 'bandpass'; >+ f.Q.value = 5; >+ f.frequency.value = 264; >+ >+ // Create the modulation source, a sinusoid with frequency 103 Hz and >+ // amplitude 148. (The amplitude of 148 is added to the filter's >+ // frequency value of 264 to produce a sinusoidal modulation of the >+ // frequency parameter from 116 to 412 Hz.) >+ let mod = context.createBufferSource(); >+ let mbuffer = >+ context.createBuffer(1, renderDuration * sampleRate, sampleRate); >+ let d = mbuffer.getChannelData(0); >+ let omega = 2 * Math.PI * 103 / sampleRate; >+ for (let k = 0; k < d.length; ++k) { >+ d[k] = 148 * Math.sin(omega * k); >+ } >+ mod.buffer = mbuffer; >+ >+ mod.connect(f.frequency); >+ >+ mod.start(); >+ context.startRendering() >+ .then(function(resultBuffer) { >+ let actual = resultBuffer.getChannelData(0); >+ // Compute the filter coefficients using the mod sine wave >+ >+ let endFrame = Math.ceil(renderDuration * sampleRate); >+ let nCoef = endFrame; >+ let b0 = new Float64Array(nCoef); >+ let b1 = new Float64Array(nCoef); >+ let b2 = new Float64Array(nCoef); >+ let a1 = new Float64Array(nCoef); >+ let a2 = new Float64Array(nCoef); >+ >+ // Generate the filter coefficients when the frequency varies from >+ // 116 to 248 Hz using the 103 Hz sinusoid. >+ for (let k = 0; k < nCoef; ++k) { >+ let freq = f.frequency.value + d[k]; >+ let c = createBandpassFilter( >+ freq / (sampleRate / 2), f.Q.value, f.gain.value); >+ b0[k] = c.b0; >+ b1[k] = c.b1; >+ b2[k] = c.b2; >+ a1[k] = c.a1; >+ a2[k] = c.a2; >+ } >+ reference = timeVaryingFilter( >+ b.getChannelData(0), >+ {b0: b0, b1: b1, b2: b2, a1: a1, a2: a2}); >+ >+ should( >+ actual, >+ 'Output of bandpass filter with sinusoidal modulation of bandpass center frequency') >+ .beCloseToArray(reference, {absoluteThreshold: 3.9787e-5}); >+ }) >+ .then(() => task.done()); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-bandpass-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-bandpass-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..fd0dece8469fdcfe5d173a55e47dbad650529574 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-bandpass-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 82: TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] Biquad bandpass filter. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-bandpass.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-bandpass.html >new file mode 100644 >index 0000000000000000000000000000000000000000..166aa9b3cb8813db11e245edbcea628bf87ef051 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-bandpass.html >@@ -0,0 +1,44 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ biquad-bandpass.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/biquad-filters.js"></script> >+ <script src="/webaudio/resources/biquad-testing.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define( >+ {label: 'test', description: 'Biquad bandpass filter.'}, >+ function(task, should) { >+ >+ // Create offline audio context. >+ let context = new OfflineAudioContext( >+ 2, sampleRate * renderLengthSeconds, sampleRate); >+ >+ // The filters we want to test. >+ let filterParameters = [ >+ {cutoff: 0, q: 0, gain: 1}, >+ {cutoff: 1, q: 0, gain: 1}, >+ {cutoff: 0.5, q: 0, gain: 1}, >+ {cutoff: 0.25, q: 1, gain: 1}, >+ ]; >+ >+ createTestAndRun(context, 'bandpass', { >+ should: should, >+ threshold: 2.2501e-8, >+ filterParameters: filterParameters >+ }).then(task.done.bind(task)); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-basic-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-basic-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..45b964d95b359b36872903401208cf65be3ee2b7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-basic-expected.txt >@@ -0,0 +1,26 @@ >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+PASS Initialize context for testing did not throw an exception. >+PASS < [initialize] All assertions passed. (total 1 assertions) >+PASS > [existence] >+PASS context.createBiquadFilter does exist. >+PASS < [existence] All assertions passed. (total 1 assertions) >+PASS > [parameters] >+PASS numberOfInputs is equal to 1. >+PASS numberOfOutputs is equal to 1. >+PASS channelCountMode is equal to max. >+PASS channelInterpretation is equal to speakers. >+PASS < [parameters] All assertions passed. (total 4 assertions) >+PASS > [exceptions-createBiquadFilter] >+PASS createBiquadFilter() did not throw an exception. >+PASS < [exceptions-createBiquadFilter] All assertions passed. (total 1 assertions) >+PASS > [exceptions-getFrequencyData] >+FAIL X getFrequencyResponse(null, new Float32Array(1), new Float32Array(1)) did not throw an exception. assert_true: expected true got false >+FAIL X getFrequencyResponse(new Float32Array(1), null, new Float32Array(1)) did not throw an exception. assert_true: expected true got false >+FAIL X getFrequencyResponse(new Float32Array(1), new Float32Array(1), null) did not throw an exception. assert_true: expected true got false >+FAIL X getFrequencyResponse(new Float32Array(10), new Float32Array(1), new Float32Array(20)) did not throw an exception. assert_true: expected true got false >+FAIL X getFrequencyResponse(new Float32Array(10), new Float32Array(20), new Float32Array(1)) did not throw an exception. assert_true: expected true got false >+FAIL < [exceptions-getFrequencyData] 5 out of 5 assertions were failed. assert_true: expected true got false >+FAIL # AUDIT TASK RUNNER FINISHED: 1 out of 5 tasks were failed. assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-basic.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-basic.html >new file mode 100644 >index 0000000000000000000000000000000000000000..c4f7c07965fa3edc0a4ddbabf5ed5dd8b192ef27 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-basic.html >@@ -0,0 +1,134 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Basic BiquadFilterNode Properties >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let sampleRate = 48000; >+ let testFrames = 100; >+ >+ // Global context that can be used by the individual tasks. It must be >+ // defined by the initialize task. >+ let context; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('initialize', (task, should) => { >+ should(() => { >+ context = new OfflineAudioContext(1, testFrames, sampleRate); >+ }, 'Initialize context for testing').notThrow(); >+ task.done(); >+ }); >+ >+ audit.define('existence', (task, should) => { >+ should(context.createBiquadFilter, 'context.createBiquadFilter') >+ .exist(); >+ task.done(); >+ }); >+ >+ audit.define('parameters', (task, should) => { >+ // Create a really simple IIR filter. Doesn't much matter what. >+ let coef = Float32Array.from([1]); >+ >+ let f = context.createBiquadFilter(coef, coef); >+ >+ should(f.numberOfInputs, 'numberOfInputs').beEqualTo(1); >+ should(f.numberOfOutputs, 'numberOfOutputs').beEqualTo(1); >+ should(f.channelCountMode, 'channelCountMode').beEqualTo('max'); >+ should(f.channelInterpretation, 'channelInterpretation') >+ .beEqualTo('speakers'); >+ >+ task.done(); >+ }); >+ >+ audit.define('exceptions-createBiquadFilter', (task, should) => { >+ should(function() { >+ // Two args are required. >+ context.createBiquadFilter(); >+ }, 'createBiquadFilter()').notThrow(); >+ >+ task.done(); >+ }); >+ >+ audit.define('exceptions-getFrequencyData', (task, should) => { >+ // Create a really simple IIR filter. Doesn't much matter what. >+ let coef = Float32Array.from([1]); >+ >+ let f = context.createBiquadFilter(coef, coef); >+ >+ should( >+ function() { >+ // frequencyHz can't be null. >+ f.getFrequencyResponse( >+ null, new Float32Array(1), new Float32Array(1)); >+ }, >+ 'getFrequencyResponse(' + >+ 'null, ' + >+ 'new Float32Array(1), ' + >+ 'new Float32Array(1))') >+ .throw('TypeError'); >+ >+ should( >+ function() { >+ // magResponse can't be null. >+ f.getFrequencyResponse( >+ new Float32Array(1), null, new Float32Array(1)); >+ }, >+ 'getFrequencyResponse(' + >+ 'new Float32Array(1), ' + >+ 'null, ' + >+ 'new Float32Array(1))') >+ .throw('TypeError'); >+ >+ should( >+ function() { >+ // phaseResponse can't be null. >+ f.getFrequencyResponse( >+ new Float32Array(1), new Float32Array(1), null); >+ }, >+ 'getFrequencyResponse(' + >+ 'new Float32Array(1), ' + >+ 'new Float32Array(1), ' + >+ 'null)') >+ .throw('TypeError'); >+ >+ should( >+ function() { >+ // magResponse array must the same length as frequencyHz >+ f.getFrequencyResponse( >+ new Float32Array(10), new Float32Array(1), >+ new Float32Array(20)); >+ }, >+ 'getFrequencyResponse(' + >+ 'new Float32Array(10), ' + >+ 'new Float32Array(1), ' + >+ 'new Float32Array(20))') >+ .throw('InvalidAccessError'); >+ >+ should( >+ function() { >+ // phaseResponse array must be the same length as frequencyHz >+ f.getFrequencyResponse( >+ new Float32Array(10), new Float32Array(20), >+ new Float32Array(1)); >+ }, >+ 'getFrequencyResponse(' + >+ 'new Float32Array(10), ' + >+ 'new Float32Array(20), ' + >+ 'new Float32Array(1))') >+ .throw('InvalidAccessError'); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-getFrequencyResponse-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-getFrequencyResponse-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..4f92778e763fbbdb52ead6ad7dc4b1ce3f97bb41 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-getFrequencyResponse-expected.txt >@@ -0,0 +1,16 @@ >+CONSOLE MESSAGE: line 302: TypeError: function is not a constructor (evaluating 'new BiquadFilterNode(context)') >+ >+Harness Error (FAIL), message = TypeError: function is not a constructor (evaluating 'new BiquadFilterNode(context)') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] Biquad frequency response >+PASS Number of non-finite values in magnitude response is equal to 0. >+PASS Number of non-finte values in phase response is equal to 0. >+PASS Number of non-finite values in the expected magnitude response is equal to 0. >+PASS Number of non-finite values in expected phase response is equal to 0. >+PASS Actual and expected results contained only finite values is true. >+PASS Max error (-124.9664097542858 dB) of magnitude response at frequency 1992 Hz is less than or equal to -120.1976646786419. >+PASS Max error (0.0000022600132665057376 deg) in phase response at frequency 1080 Hz is less than or equal to 0.0000031046864044753917. >+PASS < [test] All assertions passed. (total 7 assertions) >+PASS > [getFrequencyResponse] Test out-of-bounds frequency values >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-getFrequencyResponse.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-getFrequencyResponse.html >new file mode 100644 >index 0000000000000000000000000000000000000000..83f057fce7e708cccb43734856f7e3fce604836f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-getFrequencyResponse.html >@@ -0,0 +1,335 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test BiquadFilter getFrequencyResponse() functionality >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/biquad-filters.js"></script> >+ <script src="/webaudio/resources/biquad-testing.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ // Test the frequency response of a biquad filter. We compute the >+ // frequency response for a simple peaking biquad filter and compare it >+ // with the expected frequency response. The actual filter used doesn't >+ // matter since we're testing getFrequencyResponse and not the actual >+ // filter output. The filters are extensively tested in other biquad >+ // tests. >+ >+ // The magnitude response of the biquad filter. >+ let magResponse; >+ >+ // The phase response of the biquad filter. >+ let phaseResponse; >+ >+ // Number of frequency samples to take. >+ let numberOfFrequencies = 1000; >+ >+ // The filter parameters. >+ let filterCutoff = 1000; // Hz. >+ let filterQ = 1; >+ let filterGain = 5; // Decibels. >+ >+ // The maximum allowed error in the magnitude response. >+ let maxAllowedMagError = 9.775e-7; >+ >+ // The maximum allowed error in the phase response. >+ let maxAllowedPhaseError = 5.4187e-8; >+ >+ // The magnitudes and phases of the reference frequency response. >+ let expectedMagnitudes; >+ let expectedPhases; >+ >+ // Convert frequency in Hz to a normalized frequency between 0 to 1 with 1 >+ // corresponding to the Nyquist frequency. >+ function normalizedFrequency(freqHz, sampleRate) { >+ let nyquist = sampleRate / 2; >+ return freqHz / nyquist; >+ } >+ >+ // Get the filter response at a (normalized) frequency |f| for the filter >+ // with coefficients |coef|. >+ function getResponseAt(coef, f) { >+ let b0 = coef.b0; >+ let b1 = coef.b1; >+ let b2 = coef.b2; >+ let a1 = coef.a1; >+ let a2 = coef.a2; >+ >+ // H(z) = (b0 + b1 / z + b2 / z^2) / (1 + a1 / z + a2 / z^2) >+ // >+ // Compute H(exp(i * pi * f)). No native complex numbers in javascript, >+ // so break H(exp(i * pi * // f)) in to the real and imaginary parts of >+ // the numerator and denominator. Let omega = pi * f. Then the >+ // numerator is >+ // >+ // b0 + b1 * cos(omega) + b2 * cos(2 * omega) - i * (b1 * sin(omega) + >+ // b2 * sin(2 * omega)) >+ // >+ // and the denominator is >+ // >+ // 1 + a1 * cos(omega) + a2 * cos(2 * omega) - i * (a1 * sin(omega) + a2 >+ // * sin(2 * omega)) >+ // >+ // Compute the magnitude and phase from the real and imaginary parts. >+ >+ let omega = Math.PI * f; >+ let numeratorReal = >+ b0 + b1 * Math.cos(omega) + b2 * Math.cos(2 * omega); >+ let numeratorImag = -(b1 * Math.sin(omega) + b2 * Math.sin(2 * omega)); >+ let denominatorReal = >+ 1 + a1 * Math.cos(omega) + a2 * Math.cos(2 * omega); >+ let denominatorImag = >+ -(a1 * Math.sin(omega) + a2 * Math.sin(2 * omega)); >+ >+ let magnitude = Math.sqrt( >+ (numeratorReal * numeratorReal + numeratorImag * numeratorImag) / >+ (denominatorReal * denominatorReal + >+ denominatorImag * denominatorImag)); >+ let phase = Math.atan2(numeratorImag, numeratorReal) - >+ Math.atan2(denominatorImag, denominatorReal); >+ >+ if (phase >= Math.PI) { >+ phase -= 2 * Math.PI; >+ } else if (phase <= -Math.PI) { >+ phase += 2 * Math.PI; >+ } >+ >+ return {magnitude: magnitude, phase: phase}; >+ } >+ >+ // Compute the reference frequency response for the biquad filter |filter| >+ // at the frequency samples given by |frequencies|. >+ function frequencyResponseReference(filter, frequencies) { >+ let sampleRate = filter.context.sampleRate; >+ let normalizedFreq = >+ normalizedFrequency(filter.frequency.value, sampleRate); >+ let filterCoefficients = createFilter( >+ filter.type, normalizedFreq, filter.Q.value, filter.gain.value); >+ >+ let magnitudes = []; >+ let phases = []; >+ >+ for (let k = 0; k < frequencies.length; ++k) { >+ let response = getResponseAt( >+ filterCoefficients, >+ normalizedFrequency(frequencies[k], sampleRate)); >+ magnitudes.push(response.magnitude); >+ phases.push(response.phase); >+ } >+ >+ return {magnitudes: magnitudes, phases: phases}; >+ } >+ >+ // Compute a set of linearly spaced frequencies. >+ function createFrequencies(nFrequencies, sampleRate) { >+ let frequencies = new Float32Array(nFrequencies); >+ let nyquist = sampleRate / 2; >+ let freqDelta = nyquist / nFrequencies; >+ >+ for (let k = 0; k < nFrequencies; ++k) { >+ frequencies[k] = k * freqDelta; >+ } >+ >+ return frequencies; >+ } >+ >+ function linearToDecibels(x) { >+ if (x) { >+ return 20 * Math.log(x) / Math.LN10; >+ } else { >+ return -1000; >+ } >+ } >+ >+ // Look through the array and find any NaN or infinity. Returns the index >+ // of the first occurence or -1 if none. >+ function findBadNumber(signal) { >+ for (let k = 0; k < signal.length; ++k) { >+ if (!isValidNumber(signal[k])) { >+ return k; >+ } >+ } >+ return -1; >+ } >+ >+ // Compute absolute value of the difference between phase angles, taking >+ // into account the wrapping of phases. >+ function absolutePhaseDifference(x, y) { >+ let diff = Math.abs(x - y); >+ >+ if (diff > Math.PI) { >+ diff = 2 * Math.PI - diff; >+ } >+ return diff; >+ } >+ >+ // Compare the frequency response with our expected response. >+ function compareResponses( >+ should, filter, frequencies, magResponse, phaseResponse) { >+ let expectedResponse = frequencyResponseReference(filter, frequencies); >+ >+ expectedMagnitudes = expectedResponse.magnitudes; >+ expectedPhases = expectedResponse.phases; >+ >+ let n = magResponse.length; >+ let badResponse = false; >+ >+ let maxMagError = -1; >+ let maxMagErrorIndex = -1; >+ >+ let k; >+ let hasBadNumber; >+ >+ hasBadNumber = findBadNumber(magResponse); >+ badResponse = !should( >+ hasBadNumber >= 0 ? 1 : 0, >+ 'Number of non-finite values in magnitude response') >+ .beEqualTo(0); >+ >+ hasBadNumber = findBadNumber(phaseResponse); >+ badResponse = !should( >+ hasBadNumber >= 0 ? 1 : 0, >+ 'Number of non-finte values in phase response') >+ .beEqualTo(0); >+ >+ // These aren't testing the implementation itself. Instead, these are >+ // sanity checks on the reference. Failure here does not imply an error >+ // in the implementation. >+ hasBadNumber = findBadNumber(expectedMagnitudes); >+ badResponse = >+ !should( >+ hasBadNumber >= 0 ? 1 : 0, >+ 'Number of non-finite values in the expected magnitude response') >+ .beEqualTo(0); >+ >+ hasBadNumber = findBadNumber(expectedPhases); >+ badResponse = >+ !should( >+ hasBadNumber >= 0 ? 1 : 0, >+ 'Number of non-finite values in expected phase response') >+ .beEqualTo(0); >+ >+ // If we found a NaN or infinity, the following tests aren't very >+ // helpful, especially for NaN. We run them anyway, after printing a >+ // warning message. >+ should( >+ !badResponse, >+ 'Actual and expected results contained only finite values') >+ .beTrue(); >+ >+ for (k = 0; k < n; ++k) { >+ let error = Math.abs( >+ linearToDecibels(magResponse[k]) - >+ linearToDecibels(expectedMagnitudes[k])); >+ if (error > maxMagError) { >+ maxMagError = error; >+ maxMagErrorIndex = k; >+ } >+ } >+ >+ should( >+ linearToDecibels(maxMagError), >+ 'Max error (' + linearToDecibels(maxMagError) + >+ ' dB) of magnitude response at frequency ' + >+ frequencies[maxMagErrorIndex] + ' Hz') >+ .beLessThanOrEqualTo(linearToDecibels(maxAllowedMagError)); >+ let maxPhaseError = -1; >+ let maxPhaseErrorIndex = -1; >+ >+ for (k = 0; k < n; ++k) { >+ let error = >+ absolutePhaseDifference(phaseResponse[k], expectedPhases[k]); >+ if (error > maxPhaseError) { >+ maxPhaseError = error; >+ maxPhaseErrorIndex = k; >+ } >+ } >+ >+ should( >+ radToDegree(maxPhaseError), >+ 'Max error (' + radToDegree(maxPhaseError) + >+ ' deg) in phase response at frequency ' + >+ frequencies[maxPhaseErrorIndex] + ' Hz') >+ .beLessThanOrEqualTo(radToDegree(maxAllowedPhaseError)); >+ } >+ >+ function radToDegree(rad) { >+ // Radians to degrees >+ return rad * 180 / Math.PI; >+ } >+ >+ audit.define( >+ {label: 'test', description: 'Biquad frequency response'}, >+ function(task, should) { >+ context = new AudioContext(); >+ >+ filter = context.createBiquadFilter(); >+ >+ // Arbitrarily test a peaking filter, but any kind of filter can be >+ // tested. >+ filter.type = 'peaking'; >+ filter.frequency.value = filterCutoff; >+ filter.Q.value = filterQ; >+ filter.gain.value = filterGain; >+ >+ let frequencies = >+ createFrequencies(numberOfFrequencies, context.sampleRate); >+ magResponse = new Float32Array(numberOfFrequencies); >+ phaseResponse = new Float32Array(numberOfFrequencies); >+ >+ filter.getFrequencyResponse( >+ frequencies, magResponse, phaseResponse); >+ compareResponses( >+ should, filter, frequencies, magResponse, phaseResponse); >+ >+ task.done(); >+ }); >+ >+ audit.define( >+ { >+ label: 'getFrequencyResponse', >+ description: 'Test out-of-bounds frequency values' >+ }, >+ (task, should) => { >+ let context = new OfflineAudioContext(1, 1, sampleRate); >+ let filter = new BiquadFilterNode(context); >+ >+ // Frequencies to test. These are all outside the valid range of >+ // frequencies of 0 to Nyquist. >+ let freq = new Float32Array(2); >+ freq[0] = -1; >+ freq[1] = context.sampleRate / 2 + 1; >+ >+ let mag = new Float32Array(freq.length); >+ let phase = new Float32Array(freq.length); >+ >+ filter.getFrequencyResponse(freq, mag, phase); >+ >+ // Verify that the returned magnitude and phase entries are alL NaN >+ // since the frequencies are outside the valid range >+ for (let k = 0; k < mag.length; ++k) { >+ should(mag[k], >+ 'Magnitude response at frequency ' + freq[k]) >+ .beNaN(); >+ } >+ >+ for (let k = 0; k < phase.length; ++k) { >+ should(phase[k], >+ 'Phase response at frequency ' + freq[k]) >+ .beNaN(); >+ } >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highpass-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highpass-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..0a9ae59d3203c2e9e43121341c0db92ac44f63f8 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highpass-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 82: TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] Biquad highpass filter >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highpass.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highpass.html >new file mode 100644 >index 0000000000000000000000000000000000000000..45c335bc4b894838a28f6aa6c452d4b6a98c824a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highpass.html >@@ -0,0 +1,42 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ biquad-highpass.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/biquad-filters.js"></script> >+ <script src="/webaudio/resources/biquad-testing.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define( >+ {label: 'test', description: 'Biquad highpass filter'}, >+ function(task, should) { >+ // Create offline audio context. >+ let context = new OfflineAudioContext( >+ 2, sampleRate * renderLengthSeconds, sampleRate); >+ >+ // The filters we want to test. >+ let filterParameters = [ >+ {cutoff: 0, q: 1, gain: 1}, >+ {cutoff: 1, q: 1, gain: 1}, >+ {cutoff: 0.25, q: 1, gain: 1}, >+ ]; >+ >+ createTestAndRun(context, 'highpass', { >+ should: should, >+ threshold: 1.5487e-8, >+ filterParameters: filterParameters >+ }).then(task.done.bind(task)); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highshelf-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highshelf-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..9192e9e1d6ba102e6997e3de184bac962a31efde >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highshelf-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 82: TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] Biquad highshelf filter >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highshelf.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highshelf.html >new file mode 100644 >index 0000000000000000000000000000000000000000..345195f104e673e0e2481481f0b5e4cd5dbc0dea >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highshelf.html >@@ -0,0 +1,43 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ biquad-highshelf.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/biquad-filters.js"></script> >+ <script src="/webaudio/resources/biquad-testing.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define( >+ {label: 'test', description: 'Biquad highshelf filter'}, >+ function(task, should) { >+ >+ // Create offline audio context. >+ let context = new OfflineAudioContext( >+ 2, sampleRate * renderLengthSeconds, sampleRate); >+ >+ // The filters we want to test. >+ let filterParameters = [ >+ {cutoff: 0, q: 10, gain: 10}, >+ {cutoff: 1, q: 10, gain: 10}, >+ {cutoff: 0.25, q: 10, gain: 10}, >+ ]; >+ >+ createTestAndRun(context, 'highshelf', { >+ should: should, >+ threshold: 6.2577e-8, >+ filterParameters: filterParameters >+ }).then(task.done.bind(task)); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowpass-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowpass-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..0bcd4af4530d6df6f7c24fdba559af2a6ce8e7ff >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowpass-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 82: TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] Biquad lowpass filter >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowpass.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowpass.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d20786e36b16d7ba36841dd5fcfb30c081113fb2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowpass.html >@@ -0,0 +1,45 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ biquad-lowpass.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/biquad-filters.js"></script> >+ <script src="/webaudio/resources/biquad-testing.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define( >+ {label: 'test', description: 'Biquad lowpass filter'}, >+ function(task, should) { >+ >+ // Create offline audio context. >+ let context = new OfflineAudioContext( >+ 2, sampleRate * renderLengthSeconds, sampleRate); >+ >+ // The filters we want to test. >+ let filterParameters = [ >+ {cutoff: 0, q: 1, gain: 1}, >+ {cutoff: 1, q: 1, gain: 1}, >+ {cutoff: 0.25, q: 1, gain: 1}, >+ {cutoff: 0.25, q: 1, gain: 1, detune: 100}, >+ {cutoff: 0.01, q: 1, gain: 1, detune: -200}, >+ ]; >+ >+ createTestAndRun(context, 'lowpass', { >+ should: should, >+ threshold: 9.7869e-8, >+ filterParameters: filterParameters >+ }).then(task.done.bind(task)); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowshelf-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowshelf-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..b03f5e0b8baec05becf5f8027aea6ee837cb6b5b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowshelf-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 82: TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] Biquad lowshelf filter >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowshelf.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowshelf.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ab76cefd4bc3de478a2c450638b8adf5de5a929c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowshelf.html >@@ -0,0 +1,43 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ biquad-lowshelf.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/biquad-filters.js"></script> >+ <script src="/webaudio/resources/biquad-testing.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define( >+ {label: 'test', description: 'Biquad lowshelf filter'}, >+ function(task, should) { >+ >+ // Create offline audio context. >+ let context = new OfflineAudioContext( >+ 2, sampleRate * renderLengthSeconds, sampleRate); >+ >+ // The filters we want to test. >+ let filterParameters = [ >+ {cutoff: 0, q: 10, gain: 10}, >+ {cutoff: 1, q: 10, gain: 10}, >+ {cutoff: 0.25, q: 10, gain: 10}, >+ ]; >+ >+ createTestAndRun(context, 'lowshelf', { >+ should: should, >+ threshold: 3.8349e-8, >+ filterParameters: filterParameters >+ }).then(task.done.bind(task)); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-notch-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-notch-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..f5b9ef6bb78728518d8cb3439769a61dd443f6f0 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-notch-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 82: TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] Biquad notch filter >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-notch.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-notch.html >new file mode 100644 >index 0000000000000000000000000000000000000000..98e6e6e02c0813692c579821b48b84959cb89367 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-notch.html >@@ -0,0 +1,43 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ biquad-notch.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/biquad-filters.js"></script> >+ <script src="/webaudio/resources/biquad-testing.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define( >+ {label: 'test', description: 'Biquad notch filter'}, >+ function(task, should) { >+ >+ // Create offline audio context. >+ let context = new OfflineAudioContext( >+ 2, sampleRate * renderLengthSeconds, sampleRate); >+ >+ let filterParameters = [ >+ {cutoff: 0, q: 10, gain: 1}, >+ {cutoff: 1, q: 10, gain: 1}, >+ {cutoff: .5, q: 0, gain: 1}, >+ {cutoff: 0.25, q: 10, gain: 1}, >+ ]; >+ >+ createTestAndRun(context, 'notch', { >+ should: should, >+ threshold: 1.9669e-8, >+ filterParameters: filterParameters >+ }).then(task.done.bind(task)); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-peaking-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-peaking-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d6ec32237071a2c515b9f6775c981480db7b17a1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-peaking-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 82: TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'context.startRendering().then') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] Biquad peaking filter >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-peaking.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-peaking.html >new file mode 100644 >index 0000000000000000000000000000000000000000..90b7c1546de30e1099379e1672ea48edca7c6ba4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-peaking.html >@@ -0,0 +1,46 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ biquad-peaking.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/biquad-filters.js"></script> >+ <script src="/webaudio/resources/biquad-testing.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define( >+ {label: 'test', description: 'Biquad peaking filter'}, >+ function(task, should) { >+ >+ window.jsTestIsAsync = true; >+ >+ // Create offline audio context. >+ let context = new OfflineAudioContext( >+ 2, sampleRate * renderLengthSeconds, sampleRate); >+ >+ // The filters we want to test. >+ let filterParameters = [ >+ {cutoff: 0, q: 10, gain: 10}, >+ {cutoff: 1, q: 10, gain: 10}, >+ {cutoff: .5, q: 0, gain: 10}, >+ {cutoff: 0.25, q: 10, gain: 10}, >+ ]; >+ >+ createTestAndRun(context, 'peaking', { >+ should: should, >+ threshold: 5.8234e-8, >+ filterParameters: filterParameters >+ }).then(task.done.bind(task)); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-tail-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-tail-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..017cf25bc53bb5d0a29189ef9c92be9b4b525e83 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-tail-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 43: SyntaxError: The string did not match the expected pattern. >+ >+Harness Error (FAIL), message = SyntaxError: The string did not match the expected pattern. >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] Biquad Tail Output >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-tail.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-tail.html >new file mode 100644 >index 0000000000000000000000000000000000000000..3141bf7ff31fd39101e0635ad4febdd090f679eb >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-tail.html >@@ -0,0 +1,71 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Biquad Tail Output >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ // A high sample rate shows the issue more clearly. >+ let sampleRate = 192000; >+ // Some short duration because we don't need to run the test for very >+ // long. >+ let testDurationSec = 0.5; >+ let testDurationFrames = testDurationSec * sampleRate; >+ >+ // Amplitude experimentally determined to give a biquad output close to 1. >+ // (No attempt was made to produce exactly 1; it's not needed.) >+ let sourceAmplitude = 100; >+ >+ // The output of the biquad filter should not change by more than this >+ // much between output samples. Threshold was determined experimentally. >+ let glitchThreshold = 0.012968; >+ >+ // Test that a Biquad filter doesn't have it's output terminated because >+ // the input has gone away. Generally, when a source node is finished, it >+ // disconnects itself from any downstream nodes. This is the correct >+ // behavior. Nodes that have no inputs (disconnected) are generally >+ // assumed to output zeroes. This is also desired behavior. However, >+ // biquad filters have memory so they should not suddenly output zeroes >+ // when the input is disconnected. This test checks to see if the output >+ // doesn't suddenly change to zero. >+ audit.define( >+ {label: 'test', description: 'Biquad Tail Output'}, >+ function(task, should) { >+ let context = >+ new OfflineAudioContext(1, testDurationFrames, sampleRate); >+ >+ // Create an impulse source. >+ let buffer = context.createBuffer(1, 1, context.sampleRate); >+ buffer.getChannelData(0)[0] = sourceAmplitude; >+ let source = context.createBufferSource(); >+ source.buffer = buffer; >+ >+ // Create the biquad filter. It doesn't really matter what kind, so >+ // the default filter type and parameters is fine. Connect the >+ // source to it. >+ let biquad = context.createBiquadFilter(); >+ source.connect(biquad); >+ biquad.connect(context.destination); >+ >+ source.start(); >+ >+ context.startRendering().then(function(result) { >+ // There should be no large discontinuities in the output >+ should(result.getChannelData(0), 'Biquad output') >+ .notGlitch(glitchThreshold); >+ task.done(); >+ }) >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquadfilternode-basic-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquadfilternode-basic-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..eb445ee7638dbb106cd5bd1019b3d71e395f1e39 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquadfilternode-basic-expected.txt >@@ -0,0 +1,29 @@ >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test] Basic tests for BiquadFilterNode >+PASS Number of inputs is equal to 1. >+PASS Number of outputs is equal to 1. >+PASS Default filter type is equal to lowpass. >+PASS Default frequency value is equal to 350. >+PASS Default Q value is equal to 1. >+PASS Default gain value is equal to 0. >+PASS Setting filter.type to lowpass did not throw an exception. >+PASS Filter type is is equal to lowpass. >+PASS Setting filter.type to highpass did not throw an exception. >+PASS Filter type is is equal to highpass. >+PASS Setting filter.type to bandpass did not throw an exception. >+PASS Filter type is is equal to bandpass. >+PASS Setting filter.type to lowshelf did not throw an exception. >+PASS Filter type is is equal to lowshelf. >+PASS Setting filter.type to highshelf did not throw an exception. >+PASS Filter type is is equal to highshelf. >+PASS Setting filter.type to peaking did not throw an exception. >+PASS Filter type is is equal to peaking. >+PASS Setting filter.type to notch did not throw an exception. >+PASS Filter type is is equal to notch. >+PASS Setting filter.type to allpass did not throw an exception. >+PASS Filter type is is equal to allpass. >+PASS Setting filter.type to (invalid) 99 is not equal to 99. >+PASS < [test] All assertions passed. (total 23 assertions) >+PASS # AUDIT TASK RUNNER FINISHED: 1 tasks ran successfully. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquadfilternode-basic.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquadfilternode-basic.html >new file mode 100644 >index 0000000000000000000000000000000000000000..7e71d073024cb2040b7a4d7ea5ff681f803e21b0 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquadfilternode-basic.html >@@ -0,0 +1,64 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ biquadfilternode-basic.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define( >+ {label: 'test', description: 'Basic tests for BiquadFilterNode'}, >+ function(task, should) { >+ >+ let context = new AudioContext(); >+ let filter = context.createBiquadFilter(); >+ >+ should(filter.numberOfInputs, 'Number of inputs').beEqualTo(1); >+ >+ should(filter.numberOfOutputs, 'Number of outputs').beEqualTo(1); >+ >+ should(filter.type, 'Default filter type').beEqualTo('lowpass'); >+ >+ should(filter.frequency.value, 'Default frequency value') >+ .beEqualTo(350); >+ >+ should(filter.Q.value, 'Default Q value').beEqualTo(1); >+ >+ should(filter.gain.value, 'Default gain value').beEqualTo(0); >+ >+ // Check that all legal filter types can be set. >+ let filterTypeArray = [ >+ {type: 'lowpass'}, {type: 'highpass'}, {type: 'bandpass'}, >+ {type: 'lowshelf'}, {type: 'highshelf'}, {type: 'peaking'}, >+ {type: 'notch'}, {type: 'allpass'} >+ ]; >+ >+ for (let i = 0; i < filterTypeArray.length; ++i) { >+ should( >+ () => filter.type = filterTypeArray[i].type, >+ 'Setting filter.type to ' + filterTypeArray[i].type) >+ .notThrow(); >+ should(filter.type, 'Filter type is') >+ .beEqualTo(filterTypeArray[i].type); >+ } >+ >+ >+ // Check that numerical values are no longer supported >+ filter.type = 99; >+ should(filter.type, 'Setting filter.type to (invalid) 99') >+ .notBeEqualTo(99); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/ctor-biquadfilter-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/ctor-biquadfilter-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..4138bb89245a0498bed0ee606086953dbc8b3488 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/ctor-biquadfilter-expected.txt >@@ -0,0 +1,17 @@ >+CONSOLE MESSAGE: line 227: TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+PASS context = new OfflineAudioContext(...) did not throw an exception. >+PASS < [initialize] All assertions passed. (total 1 assertions) >+PASS > [invalid constructor] >+PASS new BiquadFilterNode() threw TypeError: "function is not a constructor (evaluating 'new window[name]()')". >+PASS new BiquadFilterNode(1) threw TypeError: "function is not a constructor (evaluating 'new window[name](1)')". >+PASS new BiquadFilterNode(context, 42) threw TypeError: "function is not a constructor (evaluating 'new window[name](context, 42)')". >+PASS < [invalid constructor] All assertions passed. (total 3 assertions) >+PASS > [default constructor] >+FAIL X node0 = new BiquadFilterNode(context) incorrectly threw TypeError: "function is not a constructor (evaluating 'new window[name](context, options.constructorOptions)')". assert_true: expected true got false >+FAIL X node0 instanceof BiquadFilterNode is not equal to true. Got false. assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/ctor-biquadfilter.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/ctor-biquadfilter.html >new file mode 100644 >index 0000000000000000000000000000000000000000..e63479f985920745f75b857fa7b639417d5bf208 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/ctor-biquadfilter.html >@@ -0,0 +1,86 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Constructor: BiquadFilter >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audionodeoptions.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let context; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('initialize', (task, should) => { >+ context = initializeContext(should); >+ task.done(); >+ }); >+ >+ audit.define('invalid constructor', (task, should) => { >+ testInvalidConstructor(should, 'BiquadFilterNode', context); >+ task.done(); >+ }); >+ >+ audit.define('default constructor', (task, should) => { >+ let prefix = 'node0'; >+ let node = testDefaultConstructor(should, 'BiquadFilterNode', context, { >+ prefix: prefix, >+ numberOfInputs: 1, >+ numberOfOutputs: 1, >+ channelCount: 2, >+ channelCountMode: 'max', >+ channelInterpretation: 'speakers' >+ }); >+ >+ testDefaultAttributes(should, node, prefix, [ >+ {name: 'type', value: 'lowpass'}, {name: 'Q', value: 1}, >+ {name: 'detune', value: 0}, {name: 'frequency', value: 350}, >+ {name: 'gain', value: 0.0} >+ ]); >+ >+ task.done(); >+ }); >+ >+ audit.define('test AudioNodeOptions', (task, should) => { >+ testAudioNodeOptions(should, context, 'BiquadFilterNode'); >+ task.done(); >+ }); >+ >+ audit.define('construct with options', (task, should) => { >+ let node; >+ let options = { >+ type: 'highpass', >+ frequency: 512, >+ detune: 1, >+ Q: 5, >+ gain: 3, >+ }; >+ >+ should( >+ () => { >+ node = new BiquadFilterNode(context, options); >+ }, >+ 'node = new BiquadFilterNode(..., ' + JSON.stringify(options) + ')') >+ .notThrow(); >+ >+ // Test that attributes are set according to the option values. >+ should(node.type, 'node.type').beEqualTo(options.type); >+ should(node.frequency.value, 'node.frequency.value') >+ .beEqualTo(options.frequency); >+ should(node.detune.value, 'node.detuen.value') >+ .beEqualTo(options.detune); >+ should(node.Q.value, 'node.Q.value').beEqualTo(options.Q); >+ should(node.gain.value, 'node.gain.value').beEqualTo(options.gain); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/no-dezippering-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/no-dezippering-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..6619b02a981a84295bd086dbe02d0051e22111c6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/no-dezippering-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 199: SyntaxError: The string did not match the expected pattern. >+ >+Harness Error (FAIL), message = SyntaxError: The string did not match the expected pattern. >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [Test 0] No dezippering for frequency >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/no-dezippering.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/no-dezippering.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d54bc0bd8abe5f65bbfa618c76c286be78b9a6ac >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/no-dezippering.html >@@ -0,0 +1,288 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ biquad-bandpass.html >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/biquad-filters.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ >+ // In the tests below, the initial values are not important, except that >+ // we wanted them to be all different so that the output contains >+ // different values for the first few samples. Otherwise, the actual >+ // values don't really matter. A peaking filter is used because the >+ // frequency, Q, gain, and detune parameters are used by this filter. >+ // >+ // Also, for the changeList option, the times and new values aren't really >+ // important. They just need to change so that we can verify that the >+ // outputs from the .value setter still matches the output from the >+ // corresponding setValueAtTime. >+ audit.define( >+ {label: 'Test 0', description: 'No dezippering for frequency'}, >+ (task, should) => { >+ doTest(should, { >+ paramName: 'frequency', >+ initializer: {type: 'peaking', Q: 1, gain: 5}, >+ changeList: >+ [{quantum: 2, newValue: 800}, {quantum: 7, newValue: 200}], >+ threshold: 3.0399e-6 >+ }).then(() => task.done()); >+ }); >+ >+ audit.define( >+ {label: 'Test 1', description: 'No dezippering for detune'}, >+ (task, should) => { >+ doTest(should, { >+ paramName: 'detune', >+ initializer: >+ {type: 'peaking', frequency: 400, Q: 3, detune: 33, gain: 10}, >+ changeList: >+ [{quantum: 2, newValue: 1000}, {quantum: 5, newValue: -400}], >+ threshold: 4.0532e-6 >+ }).then(() => task.done()); >+ }); >+ >+ audit.define( >+ {label: 'Test 2', description: 'No dezippering for Q'}, >+ (task, should) => { >+ doTest(should, { >+ paramName: 'Q', >+ initializer: {type: 'peaking', Q: 5}, >+ changeList: >+ [{quantum: 2, newValue: 10}, {quantum: 8, newValue: -10}] >+ }).then(() => task.done()); >+ }); >+ >+ audit.define( >+ {label: 'Test 3', description: 'No dezippering for gain'}, >+ (task, should) => { >+ doTest(should, { >+ paramName: 'gain', >+ initializer: {type: 'peaking', gain: 1}, >+ changeList: >+ [{quantum: 2, newValue: 5}, {quantum: 6, newValue: -.3}], >+ threshold: 1.9074e-6 >+ }).then(() => task.done()); >+ }); >+ >+ // This test compares the filter output against a JS implementation of the >+ // filter. We're only testing a change in the frequency for a lowpass >+ // filter. This assumes we don't need to test other AudioParam changes >+ // with JS code because any mistakes would be exposed in the tests above. >+ audit.define( >+ { >+ label: 'Test 4', >+ description: 'No dezippering of frequency vs JS filter' >+ }, >+ (task, should) => { >+ // Channel 0 is the source, channel 1 is the filtered output. >+ let context = new OfflineAudioContext(2, 2048, 16384); >+ >+ let merger = new ChannelMergerNode( >+ context, {numberOfInputs: context.destination.channelCount}); >+ merger.connect(context.destination); >+ >+ let src = new OscillatorNode(context); >+ let f = new BiquadFilterNode(context, {type: 'lowpass'}); >+ >+ // Remember the initial filter parameters. >+ let initialFilter = { >+ type: f.type, >+ frequency: f.frequency.value, >+ gain: f.gain.value, >+ detune: f.detune.value, >+ Q: f.Q.value >+ }; >+ >+ src.connect(merger, 0, 0); >+ src.connect(f).connect(merger, 0, 1); >+ >+ // Apply the filter change at frame |changeFrame| with a new >+ // frequency value of |newValue|. >+ let changeFrame = 2 * RENDER_QUANTUM_FRAMES; >+ let newValue = 750; >+ >+ context.suspend(changeFrame / context.sampleRate) >+ .then(() => f.frequency.value = newValue) >+ .then(() => context.resume()); >+ >+ src.start(); >+ >+ context.startRendering() >+ .then(audio => { >+ let signal = audio.getChannelData(0); >+ let actual = audio.getChannelData(1); >+ >+ // Get initial filter coefficients and updated coefficients >+ let nyquistFreq = context.sampleRate / 2; >+ let initialCoef = createFilter( >+ initialFilter.type, initialFilter.frequency / nyquistFreq, >+ initialFilter.Q, initialFilter.gain); >+ >+ let finalCoef = createFilter( >+ f.type, f.frequency.value / nyquistFreq, f.Q.value, >+ f.gain.value); >+ >+ let expected = new Float32Array(signal.length); >+ >+ // Filter the initial part of the signal. >+ expected[0] = >+ filterSample(signal[0], initialCoef, 0, 0, 0, 0); >+ expected[1] = filterSample( >+ signal[1], initialCoef, expected[0], 0, signal[0], 0); >+ >+ for (let k = 2; k < changeFrame; ++k) { >+ expected[k] = filterSample( >+ signal[k], initialCoef, expected[k - 1], >+ expected[k - 2], signal[k - 1], signal[k - 2]); >+ } >+ >+ // Filter the rest of the input with the new coefficients >+ for (let k = changeFrame; k < signal.length; ++k) { >+ expected[k] = filterSample( >+ signal[k], finalCoef, expected[k - 1], expected[k - 2], >+ signal[k - 1], signal[k - 2]); >+ } >+ >+ // The JS filter should match the actual output. >+ let match = >+ should(actual, 'Output from ' + f.type + ' filter') >+ .beCloseToArray( >+ expected, {absoluteThreshold: 4.7684e-7}); >+ should(match, 'Output matches JS filter results').beTrue(); >+ }) >+ .then(() => task.done()); >+ }); >+ >+ audit.define( >+ {label: 'Test 5', description: 'Test with modulation'}, >+ (task, should) => { >+ doTest(should, { >+ prefix: 'Modulation: ', >+ paramName: 'frequency', >+ initializer: {type: 'peaking', Q: 5, gain: 5}, >+ modulation: true, >+ changeList: >+ [{quantum: 2, newValue: 10}, {quantum: 8, newValue: -10}] >+ }).then(() => task.done()); >+ >+ }); >+ >+ audit.run(); >+ >+ // Run test, returning the promise from startRendering. |options| >+ // specifies the parameters for the test. |options.paramName| is the name >+ // of the AudioParam of the filter that is being tested. >+ // |options.initializer| is the initial value to be used in constructing >+ // the filter. |options.changeList| is an array consisting of dictionary >+ // with two members: |quantum| is the rendering quantum at which time we >+ // want to change the AudioParam value, and |newValue| is the value to be >+ // used. >+ function doTest(should, options) { >+ let paramName = options.paramName; >+ let newValue = options.newValue; >+ let prefix = options.prefix || ''; >+ >+ // Create offline audio context. The sample rate should be a power of >+ // two to eliminate any round-off errors in computing the time at which >+ // to suspend the context for the parameter change. The length is >+ // fairly arbitrary as long as it's big enough to the changeList >+ // values. There are two channels: channel 0 is output for the filter >+ // under test, and channel 1 is the output of referencef filter. >+ let context = new OfflineAudioContext(2, 2048, 16384); >+ >+ let merger = new ChannelMergerNode( >+ context, {numberOfInputs: context.destination.channelCount}); >+ merger.connect(context.destination); >+ >+ let src = new OscillatorNode(context); >+ >+ // |f0| is the filter under test that will have its AudioParam value >+ // changed. |f1| is the reference filter that uses setValueAtTime to >+ // update the AudioParam value. >+ let f0 = new BiquadFilterNode(context, options.initializer); >+ let f1 = new BiquadFilterNode(context, options.initializer); >+ >+ src.connect(f0).connect(merger, 0, 0); >+ src.connect(f1).connect(merger, 0, 1); >+ >+ // Modulate the AudioParam with an input signal, if requested. >+ if (options.modulation) { >+ // The modulation signal is a sine wave with amplitude 1/3 the cutoff >+ // frequency of the test filter. The amplitude is fairly arbitrary, >+ // but we want it to be a significant fraction of the cutoff so that >+ // the cutoff varies quite a bit in the test. >+ let mod = >+ new OscillatorNode(context, {type: 'sawtooth', frequency: 1000}); >+ let modGain = new GainNode(context, {gain: f0.frequency.value / 3}); >+ mod.connect(modGain); >+ modGain.connect(f0[paramName]); >+ modGain.connect(f1[paramName]); >+ mod.start(); >+ } >+ // Output a message showing where we're starting from. >+ should(f0[paramName].value, prefix + `At time 0, ${paramName}`) >+ .beEqualTo(f0[paramName].value); >+ >+ // Schedule all of the desired changes from |changeList|. >+ options.changeList.forEach(change => { >+ let changeTime = >+ change.quantum * RENDER_QUANTUM_FRAMES / context.sampleRate; >+ let value = change.newValue; >+ >+ // Just output a message to show what we're doing. >+ should(value, prefix + `At time ${changeTime}, ${paramName}`) >+ .beEqualTo(value); >+ >+ // Update the AudioParam value of each filter using setValueAtTime or >+ // the value setter. >+ f1[paramName].setValueAtTime(value, changeTime); >+ context.suspend(changeTime) >+ .then(() => f0[paramName].value = value) >+ .then(() => context.resume()); >+ }); >+ >+ src.start(); >+ >+ return context.startRendering().then(audio => { >+ let actual = audio.getChannelData(0); >+ let expected = audio.getChannelData(1); >+ >+ // The output from both filters MUST match exactly if dezippering has >+ // been properly removed. >+ let match = should(actual, `${prefix}Output from ${paramName} setter`) >+ .beCloseToArray( >+ expected, {absoluteThreshold: options.threshold}); >+ >+ // Just an extra message saying that what we're comparing, to make the >+ // output clearer. (Not really neceesary, but nice.) >+ should( >+ match, >+ `${prefix}Output from ${ >+ paramName >+ } setter matches setValueAtTime output`) >+ .beTrue(); >+ }); >+ } >+ >+ // Filter one sample: >+ // >+ // y[n] = b0 * x[n] + b1*x[n-1] + b2*x[n-2] - a1*y[n-1] - a2*y[n-2] >+ // >+ // where |x| is x[n], |xn1| is x[n-1], |xn2| is x[n-2], |yn1| is y[n-1], >+ // and |yn2| is y[n-2]. |coef| is a dictonary of the filter coefficients >+ // |b0|, |b1|, |b2|, |a1|, and |a2|. >+ function filterSample(x, coef, yn1, yn2, xn1, xn2) { >+ return coef.b0 * x + coef.b1 * xn1 + coef.b2 * xn2 - coef.a1 * yn1 - >+ coef.a2 * yn2; >+ } >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..2630fe7a26a25c329b0ae6e1d1b56464b9ecd591 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/w3c-import.log >@@ -0,0 +1,31 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-allpass.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-bandpass.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-basic.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-getFrequencyResponse.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highpass.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highshelf.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowpass.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowshelf.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-notch.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-peaking.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-tail.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquadfilternode-basic.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/ctor-biquadfilter.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/no-dezippering.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/ctor-channelmerger-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/ctor-channelmerger-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..caf254e8e08d7b7007cc8c13e0527bf4c60e1e63 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/ctor-channelmerger-expected.txt >@@ -0,0 +1,17 @@ >+CONSOLE MESSAGE: line 227: TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+PASS context = new OfflineAudioContext(...) did not throw an exception. >+PASS < [initialize] All assertions passed. (total 1 assertions) >+PASS > [invalid constructor] >+PASS new ChannelMergerNode() threw TypeError: "function is not a constructor (evaluating 'new window[name]()')". >+PASS new ChannelMergerNode(1) threw TypeError: "function is not a constructor (evaluating 'new window[name](1)')". >+PASS new ChannelMergerNode(context, 42) threw TypeError: "function is not a constructor (evaluating 'new window[name](context, 42)')". >+PASS < [invalid constructor] All assertions passed. (total 3 assertions) >+PASS > [default constructor] >+FAIL X node0 = new ChannelMergerNode(context) incorrectly threw TypeError: "function is not a constructor (evaluating 'new window[name](context, options.constructorOptions)')". assert_true: expected true got false >+FAIL X node0 instanceof ChannelMergerNode is not equal to true. Got false. assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/ctor-channelmerger.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/ctor-channelmerger.html >new file mode 100644 >index 0000000000000000000000000000000000000000..115bd9943490ab09efbff70239167911eb83d933 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/ctor-channelmerger.html >@@ -0,0 +1,109 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Constructor: ChannelMerger >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audionodeoptions.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let context; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('initialize', (task, should) => { >+ context = initializeContext(should); >+ task.done(); >+ }); >+ >+ audit.define('invalid constructor', (task, should) => { >+ testInvalidConstructor(should, 'ChannelMergerNode', context); >+ task.done(); >+ }); >+ >+ audit.define('default constructor', (task, should) => { >+ let prefix = 'node0'; >+ let node = >+ testDefaultConstructor(should, 'ChannelMergerNode', context, { >+ prefix: prefix, >+ numberOfInputs: 6, >+ numberOfOutputs: 1, >+ channelCount: 1, >+ channelCountMode: 'explicit', >+ channelInterpretation: 'speakers' >+ }); >+ >+ task.done(); >+ }); >+ >+ audit.define('test AudioNodeOptions', (task, should) => { >+ testAudioNodeOptions(should, context, 'ChannelMergerNode', { >+ channelCount: >+ {value: 1, isFixed: true, errorType: 'InvalidStateError'}, >+ channelCountMode: { >+ value: 'explicit', >+ isFixed: true, >+ errorType: 'InvalidStateError' >+ } >+ }); >+ task.done(); >+ }); >+ >+ audit.define('constructor options', (task, should) => { >+ let node; >+ let options = { >+ numberOfInputs: 3, >+ numberOfOutputs: 9, >+ channelInterpretation: 'discrete' >+ }; >+ >+ should( >+ () => { >+ node = new ChannelMergerNode(context, options); >+ }, >+ 'node1 = new ChannelMergerNode(context, ' + >+ JSON.stringify(options) + ')') >+ .notThrow(); >+ >+ should(node.numberOfInputs, 'node1.numberOfInputs') >+ .beEqualTo(options.numberOfInputs); >+ should(node.numberOfOutputs, 'node1.numberOfOutputs').beEqualTo(1); >+ should(node.channelInterpretation, 'node1.channelInterpretation') >+ .beEqualTo(options.channelInterpretation); >+ >+ options = {numberOfInputs: 99}; >+ should( >+ () => { >+ node = new ChannelMergerNode(context, options); >+ }, >+ 'new ChannelMergerNode(c, ' + JSON.stringify(options) + ')') >+ .throw('IndexSizeError'); >+ >+ options = {channelCount: 3}; >+ should( >+ () => { >+ node = new ChannelMergerNode(context, options); >+ }, >+ 'new ChannelMergerNode(c, ' + JSON.stringify(options) + ')') >+ .throw('InvalidStateError'); >+ >+ options = {channelCountMode: 'max'}; >+ should( >+ () => { >+ node = new ChannelMergerNode(context, options); >+ }, >+ 'new ChannelMergerNode(c, ' + JSON.stringify(options) + ')') >+ .throw('InvalidStateError'); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/w3c-import.log >index 02834d5f5f555d709cea8381a5628edd72cbab87..e3baf47c022a6c11bd7f1b14006daa7b4093d2c9 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/w3c-import.log >@@ -18,3 +18,4 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/audiochannelmerger-disconnect.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/audiochannelmerger-input-non-default.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/audiochannelmerger-input.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/ctor-channelmerger.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/ctor-channelsplitter-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/ctor-channelsplitter-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d0672b1bf55b3507f7b826ae651a84c3d0a95baa >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/ctor-channelsplitter-expected.txt >@@ -0,0 +1,17 @@ >+CONSOLE MESSAGE: line 227: TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+PASS context = new OfflineAudioContext(...) did not throw an exception. >+PASS < [initialize] All assertions passed. (total 1 assertions) >+PASS > [invalid constructor] >+PASS new ChannelSplitterNode() threw TypeError: "function is not a constructor (evaluating 'new window[name]()')". >+PASS new ChannelSplitterNode(1) threw TypeError: "function is not a constructor (evaluating 'new window[name](1)')". >+PASS new ChannelSplitterNode(context, 42) threw TypeError: "function is not a constructor (evaluating 'new window[name](context, 42)')". >+PASS < [invalid constructor] All assertions passed. (total 3 assertions) >+PASS > [default constructor] >+FAIL X node0 = new ChannelSplitterNode(context) incorrectly threw TypeError: "function is not a constructor (evaluating 'new window[name](context, options.constructorOptions)')". assert_true: expected true got false >+FAIL X node0 instanceof ChannelSplitterNode is not equal to true. Got false. assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/ctor-channelsplitter.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/ctor-channelsplitter.html >new file mode 100644 >index 0000000000000000000000000000000000000000..7fa9d6fa5466d2fbfeec8bbcf0718b80b52d2298 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/ctor-channelsplitter.html >@@ -0,0 +1,111 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Constructor: ChannelSplitter >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audionodeoptions.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let context; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('initialize', (task, should) => { >+ context = initializeContext(should); >+ task.done(); >+ }); >+ >+ audit.define('invalid constructor', (task, should) => { >+ testInvalidConstructor(should, 'ChannelSplitterNode', context); >+ task.done(); >+ }); >+ >+ audit.define('default constructor', (task, should) => { >+ testDefaultConstructor(should, 'ChannelSplitterNode', context, { >+ prefix: 'node0', >+ numberOfInputs: 1, >+ numberOfOutputs: 6, >+ channelCount: 6, >+ channelCountMode: 'explicit', >+ channelInterpretation: 'discrete' >+ }); >+ >+ task.done(); >+ }); >+ >+ audit.define('test AudioNodeOptions', (task, should) => { >+ testAudioNodeOptions(should, context, 'ChannelSplitterNode', { >+ channelCount: >+ {value: 6, isFixed: true, errorType: 'InvalidStateError'}, >+ channelCountMode: { >+ value: 'explicit', >+ isFixed: true, >+ }, >+ channelInterpretation: { >+ value: 'discrete', >+ isFixed: true, >+ errorType: 'InvalidStateError' >+ }, >+ }); >+ task.done(); >+ }); >+ >+ audit.define('constructor options', (task, should) => { >+ let node; >+ let options = { >+ numberOfInputs: 3, >+ numberOfOutputs: 9, >+ channelInterpretation: 'discrete' >+ }; >+ >+ should( >+ () => { >+ node = new ChannelSplitterNode(context, options); >+ }, >+ 'node1 = new ChannelSplitterNode(context, ' + >+ JSON.stringify(options) + ')') >+ .notThrow(); >+ >+ should(node.numberOfInputs, 'node1.numberOfInputs').beEqualTo(1); >+ should(node.numberOfOutputs, 'node1.numberOfOutputs') >+ .beEqualTo(options.numberOfOutputs); >+ should(node.channelInterpretation, 'node1.channelInterpretation') >+ .beEqualTo(options.channelInterpretation); >+ >+ options = {numberOfOutputs: 99}; >+ should( >+ () => { >+ node = new ChannelSplitterNode(context, options); >+ }, >+ 'new ChannelSplitterNode(c, ' + JSON.stringify(options) + ')') >+ .throw('IndexSizeError'); >+ >+ options = {channelCount: 3}; >+ should( >+ () => { >+ node = new ChannelSplitterNode(context, options); >+ }, >+ 'new ChannelSplitterNode(c, ' + JSON.stringify(options) + ')') >+ .throw('InvalidStateError'); >+ >+ options = {channelCountMode: 'max'}; >+ should( >+ () => { >+ node = new ChannelSplitterNode(context, options); >+ }, >+ 'new ChannelSplitterNode(c, ' + JSON.stringify(options) + ')') >+ .throw('InvalidStateError'); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/w3c-import.log >index 1eaf5b405db6af984f4eec38ef60357a8e037d87..adaa9541a57b7f0c4b5e05be8407f1e21846f08d 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/w3c-import.log >@@ -15,3 +15,4 @@ None > ------------------------------------------------------------------------ > List of files: > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/audiochannelsplitter.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/ctor-channelsplitter.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/ctor-constantsource-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/ctor-constantsource-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..9ffa6ef8a27f1668b8df0a65eac624b8eb28e1b2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/ctor-constantsource-expected.txt >@@ -0,0 +1,16 @@ >+CONSOLE MESSAGE: line 225: TypeError: Right hand side of instanceof is not an object >+ >+Harness Error (FAIL), message = TypeError: Right hand side of instanceof is not an object >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+PASS context = new OfflineAudioContext(...) did not throw an exception. >+PASS < [initialize] All assertions passed. (total 1 assertions) >+PASS > [invalid constructor] >+PASS new ConstantSourceNode() threw TypeError: "undefined is not a constructor (evaluating 'new window[name]()')". >+PASS new ConstantSourceNode(1) threw TypeError: "undefined is not a constructor (evaluating 'new window[name](1)')". >+PASS new ConstantSourceNode(context, 42) threw TypeError: "undefined is not a constructor (evaluating 'new window[name](context, 42)')". >+PASS < [invalid constructor] All assertions passed. (total 3 assertions) >+PASS > [default constructor] >+FAIL X node0 = new ConstantSourceNode(context) incorrectly threw TypeError: "undefined is not a constructor (evaluating 'new window[name](context, options.constructorOptions)')". assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/ctor-constantsource.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/ctor-constantsource.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ea4a65e146babcdad6d1c5429a1250963d120378 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/ctor-constantsource.html >@@ -0,0 +1,50 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Constructor: ConstantSource >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audionodeoptions.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let context; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('initialize', (task, should) => { >+ context = initializeContext(should); >+ task.done(); >+ }); >+ >+ audit.define('invalid constructor', (task, should) => { >+ testInvalidConstructor(should, 'ConstantSourceNode', context); >+ task.done(); >+ }); >+ >+ audit.define('default constructor', (task, should) => { >+ let prefix = 'node0'; >+ let node = >+ testDefaultConstructor(should, 'ConstantSourceNode', context, { >+ prefix: prefix, >+ numberOfInputs: 0, >+ numberOfOutputs: 1, >+ channelCount: 2, >+ channelCountMode: 'max', >+ channelInterpretation: 'speakers' >+ }); >+ >+ testDefaultAttributes( >+ should, node, prefix, [{name: 'offset', value: 1}]); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/w3c-import.log >index 3df039959ca8d23a9f41d8f3ea9d287092e8b05a..b1ced28b4b7e0340342290732b65bab21f07a059 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/w3c-import.log >@@ -17,4 +17,5 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-basic.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-onended.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-output.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/ctor-constantsource.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/test-constantsourcenode.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/ctor-convolver-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/ctor-convolver-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..f6d6a598d30083628503b4e32d566a55a592170c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/ctor-convolver-expected.txt >@@ -0,0 +1,17 @@ >+CONSOLE MESSAGE: line 227: TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+PASS context = new OfflineAudioContext(...) did not throw an exception. >+PASS < [initialize] All assertions passed. (total 1 assertions) >+PASS > [invalid constructor] >+PASS new ConvolverNode() threw TypeError: "function is not a constructor (evaluating 'new window[name]()')". >+PASS new ConvolverNode(1) threw TypeError: "function is not a constructor (evaluating 'new window[name](1)')". >+PASS new ConvolverNode(context, 42) threw TypeError: "function is not a constructor (evaluating 'new window[name](context, 42)')". >+PASS < [invalid constructor] All assertions passed. (total 3 assertions) >+PASS > [default constructor] >+FAIL X node0 = new ConvolverNode(context) incorrectly threw TypeError: "function is not a constructor (evaluating 'new window[name](context, options.constructorOptions)')". assert_true: expected true got false >+FAIL X node0 instanceof ConvolverNode is not equal to true. Got false. assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/ctor-convolver.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/ctor-convolver.html >new file mode 100644 >index 0000000000000000000000000000000000000000..cf818330060143078cacbecf77724244eee55cf8 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/ctor-convolver.html >@@ -0,0 +1,125 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Constructor: Convolver >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audionodeoptions.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let context; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('initialize', (task, should) => { >+ context = initializeContext(should); >+ task.done(); >+ }); >+ >+ audit.define('invalid constructor', (task, should) => { >+ testInvalidConstructor(should, 'ConvolverNode', context); >+ task.done(); >+ }); >+ >+ audit.define('default constructor', (task, should) => { >+ let prefix = 'node0'; >+ let node = testDefaultConstructor(should, 'ConvolverNode', context, { >+ prefix: prefix, >+ numberOfInputs: 1, >+ numberOfOutputs: 1, >+ channelCount: 2, >+ channelCountMode: 'clamped-max', >+ channelInterpretation: 'speakers' >+ }); >+ >+ testDefaultAttributes( >+ should, node, prefix, >+ [{name: 'normalize', value: true}, {name: 'buffer', value: null}]); >+ >+ task.done(); >+ }); >+ >+ audit.define('test AudioNodeOptions', (task, should) => { >+ testAudioNodeOptions(should, context, 'ConvolverNode', { >+ channelCount: >+ {value: 2, isFixed: true, errorType: 'NotSupportedError'}, >+ channelCountMode: { >+ value: 'clamped-max', >+ isFixed: true, >+ errorType: 'NotSupportedError' >+ }, >+ }); >+ task.done(); >+ }); >+ >+ audit.define('nullable buffer', (task, should) => { >+ let node; >+ let options = {buffer: null}; >+ >+ should( >+ () => { >+ node = new ConvolverNode(context, options); >+ }, >+ 'node1 = new ConvolverNode(c, ' + JSON.stringify(options)) >+ .notThrow(); >+ >+ should(node.buffer, 'node1.buffer').beEqualTo(null); >+ >+ task.done(); >+ }); >+ >+ audit.define('construct with options', (task, should) => { >+ let buf = context.createBuffer(1, 1, context.sampleRate); >+ let options = {buffer: buf, disableNormalization: false}; >+ >+ let message = >+ 'node = new ConvolverNode(c, ' + JSON.stringify(options) + ')'; >+ >+ let node; >+ should(() => { >+ node = new ConvolverNode(context, options); >+ }, message).notThrow(); >+ >+ should(node instanceof ConvolverNode, 'node1 instanceOf ConvolverNode') >+ .beEqualTo(true); >+ should(node.buffer === options.buffer, 'node1.buffer === <buf>') >+ .beEqualTo(true); >+ should(node.normalize, 'node1.normalize') >+ .beEqualTo(!options.disableNormalization); >+ >+ options.buffer = null; >+ options.disableNormalization = true; >+ >+ message = >+ 'node2 = new ConvolverNode(, ' + JSON.stringify(options) + ')'; >+ >+ should(() => { >+ node = new ConvolverNode(context, options); >+ }, message).notThrow(); >+ should(node.buffer, 'node2.buffer').beEqualTo(null); >+ should(node.normalize, 'node2.normalize') >+ .beEqualTo(!options.disableNormalization); >+ >+ options.disableNormalization = false; >+ message = 'node3 = new ConvolverNode(context, ' + >+ JSON.stringify(options) + ')'; >+ >+ should(() => { >+ node = new ConvolverNode(context, options); >+ }, message).notThrow(); >+ should(node.buffer, 'node3.buffer').beEqualTo(null); >+ should(node.normalize, 'node3.normalize') >+ .beEqualTo(!options.disableNormalization); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/w3c-import.log >index 75ae8011b3f09be948d22f958c0447503552d951..d614c73f588eb712de80820f69de0c25b60feeff 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/w3c-import.log >@@ -21,3 +21,4 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/convolver-response-2-chan.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/convolver-response-4-chan.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/convolver-setBuffer-null.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/ctor-convolver.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/ctor-delay-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/ctor-delay-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..832523b5ecbaa320fba9a6312df0e3ae27b93bb2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/ctor-delay-expected.txt >@@ -0,0 +1,17 @@ >+CONSOLE MESSAGE: line 227: TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+PASS context = new OfflineAudioContext(...) did not throw an exception. >+PASS < [initialize] All assertions passed. (total 1 assertions) >+PASS > [invalid constructor] >+PASS new DelayNode() threw TypeError: "function is not a constructor (evaluating 'new window[name]()')". >+PASS new DelayNode(1) threw TypeError: "function is not a constructor (evaluating 'new window[name](1)')". >+PASS new DelayNode(context, 42) threw TypeError: "function is not a constructor (evaluating 'new window[name](context, 42)')". >+PASS < [invalid constructor] All assertions passed. (total 3 assertions) >+PASS > [default constructor] >+FAIL X node0 = new DelayNode(context) incorrectly threw TypeError: "function is not a constructor (evaluating 'new window[name](context, options.constructorOptions)')". assert_true: expected true got false >+FAIL X node0 instanceof DelayNode is not equal to true. Got false. assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/ctor-delay.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/ctor-delay.html >new file mode 100644 >index 0000000000000000000000000000000000000000..e7ccefc655364d20bb240beacc81a4f7a10806dd >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/ctor-delay.html >@@ -0,0 +1,76 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Constructor: Delay >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audionodeoptions.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let context; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('initialize', (task, should) => { >+ context = initializeContext(should); >+ task.done(); >+ }); >+ >+ audit.define('invalid constructor', (task, should) => { >+ testInvalidConstructor(should, 'DelayNode', context); >+ task.done(); >+ }); >+ >+ audit.define('default constructor', (task, should) => { >+ let prefix = 'node0'; >+ let node = testDefaultConstructor(should, 'DelayNode', context, { >+ prefix: prefix, >+ numberOfInputs: 1, >+ numberOfOutputs: 1, >+ channelCount: 2, >+ channelCountMode: 'max', >+ channelInterpretation: 'speakers' >+ }); >+ >+ testDefaultAttributes( >+ should, node, prefix, [{name: 'delayTime', value: 0}]); >+ >+ task.done(); >+ }); >+ >+ audit.define('test AudioNodeOptions', (task, should) => { >+ testAudioNodeOptions(should, context, 'DelayNode'); >+ task.done(); >+ }); >+ >+ audit.define('constructor options', (task, should) => { >+ let node; >+ let options = { >+ delayTime: 0.5, >+ maxDelayTime: 1.5, >+ }; >+ >+ should( >+ () => { >+ node = new DelayNode(context, options); >+ }, >+ 'node1 = new DelayNode(c, ' + JSON.stringify(options) + ')') >+ .notThrow(); >+ >+ should(node.delayTime.value, 'node1.delayTime.value') >+ .beEqualTo(options.delayTime); >+ should(node.delayTime.maxValue, 'node1.delayTime.maxValue') >+ .beEqualTo(options.maxDelayTime); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/idl-test-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/idl-test-expected.txt >deleted file mode 100644 >index 7f317fe6987faf7a30628664a2527a8f18a51aa5..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/idl-test-expected.txt >+++ /dev/null >@@ -1,36 +0,0 @@ >-dictionary DelayOptions : AudioNodeOptions { >- double maxDelayTime = 1; >- double delayTime = 0; >-}; >- >-[Constructor(BaseAudioContext context, optional DelayOptions options)] >-interface DelayNode : AudioNode { >- >- readonly attribute AudioParam delayTime; >- >-}; >- >-FAIL webaudio Delay interfaces promise_test: Unhandled rejection with value: object "Unrecognised tokens, line 1 (tokens: '{"error": {') >-[ >- { >- "type": "other", >- "value": "{" >- }, >- { >- "type": "string", >- "value": "\"error\"" >- }, >- { >- "type": "other", >- "value": ":" >- }, >- { >- "type": "whitespace", >- "value": " " >- }, >- { >- "type": "other", >- "value": "{" >- } >-]" >- >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/idl-test.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/idl-test.html >deleted file mode 100644 >index eb42a4a003c893c550f8453fda0cae041b3f121c..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/idl-test.html >+++ /dev/null >@@ -1,159 +0,0 @@ >-<!DOCTYPE html> >-<html class="a"> >-<head> >-<title>DelayNode IDL Test</title> >-<script src="/resources/testharness.js"></script> >-<script src="/resources/testharnessreport.js"></script> >-<script src="/resources/idlharness.js"></script> >-<script src="/resources/WebIDLParser.js"></script> >-<script src="/webaudio/js/helpers.js"></script> >-<style type="text/css"> >- #event-target-idl, >- #base-audio-context-idl, >- #audio-node-idl, >- #audio-param-idl >- { visibility:hidden; height: 0px;} >- </style> >-</head> >-<body class="a"> >- >- <pre id="event-target-idl">interface EventTarget { >- void addEventListener(DOMString type, EventListener? callback, optional boolean capture = false); >- void removeEventListener(DOMString type, EventListener? callback, optional boolean capture = false); >- boolean dispatchEvent(Event event); >-}; >- >-/* >-callback interface EventListener { >- void handleEvent(Event event); >-}; >-*/ >-// Callback interfaces are not supported yet, but that's ok >-interface EventListener {}; >-</pre> >- >- <pre id="base-audio-context-idl">callback DecodeErrorCallback = void (DOMException error); >- >-callback DecodeSuccessCallback = void (AudioBuffer decodedData); >- >-interface BaseAudioContext : EventTarget { >- readonly attribute AudioDestinationNode destination; >- readonly attribute float sampleRate; >- readonly attribute double currentTime; >- readonly attribute AudioListener listener; >- readonly attribute AudioContextState state; >- readonly attribute double baseLatency; >- Promise<void> resume (); >- attribute EventHandler onstatechange; >- AudioBuffer createBuffer (unsigned long numberOfChannels, unsigned long length, float sampleRate); >- Promise<AudioBuffer> decodeAudioData (ArrayBuffer audioData, optional DecodeSuccessCallback successCallback, optional DecodeErrorCallback errorCallback); >- AudioBufferSourceNode createBufferSource (); >- ConstantSourceNode createConstantSource (); >- ScriptProcessorNode createScriptProcessor (optional unsigned long bufferSize = 0 >- , optional unsigned long numberOfInputChannels = 2 >- , optional unsigned long numberOfOutputChannels = 2 >- ); >- AnalyserNode createAnalyser (); >- GainNode createGain (); >- DelayNode createDelay (optional double maxDelayTime); >- BiquadFilterNode createBiquadFilter (); >- IIRFilterNode createIIRFilter (sequence<double> feedforward, sequence<double> feedback); >- WaveShaperNode createWaveShaper (); >- PannerNode createPanner (); >- StereoPannerNode createStereoPanner (); >- ConvolverNode createConvolver (); >- ChannelSplitterNode createChannelSplitter (optional unsigned long numberOfOutputs = 6 >- ); >- ChannelMergerNode createChannelMerger (optional unsigned long numberOfInputs = 6 >- ); >- DynamicsCompressorNode createDynamicsCompressor (); >- OscillatorNode createOscillator (); >- PeriodicWave createPeriodicWave (Float32Array real, Float32Array imag, optional PeriodicWaveConstraints constraints); >-};</pre> >- >- <pre id="audio-node-idl">enum ChannelCountMode { >- "max", >- "clamped-max", >- "explicit" >-}; >- >-enum ChannelInterpretation { >- "speakers", >- "discrete" >-}; >- >-interface AudioNode : EventTarget { >- >- void connect(AudioNode destination, optional unsigned long output = 0, optional unsigned long input = 0); >- void connect(AudioParam destination, optional unsigned long output = 0); >- void disconnect(optional unsigned long output = 0); >- >- readonly attribute BaseAudioContext context; >- readonly attribute unsigned long numberOfInputs; >- readonly attribute unsigned long numberOfOutputs; >- >- // Channel up-mixing and down-mixing rules for all inputs. >- attribute unsigned long channelCount; >- attribute ChannelCountMode channelCountMode; >- attribute ChannelInterpretation channelInterpretation; >- >-};</pre> >- >- <pre id="audio-param-idl">interface AudioParam { >- >- attribute float value; >- readonly attribute float defaultValue; >- readonly attribute float minValue; >- readonly attribute float maxValue; >- >- // Parameter automation. >- void setValueAtTime(float value, double startTime); >- void linearRampToValueAtTime(float value, double endTime); >- void exponentialRampToValueAtTime(float value, double endTime); >- >- // Exponentially approach the target value with a rate having the given time constant. >- void setTargetAtTime(float target, double startTime, double timeConstant); >- >- // Sets an array of arbitrary parameter values starting at time for the given duration. >- // The number of values will be scaled to fit into the desired duration. >- void setValueCurveAtTime(Float32Array values, double startTime, double duration); >- >- // Cancels all scheduled parameter changes with times greater than or equal to startTime. >- void cancelScheduledValues(double startTime); >- >-};</pre> >- >-<pre id="delay-node-idl">dictionary DelayOptions : AudioNodeOptions { >- double maxDelayTime = 1; >- double delayTime = 0; >-}; >- >-[Constructor(BaseAudioContext context, optional DelayOptions options)] >-interface DelayNode : AudioNode { >- >- readonly attribute AudioParam delayTime; >- >-};</pre> >- >- <div id="log"></div> >- >- <script> >-promise_test(async function() { >- const webAudioApi = await fetch('/interfaces/web-audio-api.idl').then(r => r.text()); >- >- var idl_array = new IdlArray(); >- idl_array.add_untested_idls(webAudioApi, { only: ['AudioNodeOptions']}); >- idl_array.add_untested_idls(document.getElementById("event-target-idl").textContent); >- idl_array.add_untested_idls(document.getElementById("base-audio-context-idl").textContent); >- idl_array.add_untested_idls(document.getElementById("audio-node-idl").textContent); >- idl_array.add_untested_idls(document.getElementById("audio-param-idl").textContent); >- idl_array.add_idls(document.getElementById("delay-node-idl").textContent); >- >- delay_node = (new AudioContext).createDelay(); >- >- idl_array.add_objects({DelayNode: ["delay_node"]}); >- idl_array.test(); >-}, 'webaudio Delay interfaces'); >- </script> >-</body> >-</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/w3c-import.log >index dac66d7b8a072dfb60a5de9bd0e9f29ba3f1d186..93fa03f695b0edb4c25349f111224ae72647a002 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/w3c-import.log >@@ -14,11 +14,11 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/ctor-delay.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/delaynode-max-default-delay.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/delaynode-max-nondefault-delay.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/delaynode-maxdelay.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/delaynode-maxdelaylimit.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/delaynode-scheduling.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/delaynode.html >-/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/idl-test.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/no-dezippering.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/ctor-dynamicscompressor-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/ctor-dynamicscompressor-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..de441223564d5cd6d2be5235733653c53257a10e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/ctor-dynamicscompressor-expected.txt >@@ -0,0 +1,17 @@ >+CONSOLE MESSAGE: line 227: TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+PASS context = new OfflineAudioContext(...) did not throw an exception. >+PASS < [initialize] All assertions passed. (total 1 assertions) >+PASS > [invalid constructor] >+PASS new DynamicsCompressorNode() threw TypeError: "function is not a constructor (evaluating 'new window[name]()')". >+PASS new DynamicsCompressorNode(1) threw TypeError: "function is not a constructor (evaluating 'new window[name](1)')". >+PASS new DynamicsCompressorNode(context, 42) threw TypeError: "function is not a constructor (evaluating 'new window[name](context, 42)')". >+PASS < [invalid constructor] All assertions passed. (total 3 assertions) >+PASS > [default constructor] >+FAIL X node0 = new DynamicsCompressorNode(context) incorrectly threw TypeError: "function is not a constructor (evaluating 'new window[name](context, options.constructorOptions)')". assert_true: expected true got false >+FAIL X node0 instanceof DynamicsCompressorNode is not equal to true. Got false. assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/ctor-dynamicscompressor.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/ctor-dynamicscompressor.html >new file mode 100644 >index 0000000000000000000000000000000000000000..799c1872f075e7f8541809c695509018bec4b0b7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/ctor-dynamicscompressor.html >@@ -0,0 +1,196 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Constructor: DynamicsCompressor >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audionodeoptions.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let context; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('initialize', (task, should) => { >+ context = initializeContext(should); >+ task.done(); >+ }); >+ >+ audit.define('invalid constructor', (task, should) => { >+ testInvalidConstructor(should, 'DynamicsCompressorNode', context); >+ task.done(); >+ }); >+ >+ audit.define('default constructor', (task, should) => { >+ let prefix = 'node0'; >+ let node = >+ testDefaultConstructor(should, 'DynamicsCompressorNode', context, { >+ prefix: prefix, >+ numberOfInputs: 1, >+ numberOfOutputs: 1, >+ channelCount: 2, >+ channelCountMode: 'clamped-max', >+ channelInterpretation: 'speakers' >+ }); >+ >+ testDefaultAttributes(should, node, prefix, [ >+ {name: 'threshold', value: -24}, {name: 'knee', value: 30}, >+ {name: 'ratio', value: 12}, {name: 'reduction', value: 0}, >+ {name: 'attack', value: Math.fround(0.003)}, >+ {name: 'release', value: 0.25} >+ ]); >+ >+ task.done(); >+ }); >+ >+ audit.define('test AudioNodeOptions', (task, should) => { >+ // Can't use testAudioNodeOptions because the constraints for this node >+ // are not supported there. >+ >+ // Array of test options to be run. Each entry is a dictionary where >+ // |testAttribute| is the name of the attribute to be tested, >+ // |testValue| is the value to be used, and |expectedErrorType| is the >+ // error type if the test is expected to throw an error. >+ // |expectedErrorType| should be set only if the test does throw. >+ let testOptions = [ >+ // Test channel count >+ { >+ testAttribute: 'channelCount', >+ testValue: 1, >+ }, >+ { >+ testAttribute: 'channelCount', >+ testValue: 2, >+ }, >+ { >+ testAttribute: 'channelCount', >+ testValue: 0, >+ expectedErrorType: 'NotSupportedError' >+ }, >+ { >+ testAttribute: 'channelCount', >+ testValue: 3, >+ expectedErrorType: 'NotSupportedError' >+ }, >+ { >+ testAttribute: 'channelCount', >+ testValue: 99, >+ expectedErrorType: 'NotSupportedError' >+ }, >+ // Test channel count mode >+ { >+ testAttribute: 'channelCountMode', >+ testValue: 'clamped-max', >+ }, >+ { >+ testAttribute: 'channelCountMode', >+ testValue: 'explicit', >+ }, >+ { >+ testAttribute: 'channelCountMode', >+ testValue: 'max', >+ expectedErrorType: 'NotSupportedError' >+ }, >+ { >+ testAttribute: 'channelCountMode', >+ testValue: 'foobar', >+ expectedErrorType: 'TypeError' >+ }, >+ // Test channel interpretation >+ { >+ testAttribute: 'channelInterpretation', >+ testValue: 'speakers', >+ }, >+ { >+ testAttribute: 'channelInterpretation', >+ testValue: 'discrete', >+ }, >+ { >+ testAttribute: 'channelInterpretation', >+ testValue: 'foobar', >+ expectedErrorType: 'TypeError' >+ } >+ ]; >+ >+ testOptions.forEach((option) => { >+ let nodeOptions = {}; >+ nodeOptions[option.testAttribute] = option.testValue; >+ >+ testNode(should, context, { >+ nodeOptions: nodeOptions, >+ testAttribute: option.testAttribute, >+ expectedValue: option.testValue, >+ expectedErrorType: option.expectedErrorType >+ }); >+ }); >+ >+ task.done(); >+ }); >+ >+ audit.define('constructor with options', (task, should) => { >+ let node; >+ let options = >+ {threshold: -33, knee: 15, ratio: 7, attack: 0.625, release: 0.125}; >+ >+ should( >+ () => { >+ node = new DynamicsCompressorNode(context, options); >+ }, >+ 'node1 = new DynamicsCompressorNode(c, ' + JSON.stringify(options) + >+ ')') >+ .notThrow(); >+ should( >+ node instanceof DynamicsCompressorNode, >+ 'node1 instanceof DynamicsCompressorNode') >+ .beEqualTo(true); >+ >+ should(node.threshold.value, 'node1.threshold.value') >+ .beEqualTo(options.threshold); >+ should(node.knee.value, 'node1.knee.value').beEqualTo(options.knee); >+ should(node.ratio.value, 'node1.ratio.value').beEqualTo(options.ratio); >+ should(node.attack.value, 'node1.attack.value') >+ .beEqualTo(options.attack); >+ should(node.release.value, 'node1.release.value') >+ .beEqualTo(options.release); >+ >+ should(node.channelCount, 'node1.channelCount').beEqualTo(2); >+ should(node.channelCountMode, 'node1.channelCountMode') >+ .beEqualTo('clamped-max'); >+ should(node.channelInterpretation, 'node1.channelInterpretation') >+ .beEqualTo('speakers'); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ >+ // Test possible options for DynamicsCompressor constructor. >+ function testNode(should, context, options) { >+ // Node to be tested >+ let node; >+ >+ let createNodeFunction = () => { >+ return () => node = >+ new DynamicsCompressorNode(context, options.nodeOptions); >+ }; >+ >+ let message = 'new DynamicsCompressorNode(c, ' + >+ JSON.stringify(options.nodeOptions) + ')'; >+ >+ if (options.expectedErrorType) { >+ should(createNodeFunction(), message) >+ .throw(options.expectedErrorType); >+ } else { >+ should(createNodeFunction(), message).notThrow(); >+ should(node[options.testAttribute], 'node.' + options.testAttribute) >+ .beEqualTo(options.expectedValue); >+ } >+ } >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/w3c-import.log >index 2aedf907a84669750be25c94a2bea08a90cb7551..c32eb784bf68f76c1983032b37766049de9ef5b7 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/w3c-import.log >@@ -14,4 +14,5 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/ctor-dynamicscompressor.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/dynamicscompressor-basic.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/ctor-gain-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/ctor-gain-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..85633c260a638f0a862aa37c96c3c10a2b457ee8 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/ctor-gain-expected.txt >@@ -0,0 +1,17 @@ >+CONSOLE MESSAGE: line 227: TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+PASS context = new OfflineAudioContext(...) did not throw an exception. >+PASS < [initialize] All assertions passed. (total 1 assertions) >+PASS > [invalid constructor] >+PASS new GainNode() threw TypeError: "function is not a constructor (evaluating 'new window[name]()')". >+PASS new GainNode(1) threw TypeError: "function is not a constructor (evaluating 'new window[name](1)')". >+PASS new GainNode(context, 42) threw TypeError: "function is not a constructor (evaluating 'new window[name](context, 42)')". >+PASS < [invalid constructor] All assertions passed. (total 3 assertions) >+PASS > [default constructor] >+FAIL X node0 = new GainNode(context) incorrectly threw TypeError: "function is not a constructor (evaluating 'new window[name](context, options.constructorOptions)')". assert_true: expected true got false >+FAIL X node0 instanceof GainNode is not equal to true. Got false. assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/ctor-gain.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/ctor-gain.html >new file mode 100644 >index 0000000000000000000000000000000000000000..dec273e9698702c5b1ee476a5c2e343bbc6e5bb6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/ctor-gain.html >@@ -0,0 +1,79 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Constructor: Gain >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audionodeoptions.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let context; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('initialize', (task, should) => { >+ context = initializeContext(should); >+ task.done(); >+ }); >+ >+ audit.define('invalid constructor', (task, should) => { >+ testInvalidConstructor(should, 'GainNode', context); >+ task.done(); >+ }); >+ >+ audit.define('default constructor', (task, should) => { >+ let prefix = 'node0'; >+ let node = testDefaultConstructor(should, 'GainNode', context, { >+ prefix: prefix, >+ numberOfInputs: 1, >+ numberOfOutputs: 1, >+ channelCount: 2, >+ channelCountMode: 'max', >+ channelInterpretation: 'speakers' >+ }); >+ >+ testDefaultAttributes(should, node, prefix, [{name: 'gain', value: 1}]); >+ >+ task.done(); >+ }); >+ >+ audit.define('test AudioNodeOptions', (task, should) => { >+ testAudioNodeOptions(should, context, 'GainNode'); >+ task.done(); >+ }); >+ >+ audit.define('constructor with options', (task, should) => { >+ let node; >+ let options = { >+ gain: -2, >+ }; >+ >+ should( >+ () => { >+ node = new GainNode(context, options); >+ }, >+ 'node1 = new GainNode(c, ' + JSON.stringify(options) + ')') >+ .notThrow(); >+ should(node instanceof GainNode, 'node1 instanceof GainNode') >+ .beEqualTo(true); >+ >+ should(node.gain.value, 'node1.gain.value').beEqualTo(options.gain); >+ >+ should(node.channelCount, 'node1.channelCount').beEqualTo(2); >+ should(node.channelCountMode, 'node1.channelCountMode') >+ .beEqualTo('max'); >+ should(node.channelInterpretation, 'node1.channelInterpretation') >+ .beEqualTo('speakers'); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/idl-test-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/idl-test-expected.txt >deleted file mode 100644 >index 8996a3b50cae4169fc606d197d4d92d344dbe110..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/idl-test-expected.txt >+++ /dev/null >@@ -1,35 +0,0 @@ >-dictionary GainOptions : AudioNodeOptions { >- float gain = 1.0; >-}; >- >-[Constructor(BaseAudioContext context, optional GainOptions options)] >-interface GainNode : AudioNode { >- >- readonly attribute AudioParam gain; >- >-}; >- >-FAIL webaudio Gain interfaces promise_test: Unhandled rejection with value: object "Unrecognised tokens, line 1 (tokens: '{"error": {') >-[ >- { >- "type": "other", >- "value": "{" >- }, >- { >- "type": "string", >- "value": "\"error\"" >- }, >- { >- "type": "other", >- "value": ":" >- }, >- { >- "type": "whitespace", >- "value": " " >- }, >- { >- "type": "other", >- "value": "{" >- } >-]" >- >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/idl-test.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/idl-test.html >deleted file mode 100644 >index 69606c977eda42e851792ac3a37d1a42481cf821..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/idl-test.html >+++ /dev/null >@@ -1,157 +0,0 @@ >-<!DOCTYPE html> >-<html class="a"> >-<head> >-<title>GainNode IDL Test</title> >-<script src="/resources/testharness.js"></script> >-<script src="/resources/testharnessreport.js"></script> >-<script src="/resources/idlharness.js"></script> >-<script src="/resources/WebIDLParser.js"></script> >-<script src="/webaudio/js/helpers.js"></script> >-<style type="text/css"> >- #event-target-idl, >- #base-audio-context-idl, >- #audio-node-idl, >- #audio-param-idl >- { visibility:hidden; height: 0px;} >- </style> >-</head> >-<body class="a"> >- >- <pre id="event-target-idl">interface EventTarget { >- void addEventListener(DOMString type, EventListener? callback, optional boolean capture = false); >- void removeEventListener(DOMString type, EventListener? callback, optional boolean capture = false); >- boolean dispatchEvent(Event event); >-}; >- >-/* >-callback interface EventListener { >- void handleEvent(Event event); >-}; >-*/ >-// Callback interfaces are not supported yet, but that's ok >-interface EventListener {}; >-</pre> >- >- <pre id="base-audio-context-idl">callback DecodeErrorCallback = void (DOMException error); >-callback DecodeSuccessCallback = void (AudioBuffer decodedData); >- >-interface BaseAudioContext : EventTarget { >- readonly attribute AudioDestinationNode destination; >- readonly attribute float sampleRate; >- readonly attribute double currentTime; >- readonly attribute AudioListener listener; >- readonly attribute AudioContextState state; >- readonly attribute double baseLatency; >- Promise<void> resume (); >- attribute EventHandler onstatechange; >- AudioBuffer createBuffer (unsigned long numberOfChannels, unsigned long length, float sampleRate); >- Promise<AudioBuffer> decodeAudioData (ArrayBuffer audioData, optional DecodeSuccessCallback successCallback, optional DecodeErrorCallback errorCallback); >- AudioBufferSourceNode createBufferSource (); >- ConstantSourceNode createConstantSource (); >- ScriptProcessorNode createScriptProcessor (optional unsigned long bufferSize = 0 >- , optional unsigned long numberOfInputChannels = 2 >- , optional unsigned long numberOfOutputChannels = 2 >- ); >- AnalyserNode createAnalyser (); >- GainNode createGain (); >- DelayNode createDelay (optional double maxDelayTime); >- BiquadFilterNode createBiquadFilter (); >- IIRFilterNode createIIRFilter (sequence<double> feedforward, sequence<double> feedback); >- WaveShaperNode createWaveShaper (); >- PannerNode createPanner (); >- StereoPannerNode createStereoPanner (); >- ConvolverNode createConvolver (); >- ChannelSplitterNode createChannelSplitter (optional unsigned long numberOfOutputs = 6 >- ); >- ChannelMergerNode createChannelMerger (optional unsigned long numberOfInputs = 6 >- ); >- DynamicsCompressorNode createDynamicsCompressor (); >- OscillatorNode createOscillator (); >- PeriodicWave createPeriodicWave (Float32Array real, Float32Array imag, optional PeriodicWaveConstraints constraints); >-};</pre> >- >- <pre id="audio-node-idl">enum ChannelCountMode { >- "max", >- "clamped-max", >- "explicit" >-}; >- >-enum ChannelInterpretation { >- "speakers", >- "discrete" >-}; >- >-interface AudioNode : EventTarget { >- >- void connect(AudioNode destination, optional unsigned long output = 0, optional unsigned long input = 0); >- void connect(AudioParam destination, optional unsigned long output = 0); >- void disconnect(optional unsigned long output = 0); >- >- readonly attribute BaseAudioContext context; >- readonly attribute unsigned long numberOfInputs; >- readonly attribute unsigned long numberOfOutputs; >- >- // Channel up-mixing and down-mixing rules for all inputs. >- attribute unsigned long channelCount; >- attribute ChannelCountMode channelCountMode; >- attribute ChannelInterpretation channelInterpretation; >- >-};</pre> >- >- <pre id="audio-param-idl">interface AudioParam { >- >- attribute float value; >- readonly attribute float defaultValue; >- readonly attribute float minValue; >- readonly attribute float maxValue; >- >- // Parameter automation. >- void setValueAtTime(float value, double startTime); >- void linearRampToValueAtTime(float value, double endTime); >- void exponentialRampToValueAtTime(float value, double endTime); >- >- // Exponentially approach the target value with a rate having the given time constant. >- void setTargetAtTime(float target, double startTime, double timeConstant); >- >- // Sets an array of arbitrary parameter values starting at time for the given duration. >- // The number of values will be scaled to fit into the desired duration. >- void setValueCurveAtTime(Float32Array values, double startTime, double duration); >- >- // Cancels all scheduled parameter changes with times greater than or equal to startTime. >- void cancelScheduledValues(double startTime); >- >-};</pre> >- >-<pre id="gain-node-idl">dictionary GainOptions : AudioNodeOptions { >- float gain = 1.0; >-}; >- >-[Constructor(BaseAudioContext context, optional GainOptions options)] >-interface GainNode : AudioNode { >- >- readonly attribute AudioParam gain; >- >-};</pre> >- >- <div id="log"></div> >- >- <script> >-promise_test(async function () { >- const webAudioApi = await fetch('/interfaces/web-audio-api.idl').then(r => r.text()); >- >- var idl_array = new IdlArray(); >- idl_array.add_untested_idls(webAudioApi, { only: ['AudioNodeOptions'] }); >- idl_array.add_untested_idls(document.getElementById("event-target-idl").textContent); >- idl_array.add_untested_idls(document.getElementById("base-audio-context-idl").textContent); >- idl_array.add_untested_idls(document.getElementById("audio-node-idl").textContent); >- idl_array.add_untested_idls(document.getElementById("audio-param-idl").textContent); >- idl_array.add_idls(document.getElementById("gain-node-idl").textContent); >- >- gain_node = (new AudioContext).createGain(); >- >- idl_array.add_objects({GainNode: ["gain_node"]}); >- idl_array.test(); >-}, 'webaudio Gain interfaces'); >- </script> >-</body> >-</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/w3c-import.log >index 66aa4d6a5b431bb25e83789cab30735666ee3c39..af79e8f70c33b582fe66a1e2b5c1dc4f00f70b89 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/w3c-import.log >@@ -14,9 +14,9 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/ctor-gain.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/gain-basic.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/gain-expected.wav > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/gain.html >-/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/idl-test.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/no-dezippering.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-gainnode-interface/test-gainnode.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/ctor-iirfilter-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/ctor-iirfilter-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..f70fdfd66543bfbe151e62cb42217fdb68393b95 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/ctor-iirfilter-expected.txt >@@ -0,0 +1,16 @@ >+CONSOLE MESSAGE: line 225: TypeError: Right hand side of instanceof is not an object >+ >+Harness Error (FAIL), message = TypeError: Right hand side of instanceof is not an object >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+PASS context = new OfflineAudioContext(...) did not throw an exception. >+PASS < [initialize] All assertions passed. (total 1 assertions) >+PASS > [invalid constructor] >+PASS new IIRFilterNode() threw TypeError: "undefined is not a constructor (evaluating 'new window[name]()')". >+PASS new IIRFilterNode(1) threw TypeError: "undefined is not a constructor (evaluating 'new window[name](1)')". >+PASS new IIRFilterNode(context, 42) threw TypeError: "undefined is not a constructor (evaluating 'new window[name](context, 42)')". >+PASS < [invalid constructor] All assertions passed. (total 3 assertions) >+PASS > [default constructor] >+FAIL X node0 = new IIRFilterNode(context, {"feedforward":[1],"feedback":[1,-0.9]}) incorrectly threw TypeError: "undefined is not a constructor (evaluating 'new window[name](context, options.constructorOptions)')". assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/ctor-iirfilter.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/ctor-iirfilter.html >new file mode 100644 >index 0000000000000000000000000000000000000000..bb89512ca62309cbefffcb070afc6e9a98fc5d2e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/ctor-iirfilter.html >@@ -0,0 +1,126 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Constructor: IIRFilter >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audionodeoptions.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let context; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('initialize', (task, should) => { >+ context = initializeContext(should); >+ task.done(); >+ }); >+ >+ audit.define('invalid constructor', (task, should) => { >+ testInvalidConstructor(should, 'IIRFilterNode', context); >+ task.done(); >+ }); >+ >+ audit.define('default constructor', (task, should) => { >+ let prefix = 'node0'; >+ let node = testDefaultConstructor(should, 'IIRFilterNode', context, { >+ prefix: prefix, >+ numberOfInputs: 1, >+ numberOfOutputs: 1, >+ channelCount: 2, >+ channelCountMode: 'max', >+ channelInterpretation: 'speakers', >+ constructorOptions: {feedforward: [1], feedback: [1, -.9]} >+ }); >+ >+ task.done(); >+ }); >+ >+ audit.define('test AudioNodeOptions', (task, should) => { >+ testAudioNodeOptions( >+ should, context, 'IIRFilterNode', >+ {additionalOptions: {feedforward: [1, 1], feedback: [1, .5]}}); >+ task.done(); >+ }); >+ >+ audit.define('constructor options', (task, should) => { >+ let node; >+ >+ let options = {feedback: [1, .5]}; >+ should( >+ () => { >+ node = new IIRFilterNode(context, options); >+ }, >+ 'node = new IIRFilterNode(, ' + JSON.stringify(options) + ')') >+ .throw('TypeError'); >+ >+ options = {feedforward: [1, 0.5]}; >+ should( >+ () => { >+ node = new IIRFilterNode(context, options); >+ }, >+ 'node = new IIRFilterNode(c, ' + JSON.stringify(options) + ')') >+ .throw('TypeError'); >+ >+ task.done(); >+ }); >+ >+ // Test functionality of constructor. This is needed because we have no >+ // way of determining if the filter coefficients were were actually set >+ // appropriately. >+ >+ // TODO(rtoy): This functionality test should be moved out to a separate >+ // file. >+ audit.define('functionality', (task, should) => { >+ let options = {feedback: [1, .5], feedforward: [1, 1]}; >+ >+ // Create two-channel offline context; sample rate and length are fairly >+ // arbitrary. Channel 0 contains the test output and channel 1 contains >+ // the expected output. >+ let sampleRate = 48000; >+ let renderLength = 0.125; >+ let testContext = >+ new OfflineAudioContext(2, renderLength * sampleRate, sampleRate); >+ >+ // The test node uses the constructor. The reference node creates the >+ // same filter but uses the old factory method. >+ let testNode = new IIRFilterNode(testContext, options); >+ let refNode = testContext.createIIRFilter( >+ Float32Array.from(options.feedforward), >+ Float32Array.from(options.feedback)); >+ >+ let source = testContext.createOscillator(); >+ source.connect(testNode); >+ source.connect(refNode); >+ >+ let merger = testContext.createChannelMerger( >+ testContext.destination.channelCount); >+ >+ testNode.connect(merger, 0, 0); >+ refNode.connect(merger, 0, 1); >+ >+ merger.connect(testContext.destination); >+ >+ source.start(); >+ testContext.startRendering() >+ .then(function(resultBuffer) { >+ let actual = resultBuffer.getChannelData(0); >+ let expected = resultBuffer.getChannelData(1); >+ >+ // The output from the two channels should be exactly equal >+ // because exactly the same IIR filter should have been created. >+ should(actual, 'Output of filter using new IIRFilter(...)') >+ .beEqualToArray(expected); >+ }) >+ .then(() => task.done()); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/w3c-import.log >index 83d9303f81f7ffcbd5e3a265223187a097cde09c..3bf707d96b84320618412671625ef0c10e5d5835 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/w3c-import.log >@@ -14,6 +14,7 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/ctor-iirfilter.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/iirfilter-basic.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/iirfilter-getFrequencyResponse.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/iirfilter.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest-expected.txt >index 05820f4721c43c8a69de29e2573ea3192eb28c8c..dffdc2e8c0fdf734209ca6eec7125c926133cf87 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest-expected.txt >@@ -1,5 +1,5 @@ > > PASS Element Source tests completed > PASS Channel 0 processed some data >-FAIL All data processed correctly assert_array_approx_equals: comparing expected and rendered buffers (channel 0) lengths differ, expected 44098 got 40003 >+FAIL All data processed correctly assert_array_approx_equals: comparing expected and rendered buffers (channel 0) lengths differ, expected 48000 got 43574 > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/ctor-offlineaudiocontext-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/ctor-offlineaudiocontext-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..201363a86c56ec804dafe666fbc778f619a3fb74 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/ctor-offlineaudiocontext-expected.txt >@@ -0,0 +1,10 @@ >+CONSOLE MESSAGE: line 39: TypeError: undefined is not an object (evaluating 'context.length') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'context.length') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [basic] Old-style constructor >+PASS new OfflineAudioContext(3) threw TypeError: "Not enough arguments". >+PASS new OfflineAudioContext(3, 42) threw TypeError: "Not enough arguments". >+FAIL X context = new OfflineAudioContext(3, 42, 12345) incorrectly threw SyntaxError: "The string did not match the expected pattern.". assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/ctor-offlineaudiocontext.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/ctor-offlineaudiocontext.html >new file mode 100644 >index 0000000000000000000000000000000000000000..79aafe7f1f060103a1dcba430e6572b47796f225 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/ctor-offlineaudiocontext.html >@@ -0,0 +1,203 @@ >+<!doctype html> >+<html> >+ <head> >+ <title>Test Constructor: OfflineAudioContext</title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audionodeoptions.js"></script> >+ </head> >+ >+ <body> >+ <script> >+ let audit = Audit.createTaskRunner(); >+ >+ // Just a simple test of the 3-arg constructor; This should be >+ // well-covered by other layout tests that use the 3-arg constructor. >+ audit.define( >+ {label: 'basic', description: 'Old-style constructor'}, >+ (task, should) => { >+ let context; >+ >+ // First and only arg should be a dictionary. >+ should(() => { >+ new OfflineAudioContext(3); >+ }, 'new OfflineAudioContext(3)').throw('TypeError'); >+ >+ // Constructor needs 1 or 3 args, so 2 should throw. >+ should(() => { >+ new OfflineAudioContext(3, 42); >+ }, 'new OfflineAudioContext(3, 42)').throw('TypeError'); >+ >+ // Valid constructor >+ should(() => { >+ context = new OfflineAudioContext(3, 42, 12345); >+ }, 'context = new OfflineAudioContext(3, 42, 12345)').notThrow(); >+ >+ // Verify that the context was constructed correctly. >+ should(context.length, 'context.length').beEqualTo(42); >+ should(context.sampleRate, 'context.sampleRate').beEqualTo(12345); >+ should( >+ context.destination.channelCount, >+ 'context.destination.channelCount') >+ .beEqualTo(3); >+ should( >+ context.destination.channelCountMode, >+ 'context.destination.channelCountMode') >+ .beEqualTo('explicit'); >+ should( >+ context.destination.channelInterpretation, >+ 'context.destination.channelInterpretation') >+ .beEqualTo('speakers'); >+ task.done(); >+ }); >+ >+ // Test constructor throws an error if the required members of the >+ // dictionary are not given. >+ audit.define( >+ {label: 'options-1', description: 'Required options'}, >+ (task, should) => { >+ let context2; >+ >+ // No args should throw >+ should(() => { >+ new OfflineAudioContext(); >+ }, 'new OfflineAudioContext()').throw('TypeError'); >+ >+ // Empty OfflineAudioContextOptions should throw >+ should(() => { >+ new OfflineAudioContext({}); >+ }, 'new OfflineAudioContext({})').throw('TypeError'); >+ >+ let options = {length: 42}; >+ // sampleRate is required. >+ should( >+ () => { >+ new OfflineAudioContext(options); >+ }, >+ 'new OfflineAudioContext(' + JSON.stringify(options) + ')') >+ .throw('TypeError'); >+ >+ options = {sampleRate: 12345}; >+ // length is required. >+ should( >+ () => { >+ new OfflineAudioContext(options); >+ }, >+ 'new OfflineAudioContext(' + JSON.stringify(options) + ')') >+ .throw('TypeError'); >+ >+ // Valid constructor. Verify that the resulting context has the >+ // correct values. >+ options = {length: 42, sampleRate: 12345}; >+ should( >+ () => { >+ context2 = new OfflineAudioContext(options); >+ }, >+ 'c2 = new OfflineAudioContext(' + JSON.stringify(options) + ')') >+ .notThrow(); >+ should( >+ context2.destination.channelCount, >+ 'c2.destination.channelCount') >+ .beEqualTo(1); >+ should(context2.length, 'c2.length').beEqualTo(options.length); >+ should(context2.sampleRate, 'c2.sampleRate') >+ .beEqualTo(options.sampleRate); >+ should( >+ context2.destination.channelCountMode, >+ 'c2.destination.channelCountMode') >+ .beEqualTo('explicit'); >+ should( >+ context2.destination.channelInterpretation, >+ 'c2.destination.channelInterpretation') >+ .beEqualTo('speakers'); >+ >+ task.done(); >+ }); >+ >+ // Constructor should throw errors for invalid values specified by >+ // OfflineAudioContextOptions. >+ audit.define( >+ {label: 'options-2', description: 'Invalid options'}, >+ (task, should) => { >+ let options = {length: 42, sampleRate: 8000, numberOfChannels: 33}; >+ >+ // channelCount too large. >+ should( >+ () => { >+ new OfflineAudioContext(options); >+ }, >+ 'new OfflineAudioContext(' + JSON.stringify(options) + ')') >+ .throw('NotSupportedError'); >+ >+ // length cannot be 0 >+ options = {length: 0, sampleRate: 8000}; >+ should( >+ () => { >+ new OfflineAudioContext(options); >+ }, >+ 'new OfflineAudioContext(' + JSON.stringify(options) + ')') >+ .throw('NotSupportedError'); >+ >+ // sampleRate outside valid range >+ options = {length: 1, sampleRate: 1}; >+ should( >+ () => { >+ new OfflineAudioContext(options); >+ }, >+ 'new OfflineAudioContext(' + JSON.stringify(options) + ')') >+ .throw('NotSupportedError'); >+ >+ task.done(); >+ }); >+ >+ audit.define( >+ {label: 'options-3', description: 'Valid options'}, >+ (task, should) => { >+ let context; >+ let options = { >+ length: 1, >+ sampleRate: 8000, >+ }; >+ >+ // Verify context with valid constructor has the correct values. >+ should( >+ () => { >+ context = new OfflineAudioContext(options); >+ }, >+ 'c = new OfflineAudioContext' + JSON.stringify(options) + ')') >+ .notThrow(); >+ should(context.length, 'c.length').beEqualTo(options.length); >+ should(context.sampleRate, 'c.sampleRate') >+ .beEqualTo(options.sampleRate); >+ should( >+ context.destination.channelCount, 'c.destination.channelCount') >+ .beEqualTo(1); >+ should( >+ context.destination.channelCountMode, >+ 'c.destination.channelCountMode') >+ .beEqualTo('explicit'); >+ should( >+ context.destination.channelInterpretation, >+ 'c.destination.channelCountMode') >+ .beEqualTo('speakers'); >+ >+ options.numberOfChannels = 7; >+ should( >+ () => { >+ context = new OfflineAudioContext(options); >+ }, >+ 'c = new OfflineAudioContext' + JSON.stringify(options) + ')') >+ .notThrow(); >+ should( >+ context.destination.channelCount, 'c.destination.channelCount') >+ .beEqualTo(options.numberOfChannels); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/w3c-import.log >index 7bf5c610145f88e6bc5dcf632b3f83011b16e4bb..61d917e913e16b5a017b7ecb9e9d245648ecc127 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/w3c-import.log >@@ -14,4 +14,5 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/ctor-offlineaudiocontext.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/current-time-block-size.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/ctor-oscillator-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/ctor-oscillator-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..7d4b76134036bb9db7a57ad06146ef90d989efe5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/ctor-oscillator-expected.txt >@@ -0,0 +1,17 @@ >+CONSOLE MESSAGE: line 227: TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+PASS context = new OfflineAudioContext(...) did not throw an exception. >+PASS < [initialize] All assertions passed. (total 1 assertions) >+PASS > [invalid constructor] >+PASS new OscillatorNode() threw TypeError: "function is not a constructor (evaluating 'new window[name]()')". >+PASS new OscillatorNode(1) threw TypeError: "function is not a constructor (evaluating 'new window[name](1)')". >+PASS new OscillatorNode(context, 42) threw TypeError: "function is not a constructor (evaluating 'new window[name](context, 42)')". >+PASS < [invalid constructor] All assertions passed. (total 3 assertions) >+PASS > [default constructor] >+FAIL X node0 = new OscillatorNode(context) incorrectly threw TypeError: "function is not a constructor (evaluating 'new window[name](context, options.constructorOptions)')". assert_true: expected true got false >+FAIL X node0 instanceof OscillatorNode is not equal to true. Got false. assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/ctor-oscillator.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/ctor-oscillator.html >new file mode 100644 >index 0000000000000000000000000000000000000000..aaf77aec555b720b343a9e63adae924c730510dc >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/ctor-oscillator.html >@@ -0,0 +1,106 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Constructor: Oscillator >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audionodeoptions.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let context; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('initialize', (task, should) => { >+ context = initializeContext(should); >+ task.done(); >+ }); >+ >+ audit.define('invalid constructor', (task, should) => { >+ testInvalidConstructor(should, 'OscillatorNode', context); >+ task.done(); >+ }); >+ >+ audit.define('default constructor', (task, should) => { >+ let prefix = 'node0'; >+ let node = testDefaultConstructor(should, 'OscillatorNode', context, { >+ prefix: prefix, >+ numberOfInputs: 0, >+ numberOfOutputs: 1, >+ channelCount: 2, >+ channelCountMode: 'max', >+ channelInterpretation: 'speakers' >+ }); >+ >+ testDefaultAttributes( >+ should, node, prefix, >+ [{name: 'type', value: 'sine'}, {name: 'frequency', value: 440}]); >+ >+ task.done(); >+ }); >+ >+ audit.define('test AudioNodeOptions', (task, should) => { >+ testAudioNodeOptions(should, context, 'OscillatorNode'); >+ task.done(); >+ }); >+ >+ audit.define('constructor options', (task, should) => { >+ let node; >+ let options = {type: 'sawtooth', detune: 7, frequency: 918}; >+ >+ should( >+ () => { >+ node = new OscillatorNode(context, options); >+ }, >+ 'node1 = new OscillatorNode(c, ' + JSON.stringify(options) + ')') >+ .notThrow(); >+ >+ should(node.type, 'node1.type').beEqualTo(options.type); >+ should(node.detune.value, 'node1.detune.value') >+ .beEqualTo(options.detune); >+ should(node.frequency.value, 'node1.frequency.value') >+ .beEqualTo(options.frequency); >+ >+ should(node.channelCount, 'node1.channelCount').beEqualTo(2); >+ should(node.channelCountMode, 'node1.channelCountMode') >+ .beEqualTo('max'); >+ should(node.channelInterpretation, 'node1.channelInterpretation') >+ .beEqualTo('speakers'); >+ >+ // Test that type and periodicWave options work as described. >+ options = { >+ type: 'sine', >+ periodicWave: new PeriodicWave(context, {real: [1, 1]}) >+ }; >+ should(() => { >+ node = new OscillatorNode(context, options); >+ }, 'new OscillatorNode(c, ' + JSON.stringify(options) + ')').notThrow(); >+ >+ options = {type: 'custom'}; >+ should( >+ () => { >+ node = new OscillatorNode(context, options); >+ }, >+ 'new OscillatorNode(c, ' + JSON.stringify(options) + ')') >+ .throw('InvalidStateError'); >+ >+ options = { >+ type: 'custom', >+ periodicWave: new PeriodicWave(context, {real: [1, 1]}) >+ }; >+ should(() => { >+ node = new OscillatorNode(context, options); >+ }, 'new OscillatorNode(, ' + JSON.stringify(options) + ')').notThrow(); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..fefaa9089696a42a6125356a603852c822b631f0 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/w3c-import.log >@@ -0,0 +1,17 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/ctor-oscillator.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..6c107d0ef3d91a9a77ed10a2e11194587e7c4aad >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner-expected.txt >@@ -0,0 +1,16 @@ >+CONSOLE MESSAGE: line 225: TypeError: Right hand side of instanceof is not an object >+ >+Harness Error (FAIL), message = TypeError: Right hand side of instanceof is not an object >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+PASS context = new OfflineAudioContext(...) did not throw an exception. >+PASS < [initialize] All assertions passed. (total 1 assertions) >+PASS > [invalid constructor] >+PASS new PannerNode() threw TypeError: "undefined is not a constructor (evaluating 'new window[name]()')". >+PASS new PannerNode(1) threw TypeError: "undefined is not a constructor (evaluating 'new window[name](1)')". >+PASS new PannerNode(context, 42) threw TypeError: "undefined is not a constructor (evaluating 'new window[name](context, 42)')". >+PASS < [invalid constructor] All assertions passed. (total 3 assertions) >+PASS > [default constructor] >+FAIL X node0 = new PannerNode(context) incorrectly threw TypeError: "undefined is not a constructor (evaluating 'new window[name](context, options.constructorOptions)')". assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html >new file mode 100644 >index 0000000000000000000000000000000000000000..48b368ddf2d1e48e40b7341793ec9811d72e1253 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html >@@ -0,0 +1,274 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Constructor: Panner >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audionodeoptions.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let context; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('initialize', (task, should) => { >+ context = initializeContext(should); >+ task.done(); >+ }); >+ >+ audit.define('invalid constructor', (task, should) => { >+ testInvalidConstructor(should, 'PannerNode', context); >+ task.done(); >+ }); >+ >+ audit.define('default constructor', (task, should) => { >+ let prefix = 'node0'; >+ let node = testDefaultConstructor(should, 'PannerNode', context, { >+ prefix: prefix, >+ numberOfInputs: 1, >+ numberOfOutputs: 1, >+ channelCount: 2, >+ channelCountMode: 'clamped-max', >+ channelInterpretation: 'speakers' >+ }); >+ >+ testDefaultAttributes(should, node, prefix, [ >+ {name: 'panningModel', value: 'equalpower'}, >+ {name: 'positionX', value: 0}, {name: 'positionY', value: 0}, >+ {name: 'positionZ', value: 0}, {name: 'orientationX', value: 1}, >+ {name: 'orientationY', value: 0}, {name: 'orientationZ', value: 0}, >+ {name: 'distanceModel', value: 'inverse'}, >+ {name: 'refDistance', value: 1}, {name: 'maxDistance', value: 10000}, >+ {name: 'rolloffFactor', value: 1}, >+ {name: 'coneInnerAngle', value: 360}, >+ {name: 'coneOuterAngle', value: 360}, >+ {name: 'coneOuterGain', value: 0} >+ ]); >+ >+ // Test the listener too, while we're at it. >+ let listenerAttributes = [ >+ {name: 'positionX', value: 0}, >+ {name: 'positionY', value: 0}, >+ {name: 'positionZ', value: 0}, >+ {name: 'forwardX', value: 0}, >+ {name: 'forwardY', value: 0}, >+ {name: 'forwardZ', value: -1}, >+ {name: 'upX', value: 0}, >+ {name: 'upY', value: 1}, >+ {name: 'upZ', value: 0}, >+ ]; >+ >+ listenerAttributes.forEach((item) => { >+ should( >+ context.listener[item.name].value, >+ 'context.listener.' + item.name + '.value') >+ .beEqualTo(item.value); >+ }); >+ >+ task.done(); >+ }); >+ >+ audit.define('test AudioNodeOptions', (task, should) => { >+ // Can't use testAudioNodeOptions because the constraints for this node >+ // are not supported there. >+ let node; >+ let success = true; >+ >+ // Test that we can set the channel count to 1 or 2. >+ let options = {channelCount: 1}; >+ should( >+ () => { >+ node = new PannerNode(context, options); >+ }, >+ 'node1 = new PannerNode(c, ' + JSON.stringify(options) + ')') >+ .notThrow(); >+ should(node.channelCount, 'node1.channelCount') >+ .beEqualTo(options.channelCount); >+ >+ options = {channelCount: 2}; >+ should( >+ () => { >+ node = new PannerNode(context, options); >+ }, >+ 'node2 = new PannerNode(c, ' + JSON.stringify(options) + ')') >+ .notThrow(); >+ should(node.channelCount, 'node2.channelCount') >+ .beEqualTo(options.channelCount); >+ >+ // Test that other channel counts throw an error >+ options = {channelCount: 0}; >+ should( >+ () => { >+ node = new PannerNode(context, options); >+ }, >+ 'new PannerNode(c, ' + JSON.stringify(options) + ')') >+ .throw('NotSupportedError'); >+ >+ options = {channelCount: 3}; >+ should( >+ () => { >+ node = new PannerNode(context, options); >+ }, >+ 'new PannerNode(c, ' + JSON.stringify(options) + ')') >+ .throw('NotSupportedError'); >+ >+ options = {channelCount: 99}; >+ should( >+ () => { >+ node = new PannerNode(context, options); >+ }, >+ 'new PannerNode(c, ' + JSON.stringify(options) + ')') >+ .throw('NotSupportedError'); >+ >+ // Test channelCountMode. A mode of "max" is illegal, but others are >+ // ok. >+ options = {channelCountMode: 'clamped-max'}; >+ should( >+ () => { >+ node = new PannerNode(context, options); >+ }, >+ 'node3 = new PannerNode(c, ' + JSON.stringify(options) + ')') >+ .notThrow(); >+ should(node.channelCountMode, 'node3.channelCountMode') >+ .beEqualTo(options.channelCountMode); >+ >+ options = {channelCountMode: 'explicit'}; >+ should( >+ () => { >+ node = new PannerNode(context, options); >+ }, >+ 'node4 = new PannerNode(c, ' + JSON.stringify(options) + ')') >+ .notThrow(); >+ should(node.channelCountMode, 'node4.channelCountMode') >+ .beEqualTo(options.channelCountMode); >+ >+ options = {channelCountMode: 'max'}; >+ should( >+ () => { >+ node = new PannerNode(context, options); >+ }, >+ 'new PannerNode(c, ' + JSON.stringify(options) + ')') >+ .throw('NotSupportedError'); >+ >+ options = {channelCountMode: 'foobar'}; >+ should( >+ () => { >+ node = new PannerNode(context, options); >+ }, >+ 'new PannerNode(c, " + JSON.stringify(options) + ")') >+ .throw('TypeError'); >+ >+ // Test channelInterpretation. >+ options = {channelInterpretation: 'speakers'}; >+ should( >+ () => { >+ node = new PannerNode(context, options); >+ }, >+ 'node5 = new PannerNode(c, ' + JSON.stringify(options) + ')') >+ .notThrow(); >+ should(node.channelInterpretation, 'node5.channelInterpretation') >+ .beEqualTo(options.channelInterpretation); >+ >+ options = {channelInterpretation: 'discrete'}; >+ should( >+ () => { >+ node = new PannerNode(context, options); >+ }, >+ 'node6 = new PannerNode(c, ' + JSON.stringify(options) + ')') >+ .notThrow(); >+ should(node.channelInterpretation, 'node6.channelInterpretation') >+ .beEqualTo(options.channelInterpretation); >+ >+ options = {channelInterpretation: 'foobar'}; >+ should( >+ () => { >+ node = new PannerNode(context, options); >+ }, >+ 'new PannerNode(c, ' + JSON.stringify(options) + ')') >+ .throw('TypeError'); >+ >+ task.done(); >+ }); >+ >+ audit.define('constructor with options', (task, should) => { >+ let node; >+ let success = true; >+ let options = { >+ panningModel: 'HRTF', >+ // We use full double float values here to verify also that the actual >+ // AudioParam value is properly rounded to a float. The actual value >+ // is immaterial as long as x != Math.fround(x). >+ positionX: Math.SQRT2, >+ positionY: 2 * Math.SQRT2, >+ positionZ: 3 * Math.SQRT2, >+ orientationX: -Math.SQRT2, >+ orientationY: -2 * Math.SQRT2, >+ orientationZ: -3 * Math.SQRT2, >+ distanceModel: 'linear', >+ // We use full double float values here to verify also that the actual >+ // attribute is a double float. The actual value is immaterial as >+ // long as x != Math.fround(x). >+ refDistance: Math.PI, >+ maxDistance: 2 * Math.PI, >+ rolloffFactor: 3 * Math.PI, >+ coneInnerAngle: 4 * Math.PI, >+ coneOuterAngle: 5 * Math.PI, >+ coneOuterGain: 6 * Math.PI >+ }; >+ >+ should( >+ () => { >+ node = new PannerNode(context, options); >+ }, >+ 'node = new PannerNode(c, ' + JSON.stringify(options) + ')') >+ .notThrow(); >+ should(node instanceof PannerNode, 'node instanceof PannerNode') >+ .beEqualTo(true); >+ >+ should(node.panningModel, 'node.panningModel') >+ .beEqualTo(options.panningModel); >+ should(node.positionX.value, 'node.positionX.value') >+ .beEqualTo(Math.fround(options.positionX)); >+ should(node.positionY.value, 'node.positionY.value') >+ .beEqualTo(Math.fround(options.positionY)); >+ should(node.positionZ.value, 'node.positionZ.value') >+ .beEqualTo(Math.fround(options.positionZ)); >+ should(node.orientationX.value, 'node.orientationX.value') >+ .beEqualTo(Math.fround(options.orientationX)); >+ should(node.orientationY.value, 'node.orientationY.value') >+ .beEqualTo(Math.fround(options.orientationY)); >+ should(node.orientationZ.value, 'node.orientationZ.value') >+ .beEqualTo(Math.fround(options.orientationZ)); >+ should(node.distanceModel, 'node.distanceModel') >+ .beEqualTo(options.distanceModel); >+ should(node.refDistance, 'node.refDistance') >+ .beEqualTo(options.refDistance); >+ should(node.maxDistance, 'node.maxDistance') >+ .beEqualTo(options.maxDistance); >+ should(node.rolloffFactor, 'node.rolloffFactor') >+ .beEqualTo(options.rolloffFactor); >+ should(node.coneInnerAngle, 'node.coneInnerAngle') >+ .beEqualTo(options.coneInnerAngle); >+ should(node.coneOuterAngle, 'node.coneOuterAngle') >+ .beEqualTo(options.coneOuterAngle); >+ should(node.coneOuterGain, 'node.coneOuterGain') >+ .beEqualTo(options.coneOuterGain); >+ >+ should(node.channelCount, 'node.channelCount').beEqualTo(2); >+ should(node.channelCountMode, 'node.channelCountMode') >+ .beEqualTo('clamped-max'); >+ should(node.channelInterpretation, 'node.channelInterpretation') >+ .beEqualTo('speakers'); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/w3c-import.log >index f045d979c28e5295063dd6e804e6e62d687a2d53..bd36b3cdea3ecb1c2e22ade5370ceb404af9146a 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/w3c-import.log >@@ -14,6 +14,7 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/distance-exponential.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/distance-inverse.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/distance-linear.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/ctor-stereopanner-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/ctor-stereopanner-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..9863f826d957e5b299d37e47f9fd8889fc7064c0 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/ctor-stereopanner-expected.txt >@@ -0,0 +1,16 @@ >+CONSOLE MESSAGE: line 225: TypeError: Right hand side of instanceof is not an object >+ >+Harness Error (FAIL), message = TypeError: Right hand side of instanceof is not an object >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+PASS context = new OfflineAudioContext(...) did not throw an exception. >+PASS < [initialize] All assertions passed. (total 1 assertions) >+PASS > [invalid constructor] >+PASS new StereoPannerNode() threw TypeError: "undefined is not a constructor (evaluating 'new window[name]()')". >+PASS new StereoPannerNode(1) threw TypeError: "undefined is not a constructor (evaluating 'new window[name](1)')". >+PASS new StereoPannerNode(context, 42) threw TypeError: "undefined is not a constructor (evaluating 'new window[name](context, 42)')". >+PASS < [invalid constructor] All assertions passed. (total 3 assertions) >+PASS > [default constructor] >+FAIL X node0 = new StereoPannerNode(context) incorrectly threw TypeError: "undefined is not a constructor (evaluating 'new window[name](context, options.constructorOptions)')". assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/ctor-stereopanner.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/ctor-stereopanner.html >new file mode 100644 >index 0000000000000000000000000000000000000000..9de58cf783a8f18069830a5990691da574a1cf1f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/ctor-stereopanner.html >@@ -0,0 +1,125 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Constructor: StereoPanner >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audionodeoptions.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let context; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('initialize', (task, should) => { >+ context = initializeContext(should); >+ task.done(); >+ }); >+ >+ audit.define('invalid constructor', (task, should) => { >+ testInvalidConstructor(should, 'StereoPannerNode', context); >+ task.done(); >+ }); >+ >+ audit.define('default constructor', (task, should) => { >+ let prefix = 'node0'; >+ let node = testDefaultConstructor(should, 'StereoPannerNode', context, { >+ prefix: prefix, >+ numberOfInputs: 1, >+ numberOfOutputs: 1, >+ channelCount: 2, >+ channelCountMode: 'clamped-max', >+ channelInterpretation: 'speakers' >+ }); >+ >+ testDefaultAttributes(should, node, prefix, [{name: 'pan', value: 0}]); >+ >+ task.done(); >+ }); >+ >+ audit.define('test AudioNodeOptions', (task, should) => { >+ // Can't use testAudioNodeOptions because the constraints for this node >+ // are not supported there. >+ let node; >+ >+ // An array of tests. >+ [{ >+ // Test that we can set the channel count to 1 or 2 and that other >+ // channel counts throw an error. >+ attribute: 'channelCount', >+ tests: [ >+ {value: 1}, {value: 2}, {value: 0, error: 'NotSupportedError'}, >+ {value: 3, error: 'NotSupportedError'}, >+ {value: 99, error: 'NotSupportedError'} >+ ] >+ }, >+ { >+ // Test channelCountMode. A mode of "max" is illegal, but others are >+ // ok. But also throw an error of unknown values. >+ attribute: 'channelCountMode', >+ tests: [ >+ {value: 'clamped-max'}, {value: 'explicit'}, >+ {value: 'max', error: 'NotSupportedError'}, >+ {value: 'foobar', error: 'TypeError'} >+ ] >+ }, >+ { >+ // Test channelInterpretation can be set for valid values and an >+ // error is thrown for others. >+ attribute: 'channelInterpretation', >+ tests: [ >+ {value: 'speakers'}, {value: 'discrete'}, >+ {value: 'foobar', error: 'TypeError'} >+ ] >+ }].forEach(entry => { >+ entry.tests.forEach(testItem => { >+ let options = {}; >+ options[entry.attribute] = testItem.value; >+ let method = testItem.error ? 'throw' : 'notThrow'; >+ >+ should( >+ () => { >+ node = new StereoPannerNode(context, options); >+ }, >+ `new StereoPannerNode(c, ${JSON.stringify(options)})`)[method]( >+ testItem.error); >+ if (!testItem.error) >+ should(node[entry.attribute], `node.${entry.attribute}`) >+ .beEqualTo(options[entry.attribute]); >+ }); >+ }); >+ >+ task.done(); >+ }); >+ >+ audit.define('constructor with options', (task, should) => { >+ let node; >+ let options = { >+ pan: 0.75, >+ }; >+ >+ should( >+ () => { >+ node = new StereoPannerNode(context, options); >+ }, >+ 'node1 = new StereoPannerNode(, ' + JSON.stringify(options) + ')') >+ .notThrow(); >+ should( >+ node instanceof StereoPannerNode, >+ 'node1 instanceof StereoPannerNode') >+ .beEqualTo(true); >+ >+ should(node.pan.value, 'node1.pan.value').beEqualTo(options.pan); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/w3c-import.log >index 32e882b3296bdc86eee3d7822b6143bccc468854..a5ca02dce83e312824dee31a24541162b78a5b7d 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/w3c-import.log >@@ -14,6 +14,7 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/ctor-stereopanner.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/no-dezippering.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/stereopannernode-basic.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/stereopannernode-panning.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/ctor-waveshaper-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/ctor-waveshaper-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..a06402fdfeff1c32fb9507d7f36f96eaed339126 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/ctor-waveshaper-expected.txt >@@ -0,0 +1,17 @@ >+CONSOLE MESSAGE: line 227: TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'node.numberOfInputs') >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [initialize] >+PASS context = new OfflineAudioContext(...) did not throw an exception. >+PASS < [initialize] All assertions passed. (total 1 assertions) >+PASS > [incorrect construction] >+PASS new WaveShaperNode() threw TypeError: "function is not a constructor (evaluating 'new window[name]()')". >+PASS new WaveShaperNode(1) threw TypeError: "function is not a constructor (evaluating 'new window[name](1)')". >+PASS new WaveShaperNode(context, 42) threw TypeError: "function is not a constructor (evaluating 'new window[name](context, 42)')". >+PASS < [incorrect construction] All assertions passed. (total 3 assertions) >+PASS > [valid default construction] >+FAIL X node0 = new WaveShaperNode(context) incorrectly threw TypeError: "function is not a constructor (evaluating 'new window[name](context, options.constructorOptions)')". assert_true: expected true got false >+FAIL X node0 instanceof WaveShaperNode is not equal to true. Got false. assert_true: expected true got false >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/ctor-waveshaper.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/ctor-waveshaper.html >new file mode 100644 >index 0000000000000000000000000000000000000000..7aa33ca5aa3323754755ebfda200976b0b292730 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/ctor-waveshaper.html >@@ -0,0 +1,72 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title> >+ Test Constructor: WaveShaper >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ <script src="/webaudio/resources/audionodeoptions.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let context; >+ >+ let audit = Audit.createTaskRunner(); >+ >+ audit.define('initialize', (task, should) => { >+ context = initializeContext(should); >+ task.done(); >+ }); >+ >+ audit.define('incorrect construction', (task, should) => { >+ testInvalidConstructor(should, 'WaveShaperNode', context); >+ task.done(); >+ }); >+ >+ audit.define('valid default construction', (task, should) => { >+ let prefix = 'node0'; >+ let node = testDefaultConstructor(should, 'WaveShaperNode', context, { >+ prefix: prefix, >+ numberOfInputs: 1, >+ numberOfOutputs: 1, >+ channelCount: 2, >+ channelCountMode: 'max', >+ channelInterpretation: 'speakers' >+ }); >+ >+ testDefaultAttributes(should, node, prefix, [ >+ {name: 'curve', value: null}, {name: 'oversample', value: 'none'} >+ ]); >+ >+ task.done(); >+ }); >+ >+ audit.define('test AudioNodeOptions', (task, should) => { >+ testAudioNodeOptions(should, context, 'WaveShaperNode'); >+ task.done(); >+ }); >+ >+ audit.define('valid non-default', (task, should) => { >+ // Construct an WaveShaperNode with options >+ let options = {curve: Float32Array.from([1, 2, 3]), oversample: '4x'}; >+ let node; >+ >+ let message = >+ 'node1 = new WaveShaperNode(, ' + JSON.stringify(options) + ')'; >+ should(() => { >+ node = new WaveShaperNode(context, options); >+ }, message).notThrow(); >+ should(node.curve, 'node1.curve').beEqualToArray(options.curve); >+ should(node.oversample, 'node1.oversample') >+ .beEqualTo(options.oversample); >+ >+ task.done(); >+ }); >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/silent-inputs-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/silent-inputs-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..96782797e14a063a460c735e8167c4b0052e6b83 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/silent-inputs-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 91: SyntaxError: The string did not match the expected pattern. >+ >+Harness Error (FAIL), message = SyntaxError: The string did not match the expected pattern. >+ >+PASS # AUDIT TASK RUNNER STARTED. >+PASS > [test-0] curve output is non-zero for silent inputs >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/silent-inputs.html b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/silent-inputs.html >new file mode 100644 >index 0000000000000000000000000000000000000000..45d2c9ad4b3cb903ad29f7269d389d9e353a0faa >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/silent-inputs.html >@@ -0,0 +1,103 @@ >+<!doctype html> >+<html> >+ <head> >+ <title> >+ Test Silent Inputs to WaveShaperNode >+ </title> >+ <script src="/resources/testharness.js"></script> >+ <script src="/resources/testharnessreport.js"></script> >+ <script src="/webaudio/resources/audit-util.js"></script> >+ <script src="/webaudio/resources/audit.js"></script> >+ </head> >+ <body> >+ <script id="layout-test-code"> >+ let audit = Audit.createTaskRunner(); >+ let sampleRate = 16000; >+ >+ // Identity curve for the wave shaper: the input value is mapped directly >+ // to the output value. >+ let identityCurve = [-1, 0, 1]; >+ let nonZeroCurve = [0.5, 0.5, 0.5]; >+ >+ audit.define( >+ { >+ label: 'test-0', >+ description: 'curve output is non-zero for silent inputs' >+ }, >+ (task, should) => { >+ let {context, source, shaper} = >+ setupGraph(nonZeroCurve, sampleRate, sampleRate); >+ >+ source.offset.setValueAtTime(0, 0); >+ >+ context.startRendering() >+ .then(audioBuffer => { >+ should( >+ audioBuffer.getChannelData(0), >+ 'WaveShaper with silent inputs and curve ' + >+ JSON.stringify(shaper.curve)) >+ .beConstantValueOf(0.5); >+ }) >+ .then(() => task.done()); >+ }); >+ >+ audit.define( >+ { >+ label: 'test-1', >+ description: '2x curve output is non-zero for silent inputs' >+ }, >+ (task, should) => { >+ let {context, source, shaper} = >+ setupGraph(nonZeroCurve, sampleRate, sampleRate); >+ >+ source.offset.setValueAtTime(0, 0); >+ shaper.overSample = '2x'; >+ >+ context.startRendering() >+ .then(audioBuffer => { >+ should( >+ audioBuffer.getChannelData(0), >+ 'WaveShaper with ' + shaper.overSample + >+ ' oversample, silent inputs, and curve ' + >+ JSON.stringify(shaper.curve)) >+ .beConstantValueOf(0.5); >+ }) >+ .then(() => task.done()); >+ }); >+ >+ audit.define( >+ { >+ label: 'test-2', >+ description: 'curve output is non-zero for no inputs' >+ }, >+ (task, should) => { >+ let {context, source, shaper} = >+ setupGraph(nonZeroCurve, sampleRate, sampleRate); >+ >+ source.disconnect(); >+ >+ context.startRendering() >+ .then(audioBuffer => { >+ should( >+ audioBuffer.getChannelData(0), >+ 'WaveShaper with no inputs and curve ' + >+ JSON.stringify(shaper.curve)) >+ .beConstantValueOf(0.5); >+ }) >+ .then(() => task.done()); >+ }); >+ >+ function setupGraph(curve, testFrames, sampleRate) { >+ let context = new OfflineAudioContext(1, testFrames, sampleRate); >+ let source = new ConstantSourceNode(context); >+ let shaper = new WaveShaperNode(context, {curve: curve}); >+ >+ source.connect(shaper).connect(context.destination); >+ >+ return {context: context, source: source, shaper: shaper}; >+ } >+ >+ audit.run(); >+ </script> >+ </body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/w3c-import.log >index fb2c15e0cbe6b0ef105918fad1108e05c17a1453..4d09a00aaff9b1543c6fc79d802793c9047065a9 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/w3c-import.log >@@ -14,7 +14,9 @@ Property values requiring vendor prefixes: > None > ------------------------------------------------------------------------ > List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/ctor-waveshaper.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/curve-tests.html >+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/silent-inputs.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/waveshaper-copy-curve.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/waveshaper-limits.html > /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-waveshapernode-interface/waveshaper-simple.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-insertDTMF.https.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-insertDTMF.https.html >index 383977c52e17f3e84958d62b9c9c20a558c7e009..7a45e5daba7eb441fe136d7a114a2a6a07c926af 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-insertDTMF.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-insertDTMF.https.html >@@ -148,7 +148,7 @@ > > 7. Set the object's toneBuffer attribute to tones. > */ >- promise_test(() => { >+ promise_test(t => { > return createDtmfSender() > .then(dtmfSender => { > dtmfSender.insertDTMF('123'); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-ontonechange.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-ontonechange.https-expected.txt >index e9ce286c59cc225157d53204cc224b59bcc99937..773a5cc4749b6773a7f7c6190500cebd2668d813 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-ontonechange.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-ontonechange.https-expected.txt >@@ -10,4 +10,6 @@ FAIL Calling insertDTMF() in the middle of tonechange events should cause future > FAIL Calling insertDTMF() multiple times in the middle of tonechange events should cause future tonechanges to be updated the last provided tones assert_unreached: Unexpected promise rejection: ReferenceError: Can't find variable: RTCDTMFSender Reached unreachable code > FAIL Calling insertDTMF('') in the middle of tonechange events should stop future tonechange events from firing assert_unreached: Unexpected promise rejection: ReferenceError: Can't find variable: RTCDTMFSender Reached unreachable code > FAIL Setting transceiver.currentDirection to recvonly in the middle of tonechange events should stop future tonechange events from firing undefined is not an object (evaluating 'dtmfSender.addEventListener') >+FAIL Tone change event constructor works Can't find variable: RTCDTMFToneChangeEvent >+FAIL Tone change event with unexpected name should not crash Can't find variable: RTCDTMFToneChangeEvent > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-ontonechange.https.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-ontonechange.https.html >index 9fa900c7368d3997152bae1127e180fdd7b1ed6d..bfb8b8c00674affac6168cbc9439afecad448802 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-ontonechange.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-ontonechange.https.html >@@ -282,4 +282,15 @@ > > }, `Setting transceiver.currentDirection to recvonly in the middle of tonechange events should stop future tonechange events from firing`); > >+ /* Section 7.3 - Tone change event */ >+ test(t => { >+ let ev = new RTCDTMFToneChangeEvent('tonechange', {'tone': '1'}); >+ assert_equals(ev.type, 'tonechange'); >+ assert_equals(ev.tone, '1'); >+ }, 'Tone change event constructor works'); >+ >+ test(t => { >+ let ev = new RTCDTMFToneChangeEvent('worngname', {}); >+ }, 'Tone change event with unexpected name should not crash'); >+ > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCIceTransport.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCIceTransport.html >index 57ecf07f7b128fdff676c25fbf0206e015bde063..9163285ac5b765fcebc48c562fe6edd6b7c3f143 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCIceTransport.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCIceTransport.html >@@ -118,7 +118,7 @@ > validateCandidateParameter(iceTransport.getRemoteParameters()); > } > >- promise_test(() => { >+ promise_test(t => { > const pc1 = new RTCPeerConnection(); > const pc2 = new RTCPeerConnection(); > >@@ -163,7 +163,7 @@ > }); > }, 'Two connected iceTransports should has matching local/remote candidates returned'); > >- promise_test(() => { >+ promise_test(t => { > const pc1 = new RTCPeerConnection(); > const pc2 = new RTCPeerConnection(); > pc1.createDataChannel(''); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-add-track-no-deadlock.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-add-track-no-deadlock.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..6a51632d96291babb6a8fdc3dfcf054a55eaf7d5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-add-track-no-deadlock.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS RTCPeerConnection addTrack does not deadlock. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-add-track-no-deadlock.https.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-add-track-no-deadlock.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..0bf58d947ca716c030f274eba9d33771ea411b69 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-add-track-no-deadlock.https.html >@@ -0,0 +1,30 @@ >+<!doctype html> >+<meta charset=utf-8> >+<title>RTCPeerConnection addTrack does not deadlock</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+ 'use strict'; >+ >+ // This test sets up two peer connections using a sequence of operations >+ // that triggered a deadlock in Chrome. See https://crbug.com/736725. >+ // If a deadlock is introduced again, this test times out. >+ promise_test(async t => { >+ const pc1 = new RTCPeerConnection(); >+ t.add_cleanup(() => pc1.close()); >+ const stream = await navigator.mediaDevices.getUserMedia( >+ {audio: false, video: true}); >+ const videoTrack = stream.getVideoTracks()[0]; >+ t.add_cleanup(() => videoTrack.stop()); >+ pc1.addTrack(videoTrack, stream); >+ const offer = await pc1.createOffer(); >+ await pc1.setLocalDescription(offer); >+ const pc2 = new RTCPeerConnection(); >+ t.add_cleanup(() => pc2.close()); >+ const srdPromise = pc2.setRemoteDescription(offer); >+ pc2.addTrack(videoTrack, stream); >+ // The deadlock encountered in https://crbug.com/736725 occured here. >+ await srdPromise; >+ await pc2.createAnswer(); >+ }, 'RTCPeerConnection addTrack does not deadlock.'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-canTrickleIceCandidates.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-canTrickleIceCandidates.html >index 63dac8f377986ff0cdba73bd7b413b94a31bfd27..38c8b632cd12fe24b3dd1109fdd295268dc256ee 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-canTrickleIceCandidates.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-canTrickleIceCandidates.html >@@ -35,7 +35,7 @@ > assert_equals(pc.canTrickleIceCandidates, null, 'canTrickleIceCandidates property is null'); > }, 'canTrickleIceCandidates property is null prior to setRemoteDescription'); > >- promise_test(function() { >+ promise_test(function(t) { > var pc = new RTCPeerConnection(); > > return pc.setRemoteDescription(new RTCSessionDescription({type: 'offer', sdp: sdp})) >@@ -44,7 +44,7 @@ > }) > }, 'canTrickleIceCandidates property is true after setRemoteDescription with a=ice-options:trickle'); > >- promise_test(function() { >+ promise_test(function(t) { > var pc = new RTCPeerConnection(); > > return pc.setRemoteDescription(new RTCSessionDescription({type: 'offer', sdp: sdp.replace('a=ice-options:trickle\r\n', '')})) >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-createOffer-offerToReceive-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-createOffer-offerToReceive-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..862f4681dc85533ec64a1aefd5cb02ff380a8818 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-createOffer-offerToReceive-expected.txt >@@ -0,0 +1,17 @@ >+ >+PASS createOffer() with offerToReceiveAudio set to false should not create a transceiver >+FAIL createOffer() with offerToReceiveAudio should create a "recvonly" transceiver assert_equals: Expect pc to have one transceiver expected 1 but got 0 >+FAIL offerToReceiveAudio option should be ignored if a non-stopped "recvonly" transceiver exists assert_equals: Expect pc to have one transceiver expected 1 but got 0 >+PASS offerToReceiveAudio option should be ignored if a non-stopped "sendrecv" transceiver exists >+FAIL offerToReceiveAudio set to false with a track should create a "sendonly" transceiver assert_equals: Expect transceiver to have "sendonly" direction expected "sendonly" but got "sendrecv" >+FAIL offerToReceiveAudio set to false with a "recvonly" transceiver should change the direction to "inactive" assert_equals: Expect transceiver to have "inactive" direction expected "inactive" but got "recvonly" >+FAIL subsequent offerToReceiveAudio set to false with a track should change the direction to "sendonly" assert_equals: Expect transceiver to have "sendonly" direction expected "sendonly" but got "sendrecv" >+PASS createOffer() with offerToReceiveVideo set to false should not create a transceiver >+FAIL createOffer() with offerToReceiveVideo should create a "recvonly" transceiver assert_equals: Expect pc to have one transceiver expected 1 but got 0 >+FAIL offerToReceiveVideo option should be ignored if a non-stopped "recvonly" transceiver exists assert_equals: Expect pc to have one transceiver expected 1 but got 0 >+PASS offerToReceiveVideo option should be ignored if a non-stopped "sendrecv" transceiver exists >+FAIL offerToReceiveVideo set to false with a track should create a "sendonly" transceiver assert_equals: Expect transceiver to have "sendonly" direction expected "sendonly" but got "sendrecv" >+FAIL offerToReceiveVideo set to false with a "recvonly" transceiver should change the direction to "inactive" assert_equals: Expect transceiver to have "inactive" direction expected "inactive" but got "recvonly" >+FAIL subsequent offerToReceiveVideo set to false with a track should change the direction to "sendonly" assert_equals: Expect transceiver to have "sendonly" direction expected "sendonly" but got "sendrecv" >+FAIL offerToReceiveAudio and Video should create two "recvonly" transceivers assert_equals: Expect pc to have two transceivers expected 2 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-createOffer-offerToReceive.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-createOffer-offerToReceive.html >new file mode 100644 >index 0000000000000000000000000000000000000000..c599b1c0d07a5d5c664120008ca48d1564df8ea9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-createOffer-offerToReceive.html >@@ -0,0 +1,169 @@ >+<!doctype html> >+<meta charset=utf-8> >+<title>Test legacy offerToReceiveAudio/Video options</title> >+<link rel="help" href="https://w3c.github.io/webrtc-pc/#legacy-configuration-extensions"> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="RTCPeerConnection-helper.js"></script> >+<script> >+ 'use strict'; >+ >+ // Run some tests for both audio and video kinds >+ ['audio', 'video'].forEach((kind) => { >+ const capsKind = kind[0].toUpperCase() + kind.slice(1); >+ >+ const offerToReceiveTrue = {}; >+ offerToReceiveTrue[`offerToReceive${capsKind}`] = true; >+ >+ const offerToReceiveFalse = {}; >+ offerToReceiveFalse[`offerToReceive${capsKind}`] = false; >+ >+ // Start testing >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ const dummy = pc.createDataChannel('foo'); // Just to have something to offer >+ >+ return pc.createOffer(offerToReceiveFalse) >+ .then(() => { >+ assert_equals(pc.getTransceivers().length, 0, >+ 'Expect pc to have no transceivers'); >+ }); >+ }, `createOffer() with offerToReceive${capsKind} set to false should not create a transceiver`); >+ >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ >+ return pc.createOffer(offerToReceiveTrue) >+ .then(() => { >+ assert_equals(pc.getTransceivers().length, 1, >+ 'Expect pc to have one transceiver'); >+ >+ const transceiver = pc.getTransceivers()[0]; >+ assert_equals(transceiver.direction, 'recvonly', >+ 'Expect transceiver to have "recvonly" direction'); >+ }); >+ }, `createOffer() with offerToReceive${capsKind} should create a "recvonly" transceiver`); >+ >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ >+ return pc.createOffer(offerToReceiveTrue) >+ .then(() => { >+ assert_equals(pc.getTransceivers().length, 1, >+ 'Expect pc to have one transceiver'); >+ >+ const transceiver = pc.getTransceivers()[0]; >+ assert_equals(transceiver.direction, 'recvonly', >+ 'Expect transceiver to have "recvonly" direction'); >+ }) >+ .then(() => pc.createOffer(offerToReceiveTrue)) >+ .then(() => { >+ assert_equals(pc.getTransceivers().length, 1, >+ 'Expect pc to still have only one transceiver'); >+ }) >+ ; >+ }, `offerToReceive${capsKind} option should be ignored if a non-stopped "recvonly" transceiver exists`); >+ >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ >+ return getTrackFromUserMedia(kind) >+ .then(([track, stream]) => { >+ pc.addTrack(track, stream); >+ return pc.createOffer(); >+ }) >+ .then(() => { >+ assert_equals(pc.getTransceivers().length, 1, >+ 'Expect pc to have one transceiver'); >+ >+ const transceiver = pc.getTransceivers()[0]; >+ assert_equals(transceiver.direction, 'sendrecv', >+ 'Expect transceiver to have "sendrecv" direction'); >+ }) >+ .then(() => pc.createOffer(offerToReceiveTrue)) >+ .then(() => { >+ assert_equals(pc.getTransceivers().length, 1, >+ 'Expect pc to still have only one transceiver'); >+ }) >+ ; >+ }, `offerToReceive${capsKind} option should be ignored if a non-stopped "sendrecv" transceiver exists`); >+ >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ >+ return getTrackFromUserMedia(kind) >+ .then(([track, stream]) => { >+ pc.addTrack(track, stream); >+ return pc.createOffer(offerToReceiveFalse); >+ }) >+ .then(() => { >+ assert_equals(pc.getTransceivers().length, 1, >+ 'Expect pc to have one transceiver'); >+ >+ const transceiver = pc.getTransceivers()[0]; >+ assert_equals(transceiver.direction, 'sendonly', >+ 'Expect transceiver to have "sendonly" direction'); >+ }) >+ ; >+ }, `offerToReceive${capsKind} set to false with a track should create a "sendonly" transceiver`); >+ >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ >+ pc.addTransceiver(kind, {direction: 'recvonly'}); >+ >+ return pc.createOffer(offerToReceiveFalse) >+ .then(() => { >+ assert_equals(pc.getTransceivers().length, 1, >+ 'Expect pc to have one transceiver'); >+ >+ const transceiver = pc.getTransceivers()[0]; >+ assert_equals(transceiver.direction, 'inactive', >+ 'Expect transceiver to have "inactive" direction'); >+ }) >+ ; >+ }, `offerToReceive${capsKind} set to false with a "recvonly" transceiver should change the direction to "inactive"`); >+ >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ const pc2 = new RTCPeerConnection(); >+ >+ return getTrackFromUserMedia(kind) >+ .then(([track, stream]) => { >+ pc.addTrack(track, stream); >+ return pc.createOffer(); >+ }) >+ .then((offer) => pc.setLocalDescription(offer)) >+ .then(() => pc2.setRemoteDescription(pc.localDescription)) >+ .then(() => pc2.createAnswer()) >+ .then((answer) => pc2.setLocalDescription(answer)) >+ .then(() => pc.setRemoteDescription(pc2.localDescription)) >+ .then(() => pc.createOffer(offerToReceiveFalse)) >+ .then((offer) => { >+ assert_equals(pc.getTransceivers().length, 1, >+ 'Expect pc to have one transceiver'); >+ >+ const transceiver = pc.getTransceivers()[0]; >+ assert_equals(transceiver.direction, 'sendonly', >+ 'Expect transceiver to have "sendonly" direction'); >+ }) >+ ; >+ }, `subsequent offerToReceive${capsKind} set to false with a track should change the direction to "sendonly"`); >+ }); >+ >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ >+ return pc.createOffer({ offerToReceiveAudio: true, offerToReceiveVideo: true }) >+ .then(() => { >+ assert_equals(pc.getTransceivers().length, 2, >+ 'Expect pc to have two transceivers'); >+ >+ assert_equals(pc.getTransceivers()[0].direction, 'recvonly', >+ 'Expect first transceiver to have "recvonly" direction'); >+ assert_equals(pc.getTransceivers()[1].direction, 'recvonly', >+ 'Expect second transceiver to have "recvonly" direction'); >+ }); >+ }, 'offerToReceiveAudio and Video should create two "recvonly" transceivers'); >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-getIdentityAssertion.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-getIdentityAssertion.html >deleted file mode 100644 >index 2ecce8363b3869984cd8ac822e494b98205be5f8..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-getIdentityAssertion.html >+++ /dev/null >@@ -1,400 +0,0 @@ >-<!doctype html> >-<meta charset=utf-8> >-<title>RTCPeerConnection.prototype.getIdentityAssertion</title> >-<script src="/resources/testharness.js"></script> >-<script src="/resources/testharnessreport.js"></script> >-<script src="identity-helper.js"></script> >-<script> >- 'use strict'; >- >- // Test is based on the following editor draft: >- // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html >- >- // The tests here interacts with the mock identity provider located at >- // /.well-known/idp-proxy/mock-idp.js >- >- // The following helper functions are called from identity-helper.js >- // parseAssertionResult >- // getIdpDomains >- // assert_rtcerror_rejection >- // hostString >- >- /* >- 9.6. RTCPeerConnection Interface Extensions >- partial interface RTCPeerConnection { >- void setIdentityProvider(DOMString provider, >- optional RTCIdentityProviderOptions options); >- Promise<DOMString> getIdentityAssertion(); >- readonly attribute Promise<RTCIdentityAssertion> peerIdentity; >- readonly attribute DOMString? idpLoginUrl; >- readonly attribute DOMString? idpErrorInfo; >- }; >- >- dictionary RTCIdentityProviderOptions { >- DOMString protocol = "default"; >- DOMString usernameHint; >- DOMString peerIdentity; >- }; >- */ >- promise_test(() => { >- const pc = new RTCPeerConnection(); >- const port = window.location.port; >- >- const [idpDomain] = getIdpDomains(); >- const idpHost = hostString(idpDomain, port); >- >- pc.setIdentityProvider(idpHost, { >- protocol: 'mock-idp.js?foo=bar', >- usernameHint: `alice@${idpDomain}`, >- peerIdentity: 'bob@example.org' >- }); >- >- return pc.getIdentityAssertion() >- .then(assertionResultStr => { >- const { idp, assertion } = parseAssertionResult(assertionResultStr); >- >- assert_equals(idp.domain, idpHost, >- 'Expect mock-idp.js to construct domain from its location.host'); >- >- assert_equals(idp.protocol, 'mock-idp.js', >- 'Expect mock-idp.js to return protocol of itself with no query string'); >- >- const { >- watermark, >- args, >- env, >- query, >- } = assertion; >- >- assert_equals(watermark, 'mock-idp.js.watermark', >- 'Expect assertion result to contain watermark left by mock-idp.js'); >- >- assert_equals(args.origin, window.origin, >- 'Expect args.origin argument to be the origin of this window'); >- >- assert_equals(env.location, >- `https://${idpHost}/.well-known/idp-proxy/idp-test.js?foo=bar`, >- 'Expect IdP proxy to be loaded with full well-known URL constructed from provider and protocol'); >- >- assert_equals(env.origin, `https://${idpHost}`, >- 'Expect IdP to have its own origin'); >- >- assert_equals(args.options.protocol, 'idp-test.js?foo=bar', >- 'Expect options.protocol to be the same value as being passed from here'); >- >- assert_equals(args.options.usernameHint, `alice@${idpDomain}`, >- 'Expect options.usernameHint to be the same value as being passed from here'); >- >- assert_equals(args.options.peerIdentity, 'bob@example.org', >- 'Expect options.peerIdentity to be the same value as being passed from here'); >- >- assert_equals(query.foo, 'bar', >- 'Expect query string to be parsed by mock-idp.js and returned back'); >- }); >- }, 'getIdentityAssertion() should load IdP proxy and return assertion generated'); >- >- // When generating assertion, the RTCPeerConnection doesn't care if the returned assertion >- // represents identity of different domain >- promise_test(() => { >- const pc = new RTCPeerConnection(); >- const port = window.location.port; >- >- const [idpDomain1, idpDomain2] = getIdpDomains(); >- assert_not_equals(idpDomain1, idpDomain2, >- 'Sanity check two idpDomains are different'); >- >- // Ask mock-idp.js to return a custom domain idpDomain2 and custom protocol foo >- pc.setIdentityProvider(hostString(idpDomain1, port), { >- protocol: `mock-idp.js?generatorAction=return-custom-idp&domain=${idpDomain2}&protocol=foo`, >- usernameHint: `alice@${idpDomain2}`, >- }); >- >- return pc.getIdentityAssertion() >- .then(assertionResultStr => { >- const { idp, assertion } = parseAssertionResult(assertionResultStr); >- assert_equals(idp.domain, idpDomain2); >- assert_equals(idp.protocol, 'foo'); >- assert_equals(assertion.options.usernameHint, `alice@${idpDomain2}`); >- }); >- }, 'getIdentityAssertion() should succeed if mock-idp.js return different domain and protocol in assertion'); >- >- /* >- 9.3. Requesting Identity Assertions >- 4. If the IdP proxy produces an error or returns a promise that does not resolve to >- a valid RTCIdentityValidationResult (see 9.5 IdP Error Handling), then identity >- validation fails. >- >- 9.5. IdP Error Handling >- - If an identity provider throws an exception or returns a promise that is ultimately >- rejected, then the procedure that depends on the IdP MUST also fail. These types of >- errors will cause an IdP failure with an RTCError with errorDetail set to >- "idp-execution-failure". >- >- 9.6. RTCPeerConnection Interface Extensions >- idpErrorInfo >- An attribute that the IdP can use to pass additional information back to the >- applications about the error. The format of this string is defined by the IdP and >- may be JSON. >- */ >- promise_test(t => { >- const pc = new RTCPeerConnection(); >- >- assert_equals(pc.idpErrorInfo, null, >- 'Expect initial pc.idpErrorInfo to be null'); >- >- const port = window.location.port; >- const [idpDomain] = getIdpDomains(); >- >- // Ask mock-idp.js to throw an error with err.errorInfo set to bar >- pc.setIdentityProvider(hostString(idpDomain, port), { >- protocol: `mock-idp.js?generatorAction=throw-error&errorInfo=bar`, >- usernameHint: `alice@${idpDomain}`, >- }); >- >- return assert_rtcerror_rejection('idp-execution-failure', >- pc.getIdentityAssertion()) >- .then(() => { >- assert_equals(pc.idpErrorInfo, 'bar', >- 'Expect pc.idpErrorInfo to be set to the err.idpErrorInfo thrown by mock-idp.js'); >- }); >- }, `getIdentityAssertion() should reject with RTCError('idp-execution-failure') if mock-idp.js throws error`); >- >- /* >- 9.5. IdP Error Handling >- - If the script loaded from the identity provider is not valid JavaScript or does >- not implement the correct interfaces, it causes an IdP failure with an RTCError >- with errorDetail set to "idp-bad-script-failure". >- */ >- promise_test(t => { >- const pc = new RTCPeerConnection(); >- >- const port = window.location.port; >- const [idpDomain] = getIdpDomains(); >- >- // Ask mock-idp.js to not register its callback to the >- // RTCIdentityProviderRegistrar >- pc.setIdentityProvider(hostString(idpDomain, port), { >- protocol: `mock-idp.js?action=do-not-register`, >- usernameHint: `alice@${idpDomain}`, >- }); >- >- return assert_rtcerror_rejection('idp-bad-script-failure', >- pc.getIdentityAssertion()); >- >- }, `getIdentityAssertion() should reject with RTCError('idp-bad-script-failure') if IdP proxy script do not register its callback`); >- >- /* >- 9.3. Requesting Identity Assertions >- 4. If the IdP proxy produces an error or returns a promise that does not resolve >- to a valid RTCIdentityAssertionResult (see 9.5 IdP Error Handling), then assertion >- generation fails. >- */ >- promise_test(t => { >- const pc = new RTCPeerConnection(); >- >- const port = window.location.port; >- const [idpDomain] = getIdpDomains(); >- >- // Ask mock-idp.js to return an invalid result that is not proper >- // RTCIdentityAssertionResult >- pc.setIdentityProvider(hostString(idpDomain, port), { >- protocol: `mock-idp.js?generatorAction=return-invalid-result`, >- usernameHint: `alice@${idpDomain}`, >- }); >- >- return promise_rejects(t, 'OperationError', >- pc.getIdentityAssertion()); >- }, `getIdentityAssertion() should reject with OperationError if mock-idp.js return invalid result`); >- >- /* >- 9.5. IdP Error Handling >- - A RTCPeerConnection might be configured with an identity provider, but loading of >- the IdP URI fails. Any procedure that attempts to invoke such an identity provider >- and cannot load the URI fails with an RTCError with errorDetail set to >- "idp-load-failure" and the httpRequestStatusCode attribute of the error set to the >- HTTP status code of the response. >- */ >- promise_test(t => { >- const pc = new RTCPeerConnection(); >- >- pc.setIdentityProvider('nonexistent-origin.web-platform.test', { >- protocol: `non-existent`, >- usernameHint: `alice@example.org`, >- }); >- >- return assert_rtcerror_rejection('idp-load-failure', >- pc.getIdentityAssertion()); >- }, `getIdentityAssertion() should reject with RTCError('idp-load-failure') if IdP cannot be loaded`); >- >- /* >- 9.3.1. User Login Procedure >- Rejecting the promise returned by generateAssertion will cause the error to >- propagate to the application. Login errors are indicated by rejecting the >- promise with an RTCError with errorDetail set to "idp-need-login". >- >- The URL to login at will be passed to the application in the idpLoginUrl >- attribute of the RTCPeerConnection. >- >- 9.5. IdP Error Handling >- - If the identity provider requires the user to login, the operation will fail >- RTCError with errorDetail set to "idp-need-login" and the idpLoginUrl attribute >- of the error set to the URL that can be used to login. >- */ >- promise_test(t => { >- const pc = new RTCPeerConnection(); >- >- assert_equals(pc.idpLoginUrl, null, >- 'Expect initial pc.idpLoginUrl to be null'); >- >- const port = window.location.port; >- const [idpDomain] = getIdpDomains(); >- const idpHost = hostString(idpDomain, port); >- >- pc.setIdentityProvider(idpHost, { >- protocol: `mock-idp.js?generatorAction=require-login`, >- usernameHint: `alice@${idpDomain}`, >- }); >- >- return assert_rtcerror_rejection('idp-need-login', >- pc.getIdentityAssertion()) >- .then(err => { >- assert_equals(err.idpLoginUrl, `https://${idpHost}/login`, >- 'Expect err.idpLoginUrl to be set to url set by mock-idp.js'); >- >- assert_equals(pc.idpLoginUrl, `https://${idpHost}/login`, >- 'Expect pc.idpLoginUrl to be set to url set by mock-idp.js'); >- >- assert_equals(pc.idpErrorInfo, 'login required', >- 'Expect pc.idpErrorInfo to be set to info set by mock-idp.js'); >- }); >- }, `getIdentityAssertion() should reject with RTCError('idp-need-login') when mock-idp.js requires login`); >- >- /* >- RTCIdentityProviderOptions Members >- peerIdentity >- The identity of the peer. For identity providers that bind their assertions to a >- particular pair of communication peers, this allows them to generate an assertion >- that includes both local and remote identities. If this value is omitted, but a >- value is provided for the peerIdentity member of RTCConfiguration, the value from >- RTCConfiguration is used. >- */ >- promise_test(() => { >- const pc = new RTCPeerConnection({ >- peerIdentity: 'bob@example.net' >- }); >- >- const port = window.location.port; >- const [idpDomain] = getIdpDomains(); >- const idpHost = hostString(idpDomain, port); >- >- pc.setIdentityProvider(idpHost, { >- protocol: 'mock-idp.js' >- }); >- >- return pc.getIdentityAssertion() >- .then(assertionResultStr => { >- const { assertion } = parseAssertionResult(assertionResultStr); >- assert_equals(assertion.args.options.peerIdentity, 'bob@example.net'); >- }); >- }, 'setIdentityProvider() with no peerIdentity provided should use peerIdentity value from getConfiguration()'); >- >- /* >- 9.6. setIdentityProvider >- 3. If any identity provider value has changed, discard any stored identity assertion. >- */ >- promise_test(() => { >- const pc = new RTCPeerConnection(); >- const port = window.location.port; >- const [idpDomain] = getIdpDomains(); >- const idpHost = hostString(idpDomain, port); >- >- pc.setIdentityProvider(idpHost, { >- protocol: 'mock-idp.js?mark=first' >- }); >- >- return pc.getIdentityAssertion() >- .then(assertionResultStr => { >- const { assertion } = parseAssertionResult(assertionResultStr); >- assert_equals(assertion.query.mark, 'first'); >- >- pc.setIdentityProvider(idpHost, { >- protocol: 'mock-idp.js?mark=second' >- }); >- >- return pc.getIdentityAssertion(); >- }) >- .then(assertionResultStr => { >- const { assertion } = parseAssertionResult(assertionResultStr); >- assert_equals(assertion.query.mark, 'second', >- 'Expect generated assertion is from second IdP config'); >- }); >- }, `Calling setIdentityProvider() multiple times should reset identity assertions`); >- >- promise_test(t => { >- const pc = new RTCPeerConnection(); >- const port = window.location.port; >- const [idpDomain] = getIdpDomains(); >- >- pc.setIdentityProvider(hostString(idpDomain, port), { >- protocol: 'mock-idp.js', >- usernameHint: `alice@${idpDomain}` >- }); >- >- return pc.getIdentityAssertion() >- .then(assertionResultStr => >- pc.createOffer() >- .then(offer => { >- assert_true(offer.sdp.includes(`\r\na=identity:${assertionResultStr}`, >- 'Expect SDP to have a=identity line containing assertion string')); >- })); >- }, 'createOffer() should return SDP containing identity assertion string if identity provider is set'); >- >- /* >- 4.4.2. Steps to create an offer >- 1. If the need for an identity assertion was identified when createOffer was >- invoked, wait for the identity assertion request process to complete. >- 2. If the identity provider was unable to produce an identity assertion, reject p >- with a newly created NotReadableError and abort these steps. >- */ >- promise_test(t => { >- const pc = new RTCPeerConnection(); >- const port = window.location.port; >- const [idpDomain] = getIdpDomains(); >- >- pc.setIdentityProvider(hostString(idpDomain, port), { >- protocol: 'mock-idp.js?generatorAction=throw-error', >- usernameHint: `alice@${idpDomain}` >- }); >- >- return promise_rejects(t, 'NotReadableError', >- pc.createOffer()); >- }, 'createOffer() should reject with NotReadableError if identitity assertion request fails'); >- >- /* >- 4.4.2. Steps to create an answer >- 1. If the need for an identity assertion was identified when createAnswer was >- invoked, wait for the identity assertion request process to complete. >- >- 2. If the identity provider was unable to produce an identity assertion, reject p >- with a newly created NotReadableError and abort these steps. >- */ >- promise_test(t => { >- const pc = new RTCPeerConnection(); >- const port = window.location.port; >- const [idpDomain] = getIdpDomains(); >- >- pc.setIdentityProvider(hostString(idpDomain, port), { >- protocol: 'mock-idp.js?generatorAction=throw-error', >- usernameHint: `alice@${idpDomain}` >- }); >- >- return new RTCPeerConnection() >- .createOffer() >- .then(offer => pc.setRemoteDescription(offer)) >- .then(() => >- promise_rejects(t, 'NotReadableError', >- pc.createAnswer())); >- >- }, 'createAnswer() should reject with NotReadableError if identitity assertion request fails'); >- >-</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-getIdentityAssertion.sub-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-getIdentityAssertion.sub-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..11d948aadfa16267749df7ed524d6804463d934e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-getIdentityAssertion.sub-expected.txt >@@ -0,0 +1,24 @@ >+ >+FAIL getIdentityAssertion() should load IdP proxy and return assertion generated undefined is not a function (near '...pc.setIdentityProvider...') >+FAIL getIdentityAssertion() should succeed if mock-idp.js return different domain and protocol in assertion undefined is not a function (near '...pc.setIdentityProvider...') >+FAIL getIdentityAssertion() should reject with RTCError('idp-execution-failure') if mock-idp.js throws error assert_equals: Expect initial pc.idpErrorInfo to be null expected (object) null but got (undefined) undefined >+FAIL getIdentityAssertion() should reject with RTCError('idp-bad-script-failure') if IdP proxy script do not register its callback undefined is not a function (near '...pc.setIdentityProvider...') >+FAIL getIdentityAssertion() should reject with OperationError if mock-idp.js return invalid result undefined is not a function (near '...pc.setIdentityProvider...') >+FAIL getIdentityAssertion() should reject with RTCError('idp-load-failure') if IdP cannot be loaded pc.setIdentityProvider is not a function. (In 'pc.setIdentityProvider('nonexistent.localhost', { >+ protocol: `non-existent`, >+ usernameHint: `alice@example.org`, >+ })', 'pc.setIdentityProvider' is undefined) >+FAIL getIdentityAssertion() should reject with RTCError('idp-need-login') when mock-idp.js requires login assert_equals: Expect initial pc.idpLoginUrl to be null expected (object) null but got (undefined) undefined >+FAIL setIdentityProvider() with no peerIdentity provided should use peerIdentity value from getConfiguration() pc.setIdentityProvider is not a function. (In 'pc.setIdentityProvider(idpHost, { >+ protocol: 'mock-idp.js' >+ })', 'pc.setIdentityProvider' is undefined) >+FAIL Calling setIdentityProvider() multiple times should reset identity assertions pc.setIdentityProvider is not a function. (In 'pc.setIdentityProvider(idpHost, { >+ protocol: 'mock-idp.js?mark=first' >+ })', 'pc.setIdentityProvider' is undefined) >+FAIL createOffer() should return SDP containing identity assertion string if identity provider is set pc.setIdentityProvider is not a function. (In 'pc.setIdentityProvider(hostString(idpDomain, port), { >+ protocol: 'mock-idp.js', >+ usernameHint: `alice@${idpDomain}` >+ })', 'pc.setIdentityProvider' is undefined) >+FAIL createOffer() should reject with NotReadableError if identitity assertion request fails undefined is not a function (near '...pc.setIdentityProvider...') >+FAIL createAnswer() should reject with NotReadableError if identitity assertion request fails undefined is not a function (near '...pc.setIdentityProvider...') >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-getIdentityAssertion.sub.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-getIdentityAssertion.sub.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2bd860d901ded78c9635da65413ac63e7dbf4460 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-getIdentityAssertion.sub.html >@@ -0,0 +1,400 @@ >+<!doctype html> >+<meta charset=utf-8> >+<title>RTCPeerConnection.prototype.getIdentityAssertion</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="identity-helper.sub.js"></script> >+<script> >+ 'use strict'; >+ >+ // Test is based on the following editor draft: >+ // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html >+ >+ // The tests here interacts with the mock identity provider located at >+ // /.well-known/idp-proxy/mock-idp.js >+ >+ // The following helper functions are called from identity-helper.sub.js >+ // parseAssertionResult >+ // getIdpDomains >+ // assert_rtcerror_rejection >+ // hostString >+ >+ /* >+ 9.6. RTCPeerConnection Interface Extensions >+ partial interface RTCPeerConnection { >+ void setIdentityProvider(DOMString provider, >+ optional RTCIdentityProviderOptions options); >+ Promise<DOMString> getIdentityAssertion(); >+ readonly attribute Promise<RTCIdentityAssertion> peerIdentity; >+ readonly attribute DOMString? idpLoginUrl; >+ readonly attribute DOMString? idpErrorInfo; >+ }; >+ >+ dictionary RTCIdentityProviderOptions { >+ DOMString protocol = "default"; >+ DOMString usernameHint; >+ DOMString peerIdentity; >+ }; >+ */ >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ const port = window.location.port; >+ >+ const [idpDomain] = getIdpDomains(); >+ const idpHost = hostString(idpDomain, port); >+ >+ pc.setIdentityProvider(idpHost, { >+ protocol: 'mock-idp.js?foo=bar', >+ usernameHint: `alice@${idpDomain}`, >+ peerIdentity: 'bob@example.org' >+ }); >+ >+ return pc.getIdentityAssertion() >+ .then(assertionResultStr => { >+ const { idp, assertion } = parseAssertionResult(assertionResultStr); >+ >+ assert_equals(idp.domain, idpHost, >+ 'Expect mock-idp.js to construct domain from its location.host'); >+ >+ assert_equals(idp.protocol, 'mock-idp.js', >+ 'Expect mock-idp.js to return protocol of itself with no query string'); >+ >+ const { >+ watermark, >+ args, >+ env, >+ query, >+ } = assertion; >+ >+ assert_equals(watermark, 'mock-idp.js.watermark', >+ 'Expect assertion result to contain watermark left by mock-idp.js'); >+ >+ assert_equals(args.origin, window.origin, >+ 'Expect args.origin argument to be the origin of this window'); >+ >+ assert_equals(env.location, >+ `https://${idpHost}/.well-known/idp-proxy/idp-test.js?foo=bar`, >+ 'Expect IdP proxy to be loaded with full well-known URL constructed from provider and protocol'); >+ >+ assert_equals(env.origin, `https://${idpHost}`, >+ 'Expect IdP to have its own origin'); >+ >+ assert_equals(args.options.protocol, 'idp-test.js?foo=bar', >+ 'Expect options.protocol to be the same value as being passed from here'); >+ >+ assert_equals(args.options.usernameHint, `alice@${idpDomain}`, >+ 'Expect options.usernameHint to be the same value as being passed from here'); >+ >+ assert_equals(args.options.peerIdentity, 'bob@example.org', >+ 'Expect options.peerIdentity to be the same value as being passed from here'); >+ >+ assert_equals(query.foo, 'bar', >+ 'Expect query string to be parsed by mock-idp.js and returned back'); >+ }); >+ }, 'getIdentityAssertion() should load IdP proxy and return assertion generated'); >+ >+ // When generating assertion, the RTCPeerConnection doesn't care if the returned assertion >+ // represents identity of different domain >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ const port = window.location.port; >+ >+ const [idpDomain1, idpDomain2] = getIdpDomains(); >+ assert_not_equals(idpDomain1, idpDomain2, >+ 'Sanity check two idpDomains are different'); >+ >+ // Ask mock-idp.js to return a custom domain idpDomain2 and custom protocol foo >+ pc.setIdentityProvider(hostString(idpDomain1, port), { >+ protocol: `mock-idp.js?generatorAction=return-custom-idp&domain=${idpDomain2}&protocol=foo`, >+ usernameHint: `alice@${idpDomain2}`, >+ }); >+ >+ return pc.getIdentityAssertion() >+ .then(assertionResultStr => { >+ const { idp, assertion } = parseAssertionResult(assertionResultStr); >+ assert_equals(idp.domain, idpDomain2); >+ assert_equals(idp.protocol, 'foo'); >+ assert_equals(assertion.options.usernameHint, `alice@${idpDomain2}`); >+ }); >+ }, 'getIdentityAssertion() should succeed if mock-idp.js return different domain and protocol in assertion'); >+ >+ /* >+ 9.3. Requesting Identity Assertions >+ 4. If the IdP proxy produces an error or returns a promise that does not resolve to >+ a valid RTCIdentityValidationResult (see 9.5 IdP Error Handling), then identity >+ validation fails. >+ >+ 9.5. IdP Error Handling >+ - If an identity provider throws an exception or returns a promise that is ultimately >+ rejected, then the procedure that depends on the IdP MUST also fail. These types of >+ errors will cause an IdP failure with an RTCError with errorDetail set to >+ "idp-execution-failure". >+ >+ 9.6. RTCPeerConnection Interface Extensions >+ idpErrorInfo >+ An attribute that the IdP can use to pass additional information back to the >+ applications about the error. The format of this string is defined by the IdP and >+ may be JSON. >+ */ >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ >+ assert_equals(pc.idpErrorInfo, null, >+ 'Expect initial pc.idpErrorInfo to be null'); >+ >+ const port = window.location.port; >+ const [idpDomain] = getIdpDomains(); >+ >+ // Ask mock-idp.js to throw an error with err.errorInfo set to bar >+ pc.setIdentityProvider(hostString(idpDomain, port), { >+ protocol: `mock-idp.js?generatorAction=throw-error&errorInfo=bar`, >+ usernameHint: `alice@${idpDomain}`, >+ }); >+ >+ return assert_rtcerror_rejection('idp-execution-failure', >+ pc.getIdentityAssertion()) >+ .then(() => { >+ assert_equals(pc.idpErrorInfo, 'bar', >+ 'Expect pc.idpErrorInfo to be set to the err.idpErrorInfo thrown by mock-idp.js'); >+ }); >+ }, `getIdentityAssertion() should reject with RTCError('idp-execution-failure') if mock-idp.js throws error`); >+ >+ /* >+ 9.5. IdP Error Handling >+ - If the script loaded from the identity provider is not valid JavaScript or does >+ not implement the correct interfaces, it causes an IdP failure with an RTCError >+ with errorDetail set to "idp-bad-script-failure". >+ */ >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ >+ const port = window.location.port; >+ const [idpDomain] = getIdpDomains(); >+ >+ // Ask mock-idp.js to not register its callback to the >+ // RTCIdentityProviderRegistrar >+ pc.setIdentityProvider(hostString(idpDomain, port), { >+ protocol: `mock-idp.js?action=do-not-register`, >+ usernameHint: `alice@${idpDomain}`, >+ }); >+ >+ return assert_rtcerror_rejection('idp-bad-script-failure', >+ pc.getIdentityAssertion()); >+ >+ }, `getIdentityAssertion() should reject with RTCError('idp-bad-script-failure') if IdP proxy script do not register its callback`); >+ >+ /* >+ 9.3. Requesting Identity Assertions >+ 4. If the IdP proxy produces an error or returns a promise that does not resolve >+ to a valid RTCIdentityAssertionResult (see 9.5 IdP Error Handling), then assertion >+ generation fails. >+ */ >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ >+ const port = window.location.port; >+ const [idpDomain] = getIdpDomains(); >+ >+ // Ask mock-idp.js to return an invalid result that is not proper >+ // RTCIdentityAssertionResult >+ pc.setIdentityProvider(hostString(idpDomain, port), { >+ protocol: `mock-idp.js?generatorAction=return-invalid-result`, >+ usernameHint: `alice@${idpDomain}`, >+ }); >+ >+ return promise_rejects(t, 'OperationError', >+ pc.getIdentityAssertion()); >+ }, `getIdentityAssertion() should reject with OperationError if mock-idp.js return invalid result`); >+ >+ /* >+ 9.5. IdP Error Handling >+ - A RTCPeerConnection might be configured with an identity provider, but loading of >+ the IdP URI fails. Any procedure that attempts to invoke such an identity provider >+ and cannot load the URI fails with an RTCError with errorDetail set to >+ "idp-load-failure" and the httpRequestStatusCode attribute of the error set to the >+ HTTP status code of the response. >+ */ >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ >+ pc.setIdentityProvider('nonexistent.{{domains[]}}', { >+ protocol: `non-existent`, >+ usernameHint: `alice@example.org`, >+ }); >+ >+ return assert_rtcerror_rejection('idp-load-failure', >+ pc.getIdentityAssertion()); >+ }, `getIdentityAssertion() should reject with RTCError('idp-load-failure') if IdP cannot be loaded`); >+ >+ /* >+ 9.3.1. User Login Procedure >+ Rejecting the promise returned by generateAssertion will cause the error to >+ propagate to the application. Login errors are indicated by rejecting the >+ promise with an RTCError with errorDetail set to "idp-need-login". >+ >+ The URL to login at will be passed to the application in the idpLoginUrl >+ attribute of the RTCPeerConnection. >+ >+ 9.5. IdP Error Handling >+ - If the identity provider requires the user to login, the operation will fail >+ RTCError with errorDetail set to "idp-need-login" and the idpLoginUrl attribute >+ of the error set to the URL that can be used to login. >+ */ >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ >+ assert_equals(pc.idpLoginUrl, null, >+ 'Expect initial pc.idpLoginUrl to be null'); >+ >+ const port = window.location.port; >+ const [idpDomain] = getIdpDomains(); >+ const idpHost = hostString(idpDomain, port); >+ >+ pc.setIdentityProvider(idpHost, { >+ protocol: `mock-idp.js?generatorAction=require-login`, >+ usernameHint: `alice@${idpDomain}`, >+ }); >+ >+ return assert_rtcerror_rejection('idp-need-login', >+ pc.getIdentityAssertion()) >+ .then(err => { >+ assert_equals(err.idpLoginUrl, `https://${idpHost}/login`, >+ 'Expect err.idpLoginUrl to be set to url set by mock-idp.js'); >+ >+ assert_equals(pc.idpLoginUrl, `https://${idpHost}/login`, >+ 'Expect pc.idpLoginUrl to be set to url set by mock-idp.js'); >+ >+ assert_equals(pc.idpErrorInfo, 'login required', >+ 'Expect pc.idpErrorInfo to be set to info set by mock-idp.js'); >+ }); >+ }, `getIdentityAssertion() should reject with RTCError('idp-need-login') when mock-idp.js requires login`); >+ >+ /* >+ RTCIdentityProviderOptions Members >+ peerIdentity >+ The identity of the peer. For identity providers that bind their assertions to a >+ particular pair of communication peers, this allows them to generate an assertion >+ that includes both local and remote identities. If this value is omitted, but a >+ value is provided for the peerIdentity member of RTCConfiguration, the value from >+ RTCConfiguration is used. >+ */ >+ promise_test(t => { >+ const pc = new RTCPeerConnection({ >+ peerIdentity: 'bob@example.net' >+ }); >+ >+ const port = window.location.port; >+ const [idpDomain] = getIdpDomains(); >+ const idpHost = hostString(idpDomain, port); >+ >+ pc.setIdentityProvider(idpHost, { >+ protocol: 'mock-idp.js' >+ }); >+ >+ return pc.getIdentityAssertion() >+ .then(assertionResultStr => { >+ const { assertion } = parseAssertionResult(assertionResultStr); >+ assert_equals(assertion.args.options.peerIdentity, 'bob@example.net'); >+ }); >+ }, 'setIdentityProvider() with no peerIdentity provided should use peerIdentity value from getConfiguration()'); >+ >+ /* >+ 9.6. setIdentityProvider >+ 3. If any identity provider value has changed, discard any stored identity assertion. >+ */ >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ const port = window.location.port; >+ const [idpDomain] = getIdpDomains(); >+ const idpHost = hostString(idpDomain, port); >+ >+ pc.setIdentityProvider(idpHost, { >+ protocol: 'mock-idp.js?mark=first' >+ }); >+ >+ return pc.getIdentityAssertion() >+ .then(assertionResultStr => { >+ const { assertion } = parseAssertionResult(assertionResultStr); >+ assert_equals(assertion.query.mark, 'first'); >+ >+ pc.setIdentityProvider(idpHost, { >+ protocol: 'mock-idp.js?mark=second' >+ }); >+ >+ return pc.getIdentityAssertion(); >+ }) >+ .then(assertionResultStr => { >+ const { assertion } = parseAssertionResult(assertionResultStr); >+ assert_equals(assertion.query.mark, 'second', >+ 'Expect generated assertion is from second IdP config'); >+ }); >+ }, `Calling setIdentityProvider() multiple times should reset identity assertions`); >+ >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ const port = window.location.port; >+ const [idpDomain] = getIdpDomains(); >+ >+ pc.setIdentityProvider(hostString(idpDomain, port), { >+ protocol: 'mock-idp.js', >+ usernameHint: `alice@${idpDomain}` >+ }); >+ >+ return pc.getIdentityAssertion() >+ .then(assertionResultStr => >+ pc.createOffer() >+ .then(offer => { >+ assert_true(offer.sdp.includes(`\r\na=identity:${assertionResultStr}`, >+ 'Expect SDP to have a=identity line containing assertion string')); >+ })); >+ }, 'createOffer() should return SDP containing identity assertion string if identity provider is set'); >+ >+ /* >+ 4.4.2. Steps to create an offer >+ 1. If the need for an identity assertion was identified when createOffer was >+ invoked, wait for the identity assertion request process to complete. >+ 2. If the identity provider was unable to produce an identity assertion, reject p >+ with a newly created NotReadableError and abort these steps. >+ */ >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ const port = window.location.port; >+ const [idpDomain] = getIdpDomains(); >+ >+ pc.setIdentityProvider(hostString(idpDomain, port), { >+ protocol: 'mock-idp.js?generatorAction=throw-error', >+ usernameHint: `alice@${idpDomain}` >+ }); >+ >+ return promise_rejects(t, 'NotReadableError', >+ pc.createOffer()); >+ }, 'createOffer() should reject with NotReadableError if identitity assertion request fails'); >+ >+ /* >+ 4.4.2. Steps to create an answer >+ 1. If the need for an identity assertion was identified when createAnswer was >+ invoked, wait for the identity assertion request process to complete. >+ >+ 2. If the identity provider was unable to produce an identity assertion, reject p >+ with a newly created NotReadableError and abort these steps. >+ */ >+ promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ const port = window.location.port; >+ const [idpDomain] = getIdpDomains(); >+ >+ pc.setIdentityProvider(hostString(idpDomain, port), { >+ protocol: 'mock-idp.js?generatorAction=throw-error', >+ usernameHint: `alice@${idpDomain}` >+ }); >+ >+ return new RTCPeerConnection() >+ .createOffer() >+ .then(offer => pc.setRemoteDescription(offer)) >+ .then(() => >+ promise_rejects(t, 'NotReadableError', >+ pc.createAnswer())); >+ >+ }, 'createAnswer() should reject with NotReadableError if identitity assertion request fails'); >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-getStats.https.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-getStats.https.html >index 73138507d4f12a2fc9385a27909fd1a69be622ae..ac69ee5e28dff16f9a9175c19cb691cca5878c89 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-getStats.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-getStats.https.html >@@ -39,12 +39,12 @@ > 1. Gather the stats indicated by selector according to the stats selection algorithm. > 2. Resolve p with the resulting RTCStatsReport object, containing the gathered stats. > */ >- promise_test(() => { >+ promise_test(t => { > const pc = new RTCPeerConnection(); > return pc.getStats(); > }, 'getStats() with no argument should succeed'); > >- promise_test(() => { >+ promise_test(t => { > const pc = new RTCPeerConnection(); > return pc.getStats(null); > }, 'getStats(null) should succeed'); >@@ -160,7 +160,7 @@ > - All stats objects referenced directly or indirectly by the RTCOutboundRTPStreamStats > objects added. > */ >- promise_test(() => { >+ promise_test(t => { > const pc = new RTCPeerConnection(); > return getTrackFromUserMedia('audio') > .then(([track, mediaStream]) => { >@@ -183,7 +183,7 @@ > - All stats objects referenced directly or indirectly by the RTCInboundRTPStreamStats > added. > */ >- promise_test(() => { >+ promise_test(t => { > const pc = new RTCPeerConnection(); > const transceiver = pc.addTransceiver('audio'); > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-helper.js b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-helper.js >index 8ccebbd867f05a2679da5d1641bd88f496db0fa6..34e0d75903c68d100627c5b41302db2212365a98 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-helper.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-helper.js >@@ -229,7 +229,7 @@ function exchangeIceCandidates(pc1, pc2) { > // There is ongoing discussion on w3c/webrtc-pc#1213 > // that there should be an empty candidate string event > // for end of candidate for each m= section. >- if(candidate) { >+ if(candidate && remotePc.signalingState !== 'closed') { > remotePc.addIceCandidate(candidate); > } > }); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-peerIdentity.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-peerIdentity.html >index d5f9db9d5d0887b70b7b2babd49a5bbadad07856..68d9f209a9e3884e1767fcade5eafedc686defba 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-peerIdentity.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-peerIdentity.html >@@ -3,7 +3,7 @@ > <title>RTCPeerConnection.prototype.peerIdentity</title> > <script src="/resources/testharness.js"></script> > <script src="/resources/testharnessreport.js"></script> >-<script src="identity-helper.js"></script> >+<script src="identity-helper.sub.js"></script> > <script> > 'use strict'; > >@@ -13,7 +13,7 @@ > // The tests here interacts with the mock identity provider located at > // /.well-known/idp-proxy/mock-idp.js > >- // The following helper functions are called from identity-helper.js >+ // The following helper functions are called from identity-helper.sub.js > // parseAssertionResult > // getIdpDomains > // assert_rtcerror_rejection >@@ -54,7 +54,7 @@ > is, there is a current value for peerIdentity ), then this also establishes a > target peer identity. > */ >- promise_test(() => { >+ promise_test(t => { > const pc1 = new RTCPeerConnection(); > const pc2 = new RTCPeerConnection(); > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setDescription-transceiver-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setDescription-transceiver-expected.txt >index 897129a16eae3af755ca5bcb8c41688848b312c8..c07e4ca07f5fb9c375e4b346a4827a596da61828 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setDescription-transceiver-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setDescription-transceiver-expected.txt >@@ -1,6 +1,6 @@ > > FAIL setLocalDescription(offer) with m= section should assign mid to corresponding transceiver assert_equals: Expect transceiver.mid to set to valid string value expected "string" but got "object" >-FAIL setRemoteDescription(offer) with m= section and no existing transceiver should create corresponding transceiver promise_test: Unhandled rejection with value: object "TypeError: pc2.setRemoteDescrption is not a function. (In 'pc2.setRemoteDescrption(offer)', 'pc2.setRemoteDescrption' is undefined)" >+FAIL setRemoteDescription(offer) with m= section and no existing transceiver should create corresponding transceiver assert_equals: Expect new transceiver added to pc2 after setRemoteDescription expected 1 but got 0 > FAIL setLocalDescription(rollback) should unset transceiver.mid assert_not_equals: got disallowed value null > FAIL setLocalDescription(rollback) should only unset transceiver mids associated with current round assert_not_equals: got disallowed value null > FAIL setRemoteDescription(rollback) should remove newly created transceiver from transceiver list assert_equals: expected 1 but got 0 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setDescription-transceiver.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setDescription-transceiver.html >index ed41d66319e14a54287ed6ec3726ecb667ef8d84..d19b4747df1d57a9b94b89ec8ec7533f1a51973e 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setDescription-transceiver.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setDescription-transceiver.html >@@ -64,7 +64,7 @@ > 2. Set transceiver's mid value to the mid of the corresponding media > description. > */ >- promise_test(() => { >+ promise_test(t => { > const pc = new RTCPeerConnection(); > const transceiver = pc.addTransceiver('audio'); > assert_equals(transceiver.mid, null); >@@ -97,7 +97,7 @@ > transceiver be the result. > 3. Set transceiver's mid value to the mid of the corresponding media description. > */ >- promise_test(() => { >+ promise_test(t => { > const pc1 = new RTCPeerConnection(); > const pc2 = new RTCPeerConnection(); > >@@ -109,7 +109,7 @@ > .then(offer => { > return Promise.all([ > pc1.setLocalDescription(offer), >- pc2.setRemoteDescrption(offer) >+ pc2.setRemoteDescription(offer) > ]) > .then(() => { > const transceivers = pc2.getTransceivers(); >@@ -137,7 +137,7 @@ > the RTCSessionDescription that is being rolled back, set the mid value > of that transceiver to null, as described by [JSEP] (section 4.1.8.2.). > */ >- promise_test(() => { >+ promise_test(t => { > const pc = new RTCPeerConnection(); > const transceiver = pc.addTransceiver('audio'); > assert_equals(transceiver.mid, null); >@@ -157,7 +157,7 @@ > }); > }, 'setLocalDescription(rollback) should unset transceiver.mid'); > >- promise_test(() => { >+ promise_test(t => { > const pc = new RTCPeerConnection(); > const transceiver1 = pc.addTransceiver('audio'); > assert_equals(transceiver1.mid, null); >@@ -202,7 +202,7 @@ > addTrack, remove that transceiver from connection's set of transceivers, > as described by [JSEP] (section 4.1.8.2.). > */ >- promise_test(() => { >+ promise_test(t => { > const pc1 = new RTCPeerConnection(); > const pc2 = new RTCPeerConnection(); > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-expected.txt >index c2d9dd199bffbcf9160d6ccb8d943c01e0f1827f..0454993c49f8b780673eec7f345b0deb040f31c1 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-expected.txt >@@ -1,8 +1,7 @@ > > PASS setRemoteDescription with invalid type and invalid SDP should reject with TypeError > PASS setRemoteDescription() with invalid SDP and stable state should reject with InvalidStateError >+PASS Negotiation should fire signalingsstate events > FAIL Calling setRemoteDescription() again after one round of remote-offer/local-answer should succeed assert_false: Expect both session descriptions to have different count of media lines expected false got true > PASS Switching role from offerer to answerer after going back to stable state should succeed >-PASS Test onsignalingstatechange event for Calling setRemoteDescription() again after one round of remote-offer/local-answer should succeed >-PASS Test onsignalingstatechange event for Switching role from offerer to answerer after going back to stable state should succeed > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-replaceTrack.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-replaceTrack.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..603a73b6aaec9eba7c64a62a27d7e31a5a32802c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-replaceTrack.https-expected.txt >@@ -0,0 +1,8 @@ >+ >+PASS replaceTrack() sets the track attribute to a new track. >+PASS replaceTrack() sets the track attribute to null. >+PASS replaceTrack() does not set the track synchronously. >+PASS replaceTrack() rejects when the peer connection is closed. >+FAIL replaceTrack() rejects when invoked after removeTrack(). assert_equals: expected "InvalidModificationError" but got "InvalidStateError" >+FAIL replaceTrack() rejects after a subsequent removeTrack(). assert_unreached: Expected replaceTrack() to be rejected with InvalidModificationError but the promise was resolved. Reached unreachable code >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-replaceTrack.https.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-replaceTrack.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..06408d072afda8acc9790b8fc152e16561cf780f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-replaceTrack.https.html >@@ -0,0 +1,139 @@ >+<!doctype html> >+<meta charset=utf-8> >+<title>RTCPeerConnection.prototype.setRemoteDescription - replaceTrack</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="RTCPeerConnection-helper.js"></script> >+<script> >+ 'use strict'; >+ >+ // The following helper functions are called from RTCPeerConnection-helper.js: >+ // getUserMediaTracksAndStreams >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ return getUserMediaTracksAndStreams(2) >+ .then(t.step_func(([tracks, streams]) => { >+ const sender = caller.addTrack(tracks[0], streams[0]); >+ return sender.replaceTrack(tracks[1]) >+ .then(t.step_func(() => { >+ assert_equals(sender.track, tracks[1]); >+ t.done(); >+ })); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'replaceTrack() sets the track attribute to a new track.'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ const sender = caller.addTrack(tracks[0], streams[0]); >+ return sender.replaceTrack(null) >+ .then(t.step_func(() => { >+ assert_equals(sender.track, null); >+ t.done(); >+ })); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'replaceTrack() sets the track attribute to null.'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ return getUserMediaTracksAndStreams(2) >+ .then(t.step_func(([tracks, streams]) => { >+ const sender = caller.addTrack(tracks[0], streams[0]); >+ assert_equals(sender.track, tracks[0]); >+ sender.replaceTrack(tracks[1]); >+ // replaceTrack() is asynchronous, there should be no synchronously >+ // observable effects. >+ assert_equals(sender.track, tracks[0]); >+ t.done(); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'replaceTrack() does not set the track synchronously.'); >+ >+ async_test(t => { >+ const expectedException = 'InvalidStateError'; >+ const caller = new RTCPeerConnection(); >+ return getUserMediaTracksAndStreams(2) >+ .then(t.step_func(([tracks, streams]) => { >+ const sender = caller.addTrack(tracks[0], streams[0]); >+ caller.close(); >+ return sender.replaceTrack(tracks[1]) >+ .then(t.step_func(() => { >+ assert_unreached('Expected replaceTrack() to be rejected with ' + >+ expectedException + ' but the promise was resolved.'); >+ }), >+ t.step_func(e => { >+ assert_equals(e.name, expectedException); >+ t.done(); >+ })); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'replaceTrack() rejects when the peer connection is closed.'); >+ >+ async_test(t => { >+ const expectedException = 'InvalidModificationError'; >+ const caller = new RTCPeerConnection(); >+ return getUserMediaTracksAndStreams(2) >+ .then(t.step_func(([tracks, streams]) => { >+ const sender = caller.addTrack(tracks[0], streams[0]); >+ caller.removeTrack(sender); >+ // replaceTrack() should fail because the sender should be inactive after >+ // removeTrack(). >+ return sender.replaceTrack(tracks[1]) >+ .then(t.step_func(() => { >+ assert_unreached('Expected replaceTrack() to be rejected with ' + >+ expectedException + ' but the promise was resolved.'); >+ }), >+ t.step_func(e => { >+ assert_equals(e.name, expectedException); >+ t.done(); >+ })); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'replaceTrack() rejects when invoked after removeTrack().'); >+ >+ async_test(t => { >+ const expectedException = 'InvalidModificationError'; >+ const caller = new RTCPeerConnection(); >+ return getUserMediaTracksAndStreams(2) >+ .then(t.step_func(([tracks, streams]) => { >+ const sender = caller.addTrack(tracks[0], streams[0]); >+ let p = sender.replaceTrack(tracks[1]) >+ caller.removeTrack(sender); >+ // replaceTrack() should fail because it executes steps in parallel and >+ // queues a task to execute after removeTrack() has occurred. The sender >+ // should be inactive. If this can be racy, update or remove the test. >+ // https://github.com/w3c/webrtc-pc/issues/1728 >+ return p.then(t.step_func(() => { >+ assert_unreached('Expected replaceTrack() to be rejected with ' + >+ expectedException + ' but the promise was resolved.'); >+ }), >+ t.step_func(e => { >+ assert_equals(e.name, expectedException); >+ t.done(); >+ })); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'replaceTrack() rejects after a subsequent removeTrack().'); >+ >+ // TODO(hbos): Verify that replaceTrack() changes what media is received on >+ // the remote end of two connected peer connections. For video tracks, this >+ // requires Chromium's video tag to update on receiving frames when running >+ // content_shell. https://crbug.com/793808 >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..323487aa0b551253444ee85ea6f62a63b5b876d9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https-expected.txt >@@ -0,0 +1,18 @@ >+ >+Harness Error (TIMEOUT), message = null >+ >+FAIL addTrack() with a track and no stream makes ontrack fire with a track and no stream. assert_equals: Expected remote track not to belong to a stream. expected 0 but got 1 >+PASS addTrack() with a track and a stream makes ontrack fire with a track and a stream. >+PASS ontrack fires before setRemoteDescription resolves. >+FAIL addTrack() with two tracks and one stream makes ontrack fire twice with the tracks and shared stream. assert_equals: Expected the remote stream to contain two tracks. expected 2 but got 1 >+PASS addTrack() for an existing stream makes stream.onaddtrack fire. >+PASS stream.onaddtrack fires before setRemoteDescription resolves. >+FAIL addTrack() with a track and two streams makes ontrack fire with a track and two streams. Cannot access uninitialized variable. >+PASS ontrack's receiver matches getReceivers(). >+PASS removeTrack() does not remove the receiver. >+TIMEOUT removeTrack() makes stream.onremovetrack fire and the track to be removed from the stream. Test timed out >+TIMEOUT stream.onremovetrack fires before setRemoteDescription resolves. Test timed out >+TIMEOUT removeTrack() makes track.onmute fire and the track to be muted. Test timed out >+TIMEOUT track.onmute fires before setRemoteDescription resolves. Test timed out >+PASS removeTrack() twice is safe. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d4663e5373be5445a0f207dc9bf2fb498426ff70 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html >@@ -0,0 +1,426 @@ >+<!doctype html> >+<meta charset=utf-8> >+<title>RTCPeerConnection.prototype.setRemoteDescription - add/remove remote tracks</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="RTCPeerConnection-helper.js"></script> >+<script> >+ 'use strict'; >+ >+ // Test is based on the following editor draft: >+ // https://w3c.github.io/webrtc-pc/archives/20171002/webrtc.html >+ >+ // The following helper functions are called from RTCPeerConnection-helper.js: >+ // getUserMediaTracksAndStreams >+ // performOffer >+ // Resolver >+ >+ // These tests are concerned with the observable consequences of processing >+ // the addition or removal of remote tracks, including events firing and the >+ // states of RTCPeerConnection, MediaStream and MediaStreamTrack. >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ const localTrack = tracks[0]; >+ caller.addTrack(localTrack); >+ const offerPromise = performOffer(caller, callee); >+ callee.ontrack = t.step_func(trackEvent => { >+ const remoteTrack = trackEvent.track; >+ assert_equals(remoteTrack.id, localTrack.id, >+ 'Expected local and remote track IDs to match.'); >+ assert_equals(trackEvent.streams.length, 0, >+ 'Expected remote track not to belong to a stream.'); >+ t.done(); >+ }); >+ return offerPromise; >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'addTrack() with a track and no stream makes ontrack fire with a track and no stream.'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ const localTrack = tracks[0]; >+ const localStream = streams[0]; >+ caller.addTrack(localTrack, localStream); >+ const offerPromise = performOffer(caller, callee); >+ callee.ontrack = t.step_func(trackEvent => { >+ assert_equals(trackEvent.streams.length, 1, >+ 'Expected track event to fire with a single stream.'); >+ const remoteTrack = trackEvent.track; >+ const remoteStream = trackEvent.streams[0]; >+ assert_equals(remoteTrack.id, localTrack.id, >+ 'Expected local and remote track IDs to match.'); >+ assert_equals(remoteStream.id, localStream.id, >+ 'Expected local and remote stream IDs to match.'); >+ assert_array_equals(remoteStream.getTracks(), [remoteTrack], >+ 'Expected the remote stream\'s tracks to be the remote track.'); >+ t.done(); >+ }); >+ return offerPromise; >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'addTrack() with a track and a stream makes ontrack fire with a track and a stream.'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ let eventSequence = ''; >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ const ontrackResolver = new Resolver(); >+ callee.ontrack = () => { >+ eventSequence += 'ontrack;'; >+ ontrackResolver.resolve(); >+ } >+ caller.addTrack(tracks[0]); >+ return Promise.all([ >+ ontrackResolver.promise, >+ performOffer(caller, callee).then(() => { >+ eventSequence += 'setRemoteDescription;'; >+ }) >+ ]); >+ })) >+ .then(t.step_func(() => { >+ assert_equals(eventSequence, 'ontrack;setRemoteDescription;'); >+ t.done(); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'ontrack fires before setRemoteDescription resolves.'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ return getUserMediaTracksAndStreams(2) >+ .then(t.step_func(([tracks, streams]) => { >+ const localTrack1 = tracks[0]; >+ const localTrack2 = tracks[1]; >+ const localStream = streams[0]; >+ caller.addTrack(localTrack1, localStream); >+ caller.addTrack(localTrack2, localStream); >+ const offerPromise = performOffer(caller, callee); >+ callee.ontrack = t.step_func(trackEvent => { >+ assert_equals(trackEvent.streams.length, 1, >+ 'Expected track event to fire with a single stream.'); >+ const remoteTrack1 = trackEvent.track; >+ const remoteStream = trackEvent.streams[0]; >+ assert_equals(remoteTrack1.id, localTrack1.id, >+ 'Expected first remote track ID to match first local track ID.'); >+ assert_equals(remoteStream.getTracks().length, 2, >+ 'Expected the remote stream to contain two tracks.'); >+ callee.ontrack = t.step_func(trackEvent => { >+ assert_equals(trackEvent.streams.length, 1, >+ 'Expected track event to fire with a single stream.'); >+ const remoteTrack2 = trackEvent.track; >+ assert_equals(trackEvent.streams[0], remoteStream, >+ 'Expected both track events to fire with the same remote stream.'); >+ assert_equals(remoteTrack2.id, localTrack2.id, >+ 'Expected second remote track ID to match second local track ID.'); >+ assert_equals(remoteStream.getTracks().length, 2, >+ 'Expected the remote stream to contain two tracks.'); >+ assert_array_equals(remoteStream.getTracks(), [remoteTrack1, remoteTrack2], >+ 'Expected the remote stream\'s tracks to be the [first, second] remote tracks.'); >+ t.done(); >+ }); >+ }); >+ return offerPromise; >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'addTrack() with two tracks and one stream makes ontrack fire twice with the tracks and shared stream.'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ return getUserMediaTracksAndStreams(2) >+ .then(t.step_func(([tracks, streams]) => { >+ const localTracks = tracks; >+ const localStream = streams[0]; >+ caller.addTrack(localTracks[0], localStream); >+ const offerPromise = performOffer(caller, callee); >+ callee.ontrack = t.step_func(trackEvent => { >+ assert_equals(trackEvent.streams.length, 1, >+ 'Expected track event to fire with a single stream.'); >+ const remoteTracks = [ trackEvent.track ]; >+ const remoteStream = trackEvent.streams[0]; >+ assert_equals(remoteTracks[0].id, localTracks[0].id, 'Remote track ID.'); >+ assert_equals(remoteStream.id, localStream.id, 'Remote stream ID.'); >+ assert_array_equals(remoteStream.getTracks(), remoteTracks, >+ 'Expected the remote stream\'s tracks to be the remote track.'); >+ caller.addTrack(localTracks[1], localStream); >+ performOffer(caller, callee); >+ remoteStream.onaddtrack = t.step_func(trackEvent => { >+ remoteTracks.push(trackEvent.track); >+ assert_equals(remoteTracks[1].id, localTracks[1].id, 'Remote track ID.'); >+ assert_array_equals(remoteStream.getTracks(), remoteTracks, >+ 'Expected the remote stream\'s tracks to be the remote tracks.'); >+ t.done(); >+ }); >+ }); >+ return offerPromise; >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'addTrack() for an existing stream makes stream.onaddtrack fire.'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ let eventSequence = ''; >+ return getUserMediaTracksAndStreams(2) >+ .then(t.step_func(([tracks, streams]) => { >+ const localTracks = tracks; >+ const localStream = streams[0]; >+ caller.addTrack(localTracks[0], localStream); >+ const offerPromise = performOffer(caller, callee); >+ callee.ontrack = t.step_func(trackEvent => { >+ callee.ontrack = null; >+ const remoteStream = trackEvent.streams[0]; >+ const onaddtrackResolver = new Resolver(); >+ remoteStream.onaddtrack = () => { >+ eventSequence += 'stream.onaddtrack;'; >+ onaddtrackResolver.resolve(); >+ } >+ caller.addTrack(localTracks[1], localStream); >+ Promise.all([ >+ onaddtrackResolver.promise, >+ performOffer(caller, callee).then(() => { >+ eventSequence += 'setRemoteDescription;'; >+ }) >+ ]).then(t.step_func(() => { >+ assert_equals(eventSequence, 'stream.onaddtrack;setRemoteDescription;'); >+ t.done(); >+ })); >+ }); >+ return offerPromise; >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'stream.onaddtrack fires before setRemoteDescription resolves.'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ return getUserMediaTracksAndStreams(2) >+ .then(t.step_func(([tracks, streams]) => { >+ const localTrack = tracks[0]; >+ const localStreams = streams; >+ caller.addTrack(localTrack, localStreams[0], localStreams[1]); >+ const performOffer = performOffer(caller, callee); >+ callee.ontrack = t.step_func(trackEvent => { >+ assert_equals(trackEvent.streams.length, 2, >+ 'Expected the track event to fire with two streams.'); >+ const remoteTrack = trackEvent.track; >+ const remoteStreams = trackEvent.streams; >+ assert_equals(remoteTrack.id, localTrack.id, >+ 'Expected local and remote track IDs to match.'); >+ assert_equals(remoteStreams[0].id, localStreams[0].id, >+ 'Expected the first remote stream ID to match the first local stream ID.'); >+ assert_equals(remoteStreams[1].id, localStreams[1].id, >+ 'Expected the second remote stream ID to match the second local stream ID.'); >+ assert_array_equals(remoteStreams[0].getTracks(), [remoteTrack], >+ 'Expected the remote stream\'s tracks to be the remote track.'); >+ assert_array_equals(remoteStreams[1].getTracks(), [remoteTrack], >+ 'Expected the remote stream\'s tracks to be the remote track.'); >+ t.done(); >+ }); >+ return performOffer; >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'addTrack() with a track and two streams makes ontrack fire with a track and two streams.'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ caller.addTrack(tracks[0]); >+ const offerPromise = performOffer(caller, callee); >+ callee.ontrack = t.step_func(trackEvent => { >+ assert_array_equals(callee.getReceivers(), [trackEvent.receiver]); >+ t.done(); >+ }); >+ return offerPromise; >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'ontrack\'s receiver matches getReceivers().'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ const sender = caller.addTrack(tracks[0]); >+ assert_not_equals(sender, null); >+ const offerPromise = performOffer(caller, callee); >+ callee.ontrack = t.step_func(trackEvent => { >+ const receivers = callee.getReceivers(); >+ assert_equals(receivers.length, 1, >+ 'Expected getReceivers() to be the track event\'s receiver.'); >+ caller.removeTrack(sender); >+ performOffer(caller, callee) >+ .then(t.step_func(() => { >+ assert_array_equals(callee.getReceivers(), receivers, >+ 'Expected the set of receivers to remain the same.'); >+ t.done(); >+ })); >+ }); >+ return offerPromise; >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'removeTrack() does not remove the receiver.'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ const sender = caller.addTrack(tracks[0], streams[0]); >+ assert_not_equals(sender, null); >+ const offerPromise = performOffer(caller, callee); >+ callee.ontrack = t.step_func(trackEvent => { >+ assert_not_equals(trackEvent.track, null); >+ assert_equals(trackEvent.streams.length, 1); >+ assert_true(trackEvent.streams[0].getTracks().includes(trackEvent.track)); >+ caller.removeTrack(sender); >+ performOffer(caller, callee); >+ trackEvent.streams[0].onremovetrack = t.step_func(removeEvent => { >+ assert_equals(removeEvent.track, trackEvent.track); >+ assert_false(trackEvent.streams[0].getTracks().includes(trackEvent.track)); >+ t.done(); >+ }); >+ }); >+ return offerPromise; >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'removeTrack() makes stream.onremovetrack fire and the track to be removed from the stream.'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ let eventSequence = ''; >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ const sender = caller.addTrack(tracks[0], streams[0]); >+ assert_not_equals(sender, null); >+ const offerPromise = performOffer(caller, callee); >+ callee.ontrack = t.step_func(trackEvent => { >+ const remoteStream = trackEvent.streams[0]; >+ const onremovetrackResolver = new Resolver(); >+ remoteStream.onremovetrack = t.step_func(removeEvent => { >+ eventSequence += 'stream.onremovetrack;'; >+ onremovetrackResolver.resolve(); >+ }); >+ caller.removeTrack(sender); >+ return Promise.all([ >+ onremovetrackResolver.promise, >+ performOffer(caller, callee).then(() => { >+ eventSequence += 'setRemoteDescription;'; >+ }) >+ ]).then(t.step_func(() => { >+ assert_equals(eventSequence, 'stream.onremovetrack;setRemoteDescription;'); >+ t.done(); >+ })); >+ }); >+ return offerPromise; >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'stream.onremovetrack fires before setRemoteDescription resolves.'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ const sender = caller.addTrack(tracks[0]); >+ assert_not_equals(sender, null); >+ const offerPromise = performOffer(caller, callee); >+ callee.ontrack = t.step_func(trackEvent => { >+ const remoteTrack = trackEvent.track; >+ caller.removeTrack(sender); >+ performOffer(caller, callee); >+ remoteTrack.onmute = t.step_func(() => { >+ assert_true(trackEvent.track.muted); >+ t.done(); >+ }); >+ }); >+ return offerPromise; >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'removeTrack() makes track.onmute fire and the track to be muted.'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ let eventSequence = ''; >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ const sender = caller.addTrack(tracks[0]); >+ assert_not_equals(sender, null); >+ const offerPromise = performOffer(caller, callee); >+ callee.ontrack = t.step_func(trackEvent => { >+ const remoteTrack = trackEvent.track; >+ const onmuteResolver = new Resolver(); >+ remoteTrack.onmute = t.step_func(() => { >+ eventSequence += 'track.onmute;'; >+ onmuteResolver.resolve(); >+ }); >+ caller.removeTrack(sender); >+ return Promise.all([ >+ onmuteResolver.promise, >+ performOffer(caller, callee).then(() => { >+ eventSequence += 'setRemoteDescription;'; >+ }) >+ ]).then(t.step_func(() => { >+ assert_equals(eventSequence, 'track.onmute;setRemoteDescription;'); >+ t.done(); >+ })); >+ }); >+ return offerPromise; >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'track.onmute fires before setRemoteDescription resolves.'); >+ >+ async_test(t => { >+ const pc = new RTCPeerConnection(); >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ const sender = pc.addTrack(tracks[0]); >+ assert_not_equals(sender, null); >+ pc.removeTrack(sender); >+ pc.removeTrack(sender); >+ t.done(); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'removeTrack() twice is safe.'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription.html >index 2efd30190031f8f5a2e1b6d6bab12d5af111e123..1dbcf41118af885c12a9cfeaf04407cc4bf39c06 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription.html >@@ -11,11 +11,8 @@ > // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html > > // The following helper functions are called from RTCPeerConnection-helper.js: >- // generateOffer() >- // generateAnswer() > // assert_session_desc_not_equals() > // assert_session_desc_equals() >- // test_state_change_event() > > /* > 4.3.2. Interface Definition >@@ -48,76 +45,99 @@ > /* > 4.6.1. enum RTCSdpType > */ >- promise_test(t => { >+ promise_test(async t => { > const pc = new RTCPeerConnection(); >+ t.add_cleanup(() => pc.close()); > > // SDP is validated after WebIDL validation >- return promise_rejects(t, new TypeError(), >- pc.setRemoteDescription({ >- type: 'bogus', >- sdp: 'bogus' >- })); >+ try { >+ await pc.setRemoteDescription({ type: 'bogus', sdp: 'bogus' }); >+ t.unreached_func("Should have rejected."); >+ } catch (e) { >+ assert_throws(new TypeError(), () => { throw e }); >+ } > }, 'setRemoteDescription with invalid type and invalid SDP should reject with TypeError'); > >- promise_test(t => { >+ promise_test(async t => { > const pc = new RTCPeerConnection(); >+ t.add_cleanup(() => pc.close()); > > // SDP is validated after validating type >- return promise_rejects(t, 'InvalidStateError', >- pc.setRemoteDescription({ >- type: 'answer', >- sdp: 'invalid' >- })); >+ try { >+ await pc.setRemoteDescription({ type: 'answer', sdp: 'invalid' }); >+ t.unreached_func("Should have rejected."); >+ } catch (e) { >+ assert_throws('InvalidStateError', () => { throw e }); >+ } > }, 'setRemoteDescription() with invalid SDP and stable state should reject with InvalidStateError'); > >- /* Operations after returning to stable state */ >+ /* Dedicated signalingstate events test. */ > >- promise_test(t => { >+ promise_test(async t => { > const pc = new RTCPeerConnection(); > const pc2 = new RTCPeerConnection(); >+ t.add_cleanup(() => pc.close()); >+ t.add_cleanup(() => pc2.close()); >+ >+ let eventCount = 0; >+ const states = [ >+ 'stable', 'have-local-offer', 'stable', 'have-remote-offer', >+ ]; >+ pc.onsignalingstatechange = t.step_func(() => >+ assert_equals(pc.signalingState, states[++eventCount])); >+ >+ const assert_state = state => { >+ assert_equals(state, pc.signalingState); >+ assert_equals(state, states[eventCount]); >+ }; >+ >+ const offer = await pc.createOffer({ offerToReceiveAudio: true }); >+ assert_state('stable'); >+ await pc.setLocalDescription(offer); >+ assert_state('have-local-offer'); >+ await pc2.setRemoteDescription(offer); >+ await pc2.setLocalDescription(await pc2.createAnswer()); >+ await pc.setRemoteDescription(pc2.localDescription); >+ assert_state('stable'); >+ await pc.setRemoteDescription(await pc2.createOffer()); >+ assert_state('have-remote-offer'); >+ }, 'Negotiation should fire signalingsstate events'); > >- test_state_change_event(t, pc, >- ['have-remote-offer', 'stable', 'have-remote-offer']); >- >- return pc2.createOffer({ offerToReceiveAudio: true }) >- .then(offer1 => >- pc.setRemoteDescription(offer1) >- .then(() => pc.createAnswer()) >- .then(answer => pc.setLocalDescription(answer)) >- .then(() => pc2.createOffer({ offerToReceiveVideo: true })) >- .then(offer2 => { >- return pc.setRemoteDescription(offer2) >- .then(() => { >- assert_equals(pc.signalingState, 'have-remote-offer'); >- assert_session_desc_not_equals(offer1, offer2); >- assert_session_desc_equals(pc.remoteDescription, offer2); >- assert_session_desc_equals(pc.currentRemoteDescription, offer1); >- assert_session_desc_equals(pc.pendingRemoteDescription, offer2); >- }); >- })); >- }, 'Calling setRemoteDescription() again after one round of remote-offer/local-answer should succeed'); >+ /* Operations after returning to stable state */ > >- promise_test(t => { >+ promise_test(async t => { > const pc = new RTCPeerConnection(); >+ const pc2 = new RTCPeerConnection(); >+ t.add_cleanup(() => pc.close()); >+ t.add_cleanup(() => pc2.close()); >+ >+ const offer1 = await pc2.createOffer({ offerToReceiveAudio: true }); >+ await pc.setRemoteDescription(offer1); >+ await pc.setLocalDescription(await pc.createAnswer()); >+ const offer2 = await pc2.createOffer({ offerToReceiveVideo: true }); >+ await pc.setRemoteDescription(offer2); >+ assert_session_desc_not_equals(offer1, offer2); >+ assert_session_desc_equals(pc.remoteDescription, offer2); >+ assert_session_desc_equals(pc.currentRemoteDescription, offer1); >+ assert_session_desc_equals(pc.pendingRemoteDescription, offer2); >+ }, 'Calling setRemoteDescription() again after one round of remote-offer/local-answer should succeed'); > >- test_state_change_event(t, pc, >- ['have-local-offer', 'stable', 'have-remote-offer']); >- >- return pc.createOffer({ offerToReceiveAudio: true }) >- .then(offer => >- pc.setLocalDescription(offer) >- .then(() => generateAnswer(offer))) >- .then(answer => >- pc.setRemoteDescription(answer) >- .then(() => generateOffer({ pc, data: true })) >- .then(offer => >- pc.setRemoteDescription(offer) >- .then(() => { >- assert_equals(pc.signalingState, 'have-remote-offer'); >- assert_session_desc_equals(pc.remoteDescription, offer); >- assert_session_desc_equals(pc.currentRemoteDescription, answer); >- assert_session_desc_equals(pc.pendingRemoteDescription, offer); >- }))); >+ promise_test(async t => { >+ const pc = new RTCPeerConnection(); >+ const pc2 = new RTCPeerConnection(); >+ t.add_cleanup(() => pc.close()); >+ t.add_cleanup(() => pc2.close()); >+ >+ const offer = await pc.createOffer({ offerToReceiveAudio: true }); >+ await pc.setLocalDescription(offer); >+ await pc2.setRemoteDescription(offer); >+ const answer = await pc2.createAnswer(); >+ await pc2.setLocalDescription(answer); >+ await pc.setRemoteDescription(answer); >+ await pc.setRemoteDescription(await pc2.createOffer()); >+ assert_equals(pc.remoteDescription.sdp, pc.pendingRemoteDescription.sdp); >+ assert_session_desc_equals(pc.remoteDescription, offer); >+ assert_session_desc_equals(pc.currentRemoteDescription, answer); > }, 'Switching role from offerer to answerer after going back to stable state should succeed'); > > /* >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-track-stats.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-track-stats.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2ce65597c05632c9b7a53add73d0ffaea51a6d7d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-track-stats.https-expected.txt >@@ -0,0 +1,20 @@ >+ >+FAIL addTrack() without setLocalDescription() yields track stats assert_true: Has stats for track expected true got false >+FAIL addTrack() without setLocalDescription() yields media stream stats assert_true: Has stats for stream expected true got false >+PASS addTrack() with setLocalDescription() yields track stats >+FAIL addTrack() with setLocalDescription() yields media stream stats assert_true: Has stats for stream expected true got false >+FAIL addTrack(): Media stream stats references track stats assert_true: Has stats for track and stream expected true got false >+FAIL Legacy addStream(): Media stream stats references track stats assert_true: Has stats for track and stream expected true got false >+FAIL O/A exchange yields outbound RTP stream stats for sending track assert_true: Has stats for outbound RTP stream expected true got false >+FAIL O/A exchange yields inbound RTP stream stats for receiving track assert_true: Has stats for outbound RTP stream expected true got false >+FAIL replaceTrack() before offer: new track attachment stats present assert_true: Has stats for replaced track expected true got false >+FAIL replaceTrack() after offer, before answer: new track attachment stats present assert_true: Has stats for replaced track expected true got false >+FAIL replaceTrack() after answer: new track attachment stats present assert_true: Has stats for replaced track expected true got false >+FAIL replaceTrack(): original track attachment stats present after replacing assert_true: expected true got undefined >+FAIL RTCRtpSender.getStats() contains only outbound-rtp and related stats assert_true: Has stats for outbound RTP stream expected true got false >+FAIL RTCRtpReceiver.getStats() contains only inbound-rtp and related stats assert_true: Has stats for outbound RTP stream expected true got false >+FAIL RTCPeerConnection.getStats(sendingTrack) is the same as RTCRtpSender.getStats() promise_test: Unhandled rejection with value: object "TypeError: sender.getStats is not a function. (In 'sender.getStats()', 'sender.getStats' is undefined)" >+FAIL RTCPeerConnection.getStats(receivingTrack) is the same as RTCRtpReceiver.getStats() promise_test: Unhandled rejection with value: object "TypeError: receiver.getStats is not a function. (In 'receiver.getStats()', 'receiver.getStats' is undefined)" >+FAIL RTCPeerConnection.getStats(track) throws InvalidAccessError when there are zero senders or receivers for the track assert_unreached: Should have rejected: undefined Reached unreachable code >+FAIL RTCPeerConnection.getStats(track) throws InvalidAccessError when there are multiple senders for the track assert_unreached: Should have rejected: undefined Reached unreachable code >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-track-stats.https.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-track-stats.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d833eb9ce112708e3bfd02edb0cf3b77ea29bcb2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-track-stats.https.html >@@ -0,0 +1,628 @@ >+<!doctype html> >+<meta charset=utf-8> >+<title>RTCPeerConnection.prototype.getStats</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="RTCPeerConnection-helper.js"></script> >+<script src="dictionary-helper.js"></script> >+<script src="RTCStats-helper.js"></script> >+<script> >+ 'use strict'; >+ >+ // The following helper functions are called from RTCPeerConnection-helper.js: >+ // doSignalingHandshake >+ // getUserMediaTracksAndStreams >+ >+ // The following helper functions are called from RTCStats-helper.js >+ // (depends on dictionary-helper.js): >+ // validateRtcStats >+ >+ async_test(t => { >+ const pc = new RTCPeerConnection(); >+ let track; >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ track = tracks[0]; >+ pc.addTrack(track); >+ return pc.getStats(); >+ })) >+ .then(t.step_func(report => { >+ let trackStats = findStatsByTypeAndId(report, 'track', track.id); >+ assert_true(trackStats != null, 'Has stats for track'); >+ // TODO(hbos): Here and elsewhere, validateRtcStats() only tests id, >+ // timestamp and type is correct type. Should validate based on stats type >+ // but it expects both audio and video members. >+ // https://github.com/web-platform-tests/wpt/issues/9010 >+ validateRtcStats(report, trackStats); >+ t.done(); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'addTrack() without setLocalDescription() yields track stats'); >+ >+ async_test(t => { >+ const pc = new RTCPeerConnection(); >+ let stream; >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ let track = tracks[0]; >+ stream = streams[0]; >+ pc.addTrack(track, stream); >+ return pc.getStats(); >+ })) >+ .then(t.step_func(report => { >+ let streamStats = findStatsByTypeAndId(report, 'stream', stream.id); >+ assert_true(streamStats != null, 'Has stats for stream'); >+ validateRtcStats(report, streamStats); >+ t.done(); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'addTrack() without setLocalDescription() yields media stream stats'); >+ >+ async_test(t => { >+ const pc = new RTCPeerConnection(); >+ let track; >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ track = tracks[0]; >+ pc.addTrack(track); >+ return pc.createOffer(); >+ })) >+ .then(t.step_func(offer => { >+ return pc.setLocalDescription(offer); >+ })) >+ .then(t.step_func(() => { >+ return pc.getStats(); >+ })) >+ .then(t.step_func(report => { >+ let trackStats = findStatsByTypeAndId(report, 'track', track.id); >+ assert_true(trackStats != null, 'Has stats for track'); >+ validateRtcStats(report, trackStats); >+ t.done(); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'addTrack() with setLocalDescription() yields track stats'); >+ >+ async_test(t => { >+ const pc = new RTCPeerConnection(); >+ let stream; >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ let track = tracks[0]; >+ stream = streams[0]; >+ pc.addTrack(track, stream); >+ return pc.createOffer(); >+ })) >+ .then(t.step_func(offer => { >+ return pc.setLocalDescription(offer); >+ })) >+ .then(t.step_func(() => { >+ return pc.getStats(); >+ })) >+ .then(t.step_func(report => { >+ let streamStats = findStatsByTypeAndId(report, 'stream', stream.id); >+ assert_true(streamStats != null, 'Has stats for stream'); >+ validateRtcStats(report, streamStats); >+ t.done(); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'addTrack() with setLocalDescription() yields media stream stats'); >+ >+ async_test(t => { >+ const pc = new RTCPeerConnection(); >+ let track; >+ let stream; >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ track = tracks[0]; >+ stream = streams[0]; >+ pc.addTrack(track, stream); >+ return pc.createOffer(); >+ })) >+ .then(t.step_func(offer => { >+ return pc.setLocalDescription(offer); >+ })) >+ .then(t.step_func(() => { >+ return pc.getStats(); >+ })) >+ .then(t.step_func(report => { >+ let trackStats = findStatsByTypeAndId(report, 'track', track.id); >+ let streamStats = findStatsByTypeAndId(report, 'stream', stream.id); >+ assert_true(trackStats != null && streamStats != null, >+ 'Has stats for track and stream'); >+ assert_array_equals(streamStats.trackIds, [ trackStats.id ], >+ 'streamStats.trackIds == [ trackStats.id ]'); >+ validateRtcStats(report, trackStats); >+ validateRtcStats(report, streamStats); >+ t.done(); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'addTrack(): Media stream stats references track stats'); >+ >+ // TODO(hbos): addStream() is legacy API not in the spec. Based on discussion >+ // whether to standardize in legacy section, consider removing this test or >+ // keeping it until addTrack() has wide support. >+ // https://github.com/w3c/webrtc-pc/issues/1705 >+ // https://github.com/w3c/webrtc-pc/issues/1125 >+ async_test(t => { >+ const pc = new RTCPeerConnection(); >+ let track; >+ let stream; >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ track = tracks[0]; >+ stream = streams[0]; >+ stream.addTrack(track); >+ pc.addStream(stream); >+ return pc.createOffer(); >+ })) >+ .then(t.step_func(offer => { >+ return pc.setLocalDescription(offer); >+ })) >+ .then(t.step_func(() => { >+ return pc.getStats(); >+ })) >+ .then(t.step_func(report => { >+ let trackStats = findStatsByTypeAndId(report, 'track', track.id); >+ let streamStats = findStatsByTypeAndId(report, 'stream', stream.id); >+ assert_true(trackStats != null && streamStats != null, >+ 'Has stats for track and stream'); >+ assert_array_equals(streamStats.trackIds, [ trackStats.id ], >+ 'streamStats.trackIds == [ trackStats.id ]'); >+ validateRtcStats(report, trackStats); >+ validateRtcStats(report, streamStats); >+ t.done(); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'Legacy addStream(): Media stream stats references track stats'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ let sendingTrack; >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ sendingTrack = tracks[0]; >+ caller.addTrack(sendingTrack); >+ return doSignalingHandshake(caller, callee); >+ })) >+ .then(t.step_func(() => { >+ return caller.getStats(); >+ })) >+ .then(t.step_func(report => { >+ let trackStats = findStatsByTypeAndId(report, 'track', sendingTrack.id); >+ assert_true(trackStats != null, 'Has stats for sending track'); >+ let outboundStats = findStatsByTypeAndMember(report, 'outbound-rtp', >+ 'trackId', trackStats.id); >+ assert_true(outboundStats != null, 'Has stats for outbound RTP stream'); >+ validateRtcStats(report, trackStats); >+ validateRtcStats(report, outboundStats); >+ t.done(); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'O/A exchange yields outbound RTP stream stats for sending track'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ let receivingTrack; >+ callee.ontrack = trackEvent => { >+ assert_true(receivingTrack == undefined, 'ontrack has not fired before'); >+ receivingTrack = trackEvent.track; >+ }; >+ return getUserMediaTracksAndStreams(1) >+ .then(t.step_func(([tracks, streams]) => { >+ caller.addTrack(tracks[0]); >+ return doSignalingHandshake(caller, callee); >+ })) >+ .then(t.step_func(() => { >+ return callee.getStats(); >+ })) >+ .then(t.step_func(report => { >+ assert_true(receivingTrack != null, 'Has a receiving track'); >+ let trackStats = findStatsByTypeAndId(report, 'track', receivingTrack.id); >+ assert_true(trackStats != null, 'Has stats for receiving track'); >+ let inboundStats = findStatsByTypeAndMember(report, 'inbound-rtp', >+ 'trackId', trackStats.id); >+ assert_true(inboundStats != null, 'Has stats for outbound RTP stream'); >+ validateRtcStats(report, trackStats); >+ validateRtcStats(report, inboundStats); >+ t.done(); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'O/A exchange yields inbound RTP stream stats for receiving track'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ let sendingTrack1; >+ let sendingTrack2; >+ let sender; >+ return getUserMediaTracksAndStreams(2) >+ .then(t.step_func(([tracks, streams]) => { >+ sendingTrack1 = tracks[0]; >+ sendingTrack2 = tracks[1]; >+ sender = caller.addTrack(sendingTrack1); >+ return sender.replaceTrack(sendingTrack2); >+ })) >+ .then(t.step_func(() => { >+ return caller.getStats(); >+ })) >+ .then(t.step_func(report => { >+ let trackStats = findStatsByTypeAndId(report, 'track', sendingTrack2.id); >+ assert_true(trackStats != null, 'Has stats for replaced track'); >+ validateRtcStats(report, trackStats); >+ t.done(); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'replaceTrack() before offer: new track attachment stats present'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ let sendingTrack1; >+ let sendingTrack2; >+ let sender; >+ return getUserMediaTracksAndStreams(2) >+ .then(t.step_func(([tracks, streams]) => { >+ sendingTrack1 = tracks[0]; >+ sendingTrack2 = tracks[1]; >+ sender = caller.addTrack(sendingTrack1); >+ return performOffer(caller, callee); >+ })) >+ .then(t.step_func(() => { >+ return sender.replaceTrack(sendingTrack2); >+ })) >+ .then(t.step_func(() => { >+ return caller.getStats(); >+ })) >+ .then(t.step_func(report => { >+ let trackStats = findStatsByTypeAndId(report, 'track', sendingTrack2.id); >+ assert_true(trackStats != null, 'Has stats for replaced track'); >+ let outboundStats = findStatsByTypeAndMember(report, 'outbound-rtp', >+ 'trackId', trackStats.id); >+ assert_true(outboundStats != null, 'Has stats for outbound RTP stream'); >+ validateRtcStats(report, trackStats); >+ validateRtcStats(report, outboundStats); >+ t.done(); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'replaceTrack() after offer, before answer: new track attachment stats ' + >+ 'present'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ let sendingTrack1; >+ let sendingTrack2; >+ let sender; >+ return getUserMediaTracksAndStreams(2) >+ .then(t.step_func(([tracks, streams]) => { >+ sendingTrack1 = tracks[0]; >+ sendingTrack2 = tracks[1]; >+ sender = caller.addTrack(sendingTrack1); >+ return doSignalingHandshake(caller, callee); >+ })) >+ .then(t.step_func(() => { >+ return sender.replaceTrack(sendingTrack2); >+ })) >+ .then(t.step_func(() => { >+ return caller.getStats(); >+ })) >+ .then(t.step_func(report => { >+ let trackStats = findStatsByTypeAndId(report, 'track', sendingTrack2.id); >+ assert_true(trackStats != null, 'Has stats for replaced track'); >+ let outboundStats = findStatsByTypeAndMember(report, 'outbound-rtp', >+ 'trackId', trackStats.id); >+ assert_true(outboundStats != null, 'Has stats for outbound RTP stream'); >+ validateRtcStats(report, trackStats); >+ validateRtcStats(report, outboundStats); >+ t.done(); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'replaceTrack() after answer: new track attachment stats present'); >+ >+ async_test(t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ let sendingTrack1; >+ let sendingTrack2; >+ let sender; >+ return getUserMediaTracksAndStreams(2) >+ .then(t.step_func(([tracks, streams]) => { >+ sendingTrack1 = tracks[0]; >+ sendingTrack2 = tracks[1]; >+ sender = caller.addTrack(sendingTrack1); >+ return doSignalingHandshake(caller, callee); >+ })) >+ .then(t.step_func(() => { >+ return sender.replaceTrack(sendingTrack2); >+ })) >+ .then(t.step_func(() => { >+ return caller.getStats(); >+ })) >+ .then(t.step_func(report => { >+ let trackStats = findStatsByTypeAndId(report, 'track', sendingTrack1.id); >+ assert_true(trackStats != null, 'Has stats for original track'); >+ assert_true(trackStats.objectDeleted); >+ let outboundStats = findStatsByTypeAndMember(report, 'outbound-rtp', >+ 'trackId', trackStats.id); >+ assert_true(outboundStats == null, >+ 'The outbound RTP stream should no longer reference the ' + >+ 'original attachment'); >+ t.done(); >+ })) >+ .catch(t.step_func(reason => { >+ assert_unreached(reason); >+ })); >+ }, 'replaceTrack(): original track attachment stats present after replacing'); >+ >+ promise_test(async t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ let [tracks, streams] = await getUserMediaTracksAndStreams(2); >+ let sender = caller.addTrack(tracks[0], streams[0]); >+ callee.addTrack(tracks[1], streams[1]); >+ exchangeIceCandidates(caller, callee); >+ await doSignalingHandshake(caller, callee); >+ await onIceConnectionStateCompleted(caller); >+ let receiver = caller.getReceivers()[0]; >+ >+ // Obtain inbound and outbound RTP stream stats on a full stats report. >+ let fullReport = await caller.getStats(); >+ let outboundTrackStats = findStatsByTypeAndId( >+ fullReport, 'track', sender.track.id); >+ let outboundStats = findStatsByTypeAndMember( >+ fullReport, 'outbound-rtp', 'trackId', outboundTrackStats.id); >+ assert_true(outboundStats != null, 'Has stats for outbound RTP stream'); >+ let inboundTrackStats = findStatsByTypeAndId( >+ fullReport, 'track', receiver.track.id); >+ let inboundStats = findStatsByTypeAndMember( >+ fullReport, 'inbound-rtp', 'trackId', inboundTrackStats.id); >+ assert_true(inboundStats != null, 'Has stats for inbound RTP stream'); >+ >+ // Perform stats selection algorithm with sender selector. The result should >+ // contain the outbound-rtp but not the inbound-rtp. >+ let senderReport = await sender.getStats(); >+ assert_true(senderReport.has(outboundStats.id)); >+ assert_false(senderReport.has(inboundStats.id)); >+ >+ // Validate the stats graph, ensuring all stats objects are reachable and >+ // valid from the outbound-rtp stats. >+ validateStatsGraph(senderReport, senderReport.get(outboundStats.id)); >+ // Ensure that the stats graph contains some expected dictionaries. >+ assert_equals(findStatsOfType(senderReport, 'track').length, 1, >+ 'senderReport should contain track stats'); >+ assert_equals(findStatsOfType(senderReport, 'transport').length, 1, >+ 'senderReport should contain transport stats'); >+ assert_equals(findStatsOfType(senderReport, 'candidate-pair').length, 1, >+ 'senderReport should contain candidate-pair stats'); >+ assert_equals(findStatsOfType(senderReport, 'local-candidate').length, 1, >+ 'senderReport should contain local-candidate stats'); >+ assert_equals(findStatsOfType(senderReport, 'remote-candidate').length, 1, >+ 'senderReport should contain remote-candidate stats'); >+ }, 'RTCRtpSender.getStats() contains only outbound-rtp and related stats'); >+ >+ promise_test(async t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ let [tracks, streams] = await getUserMediaTracksAndStreams(2); >+ let sender = caller.addTrack(tracks[0], streams[0]); >+ callee.addTrack(tracks[1], streams[1]); >+ exchangeIceCandidates(caller, callee); >+ await doSignalingHandshake(caller, callee); >+ await onIceConnectionStateCompleted(caller); >+ let receiver = caller.getReceivers()[0]; >+ >+ // Obtain inbound and outbound RTP stream stats on a full stats report. >+ let fullReport = await caller.getStats(); >+ let outboundTrackStats = findStatsByTypeAndId( >+ fullReport, 'track', sender.track.id); >+ let outboundStats = findStatsByTypeAndMember( >+ fullReport, 'outbound-rtp', 'trackId', outboundTrackStats.id); >+ assert_true(outboundStats != null, 'Has stats for outbound RTP stream'); >+ let inboundTrackStats = findStatsByTypeAndId( >+ fullReport, 'track', receiver.track.id); >+ let inboundStats = findStatsByTypeAndMember( >+ fullReport, 'inbound-rtp', 'trackId', inboundTrackStats.id); >+ assert_true(inboundStats != null, 'Has stats for inbound RTP stream'); >+ >+ // Perform stats selection algorithm with receiver selector. The result >+ // should contain the inbound-rtp but not the outbound-rtp. >+ let receiverReport = await receiver.getStats(); >+ assert_true(receiverReport.has(inboundStats.id)); >+ assert_false(receiverReport.has(outboundStats.id)); >+ >+ // Validate the stats graph, ensuring all stats objects are reachable and >+ // valid from the outbound-rtp stats. >+ validateStatsGraph(receiverReport, receiverReport.get(inboundStats.id)); >+ // Ensure that the stats graph contains some expected dictionaries. >+ assert_equals(findStatsOfType(receiverReport, 'track').length, 1, >+ 'receiverReport should contain track stats'); >+ assert_equals(findStatsOfType(receiverReport, 'transport').length, 1, >+ 'receiverReport should contain transport stats'); >+ assert_equals(findStatsOfType(receiverReport, 'candidate-pair').length, 1, >+ 'receiverReport should contain candidate-pair stats'); >+ assert_equals(findStatsOfType(receiverReport, 'local-candidate').length, 1, >+ 'receiverReport should contain local-candidate stats'); >+ assert_equals(findStatsOfType(receiverReport, 'remote-candidate').length, 1, >+ 'receiverReport should contain remote-candidate stats'); >+ }, 'RTCRtpReceiver.getStats() contains only inbound-rtp and related stats'); >+ >+ promise_test(async t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ let [tracks, streams] = await getUserMediaTracksAndStreams(2); >+ let sender = caller.addTrack(tracks[0], streams[0]); >+ callee.addTrack(tracks[1], streams[1]); >+ exchangeIceCandidates(caller, callee); >+ await doSignalingHandshake(caller, callee); >+ await onIceConnectionStateCompleted(caller); >+ >+ let senderReport = await sender.getStats(); >+ let trackReport = await caller.getStats(sender.track); >+ >+ // Verify the same stats objects are returned but don't compare each >+ // individual metric because timestamps and counters could have gone up >+ // between the two getStats() calls. >+ senderReport.forEach(senderReportStat => { >+ assert_true(trackReport.has(senderReportStat.id)); >+ }); >+ trackReport.forEach(trackReportStat => { >+ assert_true(senderReport.has(trackReportStat.id)); >+ }); >+ }, 'RTCPeerConnection.getStats(sendingTrack) is the same as ' + >+ 'RTCRtpSender.getStats()'); >+ >+ promise_test(async t => { >+ const caller = new RTCPeerConnection(); >+ const callee = new RTCPeerConnection(); >+ let [tracks, streams] = await getUserMediaTracksAndStreams(2); >+ let sender = caller.addTrack(tracks[0], streams[0]); >+ callee.addTrack(tracks[1], streams[1]); >+ exchangeIceCandidates(caller, callee); >+ await doSignalingHandshake(caller, callee); >+ await onIceConnectionStateCompleted(caller); >+ let receiver = caller.getReceivers()[0]; >+ >+ let receiverReport = await receiver.getStats(); >+ let trackReport = await caller.getStats(receiver.track); >+ >+ // Verify the same stats objects are returned but don't compare each >+ // individual metric because timestamps and counters could have gone up >+ // between the two getStats() calls. >+ receiverReport.forEach(receiverReportStat => { >+ assert_true(trackReport.has(receiverReportStat.id)); >+ }); >+ trackReport.forEach(trackReportStat => { >+ assert_true(receiverReport.has(trackReportStat.id)); >+ }); >+ }, 'RTCPeerConnection.getStats(receivingTrack) is the same as ' + >+ 'RTCRtpReceiver.getStats()'); >+ >+ promise_test(async t => { >+ const pc = new RTCPeerConnection(); >+ let [tracks, streams] = await getUserMediaTracksAndStreams(1); >+ await promise_rejects(t, 'InvalidAccessError', pc.getStats(tracks[0])); >+ }, 'RTCPeerConnection.getStats(track) throws InvalidAccessError when there ' + >+ 'are zero senders or receivers for the track'); >+ >+ promise_test(async t => { >+ const pc = new RTCPeerConnection(); >+ let [tracks, streams] = await getUserMediaTracksAndStreams(2); >+ let sender1 = pc.addTrack(tracks[0]); >+ let sender2 = pc.addTrack(tracks[1]); >+ await sender2.replaceTrack(sender1.track); >+ await promise_rejects(t, 'InvalidAccessError', pc.getStats(sender1.track)); >+ }, 'RTCPeerConnection.getStats(track) throws InvalidAccessError when there ' + >+ 'are multiple senders for the track'); >+ >+ // Helpers. >+ >+ function findStatsByTypeAndId(report, type, identifier) { >+ return findStats(report, stats => { >+ return stats.type == type && stats[type + 'Identifier'] == identifier; >+ }); >+ } >+ >+ function findStatsByTypeAndMember(report, type, member, value) { >+ return findStats(report, stats => { >+ return stats.type == type && stats[member] == value; >+ }); >+ } >+ >+ function findStats(report, findFunc) { >+ for (let it = report.values(), n = it.next(); !n.done; n = it.next()) { >+ if (findFunc(n.value)) >+ return n.value; >+ } >+ return null; >+ } >+ >+ function findStatsOfType(report, type) { >+ let stats = []; >+ for (let it = report.values(), n = it.next(); !n.done; n = it.next()) { >+ if (n.value.type == type) >+ stats.push(n.value); >+ } >+ return stats; >+ } >+ >+ // Returns a promise that is resolved when pc.iceConnectionState reaches the >+ // 'connected' or 'completed' state. This is when transport stats can be >+ // expected to have its selectedCandidatePairId defined. >+ async function onIceConnectionStateCompleted(pc) { >+ if (pc.iceConnectionState == 'connected' || >+ pc.iceConnectionState == 'completed') { >+ return Promise.resolve(); >+ } >+ let resolver = new Resolver(); >+ pc.oniceconnectionstatechange = e => { >+ if (pc.iceConnectionState == 'connected' || >+ pc.iceConnectionState == 'completed') { >+ resolver.resolve(); >+ } >+ }; >+ return resolver.promise; >+ } >+ >+ // Explores the stats graph starting from |stat|, validating each stat >+ // (validateRtcStats) and asserting that all stats of the report were visited. >+ function validateStatsGraph(report, stat) { >+ let visitedIds = new Set(); >+ validateStatsGraphRecursively(report, stat.id, visitedIds); >+ assert_equals(visitedIds.size, report.size, >+ 'Entire stats graph should have been explored.') >+ } >+ >+ function validateStatsGraphRecursively(report, currentId, visitedIds) { >+ if (visitedIds.has(currentId)) >+ return; >+ visitedIds.add(currentId); >+ assert_true(report.has(currentId), 'Broken reference.'); >+ let stat = report.get(currentId); >+ validateRtcStats(report, stat); >+ for (let member in stat) { >+ if (member.endsWith('Id')) { >+ validateStatsGraphRecursively(report, stat[member], visitedIds); >+ } else if (member.endsWith('Ids')) { >+ let ids = stat[member]; >+ for (let i = 0; i < ids.length; ++i) { >+ validateStatsGraphRecursively(report, ids[i], visitedIds); >+ } >+ } >+ } >+ } >+ >+ async function async_assert_throws(exceptionName, promise, description) { >+ try { >+ await promise; >+ } catch (e) { >+ assert_equals(e.name, exceptionName); >+ return; >+ } >+ assert_unreached('No exception was thrown.'); >+ } >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpReceiver-getContributingSources.https.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpReceiver-getContributingSources.https.html >index de1e143a6ad3eb0120950807a418e71f1e64978b..7ddc7e822f30e7ffcf7a4e851e33e4e38a8d294e 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpReceiver-getContributingSources.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpReceiver-getContributingSources.https.html >@@ -38,7 +38,7 @@ > possibly encode, and 127 represents silence. > */ > >- promise_test(() => { >+ promise_test(t => { > const pc1 = new RTCPeerConnection(); > const pc2 = new RTCPeerConnection(); > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpReceiver-getStats.https.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpReceiver-getStats.https.html >index f36c85967bba33cbe45fbd099f3bee8492b8a440..4da0b0ac6235cbf1dff2237660ead5794fde1db1 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpReceiver-getStats.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpReceiver-getStats.https.html >@@ -44,7 +44,7 @@ > added. > */ > >- promise_test(async () => { >+ promise_test(async t => { > const caller = new RTCPeerConnection(); > const callee = new RTCPeerConnection(); > const { receiver } = caller.addTransceiver('audio'); >@@ -55,7 +55,7 @@ > assert_stats_report_has_stats(statsReport, ['inbound-rtp']); > }, 'receiver.getStats() via addTransceiver should return stats report containing inbound-rtp stats'); > >- promise_test(async () => { >+ promise_test(async t => { > const caller = new RTCPeerConnection(); > const callee = new RTCPeerConnection(); > const stream = await navigator.mediaDevices.getUserMedia({audio:true}); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpReceiver-getSynchronizationSources.https.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpReceiver-getSynchronizationSources.https.html >index 3494a911c874bcac64f0991b3b608c60a70f7a37..236ec8b630ea7a069f452b6c128bc5d4c23ee540 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpReceiver-getSynchronizationSources.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpReceiver-getSynchronizationSources.https.html >@@ -25,7 +25,7 @@ > }; > */ > >- promise_test(() => { >+ promise_test(t => { > const pc1 = new RTCPeerConnection(); > const pc2 = new RTCPeerConnection(); > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpSender-getStats.https.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpSender-getStats.https.html >index 5342625ea0ccf2aa9b9437666c6d61f3c7b21358..a20304d6300d5ebd497a7ec83ba9ade1d8462ba0 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpSender-getStats.https.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpSender-getStats.https.html >@@ -39,7 +39,7 @@ > objects added. > */ > >- promise_test(async () => { >+ promise_test(async t => { > const caller = new RTCPeerConnection(); > const callee = new RTCPeerConnection(); > const { sender } = caller.addTransceiver('audio'); >@@ -50,7 +50,7 @@ > assert_stats_report_has_stats(statsReport, ['outbound-rtp']); > }, 'sender.getStats() via addTransceiver should return stats report containing outbound-rtp stats'); > >- promise_test(async () => { >+ promise_test(async t => { > const caller = new RTCPeerConnection(); > const callee = new RTCPeerConnection(); > const stream = await navigator.mediaDevices.getUserMedia({audio:true}); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCSctpTransport-maxMessageSize-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCSctpTransport-maxMessageSize-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..00e3de0928aedc844f6733c4dd6c4677d7a35568 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCSctpTransport-maxMessageSize-expected.txt >@@ -0,0 +1,7 @@ >+ >+FAIL Determine the local side send limitation (canSendSize) by offering a max-message-size of 0 assert_equals: expected (object) null but got (undefined) undefined >+FAIL Remote offer SDP missing max-message-size attribute assert_equals: expected (object) null but got (undefined) undefined >+FAIL max-message-size with a (non-zero) value provided by the remote peer assert_equals: expected (object) null but got (undefined) undefined >+FAIL Renegotiate max-message-size with a (non-zero) value provided by the remote peer assert_equals: expected (object) null but got (undefined) undefined >+FAIL max-message-size with a (non-zero) value larger than canSendSize provided by the remote peer assert_equals: expected (object) null but got (undefined) undefined >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCSctpTransport-maxMessageSize.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCSctpTransport-maxMessageSize.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d7f836292ebe4cdd162086b33072c0d8270691e9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCSctpTransport-maxMessageSize.html >@@ -0,0 +1,181 @@ >+<!doctype html> >+<meta charset=utf-8> >+<title>RTCSctpTransport.prototype.maxMessageSize</title> >+<link rel="help" href="https://w3c.github.io/webrtc-pc/#rtcsctptransport-interface"> >+<script src=/resources/testharness.js></script> >+<script src=/resources/testharnessreport.js></script> >+<script src="RTCPeerConnection-helper.js"></script> >+<script> >+'use strict'; >+ >+// This test has an assert_unreached() that requires that the variable >+// canSendSize (initiated below) is greater than 2, if non-zero. The reason >+// is that we need two non-zero values that are less that that value for >+// testing with predictable results. This is a bit unfortunate but shouldn't >+// have any practical impact. >+ >+// Helper class to read SDP attributes and generate SDPs with modified attribute values >+class SDPAttributeHelper { >+ constructor(attrName, valueRegExpStr) { >+ this.attrName = attrName; >+ this.re = new RegExp(`^a=${attrName}:(${valueRegExpStr})\\r\\n`, 'm'); >+ } >+ >+ getValue(sdp) { >+ const matches = sdp.match(this.re); >+ return matches ? matches[1] : null; >+ } >+ >+ sdpWithValue(sdp, value) { >+ const matches = sdp.match(this.re); >+ const sdpParts = sdp.split(matches[0]); >+ const attributeLine = arguments.length > 1 ? `a=${this.attrName}:${value}\r\n` : ''; >+ return `${sdpParts[0]}${attributeLine}${sdpParts[1]}`; >+ } >+ >+ sdpWithoutAttribute(sdp) { >+ return this.sdpWithValue(sdp); >+ } >+} >+ >+const mmsAttributeHelper = new SDPAttributeHelper('max-message-size', '\\d+'); >+let canSendSize; >+const remoteValue1 = 1; >+const remoteValue2 = 2; >+ >+promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ assert_equals(pc.sctp, null); >+ let maxMessageSize; >+ >+ return generateOffer({ pc, data: true }) >+ .then((offer) => { >+ assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null, >+ 'SDP should have max-message-size attribute'); >+ >+ offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, 0) }; >+ return pc.setRemoteDescription(offer); >+ }) >+ .then(() => pc.createAnswer()) >+ .then((answer) => pc.setLocalDescription(answer)) >+ .then(() => { >+ assert_not_equals(pc.sctp, null); >+ canSendSize = pc.sctp.maxMessageSize == Number.POSITIVE_INFINITY ? 0 : pc.sctp.maxMessageSize; >+ if (canSendSize != 0 && canSendSize < remoteValue2) { >+ assert_unreached('This test needs two values that are less than canSendSize (unless it is zero)'); >+ } >+ }); >+}, 'Determine the local side send limitation (canSendSize) by offering a max-message-size of 0'); >+ >+promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ assert_equals(pc.sctp, null); >+ >+ return generateOffer({ pc, data: true }) >+ .then((offer) => { >+ assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null, >+ 'SDP should have max-message-size attribute'); >+ >+ // Remove the max-message-size SDP attribute >+ offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithoutAttribute(offer.sdp) }; >+ return pc.setRemoteDescription(offer) >+ }) >+ .then(() => pc.createAnswer()) >+ .then((answer) => pc.setLocalDescription(answer)) >+ .then(() => { >+ assert_not_equals(pc.sctp, null); >+ // Test outcome depends on canSendSize value >+ if (canSendSize) { >+ assert_equals(pc.sctp.maxMessageSize, Math.min(65536, canSendSize), >+ 'Missing SDP attribute and a non-zero canSendSize should give an maxMessageSize of min(65536, canSendSize)'); >+ } else { >+ assert_equals(pc.sctp.maxMessageSize, 65536, >+ 'Missing SDP attribute and a canSendSize of 0 should give an maxMessageSize of 65536'); >+ } >+ }); >+}, 'Remote offer SDP missing max-message-size attribute'); >+ >+promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ assert_equals(pc.sctp, null); >+ >+ return generateOffer({ pc, data: true }) >+ .then((offer) => { >+ assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null, >+ 'SDP should have max-message-size attribute'); >+ >+ offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteValue1) }; >+ return pc.setRemoteDescription(offer); >+ }) >+ .then(() => pc.createAnswer()) >+ .then((answer) => pc.setLocalDescription(answer)) >+ .then(() => { >+ assert_not_equals(pc.sctp, null); >+ assert_equals(pc.sctp.maxMessageSize, remoteValue1, >+ 'maxMessageSize should be the value provided by the remote peer (as long as it is less than canSendSize)'); >+ }); >+}, 'max-message-size with a (non-zero) value provided by the remote peer'); >+ >+promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ assert_equals(pc.sctp, null); >+ >+ return generateOffer({ pc, data: true }) >+ .then((offer) => { >+ assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null, >+ 'SDP should have max-message-size attribute'); >+ >+ offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteValue1) }; >+ return pc.setRemoteDescription(offer) >+ }) >+ .then(() => pc.createAnswer()) >+ .then((answer) => pc.setLocalDescription(answer)) >+ .then(() => { >+ assert_not_equals(pc.sctp, null); >+ assert_equals(pc.sctp.maxMessageSize, remoteValue1, >+ 'maxMessageSize should be the value provided by the remote peer (as long as it is less than canSendSize)'); >+ }) >+ .then(() => pc.createOffer()) // Start new O/A exchange that updates max-message-size >+ .then((offer) => { >+ offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteValue2)}; >+ return pc.setRemoteDescription(offer) >+ }) >+ .then(() => pc.createAnswer()) >+ .then((answer) => pc.setLocalDescription(answer)) >+ .then(() => { >+ assert_not_equals(pc.sctp, null); >+ assert_equals(pc.sctp.maxMessageSize, remoteValue2, >+ 'maxMessageSize should be the new value provided by the remote peer (as long as it is less than canSendSize)'); >+ }) >+ ; >+}, 'Renegotiate max-message-size with a (non-zero) value provided by the remote peer'); >+ >+promise_test(t => { >+ const pc = new RTCPeerConnection(); >+ assert_equals(pc.sctp, null); >+ const largerThanCanSendSize = canSendSize + 1; >+ >+ return generateOffer({ pc, data: true }) >+ .then((offer) => { >+ assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null, >+ 'SDP should have max-message-size attribute'); >+ >+ offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, largerThanCanSendSize) }; >+ return pc.setRemoteDescription(offer) >+ }) >+ .then(() => pc.createAnswer()) >+ .then((answer) => pc.setLocalDescription(answer)) >+ .then(() => { >+ assert_not_equals(pc.sctp, null); >+ // Test outcome depends on canSendSize value >+ if (canSendSize) { >+ assert_equals(pc.sctp.maxMessageSize, canSendSize, >+ 'A remote value larger than a non-zero canSendSize should limit maxMessageSize to canSendSize'); >+ } else { >+ assert_equals(pc.sctp.maxMessageSize, 65536, >+ 'A canSendSize of zero should let the remote value set maxMessageSize'); >+ } >+ }); >+}, 'max-message-size with a (non-zero) value larger than canSendSize provided by the remote peer'); >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/identity-helper.js b/LayoutTests/imported/w3c/web-platform-tests/webrtc/identity-helper.js >deleted file mode 100644 >index bd35d0fbbe93115769c9a43dd8acb1f634c0b7a0..0000000000000000000000000000000000000000 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/identity-helper.js >+++ /dev/null >@@ -1,70 +0,0 @@ >-'use strict'; >- >-/* >- In web-platform-test, the following domains are required to be set up locally: >- 127.0.0.1 web-platform.test >- 127.0.0.1 www.web-platform.test >- 127.0.0.1 www1.web-platform.test >- 127.0.0.1 www2.web-platform.test >- 127.0.0.1 xn--n8j6ds53lwwkrqhv28a.web-platform.test >- 127.0.0.1 xn--lve-6lad.web-platform.test >- 0.0.0.0 nonexistent-origin.web-platform.test >- */ >- >-/* >- dictionary RTCIdentityProviderDetails { >- required DOMString domain; >- DOMString protocol = "default"; >- }; >- */ >- >-// Parse a base64 JSON encoded string returned from getIdentityAssertion(). >-// This is also the string that is set in the a=identity line. >-// Returns a { idp, assertion } where idp is of type RTCIdentityProviderDetails >-// and assertion is the deserialized JSON that was returned by the >-// IdP proxy's generateAssertion() function. >-function parseAssertionResult(assertionResultStr) { >- const assertionResult = JSON.parse(atob(assertionResultStr)); >- >- const { idp } = assertionResult; >- const assertion = JSON.parse(assertionResult.assertion); >- >- return { idp, assertion }; >-} >- >-// Return two distinct IdP domains that are different from current domain >-function getIdpDomains() { >- if(window.location.hostname === 'www1.web-platform.test') { >- return ['www.web-platform.test', 'www2.web-platform.test']; >- } else if(window.location.hostname === 'www2.web-platform.test') { >- return ['www.web-platform.test', 'www1.web-platform.test']; >- } else { >- return ['www1.web-platform.test', 'www2.web-platform.test']; >- } >-} >- >-function assert_rtcerror_rejection(errorDetail, promise, desc) { >- return promise.then( >- res => { >- assert_unreached(`Expect promise to be rejected with RTCError, but instead got ${res}`); >- }, err => { >- assert_true(err instanceof RTCError, >- 'Expect error object to be instance of RTCError'); >- >- assert_equals(err.errorDetail, errorDetail, >- `Expect RTCError object have errorDetail set to ${errorDetail}`); >- >- return err; >- }); >-} >- >-// construct a host string consist of domain and optionally port >-// If the default HTTP/HTTPS port is used, window.location.port returns >-// empty string. >-function hostString(domain, port) { >- if(port === '') { >- return domain; >- } else { >- return `${domain}:${port}`; >- } >-} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/identity-helper.sub.js b/LayoutTests/imported/w3c/web-platform-tests/webrtc/identity-helper.sub.js >new file mode 100644 >index 0000000000000000000000000000000000000000..90363662f742fbf1d31634030d2b470e08fe1421 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/identity-helper.sub.js >@@ -0,0 +1,70 @@ >+'use strict'; >+ >+/* >+ In web-platform-test, a number of domains are required to be set up locally. >+ The list is available at docs/_writing-tests/server-features.md. The >+ appropriate hosts file entries can be generated with the WPT CLI via the >+ following command: `wpt make-hosts-file`. >+ */ >+ >+/* >+ dictionary RTCIdentityProviderDetails { >+ required DOMString domain; >+ DOMString protocol = "default"; >+ }; >+ */ >+ >+// Parse a base64 JSON encoded string returned from getIdentityAssertion(). >+// This is also the string that is set in the a=identity line. >+// Returns a { idp, assertion } where idp is of type RTCIdentityProviderDetails >+// and assertion is the deserialized JSON that was returned by the >+// IdP proxy's generateAssertion() function. >+function parseAssertionResult(assertionResultStr) { >+ const assertionResult = JSON.parse(atob(assertionResultStr)); >+ >+ const { idp } = assertionResult; >+ const assertion = JSON.parse(assertionResult.assertion); >+ >+ return { idp, assertion }; >+} >+ >+// Return two distinct IdP domains that are different from current domain >+function getIdpDomains() { >+ const domainA = '{{domains[www]}}'; >+ const domainB = '{{domains[www1]}}'; >+ const domainC = '{{domains[www2]}}'; >+ >+ if(window.location.hostname === domainA) { >+ return [domainB, domainC]; >+ } else if(window.location.hostname === domainB) { >+ return [domainA, domainC]; >+ } else { >+ return [domainA, domainB]; >+ } >+} >+ >+function assert_rtcerror_rejection(errorDetail, promise, desc) { >+ return promise.then( >+ res => { >+ assert_unreached(`Expect promise to be rejected with RTCError, but instead got ${res}`); >+ }, err => { >+ assert_true(err instanceof RTCError, >+ 'Expect error object to be instance of RTCError'); >+ >+ assert_equals(err.errorDetail, errorDetail, >+ `Expect RTCError object have errorDetail set to ${errorDetail}`); >+ >+ return err; >+ }); >+} >+ >+// construct a host string consist of domain and optionally port >+// If the default HTTP/HTTPS port is used, window.location.port returns >+// empty string. >+function hostString(domain, port) { >+ if(port === '') { >+ return domain; >+ } else { >+ return `${domain}:${port}`; >+ } >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/protocol/README.txt b/LayoutTests/imported/w3c/web-platform-tests/webrtc/protocol/README.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..062db8540f43278b7a49a94c3fa25647f038ef8f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/protocol/README.txt >@@ -0,0 +1,21 @@ >+This directory contains files that test for behavior relevant to webrtc, >+but which is specified in protocol specifications from the IETF, not in >+API recommendations from the W3C. >+ >+The main specifications are given in the following internet-drafts: >+ >+- draft-ietf-rtcweb-overview >+- draft-ietf-rtcweb-transports >+- draft-ietf-rtcweb-security-arch >+- draft-ietf-rtcweb-security >+- draft-ietf-rtcweb-rtp-usage >+- draft-ietf-rtcweb-jsep >+- draft-ietf-rtcweb-ip-handling >+- draft-ietf-rtcweb-fec >+- draft-ietf-rtcweb-data-protocol >+- draft-ietf-rtcweb-data-channel >+ >+- RFC 7742, "WebRTC Video Processing and Codec Requirements" >+- RFC 7874, "WebRTC Audio Codec and Processing Requirements" >+ >+An overview of the dependencies involved is in draft-jennings-rtcweb-deps >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/protocol/video-codecs.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webrtc/protocol/video-codecs.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..019dbb2fe3f83a2294a85633cad553e4ee0f88c9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/protocol/video-codecs.https-expected.txt >@@ -0,0 +1,5 @@ >+ >+FAIL H.264 and VP8 should be supported in initial offer assert_true: expected true got false >+FAIL H.264 and VP8 should be negotiated after handshake assert_true: expected true got false >+FAIL All H.264 codecs MUST include profile-level-id promise_test: Unhandled rejection with value: object "TypeError: undefined is not an object (evaluating 'fmtp.split')" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/protocol/video-codecs.https.html b/LayoutTests/imported/w3c/web-platform-tests/webrtc/protocol/video-codecs.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..547856f2a271b5c349b529ec7f1fe1acb5a48ef0 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/protocol/video-codecs.https.html >@@ -0,0 +1,90 @@ >+<!doctype html> >+<meta charset=utf-8> >+<title>RTCPeerConnection.prototype.createOffer</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="../RTCPeerConnection-helper.js"></script> >+<script> >+'use strict'; >+ >+// Tests for conformance to RFC 7742, >+// "WebRTC Video Processing and Codec Requirements" >+// The document was formerly known as draft-ietf-rtcweb-video-codecs. >+// >+// This tests that the browser is a WebRTC Browser as defined there. >+ >+// TODO: Section 3.2: screen capture video MUST be prepared >+// to handle resolution changes. >+ >+// TODO: Section 4: MUST support generating CVO (orientation) >+ >+// Section 5: Browsers MUST implement VP8 and H.264 Constrained Baseline >+promise_test(async t => { >+ const pc = new RTCPeerConnection(); >+ const offer = await pc.createOffer({offerToReceiveVideo: true}); >+ let video_section_found = false; >+ for (let section of offer.sdp.split(/\r\nm=/)) { >+ if (section.search('video') != 0) { >+ continue; >+ } >+ video_section_found = true; >+ // RTPMAP lines have the format a=rtpmap:<pt> <codec>/<clock rate> >+ let rtpmap_regex = /\r\na=rtpmap:(\d+) (\S+)\/\d+\r\n/g; >+ let match = rtpmap_regex.exec(offer.sdp); >+ let payload_type_map = new Array(); >+ while (match) { >+ payload_type_map[match[1]] = match[2]; >+ match = rtpmap_regex.exec(offer.sdp); >+ } >+ assert_true(payload_type_map.indexOf('VP8') > -1, >+ 'VP8 is supported'); >+ assert_true(payload_type_map.indexOf('H264') > -1, >+ 'H.264 is supported'); >+ // TODO: Verify that one of the H.264 PTs supports constrained baseline >+ } >+ assert_true(video_section_found); >+}, 'H.264 and VP8 should be supported in initial offer'); >+ >+async function negotiateParameters() { >+ const pc1 = new RTCPeerConnection(); >+ const pc2 = new RTCPeerConnection(); >+ let [track, streams] = await getTrackFromUserMedia('video'); >+ const sender = pc1.addTrack(track); >+ await doSignalingHandshake(pc1, pc2); >+ return sender.getParameters(); >+} >+ >+function parseFmtp(fmtp) { >+ const params = fmtp.split(';'); >+ return params.map(param => param.split('=')); >+} >+promise_test(async t => { >+ const params = await negotiateParameters(); >+ assert_true(!!params.codecs.find(codec => codec.mimeType === 'video/H264')); >+ assert_true(!!params.codecs.find(codec => codec.mimeType === 'video/VP8')); >+}, 'H.264 and VP8 should be negotiated after handshake'); >+ >+// TODO: Section 6: Recipients MUST be able to decode 320x240@20 fps >+// TODO: Section 6.1: VP8 MUST support RFC 7741 payload formats >+// TODO: Section 6.1: VP8 MUST respect max-fr/max-fs >+// TODO: Section 6.1: VP8 MUST encode and decode square pixels >+// TODO: Section 6.2: H.264 MUST support RFC 6184 payload formats >+// TODO: Section 6.2: MUST support Constrained Baseline level 1.2 >+// TODO: Section 6.2: SHOULD support Constrained High level 1.3 >+// TODO: Section 6.2: MUST support packetization mode 1. >+promise_test(async t => { >+ const params = await negotiateParameters(); >+ const h264 = params.codecs.filter(codec => codec.mimeType === 'video/H264'); >+ h264.map(codec => { >+ const codec_params = parseFmtp(codec.sdpFmtpLine); >+ assert_true(!!codec_params.find(x => x[0] === 'profile-level-id')); >+ }) >+}, 'All H.264 codecs MUST include profile-level-id'); >+ >+// TODO: Section 6.2: SHOULD interpret max-mbps, max-smbps, max-fs et al >+// TODO: Section 6.2: MUST NOT include sprop-parameter-sets >+// TODO: Section 6.2: MUST support SEI "filler payload" >+// TODO: Section 6.2: MUST support SEI "full frame freeze" >+// TODO: Section 6.2: MUST be prepared to receive User Data messages >+// TODO: Section 6.2: MUST encode and decode square pixels unless signaled >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/protocol/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webrtc/protocol/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..ff0245b39dad45509f09de41ddc8ed48cc73ffc5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/protocol/w3c-import.log >@@ -0,0 +1,18 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webrtc/protocol/README.txt >+/LayoutTests/imported/w3c/web-platform-tests/webrtc/protocol/video-codecs.https.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/tools/README.md b/LayoutTests/imported/w3c/web-platform-tests/webrtc/tools/README.md >new file mode 100644 >index 0000000000000000000000000000000000000000..68bc284fdfa722567c136e6001aaa476689418a4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/tools/README.md >@@ -0,0 +1,14 @@ >+WebRTC Tools >+============ >+ >+This directory contains a simple Node.js project to aid the development of >+WebRTC tests. >+ >+## Lint >+ >+```bash >+npm run lint >+``` >+ >+Does basic linting of the JavaScript code. Mainly for catching usage of >+undefined variables. >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/tools/package-lock.json b/LayoutTests/imported/w3c/web-platform-tests/webrtc/tools/package-lock.json >new file mode 100644 >index 0000000000000000000000000000000000000000..79e603949cf80053c21ec7d8eb4cb974cf00b3f4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/tools/package-lock.json >@@ -0,0 +1,1213 @@ >+{ >+ "name": "webrtc-testing-tools", >+ "version": "1.0.0", >+ "lockfileVersion": 1, >+ "requires": true, >+ "dependencies": { >+ "acorn": { >+ "version": "5.2.1", >+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", >+ "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", >+ "dev": true >+ }, >+ "acorn-jsx": { >+ "version": "3.0.1", >+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", >+ "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", >+ "dev": true, >+ "requires": { >+ "acorn": "3.3.0" >+ }, >+ "dependencies": { >+ "acorn": { >+ "version": "3.3.0", >+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", >+ "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", >+ "dev": true >+ } >+ } >+ }, >+ "ajv": { >+ "version": "5.3.0", >+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.3.0.tgz", >+ "integrity": "sha1-RBT/dKUIecII7l/cgm4ywwNUnto=", >+ "dev": true, >+ "requires": { >+ "co": "4.6.0", >+ "fast-deep-equal": "1.0.0", >+ "fast-json-stable-stringify": "2.0.0", >+ "json-schema-traverse": "0.3.1" >+ } >+ }, >+ "ajv-keywords": { >+ "version": "2.1.1", >+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", >+ "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", >+ "dev": true >+ }, >+ "ansi-escapes": { >+ "version": "3.0.0", >+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", >+ "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", >+ "dev": true >+ }, >+ "ansi-regex": { >+ "version": "2.1.1", >+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", >+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", >+ "dev": true >+ }, >+ "ansi-styles": { >+ "version": "2.2.1", >+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", >+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", >+ "dev": true >+ }, >+ "argparse": { >+ "version": "1.0.9", >+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", >+ "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", >+ "dev": true, >+ "requires": { >+ "sprintf-js": "1.0.3" >+ } >+ }, >+ "array-union": { >+ "version": "1.0.2", >+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", >+ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", >+ "dev": true, >+ "requires": { >+ "array-uniq": "1.0.3" >+ } >+ }, >+ "array-uniq": { >+ "version": "1.0.3", >+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", >+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", >+ "dev": true >+ }, >+ "arrify": { >+ "version": "1.0.1", >+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", >+ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", >+ "dev": true >+ }, >+ "babel-code-frame": { >+ "version": "6.26.0", >+ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", >+ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", >+ "dev": true, >+ "requires": { >+ "chalk": "1.1.3", >+ "esutils": "2.0.2", >+ "js-tokens": "3.0.2" >+ }, >+ "dependencies": { >+ "chalk": { >+ "version": "1.1.3", >+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", >+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", >+ "dev": true, >+ "requires": { >+ "ansi-styles": "2.2.1", >+ "escape-string-regexp": "1.0.5", >+ "has-ansi": "2.0.0", >+ "strip-ansi": "3.0.1", >+ "supports-color": "2.0.0" >+ } >+ }, >+ "strip-ansi": { >+ "version": "3.0.1", >+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", >+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", >+ "dev": true, >+ "requires": { >+ "ansi-regex": "2.1.1" >+ } >+ } >+ } >+ }, >+ "balanced-match": { >+ "version": "1.0.0", >+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", >+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", >+ "dev": true >+ }, >+ "brace-expansion": { >+ "version": "1.1.8", >+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", >+ "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", >+ "dev": true, >+ "requires": { >+ "balanced-match": "1.0.0", >+ "concat-map": "0.0.1" >+ } >+ }, >+ "caller-path": { >+ "version": "0.1.0", >+ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", >+ "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", >+ "dev": true, >+ "requires": { >+ "callsites": "0.2.0" >+ } >+ }, >+ "callsites": { >+ "version": "0.2.0", >+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", >+ "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", >+ "dev": true >+ }, >+ "chalk": { >+ "version": "2.3.0", >+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", >+ "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", >+ "dev": true, >+ "requires": { >+ "ansi-styles": "3.2.0", >+ "escape-string-regexp": "1.0.5", >+ "supports-color": "4.5.0" >+ }, >+ "dependencies": { >+ "ansi-styles": { >+ "version": "3.2.0", >+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", >+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", >+ "dev": true, >+ "requires": { >+ "color-convert": "1.9.1" >+ } >+ }, >+ "supports-color": { >+ "version": "4.5.0", >+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", >+ "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", >+ "dev": true, >+ "requires": { >+ "has-flag": "2.0.0" >+ } >+ } >+ } >+ }, >+ "chardet": { >+ "version": "0.4.0", >+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.0.tgz", >+ "integrity": "sha1-C74TVaxE16PtSpJXB8TvcPgZD2w=", >+ "dev": true >+ }, >+ "circular-json": { >+ "version": "0.3.3", >+ "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", >+ "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", >+ "dev": true >+ }, >+ "cli-cursor": { >+ "version": "2.1.0", >+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", >+ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", >+ "dev": true, >+ "requires": { >+ "restore-cursor": "2.0.0" >+ } >+ }, >+ "cli-width": { >+ "version": "2.2.0", >+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", >+ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", >+ "dev": true >+ }, >+ "co": { >+ "version": "4.6.0", >+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", >+ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", >+ "dev": true >+ }, >+ "color-convert": { >+ "version": "1.9.1", >+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", >+ "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", >+ "dev": true, >+ "requires": { >+ "color-name": "1.1.3" >+ } >+ }, >+ "color-name": { >+ "version": "1.1.3", >+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", >+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", >+ "dev": true >+ }, >+ "concat-map": { >+ "version": "0.0.1", >+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", >+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", >+ "dev": true >+ }, >+ "concat-stream": { >+ "version": "1.6.0", >+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", >+ "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", >+ "dev": true, >+ "requires": { >+ "inherits": "2.0.3", >+ "readable-stream": "2.3.3", >+ "typedarray": "0.0.6" >+ } >+ }, >+ "core-util-is": { >+ "version": "1.0.2", >+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", >+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", >+ "dev": true >+ }, >+ "cross-spawn": { >+ "version": "5.1.0", >+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", >+ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", >+ "dev": true, >+ "requires": { >+ "lru-cache": "4.1.1", >+ "shebang-command": "1.2.0", >+ "which": "1.3.0" >+ } >+ }, >+ "debug": { >+ "version": "3.1.0", >+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", >+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", >+ "dev": true, >+ "requires": { >+ "ms": "2.0.0" >+ } >+ }, >+ "deep-is": { >+ "version": "0.1.3", >+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", >+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", >+ "dev": true >+ }, >+ "del": { >+ "version": "2.2.2", >+ "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", >+ "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", >+ "dev": true, >+ "requires": { >+ "globby": "5.0.0", >+ "is-path-cwd": "1.0.0", >+ "is-path-in-cwd": "1.0.0", >+ "object-assign": "4.1.1", >+ "pify": "2.3.0", >+ "pinkie-promise": "2.0.1", >+ "rimraf": "2.6.2" >+ } >+ }, >+ "doctrine": { >+ "version": "2.0.0", >+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", >+ "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", >+ "dev": true, >+ "requires": { >+ "esutils": "2.0.2", >+ "isarray": "1.0.0" >+ } >+ }, >+ "dom-serializer": { >+ "version": "0.1.0", >+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", >+ "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", >+ "dev": true, >+ "requires": { >+ "domelementtype": "1.1.3", >+ "entities": "1.1.1" >+ }, >+ "dependencies": { >+ "domelementtype": { >+ "version": "1.1.3", >+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", >+ "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", >+ "dev": true >+ } >+ } >+ }, >+ "domelementtype": { >+ "version": "1.3.0", >+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", >+ "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", >+ "dev": true >+ }, >+ "domhandler": { >+ "version": "2.4.1", >+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz", >+ "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=", >+ "dev": true, >+ "requires": { >+ "domelementtype": "1.3.0" >+ } >+ }, >+ "domutils": { >+ "version": "1.6.2", >+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.6.2.tgz", >+ "integrity": "sha1-GVjMC0yUJuntNn+xyOhUiRsPo/8=", >+ "dev": true, >+ "requires": { >+ "dom-serializer": "0.1.0", >+ "domelementtype": "1.3.0" >+ } >+ }, >+ "entities": { >+ "version": "1.1.1", >+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", >+ "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", >+ "dev": true >+ }, >+ "escape-string-regexp": { >+ "version": "1.0.5", >+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", >+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", >+ "dev": true >+ }, >+ "eslint": { >+ "version": "4.11.0", >+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.11.0.tgz", >+ "integrity": "sha512-UWbhQpaKlm8h5x/VLwm0S1kheMrDj8jPwhnBMjr/Dlo3qqT7MvcN/UfKAR3E1N4lr4YNtOvS4m3hwsrVc/ky7g==", >+ "dev": true, >+ "requires": { >+ "ajv": "5.3.0", >+ "babel-code-frame": "6.26.0", >+ "chalk": "2.3.0", >+ "concat-stream": "1.6.0", >+ "cross-spawn": "5.1.0", >+ "debug": "3.1.0", >+ "doctrine": "2.0.0", >+ "eslint-scope": "3.7.1", >+ "espree": "3.5.2", >+ "esquery": "1.0.0", >+ "estraverse": "4.2.0", >+ "esutils": "2.0.2", >+ "file-entry-cache": "2.0.0", >+ "functional-red-black-tree": "1.0.1", >+ "glob": "7.1.2", >+ "globals": "9.18.0", >+ "ignore": "3.3.7", >+ "imurmurhash": "0.1.4", >+ "inquirer": "3.3.0", >+ "is-resolvable": "1.0.0", >+ "js-yaml": "3.10.0", >+ "json-stable-stringify-without-jsonify": "1.0.1", >+ "levn": "0.3.0", >+ "lodash": "4.17.4", >+ "minimatch": "3.0.4", >+ "mkdirp": "0.5.1", >+ "natural-compare": "1.4.0", >+ "optionator": "0.8.2", >+ "path-is-inside": "1.0.2", >+ "pluralize": "7.0.0", >+ "progress": "2.0.0", >+ "require-uncached": "1.0.3", >+ "semver": "5.4.1", >+ "strip-ansi": "4.0.0", >+ "strip-json-comments": "2.0.1", >+ "table": "4.0.2", >+ "text-table": "0.2.0" >+ } >+ }, >+ "eslint-plugin-html": { >+ "version": "4.0.0", >+ "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-4.0.0.tgz", >+ "integrity": "sha512-xK/909qOTq5JVzuO2jo4a24nQcWhkOBz9dOIkORvB7RxC75a4b6B9wFpBXAl8WDhwJGFDj5gBDRN+/L3kK/ghw==", >+ "dev": true, >+ "requires": { >+ "htmlparser2": "3.9.2" >+ } >+ }, >+ "eslint-scope": { >+ "version": "3.7.1", >+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", >+ "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", >+ "dev": true, >+ "requires": { >+ "esrecurse": "4.2.0", >+ "estraverse": "4.2.0" >+ } >+ }, >+ "espree": { >+ "version": "3.5.2", >+ "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", >+ "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==", >+ "dev": true, >+ "requires": { >+ "acorn": "5.2.1", >+ "acorn-jsx": "3.0.1" >+ } >+ }, >+ "esprima": { >+ "version": "4.0.0", >+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", >+ "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", >+ "dev": true >+ }, >+ "esquery": { >+ "version": "1.0.0", >+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", >+ "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", >+ "dev": true, >+ "requires": { >+ "estraverse": "4.2.0" >+ } >+ }, >+ "esrecurse": { >+ "version": "4.2.0", >+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", >+ "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", >+ "dev": true, >+ "requires": { >+ "estraverse": "4.2.0", >+ "object-assign": "4.1.1" >+ } >+ }, >+ "estraverse": { >+ "version": "4.2.0", >+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", >+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", >+ "dev": true >+ }, >+ "esutils": { >+ "version": "2.0.2", >+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", >+ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", >+ "dev": true >+ }, >+ "external-editor": { >+ "version": "2.1.0", >+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", >+ "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", >+ "dev": true, >+ "requires": { >+ "chardet": "0.4.0", >+ "iconv-lite": "0.4.19", >+ "tmp": "0.0.33" >+ } >+ }, >+ "fast-deep-equal": { >+ "version": "1.0.0", >+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", >+ "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", >+ "dev": true >+ }, >+ "fast-json-stable-stringify": { >+ "version": "2.0.0", >+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", >+ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", >+ "dev": true >+ }, >+ "fast-levenshtein": { >+ "version": "2.0.6", >+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", >+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", >+ "dev": true >+ }, >+ "figures": { >+ "version": "2.0.0", >+ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", >+ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", >+ "dev": true, >+ "requires": { >+ "escape-string-regexp": "1.0.5" >+ } >+ }, >+ "file-entry-cache": { >+ "version": "2.0.0", >+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", >+ "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", >+ "dev": true, >+ "requires": { >+ "flat-cache": "1.3.0", >+ "object-assign": "4.1.1" >+ } >+ }, >+ "flat-cache": { >+ "version": "1.3.0", >+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", >+ "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", >+ "dev": true, >+ "requires": { >+ "circular-json": "0.3.3", >+ "del": "2.2.2", >+ "graceful-fs": "4.1.11", >+ "write": "0.2.1" >+ } >+ }, >+ "fs.realpath": { >+ "version": "1.0.0", >+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", >+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", >+ "dev": true >+ }, >+ "functional-red-black-tree": { >+ "version": "1.0.1", >+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", >+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", >+ "dev": true >+ }, >+ "glob": { >+ "version": "7.1.2", >+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", >+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", >+ "dev": true, >+ "requires": { >+ "fs.realpath": "1.0.0", >+ "inflight": "1.0.6", >+ "inherits": "2.0.3", >+ "minimatch": "3.0.4", >+ "once": "1.4.0", >+ "path-is-absolute": "1.0.1" >+ } >+ }, >+ "globals": { >+ "version": "9.18.0", >+ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", >+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", >+ "dev": true >+ }, >+ "globby": { >+ "version": "5.0.0", >+ "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", >+ "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", >+ "dev": true, >+ "requires": { >+ "array-union": "1.0.2", >+ "arrify": "1.0.1", >+ "glob": "7.1.2", >+ "object-assign": "4.1.1", >+ "pify": "2.3.0", >+ "pinkie-promise": "2.0.1" >+ } >+ }, >+ "graceful-fs": { >+ "version": "4.1.11", >+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", >+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", >+ "dev": true >+ }, >+ "has-ansi": { >+ "version": "2.0.0", >+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", >+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", >+ "dev": true, >+ "requires": { >+ "ansi-regex": "2.1.1" >+ } >+ }, >+ "has-flag": { >+ "version": "2.0.0", >+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", >+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", >+ "dev": true >+ }, >+ "htmlparser2": { >+ "version": "3.9.2", >+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz", >+ "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=", >+ "dev": true, >+ "requires": { >+ "domelementtype": "1.3.0", >+ "domhandler": "2.4.1", >+ "domutils": "1.6.2", >+ "entities": "1.1.1", >+ "inherits": "2.0.3", >+ "readable-stream": "2.3.3" >+ } >+ }, >+ "iconv-lite": { >+ "version": "0.4.19", >+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", >+ "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", >+ "dev": true >+ }, >+ "ignore": { >+ "version": "3.3.7", >+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", >+ "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", >+ "dev": true >+ }, >+ "imurmurhash": { >+ "version": "0.1.4", >+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", >+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", >+ "dev": true >+ }, >+ "inflight": { >+ "version": "1.0.6", >+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", >+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", >+ "dev": true, >+ "requires": { >+ "once": "1.4.0", >+ "wrappy": "1.0.2" >+ } >+ }, >+ "inherits": { >+ "version": "2.0.3", >+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", >+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", >+ "dev": true >+ }, >+ "inquirer": { >+ "version": "3.3.0", >+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", >+ "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", >+ "dev": true, >+ "requires": { >+ "ansi-escapes": "3.0.0", >+ "chalk": "2.3.0", >+ "cli-cursor": "2.1.0", >+ "cli-width": "2.2.0", >+ "external-editor": "2.1.0", >+ "figures": "2.0.0", >+ "lodash": "4.17.4", >+ "mute-stream": "0.0.7", >+ "run-async": "2.3.0", >+ "rx-lite": "4.0.8", >+ "rx-lite-aggregates": "4.0.8", >+ "string-width": "2.1.1", >+ "strip-ansi": "4.0.0", >+ "through": "2.3.8" >+ } >+ }, >+ "is-fullwidth-code-point": { >+ "version": "2.0.0", >+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", >+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", >+ "dev": true >+ }, >+ "is-path-cwd": { >+ "version": "1.0.0", >+ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", >+ "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", >+ "dev": true >+ }, >+ "is-path-in-cwd": { >+ "version": "1.0.0", >+ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", >+ "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", >+ "dev": true, >+ "requires": { >+ "is-path-inside": "1.0.0" >+ } >+ }, >+ "is-path-inside": { >+ "version": "1.0.0", >+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", >+ "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", >+ "dev": true, >+ "requires": { >+ "path-is-inside": "1.0.2" >+ } >+ }, >+ "is-promise": { >+ "version": "2.1.0", >+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", >+ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", >+ "dev": true >+ }, >+ "is-resolvable": { >+ "version": "1.0.0", >+ "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", >+ "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", >+ "dev": true, >+ "requires": { >+ "tryit": "1.0.3" >+ } >+ }, >+ "isarray": { >+ "version": "1.0.0", >+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", >+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", >+ "dev": true >+ }, >+ "isexe": { >+ "version": "2.0.0", >+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", >+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", >+ "dev": true >+ }, >+ "js-tokens": { >+ "version": "3.0.2", >+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", >+ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", >+ "dev": true >+ }, >+ "js-yaml": { >+ "version": "3.10.0", >+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", >+ "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", >+ "dev": true, >+ "requires": { >+ "argparse": "1.0.9", >+ "esprima": "4.0.0" >+ } >+ }, >+ "json-schema-traverse": { >+ "version": "0.3.1", >+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", >+ "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", >+ "dev": true >+ }, >+ "json-stable-stringify-without-jsonify": { >+ "version": "1.0.1", >+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", >+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", >+ "dev": true >+ }, >+ "levn": { >+ "version": "0.3.0", >+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", >+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", >+ "dev": true, >+ "requires": { >+ "prelude-ls": "1.1.2", >+ "type-check": "0.3.2" >+ } >+ }, >+ "lodash": { >+ "version": "4.17.4", >+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", >+ "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", >+ "dev": true >+ }, >+ "lru-cache": { >+ "version": "4.1.1", >+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", >+ "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", >+ "dev": true, >+ "requires": { >+ "pseudomap": "1.0.2", >+ "yallist": "2.1.2" >+ } >+ }, >+ "mimic-fn": { >+ "version": "1.1.0", >+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", >+ "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", >+ "dev": true >+ }, >+ "minimatch": { >+ "version": "3.0.4", >+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", >+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", >+ "dev": true, >+ "requires": { >+ "brace-expansion": "1.1.8" >+ } >+ }, >+ "minimist": { >+ "version": "0.0.8", >+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", >+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", >+ "dev": true >+ }, >+ "mkdirp": { >+ "version": "0.5.1", >+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", >+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", >+ "dev": true, >+ "requires": { >+ "minimist": "0.0.8" >+ } >+ }, >+ "ms": { >+ "version": "2.0.0", >+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", >+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", >+ "dev": true >+ }, >+ "mute-stream": { >+ "version": "0.0.7", >+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", >+ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", >+ "dev": true >+ }, >+ "natural-compare": { >+ "version": "1.4.0", >+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", >+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", >+ "dev": true >+ }, >+ "object-assign": { >+ "version": "4.1.1", >+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", >+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", >+ "dev": true >+ }, >+ "once": { >+ "version": "1.4.0", >+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", >+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", >+ "dev": true, >+ "requires": { >+ "wrappy": "1.0.2" >+ } >+ }, >+ "onetime": { >+ "version": "2.0.1", >+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", >+ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", >+ "dev": true, >+ "requires": { >+ "mimic-fn": "1.1.0" >+ } >+ }, >+ "optionator": { >+ "version": "0.8.2", >+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", >+ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", >+ "dev": true, >+ "requires": { >+ "deep-is": "0.1.3", >+ "fast-levenshtein": "2.0.6", >+ "levn": "0.3.0", >+ "prelude-ls": "1.1.2", >+ "type-check": "0.3.2", >+ "wordwrap": "1.0.0" >+ } >+ }, >+ "os-tmpdir": { >+ "version": "1.0.2", >+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", >+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", >+ "dev": true >+ }, >+ "path-is-absolute": { >+ "version": "1.0.1", >+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", >+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", >+ "dev": true >+ }, >+ "path-is-inside": { >+ "version": "1.0.2", >+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", >+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", >+ "dev": true >+ }, >+ "pify": { >+ "version": "2.3.0", >+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", >+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", >+ "dev": true >+ }, >+ "pinkie": { >+ "version": "2.0.4", >+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", >+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", >+ "dev": true >+ }, >+ "pinkie-promise": { >+ "version": "2.0.1", >+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", >+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", >+ "dev": true, >+ "requires": { >+ "pinkie": "2.0.4" >+ } >+ }, >+ "pluralize": { >+ "version": "7.0.0", >+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", >+ "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", >+ "dev": true >+ }, >+ "prelude-ls": { >+ "version": "1.1.2", >+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", >+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", >+ "dev": true >+ }, >+ "process-nextick-args": { >+ "version": "1.0.7", >+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", >+ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", >+ "dev": true >+ }, >+ "progress": { >+ "version": "2.0.0", >+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", >+ "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", >+ "dev": true >+ }, >+ "pseudomap": { >+ "version": "1.0.2", >+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", >+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", >+ "dev": true >+ }, >+ "readable-stream": { >+ "version": "2.3.3", >+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", >+ "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", >+ "dev": true, >+ "requires": { >+ "core-util-is": "1.0.2", >+ "inherits": "2.0.3", >+ "isarray": "1.0.0", >+ "process-nextick-args": "1.0.7", >+ "safe-buffer": "5.1.1", >+ "string_decoder": "1.0.3", >+ "util-deprecate": "1.0.2" >+ } >+ }, >+ "require-uncached": { >+ "version": "1.0.3", >+ "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", >+ "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", >+ "dev": true, >+ "requires": { >+ "caller-path": "0.1.0", >+ "resolve-from": "1.0.1" >+ } >+ }, >+ "resolve-from": { >+ "version": "1.0.1", >+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", >+ "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", >+ "dev": true >+ }, >+ "restore-cursor": { >+ "version": "2.0.0", >+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", >+ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", >+ "dev": true, >+ "requires": { >+ "onetime": "2.0.1", >+ "signal-exit": "3.0.2" >+ } >+ }, >+ "rimraf": { >+ "version": "2.6.2", >+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", >+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", >+ "dev": true, >+ "requires": { >+ "glob": "7.1.2" >+ } >+ }, >+ "run-async": { >+ "version": "2.3.0", >+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", >+ "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", >+ "dev": true, >+ "requires": { >+ "is-promise": "2.1.0" >+ } >+ }, >+ "rx-lite": { >+ "version": "4.0.8", >+ "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", >+ "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", >+ "dev": true >+ }, >+ "rx-lite-aggregates": { >+ "version": "4.0.8", >+ "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", >+ "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", >+ "dev": true, >+ "requires": { >+ "rx-lite": "4.0.8" >+ } >+ }, >+ "safe-buffer": { >+ "version": "5.1.1", >+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", >+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", >+ "dev": true >+ }, >+ "semver": { >+ "version": "5.4.1", >+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", >+ "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", >+ "dev": true >+ }, >+ "shebang-command": { >+ "version": "1.2.0", >+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", >+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", >+ "dev": true, >+ "requires": { >+ "shebang-regex": "1.0.0" >+ } >+ }, >+ "shebang-regex": { >+ "version": "1.0.0", >+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", >+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", >+ "dev": true >+ }, >+ "signal-exit": { >+ "version": "3.0.2", >+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", >+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", >+ "dev": true >+ }, >+ "slice-ansi": { >+ "version": "1.0.0", >+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", >+ "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", >+ "dev": true, >+ "requires": { >+ "is-fullwidth-code-point": "2.0.0" >+ } >+ }, >+ "sprintf-js": { >+ "version": "1.0.3", >+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", >+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", >+ "dev": true >+ }, >+ "string-width": { >+ "version": "2.1.1", >+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", >+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", >+ "dev": true, >+ "requires": { >+ "is-fullwidth-code-point": "2.0.0", >+ "strip-ansi": "4.0.0" >+ } >+ }, >+ "string_decoder": { >+ "version": "1.0.3", >+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", >+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", >+ "dev": true, >+ "requires": { >+ "safe-buffer": "5.1.1" >+ } >+ }, >+ "strip-ansi": { >+ "version": "4.0.0", >+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", >+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", >+ "dev": true, >+ "requires": { >+ "ansi-regex": "3.0.0" >+ }, >+ "dependencies": { >+ "ansi-regex": { >+ "version": "3.0.0", >+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", >+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", >+ "dev": true >+ } >+ } >+ }, >+ "strip-json-comments": { >+ "version": "2.0.1", >+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", >+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", >+ "dev": true >+ }, >+ "supports-color": { >+ "version": "2.0.0", >+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", >+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", >+ "dev": true >+ }, >+ "table": { >+ "version": "4.0.2", >+ "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", >+ "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", >+ "dev": true, >+ "requires": { >+ "ajv": "5.3.0", >+ "ajv-keywords": "2.1.1", >+ "chalk": "2.3.0", >+ "lodash": "4.17.4", >+ "slice-ansi": "1.0.0", >+ "string-width": "2.1.1" >+ } >+ }, >+ "text-table": { >+ "version": "0.2.0", >+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", >+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", >+ "dev": true >+ }, >+ "through": { >+ "version": "2.3.8", >+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", >+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", >+ "dev": true >+ }, >+ "tmp": { >+ "version": "0.0.33", >+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", >+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", >+ "dev": true, >+ "requires": { >+ "os-tmpdir": "1.0.2" >+ } >+ }, >+ "tryit": { >+ "version": "1.0.3", >+ "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", >+ "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", >+ "dev": true >+ }, >+ "type-check": { >+ "version": "0.3.2", >+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", >+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", >+ "dev": true, >+ "requires": { >+ "prelude-ls": "1.1.2" >+ } >+ }, >+ "typedarray": { >+ "version": "0.0.6", >+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", >+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", >+ "dev": true >+ }, >+ "util-deprecate": { >+ "version": "1.0.2", >+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", >+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", >+ "dev": true >+ }, >+ "which": { >+ "version": "1.3.0", >+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", >+ "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", >+ "dev": true, >+ "requires": { >+ "isexe": "2.0.0" >+ } >+ }, >+ "wordwrap": { >+ "version": "1.0.0", >+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", >+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", >+ "dev": true >+ }, >+ "wrappy": { >+ "version": "1.0.2", >+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", >+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", >+ "dev": true >+ }, >+ "write": { >+ "version": "0.2.1", >+ "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", >+ "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", >+ "dev": true, >+ "requires": { >+ "mkdirp": "0.5.1" >+ } >+ }, >+ "yallist": { >+ "version": "2.1.2", >+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", >+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", >+ "dev": true >+ } >+ } >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/tools/package.json b/LayoutTests/imported/w3c/web-platform-tests/webrtc/tools/package.json >new file mode 100644 >index 0000000000000000000000000000000000000000..70515d8b715f239636d7a50f253e17eaaaa815c4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/tools/package.json >@@ -0,0 +1,14 @@ >+{ >+ "name": "webrtc-testing-tools", >+ "version": "1.0.0", >+ "description": "Tools for WebRTC testing", >+ "scripts": { >+ "lint": "eslint -c .eslintrc.js ../*.html ../*.js" >+ }, >+ "devDependencies": { >+ "eslint": "^4.11.0", >+ "eslint-plugin-html": "^4.0.0" >+ }, >+ "license": "BSD", >+ "private": true >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/tools/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webrtc/tools/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..2367e15d7696bf043bdff964dfdf1fb7eb4fbc32 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/tools/w3c-import.log >@@ -0,0 +1,19 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webrtc/tools/README.md >+/LayoutTests/imported/w3c/web-platform-tests/webrtc/tools/package-lock.json >+/LayoutTests/imported/w3c/web-platform-tests/webrtc/tools/package.json >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webrtc/w3c-import.log >index fb9beaeabae25343effa93c68cab985b55523f4c..43b82596e0b825f6931e3e6b30a848c8bd3b0bd9 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc/w3c-import.log >@@ -33,6 +33,7 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDtlsTransport-getRemoteCertificates.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCIceCandidate-constructor.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCIceTransport.html >+/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-add-track-no-deadlock.https.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-addIceCandidate.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-addTrack.https.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-addTransceiver.html >@@ -41,10 +42,11 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-constructor.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-createAnswer.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-createDataChannel.html >+/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-createOffer-offerToReceive.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-createOffer.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-generateCertificate.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-getDefaultIceServers.html >-/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-getIdentityAssertion.html >+/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-getIdentityAssertion.sub.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-getStats.https.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-getTransceivers.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-helper.js >@@ -64,8 +66,11 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-answer.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-offer.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-pranswer.html >+/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-replaceTrack.https.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-rollback.html >+/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription.html >+/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-track-stats.https.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnectionIceEvent-constructor.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpCapabilities-helper.js > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpParameters-codecs.html >@@ -87,13 +92,14 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpTransceiver-setCodecPreferences.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpTransceiver-setDirection.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCSctpTransport-constructor.html >+/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCSctpTransport-maxMessageSize.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCStats-helper.js > /LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCTrackEvent-constructor.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/datachannel-emptystring.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/dictionary-helper.js > /LayoutTests/imported/w3c/web-platform-tests/webrtc/getstats.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/historical.html >-/LayoutTests/imported/w3c/web-platform-tests/webrtc/identity-helper.js >+/LayoutTests/imported/w3c/web-platform-tests/webrtc/identity-helper.sub.js > /LayoutTests/imported/w3c/web-platform-tests/webrtc/interfaces.https.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/no-media-call.html > /LayoutTests/imported/w3c/web-platform-tests/webrtc/promises-call.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/OWNERS b/LayoutTests/imported/w3c/web-platform-tests/webxr/OWNERS >new file mode 100644 >index 0000000000000000000000000000000000000000..8151e0df402eeff505c260fec28a7fec931e2402 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/OWNERS >@@ -0,0 +1,3 @@ >+@toji >+@paezagon >+@klausw >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/interfaces.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/interfaces.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d0e4e380cccc61f99b2f2c4a29429f0a12e0e3e9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/interfaces.https-expected.txt >@@ -0,0 +1,202 @@ >+CONSOLE MESSAGE: line 440: callback not yet supported >+CONSOLE MESSAGE: line 440: callback not yet supported >+ >+PASS Test IDL implementation of WebXR API >+FAIL Navigator interface: attribute xr assert_true: The prototype object must have a property "xr" expected true got false >+PASS Unscopable handled correctly for xr property on Navigator >+FAIL Navigator interface: navigator must inherit property "xr" with the proper type assert_inherits: property "xr" not found in prototype chain >+FAIL XR interface: existence and properties of interface object assert_own_property: self does not have own property "XR" expected property "XR" missing >+FAIL XR interface object length assert_own_property: self does not have own property "XR" expected property "XR" missing >+FAIL XR interface object name assert_own_property: self does not have own property "XR" expected property "XR" missing >+FAIL XR interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XR" expected property "XR" missing >+FAIL XR interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XR" expected property "XR" missing >+FAIL XR interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XR" expected property "XR" missing >+FAIL XR interface: operation requestDevice() assert_own_property: self does not have own property "XR" expected property "XR" missing >+PASS Unscopable handled correctly for requestDevice() on XR >+FAIL XR interface: attribute ondevicechange assert_own_property: self does not have own property "XR" expected property "XR" missing >+PASS Unscopable handled correctly for ondevicechange property on XR >+FAIL XRDevice interface: existence and properties of interface object assert_own_property: self does not have own property "XRDevice" expected property "XRDevice" missing >+FAIL XRDevice interface object length assert_own_property: self does not have own property "XRDevice" expected property "XRDevice" missing >+FAIL XRDevice interface object name assert_own_property: self does not have own property "XRDevice" expected property "XRDevice" missing >+FAIL XRDevice interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRDevice" expected property "XRDevice" missing >+FAIL XRDevice interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRDevice" expected property "XRDevice" missing >+FAIL XRDevice interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRDevice" expected property "XRDevice" missing >+FAIL XRDevice interface: operation supportsSession(XRSessionCreationOptions) assert_own_property: self does not have own property "XRDevice" expected property "XRDevice" missing >+PASS Unscopable handled correctly for supportsSession(XRSessionCreationOptions) on XRDevice >+FAIL XRDevice interface: operation requestSession(XRSessionCreationOptions) assert_own_property: self does not have own property "XRDevice" expected property "XRDevice" missing >+PASS Unscopable handled correctly for requestSession(XRSessionCreationOptions) on XRDevice >+FAIL XRSession interface: existence and properties of interface object assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+FAIL XRSession interface object length assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+FAIL XRSession interface object name assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+FAIL XRSession interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+FAIL XRSession interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+FAIL XRSession interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+FAIL XRSession interface: attribute device assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+PASS Unscopable handled correctly for device property on XRSession >+FAIL XRSession interface: attribute exclusive assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+PASS Unscopable handled correctly for exclusive property on XRSession >+FAIL XRSession interface: attribute outputContext assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+PASS Unscopable handled correctly for outputContext property on XRSession >+FAIL XRSession interface: attribute depthNear assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+PASS Unscopable handled correctly for depthNear property on XRSession >+FAIL XRSession interface: attribute depthFar assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+PASS Unscopable handled correctly for depthFar property on XRSession >+FAIL XRSession interface: attribute baseLayer assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+PASS Unscopable handled correctly for baseLayer property on XRSession >+FAIL XRSession interface: operation requestFrameOfReference(XRFrameOfReferenceType, XRFrameOfReferenceOptions) assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+PASS Unscopable handled correctly for requestFrameOfReference(XRFrameOfReferenceType, XRFrameOfReferenceOptions) on XRSession >+FAIL XRSession interface: operation requestAnimationFrame(XRFrameRequestCallback) assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+PASS Unscopable handled correctly for requestAnimationFrame(XRFrameRequestCallback) on XRSession >+FAIL XRSession interface: operation cancelAnimationFrame(long) assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+PASS Unscopable handled correctly for cancelAnimationFrame(long) on XRSession >+FAIL XRSession interface: operation end() assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+PASS Unscopable handled correctly for end() on XRSession >+FAIL XRSession interface: attribute onblur assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+PASS Unscopable handled correctly for onblur property on XRSession >+FAIL XRSession interface: attribute onfocus assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+PASS Unscopable handled correctly for onfocus property on XRSession >+FAIL XRSession interface: attribute onresetpose assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+PASS Unscopable handled correctly for onresetpose property on XRSession >+FAIL XRSession interface: attribute onend assert_own_property: self does not have own property "XRSession" expected property "XRSession" missing >+PASS Unscopable handled correctly for onend property on XRSession >+FAIL XRPresentationFrame interface: existence and properties of interface object assert_own_property: self does not have own property "XRPresentationFrame" expected property "XRPresentationFrame" missing >+FAIL XRPresentationFrame interface object length assert_own_property: self does not have own property "XRPresentationFrame" expected property "XRPresentationFrame" missing >+FAIL XRPresentationFrame interface object name assert_own_property: self does not have own property "XRPresentationFrame" expected property "XRPresentationFrame" missing >+FAIL XRPresentationFrame interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRPresentationFrame" expected property "XRPresentationFrame" missing >+FAIL XRPresentationFrame interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRPresentationFrame" expected property "XRPresentationFrame" missing >+FAIL XRPresentationFrame interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRPresentationFrame" expected property "XRPresentationFrame" missing >+FAIL XRPresentationFrame interface: attribute views assert_own_property: self does not have own property "XRPresentationFrame" expected property "XRPresentationFrame" missing >+PASS Unscopable handled correctly for views property on XRPresentationFrame >+FAIL XRPresentationFrame interface: operation getDevicePose(XRCoordinateSystem) assert_own_property: self does not have own property "XRPresentationFrame" expected property "XRPresentationFrame" missing >+PASS Unscopable handled correctly for getDevicePose(XRCoordinateSystem) on XRPresentationFrame >+FAIL XRCoordinateSystem interface: existence and properties of interface object assert_own_property: self does not have own property "XRCoordinateSystem" expected property "XRCoordinateSystem" missing >+FAIL XRCoordinateSystem interface object length assert_own_property: self does not have own property "XRCoordinateSystem" expected property "XRCoordinateSystem" missing >+FAIL XRCoordinateSystem interface object name assert_own_property: self does not have own property "XRCoordinateSystem" expected property "XRCoordinateSystem" missing >+FAIL XRCoordinateSystem interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRCoordinateSystem" expected property "XRCoordinateSystem" missing >+FAIL XRCoordinateSystem interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRCoordinateSystem" expected property "XRCoordinateSystem" missing >+FAIL XRCoordinateSystem interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRCoordinateSystem" expected property "XRCoordinateSystem" missing >+FAIL XRCoordinateSystem interface: operation getTransformTo(XRCoordinateSystem) assert_own_property: self does not have own property "XRCoordinateSystem" expected property "XRCoordinateSystem" missing >+PASS Unscopable handled correctly for getTransformTo(XRCoordinateSystem) on XRCoordinateSystem >+FAIL XRFrameOfReference interface: existence and properties of interface object assert_own_property: self does not have own property "XRFrameOfReference" expected property "XRFrameOfReference" missing >+FAIL XRFrameOfReference interface object length assert_own_property: self does not have own property "XRFrameOfReference" expected property "XRFrameOfReference" missing >+FAIL XRFrameOfReference interface object name assert_own_property: self does not have own property "XRFrameOfReference" expected property "XRFrameOfReference" missing >+FAIL XRFrameOfReference interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRFrameOfReference" expected property "XRFrameOfReference" missing >+FAIL XRFrameOfReference interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRFrameOfReference" expected property "XRFrameOfReference" missing >+FAIL XRFrameOfReference interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRFrameOfReference" expected property "XRFrameOfReference" missing >+FAIL XRFrameOfReference interface: attribute bounds assert_own_property: self does not have own property "XRFrameOfReference" expected property "XRFrameOfReference" missing >+PASS Unscopable handled correctly for bounds property on XRFrameOfReference >+FAIL XRFrameOfReference interface: attribute emulatedHeight assert_own_property: self does not have own property "XRFrameOfReference" expected property "XRFrameOfReference" missing >+PASS Unscopable handled correctly for emulatedHeight property on XRFrameOfReference >+FAIL XRFrameOfReference interface: attribute onboundschange assert_own_property: self does not have own property "XRFrameOfReference" expected property "XRFrameOfReference" missing >+PASS Unscopable handled correctly for onboundschange property on XRFrameOfReference >+FAIL XRStageBounds interface: existence and properties of interface object assert_own_property: self does not have own property "XRStageBounds" expected property "XRStageBounds" missing >+FAIL XRStageBounds interface object length assert_own_property: self does not have own property "XRStageBounds" expected property "XRStageBounds" missing >+FAIL XRStageBounds interface object name assert_own_property: self does not have own property "XRStageBounds" expected property "XRStageBounds" missing >+FAIL XRStageBounds interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRStageBounds" expected property "XRStageBounds" missing >+FAIL XRStageBounds interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRStageBounds" expected property "XRStageBounds" missing >+FAIL XRStageBounds interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRStageBounds" expected property "XRStageBounds" missing >+FAIL XRStageBounds interface: attribute geometry assert_own_property: self does not have own property "XRStageBounds" expected property "XRStageBounds" missing >+PASS Unscopable handled correctly for geometry property on XRStageBounds >+FAIL XRStageBoundsPoint interface: existence and properties of interface object assert_own_property: self does not have own property "XRStageBoundsPoint" expected property "XRStageBoundsPoint" missing >+FAIL XRStageBoundsPoint interface object length assert_own_property: self does not have own property "XRStageBoundsPoint" expected property "XRStageBoundsPoint" missing >+FAIL XRStageBoundsPoint interface object name assert_own_property: self does not have own property "XRStageBoundsPoint" expected property "XRStageBoundsPoint" missing >+FAIL XRStageBoundsPoint interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRStageBoundsPoint" expected property "XRStageBoundsPoint" missing >+FAIL XRStageBoundsPoint interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRStageBoundsPoint" expected property "XRStageBoundsPoint" missing >+FAIL XRStageBoundsPoint interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRStageBoundsPoint" expected property "XRStageBoundsPoint" missing >+FAIL XRStageBoundsPoint interface: attribute x assert_own_property: self does not have own property "XRStageBoundsPoint" expected property "XRStageBoundsPoint" missing >+PASS Unscopable handled correctly for x property on XRStageBoundsPoint >+FAIL XRStageBoundsPoint interface: attribute z assert_own_property: self does not have own property "XRStageBoundsPoint" expected property "XRStageBoundsPoint" missing >+PASS Unscopable handled correctly for z property on XRStageBoundsPoint >+FAIL XRView interface: existence and properties of interface object assert_own_property: self does not have own property "XRView" expected property "XRView" missing >+FAIL XRView interface object length assert_own_property: self does not have own property "XRView" expected property "XRView" missing >+FAIL XRView interface object name assert_own_property: self does not have own property "XRView" expected property "XRView" missing >+FAIL XRView interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRView" expected property "XRView" missing >+FAIL XRView interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRView" expected property "XRView" missing >+FAIL XRView interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRView" expected property "XRView" missing >+FAIL XRView interface: attribute eye assert_own_property: self does not have own property "XRView" expected property "XRView" missing >+PASS Unscopable handled correctly for eye property on XRView >+FAIL XRView interface: attribute projectionMatrix assert_own_property: self does not have own property "XRView" expected property "XRView" missing >+PASS Unscopable handled correctly for projectionMatrix property on XRView >+FAIL XRViewport interface: existence and properties of interface object assert_own_property: self does not have own property "XRViewport" expected property "XRViewport" missing >+FAIL XRViewport interface object length assert_own_property: self does not have own property "XRViewport" expected property "XRViewport" missing >+FAIL XRViewport interface object name assert_own_property: self does not have own property "XRViewport" expected property "XRViewport" missing >+FAIL XRViewport interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRViewport" expected property "XRViewport" missing >+FAIL XRViewport interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRViewport" expected property "XRViewport" missing >+FAIL XRViewport interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRViewport" expected property "XRViewport" missing >+FAIL XRViewport interface: attribute x assert_own_property: self does not have own property "XRViewport" expected property "XRViewport" missing >+PASS Unscopable handled correctly for x property on XRViewport >+FAIL XRViewport interface: attribute y assert_own_property: self does not have own property "XRViewport" expected property "XRViewport" missing >+PASS Unscopable handled correctly for y property on XRViewport >+FAIL XRViewport interface: attribute width assert_own_property: self does not have own property "XRViewport" expected property "XRViewport" missing >+PASS Unscopable handled correctly for width property on XRViewport >+FAIL XRViewport interface: attribute height assert_own_property: self does not have own property "XRViewport" expected property "XRViewport" missing >+PASS Unscopable handled correctly for height property on XRViewport >+FAIL XRDevicePose interface: existence and properties of interface object assert_own_property: self does not have own property "XRDevicePose" expected property "XRDevicePose" missing >+FAIL XRDevicePose interface object length assert_own_property: self does not have own property "XRDevicePose" expected property "XRDevicePose" missing >+FAIL XRDevicePose interface object name assert_own_property: self does not have own property "XRDevicePose" expected property "XRDevicePose" missing >+FAIL XRDevicePose interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRDevicePose" expected property "XRDevicePose" missing >+FAIL XRDevicePose interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRDevicePose" expected property "XRDevicePose" missing >+FAIL XRDevicePose interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRDevicePose" expected property "XRDevicePose" missing >+FAIL XRDevicePose interface: attribute poseModelMatrix assert_own_property: self does not have own property "XRDevicePose" expected property "XRDevicePose" missing >+PASS Unscopable handled correctly for poseModelMatrix property on XRDevicePose >+FAIL XRDevicePose interface: operation getViewMatrix(XRView) assert_own_property: self does not have own property "XRDevicePose" expected property "XRDevicePose" missing >+PASS Unscopable handled correctly for getViewMatrix(XRView) on XRDevicePose >+FAIL XRLayer interface: existence and properties of interface object assert_own_property: self does not have own property "XRLayer" expected property "XRLayer" missing >+FAIL XRLayer interface object length assert_own_property: self does not have own property "XRLayer" expected property "XRLayer" missing >+FAIL XRLayer interface object name assert_own_property: self does not have own property "XRLayer" expected property "XRLayer" missing >+FAIL XRLayer interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRLayer" expected property "XRLayer" missing >+FAIL XRLayer interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRLayer" expected property "XRLayer" missing >+FAIL XRLayer interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRLayer" expected property "XRLayer" missing >+FAIL XRWebGLLayer interface: existence and properties of interface object assert_own_property: self does not have own property "XRWebGLLayer" expected property "XRWebGLLayer" missing >+FAIL XRWebGLLayer interface object length assert_own_property: self does not have own property "XRWebGLLayer" expected property "XRWebGLLayer" missing >+FAIL XRWebGLLayer interface object name assert_own_property: self does not have own property "XRWebGLLayer" expected property "XRWebGLLayer" missing >+FAIL XRWebGLLayer interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRWebGLLayer" expected property "XRWebGLLayer" missing >+FAIL XRWebGLLayer interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRWebGLLayer" expected property "XRWebGLLayer" missing >+FAIL XRWebGLLayer interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRWebGLLayer" expected property "XRWebGLLayer" missing >+FAIL XRWebGLLayer interface: attribute context assert_own_property: self does not have own property "XRWebGLLayer" expected property "XRWebGLLayer" missing >+PASS Unscopable handled correctly for context property on XRWebGLLayer >+FAIL XRWebGLLayer interface: attribute antialias assert_own_property: self does not have own property "XRWebGLLayer" expected property "XRWebGLLayer" missing >+PASS Unscopable handled correctly for antialias property on XRWebGLLayer >+FAIL XRWebGLLayer interface: attribute depth assert_own_property: self does not have own property "XRWebGLLayer" expected property "XRWebGLLayer" missing >+PASS Unscopable handled correctly for depth property on XRWebGLLayer >+FAIL XRWebGLLayer interface: attribute stencil assert_own_property: self does not have own property "XRWebGLLayer" expected property "XRWebGLLayer" missing >+PASS Unscopable handled correctly for stencil property on XRWebGLLayer >+FAIL XRWebGLLayer interface: attribute alpha assert_own_property: self does not have own property "XRWebGLLayer" expected property "XRWebGLLayer" missing >+PASS Unscopable handled correctly for alpha property on XRWebGLLayer >+FAIL XRWebGLLayer interface: attribute multiview assert_own_property: self does not have own property "XRWebGLLayer" expected property "XRWebGLLayer" missing >+PASS Unscopable handled correctly for multiview property on XRWebGLLayer >+FAIL XRWebGLLayer interface: attribute framebuffer assert_own_property: self does not have own property "XRWebGLLayer" expected property "XRWebGLLayer" missing >+PASS Unscopable handled correctly for framebuffer property on XRWebGLLayer >+FAIL XRWebGLLayer interface: attribute framebufferWidth assert_own_property: self does not have own property "XRWebGLLayer" expected property "XRWebGLLayer" missing >+PASS Unscopable handled correctly for framebufferWidth property on XRWebGLLayer >+FAIL XRWebGLLayer interface: attribute framebufferHeight assert_own_property: self does not have own property "XRWebGLLayer" expected property "XRWebGLLayer" missing >+PASS Unscopable handled correctly for framebufferHeight property on XRWebGLLayer >+FAIL XRWebGLLayer interface: operation getViewport(XRView) assert_own_property: self does not have own property "XRWebGLLayer" expected property "XRWebGLLayer" missing >+PASS Unscopable handled correctly for getViewport(XRView) on XRWebGLLayer >+FAIL XRWebGLLayer interface: operation requestViewportScaling(double) assert_own_property: self does not have own property "XRWebGLLayer" expected property "XRWebGLLayer" missing >+PASS Unscopable handled correctly for requestViewportScaling(double) on XRWebGLLayer >+FAIL XRPresentationContext interface: existence and properties of interface object assert_own_property: self does not have own property "XRPresentationContext" expected property "XRPresentationContext" missing >+FAIL XRPresentationContext interface object length assert_own_property: self does not have own property "XRPresentationContext" expected property "XRPresentationContext" missing >+FAIL XRPresentationContext interface object name assert_own_property: self does not have own property "XRPresentationContext" expected property "XRPresentationContext" missing >+FAIL XRPresentationContext interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRPresentationContext" expected property "XRPresentationContext" missing >+FAIL XRPresentationContext interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRPresentationContext" expected property "XRPresentationContext" missing >+FAIL XRPresentationContext interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRPresentationContext" expected property "XRPresentationContext" missing >+FAIL XRPresentationContext interface: attribute canvas assert_own_property: self does not have own property "XRPresentationContext" expected property "XRPresentationContext" missing >+PASS Unscopable handled correctly for canvas property on XRPresentationContext >+FAIL XRSessionEvent interface: existence and properties of interface object assert_own_property: self does not have own property "XRSessionEvent" expected property "XRSessionEvent" missing >+FAIL XRSessionEvent interface object length assert_own_property: self does not have own property "XRSessionEvent" expected property "XRSessionEvent" missing >+FAIL XRSessionEvent interface object name assert_own_property: self does not have own property "XRSessionEvent" expected property "XRSessionEvent" missing >+FAIL XRSessionEvent interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRSessionEvent" expected property "XRSessionEvent" missing >+FAIL XRSessionEvent interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRSessionEvent" expected property "XRSessionEvent" missing >+FAIL XRSessionEvent interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRSessionEvent" expected property "XRSessionEvent" missing >+FAIL XRSessionEvent interface: attribute session assert_own_property: self does not have own property "XRSessionEvent" expected property "XRSessionEvent" missing >+PASS Unscopable handled correctly for session property on XRSessionEvent >+FAIL XRCoordinateSystemEvent interface: existence and properties of interface object assert_own_property: self does not have own property "XRCoordinateSystemEvent" expected property "XRCoordinateSystemEvent" missing >+FAIL XRCoordinateSystemEvent interface object length assert_own_property: self does not have own property "XRCoordinateSystemEvent" expected property "XRCoordinateSystemEvent" missing >+FAIL XRCoordinateSystemEvent interface object name assert_own_property: self does not have own property "XRCoordinateSystemEvent" expected property "XRCoordinateSystemEvent" missing >+FAIL XRCoordinateSystemEvent interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRCoordinateSystemEvent" expected property "XRCoordinateSystemEvent" missing >+FAIL XRCoordinateSystemEvent interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRCoordinateSystemEvent" expected property "XRCoordinateSystemEvent" missing >+FAIL XRCoordinateSystemEvent interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRCoordinateSystemEvent" expected property "XRCoordinateSystemEvent" missing >+FAIL XRCoordinateSystemEvent interface: attribute coordinateSystem assert_own_property: self does not have own property "XRCoordinateSystemEvent" expected property "XRCoordinateSystemEvent" missing >+PASS Unscopable handled correctly for coordinateSystem property on XRCoordinateSystemEvent >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/interfaces.https.html b/LayoutTests/imported/w3c/web-platform-tests/webxr/interfaces.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..385f835fdb6aa12ed189638a49929c1c0fdafde4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/interfaces.https.html >@@ -0,0 +1,26 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>WebXR Device API IDL Tests</title> >+<link rel="help" href="https://immersive-web.github.io/webxr/spec/latest/"> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/resources/WebIDLParser.js"></script> >+<script src="/resources/idlharness.js"></script> >+<script> >+"use strict"; >+ >+promise_test(async () => { >+ const idl_array = new IdlArray(); >+ const dom_idl = await fetch("/interfaces/dom.idl").then(r => r.text()); >+ const webxr_idl = await fetch("/interfaces/webxr.idl").then(r => r.text()); >+ >+ idl_array.add_untested_idls(dom_idl); >+ idl_array.add_untested_idls("interface Navigator {};"); >+ idl_array.add_idls(webxr_idl); >+ idl_array.add_idls("dictionary WebGLContextAttributes {};"); >+ idl_array.add_objects({ >+ Navigator:['navigator'], >+ }); >+ idl_array.test(); >+}, "Test IDL implementation of WebXR API"); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/resources/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webxr/resources/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..b1396019dc42697fa7902cad1523f9e184316543 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/resources/w3c-import.log >@@ -0,0 +1,18 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webxr/resources/webxr_check.html >+/LayoutTests/imported/w3c/web-platform-tests/webxr/resources/webxr_util.js >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/resources/webxr_check.html b/LayoutTests/imported/w3c/web-platform-tests/webxr/resources/webxr_check.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2d8e5b387dc88588921ccfa49dd14db58009900c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/resources/webxr_check.html >@@ -0,0 +1,17 @@ >+<script src=webxr_util.js></script> >+<script> >+'use strict'; >+let definedObjects = []; >+let undefinedObjects = []; >+ >+forEachWebxrObject((obj, name) => { >+ if(obj == undefined) { >+ undefinedObjects.push(name); >+ } else { >+ definedObjects.push(name); >+ } >+}); >+ >+window.parent.postMessage({ undefinedObjects, definedObjects}, '*'); >+ >+</script> >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/resources/webxr_util.js b/LayoutTests/imported/w3c/web-platform-tests/webxr/resources/webxr_util.js >new file mode 100644 >index 0000000000000000000000000000000000000000..388c7578c5e49340a305c8c4a90c74d528dddf00 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/resources/webxr_util.js >@@ -0,0 +1,28 @@ >+// This functions calls a callback with each API object as specified >+// by https://immersive-web.github.io/webxr/spec/latest/, allowing >+// checks to be made on all ojects. >+// Arguements: >+// callback: A callback function with two arguements, the first >+// being the API object, the second being the name of >+// that API object. >+function forEachWebxrObject(callback) { >+ callback(window.navigator.xr, 'navigator.xr'); >+ callback(window.XRDevice, 'XRDevice'); >+ callback(window.XRSession, 'XRSession'); >+ callback(window.XRSessionCreationOptions, 'XRSessionCreationOptions'); >+ callback(window.XRFrameRequestCallback, 'XRFrameRequestCallback'); >+ callback(window.XRPresentationContext, 'XRPresentationContext'); >+ callback(window.XRPresentationFrame, 'XRPresentationFrame'); >+ callback(window.XRView, 'XRView'); >+ callback(window.XRViewport, 'XRViewport'); >+ callback(window.XRDevicePose, 'XRDevicePose'); >+ callback(window.XRLayer, 'XRLayer'); >+ callback(window.XRWebGLLayer, 'XRWebGLLayer'); >+ callback(window.XRWebGLLayerInit, 'XRWebGLLayerInit'); >+ callback(window.XRCoordinateSystem, 'XRCoordinateSystem'); >+ callback(window.XRFrameOfReference, 'XRFrameOfReference'); >+ callback(window.XRStageBounds, 'XRStageBounds'); >+ callback(window.XRStageBoundsPoint, 'XRStageBoundsPoint'); >+ callback(window.XRSessionEvent, 'XRSessionEvent'); >+ callback(window.XRCoordinateSystemEvent, 'XRCoordinateSystemEvent'); >+} >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/webxr/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..a591672f643ff8a91b31ceef7d9fdf129af386c2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/w3c-import.log >@@ -0,0 +1,19 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/webxr/OWNERS >+/LayoutTests/imported/w3c/web-platform-tests/webxr/interfaces.https.html >+/LayoutTests/imported/w3c/web-platform-tests/webxr/webxr_availability.http.sub.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/webxr_availability.http.sub-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/webxr_availability.http.sub-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..cff5839d2dc01bcdf0523601dd02a88a8d8b6c9c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/webxr_availability.http.sub-expected.txt >@@ -0,0 +1,8 @@ >+Blocked access to external URL https://www.localhost:9443/webxr/resources/webxr_check.html >+ >+ >+Harness Error (TIMEOUT), message = null >+ >+PASS Test webxr not available in insecure context >+TIMEOUT Test webxr not available in secure context in insecure context Test timed out >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/webxr_availability.http.sub.html b/LayoutTests/imported/w3c/web-platform-tests/webxr/webxr_availability.http.sub.html >new file mode 100644 >index 0000000000000000000000000000000000000000..515b2ad1a8d015120032ea56c473922a2af73e85 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/webxr_availability.http.sub.html >@@ -0,0 +1,39 @@ >+<!DOCTYPE html> >+<body> >+ <script src=/resources/testharness.js></script> >+ <script src=/resources/testharnessreport.js></script> >+ <script src=/webxr/resources/webxr_util.js></script> >+ <script> >+ 'use strict'; >+ >+ var same_origin_src = '/webxr/resources/'; >+ var cross_origin_https_src = 'https://{{domains[www]}}:{{ports[https][0]}}' + >+ same_origin_src; >+ >+ test(t => { >+ forEachWebxrObject((obj, name) => { >+ assert_equals(obj, undefined, name + ' was defined in insecure context.'); >+ }); >+ }, 'Test webxr not available in insecure context'); >+ >+ async_test(t => { >+ let frame = document.createElement('iframe'); >+ frame.src = cross_origin_https_src + 'webxr_check.html'; >+ >+ window.addEventListener('message', t.step_func(function handler(evt) { >+ if (evt.source === frame.contentWindow) { >+ document.body.removeChild(frame); >+ window.removeEventListener('message', handler); >+ >+ assert_equals(evt.data.definedObjects.length, 0, >+ "Some objects were defined in insecure context: " + >+ evt.data.definedObjects.toString()); >+ t.done(); >+ } >+ })); >+ >+ document.body.appendChild(frame); >+ }, 'Test webxr not available in secure context in insecure context'); >+ >+ </script> >+</body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/SharedWorkerPerformanceNow-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/workers/SharedWorkerPerformanceNow-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..27019e065cdd0313f5b2f77661c2ae4a06c61f4b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/SharedWorkerPerformanceNow-expected.txt >@@ -0,0 +1,3 @@ >+ >+FAIL performance.now() exists in shared workers and reports reasonable times Can't find variable: SharedWorker >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/SharedWorkerPerformanceNow.html b/LayoutTests/imported/w3c/web-platform-tests/workers/SharedWorkerPerformanceNow.html >new file mode 100644 >index 0000000000000000000000000000000000000000..a784293b342ff43cb97d252d57330cfae48d4805 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/SharedWorkerPerformanceNow.html >@@ -0,0 +1,47 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<title>window.performance.now in shared workers</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+</head> >+<body> >+<script> >+async_test(function(t) { >+ const worker = new SharedWorker('support/WorkerSendingPerformanceNow.js'); >+ worker.port.onmessage = t.step_func(event => { >+ const results = event.data; >+ assert_true(results.length == 4); >+ assert_equals(results[0], 'undefined', >+ 'workerStart not defined on the Worker object'); >+ assert_equals(results[1], 'object', 'self.performance is defined'); >+ assert_equals(results[2], 'function', 'self.performance.now is defined'); >+ assert_greater_than(results[3], 0, 'Time in the worker should be positive'); >+ assert_greater_than(window.performance.now(), results[3], 'Time in the worker should be before the current time in the main document'); >+ setupIframe(); >+ }); >+ window.iframeStartTime = 0; >+ window.test_iframe = function(event) { >+ const workerTime = event.data[3]; >+ assert_greater_than(workerTime, window.iframeStartTime, >+ 'Time since origin time should be greater in the shared worker than the iframe'); >+ t.done(); >+ } >+ function setupIframe() { >+ const iframe = document.createElement('iframe'); >+ document.body.appendChild(iframe); >+ const script = iframe.contentWindow.document.createElement('script'); >+ script.innerHTML = >+ 'window.top.iframeStartTime = window.performance.now();' + >+ 'const worker = new SharedWorker("support/WorkerSendingPerformanceNow.js");' + >+ 'worker.port.onmessage = function(event) {' + >+ ' window.top.test_iframe(event);' + >+ '};' + >+ 'worker.port.postMessage("");'; >+ iframe.contentWindow.document.body.appendChild(script); >+ } >+ worker.port.postMessage(''); >+}, 'performance.now() exists in shared workers and reports reasonable times'); >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/SharedWorker_dataUrl-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/workers/SharedWorker_dataUrl-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..027eb4156b0d4e01f5a083a2ffd843e443602c7a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/SharedWorker_dataUrl-expected.txt >@@ -0,0 +1,9 @@ >+CONSOLE MESSAGE: line 6: ReferenceError: Can't find variable: SharedWorker >+CONSOLE MESSAGE: line 6: ReferenceError: Can't find variable: SharedWorker >+ >+ >+Harness Error (TIMEOUT), message = null >+ >+TIMEOUT Data URL not shared by cross-origin SharedWorkers Test timed out >+NOTRUN Data URLs shared by same-origin SharedWorkers >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/SharedWorker_dataUrl.html b/LayoutTests/imported/w3c/web-platform-tests/workers/SharedWorker_dataUrl.html >new file mode 100644 >index 0000000000000000000000000000000000000000..c1dec27d49f8d711f6fc8e4b5a4932b31f9875be >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/SharedWorker_dataUrl.html >@@ -0,0 +1,63 @@ >+<!DOCTYPE html> >+<title>Shared Worker: Data URL cross-origin checks</title> >+<script src="/common/get-host-info.sub.js"></script> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<body> >+</body> >+<script> >+ >+function dirname(path) { >+ return path.replace(/\/[^\/]*$/, '/'); >+} >+ >+promise_test(t => { >+ return new Promise(function(resolve) { >+ let count = 0; >+ onmessage = e => { >+ assert_equals(e.data, 1); >+ if (++count == 2) { >+ resolve(true); >+ } >+ }; >+ >+ let iframeA = document.createElement('iframe'); >+ document.body.appendChild(iframeA); >+ iframeA.src = get_host_info().HTTP_REMOTE_ORIGIN + >+ dirname(location.pathname) + >+ "support/iframe_sw_dataUrl.html"; >+ >+ let iframeB = document.createElement('iframe'); >+ document.body.appendChild(iframeB); >+ iframeB.src = get_host_info().HTTPS_REMOTE_ORIGIN + >+ dirname(location.pathname) + >+ "support/iframe_sw_dataUrl.html"; >+ }); >+}, 'Data URL not shared by cross-origin SharedWorkers'); >+ >+promise_test(t => { >+ return new Promise(function(resolve) { >+ let count = 0; >+ onmessage = e => { >+ assert_equals(e.data, ++count); >+ if (count == 2) { >+ resolve(true); >+ } >+ }; >+ >+ let iframeA = document.createElement('iframe'); >+ document.body.appendChild(iframeA); >+ iframeA.src = get_host_info().HTTP_ORIGIN + >+ dirname(location.pathname) + >+ "support/iframe_sw_dataUrl.html"; >+ >+ let iframeB = document.createElement('iframe'); >+ document.body.appendChild(iframeB); >+ iframeB.src = get_host_info().HTTP_ORIGIN + >+ dirname(location.pathname) + >+ "support/iframe_sw_dataUrl.html"; >+ }); >+}, 'Data URLs shared by same-origin SharedWorkers'); >+ >+</script> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/WorkerGlobalScope_requestAnimationFrame-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/workers/WorkerGlobalScope_requestAnimationFrame-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..12cd1d49c755af7ec0ccc5fe64352ea1b6fbfe1d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/WorkerGlobalScope_requestAnimationFrame-expected.txt >@@ -0,0 +1,6 @@ >+CONSOLE MESSAGE: line 3: ReferenceError: Can't find variable: requestAnimationFrame >+ >+Harness Error (FAIL), message = ReferenceError: Can't find variable: requestAnimationFrame >+ >+TIMEOUT WorkerGlobalScope API: requestAnimationFrame() Test timed out >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/WorkerGlobalScope_requestAnimationFrame.htm b/LayoutTests/imported/w3c/web-platform-tests/workers/WorkerGlobalScope_requestAnimationFrame.htm >new file mode 100644 >index 0000000000000000000000000000000000000000..dcf58d92497e01b4ea58db66730e5ed91b054f34 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/WorkerGlobalScope_requestAnimationFrame.htm >@@ -0,0 +1,31 @@ >+<!DOCTYPE html> >+<title> WorkerGlobalScope API: requestAnimationFrame()</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<div id=log></div> >+<script id="worker" type="text/worker"> >+const res = []; >+requestAnimationFrame((dt) => { >+ res.push(dt); >+ requestAnimationFrame((dt) => { >+ res.push(dt); >+ requestAnimationFrame((dt) => { >+ res.push(dt); >+ postMessage(res); >+ }); >+ }); >+}); >+</script> >+<script> >+async_test(function(t) { >+ var blob = new Blob([document.getElementById('worker').textContent]); >+ var worker = new Worker(URL.createObjectURL(blob)); >+ worker.addEventListener("message", (ev) => { >+ const ret = ev.data; >+ assert_equals(ret.length, 3); >+ assert_true(ret[0] < ret[1]); >+ assert_true(ret[1] < ret[2]); >+ t.done(); >+ }); >+}); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/WorkerPerformanceNow-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/workers/WorkerPerformanceNow-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2a293c5355af06d3a931f3c1b610c7bd2373e2c9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/WorkerPerformanceNow-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS performance.now() exists in dedicated workers and reports reasonable times >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/WorkerPerformanceNow.html b/LayoutTests/imported/w3c/web-platform-tests/workers/WorkerPerformanceNow.html >new file mode 100644 >index 0000000000000000000000000000000000000000..467dad44e2082aa5594b4e51eb8d418ebb2cb85b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/WorkerPerformanceNow.html >@@ -0,0 +1,26 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<title>performance.now in dedicated workers</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+</head> >+<body> >+<script> >+async_test(function(t) { >+ const worker = new Worker('support/WorkerSendingPerformanceNow.js'); >+ worker.onmessage = t.step_func_done(event => { >+ const results = event.data; >+ assert_true(results.length == 4); >+ assert_equals(results[0], 'undefined', >+ 'workerStart not defined on the Worker object'); >+ assert_equals(results[1], 'object', "self.performance is defined"); >+ assert_equals(results[2], 'function', "self.performance.now is defined"); >+ assert_greater_than(results[3], 0, "Time in the worker should be positive"); >+ assert_greater_than(window.performance.now(), results[3], "Time in the worker should be before the current time in the main document"); >+ }); >+ worker.postMessage(''); >+}, 'performance.now() exists in dedicated workers and reports reasonable times'); >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/WindowTimers/005-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/WindowTimers/005-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..f9fd5085454c544d89c9cef9537282f5b4113598 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/WindowTimers/005-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS setInterval when closing >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/WindowTimers/005.html b/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/WindowTimers/005.html >new file mode 100644 >index 0000000000000000000000000000000000000000..b86eff1fbddb601667f7b69c9ed4955998735dde >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/WindowTimers/005.html >@@ -0,0 +1,23 @@ >+<!-- >+self.close(); >+var t = setInterval(function() {}, 10); >+postMessage(t); >+/* >+--> >+<!doctype html> >+<title>setInterval when closing</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<div id=log></div> >+<script> >+async_test(function() { >+ var worker = new Worker('#'); >+ worker.onmessage = this.step_func(function(e) { >+ assert_equals(e.data, 1); >+ this.done(); >+ }); >+}); >+</script> >+<!-- >+*/ >+//--> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/WindowTimers/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/WindowTimers/w3c-import.log >index a9353f6dfabdeebda109c667b382637bbcb06854..c6f1efd12c027a585244dad18a6bfceca8718ceb 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/WindowTimers/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/WindowTimers/w3c-import.log >@@ -18,3 +18,4 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/WindowTimers/002.html > /LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/WindowTimers/003.html > /LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/WindowTimers/004.html >+/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/WindowTimers/005.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/1.headers b/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/1.headers >new file mode 100644 >index 0000000000000000000000000000000000000000..a17a9a3a12cefe883a5d4dee4d5a45bef120d050 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/1.headers >@@ -0,0 +1 @@ >+Content-Type: application/javascript >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/null.headers b/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/null.headers >new file mode 100644 >index 0000000000000000000000000000000000000000..a17a9a3a12cefe883a5d4dee4d5a45bef120d050 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/null.headers >@@ -0,0 +1 @@ >+Content-Type: application/javascript >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/undefined.headers b/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/undefined.headers >new file mode 100644 >index 0000000000000000000000000000000000000000..a17a9a3a12cefe883a5d4dee4d5a45bef120d050 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/undefined.headers >@@ -0,0 +1 @@ >+Content-Type: application/javascript >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/w3c-import.log >index d424d8ca680c1b077e210df77b45065db68df103..b0f5fc52b44fb6d26dc5303c5645035a6ca64d0f 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/w3c-import.log >@@ -27,5 +27,8 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/011.html > /LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/012.html > /LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/1 >+/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/1.headers > /LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/null >+/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/null.headers > /LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/undefined >+/LayoutTests/imported/w3c/web-platform-tests/workers/interfaces/WorkerUtils/importScripts/undefined.headers >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-csp-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-csp-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d25081d3671427ea236ccab0567da064c3dab52e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-csp-expected.txt >@@ -0,0 +1,17 @@ >+CONSOLE MESSAGE: Unrecognized Content-Security-Policy directive 'worker-src'. >+ >+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '*'. import call expects exactly one argument. >+CONSOLE MESSAGE: Unrecognized Content-Security-Policy directive 'worker-src'. >+ >+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '*'. import call expects exactly one argument. >+ >+PASS worker-src 'self' directive should disallow cross origin static import. >+FAIL worker-src * directive should allow cross origin static import. assert_equals: expected (string) "LOADED" but got (object) object "[object Object]" >+FAIL script-src 'self' directive should disallow cross origin static import. assert_equals: expected (string) "LOADED" but got (object) object "[object Object]" >+FAIL script-src * directive should allow cross origin static import. assert_equals: expected (string) "LOADED" but got (object) object "[object Object]" >+FAIL worker-src * directive should override script-src 'self' directive and allow cross origin static import. assert_equals: expected (string) "LOADED" but got (object) object "[object Object]" >+PASS worker-src 'self' directive should override script-src * directive and disallow cross origin static import. >+FAIL script-src 'self' directive should disallow cross origin dynamic import. assert_equals: expected (string) "LOADED" but got (object) object "[object Object]" >+FAIL script-src * directive should allow cross origin dynamic import. assert_equals: expected (string) "LOADED" but got (object) object "[object Object]" >+FAIL worker-src 'self' directive should not take effect on dynamic import. assert_equals: expected (string) "LOADED" but got (object) object "[object Object]" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-csp.html b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-csp.html >new file mode 100644 >index 0000000000000000000000000000000000000000..02b88e82269f370080074eea78a65490c964e3a7 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-csp.html >@@ -0,0 +1,114 @@ >+<!DOCTYPE html> >+<title>DedicatedWorker: CSP for ES Modules</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+ >+async function openWindow(url) { >+ const win = window.open(url, '_blank'); >+ add_result_callback(() => win.close()); >+ const msg_event = await new Promise(resolve => window.onmessage = resolve); >+ assert_equals(msg_event.data, 'LOADED'); >+ return win; >+} >+ >+function import_csp_test( >+ cspHeader, scriptURL, expectedImportedModules, description) { >+ const windowURL = >+ `resources/new-worker-window.html?pipe=header(` + >+ `Content-Security-Policy, ${cspHeader})`; >+ promise_test(async () => { >+ // Open a window that has the given CSP header. >+ const win = await openWindow(windowURL); >+ // Ask the window to start a dedicated worker. The worker inherits the >+ // window's CSP header. >+ // https://w3c.github.io/webappsec-csp/#initialize-global-object-csp >+ win.postMessage(scriptURL, '*'); >+ const msg_event = await new Promise(resolve => window.onmessage = resolve); >+ assert_array_equals(msg_event.data, expectedImportedModules); >+ }, description); >+} >+ >+// Tests for static import. >+// >+// Static import should obey the worker-src directive and the script-src >+// directive. If the both directives are specified, the worker-src directive >+// should be prioritized. >+// >+// Step 1: "If the result of executing 6.6.1.11 Get the effective directive for >+// request on request is "worker-src", and policy contains a directive whose >+// name is "worker-src", return "Allowed"." >+// "Note: If worker-src is present, weâll defer to it when handling worker >+// requests." >+// https://w3c.github.io/webappsec-csp/#script-src-pre-request >+ >+import_csp_test( >+ "worker-src 'self' 'unsafe-inline'", >+ "static-import-remote-origin-script-worker.sub.js", >+ ['ERROR'], >+ "worker-src 'self' directive should disallow cross origin static import."); >+ >+import_csp_test( >+ "worker-src * 'unsafe-inline'", >+ "static-import-remote-origin-script-worker.sub.js", >+ ["export-on-load-script.js"], >+ "worker-src * directive should allow cross origin static import.") >+ >+import_csp_test( >+ "script-src 'self' 'unsafe-inline'", >+ "static-import-remote-origin-script-worker.sub.js", >+ ['ERROR'], >+ "script-src 'self' directive should disallow cross origin static import."); >+ >+import_csp_test( >+ "script-src * 'unsafe-inline'", >+ "static-import-remote-origin-script-worker.sub.js", >+ ["export-on-load-script.js"], >+ "script-src * directive should allow cross origin static import.") >+ >+import_csp_test( >+ "worker-src *; script-src 'self' 'unsafe-inline'", >+ "static-import-remote-origin-script-worker.sub.js", >+ ["export-on-load-script.js"], >+ "worker-src * directive should override script-src 'self' directive and " + >+ "allow cross origin static import."); >+ >+import_csp_test( >+ "worker-src 'self'; script-src * 'unsafe-inline'", >+ "static-import-remote-origin-script-worker.sub.js", >+ ['ERROR'], >+ "worker-src 'self' directive should override script-src * directive and " + >+ "disallow cross origin static import."); >+ >+// Tests for dynamic import. >+// >+// Dynamic import should obey the script-src directive instead of the worker-src >+// directive according to the specs: >+// >+// Dynamic import has the "script" destination. >+// Step 2.4: "Fetch a module script graph given url, ..., "script", ..." >+// https://html.spec.whatwg.org/multipage/webappapis.html#hostimportmoduledynamically(referencingscriptormodule,-specifier,-promisecapability) >+// >+// The "script" destination should obey the script-src CSP directive. >+// Step 2: "If request's destination is script-like:" >+// https://w3c.github.io/webappsec-csp/#script-src-pre-request >+ >+import_csp_test( >+ "script-src 'self' 'unsafe-inline'", >+ "dynamic-import-remote-origin-script-worker.sub.js", >+ ['ERROR'], >+ "script-src 'self' directive should disallow cross origin dynamic import."); >+ >+import_csp_test( >+ "script-src * 'unsafe-inline'", >+ "dynamic-import-remote-origin-script-worker.sub.js", >+ ["export-on-load-script.js"], >+ "script-src * directive should allow cross origin dynamic import.") >+ >+import_csp_test( >+ "worker-src 'self' 'unsafe-inline'", >+ "dynamic-import-remote-origin-script-worker.sub.js", >+ ["export-on-load-script.js"], >+ "worker-src 'self' directive should not take effect on dynamic import."); >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..f3cf69d7af009f9467e7dba51dfda40b8f4d86f2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-expected.txt >@@ -0,0 +1,12 @@ >+CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '*'. import call expects exactly one argument. >+ >+Harness Error (FAIL), message = SyntaxError: Unexpected token '*'. import call expects exactly one argument. >+ >+TIMEOUT Static import. Test timed out >+NOTRUN Nested static import. >+NOTRUN Static import and then dynamic import. >+NOTRUN Dynamic import. >+NOTRUN Nested dynamic import. >+NOTRUN Dynamic import and then static import. >+NOTRUN eval(import()). >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-failure-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-failure-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..9a7f05b6d1ce19ca08e31b5e20d6aab10a90833a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-failure-expected.txt >@@ -0,0 +1,11 @@ >+CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '*'. import call expects exactly one argument. >+CONSOLE MESSAGE: line 1: SyntaxError: Unexpected string literal './non-existent-script.js'. import call expects exactly one argument. >+ >+Harness Error (FAIL), message = SyntaxError: Unexpected string literal './non-existent-script.js'. import call expects exactly one argument. >+ >+FAIL importScripts() on module worker should throw an exception. assert_equals: expected "TypeError" but got "LOADED" >+PASS Static import on classic worker should throw an exception. >+PASS Worker construction for non-existent script should dispatch an ErrorEvent. >+PASS Static import for non-existent script should dispatch an ErrorEvent. >+FAIL Dynamic import for non-existent script should throw an exception. assert_equals: expected "TypeError" but got "Error" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-failure.html b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-failure.html >new file mode 100644 >index 0000000000000000000000000000000000000000..1c3adeb343773886c1c52dee49a011ce1250cb67 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-failure.html >@@ -0,0 +1,42 @@ >+<!DOCTYPE html> >+<title>DedicatedWorker: import failure</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+ >+promise_test(async () => { >+ const scriptURL = 'resources/import-scripts-worker.js'; >+ const worker = new Worker(scriptURL, { type: 'module' }); >+ const msg_event = await new Promise(resolve => worker.onmessage = resolve); >+ assert_equals(msg_event.data, 'TypeError'); >+}, 'importScripts() on module worker should throw an exception.'); >+ >+promise_test(async () => { >+ const scriptURL = 'resources/static-import-worker.js'; >+ const worker = new Worker(scriptURL, { type: 'classic' }); >+ await new Promise(resolve => worker.onerror = resolve); >+}, 'Static import on classic worker should throw an exception.'); >+ >+promise_test(() => { >+ const scriptURL = 'resources/non-existent-worker.js'; >+ const worker = new Worker(scriptURL, { type: 'module' }); >+ return new Promise(resolve => worker.onerror = resolve); >+}, 'Worker construction for non-existent script should dispatch an ' + >+ 'ErrorEvent.'); >+ >+promise_test(() => { >+ const scriptURL = 'resources/static-import-non-existent-script-worker.js'; >+ const worker = new Worker(scriptURL, { type: 'module' }); >+ return new Promise(resolve => worker.onerror = resolve); >+}, 'Static import for non-existent script should dispatch an ErrorEvent.'); >+ >+promise_test(async () => { >+ const script_url = './non-existent-worker.js'; >+ const worker = new Worker('resources/dynamic-import-given-url-worker.js', >+ { type: 'module' }); >+ worker.postMessage(script_url); >+ const msg_event = await new Promise(resolve => worker.onmessage = resolve); >+ assert_equals(msg_event.data, 'TypeError'); >+}, 'Dynamic import for non-existent script should throw an exception.'); >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-meta-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-meta-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..1697f90ee3535f8a90c97d3df44dd00a9ff82e7b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-meta-expected.txt >@@ -0,0 +1,8 @@ >+CONSOLE MESSAGE: line 1: SyntaxError: import.meta is only valid inside modules. >+ >+Harness Error (FAIL), message = SyntaxError: import.meta is only valid inside modules. >+ >+TIMEOUT Test import.meta.url on the top-level module script. Test timed out >+NOTRUN Test import.meta.url on the imported module script. >+NOTRUN Test import.meta.url on the imported module script with a fragment. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-meta.html b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-meta.html >new file mode 100644 >index 0000000000000000000000000000000000000000..6960cbe57702e71bf51debaf796de8732864e0c2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-meta.html >@@ -0,0 +1,38 @@ >+<!DOCTYPE html> >+<title>DedicatedWorker: import.meta</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+ >+promise_test(() => { >+ const script_url = 'resources/import-meta-url-worker.js'; >+ const worker = new Worker(script_url, { type: 'module' }); >+ return new Promise(resolve => worker.onmessage = resolve) >+ .then(msg_event => assert_true(msg_event.data.endsWith(script_url))); >+}, 'Test import.meta.url on the top-level module script.'); >+ >+promise_test(() => { >+ const script_url = 'import-meta-url-worker.js'; >+ const worker = new Worker('resources/dynamic-import-given-url-worker.js', >+ { type: 'module' }); >+ worker.postMessage('./' + script_url); >+ return new Promise(resolve => worker.onmessage = resolve) >+ .then(msg_event => assert_true(msg_event.data.endsWith(script_url))); >+}, 'Test import.meta.url on the imported module script.'); >+ >+promise_test(() => { >+ const script_url = 'import-meta-url-worker.js'; >+ const worker = new Worker('resources/dynamic-import-given-url-worker.js', >+ { type: 'module' }); >+ worker.postMessage('./' + script_url); >+ >+ return new Promise(resolve => worker.onmessage = resolve) >+ .then(msg_event => assert_true(msg_event.data.endsWith(script_url))) >+ .then(() => { >+ worker.postMessage('./' + script_url + '#1'); >+ return new Promise(resolve => worker.onmessage = resolve); >+ }) >+ .then(msg_event => assert_true(msg_event.data.endsWith(script_url))); >+}, 'Test import.meta.url on the imported module script with a fragment.'); >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-referrer-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-referrer-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..1c9ccecf705cd410cbc8c85f26ad68fa589cd970 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-referrer-expected.txt >@@ -0,0 +1,21 @@ >+CONSOLE MESSAGE: line 1: SyntaxError: Unexpected string literal './referrer-checker.py'. import call expects exactly one argument. >+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected string literal 'https://www1.localhost:9443/workers/modules/resources/referrer-checker.py'. import call expects exactly one argument. >+ >+Harness Error (TIMEOUT), message = null >+ >+PASS Same-origin top-level module script loading with "no-referrer" referrer policy >+PASS Same-origin top-level module script loading with "origin" referrer policy >+FAIL Same-origin top-level module script loading with "same-origin" referrer policy assert_equals: expected "http://localhost:8800/workers/modules/resources/referrer-window.html" but got "http://localhost:8800/workers/modules/resources/new-worker-window.html" >+FAIL Same-origin static import with "no-referrer" referrer policy. promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL Same-origin static import with "origin" referrer policy. assert_equals: expected (string) "LOADED" but got (object) object "[object Object]" >+FAIL Same-origin static import with "same-origin" referrer policy. assert_equals: expected (string) "LOADED" but got (object) object "[object Object]" >+FAIL Cross-origin static import with "no-referrer" referrer policy. assert_equals: expected (string) "LOADED" but got (object) object "[object Object]" >+FAIL Cross-origin static import with "origin" referrer policy. assert_equals: expected (string) "LOADED" but got (object) object "[object Object]" >+FAIL Cross-origin static import with "same-origin" referrer policy. promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL Same-origin dynamic import with "no-referrer" referrer policy. assert_equals: expected (string) "LOADED" but got (object) object "[object Object]" >+FAIL Same-origin dynamic import with "origin" referrer policy. assert_equals: expected (string) "LOADED" but got (object) object "[object Object]" >+FAIL Same-origin dynamic import with "same-origin" referrer policy. assert_equals: expected (string) "LOADED" but got (object) object "[object Object]" >+FAIL Cross-origin dynamic import with "no-referrer" referrer policy. assert_equals: expected (string) "LOADED" but got (object) object "[object Object]" >+TIMEOUT Cross-origin dynamic import with "origin" referrer policy. Test timed out >+NOTRUN Cross-origin dynamic import with "same-origin" referrer policy. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-referrer.html b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-referrer.html >new file mode 100644 >index 0000000000000000000000000000000000000000..01322bb1ed0edf82f3d447fd5dfc59e4310dd6b5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-referrer.html >@@ -0,0 +1,209 @@ >+<!DOCTYPE html> >+<title>DedicatedWorker: Referrer</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+ >+async function openWindow(url) { >+ const win = window.open(url, '_blank'); >+ add_result_callback(() => win.close()); >+ const msg_event = await new Promise(resolve => window.onmessage = resolve); >+ assert_equals(msg_event.data, 'LOADED'); >+ return win; >+} >+ >+// Returns a URL string from the current path and the given relative path. >+function createURLString(relative_path) { >+ return (new URL(relative_path, location.href)).href; >+} >+ >+// Removes URL parameters from the given URL string and returns it. >+function removeParams(url_string) { >+ if (!url_string) >+ return url_string; >+ let url = new URL(url_string); >+ for (var key of url.searchParams.keys()) >+ url.searchParams.delete(key); >+ return url.href; >+} >+ >+// Runs a referrer policy test with the given settings. This opens a new window >+// that starts a dedicated worker. >+// >+// |settings| has options as follows: >+// >+// settings = { >+// scriptURL: 'resources/referrer-checker.sub.js', >+// windowReferrerPolicy: 'no-referrer', >+// workerReferrerPolicy: 'same-origin', >+// expectedReferrer: 'https://example.com/referrer-checker.py' >+// }; >+// >+// - |scriptURL| is used for starting a new worker. >+// - |windowReferrerPolicy| is set to the ReferrerPolicy HTTP header of the >+// window. This policy should be applied to top-level worker module script >+// loading and static imports. >+// - |workerReferrerPolicy| is set to the ReferrerPolicy HTTP header of the >+// worker. This policy should be applied to dynamic imports. >+// - |expectedReferrer| is compared with the actual referrer. URL parameters are >+// ignored. >+function import_referrer_test(settings, description) { >+ promise_test(async () => { >+ let windowURL = 'resources/new-worker-window.html'; >+ if (settings.windowReferrerPolicy) { >+ windowURL += >+ `?pipe=header(Referrer-Policy, ${settings.windowReferrerPolicy})`; >+ } >+ >+ let scriptURL = settings.scriptURL; >+ if (settings.workerReferrerPolicy) { >+ // 'sub' is necessary even if the |scriptURL| contains the '.sub' >+ // extension because the extension doesn't work with the 'pipe' parameter. >+ // See an issue on the WPT's repository: >+ // https://github.com/web-platform-tests/wpt/issues/9345 >+ scriptURL += >+ `?pipe=sub|header(Referrer-Policy, ${settings.workerReferrerPolicy})`; >+ } >+ >+ const win = await openWindow(windowURL); >+ win.postMessage(scriptURL, '*'); >+ const msgEvent = await new Promise(resolve => window.onmessage = resolve); >+ >+ // Delete query parameters from the referrers to make it easy to match the >+ // actual referrer with the expected referrer. >+ const expectedReferrer = removeParams(settings.expectedReferrer); >+ const actualReferrer = removeParams(msgEvent.data); >+ assert_equals(actualReferrer, expectedReferrer); >+ }, description); >+} >+ >+// Tests for top-level worker module script loading. >+// >+// Top-level worker module script loading should obey the window's >+// ReferrerPolicy, and send the window's URL as a referrer. >+// >+// [Current document] >+// --(open)--> [Window] whose referrer policy is |windowReferrerPolicy|. >+// --(new Worker)--> [Worker] should be loaded with [Window]'s URL as a >+// referrer if it's allowed by |windowReferrerPolicy|. >+ >+import_referrer_test( >+ { scriptURL: 'referrer-checker.py', >+ windowReferrerPolicy: 'no-referrer', >+ expectedReferrer: '' }, >+ 'Same-origin top-level module script loading with "no-referrer" referrer ' + >+ 'policy'); >+ >+import_referrer_test( >+ { scriptURL: 'referrer-checker.py', >+ windowReferrerPolicy: 'origin', >+ expectedReferrer: window.location.origin + '/' }, >+ 'Same-origin top-level module script loading with "origin" referrer ' + >+ 'policy'); >+ >+import_referrer_test( >+ { scriptURL: 'referrer-checker.py', >+ windowReferrerPolicy: 'same-origin', >+ expectedReferrer: createURLString('resources/referrer-window.html') }, >+ 'Same-origin top-level module script loading with "same-origin" referrer ' + >+ 'policy'); >+ >+// Tests for static imports. >+// >+// Static imports should obey the window's ReferrerPolicy, and send the worker's >+// URL as a referrer. >+// >+// [Current document] >+// --(open)--> [Window] whose referrer policy is |windowReferrerPolicy|. >+// --(new Worker)--> [Worker] >+// --(static import)--> [Script] should be loaded with [Worker]'s URL as a >+// referrer if it's allowed by |windowReferrerPolicy|. >+ >+import_referrer_test( >+ { scriptURL: 'static-import-same-origin-referrer-checker-worker.js', >+ windowReferrerPolicy: 'no-referrer', >+ expectedReferrer: '' }, >+ 'Same-origin static import with "no-referrer" referrer policy.'); >+ >+import_referrer_test( >+ { scriptURL: 'static-import-same-origin-referrer-checker-worker.js', >+ windowReferrerPolicy: 'origin', >+ expectedReferrer: window.location.origin + '/' }, >+ 'Same-origin static import with "origin" referrer policy.'); >+ >+import_referrer_test( >+ { scriptURL: 'static-import-same-origin-referrer-checker-worker.js', >+ windowReferrerPolicy: 'same-origin', >+ expectedReferrer: createURLString( >+ 'resources/static-import-same-origin-referrer-checker-worker.js') }, >+ 'Same-origin static import with "same-origin" referrer policy.'); >+ >+import_referrer_test( >+ { scriptURL: 'static-import-remote-origin-referrer-checker-worker.sub.js', >+ windowReferrerPolicy: 'no-referrer', >+ expectedReferrer: '' }, >+ 'Cross-origin static import with "no-referrer" referrer policy.'); >+ >+import_referrer_test( >+ { scriptURL: 'static-import-remote-origin-referrer-checker-worker.sub.js', >+ windowReferrerPolicy: 'origin', >+ expectedReferrer: window.location.origin + '/' }, >+ 'Cross-origin static import with "origin" referrer policy.'); >+ >+import_referrer_test( >+ { scriptURL: 'static-import-remote-origin-referrer-checker-worker.sub.js', >+ windowReferrerPolicy: 'same-origin', >+ expectedReferrer: '' }, >+ 'Cross-origin static import with "same-origin" referrer policy.'); >+ >+// Tests for dynamic imports. >+// >+// Dynamic imports should obey the worker's ReferrerPolicy, and send the >+// worker's URL as a referrer. Note that the worker doesn't inherit the window's >+// referrer policy and it's set by the ReferrerPolicy HTTP header on the >+// response of the top-level worker module script. >+// >+// [Current document] >+// --(open)--> [Window] >+// --(new Worker)--> [Worker] whose referrer policy is |workerReferrerPolicy|. >+// --(dynamic import)--> [Script] should be loaded with [Worker]'s URL as a >+// referrer if it's allowed by |workerReferrerPolicy|. >+ >+import_referrer_test( >+ { scriptURL: 'dynamic-import-same-origin-referrer-checker-worker.js', >+ workerReferrerPolicy: 'no-referrer', >+ expectedReferrer: '' }, >+ 'Same-origin dynamic import with "no-referrer" referrer policy.'); >+ >+import_referrer_test( >+ { scriptURL: 'dynamic-import-same-origin-referrer-checker-worker.js', >+ workerReferrerPolicy: 'origin', >+ expectedReferrer: window.location.origin + '/' }, >+ 'Same-origin dynamic import with "origin" referrer policy.'); >+ >+import_referrer_test( >+ { scriptURL: 'dynamic-import-same-origin-referrer-checker-worker.js', >+ workerReferrerPolicy: 'same-origin', >+ expectedReferrer: createURLString( >+ 'resources/dynamic-import-same-origin-referrer-checker-worker.js') }, >+ 'Same-origin dynamic import with "same-origin" referrer policy.'); >+ >+import_referrer_test( >+ { scriptURL: 'dynamic-import-remote-origin-referrer-checker-worker.sub.js', >+ workerReferrerPolicy: 'no-referrer', >+ expectedReferrer: '' }, >+ 'Cross-origin dynamic import with "no-referrer" referrer policy.'); >+ >+import_referrer_test( >+ { scriptURL: 'dynamic-import-remote-origin-referrer-checker-worker.sub.js', >+ workerReferrerPolicy: 'origin', >+ expectedReferrer: window.location.origin + '/' }, >+ 'Cross-origin dynamic import with "origin" referrer policy.'); >+ >+import_referrer_test( >+ { scriptURL: 'dynamic-import-remote-origin-referrer-checker-worker.sub.js', >+ workerReferrerPolicy: 'same-origin', >+ expectedReferrer: '' }, >+ 'Cross-origin dynamic import with "same-origin" referrer policy.'); >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import.html b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import.html >new file mode 100644 >index 0000000000000000000000000000000000000000..a45fa9ed36ff149f44069ef798154d2f65714f7d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import.html >@@ -0,0 +1,47 @@ >+<!DOCTYPE html> >+<title>DedicatedWorker: import</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+ >+// Starts a dedicated worker for |scriptURL| and waits until the list of >+// imported modules is sent from the worker. Passes if the list is equal to >+// |expectedImportedModules|. >+function import_test(scriptURL, expectedImportedModules, description) { >+ promise_test(async () => { >+ const worker = new Worker(scriptURL, { type: 'module' }); >+ const msg_event = await new Promise(resolve => worker.onmessage = resolve); >+ assert_array_equals(msg_event.data, expectedImportedModules); >+ }, description); >+} >+ >+import_test('resources/static-import-worker.js', >+ ['export-on-load-script.js'], >+ 'Static import.'); >+ >+import_test('resources/nested-static-import-worker.js', >+ ['export-on-static-import-script.js', 'export-on-load-script.js'], >+ 'Nested static import.'); >+ >+ >+import_test('resources/static-import-and-then-dynamic-import-worker.js', >+ ['export-on-dynamic-import-script.js', 'export-on-load-script.js'], >+ 'Static import and then dynamic import.'); >+ >+import_test('resources/dynamic-import-worker.js', >+ ['export-on-load-script.js'], >+ 'Dynamic import.'); >+ >+import_test('resources/nested-dynamic-import-worker.js', >+ ['export-on-dynamic-import-script.js', 'export-on-load-script.js'], >+ 'Nested dynamic import.'); >+ >+import_test('resources/dynamic-import-and-then-static-import-worker.js', >+ ['export-on-static-import-script.js', 'export-on-load-script.js'], >+ 'Dynamic import and then static import.'); >+ >+import_test('resources/eval-dynamic-import-worker.js', >+ ['export-on-load-script.js'], >+ 'eval(import()).'); >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-options-credentials-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-options-credentials-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d6501aefd5f22e6131dfe7533e1e10abdb5b73ac >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-options-credentials-expected.txt >@@ -0,0 +1,10 @@ >+ >+PASS new Worker() with the default credentials option should behave as credentials=same-origin and send the credentials >+FAIL new Worker() with credentials=omit should not send the credentials assert_equals: expected "" but got "COOKIE_VALUE" >+PASS new Worker() with credentials=same-origin should send the credentials >+PASS new Worker() with credentials=include should send the credentials >+PASS new Worker() with type=classic should always send the credentials regardless of the credentials option (default). >+PASS new Worker() with type=classic should always send the credentials regardless of the credentials option (omit). >+PASS new Worker() with type=classic should always send the credentials regardless of the credentials option (same-origin). >+PASS new Worker() with type=classic should always send the credentials regardless of the credentials option (include). >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-options-credentials.html b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-options-credentials.html >new file mode 100644 >index 0000000000000000000000000000000000000000..6603eb9be9b8f074993abc6a7ff2f1dee453b24f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-options-credentials.html >@@ -0,0 +1,85 @@ >+<!DOCTYPE html> >+<title>DedicatedWorker: WorkerOptions 'credentials'</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+ >+// Determines the expected cookie value to be reported by a dedicated worker >+// based on the given option. The worker reports an empty string as the actual >+// cookie value if the cookie wasn't sent to the server. Otherwise, it's the >+// value set by the headers file: >+// "dedicated-worker-options-credentials.html.headers" >+function DetermineExpectedCookieValue(options) { >+ // Classic script loading should always send credentials regardless of the >+ // 'credentials' option because the spec says the option takes effect only >+ // for module script loading. >+ if (options.type == 'classic') >+ return 'COOKIE_VALUE'; >+ assert_equals(options.type, 'module'); >+ >+ if (!options.credentials || >+ options.credentials == 'same-origin' || >+ options.credentials == 'include') { >+ return 'COOKIE_VALUE'; >+ } >+ if (options.credentials == 'omit') >+ return ''; >+ assert_unreached('Invalid credentials option was specified: ' + >+ options.credentials); >+} >+ >+// Runs a credentials test with the given WorkerOptions. >+function credentials_test(options, description) { >+ promise_test(async () => { >+ const worker = new Worker('resources/credentials.py', options); >+ >+ // Wait until the worker sends the actual cookie value. >+ const msg_event = await new Promise(resolve => worker.onmessage = resolve); >+ >+ const expectedCookieValue = DetermineExpectedCookieValue(options); >+ assert_equals(msg_event.data, expectedCookieValue); >+ }, description); >+} >+ >+// Tests for module scripts. >+ >+credentials_test( >+ { type: 'module'}, >+ 'new Worker() with the default credentials option should behave as ' + >+ 'credentials=same-origin and send the credentials'); >+ >+credentials_test( >+ { credentials: 'omit', type: 'module' }, >+ 'new Worker() with credentials=omit should not send the credentials'); >+ >+credentials_test( >+ { credentials: 'same-origin', type: 'module' }, >+ 'new Worker() with credentials=same-origin should send the credentials'); >+ >+credentials_test( >+ { credentials: 'include', type: 'module' }, >+ 'new Worker() with credentials=include should send the credentials'); >+ >+// Tests for classic scripts. >+ >+credentials_test( >+ { type: 'classic' }, >+ 'new Worker() with type=classic should always send the credentials ' + >+ 'regardless of the credentials option (default).'); >+ >+credentials_test( >+ { credentials: 'omit', type: 'classic' }, >+ 'new Worker() with type=classic should always send the credentials ' + >+ 'regardless of the credentials option (omit).'); >+ >+credentials_test( >+ { credentials: 'same-origin', type: 'classic' }, >+ 'new Worker() with type=classic should always send the credentials ' + >+ 'regardless of the credentials option (same-origin).'); >+ >+credentials_test( >+ { credentials: 'include', type: 'classic' }, >+ 'new Worker() with type=classic should always send the credentials ' + >+ 'regardless of the credentials option (include).'); >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-options-credentials.html.headers b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-options-credentials.html.headers >new file mode 100644 >index 0000000000000000000000000000000000000000..6f53744a6ae77b6e5bbc5585767984ffe36854a2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-options-credentials.html.headers >@@ -0,0 +1,2 @@ >+Set-Cookie: COOKIE_NAME=COOKIE_VALUE >+Access-Control-Allow-Credentials: true >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-options-type-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-options-type-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..078e2a2058dd66ca6092ae13d7adcebdf9c73922 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-options-type-expected.txt >@@ -0,0 +1,7 @@ >+ >+PASS Test worker construction with the default worker type. >+PASS Test worker construction with the "classic" worker type. >+PASS Test worker construction with the "module" worker type. >+FAIL Test worker construction with an empty worker type. assert_equals: expected "TypeError" but got "Error" >+FAIL Test worker construction with an unknown worker type. assert_equals: expected "TypeError" but got "Error" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-options-type.html b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-options-type.html >new file mode 100644 >index 0000000000000000000000000000000000000000..b7c96b152950dda87ff0a34192008a6e30ec7471 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-options-type.html >@@ -0,0 +1,47 @@ >+<!DOCTYPE html> >+<title>DedicatedWorker: WorkerOptions 'type'</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+ >+promise_test(() => { >+ const worker = new Worker('resources/post-message-on-load-worker.js'); >+ return new Promise(resolve => worker.onmessage = resolve) >+ .then(msg_event => assert_equals(msg_event.data, 'LOADED')); >+}, 'Test worker construction with the default worker type.'); >+ >+promise_test(() => { >+ const worker = new Worker('resources/post-message-on-load-worker.js', >+ { type: 'classic' }); >+ return new Promise(resolve => worker.onmessage = resolve) >+ .then(msg_event => assert_equals(msg_event.data, 'LOADED')); >+}, 'Test worker construction with the "classic" worker type.'); >+ >+promise_test(() => { >+ const worker = new Worker('resources/post-message-on-load-worker.js', >+ { type: 'module' }); >+ return new Promise(resolve => worker.onmessage = resolve) >+ .then(msg_event => assert_equals(msg_event.data, 'LOADED')); >+}, 'Test worker construction with the "module" worker type.'); >+ >+test(() => { >+ try { >+ new Worker('resources/post-message-on-load-worker.js', { type: '' }); >+ assert_unreached( >+ 'Worker construction with an empty type should throw an exception'); >+ } catch (e) { >+ assert_equals(e.name, 'TypeError'); >+ } >+}, 'Test worker construction with an empty worker type.'); >+ >+test(() => { >+ try { >+ new Worker('resources/post-message-on-load-worker.js', { type: 'unknown' }); >+ assert_unreached( >+ 'Worker construction with an unknown type should throw an exception'); >+ } catch (e) { >+ assert_equals(e.name, 'TypeError'); >+ } >+}, 'Test worker construction with an unknown worker type.'); >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/credentials.py b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/credentials.py >new file mode 100644 >index 0000000000000000000000000000000000000000..8f79563fb5ff9c966c4bd188883c460a09381349 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/credentials.py >@@ -0,0 +1,10 @@ >+def main(request, response): >+ cookie = request.cookies.first("COOKIE_NAME", None) >+ >+ response_headers = [("Content-Type", "text/javascript"), >+ ("Access-Control-Allow-Credentials", "true")] >+ >+ cookie_value = ''; >+ if cookie: >+ cookie_value = cookie.value; >+ return (200, response_headers, "postMessage('"+cookie_value+"');") >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-and-then-static-import-worker.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-and-then-static-import-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..39ab5c237e2ab54423dd32945afa3ae902087763 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-and-then-static-import-worker.js >@@ -0,0 +1,2 @@ >+import('./export-on-static-import-script.js') >+ .then(module => postMessage(module.importedModules)); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-given-url-worker.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-given-url-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..2ea88b8071875a431cb4b40225facd1adf6d5644 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-given-url-worker.js >@@ -0,0 +1,5 @@ >+// This worker dynamically imports the script URL sent by postMessage(), and >+// sends back an error name if the dynamic import fails. >+self.addEventListener('message', msg_event => { >+ import(msg_event.data).catch(e => postMessage(e.name)); >+}); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-remote-origin-referrer-checker-worker.sub.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-remote-origin-referrer-checker-worker.sub.js >new file mode 100644 >index 0000000000000000000000000000000000000000..522c5798ba738b5074e5332dbb7d7fb5268ee6a9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-remote-origin-referrer-checker-worker.sub.js >@@ -0,0 +1,2 @@ >+// Import a remote origin script. >+import('https://{{domains[www1]}}:{{ports[https][0]}}/workers/modules/resources/referrer-checker.py'); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-remote-origin-script-worker.sub.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-remote-origin-script-worker.sub.js >new file mode 100644 >index 0000000000000000000000000000000000000000..0937086d72d011d81a380e31e97b5c6a0746f02d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-remote-origin-script-worker.sub.js >@@ -0,0 +1,4 @@ >+// Import a remote origin script. >+import('https://{{domains[www1]}}:{{ports[https][0]}}/workers/modules/resources/export-on-load-script.js') >+ .then(module => postMessage(module.importedModules)) >+ .catch(e => postMessage(['ERROR'])); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-same-origin-referrer-checker-worker.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-same-origin-referrer-checker-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..1d68624c3cb5bc13f489e896d5f41760da85f2e3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-same-origin-referrer-checker-worker.js >@@ -0,0 +1 @@ >+import('./referrer-checker.py'); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-worker.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..cd321fe24606bb55f3be570e31740b99d6fbff47 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-worker.js >@@ -0,0 +1,2 @@ >+import('./export-on-load-script.js') >+ .then(module => postMessage(module.importedModules)); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/empty-worker.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/empty-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..49ceb2648a93410bdd5ee53ef0e114146210741b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/empty-worker.js >@@ -0,0 +1 @@ >+// Do nothing. >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/eval-dynamic-import-worker.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/eval-dynamic-import-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..e92aff21a885536713141bd23a37733d5a66bfe2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/eval-dynamic-import-worker.js >@@ -0,0 +1,3 @@ >+const code = "import('./export-on-load-script.js')" + >+ " .then(module => postMessage(module.importedModules));" >+eval(code); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/export-on-dynamic-import-script.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/export-on-dynamic-import-script.js >new file mode 100644 >index 0000000000000000000000000000000000000000..8d172c324d306d8e0792e3637be3fdfcdc354927 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/export-on-dynamic-import-script.js >@@ -0,0 +1,7 @@ >+// Export the list of imported modules. It's available after the |ready| promise >+// is resolved. >+export let importedModules = ['export-on-dynamic-import-script.js']; >+export let ready = import('./export-on-load-script.js') >+ .then(module => { >+ Array.prototype.push.apply(importedModules, module.importedModules); >+ }); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/export-on-load-script.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/export-on-load-script.js >new file mode 100644 >index 0000000000000000000000000000000000000000..7d1b122c32259c0972556bb036be69b785351357 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/export-on-load-script.js >@@ -0,0 +1 @@ >+export const importedModules = ['export-on-load-script.js']; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/export-on-load-script.js.headers b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/export-on-load-script.js.headers >new file mode 100644 >index 0000000000000000000000000000000000000000..cb762eff806849df46dc758ef7b98b63f27f54c9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/export-on-load-script.js.headers >@@ -0,0 +1 @@ >+Access-Control-Allow-Origin: * >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/export-on-static-import-script.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/export-on-static-import-script.js >new file mode 100644 >index 0000000000000000000000000000000000000000..3f7174eef0beb68a3f36d66d3ed7a73c9074955c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/export-on-static-import-script.js >@@ -0,0 +1,3 @@ >+import * as module from './export-on-load-script.js'; >+const filename = 'export-on-static-import-script.js'; >+export const importedModules = [filename].concat(module.importedModules); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/import-meta-url-worker.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/import-meta-url-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..9d909778eda0e3a6082b6f93a8fabf36a82b9267 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/import-meta-url-worker.js >@@ -0,0 +1 @@ >+postMessage(import.meta.url); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/import-scripts-worker.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/import-scripts-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..676cccb2ad7f6fc6c6a77474ca0683738db03983 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/import-scripts-worker.js >@@ -0,0 +1,15 @@ >+try { >+ importScripts('empty-worker.js'); >+ postMessage('LOADED'); >+} catch (e) { >+ // Post a message instead of propagating an ErrorEvent to the page because >+ // propagated event loses an error name. >+ // >+ // Step 1. "Let notHandled be the result of firing an event named error at the >+ // Worker object associated with the worker, using ErrorEvent, with the >+ // cancelable attribute initialized to true, the message, filename, lineno, >+ // and colno attributes initialized appropriately, and the error attribute >+ // initialized to null." >+ // https://html.spec.whatwg.org/multipage/workers.html#runtime-script-errors-2 >+ postMessage(e.name); >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/nested-dynamic-import-worker.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/nested-dynamic-import-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..5ae82f8aa054f8f3a61475994c4e658ba282c890 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/nested-dynamic-import-worker.js >@@ -0,0 +1,5 @@ >+import('./export-on-dynamic-import-script.js') >+ .then(async module => { >+ await module.ready; >+ postMessage(module.importedModules); >+ }); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/nested-static-import-worker.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/nested-static-import-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..72ab31cb1c6ef1b77f4de3610cde2e58e094669d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/nested-static-import-worker.js >@@ -0,0 +1,2 @@ >+import * as module from './export-on-static-import-script.js'; >+postMessage(module.importedModules); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/new-worker-window.html b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/new-worker-window.html >new file mode 100644 >index 0000000000000000000000000000000000000000..5ae150725eb973ce1c2c7b54eb45669e057e8875 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/new-worker-window.html >@@ -0,0 +1,15 @@ >+<!DOCTYPE html> >+<title>DedicatedWorker: new Worker()</title> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+let worker; >+ >+// Creates a new dedicated worker for a given script url. >+window.onmessage = e => { >+ worker = new Worker(e.data, { type: 'module' }); >+ worker.onmessage = msg => window.opener.postMessage(msg.data, '*'); >+ worker.onerror = err => window.opener.postMessage(['ERROR'], '*'); >+}; >+window.opener.postMessage('LOADED', '*'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/post-message-on-load-worker.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/post-message-on-load-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..93818ccad90c60547d724f8fdcdaf626b7301cb6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/post-message-on-load-worker.js >@@ -0,0 +1 @@ >+postMessage('LOADED'); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/referrer-checker.py b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/referrer-checker.py >new file mode 100644 >index 0000000000000000000000000000000000000000..83a90032cafff26ca729296258aeabe907993442 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/referrer-checker.py >@@ -0,0 +1,9 @@ >+# Returns a worker script that posts the request's referrer header. >+def main(request, response): >+ referrer = request.headers.get("referer", "") >+ >+ response_headers = [("Content-Type", "text/javascript"), >+ ("Access-Control-Allow-Origin", "*")] >+ >+ return (200, response_headers, >+ "postMessage('"+referrer+"')") >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-and-then-dynamic-import-worker.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-and-then-dynamic-import-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..89125e0af7b0af62823628cb248a02c9b1d24343 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-and-then-dynamic-import-worker.js >@@ -0,0 +1,2 @@ >+import * as module from './export-on-dynamic-import-script.js'; >+module.ready.then(() => postMessage(module.importedModules)); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-non-existent-script-worker.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-non-existent-script-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..16f70e9daf4909605746c6614a509afb3cf71ed1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-non-existent-script-worker.js >@@ -0,0 +1 @@ >+import './non-existent-script.js'; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-remote-origin-referrer-checker-worker.sub.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-remote-origin-referrer-checker-worker.sub.js >new file mode 100644 >index 0000000000000000000000000000000000000000..1722fc9343ecab4e27bdeae07329d6ce219068e4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-remote-origin-referrer-checker-worker.sub.js >@@ -0,0 +1,2 @@ >+// Import a remote origin script. >+import 'https://{{domains[www1]}}:{{ports[https][0]}}/workers/modules/resources/referrer-checker.py'; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-remote-origin-script-worker.sub.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-remote-origin-script-worker.sub.js >new file mode 100644 >index 0000000000000000000000000000000000000000..00ef44eff580f575621be2be250ea787b19a3200 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-remote-origin-script-worker.sub.js >@@ -0,0 +1,3 @@ >+// Import a remote origin script. >+import * as module from 'https://{{domains[www1]}}:{{ports[https][0]}}/workers/modules/resources/export-on-load-script.js'; >+postMessage(module.importedModules); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-same-origin-referrer-checker-worker.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-same-origin-referrer-checker-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..7d564f9c434415704e32b96d9d3660eceda91b0e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-same-origin-referrer-checker-worker.js >@@ -0,0 +1 @@ >+import './referrer-checker.py'; >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-worker.js b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..f0639153a94feaef8efa30feabf26752ba058853 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-worker.js >@@ -0,0 +1,2 @@ >+import * as module from './export-on-load-script.js'; >+postMessage(module.importedModules); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..a7b800f66f27c320fb56e0642562e8946917cb5d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/w3c-import.log >@@ -0,0 +1,42 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/credentials.py >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-and-then-static-import-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-given-url-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-remote-origin-referrer-checker-worker.sub.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-remote-origin-script-worker.sub.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-same-origin-referrer-checker-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/dynamic-import-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/empty-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/eval-dynamic-import-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/export-on-dynamic-import-script.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/export-on-load-script.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/export-on-load-script.js.headers >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/export-on-static-import-script.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/import-meta-url-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/import-scripts-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/nested-dynamic-import-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/nested-static-import-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/new-worker-window.html >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/post-message-on-load-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/referrer-checker.py >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-and-then-dynamic-import-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-non-existent-script-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-remote-origin-referrer-checker-worker.sub.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-remote-origin-script-worker.sub.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-same-origin-referrer-checker-worker.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/resources/static-import-worker.js >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/modules/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..22018a0ab2a9b36e03db254d4b548f6a5d63eed9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/modules/w3c-import.log >@@ -0,0 +1,24 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/w3c/web-platform-tests >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-csp.html >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-failure.html >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-meta.html >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import-referrer.html >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-import.html >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-options-credentials.html >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-options-credentials.html.headers >+/LayoutTests/imported/w3c/web-platform-tests/workers/modules/dedicated-worker-options-type.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/name-property.html b/LayoutTests/imported/w3c/web-platform-tests/workers/name-property.html >index 939601e5e3615dfe085675d9aecd499463025b4f..ccc2a9de3a9c59acc19eefb247b1c92b78a52941 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/workers/name-property.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/name-property.html >@@ -10,16 +10,21 @@ > > <script> > "use strict"; >+setup({explicit_done: true}); > >-const worker = new Worker("support/name.js", { name: "my name" }); >-fetch_tests_from_worker(worker); >+(async function() { >+ const worker = new Worker("support/name.js", { name: "my name" }); >+ await fetch_tests_from_worker(worker); > >-const worker2 = new Worker("support/name-as-accidental-global.js"); >-fetch_tests_from_worker(worker2); >+ const worker2 = new Worker("support/name-as-accidental-global.js"); >+ await fetch_tests_from_worker(worker2); > >-const sharedWorker = new SharedWorker("support/name.js", { name: "my name" }); >-fetch_tests_from_worker(sharedWorker); >+ const sharedWorker = new SharedWorker("support/name.js", { name: "my name" }); >+ await fetch_tests_from_worker(sharedWorker); > >-const sharedWorker2 = new SharedWorker("support/name-as-accidental-global.js"); >-fetch_tests_from_worker(sharedWorker2); >+ const sharedWorker2 = new SharedWorker("support/name-as-accidental-global.js"); >+ await fetch_tests_from_worker(sharedWorker2); >+ >+ done(); >+})(); > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/nested_worker.worker.js b/LayoutTests/imported/w3c/web-platform-tests/workers/nested_worker.worker.js >index 8848fa216bc0059d444a7ec0eb223ca2d5ee1e5c..005b3c2f3039729eba2e30c52557d4310f0cebea 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/workers/nested_worker.worker.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/nested_worker.worker.js >@@ -6,6 +6,6 @@ async_test(function() { > worker1.onmessage = this.step_func_done(function(evt) { > assert_equals(evt.data, "Pass"); > worker1.terminate(); >- done(); > }); > }, "Nested worker"); >+done(); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/opaque-origin.html b/LayoutTests/imported/w3c/web-platform-tests/workers/opaque-origin.html >index 0474b970c96f288229bc244c10f060e3feb33990..83574b456fec9d9867b15215b232384e6dae7f08 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/workers/opaque-origin.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/opaque-origin.html >@@ -11,6 +11,7 @@ onmessage = e => { > channel.port2.postMessage(e.data); > }; > fetch_tests_from_worker(channel.port1); >+channel.port1.start(); > </script> > <iframe sandbox="allow-scripts" src="support/sandboxed-tests.html?pipe=sub"></iframe> > </body> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/003.html b/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/003.html >index 85c688bc08276631da2dd828f0dd530652ccec83..a296db13af2086ef2039693980578611976046a3 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/003.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/003.html >@@ -27,6 +27,7 @@ async_test(function() { > assert_equals(e.data, '123'); > this.done(); > }); >+ w1.onerror = this.unreached_func("error"); > }); > </script> > <!-- >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/005.html b/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/005.html >index 289c25ec6cb90b66cc941628f5b9b8d82d238d07..d5e21ea527476b059fde7dbc67b2d04339068bd5 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/005.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/005.html >@@ -30,6 +30,7 @@ async_test(function() { > assert_equals(e.data, '123'); > this.done(); > }); >+ w1.onerror = this.unreached_func("error"); > }); > </script> > <!-- >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/006.html b/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/006.html >index ef21242563bcf99f145c35b15ebe70910859debb..7fbfd8e90f8014373f73818757b8787f0a9caeea 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/006.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/006.html >@@ -2,6 +2,9 @@ > if (location.hash == '#1') { > onconnect = function(e) { > var port = e.ports[0]; >+ onerror = e => { >+ port.postMessage(String(e)) >+ } > var w2 = new Worker('#2'); > w2.onmessage = function(e) { > port.postMessage('1'+e.data); >@@ -28,6 +31,7 @@ async_test(function() { > assert_equals(e.data, '123'); > this.done(); > }); >+ w1.onerror = this.unreached_func("error"); > }); > </script> > <!-- >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/007.html b/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/007.html >index e99345073ba4c42b4cf5168d48c9f548eb243003..1fe66e4225e7e8932dfb13e174f03de04f372edb 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/007.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/007.html >@@ -32,6 +32,7 @@ async_test(function() { > assert_equals(e.data, '123'); > this.done(); > }); >+ w1.onerror = this.unreached_func("error"); > }); > </script> > <!-- >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/008.html b/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/008.html >index fbb41e0d0b388ec93521d77adb5b1498b4caa59d..e8554a438a5ce09ae90ca654c99865a2f633d2f2 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/008.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/multiple-workers/008.html >@@ -24,6 +24,7 @@ onload = t.step_func(function() { > this.done(); > }); > }); >+ w1.onerror = this.unreached_func("error"); > }); > </script> > <!-- >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/support/WorkerSendingPerformanceNow.js b/LayoutTests/imported/w3c/web-platform-tests/workers/support/WorkerSendingPerformanceNow.js >new file mode 100644 >index 0000000000000000000000000000000000000000..ac12190efe3af9b3e7cf36f309b12d6b6ddcc49d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/support/WorkerSendingPerformanceNow.js >@@ -0,0 +1,22 @@ >+function calcResponse() { >+ const response = [ >+ typeof(workerStart), >+ typeof(performance), >+ typeof(performance.now), >+ performance.now() >+ ]; >+ return response; >+} >+ >+self.onmessage = function(event) { >+ postMessage(calcResponse()); >+ self.close(); >+} >+ >+self.addEventListener("connect", function(event) { >+ const port = event.ports[0]; >+ port.onmessage = function(event) { >+ port.postMessage(calcResponse()); >+ port.close(); >+ }; >+}); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/support/iframe_sw_dataUrl.html b/LayoutTests/imported/w3c/web-platform-tests/workers/support/iframe_sw_dataUrl.html >new file mode 100644 >index 0000000000000000000000000000000000000000..0fb0ec228079de8dd15626fb3161b53d48c68112 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/support/iframe_sw_dataUrl.html >@@ -0,0 +1,13 @@ >+<!DOCTYPE html> >+<title>Iframe for Shared Worker: Data URL cross-origin checks</title> >+<body> >+<script> >+ >+let worker = new SharedWorker('data:text/javascript,let conns=0; onconnect = e => { e.ports[0].postMessage(++conns); }'); >+worker.port.onmessage = e => { >+ parent.postMessage(e.data, '*'); >+} >+ >+</script> >+</body> >+</html> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/support/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/workers/support/w3c-import.log >index d04b94e05f0805af616d970b257b0c15a74c1c5f..5cf0afa04444d3d30bdfce2e1255c197cd27633e 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/workers/support/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/support/w3c-import.log >@@ -27,8 +27,10 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/workers/support/WorkerLocation-origin.html > /LayoutTests/imported/w3c/web-platform-tests/workers/support/WorkerLocation.js > /LayoutTests/imported/w3c/web-platform-tests/workers/support/WorkerNavigator.js >+/LayoutTests/imported/w3c/web-platform-tests/workers/support/WorkerSendingPerformanceNow.js > /LayoutTests/imported/w3c/web-platform-tests/workers/support/WorkerTerminate.js > /LayoutTests/imported/w3c/web-platform-tests/workers/support/WorkerText.txt >+/LayoutTests/imported/w3c/web-platform-tests/workers/support/iframe_sw_dataUrl.html > /LayoutTests/imported/w3c/web-platform-tests/workers/support/name-as-accidental-global.js > /LayoutTests/imported/w3c/web-platform-tests/workers/support/name.js > /LayoutTests/imported/w3c/web-platform-tests/workers/support/nosiniff-error-worker.py >diff --git a/LayoutTests/imported/w3c/web-platform-tests/workers/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/workers/w3c-import.log >index b1130e1752afee360acd1de62c7011754841479e..589509e0ba4157c5f6e770ec99514376ac09125e 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/workers/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/workers/w3c-import.log >@@ -16,7 +16,9 @@ None > List of files: > /LayoutTests/imported/w3c/web-platform-tests/workers/OWNERS > /LayoutTests/imported/w3c/web-platform-tests/workers/README.md >+/LayoutTests/imported/w3c/web-platform-tests/workers/SharedWorkerPerformanceNow.html > /LayoutTests/imported/w3c/web-platform-tests/workers/SharedWorker_blobUrl.html >+/LayoutTests/imported/w3c/web-platform-tests/workers/SharedWorker_dataUrl.html > /LayoutTests/imported/w3c/web-platform-tests/workers/WorkerGlobalScope_ErrorEvent_colno.htm > /LayoutTests/imported/w3c/web-platform-tests/workers/WorkerGlobalScope_ErrorEvent_filename.htm > /LayoutTests/imported/w3c/web-platform-tests/workers/WorkerGlobalScope_ErrorEvent_lineno.htm >@@ -25,6 +27,7 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/workers/WorkerGlobalScope_importScripts.htm > /LayoutTests/imported/w3c/web-platform-tests/workers/WorkerGlobalScope_importScripts_NetworkErr.htm > /LayoutTests/imported/w3c/web-platform-tests/workers/WorkerGlobalScope_importScripts_NosniffErr.htm >+/LayoutTests/imported/w3c/web-platform-tests/workers/WorkerGlobalScope_requestAnimationFrame.htm > /LayoutTests/imported/w3c/web-platform-tests/workers/WorkerGlobalScope_setInterval.htm > /LayoutTests/imported/w3c/web-platform-tests/workers/WorkerGlobalScope_setTimeout.htm > /LayoutTests/imported/w3c/web-platform-tests/workers/WorkerLocation-origin.sub.window.js >@@ -47,6 +50,7 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/workers/WorkerNavigator_onLine.htm > /LayoutTests/imported/w3c/web-platform-tests/workers/WorkerNavigator_platform.htm > /LayoutTests/imported/w3c/web-platform-tests/workers/WorkerNavigator_userAgent.htm >+/LayoutTests/imported/w3c/web-platform-tests/workers/WorkerPerformanceNow.html > /LayoutTests/imported/w3c/web-platform-tests/workers/Worker_ErrorEvent_bubbles_cancelable.htm > /LayoutTests/imported/w3c/web-platform-tests/workers/Worker_ErrorEvent_error.htm > /LayoutTests/imported/w3c/web-platform-tests/workers/Worker_ErrorEvent_filename.htm >diff --git a/LayoutTests/imported/w3c/web-platform-tests/xhr/resources/inspect-headers.py b/LayoutTests/imported/w3c/web-platform-tests/xhr/resources/inspect-headers.py >index a8f1258fa2586a3a3db3c0e3cfe1a55bf9311ebf..12dd33595f07c632cbe58780714e66fac15e4a6c 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/xhr/resources/inspect-headers.py >+++ b/LayoutTests/imported/w3c/web-platform-tests/xhr/resources/inspect-headers.py >@@ -15,7 +15,7 @@ def get_response(raw_headers, filter_value, filter_name): > if value == filter_value: > result += name + "," > elif name.lower() == filter_name: >- result += name + ": " + value + "\n"; >+ result += name + ": " + value + "\n" > return result > > def main(request, response): >diff --git a/LayoutTests/platform/mac/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-history-backward-navigation-manual.https-expected.txt b/LayoutTests/platform/mac/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-history-backward-navigation-manual.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..5fe7e59e72ef3b0e2b1cea24cca1c2883a0e7a67 >--- /dev/null >+++ b/LayoutTests/platform/mac/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-history-backward-navigation-manual.https-expected.txt >@@ -0,0 +1,16 @@ >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x68 >+ RenderBlock {HTML} at (0,0) size 800x68 >+ RenderBody {BODY} at (8,16) size 784x36 >+ RenderBlock {P} at (0,0) size 784x36 >+ RenderText {#text} at (0,0) size 39x18 >+ text run at (0,0) width 39: "Click " >+ RenderInline {A} at (0,0) size 53x18 [color=#0000EE] >+ RenderText {#text} at (38,0) size 53x18 >+ text run at (38,0) width 53: "this link" >+ RenderText {#text} at (90,0) size 767x36 >+ text run at (90,0) width 9: ". " >+ text run at (98,0) width 669: "Once you see \"method = GET,...\" in the page, go to another page, and then go back to the page using the" >+ text run at (0,18) width 118: "Backward button. " >+ text run at (117,18) width 394: "You should see \"method = GET, isHistoryNavigation = true\"." >diff --git a/LayoutTests/platform/mac/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-history-forward-navigation-manual.https-expected.txt b/LayoutTests/platform/mac/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-history-forward-navigation-manual.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..96c7fa32b9a2ed4ab757d89792bad073e2425366 >--- /dev/null >+++ b/LayoutTests/platform/mac/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-history-forward-navigation-manual.https-expected.txt >@@ -0,0 +1,16 @@ >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x68 >+ RenderBlock {HTML} at (0,0) size 800x68 >+ RenderBody {BODY} at (8,16) size 784x36 >+ RenderBlock {P} at (0,0) size 784x36 >+ RenderText {#text} at (0,0) size 39x18 >+ text run at (0,0) width 39: "Click " >+ RenderInline {A} at (0,0) size 53x18 [color=#0000EE] >+ RenderText {#text} at (38,0) size 53x18 >+ text run at (38,0) width 53: "this link" >+ RenderText {#text} at (90,0) size 782x36 >+ text run at (90,0) width 9: ". " >+ text run at (98,0) width 684: "Once you see \"method = GET,...\" in the page, go back to this page using the Backward button, and then go" >+ text run at (0,18) width 292: "to the second page using the Forward button. " >+ text run at (291,18) width 394: "You should see \"method = GET, isHistoryNavigation = true\"." >diff --git a/LayoutTests/platform/mac/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-reload-navigation-manual.https-expected.txt b/LayoutTests/platform/mac/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-reload-navigation-manual.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..74e1e094a1f8ea6eacf8b67b64ec9bda8825d9eb >--- /dev/null >+++ b/LayoutTests/platform/mac/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-is-reload-navigation-manual.https-expected.txt >@@ -0,0 +1,16 @@ >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x68 >+ RenderBlock {HTML} at (0,0) size 800x68 >+ RenderBody {BODY} at (8,16) size 784x36 >+ RenderBlock {P} at (0,0) size 784x36 >+ RenderText {#text} at (0,0) size 39x18 >+ text run at (0,0) width 39: "Click " >+ RenderInline {A} at (0,0) size 53x18 [color=#0000EE] >+ RenderText {#text} at (38,0) size 53x18 >+ text run at (38,0) width 53: "this link" >+ RenderText {#text} at (90,0) size 690x36 >+ text run at (90,0) width 9: ". " >+ text run at (98,0) width 403: "Once you see \"method = GET,...\" in the page, reload the page. " >+ text run at (500,0) width 190: "You will see \"method = GET," >+ text run at (0,18) width 180: "isReloadNavigation = true\"."
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 186411
:
342209
|
342215
|
342217
|
342221
|
342222
|
342255
|
342263
|
342267
|
342268
|
342269
|
342296
|
342303
|
342305
|
342306
|
342308
|
342313
|
342329
|
342335
|
342338
|
342339
|
342384
|
342388
|
342393
|
342394
|
342398
|
342399
|
342401