updated ios references, added docs & tests

This commit is contained in:
Steven Gill
2013-06-18 16:34:22 -07:00
parent 26b4948cd3
commit 5ac7d84736
23 changed files with 5022 additions and 4 deletions
+303
View File
@@ -0,0 +1,303 @@
---
license: Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
---
FileTransfer
==========
The `FileTransfer` object allows you to upload or download files to
and from a server.
Properties
----------
- __onprogress__: Called with a `ProgressEvent` whenever a new chunk of data is transferred. _(Function)_
Methods
-------
- __upload__: sends a file to a server.
- __download__: downloads a file from server.
- __abort__: Aborts an in-progress transfer.
Details
-------
The `FileTransfer` object provides a way to upload files to a remote
server using an HTTP multi-part POST request. Both HTTP and HTTPS
protocols are supported. Optional parameters can be specified by
passing a `FileUploadOptions` object to the `upload()` method. On
successful upload, a `FileUploadResult` object is passed to the
success callback. If an error occurs, a `FileTransferError` object is
passed to the error callback. It is also possible (only on iOS and
Android) to download a file from a remote server and save it on the
device.
Supported Platforms
-------------------
- Android
- BlackBerry WebWorks (OS 5.0 and higher)
- iOS
- Windows Phone 7 and 8
- Windows 8
upload
--------------
__Parameters:__
- __filePath__: Full path of the file on the device.
- __server__: URL of the server to receive the file, as encoded by `encodeURI()`.
- __successCallback__: A callback that is passed a `Metadata` object. _(Function)_
- __errorCallback__: A callback that executes if an error occurs retrieving the `Metadata`. Invoked with a `FileTransferError` object. _(Function)_
- __options__: Optional parameters such as file name and mimetype.
- __trustAllHosts__: Optional parameter, defaults to `false`. If set to true, it accepts all security certificates. This is useful since Android rejects self-signed security certificates. Not recommended for production use. Supported on Android and iOS. _(boolean)_
__Quick Example__
// !! Assumes variable fileURI contains a valid URI to a text file on the device
var win = function (r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
}
var fail = function (error) {
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = fileURI.substr(fileURI.lastIndexOf('/') + 1);
options.mimeType = "text/plain";
var params = {};
params.value1 = "test";
params.value2 = "param";
options.params = params;
var ft = new FileTransfer();
ft.upload(fileURI, encodeURI("http://some.server.com/upload.php"), win, fail, options);
__Full Example__
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>File Transfer Example</title>
<script type="text/javascript" charset="utf-8" src="cordova-x.x.x.js"></script>
<script type="text/javascript" charset="utf-8">
// Wait for device API libraries to load
//
document.addEventListener("deviceready", onDeviceReady, false);
// device APIs are available
//
function onDeviceReady() {
// Retrieve image file location from specified source
navigator.camera.getPicture(
uploadPhoto,
function(message) { alert('get picture failed'); },
{
quality : 50,
destinationType : navigator.camera.DestinationType.FILE_URI,
sourceType : navigator.camera.PictureSourceType.PHOTOLIBRARY
}
);
}
function uploadPhoto(imageURI) {
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
options.mimeType="image/jpeg";
var params = {};
params.value1 = "test";
params.value2 = "param";
options.params = params;
var ft = new FileTransfer();
ft.upload(imageURI, encodeURI("http://some.server.com/upload.php"), win, fail, options);
}
function win(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
}
function fail(error) {
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
</script>
</head>
<body>
<h1>Example</h1>
<p>Upload File</p>
</body>
</html>
__Setting Upload Headers__
Supported on Android and iOS
function win(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
}
function fail(error) {
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
var uri = encodeURI("http://some.server.com/upload.php");
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=fileURI.substr(fileURI.lastIndexOf('/')+1);
options.mimeType="text/plain";
var headers={'headerParam':'headerValue'};
options.headers = headers;
var ft = new FileTransfer();
ft.upload(fileURI, uri, win, fail, options);
__Android Quirks__
Set the `chunkedMode` option to `false` to prevent problems uploading
to a Nginx server.
download
--------------
__Parameters:__
- __source__: URL of the server to download the file, as encoded by `encodeURI()`.
- __target__: Full path of the file on the device.
- __successCallback__: A callback that is passed a `FileEntry` object. _(Function)_
- __errorCallback__: A callback that executes if an error occurs when retrieving the `Metadata`. Invoked with a `FileTransferError` object. _(Function)_
- __trustAllHosts__: Optional parameter, defaults to `false`. If set to `true` then it will accept all security certificates. This is useful as Android rejects self signed security certificates. Not recommended for production use. Supported on Android and iOS. _(boolean)_
- __options__: Optional parameters, currently only supports headers (such as Authorization (Basic Authentication), etc).
__Quick Example__
// !! Assumes filePath is a valid path on the device
var fileTransfer = new FileTransfer();
var uri = encodeURI("http://some.server.com/download.php");
fileTransfer.download(
uri,
filePath,
function(entry) {
console.log("download complete: " + entry.fullPath);
},
function(error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("upload error code" + error.code);
},
false,
{
headers: {
"Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
}
}
);
abort
--------------
Aborts an in-progress transfer. The onerror callback is passed a FileTransferError object which has an error code of FileTransferError.ABORT_ERR.
__Supported Platforms__
- Android
- iOS
__Quick Example__
// !! Assumes variable fileURI contains a valid URI to a text file on the device
var win = function(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
}
var fail = function(error) {
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=fileURI.substr(fileURI.lastIndexOf('/')+1);
options.mimeType="text/plain";
var params = {};
params.value1 = "test";
params.value2 = "param";
options.params = params;
var ft = new FileTransfer();
ft.upload(fileURI, encodeURI("http://some.server.com/upload.php"), win, fail, options);
ft.abort(win, fail);
onprogress
--------------
Called with a ProgressEvent whenever a new chunk of data is transferred.
__Supported Platforms__
- Android
- iOS
__Example__
fileTransfer.onprogress = function(progressEvent) {
if (progressEvent.lengthComputable) {
loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);
} else {
loadingStatus.increment();
}
};
fileTransfer.download(...); // or fileTransfer.upload(...);
__Quirks__
- On both Android an iOS, lengthComputable is false for downloads that use gzip encoding.
@@ -0,0 +1,45 @@
---
license: Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
---
FileTransferError
========
A `FileTransferError` object is passed to an error callback when an error occurs.
Properties
----------
- __code__: One of the predefined error codes listed below. (Number)
- __source__: URI to the source. (String)
- __target__: URI to the target. (String)
- __http_status__: HTTP status code. This attribute is only available when a response code is received from the HTTP connection. (Number)
Constants
---------
- `FileTransferError.FILE_NOT_FOUND_ERR`
- `FileTransferError.INVALID_URL_ERR`
- `FileTransferError.CONNECTION_ERR`
- `FileTransferError.ABORT_ERR`
Description
-----------
The `FileTransferError` object is passed to the error callback when an
error occurs when uploading or downloading a file.
+1 -2
View File
@@ -2,8 +2,7 @@
<plugin xmlns="http://cordova.apache.org/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="org.apache.cordova.core.FileTransfer">
version="0.1.0">
id="org.apache.cordova.core.FileTransfer" version="0.1.0">
<name>File Transfer</name>
<dependency id="org.apache.cordova.core.FileUtils" url="https://git-wip-us.apache.org/repos/asf/cordova-plugin-file" commit="master" subdir="/*" />
+1 -1
View File
@@ -18,7 +18,7 @@
*/
#import <Foundation/Foundation.h>
#import "CDVPlugin.h"
#import <Cordova/CDVPlugin.h>
enum CDVFileTransferError {
FILE_NOT_FOUND_ERR = 1,
+3 -1
View File
@@ -17,7 +17,9 @@
under the License.
*/
#import "CDV.h"
#import <Cordova/CDV.h>
#import "CDVFileTransfer.h"
#import "CDVFile"
#import <AssetsLibrary/ALAsset.h>
#import <AssetsLibrary/ALAssetRepresentation.h>
+101
View File
@@ -0,0 +1,101 @@
jasmine.HtmlReporter = function(_doc) {
var self = this;
var doc = _doc || window.document;
var reporterView;
var dom = {};
// Jasmine Reporter Public Interface
self.logRunningSpecs = false;
self.reportRunnerStarting = function(runner) {
var specs = runner.specs() || [];
if (specs.length == 0) {
return;
}
createReporterDom(runner.env.versionString());
doc.body.appendChild(dom.reporter);
reporterView = new jasmine.HtmlReporter.ReporterView(dom);
reporterView.addSpecs(specs, self.specFilter);
};
self.reportRunnerResults = function(runner) {
reporterView && reporterView.complete();
};
self.reportSuiteResults = function(suite) {
reporterView.suiteComplete(suite);
};
self.reportSpecStarting = function(spec) {
if (self.logRunningSpecs) {
self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
}
};
self.reportSpecResults = function(spec) {
reporterView.specComplete(spec);
};
self.log = function() {
var console = jasmine.getGlobal().console;
if (console && console.log) {
if (console.log.apply) {
console.log.apply(console, arguments);
} else {
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
}
}
};
self.specFilter = function(spec) {
if (!focusedSpecName()) {
return true;
}
return spec.getFullName().indexOf(focusedSpecName()) === 0;
};
return self;
function focusedSpecName() {
var specName;
(function memoizeFocusedSpec() {
if (specName) {
return;
}
var paramMap = [];
var params = doc.location.search.substring(1).split('&');
for (var i = 0; i < params.length; i++) {
var p = params[i].split('=');
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
}
specName = paramMap.spec;
})();
return specName;
}
function createReporterDom(version) {
dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
dom.banner = self.createDom('div', { className: 'banner' },
self.createDom('span', { className: 'title' }, "Jasmine "),
self.createDom('span', { className: 'version' }, version)),
dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
dom.alert = self.createDom('div', {className: 'alert'}),
dom.results = self.createDom('div', {className: 'results'},
dom.summary = self.createDom('div', { className: 'summary' }),
dom.details = self.createDom('div', { id: 'details' }))
);
}
};
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);
+60
View File
@@ -0,0 +1,60 @@
jasmine.HtmlReporterHelpers = {};
jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) {
var el = document.createElement(type);
for (var i = 2; i < arguments.length; i++) {
var child = arguments[i];
if (typeof child === 'string') {
el.appendChild(document.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;
};
jasmine.HtmlReporterHelpers.getSpecStatus = function(child) {
var results = child.results();
var status = results.passed() ? 'passed' : 'failed';
if (results.skipped) {
status = 'skipped';
}
return status;
};
jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {
var parentDiv = this.dom.summary;
var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';
var parent = child[parentSuite];
if (parent) {
if (typeof this.views.suites[parent.id] == 'undefined') {
this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);
}
parentDiv = this.views.suites[parent.id].element;
}
parentDiv.appendChild(childElement);
};
jasmine.HtmlReporterHelpers.addHelpers = function(ctor) {
for(var fn in jasmine.HtmlReporterHelpers) {
ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];
}
};
+164
View File
@@ -0,0 +1,164 @@
jasmine.HtmlReporter.ReporterView = function(dom) {
this.startedAt = new Date();
this.runningSpecCount = 0;
this.completeSpecCount = 0;
this.passedCount = 0;
this.failedCount = 0;
this.skippedCount = 0;
this.createResultsMenu = function() {
this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'),
' | ',
this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing'));
this.summaryMenuItem.onclick = function() {
dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');
};
this.detailsMenuItem.onclick = function() {
showDetails();
};
};
this.addSpecs = function(specs, specFilter) {
this.totalSpecCount = specs.length;
this.views = {
specs: {},
suites: {}
};
for (var i = 0; i < specs.length; i++) {
var spec = specs[i];
this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);
if (specFilter(spec)) {
this.runningSpecCount++;
}
}
};
this.specComplete = function(spec) {
this.completeSpecCount++;
if (isUndefined(this.views.specs[spec.id])) {
this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);
}
var specView = this.views.specs[spec.id];
switch (specView.status()) {
case 'passed':
this.passedCount++;
break;
case 'failed':
this.failedCount++;
break;
case 'skipped':
this.skippedCount++;
break;
}
specView.refresh();
this.refresh();
};
this.suiteComplete = function(suite) {
var suiteView = this.views.suites[suite.id];
if (isUndefined(suiteView)) {
return;
}
suiteView.refresh();
};
this.refresh = function() {
if (isUndefined(this.resultsMenu)) {
this.createResultsMenu();
}
// currently running UI
if (isUndefined(this.runningAlert)) {
this.runningAlert = this.createDom('a', {href: "?", className: "runningAlert bar"});
dom.alert.appendChild(this.runningAlert);
}
this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount);
// skipped specs UI
if (isUndefined(this.skippedAlert)) {
this.skippedAlert = this.createDom('a', {href: "?", className: "skippedAlert bar"});
}
this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
if (this.skippedCount === 1 && isDefined(dom.alert)) {
dom.alert.appendChild(this.skippedAlert);
}
// passing specs UI
if (isUndefined(this.passedAlert)) {
this.passedAlert = this.createDom('span', {href: "?", className: "passingAlert bar"});
}
this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount);
// failing specs UI
if (isUndefined(this.failedAlert)) {
this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"});
}
this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount);
if (this.failedCount === 1 && isDefined(dom.alert)) {
dom.alert.appendChild(this.failedAlert);
dom.alert.appendChild(this.resultsMenu);
}
// summary info
this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount);
this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing";
};
this.complete = function() {
dom.alert.removeChild(this.runningAlert);
this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
if (this.failedCount === 0) {
dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount)));
} else {
showDetails();
}
dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"));
};
return this;
function showDetails() {
if (dom.reporter.className.search(/showDetails/) === -1) {
dom.reporter.className += " showDetails";
}
}
function isUndefined(obj) {
return typeof obj === 'undefined';
}
function isDefined(obj) {
return !isUndefined(obj);
}
function specPluralizedFor(count) {
var str = count + " spec";
if (count > 1) {
str += "s"
}
return str;
}
};
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);
+79
View File
@@ -0,0 +1,79 @@
jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
this.spec = spec;
this.dom = dom;
this.views = views;
this.symbol = this.createDom('li', { className: 'pending' });
this.dom.symbolSummary.appendChild(this.symbol);
this.summary = this.createDom('div', { className: 'specSummary' },
this.createDom('a', {
className: 'description',
href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
title: this.spec.getFullName()
}, this.spec.description)
);
this.detail = this.createDom('div', { className: 'specDetail' },
this.createDom('a', {
className: 'description',
href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
title: this.spec.getFullName()
}, this.spec.getFullName())
);
};
jasmine.HtmlReporter.SpecView.prototype.status = function() {
return this.getSpecStatus(this.spec);
};
jasmine.HtmlReporter.SpecView.prototype.refresh = function() {
this.symbol.className = this.status();
switch (this.status()) {
case 'skipped':
break;
case 'passed':
this.appendSummaryToSuiteDiv();
break;
case 'failed':
this.appendSummaryToSuiteDiv();
this.appendFailureDetail();
break;
}
};
jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
this.summary.className += ' ' + this.status();
this.appendToSummary(this.spec, this.summary);
};
jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
this.detail.className += ' ' + this.status();
var resultItems = this.spec.results().getItems();
var messagesDiv = this.createDom('div', { className: 'messages' });
for (var i = 0; i < resultItems.length; i++) {
var result = resultItems[i];
if (result.type == 'log') {
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
} else if (result.type == 'expect' && result.passed && !result.passed()) {
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
if (result.trace.stack) {
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
}
}
}
if (messagesDiv.childNodes.length > 0) {
this.detail.appendChild(messagesDiv);
this.dom.details.appendChild(this.detail);
}
};
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);
+22
View File
@@ -0,0 +1,22 @@
jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {
this.suite = suite;
this.dom = dom;
this.views = views;
this.element = this.createDom('div', { className: 'suite' },
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(this.suite.getFullName()) }, this.suite.description)
);
this.appendToSummary(this.suite, this.element);
};
jasmine.HtmlReporter.SuiteView.prototype.status = function() {
return this.getSpecStatus(this.suite);
};
jasmine.HtmlReporter.SuiteView.prototype.refresh = function() {
this.element.className += " " + this.status();
};
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);
+192
View File
@@ -0,0 +1,192 @@
/* @deprecated Use jasmine.HtmlReporter instead
*/
jasmine.TrivialReporter = function(doc) {
this.document = doc || document;
this.suiteDivs = {};
this.logRunningSpecs = false;
};
jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
var el = document.createElement(type);
for (var i = 2; i < arguments.length; i++) {
var child = arguments[i];
if (typeof child === 'string') {
el.appendChild(document.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;
};
jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
var showPassed, showSkipped;
this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' },
this.createDom('div', { className: 'banner' },
this.createDom('div', { className: 'logo' },
this.createDom('span', { className: 'title' }, "Jasmine"),
this.createDom('span', { className: 'version' }, runner.env.versionString())),
this.createDom('div', { className: 'options' },
"Show ",
showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
)
),
this.runnerDiv = this.createDom('div', { className: 'runner running' },
this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
);
this.document.body.appendChild(this.outerDiv);
var suites = runner.suites();
for (var i = 0; i < suites.length; i++) {
var suite = suites[i];
var suiteDiv = this.createDom('div', { className: 'suite' },
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
this.suiteDivs[suite.id] = suiteDiv;
var parentDiv = this.outerDiv;
if (suite.parentSuite) {
parentDiv = this.suiteDivs[suite.parentSuite.id];
}
parentDiv.appendChild(suiteDiv);
}
this.startedAt = new Date();
var self = this;
showPassed.onclick = function(evt) {
if (showPassed.checked) {
self.outerDiv.className += ' show-passed';
} else {
self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
}
};
showSkipped.onclick = function(evt) {
if (showSkipped.checked) {
self.outerDiv.className += ' show-skipped';
} else {
self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
}
};
};
jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
var results = runner.results();
var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
this.runnerDiv.setAttribute("class", className);
//do it twice for IE
this.runnerDiv.setAttribute("className", className);
var specs = runner.specs();
var specCount = 0;
for (var i = 0; i < specs.length; i++) {
if (this.specFilter(specs[i])) {
specCount++;
}
}
var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
};
jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
var results = suite.results();
var status = results.passed() ? 'passed' : 'failed';
if (results.totalCount === 0) { // todo: change this to check results.skipped
status = 'skipped';
}
this.suiteDivs[suite.id].className += " " + status;
};
jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
if (this.logRunningSpecs) {
this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
}
};
jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
var results = spec.results();
var status = results.passed() ? 'passed' : 'failed';
if (results.skipped) {
status = 'skipped';
}
var specDiv = this.createDom('div', { className: 'spec ' + status },
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
this.createDom('a', {
className: 'description',
href: '?spec=' + encodeURIComponent(spec.getFullName()),
title: spec.getFullName()
}, spec.description));
var resultItems = results.getItems();
var messagesDiv = this.createDom('div', { className: 'messages' });
for (var i = 0; i < resultItems.length; i++) {
var result = resultItems[i];
if (result.type == 'log') {
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
} else if (result.type == 'expect' && result.passed && !result.passed()) {
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
if (result.trace.stack) {
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
}
}
}
if (messagesDiv.childNodes.length > 0) {
specDiv.appendChild(messagesDiv);
}
this.suiteDivs[spec.suite.id].appendChild(specDiv);
};
jasmine.TrivialReporter.prototype.log = function() {
var console = jasmine.getGlobal().console;
if (console && console.log) {
if (console.log.apply) {
console.log.apply(console, arguments);
} else {
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
}
}
};
jasmine.TrivialReporter.prototype.getLocation = function() {
return this.document.location;
};
jasmine.TrivialReporter.prototype.specFilter = function(spec) {
var paramMap = {};
var params = this.getLocation().search.substring(1).split('&');
for (var i = 0; i < params.length; i++) {
var p = params[i].split('=');
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
}
if (!paramMap.spec) {
return true;
}
return spec.getFullName().indexOf(paramMap.spec) === 0;
};
+59
View File
@@ -0,0 +1,59 @@
<!DOCTYPE html>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
<title>Cordova API Specs</title>
<link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
<script type="text/javascript" src="../cordova-incl.js"></script>
</head>
<body id="stage" class="theme">
<h1>Cordova API Specs</h1>
<a href="pages/all.html" class="btn large" style="width:100%;">Run All Tests</a>
<a href="pages/accelerometer.html" class="btn large" style="width:100%;">Run Accelerometer Tests</a>
<a href="pages/battery.html" class="btn large" style="width:100%;">Run Battery Tests</a>
<a href="pages/camera.html" class="btn large" style="width:100%;">Run Camera Tests</a>
<a href="pages/capture.html" class="btn large" style="width:100%;">Run Capture Tests</a>
<a href="pages/compass.html" class="btn large" style="width:100%;">Run Compass Tests</a>
<a href="pages/contacts.html" class="btn large" style="width:100%;">Run Contacts Tests</a>
<a href="pages/datauri.html" class="btn large" style="width:100%;">Run Data URI Tests</a>
<a href="pages/device.html" class="btn large" style="width:100%;">Run Device Tests</a>
<a href="pages/file.html" class="btn large" style="width:100%;">Run File Tests</a>
<a href="pages/filetransfer.html" class="btn large" style="width:100%;">Run FileTransfer Tests</a>
<a href="pages/geolocation.html" class="btn large" style="width:100%;">Run Geolocation Tests</a>
<a href="pages/globalization.html" class="btn large" style="width:100%;">Run Globalization Tests</a>
<a href="pages/media.html" class="btn large" style="width:100%;">Run Media Tests</a>
<a href="pages/network.html" class="btn large" style="width:100%;">Run Network Tests</a>
<a href="pages/notification.html" class="btn large" style="width:100%;">Run Notification Tests</a>
<a href="pages/platform.html" class="btn large" style="width:100%;">Run Platform Tests</a>
<a href="pages/storage.html" class="btn large" style="width:100%;">Run Storage Tests</a>
<a href="pages/bridge.html" class="btn large" style="width:100%;">Run Bridge Tests</a>
<h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
</body>
</html>
+81
View File
@@ -0,0 +1,81 @@
body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
#HTMLReporter a { text-decoration: none; }
#HTMLReporter a:hover { text-decoration: underline; }
#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
#HTMLReporter #jasmine_content { position: fixed; right: 100%; }
#HTMLReporter .version { color: #aaaaaa; }
#HTMLReporter .banner { margin-top: 14px; }
#HTMLReporter .duration { color: #aaaaaa; float: right; }
#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
#HTMLReporter .symbolSummary li.passed { font-size: 14px; }
#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; }
#HTMLReporter .symbolSummary li.failed { line-height: 9px; }
#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
#HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
#HTMLReporter .symbolSummary li.pending { line-height: 11px; }
#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
#HTMLReporter .runningAlert { background-color: #666666; }
#HTMLReporter .skippedAlert { background-color: #aaaaaa; }
#HTMLReporter .skippedAlert:first-child { background-color: #333333; }
#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
#HTMLReporter .passingAlert { background-color: #a6b779; }
#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
#HTMLReporter .failingAlert { background-color: #cf867e; }
#HTMLReporter .failingAlert:first-child { background-color: #b03911; }
#HTMLReporter .results { margin-top: 14px; }
#HTMLReporter #details { display: none; }
#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
#HTMLReporter.showDetails .summary { display: none; }
#HTMLReporter.showDetails #details { display: block; }
#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
#HTMLReporter .summary { margin-top: 14px; }
#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
#HTMLReporter .summary .specSummary.failed a { color: #b03911; }
#HTMLReporter .description + .suite { margin-top: 0; }
#HTMLReporter .suite { margin-top: 14px; }
#HTMLReporter .suite a { color: #333333; }
#HTMLReporter #details .specDetail { margin-bottom: 28px; }
#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }
#HTMLReporter .resultMessage span.result { display: block; }
#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
#TrivialReporter a:visited, #TrivialReporter a { color: #303; }
#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
#TrivialReporter .runner.running { background-color: yellow; }
#TrivialReporter .options { text-align: right; font-size: .8em; }
#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
#TrivialReporter .suite .suite { margin: 5px; }
#TrivialReporter .suite.passed { background-color: #dfd; }
#TrivialReporter .suite.failed { background-color: #fdd; }
#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
#TrivialReporter .spec.skipped { background-color: #bbb; }
#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
#TrivialReporter .passed { background-color: #cfc; display: none; }
#TrivialReporter .failed { background-color: #fbb; }
#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
#TrivialReporter .resultMessage .mismatch { color: black; }
#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
#TrivialReporter #jasmine_content { position: fixed; right: 100%; }
#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+91
View File
@@ -0,0 +1,91 @@
<!DOCTYPE html>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<html>
<head>
<title>Cordova: File API Specs</title>
<meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
<!-- Load jasmine -->
<link href="../jasmine.css" rel="stylesheet"/>
<script type="text/javascript" src="../jasmine.js"></script>
<script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
<script type="text/javascript" src="../html/HtmlReporter.js"></script>
<script type="text/javascript" src="../html/ReporterView.js"></script>
<script type="text/javascript" src="../html/SpecView.js"></script>
<script type="text/javascript" src="../html/SuiteView.js"></script>
<script type="text/javascript" src="../html/TrivialReporter.js"></script>
<!-- Source -->
<script type="text/javascript" src="../../cordova-incl.js"></script>
<!-- Load Test Runner -->
<script type="text/javascript" src="../test-runner.js"></script>
<!-- Tests -->
<script type="text/javascript" src="../tests/filetransfer.tests.js"></script>
<script type="text/javascript">
var root, temp_root, persistent_root;
document.addEventListener('deviceready', function () {
// one-time retrieval of the root file system entry
var onError = function(e) {
console.log('[ERROR] Problem setting up root filesystem for test running! Error to follow.');
console.log(JSON.stringify(e));
};
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
function(fileSystem) {
console.log('File API test Init: Setting PERSISTENT FS.');
root = fileSystem.root; // set in file.tests.js
persistent_root = root;
// Once root is set up, fire off tests
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 1000;
var htmlReporter = new jasmine.HtmlReporter();
jasmineEnv.addReporter(htmlReporter);
jasmineEnv.specFilter = function(spec) {
return htmlReporter.specFilter(spec);
};
jasmineEnv.execute();
}, onError);
window.requestFileSystem(LocalFileSystem.TEMPORARY, 0,
function(fileSystem) {
console.log('File API test Init: Setting TEMPORARY FS.');
temp_root = fileSystem.root; // set in file.tests.js
}, onError);
}, false);
</script>
</head>
<body>
<a href="javascript:" class="backBtn" onclick="backHome();">Back</a>
</body>
</html>
+62
View File
@@ -0,0 +1,62 @@
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
if (window.sessionStorage != null) {
window.sessionStorage.clear();
}
// Timeout is 2 seconds to allow physical devices enough
// time to query the response. This is important for some
// Android devices.
var Tests = function() {};
Tests.TEST_TIMEOUT = 7500;
// Creates a spy that will fail if called.
function createDoNotCallSpy(name, opt_extraMessage) {
return jasmine.createSpy().andCallFake(function() {
var errorMessage = name + ' should not have been called.';
if (arguments.length) {
errorMessage += ' Got args: ' + JSON.stringify(arguments);
}
if (opt_extraMessage) {
errorMessage += '\n' + opt_extraMessage;
}
expect(false).toBe(true, errorMessage);
});
}
// Waits for any of the given spys to be called.
// Last param may be a custom timeout duration.
function waitsForAny() {
var spys = [].slice.call(arguments);
var timeout = Tests.TEST_TIMEOUT;
if (typeof spys[spys.length - 1] == 'number') {
timeout = spys.pop();
}
waitsFor(function() {
for (var i = 0; i < spys.length; ++i) {
if (spys[i].wasCalled) {
return true;
}
}
return false;
}, "Expecting callbacks to be called.", timeout);
}
BIN
View File
Binary file not shown.
+753
View File
@@ -0,0 +1,753 @@
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
describe('FileTransfer', function() {
// https://github.com/apache/cordova-labs/tree/cordova-filetransfer
var server = "http://cordova-filetransfer.jitsu.com";
var server_with_credentials = "http://cordova_user:cordova_password@cordova-filetransfer.jitsu.com";
// deletes and re-creates the specified content
var writeFile = function(fileName, fileContent, success, error) {
deleteFile(fileName, function() {
root.getFile(fileName, {create: true}, function(fileEntry) {
fileEntry.createWriter(function (writer) {
writer.onwrite = function(evt) {
success(fileEntry);
};
writer.onabort = function(evt) {
error(evt);
};
writer.error = function(evt) {
error(evt);
};
writer.write(fileContent + "\n");
}, error);
}, error);
});
};
var readFileEntry = function(entry, success, error) {
entry.file(function(file) {
var reader = new FileReader();
reader.onerror = error;
reader.onload = function(e) {
success(reader.result);
};
reader.readAsText(file);
}, error);
};
var getMalformedUrl = function() {
if (device.platform.match(/Android/i)) {
// bad protocol causes a MalformedUrlException on Android
return "httpssss://example.com";
} else {
// iOS doesn't care about protocol, space in hostname causes error
return "httpssss://exa mple.com";
}
};
// deletes file, if it exists, then invokes callback
var deleteFile = function(fileName, callback) {
callback = callback || function() {};
var spy = jasmine.createSpy().andCallFake(callback);
root.getFile(fileName, null,
// remove file system entry
function(entry) {
entry.remove(spy, spy);
},
// doesn't exist
spy);
waitsFor(function() { return spy.wasCalled; }, Tests.TEST_TIMEOUT);
};
it("filetransfer.spec.1 should exist and be constructable", function() {
var ft = new FileTransfer();
expect(ft).toBeDefined();
});
it("filetransfer.spec.2 should contain proper functions", function() {
var ft = new FileTransfer();
expect(typeof ft.upload).toBe('function');
expect(typeof ft.download).toBe('function');
});
describe('FileTransferError', function() {
it("filetransfer.spec.3 FileTransferError constants should be defined", function() {
expect(FileTransferError.FILE_NOT_FOUND_ERR).toBe(1);
expect(FileTransferError.INVALID_URL_ERR).toBe(2);
expect(FileTransferError.CONNECTION_ERR).toBe(3);
});
});
describe('download method', function() {
// NOTE: if download tests are failing, check the white list
//
// <access origin="httpssss://example.com"/>
// <access origin="apache.org" subdomains="true" />
// <access origin="cordova-filetransfer.jitsu.com"/>
it("filetransfer.spec.4 should be able to download a file using http", function() {
var fail = createDoNotCallSpy('downloadFail');
var remoteFile = server + "/robots.txt"
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
var lastProgressEvent = null;
var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
expect(entry.name).toBe(localFileName);
expect(lastProgressEvent.loaded).toBeGreaterThan(1);
});
this.after(function() {
deleteFile(localFileName);
});
runs(function() {
var ft = new FileTransfer();
ft.onprogress = function(e) {
lastProgressEvent = e;
};
ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, fail);
});
waitsForAny(downloadWin, fail);
});
it("filetransfer.spec.5 should be able to download a file using http basic auth", function() {
var fail = createDoNotCallSpy('downloadFail');
var remoteFile = server_with_credentials + "/download_basic_auth"
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
var lastProgressEvent = null;
var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
expect(entry.name).toBe(localFileName);
expect(lastProgressEvent.loaded).toBeGreaterThan(1);
});
this.after(function() {
deleteFile(localFileName);
});
runs(function() {
var ft = new FileTransfer();
ft.onprogress = function(e) {
lastProgressEvent = e;
};
ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, fail);
});
waitsForAny(downloadWin, fail);
});
it("filetransfer.spec.6 should get http status on basic auth failure", function() {
var downloadWin = createDoNotCallSpy('downloadWin');
var remoteFile = server + "/download_basic_auth";
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
var downloadFail = jasmine.createSpy().andCallFake(function(error) {
expect(error.http_status).toBe(401);
expect(error.http_status).not.toBe(404, "Ensure " + remoteFile + " is in the white list");
});
this.after(function() {
deleteFile(localFileName);
});
runs(function() {
var ft = new FileTransfer();
ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, downloadFail);
});
waitsForAny(downloadWin, downloadFail);
});
it("filetransfer.spec.7 should be able to download a file using file:// (when hosted from file://)", function() {
var fail = createDoNotCallSpy('downloadFail');
var remoteFile = window.location.href.replace(/\?.*/, '').replace(/ /g, '%20');
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
var lastProgressEvent = null;
if (!/^file/.exec(remoteFile)) {
expect(remoteFile).toMatch(/^file:/);
return;
}
var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
expect(entry.name).toBe(localFileName);
expect(lastProgressEvent.loaded).toBeGreaterThan(1);
});
this.after(function() {
deleteFile(localFileName);
});
var ft = new FileTransfer();
ft.onprogress = function(e) {
lastProgressEvent = e;
};
ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, fail);
waitsForAny(downloadWin, fail);
});
it("filetransfer.spec.8 should be able to download a file using https", function() {
var remoteFile = "https://www.apache.org/licenses/";
var localFileName = 'httpstest.html';
var downloadFail = createDoNotCallSpy('downloadFail', 'Ensure ' + remoteFile + ' is in the white-list');
var fileFail = createDoNotCallSpy('fileFail');
var downloadWin = function(entry) {
readFileEntry(entry, fileWin, fileFail);
};
var fileWin = jasmine.createSpy().andCallFake(function(content) {
expect(content).toMatch(/The Apache Software Foundation/);
});
this.after(function() {
deleteFile(localFileName);
});
runs(function() {
var ft = new FileTransfer();
ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, downloadFail);
});
waitsForAny(fileWin, downloadFail, fileFail);
});
it("filetransfer.spec.9 should not leave partial file due to abort", function() {
var downloadWin = createDoNotCallSpy('downloadWin');
var remoteFile = 'http://cordova.apache.org/downloads/logos_2.zip';
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
var startTime = +new Date();
var downloadFail = jasmine.createSpy().andCallFake(function(e) {
expect(e.code).toBe(FileTransferError.ABORT_ERR);
var didNotExistSpy = jasmine.createSpy();
var existedSpy = createDoNotCallSpy('file existed after abort');
root.getFile(localFileName, null, existedSpy, didNotExistSpy);
waitsForAny(didNotExistSpy, existedSpy);
});
runs(function() {
var ft = new FileTransfer();
ft.onprogress = function(e) {
if (e.loaded > 0) {
ft.abort();
}
};
ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, downloadFail);
});
waitsForAny(downloadWin, downloadFail);
});
it("filetransfer.spec.10 should be stopped by abort() right away", function() {
var downloadWin = createDoNotCallSpy('downloadWin');
var remoteFile = 'http://cordova.apache.org/downloads/BlueZedEx.mp3';
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
var startTime = +new Date();
var downloadFail = jasmine.createSpy().andCallFake(function(e) {
expect(e.code).toBe(FileTransferError.ABORT_ERR);
expect(new Date() - startTime).toBeLessThan(300);
});
this.after(function() {
deleteFile(localFileName);
});
runs(function() {
var ft = new FileTransfer();
ft.abort(); // should be a no-op.
ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, downloadFail);
ft.abort();
ft.abort(); // should be a no-op.
});
waitsForAny(downloadWin, downloadFail);
});
it("filetransfer.spec.11 should call the error callback on abort()", function() {
var downloadWin = createDoNotCallSpy('downloadWin');
var downloadFail = jasmine.createSpy().andCallFake(function(e) { console.log("Abort called") });
var remoteFile = 'http://cordova.apache.org/downloads/BlueZedEx.mp3';
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
var startTime = +new Date();
this.after(function() {
deleteFile(localFileName);
});
runs(function() {
var ft = new FileTransfer();
ft.abort(); // should be a no-op.
ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, downloadFail);
ft.abort();
ft.abort(); // should be a no-op.
});
waitsForAny(downloadFail);
});
it("filetransfer.spec.12 should get http status on failure", function() {
var downloadWin = createDoNotCallSpy('downloadWin');
var remoteFile = server + "/404";
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
var downloadFail = jasmine.createSpy().andCallFake(function(error) {
expect(error.http_status).toBe(404);
expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
});
this.after(function() {
deleteFile(localFileName);
});
runs(function() {
var ft = new FileTransfer();
ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, downloadFail);
});
waitsForAny(downloadWin, downloadFail);
});
it("filetransfer.spec.13 should get response body on failure", function() {
var downloadWin = createDoNotCallSpy('downloadWin');
var remoteFile = server + "/404";
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
var downloadFail = jasmine.createSpy().andCallFake(function(error) {
expect(error.body).toBeDefined();
expect(error.body).toEqual('You requested a 404\n');
});
this.after(function() {
deleteFile(localFileName);
});
runs(function() {
var ft = new FileTransfer();
ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, downloadFail);
});
waitsForAny(downloadWin, downloadFail);
});
it("filetransfer.spec.14 should handle malformed urls", function() {
var downloadWin = createDoNotCallSpy('downloadWin');
var remoteFile = getMalformedUrl();
var localFileName = "download_malformed_url.txt";
var downloadFail = jasmine.createSpy().andCallFake(function(error) {
// Note: Android needs the bad protocol to be added to the access list
// <access origin=".*"/> won't match because ^https?:// is prepended to the regex
// The bad protocol must begin with http to avoid automatic prefix
expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
expect(error.code).toBe(FileTransferError.INVALID_URL_ERR);
});
this.after(function() {
deleteFile(localFileName);
});
runs(function() {
var ft = new FileTransfer();
ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, downloadFail);
});
waitsForAny(downloadWin, downloadFail);
});
it("filetransfer.spec.15 should handle unknown host", function() {
var downloadWin = createDoNotCallSpy('downloadWin');
var remoteFile = "http://foobar.apache.org/index.html";
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
var downloadFail = jasmine.createSpy().andCallFake(function(error) {
expect(error.code).toBe(FileTransferError.CONNECTION_ERR);
});
runs(function() {
var ft = new FileTransfer();
ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, downloadFail);
});
waitsForAny(downloadWin, downloadFail);
});
it("filetransfer.spec.16 should handle bad file path", function() {
var downloadWin = createDoNotCallSpy('downloadWin');
var remoteFile = server;
var badFilePath = "c:\\54321";
var downloadFail = jasmine.createSpy().andCallFake(function(error) {
expect(error.code).toBe(FileTransferError.FILE_NOT_FOUND_ERR);
});
runs(function() {
var ft = new FileTransfer();
ft.download(remoteFile, badFilePath, downloadWin, downloadFail);
});
waitsForAny(downloadWin, downloadFail);
});
it("filetransfer.spec.17 progress should work with gzip encoding", function() {
var downloadFail = createDoNotCallSpy('downloadFail');
var remoteFile = "http://www.apache.org/";
var localFileName = "index.html";
var lastProgressEvent = null;
var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
expect(entry.name).toBe(localFileName);
expect(lastProgressEvent.loaded).toBeGreaterThan(1, 'loaded');
expect(lastProgressEvent.total).not.toBeLessThan(lastProgressEvent.loaded);
expect(lastProgressEvent.lengthComputable).toBe(true, 'lengthComputable');
});
this.after(function() {
deleteFile(localFileName);
});
runs(function() {
var ft = new FileTransfer();
ft.onprogress = function(e) {
lastProgressEvent = e;
};
ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, downloadFail);
});
waitsForAny(downloadWin, downloadFail);
});
});
describe('upload method', function() {
it("filetransfer.spec.18 should be able to upload a file", function() {
var remoteFile = server + "/upload";
var localFileName = "upload.txt";
var fileContents = 'This file should upload';
var fileFail = createDoNotCallSpy('fileFail');
var uploadFail = createDoNotCallSpy('uploadFail', "Ensure " + remoteFile + " is in the white list");
var lastProgressEvent = null;
var uploadWin = jasmine.createSpy().andCallFake(function(uploadResult) {
expect(uploadResult.bytesSent).toBeGreaterThan(0);
expect(uploadResult.responseCode).toBe(200);
expect(uploadResult.response).toMatch(/fields:\s*{\s*value1.*/);
});
var fileWin = function(fileEntry) {
ft = new FileTransfer();
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = localFileName;
options.mimeType = "text/plain";
var params = new Object();
params.value1 = "test";
params.value2 = "param";
options.params = params;
ft.onprogress = function(e) {
expect(e.lengthComputable).toBe(true);
expect(e.total).toBeGreaterThan(0);
expect(e.loaded).toBeGreaterThan(0);
lastProgressEvent = e;
};
// removing options cause Android to timeout
ft.upload(fileEntry.fullPath, remoteFile, uploadWin, uploadFail, options);
};
this.after(function() {
deleteFile(localFileName);
});
runs(function() {
writeFile(localFileName, fileContents, fileWin, fileFail);
});
waitsForAny(uploadWin, uploadFail, fileFail);
runs(function() {
expect(lastProgressEvent).not.toBeNull('expected progress events');
});
});
it("filetransfer.spec.19 should be able to upload a file with http basic auth", function() {
var remoteFile = server_with_credentials + "/upload_basic_auth";
var localFileName = "upload.txt";
var fileContents = 'This file should upload';
var fileFail = createDoNotCallSpy('fileFail');
var uploadFail = createDoNotCallSpy('uploadFail', "Ensure " + remoteFile + " is in the white list");
var lastProgressEvent = null;
var uploadWin = jasmine.createSpy().andCallFake(function(uploadResult) {
expect(uploadResult.bytesSent).toBeGreaterThan(0);
expect(uploadResult.responseCode).toBe(200);
expect(uploadResult.response).toMatch(/fields:\s*{\s*value1.*/);
});
var fileWin = function(fileEntry) {
ft = new FileTransfer();
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = localFileName;
options.mimeType = "text/plain";
var params = new Object();
params.value1 = "test";
params.value2 = "param";
options.params = params;
ft.onprogress = function(e) {
expect(e.lengthComputable).toBe(true);
expect(e.total).toBeGreaterThan(0);
expect(e.loaded).toBeGreaterThan(0);
lastProgressEvent = e;
};
// removing options cause Android to timeout
ft.upload(fileEntry.fullPath, remoteFile, uploadWin, uploadFail, options);
};
this.after(function() {
deleteFile(localFileName);
});
runs(function() {
writeFile(localFileName, fileContents, fileWin, fileFail);
});
waitsForAny(uploadWin, uploadFail, fileFail);
runs(function() {
expect(lastProgressEvent).not.toBeNull('expected progress events');
});
});
it("filetransfer.spec.6 should get http status on basic auth failure", function() {
var fileFail = createDoNotCallSpy('fileFail');
var uploadWin = createDoNotCallSpy('uploadWin');
var remoteFile = server + "/upload_basic_auth";
var localFileName = "upload_expect_fail.txt";
var uploadFail = jasmine.createSpy().andCallFake(function(error) {
expect(error.http_status).toBe(401);
expect(error.http_status).not.toBe(404, "Ensure " + remoteFile + " is in the white list");
});
var fileWin = function(fileEntry) {
var ft = new FileTransfer();
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=fileEntry.name;
options.mimeType="text/plain";
ft.upload(fileEntry.fullPath, remoteFile, uploadWin, uploadFail, options);
};
this.after(function() {
deleteFile(localFileName);
});
runs(function() {
writeFile(localFileName, "this file should fail to upload", fileWin, fileFail);
});
waitsForAny(uploadWin, uploadFail, fileFail);
});
it("filetransfer.spec.21 should be stopped by abort() right away.", function() {
var remoteFile = server + "/upload";
var localFileName = "upload.txt";
var fileFail = createDoNotCallSpy('fileFail');
var uploadWin = createDoNotCallSpy('uploadWin', 'Should have been aborted');
var startTime;
var uploadFail = jasmine.createSpy().andCallFake(function(e) {
expect(e.code).toBe(FileTransferError.ABORT_ERR);
expect(new Date() - startTime).toBeLessThan(300);
});
var fileWin = function(fileEntry) {
ft = new FileTransfer();
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = localFileName;
options.mimeType = "text/plain";
startTime = +new Date();
// removing options cause Android to timeout
ft.abort(); // should be a no-op.
ft.upload(fileEntry.fullPath, remoteFile, uploadWin, uploadFail, options);
ft.abort();
ft.abort(); // should be a no-op.
};
this.after(function() {
deleteFile(localFileName);
});
runs(function() {
writeFile(localFileName, new Array(10000).join('aborttest!'), fileWin, fileFail);
});
waitsForAny(uploadWin, uploadFail, fileFail);
});
it("filetransfer.spec.12 should get http status on failure", function() {
var fileFail = createDoNotCallSpy('fileFail');
var uploadWin = createDoNotCallSpy('uploadWin');
var remoteFile = server + "/403";
var localFileName = "upload_expect_fail.txt";
var uploadFail = jasmine.createSpy().andCallFake(function(error) {
expect(error.http_status).toBe(403);
expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
});
var fileWin = function(fileEntry) {
var ft = new FileTransfer();
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=fileEntry.name;
options.mimeType="text/plain";
ft.upload(fileEntry.fullPath, remoteFile, uploadWin, uploadFail, options);
};
this.after(function() {
deleteFile(localFileName);
});
runs(function() {
writeFile(localFileName, "this file should fail to upload", fileWin, fileFail);
});
waitsForAny(uploadWin, uploadFail, fileFail);
});
it("filetransfer.spec.14 should handle malformed urls", function() {
var fileFail = createDoNotCallSpy('fileFail');
var uploadWin = createDoNotCallSpy('uploadWin');
var remoteFile = getMalformedUrl();
var localFileName = "malformed_url.txt";
var uploadFail = jasmine.createSpy().andCallFake(function(error) {
expect(error.code).toBe(FileTransferError.INVALID_URL_ERR);
expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
});
var fileWin = function(fileEntry) {
var ft = new FileTransfer();
ft.upload(fileEntry.fullPath, remoteFile, uploadWin, uploadFail, {});
};
this.after(function() {
deleteFile(localFileName);
});
runs(function() {
writeFile(localFileName, "Some content", fileWin, fileFail);
});
waitsForAny(uploadWin, uploadFail, fileFail);
});
it("filetransfer.spec.15 should handle unknown host", function() {
var fileFail = createDoNotCallSpy('fileFail');
var uploadWin = createDoNotCallSpy('uploadWin');
var remoteFile = "http://foobar.apache.org/robots.txt";
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
var uploadFail = jasmine.createSpy().andCallFake(function(error) {
expect(error.code).toBe(FileTransferError.CONNECTION_ERR);
expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
});
var fileWin = function(fileEntry) {
var ft = new FileTransfer();
ft.upload(fileEntry.fullPath, remoteFile, uploadWin, uploadFail, {});
};
this.after(function() {
deleteFile(localFileName);
});
runs(function() {
writeFile(localFileName, "# allow all", fileWin, fileFail);
});
waitsForAny(uploadWin, uploadFail, fileFail);
});
it("filetransfer.spec.25 should handle missing file", function() {
var uploadWin = createDoNotCallSpy('uploadWin');
var remoteFile = server + "/upload";
var localFileName = "does_not_exist.txt";
var uploadFail = jasmine.createSpy().andCallFake(function(error) {
expect(error.code).toBe(FileTransferError.FILE_NOT_FOUND_ERR);
expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
});
runs(function() {
var ft = new FileTransfer();
ft.upload(root.fullPath + "/" + localFileName, remoteFile, uploadWin, uploadFail);
});
waitsForAny(uploadWin, uploadFail);
});
it("filetransfer.spec.16 should handle bad file path", function() {
var uploadWin = createDoNotCallSpy('uploadWin');
var remoteFile = server + "/upload";
var uploadFail = jasmine.createSpy().andCallFake(function(error) {
expect(error.code).toBe(FileTransferError.FILE_NOT_FOUND_ERR);
expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
});
runs(function() {
var ft = new FileTransfer();
ft.upload("/usr/local/bad/file/path.txt", remoteFile, uploadWin, uploadFail);
});
waitsForAny(uploadWin, uploadFail);
});
it("filetransfer.spec.27 should be able to set custom headers", function() {
var remoteFile = "http://whatheaders.com";
var localFileName = "upload.txt";
var fileFail = function() {};
var uploadFail = createDoNotCallSpy('uploadFail', "Ensure " + remoteFile + " is in the white list and that Content-Length header is being set.");
var uploadWin = jasmine.createSpy().andCallFake(function(uploadResult) {
expect(uploadResult.bytesSent).toBeGreaterThan(0);
expect(uploadResult.responseCode).toBe(200);
expect(uploadResult.response).toBeDefined();
var responseHtml = decodeURIComponent(uploadResult.response);
expect(responseHtml).toMatch(/CustomHeader1[\s\S]*CustomValue1/i);
expect(responseHtml).toMatch(/CustomHeader2[\s\S]*CustomValue2[\s\S]*CustomValue3/i, "Should allow array values");
});
var fileWin = function(fileEntry) {
ft = new FileTransfer();
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = localFileName;
options.mimeType = "text/plain";
var params = new Object();
params.value1 = "test";
params.value2 = "param";
options.params = params;
options.headers = {
"CustomHeader1": "CustomValue1",
"CustomHeader2": ["CustomValue2", "CustomValue3"],
};
// removing options cause Android to timeout
ft.upload(fileEntry.fullPath, remoteFile, uploadWin, uploadFail, options);
};
this.after(function() {
deleteFile(localFileName);
});
runs(function() {
writeFile(localFileName, "this file should upload", fileWin, fileFail);
});
waitsForAny(uploadWin, uploadFail);
});
});
});
+85
View File
@@ -0,0 +1,85 @@
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
var PLAT;
(function getPlatform() {
var platforms = {
android: /Android/,
ios: /(iPad)|(iPhone)|(iPod)/,
blackberry10: /(BB10)/,
blackberry: /(PlayBook)|(BlackBerry)/,
windows8: /MSAppHost/,
windowsphone: /Windows Phone/
};
for (var key in platforms) {
if (platforms[key].exec(navigator.userAgent)) {
PLAT = key;
break;
}
}
})();
var scripts = document.getElementsByTagName('script');
var currentPath = scripts[scripts.length - 1].src;
var platformCordovaPath = currentPath.replace("cordova-incl.js", "cordova." + PLAT + ".js");
var normalCordovaPath = currentPath.replace("cordova-incl.js", "cordova.js");
var cordovaPath = normalCordovaPath;
if (PLAT) {
// XHR to local file is an error on some platforms, windowsphone for one
try {
var xhr = new XMLHttpRequest();
xhr.open("GET", platformCordovaPath, false);
xhr.onreadystatechange = function() {
if (this.readyState == this.DONE && this.responseText.length > 0) {
if(parseInt(this.status) >= 400){
cordovaPath = normalCordovaPath;
}else{
cordovaPath = platformCordovaPath;
}
}
};
xhr.send(null);
}
catch(e){
cordovaPath = normalCordovaPath;
} // access denied!
}
if (!window._doNotWriteCordovaScript) {
if (PLAT != "windows8") {
document.write('<script type="text/javascript" charset="utf-8" src="' + cordovaPath + '"></script>');
} else {
var s = document.createElement('script');
s.src = cordovaPath;
document.head.appendChild(s);
}
}
function backHome() {
if (window.device && device.platform && device.platform.toLowerCase() == 'android') {
navigator.app.backHistory();
}
else {
window.history.go(-1);
}
}
+64
View File
@@ -0,0 +1,64 @@
<!DOCTYPE html>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<html>
<head>
<meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,initial-scale=1.0" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Cordova Mobile Spec</title>
<link rel="stylesheet" href="master.css" type="text/css" media="screen" title="no title" charset="utf-8">
<script type="text/javascript" charset="utf-8" src="cordova-incl.js"></script>
<script type="text/javascript" charset="utf-8" src="main.js"></script>
</head>
<body onload="init();" id="stage" class="theme">
<h1>Apache Cordova Tests</h1>
<div id="info">
<h4>Platform: <span id="platform"> </span></h4>
<h4>Version: <span id="version"> </span></h4>
<h4>UUID: <span id="uuid"> </span></h4>
<h4>Model: <span id="model"> </span></h4>
<h4>Width: <span id="width"> </span>, Height: <span id="height">
</span>, Color Depth: <span id="colorDepth"></span></h4>
<h4>User-Agent: <span id="user-agent"> </span></h4>
</div>
<a href="autotest/index.html" class="btn large">Automatic Test</a>
<a href="accelerometer/index.html" class="btn large">Accelerometer</a>
<a href="audio/index.html" class="btn large">Audio Play/Record</a>
<a href="battery/index.html" class="btn large">Battery</a>
<a href="camera/index.html" class="btn large">Camera</a>
<a href="compass/index.html" class="btn large">Compass</a>
<a href="contacts/index.html" class="btn large">Contacts</a>
<a href="events/index.html" class="btn large">Events</a>
<a href="location/index.html" class="btn large">Location</a>
<a href="lazyloadjs/index.html" class="btn large">Lazy Loading of cordova-incl.js</a>
<a href="misc/index.html" class="btn large">Misc Content</a>
<a href="network/index.html" class="btn large">Network</a>
<a href="notification/index.html" class="btn large">Notification</a>
<a href="splashscreen/index.html" class="btn large">Splashscreen</a>
<a href="sql/index.html" class="btn large">Web SQL</a>
<a href="storage/index.html" class="btn large">Local Storage</a>
<a href="benchmarks/index.html" class="btn large">Benchmarks</a>
<a href="inappbrowser/index.html" class="btn large">In App Browser</a>
</body>
</html>
+162
View File
@@ -0,0 +1,162 @@
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
var deviceInfo = function() {
document.getElementById("platform").innerHTML = device.platform;
document.getElementById("version").innerHTML = device.version;
document.getElementById("uuid").innerHTML = device.uuid;
document.getElementById("model").innerHTML = device.model;
document.getElementById("width").innerHTML = screen.width;
document.getElementById("height").innerHTML = screen.height;
document.getElementById("colorDepth").innerHTML = screen.colorDepth;
};
var getLocation = function() {
var suc = function(p) {
alert(p.coords.latitude + " " + p.coords.longitude);
};
var locFail = function() {
};
navigator.geolocation.getCurrentPosition(suc, locFail);
};
var beep = function() {
navigator.notification.beep(2);
};
var vibrate = function() {
navigator.notification.vibrate(0);
};
function roundNumber(num) {
var dec = 3;
var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
return result;
}
var accelerationWatch = null;
function updateAcceleration(a) {
document.getElementById('x').innerHTML = roundNumber(a.x);
document.getElementById('y').innerHTML = roundNumber(a.y);
document.getElementById('z').innerHTML = roundNumber(a.z);
}
var toggleAccel = function() {
if (accelerationWatch !== null) {
navigator.accelerometer.clearWatch(accelerationWatch);
updateAcceleration({
x : "",
y : "",
z : ""
});
accelerationWatch = null;
} else {
var options = {};
options.frequency = 1000;
accelerationWatch = navigator.accelerometer.watchAcceleration(
updateAcceleration, function(ex) {
alert("accel fail (" + ex.name + ": " + ex.message + ")");
}, options);
}
};
var preventBehavior = function(e) {
e.preventDefault();
};
function dump_pic(data) {
var viewport = document.getElementById('viewport');
console.log(data);
viewport.style.display = "";
viewport.style.position = "absolute";
viewport.style.top = "10px";
viewport.style.left = "10px";
document.getElementById("test_img").src = "data:image/jpeg;base64," + data;
}
function fail(msg) {
alert(msg);
}
function show_pic() {
navigator.camera.getPicture(dump_pic, fail, {
quality : 50
});
}
function close() {
var viewport = document.getElementById('viewport');
viewport.style.position = "relative";
viewport.style.display = "none";
}
// This is just to do this.
function readFile() {
navigator.file.read('/sdcard/cordova.txt', fail, fail);
}
function writeFile() {
navigator.file.write('foo.txt', "This is a test of writing to a file",
fail, fail);
}
function contacts_success(contacts) {
alert(contacts.length
+ ' contacts returned.'
+ (contacts[2] && contacts[2].name ? (' Third contact is ' + contacts[2].name.formatted)
: ''));
}
function get_contacts() {
var obj = new ContactFindOptions();
obj.filter = "";
obj.multiple = true;
obj.limit = 5;
navigator.service.contacts.find(
[ "displayName", "name" ], contacts_success,
fail, obj);
}
var networkReachableCallback = function(reachability) {
// There is no consistency on the format of reachability
var networkState = reachability.code || reachability;
var currentState = {};
currentState[NetworkStatus.NOT_REACHABLE] = 'No network connection';
currentState[NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK] = 'Carrier data connection';
currentState[NetworkStatus.REACHABLE_VIA_WIFI_NETWORK] = 'WiFi connection';
confirm("Connection type:\n" + currentState[networkState]);
};
function check_network() {
navigator.network.isReachable("www.mobiledevelopersolutions.com",
networkReachableCallback, {});
}
function init() {
// the next line makes it impossible to see Contacts on the HTC Evo since it
// doesn't have a scroll button
// document.addEventListener("touchmove", preventBehavior, false);
document.addEventListener("deviceready", deviceInfo, true);
document.getElementById("user-agent").textContent = navigator.userAgent;
}
+164
View File
@@ -0,0 +1,164 @@
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
body {
background:#222 none repeat scroll 0 0;
color:#666;
font-family:Helvetica;
font-size:72%;
line-height:1.5em;
margin:0;
border-top:1px solid #393939;
}
#info{
background:#ffa;
border: 1px solid #ffd324;
-webkit-border-radius: 5px;
border-radius: 5px;
clear:both;
margin:15px 6px 0;
min-width:295px;
max-width:97%;
padding:4px 0px 2px 10px;
word-wrap:break-word;
margin-bottom:10px;
display:inline-block;
min-height: 160px;
max-height: 300px;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
#info > h4{
font-size:.95em;
margin:5px 0;
}
#stage.theme{
padding-top:3px;
}
/* Definition List */
#stage.theme > dl{
padding-top:10px;
clear:both;
margin:0;
list-style-type:none;
padding-left:10px;
overflow:auto;
}
#stage.theme > dl > dt{
font-weight:bold;
float:left;
margin-left:5px;
}
#stage.theme > dl > dd{
width:45px;
float:left;
color:#a87;
font-weight:bold;
}
/* Content Styling */
#stage.theme > h1, #stage.theme > h2, #stage.theme > p{
margin:1em 0 .5em 13px;
}
#stage.theme > h1{
color:#eee;
font-size:1.6em;
text-align:center;
margin:0;
margin-top:15px;
padding:0;
}
#stage.theme > h2{
clear:both;
margin:0;
padding:3px;
font-size:1em;
text-align:center;
}
/* Stage Buttons */
#stage.theme .btn{
border: 1px solid #555;
-webkit-border-radius: 5px;
border-radius: 5px;
text-align:center;
display:inline-block;
background:#444;
width:150px;
color:#9ab;
font-size:1.1em;
text-decoration:none;
padding:1.2em 0;
margin:3px 0px 3px 5px;
}
#stage.theme .large{
width:308px;
padding:1.2em 0;
}
#stage.theme .wide{
width:100%;
padding:1.2em 0;
}
#stage.theme .backBtn{
border: 1px solid #555;
-webkit-border-radius: 5px;
border-radius: 5px;
text-align:center;
display:block;
float:right;
background:#666;
width:75px;
color:#9ab;
font-size:1.1em;
text-decoration:none;
padding:1.2em 0;
margin:3px 5px 3px 5px;
}
#stage.theme .input{
border: 1px solid #555;
-webkit-border-radius: 5px;
border-radius: 5px;
text-align:center;
display:block;
float:light;
background:#888;
color:#9cd;
font-size:1.1em;
text-decoration:none;
padding:1.2em 0;
margin:3px 0px 3px 5px;
}
#stage.theme .numeric{
width:100%;
}