| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <title>Key Generator behavior with explicit keys generator overflow</title> | |
| <link rel=help href="https://w3c.github.io/IndexedDB/#key-generator-construct"> | |
| <script src="/resources/testharness.js"></script> | |
| <script src="/resources/testharnessreport.js"></script> | |
| <script src="support.js"></script> | |
| <script> | |
| function big_key_test(key, description) { | |
| indexeddb_test( | |
| (t, db) => { | |
| assert_equals(indexedDB.cmp(key, key), 0, 'Key is valid'); | |
| db.createObjectStore('store', {autoIncrement: true}); | |
| }, | |
| (t, db) => { | |
| const tx = db.transaction('store', 'readwrite'); | |
| const store = tx.objectStore('store'); | |
| const value = 0; | |
| let request; | |
| request = store.put(value); | |
| request.onerror = t.unreached_func('put should succeed'); | |
| request.onsuccess = t.step_func(e => { | |
| assert_equals(e.target.result, 1, | |
| 'Key generator should initially be 1'); | |
| }); | |
| request = store.put(value); | |
| request.onerror = t.unreached_func('put should succeed'); | |
| request.onsuccess = t.step_func(e => { | |
| assert_equals(e.target.result, 2, | |
| 'Key generator should increment'); | |
| }); | |
| request = store.put(value, 1000); | |
| request.onerror = t.unreached_func('put should succeed'); | |
| request.onsuccess = t.step_func(e => { | |
| assert_equals(e.target.result, 1000, | |
| 'Explicit key should be used'); | |
| }); | |
| request = store.put(value); | |
| request.onerror = t.unreached_func('put should succeed'); | |
| request.onsuccess = t.step_func(e => { | |
| assert_equals(e.target.result, 1001, | |
| 'Key generator should have updated'); | |
| }); | |
| request = store.put(value, key); | |
| request.onerror = t.unreached_func('put should succeed'); | |
| request.onsuccess = t.step_func(e => { | |
| assert_equals(e.target.result, key, | |
| 'Explicit key should be used'); | |
| }); | |
| if (key >= 0) { | |
| // Large positive values will max out the key generator, so it | |
| // can no longer produce keys. | |
| request = store.put(value); | |
| request.onsuccess = t.unreached_func('put should fail'); | |
| request.onerror = t.step_func(e => { | |
| e.preventDefault(); | |
| assert_equals(e.target.error.name, 'ConstraintError', | |
| 'Key generator should have returned failure'); | |
| }); | |
| } else { | |
| // Large negative values are always lower than the key generator's | |
| // current number, so have no effect on the generator. | |
| request = store.put(value); | |
| request.onerror = t.unreached_func('put should succeed'); | |
| request.onsuccess = t.step_func(e => { | |
| assert_equals(e.target.result, 1002, | |
| 'Key generator should have updated'); | |
| }); | |
| } | |
| request = store.put(value, 2000); | |
| request.onerror = t.unreached_func('put should succeed'); | |
| request.onsuccess = t.step_func(e => { | |
| assert_equals(e.target.result, 2000, | |
| 'Explicit key should be used'); | |
| }); | |
| tx.onabort = t.step_func(() => { | |
| assert_unreached(`Transaction aborted: ${tx.error.message}`); | |
| }); | |
| tx.oncomplete = t.step_func(() => { t.done(); }); | |
| }, | |
| description); | |
| } | |
| [ | |
| { | |
| key: Number.MAX_SAFE_INTEGER + 1, | |
| description: '53 bits' | |
| }, | |
| { | |
| key: Math.pow(2, 60), | |
| description: 'greater than 53 bits, less than 64 bits' | |
| }, | |
| { | |
| key: -Math.pow(2, 60), | |
| description: 'greater than 53 bits, less than 64 bits (negative)' | |
| }, | |
| { | |
| key: Math.pow(2, 63), | |
| description: '63 bits' | |
| }, | |
| { | |
| key: -Math.pow(2, 63), | |
| description: '63 bits (negative)' | |
| }, | |
| { | |
| key: Math.pow(2, 64), | |
| description: '64 bits' | |
| }, | |
| { | |
| key: -Math.pow(2, 64), | |
| description: '64 bits (negative)' | |
| }, | |
| { | |
| key: Math.pow(2, 70), | |
| description: 'greater than 64 bits, but still finite' | |
| }, | |
| { | |
| key: -Math.pow(2, 70), | |
| description: 'greater than 64 bits, but still finite (negative)' | |
| }, | |
| { | |
| key: Infinity, | |
| description: 'equal to Infinity' | |
| }, | |
| { | |
| key: -Infinity, | |
| description: 'equal to -Infinity' | |
| } | |
| ].forEach(function(testCase) { | |
| big_key_test(testCase.key, | |
| `Key generator vs. explicit key ${testCase.description}`); | |
| }); | |
| </script> |