blob: 9a4745a1c8a31e84fcad6422af7b5b1a3e8749b6 [file] [log] [blame]
/*
*
* 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.
*
*/
/* global cordova, Windows */
exports.defineAutoTests = function () {
var isWindows = cordova.platformId === 'windows';
// Checking existence of accelerometer for windows platform
// Assumed that accelerometer always exists on other platforms. Extend
// condition to support accelerometer check on other platforms
var isAccelExist = isWindows ? Windows.Devices.Sensors.Accelerometer.getDefault() !== null : true;
describe('Accelerometer (navigator.accelerometer)', function () {
var fail = function (done) {
expect(true).toBe(false);
done();
};
// This timeout is here to lessen the load on native accelerometer
// intensive use of which can lead to occasional test failures
afterEach(function (done) {
setTimeout(function () {
done();
}, 100);
});
it('accelerometer.spec.1 should exist', function () {
expect(navigator.accelerometer).toBeDefined();
});
describe('getCurrentAcceleration', function () {
it('accelerometer.spec.2 should exist', function () {
expect(typeof navigator.accelerometer.getCurrentAcceleration).toBeDefined();
expect(typeof navigator.accelerometer.getCurrentAcceleration === 'function').toBe(true);
});
it('accelerometer.spec.3 success callback should be called with an Acceleration object', function (done) {
// skip the test if Accelerometer doesn't exist on this device
if (!isAccelExist) {
pending();
}
var win = function (a) {
expect(a).toBeDefined();
expect(a.x).toBeDefined();
expect(typeof a.x === 'number').toBe(true);
expect(a.y).toBeDefined();
expect(typeof a.y === 'number').toBe(true);
expect(a.z).toBeDefined();
expect(typeof a.z === 'number').toBe(true);
expect(a.timestamp).toBeDefined();
expect(typeof a.timestamp).toBe('number');
done();
};
var onError = function (err) {
console.log(err);
console.log('Skipping gyroscope tests, marking all as pending.');
isAccelExist = false;
expect(true).toBe(true);
done();
};
navigator.accelerometer.getCurrentAcceleration(win, onError);
});
it('accelerometer.spec.4 success callback Acceleration object should have (reasonable) values for x, y and z expressed in m/s^2', function (done) {
// skip the test if Accelerometer doesn't exist on this device
if (!isAccelExist) {
pending();
}
var reasonableThreshold = 15;
var win = function (a) {
expect(a.x).toBeLessThan(reasonableThreshold);
expect(a.x).toBeGreaterThan(reasonableThreshold * -1);
expect(a.y).toBeLessThan(reasonableThreshold);
expect(a.y).toBeGreaterThan(reasonableThreshold * -1);
expect(a.z).toBeLessThan(reasonableThreshold);
expect(a.z).toBeGreaterThan(reasonableThreshold * -1);
done();
};
navigator.accelerometer.getCurrentAcceleration(win, fail.bind(null, done));
});
it('accelerometer.spec.5 success callback Acceleration object should return a recent timestamp', function (done) {
// skip the test if Accelerometer doesn't exist on this device
if (!isAccelExist) {
pending();
}
var veryRecently = new Date().getTime();
// Need to check that dates returned are not vastly greater than a recent time stamp.
// In case the timestamps returned are ridiculously high
var reasonableTimeLimit = veryRecently + 5000; // 5 seconds from now
var win = function (a) {
expect(a.timestamp).toBeGreaterThan(veryRecently - 200); // this is flakey, relaxing a bit
expect(a.timestamp).toBeLessThan(reasonableTimeLimit);
done();
};
navigator.accelerometer.getCurrentAcceleration(win, fail.bind(null, done));
});
});
describe('watchAcceleration', function () {
var id;
afterEach(function (done) {
if (id) {
navigator.accelerometer.clearWatch(id);
}
// clearWatch implementation is async but doesn't accept a cllback
// so let's give it some time before starting next spec
setTimeout(done, 100);
});
it('accelerometer.spec.6 should exist', function () {
expect(navigator.accelerometer.watchAcceleration).toBeDefined();
expect(typeof navigator.accelerometer.watchAcceleration === 'function').toBe(true);
});
it('accelerometer.spec.7 success callback should be called with an Acceleration object', function (done) {
// skip the test if Accelerometer doesn't exist on this device
if (!isAccelExist) {
pending();
}
var win = function (a) {
expect(a).toBeDefined();
expect(a.x).toBeDefined();
expect(typeof a.x === 'number').toBe(true);
expect(a.y).toBeDefined();
expect(typeof a.y === 'number').toBe(true);
expect(a.z).toBeDefined();
expect(typeof a.z === 'number').toBe(true);
expect(a.timestamp).toBeDefined();
expect(typeof a.timestamp).toBe('number');
done();
};
id = navigator.accelerometer.watchAcceleration(win, fail.bind(null, done), { frequency: 100 });
});
it('accelerometer.spec.8 success callback Acceleration object should have (reasonable) values for x, y and z expressed in m/s^2', function (done) {
// skip the test if Accelerometer doesn't exist on this device
if (!isAccelExist) {
pending();
}
var reasonableThreshold = 15;
var win = function (a) {
expect(a.x).toBeLessThan(reasonableThreshold);
expect(a.x).toBeGreaterThan(reasonableThreshold * -1);
expect(a.y).toBeLessThan(reasonableThreshold);
expect(a.y).toBeGreaterThan(reasonableThreshold * -1);
expect(a.z).toBeLessThan(reasonableThreshold);
expect(a.z).toBeGreaterThan(reasonableThreshold * -1);
done();
};
id = navigator.accelerometer.watchAcceleration(win, fail.bind(null, done), { frequency: 100 });
});
it('accelerometer.spec.9 success callback Acceleration object should return a recent timestamp', function (done) {
// skip the test if Accelerometer doesn't exist on this device
if (!isAccelExist) {
pending();
}
var veryRecently = new Date().getTime();
// Need to check that dates returned are not vastly greater than a recent time stamp.
// In case the timestamps returned are ridiculously high
var reasonableTimeLimit = veryRecently + 5000; // 5 seconds from now
var win = function (a) {
expect(a.timestamp).toBeGreaterThan(veryRecently - 200); // this is flakey, relaxing a bit
expect(a.timestamp).toBeLessThan(reasonableTimeLimit);
done();
};
id = navigator.accelerometer.watchAcceleration(win, fail.bind(null, done), { frequency: 100 });
});
it('accelerometer.spec.12 success callback should be preserved and called several times', function (done) {
// skip the test if Accelerometer doesn't exist on this device
if (!isAccelExist) {
pending();
}
var callbacksCallCount = 0;
var callbacksCallTestCount = 3;
var win = function (a) {
if (callbacksCallCount++ < callbacksCallTestCount) return;
expect(typeof a).toBe('object');
done();
};
id = navigator.accelerometer.watchAcceleration(win, fail.bind(null, done), { frequency: 100 });
});
});
describe('clearWatch', function () {
it('accelerometer.spec.10 should exist', function () {
expect(navigator.accelerometer.clearWatch).toBeDefined();
expect(typeof navigator.accelerometer.clearWatch === 'function').toBe(true);
});
it('accelerometer.spec.11 should clear an existing watch', function (done) {
// skip the test if Accelerometer doesn't exist on this device
if (!isAccelExist) {
pending();
}
var id;
// expect win to get called exactly once
var win = function (a) {
// clear watch on first call
navigator.accelerometer.clearWatch(id);
// if win isn't called again in 201 ms we assume success
var tid = setTimeout(function () {
expect(true).toBe(true);
done();
}, 101);
// if win is called again, clear the timeout and fail the test
win = function () {
clearTimeout(tid);
fail(done);
};
};
// wrap the success call in a closure since the value of win changes between calls
id = navigator.accelerometer.watchAcceleration(
function () {
win();
},
fail.bind(null, done),
{ frequency: 100 }
);
});
});
});
};
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
exports.defineManualTests = function (contentEl, createActionButton) {
function roundNumber (num) {
var dec = 3;
var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
return result;
}
var watchAccelId = null;
/**
* Set accelerometer status
*/
function setAccelStatus (status) {
document.getElementById('accel_status').innerHTML = status;
}
/**
* Stop watching the acceleration
*/
function stopAccel () {
console.log('stopAccel()');
setAccelStatus('Stopped');
if (watchAccelId) {
navigator.accelerometer.clearWatch(watchAccelId);
watchAccelId = null;
}
}
/**
* Start watching acceleration
*/
var watchAccel = function () {
console.log('watchAccel()');
// Success callback
var success = function (a) {
document.getElementById('x').innerHTML = roundNumber(a.x);
document.getElementById('y').innerHTML = roundNumber(a.y);
document.getElementById('z').innerHTML = roundNumber(a.z);
document.getElementById('t').innerHTML = a.timestamp;
};
// Fail callback
var fail = function (e) {
console.log('watchAccel fail callback with error code ' + e);
stopAccel();
setAccelStatus(e);
};
// Update acceleration every 1 sec
var opt = {};
opt.frequency = 1000;
watchAccelId = navigator.accelerometer.watchAcceleration(success, fail, opt);
setAccelStatus('Running');
};
/**
* Get current acceleration
*/
var getAccel = function () {
console.log('getAccel()');
// Stop accel if running
stopAccel();
// Success callback
var success = function (a) {
document.getElementById('x').innerHTML = roundNumber(a.x);
document.getElementById('y').innerHTML = roundNumber(a.y);
document.getElementById('z').innerHTML = roundNumber(a.z);
document.getElementById('t').innerHTML = a.timestamp;
console.log('getAccel success callback');
};
// Fail callback
var fail = function (e) {
console.log('getAccel fail callback with error code ' + e);
setAccelStatus(e);
};
// Make call
var opt = {};
navigator.accelerometer.getCurrentAcceleration(success, fail, opt);
};
/******************************************************************************/
var accelerometer_tests =
'<div id="getAcceleration"></div>' +
'Expected result: Will update the status box with X, Y, and Z values when pressed. Status will read "Stopped"' +
'<p/> <div id="watchAcceleration"></div>' +
'Expected result: When pressed, will start a watch on the accelerometer and update X,Y,Z values when movement is sensed. Status will read "Running"' +
'<p/> <div id="clearAcceleration"></div>' +
'Expected result: Will clear the accelerometer watch, so X,Y,Z values will no longer be updated. Status will read "Stopped"';
contentEl.innerHTML =
'<div id="info">' +
'Status: <span id="accel_status">Stopped</span>' +
'<table width="100%">' +
'<tr><td width="30%">X:</td><td id="x"> </td></tr>' +
'<tr><td width="30%">Y:</td><td id="y"> </td></tr>' +
'<tr><td width="30%">Z:</td><td id="z"> </td></tr>' +
'<tr><td width="30%">Timestamp:</td><td id="t"> </td></tr>' +
'</table></div>' +
accelerometer_tests;
createActionButton(
'Get Acceleration',
function () {
getAccel();
},
'getAcceleration'
);
createActionButton(
'Start Watch',
function () {
watchAccel();
},
'watchAcceleration'
);
createActionButton(
'Clear Watch',
function () {
stopAccel();
},
'clearAcceleration'
);
};