Webapp: unit test
This commit is contained in:
parent
a557640228
commit
30c6a83399
|
@ -0,0 +1,12 @@
|
|||
/* global jest, test, expect */
|
||||
import bluetooth from '.';
|
||||
|
||||
jest.mock('./webapp', () => null);
|
||||
jest.mock('./peripheral', () => null);
|
||||
|
||||
test('actions', () => {
|
||||
expect(Object.keys(bluetooth)).toEqual([
|
||||
'peripheral',
|
||||
'webapp',
|
||||
]);
|
||||
});
|
|
@ -0,0 +1,11 @@
|
|||
/* global jest, test, expect */
|
||||
import peripheral from '.';
|
||||
|
||||
jest.mock('./bleno', () => ({
|
||||
start: jest.fn().mockReturnValue('mockStart'),
|
||||
}));
|
||||
|
||||
test('peripheral', () => {
|
||||
const result = peripheral(null, null);
|
||||
expect(result).toEqual('mockStart');
|
||||
});
|
|
@ -0,0 +1,52 @@
|
|||
export default function Central(
|
||||
bluetooth,
|
||||
{ encode, decode },
|
||||
{ SERVICE_UUID, CHARACTERISTIC_UUID }) {
|
||||
const state = {
|
||||
server: null,
|
||||
characteristic: null,
|
||||
};
|
||||
|
||||
const connect = name => bluetooth
|
||||
.requestDevice({
|
||||
filters: [{ services: [SERVICE_UUID], name }],
|
||||
})
|
||||
.then(device => device.gatt.connect())
|
||||
.then((server) => {
|
||||
state.server = server;
|
||||
return server.getPrimaryService(SERVICE_UUID);
|
||||
})
|
||||
.then(service => service.getCharacteristic(CHARACTERISTIC_UUID))
|
||||
.then((characteristic) => {
|
||||
state.characteristic = characteristic;
|
||||
});
|
||||
|
||||
const handler = callback => state.characteristic.startNotifications().then(() => {
|
||||
const listerner = event => callback(decode(event.target.value));
|
||||
state.characteristic.addEventListener('characteristicvaluechanged', listerner);
|
||||
return listerner;
|
||||
});
|
||||
|
||||
const read = () => {
|
||||
if (state.server && state.server.connected && state.characteristic) {
|
||||
return state.characteristic.readValue().then(data => decode(data));
|
||||
}
|
||||
return Promise.reject(new Error('Bluetooth: Not Connected'));
|
||||
};
|
||||
|
||||
const write = (action) => {
|
||||
if (!state.server || !state.server.connected || !state.characteristic) return null;
|
||||
const stringify = JSON.stringify(action);
|
||||
const serialized = encode(stringify);
|
||||
|
||||
return state.characteristic.writeValue(serialized);
|
||||
};
|
||||
|
||||
return {
|
||||
connected: state.server && state.server.connected,
|
||||
connect,
|
||||
handler,
|
||||
read,
|
||||
write,
|
||||
};
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/* global jest, beforeEach, afterEach, test, expect */
|
||||
import { CENTRAL_CONFIG } from '../../common/config';
|
||||
import Central from './central';
|
||||
|
||||
const encoder = {
|
||||
encode: jest.fn().mockReturnValue('mockEncode'),
|
||||
decode: jest.fn().mockReturnValue('mockDecode'),
|
||||
};
|
||||
|
||||
const characteristic = {
|
||||
startNotifications: jest.fn().mockReturnValue(Promise.resolve()),
|
||||
addEventListener: jest.fn(),
|
||||
writeValue: jest.fn().mockReturnValue(Promise.resolve()),
|
||||
readValue: jest.fn().mockReturnValue(Promise.resolve('mockData')),
|
||||
};
|
||||
|
||||
const service = {
|
||||
getCharacteristic: jest.fn().mockReturnValue(Promise.resolve(characteristic)),
|
||||
};
|
||||
|
||||
const server = {
|
||||
connected: true,
|
||||
getPrimaryService: jest.fn().mockReturnValue(Promise.resolve(service)),
|
||||
};
|
||||
|
||||
const device = {
|
||||
gatt: {
|
||||
connect: jest.fn().mockReturnValue(Promise.resolve(server)),
|
||||
},
|
||||
};
|
||||
|
||||
const bluetooth = {
|
||||
requestDevice: jest.fn().mockReturnValue(Promise.resolve(device)),
|
||||
};
|
||||
|
||||
let central = null;
|
||||
|
||||
beforeEach(() => {
|
||||
central = new Central(bluetooth, encoder, CENTRAL_CONFIG);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
central = null;
|
||||
});
|
||||
|
||||
|
||||
test('Central: connect', () => {
|
||||
expect.assertions(5);
|
||||
|
||||
const promise = central.connect('mockName').then(() => {
|
||||
expect(bluetooth.requestDevice).toBeCalled();
|
||||
expect(device.gatt.connect).toBeCalled();
|
||||
expect(server.getPrimaryService).toBeCalled();
|
||||
expect(service.getCharacteristic).toBeCalled();
|
||||
return true;
|
||||
});
|
||||
|
||||
return expect(promise).resolves.toBe(true);
|
||||
});
|
||||
|
||||
test('Central: handler', () => {
|
||||
const callback = jest.fn();
|
||||
expect.assertions(3);
|
||||
|
||||
const promise = central.connect('mockName').then(() => central.handler(callback))
|
||||
.then((listerner) => {
|
||||
expect(characteristic.startNotifications).toBeCalled();
|
||||
listerner({ target: { value: 'mockEvent' } });
|
||||
expect(callback).toBeCalledWith('mockDecode');
|
||||
return true;
|
||||
});
|
||||
|
||||
return expect(promise).resolves.toBe(true);
|
||||
});
|
||||
|
||||
test('Central: read', () => {
|
||||
expect.assertions(2);
|
||||
|
||||
const promise = central.connect('mockName').then(() => central.read())
|
||||
.then((data) => {
|
||||
expect(characteristic.readValue).toBeCalled();
|
||||
return data;
|
||||
});
|
||||
|
||||
return expect(promise).resolves.toBe('mockDecode');
|
||||
});
|
||||
|
||||
test('Central: write', () => {
|
||||
expect.assertions(2);
|
||||
|
||||
const promise = central.connect('mockName')
|
||||
.then(() => central.write({ type: 'ACTION' }))
|
||||
.then(() => {
|
||||
expect(characteristic.writeValue).toBeCalledWith('mockEncode');
|
||||
return true;
|
||||
});
|
||||
|
||||
return expect(promise).resolves.toBe(true);
|
||||
});
|
||||
|
|
@ -1,57 +1,9 @@
|
|||
/* global navigator TextEncoder TextDecoder */
|
||||
import { CENTRAL_CONFIG } from '../../common/config';
|
||||
import Encoder from '../../common/encoder';
|
||||
|
||||
export function Central(bluetooth, { encode, decode }, { SERVICE_UUID, CHARACTERISTIC_UUID }) {
|
||||
const state = {
|
||||
server: null,
|
||||
characteristic: null,
|
||||
};
|
||||
import Central from './central';
|
||||
|
||||
const connect = name => bluetooth
|
||||
.requestDevice({
|
||||
filters: [{ services: [SERVICE_UUID], name }],
|
||||
})
|
||||
.then(device => device.gatt.connect())
|
||||
.then((server) => {
|
||||
state.server = server;
|
||||
return server.getPrimaryService(SERVICE_UUID);
|
||||
})
|
||||
.then(service => service.getCharacteristic(CHARACTERISTIC_UUID))
|
||||
.then((characteristic) => {
|
||||
state.characteristic = characteristic;
|
||||
});
|
||||
|
||||
const handler = callback => state.characteristic.startNotifications().then(() => {
|
||||
state.characteristic.addEventListener('characteristicvaluechanged', (event) => {
|
||||
callback(decode(event.target.value));
|
||||
});
|
||||
});
|
||||
|
||||
const read = () => {
|
||||
if (state.server && state.server.connected && state.characteristic) {
|
||||
return state.characteristic.readValue().then(data => decode(data));
|
||||
}
|
||||
return Promise.reject(new Error('Bluetooth: Not Connected'));
|
||||
};
|
||||
|
||||
const write = (action) => {
|
||||
if (!state.server || !state.server.connected || !state.characteristic) return null;
|
||||
const stringify = JSON.stringify(action);
|
||||
const serialized = encode(stringify);
|
||||
|
||||
return state.characteristic.writeValue(serialized);
|
||||
};
|
||||
|
||||
return {
|
||||
connected: state.server && state.server.connected,
|
||||
connect,
|
||||
handler,
|
||||
read,
|
||||
write,
|
||||
};
|
||||
}
|
||||
|
||||
/* global navigator TextEncoder TextDecoder */
|
||||
export default new Central(
|
||||
navigator.bluetooth,
|
||||
Encoder({ TextEncoder, TextDecoder }),
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/* global jest, test, expect, beforeEach, afterEach */
|
||||
import middleware from '.';
|
||||
|
||||
jest.mock('../actions', () => ({
|
||||
sendAction: jest.fn().mockReturnValue('mockAction'),
|
||||
}));
|
||||
|
||||
let store = null;
|
||||
let next = null;
|
||||
|
||||
beforeEach(() => {
|
||||
store = {
|
||||
dispatch: jest.fn(),
|
||||
};
|
||||
next = jest.fn();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
store = null;
|
||||
next = null;
|
||||
});
|
||||
|
||||
test('actions empty', () => {
|
||||
middleware()(store)(next)({ type: 'ACTION' });
|
||||
expect(next).toBeCalledWith({ type: 'ACTION' });
|
||||
});
|
||||
|
||||
test('actions not included', () => {
|
||||
middleware(['ACTION'])(store)(next)({ type: 'NOTEXISTS' });
|
||||
expect(next).toBeCalledWith({ type: 'NOTEXISTS' });
|
||||
});
|
||||
|
||||
test('actions included', () => {
|
||||
middleware(['ACTION'])(store)(next)({ type: 'ACTION' });
|
||||
expect(store.dispatch).toBeCalledWith('mockAction');
|
||||
expect(next).toBeCalledWith({ type: 'ACTION' });
|
||||
});
|
|
@ -1,6 +1,18 @@
|
|||
/* global test, expect */
|
||||
import * as STATUS from '../central/status';
|
||||
import * as TYPES from '../actions/types';
|
||||
|
||||
import initial from './initial';
|
||||
import Reducer from '.';
|
||||
|
||||
test('Default State', () => {
|
||||
const reducer = Reducer();
|
||||
|
||||
const nextState = reducer(undefined, { type: 'UNKNOWN' });
|
||||
|
||||
return expect(nextState).toBe(initial);
|
||||
});
|
||||
|
||||
test('type: UNKNOWN', () => {
|
||||
const reducer = Reducer();
|
||||
|
||||
|
@ -9,3 +21,40 @@ test('type: UNKNOWN', () => {
|
|||
|
||||
return expect(nextState).toBe(originalState);
|
||||
});
|
||||
|
||||
test('type: BLUETOOTH_CONNECTING', () => {
|
||||
const reducer = Reducer();
|
||||
|
||||
const originalState = { };
|
||||
const nextState = reducer(originalState, { type: TYPES.BLUETOOTH_CONNECTING });
|
||||
|
||||
return expect(nextState).toEqual({ status: STATUS.CONNECTING });
|
||||
});
|
||||
|
||||
test('type: BLUETOOTH_CONNECTED', () => {
|
||||
const reducer = Reducer();
|
||||
|
||||
const originalState = { };
|
||||
const nextState = reducer(originalState, { type: TYPES.BLUETOOTH_CONNECTED });
|
||||
|
||||
return expect(nextState).toEqual({ status: STATUS.CONNECTED });
|
||||
});
|
||||
|
||||
test('type: BLUETOOTH_SYNC', () => {
|
||||
const reducer = Reducer();
|
||||
|
||||
const originalState = { };
|
||||
const nextState = reducer(originalState, { type: TYPES.BLUETOOTH_SYNC, payload: 'mockPayload' });
|
||||
|
||||
return expect(nextState).toEqual({ store: 'mockPayload' });
|
||||
});
|
||||
|
||||
test('type: BLUETOOTH_SYNC, autosync: false', () => {
|
||||
const reducer = Reducer(false);
|
||||
|
||||
const originalState = { };
|
||||
const nextState = reducer(originalState, { type: TYPES.BLUETOOTH_SYNC, payload: 'mockPayload' });
|
||||
|
||||
return expect(nextState).toEqual({ });
|
||||
});
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
import * as STATUS from '../central/status';
|
||||
|
||||
export default { status: STATUS.INIT };
|
|
@ -0,0 +1,16 @@
|
|||
/* global jest, test, expect */
|
||||
import createSyncStore from '.';
|
||||
|
||||
jest.mock('redux', () => ({
|
||||
createStore: jest.fn().mockReturnValue('mockStore'),
|
||||
applyMiddleware: jest.fn(),
|
||||
compose: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('../middleware', () => jest.fn());
|
||||
jest.mock('../reducers', () => jest.fn());
|
||||
|
||||
test('createSyncStore', () => {
|
||||
const store = createSyncStore(['ACTION']);
|
||||
return expect(store).toBe('mockStore');
|
||||
});
|
Loading…
Reference in New Issue