| OLD | NEW |
| (Empty) |
| 1 (function() { | |
| 2 var next_cache_index = 1; | |
| 3 | |
| 4 // Returns a promise that resolves to a newly created Cache object. The | |
| 5 // returned Cache will be destroyed when |test| completes. | |
| 6 function create_temporary_cache(test) { | |
| 7 var uniquifier = String(++next_cache_index); | |
| 8 var cache_name = self.location.pathname + '/' + uniquifier; | |
| 9 | |
| 10 test.add_cleanup(function() { | |
| 11 self.caches.delete(cache_name); | |
| 12 }); | |
| 13 | |
| 14 return self.caches.delete(cache_name) | |
| 15 .then(function() { | |
| 16 return self.caches.open(cache_name); | |
| 17 }); | |
| 18 } | |
| 19 | |
| 20 self.create_temporary_cache = create_temporary_cache; | |
| 21 })(); | |
| 22 | |
| 23 // Runs |test_function| with a temporary unique Cache passed in as the only | |
| 24 // argument. The function is run as a part of Promise chain owned by | |
| 25 // promise_test(). As such, it is expected to behave in a manner identical (with | |
| 26 // the exception of the argument) to a function passed into promise_test(). | |
| 27 // | |
| 28 // E.g.: | |
| 29 // cache_test(function(cache) { | |
| 30 // // Do something with |cache|, which is a Cache object. | |
| 31 // }, "Some Cache test"); | |
| 32 function cache_test(test_function, description) { | |
| 33 promise_test(function(test) { | |
| 34 return create_temporary_cache(test) | |
| 35 .then(cache => test_function(cache, test)); | |
| 36 }, description); | |
| 37 } | |
| 38 | |
| 39 // A set of Request/Response pairs to be used with prepopulated_cache_test(). | |
| 40 var simple_entries = [ | |
| 41 { | |
| 42 name: 'a', | |
| 43 request: new Request('http://example.com/a'), | |
| 44 response: new Response('') | |
| 45 }, | |
| 46 | |
| 47 { | |
| 48 name: 'b', | |
| 49 request: new Request('http://example.com/b'), | |
| 50 response: new Response('') | |
| 51 }, | |
| 52 | |
| 53 { | |
| 54 name: 'a_with_query', | |
| 55 request: new Request('http://example.com/a?q=r'), | |
| 56 response: new Response('') | |
| 57 }, | |
| 58 | |
| 59 { | |
| 60 name: 'A', | |
| 61 request: new Request('http://example.com/A'), | |
| 62 response: new Response('') | |
| 63 }, | |
| 64 | |
| 65 { | |
| 66 name: 'a_https', | |
| 67 request: new Request('https://example.com/a'), | |
| 68 response: new Response('') | |
| 69 }, | |
| 70 | |
| 71 { | |
| 72 name: 'a_org', | |
| 73 request: new Request('http://example.org/a'), | |
| 74 response: new Response('') | |
| 75 }, | |
| 76 | |
| 77 { | |
| 78 name: 'cat', | |
| 79 request: new Request('http://example.com/cat'), | |
| 80 response: new Response('') | |
| 81 }, | |
| 82 | |
| 83 { | |
| 84 name: 'catmandu', | |
| 85 request: new Request('http://example.com/catmandu'), | |
| 86 response: new Response('') | |
| 87 }, | |
| 88 | |
| 89 { | |
| 90 name: 'cat_num_lives', | |
| 91 request: new Request('http://example.com/cat?lives=9'), | |
| 92 response: new Response('') | |
| 93 }, | |
| 94 | |
| 95 { | |
| 96 name: 'cat_in_the_hat', | |
| 97 request: new Request('http://example.com/cat/in/the/hat'), | |
| 98 response: new Response('') | |
| 99 }, | |
| 100 | |
| 101 { | |
| 102 name: 'non_2xx_response', | |
| 103 request: new Request('http://example.com/non2xx'), | |
| 104 response: new Response('', {status: 404, statusText: 'nope'}) | |
| 105 }, | |
| 106 | |
| 107 { | |
| 108 name: 'error_response', | |
| 109 request: new Request('http://example.com/error'), | |
| 110 response: Response.error() | |
| 111 }, | |
| 112 ]; | |
| 113 | |
| 114 // A set of Request/Response pairs to be used with prepopulated_cache_test(). | |
| 115 // These contain a mix of test cases that use Vary headers. | |
| 116 var vary_entries = [ | |
| 117 { | |
| 118 name: 'vary_cookie_is_cookie', | |
| 119 request: new Request('http://example.com/c', | |
| 120 {headers: {'Cookies': 'is-for-cookie'}}), | |
| 121 response: new Response('', | |
| 122 {headers: {'Vary': 'Cookies'}}) | |
| 123 }, | |
| 124 | |
| 125 { | |
| 126 name: 'vary_cookie_is_good', | |
| 127 request: new Request('http://example.com/c', | |
| 128 {headers: {'Cookies': 'is-good-enough-for-me'}}), | |
| 129 response: new Response('', | |
| 130 {headers: {'Vary': 'Cookies'}}) | |
| 131 }, | |
| 132 | |
| 133 { | |
| 134 name: 'vary_cookie_absent', | |
| 135 request: new Request('http://example.com/c'), | |
| 136 response: new Response('', | |
| 137 {headers: {'Vary': 'Cookies'}}) | |
| 138 } | |
| 139 ]; | |
| 140 | |
| 141 // Run |test_function| with a Cache object and a map of entries. Prior to the | |
| 142 // call, the Cache is populated by cache entries from |entries|. The latter is | |
| 143 // expected to be an Object mapping arbitrary keys to objects of the form | |
| 144 // {request: <Request object>, response: <Response object>}. The entries are | |
| 145 // added sequentially so that tests can verify the ordering of the cache | |
| 146 // methods. | |
| 147 // | |
| 148 // |test_function| should return a Promise that can be used with promise_test. | |
| 149 function prepopulated_cache_test(entries, test_function, description) { | |
| 150 cache_test(function(cache) { | |
| 151 var hash = {}; | |
| 152 var resolveMethod = null; | |
| 153 | |
| 154 var promise = new Promise(function(resolve, reject) { | |
| 155 resolveMethod = resolve; | |
| 156 }) | |
| 157 .then(function() { | |
| 158 assert_equals(Object.keys(hash).length, entries.length); | |
| 159 return test_function(cache, hash); | |
| 160 }); | |
| 161 | |
| 162 // Add the entries to the cache sequentially. | |
| 163 // TODO(jkarlin): Once async/await is available use it to prettify this | |
| 164 // code. | |
| 165 var i = 0; | |
| 166 var processNextEntry = function(i) { | |
| 167 if (i == entries.length) { | |
| 168 resolveMethod(); | |
| 169 return; | |
| 170 } | |
| 171 entry = entries[i]; | |
| 172 hash[entry.name] = entry; | |
| 173 cache.put(entry.request.clone(), entry.response.clone()) | |
| 174 .then(function() { | |
| 175 processNextEntry(i+1); | |
| 176 }) | |
| 177 .catch(function(e) { | |
| 178 assert_unreached( | |
| 179 'Test setup failed for entry ' + entry.name + ': ' + e); | |
| 180 }) | |
| 181 } | |
| 182 | |
| 183 processNextEntry(0); | |
| 184 return promise; | |
| 185 }, description); | |
| 186 } | |
| 187 | |
| 188 // Helper for testing with Headers objects. Compares Headers instances | |
| 189 // by serializing |expected| and |actual| to arrays and comparing. | |
| 190 function assert_header_equals(actual, expected, description) { | |
| 191 assert_class_string(actual, "Headers", description); | |
| 192 var header; | |
| 193 var actual_headers = []; | |
| 194 var expected_headers = []; | |
| 195 for (header of actual) | |
| 196 actual_headers.push(header[0] + ": " + header[1]); | |
| 197 for (header of expected) | |
| 198 expected_headers.push(header[0] + ": " + header[1]); | |
| 199 assert_array_equals(actual_headers, expected_headers, | |
| 200 description + " Headers differ."); | |
| 201 } | |
| 202 | |
| 203 // Helper for testing with Response objects. Compares simple | |
| 204 // attributes defined on the interfaces, as well as the headers. It | |
| 205 // does not compare the response bodies. | |
| 206 function assert_response_equals(actual, expected, description) { | |
| 207 assert_class_string(actual, "Response", description); | |
| 208 ["type", "url", "status", "ok", "statusText"].forEach(function(attribute) { | |
| 209 assert_equals(actual[attribute], expected[attribute], | |
| 210 description + " Attributes differ: " + attribute + "."); | |
| 211 }); | |
| 212 assert_header_equals(actual.headers, expected.headers, description); | |
| 213 } | |
| 214 | |
| 215 // Asserts that two arrays |actual| and |expected| contain the same | |
| 216 // set of Responses as determined by assert_response_equals(). The | |
| 217 // corresponding elements must occupy corresponding indices in their | |
| 218 // respective arrays. | |
| 219 function assert_response_array_equals(actual, expected, description) { | |
| 220 assert_true(Array.isArray(actual), description); | |
| 221 assert_equals(actual.length, expected.length, description); | |
| 222 actual.forEach(function(value, index) { | |
| 223 assert_response_equals(value, expected[index], | |
| 224 description + " : object[" + index + "]"); | |
| 225 }); | |
| 226 } | |
| 227 | |
| 228 // Equivalent to assert_in_array, but uses assert_response_equals. | |
| 229 function assert_response_in_array(actual, expected_array, description) { | |
| 230 assert_true(expected_array.some(function(element) { | |
| 231 try { | |
| 232 assert_response_equals(actual, element); | |
| 233 return true; | |
| 234 } catch (e) { | |
| 235 return false; | |
| 236 } | |
| 237 }), description); | |
| 238 } | |
| 239 | |
| 240 // Helper for testing with Request objects. Compares simple | |
| 241 // attributes defined on the interfaces, as well as the headers. | |
| 242 function assert_request_equals(actual, expected, description) { | |
| 243 assert_class_string(actual, "Request", description); | |
| 244 ["url"].forEach(function(attribute) { | |
| 245 assert_equals(actual[attribute], expected[attribute], | |
| 246 description + " Attributes differ: " + attribute + "."); | |
| 247 }); | |
| 248 assert_header_equals(actual.headers, expected.headers, description); | |
| 249 } | |
| 250 | |
| 251 // TODO(zino): Should remove this function once keys() returns request | |
| 252 // keys in key insertion order. Please see http://crbug.com/627821. | |
| 253 // | |
| 254 // Assert that the two arrays |actual| and |expected| contain the same | |
| 255 // set of Requests as determined by assert_request_equals. The order | |
| 256 // is not significant. | |
| 257 // | |
| 258 // |expected| is assumed to not contain any duplicates. | |
| 259 function assert_request_array_equivalent(actual, expected, description) { | |
| 260 assert_true(Array.isArray(actual), description); | |
| 261 assert_equals(actual.length, expected.length, description); | |
| 262 expected.forEach(function(expected_element) { | |
| 263 // assert_request_in_array treats the first argument as being | |
| 264 // 'actual', and the second as being 'expected array'. We are | |
| 265 // switching them around because we want to be resilient | |
| 266 // against the |actual| array containing duplicates. | |
| 267 assert_request_in_array(expected_element, actual, description); | |
| 268 }); | |
| 269 } | |
| 270 | |
| 271 // Asserts that two arrays |actual| and |expected| contain the same | |
| 272 // set of Requests as determined by assert_request_equals(). The | |
| 273 // corresponding elements must occupy corresponding indices in their | |
| 274 // respective arrays. | |
| 275 function assert_request_array_equals(actual, expected, description) { | |
| 276 assert_true(Array.isArray(actual), description); | |
| 277 assert_equals(actual.length, expected.length, description); | |
| 278 actual.forEach(function(value, index) { | |
| 279 assert_request_equals(value, expected[index], | |
| 280 description + " : object[" + index + "]"); | |
| 281 }); | |
| 282 } | |
| 283 | |
| 284 // Equivalent to assert_in_array, but uses assert_request_equals. | |
| 285 function assert_request_in_array(actual, expected_array, description) { | |
| 286 assert_true(expected_array.some(function(element) { | |
| 287 try { | |
| 288 assert_request_equals(actual, element); | |
| 289 return true; | |
| 290 } catch (e) { | |
| 291 return false; | |
| 292 } | |
| 293 }), description); | |
| 294 } | |
| 295 | |
| 296 // Deletes all caches, returning a promise indicating success. | |
| 297 function delete_all_caches() { | |
| 298 return self.caches.keys() | |
| 299 .then(function(keys) { | |
| 300 return Promise.all(keys.map(self.caches.delete.bind(self.caches))); | |
| 301 }); | |
| 302 } | |
| OLD | NEW |