/tests/test.html

https://github.com/podviaznikov/indexeddb-backbonejs-adapter · HTML · 658 lines · 635 code · 22 blank · 1 comment · 0 complexity · b08e1c42c2d4f5f887125f7351602ddc MD5 · raw file

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <script src="../lib/jquery.js"></script>
  5. <link rel="stylesheet" href="../lib/qunit.css" type="text/css" media="screen" />
  6. <script type="text/javascript" src="../lib/qunit.js"></script>
  7. <!-- Dependencies -->
  8. <script src="../lib/underscore-min.js" type="text/javascript"></script>
  9. <script src="../lib/backbone.js" type="text/javascript"></script>
  10. <script src="../backbone-indexeddb.js" type="text/javascript"></script>
  11. <script>
  12. var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;
  13. var database = {
  14. id: "movies-database",
  15. description: "The database for the Movies",
  16. migrations: [{
  17. version: "1.0",
  18. migrate: function (db, versionRequest, next) {
  19. var store = db.createObjectStore("movies");
  20. next();
  21. }
  22. }, {
  23. version: "1.1",
  24. migrate: function (db, versionRequest, next) {
  25. var store = versionRequest.transaction.objectStore("movies");
  26. store.createIndex("titleIndex", "title", {
  27. unique: false
  28. });
  29. store.createIndex("formatIndex", "format", {
  30. unique: false
  31. });
  32. next();
  33. }
  34. }]
  35. };
  36. var Movie = Backbone.Model.extend({
  37. database: database,
  38. storeName: "movies"
  39. });
  40. var Theater = Backbone.Collection.extend({
  41. database: database,
  42. storeName: "movies",
  43. model: Movie
  44. });
  45. function addAllMovies(movies, done) {
  46. if (!movies) {
  47. movies = [{
  48. title: "Hello",
  49. format: "blueray",
  50. id: "1"
  51. }, {
  52. title: "Bonjour",
  53. format: "dvd",
  54. id: "2"
  55. }, {
  56. title: "Halo",
  57. format: "blueray",
  58. id: "3"
  59. }, {
  60. title: "Nihao",
  61. format: "streaming",
  62. id: "4"
  63. }, {
  64. title: "Ciao",
  65. format: "dvd",
  66. id: "5"
  67. }];
  68. }
  69. var movie = movies.shift();
  70. if (movie) {
  71. var m = new Movie();
  72. m.save(movie, {
  73. success: function () {
  74. addAllMovies(movies, done);
  75. },
  76. error: function (o, error) {
  77. start();
  78. equals(true, false, error.error.target.webkitErrorMessage);
  79. }
  80. });
  81. } else {
  82. done();
  83. }
  84. }
  85. function deleteNext(movies, done) {
  86. if (movies.length === 0) {
  87. done();
  88. } else {
  89. movies[0].destroy({
  90. success: function () {
  91. deleteNext(movies, done);
  92. }
  93. });
  94. }
  95. }
  96. function nextTest() {
  97. var t = tests.shift();
  98. if (t) {
  99. console.log(t[0]);
  100. asyncTest(t[0], t[1]);
  101. }
  102. }
  103. var tests = [
  104. ["create model", function () {
  105. var movie = new Movie();
  106. movie.save({
  107. title: "The Matrix",
  108. format: "dvd"
  109. }, {
  110. success: function () {
  111. start();
  112. equals(true, true, "The movie should be saved successfully");
  113. nextTest();
  114. },
  115. error: function (o, error) {
  116. start();
  117. if (window.console && window.console.log) window.console.log(error);
  118. equals(true, false, error.error.target.webkitErrorMessage);
  119. nextTest();
  120. }
  121. });
  122. }],
  123. ["read model with id", function () {
  124. var movie = new Movie();
  125. movie.save({
  126. title: "Avatar",
  127. format: "blue-ray"
  128. }, {
  129. success: function () {
  130. // Ok, now we need to create a new movie object and retrieve it
  131. var saved = new Movie({
  132. id: movie.id
  133. });
  134. saved.fetch({
  135. success: function (object) {
  136. // success
  137. start();
  138. equals(saved.toJSON().title, movie.toJSON().title, "The movie should have the right title");
  139. equals(saved.toJSON().format, movie.toJSON().format, "The movie should have the right format");
  140. equals(object.toJSON().title, movie.toJSON().title, "The movie should have the right title");
  141. equals(object.toJSON().format, movie.toJSON().format, "The movie should have the right format");
  142. nextTest();
  143. },
  144. error: function (object, error) {
  145. start();
  146. equals(true, false, error);
  147. nextTest();
  148. // Failure
  149. }
  150. });
  151. },
  152. error: function (o, error) {
  153. start();
  154. equals(true, false, error.error.target.webkitErrorMessage);
  155. nextTest();
  156. }
  157. });
  158. }],
  159. ["read model with index", function () {
  160. function saveMovieAndReadWithIndex(movie) {
  161. movie.save({}, {
  162. success: function () {
  163. // Ok, now we need to create a new movie object and retrieve it
  164. var movie2 = new Movie({
  165. title: "Avatar",
  166. });
  167. movie2.fetch({
  168. success: function (object) {
  169. console.log("FOUND! SUCCESS");
  170. // success
  171. start();
  172. equals(movie2.toJSON().title, movie.toJSON().title, "The movie should have the right title");
  173. equals(movie2.toJSON().format, movie.toJSON().format, "The movie should have the right format");
  174. nextTest();
  175. },
  176. error: function (object, error) {
  177. start();
  178. equals(true, false, error);
  179. nextTest();
  180. }
  181. });
  182. },
  183. error: function (o, error) {
  184. start();
  185. equals(true, false, error.error.target.webkitErrorMessage);
  186. nextTest();
  187. }
  188. });
  189. }
  190. var movie = new Movie({
  191. title: "Avatar",
  192. });
  193. movie.fetch({
  194. success: function () {
  195. movie.destroy({
  196. success: function () {
  197. saveMovieAndReadWithIndex(movie);
  198. }
  199. });
  200. },
  201. error: function () {
  202. saveMovieAndReadWithIndex(movie);
  203. }
  204. });
  205. }],
  206. ["read model that do not exist with index", function () {
  207. var movie = new Movie({
  208. title: "Memento",
  209. });
  210. movie.fetch({
  211. success: function (object) {
  212. // success
  213. start();
  214. equals(true, false, error);
  215. nextTest();
  216. },
  217. error: function (object, error) {
  218. start();
  219. equals(true, true, error);
  220. nextTest();
  221. }
  222. });
  223. }],
  224. ["update model", function () {
  225. var movie = new Movie();
  226. movie.save({
  227. title: "Star Wars, Episode IV",
  228. format: "dvd"
  229. }, {
  230. success: function () {
  231. movie.save({
  232. title: "Star Wars, Episode V"
  233. }, {
  234. success: function () {
  235. movie.fetch({
  236. success: function (object) {
  237. // success
  238. start();
  239. equals("Star Wars, Episode V", movie.toJSON().title, "The movie should have the right title");
  240. equals("dvd", movie.toJSON().format, "The movie should have the right format");
  241. nextTest();
  242. },
  243. error: function (object, error) {
  244. start();
  245. equals(true, false, error);
  246. nextTest();
  247. }
  248. });
  249. },
  250. error: function () {
  251. start();
  252. equals(true, false, "Would not update");
  253. nextTest();
  254. }
  255. });
  256. },
  257. error: function (object, error) {
  258. start();
  259. equals(true, false, error.error.target.webkitErrorMessage);
  260. nextTest();
  261. }
  262. });
  263. }],
  264. ["delete model", function () {
  265. var movie = new Movie();
  266. movie.save({
  267. title: "Avatar",
  268. format: "blue-ray"
  269. }, {
  270. success: function (object) {
  271. // success
  272. movie.destroy({
  273. success: function (object) {
  274. // success
  275. equals(true, true, "It should delete the object");
  276. movie.fetch({
  277. success: function () {
  278. start();
  279. equals(true, false, "Object was not deleted");
  280. nextTest();
  281. },
  282. error: function (object, error) {
  283. start();
  284. equals(error, "Not Found", "Object was deleted");
  285. nextTest();
  286. }
  287. });
  288. },
  289. error: function (object, error) {
  290. // error
  291. start();
  292. equals(true, false, error);
  293. nextTest();
  294. }
  295. });
  296. },
  297. error: function (error) {
  298. // error
  299. start();
  300. equals(true, false, error.error.target.webkitErrorMessage);
  301. nextTest();
  302. }
  303. });
  304. }],
  305. ["read collection with no options", function () {
  306. var theater = new Theater();
  307. theater.fetch({
  308. success: function () {
  309. deleteNext(theater.models, function () {
  310. addAllMovies(null, function () {
  311. // Now all movies are inserted. Which is good.
  312. theater.fetch({
  313. success: function () {
  314. start();
  315. equals(theater.models.length, 5, "Should have 5 elements");
  316. deepEqual(theater.pluck("title"), ["Hello", "Bonjour", "Halo", "Nihao", "Ciao"], "Should have [\"Hello\", \"Bonjour\", \"Halo\", \"Nihao\", \"Ciao\"]");
  317. nextTest();
  318. }
  319. });
  320. });
  321. });
  322. }
  323. });
  324. }],
  325. ["read collection with limit", function () {
  326. var theaterToClean = new Theater();
  327. theaterToClean.fetch({
  328. success: function () {
  329. deleteNext(theaterToClean.models, function () {
  330. addAllMovies(null, function () {
  331. // Now all movies are inserted. Which is good.
  332. var theater = new Theater();
  333. theater.fetch({
  334. limit: 3,
  335. success: function () {
  336. start();
  337. equals(theater.models.length, 3, "Should have 3 elements");
  338. deepEqual(theater.pluck("title"), ["Hello", "Bonjour", "Halo"], "Should have [\"Hello\", \"Bonjour\", \"Halo\"]");
  339. nextTest();
  340. }
  341. });
  342. });
  343. });
  344. }
  345. });
  346. }],
  347. ["read collection with offset", function () {
  348. var theaterToClean = new Theater();
  349. theaterToClean.fetch({
  350. success: function () {
  351. deleteNext(theaterToClean.models, function () {
  352. addAllMovies(null, function () {
  353. // Now all movies are inserted. Which is good.
  354. var theater = new Theater();
  355. theater.fetch({
  356. offset: 2,
  357. success: function () {
  358. start();
  359. equals(theater.models.length, 3, "Should have 3 elements");
  360. deepEqual(theater.pluck("title"), ["Halo", "Nihao", "Ciao"], "Should have [\"Halo\", \"Nihao\", \"Ciao\"]");
  361. nextTest();
  362. }
  363. });
  364. });
  365. });
  366. }
  367. });
  368. }],
  369. ["read collection with offset and limit", function () {
  370. var theaterToClean = new Theater();
  371. theaterToClean.fetch({
  372. success: function () {
  373. deleteNext(theaterToClean.models, function () {
  374. addAllMovies(null, function () {
  375. // Now all movies are inserted. Which is good.
  376. var theater = new Theater();
  377. theater.fetch({
  378. offset: 1,
  379. limit: 2,
  380. success: function () {
  381. start();
  382. equals(theater.models.length, 2, "Should have 2 elements");
  383. deepEqual(theater.pluck("title"), ["Bonjour", "Halo"], "Should have [\"Bonjour\", \"Halo\"]");
  384. nextTest();
  385. }
  386. });
  387. });
  388. });
  389. }
  390. });
  391. }],
  392. ["read collection with range", function () {
  393. var theaterToClean = new Theater();
  394. theaterToClean.fetch({
  395. success: function () {
  396. deleteNext(theaterToClean.models, function () {
  397. addAllMovies(null, function () {
  398. // Now all movies are inserted. Which is good.
  399. var theater = new Theater();
  400. theater.fetch({
  401. range: ["1.5", "4.5"],
  402. success: function () {
  403. start();
  404. equals(theater.models.length, 3, "Should have 3 elements");
  405. deepEqual(theater.pluck("title"), ["Bonjour", "Halo", "Nihao"], "Should have [\"Bonjour\", \"Halo\", \"Nihao\"]");
  406. nextTest();
  407. }
  408. });
  409. });
  410. });
  411. }
  412. });
  413. }],
  414. ["read collection via condition on index with a single value", function () {
  415. var theaterToClean = new Theater();
  416. theaterToClean.fetch({
  417. success: function () {
  418. deleteNext(theaterToClean.models, function () {
  419. addAllMovies(null, function () {
  420. // Now all movies are inserted. Which is good.
  421. var theater = new Theater();
  422. theater.fetch({
  423. conditions: {
  424. format: "dvd"
  425. },
  426. success: function () {
  427. start();
  428. equals(theater.models.length, 2, "Should have 2 elements");
  429. deepEqual(theater.pluck("title"), ["Bonjour", "Ciao"], "Should have [\"Bonjour\", \"Ciao\"]");
  430. nextTest();
  431. }
  432. });
  433. });
  434. });
  435. }
  436. });
  437. }],
  438. ["read collection via condition on index with a range", function () {
  439. var theaterToClean = new Theater();
  440. theaterToClean.fetch({
  441. success: function () {
  442. deleteNext(theaterToClean.models, function () {
  443. addAllMovies(null, function () {
  444. // Now all movies are inserted. Which is good.
  445. var theater = new Theater();
  446. theater.fetch({
  447. conditions: {
  448. format: ["a", "f"]
  449. },
  450. success: function () {
  451. start();
  452. equals(theater.models.length, 4, "Should have 4 elements");
  453. deepEqual(theater.pluck("title"), ["Hello", "Halo", "Bonjour", "Ciao"], "Should have [\"Hello\", \"Halo\", \"Bonjour\", \"Ciao\"]");
  454. nextTest();
  455. }
  456. });
  457. });
  458. });
  459. }
  460. });
  461. }],
  462. ["read collection via condition on index with a range and a limit", function () {
  463. var theaterToClean = new Theater();
  464. theaterToClean.fetch({
  465. success: function () {
  466. deleteNext(theaterToClean.models, function () {
  467. addAllMovies(null, function () {
  468. // Now all movies are inserted. Which is good.
  469. var theater = new Theater();
  470. theater.fetch({
  471. limit: 2,
  472. conditions: {
  473. format: ["a", "f"]
  474. },
  475. success: function () {
  476. start();
  477. equals(theater.models.length, 2, "Should have 2 elements");
  478. deepEqual(theater.pluck("title"), ["Hello", "Halo"], "Should have [\"Hello\", \"Halo\"]");
  479. nextTest();
  480. }
  481. });
  482. });
  483. });
  484. }
  485. });
  486. }],
  487. ["read collection via condition on index with a range, an offset and a limit", function () {
  488. var theaterToClean = new Theater();
  489. theaterToClean.fetch({
  490. success: function () {
  491. deleteNext(theaterToClean.models, function () {
  492. addAllMovies(null, function () {
  493. // Now all movies are inserted. Which is good.
  494. var theater = new Theater();
  495. theater.fetch({
  496. offset: 2,
  497. limit: 2,
  498. conditions: {
  499. format: ["a", "f"]
  500. },
  501. success: function () {
  502. start();
  503. equals(theater.models.length, 2, "Should have 2 elements");
  504. deepEqual(theater.pluck("title"), ["Bonjour", "Ciao"], "Should have [\"Bonjour\", \"Ciao\"]");
  505. nextTest();
  506. }
  507. });
  508. });
  509. });
  510. }
  511. });
  512. }],
  513. ["read collection via condition on index with a range reversed", function () {
  514. var theaterToClean = new Theater();
  515. theaterToClean.fetch({
  516. success: function () {
  517. deleteNext(theaterToClean.models, function () {
  518. addAllMovies(null, function () {
  519. // Now all movies are inserted. Which is good.
  520. var theater = new Theater();
  521. theater.fetch({
  522. conditions: {
  523. format: ["f", "a"]
  524. },
  525. success: function () {
  526. start();
  527. equals(theater.models.length, 4, "Should have 4 elements");
  528. deepEqual(theater.pluck("title"), ["Ciao", "Bonjour", "Halo", "Hello"], "Should have [\"Ciao\", \"Bonjour\", \"Halo\", \"Hello\"]");
  529. nextTest();
  530. }
  531. });
  532. });
  533. });
  534. }
  535. });
  536. }],
  537. ["support for the 'addIndividually' property", function () {
  538. var counter = 0,
  539. theater = new Theater();
  540. theater.fetch({
  541. addIndividually: true,
  542. success: function () {
  543. // console.log('success callback', arguments);
  544. },
  545. error: function () {
  546. // console.log('error callback', arguments);
  547. }
  548. });
  549. start();
  550. // we want 5 'add' events
  551. expect(5);
  552. theater.bind('add', function (model, collection) {
  553. counter += 1;
  554. equal(collection.length, counter)
  555. // this is a bit hokey, but will do the trick.
  556. if (collection.length === 5) nextTest();
  557. });
  558. }]
  559. ];
  560. // Let's go run the tests
  561. nextTest(tests);
  562. // First, let's see the content of the database... because I'm little worried about it!
  563. // var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;
  564. // var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction; // No prefix in moz
  565. //
  566. // var dbRequest = indexedDB.open(database.id, "");
  567. //
  568. // var db = null;
  569. // var cycles = 0;
  570. //
  571. // var all = [];
  572. //
  573. // dbRequest.onsuccess = function (e) {
  574. // db = e.target.result; // Attach the connection ot the queue.
  575. // var readTransaction = db.transaction(["movies"], IDBTransaction.READ_ONLY);
  576. // var store = readTransaction.objectStore("movies");
  577. //
  578. // var index = store.index("titleIndex");
  579. // var readCursor = index.openCursor();
  580. //
  581. // readCursor.onsuccess = function (e) {
  582. // var cursor = e.target.result;
  583. // if (!cursor) {
  584. // var done = _.after(all.length + 1, function(){
  585. // console.log("----- END OF DEBUG -----");
  586. // nextTest(tests);
  587. // })
  588. // done();
  589. // _.each(all, function (obj, index) {
  590. // console.log("Deleting : " + JSON.stringify(obj));
  591. //
  592. // var deleteTransaction = db.transaction(["movies"], IDBTransaction.READ_WRITE);
  593. // var store = deleteTransaction.objectStore("movies");
  594. //
  595. // var deleteRequest = store.delete(obj.id);
  596. // deleteRequest.onsuccess = function (event) {
  597. // console.log("OK. ONE LESS");
  598. // done();
  599. // };
  600. // deleteRequest.onerror = function (event) {
  601. // console.log("DANG")
  602. // };
  603. // });
  604. // }
  605. // else {
  606. // all.push(cursor.value);
  607. // cursor.continue();
  608. // }
  609. // };
  610. // }
  611. // dbRequest.onerror = function (e) {
  612. // console.error("Couldn't not connect to the database");
  613. // };
  614. //
  615. // dbRequest.onabort = function (e) {
  616. // console.error("Connection to the database aborted");
  617. // };
  618. //
  619. </script>
  620. </head>
  621. <body>
  622. <h1 id="qunit-header">
  623. Inbox QUnit test
  624. </h1>
  625. <h2 id="qunit-banner">
  626. </h2>
  627. <div id="qunit-testrunner-toolbar">
  628. </div>
  629. <h2 id="qunit-userAgent">
  630. </h2>
  631. <ol id="qunit-tests">
  632. </ol>
  633. <div id="log" style="">
  634. </div>
  635. </body>
  636. </html>