Fix a few bugs in reducers/channels, start adding tests
This commit is contained in:
parent
307c83958a
commit
35e2ea39f1
|
@ -8,6 +8,9 @@
|
||||||
"development": {
|
"development": {
|
||||||
"plugins": ["react-hot-loader/babel"]
|
"plugins": ["react-hot-loader/babel"]
|
||||||
},
|
},
|
||||||
|
"test": {
|
||||||
|
"plugins": ["transform-es2015-modules-commonjs"]
|
||||||
|
},
|
||||||
"production": {
|
"production": {
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"transform-react-inline-elements",
|
"transform-react-inline-elements",
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-core": "^6.23.1",
|
"babel-core": "^6.23.1",
|
||||||
"babel-eslint": "^7.1.1",
|
"babel-eslint": "^7.1.1",
|
||||||
|
"babel-jest": "^19.0.0",
|
||||||
"babel-loader": "^6.3.1",
|
"babel-loader": "^6.3.1",
|
||||||
"babel-plugin-transform-react-constant-elements": "^6.23.0",
|
"babel-plugin-transform-react-constant-elements": "^6.23.0",
|
||||||
"babel-plugin-transform-react-inline-elements": "^6.22.0",
|
"babel-plugin-transform-react-inline-elements": "^6.22.0",
|
||||||
|
@ -29,6 +30,7 @@
|
||||||
"gulp-concat": "^2.6.1",
|
"gulp-concat": "^2.6.1",
|
||||||
"gulp-cssnano": "^2.1.2",
|
"gulp-cssnano": "^2.1.2",
|
||||||
"gulp-util": "^3.0.8",
|
"gulp-util": "^3.0.8",
|
||||||
|
"jest": "^19.0.2",
|
||||||
"style-loader": "^0.16.0",
|
"style-loader": "^0.16.0",
|
||||||
"through2": "^2.0.3",
|
"through2": "^2.0.3",
|
||||||
"webpack": "^2.4.1",
|
"webpack": "^2.4.1",
|
||||||
|
@ -52,5 +54,9 @@
|
||||||
"redux": "^3.6.0",
|
"redux": "^3.6.0",
|
||||||
"redux-thunk": "^2.2.0",
|
"redux-thunk": "^2.2.0",
|
||||||
"reselect": "^3.0.0"
|
"reselect": "^3.0.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "jest",
|
||||||
|
"test:watch": "npm test -- --watch"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,293 @@
|
||||||
|
import Immutable from 'immutable';
|
||||||
|
import reducer from '../reducers/channels';
|
||||||
|
import * as actions from '../actions';
|
||||||
|
import { connect } from '../actions/server';
|
||||||
|
|
||||||
|
describe('reducers/channels', () => {
|
||||||
|
it('removes channels on PART', () => {
|
||||||
|
let state = Immutable.fromJS({
|
||||||
|
srv1: {
|
||||||
|
chan1: {}, chan2: {}, chan3: {}
|
||||||
|
},
|
||||||
|
srv2: {
|
||||||
|
chan1: {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
state = reducer(state, {
|
||||||
|
type: actions.PART,
|
||||||
|
server: 'srv1',
|
||||||
|
channels: ['chan1', 'chan3']
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(state.toJS()).toEqual({
|
||||||
|
srv1: {
|
||||||
|
chan2: {}
|
||||||
|
},
|
||||||
|
srv2: {
|
||||||
|
chan1: {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles SOCKET_PART', () => {
|
||||||
|
let state = reducer(undefined, socket_join('srv', 'chan1', 'nick1'));
|
||||||
|
state = reducer(state, socket_join('srv', 'chan1', 'nick2'));
|
||||||
|
state = reducer(state, socket_join('srv', 'chan2', 'nick2'));
|
||||||
|
|
||||||
|
state = reducer(state, {
|
||||||
|
type: actions.SOCKET_PART,
|
||||||
|
server: 'srv',
|
||||||
|
channel: 'chan1',
|
||||||
|
user: 'nick2'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(state.toJS()).toEqual({
|
||||||
|
srv: {
|
||||||
|
chan1: {
|
||||||
|
users: [
|
||||||
|
{ mode: '', nick: 'nick1', renderName: 'nick1' },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
chan2: {
|
||||||
|
users: [
|
||||||
|
{ mode: '', nick: 'nick2', renderName: 'nick2' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles SOCKET_JOIN', () => {
|
||||||
|
const state = reducer(undefined, socket_join('srv', 'chan1', 'nick1'));
|
||||||
|
|
||||||
|
expect(state.toJS()).toEqual({
|
||||||
|
srv: {
|
||||||
|
chan1: {
|
||||||
|
users: [
|
||||||
|
{ mode: '', nick: 'nick1', renderName: 'nick1' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles SOCKET_QUIT', () => {
|
||||||
|
let state = reducer(undefined, socket_join('srv', 'chan1', 'nick1'));
|
||||||
|
state = reducer(state, socket_join('srv', 'chan1', 'nick2'));
|
||||||
|
state = reducer(state, socket_join('srv', 'chan2', 'nick2'));
|
||||||
|
|
||||||
|
state = reducer(state, {
|
||||||
|
type: actions.SOCKET_QUIT,
|
||||||
|
server: 'srv',
|
||||||
|
user: 'nick2'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(state.toJS()).toEqual({
|
||||||
|
srv: {
|
||||||
|
chan1: {
|
||||||
|
users: [
|
||||||
|
{ mode: '', nick: 'nick1', renderName: 'nick1' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
chan2: {
|
||||||
|
users: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles SOCKET_NICK', () => {
|
||||||
|
let state = reducer(undefined, socket_join('srv', 'chan1', 'nick1'));
|
||||||
|
state = reducer(state, socket_join('srv', 'chan1', 'nick2'));
|
||||||
|
state = reducer(state, socket_join('srv', 'chan2', 'nick2'));
|
||||||
|
|
||||||
|
state = reducer(state, {
|
||||||
|
type: actions.SOCKET_NICK,
|
||||||
|
server: 'srv',
|
||||||
|
old: 'nick1',
|
||||||
|
new: 'nick3'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(state.toJS()).toEqual({
|
||||||
|
srv: {
|
||||||
|
chan1: {
|
||||||
|
users: [
|
||||||
|
{ mode: '', nick: 'nick2', renderName: 'nick2' },
|
||||||
|
{ mode: '', nick: 'nick3', renderName: 'nick3' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
chan2: {
|
||||||
|
users: [
|
||||||
|
{ mode: '', nick: 'nick2', renderName: 'nick2' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles SOCKET_USERS', () => {
|
||||||
|
const state = reducer(undefined, {
|
||||||
|
type: actions.SOCKET_USERS,
|
||||||
|
server: 'srv',
|
||||||
|
channel: 'chan1',
|
||||||
|
users: [
|
||||||
|
'user3',
|
||||||
|
'user2',
|
||||||
|
'@user4',
|
||||||
|
'user1',
|
||||||
|
'+user5'
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(state.toJS()).toEqual({
|
||||||
|
srv: {
|
||||||
|
chan1: {
|
||||||
|
users: [
|
||||||
|
{ mode: 'o', nick: 'user4', renderName: '@user4' },
|
||||||
|
{ mode: 'v', nick: 'user5', renderName: '+user5' },
|
||||||
|
{ mode: '', nick: 'user1', renderName: 'user1' },
|
||||||
|
{ mode: '', nick: 'user2', renderName: 'user2' },
|
||||||
|
{ mode: '', nick: 'user3', renderName: 'user3' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles SOCKET_TOPIC', () => {
|
||||||
|
const state = reducer(undefined, {
|
||||||
|
type: actions.SOCKET_TOPIC,
|
||||||
|
server: 'srv',
|
||||||
|
channel: 'chan1',
|
||||||
|
topic: 'the topic'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(state.toJS()).toEqual({
|
||||||
|
srv: {
|
||||||
|
chan1: {
|
||||||
|
topic: 'the topic'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles SOCKET_MODE', () => {
|
||||||
|
let state = reducer(undefined, socket_join('srv', 'chan1', 'nick1'));
|
||||||
|
state = reducer(state, socket_join('srv', 'chan1', 'nick2'));
|
||||||
|
state = reducer(state, socket_join('srv', 'chan2', 'nick2'));
|
||||||
|
|
||||||
|
state = reducer(state, socket_mode('srv', 'chan1', 'nick1', 'o', ''));
|
||||||
|
|
||||||
|
expect(state.toJS()).toEqual({
|
||||||
|
srv: {
|
||||||
|
chan1: {
|
||||||
|
users: [
|
||||||
|
{ mode: 'o', nick: 'nick1', renderName: '@nick1' },
|
||||||
|
{ mode: '', nick: 'nick2', renderName: 'nick2' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
chan2: {
|
||||||
|
users: [
|
||||||
|
{ mode: '', nick: 'nick2', renderName: 'nick2' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
state = reducer(state, socket_mode('srv', 'chan1', 'nick1' ,'v', 'o'));
|
||||||
|
state = reducer(state, socket_mode('srv', 'chan1', 'nick2', 'o', ''));
|
||||||
|
state = reducer(state, socket_mode('srv', 'chan2', 'not_there', 'x', ''));
|
||||||
|
|
||||||
|
expect(state.toJS()).toEqual({
|
||||||
|
srv: {
|
||||||
|
chan1: {
|
||||||
|
users: [
|
||||||
|
{ mode: 'o', nick: 'nick2', renderName: '@nick2' },
|
||||||
|
{ mode: 'v', nick: 'nick1', renderName: '+nick1' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
chan2: {
|
||||||
|
users: [
|
||||||
|
{ mode: '', nick: 'nick2', renderName: 'nick2' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles SOCKET_CHANNELS', () => {
|
||||||
|
const state = reducer(undefined, {
|
||||||
|
type: actions.SOCKET_CHANNELS,
|
||||||
|
data: [
|
||||||
|
{ server: 'srv', name: 'chan1', topic: 'the topic' },
|
||||||
|
{ server: 'srv', name: 'chan2' },
|
||||||
|
{ server: 'srv2', name: 'chan1' }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(state.toJS()).toEqual({
|
||||||
|
srv: {
|
||||||
|
chan1: { topic: 'the topic', users: [] },
|
||||||
|
chan2: { users: [] }
|
||||||
|
},
|
||||||
|
srv2: {
|
||||||
|
chan1: { users: [] }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles SOCKET_SERVERS', () => {
|
||||||
|
const state = reducer(undefined, {
|
||||||
|
type: actions.SOCKET_SERVERS,
|
||||||
|
data: [
|
||||||
|
{ host: '127.0.0.1' },
|
||||||
|
{ host: 'thehost' }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(state.toJS()).toEqual({
|
||||||
|
'127.0.0.1': {},
|
||||||
|
thehost: {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('optimistically adds the server on CONNECT', () => {
|
||||||
|
const state = reducer(undefined, connect('127.0.0.1:1337', 'nick', {}));
|
||||||
|
|
||||||
|
expect(state.toJS()).toEqual({
|
||||||
|
'127.0.0.1': {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('removes the server on DISCONNECT', () => {
|
||||||
|
let state = Immutable.fromJS({
|
||||||
|
srv: {},
|
||||||
|
srv2: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
state = reducer(state, {
|
||||||
|
type: actions.DISCONNECT,
|
||||||
|
server: 'srv2'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(state.toJS()).toEqual({
|
||||||
|
srv: {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function socket_join(server, channel, user) {
|
||||||
|
return {
|
||||||
|
type: 'SOCKET_JOIN',
|
||||||
|
server, user,
|
||||||
|
channels: [channel]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function socket_mode(server, channel, user, add, remove) {
|
||||||
|
return {
|
||||||
|
type: 'SOCKET_MODE',
|
||||||
|
server, channel, user, add, remove
|
||||||
|
};
|
||||||
|
}
|
|
@ -107,12 +107,16 @@ export default createReducer(Map(), {
|
||||||
const { server } = action;
|
const { server } = action;
|
||||||
return state.withMutations(s => {
|
return state.withMutations(s => {
|
||||||
s.get(server).forEach((v, channel) => {
|
s.get(server).forEach((v, channel) => {
|
||||||
s.updateIn([server, channel, 'users'], users =>
|
s.updateIn([server, channel, 'users'], users => {
|
||||||
users.update(
|
const i = users.findIndex(user => user.nick === action.old);
|
||||||
users.findIndex(user => user.nick === action.old),
|
if (i < 0) {
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
|
return users.update(i,
|
||||||
user => updateRenderName(user.set('nick', action.new))
|
user => updateRenderName(user.set('nick', action.new))
|
||||||
).sort(compareUsers)
|
).sort(compareUsers);
|
||||||
);
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -131,9 +135,13 @@ export default createReducer(Map(), {
|
||||||
[actions.SOCKET_MODE](state, action) {
|
[actions.SOCKET_MODE](state, action) {
|
||||||
const { server, channel, user, remove, add } = action;
|
const { server, channel, user, remove, add } = action;
|
||||||
|
|
||||||
const i = state.getIn([server, channel, 'users']).findIndex(u => u.nick === user);
|
return state.updateIn([server, channel, 'users'], users => {
|
||||||
return state
|
const i = users.findIndex(u => u.nick === user);
|
||||||
.updateIn([server, channel, 'users', i], u => {
|
if (i < 0) {
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
|
return users.update(i, u => {
|
||||||
let mode = u.mode;
|
let mode = u.mode;
|
||||||
let j = remove.length;
|
let j = remove.length;
|
||||||
while (j--) {
|
while (j--) {
|
||||||
|
@ -141,8 +149,8 @@ export default createReducer(Map(), {
|
||||||
}
|
}
|
||||||
|
|
||||||
return updateRenderName(u.set('mode', mode + add));
|
return updateRenderName(u.set('mode', mode + add));
|
||||||
})
|
}).sort(compareUsers);
|
||||||
.updateIn([server, channel, 'users'], users => users.sort(compareUsers));
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
[actions.SOCKET_CHANNELS](state, action) {
|
[actions.SOCKET_CHANNELS](state, action) {
|
||||||
|
|
707
client/yarn.lock
707
client/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue