Merge pull request #10 from jvallelunga/ISSUE-9
[ISSUE-9] Reafactor Peripheral
This commit is contained in:
commit
bd9569c678
|
@ -1,3 +1,4 @@
|
|||
{
|
||||
"testPathIgnorePatterns": ["/build/"],
|
||||
"collectCoverageFrom": ["src/**/*.js"]
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { createStore } from 'redux';
|
||||
import startPeripheral from 'redux-bluetooth/build/peripheral';
|
||||
import { connectSyncStore } from 'redux-bluetooth/build/peripheral';
|
||||
|
||||
import reducer from './reducer';
|
||||
import output from './output';
|
||||
|
@ -7,5 +7,4 @@ import output from './output';
|
|||
const store = createStore(reducer);
|
||||
|
||||
output(store);
|
||||
startPeripheral('Counter', store);
|
||||
|
||||
connectSyncStore('Counter', store);
|
||||
|
|
|
@ -6,25 +6,11 @@ export default function Characteristic(uuid, Parent, util, descriptor, { encode,
|
|||
descriptors: [descriptor],
|
||||
});
|
||||
|
||||
this.store = null;
|
||||
this.state = null;
|
||||
}
|
||||
|
||||
util.inherits(ReduxCharacteristic, Parent);
|
||||
|
||||
ReduxCharacteristic.prototype.connect = function (store) {
|
||||
this.store = store;
|
||||
this.store.subscribe(() => {
|
||||
if (this.updateValueCallback && this.store) {
|
||||
const state = this.store.getState();
|
||||
this.updateValueCallback(encode(state));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ReduxCharacteristic.prototype.disconnect = function () {
|
||||
this.store = null;
|
||||
};
|
||||
|
||||
ReduxCharacteristic.prototype.onWriteRequest =
|
||||
function (data, offset, withoutResponse, callback) {
|
||||
if (offset) {
|
||||
|
@ -32,7 +18,7 @@ export default function Characteristic(uuid, Parent, util, descriptor, { encode,
|
|||
return;
|
||||
}
|
||||
|
||||
if (this.store) this.store.dispatch(decode(data));
|
||||
this.onAction(decode(data));
|
||||
|
||||
callback(this.RESULT_SUCCESS);
|
||||
};
|
||||
|
@ -47,7 +33,7 @@ export default function Characteristic(uuid, Parent, util, descriptor, { encode,
|
|||
callback(this.RESULT_SUCCESS, null);
|
||||
return;
|
||||
}
|
||||
callback(this.RESULT_SUCCESS, encode(this.store.getState()));
|
||||
callback(this.RESULT_SUCCESS, this.state);
|
||||
};
|
||||
|
||||
ReduxCharacteristic.prototype.onSubscribe = function (maxValueSize, updateValueCallback) {
|
||||
|
@ -58,5 +44,16 @@ export default function Characteristic(uuid, Parent, util, descriptor, { encode,
|
|||
this.updateValueCallback = null;
|
||||
};
|
||||
|
||||
ReduxCharacteristic.prototype.onAction = function () {
|
||||
return true;
|
||||
};
|
||||
|
||||
ReduxCharacteristic.prototype.updateState = function (state) {
|
||||
this.state = encode(state);
|
||||
if (this.updateValueCallback) {
|
||||
this.updateValueCallback(this.state);
|
||||
}
|
||||
};
|
||||
|
||||
return new ReduxCharacteristic();
|
||||
}
|
||||
|
|
|
@ -22,27 +22,37 @@ export function Bleno(bleno, encoder, { SERVICE_UUID, CHARACTERISTIC_UUID, DESCR
|
|||
|
||||
const service = Service(SERVICE_UUID, bleno.PrimaryService, util, characteristic);
|
||||
|
||||
const start = (name, store) => {
|
||||
bleno.on('stateChange', (state) => {
|
||||
if (state === 'poweredOn') {
|
||||
const start = (name, state) => {
|
||||
bleno.on('stateChange', (status) => {
|
||||
if (status === 'poweredOn') {
|
||||
bleno.startAdvertising(name, [SERVICE_UUID], (err) => {
|
||||
if (err) console.log('startAdvertising.err: ', err);
|
||||
if (!err) characteristic.updateState(state);
|
||||
});
|
||||
} else {
|
||||
bleno.stopAdvertising();
|
||||
characteristic.disconnect();
|
||||
}
|
||||
});
|
||||
|
||||
bleno.on('advertisingStart', (err) => {
|
||||
if (!err) {
|
||||
bleno.setServices([service]);
|
||||
characteristic.connect(store);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return { start };
|
||||
const handler = (callback) => {
|
||||
characteristic.onAction = callback;
|
||||
};
|
||||
|
||||
const notify = (state) => {
|
||||
characteristic.updateState(state);
|
||||
};
|
||||
|
||||
return {
|
||||
start,
|
||||
handler,
|
||||
notify,
|
||||
};
|
||||
}
|
||||
|
||||
export default new Bleno(BLENO, Encoder(TextEncoding), BLENO_CONFIG);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import bleno from './bleno';
|
||||
import BLUETOOTH from './bleno';
|
||||
import STORE from './store';
|
||||
|
||||
export default (name, store) => bleno.start(name, store);
|
||||
export const bluetooth = BLUETOOTH;
|
||||
export const connectSyncStore = STORE(BLUETOOTH);
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
/* global jest, test, expect */
|
||||
import peripheral from '.';
|
||||
import * as peripheral from '.';
|
||||
|
||||
jest.mock('./bleno', () => ({
|
||||
start: jest.fn().mockReturnValue('mockStart'),
|
||||
}));
|
||||
jest.mock('./bleno', () => null);
|
||||
jest.mock('./store', () => () => null);
|
||||
|
||||
test('peripheral', () => {
|
||||
const result = peripheral(null, null);
|
||||
expect(result).toEqual('mockStart');
|
||||
test('actions', () => {
|
||||
expect(Object.keys(peripheral)).toEqual([
|
||||
'bluetooth',
|
||||
'connectSyncStore',
|
||||
]);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
export default bluetooth => (name, store) => {
|
||||
bluetooth.start(name, store.getState());
|
||||
|
||||
const handleSubscribe = () => {
|
||||
bluetooth.notify(store.getState());
|
||||
};
|
||||
|
||||
const handleActions = (action) => {
|
||||
store.dispatch(action);
|
||||
};
|
||||
|
||||
store.subscribe(handleSubscribe);
|
||||
bluetooth.handler(handleActions);
|
||||
|
||||
return { handleSubscribe, handleActions };
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
/* global jest, test, expect, beforeEach */
|
||||
import connectSyncStore from '.';
|
||||
|
||||
let store = null;
|
||||
let bleno = null;
|
||||
|
||||
beforeEach(() => {
|
||||
bleno = {
|
||||
start: jest.fn(),
|
||||
handler: jest.fn(),
|
||||
notify: jest.fn(),
|
||||
};
|
||||
|
||||
store = {
|
||||
subscribe: jest.fn(),
|
||||
getState: jest.fn().mockReturnValue('mockState'),
|
||||
dispatch: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
test('connectSyncStore', () => {
|
||||
const { handleSubscribe, handleActions } = connectSyncStore(bleno)('mockName', store);
|
||||
|
||||
expect(bleno.start).toBeCalledWith('mockName', 'mockState');
|
||||
expect(store.subscribe).toBeCalled();
|
||||
expect(bleno.handler).toBeCalled();
|
||||
|
||||
handleSubscribe();
|
||||
expect(bleno.notify).toBeCalledWith('mockState');
|
||||
expect(store.getState.mock.calls.length).toBe(2);
|
||||
|
||||
handleActions('mockAction');
|
||||
expect(store.dispatch).toBeCalledWith('mockAction');
|
||||
});
|
|
@ -1,9 +1,11 @@
|
|||
/* global navigator TextEncoder TextDecoder */
|
||||
/* global window */
|
||||
import { CENTRAL_CONFIG } from '../../common/config';
|
||||
import Encoder from '../../common/encoder';
|
||||
|
||||
import Central from './central';
|
||||
|
||||
const { navigator, TextDecoder, TextEncoder } = window;
|
||||
|
||||
export default new Central(
|
||||
navigator.bluetooth,
|
||||
Encoder({ TextEncoder, TextDecoder }),
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/* global jest, test, expect */
|
||||
import central from '.';
|
||||
import Central from './central';
|
||||
import { CENTRAL_CONFIG } from '../../common/config';
|
||||
|
||||
jest.mock('../../common/encoder', () => () => true);
|
||||
|
||||
global.TextEncoder = null;
|
||||
global.TextDecoder = null;
|
||||
global.navigator = { bluetooth: null };
|
||||
|
||||
test('central', () => {
|
||||
const result = new Central(
|
||||
null,
|
||||
true,
|
||||
CENTRAL_CONFIG,
|
||||
);
|
||||
|
||||
expect(Object.keys(central)).toEqual(Object.keys(result));
|
||||
});
|
|
@ -0,0 +1,20 @@
|
|||
/* global jest, test, expect */
|
||||
import * as webapp from '.';
|
||||
|
||||
jest.mock('./actions/types', () => true);
|
||||
jest.mock('./central/status', () => true);
|
||||
jest.mock('./actions', () => true);
|
||||
jest.mock('./middleware', () => true);
|
||||
jest.mock('./reducers', () => true);
|
||||
jest.mock('./store', () => true);
|
||||
|
||||
test('actions', () => {
|
||||
expect(Object.keys(webapp)).toEqual([
|
||||
'types',
|
||||
'status',
|
||||
'actions',
|
||||
'reducers',
|
||||
'middleware',
|
||||
'createSyncStore',
|
||||
]);
|
||||
});
|
Loading…
Reference in New Issue