1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/storage/test/unit/test_connection_executeAsync.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,260 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/* 1.9 + * This file tests the functionality of mozIStorageConnection::executeAsync for 1.10 + * both mozIStorageStatement and mozIStorageAsyncStatement. 1.11 + */ 1.12 + 1.13 +const INTEGER = 1; 1.14 +const TEXT = "this is test text"; 1.15 +const REAL = 3.23; 1.16 +const BLOB = [1, 2]; 1.17 + 1.18 +function test_create_and_add() 1.19 +{ 1.20 + getOpenedDatabase().executeSimpleSQL( 1.21 + "CREATE TABLE test (" + 1.22 + "id INTEGER, " + 1.23 + "string TEXT, " + 1.24 + "number REAL, " + 1.25 + "nuller NULL, " + 1.26 + "blober BLOB" + 1.27 + ")" 1.28 + ); 1.29 + 1.30 + let stmts = []; 1.31 + stmts[0] = getOpenedDatabase().createStatement( 1.32 + "INSERT INTO test (id, string, number, nuller, blober) VALUES (?, ?, ?, ?, ?)" 1.33 + ); 1.34 + stmts[0].bindByIndex(0, INTEGER); 1.35 + stmts[0].bindByIndex(1, TEXT); 1.36 + stmts[0].bindByIndex(2, REAL); 1.37 + stmts[0].bindByIndex(3, null); 1.38 + stmts[0].bindBlobByIndex(4, BLOB, BLOB.length); 1.39 + stmts[1] = getOpenedDatabase().createAsyncStatement( 1.40 + "INSERT INTO test (string, number, nuller, blober) VALUES (?, ?, ?, ?)" 1.41 + ); 1.42 + stmts[1].bindByIndex(0, TEXT); 1.43 + stmts[1].bindByIndex(1, REAL); 1.44 + stmts[1].bindByIndex(2, null); 1.45 + stmts[1].bindBlobByIndex(3, BLOB, BLOB.length); 1.46 + 1.47 + getOpenedDatabase().executeAsync(stmts, stmts.length, { 1.48 + handleResult: function(aResultSet) 1.49 + { 1.50 + dump("handleResult("+aResultSet+")\n"); 1.51 + do_throw("unexpected results obtained!"); 1.52 + }, 1.53 + handleError: function(aError) 1.54 + { 1.55 + dump("handleError("+aError.result+")\n"); 1.56 + do_throw("unexpected error!"); 1.57 + }, 1.58 + handleCompletion: function(aReason) 1.59 + { 1.60 + dump("handleCompletion("+aReason+")\n"); 1.61 + do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason); 1.62 + 1.63 + // Check that the result is in the table 1.64 + let stmt = getOpenedDatabase().createStatement( 1.65 + "SELECT string, number, nuller, blober FROM test WHERE id = ?" 1.66 + ); 1.67 + stmt.bindByIndex(0, INTEGER); 1.68 + try { 1.69 + do_check_true(stmt.executeStep()); 1.70 + do_check_eq(TEXT, stmt.getString(0)); 1.71 + do_check_eq(REAL, stmt.getDouble(1)); 1.72 + do_check_true(stmt.getIsNull(2)); 1.73 + let count = { value: 0 }; 1.74 + let blob = { value: null }; 1.75 + stmt.getBlob(3, count, blob); 1.76 + do_check_eq(BLOB.length, count.value); 1.77 + for (let i = 0; i < BLOB.length; i++) 1.78 + do_check_eq(BLOB[i], blob.value[i]); 1.79 + } 1.80 + finally { 1.81 + stmt.finalize(); 1.82 + } 1.83 + 1.84 + // Make sure we have two rows in the table 1.85 + stmt = getOpenedDatabase().createStatement( 1.86 + "SELECT COUNT(1) FROM test" 1.87 + ); 1.88 + try { 1.89 + do_check_true(stmt.executeStep()); 1.90 + do_check_eq(2, stmt.getInt32(0)); 1.91 + } 1.92 + finally { 1.93 + stmt.finalize(); 1.94 + } 1.95 + 1.96 + // Run the next test. 1.97 + run_next_test(); 1.98 + } 1.99 + }); 1.100 + stmts[0].finalize(); 1.101 + stmts[1].finalize(); 1.102 +} 1.103 + 1.104 +function test_multiple_bindings_on_statements() 1.105 +{ 1.106 + // This tests to make sure that we pass all the statements multiply bound 1.107 + // parameters when we call executeAsync. 1.108 + const AMOUNT_TO_ADD = 5; 1.109 + const ITERATIONS = 5; 1.110 + 1.111 + let stmts = []; 1.112 + let db = getOpenedDatabase(); 1.113 + let sqlString = "INSERT INTO test (id, string, number, nuller, blober) " + 1.114 + "VALUES (:int, :text, :real, :null, :blob)"; 1.115 + // We run the same statement twice, and should insert 2 * AMOUNT_TO_ADD. 1.116 + for (let i = 0; i < ITERATIONS; i++) { 1.117 + // alternate the type of statement we create 1.118 + if (i % 2) 1.119 + stmts[i] = db.createStatement(sqlString); 1.120 + else 1.121 + stmts[i] = db.createAsyncStatement(sqlString); 1.122 + 1.123 + let params = stmts[i].newBindingParamsArray(); 1.124 + for (let j = 0; j < AMOUNT_TO_ADD; j++) { 1.125 + let bp = params.newBindingParams(); 1.126 + bp.bindByName("int", INTEGER); 1.127 + bp.bindByName("text", TEXT); 1.128 + bp.bindByName("real", REAL); 1.129 + bp.bindByName("null", null); 1.130 + bp.bindBlobByName("blob", BLOB, BLOB.length); 1.131 + params.addParams(bp); 1.132 + } 1.133 + stmts[i].bindParameters(params); 1.134 + } 1.135 + 1.136 + // Get our current number of rows in the table. 1.137 + let currentRows = 0; 1.138 + let countStmt = getOpenedDatabase().createStatement( 1.139 + "SELECT COUNT(1) AS count FROM test" 1.140 + ); 1.141 + try { 1.142 + do_check_true(countStmt.executeStep()); 1.143 + currentRows = countStmt.row.count; 1.144 + } 1.145 + finally { 1.146 + countStmt.reset(); 1.147 + } 1.148 + 1.149 + // Execute asynchronously. 1.150 + getOpenedDatabase().executeAsync(stmts, stmts.length, { 1.151 + handleResult: function(aResultSet) 1.152 + { 1.153 + do_throw("Unexpected call to handleResult!"); 1.154 + }, 1.155 + handleError: function(aError) 1.156 + { 1.157 + print("Error code " + aError.result + " with message '" + 1.158 + aError.message + "' returned."); 1.159 + do_throw("Unexpected error!"); 1.160 + }, 1.161 + handleCompletion: function(aReason) 1.162 + { 1.163 + print("handleCompletion(" + aReason + 1.164 + ") for test_multiple_bindings_on_statements"); 1.165 + do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason); 1.166 + 1.167 + // Check to make sure we added all of our rows. 1.168 + try { 1.169 + do_check_true(countStmt.executeStep()); 1.170 + do_check_eq(currentRows + (ITERATIONS * AMOUNT_TO_ADD), 1.171 + countStmt.row.count); 1.172 + } 1.173 + finally { 1.174 + countStmt.finalize(); 1.175 + } 1.176 + 1.177 + // Run the next test. 1.178 + run_next_test(); 1.179 + } 1.180 + }); 1.181 + stmts.forEach(function(stmt) stmt.finalize()); 1.182 +} 1.183 + 1.184 +function test_asyncClose_does_not_complete_before_statements() 1.185 +{ 1.186 + let stmt = createStatement("SELECT * FROM sqlite_master"); 1.187 + let executed = false; 1.188 + stmt.executeAsync({ 1.189 + handleResult: function(aResultSet) 1.190 + { 1.191 + }, 1.192 + handleError: function(aError) 1.193 + { 1.194 + print("Error code " + aError.result + " with message '" + 1.195 + aError.message + "' returned."); 1.196 + do_throw("Unexpected error!"); 1.197 + }, 1.198 + handleCompletion: function(aReason) 1.199 + { 1.200 + print("handleCompletion(" + aReason + 1.201 + ") for test_asyncClose_does_not_complete_before_statements"); 1.202 + do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason); 1.203 + executed = true; 1.204 + } 1.205 + }); 1.206 + stmt.finalize(); 1.207 + 1.208 + getOpenedDatabase().asyncClose(function() { 1.209 + // Ensure that the statement executed to completion. 1.210 + do_check_true(executed); 1.211 + 1.212 + // Reset gDBConn so that later tests will get a new connection object. 1.213 + gDBConn = null; 1.214 + run_next_test(); 1.215 + }); 1.216 +} 1.217 + 1.218 +function test_asyncClose_does_not_throw_no_callback() 1.219 +{ 1.220 + getOpenedDatabase().asyncClose(); 1.221 + 1.222 + // Reset gDBConn so that later tests will get a new connection object. 1.223 + gDBConn = null; 1.224 + run_next_test(); 1.225 +} 1.226 + 1.227 +function test_double_asyncClose_throws() 1.228 +{ 1.229 + let conn = getOpenedDatabase(); 1.230 + conn.asyncClose(); 1.231 + try { 1.232 + conn.asyncClose(); 1.233 + do_throw("should have thrown"); 1.234 + // There is a small race condition here, which can cause either of 1.235 + // Cr.NS_ERROR_NOT_INITIALIZED or Cr.NS_ERROR_UNEXPECTED to be thrown. 1.236 + } catch (e if "result" in e && e.result == Cr.NS_ERROR_NOT_INITIALIZED) { 1.237 + do_print("NS_ERROR_NOT_INITIALIZED"); 1.238 + } catch (e if "result" in e && e.result == Cr.NS_ERROR_UNEXPECTED) { 1.239 + do_print("NS_ERROR_UNEXPECTED"); 1.240 + } catch (e) { 1.241 + } 1.242 + 1.243 + // Reset gDBConn so that later tests will get a new connection object. 1.244 + gDBConn = null; 1.245 + run_next_test(); 1.246 +} 1.247 + 1.248 +//////////////////////////////////////////////////////////////////////////////// 1.249 +//// Test Runner 1.250 + 1.251 +[ 1.252 + test_create_and_add, 1.253 + test_multiple_bindings_on_statements, 1.254 + test_asyncClose_does_not_complete_before_statements, 1.255 + test_asyncClose_does_not_throw_no_callback, 1.256 + test_double_asyncClose_throws, 1.257 +].forEach(add_test); 1.258 + 1.259 +function run_test() 1.260 +{ 1.261 + cleanup(); 1.262 + run_next_test(); 1.263 +}