Skip to content

Commit 64cc61b

Browse files
Merge pull request #13 from richardeschloss/development
Achieved 100% coverage
2 parents 6eb7d29 + c8a8194 commit 64cc61b

File tree

6 files changed

+240
-73
lines changed

6 files changed

+240
-73
lines changed

.nycrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"all": false,
3+
"reporter": ["html", "text"],
34
"exclude": ["node_modules"],
45
"include": ["io"],
56
"extension": [".js"]

io/plugin.js

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,44 @@
55
import io from 'socket.io-client'
66
import consola from 'consola'
77

8+
function PluginOptions() {
9+
let _pluginOptions
10+
return Object.freeze({
11+
get() {
12+
if (!process.env.TEST) {
13+
return <%= JSON.stringify(options) %>
14+
}
15+
return _pluginOptions
16+
},
17+
set(opts) {
18+
_pluginOptions = opts
19+
}
20+
})
21+
}
22+
23+
export const pOptions = PluginOptions()
24+
825
function nuxtSocket(ioOpts) {
926
const { name, channel = '', ...connectOpts } = ioOpts
10-
const pluginOptions = <%= JSON.stringify(options) %>
27+
const pluginOptions = pOptions.get()
1128
const { sockets } = pluginOptions
1229
const { $store: store } = this
1330

14-
if (!sockets || sockets.length === 0) {
31+
if (
32+
!sockets ||
33+
sockets.constructor.name !== 'Array' ||
34+
sockets.length === 0
35+
) {
1536
throw new Error(
1637
"Please configure sockets if planning to use nuxt-socket-io: \r\n [{name: '', url: ''}]"
1738
)
1839
}
1940

2041
let useSocket = null
21-
if (sockets && sockets.length && sockets.length > 0) {
22-
if (!name) {
23-
useSocket = sockets.find((s) => s.default === true)
24-
} else {
25-
useSocket = sockets.find((s) => s.name === name)
26-
}
42+
if (!name) {
43+
useSocket = sockets.find((s) => s.default === true)
44+
} else {
45+
useSocket = sockets.find((s) => s.name === name)
2746
}
2847

2948
if (!useSocket) {
@@ -54,7 +73,7 @@ function nuxtSocket(ioOpts) {
5473
if (typeof item === 'string') {
5574
evt = mappedItem = item
5675
} else {
57-
[[evt, mappedItem]] = Object.entries(item)
76+
;[[evt, mappedItem]] = Object.entries(item)
5877
}
5978

6079
socket.on(evt, (data) => {
@@ -72,26 +91,32 @@ function nuxtSocket(ioOpts) {
7291
if (typeof emitBack === 'string') {
7392
evt = stateProps = emitBack
7493
} else {
75-
[[stateProps, evt]] = Object.entries(emitBack)
94+
;[[stateProps, evt]] = Object.entries(emitBack)
7695
}
7796
stateProps = stateProps.split('/')
78-
this.$store.watch((state) => {
79-
const out = Object.assign({}, state)
80-
const watchProp = stateProps.reduce((outProp, prop) => {
81-
outProp = outProp[prop]
82-
return outProp
83-
}, out)
84-
85-
if (typeof watchProp === 'object'
86-
&& Object.prototype.hasOwnProperty.call(watchProp, '__ob__')) {
87-
const errMsg = emitBack + 'is a vuex module. You probably want to watch its properties'
88-
throw Error(errMsg)
97+
this.$store.watch(
98+
(state) => {
99+
const out = Object.assign({}, state)
100+
const watchProp = stateProps.reduce((outProp, prop) => {
101+
outProp = outProp[prop]
102+
return outProp
103+
}, out)
104+
105+
if (
106+
typeof watchProp === 'object' &&
107+
Object.prototype.hasOwnProperty.call(watchProp, '__ob__')
108+
) {
109+
const errMsg =
110+
emitBack +
111+
' is a vuex module. You probably want to watch its properties'
112+
throw new Error(errMsg)
89113
}
90-
return watchProp
91-
}, (data) => {
92-
console.log('val changed', data, evt)
93-
socket.emit(evt, { data })
94-
})
114+
return watchProp
115+
},
116+
(data) => {
117+
socket.emit(evt, { data })
118+
}
119+
)
95120
})
96121
}
97122
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nuxt-socket-io",
3-
"version": "1.0.2",
3+
"version": "1.0.3",
44
"description": "Socket.io module for Nuxt. Just plug it in and GO",
55
"author": "Richard Schloss",
66
"main": "io/module.js",

server/io.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const consola = require('consola')
44
const socketIO = require('socket.io')
55

66
function IOServer({ host, port, server = http.createServer() }) {
7+
let _io
78
function registerIO(io) {
89
const ioChannels = fs
910
.readdirSync('./server/channels')
@@ -41,14 +42,19 @@ function IOServer({ host, port, server = http.createServer() }) {
4142
consola.info('IO server not listening...will fix that...')
4243
await listen()
4344
}
44-
const io = socketIO(server)
45-
registerIO(io)
46-
return io
45+
_io = socketIO(server)
46+
registerIO(_io)
47+
return _io
48+
}
49+
50+
function stop() {
51+
return new Promise((resolve) => _io.close(resolve))
4752
}
4853

4954
return Object.freeze({
5055
registerIO,
51-
start
56+
start,
57+
stop
5258
})
5359
}
5460

test/specs/Plugin.spec.js

Lines changed: 174 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,193 @@
11
import fs from 'fs'
22
import path from 'path'
33
import consola from 'consola'
4-
import { serial as test } from 'ava'
4+
import { serial as test, before, after } from 'ava'
55
import config from '@/nuxt.config'
66
import { state as indexState } from '@/store/index'
77
import { state as examplesState } from '@/store/examples'
8-
import { compilePlugin, removeCompiledPlugin } from '@/test/utils'
8+
import { compilePlugin, ioServerInit, removeCompiledPlugin } from '@/test/utils'
99

1010
const { io } = config
1111
const state = indexState()
1212
state.examples = examplesState()
13+
state.examples.__ob__ = ''
14+
const src = path.resolve('./io/plugin.js')
15+
const tmpFile = path.resolve('./io/plugin.compiled.js')
1316

14-
test.only('Socket plugin', async (t) => {
15-
consola.log('testing with plugin options', io)
16-
const src = path.resolve('./io/plugin.js')
17-
const tmpFile = path.resolve('./io/plugin.compiled.js')
18-
const Plugin = await compilePlugin({ src, tmpFile, options: io }).catch(
17+
function loadPlugin(t, ioOpts = {}) {
18+
return new Promise((resolve, reject) => {
19+
const context = {}
20+
Plugin(context, (label, NuxtSocket) => {
21+
const testObj = {
22+
$store: {
23+
commit: (msg) => {
24+
consola.log('commit', msg)
25+
},
26+
dispatch: (msg) => {
27+
consola.log('dispatch', msg)
28+
},
29+
watch: (stateCb, dataCb) => {
30+
stateCb(state)
31+
dataCb({ sample: 123 })
32+
}
33+
},
34+
testSocket: NuxtSocket
35+
}
36+
37+
try {
38+
const socket = testObj.testSocket(ioOpts)
39+
t.is(label, 'nuxtSocket')
40+
t.is(typeof NuxtSocket, 'function')
41+
t.is(NuxtSocket.name, 'nuxtSocket')
42+
t.is(socket.constructor.name, 'Socket')
43+
resolve(socket)
44+
} catch (e) {
45+
reject(e)
46+
}
47+
})
48+
})
49+
}
50+
51+
let Plugin, pOptions
52+
53+
before('Compile Plugin', async (t) => {
54+
const compiled = await compilePlugin({ src, tmpFile, options: io }).catch(
1955
(err) => {
2056
consola.error(err)
2157
t.fail()
2258
}
2359
)
24-
const context = {}
25-
Plugin(context, (label, NuxtSocket) => {
26-
const testObj = {
27-
$store: {
28-
commit: (msg) => {
29-
consola.log('commit', msg)
30-
},
31-
dispatch: (msg) => {
32-
consola.log('dispatch', msg)
33-
},
34-
watch: (stateCb, dataCb) => {
35-
stateCb(state)
36-
dataCb({ sample: 123 })
60+
Plugin = compiled.Plugin
61+
pOptions = compiled.pOptions
62+
t.pass()
63+
})
64+
65+
before('Init IO Server', ioServerInit)
66+
67+
after('Remove compiled plugin', () => {
68+
removeCompiledPlugin(tmpFile)
69+
})
70+
71+
test('Socket plugin (empty options)', async (t) => {
72+
const testCfg = { sockets: [] }
73+
pOptions.set(testCfg)
74+
await loadPlugin(t).catch((e) => {
75+
t.is(
76+
e.message,
77+
"Please configure sockets if planning to use nuxt-socket-io: \r\n [{name: '', url: ''}]"
78+
)
79+
})
80+
})
81+
82+
test('Socket plugin (malformed sockets)', async (t) => {
83+
const testCfg = { sockets: {} }
84+
pOptions.set(testCfg)
85+
await loadPlugin(t).catch((e) => {
86+
t.is(
87+
e.message,
88+
"Please configure sockets if planning to use nuxt-socket-io: \r\n [{name: '', url: ''}]"
89+
)
90+
})
91+
})
92+
93+
test('Socket plugin (options missing info)', async (t) => {
94+
const testCfg = { sockets: [{}] }
95+
pOptions.set(testCfg)
96+
await loadPlugin(t).catch((e) => {
97+
t.is(e.message, 'URL must be defined for nuxtSocket')
98+
})
99+
})
100+
101+
test('Socket plugin (no vuex options)', async (t) => {
102+
const testCfg = {
103+
sockets: [
104+
{
105+
name: 'home',
106+
default: true,
107+
url: 'http://localhost:3000'
108+
}
109+
]
110+
}
111+
pOptions.set(testCfg)
112+
await loadPlugin(t, { name: 'home' })
113+
})
114+
115+
test('Socket plugin (malformed vuex options)', async (t) => {
116+
const testCfg = {
117+
sockets: [
118+
{
119+
default: true,
120+
url: 'http://localhost:3000',
121+
vuex: {
122+
actions: {},
123+
mutations: {},
124+
emitBacks: {}
37125
}
38-
},
39-
testSocket: NuxtSocket
40-
}
41-
try {
42-
const socket = testObj.testSocket({})
43-
t.is(label, 'nuxtSocket')
44-
t.is(typeof NuxtSocket, 'function')
45-
t.is(NuxtSocket.name, 'nuxtSocket')
46-
t.is(socket.constructor.name, 'Socket')
47-
} catch (e) {
48-
consola.error(
49-
'Plugin error:',
50-
e,
51-
'\r\n\r\n(were mocks set up correctly?)'
52-
)
53-
t.fail()
54-
}
126+
}
127+
]
128+
}
129+
pOptions.set(testCfg)
130+
await loadPlugin(t)
131+
})
132+
133+
test('Socket plugin (vuex opts as strings)', async (t) => {
134+
const testCfg = {
135+
sockets: [
136+
{
137+
default: true,
138+
url: 'http://localhost:3000',
139+
vuex: {
140+
actions: ['someAction'],
141+
mutations: ['someMutation']
142+
}
143+
}
144+
]
145+
}
146+
pOptions.set(testCfg)
147+
await loadPlugin(t)
148+
})
149+
150+
test('Socket plugin (malformed emitBacks)', async (t) => {
151+
const emitBack = 'examples'
152+
const testCfg = {
153+
sockets: [
154+
{
155+
default: true,
156+
url: 'http://localhost:3000',
157+
vuex: {
158+
actions: [],
159+
mutations: [],
160+
emitBacks: [emitBack]
161+
}
162+
}
163+
]
164+
}
165+
pOptions.set(testCfg)
166+
await loadPlugin(t).catch((e) => {
167+
t.is(
168+
e.message,
169+
emitBack + ' is a vuex module. You probably want to watch its properties'
170+
)
171+
})
172+
})
173+
174+
test('Socket plugin (from nuxt.config)', async (t) => {
175+
delete process.env.TEST
176+
const { ioServer } = t.context
177+
const testSocket = await loadPlugin(t, {
178+
name: 'test',
179+
channel: '/index'
180+
})
181+
const testJSON = { msg: 'it worked!' }
182+
const expected = 'It worked! Received msg: ' + JSON.stringify(testJSON)
183+
return new Promise((resolve) => {
184+
testSocket
185+
.emit('getMessage', testJSON, async (actual) => {
186+
t.is(expected, actual)
187+
await ioServer.stop()
188+
})
189+
.on('disconnect', () => {
190+
resolve()
191+
})
55192
})
56-
removeCompiledPlugin(tmpFile)
57193
})

0 commit comments

Comments
 (0)