Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / LayoutTests / storage / indexeddb / bindings-edges.html
blob252179157e8463e8b0624ff037a50a8a266a02cb
1 <!DOCTYPE html>
2 <title>IndexedDB: Verify bindings edge cases</title>
3 <script src="../../resources/testharness.js"></script>
4 <script src="../../resources/testharnessreport.js"></script>
5 <script src="resources/testharness-helpers.js"></script>
6 <script>
7 indexeddb_test(
8 function(t, db) {
9 db.createObjectStore('store');
11 function(t, db) {
12 var tx = db.transaction('store', 'readwrite');
13 var request = tx.objectStore('store').put('value', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'key']);
15 var setter_called = false;
16 Object.defineProperty(Object.prototype, '10', {
17 set: t.step_func(function(value) { setter_called = true; })
18 });
19 request.onerror = t.unreached_func('request should not fail');
20 request.onsuccess = t.step_func(function() {
21 var result = request.result;
22 assert_false(setter_called,
23 'Setter should not be called for key result.');
24 assert_true(result.hasOwnProperty('10'),
25 'Result should have own-property overriding prototype setter.');
26 assert_equals(result[10], 'key',
27 'Result should have expected property.');
28 t.done();
29 });
31 'Returning keys to script should bypass prototype setters'
34 indexeddb_test(
35 function(t, db) {
36 db.createObjectStore('store', {autoIncrement: true, keyPath: 'id'});
38 function(t, db) {
39 var tx = db.transaction('store', 'readwrite');
40 tx.objectStore('store').put({});
41 var request = tx.objectStore('store').get(1);
43 var setter_called = false;
44 Object.defineProperty(Object.prototype, 'id', {
45 set: t.step_func(function(value) { setter_called = true; })
46 });
47 request.onerror = t.unreached_func('request should not fail');
48 request.onsuccess = t.step_func(function() {
49 var result = request.result;
50 assert_false(setter_called,
51 'Setter should not be called for key result.');
52 assert_true(result.hasOwnProperty('id'),
53 'Result should have own-property overriding prototype setter.');
54 assert_equals(result.id, 1,
55 'Own property should match primary key generator value');
56 t.done();
57 });
59 'Returning values to script should bypass prototype setters'
62 indexeddb_test(
63 function(t, db) {
64 db.createObjectStore('store', {autoIncrement: true, keyPath: 'a.b.c'});
66 function(t, db) {
67 var tx = db.transaction('store', 'readwrite');
68 tx.objectStore('store').put({});
69 var request = tx.objectStore('store').get(1);
71 Object.prototype.a = {b: {c: 'on proto'}};
73 request.onerror = t.unreached_func('request should not fail');
74 request.onsuccess = t.step_func(function() {
75 var result = request.result;
76 assert_true(result.hasOwnProperty('a'),
77 'Result should have own-properties overriding prototype.');
78 assert_true(result.a.hasOwnProperty('b'),
79 'Result should have own-properties overriding prototype.');
80 assert_true(result.a.b.hasOwnProperty('c'),
81 'Result should have own-properties overriding prototype.');
82 assert_equals(result.a.b.c, 1,
83 'Own property should match primary key generator value');
84 assert_equals(Object.prototype.a.b.c, 'on proto',
85 'Prototype should not be modified');
86 t.done();
87 });
89 'Returning values to script should bypass prototype chain'
92 indexeddb_test(
93 function(t, db) {
94 db.createObjectStore('store', {autoIncrement: true, keyPath: 'a.b.c'});
96 function(t, db) {
97 var tx = db.transaction('store', 'readwrite');
98 assert_throws({name: 'DataError'}, function() {
99 tx.objectStore('store').put({a: {b: "foo"}});
100 }, 'Put should throw if key can not be inserted at key path location.');
101 t.done();
103 'The last element of keypath is validated'
108 type: 'String',
109 property: 'length',
110 instance: 'abc'
113 type: 'Array',
114 property: 'length',
115 instance: ['a', 'b', 'c']
118 type: 'Blob',
119 property: 'size',
120 instance: new Blob(['abc'])
123 type: 'Blob',
124 property: 'type',
125 instance: new Blob([''], {type:'foo/bar'})
128 type: 'File',
129 property: 'name',
130 instance: new File([''], 'foo')
133 type: 'File',
134 property: 'lastModified',
135 instance: new File([''], '', {lastModified: 123})
138 type: 'File',
139 property: 'lastModifiedDate',
140 instance: new File([''], '', {lastModified: 123})
142 ].forEach(function(testcase) {
143 indexeddb_test(
144 function(t, db) {
145 db.createObjectStore('store', {autoIncrement: true, keyPath: testcase.property});
147 function(t, db) {
148 var key = testcase.instance[testcase.property];
149 var tx = db.transaction('store', 'readwrite');
150 tx.objectStore('store').put(testcase.instance);
151 var request = tx.objectStore('store').get(key);
152 request.onerror = t.unreached_func('request should not fail');
153 request.onsuccess = t.step_func(function() {
154 var result = request.result;
155 assert_key_equals(result[testcase.property], key,
156 'Property should be used as key');
157 t.done();
160 'Type: ' + testcase.type + ', implicit property: ' + testcase.property
164 function throws(name) {
165 return function() {
166 var err = Error();
167 err.name = name;
168 throw err;
172 indexeddb_test(
173 function(t, db) {
174 var o = {};
175 Object.defineProperty(o, 'throws', {get: throws('getter'),
176 enumerable: false, configurable: true});
178 // Value should be cloned before key path is evaluated,
179 // and non-enumerable getter will be ignored. The clone
180 // will have no such property, so key path evaluation
181 // will fail.
182 var s1 = db.createObjectStore('s1',
183 {keyPath: 'throws'});
184 assert_throws('DataError', function() {
185 s1.put(o);
186 }, 'Key path failing to resolve should throw');
188 // Value should be cloned before key path is evaluated,
189 // and non-enumerable getter will be ignored. The clone
190 // will have no such property, so key path evaluation
191 // will fail.
192 var s2 = db.createObjectStore('s2',
193 {keyPath: 'throws.x'});
194 assert_throws('DataError', function() {
195 s2.put(o);
196 }, 'Key path failing to resolve should throw');
198 // Value should be cloned before key path is evaluated,
199 // and non-enumerable getter will be ignored. The clone
200 // will have no such property, so generated key can be
201 // inserted.
202 var s3 = db.createObjectStore('s3',
203 {keyPath: 'throws', autoIncrement: true});
204 assert_class_string(s3.put(o), 'IDBRequest',
205 'Key injectability test at throwing getter should succeed');
207 // Value should be cloned before key path is evaluated,
208 // and non-enumerable getter will be ignored. The clone
209 // will have no such property, so intermediate object
210 // and generated key can be inserted.
211 var s4 = db.createObjectStore('s4',
212 {keyPath: 'throws.x', autoIncrement: true});
213 assert_class_string(s4.put(o), 'IDBRequest',
214 'Key injectability test past throwing getter should succeed');
216 function(t, db) {
217 t.done();
219 'Key path evaluation: Exceptions from non-enumerable getters'
222 indexeddb_test(
223 function(t, db) {
224 var o = {};
225 Object.defineProperty(o, 'throws', {get: throws('getter'),
226 enumerable: true, configurable: true});
228 // Value should be cloned before key path is evaluated,
229 // and enumerable getter will rethrow.
230 var s1 = db.createObjectStore('s1',
231 {keyPath: 'throws'});
232 assert_throws({name: 'getter'}, function() {
233 s1.put(o);
234 }, 'Key path resolving to throwing getter rethrows');
236 // Value should be cloned before key path is evaluated,
237 // and enumerable getter will rethrow.
238 var s2 = db.createObjectStore('s2',
239 {keyPath: 'throws.x'});
240 assert_throws({name: 'getter'}, function() {
241 s2.put(o);
242 }, 'Key path resolving past throwing getter rethrows');
244 // Value should be cloned before key path is evaluated,
245 // and enumerable getter will rethrow.
246 var s3 = db.createObjectStore('s3',
247 {keyPath: 'throws', autoIncrement: true});
248 assert_throws({name: 'getter'}, function() {
249 s3.put(o);
250 }, 'Key injectability test at throwing getter should rethrow');
252 // Value should be cloned before key path is evaluated,
253 // and enumerable getter will rethrow.
254 var s4 = db.createObjectStore('s4',
255 {keyPath: 'throws.x', autoIncrement: true});
256 assert_throws({name: 'getter'}, function() {
257 s4.put(o);
258 }, 'Key injectability test past throwing getter should rethrow');
260 function(t, db) {
261 t.done();
263 'Key path evaluation: Exceptions from enumerable getters'
266 indexeddb_test(
267 function(t, db) {
268 // Implemented as function wrapper to clean up
269 // immediately after use, otherwise it may
270 // interfere with the test harness.
271 function with_proto_getter(f) {
272 return function() {
273 Object.defineProperty(Object.prototype, 'throws', {
274 get: throws('getter'),
275 enumerable: false, configurable: true
277 try {
278 f();
279 } finally {
280 delete Object.prototype['throws'];
285 // Value should be cloned before key path is evaluated,
286 // and non-enumerable getter will be ignored. The clone
287 // will have no such property, so key path evaluation
288 // will hit prototype property and rethrow.
289 var s1 = db.createObjectStore('s1',
290 {keyPath: 'throws'});
291 assert_throws({name: 'getter'}, with_proto_getter(function() {
292 s1.put({});
293 }), 'Key path resolving to throwing getter rethrows');
295 // Value should be cloned before key path is evaluated,
296 // and non-enumerable getter will be ignored. The clone
297 // will have no such property, so key path evaluation
298 // will hit prototype property and rethrow.
299 var s2 = db.createObjectStore('s2',
300 {keyPath: 'throws.x'});
301 assert_throws({name: 'getter'}, with_proto_getter(function() {
302 s2.put({});
303 }), 'Key path resolving past throwing getter rethrows');
305 // Value should be cloned before key path is evaluated,
306 // and non-enumerable getter will be ignored. The clone
307 // will have no such property, so key path evaluation
308 // will hit prototype property and rethrow.
309 var s3 = db.createObjectStore('s3',
310 {keyPath: 'throws', autoIncrement: true});
311 assert_throws({name: 'getter'}, with_proto_getter(function() {
312 s3.put({});
313 }), 'Key injectability test at throwing getter rethrows');
315 // Value should be cloned before key path is evaluated,
316 // and non-enumerable getter will be ignored. The clone
317 // will have no such property, so key path evaluation
318 // will hit prototype property and rethrow.
319 var s4 = db.createObjectStore('s4',
320 {keyPath: 'throws.x', autoIncrement: true});
321 assert_throws({name: 'getter'}, with_proto_getter(function() {
322 s4.put({});
323 }), 'Key injectability test past throwing getter rethrows');
325 function(t, db) {
326 t.done();
328 'Key path evaluation: Exceptions from non-enumerable getters on prototype'
331 indexeddb_test(
332 function(t, db) {
333 // Implemented as function wrapper to clean up
334 // immediately after use, otherwise it may
335 // interfere with the test harness.
336 function with_proto_getter(f) {
337 return function() {
338 Object.defineProperty(Object.prototype, 'throws', {
339 get: throws('getter'),
340 enumerable: true, configurable: true
342 try {
343 f();
344 } finally {
345 delete Object.prototype['throws'];
350 // Value should be cloned before key path is evaluated,
351 // and enumerable getter will rethrow.
352 var s1 = db.createObjectStore('s1',
353 {keyPath: 'throws'});
354 assert_throws({name: 'getter'}, with_proto_getter(function() {
355 s1.put({});
356 }), 'Key path resolving to throwing getter rethrows');
358 // Value should be cloned before key path is evaluated,
359 // and enumerable getter will rethrow.
360 var s2 = db.createObjectStore('s2',
361 {keyPath: 'throws.x'});
362 assert_throws({name: 'getter'}, with_proto_getter(function() {
363 s2.put({});
364 }), 'Key path resolving past throwing getter rethrows');
366 // Value should be cloned before key path is evaluated,
367 // and enumerable getter will rethrow.
368 var s3 = db.createObjectStore('s3',
369 {keyPath: 'throws', autoIncrement: true});
370 assert_throws({name: 'getter'}, with_proto_getter(function() {
371 s3.put({});
372 }), 'Key injectability test at throwing getter rethrows');
374 // Value should be cloned before key path is evaluated,
375 // and enumerable getter will rethrow.
376 var s4 = db.createObjectStore('s4',
377 {keyPath: 'throws.x', autoIncrement: true});
378 assert_throws({name: 'getter'}, with_proto_getter(function() {
379 s4.put({});
380 }), 'Key injectability test past throwing getter rethrows');
382 function(t, db) {
383 t.done();
385 'Key path evaluation: Exceptions from enumerable getters on prototype'
387 </script>