增加晶全app静态页面
This commit is contained in:
45
node_modules/cordova-sqlite-storage/spec/www/index.html
generated
vendored
Normal file
45
node_modules/cordova-sqlite-storage/spec/www/index.html
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="user-scalable=no" />
|
||||
|
||||
<title>SQLitePlugin Jasmine Spec Runner</title>
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="lib/jasmine-2.5.2/jasmine_favicon.png">
|
||||
<link rel="stylesheet" href="lib/jasmine-2.5.2/jasmine.css">
|
||||
|
||||
<script src="lib/jasmine-2.5.2/jasmine.js"></script>
|
||||
<script src="lib/jasmine-2.5.2/jasmine-html.js"></script>
|
||||
<script src="lib/jasmine-2.5.2/boot.js"></script>
|
||||
|
||||
<!-- [Cordova] source file(s): -->
|
||||
<script src="cordova.js"></script>
|
||||
|
||||
<!-- browser startup test: -->
|
||||
<script src="spec/browser-check-startup.js"></script>
|
||||
|
||||
<!-- other spec file(s): -->
|
||||
<script src="spec/self-test.js"></script>
|
||||
<script src="spec/sqlite-version-test.js"></script>
|
||||
<script src="spec/db-tx-string-test.js"></script>
|
||||
<script src="spec/db-tx-sql-select-value-test.js"></script>
|
||||
<script src="spec/basic-db-tx-sql-storage-results.js"></script>
|
||||
<script src="spec/db-sql-operations-test.js"></script>
|
||||
<script src="spec/sql-batch-test.js"></script>
|
||||
<script src="spec/db-tx-sql-features-test.js"></script>
|
||||
<script src="spec/regexp-test.js"></script>
|
||||
<script src="spec/db-simultaneous-tx-access-test.js"></script>
|
||||
<script src="spec/db-tx-multiple-update-test.js"></script>
|
||||
<script src="spec/tx-semantics-test.js"></script>
|
||||
<script src="spec/db-tx-value-bindings-test.js"></script> <!-- stored [INSERT] value binding tests -->
|
||||
<script src="spec/db-tx-error-handling-test.js"></script>
|
||||
<script src="spec/db-tx-error-mapping-test.js"></script>
|
||||
<script src="spec/ext-tx-blob-test.js"></script> <!-- Blob object value test(s) -->
|
||||
<script src="spec/db-open-close-delete-test.js"></script> <!-- extended db open/close/delete testing -->
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html> <!-- vim: set expandtab : -->
|
130
node_modules/cordova-sqlite-storage/spec/www/lib/jasmine-2.5.2/boot.js
generated
vendored
Normal file
130
node_modules/cordova-sqlite-storage/spec/www/lib/jasmine-2.5.2/boot.js
generated
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
/**
|
||||
Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
|
||||
|
||||
If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms.
|
||||
|
||||
The location of `boot.js` can be specified and/or overridden in `jasmine.yml`.
|
||||
|
||||
[jasmine-gem]: http://github.com/pivotal/jasmine-gem
|
||||
*/
|
||||
|
||||
(function() {
|
||||
|
||||
/**
|
||||
* ## Require & Instantiate
|
||||
*
|
||||
* Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
|
||||
*/
|
||||
window.jasmine = jasmineRequire.core(jasmineRequire);
|
||||
|
||||
/**
|
||||
* Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.
|
||||
*/
|
||||
jasmineRequire.html(jasmine);
|
||||
|
||||
/**
|
||||
* Create the Jasmine environment. This is used to run all specs in a project.
|
||||
*/
|
||||
var env = jasmine.getEnv();
|
||||
|
||||
/**
|
||||
* ## The Global Interface
|
||||
*
|
||||
* Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
|
||||
*/
|
||||
var jasmineInterface = jasmineRequire.interface(jasmine, env);
|
||||
|
||||
/**
|
||||
* Add all of the Jasmine global/public interface to the global scope, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
|
||||
*/
|
||||
extend(window, jasmineInterface);
|
||||
|
||||
/**
|
||||
* ## Runner Parameters
|
||||
*
|
||||
* More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface.
|
||||
*/
|
||||
|
||||
var queryString = new jasmine.QueryString({
|
||||
getWindowLocation: function() { return window.location; }
|
||||
});
|
||||
|
||||
var catchingExceptions = queryString.getParam("catch");
|
||||
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
|
||||
|
||||
var throwingExpectationFailures = queryString.getParam("throwFailures");
|
||||
env.throwOnExpectationFailure(throwingExpectationFailures);
|
||||
|
||||
var random = queryString.getParam("random");
|
||||
env.randomizeTests(random);
|
||||
|
||||
var seed = queryString.getParam("seed");
|
||||
if (seed) {
|
||||
env.seed(seed);
|
||||
}
|
||||
|
||||
/**
|
||||
* ## Reporters
|
||||
* The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
|
||||
*/
|
||||
var htmlReporter = new jasmine.HtmlReporter({
|
||||
env: env,
|
||||
onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); },
|
||||
onThrowExpectationsClick: function() { queryString.navigateWithNewParam("throwFailures", !env.throwingExpectationFailures()); },
|
||||
onRandomClick: function() { queryString.navigateWithNewParam("random", !env.randomTests()); },
|
||||
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
|
||||
getContainer: function() { return document.body; },
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
|
||||
timer: new jasmine.Timer()
|
||||
});
|
||||
|
||||
/**
|
||||
* The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript.
|
||||
*/
|
||||
env.addReporter(jasmineInterface.jsApiReporter);
|
||||
env.addReporter(htmlReporter);
|
||||
|
||||
/**
|
||||
* Filter which specs will be run by matching the start of the full name against the `spec` query param.
|
||||
*/
|
||||
var specFilter = new jasmine.HtmlSpecFilter({
|
||||
filterString: function() { return queryString.getParam("spec"); }
|
||||
});
|
||||
|
||||
env.specFilter = function(spec) {
|
||||
return specFilter.matches(spec.getFullName());
|
||||
};
|
||||
|
||||
/**
|
||||
* Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack.
|
||||
*/
|
||||
window.setTimeout = window.setTimeout;
|
||||
window.setInterval = window.setInterval;
|
||||
window.clearTimeout = window.clearTimeout;
|
||||
window.clearInterval = window.clearInterval;
|
||||
|
||||
/**
|
||||
* ## Execution
|
||||
*
|
||||
* Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded.
|
||||
*/
|
||||
var currentWindowOnload = window.onload;
|
||||
|
||||
window.onload = function() {
|
||||
if (currentWindowOnload) {
|
||||
currentWindowOnload();
|
||||
}
|
||||
htmlReporter.initialize();
|
||||
env.execute();
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function for readability above.
|
||||
*/
|
||||
function extend(destination, source) {
|
||||
for (var property in source) destination[property] = source[property];
|
||||
return destination;
|
||||
}
|
||||
|
||||
}());
|
190
node_modules/cordova-sqlite-storage/spec/www/lib/jasmine-2.5.2/console.js
generated
vendored
Normal file
190
node_modules/cordova-sqlite-storage/spec/www/lib/jasmine-2.5.2/console.js
generated
vendored
Normal file
@ -0,0 +1,190 @@
|
||||
/*
|
||||
Copyright (c) 2008-2016 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
function getJasmineRequireObj() {
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
return exports;
|
||||
} else {
|
||||
window.jasmineRequire = window.jasmineRequire || {};
|
||||
return window.jasmineRequire;
|
||||
}
|
||||
}
|
||||
|
||||
getJasmineRequireObj().console = function(jRequire, j$) {
|
||||
j$.ConsoleReporter = jRequire.ConsoleReporter();
|
||||
};
|
||||
|
||||
getJasmineRequireObj().ConsoleReporter = function() {
|
||||
|
||||
var noopTimer = {
|
||||
start: function(){},
|
||||
elapsed: function(){ return 0; }
|
||||
};
|
||||
|
||||
function ConsoleReporter(options) {
|
||||
var print = options.print,
|
||||
showColors = options.showColors || false,
|
||||
onComplete = options.onComplete || function() {},
|
||||
timer = options.timer || noopTimer,
|
||||
specCount,
|
||||
failureCount,
|
||||
failedSpecs = [],
|
||||
pendingCount,
|
||||
ansi = {
|
||||
green: '\x1B[32m',
|
||||
red: '\x1B[31m',
|
||||
yellow: '\x1B[33m',
|
||||
none: '\x1B[0m'
|
||||
},
|
||||
failedSuites = [];
|
||||
|
||||
print('ConsoleReporter is deprecated and will be removed in a future version.');
|
||||
|
||||
this.jasmineStarted = function() {
|
||||
specCount = 0;
|
||||
failureCount = 0;
|
||||
pendingCount = 0;
|
||||
print('Started');
|
||||
printNewline();
|
||||
timer.start();
|
||||
};
|
||||
|
||||
this.jasmineDone = function() {
|
||||
printNewline();
|
||||
for (var i = 0; i < failedSpecs.length; i++) {
|
||||
specFailureDetails(failedSpecs[i]);
|
||||
}
|
||||
|
||||
if(specCount > 0) {
|
||||
printNewline();
|
||||
|
||||
var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' +
|
||||
failureCount + ' ' + plural('failure', failureCount);
|
||||
|
||||
if (pendingCount) {
|
||||
specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount);
|
||||
}
|
||||
|
||||
print(specCounts);
|
||||
} else {
|
||||
print('No specs found');
|
||||
}
|
||||
|
||||
printNewline();
|
||||
var seconds = timer.elapsed() / 1000;
|
||||
print('Finished in ' + seconds + ' ' + plural('second', seconds));
|
||||
printNewline();
|
||||
|
||||
for(i = 0; i < failedSuites.length; i++) {
|
||||
suiteFailureDetails(failedSuites[i]);
|
||||
}
|
||||
|
||||
onComplete(failureCount === 0);
|
||||
};
|
||||
|
||||
this.specDone = function(result) {
|
||||
specCount++;
|
||||
|
||||
if (result.status == 'pending') {
|
||||
pendingCount++;
|
||||
print(colored('yellow', '*'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.status == 'passed') {
|
||||
print(colored('green', '.'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.status == 'failed') {
|
||||
failureCount++;
|
||||
failedSpecs.push(result);
|
||||
print(colored('red', 'F'));
|
||||
}
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
if (result.failedExpectations && result.failedExpectations.length > 0) {
|
||||
failureCount++;
|
||||
failedSuites.push(result);
|
||||
}
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function printNewline() {
|
||||
print('\n');
|
||||
}
|
||||
|
||||
function colored(color, str) {
|
||||
return showColors ? (ansi[color] + str + ansi.none) : str;
|
||||
}
|
||||
|
||||
function plural(str, count) {
|
||||
return count == 1 ? str : str + 's';
|
||||
}
|
||||
|
||||
function repeat(thing, times) {
|
||||
var arr = [];
|
||||
for (var i = 0; i < times; i++) {
|
||||
arr.push(thing);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
function indent(str, spaces) {
|
||||
var lines = (str || '').split('\n');
|
||||
var newArr = [];
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
newArr.push(repeat(' ', spaces).join('') + lines[i]);
|
||||
}
|
||||
return newArr.join('\n');
|
||||
}
|
||||
|
||||
function specFailureDetails(result) {
|
||||
printNewline();
|
||||
print(result.fullName);
|
||||
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
var failedExpectation = result.failedExpectations[i];
|
||||
printNewline();
|
||||
print(indent(failedExpectation.message, 2));
|
||||
print(indent(failedExpectation.stack, 2));
|
||||
}
|
||||
|
||||
printNewline();
|
||||
}
|
||||
|
||||
function suiteFailureDetails(result) {
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
printNewline();
|
||||
print(colored('red', 'An error was thrown in an afterAll'));
|
||||
printNewline();
|
||||
print(colored('red', 'AfterAll ' + result.failedExpectations[i].message));
|
||||
|
||||
}
|
||||
printNewline();
|
||||
}
|
||||
}
|
||||
|
||||
return ConsoleReporter;
|
||||
};
|
481
node_modules/cordova-sqlite-storage/spec/www/lib/jasmine-2.5.2/jasmine-html.js
generated
vendored
Normal file
481
node_modules/cordova-sqlite-storage/spec/www/lib/jasmine-2.5.2/jasmine-html.js
generated
vendored
Normal file
@ -0,0 +1,481 @@
|
||||
/*
|
||||
Copyright (c) 2008-2016 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
jasmineRequire.html = function(j$) {
|
||||
j$.ResultsNode = jasmineRequire.ResultsNode();
|
||||
j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);
|
||||
j$.QueryString = jasmineRequire.QueryString();
|
||||
j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter();
|
||||
};
|
||||
|
||||
jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
var noopTimer = {
|
||||
start: function() {},
|
||||
elapsed: function() { return 0; }
|
||||
};
|
||||
|
||||
function HtmlReporter(options) {
|
||||
var env = options.env || {},
|
||||
getContainer = options.getContainer,
|
||||
createElement = options.createElement,
|
||||
createTextNode = options.createTextNode,
|
||||
onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},
|
||||
onThrowExpectationsClick = options.onThrowExpectationsClick || function() {},
|
||||
onRandomClick = options.onRandomClick || function() {},
|
||||
addToExistingQueryString = options.addToExistingQueryString || defaultQueryString,
|
||||
timer = options.timer || noopTimer,
|
||||
results = [],
|
||||
specsExecuted = 0,
|
||||
failureCount = 0,
|
||||
pendingSpecCount = 0,
|
||||
htmlReporterMain,
|
||||
symbols,
|
||||
failedSuites = [];
|
||||
|
||||
this.initialize = function() {
|
||||
clearPrior();
|
||||
htmlReporterMain = createDom('div', {className: 'jasmine_html-reporter'},
|
||||
createDom('div', {className: 'jasmine-banner'},
|
||||
createDom('a', {className: 'jasmine-title', href: 'http://jasmine.github.io/', target: '_blank'}),
|
||||
createDom('span', {className: 'jasmine-version'}, j$.version)
|
||||
),
|
||||
createDom('ul', {className: 'jasmine-symbol-summary'}),
|
||||
createDom('div', {className: 'jasmine-alert'}),
|
||||
createDom('div', {className: 'jasmine-results'},
|
||||
createDom('div', {className: 'jasmine-failures'})
|
||||
)
|
||||
);
|
||||
getContainer().appendChild(htmlReporterMain);
|
||||
};
|
||||
|
||||
var totalSpecsDefined;
|
||||
this.jasmineStarted = function(options) {
|
||||
totalSpecsDefined = options.totalSpecsDefined || 0;
|
||||
timer.start();
|
||||
};
|
||||
|
||||
var summary = createDom('div', {className: 'jasmine-summary'});
|
||||
|
||||
var topResults = new j$.ResultsNode({}, '', null),
|
||||
currentParent = topResults;
|
||||
|
||||
this.suiteStarted = function(result) {
|
||||
currentParent.addChild(result, 'suite');
|
||||
currentParent = currentParent.last();
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
if (result.status == 'failed') {
|
||||
failedSuites.push(result);
|
||||
}
|
||||
|
||||
if (currentParent == topResults) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentParent = currentParent.parent;
|
||||
};
|
||||
|
||||
this.specStarted = function(result) {
|
||||
currentParent.addChild(result, 'spec');
|
||||
};
|
||||
|
||||
var failures = [];
|
||||
this.specDone = function(result) {
|
||||
if(noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') {
|
||||
console.error('Spec \'' + result.fullName + '\' has no expectations.');
|
||||
}
|
||||
|
||||
if (result.status != 'disabled') {
|
||||
specsExecuted++;
|
||||
}
|
||||
|
||||
if (!symbols){
|
||||
symbols = find('.jasmine-symbol-summary');
|
||||
}
|
||||
|
||||
symbols.appendChild(createDom('li', {
|
||||
className: noExpectations(result) ? 'jasmine-empty' : 'jasmine-' + result.status,
|
||||
id: 'spec_' + result.id,
|
||||
title: result.fullName
|
||||
}
|
||||
));
|
||||
|
||||
if (result.status == 'failed') {
|
||||
failureCount++;
|
||||
|
||||
var failure =
|
||||
createDom('div', {className: 'jasmine-spec-detail jasmine-failed'},
|
||||
createDom('div', {className: 'jasmine-description'},
|
||||
createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName)
|
||||
),
|
||||
createDom('div', {className: 'jasmine-messages'})
|
||||
);
|
||||
var messages = failure.childNodes[1];
|
||||
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
var expectation = result.failedExpectations[i];
|
||||
messages.appendChild(createDom('div', {className: 'jasmine-result-message'}, expectation.message));
|
||||
messages.appendChild(createDom('div', {className: 'jasmine-stack-trace'}, expectation.stack));
|
||||
}
|
||||
|
||||
failures.push(failure);
|
||||
}
|
||||
|
||||
if (result.status == 'pending') {
|
||||
pendingSpecCount++;
|
||||
}
|
||||
};
|
||||
|
||||
this.jasmineDone = function(doneResult) {
|
||||
var banner = find('.jasmine-banner');
|
||||
var alert = find('.jasmine-alert');
|
||||
var order = doneResult && doneResult.order;
|
||||
alert.appendChild(createDom('span', {className: 'jasmine-duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
|
||||
|
||||
banner.appendChild(
|
||||
createDom('div', { className: 'jasmine-run-options' },
|
||||
createDom('span', { className: 'jasmine-trigger' }, 'Options'),
|
||||
createDom('div', { className: 'jasmine-payload' },
|
||||
createDom('div', { className: 'jasmine-exceptions' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-raise',
|
||||
id: 'jasmine-raise-exceptions',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-raise-exceptions' }, 'raise exceptions')),
|
||||
createDom('div', { className: 'jasmine-throw-failures' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-throw',
|
||||
id: 'jasmine-throw-failures',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-throw-failures' }, 'stop spec on expectation failure')),
|
||||
createDom('div', { className: 'jasmine-random-order' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-random',
|
||||
id: 'jasmine-random-order',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-random-order' }, 'run tests in random order'))
|
||||
)
|
||||
));
|
||||
|
||||
var raiseCheckbox = find('#jasmine-raise-exceptions');
|
||||
|
||||
raiseCheckbox.checked = !env.catchingExceptions();
|
||||
raiseCheckbox.onclick = onRaiseExceptionsClick;
|
||||
|
||||
var throwCheckbox = find('#jasmine-throw-failures');
|
||||
throwCheckbox.checked = env.throwingExpectationFailures();
|
||||
throwCheckbox.onclick = onThrowExpectationsClick;
|
||||
|
||||
var randomCheckbox = find('#jasmine-random-order');
|
||||
randomCheckbox.checked = env.randomTests();
|
||||
randomCheckbox.onclick = onRandomClick;
|
||||
|
||||
var optionsMenu = find('.jasmine-run-options'),
|
||||
optionsTrigger = optionsMenu.querySelector('.jasmine-trigger'),
|
||||
optionsPayload = optionsMenu.querySelector('.jasmine-payload'),
|
||||
isOpen = /\bjasmine-open\b/;
|
||||
|
||||
optionsTrigger.onclick = function() {
|
||||
if (isOpen.test(optionsPayload.className)) {
|
||||
optionsPayload.className = optionsPayload.className.replace(isOpen, '');
|
||||
} else {
|
||||
optionsPayload.className += ' jasmine-open';
|
||||
}
|
||||
};
|
||||
|
||||
if (specsExecuted < totalSpecsDefined) {
|
||||
var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
|
||||
var skippedLink = order && order.random ? '?random=true' : '?';
|
||||
alert.appendChild(
|
||||
createDom('span', {className: 'jasmine-bar jasmine-skipped'},
|
||||
createDom('a', {href: skippedLink, title: 'Run all specs'}, skippedMessage)
|
||||
)
|
||||
);
|
||||
}
|
||||
var statusBarMessage = '';
|
||||
var statusBarClassName = 'jasmine-bar ';
|
||||
|
||||
if (totalSpecsDefined > 0) {
|
||||
statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount);
|
||||
if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); }
|
||||
statusBarClassName += (failureCount > 0) ? 'jasmine-failed' : 'jasmine-passed';
|
||||
} else {
|
||||
statusBarClassName += 'jasmine-skipped';
|
||||
statusBarMessage += 'No specs found';
|
||||
}
|
||||
|
||||
var seedBar;
|
||||
if (order && order.random) {
|
||||
seedBar = createDom('span', {className: 'jasmine-seed-bar'},
|
||||
', randomized with seed ',
|
||||
createDom('a', {title: 'randomized with seed ' + order.seed, href: seedHref(order.seed)}, order.seed)
|
||||
);
|
||||
}
|
||||
|
||||
alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage, seedBar));
|
||||
|
||||
var errorBarClassName = 'jasmine-bar jasmine-errored';
|
||||
var errorBarMessagePrefix = 'AfterAll ';
|
||||
|
||||
for(var i = 0; i < failedSuites.length; i++) {
|
||||
var failedSuite = failedSuites[i];
|
||||
for(var j = 0; j < failedSuite.failedExpectations.length; j++) {
|
||||
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failedSuite.failedExpectations[j].message));
|
||||
}
|
||||
}
|
||||
|
||||
var globalFailures = (doneResult && doneResult.failedExpectations) || [];
|
||||
for(i = 0; i < globalFailures.length; i++) {
|
||||
var failure = globalFailures[i];
|
||||
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failure.message));
|
||||
}
|
||||
|
||||
var results = find('.jasmine-results');
|
||||
results.appendChild(summary);
|
||||
|
||||
summaryList(topResults, summary);
|
||||
|
||||
function summaryList(resultsTree, domParent) {
|
||||
var specListNode;
|
||||
for (var i = 0; i < resultsTree.children.length; i++) {
|
||||
var resultNode = resultsTree.children[i];
|
||||
if (resultNode.type == 'suite') {
|
||||
var suiteListNode = createDom('ul', {className: 'jasmine-suite', id: 'suite-' + resultNode.result.id},
|
||||
createDom('li', {className: 'jasmine-suite-detail'},
|
||||
createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description)
|
||||
)
|
||||
);
|
||||
|
||||
summaryList(resultNode, suiteListNode);
|
||||
domParent.appendChild(suiteListNode);
|
||||
}
|
||||
if (resultNode.type == 'spec') {
|
||||
if (domParent.getAttribute('class') != 'jasmine-specs') {
|
||||
specListNode = createDom('ul', {className: 'jasmine-specs'});
|
||||
domParent.appendChild(specListNode);
|
||||
}
|
||||
var specDescription = resultNode.result.description;
|
||||
if(noExpectations(resultNode.result)) {
|
||||
specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
|
||||
}
|
||||
if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') {
|
||||
specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason;
|
||||
}
|
||||
specListNode.appendChild(
|
||||
createDom('li', {
|
||||
className: 'jasmine-' + resultNode.result.status,
|
||||
id: 'spec-' + resultNode.result.id
|
||||
},
|
||||
createDom('a', {href: specHref(resultNode.result)}, specDescription)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (failures.length) {
|
||||
alert.appendChild(
|
||||
createDom('span', {className: 'jasmine-menu jasmine-bar jasmine-spec-list'},
|
||||
createDom('span', {}, 'Spec List | '),
|
||||
createDom('a', {className: 'jasmine-failures-menu', href: '#'}, 'Failures')));
|
||||
alert.appendChild(
|
||||
createDom('span', {className: 'jasmine-menu jasmine-bar jasmine-failure-list'},
|
||||
createDom('a', {className: 'jasmine-spec-list-menu', href: '#'}, 'Spec List'),
|
||||
createDom('span', {}, ' | Failures ')));
|
||||
|
||||
find('.jasmine-failures-menu').onclick = function() {
|
||||
setMenuModeTo('jasmine-failure-list');
|
||||
};
|
||||
find('.jasmine-spec-list-menu').onclick = function() {
|
||||
setMenuModeTo('jasmine-spec-list');
|
||||
};
|
||||
|
||||
setMenuModeTo('jasmine-failure-list');
|
||||
|
||||
var failureNode = find('.jasmine-failures');
|
||||
for (i = 0; i < failures.length; i++) {
|
||||
failureNode.appendChild(failures[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function find(selector) {
|
||||
return getContainer().querySelector('.jasmine_html-reporter ' + selector);
|
||||
}
|
||||
|
||||
function clearPrior() {
|
||||
// return the reporter
|
||||
var oldReporter = find('');
|
||||
|
||||
if(oldReporter) {
|
||||
getContainer().removeChild(oldReporter);
|
||||
}
|
||||
}
|
||||
|
||||
function createDom(type, attrs, childrenVarArgs) {
|
||||
var el = createElement(type);
|
||||
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
var child = arguments[i];
|
||||
|
||||
if (typeof child === 'string') {
|
||||
el.appendChild(createTextNode(child));
|
||||
} else {
|
||||
if (child) {
|
||||
el.appendChild(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var attr in attrs) {
|
||||
if (attr == 'className') {
|
||||
el[attr] = attrs[attr];
|
||||
} else {
|
||||
el.setAttribute(attr, attrs[attr]);
|
||||
}
|
||||
}
|
||||
|
||||
return el;
|
||||
}
|
||||
|
||||
function pluralize(singular, count) {
|
||||
var word = (count == 1 ? singular : singular + 's');
|
||||
|
||||
return '' + count + ' ' + word;
|
||||
}
|
||||
|
||||
function specHref(result) {
|
||||
return addToExistingQueryString('spec', result.fullName);
|
||||
}
|
||||
|
||||
function seedHref(seed) {
|
||||
return addToExistingQueryString('seed', seed);
|
||||
}
|
||||
|
||||
function defaultQueryString(key, value) {
|
||||
return '?' + key + '=' + value;
|
||||
}
|
||||
|
||||
function setMenuModeTo(mode) {
|
||||
htmlReporterMain.setAttribute('class', 'jasmine_html-reporter ' + mode);
|
||||
}
|
||||
|
||||
function noExpectations(result) {
|
||||
return (result.failedExpectations.length + result.passedExpectations.length) === 0 &&
|
||||
result.status === 'passed';
|
||||
}
|
||||
}
|
||||
|
||||
return HtmlReporter;
|
||||
};
|
||||
|
||||
jasmineRequire.HtmlSpecFilter = function() {
|
||||
function HtmlSpecFilter(options) {
|
||||
var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
|
||||
var filterPattern = new RegExp(filterString);
|
||||
|
||||
this.matches = function(specName) {
|
||||
return filterPattern.test(specName);
|
||||
};
|
||||
}
|
||||
|
||||
return HtmlSpecFilter;
|
||||
};
|
||||
|
||||
jasmineRequire.ResultsNode = function() {
|
||||
function ResultsNode(result, type, parent) {
|
||||
this.result = result;
|
||||
this.type = type;
|
||||
this.parent = parent;
|
||||
|
||||
this.children = [];
|
||||
|
||||
this.addChild = function(result, type) {
|
||||
this.children.push(new ResultsNode(result, type, this));
|
||||
};
|
||||
|
||||
this.last = function() {
|
||||
return this.children[this.children.length - 1];
|
||||
};
|
||||
}
|
||||
|
||||
return ResultsNode;
|
||||
};
|
||||
|
||||
jasmineRequire.QueryString = function() {
|
||||
function QueryString(options) {
|
||||
|
||||
this.navigateWithNewParam = function(key, value) {
|
||||
options.getWindowLocation().search = this.fullStringWithNewParam(key, value);
|
||||
};
|
||||
|
||||
this.fullStringWithNewParam = function(key, value) {
|
||||
var paramMap = queryStringToParamMap();
|
||||
paramMap[key] = value;
|
||||
return toQueryString(paramMap);
|
||||
};
|
||||
|
||||
this.getParam = function(key) {
|
||||
return queryStringToParamMap()[key];
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function toQueryString(paramMap) {
|
||||
var qStrPairs = [];
|
||||
for (var prop in paramMap) {
|
||||
qStrPairs.push(encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop]));
|
||||
}
|
||||
return '?' + qStrPairs.join('&');
|
||||
}
|
||||
|
||||
function queryStringToParamMap() {
|
||||
var paramStr = options.getWindowLocation().search.substring(1),
|
||||
params = [],
|
||||
paramMap = {};
|
||||
|
||||
if (paramStr.length > 0) {
|
||||
params = paramStr.split('&');
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var p = params[i].split('=');
|
||||
var value = decodeURIComponent(p[1]);
|
||||
if (value === 'true' || value === 'false') {
|
||||
value = JSON.parse(value);
|
||||
}
|
||||
paramMap[decodeURIComponent(p[0])] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return paramMap;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return QueryString;
|
||||
};
|
58
node_modules/cordova-sqlite-storage/spec/www/lib/jasmine-2.5.2/jasmine.css
generated
vendored
Normal file
58
node_modules/cordova-sqlite-storage/spec/www/lib/jasmine-2.5.2/jasmine.css
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
3655
node_modules/cordova-sqlite-storage/spec/www/lib/jasmine-2.5.2/jasmine.js
generated
vendored
Normal file
3655
node_modules/cordova-sqlite-storage/spec/www/lib/jasmine-2.5.2/jasmine.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
node_modules/cordova-sqlite-storage/spec/www/lib/jasmine-2.5.2/jasmine_favicon.png
generated
vendored
Normal file
BIN
node_modules/cordova-sqlite-storage/spec/www/lib/jasmine-2.5.2/jasmine_favicon.png
generated
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
1132
node_modules/cordova-sqlite-storage/spec/www/spec/basic-db-tx-sql-storage-results.js
generated
vendored
Normal file
1132
node_modules/cordova-sqlite-storage/spec/www/spec/basic-db-tx-sql-storage-results.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
35
node_modules/cordova-sqlite-storage/spec/www/spec/browser-check-startup.js
generated
vendored
Normal file
35
node_modules/cordova-sqlite-storage/spec/www/spec/browser-check-startup.js
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
/* 'use strict'; */
|
||||
|
||||
var MYTIMEOUT = 12000;
|
||||
|
||||
var isWindows = /MSAppHost/.test(navigator.userAgent);
|
||||
var isAndroid = !isWindows && /Android/.test(navigator.userAgent);
|
||||
var isFirefox = /Firefox/.test(navigator.userAgent);
|
||||
var isWebKitBrowser = !isWindows && !isAndroid && /Safari/.test(navigator.userAgent);
|
||||
var isBrowser = isWebKitBrowser || isFirefox;
|
||||
var isEdgeBrowser = isBrowser && (/Edge/.test(navigator.userAgent));
|
||||
var isChromeBrowser = isBrowser && !isEdgeBrowser && (/Chrome/.test(navigator.userAgent));
|
||||
var isMac = !isBrowser && /Macintosh/.test(navigator.userAgent);
|
||||
var isAppleMobileOS = /iPhone/.test(navigator.userAgent) ||
|
||||
/iPad/.test(navigator.userAgent) || /iPod/.test(navigator.userAgent);
|
||||
var hasMobileWKWebView = isAppleMobileOS && !!window.webkit && !!window.webkit.messageHandlers;
|
||||
|
||||
window.hasBrowser = true;
|
||||
window.hasWebKitWebSQL = isAndroid || isChromeBrowser;
|
||||
|
||||
describe('Check startup for navigator.userAgent: ' + navigator.userAgent, function() {
|
||||
it('receives deviceready event', function(done) {
|
||||
expect(true).toBe(true);
|
||||
document.addEventListener("deviceready", function() {
|
||||
done();
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it('has openDatabase', function() {
|
||||
if (window.hasWebKitWebSQL) expect(window.openDatabase).toBeDefined();
|
||||
expect(window.sqlitePlugin).toBeDefined();
|
||||
expect(window.sqlitePlugin.openDatabase).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
/* vim: set expandtab : */
|
2128
node_modules/cordova-sqlite-storage/spec/www/spec/db-open-close-delete-test.js
generated
vendored
Normal file
2128
node_modules/cordova-sqlite-storage/spec/www/spec/db-open-close-delete-test.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
430
node_modules/cordova-sqlite-storage/spec/www/spec/db-simultaneous-tx-access-test.js
generated
vendored
Normal file
430
node_modules/cordova-sqlite-storage/spec/www/spec/db-simultaneous-tx-access-test.js
generated
vendored
Normal file
@ -0,0 +1,430 @@
|
||||
/* 'use strict'; */
|
||||
|
||||
var MYTIMEOUT = 12000;
|
||||
|
||||
// NOTE: DEFAULT_SIZE wanted depends on type of browser
|
||||
|
||||
var isWindows = /MSAppHost/.test(navigator.userAgent);
|
||||
var isAndroid = !isWindows && /Android/.test(navigator.userAgent);
|
||||
var isFirefox = /Firefox/.test(navigator.userAgent);
|
||||
var isWebKitBrowser = !isWindows && !isAndroid && /Safari/.test(navigator.userAgent);
|
||||
var isBrowser = isWebKitBrowser || isFirefox;
|
||||
var isEdgeBrowser = isBrowser && (/Edge/.test(navigator.userAgent));
|
||||
var isChromeBrowser = isBrowser && !isEdgeBrowser && (/Chrome/.test(navigator.userAgent));
|
||||
var isSafariBrowser = isWebKitBrowser && !isEdgeBrowser && !isChromeBrowser;
|
||||
|
||||
// should avoid popups (Safari seems to count 2x)
|
||||
var DEFAULT_SIZE = isSafariBrowser ? 2000000 : 5000000;
|
||||
// FUTURE TBD: 50MB should be OK on Chrome and some other test browsers.
|
||||
|
||||
// NOTE: While in certain version branches there is no difference between
|
||||
// the default Android implementation and implementation #2,
|
||||
// this test script will also apply the androidLockWorkaround: 1 option
|
||||
// in case of implementation #2.
|
||||
var scenarioList = [
|
||||
isAndroid ? 'Plugin-implementation-default' : 'Plugin',
|
||||
'HTML5',
|
||||
'Plugin-implementation-2'
|
||||
];
|
||||
|
||||
var scenarioCount = (!!window.hasWebKitWebSQL) ? (isAndroid ? 3 : 2) : 1;
|
||||
|
||||
function logSuccess(message) { console.log('OK - ' + message); }
|
||||
function logError(message) { console.log('FAILED - ' + message); }
|
||||
|
||||
var mytests = function() {
|
||||
|
||||
for (var i=0; i<scenarioCount; ++i) {
|
||||
|
||||
describe(scenarioList[i] + ': simultaneous tx access test(s)', function() {
|
||||
var scenarioName = scenarioList[i];
|
||||
var suiteName = scenarioName + ': ';
|
||||
var isWebSql = (i === 1);
|
||||
var isImpl2 = (i === 2);
|
||||
|
||||
// NOTE: MUST be defined in function scope, NOT outer scope:
|
||||
var openDatabase = function(name, ignored1, ignored2, ignored3) {
|
||||
if (isImpl2) {
|
||||
return window.sqlitePlugin.openDatabase({
|
||||
// prevent reuse of database from default db implementation:
|
||||
name: 'i2-'+name,
|
||||
// explicit database location:
|
||||
location: 'default',
|
||||
androidDatabaseImplementation: 2,
|
||||
androidLockWorkaround: 1
|
||||
});
|
||||
}
|
||||
if (isWebSql) {
|
||||
return window.openDatabase(name, '1.0', 'Test', DEFAULT_SIZE);
|
||||
} else {
|
||||
// explicit database location:
|
||||
return window.sqlitePlugin.openDatabase({name: name, location: 'default'});
|
||||
}
|
||||
}
|
||||
|
||||
it(suiteName + ' open same db twice with string test', function (done) {
|
||||
var dbName = 'open-same-db-twice-string-test.db';
|
||||
|
||||
var db1 = openDatabase(dbName, "1.0", "Demo", DEFAULT_SIZE);
|
||||
var db2 = openDatabase(dbName, "1.0", "Demo", DEFAULT_SIZE);
|
||||
|
||||
expect(db1).toBeTruthy(); // valid db1 database handle object
|
||||
expect(db2).toBeTruthy(); // valid db2 database handle object
|
||||
|
||||
// Replacement for QUnit stop()/start() functions:
|
||||
var checkCount = 0;
|
||||
var expectedCheckCount = 2;
|
||||
|
||||
db1.readTransaction(function(tx) {
|
||||
expect(tx).toBeTruthy(); // valid db1 tx object
|
||||
tx.executeSql("select upper('first') as uppertext", [], function(tx, result) {
|
||||
expect(result).toBeTruthy(); // valid db1 read tx result object
|
||||
expect(result.rows.item(0).uppertext).toBe('FIRST'); // check db1 read tx result
|
||||
if (++checkCount === expectedCheckCount) done();
|
||||
}, function(error) {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError(error);
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
});
|
||||
}, function(error) {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError(error);
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
});
|
||||
db2.readTransaction(function(tx) {
|
||||
expect(tx).toBeTruthy(); // valid db2 tx object
|
||||
tx.executeSql("select upper('second') as uppertext", [], function(tx, result) {
|
||||
expect(result).toBeTruthy(); // valid db2 read tx result object
|
||||
expect(result.rows.item(0).uppertext).toBe('SECOND'); // check db2 read tx result
|
||||
if (++checkCount === expectedCheckCount) done();
|
||||
}, function(error) {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError(error);
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
});
|
||||
}, function(error) {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError(error);
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
});
|
||||
});
|
||||
|
||||
it(suiteName + ' test simultaneous transactions (same db handle)', function (done) {
|
||||
var db = openDatabase("Database-Simultaneous-Tx", "1.0", "Demo", DEFAULT_SIZE);
|
||||
|
||||
var numDone = 0;
|
||||
function checkDone() {
|
||||
if (++numDone == 2) {
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql('DROP TABLE IF EXISTS test', [], function () {
|
||||
tx.executeSql('CREATE TABLE test (name);');
|
||||
|
||||
});
|
||||
}, function(error) {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError(error);
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
}, function () {
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql('INSERT INTO test VALUES ("foo")', [], function () {
|
||||
tx.executeSql('SELECT * FROM test', [], function (tx, res) {
|
||||
expect(res.rows.length).toBe(1); // only one row
|
||||
expect(res.rows.item(0).name).toBe('foo');
|
||||
|
||||
tx.executeSql('SELECT * FROM bogustable'); // force rollback
|
||||
});
|
||||
});
|
||||
}, function(error) {
|
||||
// EXPECTED RESULT - expected error:
|
||||
expect(error).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
checkDone();
|
||||
}, function () {
|
||||
// NOT EXPECTED - should have rolled back:
|
||||
logError('should have rolled back');
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
});
|
||||
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql('INSERT INTO test VALUES ("bar")', [], function () {
|
||||
tx.executeSql('SELECT * FROM test', [], function (tx, res) {
|
||||
expect(res.rows.length).toBe(1); // only one row
|
||||
expect(res.rows.item(0).name).toBe('bar');
|
||||
|
||||
tx.executeSql('SELECT * FROM bogustable'); // force rollback
|
||||
});
|
||||
});
|
||||
}, function(error) {
|
||||
// EXPECTED RESULT - expected error:
|
||||
expect(error).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
checkDone();
|
||||
}, function () {
|
||||
// NOT EXPECTED - should have rolled back:
|
||||
logError('should have rolled back');
|
||||
done.fail();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it(suiteName + ' test simultaneous transactions, different db handles (same db)', function (done) {
|
||||
var dbName = "Database-Simultaneous-Tx-Diff-DB-handles";
|
||||
|
||||
var db = openDatabase(dbName, "1.0", "Demo", DEFAULT_SIZE);
|
||||
|
||||
var numDone = 0;
|
||||
function checkDone() {
|
||||
if (++numDone == 2) {
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql('DROP TABLE IF EXISTS test', [], function () {
|
||||
tx.executeSql('CREATE TABLE test (name);');
|
||||
|
||||
});
|
||||
}, function(error) {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError(error);
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
}, function () {
|
||||
var db1 = openDatabase(dbName, "1.0", "Demo", DEFAULT_SIZE);
|
||||
db1.transaction(function(tx) {
|
||||
tx.executeSql('INSERT INTO test VALUES ("foo")', [], function () {
|
||||
tx.executeSql('SELECT * FROM test', [], function (tx, res) {
|
||||
expect(res.rows.length).toBe(1); // only one row
|
||||
expect(res.rows.item(0).name).toBe('foo');
|
||||
|
||||
tx.executeSql('SELECT * FROM bogustable'); // force rollback
|
||||
});
|
||||
});
|
||||
}, function(error) {
|
||||
// EXPECTED RESULT - expected error:
|
||||
expect(error).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
checkDone();
|
||||
}, function () {
|
||||
// NOT EXPECTED - should have rolled back:
|
||||
logError('should have rolled back');
|
||||
done.fail();
|
||||
});
|
||||
|
||||
var db2 = openDatabase(dbName, "1.0", "Demo", DEFAULT_SIZE);
|
||||
|
||||
db2.transaction(function(tx) {
|
||||
tx.executeSql('INSERT INTO test VALUES ("bar")', [], function () {
|
||||
tx.executeSql('SELECT * FROM test', [], function (tx, res) {
|
||||
expect(res.rows.length).toBe(1); // only one row
|
||||
expect(res.rows.item(0).name).toBe('bar');
|
||||
|
||||
tx.executeSql('SELECT * FROM bogustable'); // force rollback
|
||||
});
|
||||
});
|
||||
}, function(error) {
|
||||
// EXPECTED RESULT - expected error:
|
||||
expect(error).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
checkDone();
|
||||
}, function () {
|
||||
// NOT EXPECTED - should have rolled back:
|
||||
logError('should have rolled back');
|
||||
done.fail();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it(suiteName + ' can open two databases at the same time', function (done) {
|
||||
// create databases and tables
|
||||
var db1 = openDatabase("DB1", "1.0", "Demo", DEFAULT_SIZE);
|
||||
db1.transaction(function (tx1) {
|
||||
tx1.executeSql('CREATE TABLE IF NOT EXISTS test1 (x int)');
|
||||
});
|
||||
|
||||
var db2 = openDatabase("DB2", "1.0", "Demo", DEFAULT_SIZE);
|
||||
db2.transaction(function (tx2) {
|
||||
tx2.executeSql('CREATE TABLE IF NOT EXISTS test2 (x int)');
|
||||
});
|
||||
|
||||
// two databases that perform two queries and one commit each, then repeat
|
||||
|
||||
// Quick replacement for QUnit stop()/start() functions:
|
||||
var checkCount = 0;
|
||||
var expectedCheckCount = 12;
|
||||
|
||||
// create overlapping transactions
|
||||
db1.transaction(function (tx1) {
|
||||
db2.transaction(function (tx2) {
|
||||
|
||||
tx2.executeSql('INSERT INTO test2 VALUES (2)', [], function (tx, result) {
|
||||
logSuccess('inserted into second database');
|
||||
++checkCount;
|
||||
});
|
||||
tx2.executeSql('SELECT * from test2', [], function (tx, result) {
|
||||
expect(result.rows.item(0).x).toBe(2); // selected from second database
|
||||
++checkCount;
|
||||
});
|
||||
}, function (error) {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError('transaction 2 failed ' + error);
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
}, function () {
|
||||
logSuccess('transaction 2 committed');
|
||||
++checkCount;
|
||||
});
|
||||
|
||||
tx1.executeSql('INSERT INTO test1 VALUES (1)', [], function (tx, result) {
|
||||
logSuccess('inserted into first database');
|
||||
++checkCount;
|
||||
});
|
||||
|
||||
tx1.executeSql('SELECT * from test1', [], function (tx, result) {
|
||||
expect(result.rows.item(0).x).toBe(1); // selected from first database
|
||||
++checkCount;
|
||||
});
|
||||
}, function (error) {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError('transaction 1 failed ' + error);
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
}, function () {
|
||||
logSuccess('transaction 1 committed');
|
||||
if (++checkCount === expectedCheckCount) done();
|
||||
});
|
||||
|
||||
// now that the databases are truly open, do it again!
|
||||
// - should wait for first db1.transaction() call to finish
|
||||
// - must check for - checkCount === expectedCheckCount in both
|
||||
// db1.transaction() callback & db2.transaction() callback
|
||||
// since it is not certain which will finish first or last.
|
||||
db1.transaction(function (tx1) {
|
||||
db2.transaction(function (tx2) {
|
||||
|
||||
tx2.executeSql('INSERT INTO test2 VALUES (2)', [], function (tx, result) {
|
||||
logSuccess('inserted into second database');
|
||||
++checkCount;
|
||||
});
|
||||
tx2.executeSql('SELECT * from test2', [], function (tx, result) {
|
||||
expect(result.rows.item(0).x).toBe(2); // selected from second database
|
||||
++checkCount;
|
||||
});
|
||||
}, function (error) {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError('transaction 2 failed ' + error);
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
}, function () {
|
||||
logSuccess('transaction 2 committed');
|
||||
if (++checkCount === expectedCheckCount) done();
|
||||
});
|
||||
|
||||
tx1.executeSql('INSERT INTO test1 VALUES (1)', [], function (tx, result) {
|
||||
logSuccess('inserted into first database');
|
||||
++checkCount;
|
||||
});
|
||||
|
||||
tx1.executeSql('SELECT * from test1', [], function (tx, result) {
|
||||
expect(result.rows.item(0).x).toBe(1); // selected from first database
|
||||
++checkCount;
|
||||
});
|
||||
}, function (error) {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError('transaction 1 failed ' + error);
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
}, function () {
|
||||
logSuccess('transaction 1 committed');
|
||||
if (++checkCount === expectedCheckCount) done();
|
||||
});
|
||||
});
|
||||
|
||||
it(suiteName + ' same database file with separate writer/reader db handles', function (done) {
|
||||
var dbname = 'writer-reader-test.db';
|
||||
var dbw = openDatabase(dbname, "1.0", "Demo", DEFAULT_SIZE);
|
||||
var dbr = openDatabase(dbname, "1.0", "Demo", DEFAULT_SIZE);
|
||||
|
||||
dbw.transaction(function (tx) {
|
||||
tx.executeSql('DROP TABLE IF EXISTS tt');
|
||||
tx.executeSql('CREATE TABLE IF NOT EXISTS tt (test_data)');
|
||||
tx.executeSql('INSERT INTO tt VALUES (?)', ['My-test-data']);
|
||||
}, function(error) {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError(error.message);
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
}, function() {
|
||||
dbr.readTransaction(function (tx) {
|
||||
tx.executeSql('SELECT test_data from tt', [], function (tx, result) {
|
||||
expect(result.rows.item(0).test_data).toBe('My-test-data'); // read data from reader handle
|
||||
done();
|
||||
});
|
||||
}, function(error) {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError(error.message);
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it(suiteName + ' same database file with multiple writer db handles', function (done) {
|
||||
var dbname = 'multi-writer-test.db';
|
||||
var dbw1 = openDatabase(dbname, "1.0", "Demo", DEFAULT_SIZE);
|
||||
var dbw2 = openDatabase(dbname, "1.0", "Demo", DEFAULT_SIZE);
|
||||
var dbr = openDatabase(dbname, "1.0", "Demo", DEFAULT_SIZE);
|
||||
|
||||
dbw1.transaction(function (tx) {
|
||||
tx.executeSql('DROP TABLE IF EXISTS tt');
|
||||
tx.executeSql('CREATE TABLE IF NOT EXISTS tt (test_data)');
|
||||
}, function(error) {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError(error.message);
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
}, function() {
|
||||
dbw2.transaction(function (tx) {
|
||||
tx.executeSql('INSERT INTO tt VALUES (?)', ['My-test-data']);
|
||||
}, function(error) {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError(error.message);
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
}, function() {
|
||||
dbr.readTransaction(function (tx) {
|
||||
tx.executeSql('SELECT test_data from tt', [], function (tx, result) {
|
||||
expect(result.rows.item(0).test_data).toBe('My-test-data'); // read data from reader handle
|
||||
done();
|
||||
});
|
||||
}, function(error) {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError(error.message);
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (window.hasBrowser) mytests();
|
||||
else exports.defineAutoTests = mytests;
|
||||
|
||||
/* vim: set expandtab : */
|
1619
node_modules/cordova-sqlite-storage/spec/www/spec/db-sql-operations-test.js
generated
vendored
Normal file
1619
node_modules/cordova-sqlite-storage/spec/www/spec/db-sql-operations-test.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4064
node_modules/cordova-sqlite-storage/spec/www/spec/db-tx-error-handling-test.js
generated
vendored
Normal file
4064
node_modules/cordova-sqlite-storage/spec/www/spec/db-tx-error-handling-test.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
929
node_modules/cordova-sqlite-storage/spec/www/spec/db-tx-error-mapping-test.js
generated
vendored
Normal file
929
node_modules/cordova-sqlite-storage/spec/www/spec/db-tx-error-mapping-test.js
generated
vendored
Normal file
@ -0,0 +1,929 @@
|
||||
/* 'use strict'; */
|
||||
|
||||
var MYTIMEOUT = 12000;
|
||||
|
||||
// NOTE: DEFAULT_SIZE wanted depends on type of browser
|
||||
|
||||
var isWindows = /MSAppHost/.test(navigator.userAgent);
|
||||
var isAndroid = !isWindows && /Android/.test(navigator.userAgent);
|
||||
var isFirefox = /Firefox/.test(navigator.userAgent);
|
||||
var isWebKitBrowser = !isWindows && !isAndroid && /Safari/.test(navigator.userAgent);
|
||||
var isBrowser = isWebKitBrowser || isFirefox;
|
||||
var isEdgeBrowser = isBrowser && (/Edge/.test(navigator.userAgent));
|
||||
var isChromeBrowser = isBrowser && !isEdgeBrowser && (/Chrome/.test(navigator.userAgent));
|
||||
var isSafariBrowser = isWebKitBrowser && !isEdgeBrowser && !isChromeBrowser;
|
||||
// detect iOS platform:
|
||||
var isAppleMobileOS =
|
||||
(/iPhone/.test(navigator.userAgent)
|
||||
|| /iPad/.test(navigator.userAgent)
|
||||
|| /iPod/.test(navigator.userAgent));
|
||||
|
||||
// should avoid popups (Safari seems to count 2x)
|
||||
var DEFAULT_SIZE = isSafariBrowser ? 2000000 : 5000000;
|
||||
// FUTURE TBD: 50MB should be OK on Chrome and some other test browsers.
|
||||
|
||||
// NOTE: While in certain version branches there is no difference between
|
||||
// the default Android implementation and implementation #2,
|
||||
// this test script will also apply the androidLockWorkaround: 1 option
|
||||
// in case of implementation #2.
|
||||
var scenarioList = [
|
||||
isAndroid ? 'Plugin-implementation-default' : 'Plugin',
|
||||
'HTML5',
|
||||
'Plugin-implementation-2'
|
||||
];
|
||||
|
||||
var scenarioCount = (!!window.hasWebKitWebSQL) ? (isAndroid ? 3 : 2) : 1;
|
||||
|
||||
var mytests = function() {
|
||||
|
||||
for (var i=0; i<scenarioCount; ++i) {
|
||||
|
||||
describe(scenarioList[i] + ': db tx error mapping test(s) [TBD INCORRECT & INCONSISTENT error message on Windows - missing actual error info ref: litehelpers/Cordova-sqlite-storage#539]', function() {
|
||||
var scenarioName = scenarioList[i];
|
||||
var suiteName = scenarioName + ': ';
|
||||
var isWebSql = (i === 1);
|
||||
var isImpl2 = (i === 2);
|
||||
// XXX TBD WORKAROUND SOLUTION for (WebKit) Web SQL on Safari browser (TEST DB NAME IGNORED):
|
||||
var recycleWebDatabase = null;
|
||||
|
||||
// NOTE: MUST be defined in function scope, NOT outer scope:
|
||||
var openDatabase = function(name, ignored1, ignored2, ignored3) {
|
||||
if (isWebSql && isSafariBrowser && !!recycleWebDatabase)
|
||||
return recycleWebDatabase;
|
||||
if (isImpl2) {
|
||||
return window.sqlitePlugin.openDatabase({
|
||||
// prevent reuse of database from default db implementation:
|
||||
name: 'i2-'+name,
|
||||
androidDatabaseImplementation: 2,
|
||||
androidLockWorkaround: 1,
|
||||
location: 1
|
||||
});
|
||||
}
|
||||
if (isWebSql) {
|
||||
return recycleWebDatabase =
|
||||
window.openDatabase(name, '1.0', 'Test', DEFAULT_SIZE);
|
||||
} else {
|
||||
return window.sqlitePlugin.openDatabase({name: name, location: 0});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ERROR MAPPING ISSUES/DEVIATIONS:
|
||||
//
|
||||
// - In case an executeSql error handler returns true (WebKit) Web SQL indicates
|
||||
// error code 0 (SQLError.UNKNOWN_ERR) in the transaction error callback
|
||||
// - In certain database error cases (WebKit) Web SQL and plugin on Android
|
||||
// (no androidDatabaseImplementation: 2 setting) & iOS report SQLError code 5
|
||||
// (SQLError.SYNTAX_ERR) wile it should be 1 (SQLError.DATABASE_ERR)
|
||||
// ("not covered by any other error code") ref:
|
||||
// https://www.w3.org/TR/webdatabase/#dom-sqlerror-code-1
|
||||
// - Android plugin with androidDatabaseImplementation: 2 setting indicates SQLError code 0
|
||||
// (SQLError.UNKNOWN_ERR) in cases other than a syntax error or constraint violation
|
||||
// - Windows plugin always reports error code 0 (SQLError.UNKNOWN_ERR) and
|
||||
// INCONSISTENT messages (missing actual error info)
|
||||
|
||||
// OTHER ERROR MAPPING NOTES:
|
||||
//
|
||||
// - (WebKit) Web SQL apparently includes 'prepare statement error' vs
|
||||
// 'execute statement error' info along with the sqlite error code
|
||||
// - Default Android implementation (Android-sqlite-connector) includes
|
||||
// sqlite3_prepare_v2 vs sqlite3_step function call info indicating
|
||||
// 'prepare statement error' vs 'execute statement error'
|
||||
// - Android plugin with androidDatabaseImplementation: 2 setting includes the sqlite error code
|
||||
// - Windows plugin also includes info indicating 'prepare statement error' vs
|
||||
// 'execute statement error', along with sqlite error code in case of
|
||||
// 'execute statement error'
|
||||
|
||||
// GENERAL NOTE: ERROR MESSAGES are subject to improvements and other possible changes.
|
||||
|
||||
it(suiteName + 'syntax error: command with misspelling', function(done) {
|
||||
var db = openDatabase("Syntax-error-test.db", "1.0", "Demo", DEFAULT_SIZE);
|
||||
expect(db).toBeDefined();
|
||||
|
||||
// VERIFY that an error object was received in the end
|
||||
var sqlerror = null;
|
||||
|
||||
db.transaction(function(tx) {
|
||||
// syntax error due to misspelling:
|
||||
tx.executeSql('SLCT 1 ', [], function(tx) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
throw new Error('abort tx');
|
||||
|
||||
}, function(tx, error) {
|
||||
sqlerror = error;
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (!isWebSql && (isBrowser || isWindows || (isAndroid && isImpl2)))
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(5);
|
||||
|
||||
if (isWebSql && !(/Android 4.[1-3]/.test(navigator.userAgent)))
|
||||
expect(error.message).toMatch(/could not prepare statement.*1 near \"SLCT\": syntax error/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/Error preparing an SQLite statement/);
|
||||
else if (!isWebSql && !isWindows && isAndroid && !isImpl2)
|
||||
expect(error.message).toMatch(/sqlite3_prepare_v2 failure:.*near \"SLCT\": syntax error/);
|
||||
else if (!isWebSql && !isWindows && isAndroid && isImpl2)
|
||||
expect(error.message).toMatch(/near \"SLCT\": syntax error.*code 1.*while compiling: SLCT 1/);
|
||||
else
|
||||
expect(error.message).toMatch(/near \"SLCT\": syntax error/);
|
||||
|
||||
// FAIL transaction & check reported transaction error:
|
||||
return true;
|
||||
});
|
||||
}, function (error) {
|
||||
expect(!!sqlerror).toBe(true); // VERIFY the SQL error callback was triggered
|
||||
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (isWebSql || isBrowser || isWindows || (isAndroid && isImpl2))
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(5);
|
||||
|
||||
if (isWebSql)
|
||||
expect(error.message).toMatch(/callback raised an exception.*or.*error callback did not return false/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/error callback did not return false.*Error preparing an SQLite statement/);
|
||||
else
|
||||
expect(error.message).toMatch(/error callback did not return false.*syntax error/);
|
||||
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
}, function() {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'syntax error: comma after a field name', function(done) {
|
||||
var db = openDatabase('comma-after-field-name-error-test.db');
|
||||
expect(db).toBeDefined();
|
||||
|
||||
// VERIFY that an error object was received in the end
|
||||
var sqlerror = null;
|
||||
|
||||
db.transaction(function(tx) {
|
||||
// This insertion has a SQL syntax error
|
||||
tx.executeSql('SELECT name, from Users', [], function(tx) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
throw new Error('abort tx');
|
||||
|
||||
}, function(tx, error) {
|
||||
sqlerror = error;
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (!isWebSql && (isBrowser || isWindows || (isAndroid && isImpl2)))
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(5);
|
||||
|
||||
if (isWebSql && !(/Android 4.[1-3]/.test(navigator.userAgent)))
|
||||
expect(error.message).toMatch(/could not prepare statement.*1 near \"from\": syntax error/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/Error preparing an SQLite statement/);
|
||||
else
|
||||
expect(error.message).toMatch(/near \"from\": syntax error/);
|
||||
|
||||
// FAIL transaction & check reported transaction error:
|
||||
return true;
|
||||
});
|
||||
}, function (error) {
|
||||
expect(!!sqlerror).toBe(true); // VERIFY the SQL error callback was triggered
|
||||
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (isBrowser || isWindows || isWebSql || (isAndroid && isImpl2))
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(5);
|
||||
|
||||
if (isWebSql)
|
||||
expect(error.message).toMatch(/callback raised an exception.*or.*error callback did not return false/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/error callback did not return false.*Error preparing an SQLite statement/);
|
||||
else
|
||||
expect(error.message).toMatch(/error callback did not return false.*syntax error/);
|
||||
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
}, function() {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'INSERT with VALUES in the wrong place (and with a trailing space) [TBD "incomplete input" vs "syntax error" message IGNORED on (WebKit) Web SQL on Android 7.0(+) & iOS 12.0(+)]', function(done) {
|
||||
var db = openDatabase("INSERT-Syntax-error-test.db", "1.0", "Demo", DEFAULT_SIZE);
|
||||
expect(db).toBeDefined();
|
||||
|
||||
// VERIFY that an error object was received in the end
|
||||
var sqlerror = null;
|
||||
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql('DROP TABLE IF EXISTS test_table');
|
||||
tx.executeSql('CREATE TABLE IF NOT EXISTS test_table (data unique)');
|
||||
|
||||
// This insertion has a SQL syntax error
|
||||
tx.executeSql('INSERT INTO test_table (data) VALUES ', [123], function(tx) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
throw new Error('abort tx');
|
||||
|
||||
}, function(tx, error) {
|
||||
sqlerror = error;
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (!isWebSql && (isBrowser || isWindows || (isAndroid && isImpl2)))
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(5);
|
||||
|
||||
if (isWebSql && (isAppleMobileOS || /Android [7-9]/.test(navigator.userAgent) || /Android 1/.test(navigator.userAgent)))
|
||||
// TBD incomplete input vs syntax error message IGNORED on Android 7.0(+) & iOS 12.0(+)
|
||||
expect(error.message).toMatch(/could not prepare statement.*/);
|
||||
else if (isWebSql && !isBrowser && !(/Android 4.[1-3]/.test(navigator.userAgent)))
|
||||
expect(error.message).toMatch(/could not prepare statement.*1 near \"VALUES\": syntax error/);
|
||||
else if (isWebSql && isBrowser)
|
||||
expect(error.message).toMatch(/could not prepare statement.*1 incomplete input/);
|
||||
else if (isWebSql)
|
||||
expect(error.message).toMatch(/near \"VALUES\": syntax error/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/Error preparing an SQLite statement/);
|
||||
else if (isAndroid && !isImpl2)
|
||||
expect(error.message).toMatch(/sqlite3_prepare_v2 failure:.*incomplete input/);
|
||||
else if (isAndroid && isImpl2)
|
||||
// TBD more general pattern for Android 9 vs ...
|
||||
expect(error.message).toMatch(/code 1.*while compiling: INSERT INTO test_table/);
|
||||
else
|
||||
expect(error.message).toMatch(/incomplete input/);
|
||||
|
||||
// FAIL transaction & check reported transaction error:
|
||||
return true;
|
||||
});
|
||||
}, function (error) {
|
||||
expect(!!sqlerror).toBe(true); // VERIFY the SQL error callback was triggered
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (isWebSql || isBrowser || isWindows || (isAndroid && isImpl2))
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(5);
|
||||
|
||||
if (isWebSql)
|
||||
expect(error.message).toMatch(/callback raised an exception.*or.*error callback did not return false/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/error callback did not return false.*Error preparing an SQLite statement/);
|
||||
else if (isAndroid && isImpl2)
|
||||
// TBD more general pattern for Android 9 vs ...
|
||||
expect(error.message).toMatch(/error callback did not return false.*code 1/);
|
||||
else
|
||||
expect(error.message).toMatch(/error callback did not return false.*incomplete input/);
|
||||
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
}, function() {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'constraint violation', function(done) {
|
||||
var db = openDatabase("Constraint-violation-test.db", "1.0", "Demo", DEFAULT_SIZE);
|
||||
expect(db).toBeDefined();
|
||||
|
||||
// VERIFY that an error object was received in the end
|
||||
var sqlerror = null;
|
||||
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql('DROP TABLE IF EXISTS test_table');
|
||||
tx.executeSql('CREATE TABLE IF NOT EXISTS test_table (data unique)');
|
||||
|
||||
// First INSERT OK:
|
||||
tx.executeSql("INSERT INTO test_table (data) VALUES (?)", [123], null, function(tx, error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
});
|
||||
|
||||
// Second INSERT will violate the unique constraint:
|
||||
tx.executeSql('INSERT INTO test_table (data) VALUES (?)', [123], function(tx) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
throw new Error('abort tx');
|
||||
|
||||
}, function(tx, error) {
|
||||
sqlerror = error;
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (isWebSql && (!isAndroid || /Android 4.[1-3]/.test(navigator.userAgent)))
|
||||
expect(true).toBe(true); // SKIP for iOS (WebKit) & Android 4.1-4.3 (WebKit) Web SQL
|
||||
else if (isBrowser || isWindows)
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(6);
|
||||
|
||||
// (WebKit) Web SQL (Android/iOS) possibly with a missing 'r'
|
||||
if (isWebSql && /Android 4.[1-3]/.test(navigator.userAgent))
|
||||
expect(error.message).toMatch(/column data is not unique/);
|
||||
else if (isWebSql && isAndroid)
|
||||
expect(error.message).toMatch(/could not execute statement due to a constr?aint failure.*19.*constraint failed/);
|
||||
else if (isWebSql)
|
||||
expect(error.message).toMatch(/constr?aint fail/); // [possibly missing letter on iOS (WebKit) Web SQL]
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/SQLite3 step error result code: 1/);
|
||||
else if (isAndroid && !isImpl2)
|
||||
expect(error.message).toMatch(/sqlite3_step failure: UNIQUE constraint failed: test_table\.data/);
|
||||
else if (isAndroid && isImpl2)
|
||||
expect(error.message).toMatch(/constraint failure/);
|
||||
else
|
||||
expect(error.message).toMatch(/UNIQUE constraint failed: test_table\.data/);
|
||||
|
||||
// FAIL transaction & check reported transaction error:
|
||||
return true;
|
||||
});
|
||||
}, function (error) {
|
||||
expect(!!sqlerror).toBe(true); // VERIFY the SQL error callback was triggered
|
||||
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (isWebSql || isBrowser || isWindows)
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(6);
|
||||
|
||||
if (isWebSql)
|
||||
expect(error.message).toMatch(/callback raised an exception.*or.*error callback did not return false/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/error callback did not return false.*SQLite3 step error result code: 1/);
|
||||
else
|
||||
expect(error.message).toMatch(/error callback did not return false.*constraint fail/);
|
||||
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
}, function() {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'SELECT uper("Test") (misspelled function name) [INCORRECT error code WebKit Web SQL & plugin]', function(done) {
|
||||
var db = openDatabase("Misspelled-function-name-error-test.db", "1.0", "Demo", DEFAULT_SIZE);
|
||||
expect(db).toBeDefined();
|
||||
|
||||
// VERIFY that an error object was received in the end
|
||||
var sqlerror = null;
|
||||
|
||||
db.transaction(function(tx) {
|
||||
// This insertion has a SQL syntax error
|
||||
tx.executeSql('SELECT uper("Test")', [], function(tx) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
throw new Error('abort tx');
|
||||
|
||||
}, function(tx, error) {
|
||||
sqlerror = error;
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (!isWebSql && (isBrowser || isWindows || (isAndroid && isImpl2)))
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(5);
|
||||
|
||||
// ACTUAL WebKit Web SQL vs plugin error.message
|
||||
if (isWebSql && !(/Android 4.[1-3]/.test(navigator.userAgent)))
|
||||
expect(error.message).toMatch(/could not prepare statement.*1 no such function: uper/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/Error preparing an SQLite statement/);
|
||||
else if (!isWebSql && !isWindows && isAndroid && !isImpl2)
|
||||
expect(error.message).toMatch(/sqlite3_prepare_v2 failure:.*no such function: uper/);
|
||||
else if (!isWebSql && !isWindows && isAndroid && isImpl2)
|
||||
expect(error.message).toMatch(/no such function: uper.*code 1/);
|
||||
else
|
||||
expect(error.message).toMatch(/no such function: uper/);
|
||||
|
||||
// FAIL transaction & check reported transaction error:
|
||||
return true;
|
||||
});
|
||||
}, function (error) {
|
||||
expect(!!sqlerror).toBe(true); // VERIFY the SQL error callback was triggered
|
||||
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (isWebSql || isBrowser || isWindows || (isAndroid && isImpl2))
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(5);
|
||||
|
||||
if (isWebSql)
|
||||
expect(error.message).toMatch(/callback raised an exception.*or.*error callback did not return false/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/error callback did not return false.*Error preparing an SQLite statement/);
|
||||
else
|
||||
expect(error.message).toMatch(/error callback did not return false.*no such function: uper/);
|
||||
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
}, function() {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'SELECT FROM bogus table (other database error) [INCORRECT error code WebKit Web SQL & plugin]', function(done) {
|
||||
var db = openDatabase("SELECT-FROM-bogus-table-error-test.db", "1.0", "Demo", DEFAULT_SIZE);
|
||||
expect(db).toBeDefined();
|
||||
|
||||
// VERIFY that an error object was received in the end
|
||||
var sqlerror = null;
|
||||
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql('DROP TABLE IF EXISTS BogusTable');
|
||||
// Attempt to SELECT FROM a bogus table:
|
||||
tx.executeSql('SELECT * FROM BogusTable', [], function(ignored1, ignored2) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
throw new Error('abort tx');
|
||||
|
||||
}, function(tx, error) {
|
||||
sqlerror = error;
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (!isWebSql && (isBrowser || isWindows || (isAndroid && isImpl2)))
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(5);
|
||||
|
||||
if (isWebSql && !(/Android 4.[1-3]/.test(navigator.userAgent)))
|
||||
expect(error.message).toMatch(/could not prepare statement.*1 no such table: BogusTable/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/Error preparing an SQLite statement/);
|
||||
else if (!isWebSql && !isWindows && isAndroid && !isImpl2)
|
||||
expect(error.message).toMatch(/sqlite3_prepare_v2 failure:.*no such table: BogusTable/);
|
||||
else if (!isWebSql && !isWindows && isAndroid && isImpl2)
|
||||
expect(error.message).toMatch(/no such table: BogusTable.*code 1/);
|
||||
else
|
||||
expect(error.message).toMatch(/no such table: BogusTable/);
|
||||
|
||||
// FAIL transaction & check reported transaction error:
|
||||
return true;
|
||||
});
|
||||
}, function (error) {
|
||||
expect(!!sqlerror).toBe(true); // VERIFY the SQL error callback was triggered
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (isWebSql || isBrowser || isWindows || (isAndroid && isImpl2))
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(5);
|
||||
|
||||
if (isWebSql)
|
||||
expect(error.message).toMatch(/callback raised an exception.*or.*error callback did not return false/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/error callback did not return false.*Error preparing an SQLite statement/);
|
||||
else
|
||||
expect(error.message).toMatch(/error callback did not return false.*no such table: BogusTable/);
|
||||
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
}, function() {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'INSERT missing column [INCORRECT error code WebKit Web SQL & plugin]', function(done) {
|
||||
var db = openDatabase("INSERT-missing-column-test.db", "1.0", "Demo", DEFAULT_SIZE);
|
||||
expect(db).toBeDefined();
|
||||
|
||||
// VERIFY that an error object was received in the end
|
||||
var sqlerror = null;
|
||||
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql('DROP TABLE IF EXISTS test_table');
|
||||
tx.executeSql('CREATE TABLE IF NOT EXISTS test_table (data1, data2)');
|
||||
|
||||
tx.executeSql('INSERT INTO test_table VALUES (?)', ['abcdef'], function(tx) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
throw new Error('abort tx');
|
||||
|
||||
}, function(tx, error) {
|
||||
sqlerror = error;
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (!isWebSql && (isBrowser || isWindows || (isAndroid && isImpl2)))
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(5);
|
||||
|
||||
if (isWebSql && !(/Android 4.[1-3]/.test(navigator.userAgent)))
|
||||
expect(error.message).toMatch(/could not prepare statement.*1 table test_table has 2 columns but 1 values were supplied/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/Error preparing an SQLite statement/);
|
||||
else if (!isWebSql && !isWindows && isAndroid && !isImpl2)
|
||||
expect(error.message).toMatch(/sqlite3_prepare_v2 failure:.*table test_table has 2 columns but 1 values were supplied/);
|
||||
else if (!isWebSql && !isWindows && isAndroid && isImpl2)
|
||||
expect(error.message).toMatch(/table test_table has 2 columns but 1 values were supplied.*code 1.*while compiling: INSERT INTO test_table/);
|
||||
else
|
||||
expect(error.message).toMatch(/table test_table has 2 columns but 1 values were supplied/);
|
||||
|
||||
// FAIL transaction & check reported transaction error:
|
||||
return true;
|
||||
});
|
||||
}, function (error) {
|
||||
expect(!!sqlerror).toBe(true); // VERIFY the SQL error callback was triggered
|
||||
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (isWebSql || isBrowser || isWindows || (isAndroid && isImpl2))
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(5);
|
||||
|
||||
if (isWebSql)
|
||||
expect(error.message).toMatch(/callback raised an exception.*or.*error callback did not return false/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/error callback did not return false.*Error preparing an SQLite statement/);
|
||||
else
|
||||
expect(error.message).toMatch(/error callback did not return false.*table test_table has 2 columns but 1 values were supplied/);
|
||||
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
}, function() {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'INSERT wrong column name [INCORRECT error code WebKit Web SQL & plugin]', function(done) {
|
||||
var db = openDatabase("INSERT-wrong-column-name-test.db", "1.0", "Demo", DEFAULT_SIZE);
|
||||
expect(db).toBeDefined();
|
||||
|
||||
// VERIFY that an error object was received in the end
|
||||
var sqlerror = null;
|
||||
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql('DROP TABLE IF EXISTS test_table');
|
||||
tx.executeSql('CREATE TABLE IF NOT EXISTS test_table (data1)');
|
||||
|
||||
tx.executeSql('INSERT INTO test_table (wrong_column) VALUES (?)', ['abcdef'], function(tx) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
throw new Error('abort tx');
|
||||
|
||||
}, function(tx, error) {
|
||||
sqlerror = error;
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (!isWebSql && (isBrowser || isWindows || (isAndroid && isImpl2)))
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(5);
|
||||
|
||||
if (isWebSql && !(/Android 4.[1-3]/.test(navigator.userAgent)))
|
||||
expect(error.message).toMatch(/could not prepare statement.*1 table test_table has no column named wrong_column/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/Error preparing an SQLite statement/);
|
||||
else if (!isWebSql && !isWindows && isAndroid && !isImpl2)
|
||||
expect(error.message).toMatch(/sqlite3_prepare_v2 failure:.*table test_table has no column named wrong_column/);
|
||||
else if (!isWebSql && !isWindows && isAndroid && isImpl2)
|
||||
expect(error.message).toMatch(/table test_table has no column named wrong_column.*code 1.*while compiling: INSERT INTO test_table/);
|
||||
else
|
||||
expect(error.message).toMatch(/table test_table has no column named wrong_column/);
|
||||
|
||||
// FAIL transaction & check reported transaction error:
|
||||
return true;
|
||||
});
|
||||
}, function (error) {
|
||||
expect(!!sqlerror).toBe(true); // VERIFY the SQL error callback was triggered
|
||||
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (isWebSql || isBrowser || isWindows || (isAndroid && isImpl2))
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(5);
|
||||
|
||||
if (isWebSql)
|
||||
expect(error.message).toMatch(/callback raised an exception.*or.*error callback did not return false/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/error callback did not return false.*Error preparing an SQLite statement/);
|
||||
else
|
||||
expect(error.message).toMatch(/error callback did not return false.*table test_table has no column named wrong_column/);
|
||||
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
}, function() {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
// NOTE: For some reason the Android/iOS (WebKit) Web SQL implementation
|
||||
// claims to detect the error at the "prepare statement" stage while the
|
||||
// plugin detects the error at the "execute statement" stage.
|
||||
it(suiteName + 'CREATE VIRTUAL TABLE USING bogus module (other database error) [INCORRECT error code WebKit Web SQL & plugin]', function(done) {
|
||||
var db = openDatabase("create-virtual-table-using-bogus-module-error-test.db", "1.0", "Demo", DEFAULT_SIZE);
|
||||
expect(db).toBeDefined();
|
||||
|
||||
// VERIFY that an error object was received in the end
|
||||
var sqlerror = null;
|
||||
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql('DROP TABLE IF EXISTS test_table');
|
||||
// Attempt to use a bogus module:
|
||||
tx.executeSql('CREATE VIRTUAL TABLE test_table USING bogus_module (data)', [], function(ignored1, ignored2) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
throw new Error('abort tx');
|
||||
|
||||
}, function(tx, error) {
|
||||
sqlerror = error;
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (!isWebSql && (isBrowser || isWindows || (isAndroid && isImpl2)))
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(5);
|
||||
|
||||
if (isWebSql && isAndroid && !(/Android 4.[1-3]/.test(navigator.userAgent)))
|
||||
expect(error.message).toMatch(/could not prepare statement.*not authorized/);
|
||||
else if (isWebSql && isAndroid)
|
||||
expect(error.message).toMatch(/not authorized/);
|
||||
else if (isWebSql && (isBrowser && (/Chrome/.test(navigator.userAgent))))
|
||||
expect(error.message).toMatch(/could not prepare statement.*23 not authorized/);
|
||||
else if (isWebSql) // [iOS (WebKit) Web SQL]
|
||||
expect(error.message).toMatch(/could not prepare statement.*1 not authorized/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/SQLite3 step error result code: 1/);
|
||||
else if (isAndroid && !isImpl2)
|
||||
expect(error.message).toMatch(/sqlite3_step failure: no such module: bogus/);
|
||||
else if (isAndroid && isImpl2)
|
||||
expect(error.message).toMatch(/no such module: bogus.*code 1/);
|
||||
else
|
||||
expect(error.message).toMatch(/no such module: bogus/);
|
||||
|
||||
// FAIL transaction & check reported transaction error:
|
||||
return true;
|
||||
});
|
||||
}, function (error) {
|
||||
expect(!!sqlerror).toBe(true); // VERIFY the SQL error callback was triggered
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (isWebSql || isBrowser || isWindows || (isAndroid && isImpl2))
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(5);
|
||||
|
||||
if (isWebSql)
|
||||
expect(error.message).toMatch(/callback raised an exception.*or.*error callback did not return false/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/error callback did not return false.*SQLite3 step error result code: 1/);
|
||||
else
|
||||
expect(error.message).toMatch(/error callback did not return false.*no such module: bogus/);
|
||||
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
}, function() {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
// TESTS with no SQL error handler:
|
||||
|
||||
it(suiteName + 'transaction.executeSql syntax error (command with misspelling) with no SQL error handler', function(done) {
|
||||
db = openDatabase('tx-sql-syntax-error-with-no-sql-error-handler-test.db');
|
||||
db.transaction(function(transaction) {
|
||||
transaction.executeSql('SLCT 1');
|
||||
}, function(error) {
|
||||
// EXPECTED RESULT:
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (!isWebSql && (isBrowser || isWindows || (isAndroid && isImpl2)))
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(5);
|
||||
|
||||
if (isWebSql && !(/Android 4.[1-3]/.test(navigator.userAgent)))
|
||||
expect(error.message).toMatch(/could not prepare statement.*1 near \"SLCT\": syntax error/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/a statement with no error handler failed: Error preparing an SQLite statement/);
|
||||
else if (!isWebSql && !isWindows && isAndroid && !isImpl2)
|
||||
expect(error.message).toMatch(/sqlite3_prepare_v2 failure:.*near \"SLCT\": syntax error/);
|
||||
else if (!isWebSql && !isWindows && isAndroid && isImpl2)
|
||||
expect(error.message).toMatch(/a statement with no error handler failed: near \"SLCT\": syntax error.*code 1.*while compiling: SLCT 1/);
|
||||
else if (!isWebSql) // [iOS/macOS plugin]
|
||||
expect(error.message).toMatch(/a statement with no error handler failed.*near \"SLCT\": syntax error/);
|
||||
else
|
||||
expect(error.message).toMatch(/near \"SLCT\": syntax error/);
|
||||
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
}, function() {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
})
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'transaction.executeSql constraint violation with no SQL error handler', function(done) {
|
||||
var db = openDatabase("Constraint-violation-with-no-sql-error-handler.db", "1.0", "Demo", DEFAULT_SIZE);
|
||||
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql('DROP TABLE IF EXISTS test_table');
|
||||
tx.executeSql('CREATE TABLE IF NOT EXISTS test_table (data unique)');
|
||||
|
||||
// First INSERT OK:
|
||||
tx.executeSql('INSERT INTO test_table (data) VALUES (?)', [123]);
|
||||
// Second INSERT will violate the unique constraint:
|
||||
tx.executeSql('INSERT INTO test_table (data) VALUES (?)', [123]);
|
||||
}, function (error) {
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
if (isWebSql && (!isAndroid || /Android 4.[1-3]/.test(navigator.userAgent)))
|
||||
expect(true).toBe(true); // SKIP for iOS (WebKit) & Android 4.1-4.3 (WebKit) Web SQL
|
||||
else if (isBrowser || isWindows)
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(6);
|
||||
|
||||
// (WebKit) Web SQL (Android/iOS) possibly with a missing 'r'
|
||||
if (isWebSql && /Android 4.[1-3]/.test(navigator.userAgent))
|
||||
expect(error.message).toMatch(/column data is not unique/);
|
||||
else if (isWebSql && isAndroid)
|
||||
expect(error.message).toMatch(/could not execute statement due to a constr?aint failure.*19.*constraint failed/);
|
||||
else if (isWebSql)
|
||||
expect(error.message).toMatch(/constr?aint fail/);
|
||||
else if (isWindows)
|
||||
expect(error.message).toMatch(/a statement with no error handler failed: SQLite3 step error result code: 1/);
|
||||
else if (isAndroid && !isImpl2)
|
||||
expect(error.message).toMatch(/a statement with no error handler failed: sqlite3_step failure: UNIQUE constraint failed: test_table\.data/);
|
||||
else if (isAndroid && isImpl2)
|
||||
expect(error.message).toMatch(/a statement with no error handler failed:.*constraint failure/);
|
||||
else if (isBrowser)
|
||||
expect(error.message).toMatch(/a statement with no error handler failed: Error: UNIQUE constraint failed: test_table\.data/);
|
||||
else
|
||||
expect(error.message).toMatch(/a statement with no error handler failed: UNIQUE constraint failed: test_table\.data/);
|
||||
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
}, function() {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
isWebSql ? done() : db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (window.hasBrowser) mytests();
|
||||
else exports.defineAutoTests = mytests;
|
||||
|
||||
/* vim: set expandtab : */
|
116
node_modules/cordova-sqlite-storage/spec/www/spec/db-tx-multiple-update-test.js
generated
vendored
Normal file
116
node_modules/cordova-sqlite-storage/spec/www/spec/db-tx-multiple-update-test.js
generated
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
/* 'use strict'; */
|
||||
|
||||
var MYTIMEOUT = 12000;
|
||||
|
||||
// NOTE: DEFAULT_SIZE wanted depends on type of browser
|
||||
|
||||
var isWindows = /MSAppHost/.test(navigator.userAgent);
|
||||
var isAndroid = !isWindows && /Android/.test(navigator.userAgent);
|
||||
var isFirefox = /Firefox/.test(navigator.userAgent);
|
||||
var isWebKitBrowser = !isWindows && !isAndroid && /Safari/.test(navigator.userAgent);
|
||||
var isBrowser = isWebKitBrowser || isFirefox;
|
||||
var isEdgeBrowser = isBrowser && (/Edge/.test(navigator.userAgent));
|
||||
var isChromeBrowser = isBrowser && !isEdgeBrowser && (/Chrome/.test(navigator.userAgent));
|
||||
var isSafariBrowser = isWebKitBrowser && !isEdgeBrowser && !isChromeBrowser;
|
||||
|
||||
// should avoid popups (Safari seems to count 2x)
|
||||
var DEFAULT_SIZE = isSafariBrowser ? 2000000 : 5000000;
|
||||
// FUTURE TBD: 50MB should be OK on Chrome and some other test browsers.
|
||||
|
||||
// NOTE: While in certain version branches there is no difference between
|
||||
// the default Android implementation and implementation #2,
|
||||
// this test script will also apply the androidLockWorkaround: 1 option
|
||||
// in case of implementation #2.
|
||||
var scenarioList = [
|
||||
isAndroid ? 'Plugin-implementation-default' : 'Plugin',
|
||||
'HTML5',
|
||||
'Plugin-implementation-2'
|
||||
];
|
||||
|
||||
var scenarioCount = (!!window.hasWebKitWebSQL) ? (isAndroid ? 3 : 2) : 1;
|
||||
|
||||
var mytests = function() {
|
||||
|
||||
for (var i=0; i<scenarioCount; ++i) {
|
||||
|
||||
describe(scenarioList[i] + ': db tx multiple update test(s)', function() {
|
||||
var scenarioName = scenarioList[i];
|
||||
var suiteName = scenarioName + ': ';
|
||||
var isWebSql = (i === 1);
|
||||
var isImpl2 = (i === 2);
|
||||
|
||||
// NOTE: MUST be defined in function scope, NOT outer scope:
|
||||
var openDatabase = function(name, ignored1, ignored2, ignored3) {
|
||||
if (isImpl2) {
|
||||
return window.sqlitePlugin.openDatabase({
|
||||
// prevent reuse of database from default db implementation:
|
||||
name: 'i2-'+name,
|
||||
androidDatabaseImplementation: 2,
|
||||
androidLockWorkaround: 1,
|
||||
location: 1
|
||||
});
|
||||
}
|
||||
if (isWebSql) {
|
||||
return window.openDatabase(name, "1.0", "Demo", DEFAULT_SIZE);
|
||||
} else {
|
||||
return window.sqlitePlugin.openDatabase({name: name, location: 0});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ref: litehelpers/Cordova-sqlite-storage#128
|
||||
// Was caused by a failure to create temporary transaction files on WP8.
|
||||
// Workaround by Mark Oppenheim mailto:mark.oppenheim@mnetics.co.uk
|
||||
// solved the issue for WP8.
|
||||
// @brodybits noticed similar issue possible with Android-sqlite-connector
|
||||
// if the Android-sqlite-native-driver part is not built correctly.
|
||||
it(suiteName + 'Multiple updates with key (evidently needs temporary transaction files to work)', function (done) {
|
||||
// if (!isWebSql && isBrowser) pending('NOT WORKING on browser plugin'); // XXX TBD
|
||||
var db = openDatabase("MultipleUpdatesWithKey", "1.0",
|
||||
"Demo", DEFAULT_SIZE);
|
||||
|
||||
var updateSuccessCount = 0;
|
||||
|
||||
db.transaction(function (tx) {
|
||||
tx.executeSql('DROP TABLE IF EXISTS Task');
|
||||
tx.executeSql('CREATE TABLE IF NOT EXISTS Task (id primary key, subject)');
|
||||
tx.executeSql('INSERT INTO Task VALUES (?,?)', ['928238b3-a227-418f-aa15-12bb1943c1f2', 'test1']);
|
||||
tx.executeSql('INSERT INTO Task VALUES (?,?)', ['511e3fb7-5aed-4c1a-b1b7-96bf9c5012e2', 'test2']);
|
||||
|
||||
tx.executeSql('UPDATE Task SET subject="Send reminder", id="928238b3-a227-418f-aa15-12bb1943c1f2" WHERE id = "928238b3-a227-418f-aa15-12bb1943c1f2"', [], function(tx, res) {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.rowsAffected).toEqual(1);
|
||||
check1 = true;
|
||||
++updateSuccessCount;
|
||||
}, function (error) {
|
||||
// NOT EXPECTED:
|
||||
expect('1st update failed ' + error.message).toBe(true);
|
||||
});
|
||||
|
||||
tx.executeSql('UPDATE Task SET subject="Task", id="511e3fb7-5aed-4c1a-b1b7-96bf9c5012e2" WHERE id = "511e3fb7-5aed-4c1a-b1b7-96bf9c5012e2"', [], function(tx, res) {
|
||||
expect(res.rowsAffected).toEqual(1);
|
||||
++updateSuccessCount;
|
||||
}, function (error) {
|
||||
// NOT EXPECTED:
|
||||
expect('2nd update failed ' + error.message).toBe('--');
|
||||
});
|
||||
}, function (error) {
|
||||
// NOT EXPECTED:
|
||||
expect('transaction failed: ' + error.message).toBe('--');
|
||||
done.fail();
|
||||
}, function () {
|
||||
// transaction committed ok:
|
||||
expect(updateSuccessCount).toBe(2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (window.hasBrowser) mytests();
|
||||
else exports.defineAutoTests = mytests;
|
||||
|
||||
/* vim: set expandtab : */
|
376
node_modules/cordova-sqlite-storage/spec/www/spec/db-tx-sql-features-test.js
generated
vendored
Normal file
376
node_modules/cordova-sqlite-storage/spec/www/spec/db-tx-sql-features-test.js
generated
vendored
Normal file
@ -0,0 +1,376 @@
|
||||
/* 'use strict'; */
|
||||
|
||||
var MYTIMEOUT = 20000;
|
||||
|
||||
// NOTE: DEFAULT_SIZE wanted depends on type of browser
|
||||
|
||||
var isWindows = /MSAppHost/.test(navigator.userAgent);
|
||||
var isAndroid = !isWindows && /Android/.test(navigator.userAgent);
|
||||
var isFirefox = /Firefox/.test(navigator.userAgent);
|
||||
var isWebKitBrowser = !isWindows && !isAndroid && /Safari/.test(navigator.userAgent);
|
||||
var isBrowser = isWebKitBrowser || isFirefox;
|
||||
var isEdgeBrowser = isBrowser && (/Edge/.test(navigator.userAgent));
|
||||
var isChromeBrowser = isBrowser && !isEdgeBrowser && (/Chrome/.test(navigator.userAgent));
|
||||
var isSafariBrowser = isWebKitBrowser && !isEdgeBrowser && !isChromeBrowser;
|
||||
var isMac = !isBrowser && /Macintosh/.test(navigator.userAgent);
|
||||
var isAppleMobileOS = /iPhone/.test(navigator.userAgent) ||
|
||||
/iPad/.test(navigator.userAgent) || /iPod/.test(navigator.userAgent);
|
||||
|
||||
// should avoid popups (Safari seems to count 2x)
|
||||
var DEFAULT_SIZE = isSafariBrowser ? 2000000 : 5000000;
|
||||
// FUTURE TBD: 50MB should be OK on Chrome and some other test browsers.
|
||||
|
||||
// NOTE: While in certain version branches there is no difference between
|
||||
// the default Android implementation and implementation #2,
|
||||
// this test script will also apply the androidLockWorkaround: 1 option
|
||||
// in case of implementation #2.
|
||||
var scenarioList = [
|
||||
isAndroid ? 'Plugin-implementation-default' : 'Plugin',
|
||||
'HTML5',
|
||||
'Plugin-implementation-2'
|
||||
];
|
||||
|
||||
var scenarioCount = (!!window.hasWebKitWebSQL) ? (isAndroid ? 3 : 2) : 1;
|
||||
|
||||
var mytests = function() {
|
||||
|
||||
for (var i=0; i<scenarioCount; ++i) {
|
||||
|
||||
describe(scenarioList[i] + ': db tx sql features test(s)', function() {
|
||||
var scenarioName = scenarioList[i];
|
||||
var suiteName = scenarioName + ': ';
|
||||
var isWebSql = (i === 1);
|
||||
var isImpl2 = (i === 2);
|
||||
|
||||
// NOTE: MUST be defined in proper describe function scope, NOT outer scope:
|
||||
var openDatabase = function(name, ignored1, ignored2, ignored3) {
|
||||
if (isImpl2) {
|
||||
return window.sqlitePlugin.openDatabase({
|
||||
// prevent reuse of database from default db implementation:
|
||||
name: 'i2-'+name,
|
||||
androidDatabaseImplementation: 2,
|
||||
androidLockWorkaround: 1,
|
||||
location: 1
|
||||
});
|
||||
}
|
||||
if (isWebSql) {
|
||||
return window.openDatabase(name, '1.0', 'Test', DEFAULT_SIZE);
|
||||
} else {
|
||||
return window.sqlitePlugin.openDatabase({name: name, location: 0});
|
||||
}
|
||||
}
|
||||
|
||||
// Known to work with:
|
||||
// - iOS 9 Web SQL
|
||||
// - Android (default Android-sqlite-connector implementation)
|
||||
// - iOS & Windows (with newer sqlite3 build)
|
||||
it(suiteName + 'db readTransaction with a WITH clause', function(done) {
|
||||
if (isWebSql && !isBrowser) pending('SKIP for Android/iOS (WebKit) Web SQL'); // XXX TBD NOT WORKING on all Android/iOS versions
|
||||
if (isAndroid && isImpl2) pending('SKIP for android.database implementation'); // NOT WORKING on all versions
|
||||
|
||||
var db = openDatabase('tx-with-a-with-clause-test.db', '1.0', 'Test', DEFAULT_SIZE);
|
||||
|
||||
db.readTransaction(function(tx) {
|
||||
tx.executeSql('WITH one(x) AS (SELECT 1) SELECT x FROM one;');
|
||||
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(JSON.stringify(error)).toBe('---');
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
|
||||
}, function() {
|
||||
// EXPECTED RESULT:
|
||||
expect(true).toBe(true);
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
});
|
||||
|
||||
}, MYTIMEOUT);
|
||||
|
||||
/* THANKS to @calebeaires: */
|
||||
it(suiteName + 'create virtual table using FTS3', function(done) {
|
||||
if (isWebSql && isSafariBrowser) pending('SKIP for (WebKit) Web SQL on Safari browser');
|
||||
if (isWebSql && isAndroid) pending('SKIP for Android Web SQL');
|
||||
if (isWebSql && isAppleMobileOS && (/OS 1[1-9]/.test(navigator.userAgent))) pending('SKIP (WebKit) Web SQL on iOS 11(+)');
|
||||
|
||||
var db = openDatabase('virtual-table-using-fts3.db', '1.0', 'Test', DEFAULT_SIZE);
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
var isCreateOK = false;
|
||||
var createError = null;
|
||||
|
||||
db.transaction(function(tx) {
|
||||
expect(tx).toBeDefined();
|
||||
|
||||
//tx.executeSql('CREATE INDEX liv_index ON book (liv, cap);');
|
||||
tx.executeSql('DROP TABLE IF EXISTS virtual_book');
|
||||
tx.executeSql('CREATE VIRTUAL TABLE IF NOT EXISTS virtual_book USING FTS3 (liv, cap, ver, tex, tes);', [], function(tx_ignored, rs_ignored) {
|
||||
// CREATE OK:
|
||||
expect(true).toBe(true);
|
||||
isCreateOK = true;
|
||||
}, function(tx_ignored, error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(JSON.stringify(error)).toBe('---');
|
||||
createError = error;
|
||||
return true; // report error for both Web SQL & plugin
|
||||
});
|
||||
|
||||
}, function(err) {
|
||||
// NOTE: CREATE ERROR should have already been reported above.
|
||||
expect(createError).toBeDefined();
|
||||
expect(createError).not.toBeNull();
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
|
||||
}, function() {
|
||||
// EXPECTED RESULT (verify CREATE was ok):
|
||||
expect(isCreateOK).toBe(true);
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
// NOTE: looking at sqlite3.c (newer versions), if FTS3 is enabled,
|
||||
// FTS4 seems to be working as well!
|
||||
// (thanks again to @calebeaires for this scenario)
|
||||
it(suiteName + 'create virtual table using FTS4', function(done) {
|
||||
if (isWebSql) pending('SKIP for Web SQL');
|
||||
|
||||
var db = openDatabase('virtual-table-using-fts4.db', '1.0', 'Test', DEFAULT_SIZE);
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
var isCreateOK = false;
|
||||
var createError = null;
|
||||
|
||||
db.transaction(function(tx) {
|
||||
expect(tx).toBeDefined();
|
||||
|
||||
//tx.executeSql('CREATE INDEX liv_index ON book (liv, cap);');
|
||||
tx.executeSql('DROP TABLE IF EXISTS virtual_book');
|
||||
tx.executeSql('CREATE VIRTUAL TABLE IF NOT EXISTS virtual_book USING FTS4 (liv, cap, ver, tex, tes);', [], function(tx_ignored, rs_ignored) {
|
||||
// CREATE OK:
|
||||
expect(true).toBe(true);
|
||||
isCreateOK = true;
|
||||
}, function(tx_ignored, error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(JSON.stringify(error)).toBe('---');
|
||||
createError = error;
|
||||
return true; // report error for both Web SQL & plugin
|
||||
});
|
||||
|
||||
}, function(err) {
|
||||
// NOTE: CREATE ERROR should have already been reported above.
|
||||
expect(createError).toBeDefined();
|
||||
expect(createError).not.toBeNull();
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
|
||||
}, function() {
|
||||
// EXPECTED RESULT (verify CREATE was ok):
|
||||
expect(isCreateOK).toBe(true);
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
// now enabled by default in recent SQLite versions
|
||||
// as spotted in sql.js update history
|
||||
it(suiteName + 'Basic JSON1 json test', function(done) {
|
||||
if (isWebSql || isImpl2) pending('SKIP ...'); // XXX TBD ...
|
||||
|
||||
var db = openDatabase('basic-json1-json-test.db', '1.0', 'Test', DEFAULT_SIZE);
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.transaction(function(tx) {
|
||||
|
||||
expect(tx).toBeDefined();
|
||||
|
||||
// Derived from sample in: https://www.sqlite.org/json1.html
|
||||
tx.executeSql("SELECT json(?) AS my_json;", [' { "this" : "is", "a": [ "test" ] } '], function(tx, res) {
|
||||
expect(res.rows.item(0).my_json).toEqual('{"this":"is","a":["test"]}');
|
||||
//done();
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
}, function(tx, e) {
|
||||
// NOT EXPECTED (went wrong):
|
||||
expect(false).toBe(true);
|
||||
expect(JSON.stringify(e)).toBe('--');
|
||||
//done();
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
});
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
// now enabled by default in recent SQLite versions
|
||||
// as spotted in sql.js update history
|
||||
it(suiteName + 'JSON1 json_object test', function(done) {
|
||||
if (isWebSql || isImpl2) pending('SKIP ...'); // XXX TBD ...
|
||||
|
||||
var db = openDatabase('json1-json-object-test.db', '1.0', 'Test', DEFAULT_SIZE);
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.transaction(function(tx) {
|
||||
expect(tx).toBeDefined();
|
||||
|
||||
// Derived from sample in: https://www.sqlite.org/json1.html
|
||||
tx.executeSql("SELECT json_object(?,?) AS my_object;", ['ex','[52,3.14159]'], function(tx, res) {
|
||||
// EXPECTED RESULT:
|
||||
expect(res.rows.item(0).my_object).toEqual('{"ex":"[52,3.14159]"}');
|
||||
//done();
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
|
||||
}, function(tx, e) {
|
||||
// NOT EXPECTED (went wrong):
|
||||
expect(false).toBe(true);
|
||||
expect(JSON.stringify(e)).toBe('--');
|
||||
//done();
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
});
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
// Test for Cordova-sqlcipher-adapter version (SQLCipher 3.4.0 based on SQLite 3.11.0)
|
||||
it(suiteName + 'create virtual table using FTS5', function(done) {
|
||||
//if (isWebSql) pending('SKIP for Web SQL (not implemented)');
|
||||
pending('SKIP: NOT IMPLEMENTED for this version');
|
||||
|
||||
var db = openDatabase('virtual-table-using-fts5.db', '1.0', 'Test', DEFAULT_SIZE);
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
var isCreateOK = false;
|
||||
var createError = null;
|
||||
|
||||
db.transaction(function(tx) {
|
||||
expect(tx).toBeDefined();
|
||||
|
||||
//tx.executeSql('CREATE INDEX liv_index ON book (liv, cap);');
|
||||
tx.executeSql('DROP TABLE IF EXISTS virtual_book');
|
||||
tx.executeSql('CREATE VIRTUAL TABLE IF NOT EXISTS virtual_book USING FTS5 (liv, cap, ver, tex, tes);', [], function(tx, res) {
|
||||
// EXPECTED RESULT:
|
||||
expect(true).toBe(true);
|
||||
isCreateOK = true;
|
||||
}, function(tx, error) {
|
||||
// NOT EXPECTED (went wrong):
|
||||
expect(false).toBe(true);
|
||||
expect(JSON.stringify(error)).toBe('---');
|
||||
createError = error;
|
||||
return true; // report error for both Web SQL & plugin
|
||||
});
|
||||
|
||||
}, function(err) {
|
||||
// NOTE: CREATE ERROR should have already been reported above.
|
||||
expect(createError).toBeDefined();
|
||||
expect(createError).not.toBeNull();
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
|
||||
}, function() {
|
||||
// EXPECTED RESULT (verify CREATE was ok):
|
||||
expect(isCreateOK).toBe(true);
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'create virtual table using R-Tree', function(done) {
|
||||
if (isWebSql) pending('SKIP for Web SQL');
|
||||
if (isAndroid && isImpl2) pending('NOT IMPLEMENTED for all versions of android.database'); // NOT IMPLEMENTED for all versions of Android database (failed in Circle CI)
|
||||
if (!isWebSql && isBrowser) pending('NOT IMPLEMENTED on plugin for browser platform'); // FUTURE TODO
|
||||
|
||||
var db = openDatabase('virtual-table-using-r-tree.db', '1.0', 'Test', DEFAULT_SIZE);
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
var isCreateOK = false;
|
||||
var createError = null;
|
||||
|
||||
db.transaction(function(tx) {
|
||||
expect(tx).toBeDefined();
|
||||
|
||||
tx.executeSql('DROP TABLE IF EXISTS demo_index');
|
||||
// from https://www.sqlite.org/rtree.html
|
||||
tx.executeSql('CREATE VIRTUAL TABLE IF NOT EXISTS demo_index USING rtree (id, minX, maxX, minY, maxY);', [], function(tx, res) {
|
||||
// EXPECTED RESULT:
|
||||
expect(true).toBe(true);
|
||||
isCreateOK = true;
|
||||
}, function(err) {
|
||||
// NOT EXPECTED (went wrong):
|
||||
expect(false).toBe(true);
|
||||
expect(JSON.stringify(e)).toBe('--');
|
||||
createError = error;
|
||||
});
|
||||
|
||||
}, function(err) {
|
||||
// NOTE: CREATE ERROR should have already been reported above.
|
||||
expect(createError).toBeDefined();
|
||||
expect(createError).not.toBeNull();
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
|
||||
}, function() {
|
||||
// EXPECTED RESULT (verify CREATE was ok):
|
||||
expect(isCreateOK).toBe(true);
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
// NOTE: NOT supported by SQLite amalgamation.
|
||||
// SQLite amalgamation must be rebuilt with
|
||||
// SQLITE_ENABLE_UPDATE_DELETE_LIMIT defined
|
||||
// for this feature to work.
|
||||
xit(suiteName + 'DELETE LIMIT', function(done) {
|
||||
if (isWebSql) pending('SKIP for Web SQL (NOT IMPLEMENTED)');
|
||||
if (isWindows) pending('NOT IMPLEMENTED for Windows');
|
||||
if (isAndroid && !isWebSql) pending('SKIP for Android plugin'); // FUTURE TBD test with newer versions (android.database)
|
||||
if (isAppleMobileOS || isMac) pending('SKIP for iOS/macOS'); // NOT WORKING on any versions of iOS/macOS (plugin or Web SQL)
|
||||
|
||||
var db = openDatabase('delete-limit-test.db', '1.0', 'Test', DEFAULT_SIZE);
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.transaction(function(tx) {
|
||||
expect(tx).toBeDefined();
|
||||
|
||||
tx.executeSql('CREATE TABLE TT(C);');
|
||||
tx.executeSql('INSERT INTO TT VALUES (?),(?),(?),(?),(?);', [1,2,3,4,5]);
|
||||
tx.executeSql('DELETE FROM TT LIMIT 3;', [], function(tx, res) {
|
||||
tx.executeSql('SELECT * FROM TT;', [], function(tx, res) {
|
||||
// EXPECTED RESULT:
|
||||
expect(true).toBe(true);
|
||||
expect(res.rows.length).toBe(2);
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
});
|
||||
|
||||
}, function(tx, err) {
|
||||
// NOT EXPECTED (went wrong):
|
||||
expect(false).toBe(true);
|
||||
expect(JSON.stringify(err)).toBe('--');
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
});
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (window.hasBrowser) mytests();
|
||||
else exports.defineAutoTests = mytests;
|
||||
|
||||
/* vim: set expandtab : */
|
1885
node_modules/cordova-sqlite-storage/spec/www/spec/db-tx-sql-select-value-test.js
generated
vendored
Normal file
1885
node_modules/cordova-sqlite-storage/spec/www/spec/db-tx-sql-select-value-test.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3004
node_modules/cordova-sqlite-storage/spec/www/spec/db-tx-string-test.js
generated
vendored
Normal file
3004
node_modules/cordova-sqlite-storage/spec/www/spec/db-tx-string-test.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1763
node_modules/cordova-sqlite-storage/spec/www/spec/db-tx-value-bindings-test.js
generated
vendored
Normal file
1763
node_modules/cordova-sqlite-storage/spec/www/spec/db-tx-value-bindings-test.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
123
node_modules/cordova-sqlite-storage/spec/www/spec/ext-tx-blob-test.js
generated
vendored
Normal file
123
node_modules/cordova-sqlite-storage/spec/www/spec/ext-tx-blob-test.js
generated
vendored
Normal file
@ -0,0 +1,123 @@
|
||||
/* 'use strict'; */
|
||||
|
||||
var MYTIMEOUT = 12000;
|
||||
|
||||
// NOTE: DEFAULT_SIZE wanted depends on type of browser
|
||||
|
||||
var isWindows = /MSAppHost/.test(navigator.userAgent);
|
||||
var isAndroid = !isWindows && /Android/.test(navigator.userAgent);
|
||||
var isFirefox = /Firefox/.test(navigator.userAgent);
|
||||
var isWebKitBrowser = !isWindows && !isAndroid && /Safari/.test(navigator.userAgent);
|
||||
var isBrowser = isWebKitBrowser || isFirefox;
|
||||
var isEdgeBrowser = isBrowser && (/Edge/.test(navigator.userAgent));
|
||||
var isChromeBrowser = isBrowser && !isEdgeBrowser && (/Chrome/.test(navigator.userAgent));
|
||||
var isSafariBrowser = isWebKitBrowser && !isEdgeBrowser && !isChromeBrowser;
|
||||
|
||||
// should avoid popups (Safari seems to count 2x)
|
||||
var DEFAULT_SIZE = isSafariBrowser ? 2000000 : 5000000;
|
||||
// FUTURE TBD: 50MB should be OK on Chrome and some other test browsers.
|
||||
|
||||
// NOTE: While in certain version branches there is no difference between
|
||||
// the default Android implementation and implementation #2,
|
||||
// this test script will also apply the androidLockWorkaround: 1 option
|
||||
// in case of implementation #2.
|
||||
var scenarioList = [
|
||||
isAndroid ? 'Plugin-implementation-default' : 'Plugin',
|
||||
'HTML5',
|
||||
'Plugin-implementation-2'
|
||||
];
|
||||
|
||||
var scenarioCount = (!!window.hasWebKitWebSQL) ? (isAndroid ? 3 : 2) : 1;
|
||||
|
||||
var mytests = function() {
|
||||
|
||||
for (var i=0; i<scenarioCount; ++i) {
|
||||
|
||||
describe(scenarioList[i] + ': ext tx blob test(s)', function() {
|
||||
var scenarioName = scenarioList[i];
|
||||
var suiteName = scenarioName + ': ';
|
||||
var isWebSql = (i === 1);
|
||||
var isImpl2 = (i === 2);
|
||||
|
||||
// NOTE: MUST be defined in function scope, NOT outer scope:
|
||||
var openDatabase = function(name, ignored1, ignored2, ignored3) {
|
||||
if (isImpl2) {
|
||||
return window.sqlitePlugin.openDatabase({
|
||||
// prevent reuse of database from default db implementation:
|
||||
name: 'i2-'+name,
|
||||
// explicit database location:
|
||||
location: 'default',
|
||||
androidDatabaseImplementation: 2,
|
||||
androidLockWorkaround: 1
|
||||
});
|
||||
}
|
||||
if (isWebSql) {
|
||||
return window.openDatabase(name, '1.0', 'Test', DEFAULT_SIZE);
|
||||
} else {
|
||||
// explicit database location:
|
||||
return window.sqlitePlugin.openDatabase({name: name, location: 'default'});
|
||||
}
|
||||
}
|
||||
|
||||
describe(scenarioList[i] + ': Blob object test(s)', function() {
|
||||
|
||||
// This test shows that the plugin does not throw an error when trying to serialize
|
||||
// a non-standard parameter type. Blob becomes an empty dictionary on iOS, for example,
|
||||
// and so this verifies the type is converted to a string and continues. Web SQL does
|
||||
// the same but on the JavaScript side and converts to a string like `[object Blob]`.
|
||||
it(suiteName + "INSERT Blob from ArrayBuffer (non-standard parameter type)", function(done) {
|
||||
if (/Android 4.[1-3]/.test(navigator.userAgent)) pending('SKIP for Android 4.1-4.3');
|
||||
|
||||
// IMPORTANT:
|
||||
if (typeof Blob === "undefined") pending('Blob type does not exist');
|
||||
|
||||
// SKIP this test if ArrayBuffer is undefined
|
||||
// TODO: consider trying this for multiple non-standard parameter types instead
|
||||
if (typeof ArrayBuffer === "undefined") pending('ArrayBuffer type does not exist');
|
||||
|
||||
var db = openDatabase('Blob-object-from-ArrayBuffer-test.db');
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.transaction(function(tx) {
|
||||
expect(tx).toBeDefined();
|
||||
|
||||
var buffer = new ArrayBuffer(5);
|
||||
var view = new Uint8Array(buffer);
|
||||
view[0] = 'h'.charCodeAt();
|
||||
view[1] = 'e'.charCodeAt();
|
||||
view[2] = 'l'.charCodeAt();
|
||||
view[3] = 'l'.charCodeAt();
|
||||
view[4] = 'o'.charCodeAt();
|
||||
var blob = new Blob([view.buffer], { type:"application/octet-stream" });
|
||||
|
||||
tx.executeSql('DROP TABLE IF EXISTS test_table');
|
||||
tx.executeSql('CREATE TABLE IF NOT EXISTS test_table (foo blob)');
|
||||
tx.executeSql('INSERT INTO test_table VALUES (?)', [blob], function(txIgnored, rs) {
|
||||
// EXPECTED RESULT:
|
||||
expect(rs).toBeDefined();
|
||||
done();
|
||||
}, function(tx, error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
done();
|
||||
});
|
||||
}, function(err) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(err.message).toBe('--');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (window.hasBrowser) mytests();
|
||||
else exports.defineAutoTests = mytests;
|
||||
|
||||
/* vim: set expandtab : */
|
97
node_modules/cordova-sqlite-storage/spec/www/spec/regexp-test.js
generated
vendored
Normal file
97
node_modules/cordova-sqlite-storage/spec/www/spec/regexp-test.js
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
/* 'use strict'; */
|
||||
|
||||
var MYTIMEOUT = 12000;
|
||||
|
||||
// NOTE: DEFAULT_SIZE wanted depends on type of browser
|
||||
|
||||
// Detect actual platform:
|
||||
var isWindows = /MSAppHost/.test(navigator.userAgent);
|
||||
var isAndroid = !isWindows && /Android/.test(navigator.userAgent);
|
||||
var isFirefox = /Firefox/.test(navigator.userAgent);
|
||||
var isWebKitBrowser = !isWindows && !isAndroid && /Safari/.test(navigator.userAgent);
|
||||
var isBrowser = isWebKitBrowser || isFirefox;
|
||||
var isEdgeBrowser = isBrowser && (/Edge/.test(navigator.userAgent));
|
||||
var isChromeBrowser = isBrowser && !isEdgeBrowser && (/Chrome/.test(navigator.userAgent));
|
||||
var isSafariBrowser = isWebKitBrowser && !isEdgeBrowser && !isChromeBrowser;
|
||||
var isMac = !isBrowser && /Macintosh/.test(navigator.userAgent);
|
||||
var isAppleMobileOS = /iPhone/.test(navigator.userAgent) ||
|
||||
/iPad/.test(navigator.userAgent) || /iPod/.test(navigator.userAgent);
|
||||
|
||||
// should avoid popups (Safari seems to count 2x)
|
||||
var DEFAULT_SIZE = isSafariBrowser ? 2000000 : 5000000;
|
||||
// FUTURE TBD: 50MB should be OK on Chrome and some other test browsers.
|
||||
|
||||
var scenarioList = [ isAndroid ? 'Plugin-implementation-default' : 'Plugin', 'HTML5', 'Plugin-implementation-2' ];
|
||||
|
||||
var scenarioCount = (!!window.hasWebKitWebSQL) ? (isAndroid ? 3 : 2) : 1;
|
||||
|
||||
var mytests = function() {
|
||||
|
||||
for (var i=0; i<scenarioCount; ++i) {
|
||||
|
||||
describe(scenarioList[i] + ': REGEX test(s)', function() {
|
||||
var scenarioName = scenarioList[i];
|
||||
var suiteName = scenarioName + ': ';
|
||||
var isWebSql = (i === 1);
|
||||
var isImpl2 = (i === 2);
|
||||
|
||||
// NOTE: MUST be defined in function scope, NOT outer scope:
|
||||
var openDatabase = function(name, ignored1, ignored2, ignored3) {
|
||||
if (isImpl2) {
|
||||
// explicit database location:
|
||||
return window.sqlitePlugin.openDatabase({name: name, location: 'default', androidDatabaseImplementation: 2});
|
||||
}
|
||||
if (isWebSql) {
|
||||
return window.openDatabase(name, "1.0", "Demo", DEFAULT_SIZE);
|
||||
} else {
|
||||
// explicit database location:
|
||||
return window.sqlitePlugin.openDatabase({name: name, location: 'default'});
|
||||
}
|
||||
}
|
||||
|
||||
it(suiteName + 'Simple REGEXP test',
|
||||
function(done) {
|
||||
if (isWebSql && isBrowser && !isChromeBrowser) pending('SKIP on (WebKit) Web SQL on non-Chrome desktop browser');
|
||||
if (isWebSql && /Android 4.[1-3]/.test(navigator.userAgent)) pending('SKIP for Android 4.1-4.3 (WebKit) Web SQL');
|
||||
if (isWebSql && isAppleMobileOS) pending('SKIP on iOS (WebKit) Web SQL');
|
||||
if (!isWebSql && isBrowser) pending('SKIP on plugin on browser - NOT IMPLEMENTED');
|
||||
if (!isWebSql && isWindows) pending('SKIP on Windows plugin - NOT IMPLEMENTED');
|
||||
if (!isWebSql && isAndroid && isImpl2 && /Android [2-4]/.test(navigator.userAgent)) pending('TBD SKIP for system android.database provider on Android 2.x-4.x');
|
||||
// TBD REMOVE the following conditions for plugin versions such as cordova-sqlite-ext:
|
||||
if (!isWebSql && isAndroid && !isImpl2) pending('SKIP on Android plugin with default database provider');
|
||||
if (!isWebSql && (isAppleMobileOS || isMac)) pending('SKIP on iOS/macOS plugin');
|
||||
|
||||
var db = openDatabase('simple-regexp-test.db', '1.0', 'test', DEFAULT_SIZE);
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.transaction(function(tx) {
|
||||
|
||||
expect(tx).toBeDefined();
|
||||
tx.executeSql('DROP TABLE IF EXISTS tt');
|
||||
tx.executeSql('CREATE TABLE tt (tv TEXT)');
|
||||
|
||||
tx.executeSql('INSERT INTO tt VALUES (?)', ['test']);
|
||||
tx.executeSql('INSERT INTO tt VALUES (?)', ['tst2']);
|
||||
|
||||
tx.executeSql("SELECT * from tt WHERE tv REGEXP('te?st2+')", [], function(tx, res) {
|
||||
expect(res.rows.length).toBe(1);
|
||||
expect(res.rows.item(0).tv).toBe('tst2');
|
||||
|
||||
done();
|
||||
}, function(e) {
|
||||
// went wrong:
|
||||
expect(false).toBe(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
if (window.hasBrowser) mytests();
|
||||
else exports.defineAutoTests = mytests;
|
||||
|
||||
/* vim: set expandtab : */
|
52
node_modules/cordova-sqlite-storage/spec/www/spec/self-test.js
generated
vendored
Normal file
52
node_modules/cordova-sqlite-storage/spec/www/spec/self-test.js
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
/* 'use strict'; */
|
||||
|
||||
var MYTIMEOUT = 12000;
|
||||
|
||||
var isWindows = /MSAppHost/.test(navigator.userAgent);
|
||||
var isAndroid = !isWindows && /Android/.test(navigator.userAgent);
|
||||
var isFirefox = /Firefox/.test(navigator.userAgent);
|
||||
var isWebKitBrowser = !isWindows && !isAndroid && /Safari/.test(navigator.userAgent);
|
||||
var isBrowser = isWebKitBrowser || isFirefox;
|
||||
|
||||
var mytests = function() {
|
||||
|
||||
describe('Built-in test(s)', function() {
|
||||
|
||||
describe('Self test(s)', function() {
|
||||
it('Echo test',
|
||||
function(done) {
|
||||
window.sqlitePlugin.echoTest(function() {
|
||||
// ok:
|
||||
expect(true).toBe(true);
|
||||
done();
|
||||
}, function(err) {
|
||||
// went wrong:
|
||||
expect(false).toBe(true);
|
||||
expect('Echo test error: ' + JSON.stringify(err)).toBe('--');
|
||||
done();
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it('Self-test with CRUD operations & cleanup',
|
||||
function(done) {
|
||||
window.sqlitePlugin.selfTest(function() {
|
||||
// ok:
|
||||
expect(true).toBe(true);
|
||||
done();
|
||||
}, function(err) {
|
||||
// went wrong:
|
||||
expect(false).toBe(true);
|
||||
expect('Self-test error: ' + JSON.stringify(err)).toBe('--');
|
||||
done();
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
if (window.hasBrowser) mytests();
|
||||
else exports.defineAutoTests = mytests;
|
||||
|
||||
/* vim: set expandtab : */
|
788
node_modules/cordova-sqlite-storage/spec/www/spec/sql-batch-test.js
generated
vendored
Normal file
788
node_modules/cordova-sqlite-storage/spec/www/spec/sql-batch-test.js
generated
vendored
Normal file
@ -0,0 +1,788 @@
|
||||
/* 'use strict'; */
|
||||
|
||||
var MYTIMEOUT = 12000;
|
||||
|
||||
var isWindows = /MSAppHost/.test(navigator.userAgent);
|
||||
var isAndroid = !isWindows && /Android/.test(navigator.userAgent);
|
||||
var isFirefox = /Firefox/.test(navigator.userAgent);
|
||||
var isWebKitBrowser = !isWindows && !isAndroid && /Safari/.test(navigator.userAgent);
|
||||
var isBrowser = isWebKitBrowser || isFirefox;
|
||||
var isMac = !isBrowser && /Macintosh/.test(navigator.userAgent);
|
||||
var isAppleMobileOS = /iPhone/.test(navigator.userAgent) ||
|
||||
/iPad/.test(navigator.userAgent) || /iPod/.test(navigator.userAgent);
|
||||
var hasMobileWKWebView = isAppleMobileOS && !!window.webkit && !!window.webkit.messageHandlers;
|
||||
|
||||
// NOTE: While in certain version branches there is no difference between
|
||||
// the default Android implementation and implementation #2,
|
||||
// this test script will also apply the androidLockWorkaround: 1 option
|
||||
// in case of implementation #2.
|
||||
var pluginScenarioList = [
|
||||
isAndroid ? 'Plugin-implementation-default' : 'Plugin',
|
||||
'Plugin-implementation-2'
|
||||
];
|
||||
|
||||
var pluginScenarioCount = isAndroid ? 2 : 1;
|
||||
|
||||
var mytests = function() {
|
||||
|
||||
for (var i=0; i<pluginScenarioCount; ++i) {
|
||||
|
||||
describe(pluginScenarioList[i] + ': sqlBatch test(s)', function() {
|
||||
|
||||
var scenarioName = pluginScenarioList[i];
|
||||
var suiteName = scenarioName + ': ';
|
||||
var isImpl2 = (i === 1);
|
||||
|
||||
// NOTE: MUST be defined in function scope, NOT outer scope:
|
||||
var openDatabase = function(name, ignored1, ignored2, ignored3) {
|
||||
if (isImpl2) {
|
||||
return window.sqlitePlugin.openDatabase({
|
||||
// prevent reuse of database from default db implementation:
|
||||
name: 'i2-'+name,
|
||||
// explicit database location:
|
||||
location: 'default',
|
||||
androidDatabaseImplementation: 2,
|
||||
androidLockWorkaround: 1
|
||||
});
|
||||
} else {
|
||||
// explicit database location:
|
||||
return window.sqlitePlugin.openDatabase({name: name, location: 'default'});
|
||||
}
|
||||
}
|
||||
|
||||
describe(pluginScenarioList[i] + ': Basic sql batch test(s)', function() {
|
||||
|
||||
it(suiteName + 'Single-column batch sql test', function(done) {
|
||||
var db = openDatabase('Single-column-batch-sql-test.db');
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.sqlBatch([
|
||||
'DROP TABLE IF EXISTS MyTable',
|
||||
'CREATE TABLE MyTable (data)',
|
||||
[ 'INSERT INTO MyTable VALUES (?)', ['test-value'] ],
|
||||
], function() {
|
||||
db.executeSql('SELECT * FROM MyTable', [], function (rs) {
|
||||
expect(rs.rows).toBeDefined();
|
||||
expect(rs.rows.length).toBe(1);
|
||||
expect(rs.rows.item(0).data).toBe('test-value');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'Single-column batch sql test 2 (CREATE TABLE SQL statement with no parameters in [])', function(done) {
|
||||
var db = openDatabase('Single-column-batch-sql-test-2.db');
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.sqlBatch([
|
||||
'DROP TABLE IF EXISTS MyTable',
|
||||
[ 'CREATE TABLE MyTable (data)' ],
|
||||
[ 'INSERT INTO MyTable VALUES (?)', ['test-value'] ],
|
||||
], function() {
|
||||
db.executeSql('SELECT * FROM MyTable', [], function (rs) {
|
||||
expect(rs.rows).toBeDefined();
|
||||
expect(rs.rows.length).toBe(1);
|
||||
expect(rs.rows.item(0).data).toBe('test-value');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'Single-column batch sql test values: INSERT INTEGER/REAL number values and check stored data', function(done) {
|
||||
var db = openDatabase('Single-column-batch-sql-test-number-values.db');
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.sqlBatch([
|
||||
'DROP TABLE IF EXISTS MyTable',
|
||||
'CREATE TABLE MyTable (data)',
|
||||
[ 'INSERT INTO MyTable VALUES (?)', [101] ],
|
||||
[ 'INSERT INTO MyTable VALUES (?)', [-101] ],
|
||||
[ 'INSERT INTO MyTable VALUES (?)', [123.456] ],
|
||||
[ 'INSERT INTO MyTable VALUES (?)', [-123.456] ],
|
||||
[ 'INSERT INTO MyTable VALUES (?)', [1234567890123] ],
|
||||
[ 'INSERT INTO MyTable VALUES (?)', [-1234567890123] ],
|
||||
[ 'INSERT INTO MyTable VALUES (?)', [0] ],
|
||||
], function() {
|
||||
db.executeSql('SELECT data AS d1, TYPEOF(data) AS t1, ABS(data) AS a1, UPPER(data) as u1 FROM MyTable', [], function (rs) {
|
||||
expect(rs.rows).toBeDefined();
|
||||
expect(rs.rows.length).toBe(7);
|
||||
expect(rs.rows.item(0).d1).toBe(101);
|
||||
if (isMac || hasMobileWKWebView)
|
||||
expect(rs.rows.item(0).t1).toBe('real');
|
||||
else
|
||||
expect(rs.rows.item(0).t1).toBe('integer');
|
||||
expect(rs.rows.item(0).a1).toBe(101);
|
||||
if (isMac || hasMobileWKWebView)
|
||||
expect(rs.rows.item(0).u1).toBe('101.0');
|
||||
else
|
||||
expect(rs.rows.item(0).u1).toBe('101');
|
||||
expect(rs.rows.item(1).d1).toBe(-101);
|
||||
if (isMac || hasMobileWKWebView)
|
||||
expect(rs.rows.item(1).t1).toBe('real');
|
||||
else
|
||||
expect(rs.rows.item(1).t1).toBe('integer');
|
||||
expect(rs.rows.item(1).a1).toBe(101);
|
||||
if (isMac || hasMobileWKWebView)
|
||||
expect(rs.rows.item(1).u1).toBe('-101.0');
|
||||
else
|
||||
expect(rs.rows.item(1).u1).toBe('-101');
|
||||
expect(rs.rows.item(2).d1).toBe(123.456);
|
||||
expect(rs.rows.item(2).t1).toBe('real');
|
||||
expect(rs.rows.item(2).a1).toBe(123.456);
|
||||
expect(rs.rows.item(2).u1).toBe('123.456');
|
||||
expect(rs.rows.item(3).d1).toBe(-123.456);
|
||||
expect(rs.rows.item(3).t1).toBe('real');
|
||||
expect(rs.rows.item(3).a1).toBe(123.456);
|
||||
expect(rs.rows.item(3).u1).toBe('-123.456');
|
||||
expect(rs.rows.item(4).d1).toBe(1234567890123);
|
||||
if (isBrowser || isMac || hasMobileWKWebView)
|
||||
expect(rs.rows.item(4).t1).toBe('real');
|
||||
else
|
||||
expect(rs.rows.item(4).t1).toBe('integer');
|
||||
expect(rs.rows.item(4).a1).toBe(1234567890123);
|
||||
if (isBrowser || isMac || hasMobileWKWebView)
|
||||
expect(rs.rows.item(4).u1).toBe('1234567890123.0');
|
||||
else
|
||||
expect(rs.rows.item(4).u1).toBe('1234567890123');
|
||||
expect(rs.rows.item(5).d1).toBe(-1234567890123);
|
||||
if (isBrowser || isMac || hasMobileWKWebView)
|
||||
expect(rs.rows.item(5).t1).toBe('real');
|
||||
else
|
||||
expect(rs.rows.item(5).t1).toBe('integer');
|
||||
expect(rs.rows.item(5).a1).toBe(1234567890123);
|
||||
if (isBrowser || isMac || hasMobileWKWebView)
|
||||
expect(rs.rows.item(5).u1).toBe('-1234567890123.0');
|
||||
else
|
||||
expect(rs.rows.item(5).u1).toBe('-1234567890123');
|
||||
expect(rs.rows.item(6).d1).toBe(0);
|
||||
if (isMac || hasMobileWKWebView)
|
||||
expect(rs.rows.item(6).t1).toBe('real');
|
||||
else
|
||||
expect(rs.rows.item(6).t1).toBe('integer');
|
||||
expect(rs.rows.item(6).a1).toBe(0);
|
||||
if (isMac || hasMobileWKWebView)
|
||||
expect(rs.rows.item(6).u1).toBe('0.0');
|
||||
else
|
||||
expect(rs.rows.item(6).u1).toBe('0');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'Single-column batch sql test values: INSERT null/undefined values and check stored data', function(done) {
|
||||
var db = openDatabase('Single-column-batch-sql-test-null-undefined-values.db');
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.sqlBatch([
|
||||
'DROP TABLE IF EXISTS MyTable',
|
||||
'CREATE TABLE MyTable (data)',
|
||||
[ 'INSERT INTO MyTable VALUES (?)', [null] ],
|
||||
[ 'INSERT INTO MyTable VALUES (?)', [undefined] ],
|
||||
], function() {
|
||||
db.executeSql('SELECT data AS d1, TYPEOF(data) AS t1, ABS(data) AS a1, UPPER(data) as u1 FROM MyTable', [], function (rs) {
|
||||
expect(rs.rows).toBeDefined();
|
||||
expect(rs.rows.length).toBe(2);
|
||||
expect(rs.rows.item(0).d1).toBe(null);
|
||||
expect(rs.rows.item(0).t1).toBe('null');
|
||||
expect(rs.rows.item(0).a1).toBe(null);
|
||||
expect(rs.rows.item(0).u1).toBe(null);
|
||||
expect(rs.rows.item(1).d1).toBe(null);
|
||||
expect(rs.rows.item(1).t1).toBe('null');
|
||||
expect(rs.rows.item(1).a1).toBe(null);
|
||||
expect(rs.rows.item(1).u1).toBe(null);
|
||||
db.close(done, done);
|
||||
});
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'Single-column batch sql test values: INSERT +/- Infinity & NaN values and check stored data [TBD Android/iOS/macOS plugin result for +/- Infinity]', function(done) {
|
||||
if (isMac) pending('SKIP for macOS [CRASH]'); // FUTURE TBD
|
||||
|
||||
var db = openDatabase('Single-column-batch-sql-test-infinity-nan-values.db');
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.sqlBatch([
|
||||
'DROP TABLE IF EXISTS MyTable',
|
||||
'CREATE TABLE MyTable (data)',
|
||||
[ 'INSERT INTO MyTable VALUES (?)', [Infinity] ],
|
||||
[ 'INSERT INTO MyTable VALUES (?)', [-Infinity] ],
|
||||
[ 'INSERT INTO MyTable VALUES (?)', [NaN] ],
|
||||
], function() {
|
||||
db.executeSql('SELECT data AS d1, TYPEOF(data) AS t1, ABS(data) AS a1, UPPER(data) as u1 FROM MyTable', [], function (rs) {
|
||||
expect(rs.rows).toBeDefined();
|
||||
expect(rs.rows.length).toBe(3);
|
||||
if (isBrowser || isWindows) {
|
||||
expect(rs.rows.item(0).d1).toBe(Infinity);
|
||||
expect(rs.rows.item(0).t1).toBe('real');
|
||||
expect(rs.rows.item(0).a1).toBe(Infinity);
|
||||
expect(rs.rows.item(0).u1).toBe('INF');
|
||||
expect(rs.rows.item(1).d1).toBe(-Infinity);
|
||||
expect(rs.rows.item(1).t1).toBe('real');
|
||||
expect(rs.rows.item(1).a1).toBe(Infinity);
|
||||
expect(rs.rows.item(1).u1).toBe('-INF');
|
||||
} else {
|
||||
expect(rs.rows.item(0).d1).toBe(null);
|
||||
expect(rs.rows.item(0).t1).toBe('null');
|
||||
expect(rs.rows.item(0).a1).toBe(null);
|
||||
expect(rs.rows.item(0).u1).toBe(null);
|
||||
expect(rs.rows.item(1).d1).toBe(null);
|
||||
expect(rs.rows.item(1).t1).toBe('null');
|
||||
expect(rs.rows.item(1).a1).toBe(null);
|
||||
expect(rs.rows.item(1).u1).toBe(null);
|
||||
}
|
||||
expect(rs.rows.item(2).d1).toBe(null);
|
||||
expect(rs.rows.item(2).t1).toBe('null');
|
||||
expect(rs.rows.item(2).a1).toBe(null);
|
||||
expect(rs.rows.item(2).u1).toBe(null);
|
||||
db.close(done, done);
|
||||
});
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'Single-column batch sql test values: INSERT true/false values and check stored data [stored as strings]', function(done) {
|
||||
var db = openDatabase('Single-column-batch-sql-test-true-false-values.db');
|
||||
|
||||
db.sqlBatch([
|
||||
'DROP TABLE IF EXISTS MyTable',
|
||||
'CREATE TABLE MyTable (data)',
|
||||
[ 'INSERT INTO MyTable VALUES (?)', [true] ],
|
||||
[ 'INSERT INTO MyTable VALUES (?)', [false] ],
|
||||
], function() {
|
||||
db.executeSql('SELECT data AS d1, TYPEOF(data) AS t1, ABS(data) AS a1, UPPER(data) as u1 FROM MyTable', [], function (rs) {
|
||||
expect(rs.rows).toBeDefined();
|
||||
expect(rs.rows.length).toBe(2);
|
||||
expect(rs.rows.item(0).d1).toBe('true');
|
||||
expect(rs.rows.item(0).t1).toBe('text');
|
||||
expect(rs.rows.item(0).a1).toBe(0);
|
||||
expect(rs.rows.item(0).u1).toBe('TRUE');
|
||||
expect(rs.rows.item(1).d1).toBe('false');
|
||||
expect(rs.rows.item(1).t1).toBe('text');
|
||||
expect(rs.rows.item(1).a1).toBe(0);
|
||||
expect(rs.rows.item(1).u1).toBe('FALSE');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'sql batch with changing SQL element [TBD POSSIBLY INCONSISTENT BEHAVIOR]', function(done) {
|
||||
var db = openDatabase('sql-batch-with-changing-sql-test.db');
|
||||
|
||||
var mybatch = [
|
||||
'DROP TABLE IF EXISTS MyTable',
|
||||
'CREATE TABLE MyTable (data)',
|
||||
"INSERT INTO MyTable VALUES ('Alice')"
|
||||
];
|
||||
|
||||
db.sqlBatch(mybatch, function() {
|
||||
db.executeSql('SELECT * FROM MyTable', [], function (rs) {
|
||||
expect(rs.rows.length).toBe(1);
|
||||
expect(rs.rows.item(0).data).toBe('Alice');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
db.close(done, done);
|
||||
});
|
||||
mybatch[2] = "INSERT INTO MyTable VALUES ('Betty')";
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'sql batch with changing argument value [TBD POSSIBLY INCONSISTENT BEHAVIOR]', function(done) {
|
||||
var db = openDatabase('sql-batch-with-changing-argument-value-test.db');
|
||||
|
||||
var mybatch = [
|
||||
'DROP TABLE IF EXISTS MyTable',
|
||||
'CREATE TABLE MyTable (data)',
|
||||
['INSERT INTO MyTable VALUES (?)', ['Alice']]
|
||||
];
|
||||
|
||||
db.sqlBatch(mybatch, function() {
|
||||
db.executeSql('SELECT * FROM MyTable', [], function (rs) {
|
||||
expect(rs.rows.length).toBe(1);
|
||||
expect(rs.rows.item(0).data).toBe('Betty');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
db.close(done, done);
|
||||
});
|
||||
mybatch[2][1][0] = 'Betty';
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'batch sql with dynamic object for SQL [INCONSISTENT BEHAVIOR]', function(done) {
|
||||
// MyDynamicObject "class":
|
||||
function MyDynamicObject() { this.name = 'Alice'; };
|
||||
MyDynamicObject.prototype.toString = function() {return "INSERT INTO MyTable VALUES ('" + this.name + "')";}
|
||||
|
||||
var myObject = new MyDynamicObject();
|
||||
// Check myObject:
|
||||
expect(myObject.toString()).toBe("INSERT INTO MyTable VALUES ('Alice')");
|
||||
|
||||
var db = openDatabase('batch-sql-with-dynamic-object-for-sql.db');
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
myObject.name = 'Betty';
|
||||
db.sqlBatch([
|
||||
'DROP TABLE IF EXISTS MyTable',
|
||||
'CREATE TABLE MyTable (data)',
|
||||
myObject
|
||||
], function() {
|
||||
db.executeSql('SELECT * FROM MyTable', [], function (res) {
|
||||
expect(res.rows.item(0).data).toBe('Carol');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
db.close(done, done);
|
||||
});
|
||||
myObject.name = 'Carol';
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'batch sql with dynamic object for SQL arg value [INCONSISTENT BEHAVIOR]', function(done) {
|
||||
// MyDynamicParameterObject "class":
|
||||
function MyDynamicParameterObject() {this.name='Alice';};
|
||||
MyDynamicParameterObject.prototype.toString = function() {return this.name;};
|
||||
|
||||
var myObject = new MyDynamicParameterObject();
|
||||
|
||||
// Check myObject:
|
||||
expect(myObject.toString()).toBe('Alice');
|
||||
|
||||
var db = openDatabase('batch-sql-with-dynamic-object-for-sql-arg-value.db');
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
myObject.name = 'Betty';
|
||||
db.sqlBatch([
|
||||
'DROP TABLE IF EXISTS MyTable',
|
||||
'CREATE TABLE MyTable (data)',
|
||||
[ 'INSERT INTO MyTable VALUES (?)', [myObject] ],
|
||||
], function() {
|
||||
db.executeSql('SELECT * FROM MyTable', [], function (res) {
|
||||
expect(res.rows.item(0).data).toBe('Carol');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
db.close(done, done);
|
||||
});
|
||||
myObject.name = 'Carol';
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'Multi-row INSERT with parameters in batch sql test', function(done) {
|
||||
var db = openDatabase('Multi-row-INSERT-with-parameters-batch-sql-test.db');
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.sqlBatch([
|
||||
'DROP TABLE IF EXISTS MyTable',
|
||||
'CREATE TABLE MyTable (x,y)',
|
||||
[ 'INSERT INTO MyTable VALUES (?,?),(?,?)', ['a',1,'b',2] ],
|
||||
], function() {
|
||||
db.executeSql('SELECT * FROM MyTable', [], function (resultSet) {
|
||||
// EXPECTED: CORRECT RESULT:
|
||||
expect(resultSet.rows.length).toBe(2);
|
||||
expect(resultSet.rows.item(0).x).toBe('a');
|
||||
expect(resultSet.rows.item(0).y).toBe(1);
|
||||
expect(resultSet.rows.item(1).x).toBe('b');
|
||||
expect(resultSet.rows.item(1).y).toBe(2);
|
||||
db.close(done, done);
|
||||
});
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'sqlBatch INSERT with numbered parameters (reversed)', function(done) {
|
||||
var db = openDatabase('sqlBatch-INSERT-with-numbered-parameters-reversed-test.db');
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.sqlBatch([
|
||||
'DROP TABLE IF EXISTS MyTable',
|
||||
'CREATE TABLE MyTable (x,y)',
|
||||
[ 'INSERT INTO MyTable VALUES (?2,?1)', ['a',1] ],
|
||||
], function() {
|
||||
db.executeSql('SELECT * FROM MyTable', [], function (resultSet) {
|
||||
// EXPECTED: CORRECT RESULT:
|
||||
expect(resultSet.rows.length).toBe(1);
|
||||
expect(resultSet.rows.item(0).x).toBe(1);
|
||||
expect(resultSet.rows.item(0).y).toBe('a');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'batch sql with syntax error', function(done) {
|
||||
var db = openDatabase('batch-sql-syntax-error-test.db');
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.sqlBatch([
|
||||
'DROP TABLE IF EXISTS MyTable',
|
||||
// syntax error below:
|
||||
'CRETE TABLE MyTable (SampleColumn)',
|
||||
[ 'INSERT INTO MyTable VALUES (?)', ['test-value'] ],
|
||||
], function() {
|
||||
// NOT EXPECTED:
|
||||
expect(true).toBe(false);
|
||||
db.close(done, done);
|
||||
}, function(error) {
|
||||
// EXPECTED RESULT:
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
if (isBrowser || isWindows || (isAndroid && isImpl2))
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(5);
|
||||
|
||||
if (isWindows)
|
||||
expect(error.message).toMatch(/a statement with no error handler failed: Error preparing an SQLite statement/);
|
||||
else
|
||||
expect(error.message).toMatch(/a statement with no error handler failed.*near \"CRETE\": syntax error/);
|
||||
|
||||
db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'batch sql with constraint violation (check error code & basic error message pattern)', function(done) {
|
||||
var db = openDatabase('batch-sql-constraint-violation-test.db');
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.sqlBatch([
|
||||
'DROP TABLE IF EXISTS MyTable',
|
||||
// syntax error below:
|
||||
'CREATE TABLE MyTable (data UNIQUE)',
|
||||
[ 'INSERT INTO MyTable VALUES (?)', [123] ],
|
||||
[ 'INSERT INTO MyTable VALUES (?)', [123] ],
|
||||
], function() {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
db.close(done, done);
|
||||
}, function(error) {
|
||||
// EXPECTED RESULT:
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
if (isBrowser || isWindows)
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(6);
|
||||
|
||||
if (isWindows)
|
||||
expect(error.message).toMatch(/a statement with no error handler failed: SQLite3 step error result code: 1/);
|
||||
else
|
||||
expect(error.message).toMatch(/a statement with no error handler failed.*constraint fail/);
|
||||
db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'batch sql failure-safe semantics', function(done) {
|
||||
var db = openDatabase('batch-sql-failure-safe-test.db');
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.executeSql('DROP TABLE IF EXISTS MyTable');
|
||||
db.executeSql('CREATE TABLE MyTable (SampleColumn)');
|
||||
db.executeSql('INSERT INTO MyTable VALUES (?)', ['test-value'], function() {
|
||||
db.sqlBatch([
|
||||
'DELETE FROM MyTable',
|
||||
// syntax error below:
|
||||
[ 'INSRT INTO MyTable VALUES (?)', 'test-value' ]
|
||||
], function() {
|
||||
// NOT EXPECTED:
|
||||
expect(true).toBe(false);
|
||||
db.close(done, done);
|
||||
}, function(error) {
|
||||
// CHECK INTEGRITY & FINISH:
|
||||
db.executeSql('SELECT * FROM MyTable', [], function (res) {
|
||||
expect(res.rows.item(0).SampleColumn).toBe('test-value');
|
||||
db.close(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'sqlBatch() with no arguments (BOGUS)', function(done) {
|
||||
var db = openDatabase('sql-batch-with-no-arguments.db');
|
||||
|
||||
try {
|
||||
db.sqlBatch();
|
||||
// SHOULD NOT GET HERE:
|
||||
expect(false).toBe(true);
|
||||
} catch(e) {
|
||||
// EXPECTED:
|
||||
expect(e).toBeDefined();
|
||||
expect(e.message).toMatch(/sqlBatch expects an array/);
|
||||
db.close(done, done);
|
||||
};
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'sqlBatch([]) (empty array) - reports success', function(done) {
|
||||
var db = openDatabase('sql-batch-with-empty-array-argument-test.db');
|
||||
expect(db).toBeDefined();
|
||||
|
||||
try {
|
||||
db.sqlBatch([], function() {
|
||||
// EXPECTED RESULT:
|
||||
db.close(done, done);
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
expect(error.message).toBe('--');
|
||||
db.close(done, done);
|
||||
});
|
||||
} catch(e) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(e).toBeDefined();
|
||||
expect(e.message).toBeDefined();
|
||||
expect(e.message).toBe('--');
|
||||
db.close(done, done);
|
||||
};
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'sqlBatch with [] for sql batch item (BOGUS)', function(done) {
|
||||
var db = openDatabase('sql-batch-with-empty-array-for-batch-item.db');
|
||||
|
||||
try {
|
||||
db.sqlBatch(['SELECT 1', []], function() {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
db.close(done, done);
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
db.close(done, done);
|
||||
});
|
||||
// SHOULD NOT GET HERE:
|
||||
expect(false).toBe(true);
|
||||
} catch(e) {
|
||||
expect(e).toBeDefined();
|
||||
expect(e.message).toMatch(/sqlBatch array element of zero .*0.* length/);
|
||||
db.close(done, done);
|
||||
};
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'sqlBatch with true for SQL statements (BOGUS)', function(done) {
|
||||
var db = openDatabase('sql-batch-with-true-for-sql-statements.db');
|
||||
|
||||
try {
|
||||
db.sqlBatch(true, function() {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
db.close(done, done);
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
db.close(done, done);
|
||||
});
|
||||
// SHOULD NOT GET HERE:
|
||||
expect(false).toBe(true);
|
||||
} catch(e) {
|
||||
expect(e).toBeDefined();
|
||||
expect(e.message).toMatch(/sqlBatch expects an array/);
|
||||
db.close(done, done);
|
||||
};
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'batch sql with batch item with false for arguments array (BOGUS)', function(done) {
|
||||
var db = openDatabase('batch-sql-with-false-for-args-array.db');
|
||||
|
||||
var check1 = false;
|
||||
try {
|
||||
db.sqlBatch([
|
||||
'SELECT 1',
|
||||
[ 'SELECT 1', false ],
|
||||
], function() {
|
||||
// TBD EXPECTED RESULT:
|
||||
check1 = true;
|
||||
}, function(error) {
|
||||
// TBD NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
});
|
||||
} catch(e) {
|
||||
expect('Plugin behavior changed please update this test').toBe('--');
|
||||
db.close(done, done);
|
||||
};
|
||||
|
||||
db.sqlBatch([
|
||||
'SELECT 1',
|
||||
], function() {
|
||||
// EXPECTED RESULT:
|
||||
expect(check1).toBe(true);
|
||||
db.close(done, done);
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'batch sql with batch item with "string-value" for arguments array (BOGUS)', function(done) {
|
||||
var db = openDatabase('batch-sql-with-false-for-args-array.db');
|
||||
|
||||
var check1 = false;
|
||||
try {
|
||||
db.sqlBatch([
|
||||
'SELECT 1',
|
||||
[ 'SELECT 1', 'string-value' ],
|
||||
], function() {
|
||||
// TBD EXPECTED RESULT:
|
||||
check1 = true;
|
||||
}, function(error) {
|
||||
// TBD NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
});
|
||||
} catch(e) {
|
||||
expect('Plugin behavior changed please update this test').toBe('--');
|
||||
db.close(done, done);
|
||||
};
|
||||
|
||||
db.sqlBatch([
|
||||
'SELECT 1',
|
||||
], function() {
|
||||
// EXPECTED RESULT:
|
||||
expect(check1).toBe(true);
|
||||
db.close(done, done);
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
db.close(done, done);
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'sqlBatch with single SELECT statement, false for error callback (BOGUS)', function(done) {
|
||||
var db = openDatabase('sql-batch-with-select-false-for-error-cb.db');
|
||||
|
||||
try {
|
||||
db.sqlBatch(['SELECT 1'], function() {
|
||||
// EXPECTED:
|
||||
expect(true).toBe(true);
|
||||
db.close(done, done);
|
||||
}, false);
|
||||
} catch(e) {
|
||||
expect('Plugin behavior changed please update this test').toBe('--');
|
||||
db.close(done, done);
|
||||
};
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'sqlBatch with single SELECT statement, string-value for error callback (BOGUS)', function(done) {
|
||||
var db = openDatabase('sql-batch-with-select-string-value-for-error-cb.db');
|
||||
|
||||
try {
|
||||
db.sqlBatch(['SELECT 1'], function() {
|
||||
// EXPECTED:
|
||||
expect(true).toBe(true);
|
||||
db.close(done, done);
|
||||
}, 'stirng-value');
|
||||
} catch(e) {
|
||||
expect('Plugin behavior changed please update this test').toBe('--');
|
||||
db.close(done, done);
|
||||
};
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'sqlBatch with error, false for success callback (BOGUS)', function(done) {
|
||||
var db = openDatabase('sql-batch-with-select-false-for-success-cb.db');
|
||||
|
||||
try {
|
||||
db.sqlBatch(['SLCT 1'], false, function(e) {
|
||||
// EXPECTED:
|
||||
expect(e).toBeDefined();
|
||||
// TBD ...
|
||||
db.close(done, done);
|
||||
}, true);
|
||||
} catch(e) {
|
||||
expect('Plugin behavior changed please update this test').toBe('--');
|
||||
db.close(done, done);
|
||||
};
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'sqlBatch with error, string-value for success callback (BOGUS)', function(done) {
|
||||
var db = openDatabase('sql-batch-with-select-string-value-for-success-cb.db');
|
||||
|
||||
try {
|
||||
db.sqlBatch(['SLCT 1'], 'string-value', function(e) {
|
||||
// EXPECTED:
|
||||
expect(e).toBeDefined();
|
||||
// TBD ...
|
||||
db.close(done, done);
|
||||
}, true);
|
||||
} catch(e) {
|
||||
expect('Plugin behavior changed please update this test').toBe('--');
|
||||
db.close(done, done);
|
||||
};
|
||||
}, MYTIMEOUT);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (window.hasBrowser) mytests();
|
||||
else exports.defineAutoTests = mytests;
|
||||
|
||||
/* vim: set expandtab : */
|
253
node_modules/cordova-sqlite-storage/spec/www/spec/sqlite-version-test.js
generated
vendored
Normal file
253
node_modules/cordova-sqlite-storage/spec/www/spec/sqlite-version-test.js
generated
vendored
Normal file
@ -0,0 +1,253 @@
|
||||
/* 'use strict'; */
|
||||
|
||||
var MYTIMEOUT = 12000;
|
||||
|
||||
// NOTE: DEFAULT_SIZE wanted depends on type of browser
|
||||
|
||||
var isWindows = /MSAppHost/.test(navigator.userAgent);
|
||||
var isAndroid = !isWindows && /Android/.test(navigator.userAgent);
|
||||
var isFirefox = /Firefox/.test(navigator.userAgent);
|
||||
var isWebKitBrowser = !isWindows && !isAndroid && /Safari/.test(navigator.userAgent);
|
||||
var isBrowser = isWebKitBrowser || isFirefox;
|
||||
var isEdgeBrowser = isBrowser && (/Edge/.test(navigator.userAgent));
|
||||
var isChromeBrowser = isBrowser && !isEdgeBrowser && (/Chrome/.test(navigator.userAgent));
|
||||
var isSafariBrowser = isWebKitBrowser && !isEdgeBrowser && !isChromeBrowser;
|
||||
|
||||
// should avoid popups (Safari seems to count 2x)
|
||||
var DEFAULT_SIZE = isSafariBrowser ? 2000000 : 5000000;
|
||||
// FUTURE TBD: 50MB should be OK on Chrome and some other test browsers.
|
||||
|
||||
// The following openDatabase settings are used for Plugin-implementation-2
|
||||
// on Android:
|
||||
// - androidDatabaseImplementation: 2
|
||||
// - androidLockWorkaround: 1
|
||||
var scenarioList = [
|
||||
isAndroid ? 'Plugin-implementation-default' : 'Plugin',
|
||||
'HTML5',
|
||||
'Plugin-implementation-2'
|
||||
];
|
||||
|
||||
var scenarioCount = (!!window.hasWebKitWebSQL) ? (isAndroid ? 3 : 2) : 1;
|
||||
|
||||
var mytests = function() {
|
||||
|
||||
for (var i=0; i<scenarioCount; ++i) {
|
||||
|
||||
describe(scenarioList[i] + ': sqlite version test(s)', function() {
|
||||
var scenarioName = scenarioList[i];
|
||||
var suiteName = scenarioName + ': ';
|
||||
var isWebSql = (i === 1);
|
||||
var isImpl2 = (i === 2);
|
||||
|
||||
// NOTE 1: MUST be defined in proper describe function scope, NOT outer scope.
|
||||
// NOTE 2: Using same database name in this script to avoid creating extra,
|
||||
// unneeded database files.
|
||||
var openDatabase = function(name_ignored, ignored1, ignored2, ignored3) {
|
||||
var name = 'sqlite-version-test.db';
|
||||
if (isImpl2) {
|
||||
return window.sqlitePlugin.openDatabase({
|
||||
// prevent reuse of database from default db implementation:
|
||||
name: 'i2-'+name,
|
||||
androidDatabaseImplementation: 2,
|
||||
androidLockWorkaround: 1,
|
||||
location: 'default'
|
||||
});
|
||||
}
|
||||
if (isWebSql) {
|
||||
return window.openDatabase(name, "1.0", "Demo", DEFAULT_SIZE);
|
||||
} else {
|
||||
return window.sqlitePlugin.openDatabase({name: name, location: 'default'});
|
||||
}
|
||||
}
|
||||
|
||||
describe(suiteName + 'basic sqlite version test(s)', function() {
|
||||
|
||||
it(suiteName + 'Check sqlite version correctly matches pattern', function(done) {
|
||||
var db = openDatabase("check-sqlite-version-matches-pattern.db", "1.0", "Demo", DEFAULT_SIZE);
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.transaction(function(tx) {
|
||||
expect(tx).toBeDefined();
|
||||
|
||||
tx.executeSql('SELECT SQLITE_VERSION() AS myResult', [], function(tx_ignored, rs) {
|
||||
expect(rs).toBeDefined();
|
||||
expect(rs.rows).toBeDefined();
|
||||
expect(rs.rows.length).toBe(1);
|
||||
expect(rs.rows.item(0).myResult).toMatch(/3\.[0-9]+\.[0-9]+/);
|
||||
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
});
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
done();
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'Check actual sqlite version', function(done) {
|
||||
if (isWebSql) pending('NOT DETERMINISTIC for (WebKit) Web SQL');
|
||||
if (!isWebSql && isAndroid && isImpl2) pending('NOT DETERMINISTIC for plugin on Android with androidDatabaseImplementation: 2');
|
||||
|
||||
var db = openDatabase("check-actual-sqlite-version.db", "1.0", "Demo", DEFAULT_SIZE);
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.transaction(function(tx) {
|
||||
expect(tx).toBeDefined();
|
||||
|
||||
tx.executeSql('SELECT SQLITE_VERSION() AS myResult', [], function(tx_ignored, rs) {
|
||||
expect(rs).toBeDefined();
|
||||
expect(rs.rows).toBeDefined();
|
||||
expect(rs.rows.length).toBe(1);
|
||||
expect(rs.rows.item(0).myResult).toBe('3.40.0');
|
||||
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
});
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
done();
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
});
|
||||
|
||||
describe(suiteName + 'sqlite encoding test(s)', function() {
|
||||
|
||||
it(suiteName + 'Check internal database encoding: UTF-16le for Windows, UTF-8 for others (plugin ONLY)', function(done) {
|
||||
if (isWebSql) pending('SKIP: NOT SUPPORTED for (WebKit) Web SQL');
|
||||
|
||||
var db = openDatabase("Check-sqlite-PRAGMA-encoding.db", "1.0", "Demo", DEFAULT_SIZE);
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.executeSql('PRAGMA encoding', [], function(rs) {
|
||||
expect(rs).toBeDefined();
|
||||
expect(rs.rows).toBeDefined();
|
||||
expect(rs.rows.length).toBe(1);
|
||||
if (isWindows)
|
||||
expect(rs.rows.item(0).encoding).toBe('UTF-16le');
|
||||
else
|
||||
expect(rs.rows.item(0).encoding).toBe('UTF-8');
|
||||
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
done();
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
});
|
||||
|
||||
describe(suiteName + 'default page/cache size check(s)', function() {
|
||||
|
||||
it(suiteName + 'Check default page size (plugin ONLY)', function(done) {
|
||||
// ref: litehelpers/Cordova-sqlite-storage#781
|
||||
if (isWebSql) pending('SKIP: NOT SUPPORTED for (WebKit) Web SQL');
|
||||
|
||||
var db = openDatabase('default-page-size.db');
|
||||
|
||||
db.executeSql('PRAGMA page_size', null, function(rs) {
|
||||
expect(rs).toBeDefined();
|
||||
expect(rs.rows).toBeDefined();
|
||||
expect(rs.rows.length).toBe(1);
|
||||
expect(rs.rows.item(0).page_size).toBe(4096);
|
||||
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
done();
|
||||
});
|
||||
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'Check default cache size (plugin ONLY)', function(done) {
|
||||
// ref: litehelpers/Cordova-sqlite-storage#781
|
||||
if (isWebSql) pending('SKIP: NOT SUPPORTED for (WebKit) Web SQL');
|
||||
|
||||
var db = openDatabase('default-cache-size.db');
|
||||
|
||||
db.executeSql('PRAGMA cache_size', null, function(rs) {
|
||||
expect(rs).toBeDefined();
|
||||
expect(rs.rows).toBeDefined();
|
||||
expect(rs.rows.length).toBe(1);
|
||||
var resultRow = rs.rows.item(0);
|
||||
expect(resultRow).toBeDefined();
|
||||
expect(resultRow.cache_size).toBeDefined();
|
||||
if (!isWebSql && isAndroid && isImpl2
|
||||
&& (/Android [3-7]/.test(navigator.userAgent)))
|
||||
expect(resultRow.cache_size).toBe(2000); // TBD OLD VALUE on Android (...)
|
||||
else
|
||||
expect(resultRow.cache_size).toBe(-2000); // NEW VALUE, otherwise
|
||||
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
done();
|
||||
});
|
||||
|
||||
}, MYTIMEOUT);
|
||||
|
||||
});
|
||||
|
||||
describe(suiteName + 'additional sqlite check(s)', function() {
|
||||
|
||||
it(suiteName + 'Check default PRAGMA journal_mode setting (plugin ONLY)', function(done) {
|
||||
if (isWebSql) pending('SKIP: NOT SUPPORTED for (WebKit) Web SQL');
|
||||
|
||||
var db = openDatabase("Check-sqlite-PRAGMA-encoding.db", "1.0", "Demo", DEFAULT_SIZE);
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.executeSql('PRAGMA journal_mode', [], function(rs) {
|
||||
expect(rs).toBeDefined();
|
||||
expect(rs.rows).toBeDefined();
|
||||
expect(rs.rows.length).toBe(1);
|
||||
// DEFAULT PRAGMA journal_mode setting is
|
||||
// DIFFERENT for builtin android.database implementation:
|
||||
if (!isWindows && isAndroid && isImpl2)
|
||||
expect(rs.rows.item(0).journal_mode).toBe(
|
||||
(/Android 1/.test(navigator.userAgent)) ? 'truncate' :
|
||||
(/Android 9/.test(navigator.userAgent)) ? 'wal' :
|
||||
(/Android 8.1.99/.test(navigator.userAgent)) ? 'wal' :
|
||||
(/Android 8/.test(navigator.userAgent)) ? 'truncate' :
|
||||
'persist');
|
||||
else
|
||||
expect(rs.rows.item(0).journal_mode).toBe('delete');
|
||||
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
done();
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (window.hasBrowser) mytests();
|
||||
else exports.defineAutoTests = mytests;
|
||||
|
||||
/* vim: set expandtab : */
|
814
node_modules/cordova-sqlite-storage/spec/www/spec/tx-semantics-test.js
generated
vendored
Normal file
814
node_modules/cordova-sqlite-storage/spec/www/spec/tx-semantics-test.js
generated
vendored
Normal file
@ -0,0 +1,814 @@
|
||||
/* 'use strict'; */
|
||||
|
||||
var MYTIMEOUT = 12000;
|
||||
|
||||
// NOTE: DEFAULT_SIZE wanted depends on type of browser
|
||||
|
||||
var isWindows = /MSAppHost/.test(navigator.userAgent);
|
||||
var isAndroid = !isWindows && /Android/.test(navigator.userAgent);
|
||||
var isFirefox = /Firefox/.test(navigator.userAgent);
|
||||
var isWebKitBrowser = !isWindows && !isAndroid && /Safari/.test(navigator.userAgent);
|
||||
var isBrowser = isWebKitBrowser || isFirefox;
|
||||
var isEdgeBrowser = isBrowser && (/Edge/.test(navigator.userAgent));
|
||||
var isChromeBrowser = isBrowser && !isEdgeBrowser && (/Chrome/.test(navigator.userAgent));
|
||||
var isSafariBrowser = isWebKitBrowser && !isEdgeBrowser && !isChromeBrowser;
|
||||
|
||||
// should avoid popups (Safari seems to count 2x)
|
||||
var DEFAULT_SIZE = isSafariBrowser ? 2000000 : 5000000;
|
||||
// FUTURE TBD: 50MB should be OK on Chrome and some other test browsers.
|
||||
|
||||
// NOTE: While in certain version branches there is no difference between
|
||||
// the default Android implementation and system database provider,
|
||||
// this test script will also apply the androidLockWorkaround: 1 option
|
||||
// in case of androidDatabaseProvider: 'system'.
|
||||
var scenarioList = [
|
||||
isAndroid ? 'Plugin-implementation-default' : 'Plugin',
|
||||
'HTML5',
|
||||
'Plugin-system-database-provider'
|
||||
];
|
||||
|
||||
var scenarioCount = (!!window.hasWebKitWebSQL) ? (isAndroid ? 3 : 2) : 1;
|
||||
|
||||
function logSuccess(message) { console.log('OK - ' + message); }
|
||||
function logFailure(message) { console.log('FAILED - ' + message); }
|
||||
|
||||
var mytests = function() {
|
||||
|
||||
for (var i=0; i<scenarioCount; ++i) {
|
||||
|
||||
describe(scenarioList[i] + ': tx semantics test(s)', function() {
|
||||
var scenarioName = scenarioList[i];
|
||||
var suiteName = scenarioName + ': ';
|
||||
var isWebSql = (i === 1);
|
||||
var isSystemDatabaseProvider = (i === 2);
|
||||
|
||||
// NOTE: MUST be defined in function scope, NOT outer scope:
|
||||
var openDatabase = function(name, ignored1, ignored2, ignored3) {
|
||||
if (isSystemDatabaseProvider) {
|
||||
return window.sqlitePlugin.openDatabase({
|
||||
// prevent reuse of database from default db implementation:
|
||||
name: 'system-'+name,
|
||||
// explicit database location:
|
||||
location: 'default',
|
||||
androidDatabaseProvider: 'system',
|
||||
androidLockWorkaround: 1
|
||||
});
|
||||
}
|
||||
if (isWebSql) {
|
||||
return window.openDatabase(name, '1.0', 'Test', DEFAULT_SIZE);
|
||||
} else {
|
||||
// explicit database location:
|
||||
return window.sqlitePlugin.openDatabase({name: name, location: 'default'});
|
||||
}
|
||||
}
|
||||
|
||||
it(suiteName + 'Simple tx sql order test', function(done) {
|
||||
// This test shows that executeSql statements run in intermediate callback
|
||||
// are executed AFTER executeSql statements that were queued before
|
||||
|
||||
var db = openDatabase('Simple-tx-order-test.db', '1.0', 'Test', DEFAULT_SIZE);
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.transaction(function(tx) {
|
||||
expect(tx).toBeDefined();
|
||||
|
||||
tx.executeSql('DROP TABLE IF EXISTS tt');
|
||||
tx.executeSql('CREATE TABLE tt (data)');
|
||||
|
||||
tx.executeSql('INSERT INTO tt VALUES (?)', ['first'], function(tx, res) {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.insertId).toBeDefined();
|
||||
expect(res.rowsAffected).toBe(1);
|
||||
|
||||
tx.executeSql('INSERT INTO tt VALUES (?)', ['middle']);
|
||||
});
|
||||
|
||||
tx.executeSql("INSERT INTO tt VALUES ('last')");
|
||||
|
||||
}, null, function() {
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql('SELECT * FROM tt', [], function(tx, res) {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.rows).toBeDefined();
|
||||
expect(res.rows.length).toBe(3);
|
||||
expect(res.rows.item(0).data).toBe('first');
|
||||
expect(res.rows.item(1).data).toBe('last');
|
||||
expect(res.rows.item(2).data).toBe('middle');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'Simple tx sql order test with error recovery', function(done) {
|
||||
// This test shows that executeSql statements run in intermediate error handling callback
|
||||
// are executed _after_ executeSql statements that were queued before
|
||||
|
||||
var db = openDatabase('tx-order-with-error-test.db', '1.0', 'Test', DEFAULT_SIZE);
|
||||
|
||||
expect(db).toBeDefined();
|
||||
|
||||
db.transaction(function(tx) {
|
||||
expect(tx).toBeDefined();
|
||||
|
||||
tx.executeSql('DROP TABLE IF EXISTS tt');
|
||||
tx.executeSql('CREATE TABLE tt (data)');
|
||||
|
||||
tx.executeSql('INSERT INTO tt VALUES (?)', [1], function(tx, res) {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.insertId).toBeDefined();
|
||||
expect(res.rowsAffected).toBe(1);
|
||||
|
||||
tx.executeSql('INSERT INTO tt VALUES (?)', [2]);
|
||||
});
|
||||
|
||||
// syntax error:
|
||||
tx.executeSql('INSRT INTO tt VALUES (?)', ['bogus'], null, function(err) {
|
||||
expect(err).toBeDefined();
|
||||
// TBD check err
|
||||
|
||||
tx.executeSql('INSERT INTO tt VALUES (?)', [3]);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
tx.executeSql('INSERT INTO tt VALUES (?)', [4]);
|
||||
|
||||
}, function(err) {
|
||||
// not expected:
|
||||
expect(false).toBe(true);
|
||||
done();
|
||||
}, function() {
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql('SELECT * FROM tt', [], function(tx, res) {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.rows).toBeDefined();
|
||||
expect(res.rows.length).toBe(4);
|
||||
expect(res.rows.item(0).data).toBe(1);
|
||||
expect(res.rows.item(1).data).toBe(4);
|
||||
expect(res.rows.item(2).data).toBe(2);
|
||||
expect(res.rows.item(3).data).toBe(3);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
}, MYTIMEOUT);
|
||||
|
||||
it(suiteName + 'transaction test: check rowsAffected [intermediate]', function (done) {
|
||||
var db = openDatabase("RowsAffected", "1.0", "Demo", DEFAULT_SIZE);
|
||||
|
||||
function test1(tx) {
|
||||
tx.executeSql('DROP TABLE IF EXISTS characters');
|
||||
tx.executeSql('CREATE TABLE IF NOT EXISTS characters (name, creator, fav tinyint(1))');
|
||||
tx.executeSql('UPDATE characters SET name = ?', ['foo'], function (tx, res) {
|
||||
expect(res.rowsAffected).toBe(0); // nothing updated
|
||||
tx.executeSql('DELETE from characters WHERE name = ?', ['foo'], function (tx, res) {
|
||||
expect(res.rowsAffected).toBe(0); // nothing deleted
|
||||
tx.executeSql('UPDATE characters SET name = ?', ['foo'], function (tx, res) {
|
||||
expect(res.rowsAffected).toBe(0); // nothing updated
|
||||
tx.executeSql('DELETE from characters', [], function (tx, res) {
|
||||
expect(res.rowsAffected).toBe(0); // nothing deleted
|
||||
test2(tx);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function test2(tx) {
|
||||
tx.executeSql('INSERT INTO characters VALUES (?,?,?)', ['Sonic', 'Sega', 0], function (tx, res) {
|
||||
expect(res.rowsAffected).toBe(1);
|
||||
tx.executeSql('INSERT INTO characters VALUES (?,?,?)', ['Mario', 'Nintendo', 0], function (tx, res) {
|
||||
expect(res.rowsAffected).toBe(1);
|
||||
tx.executeSql('INSERT INTO characters VALUES (?,?,?)', ['Samus', 'Nintendo', 0], function (tx, res) {
|
||||
expect(res.rowsAffected).toBe(1);
|
||||
tx.executeSql('UPDATE characters SET fav=1 WHERE creator=?', ['Nintendo'], function (tx, res) {
|
||||
expect(res.rowsAffected).toBe(2);
|
||||
tx.executeSql('UPDATE characters SET fav=1 WHERE creator=?', ['Konami'], function (tx, res) {
|
||||
expect(res.rowsAffected).toBe(0);
|
||||
tx.executeSql('UPDATE characters SET fav=1', [], function (tx, res) {
|
||||
expect(res.rowsAffected).toBe(3);
|
||||
test3(tx);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function test3(tx) {
|
||||
tx.executeSql('INSERT INTO characters VALUES (?,?,?)', ['Mega Man', 'Capcom', 0], function (tx, res) {
|
||||
expect(res.rowsAffected).toBe(1);
|
||||
tx.executeSql('UPDATE characters SET fav=?, name=? WHERE creator=?;', [1, 'X', 'Capcom'], function (tx, res) {
|
||||
expect(res.rowsAffected).toBe(1);
|
||||
tx.executeSql('UPDATE characters SET fav=? WHERE (creator=? OR creator=?)', [1, 'Capcom', 'Nintendo'], function (tx, res) {
|
||||
expect(res.rowsAffected).toBe(3);
|
||||
tx.executeSql('DELETE FROM characters WHERE name="Samus";', [], function (tx, res) {
|
||||
expect(res.rowsAffected).toBe(1);
|
||||
tx.executeSql('UPDATE characters SET fav=0,name=?', ["foo"], function (tx, res) {
|
||||
expect(res.rowsAffected).toBe(3);
|
||||
tx.executeSql('DELETE FROM characters', [], function (tx, res) {
|
||||
expect(res.rowsAffected).toBe(3);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
db.transaction(function (tx) {
|
||||
test1(tx);
|
||||
})
|
||||
});
|
||||
|
||||
it(suiteName + 'test insertId & rowsAffected [advanced] - plugin vs (WebKit) Web SQL', function (done) {
|
||||
var db = openDatabase('test-rowsAffected-advanced.db');
|
||||
|
||||
db.transaction(function (tx) {
|
||||
tx.executeSql('DROP TABLE IF EXISTS characters');
|
||||
tx.executeSql('CREATE TABLE IF NOT EXISTS characters (name unique, creator, fav tinyint(1))');
|
||||
tx.executeSql('DROP TABLE IF EXISTS companies');
|
||||
tx.executeSql('CREATE TABLE IF NOT EXISTS companies (name unique, fav tinyint(1))');
|
||||
|
||||
// INSERT or IGNORE with the real thing:
|
||||
tx.executeSql('INSERT or IGNORE INTO characters VALUES (?,?,?)', ['Sonic', 'Sega', 0], function (txIgnored, rs1) {
|
||||
expect(rs1.rowsAffected).toBe(1);
|
||||
expect(rs1.insertId).toBe(1);
|
||||
|
||||
tx.executeSql('INSERT INTO characters VALUES (?,?,?)', ['Tails', 'Sega', 0], function (txIgnored, rs2) {
|
||||
expect(rs2.rowsAffected).toBe(1);
|
||||
expect(rs2.insertId).toBe(2);
|
||||
|
||||
tx.executeSql('INSERT INTO companies VALUES (?,?)', ['Sega', 1], function (txIgnored, rs3) {
|
||||
expect(rs3.rowsAffected).toBe(1);
|
||||
expect(rs3.insertId).toBe(1);
|
||||
|
||||
// query with subquery
|
||||
var sql = 'UPDATE characters ' +
|
||||
' SET fav=(SELECT fav FROM companies WHERE name=?)' +
|
||||
' WHERE creator=?';
|
||||
tx.executeSql(sql, ['Sega', 'Sega'], function (txIgnored, rs4) {
|
||||
expect(rs4.rowsAffected).toBe(2);
|
||||
try {
|
||||
// defined on plugin (except for Android with androidDatabaseImplementation: 2);
|
||||
// throws on (WebKit) Web SQL:
|
||||
if (!isWebSql && isAndroid && isSystemDatabaseProvider)
|
||||
expect(rs4.insertId).not.toBeDefined();
|
||||
else
|
||||
expect(rs4.insertId).toBeDefined();
|
||||
|
||||
// NOT EXPECTED to get here on (WebKit) Web SQL:
|
||||
if (isWebSql) expect('(WebKit) Web SQL behavior changed').toBe('--');
|
||||
|
||||
if (!(isAndroid && isSystemDatabaseProvider))
|
||||
expect(rs4.insertId).toBe(1);
|
||||
} catch(ex) {
|
||||
// SHOULD NOT CATCH EXCEPTION on plugin:
|
||||
if (!isWebSql) expect('EXCEPTION NOT EXPECTED on plugin with message: ' + ex.message).toBe('--');
|
||||
expect(ex).toBeDefined();
|
||||
expect(ex.message).toBeDefined();
|
||||
// FUTURE TBD check message
|
||||
}
|
||||
|
||||
// query with 2 subqueries
|
||||
var sql = 'UPDATE characters ' +
|
||||
' SET fav=(SELECT fav FROM companies WHERE name=?),' +
|
||||
' creator=(SELECT name FROM companies WHERE name=?)' +
|
||||
' WHERE creator=?';
|
||||
tx.executeSql(sql, ['Sega', 'Sega', 'Sega'], function (txIgnored, rs5) {
|
||||
expect(rs5.rowsAffected).toBe(2);
|
||||
try {
|
||||
// defined on plugin (except for Android with androidDatabaseImplementation: 2);
|
||||
// throws on (WebKit) Web SQL:
|
||||
if (!isWebSql && isAndroid && isSystemDatabaseProvider)
|
||||
expect(rs5.insertId).not.toBeDefined();
|
||||
else
|
||||
expect(rs5.insertId).toBeDefined();
|
||||
|
||||
// EXPECTED to get here on plugin only:
|
||||
if (isWebSql) expect('(WebKit) Web SQL behavior changed').toBe('--');
|
||||
|
||||
if (!(isAndroid && isSystemDatabaseProvider))
|
||||
expect(rs5.insertId).toBe(1);
|
||||
} catch(ex) {
|
||||
// SHOULD NOT CATCH EXCEPTION on plugin:
|
||||
if (!isWebSql) expect('EXCEPTION NOT EXPECTED on plugin with message: ' + ex.message).toBe('--');
|
||||
// XXX TODO CHECK message, etc.
|
||||
}
|
||||
|
||||
// knockoffs shall be ignored:
|
||||
tx.executeSql('INSERT or IGNORE INTO characters VALUES (?,?,?)', ['Sonic', 'knockoffs4you', 0], function (txIgnored, rs6) {
|
||||
// EXPECTED RESULT:
|
||||
expect(rs6.rowsAffected).toBe(0);
|
||||
|
||||
// insertId plugin vs (WebKit) Web SQL:
|
||||
if (isWebSql)
|
||||
expect(rs6.insertId).toBe(1);
|
||||
else
|
||||
expect(rs6.insertId).not.toBeDefined();
|
||||
|
||||
done();
|
||||
}, function(txIgnored, error) {
|
||||
// ERROR NOT EXPECTED here - knockoff should have been ignored:
|
||||
logError('knockoff should have been ignored');
|
||||
expect(error.message).toBe('--');
|
||||
|
||||
done.fail();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}, function(error) {
|
||||
// NOT EXPECTED:
|
||||
expect(false).toBe(true);
|
||||
expect(error.message).toBe('--');
|
||||
// Close (plugin only) & finish:
|
||||
(isWebSql) ? done() : db.close(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
// FUTURE TODO: fix these tests to follow the Jasmine style and move into a separate spec file:
|
||||
|
||||
it(suiteName + "nested transaction test", function(done) {
|
||||
var db = openDatabase("Database2", "1.0", "Demo", DEFAULT_SIZE);
|
||||
|
||||
expect(db).toBeTruthy(); // db object
|
||||
|
||||
db.transaction(function(tx) {
|
||||
expect(tx).toBeTruthy(); // tx object
|
||||
|
||||
tx.executeSql('DROP TABLE IF EXISTS test_table');
|
||||
tx.executeSql('CREATE TABLE IF NOT EXISTS test_table (id integer primary key, data text, data_num integer)');
|
||||
|
||||
tx.executeSql("INSERT INTO test_table (data, data_num) VALUES (?,?)", ["test", 100], function(tx, res) {
|
||||
console.log("insertId: " + res.insertId + " -- probably 1");
|
||||
console.log("rowsAffected: " + res.rowsAffected + " -- should be 1");
|
||||
|
||||
expect(res).toBeDefined();
|
||||
expect(res.insertId).toBeDefined();
|
||||
expect(res.rowsAffected).toBe(1);
|
||||
|
||||
tx.executeSql("select count(id) as cnt from test_table;", [], function(tx, res) {
|
||||
console.log("res.rows.length: " + res.rows.length + " -- should be 1");
|
||||
console.log("res.rows.item(0).cnt: " + res.rows.item(0).cnt + " -- should be 1");
|
||||
|
||||
expect(res.rows.length).toBe(1); // res rows length
|
||||
expect(res.rows.item(0).cnt).toBe(1); // select count
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe(suiteName + 'transaction callback semantics test(s)', function() {
|
||||
|
||||
function withTestTable(func) {
|
||||
var db = openDatabase("Database", "1.0", "Demo", DEFAULT_SIZE);
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql('DROP TABLE IF EXISTS test_table');
|
||||
tx.executeSql('CREATE TABLE IF NOT EXISTS test_table (id integer primary key, data text, data_num integer)');
|
||||
}, function(err) { ok(false, err.message) }, function() {
|
||||
//start();
|
||||
func(db);
|
||||
});
|
||||
};
|
||||
|
||||
it(suiteName + "transaction encompasses all callbacks", function(done) {
|
||||
var db = openDatabase("tx-all-callbacks.db", "1.0", "Demo", DEFAULT_SIZE);
|
||||
|
||||
db.transaction(function(tx) {
|
||||
|
||||
tx.executeSql('DROP TABLE IF EXISTS test_table');
|
||||
tx.executeSql('CREATE TABLE IF NOT EXISTS test_table (id integer primary key, data text, data_num integer)');
|
||||
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql('INSERT INTO test_table (data, data_num) VALUES (?,?)', ['test', 100], function(tx, res) {
|
||||
tx.executeSql("SELECT count(*) as cnt from test_table", [], function(tx, res) {
|
||||
expect(res.rows.item(0).cnt).toBe(1); // did insert row
|
||||
throw new Error("deliberately aborting transaction");
|
||||
});
|
||||
});
|
||||
}, function(error) {
|
||||
if (!isWebSql) expect(error.message).toBe("deliberately aborting transaction");
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql("select count(*) as cnt from test_table", [], function(tx, res) {
|
||||
// EXPECTED RESULT:
|
||||
expect(res.rows.item(0).cnt).toBe(0); // final count shows we rolled back
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
}, function() {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError("transaction succeeded but wasn't supposed to");done.fail();
|
||||
expect(error.message).toBe('--');
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it(suiteName + 'exception from transaction handler causes failure', function(done) {
|
||||
var db = openDatabase("exception-causes-failure.db", "1.0", "Demo", DEFAULT_SIZE);
|
||||
|
||||
try {
|
||||
db.transaction(function(tx) {
|
||||
throw new Error("boom");
|
||||
}, function(error) {
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
// error.hasOwnProperty('message') apparently NOT WORKING on
|
||||
// WebKit Web SQL on Android 5.x/... or iOS 10.x/...:
|
||||
if (!isWebSql || isWindows || (isAndroid && (/Android 4/.test(navigator.userAgent))))
|
||||
expect(error.hasOwnProperty('message')).toBe(true);
|
||||
|
||||
expect(error.code).toBe(0);
|
||||
|
||||
if (isWebSql)
|
||||
expect(error.message).toMatch(/the SQLTransactionCallback was null or threw an exception/);
|
||||
else
|
||||
expect(error.message).toBe('boom');
|
||||
|
||||
done();
|
||||
}, function() {
|
||||
// transaction success callback not expected
|
||||
expect(false).toBe(true);
|
||||
done();
|
||||
});
|
||||
logSuccess("db.transaction() did not throw an error");
|
||||
} catch(ex) {
|
||||
// exception not expected here
|
||||
expect(false).toBe(true);
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it(suiteName + 'exception with code from transaction handler', function(done) {
|
||||
var db = openDatabase("exception-with-code.db", "1.0", "Demo", DEFAULT_SIZE);
|
||||
|
||||
try {
|
||||
db.transaction(function(tx) {
|
||||
var e = new Error("boom");
|
||||
e.code = 3;
|
||||
throw e;
|
||||
}, function(error) {
|
||||
expect(error).toBeDefined();
|
||||
expect(error.code).toBeDefined();
|
||||
expect(error.message).toBeDefined();
|
||||
|
||||
if (isWebSql)
|
||||
expect(error.code).toBe(0);
|
||||
else
|
||||
expect(error.code).toBe(3);
|
||||
|
||||
if (isWebSql)
|
||||
expect(error.message).toMatch(/the SQLTransactionCallback was null or threw an exception/);
|
||||
else
|
||||
expect(error.message).toBe('boom');
|
||||
|
||||
done();
|
||||
}, function() {
|
||||
// transaction success callback not expected
|
||||
expect(false).toBe(true);
|
||||
done();
|
||||
});
|
||||
} catch(ex) {
|
||||
// exception not expected here
|
||||
expect(false).toBe(true);
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it(suiteName + "error handler returning true causes rollback", function(done) {
|
||||
withTestTable(function(db) {
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql("insert into test_table (data, data_num) VALUES (?,?)", ['test', null], function(tx, res) {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.rowsAffected).toBe(1);
|
||||
|
||||
tx.executeSql("select * from bogustable", [], function(tx, res) {
|
||||
// NOT EXPECTED:
|
||||
done.fail();
|
||||
}, function(tx, err) {
|
||||
// EXPECTED RESULT:
|
||||
expect(err.message).toBeDefined();
|
||||
return true;
|
||||
});
|
||||
});
|
||||
}, function(err) {
|
||||
// EXPECTED RESULT:
|
||||
expect(err.message).toBeTruthy(); // should report error message
|
||||
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql("select count(*) as cnt from test_table", [], function(tx, res) {
|
||||
// EXPECTED RESULT:
|
||||
expect(res.rows.item(0).cnt).toBe(0); // should have rolled back
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
}, function() {
|
||||
// NOT EXPECTED - not supposed to succeed:
|
||||
logError('not supposed to succeed');
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// NOTE: conclusion reached with @aarononeal and @nolanlawson in litehelpers/Cordova-sqlite-storage#232
|
||||
// that the according to the spec at http://www.w3.org/TR/webdatabase/ the transaction should be
|
||||
// recovered *only* if the sql error handler returns false.
|
||||
it(suiteName + 'error handler returning false lets transaction continue', function(done) {
|
||||
var check1 = false;
|
||||
withTestTable(function(db) {
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql("insert into test_table (data, data_num) VALUES (?,?)", ['test', null], function(tx, res) {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.rowsAffected).toBe(1);
|
||||
tx.executeSql("select * from bogustable", [], function(tx, res) {
|
||||
// NOT EXPECTED:
|
||||
logError("select statement not supposed to succeed");
|
||||
done.fail();
|
||||
}, function(tx, err) {
|
||||
// EXPECTED RESULT:
|
||||
check1 = true;
|
||||
expect(err.message).toBeTruthy(); // should report a valid error message
|
||||
return false;
|
||||
});
|
||||
});
|
||||
}, function(error) {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError('transaction was supposed to succeed: ' + error.message);
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
}, function() {
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql("select count(*) as cnt from test_table", [], function(tx, res) {
|
||||
expect(check1).toBe(true);
|
||||
expect(res.rows.item(0).cnt).toBe(1); // should have commited
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it(suiteName + "missing error handler causes rollback", function(done) {
|
||||
withTestTable(function(db) {
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql("insert into test_table (data, data_num) VALUES (?,?)", ['test', null], function(tx, res) {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.rowsAffected).toEqual(1);
|
||||
tx.executeSql("select * from bogustable", [], function(tx, res) {
|
||||
// NOT EXPECTED:
|
||||
logError("select statement not supposed to succeed");
|
||||
done.fail();
|
||||
});
|
||||
});
|
||||
}, function(err) {
|
||||
// EXPECTED RESULT:
|
||||
expect(err.message).toBeTruthy(); // should report a valid error message
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql("select count(*) as cnt from test_table", [], function(tx, res) {
|
||||
expect(res.rows.item(0).cnt).toBe(0); // should have rolled back
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
}, function() {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError("transaction was supposed to fail");done.fail();
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it(suiteName + "executeSql fails outside transaction", function(done) {
|
||||
var check1 = false;
|
||||
withTestTable(function(db) {
|
||||
expect(db).toBeTruthy(); // db ok
|
||||
var txg;
|
||||
db.transaction(function(tx) {
|
||||
expect(tx).toBeTruthy(); // tx ok
|
||||
txg = tx;
|
||||
tx.executeSql("insert into test_table (data, data_num) VALUES (?,?)", ['test', null], function(tx, res) {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.rowsAffected).toEqual(1);
|
||||
check1 = true;
|
||||
});
|
||||
}, function(error) {
|
||||
// ERROR NOT EXPECTED here:
|
||||
logError('unexpected error callback with message: ' + error.message);
|
||||
expect(error.message).toBe('--');
|
||||
done.fail();
|
||||
}, function() {
|
||||
// this simulates what would happen if a Promise ran on the next tick
|
||||
// and invoked an execute on the transaction
|
||||
try {
|
||||
txg.executeSql("select count(*) as cnt from test_table", [], null, null);
|
||||
// NOT EXPECTED to get here:
|
||||
logError("executeSql should have thrown but continued instead");
|
||||
done.fail();
|
||||
} catch(err) {
|
||||
expect(err.message).toBeTruthy(); // error had valid message
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it(suiteName + "readTransaction should fail & report error on modification", function(done) {
|
||||
var db = openDatabase("tx-readonly-test.db", "1.0", "Demo", DEFAULT_SIZE);
|
||||
|
||||
db.transaction(function(tx) {
|
||||
tx.executeSql('DROP TABLE IF EXISTS test_table');
|
||||
tx.executeSql('DROP TABLE IF EXISTS ExtraTestTable1');
|
||||
tx.executeSql('DROP TABLE IF EXISTS ExtraTestTable2');
|
||||
tx.executeSql('DROP TABLE IF EXISTS ExtraTestTable3');
|
||||
tx.executeSql('DROP TABLE IF EXISTS ExtraTestTable4');
|
||||
tx.executeSql('DROP TABLE IF EXISTS ExtraTestTable5');
|
||||
tx.executeSql('DROP TABLE IF EXISTS ExtraTestTable6');
|
||||
tx.executeSql('DROP TABLE IF EXISTS AlterTestTable');
|
||||
|
||||
tx.executeSql('CREATE TABLE test_table (data)');
|
||||
tx.executeSql('INSERT INTO test_table VALUES (?)', ['first']);
|
||||
|
||||
tx.executeSql('CREATE TABLE AlterTestTable (FirstColumn)');
|
||||
}, function () {}, function () {
|
||||
db.readTransaction(function (tx) {
|
||||
tx.executeSql('SELECT * from test_table', [], function (tx, res) {
|
||||
expect(res.rows.length).toBe(1);
|
||||
expect(res.rows.item(0).data).toBe('first');
|
||||
});
|
||||
}, function () {}, function () {
|
||||
var numDone = 0;
|
||||
var failed = false;
|
||||
var tasks;
|
||||
|
||||
function checkDone() {
|
||||
if (++numDone === tasks.length) {
|
||||
done();
|
||||
}
|
||||
}
|
||||
function fail() {
|
||||
if (!failed) {
|
||||
expect(false).toBe(true);
|
||||
expect('readTransaction was supposed to fail').toBe('--');
|
||||
failed = true;
|
||||
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
tasks = [
|
||||
// these transactions should be OK:
|
||||
function () {
|
||||
db.readTransaction(function (tx) {
|
||||
tx.executeSql(' SELECT 1;');
|
||||
}, fail, checkDone);
|
||||
},
|
||||
function () {
|
||||
db.readTransaction(function (tx) {
|
||||
tx.executeSql('; SELECT 1;');
|
||||
}, fail, checkDone);
|
||||
},
|
||||
|
||||
// all of these transactions should report an error
|
||||
function () {
|
||||
db.readTransaction(function (tx) {
|
||||
tx.executeSql('UPDATE test_table SET foo = "another"');
|
||||
}, checkDone, fail);
|
||||
},
|
||||
function () {
|
||||
db.readTransaction(function (tx) {
|
||||
tx.executeSql('INSERT INTO test_table VALUES ("another")');
|
||||
}, checkDone, fail);
|
||||
},
|
||||
function () {
|
||||
db.readTransaction(function (tx) {
|
||||
tx.executeSql('DELETE from test_table');
|
||||
}, checkDone, fail);
|
||||
},
|
||||
function () {
|
||||
db.readTransaction(function (tx) {
|
||||
tx.executeSql('DROP TABLE test_table');
|
||||
}, checkDone, fail);
|
||||
},
|
||||
function () {
|
||||
db.readTransaction(function (tx) {
|
||||
// extra space before sql (OK)
|
||||
tx.executeSql(' CREATE TABLE test_table2 (data)');
|
||||
}, checkDone, fail);
|
||||
},
|
||||
function () {
|
||||
db.readTransaction(function (tx) {
|
||||
// two extra spaces before sql (OK)
|
||||
tx.executeSql(' CREATE TABLE test_table3 (data)');
|
||||
}, checkDone, fail);
|
||||
},
|
||||
function () {
|
||||
db.readTransaction(function (tx) {
|
||||
tx.executeSql('; CREATE TABLE ExtraTestTable1 (data)');
|
||||
}, checkDone, fail);
|
||||
},
|
||||
function () {
|
||||
db.readTransaction(function (tx) {
|
||||
tx.executeSql(' ; CREATE TABLE ExtraTestTable2 (data)');
|
||||
}, checkDone, fail);
|
||||
},
|
||||
function () {
|
||||
db.readTransaction(function (tx) {
|
||||
tx.executeSql(';CREATE TABLE ExtraTestTable3 (data)');
|
||||
}, checkDone, fail);
|
||||
},
|
||||
function () {
|
||||
db.readTransaction(function (tx) {
|
||||
tx.executeSql(';; CREATE TABLE ExtraTestTable4 (data)');
|
||||
}, checkDone, fail);
|
||||
},
|
||||
function () {
|
||||
db.readTransaction(function (tx) {
|
||||
tx.executeSql('; ;CREATE TABLE ExtraTestTable5 (data)');
|
||||
}, checkDone, fail);
|
||||
},
|
||||
function () {
|
||||
db.readTransaction(function (tx) {
|
||||
tx.executeSql('; ; CREATE TABLE ExtraTestTable6 (data)');
|
||||
}, checkDone, fail);
|
||||
},
|
||||
function () {
|
||||
db.readTransaction(function (tx) {
|
||||
tx.executeSql('ALTER TABLE AlterTestTable ADD COLUMN NewColumn');
|
||||
}, checkDone, fail);
|
||||
},
|
||||
function () {
|
||||
db.readTransaction(function (tx) {
|
||||
tx.executeSql('REINDEX');
|
||||
}, checkDone, fail);
|
||||
},
|
||||
function () {
|
||||
db.readTransaction(function (tx) {
|
||||
tx.executeSql('REPLACE INTO test_table VALUES ("another")');
|
||||
}, checkDone, fail);
|
||||
},
|
||||
];
|
||||
for (var i = 0; i < tasks.length; i++) {
|
||||
tasks[i]();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it(suiteName + ' test callback order', function (done) {
|
||||
var db = openDatabase("Database-Callback-Order", "1.0", "Demo", DEFAULT_SIZE);
|
||||
var blocked = true;
|
||||
|
||||
db.transaction(function(tx) {
|
||||
// callback to the transaction shouldn't block (1)
|
||||
expect(blocked).toBe(false);
|
||||
tx.executeSql('SELECT 1', [], function () {
|
||||
// callback to the transaction shouldn't block (2)
|
||||
expect(blocked).toBe(false);
|
||||
});
|
||||
}, function(err) { ok(false, err.message) }, function() {
|
||||
// callback to the transaction shouldn't block (3)
|
||||
expect(blocked).toBe(false);
|
||||
|
||||
done();
|
||||
});
|
||||
blocked = false;
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (window.hasBrowser) mytests();
|
||||
else exports.defineAutoTests = mytests;
|
||||
|
||||
/* vim: set expandtab : */
|
Reference in New Issue
Block a user