chromium/third_party/blink/web_tests/storage/indexeddb/cursor-leak.html

<!DOCTYPE html>
<script src="../../resources/gc.js"></script>
<script src="../../resources/js-test.js"></script>
<script src="resources/shared.js"></script>
<script>

description("Verify that that cursors weakly hold script value properties");

if (window.internals) {
    indexedDBTest(prepareDatabase, onOpen);
} else {
    testFailed('This test requires access to the Internals object');
    finishJSTest();
}

function prepareDatabase(evt)
{
    db = event.target.result;
    store = db.createObjectStore('store');
    store.put({value: 'value'}, ['key']);
}

function onOpen(evt)
{
    // evalAndLog() is not used as that generates new DOM nodes.

    db = evt.target.result;
    tx = db.transaction('store', 'readonly', {durability: 'relaxed'});
    store = tx.objectStore('store');
    cursorRequest = store.openCursor();
    cursorRequest.onsuccess = function() {
        cursor = cursorRequest.result;
    };
    tx.oncomplete = function() {
        db.close();
        
        // Do initialization work in an inner function to avoid references to
        // objects remaining live on this function's stack frame
        // (http://crbug.com/595672/).
        (function() {
            // Try and induce a leak by a reference cycle from DOM to V8 and
            // back. If the v8 value of cursor.key (etc) is only held by the
            // cursor's V8 wrapper then there will be no leak.
            cursor.key.cursor = cursor;
            cursor.primaryKey.cursor = cursor;
            cursor.value.cursor = cursor;
            cursorObserver = internals.observeGC(cursor);
        })();

        cursorRequest = null;
        cursor = null;

        asyncGC(function () {
            shouldBeTrue("cursorObserver.wasCollected");
            finishJSTest();
        });
    };
}


</script>