etcher/tests/shared/robot.spec.js
Juan Cruz Viotti d8e31665a0 chore: follow standardjs guidelines (#1664)
- Extend the `standard` ESLint configuration
- Remove ESLint rules that are defined in the `standard` configuration
- Get rid of semi-colons

See: https://github.com/resin-io/etcher/pull/1657
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
2017-08-03 09:01:54 -04:00

349 lines
11 KiB
JavaScript

/*
* Copyright 2016 resin.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict'
const m = require('mochainon')
const _ = require('lodash')
const robot = require('../../lib/shared/robot')
describe('Shared: Robot', function () {
describe('.COMMAND', function () {
it('should be a plain object', function () {
m.chai.expect(_.isPlainObject(robot.COMMAND)).to.be.true
})
it('should only contain string values', function () {
m.chai.expect(_.every(_.values(robot.COMMAND), _.isString)).to.be.true
})
it('should contain only unique values', function () {
const numberOfKeys = _.size(_.keys(robot.COMMAND))
m.chai.expect(_.size(_.uniq(_.values(robot.COMMAND)))).to.equal(numberOfKeys)
})
})
describe('.isEnabled()', function () {
it('should return false if ETCHER_CLI_ROBOT is not set', function () {
m.chai.expect(robot.isEnabled({})).to.be.false
})
it('should return true if ETCHER_CLI_ROBOT=1', function () {
m.chai.expect(robot.isEnabled({
ETCHER_CLI_ROBOT: 1
})).to.be.true
})
it('should return false if ETCHER_CLI_ROBOT=0', function () {
m.chai.expect(robot.isEnabled({
ETCHER_CLI_ROBOT: 0
})).to.be.false
})
it('should return true if ETCHER_CLI_ROBOT="true"', function () {
m.chai.expect(robot.isEnabled({
ETCHER_CLI_ROBOT: 'true'
})).to.be.true
})
it('should return false if ETCHER_CLI_ROBOT="false"', function () {
m.chai.expect(robot.isEnabled({
ETCHER_CLI_ROBOT: 'false'
})).to.be.false
})
it('should return true if ETCHER_CLI_ROBOT=true', function () {
m.chai.expect(robot.isEnabled({
ETCHER_CLI_ROBOT: true
})).to.be.true
})
it('should return false if ETCHER_CLI_ROBOT=false', function () {
m.chai.expect(robot.isEnabled({
ETCHER_CLI_ROBOT: false
})).to.be.false
})
})
describe('.buildMessage()', function () {
it('should build a message without data', function () {
const message = robot.buildMessage('hello')
const result = '{"command":"hello","data":{}}'
m.chai.expect(message).to.equal(result)
})
it('should build a message with data', function () {
const message = robot.buildMessage('hello', {
foo: 1,
bar: 2
})
const result = '{"command":"hello","data":{"foo":1,"bar":2}}'
m.chai.expect(message).to.equal(result)
})
it('should throw if data is defined but it not an object', function () {
m.chai.expect(() => {
robot.buildMessage('hello', 'world')
}).to.throw('Invalid data: world')
})
})
describe('.isMessage()', function () {
it('should return true if message is an empty object', function () {
m.chai.expect(robot.isMessage('{}')).to.be.true
})
it('should return true if message is an object', function () {
m.chai.expect(robot.isMessage('{"command":"foo"}')).to.be.true
})
it('should return false if message is an invalid object', function () {
m.chai.expect(robot.isMessage('{"command":\\foo"}')).to.be.false
})
it('should return false if message is an unquoted string', function () {
m.chai.expect(robot.isMessage('foo')).to.be.false
})
it('should return false if message is an quoted string', function () {
m.chai.expect(robot.isMessage('"foo"')).to.be.false
})
it('should return false if message is an empty string', function () {
m.chai.expect(robot.isMessage('')).to.be.false
})
it('should return false if message is undefined', function () {
m.chai.expect(robot.isMessage(undefined)).to.be.false
})
it('should return false if message is null', function () {
m.chai.expect(robot.isMessage(null)).to.be.false
})
it('should return false if message is a positive integer string', function () {
m.chai.expect(robot.isMessage('5')).to.be.false
})
it('should return false if message is a negative integer string', function () {
m.chai.expect(robot.isMessage('-3')).to.be.false
})
it('should return false if message is a zero string', function () {
m.chai.expect(robot.isMessage('0')).to.be.false
})
it('should return false if message is a positive float string', function () {
m.chai.expect(robot.isMessage('5.3')).to.be.false
})
it('should return false if message is a negative float string', function () {
m.chai.expect(robot.isMessage('-2.1')).to.be.false
})
it('should return false if message is a positive integer', function () {
m.chai.expect(robot.isMessage(5)).to.be.false
})
it('should return false if message is a negative integer', function () {
m.chai.expect(robot.isMessage(-3)).to.be.false
})
it('should return false if message is zero', function () {
m.chai.expect(robot.isMessage(0)).to.be.false
})
it('should return false if message is a positive float', function () {
m.chai.expect(robot.isMessage(5.3)).to.be.false
})
it('should return false if message is a negative float', function () {
m.chai.expect(robot.isMessage(-2.1)).to.be.false
})
it('should return false if message is an array', function () {
m.chai.expect(robot.isMessage([ 'foo' ])).to.be.false
})
it('should return false if message is an array string', function () {
m.chai.expect(robot.isMessage('["foo"]')).to.be.false
})
it('should return true for a message built with .buildMessage()', function () {
m.chai.expect(robot.isMessage(robot.buildMessage('foo', {
message: 'bar'
}))).to.be.true
})
it('should return true for a message built with .buildErrorMessage()', function () {
const error = new Error('foo')
m.chai.expect(robot.isMessage(robot.buildErrorMessage(error))).to.be.true
})
})
describe('.buildErrorMessage()', function () {
it('should build a message from a simple error', function () {
const error = new Error('foo')
const message = robot.buildErrorMessage(error)
m.chai.expect(JSON.parse(message)).to.deep.equal({
command: robot.COMMAND.ERROR,
data: {
message: 'foo',
stack: error.stack
}
})
})
it('should save the error description', function () {
const error = new Error('foo')
error.description = 'error description'
const message = robot.buildErrorMessage(error)
m.chai.expect(JSON.parse(message)).to.deep.equal({
command: robot.COMMAND.ERROR,
data: {
message: 'foo',
description: 'error description',
stack: error.stack
}
})
})
it('should save the error code', function () {
const error = new Error('foo')
error.code = 'MYERROR'
const message = robot.buildErrorMessage(error)
m.chai.expect(JSON.parse(message)).to.deep.equal({
command: robot.COMMAND.ERROR,
data: {
message: 'foo',
code: 'MYERROR',
stack: error.stack
}
})
})
it('should handle a string error', function () {
const message = JSON.parse(robot.buildErrorMessage('foo'))
m.chai.expect(message.data.message).to.equal('foo')
m.chai.expect(message.data.stack).to.be.a.string
m.chai.expect(_.isEmpty(message.data.stack)).to.be.false
})
})
describe('.parseMessage()', function () {
it('should parse a valid message', function () {
const message = robot.buildMessage('foo', {
bar: 1
})
m.chai.expect(robot.parseMessage(message)).to.deep.equal({
command: 'foo',
data: {
bar: 1
}
})
})
it('should parse a valid without data', function () {
const message = robot.buildMessage('foo')
m.chai.expect(robot.parseMessage(message)).to.deep.equal({
command: 'foo',
data: {}
})
})
it('should throw if input is not valid JSON', function () {
m.chai.expect(() => {
robot.parseMessage('Hello world\nFoo Bar')
}).to.throw('Invalid message')
})
it('should throw if input has no command', function () {
m.chai.expect(() => {
robot.parseMessage('{"data":{"foo":"bar"}}')
}).to.throw('Invalid message')
})
it('should throw if input has no data', function () {
m.chai.expect(() => {
robot.parseMessage('{"command":"foo"}')
}).to.throw('Invalid message')
})
})
describe('.getCommand()', function () {
it('should get the command of a message', function () {
const message = robot.parseMessage(robot.buildMessage('hello', {
foo: 1,
bar: 2
}))
m.chai.expect(robot.getCommand(message)).to.equal('hello')
})
})
describe('.getData()', function () {
it('should get the data of a message', function () {
const message = robot.parseMessage(robot.buildMessage('hello', {
foo: 1,
bar: 2
}))
m.chai.expect(robot.getData(message)).to.deep.equal({
foo: 1,
bar: 2
})
})
it('should return an empty object if the message has no data', function () {
m.chai.expect(robot.getData({
command: 'foo'
})).to.deep.equal({})
})
})
describe('.recomposeErrorMessage()', function () {
it('should return an instance of Error', function () {
const error = new Error('Foo bar')
const message = robot.parseMessage(robot.buildErrorMessage(error))
m.chai.expect(robot.recomposeErrorMessage(message)).to.be.an.instanceof(Error)
})
it('should be able to recompose an error object', function () {
const error = new Error('Foo bar')
const message = robot.parseMessage(robot.buildErrorMessage(error))
m.chai.expect(robot.recomposeErrorMessage(message)).to.deep.equal(error)
})
it('should be able to recompose an error object with a code', function () {
const error = new Error('Foo bar')
error.code = 'FOO'
const message = robot.parseMessage(robot.buildErrorMessage(error))
m.chai.expect(robot.recomposeErrorMessage(message)).to.deep.equal(error)
})
it('should be able to recompose an error object with a description', function () {
const error = new Error('Foo bar')
error.description = 'My description'
const message = robot.parseMessage(robot.buildErrorMessage(error))
m.chai.expect(robot.recomposeErrorMessage(message)).to.deep.equal(error)
})
})
})