mirror of
https://github.com/tenrok/vue-native-websocket.git
synced 2026-06-23 17:50:35 +03:00
+6
-2
@@ -1,4 +1,8 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
node_modules/
|
node_modules/
|
||||||
npm-debug.log
|
npm-debug.log*
|
||||||
.idea/
|
yarn-error.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
test/unit/coverage
|
||||||
|
test/e2e/reports
|
||||||
|
.idea/
|
||||||
|
|||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
dist: trusty
|
||||||
|
sudo: required
|
||||||
|
|
||||||
|
language: node_js
|
||||||
|
cache: yarn
|
||||||
|
|
||||||
|
addons:
|
||||||
|
firefox: latest
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- google-chrome
|
||||||
|
packages:
|
||||||
|
- google-chrome-stable fluxbox
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- "export DISPLAY=:99.0"
|
||||||
|
- "sh -e /etc/init.d/xvfb start"
|
||||||
|
- sleep 3
|
||||||
|
- fluxbox >/dev/null 2>&1 &
|
||||||
+22
-3
@@ -5,7 +5,9 @@
|
|||||||
"main": "dist/build.js",
|
"main": "dist/build.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "eslint --ext .js src && webpack --progress --hide-modules",
|
"build": "eslint --ext .js src && webpack --progress --hide-modules",
|
||||||
"lint": "eslint --ext .js src"
|
"lint": "eslint --ext .js src",
|
||||||
|
"unit": "karma start test/unit/karma.conf.js",
|
||||||
|
"test": "karma start test/unit/karma.conf.js --single-run "
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -32,12 +34,29 @@
|
|||||||
"babel-eslint": "^7.2.3",
|
"babel-eslint": "^7.2.3",
|
||||||
"babel-loader": "^7.0.0",
|
"babel-loader": "^7.0.0",
|
||||||
"babel-preset-es2015": "^6.24.1",
|
"babel-preset-es2015": "^6.24.1",
|
||||||
|
"chai": "^4.0.2",
|
||||||
"eslint": "^3.19.0",
|
"eslint": "^3.19.0",
|
||||||
"eslint-config-standard": "^10.2.1",
|
"eslint-config-standard": "^10.2.1",
|
||||||
"eslint-plugin-import": "^2.2.0",
|
"eslint-plugin-import": "^2.2.0",
|
||||||
"eslint-plugin-node": "^4.2.2",
|
"eslint-plugin-node": "^4.2.2",
|
||||||
"eslint-plugin-promise": "^3.5.0",
|
"eslint-plugin-promise": "^3.5.0",
|
||||||
"eslint-plugin-standard": "^3.0.1",
|
"eslint-plugin-standard": "^3.0.1",
|
||||||
"webpack": "^2.5.1"
|
"exports-loader": "^0.6.4",
|
||||||
}
|
"karma": "^1.7.0",
|
||||||
|
"karma-chrome-launcher": "^2.2.0",
|
||||||
|
"karma-coverage": "^1.1.1",
|
||||||
|
"karma-mocha": "^1.3.0",
|
||||||
|
"karma-sinon-chai": "^1.3.1",
|
||||||
|
"karma-sourcemap-loader": "^0.3.7",
|
||||||
|
"karma-spec-reporter": "^0.0.31",
|
||||||
|
"karma-webpack": "^2.0.3",
|
||||||
|
"mocha": "^3.4.2",
|
||||||
|
"mock-socket": "^6.1.0",
|
||||||
|
"script-loader": "^0.7.0",
|
||||||
|
"sinon": "^2.3.6",
|
||||||
|
"sinon-chai": "^2.11.0",
|
||||||
|
"vue": "^2.3.4",
|
||||||
|
"webpack": "^3.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-12
@@ -3,13 +3,13 @@ import Emitter from './Emitter'
|
|||||||
export default class {
|
export default class {
|
||||||
constructor (connectionUrl, protocol, store, opts = {}) {
|
constructor (connectionUrl, protocol, store, opts = {}) {
|
||||||
this.format = opts.format && opts.format.toLowerCase()
|
this.format = opts.format && opts.format.toLowerCase()
|
||||||
this.connect(connectionUrl, protocol)
|
this.connect(connectionUrl, protocol, opts)
|
||||||
if (store) { this.store = store }
|
if (store) { this.store = store }
|
||||||
this.onEvent()
|
this.onEvent()
|
||||||
}
|
}
|
||||||
|
|
||||||
connect (connectionUrl, protocol) {
|
connect (connectionUrl, protocol, opts = {}) {
|
||||||
this.WebSocket = new WebSocket(connectionUrl, protocol)
|
this.WebSocket = opts.WebSocket || new WebSocket(connectionUrl, protocol)
|
||||||
if (this.format === 'json') {
|
if (this.format === 'json') {
|
||||||
if (!('sendObj' in this.WebSocket)) {
|
if (!('sendObj' in this.WebSocket)) {
|
||||||
this.WebSocket.sendObj = (obj) => this.WebSocket.send(JSON.stringify(obj))
|
this.WebSocket.sendObj = (obj) => this.WebSocket.send(JSON.stringify(obj))
|
||||||
@@ -28,18 +28,16 @@ export default class {
|
|||||||
|
|
||||||
passToStore (eventName, event) {
|
passToStore (eventName, event) {
|
||||||
if (!eventName.startsWith('SOCKET_')) { return }
|
if (!eventName.startsWith('SOCKET_')) { return }
|
||||||
|
let method = 'commit'
|
||||||
|
let target = eventName.toUpperCase()
|
||||||
|
let msg = event
|
||||||
if (this.format === 'json' && event.data) {
|
if (this.format === 'json' && event.data) {
|
||||||
let msg = JSON.parse(event.data)
|
msg = JSON.parse(event.data)
|
||||||
let target = msg.namespace || ''
|
target = [msg.namespace || '', msg.mutation].filter((e) => !!e).join('/')
|
||||||
if (msg.mutation) {
|
|
||||||
this.store.commit([target, msg.mutation].join('/'), msg)
|
|
||||||
}
|
|
||||||
if (msg.action) {
|
if (msg.action) {
|
||||||
this.store.dispatch([target, msg.action].join('/'), msg)
|
method = 'dispatch'
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// default mutation
|
|
||||||
this.store.commit(eventName.toUpperCase(), event)
|
|
||||||
}
|
}
|
||||||
|
this.store[method](target, msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
Vue.config.productionTip = false
|
||||||
|
|
||||||
|
// require all test files (files that ends with .spec.js)
|
||||||
|
const testsContext = require.context('./specs', true, /\.spec$/)
|
||||||
|
testsContext.keys().forEach(testsContext)
|
||||||
|
|
||||||
|
// require all src files except main.js for coverage.
|
||||||
|
// you can also change this to match only the subset of files that
|
||||||
|
// you want coverage for.
|
||||||
|
const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/)
|
||||||
|
srcContext.keys().forEach(srcContext)
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
var webpackConfig = require('../../webpack.config.js')
|
||||||
|
|
||||||
|
module.exports = function (config) {
|
||||||
|
configuration = {
|
||||||
|
browsers: [
|
||||||
|
//'Chrome'
|
||||||
|
'ChromeHeadless'
|
||||||
|
],
|
||||||
|
frameworks: [
|
||||||
|
'mocha',
|
||||||
|
'sinon-chai'
|
||||||
|
],
|
||||||
|
reporters: ['spec', 'coverage'],
|
||||||
|
files: ['./index.js'],
|
||||||
|
preprocessors: {
|
||||||
|
'./index.js': ['webpack', 'sourcemap']
|
||||||
|
},
|
||||||
|
webpack: webpackConfig,
|
||||||
|
webpackMiddleware: {
|
||||||
|
noInfo: true
|
||||||
|
},
|
||||||
|
coverageReporter: {
|
||||||
|
dir: './coverage',
|
||||||
|
reporters: [
|
||||||
|
{ type: 'lcov', subdir: '.' },
|
||||||
|
{ type: 'text-summary' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
customLaunchers: {
|
||||||
|
ChromeHeadless: {
|
||||||
|
base: 'Chrome',
|
||||||
|
flags: [
|
||||||
|
'--headless',
|
||||||
|
'--disable-gpu',
|
||||||
|
// Without a remote debugging port, Google Chrome exits immediately.
|
||||||
|
'--remote-debugging-port=9222',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config.set(configuration)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
// bring in the Emitter class, not the singleton
|
||||||
|
let EmitterClass = require('exports-loader?Emitter!@/Emitter')
|
||||||
|
|
||||||
|
describe ("Emitter.js", () => {
|
||||||
|
|
||||||
|
let vm = new Vue()
|
||||||
|
let Emitter
|
||||||
|
|
||||||
|
beforeEach (() => {
|
||||||
|
Emitter = new EmitterClass()
|
||||||
|
})
|
||||||
|
|
||||||
|
it ('registers an handler', () => {
|
||||||
|
expect(Emitter.listeners.size).to.equal(0)
|
||||||
|
Emitter.addListener('[event_type]', (value) => {}, vm)
|
||||||
|
expect(Emitter.listeners.size).to.equal(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it ('unregisters a registered handler', () => {
|
||||||
|
let event_type = 'atype', cb = (value) => {}
|
||||||
|
should.not.exist(Emitter.listeners.get(event_type))
|
||||||
|
Emitter.addListener(event_type, cb, vm)
|
||||||
|
expect(Emitter.listeners.get(event_type).length).to.equal(1)
|
||||||
|
Emitter.removeListener(event_type, cb, vm)
|
||||||
|
expect(Emitter.listeners.get(event_type).length).to.equal(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
it ('fires an events', (done) => {
|
||||||
|
let event_type = 'syn', expected_response = 'ack'
|
||||||
|
expect(Emitter.listeners.size).to.equal(0)
|
||||||
|
Emitter.addListener(event_type, (value) => {
|
||||||
|
expect(value).to.equal(expected_response)
|
||||||
|
done()
|
||||||
|
}, vm)
|
||||||
|
expect(Emitter.listeners.size).to.equal(1)
|
||||||
|
Emitter.emit(event_type, expected_response)
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import VueNativeSock from '@/Main'
|
||||||
|
|
||||||
|
import { Server } from 'mock-socket'
|
||||||
|
|
||||||
|
describe("Main.js", () =>{
|
||||||
|
|
||||||
|
let mockServer
|
||||||
|
|
||||||
|
it ('can be bound to the onopen event', (done) => {
|
||||||
|
mockServer = new Server('ws://localhost:8080')
|
||||||
|
Vue.use(VueNativeSock, 'ws://localhost:8080', null)
|
||||||
|
let vm = new Vue()
|
||||||
|
vm.$options.sockets.onopen = (data) => {
|
||||||
|
expect(data.type).to.equal('open')
|
||||||
|
mockServer.stop(done)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import Emitter from '@/Emitter'
|
||||||
|
import Observer from '@/Observer'
|
||||||
|
|
||||||
|
import { Server, WebSocket } from 'mock-socket'
|
||||||
|
|
||||||
|
describe ("Observer.js", () => {
|
||||||
|
let observer, mockServer
|
||||||
|
|
||||||
|
let wsUrl = 'ws://localhost:8080'
|
||||||
|
|
||||||
|
it ('fires onopen event', (done) => {
|
||||||
|
mockServer = new Server(wsUrl)
|
||||||
|
mockServer.on('connection', ws => {
|
||||||
|
ws.send('hi')
|
||||||
|
})
|
||||||
|
Vue.use(VueNativeSock, wsUrl)
|
||||||
|
let vm = new Vue()
|
||||||
|
observer = new Observer(wsUrl)
|
||||||
|
Emitter.addListener('onopen', (data) => {
|
||||||
|
expect(data.type).to.equal('open')
|
||||||
|
mockServer.stop(done)
|
||||||
|
}, vm)
|
||||||
|
})
|
||||||
|
|
||||||
|
// TODO: DRY
|
||||||
|
it ('passes a json event to the provided vuex store', (done) => {
|
||||||
|
let expectedMsg = { mutation: 'setName', value: 'steve' }
|
||||||
|
let mockStore = sinon.mock({ commit: () => {} })
|
||||||
|
mockStore.expects('commit').withArgs('SOCKET_ONOPEN')
|
||||||
|
mockStore.expects('commit').withArgs(expectedMsg.mutation)
|
||||||
|
|
||||||
|
mockServer = new Server(wsUrl)
|
||||||
|
mockServer.on('connection', ws => {
|
||||||
|
ws.send(JSON.stringify(expectedMsg))
|
||||||
|
})
|
||||||
|
|
||||||
|
Vue.use(VueNativeSock, wsUrl)
|
||||||
|
let vm = new Vue()
|
||||||
|
observer = new Observer(wsUrl, null, mockStore.object, {
|
||||||
|
format: 'json',
|
||||||
|
websocket: new WebSocket(wsUrl)
|
||||||
|
})
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
mockStore.verify()
|
||||||
|
mockServer.stop(done)
|
||||||
|
}, 100)
|
||||||
|
})
|
||||||
|
|
||||||
|
// TODO: DRY
|
||||||
|
it ('passes a namespaced json event to the provided vuex store', (done) => {
|
||||||
|
let expectedMsg = { namespace: 'users', mutation: 'setName', value: 'steve' }
|
||||||
|
let mockStore = sinon.mock({ commit: () => {} })
|
||||||
|
mockStore.expects('commit').withArgs('SOCKET_ONOPEN')
|
||||||
|
mockStore.expects('commit').withArgs(expectedMsg.namespace + '/' + expectedMsg.mutation)
|
||||||
|
|
||||||
|
mockServer = new Server(wsUrl)
|
||||||
|
mockServer.on('connection', ws => {
|
||||||
|
ws.send(JSON.stringify(expectedMsg))
|
||||||
|
})
|
||||||
|
|
||||||
|
Vue.use(VueNativeSock, wsUrl)
|
||||||
|
let vm = new Vue()
|
||||||
|
observer = new Observer(wsUrl, null, mockStore.object, {
|
||||||
|
format: 'json',
|
||||||
|
websocket: new WebSocket(wsUrl)
|
||||||
|
})
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
mockStore.verify()
|
||||||
|
mockServer.stop(done)
|
||||||
|
}, 100)
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
+8
-2
@@ -1,5 +1,6 @@
|
|||||||
var path = require('path');
|
var path = require('path')
|
||||||
var webpack = require('webpack');
|
var webpack = require('webpack')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
entry: ['./src/Main.js'],
|
entry: ['./src/Main.js'],
|
||||||
output: {
|
output: {
|
||||||
@@ -16,6 +17,11 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': path.resolve(__dirname, './src'),
|
||||||
|
}
|
||||||
|
},
|
||||||
module: {
|
module: {
|
||||||
loaders: [
|
loaders: [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user