const VmixConnector = require('../lib/VmixConnector')
const net = require('net')
const EventEmitter = require('events')
const waitUntil = (fn) => {
return new Promise((resolve, _) => {
setInterval(() => {
if (fn() === true) {
resolve()
}
}, 100)
})
}
class MockCommunicator {
constructor(configuration, emitter) {
this.isConnected = false
this.channelCount
this.channelNames
this.programs
this.previews
}
notifyProgramChanged(programs, previews) {
this.programs = programs
this.previews = previews
}
notifyChannels(count, names) {
this.channelCount = count
this.channelNames = names
}
notifyMixerIsConnected() {
this.isConnected = true
}
notifyMixerIsDisconnected() {
this.isConnected = false
}
}
describe('VmixConnector', () => {
describe('onData', () => {
beforeEach(() => {
global.vMixServerConfig = {
version: "0.1.2.3",
tallies: "012",
xml: '{version}TrialBlankBlank11FalseFalseFalseFalseFalseFalseFalse'
}
const server = net.Server((sck) => {
sck.on('data', data => {
data = data.toString()
data.toString().replace(/[\r\n]*$/, "").split("\r\n").forEach(command => {
console.debug(`< ${command}`)
if(command === "XML") {
const response = global.vMixServerConfig.xml.replace("{version}", global.vMixServerConfig.version)
sck.write(Buffer.from(`'XML ${response.length}\r\n${response}\r\n`))
} else if(command === "SUBSCRIBE TALLY") {
sck.write(Buffer.from("SUBSCRIBE OK TALLY Subscribed\r\n", "utf-8"))
setTimeout(() => {
sck.writable && sck.write(Buffer.from(`TALLY OK ${global.vMixServerConfig.tallies}\r\n`, "utf-8"))
}, 100)
} else {
console.log(`vMix Mock received an unknown command: ${command}`)
}
})
})
sck.write(Buffer.from(`VERSION OK ${global.vMixServerConfig.version}\r\n`, "utf-8"))
})
const promise = new Promise((resolve, reject) => {
server.listen({
port: 0,
host: 'localhost',
}, (error) => {
if (error) {
console.error(error)
reject(error)
} else {
global.vMixServerConfig.serverIp = server.address().address
global.vMixServerConfig.serverPort = server.address().port
resolve()
}
})
})
global.vMixServerConfig.close = server.close.bind(server)
return promise
})
afterEach(() => {
if (global.vMixServerConfig) {
return new Promise((resolve, reject) => {
global.vMixServerConfig.close((error) => {
if (error) {
console.error(error)
reject(error)
} else {
resolve()
}
})
})
}
})
test('recognizes VERSION OK', async () => {
const communicator = new MockCommunicator()
const server = global.vMixServerConfig
const vmix = new VmixConnector(server.serverIp, server.serverPort, communicator)
try {
expect(vmix.wasHelloReceived).toBe(false)
vmix.connect()
await waitUntil(() => vmix.wasHelloReceived === true).then(() =>
expect(vmix.wasHelloReceived).toBe(true)
)
} finally {
await vmix.disconnect()
}
})
test('recognizes SUBSCRIBE OK TALLY', async () => {
const communicator = new MockCommunicator()
const server = global.vMixServerConfig
const vmix = new VmixConnector(server.serverIp, server.serverPort, communicator)
try {
expect(vmix.wasSubcribeOkReceived).toBe(false)
vmix.connect()
await waitUntil(() => vmix.wasSubcribeOkReceived === true).then(() =>
expect(vmix.wasSubcribeOkReceived).toBe(true)
)
} finally {
await vmix.disconnect()
}
})
test('parses TALLY OK command', async () => {
const communicator = new MockCommunicator()
const server = global.vMixServerConfig
server.tallies = "012"
const vmix = new VmixConnector(server.serverIp, server.serverPort, communicator)
try {
vmix.connect()
await waitUntil(() => communicator.programs !== undefined).then(() => {
expect(communicator.programs).toEqual([2])
expect(communicator.previews).toEqual([3])
})
} finally {
await vmix.disconnect()
}
})
test('parses complex TALLY OK command', async () => {
const communicator = new MockCommunicator()
const server = global.vMixServerConfig
server.tallies = "012210"
const vmix = new VmixConnector(server.serverIp, server.serverPort, communicator)
try {
vmix.connect()
await waitUntil(() => communicator.programs !== undefined).then(() => {
expect(communicator.programs).toEqual([2, 5])
expect(communicator.previews).toEqual([3, 4])
})
} finally {
await vmix.disconnect()
}
})
test('recognizes XML response', async () => {
const communicator = new MockCommunicator()
const server = global.vMixServerConfig
server.xml = '{version}TrialFoobarTolle rote FarbeColour Bars23FalseFalseFalseFalseFalseFalseFalse'
const vmix = new VmixConnector(server.serverIp, server.serverPort, communicator)
try {
vmix.connect()
await waitUntil(() => communicator.channelCount !== undefined).then(() => {
expect(communicator.channelCount).toEqual(3)
expect(communicator.channelNames).toEqual({1: "Foobar", 2: "Tolle rote Farbe", 3: "Colour Bars"})
})
} finally {
await vmix.disconnect()
}
})
})
})