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 |