Update web-platform-tests to revision 000905d008db2538360020335bc2dbba16d322b5.

This commit is contained in:
Ms2ger 2015-04-16 12:51:35 +02:00
parent 53d2432c90
commit 2d49203b9c
100 changed files with 3807 additions and 201 deletions

View file

@ -0,0 +1,51 @@
<!DOCTYPE html>
<title>Cache Storage: Verify that Window and Workers see same storage</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/testharness-helpers.js"></script>
<script>
function wait_for_message(worker) {
return new Promise(function(resolve) {
worker.addEventListener('message', function listener(e) {
resolve(e.data);
worker.removeEventListener('message', listener);
});
});
}
promise_test(function(t) {
var cache_name = 'common-test';
return self.caches.delete(cache_name)
.then(function() {
var worker = new Worker('resources/common-worker.js');
worker.postMessage({name: cache_name});
return wait_for_message(worker);
})
.then(function(message) {
return self.caches.open(cache_name);
})
.then(function(cache) {
return Promise.all([
cache.match('https://example.com/a'),
cache.match('https://example.com/b'),
cache.match('https://example.com/c')
]);
})
.then(function(responses) {
return Promise.all(responses.map(
function(response) { return response.text(); }
));
})
.then(function(bodies) {
assert_equals(bodies[0], 'a',
'Body should match response put by worker');
assert_equals(bodies[1], 'b',
'Body should match response put by worker');
assert_equals(bodies[2], 'c',
'Body should match response put by worker');
});
}, 'Window sees cache puts by Worker');
</script>

View file

@ -0,0 +1,2 @@
<!DOCTYPE html>
<title>Empty doc</title>

View file

@ -0,0 +1,15 @@
self.onmessage = function(e) {
var cache_name = e.data.name;
self.caches.open(cache_name)
.then(function(cache) {
return Promise.all([
cache.put('https://example.com/a', new Response('a')),
cache.put('https://example.com/b', new Response('b')),
cache.put('https://example.com/c', new Response('c'))
]);
})
.then(function() {
self.postMessage('ok');
});
};

View file

@ -0,0 +1,2 @@
def main(request, response):
return int(request.GET["status"]), [], ""

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<title>ok</title>
<script>
window.onmessage = function(e) {
var id = e.data.id;
try {
self.caches;
window.parent.postMessage({id: id, result: 'allowed'}, '*');
} catch (e) {
window.parent.postMessage({id: id, result: 'denied', name: e.name, message: e.message}, '*');
}
};
</script>

View file

@ -0,0 +1 @@
a simple text file

View file

@ -0,0 +1,37 @@
(function() {
var next_cache_index = 1;
// Returns a promise that resolves to a newly created Cache object. The
// returned Cache will be destroyed when |test| completes.
function create_temporary_cache(test) {
var uniquifier = String(++next_cache_index);
var cache_name = self.location.pathname + '/' + uniquifier;
test.add_cleanup(function() {
self.caches.delete(cache_name);
});
return self.caches.delete(cache_name)
.then(function() {
return self.caches.open(cache_name);
});
}
self.create_temporary_cache = create_temporary_cache;
})();
// Runs |test_function| with a temporary unique Cache passed in as the only
// argument. The function is run as a part of Promise chain owned by
// promise_test(). As such, it is expected to behave in a manner identical (with
// the exception of the argument) to a function passed into promise_test().
//
// E.g.:
// cache_test(function(cache) {
// // Do something with |cache|, which is a Cache object.
// }, "Some Cache test");
function cache_test(test_function, description) {
promise_test(function(test) {
return create_temporary_cache(test)
.then(test_function);
}, description);
}

View file

@ -0,0 +1,163 @@
/*
* testharness-helpers contains various useful extensions to testharness.js to
* allow them to be used across multiple tests before they have been
* upstreamed. This file is intended to be usable from both document and worker
* environments, so code should for example not rely on the DOM.
*/
// Returns a promise that fulfills after the provided |promise| is fulfilled.
// The |test| succeeds only if |promise| rejects with an exception matching
// |code|. Accepted values for |code| follow those accepted for assert_throws().
// The optional |description| describes the test being performed.
//
// E.g.:
// assert_promise_rejects(
// new Promise(...), // something that should throw an exception.
// 'NotFoundError',
// 'Should throw NotFoundError.');
//
// assert_promise_rejects(
// new Promise(...),
// new TypeError(),
// 'Should throw TypeError');
function assert_promise_rejects(promise, code, description) {
return promise.then(
function() {
throw 'assert_promise_rejects: ' + description + ' Promise did not reject.';
},
function(e) {
if (code !== undefined) {
assert_throws(code, function() { throw e; }, description);
}
});
}
// Asserts that two objects |actual| and |expected| are weakly equal under the
// following definition:
//
// |a| and |b| are weakly equal if any of the following are true:
// 1. If |a| is not an 'object', and |a| === |b|.
// 2. If |a| is an 'object', and all of the following are true:
// 2.1 |a.p| is weakly equal to |b.p| for all own properties |p| of |a|.
// 2.2 Every own property of |b| is an own property of |a|.
//
// This is a replacement for the the version of assert_object_equals() in
// testharness.js. The latter doesn't handle own properties correctly. I.e. if
// |a.p| is not an own property, it still requires that |b.p| be an own
// property.
//
// Note that |actual| must not contain cyclic references.
self.assert_object_equals = function(actual, expected, description) {
var object_stack = [];
function _is_equal(actual, expected, prefix) {
if (typeof actual !== 'object') {
assert_equals(actual, expected, prefix);
return;
}
assert_true(typeof expected === 'object', prefix);
assert_equals(object_stack.indexOf(actual), -1,
prefix + ' must not contain cyclic references.');
object_stack.push(actual);
Object.getOwnPropertyNames(expected).forEach(function(property) {
assert_own_property(actual, property, prefix);
_is_equal(actual[property], expected[property],
prefix + '.' + property);
});
Object.getOwnPropertyNames(actual).forEach(function(property) {
assert_own_property(expected, property, prefix);
});
object_stack.pop();
}
function _brand(object) {
return Object.prototype.toString.call(object).match(/^\[object (.*)\]$/)[1];
}
_is_equal(actual, expected,
(description ? description + ': ' : '') + _brand(expected));
};
// Equivalent to assert_in_array, but uses a weaker equivalence relation
// (assert_object_equals) than '==='.
function assert_object_in_array(actual, expected_array, description) {
assert_true(expected_array.some(function(element) {
try {
assert_object_equals(actual, element);
return true;
} catch (e) {
return false;
}
}), description);
}
// Assert that the two arrays |actual| and |expected| contain the same set of
// elements as determined by assert_object_equals. The order is not significant.
//
// |expected| is assumed to not contain any duplicates as determined by
// assert_object_equals().
function assert_array_equivalent(actual, expected, description) {
assert_true(Array.isArray(actual), description);
assert_equals(actual.length, expected.length, description);
expected.forEach(function(expected_element) {
// assert_in_array treats the first argument as being 'actual', and the
// second as being 'expected array'. We are switching them around because
// we want to be resilient against the |actual| array containing
// duplicates.
assert_object_in_array(expected_element, actual, description);
});
}
// Asserts that two arrays |actual| and |expected| contain the same set of
// elements as determined by assert_object_equals(). The corresponding elements
// must occupy corresponding indices in their respective arrays.
function assert_array_objects_equals(actual, expected, description) {
assert_true(Array.isArray(actual), description);
assert_equals(actual.length, expected.length, description);
actual.forEach(function(value, index) {
assert_object_equals(value, expected[index],
description + ' : object[' + index + ']');
});
}
// Asserts that |object| that is an instance of some interface has the attribute
// |attribute_name| following the conditions specified by WebIDL, but it's
// acceptable that the attribute |attribute_name| is an own property of the
// object because we're in the middle of moving the attribute to a prototype
// chain. Once we complete the transition to prototype chains,
// assert_will_be_idl_attribute must be replaced with assert_idl_attribute
// defined in testharness.js.
//
// FIXME: Remove assert_will_be_idl_attribute once we complete the transition
// of moving the DOM attributes to prototype chains. (http://crbug.com/43394)
function assert_will_be_idl_attribute(object, attribute_name, description) {
assert_true(typeof object === "object", description);
assert_true("hasOwnProperty" in object, description);
// Do not test if |attribute_name| is not an own property because
// |attribute_name| is in the middle of the transition to a prototype
// chain. (http://crbug.com/43394)
assert_true(attribute_name in object, description);
}
// Stringifies a DOM object. This function stringifies not only own properties
// but also DOM attributes which are on a prototype chain. Note that
// JSON.stringify only stringifies own properties.
function stringifyDOMObject(object)
{
function deepCopy(src) {
if (typeof src != "object")
return src;
var dst = Array.isArray(src) ? [] : {};
for (var property in src) {
dst[property] = deepCopy(src[property]);
}
return dst;
}
return JSON.stringify(deepCopy(object));
}

View file

@ -0,0 +1,145 @@
if (self.importScripts) {
importScripts('/resources/testharness.js');
importScripts('../resources/testharness-helpers.js');
importScripts('../resources/test-helpers.js');
}
cache_test(function(cache) {
return assert_promise_rejects(
cache.add(),
new TypeError(),
'Cache.add should throw a TypeError when no arguments are given.');
}, 'Cache.add called with no arguments');
cache_test(function(cache) {
return cache.add('../resources/simple.txt')
.then(function(result) {
assert_equals(result, undefined,
'Cache.add should resolve with undefined on success.');
});
}, 'Cache.add called with relative URL specified as a string');
cache_test(function(cache) {
return assert_promise_rejects(
cache.add('javascript://this-is-not-http-mmkay'),
'NetworkError',
'Cache.add should throw a NetworkError for non-HTTP/HTTPS URLs.');
}, 'Cache.add called with non-HTTP/HTTPS URL');
cache_test(function(cache) {
var request = new Request('../resources/simple.txt', {method: 'POST', body: 'Hello'});
return cache.add(request)
.then(function(result) {
assert_equals(result, undefined,
'Cache.add should resolve with undefined on success.');
});
}, 'Cache.add called with Request object');
cache_test(function(cache) {
var request = new Request('../resources/simple.txt', {method: 'POST', body: 'Hello'});
return request.text()
.then(function() {
assert_false(request.bodyUsed);
})
.then(function() {
return cache.add(request);
});
}, 'Cache.add called with Request object with a used body');
cache_test(function(cache) {
var request = new Request('../resources/simple.txt', {method: 'POST', body: 'Hello'});
return cache.add(request)
.then(function(result) {
assert_equals(result, undefined,
'Cache.add should resolve with undefined on success.');
})
.then(function() {
return assert_promise_rejects(
cache.add(request),
new TypeError(),
'Cache.add should throw TypeError if same request is added twice.');
});
}, 'Cache.add called twice with the same Request object');
cache_test(function(cache) {
return cache.add('this-does-not-exist-please-dont-create-it')
.then(function(result) {
assert_equals(result, undefined,
'Cache.add should resolve with undefined on success.');
});
}, 'Cache.add with request that results in a status of 404');
cache_test(function(cache) {
return cache.add('../resources/fetch-status.py?status=500')
.then(function(result) {
assert_equals(result, undefined,
'Cache.add should resolve with undefined on success.');
});
}, 'Cache.add with request that results in a status of 500');
cache_test(function(cache) {
return assert_promise_rejects(
cache.addAll(),
new TypeError(),
'Cache.addAll with no arguments should throw TypeError.');
}, 'Cache.addAll with no arguments');
cache_test(function(cache) {
// Assumes the existence of ../resources/simple.txt and ../resources/blank.html
var urls = ['../resources/simple.txt', undefined, '../resources/blank.html'];
return assert_promise_rejects(
cache.addAll(),
new TypeError(),
'Cache.addAll should throw TypeError for an undefined argument.');
}, 'Cache.addAll with a mix of valid and undefined arguments');
cache_test(function(cache) {
// Assumes the existence of ../resources/simple.txt and ../resources/blank.html
var urls = ['../resources/simple.txt', self.location.href, '../resources/blank.html'];
return cache.addAll(urls)
.then(function(result) {
assert_equals(result, undefined,
'Cache.addAll should resolve with undefined on ' +
'success.');
});
}, 'Cache.addAll with string URL arguments');
cache_test(function(cache) {
// Assumes the existence of ../resources/simple.txt and ../resources/blank.html
var urls = ['../resources/simple.txt', self.location.href, '../resources/blank.html'];
var requests = urls.map(function(url) {
return new Request(url);
});
return cache.addAll(requests)
.then(function(result) {
assert_equals(result, undefined,
'Cache.addAll should resolve with undefined on ' +
'success.');
});
}, 'Cache.addAll with Request arguments');
cache_test(function(cache) {
// Assumes that ../resources/simple.txt and ../resources/blank.html exist. The second
// resource does not.
var urls = ['../resources/simple.txt', 'this-resource-should-not-exist', '../resources/blank.html'];
var requests = urls.map(function(url) {
return new Request(url);
});
return cache.addAll(requests)
.then(function(result) {
assert_equals(result, undefined,
'Cache.addAll should resolve with undefined on ' +
'success.');
});
}, 'Cache.addAll with a mix of succeeding and failing requests');
cache_test(function(cache) {
var request = new Request('../resources/simple.txt');
return assert_promise_rejects(
cache.addAll([request, request]),
new TypeError(),
'Cache.addAll should throw TypeError if the same request is added ' +
'twice.');
}, 'Cache.addAll called with the same Request object specified twice');
done();

View file

@ -0,0 +1,120 @@
if (self.importScripts) {
importScripts('/resources/testharness.js');
importScripts('../resources/testharness-helpers.js');
importScripts('../resources/test-helpers.js');
}
var test_url = 'https://example.com/foo';
// Construct a generic Request object. The URL is |test_url|. All other fields
// are defaults.
function new_test_request() {
return new Request(test_url);
}
// Construct a generic Response object.
function new_test_response() {
return new Response('Hello world!', { status: 200 });
}
cache_test(function(cache) {
return assert_promise_rejects(
cache.delete(),
new TypeError(),
'Cache.delete should reject with a TypeError when called with no ' +
'arguments.');
}, 'Cache.delete with no arguments');
cache_test(function(cache) {
return cache.put(new_test_request(), new_test_response())
.then(function() {
return cache.delete(test_url);
})
.then(function(result) {
assert_true(result,
'Cache.delete should resolve with "true" if an entry ' +
'was successfully deleted.');
return cache.match(test_url);
})
.then(function(result) {
assert_equals(result, undefined,
'Cache.delete should remove matching entries from cache.');
});
}, 'Cache.delete called with a string URL');
cache_test(function(cache) {
var request = new Request(test_url, { method: 'POST', body: 'Abc' });
return cache.put(request.clone(), new_test_response())
.then(function() {
return cache.delete(request);
})
.then(function(result) {
assert_true(result,
'Cache.delete should resolve with "true" if an entry ' +
'was successfully deleted.');
assert_false(request.bodyUsed,
'Cache.delete should not consume request body.');
});
}, 'Cache.delete called with a Request object');
cache_test(function(cache) {
var request = new Request(test_url, { method: 'POST', body: 'Abc' });
return cache.put(request.clone(), new_test_response())
.then(function() {
return request.text();
})
.then(function() {
assert_true(request.bodyUsed,
'[https://fetch.spec.whatwg.org/#body-mixin] ' +
'Request.bodyUsed should be true after text() method ' +
'resolves.');
})
.then(function() {
return cache.delete(request);
})
.then(function(result) {
assert_true(result,
'Cache.delete should resolve with "true" if an entry ' +
'was successfully deleted.');
});
}, 'Cache.delete with a Request object containing used body');
cache_test(function(cache) {
return cache.delete(test_url)
.then(function(result) {
assert_false(result,
'Cache.delete should resolve with "false" if there ' +
'are no matching entries.');
});
}, 'Cache.delete with a non-existent entry');
var cache_entries = {
a: {
request: new Request('http://example.com/abc'),
response: new Response('')
},
b: {
request: new Request('http://example.com/b'),
response: new Response('')
},
a_with_query: {
request: new Request('http://example.com/abc?q=r'),
response: new Response('')
}
};
function prepopulated_cache_test(test_function, description) {
cache_test(function(cache) {
return Promise.all(Object.keys(cache_entries).map(function(k) {
return cache.put(cache_entries[k].request.clone(),
cache_entries[k].response.clone());
}))
.then(function() {
return test_function(cache);
});
}, description);
}
done();

View file

@ -0,0 +1,501 @@
if (self.importScripts) {
importScripts('/resources/testharness.js');
importScripts('../resources/testharness-helpers.js');
importScripts('../resources/test-helpers.js');
}
// A set of Request/Response pairs to be used with prepopulated_cache_test().
var simple_entries = [
{
name: 'a',
request: new Request('http://example.com/a'),
response: new Response('')
},
{
name: 'b',
request: new Request('http://example.com/b'),
response: new Response('')
},
{
name: 'a_with_query',
request: new Request('http://example.com/a?q=r'),
response: new Response('')
},
{
name: 'A',
request: new Request('http://example.com/A'),
response: new Response('')
},
{
name: 'a_https',
request: new Request('https://example.com/a'),
response: new Response('')
},
{
name: 'a_org',
request: new Request('http://example.org/a'),
response: new Response('')
},
{
name: 'cat',
request: new Request('http://example.com/cat'),
response: new Response('')
},
{
name: 'catmandu',
request: new Request('http://example.com/catmandu'),
response: new Response('')
},
{
name: 'cat_num_lives',
request: new Request('http://example.com/cat?lives=9'),
response: new Response('')
},
{
name: 'cat_in_the_hat',
request: new Request('http://example.com/cat/in/the/hat'),
response: new Response('')
},
{
name: 'secret_cat',
request: new Request('http://tom:jerry@example.com/cat'),
response: new Response('')
},
{
name: 'top_secret_cat',
request: new Request('http://tom:j3rry@example.com/cat'),
response: new Response('')
}
];
// A set of Request/Response pairs to be used with prepopulated_cache_test().
// These contain a mix of test cases that use Vary headers.
var vary_entries = [
{
name: 'vary_cookie_is_cookie',
request: new Request('http://example.com/c',
{headers: {'Cookies': 'is-for-cookie'}}),
response: new Response('',
{headers: {'Vary': 'Cookies'}})
},
{
name: 'vary_cookie_is_good',
request: new Request('http://example.com/c',
{headers: {'Cookies': 'is-good-enough-for-me'}}),
response: new Response('',
{headers: {'Vary': 'Cookies'}})
},
{
name: 'vary_cookie_absent',
request: new Request('http://example.com/c'),
response: new Response('',
{headers: {'Vary': 'Cookies'}})
},
{
name: 'vary_wildcard',
request: new Request('http://example.com/c',
{headers: {'Cookies': 'x', 'X-Key': '1'}}),
response: new Response('',
{headers: {'Vary': '*'}})
}
];
prepopulated_cache_test(simple_entries, function(cache, entries) {
return cache.matchAll('not-present-in-the-cache')
.then(function(result) {
assert_array_equivalent(
result, [],
'Cache.matchAll should resolve with an empty array on failure.');
});
}, 'Cache.matchAll with no matching entries');
prepopulated_cache_test(simple_entries, function(cache, entries) {
return cache.match('not-present-in-the-cache')
.then(function(result) {
assert_equals(result, undefined,
'Cache.match failures should resolve with undefined.');
});
}, 'Cache.match with no matching entries');
prepopulated_cache_test(simple_entries, function(cache, entries) {
return cache.matchAll(entries.a.request.url)
.then(function(result) {
assert_array_objects_equals(result, [entries.a.response],
'Cache.matchAll should match by URL.');
});
}, 'Cache.matchAll with URL');
prepopulated_cache_test(simple_entries, function(cache, entries) {
return cache.match(entries.a.request.url)
.then(function(result) {
assert_object_equals(result, entries.a.response,
'Cache.match should match by URL.');
});
}, 'Cache.match with URL');
prepopulated_cache_test(simple_entries, function(cache, entries) {
return cache.matchAll(entries.a.request)
.then(function(result) {
assert_array_objects_equals(
result, [entries.a.response],
'Cache.matchAll should match by Request.');
});
}, 'Cache.matchAll with Request');
prepopulated_cache_test(simple_entries, function(cache, entries) {
return cache.match(entries.a.request)
.then(function(result) {
assert_object_equals(result, entries.a.response,
'Cache.match should match by Request.');
});
}, 'Cache.match with Request');
prepopulated_cache_test(simple_entries, function(cache, entries) {
return cache.matchAll(new Request(entries.a.request.url))
.then(function(result) {
assert_array_objects_equals(
result, [entries.a.response],
'Cache.matchAll should match by Request.');
});
}, 'Cache.matchAll with new Request');
prepopulated_cache_test(simple_entries, function(cache, entries) {
return cache.match(new Request(entries.a.request.url))
.then(function(result) {
assert_object_equals(result, entries.a.response,
'Cache.match should match by Request.');
});
}, 'Cache.match with new Request');
cache_test(function(cache) {
var request = new Request('https://example.com/foo', {
method: 'POST',
body: 'Hello world!'
});
var response = new Response('Booyah!', {
status: 200,
headers: {'Content-Type': 'text/plain'}
});
return cache.put(request.clone(), response.clone())
.then(function() {
assert_false(
request.bodyUsed,
'[https://fetch.spec.whatwg.org/#concept-body-used-flag] ' +
'Request.bodyUsed flag should be initially false.');
})
.then(function() {
return cache.match(request);
})
.then(function(result) {
assert_false(request.bodyUsed,
'Cache.match should not consume Request body.');
});
}, 'Cache.match with Request containing non-empty body');
prepopulated_cache_test(simple_entries, function(cache, entries) {
return cache.matchAll(entries.a.request,
{ignoreSearch: true})
.then(function(result) {
assert_array_equivalent(
result,
[
entries.a.response,
entries.a_with_query.response
],
'Cache.matchAll with ignoreSearch should ignore the ' +
'search parameters of cached request.');
});
},
'Cache.matchAll with ignoreSearch option (request with no search ' +
'parameters)');
prepopulated_cache_test(simple_entries, function(cache, entries) {
return cache.match(entries.a.request,
{ignoreSearch: true})
.then(function(result) {
assert_object_in_array(
result,
[
entries.a.response,
entries.a_with_query.response
],
'Cache.match with ignoreSearch should ignore the ' +
'search parameters of cached request.');
});
},
'Cache.match with ignoreSearch option (request with no search ' +
'parameters)');
prepopulated_cache_test(simple_entries, function(cache, entries) {
return cache.matchAll(entries.a_with_query.request,
{ignoreSearch: true})
.then(function(result) {
assert_array_equivalent(
result,
[
entries.a.response,
entries.a_with_query.response
],
'Cache.matchAll with ignoreSearch should ignore the ' +
'search parameters of request.');
});
},
'Cache.matchAll with ignoreSearch option (request with search parameter)');
prepopulated_cache_test(simple_entries, function(cache, entries) {
return cache.match(entries.a_with_query.request,
{ignoreSearch: true})
.then(function(result) {
assert_object_in_array(
result,
[
entries.a.response,
entries.a_with_query.response
],
'Cache.match with ignoreSearch should ignore the ' +
'search parameters of request.');
});
},
'Cache.match with ignoreSearch option (request with search parameter)');
prepopulated_cache_test(simple_entries, function(cache, entries) {
return cache.matchAll(entries.cat.request.url + '#mouse')
.then(function(result) {
assert_array_equivalent(
result,
[
entries.cat.response,
],
'Cache.matchAll should ignore URL fragment.');
});
}, 'Cache.matchAll with URL containing fragment');
prepopulated_cache_test(simple_entries, function(cache, entries) {
return cache.match(entries.cat.request.url + '#mouse')
.then(function(result) {
assert_object_equals(result, entries.cat.response,
'Cache.match should ignore URL fragment.');
});
}, 'Cache.match with URL containing fragment');
prepopulated_cache_test(simple_entries, function(cache, entries) {
return cache.matchAll('http')
.then(function(result) {
assert_array_equivalent(
result, [],
'Cache.matchAll should treat query as a URL and not ' +
'just a string fragment.');
});
}, 'Cache.matchAll with string fragment "http" as query');
prepopulated_cache_test(simple_entries, function(cache, entries) {
return cache.match('http')
.then(function(result) {
assert_equals(
result, undefined,
'Cache.match should treat query as a URL and not ' +
'just a string fragment.');
});
}, 'Cache.match with string fragment "http" as query');
prepopulated_cache_test(simple_entries, function(cache, entries) {
return cache.matchAll(entries.secret_cat.request.url)
.then(function(result) {
assert_array_equivalent(
result, [entries.secret_cat.response],
'Cache.matchAll should not ignore embedded credentials');
});
}, 'Cache.matchAll with URL containing credentials');
prepopulated_cache_test(simple_entries, function(cache, entries) {
return cache.match(entries.secret_cat.request.url)
.then(function(result) {
assert_object_equals(
result, entries.secret_cat.response,
'Cache.match should not ignore embedded credentials');
});
}, 'Cache.match with URL containing credentials');
prepopulated_cache_test(vary_entries, function(cache, entries) {
return cache.matchAll('http://example.com/c')
.then(function(result) {
assert_array_equivalent(
result,
[
entries.vary_wildcard.response,
entries.vary_cookie_absent.response
],
'Cache.matchAll should exclude matches if a vary header is ' +
'missing in the query request, but is present in the cached ' +
'request.');
})
.then(function() {
return cache.matchAll(
new Request('http://example.com/c',
{headers: {'Cookies': 'none-of-the-above'}}));
})
.then(function(result) {
assert_array_equivalent(
result,
[
entries.vary_wildcard.response
],
'Cache.matchAll should exclude matches if a vary header is ' +
'missing in the cached request, but is present in the query ' +
'request.');
})
.then(function() {
return cache.matchAll(
new Request('http://example.com/c',
{headers: {'Cookies': 'is-for-cookie'}}));
})
.then(function(result) {
assert_array_equivalent(
result,
[entries.vary_cookie_is_cookie.response],
'Cache.matchAll should match the entire header if a vary header ' +
'is present in both the query and cached requests.');
});
}, 'Cache.matchAll with responses containing "Vary" header');
prepopulated_cache_test(vary_entries, function(cache, entries) {
return cache.match('http://example.com/c')
.then(function(result) {
assert_object_in_array(
result,
[
entries.vary_wildcard.response,
entries.vary_cookie_absent.response
],
'Cache.match should honor "Vary" header.');
});
}, 'Cache.match with responses containing "Vary" header');
prepopulated_cache_test(vary_entries, function(cache, entries) {
return cache.matchAll('http://example.com/c',
{ignoreVary: true})
.then(function(result) {
assert_array_equivalent(
result,
[
entries.vary_cookie_is_cookie.response,
entries.vary_cookie_is_good.response,
entries.vary_cookie_absent.response,
entries.vary_wildcard.response
],
'Cache.matchAll should honor "ignoreVary" parameter.');
});
}, 'Cache.matchAll with "ignoreVary" parameter');
cache_test(function(cache) {
var request = new Request('http://example.com');
var response;
var request_url = new URL('../resources/simple.txt', location.href).href;
return fetch(request_url)
.then(function(fetch_result) {
response = fetch_result;
assert_equals(
response.url, request_url,
'[https://fetch.spec.whatwg.org/#dom-response-url] ' +
'Reponse.url should return the URL of the response.');
return cache.put(request, response.clone());
})
.then(function() {
return cache.match(request.url);
})
.then(function(result) {
assert_object_equals(
result, response,
'Cache.match should return a Response object that has the same ' +
'properties as the stored response.');
return cache.match(response.url);
})
.then(function(result) {
assert_equals(
result, undefined,
'Cache.match should not match cache entry based on response URL.');
});
}, 'Cache.match with Request and Response objects with different URLs');
cache_test(function(cache) {
var request_url = new URL('../resources/simple.txt', location.href).href;
return fetch(request_url)
.then(function(fetch_result) {
return cache.put(new Request(request_url), fetch_result);
})
.then(function() {
return cache.match(request_url);
})
.then(function(result) {
return result.text();
})
.then(function(body_text) {
assert_equals(body_text, 'a simple text file\n',
'Cache.match should return a Response object with a ' +
'valid body.');
})
.then(function() {
return cache.match(request_url);
})
.then(function(result) {
return result.text();
})
.then(function(body_text) {
assert_equals(body_text, 'a simple text file\n',
'Cache.match should return a Response object with a ' +
'valid body each time it is called.');
});
}, 'Cache.match invoked multiple times for the same Request/Response');
// Helpers ---
// Run |test_function| with a Cache object as its only parameter. Prior to the
// call, the Cache is populated by cache entries from |entries|. The latter is
// expected to be an Object mapping arbitrary keys to objects of the form
// {request: <Request object>, response: <Response object>}. There's no
// guarantee on the order in which entries will be added to the cache.
//
// |test_function| should return a Promise that can be used with promise_test.
function prepopulated_cache_test(entries, test_function, description) {
cache_test(function(cache) {
var p = Promise.resolve();
var hash = {};
entries.forEach(function(entry) {
p = p.then(function() {
return cache.put(entry.request.clone(),
entry.response.clone())
.catch(function(e) {
assert_unreached('Test setup failed for entry ' +
entry.name + ': ' + e);
});
});
hash[entry.name] = entry;
});
p = p.then(function() {
assert_equals(Object.keys(hash).length, entries.length);
});
return p.then(function() {
return test_function(cache, hash);
});
}, description);
}
done();

View file

@ -0,0 +1,324 @@
if (self.importScripts) {
importScripts('/resources/testharness.js');
importScripts('../resources/testharness-helpers.js');
importScripts('../resources/test-helpers.js');
}
var test_url = 'https://example.com/foo';
var test_body = 'Hello world!';
cache_test(function(cache) {
var request = new Request(test_url);
var response = new Response(test_body);
return cache.put(request, response)
.then(function(result) {
assert_equals(result, undefined,
'Cache.put should resolve with undefined on success.');
});
}, 'Cache.put called with simple Request and Response');
cache_test(function(cache) {
var test_url = new URL('../resources/simple.txt', location.href).href;
var request = new Request(test_url);
var response;
return fetch(test_url)
.then(function(fetch_result) {
response = fetch_result.clone();
return cache.put(request, fetch_result);
})
.then(function() {
return cache.match(test_url);
})
.then(function(result) {
assert_object_equals(result, response,
'Cache.put should update the cache with ' +
'new request and response.');
return result.text();
})
.then(function(body) {
assert_equals(body, 'a simple text file\n',
'Cache.put should store response body.');
});
}, 'Cache.put called with Request and Response from fetch()');
cache_test(function(cache) {
var request = new Request(test_url);
var response = new Response(test_body);
assert_false(request.bodyUsed,
'[https://fetch.spec.whatwg.org/#dom-body-bodyused] ' +
'Request.bodyUsed should be initially false.');
return cache.put(request, response)
.then(function() {
assert_false(request.bodyUsed,
'Cache.put should not mark empty request\'s body used');
});
}, 'Cache.put with Request without a body');
cache_test(function(cache) {
var request = new Request(test_url);
var response = new Response();
assert_false(response.bodyUsed,
'[https://fetch.spec.whatwg.org/#dom-body-bodyused] ' +
'Response.bodyUsed should be initially false.');
return cache.put(request, response)
.then(function() {
assert_false(response.bodyUsed,
'Cache.put should not mark empty response\'s body used');
});
}, 'Cache.put with Response without a body');
cache_test(function(cache) {
var request = new Request(test_url, {
method: 'POST',
body: 'Hello'
});
var response = new Response(test_body);
assert_false(request.bodyUsed,
'[https://fetch.spec.whatwg.org/#dom-body-bodyused] ' +
'Request.bodyUsed should be initially false.');
return cache.put(request, response.clone())
.then(function() {
assert_true(request.bodyUsed,
'Cache.put should consume Request body.');
})
.then(function() {
return cache.match(request);
})
.then(function(result) {
assert_object_equals(result, response,
'Cache.put should store response body.');
});
}, 'Cache.put with Request containing a body');
cache_test(function(cache) {
var request = new Request(test_url);
var response = new Response(test_body);
return cache.put(request, response.clone())
.then(function() {
return cache.match(test_url);
})
.then(function(result) {
assert_object_equals(result, response,
'Cache.put should update the cache with ' +
'new Request and Response.');
});
}, 'Cache.put with a Response containing an empty URL');
cache_test(function(cache) {
var request = new Request(test_url);
var response = new Response('', {
status: 200,
headers: [['Content-Type', 'text/plain']]
});
return cache.put(request, response)
.then(function() {
return cache.match(test_url);
})
.then(function(result) {
assert_equals(result.status, 200, 'Cache.put should store status.');
assert_equals(result.headers.get('Content-Type'), 'text/plain',
'Cache.put should store headers.');
return result.text();
})
.then(function(body) {
assert_equals(body, '',
'Cache.put should store response body.');
});
}, 'Cache.put with an empty response body');
cache_test(function(cache) {
var test_url = new URL('../resources/fetch-status.py?status=500', location.href).href;
var request = new Request(test_url);
var response;
return fetch(test_url)
.then(function(fetch_result) {
assert_equals(fetch_result.status, 500,
'Test framework error: The status code should be 500.');
response = fetch_result.clone();
return cache.put(request, fetch_result);
})
.then(function() {
return cache.match(test_url);
})
.then(function(result) {
assert_object_equals(result, response,
'Cache.put should update the cache with ' +
'new request and response.');
return result.text();
})
.then(function(body) {
assert_equals(body, '',
'Cache.put should store response body.');
});
}, 'Cache.put with HTTP 500 response');
cache_test(function(cache) {
var alternate_response_body = 'New body';
var alternate_response = new Response(alternate_response_body,
{ statusText: 'New status' });
return cache.put(new Request(test_url),
new Response('Old body', { statusText: 'Old status' }))
.then(function() {
return cache.put(new Request(test_url), alternate_response.clone());
})
.then(function() {
return cache.match(test_url);
})
.then(function(result) {
assert_object_equals(result, alternate_response,
'Cache.put should replace existing ' +
'response with new response.');
return result.text();
})
.then(function(body) {
assert_equals(body, alternate_response_body,
'Cache put should store new response body.');
});
}, 'Cache.put called twice with matching Requests and different Responses');
cache_test(function(cache) {
var first_url = test_url;
var second_url = first_url + '#(O_o)';
var alternate_response_body = 'New body';
var alternate_response = new Response(alternate_response_body,
{ statusText: 'New status' });
return cache.put(new Request(first_url),
new Response('Old body', { statusText: 'Old status' }))
.then(function() {
return cache.put(new Request(second_url), alternate_response.clone());
})
.then(function() {
return cache.match(test_url);
})
.then(function(result) {
assert_object_equals(result, alternate_response,
'Cache.put should replace existing ' +
'response with new response.');
return result.text();
})
.then(function(body) {
assert_equals(body, alternate_response_body,
'Cache put should store new response body.');
});
}, 'Cache.put called twice with request URLs that differ only by a fragment');
cache_test(function(cache) {
var entries = {
dark: {
url: 'http://darkhelmet:12345@example.com/spaceballs',
body: 'Moranis'
},
skroob: {
url: 'http://skroob:12345@example.com/spaceballs',
body: 'Brooks'
},
control: {
url: 'http://example.com/spaceballs',
body: 'v(o.o)v'
}
};
return Promise.all(Object.keys(entries).map(function(key) {
return cache.put(new Request(entries[key].url),
new Response(entries[key].body));
}))
.then(function() {
return Promise.all(Object.keys(entries).map(function(key) {
return cache.match(entries[key].url)
.then(function(result) {
return result.text();
})
.then(function(body) {
assert_equals(body, entries[key].body,
'Cache put should store response body.');
});
}));
});
}, 'Cache.put with request URLs containing embedded credentials');
cache_test(function(cache) {
var url = 'http://example.com/foo';
return cache.put(url, new Response('some body'))
.then(function() { return cache.match(url); })
.then(function(response) { return response.text(); })
.then(function(body) {
assert_equals(body, 'some body',
'Cache.put should accept a string as request.');
});
}, 'Cache.put with a string request');
cache_test(function(cache) {
return assert_promise_rejects(
cache.put(new Request(test_url), 'Hello world!'),
new TypeError(),
'Cache.put should only accept a Response object as the response.');
}, 'Cache.put with an invalid response');
cache_test(function(cache) {
return assert_promise_rejects(
cache.put(new Request('file:///etc/passwd'),
new Response(test_body)),
new TypeError(),
'Cache.put should reject non-HTTP/HTTPS requests with a TypeError.');
}, 'Cache.put with a non-HTTP/HTTPS request');
cache_test(function(cache) {
var response = new Response(test_body);
return cache.put(new Request('relative-url'), response.clone())
.then(function() {
return cache.match(new URL('relative-url', location.href).href);
})
.then(function(result) {
assert_object_equals(result, response,
'Cache.put should accept a relative URL ' +
'as the request.');
});
}, 'Cache.put with a relative URL');
cache_test(function(cache) {
var request = new Request('http://example.com/foo', { method: 'HEAD' });
return assert_promise_rejects(
cache.put(request, new Response(test_body)),
new TypeError(),
'Cache.put should throw a TypeError for non-GET requests.');
}, 'Cache.put with a non-GET request');
cache_test(function(cache) {
return assert_promise_rejects(
cache.put(new Request(test_url), null),
new TypeError(),
'Cache.put should throw a TypeError for a null response.');
}, 'Cache.put with a null response');
cache_test(function(cache) {
var request = new Request(test_url, {method: 'POST', body: test_body});
assert_false(request.bodyUsed,
'[https://fetch.spec.whatwg.org/#dom-body-bodyused] ' +
'Request.bodyUsed should be initially false.');
var copy = new Request(request);
assert_true(request.bodyUsed,
'[https://fetch.spec.whatwg.org/#dom-request] ' +
'Request constructor should set input\'s used flag.');
return assert_promise_rejects(
cache.put(request, new Response(test_body)),
new TypeError(),
'Cache.put should throw a TypeError for a request with used body.');
}, 'Cache.put with a used request body');
cache_test(function(cache) {
var response = new Response(test_body);
assert_false(response.bodyUsed,
'[https://fetch.spec.whatwg.org/#dom-body-bodyused] ' +
'Response.bodyUsed should be initially false.');
return response.text().then(function() {
assert_false(
response.bodyUsed,
'[https://fetch.spec.whatwg.org/#concept-body-consume-body] ' +
'The text() method should not set "body passed" flag.');
return cache.put(new Request(test_url), response);
});
}, 'Cache.put with a used response body');
done();

View file

@ -0,0 +1,36 @@
if (self.importScripts) {
importScripts('/resources/testharness.js');
importScripts('../resources/testharness-helpers.js');
importScripts('../resources/test-helpers.js');
}
var test_cache_list =
['', 'example', 'Another cache name', 'A', 'a', 'ex ample'];
promise_test(function(test) {
return self.caches.keys()
.then(function(keys) {
assert_true(Array.isArray(keys),
'CacheStorage.keys should return an Array.');
return Promise.all(keys.map(function(key) {
return self.caches.delete(key);
}));
})
.then(function() {
return Promise.all(test_cache_list.map(function(key) {
return self.caches.open(key);
}));
})
.then(function() { return self.caches.keys(); })
.then(function(keys) {
assert_true(Array.isArray(keys),
'CacheStorage.keys should return an Array.');
assert_array_equals(keys,
test_cache_list,
'CacheStorage.keys should only return ' +
'existing caches.');
});
}, 'CacheStorage keys');
done();

View file

@ -0,0 +1,123 @@
if (self.importScripts) {
importScripts('/resources/testharness.js');
importScripts('../resources/testharness-helpers.js');
importScripts('../resources/test-helpers.js');
}
(function() {
var next_index = 1;
// Returns a transaction (request, response, and url) for a unique URL.
function create_unique_transaction(test) {
var uniquifier = String(next_index++);
var url = 'http://example.com/' + uniquifier;
return {
request: new Request(url),
response: new Response('hello'),
url: url
};
}
self.create_unique_transaction = create_unique_transaction;
})();
cache_test(function(cache) {
var transaction = create_unique_transaction();
return cache.put(transaction.request.clone(), transaction.response.clone())
.then(function() {
return self.caches.match(transaction.request);
})
.then(function(response) {
assert_object_equals(response, transaction.response,
'The response should not have changed.');
});
}, 'CacheStorageMatch with no cache name provided');
cache_test(function(cache) {
var transaction = create_unique_transaction();
var test_cache_list = ['a', 'b', 'c'];
return cache.put(transaction.request.clone(), transaction.response.clone())
.then(function() {
return Promise.all(test_cache_list.map(function(key) {
return self.caches.open(key);
}));
})
.then(function() {
return self.caches.match(transaction.request);
})
.then(function(response) {
assert_object_equals(response, transaction.response,
'The response should not have changed.');
});
}, 'CacheStorageMatch from one of many caches');
promise_test(function(test) {
var transaction = create_unique_transaction();
var test_cache_list = ['x', 'y', 'z'];
return Promise.all(test_cache_list.map(function(key) {
return self.caches.open(key);
}))
.then(function() { return caches.open('x'); })
.then(function(cache) {
return cache.put(transaction.request.clone(),
transaction.response.clone());
})
.then(function() {
return self.caches.match(transaction.request, {cacheName: 'x'});
})
.then(function(response) {
assert_object_equals(response, transaction.response,
'The response should not have changed.');
})
.then(function() {
return self.caches.match(transaction.request, {cacheName: 'y'});
})
.then(function(response) {
assert_equals(response, undefined,
'Cache y should not have a response for the request.');
});
}, 'CacheStorageMatch from one of many caches by name');
cache_test(function(cache) {
var transaction = create_unique_transaction();
return cache.put(transaction.url, transaction.response.clone())
.then(function() {
return self.caches.match(transaction.request);
})
.then(function(response) {
assert_object_equals(response, transaction.response,
'The response should not have changed.');
});
}, 'CacheStorageMatch a string request');
promise_test(function(test) {
var transaction = create_unique_transaction();
return self.caches.match(transaction.request)
.then(function(response) {
assert_equals(response, undefined,
'The response should not be found.');
})
}, 'CacheStorageMatch with no cached entry');
promise_test(function(test) {
var transaction = create_unique_transaction();
return self.caches.has('foo')
.then(function(has_foo) {
assert_false(has_foo, "The cache should not exist.");
return self.caches.match(transaction.request, {cacheName: 'foo'});
})
.then(function(response) {
assert_equals(response, undefined,
'The response should not be found.');
return self.caches.has('foo');
})
.then(function(has_foo) {
assert_false(has_foo, "The cache should still not exist.");
})
}, 'CacheStorageMatch with no caches available but name provided');
done();

View file

@ -0,0 +1,192 @@
if (self.importScripts) {
importScripts('/resources/testharness.js');
importScripts('../resources/testharness-helpers.js');
importScripts('../resources/test-helpers.js');
}
promise_test(function(t) {
var cache_name = 'cache-storage/foo';
return self.caches.delete(cache_name)
.then(function() {
return self.caches.open(cache_name);
})
.then(function(cache) {
assert_true(cache instanceof Cache,
'CacheStorage.open should return a Cache.');
});
}, 'CacheStorage.open');
promise_test(function(t) {
// Note that this test may collide with other tests running in the same
// origin that also uses an empty cache name.
var cache_name = '';
return self.caches.delete(cache_name)
.then(function() {
return self.caches.open(cache_name);
})
.then(function(cache) {
assert_true(cache instanceof Cache,
'CacheStorage.open should accept an empty name.');
});
}, 'CacheStorage.open with an empty name');
promise_test(function(t) {
return assert_promise_rejects(
self.caches.open(),
new TypeError(),
'CacheStorage.open should throw TypeError if called with no arguments.');
}, 'CacheStorage.open with no arguments');
promise_test(function(t) {
var test_cases = [
{
name: 'cache-storage/lowercase',
should_not_match:
[
'cache-storage/Lowercase',
' cache-storage/lowercase',
'cache-storage/lowercase '
]
},
{
name: 'cache-storage/has a space',
should_not_match:
[
'cache-storage/has'
]
},
{
name: 'cache-storage/has\000_in_the_name',
should_not_match:
[
'cache-storage/has',
'cache-storage/has_in_the_name'
]
}
];
return Promise.all(test_cases.map(function(testcase) {
var cache_name = testcase.name;
return self.caches.delete(cache_name)
.then(function() {
return self.caches.open(cache_name);
})
.then(function() {
return self.caches.has(cache_name);
})
.then(function(result) {
assert_true(result,
'CacheStorage.has should return true for existing ' +
'cache.');
})
.then(function() {
return Promise.all(
testcase.should_not_match.map(function(cache_name) {
return self.caches.has(cache_name)
.then(function(result) {
assert_false(result,
'CacheStorage.has should only perform ' +
'exact matches on cache names.');
});
}));
})
.then(function() {
return self.caches.delete(cache_name);
});
}));
}, 'CacheStorage.has with existing cache');
promise_test(function(t) {
return self.caches.has('cheezburger')
.then(function(result) {
assert_false(result,
'CacheStorage.has should return false for ' +
'nonexistent cache.');
});
}, 'CacheStorage.has with nonexistent cache');
promise_test(function(t) {
var cache_name = 'cache-storage/open';
var cache;
return self.caches.delete(cache_name)
.then(function() {
return self.caches.open(cache_name);
})
.then(function(result) {
cache = result;
})
.then(function() {
return self.caches.open(cache_name);
})
.then(function(result) {
assert_equals(result, cache,
'CacheStorage.open should return the named Cache ' +
'object if it exists.');
})
.then(function() {
return self.caches.open(cache_name);
})
.then(function(result) {
assert_equals(result, cache,
'CacheStorage.open should return the same ' +
'instance of an existing Cache object.');
});
}, 'CacheStorage.open with existing cache');
promise_test(function(t) {
var cache_name = 'cache-storage/delete';
return self.caches.delete(cache_name)
.then(function() {
return self.caches.open(cache_name);
})
.then(function() { return self.caches.delete(cache_name); })
.then(function(result) {
assert_true(result,
'CacheStorage.delete should return true after ' +
'deleting an existing cache.');
})
.then(function() { return self.caches.has(cache_name); })
.then(function(cache_exists) {
assert_false(cache_exists,
'CacheStorage.has should return false after ' +
'fulfillment of CacheStorage.delete promise.');
});
}, 'CacheStorage.delete with existing cache');
promise_test(function(t) {
return self.caches.delete('cheezburger')
.then(function(result) {
assert_false(result,
'CacheStorage.delete should return false for a ' +
'nonexistent cache.');
});
}, 'CacheStorage.delete with nonexistent cache');
promise_test(function(t) {
var bad_name = 'unpaired\uD800';
var converted_name = 'unpaired\uFFFD'; // Don't create cache with this name.
return self.caches.has(converted_name)
.then(function(cache_exists) {
assert_false(cache_exists,
'Test setup failure: cache should not exist');
})
.then(function() { return self.caches.open(bad_name); })
.then(function() { return self.caches.keys(); })
.then(function(keys) {
assert_true(keys.indexOf(bad_name) !== -1,
'keys should include cache with bad name');
})
.then(function() { return self.caches.has(bad_name); })
.then(function(cache_exists) {
assert_true(cache_exists,
'CacheStorage names should be not be converted.');
})
.then(function() { return self.caches.has(converted_name); })
.then(function(cache_exists) {
assert_false(cache_exists,
'CacheStorage names should be not be converted.');
});
}, 'CacheStorage names are DOMStrings not USVStrings');
done();

View file

@ -0,0 +1,9 @@
<!DOCTYPE html>
<title>Cache.add and Cache.addAll</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-add">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../service-workers/resources/test-helpers.js"></script>
<script>
service_worker_test('../script-tests/cache-add.js');
</script>

View file

@ -0,0 +1,9 @@
<!DOCTYPE html>
<title>Cache.delete</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-delete">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../service-workers/resources/test-helpers.js"></script>
<script>
service_worker_test('../script-tests/cache-delete.js');
</script>

View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<title>Cache.match and Cache.matchAll</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-match">
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../service-workers/resources/test-helpers.js"></script>
<script>
service_worker_test('../script-tests/cache-match.js');
</script>

View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<title>Cache.put</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-put">
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../service-workers/resources/test-helpers.js"></script>
<script>
service_worker_test('../script-tests/cache-put.js');
</script>

View file

@ -0,0 +1,9 @@
<!DOCTYPE html>
<title>CacheStorage.keys</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../service-workers/resources/test-helpers.js"></script>
<script>
service_worker_test('../script-tests/cache-storage-keys.js');
</script>

View file

@ -0,0 +1,9 @@
<!DOCTYPE html>
<title>CacheStorage.match</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage-match">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../service-workers/resources/test-helpers.js"></script>
<script>
service_worker_test('../script-tests/cache-storage-match.js');
</script>

View file

@ -0,0 +1,9 @@
<!DOCTYPE html>
<title>CacheStorage</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../service-workers/resources/test-helpers.js"></script>
<script>
service_worker_test('../script-tests/cache-storage.js');
</script>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<title>Cache Storage: Cache.add and Cache.addAll</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-add">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/testharness-helpers.js"></script>
<script src="../resources/test-helpers.js"></script>
<script src="../script-tests/cache-add.js"></script>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<title>Cache Storage: Cache.delete</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-delete">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/testharness-helpers.js"></script>
<script src="../resources/test-helpers.js"></script>
<script src="../script-tests/cache-delete.js"></script>

View file

@ -0,0 +1,9 @@
<!DOCTYPE html>
<title>Cache Storage: Cache.match and Cache.matchAll</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-match">
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/testharness-helpers.js"></script>
<script src="../resources/test-helpers.js"></script>
<script src="../script-tests/cache-match.js"></script>

View file

@ -0,0 +1,9 @@
<!DOCTYPE html>
<title>Cache Storage: Cache.put</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-put">
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/testharness-helpers.js"></script>
<script src="../resources/test-helpers.js"></script>
<script src="../script-tests/cache-put.js"></script>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<title>Cache Storage: CacheStorage.keys</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/testharness-helpers.js"></script>
<script src="../resources/test-helpers.js"></script>
<script src="../script-tests/cache-storage-keys.js"></script>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<title>Cache Storage: CacheStorage.match</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage-match">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/testharness-helpers.js"></script>
<script src="../resources/test-helpers.js"></script>
<script src="../script-tests/cache-storage-match.js"></script>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<title>Cache Storage: CacheStorage</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/testharness-helpers.js"></script>
<script src="../resources/test-helpers.js"></script>
<script src="../script-tests/cache-storage.js"></script>

View file

@ -0,0 +1,66 @@
<!DOCTYPE html>
<title>Cache Storage: Verify access in sandboxed iframes</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/testharness-helpers.js"></script>
<script>
function load_iframe(src, sandbox) {
return new Promise(function(resolve, reject) {
var iframe = document.createElement('iframe');
iframe.onload = function() { resolve(iframe); };
iframe.sandbox = sandbox;
iframe.src = src;
document.documentElement.appendChild(iframe);
});
}
function wait_for_message(id) {
return new Promise(function(resolve) {
self.addEventListener('message', function listener(e) {
if (e.data.id === id) {
resolve(e.data);
self.removeEventListener(listener);
}
});
});
}
var counter = 0;
promise_test(function(t) {
return load_iframe('../resources/iframe.html',
'allow-scripts allow-same-origin')
.then(function(iframe) {
var id = ++counter;
iframe.contentWindow.postMessage({id: id}, '*');
return wait_for_message(id);
})
.then(function(message) {
assert_equals(
message.result, 'allowed',
'Access should be allowed if sandbox has allow-same-origin');
});
}, 'Sandboxed iframe with allow-same-origin is allowed access');
promise_test(function(t) {
return load_iframe('../resources/iframe.html',
'allow-scripts')
.then(function(iframe) {
var id = ++counter;
iframe.contentWindow.postMessage({id: id}, '*');
return wait_for_message(id);
})
.then(function(message) {
assert_equals(
message.result, 'denied',
'Access should be denied if sandbox lacks allow-same-origin');
assert_equals(message.name, 'SecurityError',
'Failure should be a SecurityError');
});
}, 'Sandboxed iframe without allow-same-origin is denied access');
</script>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<title>Cache.add and Cache.addAll</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-add">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
fetch_tests_from_worker(new Worker('../script-tests/cache-add.js'));
</script>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<title>Cache.delete</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-delete">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
fetch_tests_from_worker(new Worker('../script-tests/cache-delete.js'));
</script>

View file

@ -0,0 +1,9 @@
<!DOCTYPE html>
<title>Cache.match and Cache.matchAll</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-match">
<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-match.js'));
</script>

View file

@ -0,0 +1,9 @@
<!DOCTYPE html>
<title>Cache.put</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-put">
<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-put.js'));
</script>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<title>CacheStorage.keys</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
fetch_tests_from_worker(new Worker('../script-tests/cache-storage-keys.js'));
</script>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<title>CacheStorage.match</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage-match">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
fetch_tests_from_worker(new Worker('../script-tests/cache-storage-match.js'));
</script>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<title>CacheStorage</title>
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
fetch_tests_from_worker(new Worker('../script-tests/cache-storage.js'));
</script>