library IndexedDB1Test;
import 'package:unittest/unittest.dart';
import 'package:unittest/html_individual_config.dart';
import 'dart:async';
import 'dart:html' as html;
import 'dart:math' as math;
import 'dart:indexed_db' as idb;

const String STORE_NAME = 'TEST';
const int VERSION = 1;

var databaseNameIndex = 0;
String nextDatabaseName() {
  return 'Test1_${databaseNameIndex++}';
}

Future testUpgrade() {
  var dbName = nextDatabaseName();
  var upgraded = false;

  // Delete any existing DBs.
  return html.window.indexedDB.deleteDatabase(dbName).then((_) {

      return html.window.indexedDB.open(dbName, version: 1,
          onUpgradeNeeded: (e) {});
    }).then((db) {
      db.close();
    }).then((_) {
      return html.window.indexedDB.open(dbName, version: 2,
          onUpgradeNeeded: (e) {
            expect(e.oldVersion, 1);
            expect(e.newVersion, 2);
            upgraded = true;
          });
    }).then((_) {
      expect(upgraded, isTrue);
    });
}

testReadWrite(key, value, matcher,
    [dbName, storeName = STORE_NAME, version = VERSION,
    stringifyResult = false]) => () {
  if (dbName == null) {
    dbName = nextDatabaseName();
  }
  createObjectStore(e) {
    var store = e.target.result.createObjectStore(storeName);
    expect(store, isNotNull);
  }

  var db;
  return html.window.indexedDB.deleteDatabase(dbName).then((_) {
      return html.window.indexedDB.open(dbName, version: version,
          onUpgradeNeeded: createObjectStore);
    }).then((result) {
      db = result;
      var transaction = db.transactionList([storeName], 'readwrite');
      transaction.objectStore(storeName).put(value, key);
      return transaction.completed;
    }).then((_) {
      var transaction = db.transaction(storeName, 'readonly');
      return transaction.objectStore(storeName).getObject(key);
    }).then((object) {
      db.close();
      if (stringifyResult) {
        // Stringify the numbers to verify that we're correctly returning ints
        // as ints vs doubles.
        expect(object.toString(), matcher);
      } else {
        expect(object, matcher);
      }
    }).whenComplete(() {
      if (db != null) {
        db.close();
      }
      return html.window.indexedDB.deleteDatabase(dbName);
    });
};

testReadWriteTyped(key, value, matcher,
    [dbName, String storeName = STORE_NAME, version = VERSION,
    stringifyResult = false]) => () {
  if (dbName == null) {
    dbName = nextDatabaseName();
  }
  void createObjectStore(e) {
    var store = e.target.result.createObjectStore(storeName);
    expect(store, isNotNull);
  }

  idb.Database db;
  // Delete any existing DBs.
  return html.window.indexedDB.deleteDatabase(dbName).then((_) {
      return html.window.indexedDB.open(dbName, version: version,
        onUpgradeNeeded: createObjectStore);
    }).then((idb.Database result) {
      db = result;
      idb.Transaction transaction = db.transactionList([storeName], 'readwrite');
      transaction.objectStore(storeName).put(value, key);

      return transaction.completed;
    }).then((idb.Database result) {
      idb.Transaction transaction = db.transaction(storeName, 'readonly');
      return transaction.objectStore(storeName).getObject(key);
    }).then((object) {
      db.close();
      if (stringifyResult) {
        // Stringify the numbers to verify that we're correctly returning ints
        // as ints vs doubles.
        expect(object.toString(), matcher);
      } else {
        expect(object, matcher);
      }
    }).whenComplete(() {
      if (db != null) {
        db.close();
      }
      return html.window.indexedDB.deleteDatabase(dbName);
    });
};

void testTypes(testFunction) {
  test('String', testFunction(123, 'Hoot!', equals('Hoot!')));
  test('int', testFunction(123, 12345, equals(12345)));
  test('List', testFunction(123, [1, 2, 3], equals([1, 2, 3])));
  test('List 2', testFunction(123, [2, 3, 4], equals([2, 3, 4])));
  test('bool', testFunction(123, [true, false], equals([true, false])));
  test('largeInt', testFunction(123, 1371854424211,
      equals("1371854424211"), null, STORE_NAME, VERSION, true));
  test('largeDoubleConvertedToInt', testFunction(123, 1371854424211.0,
      equals("1371854424211"), null, STORE_NAME, VERSION, true));
  test('largeIntInMap', testFunction(123, {'time': 4503599627370492},
      equals("{time: 4503599627370492}"), null, STORE_NAME, VERSION, true));
  var now = new DateTime.now();
  test('DateTime', testFunction(123, now,
    predicate((date) =>
      date.millisecondsSinceEpoch == now.millisecondsSinceEpoch)));
}

main() {
  useHtmlIndividualConfiguration();

  // Test that indexed_db is properly flagged as supported or not.
  // Note that the rest of the indexed_db tests assume that this has been
  // checked.
  group('supported', () {
    test('supported', () {
      expect(idb.IdbFactory.supported, true);
    });
  });

  group('supportsDatabaseNames', () {
    test('supported', () {
      expect(html.window.indexedDB.supportsDatabaseNames, isTrue);
    });
  });

  group('functional', () {
    test('throws when unsupported', () {
      var expectation = idb.IdbFactory.supported ? returnsNormally : throws;

      expect(() {
        var db = html.window.indexedDB;
        db.open('random_db');
      }, expectation);
    });

    // Don't bother with these tests if it's unsupported.
    if (idb.IdbFactory.supported) {
      test('upgrade', testUpgrade);
      group('dynamic', () {
        testTypes(testReadWrite);
      });
      group('typed', () {
        testTypes(testReadWriteTyped);
      });
    }
  });
}
