/* * * 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. * */ /* jshint jasmine: true */ /* global Windows */ exports.defineAutoTests = function () { var isWindows = (cordova.platformId === "windows") || (cordova.platformId === "windows8"), // Checking existence of accelerometer for windows platform // Assumed that accelerometer always exists on other platforms. Extend // condition to support accelerometer check on other platforms 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); expect(a.timestamp).toBeLessThan(reasonableTimeLimit); done(); }; navigator.accelerometer.getCurrentAcceleration(win, fail.bind(null,done)); }); }); describe("watchAcceleration", function() { var id; afterEach(function() { navigator.accelerometer.clearWatch(id); }); 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(); var ACCEPTABLE_PERCENT_RANGE = 95; // 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) { // Checking if the returned timestamp is atleast 95% of the veryRecently timestamp // If it is greater than very recently (for eg: 125%) it is fine and we do not want // a positive delta comparison in this assert expect((a.timestamp * 100) / veryRecently).toBeGreaterThan(ACCEPTABLE_PERCENT_RANGE); 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, 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); }; // 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); 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 = '
' + 'Expected result: Will update the status box with X, Y, and Z values when pressed. Status will read "Stopped"' + '

' + '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"' + '

' + 'Expected result: Will clear the accelerometer watch, so X,Y,Z values will no longer be updated. Status will read "Stopped"'; contentEl.innerHTML = '
' + 'Status: Stopped' + '' + '' + '' + '' + '
X:
Y:
Z:
' + accelerometer_tests; createActionButton('Get Acceleration', function () { getAccel(); }, 'getAcceleration'); createActionButton('Start Watch', function () { watchAccel(); }, 'watchAcceleration'); createActionButton('Clear Watch', function () { stopAccel(); }, 'clearAcceleration'); };