You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by fi...@apache.org on 2012/05/07 22:52:06 UTC
[1/8] js commit: tweaked our geolocation native framework api (now
should support three actions: getLocation,
addWatch and clearWatch). finished off tests
Updated Branches:
refs/heads/master 34f5fec1f -> dd7ab2827
tweaked our geolocation native framework api (now should support three actions: getLocation, addWatch and clearWatch). finished off tests
Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/commit/95b11dd0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/tree/95b11dd0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/diff/95b11dd0
Branch: refs/heads/master
Commit: 95b11dd053dc689a1658718252a2d0ecaad53e91
Parents: 0d7e3e7
Author: Fil Maj <ma...@gmail.com>
Authored: Mon Mar 26 15:39:55 2012 -0700
Committer: Fil Maj <ma...@gmail.com>
Committed: Mon May 7 13:51:05 2012 -0700
----------------------------------------------------------------------
lib/common/plugin/geolocation.js | 64 +++++++++++++++---
test/test.geolocation.js | 117 ++++++++++++++++++++++++---------
2 files changed, 139 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/95b11dd0/lib/common/plugin/geolocation.js
----------------------------------------------------------------------
diff --git a/lib/common/plugin/geolocation.js b/lib/common/plugin/geolocation.js
index 0831d0c..55159f2 100644
--- a/lib/common/plugin/geolocation.js
+++ b/lib/common/plugin/geolocation.js
@@ -32,6 +32,19 @@ function parseParameters(options) {
return opt;
}
+// Returns a timeout failure, closed over a specified timeout value and error callback.
+function createTimeout(errorCallback, timeout) {
+ var t = setTimeout(function() {
+ clearTimeout(t);
+ t = null;
+ errorCallback({
+ code:PositionError.TIMEOUT,
+ message:"Position retrieval timed out."
+ });
+ }, timeout);
+ return t;
+}
+
var geolocation = {
lastPosition:null, // reference to last known (cached) position returned
/**
@@ -99,22 +112,16 @@ var geolocation = {
// If the timeout value was not set to Infinity (default), then
// set up a timeout function that will fire the error callback
// if no successful position was retrieved before timeout expired.
- timeoutTimer = setTimeout(function() {
- clearTimeout(timeoutTimer);
- timeoutTimer = null;
- fail({
- code:PositionError.TIMEOUT,
- message:"Position retrieval timed out."
- });
- }, options.timeout);
+ timeoutTimer = createTimeout(fail, options.timeout);
} else {
// This is here so the check in the win function doesn't mess stuff up
// may seem weird but this guarantees timeoutTimer is
// always truthy before we call into native
timeoutTimer = true;
}
- exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.timeout, options.maximumAge]);
+ exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.maximumAge]);
}
+ return timeoutTimer;
},
/**
* Asynchronously watches the geolocation for changes to geolocation. When a change occurs,
@@ -126,10 +133,46 @@ var geolocation = {
* @return String The watch id that must be passed to #clearWatch to stop watching.
*/
watchPosition:function(successCallback, errorCallback, options) {
+ if (arguments.length === 0) {
+ throw new Error("watchPosition must be called with at least one argument.");
+ }
options = parseParameters(options);
var id = utils.createUUID();
+ timers[id] = geolocation.getCurrentPosition(successCallback, errorCallback, options);
+
+ var fail = function(e) {
+ clearTimeout(timers[id]);
+ var err = new PositionError(e.code, e.message);
+ if (errorCallback) {
+ errorCallback(err);
+ }
+ };
+
+ var win = function(p) {
+ clearTimeout(timers[id]);
+ if (options.timeout !== Infinity) {
+ timers[id] = createTimeout(fail, options.timeout);
+ }
+ var pos = new Position(
+ {
+ latitude:p.latitude,
+ longitude:p.longitude,
+ altitude:p.altitude,
+ accuracy:p.accuracy,
+ heading:p.heading,
+ velocity:p.velocity,
+ altitudeAccuracy:p.altitudeAccuracy
+ },
+ p.timestamp || new Date()
+ );
+ geolocation.lastPosition = pos;
+ successCallback(pos);
+ };
+
+ exec(win, fail, "Geolocation", "addWatch", [id, options.enableHighAccuracy]);
+
return id;
},
/**
@@ -139,8 +182,9 @@ var geolocation = {
*/
clearWatch:function(id) {
if (id && timers[id] !== undefined) {
- window.clearInterval(timers[id]);
+ clearTimeout(timers[id]);
delete timers[id];
+ exec(null, null, "Geolocation", "clearWatch", [id]);
}
}
};
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/95b11dd0/test/test.geolocation.js
----------------------------------------------------------------------
diff --git a/test/test.geolocation.js b/test/test.geolocation.js
index 6daaa4c..8ea5139 100644
--- a/test/test.geolocation.js
+++ b/test/test.geolocation.js
@@ -2,7 +2,7 @@ describe("geolocation", function () {
var geo = require('cordova/plugin/geolocation'),
Position = require('cordova/plugin/Position'),
PositionError = require('cordova/plugin/PositionError'),
- s, e;
+ s, e,
exec = require('cordova/exec');
beforeEach(function () {
@@ -16,22 +16,17 @@ describe("geolocation", function () {
describe("arguments", function () {
it("uses default PositionOptions if none are specified", function () {
geo.getCurrentPosition(s, e);
- expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [false, Infinity, 0]);
- });
-
- it("uses the maximumAge option if specified", function () {
- geo.getCurrentPosition(s, e, {maximumAge: 10});
- expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [false, Infinity, 10]);
+ expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [false, 0]);
});
it("uses the enableHighAccuracy option if specified", function () {
- geo.getCurrentPosition(s, e, {enableHighAccuracy: true, maximumAge: 100});
- expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [true, Infinity, 100]);
+ geo.getCurrentPosition(s, e, {enableHighAccuracy: true});
+ expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [true, 0]);
});
- it("uses the timeout option if specified and positive", function () {
- geo.getCurrentPosition(s, e, {timeout: 1000});
- expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [false, 1000, 0]);
+ it("uses the maximumAge option if specified", function () {
+ geo.getCurrentPosition(s, e, {maximumAge: 100});
+ expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [false, 100]);
});
it("uses a timeout value of 0 if specified and negative, which should call the error callback immediately (since we have no cached position)", function () {
@@ -75,13 +70,13 @@ describe("geolocation", function () {
geo.getCurrentPosition(s, e, {maximumAge:100});
- expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [false, Infinity, 100]);
+ expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [false, 100]);
});
it("should fire error callback with TIMEOUT code after timeout period has elapsed and no position is available", function() {
runs(function() {
geo.getCurrentPosition(s, e, {timeout: 50});
- expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [false, 50, 0]);
+ expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [false, 0]);
});
waits(75);
@@ -150,30 +145,23 @@ describe("geolocation", function () {
});
describe("watchPosition", function () {
- var utils = require('cordova/utils');
-
describe("arguments", function () {
it("uses default PositionOptions if none are specified", function () {
- geo.watchPosition(s, e);
- expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [false, Infinity, 0]);
- });
-
- it("uses the maximumAge option if specified", function () {
- geo.watchPosition(s, e, {maximumAge: 10});
- expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [false, Infinity, 10]);
+ var id = geo.watchPosition(s, e);
+ expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "addWatch", [id, false]);
});
it("uses the enableHighAccuracy option if specified", function () {
- geo.watchPosition(s, e, {enableHighAccuracy: true, maximumAge: 100});
- expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [true, Infinity, 100]);
+ var id = geo.watchPosition(s, e, {enableHighAccuracy: true});
+ expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "addWatch", [id, true]);
});
- it("uses the timeout option if specified and positive", function () {
- geo.watchPosition(s, e, {timeout: 1000});
- expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [false, 1000, 0]);
+ it("uses the maximumAge option if specified", function () {
+ var id = geo.watchPosition(s, e, {maximumAge: 100});
+ expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "addWatch", [id, false]);
});
- it("uses a timeout value of 0 if specified and negative, which should call the error callback immediately (since we have no cached position)", function () {
+ it("uses a timeout value of 0 if specified and negative, which should call the error callback immediately", function () {
geo.watchPosition(s, e, {timeout: -1000});
expect(e).toHaveBeenCalledWith({
code:PositionError.TIMEOUT,
@@ -192,12 +180,77 @@ describe("geolocation", function () {
});
});
describe("position acquisition", function() {
- it("should invoke the success callback every time the position changes");
- it("should invoke the error callback if position could not be retrieved");
-
+ it("should invoke the success callback every time the position changes", function() {
+ runs(function() {
+ geo.watchPosition(s, e);
+ });
+ waits(50);
+ runs(function() {
+ exec.mostRecentCall.args[0]({}); // fake success callback from native
+ expect(s).toHaveBeenCalled();
+ s.reset();
+ exec.mostRecentCall.args[0]({}); // fake success callback from native
+ expect(s).toHaveBeenCalled();
+ });
+ });
+ it("should invoke the error callback if position could not be retrieved", function() {
+ geo.watchPosition(s, e);
+ exec.mostRecentCall.args[1]({
+ code:PositionError.POSITION_UNAVAILABLE
+ });
+ expect(e).toHaveBeenCalledWith({
+ code:PositionError.POSITION_UNAVAILABLE,
+ message:""
+ });
+ });
+ it("should invoke the error callback if no position could be acquired within the specified timeout", function() {
+ runs(function() {
+ geo.watchPosition(s, e, {timeout:50});
+ });
+ waits(75);
+ runs(function() {
+ expect(e).toHaveBeenCalledWith({
+ code:PositionError.TIMEOUT,
+ message:"Position retrieval timed out."
+ });
+ });
+ });
+ it("should invoke the error callback if no position could be acquired within the specified timeout, even after successfully retrieving the position once", function() {
+ runs(function() {
+ geo.watchPosition(s, e, {timeout:50});
+ });
+ waits(25);
+ runs(function() {
+ exec.mostRecentCall.args[0]({}); // fire new position return
+ expect(s).toHaveBeenCalled();
+ });
+ waits(30);
+ runs(function() {
+ // The error callback should NOT be fired, since the timeout should have reset when we fired a new position return above
+ expect(e).not.toHaveBeenCalled();
+ });
+ waits(25);
+ runs(function() {
+ // NOW the error callback should be fired with a TIMEOUT error
+ expect(e).toHaveBeenCalledWith({
+ code:PositionError.TIMEOUT,
+ message:"Position retrieval timed out."
+ });
+ });
+ });
});
});
describe("clearWatch", function () {
+ it("should tell native to remove an id from the watch list if it exists", function() {
+ var id = geo.watchPosition(s, e);
+ geo.clearWatch(id);
+ expect(exec).toHaveBeenCalledWith(null, null, "Geolocation", "clearWatch", [id]);
+ });
+ it("should not call into native if id does not exist", function() {
+ var id = "this is bat country";
+ geo.clearWatch(id);
+ expect(exec).not.toHaveBeenCalled();
+ });
});
});