fixed wrong use of timeout (instead of maximumage) and added full position acquisition tests for getCurrentPosition
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/97aa789a Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/tree/97aa789a Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/diff/97aa789a Branch: refs/heads/master Commit: 97aa789aa4d040fb4c043932d01efc944782e06b Parents: ee713bb Author: Fil Maj <maj....@gmail.com> Authored: Fri Mar 23 14:25:13 2012 -0700 Committer: Fil Maj <maj....@gmail.com> Committed: Mon May 7 13:51:05 2012 -0700 ---------------------------------------------------------------------- lib/common/plugin/geolocation.js | 6 +- test/test.geolocation.js | 91 +++++++++++++++++++++++++++++++-- 2 files changed, 90 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/97aa789a/lib/common/plugin/geolocation.js ---------------------------------------------------------------------- diff --git a/lib/common/plugin/geolocation.js b/lib/common/plugin/geolocation.js index 443fb61..2cc7330 100644 --- a/lib/common/plugin/geolocation.js +++ b/lib/common/plugin/geolocation.js @@ -83,10 +83,10 @@ var geolocation = { } }; - // Check our cached position, if its timestamp difference with current time is less than the timeout, then just + // Check our cached position, if its timestamp difference with current time is less than the maximumAge, then just // fire the success callback with the cached position. - if (geolocation.lastPosition && options.timeout && ((new Date()).getTime() - geolocation.lastPosition.timestamp.getTime() <= options.timeout)) { - successCallback(cachedPosition); + if (geolocation.lastPosition && options.maximumAge && (((new Date()).getTime() - geolocation.lastPosition.timestamp.getTime()) <= options.maximumAge)) { + successCallback(geolocation.lastPosition); // If the cached position check failed and the timeout was set to 0, error out with a TIMEOUT error object. } else if (options.timeout === 0) { fail({ http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/97aa789a/test/test.geolocation.js ---------------------------------------------------------------------- diff --git a/test/test.geolocation.js b/test/test.geolocation.js index 87b1b24..dbd04cf 100644 --- a/test/test.geolocation.js +++ b/test/test.geolocation.js @@ -9,14 +9,11 @@ describe("geolocation", function () { s = jasmine.createSpy("success"); e = jasmine.createSpy("error"); exec.reset(); + geo.lastPosition = null; // reset the cached position }); describe("getCurrentPosition", function() { describe("arguments", function () { - beforeEach(function() { - geo.lastPosition = null; // reset the cached position - }); - 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]); @@ -36,6 +33,7 @@ describe("geolocation", function () { geo.getCurrentPosition(s, e, {timeout: 1000}); expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [false, 1000, 0]); }); + 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 () { geo.getCurrentPosition(s, e, {timeout: -1000}); expect(e).toHaveBeenCalledWith({ @@ -43,25 +41,110 @@ describe("geolocation", function () { message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceed's provided PositionOptions' maximumAge parameter." }); }); + it("can be used with one, two or three arguments", function() { expect(function() { geo.getCurrentPosition(s); }).not.toThrow(); expect(function() { geo.getCurrentPosition(s,e); }).not.toThrow(); expect(function() { geo.getCurrentPosition(s,e,{}); }).not.toThrow(); }); + it("should throw an exception if used with no arguments", function() { expect(function() { geo.getCurrentPosition();}).toThrow("getCurrentPosition must be called with at least one argument."); }); }) describe("position acquisition", function() { it("should provide a cached position if one exists and has a timestamp value conforming with passed in maximumAge", function() { + // Create a date object from 2 seconds ago to store as cached position. + var d = new Date(); + d.setTime(d.getTime() - 2000); + var p = new Position(null, d); + geo.lastPosition = p; + + geo.getCurrentPosition(s, e, {maximumAge:3000}); + + expect(s).toHaveBeenCalledWith(p); + expect(exec).not.toHaveBeenCalled(); }); + + it("should fire exec if a cached position exists but whose timestamp is longer than the maximumAge parameter", function() { + // Create a date object from 2 seconds ago to store as cached position. + var d = new Date(); + d.setTime(d.getTime() - 2000); + var p = new Position(null, d); + geo.lastPosition = p; + + geo.getCurrentPosition(s, e, {maximumAge:100}); + + expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [false, Infinity, 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]); + }); + + waits(75); + + runs(function() { + expect(e).toHaveBeenCalledWith({ + code:PositionError.TIMEOUT, + message:"Position retrieval timed out." + }); + }); }); + it("should not fire error callback with TIMEOUT if a position is obtained within the timeout period", function() { + runs(function() { + geo.getCurrentPosition(s, e, {timeout:50}); + + // Call the success callback to "fake" the native framework returning a (empty) position object. + // This should also disable the timeout timer. + exec.mostRecentCall.args[0]({}); + }); + + waits(75); + + runs(function() { + expect(e).not.toHaveBeenCalled(); + expect(s).toHaveBeenCalled(); + }); }); + it("should fire error callback with POSITION_UNAVAILABLE if error occurs during acquisition before timeout expires", function() { + geo.getCurrentPosition(s, e, {timeout: 50}); + + // Call the error callback to "fake" the native framework returning an error object. + var eObj = { + code:PositionError.POSITION_UNAVAILABLE + }; + exec.mostRecentCall.args[1](eObj); + + expect(e).toHaveBeenCalledWith({ + code:PositionError.POSITION_UNAVAILABLE, + message:"" + }); }); + it("should not fire error callback with TIMEOUT if error occurs during acquisition before timeout expires", function() { + runs(function() { + geo.getCurrentPosition(s, e, {timeout: 50}); + + // Call the error callback to "fake" the native framework returning an error object. + var eObj = { + code:PositionError.POSITION_UNAVAILABLE + }; + exec.mostRecentCall.args[1](eObj); + }); + + waits(75); + + runs(function() { + expect(e).not.toHaveBeenCalledWith({ + code:PositionError.TIMEOUT, + message:"Position retrieval timed out." + }); + }); }); }); });