mirror of
https://github.com/google/pebble.git
synced 2025-05-28 05:53:12 +00:00
Import of the watch repository from Pebble
This commit is contained in:
commit
3b92768480
10334 changed files with 2564465 additions and 0 deletions
42
sdk/tests/include/.eslintrc.js
Normal file
42
sdk/tests/include/.eslintrc.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"commonjs": true,
|
||||
"es6": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"rules": {
|
||||
"indent": [
|
||||
"error",
|
||||
2
|
||||
],
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"unix"
|
||||
],
|
||||
"quotes": [
|
||||
"error",
|
||||
"single"
|
||||
],
|
||||
"semi": [
|
||||
"error",
|
||||
"always"
|
||||
]
|
||||
}
|
||||
};
|
1
sdk/tests/include/.gitignore
vendored
Normal file
1
sdk/tests/include/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
node_modules
|
50
sdk/tests/include/README.md
Normal file
50
sdk/tests/include/README.md
Normal file
|
@ -0,0 +1,50 @@
|
|||
# sdk/include/*.js unit testing how-to
|
||||
This folder contains tests for the .js code in sdk/include.
|
||||
|
||||
## Installing dependencies
|
||||
1. `cd sdk/tests/include`
|
||||
2. `npm install`
|
||||
|
||||
## Running tests
|
||||
1. `cd sdk/tests/include`
|
||||
2. `npm test` – this runs the tests using the [mocha](http://mochajs.org/) test runner.
|
||||
|
||||
You should see some output, similar to this:
|
||||
|
||||
```
|
||||
$ npm test
|
||||
|
||||
> pebble-pkjs-tests@1.0.0 test /Users/martijn/tintin/sdk/tests/include
|
||||
> NODE_PATH=../include ./node_modules/mocha/bin/mocha *.js
|
||||
|
||||
Pebble
|
||||
interprets received postMessage API data as UTF-8
|
||||
✓ interprets [34,34] as ""
|
||||
✓ interprets [34,240,159,146,169,34] as "💩"
|
||||
✓ interprets [34,237,160,181,237,188,128,34] as {}
|
||||
✓ interprets [34,196,145,34] as "đ"
|
||||
✓ interprets [34,224,160,149,34] as "ࠕ"
|
||||
encodes sent postMessage API data as UTF-8
|
||||
sendAppMessage: [object Object]
|
||||
✓ encodes "" as [34,34,0]
|
||||
sendAppMessage: [object Object]
|
||||
✓ encodes "💩" as [34,240,159,146,169,34,0]
|
||||
sendAppMessage: [object Object]
|
||||
✓ encodes "đ" as [34,196,145,34,0]
|
||||
sendAppMessage: [object Object]
|
||||
✓ encodes "ࠕ" as [34,224,160,149,34,0]
|
||||
|
||||
9 passing (25ms)
|
||||
|
||||
```
|
||||
|
||||
## Linting the test code
|
||||
|
||||
1. `cd sdk/tests/include`
|
||||
2. `npm run-script lint`
|
||||
|
||||
## Adding tests
|
||||
|
||||
* You can add `test_xyz.js` files in the `tests` folder. It will automatically get picked up by the test runner.
|
||||
* If you need to a mock for the global `Pebble` object, check out `pebble-mock.js`. It's probably worth using and extending that than to re-invent the wheel.
|
||||
* When adding additional dependencies (node packages), make sure to install them using `npm install --save-dev <PACKAGE_NAME>` so that they get added to the `devDependencies` in the `package.json` file.
|
23
sdk/tests/include/package.json
Normal file
23
sdk/tests/include/package.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "pebble-pkjs-tests",
|
||||
"version": "1.0.0",
|
||||
"description": "Unit tests for .js pkjs assets",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"utf8": "^2.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^2.10.2",
|
||||
"eslint-plugin-import": "^1.11.1",
|
||||
"eslint-plugin-jsx-a11y": "^2.0.1",
|
||||
"mocha": "^2.5.3",
|
||||
"simple-mock": "^0.7.0",
|
||||
"unroll": "^1.1.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "NODE_PATH=./node_modules ./node_modules/mocha/bin/mocha *.js",
|
||||
"lint": "./node_modules/eslint/bin/eslint.js -c .eslintrc.js *.js"
|
||||
},
|
||||
"author": "",
|
||||
"license": "© Pebble Technology Corp."
|
||||
}
|
50
sdk/tests/include/pebble-mock.js
Normal file
50
sdk/tests/include/pebble-mock.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
/* eslint-env mocha */
|
||||
/* eslint func-names: 0 */
|
||||
/* eslint no-console: 0 */
|
||||
|
||||
// Constructor to build a mock for the global Pebble object:
|
||||
module.exports = function() {
|
||||
const simple = require('simple-mock');
|
||||
const assert = require('assert');
|
||||
|
||||
var eventHandlers = {
|
||||
appmessage: [],
|
||||
ready: []
|
||||
};
|
||||
|
||||
simple.mock(this, 'addEventListener', (event_name, handler) => {
|
||||
assert(event_name in eventHandlers, '\'' + event_name + '\' not known');
|
||||
eventHandlers[event_name].push(handler);
|
||||
});
|
||||
|
||||
simple.mock(this, 'handleEvent', (event) => {
|
||||
assert(event.name in eventHandlers, '\'' + event.name + '\' not known');
|
||||
for (let handler of eventHandlers[event.name]) {
|
||||
handler(event);
|
||||
}
|
||||
});
|
||||
|
||||
simple.mock(this, 'sendAppMessage', (msg, complCb, errCb) => {
|
||||
console.log(
|
||||
'sendAppMessage: ' + msg + ' complCb: ' + complCb + ' errCb: ' + errCb);
|
||||
if (complCb) {
|
||||
complCb(msg);
|
||||
}
|
||||
});
|
||||
};
|
457
sdk/tests/include/test_message.js
Normal file
457
sdk/tests/include/test_message.js
Normal file
|
@ -0,0 +1,457 @@
|
|||
/**
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
/* eslint-env mocha */
|
||||
/* eslint func-names: 0 */
|
||||
|
||||
const assert = require('assert');
|
||||
const unroll = require('unroll');
|
||||
unroll.use(it);
|
||||
|
||||
// Override setTimeout() to fire immediately:
|
||||
var origSetTimeout = setTimeout;
|
||||
setTimeout = function(f, t) {
|
||||
origSetTimeout(f.bind(undefined), 0);
|
||||
};
|
||||
|
||||
describe('Pebble', () => {
|
||||
|
||||
var mockPebble;
|
||||
|
||||
const simulateReceivingAppMessageEvent = (payload) => {
|
||||
const appMessageEvent = {
|
||||
name: 'appmessage',
|
||||
payload: payload
|
||||
};
|
||||
global.Pebble.handleEvent(appMessageEvent);
|
||||
};
|
||||
|
||||
const enterSessionOpen = () => {
|
||||
global.Pebble.handleEvent({ name : "ready" });
|
||||
var data = new Uint8Array(6);
|
||||
data[0] = 1;
|
||||
data[1] = 3;
|
||||
data[2] = 0;
|
||||
data[3] = 155;
|
||||
data[4] = 0;
|
||||
data[5] = 155;
|
||||
simulateReceivingAppMessageEvent({ 'ControlKeyResetComplete' : Array.from(data) });
|
||||
mockPebble.sendAppMessage.reset();
|
||||
};
|
||||
|
||||
const createChunk = (offset, size, data) => {
|
||||
if (offset == 0) { // First msg
|
||||
var isFirst = (1 << 7);
|
||||
var n = size + 1;
|
||||
} else {
|
||||
var isFirst = 0;
|
||||
var n = offset;
|
||||
}
|
||||
var rv = [ (n) & 255,
|
||||
(n >> 8) & 255,
|
||||
(n >> 16) & 255,
|
||||
((n >> 24) & ~(1 << 7)) | isFirst ];
|
||||
Array.prototype.push.apply(rv, data.slice(offset, offset + size));
|
||||
if (offset + size == data.length) {
|
||||
rv.push(0);
|
||||
}
|
||||
return { "ControlKeyChunk" : rv };
|
||||
};
|
||||
|
||||
const simulateReceivingPostMessageChunk = () => {
|
||||
var data = '{ "msg_num" : 0 }'.split('').map(function(x) { return x.charCodeAt(0); });
|
||||
var chunk = createChunk(0, data.length, data);
|
||||
simulateReceivingAppMessageEvent(chunk);
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
// Create a new mock for the Pebble global object for each test:
|
||||
const PebbleMockConstructor = require('./pebble-mock.js');
|
||||
global.Pebble = new PebbleMockConstructor();
|
||||
|
||||
// Keep a reference to the mock that will be "wrapped" as soon as _pkjs_message_wrapper.js
|
||||
// is loaded...
|
||||
mockPebble = global.Pebble;
|
||||
|
||||
// Reload it to 'patch' the Pebble object:
|
||||
const message_js_path = '../../include/_pkjs_message_wrapper.js';
|
||||
delete require.cache[require.resolve(message_js_path)];
|
||||
require(message_js_path);
|
||||
enterSessionOpen();
|
||||
});
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Message Encoding
|
||||
***************************************************************************/
|
||||
|
||||
describe('interprets received postMessage API data as UTF-8', () => {
|
||||
unroll('interprets #utf8_data as #result', (done, fixture) => {
|
||||
global.Pebble.on('message', (event) => {
|
||||
assert.equal(event.type, 'message');
|
||||
assert.equal(event.data, fixture.result);
|
||||
done();
|
||||
});
|
||||
|
||||
const payload = createChunk(0, fixture.utf8_data.length, fixture.utf8_data);
|
||||
|
||||
if (fixture.result instanceof Error) {
|
||||
assert.throws(() => {
|
||||
simulateReceivingAppMessageEvent(payload);
|
||||
}, typeof(fixture.result), fixture.result.message);
|
||||
done();
|
||||
} else {
|
||||
simulateReceivingAppMessageEvent(payload);
|
||||
}
|
||||
|
||||
}, [
|
||||
['utf8_data', 'result'],
|
||||
// empty string:
|
||||
[[34, 34], ''],
|
||||
// Pile of Poo, in double quotes:
|
||||
[[34, 240, 159, 146, 169,34], '💩'],
|
||||
// Surrogates are illegal in UTF-8:
|
||||
[[34, 0xED, 0xA0, 0xB5, 0xED, 0xBC, 0x80, 34], Error('Lone surrogate U+D835 is not a scalar value')],
|
||||
// 2-byte code point, in double quotes:
|
||||
[[34, 196, 145, 34], '\u0111'],
|
||||
// 3-byte codepoint, in double quotes:
|
||||
[[34, 0xE0, 0xA0, 0x95, 34], '\u0815']
|
||||
]);
|
||||
});
|
||||
|
||||
describe('encodes sent postMessage API data as UTF-8', () => {
|
||||
unroll('encodes #input as #utf8_data', (done, fixture) => {
|
||||
|
||||
global.Pebble.postMessage(fixture.input);
|
||||
assert.equal(mockPebble.sendAppMessage.callCount, 1);
|
||||
const lastAppMessage = mockPebble.sendAppMessage.lastCall.args[0];
|
||||
assert.deepEqual(lastAppMessage['ControlKeyChunk'].slice(4), fixture.utf8_data);
|
||||
done();
|
||||
|
||||
}, [
|
||||
['input', 'utf8_data'],
|
||||
// empty string:
|
||||
['', [34, 34, 0]],
|
||||
// Pile of Poo, in double quotes:
|
||||
['💩', [34, 240, 159, 146, 169, 34, 0]],
|
||||
// 2-byte code point, in double quotes:
|
||||
['\u0111', [34, 196, 145, 34, 0]],
|
||||
// 3-byte codepoint, in double quotes:
|
||||
['\u0815', [34, 0xE0, 0xA0, 0x95, 34, 0]]
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Message Handlers
|
||||
***************************************************************************/
|
||||
|
||||
describe('Ensure that AppMessage is blocked', () => {
|
||||
it('tries to register a Pebble.on("appmessage") handler', (done) => {
|
||||
assert.throws(() => {
|
||||
global.Pebble.on('appmessage', (e) => {
|
||||
assert(0, "Should not have been called");
|
||||
});
|
||||
}, /not supported/);
|
||||
|
||||
// If this results in our callback being called, we'll throw an Error().
|
||||
simulateReceivingAppMessageEvent({ 'KEY' : 'DATA' });
|
||||
done();
|
||||
});
|
||||
it('tries to Pebble.addEventListener("appmessage")', (done) => {
|
||||
assert.throws(() => {
|
||||
global.Pebble.addEventListener('appmessage', (e) => {
|
||||
// This will be thrown if the eventlistener was registered
|
||||
assert(0, "Should not have been called");
|
||||
});
|
||||
}, /not supported/);
|
||||
|
||||
// If this results in our callback being called, we'll throw an Error().
|
||||
simulateReceivingAppMessageEvent({ 'KEY' : 'DATA' });
|
||||
done();
|
||||
});
|
||||
it('tries to call Pebble.sendAppMessage()', (done) => {
|
||||
assert.notStrictEqual(typeof global.Pebble.sendAppMessage, 'function');
|
||||
assert.equal(global.Pebble.sendAppMessage, undefined);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('registers multiple message handlers', () => {
|
||||
unroll('registers #num_handlers handlers to receive #num_messages messages each', (done, fixture) => {
|
||||
var callback_count = 0;
|
||||
var handler = function(e) { ++callback_count; };
|
||||
|
||||
for (var h = 0; h < fixture.num_handlers; ++h) {
|
||||
global.Pebble.on('message', handler);
|
||||
}
|
||||
for (var i = 0; i < fixture.num_messages; ++i) {
|
||||
simulateReceivingPostMessageChunk();
|
||||
}
|
||||
assert.equal(callback_count, fixture.num_handlers * fixture.num_messages);
|
||||
done();
|
||||
}, [
|
||||
[ 'num_handlers', 'num_messages' ],
|
||||
[ 1, 1 ],
|
||||
[ 2, 1 ],
|
||||
[ 3, 2 ],
|
||||
]);
|
||||
});
|
||||
|
||||
describe('registers multiple message handlers, unsubscribes one', () => {
|
||||
unroll('registers #num_handlers, then unregisters #num_unregister', (done, fixture) => {
|
||||
var callback_count = 0;
|
||||
var handler = function(e) { ++callback_count; };
|
||||
|
||||
for (var h = 0; h < fixture.num_handlers; ++h) {
|
||||
global.Pebble.on('message', handler);
|
||||
}
|
||||
for (var u = 0; u < fixture.num_unregister; ++u) {
|
||||
global.Pebble.off('message', handler);
|
||||
}
|
||||
simulateReceivingPostMessageChunk();
|
||||
assert.equal(callback_count, fixture.num_handlers - fixture.num_unregister);
|
||||
done();
|
||||
}, [
|
||||
[ 'num_handlers', 'num_unregister' ],
|
||||
[ 4, 2 ],
|
||||
[ 10, 10 ],
|
||||
]);
|
||||
});
|
||||
|
||||
describe('call Pebble.off("message", handler) from within that event handler', () => {
|
||||
unroll('calling while #num_registered other handlers are registered', (done, fixture) => {
|
||||
var callback_count = 0;
|
||||
var handler = function(e) { ++callback_count; };
|
||||
var remove_handler = function(e) { ++callback_count; global.Pebble.off('message', remove_handler); }
|
||||
|
||||
global.Pebble.on('message', remove_handler);
|
||||
for (var i = 0; i < fixture.num_registered; ++i) {
|
||||
global.Pebble.on('message', handler);
|
||||
}
|
||||
simulateReceivingPostMessageChunk();
|
||||
assert.equal(callback_count, fixture.num_registered + 1);
|
||||
|
||||
// Now that the remove_handler has been removed, send another and make
|
||||
// sure that we have one less called.
|
||||
callback_count = 0;
|
||||
simulateReceivingPostMessageChunk();
|
||||
assert.equal(callback_count, fixture.num_registered);
|
||||
done();
|
||||
}, [
|
||||
[ 'num_registered' ],
|
||||
[ 0 ],
|
||||
[ 1 ],
|
||||
[ 10 ],
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* postmessageerror event
|
||||
***************************************************************************/
|
||||
|
||||
describe('postmessageerror Event', () => {
|
||||
it('event.data is set to the object that was attempted to be sent', (done) => {
|
||||
global.Pebble.handleEvent({ name : "ready" });
|
||||
mockPebble.sendAppMessage.reset();
|
||||
|
||||
global.Pebble.on('postmessageerror', function(e) {
|
||||
assert.deepEqual(e.data, {b: 'c'});
|
||||
done();
|
||||
});
|
||||
|
||||
var a = { b: 'c' };
|
||||
global.Pebble.postMessage(a);
|
||||
a.b = 'd'; // modify to test that a copy of 'a' is sent
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* postmessageconnected / postmessagedisconnected event
|
||||
***************************************************************************/
|
||||
|
||||
describe('Connection Events', () => {
|
||||
unroll('postmessageconnected. Start connected: #start_connected', (done, fixture) => {
|
||||
var connected_call_count = 0;
|
||||
|
||||
if (!fixture.start_connected) {
|
||||
// Disconnect
|
||||
global.Pebble.handleEvent({ name : "ready" });
|
||||
}
|
||||
global.Pebble.on('postmessageconnected', function(e) {
|
||||
assert.equal(e.type, 'postmessageconnected');
|
||||
++connected_call_count;
|
||||
});
|
||||
|
||||
enterSessionOpen(); // establish connection
|
||||
|
||||
if (fixture.start_connected) {
|
||||
assert.equal(connected_call_count, 2);
|
||||
} else {
|
||||
assert.equal(connected_call_count, 1);
|
||||
}
|
||||
|
||||
done();
|
||||
}, [
|
||||
[ 'start_connected' ],
|
||||
[ true, ],
|
||||
[ false, ],
|
||||
]);
|
||||
|
||||
unroll('postmessagedisconnected. Start disconnected: #start_disconnected', (done, fixture) => {
|
||||
var disconnected_call_count = 0;
|
||||
|
||||
if (fixture.start_disconnected) {
|
||||
// Disconnect
|
||||
global.Pebble.handleEvent({ name : "ready" });
|
||||
}
|
||||
global.Pebble.on('postmessagedisconnected', function(e) {
|
||||
assert.equal(e.type, 'postmessagedisconnected');
|
||||
++disconnected_call_count;
|
||||
});
|
||||
|
||||
if (fixture.start_disconnected) {
|
||||
// Need to establish a connection before we can disconnect
|
||||
enterSessionOpen();
|
||||
}
|
||||
|
||||
global.Pebble.handleEvent({ name : "ready" }); // Disconnect again
|
||||
|
||||
if (fixture.start_disconnected) {
|
||||
assert.equal(disconnected_call_count, 2);
|
||||
} else {
|
||||
assert.equal(disconnected_call_count, 1);
|
||||
}
|
||||
|
||||
done();
|
||||
}, [
|
||||
[ 'start_disconnected' ],
|
||||
[ true, ],
|
||||
[ false, ],
|
||||
]);
|
||||
});
|
||||
|
||||
/****************************************************************************
|
||||
* Control Layer
|
||||
***************************************************************************/
|
||||
|
||||
describe('Control Layer', () => {
|
||||
it('Ready message => ResetRequest', (done) => {
|
||||
global.Pebble.handleEvent({ name : "ready" });
|
||||
|
||||
assert.equal(mockPebble.sendAppMessage.callCount, 1);
|
||||
assert('ControlKeyResetRequest' in mockPebble.sendAppMessage.lastCall.args[0]);
|
||||
done();
|
||||
});
|
||||
it ('Disconnected => AwaitingResetCompleteLocalInitiated => SessionOpen', (done) => {
|
||||
global.Pebble.handleEvent({ name : "ready" });
|
||||
mockPebble.sendAppMessage.reset();
|
||||
|
||||
var data = new Uint8Array(6);
|
||||
data[0] = 1;
|
||||
data[1] = 3;
|
||||
data[2] = 0;
|
||||
data[3] = 155;
|
||||
data[4] = 0;
|
||||
data[5] = 155;
|
||||
simulateReceivingAppMessageEvent({ 'ControlKeyResetComplete' : Array.from(data) });
|
||||
|
||||
assert.equal(mockPebble.sendAppMessage.callCount, 1);
|
||||
assert('ControlKeyResetComplete' in mockPebble.sendAppMessage.lastCall.args[0]);
|
||||
done();
|
||||
});
|
||||
it ('Disconnected => AwaitingResetCompleteLocalInitiated => UnsupportedError', (done) => {
|
||||
global.Pebble.handleEvent({ name : "ready" });
|
||||
mockPebble.sendAppMessage.reset();
|
||||
|
||||
var data = new Uint8Array(6);
|
||||
data[0] = 155; // Unsupported min version
|
||||
data[1] = 156; // Unsupported max version
|
||||
data[2] = 0;
|
||||
data[3] = 155;
|
||||
data[4] = 0;
|
||||
data[5] = 155;
|
||||
simulateReceivingAppMessageEvent({ 'ControlKeyResetComplete' : Array.from(data) });
|
||||
|
||||
assert.equal(mockPebble.sendAppMessage.callCount, 1);
|
||||
assert('ControlKeyUnsupportedError' in mockPebble.sendAppMessage.lastCall.args[0]);
|
||||
done();
|
||||
});
|
||||
it ('SessionOpen => AwaitingResetCompleteRemoteInitiated => UnsupportedError => Error', (done) => {
|
||||
simulateReceivingAppMessageEvent({ 'ControlKeyResetRequest' : 0 });
|
||||
assert.equal(mockPebble.sendAppMessage.callCount, 1);
|
||||
assert('ControlKeyResetComplete' in mockPebble.sendAppMessage.lastCall.args[0]);
|
||||
|
||||
try {
|
||||
simulateReceivingAppMessageEvent({ 'ControlKeyUnsupportedError' : "Test Error" });
|
||||
} catch (e) {
|
||||
assert.equal("Error: Unsupported protocol error: Test Error", e.toString());
|
||||
}
|
||||
done();
|
||||
});
|
||||
it ('Retry sending control message, check max retries.', (done) => {
|
||||
// override setTimeout
|
||||
setTimeout = function(fn, delay) {
|
||||
fn(); // Use a synchronous call here because we want to make sure that there
|
||||
// is a maximum of 3 callbacks. If we do these asynchronously,
|
||||
// there is no nice way to test this.
|
||||
}
|
||||
|
||||
// Replace our sendAppMessage with one that will always call the error callback
|
||||
_mockSendAppMessage = mockPebble.sendAppMessage;
|
||||
mockPebble.sendAppMessage = function(msg, complCb, errCb) {
|
||||
_mockSendAppMessage(msg, undefined, errCb);
|
||||
errCb(msg);
|
||||
};
|
||||
simulateReceivingAppMessageEvent({ 'ControlKeyResetRequest' : 0 });
|
||||
|
||||
// Should be called 1 + 3 retries, no more.
|
||||
assert.equal(_mockSendAppMessage.callCount, 4);
|
||||
done();
|
||||
});
|
||||
it('Retry sending control message, asynch', (done) => {
|
||||
// This test will fail due to timeout if retry isn't working correctly.
|
||||
|
||||
var _setTimeout = setTimeout;
|
||||
setTimeout = function(fn, delay) {
|
||||
_setTimeout(fn, 0);
|
||||
}
|
||||
_mockSendAppMessage = mockPebble.sendAppMessage;
|
||||
mockPebble.sendAppMessage = function(msg, complCb, errCb) {
|
||||
_mockSendAppMessage(msg, undefined, errCb);
|
||||
if (_mockSendAppMessage.callCount == 4) {
|
||||
// 4 calls is 1 + 3 retries. We're done here
|
||||
done();
|
||||
} else {
|
||||
_setTimeout(errCb.bind(msg), 0);
|
||||
}
|
||||
};
|
||||
simulateReceivingAppMessageEvent({ 'ControlKeyResetRequest' : 0 });
|
||||
});
|
||||
});
|
||||
|
||||
it('.postMessage(nonJSONable) should throw a TypeError', (done) => {
|
||||
var expectedMsg =
|
||||
"Argument at index 0 is not a JSON.stringify()-able object";
|
||||
assert.throws(
|
||||
() => { global.Pebble.postMessage(undefined); }, TypeError, expectedMsg);
|
||||
assert.throws(
|
||||
() => { global.Pebble.postMessage(() => {}); }, TypeError, expectedMsg);
|
||||
done()
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue