| LEFT | RIGHT |
| 1 // Copyright 2008, Google Inc. | 1 // Copyright 2008, Google Inc. |
| 2 // | 2 // |
| 3 // Redistribution and use in source and binary forms, with or without | 3 // Redistribution and use in source and binary forms, with or without |
| 4 // modification, are permitted provided that the following conditions are met: | 4 // modification, are permitted provided that the following conditions are met: |
| 5 // | 5 // |
| 6 // 1. Redistributions of source code must retain the above copyright notice, | 6 // 1. Redistributions of source code must retain the above copyright notice, |
| 7 // this list of conditions and the following disclaimer. | 7 // this list of conditions and the following disclaimer. |
| 8 // 2. Redistributions in binary form must reproduce the above copyright notice, | 8 // 2. Redistributions in binary form must reproduce the above copyright notice, |
| 9 // this list of conditions and the following disclaimer in the documentation | 9 // this list of conditions and the following disclaimer in the documentation |
| 10 // and/or other materials provided with the distribution. | 10 // and/or other materials provided with the distribution. |
| 11 // 3. Neither the name of Google Inc. nor the names of its contributors may be | 11 // 3. Neither the name of Google Inc. nor the names of its contributors may be |
| 12 // used to endorse or promote products derived from this software without | 12 // used to endorse or promote products derived from this software without |
| 13 // specific prior written permission. | 13 // specific prior written permission. |
| 14 // | 14 // |
| 15 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED | 15 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
| 16 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | 16 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| 17 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO | 17 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
| 18 // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 18 // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 19 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 19 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 20 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | 20 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
| 21 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | 21 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| 22 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | 22 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
| 23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | 23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
| 24 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 24 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 25 | 25 |
| 26 var db_manager = google.gears.factory.create('beta.databasemanager'); | 26 var db_manager = google.gears.factory.create('beta.databasemanager'); |
| 27 | 27 |
| 28 function testDatabaseManagerCreation() { | 28 function testDatabaseManagerCreation() { |
| 29 assertNotNull(db_manager, 'Database manager should be a value'); | 29 assertNotNull(db_manager, 'Database manager should be a value'); |
| 30 } | 30 } |
| 31 | 31 |
| 32 function testDatabaseManagerApiSig() { | 32 function testDatabaseManagerApiSig() { |
| 33 var method = 'DatabaseManager.openDatabase()'; | 33 var method = 'DatabaseManager.openDatabase()'; |
| 34 assert(db_manager.openDatabase, method + ' should be present'); | 34 assert(db_manager.openDatabase, method + ' should be present'); |
| 35 assertError(function() { | 35 assertError(function() { |
| 36 db_manager.openDatabase(); | 36 db_manager.openDatabase(); |
| 37 }, null, method + ' has required parameters'); | 37 }, null, method + ' has required parameters'); |
| 38 assertError(function() { | 38 assertError(function() { |
| 39 db_manager.openDatabase('unit_test_db'); | 39 db_manager.openDatabase('unit_test_db'); |
| 40 }, null, method + ' requires a version parameter'); | 40 }, null, method + ' requires a version parameter'); |
| 41 } | 41 } |
| 42 | 42 |
| 43 function testDatabaseOpening() { | 43 function testDatabaseOpening() { |
| 44 var db = db_manager.openDatabase('unit_test_db', '', 'ignored_description', | 44 var db = db_manager.openDatabase('unit_test_db', '', 'ignored_description', |
| 45 'ignored_estimated_size'); | 45 'ignored_estimated_size'); |
| 46 assert(db, 'Database should be a value'); | 46 assert(db, 'Database should be a value'); |
| 47 } | 47 } |
| 48 | 48 |
| 49 function testDatabaseOptionalParams() { | 49 function testDatabaseOptionalParams() { |
| 50 var db = db_manager.openDatabase('unit_test_db', ''); | 50 var db = db_manager.openDatabase('unit_test_db', ''); |
| 51 assert(db, 'Database should be a value'); | 51 assert(db, 'Database should be a value'); |
| 52 } | 52 } |
| 53 | 53 |
| 54 function testDatabaseVersionNull() { | 54 function testDatabaseVersionNull() { |
| 55 assertError(function() { | 55 assertError(function() { |
| 56 var db = db_manager.openDatabase('unit_test_db', null); | 56 var db = db_manager.openDatabase('unit_test_db', null); |
| 57 }, "Required argument 2 is missing."); | 57 }, "Required argument 2 is missing."); |
| 58 } | 58 } |
| 59 | 59 |
| 60 function testDatabaseVersionNonNull() { | 60 function testDatabaseVersionNonNull() { |
| 61 var db = db_manager.openDatabase('unit_test_db', '1.0', 'ignored_description', | 61 var db = db_manager.openDatabase('unit_test_db', '1.0', 'ignored_description', |
| 62 'ignored_estimated_size'); | 62 'ignored_estimated_size'); |
| 63 assert(db, 'Database should be a value'); | 63 assert(db, 'Database should be a value'); |
| 64 } | 64 } |
| 65 | 65 |
| 66 function testDatabaseApiSig() { | 66 function testDatabaseApiSig() { |
| 67 withDb(function(db) { | 67 withDb(function(db) { |
| 68 var method = 'Database2.transaction()'; | 68 var method = 'Database2.transaction()'; |
| 69 assert(db.transaction, method + ' should be present'); | 69 assert(db.transaction, method + ' should be present'); |
| 70 assertError(function() { | 70 assertError(function() { |
| 71 db.transaction(); | 71 db.transaction(); |
| 72 }, null, method + ' requires a callback'); | 72 }, null, method + ' requires a callback'); |
| 73 | 73 |
| 74 var method = 'Database2.synchronousTransaction()'; | 74 var method = 'Database2.synchronousTransaction()'; |
| 75 assert(db.synchronousTransaction, method + ' should be present'); | 75 assert(db.synchronousTransaction, method + ' should be present'); |
| 76 | 76 |
| 77 var method = 'Database2.changeVersion()'; | 77 var method = 'Database2.changeVersion()'; |
| 78 assert(db.changeVersion, method + ' should be present'); | 78 assert(db.changeVersion, method + ' should be present'); |
| 79 }); | 79 }); |
| 80 } | 80 } |
| 81 | 81 |
| 82 // TODO(dimitri.glazkov): Uncomment when functionality implemented | 82 function testDatabaseTransaction() { |
| 83 //function testDatabaseTransaction() { | 83 withDb(function(db) { |
| 84 // withDb(function(db) { | 84 var method = 'Database2.transaction()'; |
| 85 // var method = 'Database2.transaction()'; | 85 var inFlight; |
| 86 // var inFlight; | 86 var outOfOrder = 0; |
| 87 // var outOfOrder = 0; | 87 // this tests the fact that the transaction callback is called |
| 88 // // this tests the fact that the transaction callback is called | 88 // asynchronously and whether the callback is invoked in a proper sequence |
| 89 // // asynchronously and whether the callback is invoked in a proper sequence | 89 // if startAsync times out, the callback is not invoked at all |
| 90 // // if startAsync times out, the callback is not invoked at all | 90 db.transaction(function(tx) { |
| 91 // db.transaction(function(tx) { | 91 inFlight = true; |
| 92 // inFlight = true; | 92 outOfOrder--; |
| 93 // outOfOrder--; | 93 if (outOfOrder) { |
| 94 // if (outOfOrder) { | 94 assert(false, method + ' invokes callback out of sequence'); |
| 95 // assert(false, method + ' invokes callback out of sequence'); | 95 } |
| 96 // } | 96 completeAsync(); |
| 97 // completeAsync(); | 97 }); |
| 98 // }); | 98 outOfOrder++; |
| 99 // outOfOrder++; | 99 if (inFlight) { |
| 100 // if (inFlight) { | 100 assert(false, method + ' is not called asynchronously'); |
| 101 // assert(false, method + ' is not called asynchronously'); | 101 } |
| 102 // } | 102 startAsync(); |
| 103 // startAsync(); | 103 }); |
| 104 // }); | 104 } |
| 105 //} | |
| 106 | 105 |
| 107 function testDatabaseSynchronousTransaction() { | 106 function testDatabaseSynchronousTransaction() { |
| 108 withDb(function(db) { | 107 withDb(function(db) { |
| 109 var method = 'Database2.synchronousTransaction() '; | 108 var method = 'Database2.synchronousTransaction() '; |
| 110 var inFlight; | 109 var inFlight; |
| 111 var outOfOrder = 0; | 110 var outOfOrder = 0; |
| 112 // this tests the fact that the transaction callback is called | 111 // this tests the fact that the transaction callback is called |
| 113 // synchronously and whether the callback is invoked in a proper sequence | 112 // synchronously and whether the callback is invoked in a proper sequence |
| 114 db.synchronousTransaction(function(tx) { | 113 db.synchronousTransaction(function(tx) { |
| 115 inFlight = true; | 114 inFlight = true; |
| 116 if (outOfOrder) { | 115 if (outOfOrder) { |
| 117 assert(false, method + ' invokes callback out of sequence'); | 116 assert(false, method + ' invokes callback out of sequence'); |
| 118 } | 117 } |
| 119 }); | 118 }); |
| 120 outOfOrder++; | 119 outOfOrder++; |
| 121 if (!inFlight) { | 120 if (!inFlight) { |
| 122 assert(false, method + ' is not called synchronously'); | 121 assert(false, method + ' is not called synchronously'); |
| 123 } | 122 } |
| 124 | 123 |
| 125 // test statement execution | 124 // test statement execution |
| 126 db.synchronousTransaction(function(tx) { | 125 db.synchronousTransaction(function(tx) { |
| 127 var method = 'Database2Transaction.executeSql()'; | 126 var method = 'Database2Transaction.executeSql()'; |
| 128 var rs = tx.executeSql('SELECT * FROM Pages;'); | 127 var rs = tx.executeSql('SELECT * FROM Pages;'); |
| 129 assert(rs, method + ' should return a result set'); | 128 assert(rs, method + ' should return a result set'); |
| 130 }); | 129 }); |
| 131 }); | 130 }); |
| 132 } | 131 } |
| 133 | 132 |
| 134 function testStatementArguments() { | 133 function testStatementArguments() { |
| 135 withDb(function(db) { | 134 withDb(function(db) { |
| 136 db.synchronousTransaction(function(tx) { | 135 db.synchronousTransaction(function(tx) { |
| 137 // valid arguments | 136 // valid arguments |
| 138 tx.executeSql('SELECT * FROM Pages WHERE pageId = ? and version = ?', | 137 tx.executeSql('SELECT * FROM Pages WHERE pageId = ? and version = ?', |
| 139 [ 1972, '1.0.0.0' ]); | 138 [ 1972, '1.0.0.0' ]); |
| 140 // arguments with null | 139 // arguments with null |
| 141 tx.executeSql('SELECT * FROM Pages WHERE pageId = ? and version = ?', | 140 tx.executeSql('SELECT * FROM Pages WHERE pageId = ? and version = ?', |
| 142 [ 1972, null ]); | 141 [ 1972, null ]); |
| 143 // null arguments | 142 // null arguments |
| 144 tx.executeSql('SELECT * FROM Pages', null); | 143 tx.executeSql('SELECT * FROM Pages', null); |
| 145 // invalid arguments: function | 144 // invalid arguments: function |
| 146 assertError(function() { | 145 assertError(function() { |
| 147 tx.executeSql('SELECT * FROM Pages WHERE pageId = ? and version = ?', | 146 tx.executeSql('SELECT * FROM Pages WHERE pageId = ? and version = ?', |
| 148 [ function() {}, '1.0.0.0' ]); | 147 [ function() {}, '1.0.0.0' ]); |
| 149 }, null, 'Function arguments are not allowed'); | 148 }, null, 'Function arguments are not allowed'); |
| 150 // invalid arguments: object | 149 // invalid arguments: object |
| 151 assertError(function() { | 150 assertError(function() { |
| 152 tx.executeSql('SELECT * FROM Pages WHERE pageId = ? and version = ?', | 151 tx.executeSql('SELECT * FROM Pages WHERE pageId = ? and version = ?', |
| 153 [ { you: 'is wrong' }, '1.0.0.0' ]); | 152 [ { you: 'is wrong' }, '1.0.0.0' ]); |
| 154 }, null, 'Function arguments are not allowed'); | 153 }, null, 'Function arguments are not allowed'); |
| 155 }); | 154 }); |
| 156 }); | 155 }); |
| 157 } | 156 } |
| 158 | 157 |
| 159 // TODO(dimitri.glazkov): Add tests for type fidelity, large integers, and | |
| 160 // unsupported types. | |
| 161 // TODO(dimitri.glazkov): Rework the tests to create/drop test tables with setup | |
| 162 // and tear-down methods. | |
| 163 function testSyncExecution() { | |
| 164 withDb(function(db) { | |
| 165 db.synchronousTransaction(function(tx) { | |
| 166 var rs; | |
| 167 tx.executeSql('CREATE TABLE IF NOT EXISTS Pages(' + | |
| 168 ' pageId INTEGER PRIMARY KEY,' + | |
| 169 ' version TEXT)'); | |
| 170 var pageId; | |
| 171 rs = tx.executeSql('SELECT IFNULL(MAX(pageId) + 1, 1) AS max FROM Pages'); | |
| 172 assert(rs, 'Synchronous execute should return a result set'); | |
| 173 assert(rs.rows, 'result set must contain rows'); | |
| 174 assert(rs.rows.length, 'result set must contain one row'); | |
| 175 assert(rs.rows[0].max, | |
| 176 'result set must return one non-zero int value with the key of "max"'); | |
| 177 pageId = rs.rows[0].max; | |
| 178 tx.executeSql('INSERT INTO Pages(pageId, version) ' + | |
| 179 'VALUES(?,?)', [ pageId, 'test' ]); | |
| 180 var rs = tx.executeSql('SELECT * FROM Pages WHERE pageId = ?', | |
| 181 [ pageId ]); | |
| 182 assert(rs.rows[0].pageId == pageId, | |
| 183 'result set must return the last returned value'); | |
| 184 }); | |
| 185 }); | |
| 186 } | |
| 187 | |
| 188 function testSQLTransactionApiSig() { | 158 function testSQLTransactionApiSig() { |
| 189 withDb(function(db) { | 159 withDb(function(db) { |
| 190 var method = 'SQLTransaction.executeSql'; | 160 var method = 'SQLTransaction.executeSql'; |
| 191 db.transaction(function(tx) { | 161 db.transaction(function(tx) { |
| 192 assert(tx.executeSQL, method + ' should be present'); | 162 assert(tx.executeSQL, method + ' should be present'); |
| 193 }); | 163 }); |
| 194 }); | 164 }); |
| 195 } | 165 } |
| 196 | 166 |
| 197 function withDb(fn, version) { | 167 function withDb(fn, version) { |
| 198 db_manager && fn && fn.call( | 168 db_manager && fn && fn.call( |
| 199 this, db_manager.openDatabase('unit_test_db', version || '')); | 169 this, db_manager.openDatabase('unit_test_db', version || '')); |
| 200 } | 170 } |
| 171 |
| LEFT | RIGHT |