// META: script=resources/support-promises.js

promise_test(async testCase => {
  let result = indexedDB.databases();
  assert_true(result instanceof Promise,
      "databases() should return a promise.");
  result.catch(() => {});
}, "Ensure that databases() returns a promise.");

promise_test(async testCase => {
  // Delete any databases that may not have been cleaned up after previous test
  // runs.
  await deleteAllDatabases(testCase);

  const db_name = "TestDatabase";
  const db = await createNamedDatabase(testCase, db_name, ()=>{});
  const databases_result = await indexedDB.databases();
  db.close();
  const expected_result = {"name": db_name, "version": 1};
  assert_equals(
      databases_result.length,
      1,
      "The result of databases() should contain one result per database.");
  assert_true(
      databases_result[0].name === expected_result.name
          && databases_result[0].version === expected_result.version,
      "The result of databases() should be a sequence of the correct names "
      + "and versions of all databases for the origin.");
}, "Enumerate one database.");

promise_test(async testCase => {
  // Delete any databases that may not have been cleaned up after previous test
  // runs.
  await deleteAllDatabases(testCase);

  const db_name1 = "TestDatabase1";
  const db_name2 = "TestDatabase2";
  const db_name3 = "TestDatabase3";
  const db1 = await createNamedDatabase(testCase, db_name1, ()=>{});
  const db2 = await createNamedDatabase(testCase, db_name2, ()=>{});
  const db3 = await createNamedDatabase(testCase, db_name3, ()=>{});
  db1.close();
  db2.close();
  db3.close();
  const version_promise =
      await migrateNamedDatabase(testCase, db_name2, 2, () => {});
  const databases_result = await indexedDB.databases();
  const expected_result = [
    {"name": db_name1, "version": 1},
    {"name": db_name2, "version": 2},
    {"name": db_name3, "version": 1},
  ];
  assert_equals(
      databases_result.length,
      expected_result.length,
      "The result of databases() should contain one result per database.");
  for ( let i = 0; i < expected_result.length; i += 1 ) {
    result = expected_result[i];
    assert_true(
        databases_result.some(
            e => e.name === result.name && e.version === result.version),
        "The result of databases() should be a sequence of the correct names "
        + "and versions of all databases for the origin.");
  }
}, "Enumerate multiple databases.");

promise_test(async testCase => {
  // Add some databases and close their connections.
  const db1 = await createNamedDatabase(testCase, "DB1", () => {});
  const db2 = await createNamedDatabase(testCase, "DB2", () => {});
  db1.close();
  db2.close();

  // Delete any databases that may not have been cleaned up after previous test
  // runs as well as the two databases made above.
  await deleteAllDatabases(testCase);

  // Make sure the databases are no longer returned.
  const databases_result = await indexedDB.databases();
  assert_equals(
      databases_result.length,
      0,
      "The result of databases() should be an empty sequence for the case of "
      + "no databases for the origin.");
}, "Make sure an empty list is returned for the case of no databases.");

promise_test(async testCase => {
  // Delete any databases that may not have been cleaned up after previous test
  // runs as well as the two databases made above.
  await deleteAllDatabases(testCase);

  const db1 = await createNamedDatabase(testCase, "DB1", ()=>{});
  const db2 = await createNamedDatabase(testCase, "DB2", async () => {
    const databases_result1 = await indexedDB.databases();
    assert_equals(
        databases_result1.length,
        1,
        "The result of databases() should be only those databases which have "
        + "been created at the time of calling, regardless of versionchange "
        + "transactions currently running.");
  });
  db1.close();
  db2.close();
  const databases_result2 = await indexedDB.databases();
  assert_equals(
      databases_result2.length,
      2,
      "The result of databases() should include all databases which have "
      + "been created at the time of calling.");
  await migrateNamedDatabase(testCase, "DB2", 2, async () => {
    const databases_result3 = await indexedDB.databases();
    assert_true(
        databases_result3[0].version === 1
        && databases_result3[1].version === 1,
        "The result of databases() should contain the versions of databases "
        + "at the time of calling, regardless of versionchange transactions "
        + "currently running.");
  });
}, "Ensure that databases() doesn't pick up changes that haven't commited.");
