test_autoIncrement.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. /**
  2. * Any copyright is dedicated to the Public Domain.
  3. * http://creativecommons.org/publicdomain/zero/1.0/
  4. */
  5. var disableWorkerTest = "Need to implement a gc() function for worker tests";
  6. if (!this.window) {
  7. this.runTest = function() {
  8. todo(false, "Test disabled in xpcshell test suite for now");
  9. finishTest();
  10. }
  11. }
  12. var testGenerator = testSteps();
  13. function genCheck(key, value, test, options) {
  14. return function(event) {
  15. is(JSON.stringify(event.target.result), JSON.stringify(key),
  16. "correct returned key in " + test);
  17. if (options && options.store) {
  18. is(event.target.source, options.store, "correct store in " + test);
  19. }
  20. if (options && options.trans) {
  21. is(event.target.transaction, options.trans, "correct transaction in " + test);
  22. }
  23. event.target.source.get(key).onsuccess = function(event) {
  24. is(JSON.stringify(event.target.result), JSON.stringify(value),
  25. "correct stored value in " + test);
  26. continueToNextStepSync();
  27. }
  28. }
  29. }
  30. function testSteps()
  31. {
  32. const dbname = this.window ? window.location.pathname : "Splendid Test";
  33. const RW = "readwrite";
  34. let c1 = 1;
  35. let c2 = 1;
  36. let openRequest = indexedDB.open(dbname, 1);
  37. openRequest.onerror = errorHandler;
  38. openRequest.onupgradeneeded = grabEventAndContinueHandler;
  39. openRequest.onsuccess = unexpectedSuccessHandler;
  40. let event = yield undefined;
  41. let db = event.target.result;
  42. let trans = event.target.transaction;
  43. // Create test stores
  44. let store1 = db.createObjectStore("store1", { autoIncrement: true });
  45. let store2 = db.createObjectStore("store2", { autoIncrement: true, keyPath: "id" });
  46. let store3 = db.createObjectStore("store3", { autoIncrement: false });
  47. is(store1.autoIncrement, true, "store1 .autoIncrement");
  48. is(store2.autoIncrement, true, "store2 .autoIncrement");
  49. is(store3.autoIncrement, false, "store3 .autoIncrement");
  50. store1.createIndex("unique1", "unique", { unique: true });
  51. store2.createIndex("unique1", "unique", { unique: true });
  52. // Test simple inserts
  53. let test = " for test simple insert"
  54. store1.add({ foo: "value1" }).onsuccess =
  55. genCheck(c1++, { foo: "value1" }, "first" + test);
  56. store1.add({ foo: "value2" }).onsuccess =
  57. genCheck(c1++, { foo: "value2" }, "second" + test);
  58. yield undefined;
  59. yield undefined;
  60. store2.put({ bar: "value1" }).onsuccess =
  61. genCheck(c2, { bar: "value1", id: c2 }, "first in store2" + test,
  62. { store: store2 });
  63. c2++;
  64. store1.put({ foo: "value3" }).onsuccess =
  65. genCheck(c1++, { foo: "value3" }, "third" + test,
  66. { store: store1 });
  67. yield undefined;
  68. yield undefined;
  69. store2.get(IDBKeyRange.lowerBound(c2)).onsuccess = grabEventAndContinueHandler;
  70. event = yield undefined;
  71. is(event.target.result, undefined, "no such value" + test);
  72. // Close version_change transaction
  73. openRequest.onsuccess = grabEventAndContinueHandler;
  74. event = yield undefined;
  75. is(event.target, openRequest, "succeeded to open" + test);
  76. is(event.type, "success", "succeeded to open" + test);
  77. // Test inserting explicit keys
  78. test = " for test explicit keys";
  79. trans = db.transaction("store1", RW);
  80. trans.objectStore("store1").add({ explicit: 1 }, 100).onsuccess =
  81. genCheck(100, { explicit: 1 }, "first" + test);
  82. c1 = 101;
  83. trans = db.transaction("store1", RW);
  84. trans.objectStore("store1").add({ explicit: 2 }).onsuccess =
  85. genCheck(c1++, { explicit: 2 }, "second" + test);
  86. yield undefined; yield undefined;
  87. trans = db.transaction("store1", RW);
  88. trans.objectStore("store1").add({ explicit: 3 }, 200).onsuccess =
  89. genCheck(200, { explicit: 3 }, "third" + test);
  90. c1 = 201;
  91. trans.objectStore("store1").add({ explicit: 4 }).onsuccess =
  92. genCheck(c1++, { explicit: 4 }, "fourth" + test);
  93. yield undefined; yield undefined;
  94. trans = db.transaction("store1", RW);
  95. trans.objectStore("store1").add({ explicit: 5 }, 150).onsuccess =
  96. genCheck(150, { explicit: 5 }, "fifth" + test);
  97. yield undefined;
  98. trans.objectStore("store1").add({ explicit: 6 }).onsuccess =
  99. genCheck(c1++, { explicit: 6 }, "sixth" + test);
  100. yield undefined;
  101. trans = db.transaction("store1", RW);
  102. trans.objectStore("store1").add({ explicit: 7 }, "key").onsuccess =
  103. genCheck("key", { explicit: 7 }, "seventh" + test);
  104. yield undefined;
  105. trans.objectStore("store1").add({ explicit: 8 }).onsuccess =
  106. genCheck(c1++, { explicit: 8 }, "eighth" + test);
  107. yield undefined;
  108. trans = db.transaction("store1", RW);
  109. trans.objectStore("store1").add({ explicit: 7 }, [100000]).onsuccess =
  110. genCheck([100000], { explicit: 7 }, "seventh" + test);
  111. yield undefined;
  112. trans.objectStore("store1").add({ explicit: 8 }).onsuccess =
  113. genCheck(c1++, { explicit: 8 }, "eighth" + test);
  114. yield undefined;
  115. trans = db.transaction("store1", RW);
  116. trans.objectStore("store1").add({ explicit: 9 }, -100000).onsuccess =
  117. genCheck(-100000, { explicit: 9 }, "ninth" + test);
  118. yield undefined;
  119. trans.objectStore("store1").add({ explicit: 10 }).onsuccess =
  120. genCheck(c1++, { explicit: 10 }, "tenth" + test);
  121. yield undefined;
  122. trans = db.transaction("store2", RW);
  123. trans.objectStore("store2").add({ explicit2: 1, id: 300 }).onsuccess =
  124. genCheck(300, { explicit2: 1, id: 300 }, "first store2" + test);
  125. c2 = 301;
  126. trans = db.transaction("store2", RW);
  127. trans.objectStore("store2").add({ explicit2: 2 }).onsuccess =
  128. genCheck(c2, { explicit2: 2, id: c2 }, "second store2" + test);
  129. c2++;
  130. yield undefined; yield undefined;
  131. trans = db.transaction("store2", RW);
  132. trans.objectStore("store2").add({ explicit2: 3, id: 400 }).onsuccess =
  133. genCheck(400, { explicit2: 3, id: 400 }, "third store2" + test);
  134. c2 = 401;
  135. trans.objectStore("store2").add({ explicit2: 4 }).onsuccess =
  136. genCheck(c2, { explicit2: 4, id: c2 }, "fourth store2" + test);
  137. c2++;
  138. yield undefined; yield undefined;
  139. trans = db.transaction("store2", RW);
  140. trans.objectStore("store2").add({ explicit: 5, id: 150 }).onsuccess =
  141. genCheck(150, { explicit: 5, id: 150 }, "fifth store2" + test);
  142. yield undefined;
  143. trans.objectStore("store2").add({ explicit: 6 }).onsuccess =
  144. genCheck(c2, { explicit: 6, id: c2 }, "sixth store2" + test);
  145. c2++;
  146. yield undefined;
  147. trans = db.transaction("store2", RW);
  148. trans.objectStore("store2").add({ explicit: 7, id: "key" }).onsuccess =
  149. genCheck("key", { explicit: 7, id: "key" }, "seventh store2" + test);
  150. yield undefined;
  151. trans.objectStore("store2").add({ explicit: 8 }).onsuccess =
  152. genCheck(c2, { explicit: 8, id: c2 }, "eighth store2" + test);
  153. c2++;
  154. yield undefined;
  155. trans = db.transaction("store2", RW);
  156. trans.objectStore("store2").add({ explicit: 7, id: [100000] }).onsuccess =
  157. genCheck([100000], { explicit: 7, id: [100000] }, "seventh store2" + test);
  158. yield undefined;
  159. trans.objectStore("store2").add({ explicit: 8 }).onsuccess =
  160. genCheck(c2, { explicit: 8, id: c2 }, "eighth store2" + test);
  161. c2++;
  162. yield undefined;
  163. trans = db.transaction("store2", RW);
  164. trans.objectStore("store2").add({ explicit: 9, id: -100000 }).onsuccess =
  165. genCheck(-100000, { explicit: 9, id: -100000 }, "ninth store2" + test);
  166. yield undefined;
  167. trans.objectStore("store2").add({ explicit: 10 }).onsuccess =
  168. genCheck(c2, { explicit: 10, id: c2 }, "tenth store2" + test);
  169. c2++;
  170. yield undefined;
  171. // Test separate transactions doesn't generate overlapping numbers
  172. test = " for test non-overlapping counts";
  173. trans = db.transaction("store1", RW);
  174. trans2 = db.transaction("store1", RW);
  175. trans2.objectStore("store1").put({ over: 2 }).onsuccess =
  176. genCheck(c1 + 1, { over: 2 }, "first" + test,
  177. { trans: trans2 });
  178. trans.objectStore("store1").put({ over: 1 }).onsuccess =
  179. genCheck(c1, { over: 1 }, "second" + test,
  180. { trans: trans });
  181. c1 += 2;
  182. yield undefined; yield undefined;
  183. trans = db.transaction("store2", RW);
  184. trans2 = db.transaction("store2", RW);
  185. trans2.objectStore("store2").put({ over: 2 }).onsuccess =
  186. genCheck(c2 + 1, { over: 2, id: c2 + 1 }, "third" + test,
  187. { trans: trans2 });
  188. trans.objectStore("store2").put({ over: 1 }).onsuccess =
  189. genCheck(c2, { over: 1, id: c2 }, "fourth" + test,
  190. { trans: trans });
  191. c2 += 2;
  192. yield undefined; yield undefined;
  193. // Test that error inserts doesn't increase generator
  194. test = " for test error inserts";
  195. trans = db.transaction(["store1", "store2"], RW);
  196. trans.objectStore("store1").add({ unique: 1 }, -1);
  197. trans.objectStore("store2").add({ unique: 1, id: "unique" });
  198. trans.objectStore("store1").add({ error: 1, unique: 1 }).
  199. addEventListener("error", new ExpectError("ConstraintError", true));
  200. trans.objectStore("store1").add({ error: 2 }).onsuccess =
  201. genCheck(c1++, { error: 2 }, "first" + test);
  202. yield undefined; yield undefined;
  203. trans.objectStore("store2").add({ error: 3, unique: 1 }).
  204. addEventListener("error", new ExpectError("ConstraintError", true));
  205. trans.objectStore("store2").add({ error: 4 }).onsuccess =
  206. genCheck(c2, { error: 4, id: c2 }, "second" + test);
  207. c2++;
  208. yield undefined; yield undefined;
  209. trans.objectStore("store1").add({ error: 5, unique: 1 }, 100000).
  210. addEventListener("error", new ExpectError("ConstraintError", true));
  211. trans.objectStore("store1").add({ error: 6 }).onsuccess =
  212. genCheck(c1++, { error: 6 }, "third" + test);
  213. yield undefined; yield undefined;
  214. trans.objectStore("store2").add({ error: 7, unique: 1, id: 100000 }).
  215. addEventListener("error", new ExpectError("ConstraintError", true));
  216. trans.objectStore("store2").add({ error: 8 }).onsuccess =
  217. genCheck(c2, { error: 8, id: c2 }, "fourth" + test);
  218. c2++;
  219. yield undefined; yield undefined;
  220. // Test that aborts doesn't increase generator
  221. test = " for test aborted transaction";
  222. trans = db.transaction(["store1", "store2"], RW);
  223. trans.objectStore("store1").add({ abort: 1 }).onsuccess =
  224. genCheck(c1, { abort: 1 }, "first" + test);
  225. trans.objectStore("store2").put({ abort: 2 }).onsuccess =
  226. genCheck(c2, { abort: 2, id: c2 }, "second" + test);
  227. yield undefined; yield undefined;
  228. trans.objectStore("store1").add({ abort: 3 }, 500).onsuccess =
  229. genCheck(500, { abort: 3 }, "third" + test);
  230. trans.objectStore("store2").put({ abort: 4, id: 600 }).onsuccess =
  231. genCheck(600, { abort: 4, id: 600 }, "fourth" + test);
  232. yield undefined; yield undefined;
  233. trans.objectStore("store1").add({ abort: 5 }).onsuccess =
  234. genCheck(501, { abort: 5 }, "fifth" + test);
  235. trans.objectStore("store2").put({ abort: 6 }).onsuccess =
  236. genCheck(601, { abort: 6, id: 601 }, "sixth" + test);
  237. yield undefined; yield undefined;
  238. trans.abort();
  239. trans.onabort = grabEventAndContinueHandler;
  240. event = yield
  241. is(event.type, "abort", "transaction aborted");
  242. is(event.target, trans, "correct transaction aborted");
  243. trans = db.transaction(["store1", "store2"], RW);
  244. trans.objectStore("store1").add({ abort: 1 }).onsuccess =
  245. genCheck(c1++, { abort: 1 }, "re-first" + test);
  246. trans.objectStore("store2").put({ abort: 2 }).onsuccess =
  247. genCheck(c2, { abort: 2, id: c2 }, "re-second" + test);
  248. c2++;
  249. yield undefined; yield undefined;
  250. // Test that delete doesn't decrease generator
  251. test = " for test delete items"
  252. trans = db.transaction(["store1", "store2"], RW);
  253. trans.objectStore("store1").add({ delete: 1 }).onsuccess =
  254. genCheck(c1++, { delete: 1 }, "first" + test);
  255. trans.objectStore("store2").put({ delete: 2 }).onsuccess =
  256. genCheck(c2, { delete: 2, id: c2 }, "second" + test);
  257. c2++;
  258. yield undefined; yield undefined;
  259. trans.objectStore("store1").delete(c1 - 1).onsuccess =
  260. grabEventAndContinueHandler;
  261. trans.objectStore("store2").delete(c2 - 1).onsuccess =
  262. grabEventAndContinueHandler;
  263. yield undefined; yield undefined;
  264. trans.objectStore("store1").add({ delete: 3 }).onsuccess =
  265. genCheck(c1++, { delete: 3 }, "first" + test);
  266. trans.objectStore("store2").put({ delete: 4 }).onsuccess =
  267. genCheck(c2, { delete: 4, id: c2 }, "second" + test);
  268. c2++;
  269. yield undefined; yield undefined;
  270. trans.objectStore("store1").delete(c1 - 1).onsuccess =
  271. grabEventAndContinueHandler;
  272. trans.objectStore("store2").delete(c2 - 1).onsuccess =
  273. grabEventAndContinueHandler;
  274. yield undefined; yield undefined;
  275. trans = db.transaction(["store1", "store2"], RW);
  276. trans.objectStore("store1").add({ delete: 5 }).onsuccess =
  277. genCheck(c1++, { delete: 5 }, "first" + test);
  278. trans.objectStore("store2").put({ delete: 6 }).onsuccess =
  279. genCheck(c2, { delete: 6, id: c2 }, "second" + test);
  280. c2++;
  281. yield undefined; yield undefined;
  282. // Test that clears doesn't decrease generator
  283. test = " for test clear stores";
  284. trans = db.transaction(["store1", "store2"], RW);
  285. trans.objectStore("store1").add({ clear: 1 }).onsuccess =
  286. genCheck(c1++, { clear: 1 }, "first" + test);
  287. trans.objectStore("store2").put({ clear: 2 }).onsuccess =
  288. genCheck(c2, { clear: 2, id: c2 }, "second" + test);
  289. c2++;
  290. yield undefined; yield undefined;
  291. trans.objectStore("store1").clear().onsuccess =
  292. grabEventAndContinueHandler;
  293. trans.objectStore("store2").clear().onsuccess =
  294. grabEventAndContinueHandler;
  295. yield undefined; yield undefined;
  296. trans.objectStore("store1").add({ clear: 3 }).onsuccess =
  297. genCheck(c1++, { clear: 3 }, "third" + test);
  298. trans.objectStore("store2").put({ clear: 4 }).onsuccess =
  299. genCheck(c2, { clear: 4, id: c2 }, "forth" + test);
  300. c2++;
  301. yield undefined; yield undefined;
  302. trans.objectStore("store1").clear().onsuccess =
  303. grabEventAndContinueHandler;
  304. trans.objectStore("store2").clear().onsuccess =
  305. grabEventAndContinueHandler;
  306. yield undefined; yield undefined;
  307. trans = db.transaction(["store1", "store2"], RW);
  308. trans.objectStore("store1").add({ clear: 5 }).onsuccess =
  309. genCheck(c1++, { clear: 5 }, "fifth" + test);
  310. trans.objectStore("store2").put({ clear: 6 }).onsuccess =
  311. genCheck(c2, { clear: 6, id: c2 }, "sixth" + test);
  312. c2++;
  313. yield undefined; yield undefined;
  314. // Test that close/reopen doesn't decrease generator
  315. test = " for test clear stores";
  316. trans = db.transaction(["store1", "store2"], RW);
  317. trans.objectStore("store1").clear().onsuccess =
  318. grabEventAndContinueHandler;
  319. trans.objectStore("store2").clear().onsuccess =
  320. grabEventAndContinueHandler;
  321. yield undefined; yield undefined;
  322. db.close();
  323. gc();
  324. openRequest = indexedDB.open(dbname, 2);
  325. openRequest.onerror = errorHandler;
  326. openRequest.onupgradeneeded = grabEventAndContinueHandler;
  327. openRequest.onsuccess = unexpectedSuccessHandler;
  328. event = yield undefined;
  329. db = event.target.result;
  330. trans = event.target.transaction;
  331. trans.objectStore("store1").add({ reopen: 1 }).onsuccess =
  332. genCheck(c1++, { reopen: 1 }, "first" + test);
  333. trans.objectStore("store2").put({ reopen: 2 }).onsuccess =
  334. genCheck(c2, { reopen: 2, id: c2 }, "second" + test);
  335. c2++;
  336. yield undefined; yield undefined;
  337. openRequest.onsuccess = grabEventAndContinueHandler;
  338. yield undefined;
  339. finishTest();
  340. yield undefined;
  341. }