OLD | NEW |
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <title>IndexedDB: Exceptions thrown during key conversion</title> | 2 <title>IndexedDB: Exceptions thrown during key conversion</title> |
3 <script src="../../resources/testharness.js"></script> | 3 <script src="../../resources/testharness.js"></script> |
4 <script src="../../resources/testharnessreport.js"></script> | 4 <script src="../../resources/testharnessreport.js"></script> |
5 <script> | 5 <script> |
6 | 6 |
7 function simple_idb_test(upgrade_callback, description) { | 7 function simple_idb_test(upgrade_callback, description) { |
8 async_test(function(t) { | 8 async_test(function(t) { |
9 var dbname = document.location + '-' + t.name; | 9 var dbname = document.location + '-' + t.name; |
10 var del = indexedDB.deleteDatabase(dbname); | 10 var del = indexedDB.deleteDatabase(dbname); |
(...skipping 11 matching lines...) Expand all Loading... |
22 } | 22 } |
23 | 23 |
24 // Key that throws during conversion. | 24 // Key that throws during conversion. |
25 function throwing_key(name) { | 25 function throwing_key(name) { |
26 var throws = []; | 26 var throws = []; |
27 throws.length = 1; | 27 throws.length = 1; |
28 Object.defineProperty(throws, '0', {get: function() { | 28 Object.defineProperty(throws, '0', {get: function() { |
29 var err = new Error('throwing from getter'); | 29 var err = new Error('throwing from getter'); |
30 err.name = name; | 30 err.name = name; |
31 throw err; | 31 throw err; |
32 }}); | 32 }, enumerable: true}); |
33 return throws; | 33 return throws; |
34 } | 34 } |
35 | 35 |
36 var valid_key = []; | 36 var valid_key = []; |
37 var invalid_key = {}; | 37 var invalid_key = {}; |
38 | 38 |
39 // Calls method on receiver with the specified number of args (default 1) | 39 // Calls method on receiver with the specified number of args (default 1) |
40 // and asserts that the method fails appropriately (rethrowing if | 40 // and asserts that the method fails appropriately (rethrowing if |
41 // conversion throws, or DataError if not a valid key), and that | 41 // conversion throws, or DataError if not a valid key), and that |
42 // the first argument is fully processed before the second argument | 42 // the first argument is fully processed before the second argument |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 simple_idb_test(function(t, db) { | 108 simple_idb_test(function(t, db) { |
109 var store = db.createObjectStore('store', {keyPath: 'prop'}); | 109 var store = db.createObjectStore('store', {keyPath: 'prop'}); |
110 store.put({prop: 1}).onerror = t.unreached_func('put should succeed'); | 110 store.put({prop: 1}).onerror = t.unreached_func('put should succeed'); |
111 | 111 |
112 var request = store.openCursor(); | 112 var request = store.openCursor(); |
113 request.onerror = t.unreached_func('openCursor should succeed'); | 113 request.onerror = t.unreached_func('openCursor should succeed'); |
114 request.onsuccess = t.step_func(function() { | 114 request.onsuccess = t.step_func(function() { |
115 var cursor = request.result; | 115 var cursor = request.result; |
116 assert_not_equals(cursor, null, 'cursor should find a value'); | 116 assert_not_equals(cursor, null, 'cursor should find a value'); |
117 | 117 |
118 // Put property on prototype because the keypath is | |
119 // evaluated against a structured clone, not the passed value. | |
120 var value = {}; | 118 var value = {}; |
| 119 value.prop = throwing_key('getter'); |
| 120 assert_throws({name: 'getter'}, function() { |
| 121 cursor.update(value); |
| 122 }, 'throwing getter should rethrow during clone'); |
121 | 123 |
122 value.__proto__.prop = throwing_key('getter'); | 124 // Throwing from the getter during key conversion is |
123 assert_throws({name:'getter'}, function() { | 125 // not possible since (1) a clone is used, (2) only own |
124 cursor.update(value); | 126 // properties are cloned, and (3) only own properties |
125 }, 'key conversion with throwing getter should rethrow'); | 127 // are used for key path evaluation. |
126 | 128 |
127 value.__proto__.prop = invalid_key; | 129 value.prop = invalid_key; |
128 assert_throws('DataError', function() { | 130 assert_throws('DataError', function() { |
129 cursor.update(value); | 131 cursor.update(value); |
130 }, 'key conversion with invalid key should throw DataError'); | 132 }, 'key conversion with invalid key should throw DataError'); |
131 }); | 133 }); |
132 }, 'IDBCursor update() method with throwing/invalid keys'); | 134 }, 'IDBCursor update() method with throwing/invalid keys'); |
133 | 135 |
134 // Static constructors on IDBKeyRange | 136 // Static constructors on IDBKeyRange |
135 ['only', 'lowerBound', 'upperBound'].forEach(function(method) { | 137 ['only', 'lowerBound', 'upperBound'].forEach(function(method) { |
136 test(function(t) { | 138 test(function(t) { |
137 check_method(IDBKeyRange, method); | 139 check_method(IDBKeyRange, method); |
(...skipping 11 matching lines...) Expand all Loading... |
149 var in_line = db.createObjectStore('in-line keys', {keyPath: 'prop'}); | 151 var in_line = db.createObjectStore('in-line keys', {keyPath: 'prop'}); |
150 | 152 |
151 assert_throws({name:'getter'}, function() { | 153 assert_throws({name:'getter'}, function() { |
152 out_of_line[method]('value', throwing_key('getter')); | 154 out_of_line[method]('value', throwing_key('getter')); |
153 }, 'key conversion with throwing getter should rethrow'); | 155 }, 'key conversion with throwing getter should rethrow'); |
154 | 156 |
155 assert_throws('DataError', function() { | 157 assert_throws('DataError', function() { |
156 out_of_line[method]('value', invalid_key); | 158 out_of_line[method]('value', invalid_key); |
157 }, 'key conversion with invalid key should throw DataError'); | 159 }, 'key conversion with invalid key should throw DataError'); |
158 | 160 |
159 // Put property on prototype because the keypath is | |
160 // evaluated against a structured clone, not the passed value. | |
161 var value = {}; | 161 var value = {}; |
162 | 162 value.prop = throwing_key('getter'); |
163 value.__proto__.prop = throwing_key('getter'); | |
164 assert_throws({name:'getter'}, function() { | 163 assert_throws({name:'getter'}, function() { |
165 in_line[method](value); | 164 in_line[method](value); |
166 }, 'key conversion with throwing getter should rethrow'); | 165 }, 'throwing getter should rethrow during clone'); |
167 | 166 |
168 value.__proto__.prop = invalid_key; | 167 // Throwing from the getter during key conversion is |
| 168 // not possible since (1) a clone is used, (2) only own |
| 169 // properties are cloned, and (3) only own properties |
| 170 // are used for key path evaluation. |
| 171 |
| 172 value.prop = invalid_key; |
169 assert_throws('DataError', function() { | 173 assert_throws('DataError', function() { |
170 in_line[method](value); | 174 in_line[method](value); |
171 }, 'key conversion with invalid key should throw DataError'); | 175 }, 'key conversion with invalid key should throw DataError'); |
172 }, 'IDBObjectStore ' + method + '() method with throwing/invalid keys'); | 176 }, 'IDBObjectStore ' + method + '() method with throwing/invalid keys'); |
173 }); | 177 }); |
174 | 178 |
175 // Generic (key-or-key-path) methods on IDBObjectStore. | 179 // Generic (key-or-key-path) methods on IDBObjectStore. |
176 [ | 180 [ |
177 // TODO(jsbell): Add 'getAllKeys' | 181 // TODO(jsbell): Add 'getAllKeys' |
178 'delete', 'get', 'getAll', 'count', 'openCursor', 'openKeyCursor' | 182 'delete', 'get', 'getAll', 'count', 'openCursor', 'openKeyCursor' |
(...skipping 12 matching lines...) Expand all Loading... |
191 ].forEach(function(method) { | 195 ].forEach(function(method) { |
192 simple_idb_test(function(t, db) { | 196 simple_idb_test(function(t, db) { |
193 var store = db.createObjectStore('store'); | 197 var store = db.createObjectStore('store'); |
194 var index = store.createIndex('index', 'keyPath'); | 198 var index = store.createIndex('index', 'keyPath'); |
195 | 199 |
196 check_method(index, method); | 200 check_method(index, method); |
197 }, 'IDBIndex ' + method + '() method with throwing/invalid keys'); | 201 }, 'IDBIndex ' + method + '() method with throwing/invalid keys'); |
198 }); | 202 }); |
199 | 203 |
200 </script> | 204 </script> |
OLD | NEW |