Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

geolocation mock #31

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions programming/javascript/geolocation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# geo-mock

If you are testing geolocation-based features, you may have been need to change your geolocation according to different tests. One more purpose is to use geolocation speed change. This javascript mock will help you, you can use it inside any test within any programming language.

Just include this file to your testing page or execute the whole code in page context.
```
<script type="text/javascript" src="geo-mock.js"></script>
```

And use it:

<ul>
<li>
latitude, longitude mock:
<ul><li>window.mockGeo.setPosition(10, -15.1212);</li></ul>
</li>

<li>
geolocation error mock:
<ul>
<li>window.mockGeo.setPositionErr(mockGeo.PERMISSION_DENIED);</li>
<li>window.mockGeo.setPositionErr(mockGeo.POSITION_UNAVAILABLE);</li>
<li>window.mockGeo.setPositionErr(mockGeo.TIMEOUT);</li>
</ul>
</li>

<li>
speed mock (m/s):
<ul><li>window.mockGeo.setSpeed(9);</li></ul>
</li>
</ul>





153 changes: 153 additions & 0 deletions programming/javascript/geolocation/geo-mock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/*
* https://github.com/fat-troll/js-geo-mock
* Mock lat, long, speed, geolocation errors
* in real time within your tests :)
*/

var mockGeo;

window.mockGeo = {

PERMISSION_DENIED: {
PERMISSION_DENIED: 1,
POSITION_UNAVAILABLE: 2,
TIMEOUT: 3,
code: 1,
message: "Geolocation error: PERMISSION_DENIED"
},

POSITION_UNAVAILABLE: {
PERMISSION_DENIED: 1,
POSITION_UNAVAILABLE: 2,
TIMEOUT: 3,
code: 2,
message: "Geolocation error: POSITION_UNAVAILABLE"
},

TIMEOUT: {
PERMISSION_DENIED: 1,
POSITION_UNAVAILABLE: 2,
TIMEOUT: 3,
code: 3,
message: "Geolocation error: TIMEOUT"
},

_SUCCESS: 0,
_ERROR: 1,

_watches: [],
_curErr: null,
_curPos: null,

_notInited: [],

_isInited: function () {
return this._curErr !== null || this._curPos !== null;
},

_asyncExec: function (callback, args) {
setTimeout(function () {
callback(args);
}, 0);
},

_cbExec: function (resultsArray) {
if (this._curErr && resultsArray[this._ERROR]) {
this._asyncExec(resultsArray[this._ERROR], this._curErr);
} else if (this._curPos && resultsArray[this._SUCCESS]) {
this._asyncExec(resultsArray[this._SUCCESS], this._curPos);
}
},

_cbWatch: function () {
for (var idx = 0; idx < this._notInited.length; idx++) {
this._cbExec(this._notInited[idx]);
}

this._notInited = [];

for (var idx2 = 0; idx2 < this._watches.length; idx2++) {
if (this._watches[idx2]) {
this._cbExec(this._watches[idx2]);
}
}
},

_setCurPosition: function (currentPosition) {
this._curErr = null;
this._curPos = currentPosition;
if (currentPosition) {
this._cbWatch();
}
},

/*
* Simulate geolocation error
*/
setPositionErr: function (currentError) {
this._curPos = null;
this._curErr = currentError;
if (currentError) {
this._cbWatch();
}
},

/*
* Simulate current position
*/
setPosition: function (lat, lng) {
this._setCurPosition({
coords: {
latitude: lat,
longitude: lng,
accuracy: 20
}
});
},

/*
* Simulate current speed
* based on current position
*/
setSpeed: function(spd) {
/*
* Here you should add your default coordinates or take them from geolocation
* as speed mock doesn't work without lat and lon emulation
*/
this._setCurPosition({
coords: {
/*
* Seems like it's impossible to mock
* only speed, without lat and lon
*/
latitude: 1,
longitude: 1,
accuracy: 20,
speed: spd
}
});
}
};

if (!navigator.geolocation) {
window.navigator.geolocation = {};
}

navigator.geolocation.getCurrentPosition = function(success, error) {
if (mockGeo._isInited()) {
mockGeo._cbExec([success, error]);
} else {
mockGeo._notInited.push([success, error]);
}
};

navigator.geolocation.watchPosition = function(success, error) {
if (mockGeo._isInited()) {
mockGeo._cbExec([success, error]);
}
return mockGeo._watches.push([success, error]) - 1;
};

navigator.geolocation.clearWatch = function(id) {
mockGeo._watches[id] = null;
};