gecko/storage/test/unit/test_statement_executeAsync.js
Shawn Wilsher 6cbf5ad014 Bug 490085 - Add ability to bind multiple sets of parameters and execute asynchronously
Improves the asynchronous API by allowing multiple parameters to be bound before
executing it.  The statement is then executed with each set of parameters
asynchronously.
r=asuth
sr=vlad
2009-06-17 12:12:51 -07:00

1007 lines
27 KiB
JavaScript

/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Storage Test Code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// This file tests the functionality of mozIStorageStatement::executeAsync
const INTEGER = 1;
const TEXT = "this is test text";
const REAL = 3.23;
const BLOB = [1, 2];
function test_create_table()
{
// Ensure our table doesn't exists
do_check_false(getOpenedDatabase().tableExists("test"));
var stmt = getOpenedDatabase().createStatement(
"CREATE TABLE test (" +
"id INTEGER, " +
"string TEXT, " +
"number REAL, " +
"nuller NULL, " +
"blober BLOB" +
")"
);
stmt.executeAsync({
handleResult: function(aResultSet)
{
dump("handleResult("+aResultSet+");\n");
do_throw("unexpected results obtained!");
},
handleError: function(aError)
{
print("error code " + aerror.result + " with message '" +
aerror.message + "' returned.");
do_throw("unexpected error!");
},
handleCompletion: function(aReason)
{
print("handleCompletion(" + aReason + ") for test_create_table");
do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
// Check that the table has been created
do_check_true(getOpenedDatabase().tableExists("test"));
// Verify that it's created correctly (this will throw if it wasn't)
var stmt = getOpenedDatabase().createStatement(
"SELECT id, string, number, nuller, blober FROM test"
);
stmt.finalize();
// Run the next test.
run_next_test();
}
});
stmt.finalize();
}
function test_add_data()
{
var stmt = getOpenedDatabase().createStatement(
"INSERT INTO test (id, string, number, nuller, blober) " +
"VALUES (?, ?, ?, ?, ?)"
);
stmt.bindInt32Parameter(0, INTEGER);
stmt.bindStringParameter(1, TEXT);
stmt.bindDoubleParameter(2, REAL);
stmt.bindNullParameter(3);
stmt.bindBlobParameter(4, BLOB, BLOB.length);
stmt.executeAsync({
handleResult: function(aResultSet)
{
do_throw("unexpected results obtained!");
},
handleError: function(aError)
{
print("error code " + aerror.result + " with message '" +
aerror.message + "' returned.");
do_throw("unexpected error!");
},
handleCompletion: function(aReason)
{
print("handleCompletion(" + aReason + ") for test_add_data");
do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
// Check that the result is in the table
var stmt = getOpenedDatabase().createStatement(
"SELECT string, number, nuller, blober FROM test WHERE id = ?"
);
stmt.bindInt32Parameter(0, INTEGER);
try {
do_check_true(stmt.executeStep());
do_check_eq(TEXT, stmt.getString(0));
do_check_eq(REAL, stmt.getDouble(1));
do_check_true(stmt.getIsNull(2));
var count = { value: 0 };
var blob = { value: null };
stmt.getBlob(3, count, blob);
do_check_eq(BLOB.length, count.value);
for (var i = 0; i < BLOB.length; i++)
do_check_eq(BLOB[i], blob.value[i]);
}
finally {
stmt.reset();
stmt.finalize();
}
// Run the next test.
run_next_test();
}
});
stmt.finalize();
}
function test_get_data()
{
var stmt = getOpenedDatabase().createStatement(
"SELECT string, number, nuller, blober, id FROM test WHERE id = ?"
);
stmt.bindInt32Parameter(0, 1);
stmt.executeAsync({
resultObtained: false,
handleResult: function(aResultSet)
{
dump("handleResult("+aResultSet+");\n");
do_check_false(this.resultObtained);
this.resultObtained = true;
// Check that we have a result
var tuple = aResultSet.getNextRow();
do_check_neq(null, tuple);
// Check that it's what we expect
do_check_eq(tuple.getResultByName("string"), tuple.getResultByIndex(0));
do_check_eq(TEXT, tuple.getResultByName("string"));
do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_TEXT,
tuple.getTypeOfIndex(0));
do_check_eq(tuple.getResultByName("number"), tuple.getResultByIndex(1));
do_check_eq(REAL, tuple.getResultByName("number"));
do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_FLOAT,
tuple.getTypeOfIndex(1));
do_check_eq(tuple.getResultByName("nuller"), tuple.getResultByIndex(2));
do_check_eq(null, tuple.getResultByName("nuller"));
do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_NULL,
tuple.getTypeOfIndex(2));
var blobByName = tuple.getResultByName("blober");
do_check_eq(BLOB.length, blobByName.length);
var blobByIndex = tuple.getResultByIndex(3);
do_check_eq(BLOB.length, blobByIndex.length);
for (var i = 0; i < BLOB.length; i++) {
do_check_eq(BLOB[i], blobByName[i]);
do_check_eq(BLOB[i], blobByIndex[i]);
}
var count = { value: 0 };
var blob = { value: null };
tuple.getBlob(3, count, blob);
do_check_eq(BLOB.length, count.value);
for (var i = 0; i < BLOB.length; i++)
do_check_eq(BLOB[i], blob.value[i]);
do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_BLOB,
tuple.getTypeOfIndex(3));
do_check_eq(tuple.getResultByName("id"), tuple.getResultByIndex(4));
do_check_eq(INTEGER, tuple.getResultByName("id"));
do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_INTEGER,
tuple.getTypeOfIndex(4));
// check that we have no more results
tuple = aResultSet.getNextRow();
do_check_eq(null, tuple);
},
handleError: function(aError)
{
print("error code " + aerror.result + " with message '" +
aerror.message + "' returned.");
do_throw("unexpected error!");
},
handleCompletion: function(aReason)
{
print("handleCompletion(" + aReason + ") for test_get_data");
do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
do_check_true(this.resultObtained);
// Run the next test.
run_next_test();
}
});
stmt.finalize();
}
function test_tuple_out_of_bounds()
{
var stmt = getOpenedDatabase().createStatement(
"SELECT string FROM test"
);
stmt.executeAsync({
resultObtained: false,
handleResult: function(aResultSet)
{
dump("handleResult("+aResultSet+");\n");
do_check_false(this.resultObtained);
this.resultObtained = true;
// Check that we have a result
var tuple = aResultSet.getNextRow();
do_check_neq(null, tuple);
// Check all out of bounds - should throw
var methods = [
"getTypeOfIndex",
"getInt32",
"getInt64",
"getDouble",
"getUTF8String",
"getString",
"getIsNull",
];
for (var i in methods) {
try {
tuple[methods[i]](tuple.numEntries);
do_throw("did not throw :(");
}
catch (e) {
do_check_eq(Cr.NS_ERROR_ILLEGAL_VALUE, e.result);
}
}
// getBlob requires more args...
try {
var blob = { value: null };
var size = { value: 0 };
tuple.getBlob(tuple.numEntries, blob, size);
do_throw("did not throw :(");
}
catch (e) {
do_check_eq(Cr.NS_ERROR_ILLEGAL_VALUE, e.result);
}
},
handleError: function(aError)
{
print("Error code " + aError.result + " with message '" +
aError.message + "' returned.");
do_throw("unexpected error!");
},
handleCompletion: function(aReason)
{
print("handleCompletion(" + aReason +
") for test_tuple_out_of_bounds");
do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
do_check_true(this.resultObtained);
// Run the next test.
run_next_test();
}
});
stmt.finalize();
}
function test_no_listener_works_on_success()
{
var stmt = getOpenedDatabase().createStatement(
"DELETE FROM test WHERE id = ?"
);
stmt.bindInt32Parameter(0, 0);
stmt.executeAsync();
stmt.finalize();
// Run the next test.
run_next_test();
}
function test_no_listener_works_on_results()
{
var stmt = getOpenedDatabase().createStatement(
"SELECT ?"
);
stmt.bindInt32Parameter(0, 1);
stmt.executeAsync();
stmt.finalize();
// Run the next test.
run_next_test();
}
function test_no_listener_works_on_error()
{
// commit without a transaction will trigger an error
var stmt = getOpenedDatabase().createStatement(
"COMMIT"
);
stmt.executeAsync();
stmt.finalize();
// Run the next test.
run_next_test();
}
function test_partial_listener_works()
{
var stmt = getOpenedDatabase().createStatement(
"DELETE FROM test WHERE id = ?"
);
stmt.bindInt32Parameter(0, 0);
stmt.executeAsync({
handleResult: function(aResultSet)
{
}
});
stmt.executeAsync({
handleError: function(aError)
{
}
});
stmt.executeAsync({
handleCompletion: function(aReason)
{
}
});
stmt.finalize();
// Run the next test.
run_next_test();
}
function test_immediate_cancellation()
{
var stmt = getOpenedDatabase().createStatement(
"DELETE FROM test WHERE id = ?"
);
stmt.bindInt32Parameter(0, 0);
let reason = Ci.mozIStorageStatementCallback.REASON_CANCELED;
var pendingStatement = stmt.executeAsync({
handleResult: function(aResultSet)
{
do_throw("unexpected result!");
},
handleError: function(aError)
{
print("Error code " + aError.result + " with message '" +
aError.message + "' returned.");
do_throw("unexpected error!");
},
handleCompletion: function(aReason)
{
print("handleCompletion(" + aReason +
") for test_immediate_cancellation");
do_check_eq(reason, aReason);
// Run the next test.
run_next_test();
}
});
// Cancel immediately
if (!pendingStatement.cancel()) {
// It is possible that we finished before we canceled
reason = Ci.mozIStorageStatementCallback.REASON_FINISHED;
}
stmt.finalize();
}
function test_double_cancellation()
{
var stmt = getOpenedDatabase().createStatement(
"DELETE FROM test WHERE id = ?"
);
stmt.bindInt32Parameter(0, 0);
let reason = Ci.mozIStorageStatementCallback.REASON_CANCELED;
var pendingStatement = stmt.executeAsync({
handleResult: function(aResultSet)
{
do_throw("unexpected result!");
},
handleError: function(aError)
{
print("Error code " + aError.result + " with message '" +
aError.message + "' returned.");
do_throw("unexpected error!");
},
handleCompletion: function(aReason)
{
print("handleCompletion(" + aReason +
") for test_double_cancellation");
do_check_eq(reason, aReason);
// Run the next test.
run_next_test();
}
});
// Cancel immediately
if (!pendingStatement.cancel()) {
// It is possible that we finished before we canceled
reason = Ci.mozIStorageStatementCallback.REASON_FINISHED;
}
// And cancel again - expect an exception
try {
pendingStatement.cancel();
do_throw("function call should have thrown!");
}
catch (e) {
do_check_eq(Cr.NS_ERROR_UNEXPECTED, e.result);
}
stmt.finalize();
}
function test_double_execute()
{
var stmt = getOpenedDatabase().createStatement(
"SELECT * FROM test"
);
var listener = {
_timesCompleted: 0,
_hasResults: false,
handleResult: function(aResultSet)
{
do_check_false(this._hasResults);
this._hasResults = true;
},
handleError: function(aError)
{
print("Error code " + aError.result + " with message '" +
aError.message + "' returned.");
do_throw("unexpected error!");
},
handleCompletion: function(aReason)
{
print("handleCompletion(" + aReason +
") for test_double_execute (iteration " +
(this._timesCompleted + 1) + ")");
do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
do_check_true(this._hasResults);
this._hasResults = false;
this._timesCompleted++;
// Run the next test.
if (this._timesCompleted == 2)
run_next_test();
}
}
stmt.executeAsync(listener);
stmt.executeAsync(listener);
stmt.finalize();
}
function test_finalized_statement_does_not_crash()
{
var stmt = getOpenedDatabase().createStatement(
"SELECT * FROM TEST"
);
stmt.finalize();
// we are concerned about a crash here; an error is fine.
try {
stmt.executeAsync();
}
catch (ex) {}
// Run the next test.
run_next_test();
}
function test_bind_multiple_rows_by_index()
{
const AMOUNT_TO_ADD = 5;
var stmt = getOpenedDatabase().createStatement(
"INSERT INTO test (id, string, number, nuller, blober) " +
"VALUES (?, ?, ?, ?, ?)"
);
var array = stmt.newBindingParamsArray();
for (let i = 0; i < AMOUNT_TO_ADD; i++) {
let bp = array.newBindingParams();
bp.bindByIndex(0, INTEGER);
bp.bindByIndex(1, TEXT);
bp.bindByIndex(2, REAL);
bp.bindByIndex(3, null);
bp.bindBlobByIndex(4, BLOB, BLOB.length);
array.addParams(bp);
}
stmt.bindParameters(array);
// Get our current number of rows in the table.
var currentRows = 0;
var countStmt = getOpenedDatabase().createStatement(
"SELECT COUNT(1) AS count FROM test"
);
try {
do_check_true(countStmt.executeStep());
currentRows = countStmt.row.count;
print("We have " + currentRows + " rows in test_bind_multiple_rows_by_index");
}
finally {
countStmt.reset();
}
// Execute asynchronously.
stmt.executeAsync({
handleResult: function(aResultSet)
{
do_throw("Unexpected call to handleResult!");
},
handleError: function(aError)
{
print("Error code " + aError.result + " with message '" +
aError.message + "' returned.");
do_throw("unexpected error!");
},
handleCompletion: function(aReason)
{
print("handleCompletion(" + aReason +
") for test_bind_multiple_rows_by_index");
do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
// Check to make sure we added all of our rows.
try {
do_check_true(countStmt.executeStep());
print("We now have " + currentRows +
" rows in test_bind_multiple_rows_by_index");
do_check_eq(currentRows + AMOUNT_TO_ADD, countStmt.row.count);
}
finally {
countStmt.finalize();
}
// Run the next test.
run_next_test();
}
});
stmt.finalize();
}
function test_bind_multiple_rows_by_name()
{
const AMOUNT_TO_ADD = 5;
var stmt = getOpenedDatabase().createStatement(
"INSERT INTO test (id, string, number, nuller, blober) " +
"VALUES (:int, :text, :real, :null, :blob)"
);
var array = stmt.newBindingParamsArray();
for (let i = 0; i < AMOUNT_TO_ADD; i++) {
let bp = array.newBindingParams();
bp.bindByName("int", INTEGER);
bp.bindByName("text", TEXT);
bp.bindByName("real", REAL);
bp.bindByName("null", null);
bp.bindBlobByName("blob", BLOB, BLOB.length);
array.addParams(bp);
}
stmt.bindParameters(array);
// Get our current number of rows in the table.
var currentRows = 0;
var countStmt = getOpenedDatabase().createStatement(
"SELECT COUNT(1) AS count FROM test"
);
try {
do_check_true(countStmt.executeStep());
currentRows = countStmt.row.count;
print("We have " + currentRows + " rows in test_bind_multiple_rows_by_name");
}
finally {
countStmt.reset();
}
// Execute asynchronously.
stmt.executeAsync({
handleResult: function(aResultSet)
{
do_throw("Unexpected call to handleResult!");
},
handleError: function(aError)
{
print("Error code " + aError.result + " with message '" +
aError.message + "' returned.");
do_throw("unexpected error!");
},
handleCompletion: function(aReason)
{
print("handleCompletion(" + aReason +
") for test_bind_multiple_rows_by_name");
do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
// Check to make sure we added all of our rows.
try {
do_check_true(countStmt.executeStep());
print("We now have " + currentRows +
" rows in test_bind_multiple_rows_by_name");
do_check_eq(currentRows + AMOUNT_TO_ADD, countStmt.row.count);
}
finally {
countStmt.finalize();
}
// Run the next test.
run_next_test();
}
});
stmt.finalize();
}
function test_bind_out_of_bounds()
{
let stmt = getOpenedDatabase().createStatement(
"INSERT INTO test (id) " +
"VALUES (?)"
);
let array = stmt.newBindingParamsArray();
let bp = array.newBindingParams();
// Check variant binding.
let exceptionCaught = false;
try {
bp.bindByIndex(1, INTEGER);
do_throw("we should have an exception!");
}
catch(e) {
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
exceptionCaught = true;
}
do_check_true(exceptionCaught);
// Check blob binding.
exceptionCaught = false;
try {
bp.bindBlobByIndex(1, BLOB, BLOB.length);
do_throw("we should have an exception!");
}
catch(e) {
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
exceptionCaught = true;
}
do_check_true(exceptionCaught);
stmt.finalize();
// Run the next test.
run_next_test();
}
function test_bind_no_such_name()
{
let stmt = getOpenedDatabase().createStatement(
"INSERT INTO test (id) " +
"VALUES (:foo)"
);
let array = stmt.newBindingParamsArray();
let bp = array.newBindingParams();
// Check variant binding.
let exceptionCaught = false;
try {
bp.bindByName("doesnotexist", INTEGER);
do_throw("we should have an exception!");
}
catch(e) {
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
exceptionCaught = true;
}
do_check_true(exceptionCaught);
// Check blob binding.
exceptionCaught = false;
try {
bp.bindBlobByName("doesnotexist", BLOB, BLOB.length);
do_throw("we should have an exception!");
}
catch(e) {
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
exceptionCaught = true;
}
do_check_true(exceptionCaught);
stmt.finalize();
// Run the next test.
run_next_test();
}
function test_bind_bogus_type_by_index()
{
// We try to bind a JS Object here that should fail to bind.
let stmt = getOpenedDatabase().createStatement(
"INSERT INTO test (blober) " +
"VALUES (?)"
);
// We get an error after calling executeAsync, not when we bind.
let array = stmt.newBindingParamsArray();
let bp = array.newBindingParams();
bp.bindByIndex(0, run_test);
array.addParams(bp);
stmt.bindParameters(array);
stmt.executeAsync({
_errorObtained: false,
handleResult: function(aResultSet)
{
do_throw("Unexpected call to handleResult!");
},
handleError: function(aError)
{
print("Error code " + aError.result + " with message '" +
aError.message + "' returned.");
this._errorObtained = true;
do_check_eq(aError.result, Ci.mozIStorageError.MISMATCH);
},
handleCompletion: function(aReason)
{
print("handleCompletion(" + aReason +
") for test_bind_bogus_type_by_index");
do_check_eq(Ci.mozIStorageStatementCallback.REASON_ERROR, aReason);
do_check_true(this._errorObtained);
// Run the next test.
run_next_test();
}
});
stmt.finalize();
}
function test_bind_bogus_type_by_name()
{
// We try to bind a JS Object here that should fail to bind.
let stmt = getOpenedDatabase().createStatement(
"INSERT INTO test (blober) " +
"VALUES (:blob)"
);
// We get an error after calling executeAsync, not when we bind.
let array = stmt.newBindingParamsArray();
let bp = array.newBindingParams();
bp.bindByName("blob", run_test);
array.addParams(bp);
stmt.bindParameters(array);
stmt.executeAsync({
_errorObtained: false,
handleResult: function(aResultSet)
{
do_throw("Unexpected call to handleResult!");
},
handleError: function(aError)
{
print("Error code " + aError.result + " with message '" +
aError.message + "' returned.");
this._errorObtained = true;
do_check_eq(aError.result, Ci.mozIStorageError.MISMATCH);
},
handleCompletion: function(aReason)
{
print("handleCompletion(" + aReason +
") for test_bind_bogus_type_by_name");
do_check_eq(Ci.mozIStorageStatementCallback.REASON_ERROR, aReason);
do_check_true(this._errorObtained);
// Run the next test.
run_next_test();
}
});
stmt.finalize();
}
function test_bind_params_already_locked()
{
let stmt = getOpenedDatabase().createStatement(
"INSERT INTO test (id) " +
"VALUES (:int)"
);
let array = stmt.newBindingParamsArray();
let bp = array.newBindingParams();
bp.bindByName("int", INTEGER);
array.addParams(bp);
// We should get an error after we call addParams and try to bind again.
let exceptionCaught = false;
try {
bp.bindByName("int", INTEGER);
do_throw("we should have an exception!");
}
catch(e) {
do_check_eq(e.result, Cr.NS_ERROR_UNEXPECTED);
exceptionCaught = true;
}
do_check_true(exceptionCaught);
// Run the next test.
run_next_test();
}
function test_bind_params_array_already_locked()
{
let stmt = getOpenedDatabase().createStatement(
"INSERT INTO test (id) " +
"VALUES (:int)"
);
let array = stmt.newBindingParamsArray();
let bp1 = array.newBindingParams();
bp1.bindByName("int", INTEGER);
array.addParams(bp1);
let bp2 = array.newBindingParams();
stmt.bindParameters(array);
bp2.bindByName("int", INTEGER);
// We should get an error after we have bound the array to the statement.
let exceptionCaught = false;
try {
array.addParams(bp2);
do_throw("we should have an exception!");
}
catch(e) {
do_check_eq(e.result, Cr.NS_ERROR_UNEXPECTED);
exceptionCaught = true;
}
do_check_true(exceptionCaught);
// Run the next test.
run_next_test();
}
function test_no_binding_params_from_locked_array()
{
let stmt = getOpenedDatabase().createStatement(
"INSERT INTO test (id) " +
"VALUES (:int)"
);
let array = stmt.newBindingParamsArray();
let bp = array.newBindingParams();
bp.bindByName("int", INTEGER);
array.addParams(bp);
stmt.bindParameters(array);
// We should not be able to get a new BindingParams object after we have bound
// to the statement.
let exceptionCaught = false;
try {
bp = array.newBindingParams();
do_throw("we should have an exception!");
}
catch(e) {
do_check_eq(e.result, Cr.NS_ERROR_UNEXPECTED);
exceptionCaught = true;
}
do_check_true(exceptionCaught);
// Run the next test.
run_next_test();
}
function test_not_right_owning_array()
{
let stmt = getOpenedDatabase().createStatement(
"INSERT INTO test (id) " +
"VALUES (:int)"
);
let array1 = stmt.newBindingParamsArray();
let array2 = stmt.newBindingParamsArray();
let bp = array1.newBindingParams();
bp.bindByName("int", INTEGER);
// We should not be able to add bp to array2 since it was created from array1.
let exceptionCaught = false;
try {
array2.addParams(bp);
do_throw("we should have an exception!");
}
catch(e) {
do_check_eq(e.result, Cr.NS_ERROR_UNEXPECTED);
exceptionCaught = true;
}
do_check_true(exceptionCaught);
// Run the next test.
run_next_test();
}
function test_not_right_owning_statement()
{
let stmt1 = getOpenedDatabase().createStatement(
"INSERT INTO test (id) " +
"VALUES (:int)"
);
let stmt2 = getOpenedDatabase().createStatement(
"INSERT INTO test (id) " +
"VALUES (:int)"
);
let array1 = stmt1.newBindingParamsArray();
let array2 = stmt2.newBindingParamsArray();
let bp = array1.newBindingParams();
bp.bindByName("int", INTEGER);
array1.addParams(bp);
// We should not be able to bind array1 since it was created from stmt1.
let exceptionCaught = false;
try {
stmt2.bindParameters(array1);
do_throw("we should have an exception!");
}
catch(e) {
do_check_eq(e.result, Cr.NS_ERROR_UNEXPECTED);
exceptionCaught = true;
}
do_check_true(exceptionCaught);
// Run the next test.
run_next_test();
}
////////////////////////////////////////////////////////////////////////////////
//// Test Runner
var tests =
[
test_create_table,
test_add_data,
test_get_data,
test_tuple_out_of_bounds,
test_no_listener_works_on_success,
test_no_listener_works_on_results,
test_no_listener_works_on_error,
test_partial_listener_works,
test_immediate_cancellation,
test_double_cancellation,
test_double_execute,
test_finalized_statement_does_not_crash,
test_bind_multiple_rows_by_index,
test_bind_multiple_rows_by_name,
test_bind_out_of_bounds,
test_bind_no_such_name,
test_bind_bogus_type_by_index,
test_bind_bogus_type_by_name,
test_bind_params_already_locked,
test_bind_params_array_already_locked,
test_no_binding_params_from_locked_array,
test_not_right_owning_array,
test_not_right_owning_statement,
];
let index = 0;
function run_next_test()
{
if (index < tests.length) {
do_test_pending();
print("Running the next test: " + tests[index].name);
tests[index++]();
}
do_test_finished();
}
function run_test()
{
cleanup();
do_test_pending();
run_next_test();
}