refactor: adhere mostly to StandardJS guidelines (#1657)

This commit changes the whole codebase to adhere to all StandardJS
guidelines rules except semicolons, since the removal of semicolons
affect pretty much all lines, and the final diff is very hard to follow
(and to assess other more involved changes).

In a nutshell:

- When using `function`, we now require a space before the opening
  parenthesis
- If a line with operators is broken into multiple lines, the operator
  should now go after the line break
- Unnecessary padding lines are now forbidden

There were also some minor things that the `standard` CLI caught that I
updated here.

See: https://standardjs.com
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
This commit is contained in:
Juan Cruz Viotti 2017-08-03 06:59:02 -04:00 committed by GitHub
parent 064c741e3f
commit 5c19b70e83
91 changed files with 1339 additions and 1956 deletions

View File

@ -461,10 +461,10 @@ rules:
- always - always
operator-linebreak: operator-linebreak:
- error - error
- before - after
padded-blocks: padded-blocks:
- error - error
- classes: always - never
quote-props: quote-props:
- error - error
- as-needed - as-needed
@ -489,7 +489,9 @@ rules:
- error - error
space-before-function-paren: space-before-function-paren:
- error - error
- never - anonymous: always
named: always
asyncArrow: never
space-in-parens: space-in-parens:
- error - error
- never - never

View File

@ -86,7 +86,6 @@ exports.write = (image, drive, options) => {
* terminateServer(); * terminateServer();
*/ */
const terminateServer = () => { const terminateServer = () => {
// Turns out we need to destroy all sockets for // Turns out we need to destroy all sockets for
// the server to actually close. Otherwise, it // the server to actually close. Otherwise, it
// just stops receiving any further connections, // just stops receiving any further connections,
@ -137,7 +136,6 @@ exports.write = (image, drive, options) => {
return robot.parseMessage(robot.buildMessage(robot.COMMAND.LOG, { return robot.parseMessage(robot.buildMessage(robot.COMMAND.LOG, {
message message
})); }));
}); });
if (_.isError(parsedMessage)) { if (_.isError(parsedMessage)) {
@ -146,7 +144,6 @@ exports.write = (image, drive, options) => {
} }
try { try {
// These are lighweight accessor methods for // These are lighweight accessor methods for
// the properties of the parsed message // the properties of the parsed message
const messageCommand = robot.getCommand(parsedMessage); const messageCommand = robot.getCommand(parsedMessage);
@ -158,7 +155,6 @@ exports.write = (image, drive, options) => {
if (messageCommand === robot.COMMAND.ERROR) { if (messageCommand === robot.COMMAND.ERROR) {
emitError(robot.recomposeErrorMessage(parsedMessage)); emitError(robot.recomposeErrorMessage(parsedMessage));
} else if (messageCommand === robot.COMMAND.LOG) { } else if (messageCommand === robot.COMMAND.LOG) {
// If the message data is an object and it contains a // If the message data is an object and it contains a
// message string then log the message string only. // message string then log the message string only.
if (_.isPlainObject(messageData) && _.isString(messageData.message)) { if (_.isPlainObject(messageData) && _.isString(messageData.message)) {
@ -166,11 +162,9 @@ exports.write = (image, drive, options) => {
} else { } else {
console.log(messageData); console.log(messageData);
} }
} else { } else {
emitter.emit(messageCommand, messageData); emitter.emit(messageCommand, messageData);
} }
} catch (error) { } catch (error) {
emitError(error); emitError(error);
} }
@ -194,7 +188,6 @@ exports.write = (image, drive, options) => {
// This function causes the `close` event to be emitted // This function causes the `close` event to be emitted
child.kill(); child.kill();
}); });
child.on('error', emitError); child.on('error', emitError);

View File

@ -47,5 +47,4 @@ exports.getApplicationEntryPoint = () => {
// from `/root`, therefore we pass an absolute path, // from `/root`, therefore we pass an absolute path,
// in order to be on the safe side. // in order to be on the safe side.
return path.join(CONSTANTS.PROJECT_ROOT, relativeEntryPoint); return path.join(CONSTANTS.PROJECT_ROOT, relativeEntryPoint);
}; };

View File

@ -64,14 +64,12 @@ const OPTIONS_INDEX_START = 2;
*/ */
const etcherArguments = process.argv.slice(OPTIONS_INDEX_START); const etcherArguments = process.argv.slice(OPTIONS_INDEX_START);
return permissions.isElevated().then((elevated) => { permissions.isElevated().then((elevated) => {
if (!elevated) { if (!elevated) {
console.log('Attempting to elevate'); console.log('Attempting to elevate');
const commandArguments = _.attempt(() => { const commandArguments = _.attempt(() => {
if (os.platform() === 'linux' && process.env.APPIMAGE && process.env.APPDIR) { if (os.platform() === 'linux' && process.env.APPIMAGE && process.env.APPDIR) {
// Translate the current arguments to point to the AppImage // Translate the current arguments to point to the AppImage
// Relative paths are resolved from `/tmp/.mount_XXXXXX/usr` // Relative paths are resolved from `/tmp/.mount_XXXXXX/usr`
const translatedArguments = _.chain(process.argv) const translatedArguments = _.chain(process.argv)
@ -125,7 +123,6 @@ return permissions.isElevated().then((elevated) => {
ipc.connectTo(process.env.IPC_SERVER_ID, () => { ipc.connectTo(process.env.IPC_SERVER_ID, () => {
ipc.of[process.env.IPC_SERVER_ID].on('error', reject); ipc.of[process.env.IPC_SERVER_ID].on('error', reject);
ipc.of[process.env.IPC_SERVER_ID].on('connect', () => { ipc.of[process.env.IPC_SERVER_ID].on('connect', () => {
const child = childProcess.spawn(executable, etcherArguments, { const child = childProcess.spawn(executable, etcherArguments, {
env: { env: {
@ -160,7 +157,6 @@ return permissions.isElevated().then((elevated) => {
* }))); * })));
*/ */
const emitMessage = (data) => { const emitMessage = (data) => {
// Output from stdout/stderr coming from the CLI might be buffered, // Output from stdout/stderr coming from the CLI might be buffered,
// causing several progress lines to come up at once as single message. // causing several progress lines to come up at once as single message.
// Trying to parse multiple JSON objects separated by new lines will // Trying to parse multiple JSON objects separated by new lines will
@ -168,7 +164,6 @@ return permissions.isElevated().then((elevated) => {
_.each(utils.splitObjectLines(data.toString()), (object) => { _.each(utils.splitObjectLines(data.toString()), (object) => {
ipc.of[process.env.IPC_SERVER_ID].emit('message', object); ipc.of[process.env.IPC_SERVER_ID].emit('message', object);
}); });
}; };
child.stdout.on('data', emitMessage); child.stdout.on('data', emitMessage);

View File

@ -94,7 +94,6 @@ permissions.isElevated().then((elevated) => {
unmountOnSuccess: options.unmount, unmountOnSuccess: options.unmount,
validateWriteOnSuccess: options.check validateWriteOnSuccess: options.check
}, (state) => { }, (state) => {
if (robot.isEnabled(process.env)) { if (robot.isEnabled(process.env)) {
robot.printMessage('progress', { robot.printMessage('progress', {
type: state.type, type: state.type,
@ -105,7 +104,6 @@ permissions.isElevated().then((elevated) => {
} else { } else {
progressBars[state.type].update(state); progressBars[state.type].update(state);
} }
}).then((results) => { }).then((results) => {
return { return {
imagePath, imagePath,
@ -115,7 +113,6 @@ permissions.isElevated().then((elevated) => {
}); });
}); });
}).then((results) => { }).then((results) => {
return Bluebird.try(() => { return Bluebird.try(() => {
if (robot.isEnabled(process.env)) { if (robot.isEnabled(process.env)) {
return robot.printMessage('done', { return robot.printMessage('done', {
@ -136,9 +133,7 @@ permissions.isElevated().then((elevated) => {
}).then(() => { }).then(() => {
process.exit(EXIT_CODES.SUCCESS); process.exit(EXIT_CODES.SUCCESS);
}); });
}).catch((error) => { }).catch((error) => {
return Bluebird.try(() => { return Bluebird.try(() => {
if (robot.isEnabled(process.env)) { if (robot.isEnabled(process.env)) {
return robot.printError(error); return robot.printError(error);
@ -153,5 +148,4 @@ permissions.isElevated().then((elevated) => {
process.exit(EXIT_CODES.GENERAL_ERROR); process.exit(EXIT_CODES.GENERAL_ERROR);
}); });
}); });

View File

@ -65,7 +65,6 @@ const UNMOUNT_ON_SUCCESS_TIMEOUT_MS = 2000;
*/ */
exports.writeImage = (imagePath, drive, options, onProgress) => { exports.writeImage = (imagePath, drive, options, onProgress) => {
return Bluebird.try(() => { return Bluebird.try(() => {
// Unmounting a drive in Windows means we can't write to it anymore // Unmounting a drive in Windows means we can't write to it anymore
if (os.platform() === 'win32') { if (os.platform() === 'win32') {
return Bluebird.resolve(); return Bluebird.resolve();
@ -103,14 +102,12 @@ exports.writeImage = (imagePath, drive, options, onProgress) => {
writer.on('done', resolve); writer.on('done', resolve);
}); });
}).tap(() => { }).tap(() => {
// Make sure the device stream file descriptor is closed // Make sure the device stream file descriptor is closed
// before returning control the the caller. Not closing // before returning control the the caller. Not closing
// the file descriptor (and waiting for it) results in // the file descriptor (and waiting for it) results in
// `EBUSY` errors when attempting to unmount the drive // `EBUSY` errors when attempting to unmount the drive
// right afterwards in some Windows 7 systems. // right afterwards in some Windows 7 systems.
return fs.closeAsync(driveFileDescriptor).then(() => { return fs.closeAsync(driveFileDescriptor).then(() => {
if (!options.unmountOnSuccess) { if (!options.unmountOnSuccess) {
return Bluebird.resolve(); return Bluebird.resolve();
} }
@ -122,7 +119,6 @@ exports.writeImage = (imagePath, drive, options, onProgress) => {
return Bluebird.delay(UNMOUNT_ON_SUCCESS_TIMEOUT_MS) return Bluebird.delay(UNMOUNT_ON_SUCCESS_TIMEOUT_MS)
.return(drive.device) .return(drive.device)
.then(mountutils.unmountDiskAsync); .then(mountutils.unmountDiskAsync);
}); });
}); });
}); });

View File

@ -184,7 +184,6 @@ app.run(() => {
app.run(($timeout) => { app.run(($timeout) => {
driveScanner.on('drives', (drives) => { driveScanner.on('drives', (drives) => {
// Safely trigger a digest cycle. // Safely trigger a digest cycle.
// In some cases, AngularJS doesn't acknowledge that the // In some cases, AngularJS doesn't acknowledge that the
// available drives list has changed, and incorrectly // available drives list has changed, and incorrectly
@ -195,7 +194,6 @@ app.run(($timeout) => {
}); });
driveScanner.on('error', (error) => { driveScanner.on('error', (error) => {
// Stop the drive scanning loop in case of errors, // Stop the drive scanning loop in case of errors,
// otherwise we risk presenting the same error over // otherwise we risk presenting the same error over
// and over again to the user, while also heavily // and over again to the user, while also heavily
@ -241,7 +239,6 @@ app.run(($window) => {
// This circumvents the 'beforeunload' event unlike // This circumvents the 'beforeunload' event unlike
// electron.remote.app.quit() which does not. // electron.remote.app.quit() which does not.
electron.remote.process.exit(EXIT_CODES.SUCCESS); electron.remote.process.exit(EXIT_CODES.SUCCESS);
} }
analytics.logEvent('Close rejected while flashing'); analytics.logEvent('Close rejected while flashing');
@ -252,7 +249,6 @@ app.run(($window) => {
app.run(($rootScope) => { app.run(($rootScope) => {
$rootScope.$on('$stateChangeSuccess', (event, toState, toParams, fromState) => { $rootScope.$on('$stateChangeSuccess', (event, toState, toParams, fromState) => {
// Ignore first navigation // Ignore first navigation
if (!fromState.name) { if (!fromState.name) {
return; return;
@ -278,8 +274,7 @@ app.config(($provide) => {
}); });
}); });
app.controller('HeaderController', function(OSOpenExternalService) { app.controller('HeaderController', function (OSOpenExternalService) {
/** /**
* @summary Open help page * @summary Open help page
* @function * @function
@ -297,10 +292,9 @@ app.controller('HeaderController', function(OSOpenExternalService) {
const supportUrl = selectionState.getImageSupportUrl() || DEFAULT_SUPPORT_URL; const supportUrl = selectionState.getImageSupportUrl() || DEFAULT_SUPPORT_URL;
OSOpenExternalService.open(supportUrl); OSOpenExternalService.open(supportUrl);
}; };
}); });
app.controller('StateController', function($rootScope, $scope) { app.controller('StateController', function ($rootScope, $scope) {
const unregisterStateChange = $rootScope.$on('$stateChangeSuccess', (event, toState, toParams, fromState) => { const unregisterStateChange = $rootScope.$on('$stateChangeSuccess', (event, toState, toParams, fromState) => {
this.previousName = fromState.name; this.previousName = fromState.name;
this.currentName = toState.name; this.currentName = toState.name;
@ -335,5 +329,4 @@ app.controller('StateController', function($rootScope, $scope) {
* } * }
*/ */
this.currentName = null; this.currentName = null;
}); });

View File

@ -24,12 +24,11 @@ const analytics = require('../../../modules/analytics');
const availableDrives = require('../../../../shared/models/available-drives'); const availableDrives = require('../../../../shared/models/available-drives');
const selectionState = require('../../../../shared/models/selection-state'); const selectionState = require('../../../../shared/models/selection-state');
module.exports = function( module.exports = function (
$q, $q,
$uibModalInstance, $uibModalInstance,
WarningModalService WarningModalService
) { ) {
/** /**
* @summary The drive selector state * @summary The drive selector state
* @type {Object} * @type {Object}
@ -108,7 +107,6 @@ module.exports = function(
* }); * });
*/ */
this.toggleDrive = (drive) => { this.toggleDrive = (drive) => {
analytics.logEvent('Toggle drive', { analytics.logEvent('Toggle drive', {
drive, drive,
previouslySelected: selectionState.isCurrentDrive(drive.device) previouslySelected: selectionState.isCurrentDrive(drive.device)
@ -118,7 +116,6 @@ module.exports = function(
if (canChangeDriveSelectionState) { if (canChangeDriveSelectionState) {
selectionState.toggleSetDrive(drive.device); selectionState.toggleSetDrive(drive.device);
} }
}); });
}; };
@ -141,7 +138,6 @@ module.exports = function(
} else { } else {
$uibModalInstance.close(selectedDrive); $uibModalInstance.close(selectedDrive);
} }
}; };
/** /**
@ -208,7 +204,6 @@ module.exports = function(
areArgsInTuple = true; areArgsInTuple = true;
if (angular.equals(state, oldState)) { if (angular.equals(state, oldState)) {
// Use the previously memoized state for this argument // Use the previously memoized state for this argument
state = oldState; state = oldState;
} }
@ -224,7 +219,6 @@ module.exports = function(
// Add the state associated with these args to be memoized // Add the state associated with these args to be memoized
if (!areArgsInTuple) { if (!areArgsInTuple) {
previousTuples.push([ restArgs, state ]); previousTuples.push([ restArgs, state ]);
} }
return state; return state;
@ -257,5 +251,4 @@ module.exports = function(
this.getDriveStatuses = this.memoizeImmutableListReference((drive) => { this.getDriveStatuses = this.memoizeImmutableListReference((drive) => {
return this.constraints.getDriveImageCompatibilityStatuses(drive, this.state.getImage()); return this.constraints.getDriveImageCompatibilityStatuses(drive, this.state.getImage());
}); });
}; };

View File

@ -16,8 +16,7 @@
'use strict'; 'use strict';
module.exports = function(ModalService, $q) { module.exports = function (ModalService, $q) {
let modal = null; let modal = null;
/** /**
@ -55,7 +54,6 @@ module.exports = function(ModalService, $q) {
* DriveSelectorService.close(); * DriveSelectorService.close();
*/ */
this.close = () => { this.close = () => {
if (modal) { if (modal) {
return modal.close(); return modal.close();
} }
@ -63,7 +61,5 @@ module.exports = function(ModalService, $q) {
// Resolve `undefined` if the modal // Resolve `undefined` if the modal
// was already closed for consistency // was already closed for consistency
return $q.resolve(); return $q.resolve();
}; };
}; };

View File

@ -20,8 +20,7 @@ const flashState = require('../../../../shared/models/flash-state');
const selectionState = require('../../../../shared/models/selection-state'); const selectionState = require('../../../../shared/models/selection-state');
const analytics = require('../../../modules/analytics'); const analytics = require('../../../modules/analytics');
module.exports = function(WarningModalService) { module.exports = function (WarningModalService) {
/** /**
* @summary Open the flash error modal * @summary Open the flash error modal
* @function * @function
@ -47,5 +46,4 @@ module.exports = function(WarningModalService) {
} }
}); });
}; };
}; };

View File

@ -19,8 +19,7 @@
const _ = require('lodash'); const _ = require('lodash');
const analytics = require('../../../modules/analytics'); const analytics = require('../../../modules/analytics');
module.exports = function($uibModal, $q) { module.exports = function ($uibModal, $q) {
/** /**
* @summary Open a modal * @summary Open a modal
* @function * @function
@ -40,7 +39,6 @@ module.exports = function($uibModal, $q) {
* }); * });
*/ */
this.open = (options = {}) => { this.open = (options = {}) => {
_.defaults(options, { _.defaults(options, {
size: 'sm' size: 'sm'
}); });
@ -67,7 +65,6 @@ module.exports = function($uibModal, $q) {
resolve(value); resolve(value);
}).catch((error) => { }).catch((error) => {
// Bootstrap doesn't 'resolve' these but cancels the dialog // Bootstrap doesn't 'resolve' these but cancels the dialog
if (error === 'escape key press' || error === 'backdrop click') { if (error === 'escape key press' || error === 'backdrop click') {
analytics.logEvent('Modal rejected', { analytics.logEvent('Modal rejected', {
@ -86,5 +83,4 @@ module.exports = function($uibModal, $q) {
}) })
}; };
}; };
}; };

View File

@ -78,18 +78,17 @@ const API_VERSION = 1;
* <safe-webview src="https://etcher.io/"></safe-webview> * <safe-webview src="https://etcher.io/"></safe-webview>
*/ */
class SafeWebview extends react.PureComponent { class SafeWebview extends react.PureComponent {
/** /**
* @param {Object} props - React element properties * @param {Object} props - React element properties
*/ */
constructor(props) { constructor (props) {
super(props); super(props);
this.state = { this.state = {
shouldShow: true shouldShow: true
}; };
const url = new URL(props.src); const url = new window.URL(props.src);
// We set the version GET parameters here. // We set the version GET parameters here.
url.searchParams.set(ETCHER_VERSION_PARAM, packageJSON.version); url.searchParams.set(ETCHER_VERSION_PARAM, packageJSON.version);
@ -119,7 +118,7 @@ class SafeWebview extends react.PureComponent {
/** /**
* @returns {react.Element} * @returns {react.Element}
*/ */
render() { render () {
return react.createElement('webview', { return react.createElement('webview', {
ref: 'webview', ref: 'webview',
style: { style: {
@ -133,8 +132,7 @@ class SafeWebview extends react.PureComponent {
/** /**
* @summary Add the Webview events * @summary Add the Webview events
*/ */
componentDidMount() { componentDidMount () {
// Events React is unaware of have to be handled manually // Events React is unaware of have to be handled manually
_.map(this.eventTuples, (tuple) => { _.map(this.eventTuples, (tuple) => {
this.refs.webview.addEventListener(...tuple); this.refs.webview.addEventListener(...tuple);
@ -151,8 +149,7 @@ class SafeWebview extends react.PureComponent {
/** /**
* @summary Remove the Webview events * @summary Remove the Webview events
*/ */
componentWillUnmount() { componentWillUnmount () {
// Events that React is unaware of have to be handled manually // Events that React is unaware of have to be handled manually
_.map(this.eventTuples, (tuple) => { _.map(this.eventTuples, (tuple) => {
this.refs.webview.removeEventListener(...tuple); this.refs.webview.removeEventListener(...tuple);
@ -163,15 +160,13 @@ class SafeWebview extends react.PureComponent {
* @summary Refresh the webview if we are navigating away from the success page * @summary Refresh the webview if we are navigating away from the success page
* @param {Object} nextProps - upcoming properties * @param {Object} nextProps - upcoming properties
*/ */
componentWillReceiveProps(nextProps) { componentWillReceiveProps (nextProps) {
if (nextProps.refreshNow && !this.props.refreshNow) { if (nextProps.refreshNow && !this.props.refreshNow) {
// Reload the page if it hasn't changed, otherwise reset the source URL, // Reload the page if it hasn't changed, otherwise reset the source URL,
// because reload interferes with 'src' setting, resetting the 'src' attribute // because reload interferes with 'src' setting, resetting the 'src' attribute
// to what it was was just prior. // to what it was was just prior.
if (this.refs.webview.src === this.entryHref) { if (this.refs.webview.src === this.entryHref) {
this.refs.webview.reload(); this.refs.webview.reload();
} else { } else {
this.refs.webview.src = this.entryHref; this.refs.webview.src = this.entryHref;
} }
@ -185,7 +180,7 @@ class SafeWebview extends react.PureComponent {
/** /**
* @summary Set the element state to hidden * @summary Set the element state to hidden
*/ */
didFailLoad() { didFailLoad () {
this.setState({ this.setState({
shouldShow: false shouldShow: false
}); });
@ -195,7 +190,7 @@ class SafeWebview extends react.PureComponent {
* @summary Set the element state depending on the HTTP response code * @summary Set the element state depending on the HTTP response code
* @param {Event} event - Event object * @param {Event} event - Event object
*/ */
didGetResponseDetails(event) { didGetResponseDetails (event) {
const HTTP_OK = 200; const HTTP_OK = 200;
const HTTP_ERR = 400; const HTTP_ERR = 400;
@ -208,8 +203,8 @@ class SafeWebview extends react.PureComponent {
* @summary Open link in browser if it's opened as a 'foreground-tab' * @summary Open link in browser if it's opened as a 'foreground-tab'
* @param {Event} event - event object * @param {Event} event - event object
*/ */
static newWindow(event) { static newWindow (event) {
const url = new URL(event.url); const url = new window.URL(event.url);
if (_.every([ if (_.every([
url.protocol === 'http:' || url.protocol === 'https:', url.protocol === 'http:' || url.protocol === 'https:',
@ -236,7 +231,7 @@ class SafeWebview extends react.PureComponent {
* data: 'Hello, Mars!' * data: 'Hello, Mars!'
* })); * }));
*/ */
static consoleMessage(event) { static consoleMessage (event) {
if (!robot.isMessage(event.message)) { if (!robot.isMessage(event.message)) {
return; return;
} }
@ -245,12 +240,10 @@ class SafeWebview extends react.PureComponent {
if (robot.getCommand(message) === robot.COMMAND.LOG) { if (robot.getCommand(message) === robot.COMMAND.LOG) {
analytics.logEvent(robot.getData(message)); analytics.logEvent(robot.getData(message));
} else if (robot.getCommand(message) === robot.COMMAND.ERROR) { } else if (robot.getCommand(message) === robot.COMMAND.ERROR) {
analytics.logException(robot.getData(message)); analytics.logException(robot.getData(message));
} }
} }
} }
SafeWebview.propTypes = { SafeWebview.propTypes = {

View File

@ -41,13 +41,11 @@ const DEFAULT_SIZE = '40px';
* @public * @public
*/ */
class SVGIcon extends react.Component { class SVGIcon extends react.Component {
/** /**
* @summary Render the SVG * @summary Render the SVG
* @returns {react.Element} * @returns {react.Element}
*/ */
render() { render () {
// This means the path to the icon should be // This means the path to the icon should be
// relative to *this directory*. // relative to *this directory*.
// TODO: There might be a way to compute the path // TODO: There might be a way to compute the path
@ -58,7 +56,6 @@ class SVGIcon extends react.Component {
if (_.startsWith(this.props.path, '<')) { if (_.startsWith(this.props.path, '<')) {
contents = this.props.path; contents = this.props.path;
} else { } else {
contents = fs.readFileSync(imagePath, { contents = fs.readFileSync(imagePath, {
encoding: 'utf8' encoding: 'utf8'
@ -68,7 +65,7 @@ class SVGIcon extends react.Component {
const width = this.props.width || DEFAULT_SIZE; const width = this.props.width || DEFAULT_SIZE;
const height = this.props.height || DEFAULT_SIZE; const height = this.props.height || DEFAULT_SIZE;
const parser = new DOMParser(); const parser = new window.DOMParser();
const doc = parser.parseFromString(contents, 'image/svg+xml'); const doc = parser.parseFromString(contents, 'image/svg+xml');
const svg = doc.querySelector('svg'); const svg = doc.querySelector('svg');
@ -94,12 +91,10 @@ class SVGIcon extends react.Component {
* @summary Cause a re-render due to changed element properties * @summary Cause a re-render due to changed element properties
* @param {Object} nextProps - the new properties * @param {Object} nextProps - the new properties
*/ */
componentWillReceiveProps(nextProps) { componentWillReceiveProps (nextProps) {
// This will update the element if the properties change // This will update the element if the properties change
this.setState(nextProps); this.setState(nextProps);
} }
} }
SVGIcon.propTypes = { SVGIcon.propTypes = {

View File

@ -16,8 +16,7 @@
'use strict'; 'use strict';
module.exports = function($uibModalInstance, tooltipData) { module.exports = function ($uibModalInstance, tooltipData) {
/** /**
* @summary Tooltip data * @summary Tooltip data
* @type {Object} * @type {Object}
@ -36,5 +35,4 @@ module.exports = function($uibModalInstance, tooltipData) {
this.closeModal = () => { this.closeModal = () => {
$uibModalInstance.dismiss(); $uibModalInstance.dismiss();
}; };
}; };

View File

@ -18,8 +18,7 @@
const _ = require('lodash'); const _ = require('lodash');
module.exports = function(ModalService) { module.exports = function (ModalService) {
/** /**
* @summary Open the tooltip modal * @summary Open the tooltip modal
* @function * @function
@ -46,5 +45,4 @@ module.exports = function(ModalService) {
} }
}).result; }).result;
}; };
}; };

View File

@ -125,7 +125,6 @@ exports.notify = (version, options = {}) => {
}); });
}); });
}).tap((results) => { }).tap((results) => {
// Only update the last slept update timestamp if the // Only update the last slept update timestamp if the
// user ticked the "Remind me again in ..." checkbox, // user ticked the "Remind me again in ..." checkbox,
// but didn't agree. // but didn't agree.

View File

@ -16,8 +16,7 @@
'use strict'; 'use strict';
module.exports = function($uibModalInstance, options) { module.exports = function ($uibModalInstance, options) {
/** /**
* @summary Modal options * @summary Modal options
* @type {Object} * @type {Object}
@ -48,5 +47,4 @@ module.exports = function($uibModalInstance, options) {
this.accept = () => { this.accept = () => {
$uibModalInstance.close(true); $uibModalInstance.close(true);
}; };
}; };

View File

@ -18,8 +18,7 @@
const _ = require('lodash'); const _ = require('lodash');
module.exports = function($sce, ModalService) { module.exports = function ($sce, ModalService) {
/** /**
* @summary Display the warning modal * @summary Display the warning modal
* @function * @function
@ -49,5 +48,4 @@ module.exports = function($sce, ModalService) {
} }
}).result; }).result;
}; };
}; };

View File

@ -39,7 +39,6 @@ electron.app.on('before-quit', () => {
}); });
electron.app.on('ready', () => { electron.app.on('ready', () => {
// No menu bar // No menu bar
electron.Menu.setApplicationMenu(null); electron.Menu.setApplicationMenu(null);
@ -83,7 +82,6 @@ electron.app.on('ready', () => {
// See: https://github.com/electron/electron/issues/8841 // See: https://github.com/electron/electron/issues/8841
electron.globalShortcut.register('CmdOrCtrl+R', _.noop); electron.globalShortcut.register('CmdOrCtrl+R', _.noop);
electron.globalShortcut.register('F5', _.noop); electron.globalShortcut.register('F5', _.noop);
}); });
mainWindow.on('blur', () => { mainWindow.on('blur', () => {
@ -109,4 +107,3 @@ electron.app.on('ready', () => {
mainWindow.loadURL(`file://${path.join(__dirname, 'index.html')}`); mainWindow.loadURL(`file://${path.join(__dirname, 'index.html')}`);
}); });

View File

@ -40,7 +40,7 @@ const LOCAL_STORAGE_SETTINGS_KEY = 'etcher-settings';
*/ */
exports.readAll = () => { exports.readAll = () => {
return Bluebird.try(() => { return Bluebird.try(() => {
return JSON.parse(localStorage.getItem(LOCAL_STORAGE_SETTINGS_KEY)) || {}; return JSON.parse(window.localStorage.getItem(LOCAL_STORAGE_SETTINGS_KEY)) || {};
}); });
}; };
@ -62,7 +62,7 @@ exports.readAll = () => {
exports.writeAll = (settings) => { exports.writeAll = (settings) => {
const INDENTATION_SPACES = 2; const INDENTATION_SPACES = 2;
return Bluebird.try(() => { return Bluebird.try(() => {
localStorage.setItem(LOCAL_STORAGE_SETTINGS_KEY, JSON.stringify(settings, null, INDENTATION_SPACES)); window.localStorage.setItem(LOCAL_STORAGE_SETTINGS_KEY, JSON.stringify(settings, null, INDENTATION_SPACES));
}); });
}; };
@ -83,6 +83,6 @@ exports.writeAll = (settings) => {
*/ */
exports.clear = () => { exports.clear = () => {
return Bluebird.try(() => { return Bluebird.try(() => {
localStorage.removeItem(LOCAL_STORAGE_SETTINGS_KEY); window.localStorage.removeItem(LOCAL_STORAGE_SETTINGS_KEY);
}); });
}; };

View File

@ -56,7 +56,6 @@ const setSettingsObject = (settings) => {
data: settings data: settings
}); });
}).then(() => { }).then(() => {
// Revert the application state if writing the data // Revert the application state if writing the data
// to the local machine was not successful // to the local machine was not successful
return localSettings.writeAll(settings).catch((error) => { return localSettings.writeAll(settings).catch((error) => {
@ -67,7 +66,6 @@ const setSettingsObject = (settings) => {
throw error; throw error;
}); });
}); });
}; };

View File

@ -32,8 +32,7 @@ const analytics = require('../modules/analytics');
const MODULE_NAME = 'Etcher.Modules.ImageWriter'; const MODULE_NAME = 'Etcher.Modules.ImageWriter';
const imageWriter = angular.module(MODULE_NAME, []); const imageWriter = angular.module(MODULE_NAME, []);
imageWriter.service('ImageWriterService', function($q, $rootScope) { imageWriter.service('ImageWriterService', function ($q, $rootScope) {
/** /**
* @summary Perform write operation * @summary Perform write operation
* @function * @function
@ -105,7 +104,6 @@ imageWriter.service('ImageWriterService', function($q, $rootScope) {
analytics.logEvent('Flash', analyticsData); analytics.logEvent('Flash', analyticsData);
return this.performWrite(image, drive, (state) => { return this.performWrite(image, drive, (state) => {
// Bring this value to the world of angular. // Bring this value to the world of angular.
// If we don't trigger a digest loop, // If we don't trigger a digest loop,
// `.getFlashState()` will not return // `.getFlashState()` will not return
@ -113,7 +111,6 @@ imageWriter.service('ImageWriterService', function($q, $rootScope) {
$rootScope.$apply(() => { $rootScope.$apply(() => {
flashState.setProgressState(state); flashState.setProgressState(state);
}); });
}).then(flashState.unsetFlashingFlag).then(() => { }).then(flashState.unsetFlashingFlag).then(() => {
if (flashState.wasLastFlashCancelled()) { if (flashState.wasLastFlashCancelled()) {
analytics.logEvent('Elevation cancelled', analyticsData); analytics.logEvent('Elevation cancelled', analyticsData);
@ -144,7 +141,6 @@ imageWriter.service('ImageWriterService', function($q, $rootScope) {
windowProgress.clear(); windowProgress.clear();
}); });
}; };
}); });
module.exports = MODULE_NAME; module.exports = MODULE_NAME;

View File

@ -68,12 +68,10 @@ exports.selectImage = () => {
} }
] ]
}, (files) => { }, (files) => {
// `_.first` is smart enough to not throw and return `undefined` // `_.first` is smart enough to not throw and return `undefined`
// if we pass it an `undefined` value (e.g: when the selection // if we pass it an `undefined` value (e.g: when the selection
// dialog was cancelled). // dialog was cancelled).
return resolve(_.first(files)); return resolve(_.first(files));
}); });
}); });
}; };

View File

@ -41,11 +41,10 @@ const electron = require('electron');
* }); * });
*/ */
exports.send = (title, options) => { exports.send = (title, options) => {
// `app.dock` is only defined in OS X // `app.dock` is only defined in OS X
if (electron.remote.app.dock) { if (electron.remote.app.dock) {
electron.remote.app.dock.bounce(); electron.remote.app.dock.bounce();
} }
return new Notification(title, options); return new window.Notification(title, options);
}; };

View File

@ -36,7 +36,6 @@ module.exports = (OSOpenExternalService) => {
restrict: 'A', restrict: 'A',
scope: false, scope: false,
link: (scope, element, attributes) => { link: (scope, element, attributes) => {
// This directive might be added to elements // This directive might be added to elements
// other than buttons. // other than buttons.
element.css('cursor', 'pointer'); element.css('cursor', 'pointer');

View File

@ -32,9 +32,10 @@ OSOpenExternal.run((OSOpenExternalService) => {
document.addEventListener('click', (event) => { document.addEventListener('click', (event) => {
const target = event.target; const target = event.target;
if (target.tagName === 'A' && angular.isDefined(target.href)) { if (target.tagName === 'A' && angular.isDefined(target.href)) {
// Electron interprets relative URLs as being relative to the
// Electron interprets relative URLs as being relative to the current loaded URL (with `webContents.loadURL`) and expands // current loaded URL (with `webContents.loadURL`) and expands
// them to the corresponding absolute URL. If it's a `file://` URL, we don't want it opened in an external browser. // them to the corresponding absolute URL. If it's a `file://`
// URL, we don't want it opened in an external browser.
if (url.parse(target.href).protocol !== 'file:') { if (url.parse(target.href).protocol !== 'file:') {
OSOpenExternalService.open(target.href); OSOpenExternalService.open(target.href);
} }

View File

@ -19,8 +19,7 @@
const electron = require('electron'); const electron = require('electron');
const analytics = require('../../../modules/analytics'); const analytics = require('../../../modules/analytics');
module.exports = function() { module.exports = function () {
/** /**
* @summary Open an external resource * @summary Open an external resource
* @function * @function
@ -40,5 +39,4 @@ module.exports = function() {
electron.shell.openExternal(url); electron.shell.openExternal(url);
} }
}; };
}; };

View File

@ -55,7 +55,6 @@ exports.set = (percentage) => {
* windowProgress.clear(); * windowProgress.clear();
*/ */
exports.clear = () => { exports.clear = () => {
// Passing 0 or null/undefined doesn't work. // Passing 0 or null/undefined doesn't work.
const ELECTRON_PROGRESS_BAR_RESET_VALUE = -1; const ELECTRON_PROGRESS_BAR_RESET_VALUE = -1;

View File

@ -21,8 +21,7 @@ const flashState = require('../../../../shared/models/flash-state');
const selectionState = require('../../../../shared/models/selection-state'); const selectionState = require('../../../../shared/models/selection-state');
const analytics = require('../../../modules/analytics'); const analytics = require('../../../modules/analytics');
module.exports = function($state) { module.exports = function ($state) {
/** /**
* @summary Settings model * @summary Settings model
* @type {Object} * @type {Object}
@ -53,5 +52,4 @@ module.exports = function($state) {
analytics.logEvent('Restart', options); analytics.logEvent('Restart', options);
$state.go('main'); $state.go('main');
}; };
}; };

View File

@ -21,8 +21,7 @@ const selectionState = require('../../../../shared/models/selection-state');
const analytics = require('../../../modules/analytics'); const analytics = require('../../../modules/analytics');
const exceptionReporter = require('../../../modules/exception-reporter'); const exceptionReporter = require('../../../modules/exception-reporter');
module.exports = function(DriveSelectorService) { module.exports = function (DriveSelectorService) {
/** /**
* @summary Open drive selector * @summary Open drive selector
* @function * @function
@ -58,5 +57,4 @@ module.exports = function(DriveSelectorService) {
this.openDriveSelector(); this.openDriveSelector();
analytics.logEvent('Reselect drive'); analytics.logEvent('Reselect drive');
}; };
}; };

View File

@ -25,12 +25,11 @@ const notification = require('../../../os/notification');
const exceptionReporter = require('../../../modules/exception-reporter'); const exceptionReporter = require('../../../modules/exception-reporter');
const path = require('path'); const path = require('path');
module.exports = function( module.exports = function (
$state, $state,
ImageWriterService, ImageWriterService,
FlashErrorModalService FlashErrorModalService
) { ) {
/** /**
* @summary Flash image to a drive * @summary Flash image to a drive
* @function * @function
@ -98,9 +97,7 @@ module.exports = function(
FlashErrorModalService.show(messages.error.genericFlashError()); FlashErrorModalService.show(messages.error.genericFlashError());
exceptionReporter.report(error); exceptionReporter.report(error);
} }
}).finally(() => {
})
.finally(() => {
driveScanner.start(); driveScanner.start();
}); });
}; };
@ -135,5 +132,4 @@ module.exports = function(
return `${currentFlashState.percentage}%`; return `${currentFlashState.percentage}%`;
}; };
}; };

View File

@ -28,11 +28,10 @@ const selectionState = require('../../../../shared/models/selection-state');
const osDialog = require('../../../os/dialog'); const osDialog = require('../../../os/dialog');
const exceptionReporter = require('../../../modules/exception-reporter'); const exceptionReporter = require('../../../modules/exception-reporter');
module.exports = function( module.exports = function (
$timeout, $timeout,
WarningModalService WarningModalService
) { ) {
/** /**
* @summary Main supported extensions * @summary Main supported extensions
* @constant * @constant
@ -103,9 +102,7 @@ module.exports = function(
} }
return false; return false;
}).then((shouldChange) => { }).then((shouldChange) => {
if (shouldChange) { if (shouldChange) {
return this.reselectImage(); return this.reselectImage();
} }
@ -164,7 +161,6 @@ module.exports = function(
analytics.logEvent('Open image selector'); analytics.logEvent('Open image selector');
osDialog.selectImage().then((imagePath) => { osDialog.selectImage().then((imagePath) => {
// Avoid analytics and selection state changes // Avoid analytics and selection state changes
// if no file was resolved from the dialog. // if no file was resolved from the dialog.
if (!imagePath) { if (!imagePath) {
@ -209,5 +205,4 @@ module.exports = function(
return path.basename(selectionState.getImagePath()); return path.basename(selectionState.getImagePath());
}; };
}; };

View File

@ -23,11 +23,10 @@ const exceptionReporter = require('../../../modules/exception-reporter');
const availableDrives = require('../../../../shared/models/available-drives'); const availableDrives = require('../../../../shared/models/available-drives');
const selectionState = require('../../../../shared/models/selection-state'); const selectionState = require('../../../../shared/models/selection-state');
module.exports = function( module.exports = function (
TooltipModalService, TooltipModalService,
OSOpenExternalService OSOpenExternalService
) { ) {
// Expose several modules to the template for convenience // Expose several modules to the template for convenience
this.selection = selectionState; this.selection = selectionState;
this.drives = availableDrives; this.drives = availableDrives;
@ -87,5 +86,4 @@ module.exports = function(
message: selectionState.getImagePath() message: selectionState.getImagePath()
}).catch(exceptionReporter.report); }).catch(exceptionReporter.report);
}; };
}; };

View File

@ -22,8 +22,7 @@ const settings = require('../../../models/settings');
const analytics = require('../../../modules/analytics'); const analytics = require('../../../modules/analytics');
const exceptionReporter = require('../../../modules/exception-reporter'); const exceptionReporter = require('../../../modules/exception-reporter');
module.exports = function(WarningModalService) { module.exports = function (WarningModalService) {
/** /**
* @summary Client platform * @summary Client platform
* @type {String} * @type {String}
@ -82,7 +81,6 @@ module.exports = function(WarningModalService) {
* }); * });
*/ */
this.toggle = (setting, options) => { this.toggle = (setting, options) => {
const value = this.currentData[setting]; const value = this.currentData[setting];
const dangerous = !_.isUndefined(options); const dangerous = !_.isUndefined(options);
@ -106,5 +104,4 @@ module.exports = function(WarningModalService) {
} }
}).catch(exceptionReporter.report); }).catch(exceptionReporter.report);
}; };
}; };

View File

@ -19,7 +19,6 @@
const units = require('../../../shared/units'); const units = require('../../../shared/units');
module.exports = () => { module.exports = () => {
/** /**
* @summary Convert bytes to the closest unit * @summary Convert bytes to the closest unit
* @function * @function
@ -32,5 +31,4 @@ module.exports = () => {
* {{ 7801405440 | closestUnit }} * {{ 7801405440 | closestUnit }}
*/ */
return units.bytesToClosestUnit; return units.bytesToClosestUnit;
}; };

View File

@ -19,8 +19,7 @@
const _ = require('lodash'); const _ = require('lodash');
const packageJSON = require('../../../../../package.json'); const packageJSON = require('../../../../../package.json');
module.exports = function() { module.exports = function () {
/** /**
* @summary Get a package.json property * @summary Get a package.json property
* @function * @function
@ -35,5 +34,4 @@ module.exports = function() {
this.get = (attribute) => { this.get = (attribute) => {
return _.get(packageJSON, attribute); return _.get(packageJSON, attribute);
}; };
}; };

View File

@ -172,7 +172,6 @@ const extractArchiveMetadata = (archive, basePath, options) => {
*/ */
exports.extractImage = (archive, hooks) => { exports.extractImage = (archive, hooks) => {
return hooks.getEntries(archive).then((entries) => { return hooks.getEntries(archive).then((entries) => {
const imageEntries = _.filter(entries, (entry) => { const imageEntries = _.filter(entries, (entry) => {
return _.includes(IMAGE_EXTENSIONS, fileExtensions.getLastFileExtension(entry.name)); return _.includes(IMAGE_EXTENSIONS, fileExtensions.getLastFileExtension(entry.name));
}); });

View File

@ -186,9 +186,9 @@ module.exports = {
if (/invalid footer/i.test(error.message)) { if (/invalid footer/i.test(error.message)) {
throw errors.createUserError({ throw errors.createUserError({
title: 'Invalid image', title: 'Invalid image',
description: `There was an error reading "${path.basename(imagePath)}". ` description: `There was an error reading "${path.basename(imagePath)}". ` +
+ 'The image does not appear to be a valid Apple Disk Image (dmg), or may have the wrong filename extension.\n\n' 'The image does not appear to be a valid Apple Disk Image (dmg), or may have the wrong filename extension.\n\n' +
+ `Error: ${error.description || error.message}` `Error: ${error.description || error.message}`
}); });
} }
throw error; throw error;

View File

@ -66,7 +66,6 @@ const MAX_BLOCK_SIZE = 4096;
* } * }
*/ */
const detectGPT = (buffer) => { const detectGPT = (buffer) => {
let blockSize = INITIAL_BLOCK_SIZE; let blockSize = INITIAL_BLOCK_SIZE;
let gpt = null; let gpt = null;
@ -83,7 +82,6 @@ const detectGPT = (buffer) => {
} }
return null; return null;
}; };
/** /**
@ -102,7 +100,6 @@ const detectGPT = (buffer) => {
* } * }
*/ */
const parsePartitionTables = (image, buffer) => { const parsePartitionTables = (image, buffer) => {
const mbr = _.attempt(MBR.parse, buffer); const mbr = _.attempt(MBR.parse, buffer);
let gpt = null; let gpt = null;
@ -138,7 +135,6 @@ const parsePartitionTables = (image, buffer) => {
}; };
}); });
} }
}; };
/** /**
@ -163,7 +159,6 @@ const parsePartitionTables = (image, buffer) => {
*/ */
module.exports = (image) => { module.exports = (image) => {
return new Bluebird((resolve, reject) => { return new Bluebird((resolve, reject) => {
const chunks = []; const chunks = [];
let length = INITIAL_LENGTH; let length = INITIAL_LENGTH;
let destroyed = false; let destroyed = false;
@ -184,7 +179,6 @@ module.exports = (image) => {
// Once we've read enough bytes, terminate the stream // Once we've read enough bytes, terminate the stream
if (length >= MAX_STREAM_BYTES && !destroyed) { if (length >= MAX_STREAM_BYTES && !destroyed) {
// Prefer close() over destroy(), as some streams // Prefer close() over destroy(), as some streams
// from dependencies exhibit quirky behavior when destroyed // from dependencies exhibit quirky behavior when destroyed
if (image.stream.close) { if (image.stream.close) {
@ -202,10 +196,7 @@ module.exports = (image) => {
// Parse the MBR, GPT and partitions from the obtained buffer // Parse the MBR, GPT and partitions from the obtained buffer
parsePartitionTables(image, Buffer.concat(chunks)); parsePartitionTables(image, Buffer.concat(chunks));
resolve(image); resolve(image);
} }
}); });
}); });
}; };

View File

@ -145,7 +145,6 @@ exports.isDriveLargeEnough = (drive, image) => {
const driveSize = _.get(drive, [ 'size' ], UNKNOWN_SIZE); const driveSize = _.get(drive, [ 'size' ], UNKNOWN_SIZE);
if (_.get(image, [ 'size', 'final', 'estimation' ])) { if (_.get(image, [ 'size', 'final', 'estimation' ])) {
// If the drive size is smaller than the original image size, and // If the drive size is smaller than the original image size, and
// the final image size is just an estimation, then we stop right // the final image size is just an estimation, then we stop right
// here, based on the assumption that the final size will never // here, based on the assumption that the final size will never
@ -159,7 +158,6 @@ exports.isDriveLargeEnough = (drive, image) => {
// the drive has ran out of space, instead of prohibiting the flash // the drive has ran out of space, instead of prohibiting the flash
// at all, when the estimation may be wrong. // at all, when the estimation may be wrong.
return true; return true;
} }
return driveSize >= _.get(image, [ return driveSize >= _.get(image, [
@ -349,21 +347,17 @@ exports.getDriveImageCompatibilityStatuses = (drive, image) => {
type: exports.COMPATIBILITY_STATUS_TYPES.ERROR, type: exports.COMPATIBILITY_STATUS_TYPES.ERROR,
message: exports.COMPATIBILITY_STATUS_MESSAGES.CONTAINS_IMAGE message: exports.COMPATIBILITY_STATUS_MESSAGES.CONTAINS_IMAGE
}); });
} else if (exports.isDriveLocked(drive)) { } else if (exports.isDriveLocked(drive)) {
statusList.push({ statusList.push({
type: exports.COMPATIBILITY_STATUS_TYPES.ERROR, type: exports.COMPATIBILITY_STATUS_TYPES.ERROR,
message: exports.COMPATIBILITY_STATUS_MESSAGES.LOCKED message: exports.COMPATIBILITY_STATUS_MESSAGES.LOCKED
}); });
} else if (!_.isNil(drive) && !exports.isDriveLargeEnough(drive, image)) { } else if (!_.isNil(drive) && !exports.isDriveLargeEnough(drive, image)) {
statusList.push({ statusList.push({
type: exports.COMPATIBILITY_STATUS_TYPES.ERROR, type: exports.COMPATIBILITY_STATUS_TYPES.ERROR,
message: exports.COMPATIBILITY_STATUS_MESSAGES.TOO_SMALL message: exports.COMPATIBILITY_STATUS_MESSAGES.TOO_SMALL
}); });
} else { } else {
if (exports.isSystemDrive(drive)) { if (exports.isSystemDrive(drive)) {
statusList.push({ statusList.push({
type: exports.COMPATIBILITY_STATUS_TYPES.WARNING, type: exports.COMPATIBILITY_STATUS_TYPES.WARNING,

View File

@ -326,7 +326,6 @@ exports.isUserError = (error) => {
* > 'foo' * > 'foo'
*/ */
exports.toJSON = (error) => { exports.toJSON = (error) => {
// Handle string error objects to be on the safe side // Handle string error objects to be on the safe side
const isErrorLike = _.isError(error) || _.isPlainObject(error); const isErrorLike = _.isError(error) || _.isPlainObject(error);
const errorObject = isErrorLike ? error : new Error(error); const errorObject = isErrorLike ? error : new Error(error);

View File

@ -123,11 +123,9 @@ exports.setProgressState = (state) => {
speed: _.attempt(() => { speed: _.attempt(() => {
if (_.isNumber(state.speed) && !_.isNaN(state.speed)) { if (_.isNumber(state.speed) && !_.isNaN(state.speed)) {
// Preserve only two decimal places // Preserve only two decimal places
const PRECISION = 2; const PRECISION = 2;
return _.round(units.bytesToMegabytes(state.speed), PRECISION); return _.round(units.bytesToMegabytes(state.speed), PRECISION);
} }
return null; return null;

View File

@ -57,7 +57,6 @@ const UNIX_SUPERUSER_USER_ID = 0;
*/ */
exports.isElevated = () => { exports.isElevated = () => {
if (os.platform() === 'win32') { if (os.platform() === 'win32') {
// `fltmc` is available on WinPE, XP, Vista, 7, 8, and 10 // `fltmc` is available on WinPE, XP, Vista, 7, 8, and 10
// Works even when the "Server" service is disabled // Works even when the "Server" service is disabled
// See http://stackoverflow.com/a/28268802 // See http://stackoverflow.com/a/28268802
@ -66,7 +65,6 @@ exports.isElevated = () => {
.catch({ .catch({
code: os.constants.errno.EPERM code: os.constants.errno.EPERM
}, _.constant(false)); }, _.constant(false));
} }
return Bluebird.resolve(process.geteuid() === UNIX_SUPERUSER_USER_ID); return Bluebird.resolve(process.geteuid() === UNIX_SUPERUSER_USER_ID);
@ -108,11 +106,9 @@ exports.getEnvironmentCommandPrefix = (environment) => {
}); });
if (isWindows) { if (isWindows) {
// This is a trick to make the binary afterwards catch // This is a trick to make the binary afterwards catch
// the environment variables set just previously. // the environment variables set just previously.
return _.concat(argv, [ 'call' ]); return _.concat(argv, [ 'call' ]);
} }
return _.concat([ 'env' ], argv); return _.concat([ 'env' ], argv);
@ -197,7 +193,6 @@ exports.elevateCommand = (command, options) => {
// There doesn't seem to be a better way to handle these errors, so // There doesn't seem to be a better way to handle these errors, so
// for now, we should make sure we double check if the error messages // for now, we should make sure we double check if the error messages
// have changed every time we upgrade `sudo-prompt`. // have changed every time we upgrade `sudo-prompt`.
}).catch((error) => { }).catch((error) => {
return _.includes(error.message, 'is not in the sudoers file'); return _.includes(error.message, 'is not in the sudoers file');
}, () => { }, () => {
@ -219,5 +214,4 @@ exports.elevateCommand = (command, options) => {
description: 'Please install a polkit authentication agent for your desktop environment of choice to continue' description: 'Please install a polkit authentication agent for your desktop environment of choice to continue'
}); });
}); });
}; };

View File

@ -187,7 +187,6 @@ exports.getRemoteVersions = _.memoize((bucketUrl) => {
* } * }
*/ */
const semverSatisfies = (version, range) => { const semverSatisfies = (version, range) => {
// The `semver` module refuses to apply ranges to prerelease versions // The `semver` module refuses to apply ranges to prerelease versions
// As a workaround, we drop the prerelease tags, if any, apply the range // As a workaround, we drop the prerelease tags, if any, apply the range
// on that, and keep using the prerelease tag from then on. // on that, and keep using the prerelease tag from then on.
@ -218,7 +217,6 @@ const semverSatisfies = (version, range) => {
* }); * });
*/ */
exports.getLatestVersion = (releaseType, options = {}) => { exports.getLatestVersion = (releaseType, options = {}) => {
// For manual testing purposes // For manual testing purposes
const ETCHER_FAKE_S3_LATEST_VERSION = process.env.ETCHER_FAKE_S3_LATEST_VERSION; const ETCHER_FAKE_S3_LATEST_VERSION = process.env.ETCHER_FAKE_S3_LATEST_VERSION;
if (!_.isNil(ETCHER_FAKE_S3_LATEST_VERSION)) { if (!_.isNil(ETCHER_FAKE_S3_LATEST_VERSION)) {
@ -235,11 +233,8 @@ exports.getLatestVersion = (releaseType, options = {}) => {
} }
/* eslint-disable lodash/prefer-lodash-method */ /* eslint-disable lodash/prefer-lodash-method */
return exports.getRemoteVersions(bucketUrl).filter((version) => { return exports.getRemoteVersions(bucketUrl).filter((version) => {
/* eslint-enable lodash/prefer-lodash-method */ /* eslint-enable lodash/prefer-lodash-method */
if (_.some([ if (_.some([
// This check allows us to ignore snapshot builds in production // This check allows us to ignore snapshot builds in production

View File

@ -88,7 +88,6 @@ const ACTIONS = _.fromPairs(_.map([
* const drive = findDrive(state, '/dev/disk2'); * const drive = findDrive(state, '/dev/disk2');
*/ */
const findDrive = (state, device) => { const findDrive = (state, device) => {
/* eslint-disable lodash/prefer-lodash-method */ /* eslint-disable lodash/prefer-lodash-method */
return state.get('availableDrives').find((drive) => { return state.get('availableDrives').find((drive) => {
@ -96,7 +95,6 @@ const findDrive = (state, device) => {
}); });
/* eslint-enable lodash/prefer-lodash-method */ /* eslint-enable lodash/prefer-lodash-method */
}; };
/** /**
@ -115,7 +113,6 @@ const findDrive = (state, device) => {
*/ */
const storeReducer = (state = DEFAULT_STATE, action) => { const storeReducer = (state = DEFAULT_STATE, action) => {
switch (action.type) { switch (action.type) {
case ACTIONS.SET_AVAILABLE_DRIVES: { case ACTIONS.SET_AVAILABLE_DRIVES: {
if (!action.data) { if (!action.data) {
throw errors.createError({ throw errors.createError({
@ -134,7 +131,6 @@ const storeReducer = (state = DEFAULT_STATE, action) => {
const AUTOSELECT_DRIVE_COUNT = 1; const AUTOSELECT_DRIVE_COUNT = 1;
const numberOfDrives = action.data.length; const numberOfDrives = action.data.length;
if (numberOfDrives === AUTOSELECT_DRIVE_COUNT) { if (numberOfDrives === AUTOSELECT_DRIVE_COUNT) {
const drive = _.first(action.data); const drive = _.first(action.data);
// Even if there's no image selected, we need to call several // Even if there's no image selected, we need to call several
@ -155,7 +151,6 @@ const storeReducer = (state = DEFAULT_STATE, action) => {
data: drive.device data: drive.device
}); });
} }
} }
const selectedDevice = newState.getIn([ 'selection', 'drive' ]); const selectedDevice = newState.getIn([ 'selection', 'drive' ]);
@ -482,7 +477,6 @@ const storeReducer = (state = DEFAULT_STATE, action) => {
default: { default: {
return state; return state;
} }
} }
}; };

View File

@ -32,7 +32,6 @@ process.env.DEBUG = '*';
// using `child_process.fork()`. // using `child_process.fork()`.
if (process.env.ELECTRON_RUN_AS_NODE || process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE) { if (process.env.ELECTRON_RUN_AS_NODE || process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE) {
require('./cli/etcher'); require('./cli/etcher');
} else { } else {
require('./gui/etcher'); require('./gui/etcher');
} }

View File

@ -42,4 +42,3 @@ _.each([
const filename = path.join(currentDirectory, `Dockerfile-${options.architecture}`); const filename = path.join(currentDirectory, `Dockerfile-${options.architecture}`);
fs.writeFileSync(filename, result); fs.writeFileSync(filename, result);
}); });

View File

@ -113,11 +113,9 @@ const getShrinkwrapDependencyManifest = (shrinkwrapPath) => {
.value(); .value();
try { try {
// For example // For example
// ./node_modules/drivelist/node_modules/lodash/package.json // ./node_modules/drivelist/node_modules/lodash/package.json
return require(`.${path.sep}${manifestPath}`); return require(`.${path.sep}${manifestPath}`);
} catch (error) { } catch (error) {
if (error.code === 'MODULE_NOT_FOUND') { if (error.code === 'MODULE_NOT_FOUND') {
return null; return null;

View File

@ -47,7 +47,6 @@ angularValidate.validate(
} }
).then((result) => { ).then((result) => {
_.each(result.failed, (failure) => { _.each(result.failed, (failure) => {
// The module has a typo in the "numbers" property // The module has a typo in the "numbers" property
console.error(chalk.red(`${failure.numerrs} errors at ${path.relative(PROJECT_ROOT, failure.filepath)}`)); console.error(chalk.red(`${failure.numerrs} errors at ${path.relative(PROJECT_ROOT, failure.filepath)}`));
@ -77,9 +76,7 @@ angularValidate.validate(
setTimeout(() => { setTimeout(() => {
process.exit(EXIT_CODES.GENERAL_ERROR); process.exit(EXIT_CODES.GENERAL_ERROR);
}, EXIT_TIMEOUT_MS); }, EXIT_TIMEOUT_MS);
} }
}, (error) => { }, (error) => {
console.error(error); console.error(error);
process.exit(EXIT_CODES.GENERAL_ERROR); process.exit(EXIT_CODES.GENERAL_ERROR);

View File

@ -19,31 +19,27 @@
const m = require('mochainon'); const m = require('mochainon');
const cli = require('../../lib/child-writer/cli'); const cli = require('../../lib/child-writer/cli');
describe('ChildWriter CLI', function() { describe('ChildWriter CLI', function () {
describe('.getBooleanArgumentForm()', function () {
describe('.getBooleanArgumentForm()', function() { it('should prepend --no if the value is false and option is long', function () {
it('should prepend --no if the value is false and option is long', function() {
m.chai.expect(cli.getBooleanArgumentForm('foo', false)).to.equal('--no-foo'); m.chai.expect(cli.getBooleanArgumentForm('foo', false)).to.equal('--no-foo');
}); });
it('should prepend -- if the value is true and option is long', function() { it('should prepend -- if the value is true and option is long', function () {
m.chai.expect(cli.getBooleanArgumentForm('foo', true)).to.equal('--foo'); m.chai.expect(cli.getBooleanArgumentForm('foo', true)).to.equal('--foo');
}); });
it('should prepend --no if the value is false and option is short', function() { it('should prepend --no if the value is false and option is short', function () {
m.chai.expect(cli.getBooleanArgumentForm('x', false)).to.equal('--no-x'); m.chai.expect(cli.getBooleanArgumentForm('x', false)).to.equal('--no-x');
}); });
it('should prepend - if the value is true and option is short', function() { it('should prepend - if the value is true and option is short', function () {
m.chai.expect(cli.getBooleanArgumentForm('x', true)).to.equal('-x'); m.chai.expect(cli.getBooleanArgumentForm('x', true)).to.equal('-x');
}); });
}); });
describe('.getArguments()', function() { describe('.getArguments()', function () {
it('should return a list of arguments given validate = false, unmount = false', function () {
it('should return a list of arguments given validate = false, unmount = false', function() {
m.chai.expect(cli.getArguments({ m.chai.expect(cli.getArguments({
image: 'path/to/image.img', image: 'path/to/image.img',
device: '/dev/disk2', device: '/dev/disk2',
@ -60,7 +56,7 @@ describe('ChildWriter CLI', function() {
]); ]);
}); });
it('should return a list of arguments given validate = false, unmount = true', function() { it('should return a list of arguments given validate = false, unmount = true', function () {
m.chai.expect(cli.getArguments({ m.chai.expect(cli.getArguments({
image: 'path/to/image.img', image: 'path/to/image.img',
device: '/dev/disk2', device: '/dev/disk2',
@ -77,7 +73,7 @@ describe('ChildWriter CLI', function() {
]); ]);
}); });
it('should return a list of arguments given validate = true, unmount = false', function() { it('should return a list of arguments given validate = true, unmount = false', function () {
m.chai.expect(cli.getArguments({ m.chai.expect(cli.getArguments({
image: 'path/to/image.img', image: 'path/to/image.img',
device: '/dev/disk2', device: '/dev/disk2',
@ -94,7 +90,7 @@ describe('ChildWriter CLI', function() {
]); ]);
}); });
it('should return a list of arguments given validate = true, unmount = true', function() { it('should return a list of arguments given validate = true, unmount = true', function () {
m.chai.expect(cli.getArguments({ m.chai.expect(cli.getArguments({
image: 'path/to/image.img', image: 'path/to/image.img',
device: '/dev/disk2', device: '/dev/disk2',
@ -110,7 +106,5 @@ describe('ChildWriter CLI', function() {
'--check' '--check'
]); ]);
}); });
}); });
}); });

View File

@ -19,11 +19,9 @@
const m = require('mochainon'); const m = require('mochainon');
const utils = require('../../lib/child-writer/utils'); const utils = require('../../lib/child-writer/utils');
describe('ChildWriter Utils', function() { describe('ChildWriter Utils', function () {
describe('.splitObjectLines()', function () {
describe('.splitObjectLines()', function() { it('should split multiple object lines', function () {
it('should split multiple object lines', function() {
const input = '{"id":"foo"}\n{"id":"bar"}\n{"id":"baz"}'; const input = '{"id":"foo"}\n{"id":"bar"}\n{"id":"baz"}';
m.chai.expect(utils.splitObjectLines(input)).to.deep.equal([ m.chai.expect(utils.splitObjectLines(input)).to.deep.equal([
'{"id":"foo"}', '{"id":"foo"}',
@ -32,7 +30,7 @@ describe('ChildWriter Utils', function() {
]); ]);
}); });
it('should ignore spaces in between', function() { it('should ignore spaces in between', function () {
const input = '{"id":"foo"} \n {"id":"bar"}\n {"id":"baz"}'; const input = '{"id":"foo"} \n {"id":"bar"}\n {"id":"baz"}';
m.chai.expect(utils.splitObjectLines(input)).to.deep.equal([ m.chai.expect(utils.splitObjectLines(input)).to.deep.equal([
'{"id":"foo"}', '{"id":"foo"}',
@ -41,7 +39,7 @@ describe('ChildWriter Utils', function() {
]); ]);
}); });
it('should ignore multiple new lines', function() { it('should ignore multiple new lines', function () {
const input = '{"id":"foo"}\n\n\n\n{"id":"bar"}\n\n{"id":"baz"}'; const input = '{"id":"foo"}\n\n\n\n{"id":"bar"}\n\n{"id":"baz"}';
m.chai.expect(utils.splitObjectLines(input)).to.deep.equal([ m.chai.expect(utils.splitObjectLines(input)).to.deep.equal([
'{"id":"foo"}', '{"id":"foo"}',
@ -50,7 +48,7 @@ describe('ChildWriter Utils', function() {
]); ]);
}); });
it('should ignore new lines inside properties', function() { it('should ignore new lines inside properties', function () {
const input = '{"id":"foo\nbar"}\n{"id":"\nhello\n"}'; const input = '{"id":"foo\nbar"}\n{"id":"\nhello\n"}';
m.chai.expect(utils.splitObjectLines(input)).to.deep.equal([ m.chai.expect(utils.splitObjectLines(input)).to.deep.equal([
'{"id":"foo\nbar"}', '{"id":"foo\nbar"}',
@ -58,7 +56,7 @@ describe('ChildWriter Utils', function() {
]); ]);
}); });
it('should handle carriage returns', function() { it('should handle carriage returns', function () {
const input = '{"id":"foo"}\r\n{"id":"bar"}\r\n{"id":"baz"}'; const input = '{"id":"foo"}\r\n{"id":"bar"}\r\n{"id":"baz"}';
m.chai.expect(utils.splitObjectLines(input)).to.deep.equal([ m.chai.expect(utils.splitObjectLines(input)).to.deep.equal([
'{"id":"foo"}', '{"id":"foo"}',
@ -67,7 +65,7 @@ describe('ChildWriter Utils', function() {
]); ]);
}); });
it('should ignore multiple carriage returns', function() { it('should ignore multiple carriage returns', function () {
const input = '{"id":"foo"}\r\n\r\n{"id":"bar"}\r\n\r\n\r\n{"id":"baz"}'; const input = '{"id":"foo"}\r\n\r\n{"id":"bar"}\r\n\r\n\r\n{"id":"baz"}';
m.chai.expect(utils.splitObjectLines(input)).to.deep.equal([ m.chai.expect(utils.splitObjectLines(input)).to.deep.equal([
'{"id":"foo"}', '{"id":"foo"}',
@ -75,7 +73,5 @@ describe('ChildWriter Utils', function() {
'{"id":"baz"}' '{"id":"baz"}'
]); ]);
}); });
}); });
}); });

View File

@ -1,3 +1,19 @@
/*
* Copyright 2017 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'; 'use strict';
const _ = require('lodash'); const _ = require('lodash');
@ -5,14 +21,12 @@ const m = require('mochainon');
const angular = require('angular'); const angular = require('angular');
require('angular-mocks'); require('angular-mocks');
describe('Browser: DriveSelector', function() { describe('Browser: DriveSelector', function () {
beforeEach(angular.mock.module( beforeEach(angular.mock.module(
require('../../../lib/gui/components/drive-selector/drive-selector') require('../../../lib/gui/components/drive-selector/drive-selector')
)); ));
describe('DriveSelectorController', function() { describe('DriveSelectorController', function () {
let $controller; let $controller;
let $rootScope; let $rootScope;
let $q; let $q;
@ -21,7 +35,7 @@ describe('Browser: DriveSelector', function() {
let controller; let controller;
beforeEach(angular.mock.inject(function( beforeEach(angular.mock.inject(function (
_$controller_, _$controller_,
_$rootScope_, _$rootScope_,
_$q_, _$q_,
@ -43,14 +57,13 @@ describe('Browser: DriveSelector', function() {
}); });
}); });
describe('.memoizeImmutableListReference()', function() { describe('.memoizeImmutableListReference()', function () {
it('constant true should return memoized true', function () {
it('constant true should return memoized true', function() {
const memoizedConstTrue = controller.memoizeImmutableListReference(_.constant(true)); const memoizedConstTrue = controller.memoizeImmutableListReference(_.constant(true));
m.chai.expect(memoizedConstTrue()).to.be.true; m.chai.expect(memoizedConstTrue()).to.be.true;
}); });
it('should reflect state changes', function() { it('should reflect state changes', function () {
let stateA = false; let stateA = false;
const memoizedStateA = controller.memoizeImmutableListReference(() => { const memoizedStateA = controller.memoizeImmutableListReference(() => {
return stateA; return stateA;
@ -63,14 +76,14 @@ describe('Browser: DriveSelector', function() {
m.chai.expect(memoizedStateA()).to.be.true; m.chai.expect(memoizedStateA()).to.be.true;
}); });
it('should reflect different arguments', function() { it('should reflect different arguments', function () {
const memoizedParameter = controller.memoizeImmutableListReference(_.identity); const memoizedParameter = controller.memoizeImmutableListReference(_.identity);
m.chai.expect(memoizedParameter(false)).to.be.false; m.chai.expect(memoizedParameter(false)).to.be.false;
m.chai.expect(memoizedParameter(true)).to.be.true; m.chai.expect(memoizedParameter(true)).to.be.true;
}); });
it('should handle equal angular objects with different hashes', function() { it('should handle equal angular objects with different hashes', function () {
const memoizedParameter = controller.memoizeImmutableListReference(_.identity); const memoizedParameter = controller.memoizeImmutableListReference(_.identity);
const angularObjectA = { const angularObjectA = {
$$hashKey: 1, $$hashKey: 1,
@ -84,9 +97,6 @@ describe('Browser: DriveSelector', function() {
m.chai.expect(memoizedParameter(angularObjectA)).to.equal(angularObjectA); m.chai.expect(memoizedParameter(angularObjectA)).to.equal(angularObjectA);
m.chai.expect(memoizedParameter(angularObjectB)).to.equal(angularObjectA); m.chai.expect(memoizedParameter(angularObjectB)).to.equal(angularObjectA);
}); });
}); });
}); });
}); });

View File

@ -1,3 +1,19 @@
/*
* Copyright 2017 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'; 'use strict';
const m = require('mochainon'); const m = require('mochainon');
@ -7,24 +23,21 @@ const path = require('path');
const angular = require('angular'); const angular = require('angular');
require('angular-mocks'); require('angular-mocks');
describe('Browser: SVGIcon', function() { describe('Browser: SVGIcon', function () {
beforeEach(angular.mock.module( beforeEach(angular.mock.module(
require('../../../lib/gui/components/svg-icon') require('../../../lib/gui/components/svg-icon')
)); ));
describe('svgIcon', function() { describe('svgIcon', function () {
let $compile; let $compile;
let $rootScope; let $rootScope;
beforeEach(angular.mock.inject(function(_$compile_, _$rootScope_) { beforeEach(angular.mock.inject(function (_$compile_, _$rootScope_) {
$compile = _$compile_; $compile = _$compile_;
$rootScope = _$rootScope_; $rootScope = _$rootScope_;
})); }));
it('should inline the svg contents in the element', function() { it('should inline the svg contents in the element', function () {
const icon = '../../../lib/gui/assets/etcher.svg'; const icon = '../../../lib/gui/assets/etcher.svg';
let iconContents = _.split(fs.readFileSync(path.join(__dirname, '../../../lib/gui/assets/etcher.svg'), { let iconContents = _.split(fs.readFileSync(path.join(__dirname, '../../../lib/gui/assets/etcher.svg'), {
encoding: 'utf8' encoding: 'utf8'
@ -49,7 +62,7 @@ describe('Browser: SVGIcon', function() {
m.chai.expect(compiledDoc.outerHTML).to.equal(originalDoc.outerHTML); m.chai.expect(compiledDoc.outerHTML).to.equal(originalDoc.outerHTML);
}); });
it('should accept an SVG in the path attribute', function() { it('should accept an SVG in the path attribute', function () {
const iconContents = '<svg><rect x="10" y="10" height="100" width="100" style="stroke:red;fill:blue;"/></svg>'; const iconContents = '<svg><rect x="10" y="10" height="100" width="100" style="stroke:red;fill:blue;"/></svg>';
const img = `<img src="data:image/svg+xml,${encodeURIComponent(iconContents)}">`; const img = `<img src="data:image/svg+xml,${encodeURIComponent(iconContents)}">`;
$rootScope.iconContents = iconContents; $rootScope.iconContents = iconContents;
@ -59,7 +72,7 @@ describe('Browser: SVGIcon', function() {
m.chai.expect(element.children().html()).to.equal(img); m.chai.expect(element.children().html()).to.equal(img);
}); });
it('should default the size to 40x40 pixels', function() { it('should default the size to 40x40 pixels', function () {
const icon = '../../../lib/gui/assets/etcher.svg'; const icon = '../../../lib/gui/assets/etcher.svg';
const element = $compile(`<svg-icon path="'${icon}'">Resin.io</svg-icon>`)($rootScope); const element = $compile(`<svg-icon path="'${icon}'">Resin.io</svg-icon>`)($rootScope);
$rootScope.$digest(); $rootScope.$digest();
@ -67,7 +80,7 @@ describe('Browser: SVGIcon', function() {
m.chai.expect(element.children().css('height')).to.equal('40px'); m.chai.expect(element.children().css('height')).to.equal('40px');
}); });
it('should be able to set a custom width', function() { it('should be able to set a custom width', function () {
const icon = '../../../lib/gui/assets/etcher.svg'; const icon = '../../../lib/gui/assets/etcher.svg';
const element = $compile(`<svg-icon path="'${icon}'" width="'20px'">Resin.io</svg-icon>`)($rootScope); const element = $compile(`<svg-icon path="'${icon}'" width="'20px'">Resin.io</svg-icon>`)($rootScope);
$rootScope.$digest(); $rootScope.$digest();
@ -75,14 +88,12 @@ describe('Browser: SVGIcon', function() {
m.chai.expect(element.children().css('height')).to.equal('40px'); m.chai.expect(element.children().css('height')).to.equal('40px');
}); });
it('should be able to set a custom height', function() { it('should be able to set a custom height', function () {
const icon = '../../../lib/gui/assets/etcher.svg'; const icon = '../../../lib/gui/assets/etcher.svg';
const element = $compile(`<svg-icon path="'${icon}'" height="'20px'">Resin.io</svg-icon>`)($rootScope); const element = $compile(`<svg-icon path="'${icon}'" height="'20px'">Resin.io</svg-icon>`)($rootScope);
$rootScope.$digest(); $rootScope.$digest();
m.chai.expect(element.children().css('width')).to.equal('40px'); m.chai.expect(element.children().css('width')).to.equal('40px');
m.chai.expect(element.children().css('height')).to.equal('20px'); m.chai.expect(element.children().css('height')).to.equal('20px');
}); });
}); });
}); });

View File

@ -21,22 +21,18 @@ const _ = require('lodash');
const units = require('../../../lib/shared/units'); const units = require('../../../lib/shared/units');
const updateNotifier = require('../../../lib/gui/components/update-notifier'); const updateNotifier = require('../../../lib/gui/components/update-notifier');
describe('Browser: updateNotifier', function() { describe('Browser: updateNotifier', function () {
describe('.UPDATE_NOTIFIER_SLEEP_DAYS', function () {
describe('.UPDATE_NOTIFIER_SLEEP_DAYS', function() { it('should be an integer', function () {
it('should be an integer', function() {
m.chai.expect(_.isInteger(updateNotifier.UPDATE_NOTIFIER_SLEEP_DAYS)).to.be.true; m.chai.expect(_.isInteger(updateNotifier.UPDATE_NOTIFIER_SLEEP_DAYS)).to.be.true;
}); });
it('should be greater than 0', function() { it('should be greater than 0', function () {
m.chai.expect(updateNotifier.UPDATE_NOTIFIER_SLEEP_DAYS > 0).to.be.true; m.chai.expect(updateNotifier.UPDATE_NOTIFIER_SLEEP_DAYS > 0).to.be.true;
}); });
}); });
describe('.shouldCheckForUpdates()', function() { describe('.shouldCheckForUpdates()', function () {
const UPDATE_NOTIFIER_SLEEP_MS = units.daysToMilliseconds(updateNotifier.UPDATE_NOTIFIER_SLEEP_DAYS); const UPDATE_NOTIFIER_SLEEP_MS = units.daysToMilliseconds(updateNotifier.UPDATE_NOTIFIER_SLEEP_DAYS);
_.each([ _.each([
@ -441,18 +437,14 @@ describe('Browser: updateNotifier', function() {
} }
], (testCase) => { ], (testCase) => {
it(_.join([ it(_.join([
`should return ${testCase.expected} if`, `should return ${testCase.expected} if`,
`lastSleptUpdateNotifier=${testCase.options.lastSleptUpdateNotifier},`, `lastSleptUpdateNotifier=${testCase.options.lastSleptUpdateNotifier},`,
`lastSleptUpdateNotifierVersion=${testCase.options.lastSleptUpdateNotifierVersion}, and`, `lastSleptUpdateNotifierVersion=${testCase.options.lastSleptUpdateNotifierVersion}, and`,
`currentVersion=${testCase.options.currentVersion}` `currentVersion=${testCase.options.currentVersion}`
], ' '), function() { ], ' '), function () {
m.chai.expect(updateNotifier.shouldCheckForUpdates(testCase.options)).to.equal(testCase.expected); m.chai.expect(updateNotifier.shouldCheckForUpdates(testCase.options)).to.equal(testCase.expected);
}); });
}); });
}); });
}); });

View File

@ -1,3 +1,19 @@
/*
* Copyright 2017 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'; 'use strict';
const m = require('mochainon'); const m = require('mochainon');
@ -7,15 +23,14 @@ const store = require('../../../lib/shared/store');
const settings = require('../../../lib/gui/models/settings'); const settings = require('../../../lib/gui/models/settings');
const localSettings = require('../../../lib/gui/models/local-settings'); const localSettings = require('../../../lib/gui/models/local-settings');
describe('Browser: settings', function() { describe('Browser: settings', function () {
beforeEach(function () {
beforeEach(function() {
return settings.reset(); return settings.reset();
}); });
const DEFAULT_SETTINGS = store.Defaults.get('settings').toJS(); const DEFAULT_SETTINGS = store.Defaults.get('settings').toJS();
it('should be able to set and read values', function() { it('should be able to set and read values', function () {
m.chai.expect(settings.get('foo')).to.be.undefined; m.chai.expect(settings.get('foo')).to.be.undefined;
return settings.set('foo', true).then(() => { return settings.set('foo', true).then(() => {
m.chai.expect(settings.get('foo')).to.be.true; m.chai.expect(settings.get('foo')).to.be.true;
@ -25,9 +40,8 @@ describe('Browser: settings', function() {
}); });
}); });
describe('.reset()', function() { describe('.reset()', function () {
it('should reset the settings to their default values', function () {
it('should reset the settings to their default values', function() {
m.chai.expect(settings.getAll()).to.deep.equal(DEFAULT_SETTINGS); m.chai.expect(settings.getAll()).to.deep.equal(DEFAULT_SETTINGS);
return settings.set('foo', 1234).then(() => { return settings.set('foo', 1234).then(() => {
m.chai.expect(settings.getAll()).to.not.deep.equal(DEFAULT_SETTINGS); m.chai.expect(settings.getAll()).to.not.deep.equal(DEFAULT_SETTINGS);
@ -37,7 +51,7 @@ describe('Browser: settings', function() {
}); });
}); });
it('should reset the local settings to their default values', function() { it('should reset the local settings to their default values', function () {
return settings.set('foo', 1234).then(localSettings.readAll).then((data) => { return settings.set('foo', 1234).then(localSettings.readAll).then((data) => {
m.chai.expect(data).to.not.deep.equal(DEFAULT_SETTINGS); m.chai.expect(data).to.not.deep.equal(DEFAULT_SETTINGS);
return settings.reset(); return settings.reset();
@ -46,25 +60,21 @@ describe('Browser: settings', function() {
}); });
}); });
describe('given the local settings are cleared', function() { describe('given the local settings are cleared', function () {
beforeEach(function () {
beforeEach(function() {
return localSettings.clear(); return localSettings.clear();
}); });
it('should set the local settings to their default values', function() { it('should set the local settings to their default values', function () {
return settings.reset().then(localSettings.readAll).then((data) => { return settings.reset().then(localSettings.readAll).then((data) => {
m.chai.expect(data).to.deep.equal(DEFAULT_SETTINGS); m.chai.expect(data).to.deep.equal(DEFAULT_SETTINGS);
}); });
}); });
}); });
}); });
describe('.assign()', function() { describe('.assign()', function () {
it('should throw if no settings', function (done) {
it('should throw if no settings', function(done) {
settings.assign().asCallback((error) => { settings.assign().asCallback((error) => {
m.chai.expect(error).to.be.an.instanceof(Error); m.chai.expect(error).to.be.an.instanceof(Error);
m.chai.expect(error.message).to.equal('Missing settings'); m.chai.expect(error.message).to.equal('Missing settings');
@ -72,7 +82,7 @@ describe('Browser: settings', function() {
}); });
}); });
it('should throw if setting an array', function(done) { it('should throw if setting an array', function (done) {
settings.assign({ settings.assign({
foo: 'bar', foo: 'bar',
bar: [ 1, 2, 3 ] bar: [ 1, 2, 3 ]
@ -83,7 +93,7 @@ describe('Browser: settings', function() {
}); });
}); });
it('should not override all settings', function() { it('should not override all settings', function () {
return settings.assign({ return settings.assign({
foo: 'bar', foo: 'bar',
bar: 'baz' bar: 'baz'
@ -95,7 +105,7 @@ describe('Browser: settings', function() {
}); });
}); });
it('should not store invalid settings to the local machine', function() { it('should not store invalid settings to the local machine', function () {
return localSettings.readAll().then((data) => { return localSettings.readAll().then((data) => {
m.chai.expect(data.foo).to.be.undefined; m.chai.expect(data.foo).to.be.undefined;
@ -113,7 +123,7 @@ describe('Browser: settings', function() {
}); });
}); });
it('should store the settings to the local machine', function() { it('should store the settings to the local machine', function () {
return localSettings.readAll().then((data) => { return localSettings.readAll().then((data) => {
m.chai.expect(data.foo).to.be.undefined; m.chai.expect(data.foo).to.be.undefined;
m.chai.expect(data.bar).to.be.undefined; m.chai.expect(data.bar).to.be.undefined;
@ -128,7 +138,7 @@ describe('Browser: settings', function() {
}); });
}); });
it('should not change the application state if storing to the local machine results in an error', function(done) { it('should not change the application state if storing to the local machine results in an error', function (done) {
settings.set('foo', 'bar').then(() => { settings.set('foo', 'bar').then(() => {
m.chai.expect(settings.get('foo')).to.equal('bar'); m.chai.expect(settings.get('foo')).to.equal('bar');
@ -146,12 +156,10 @@ describe('Browser: settings', function() {
}); });
}).catch(done); }).catch(done);
}); });
}); });
describe('.load()', function() { describe('.load()', function () {
it('should extend the application state with the local settings content', function () {
it('should extend the application state with the local settings content', function() {
const object = { const object = {
foo: 'bar' foo: 'bar'
}; };
@ -166,25 +174,23 @@ describe('Browser: settings', function() {
}); });
}); });
it('should keep the application state intact if there are no local settings', function() { it('should keep the application state intact if there are no local settings', function () {
m.chai.expect(settings.getAll()).to.deep.equal(DEFAULT_SETTINGS); m.chai.expect(settings.getAll()).to.deep.equal(DEFAULT_SETTINGS);
return localSettings.clear().then(settings.load).then(() => { return localSettings.clear().then(settings.load).then(() => {
m.chai.expect(settings.getAll()).to.deep.equal(DEFAULT_SETTINGS); m.chai.expect(settings.getAll()).to.deep.equal(DEFAULT_SETTINGS);
}); });
}); });
}); });
describe('.set()', function() { describe('.set()', function () {
it('should set an unknown key', function () {
it('should set an unknown key', function() {
m.chai.expect(settings.get('foobar')).to.be.undefined; m.chai.expect(settings.get('foobar')).to.be.undefined;
return settings.set('foobar', true).then(() => { return settings.set('foobar', true).then(() => {
m.chai.expect(settings.get('foobar')).to.be.true; m.chai.expect(settings.get('foobar')).to.be.true;
}); });
}); });
it('should reject if no key', function(done) { it('should reject if no key', function (done) {
settings.set(null, true).asCallback((error) => { settings.set(null, true).asCallback((error) => {
m.chai.expect(error).to.be.an.instanceof(Error); m.chai.expect(error).to.be.an.instanceof(Error);
m.chai.expect(error.message).to.equal('Missing setting key'); m.chai.expect(error.message).to.equal('Missing setting key');
@ -192,7 +198,7 @@ describe('Browser: settings', function() {
}); });
}); });
it('should throw if key is not a string', function(done) { it('should throw if key is not a string', function (done) {
settings.set(1234, true).asCallback((error) => { settings.set(1234, true).asCallback((error) => {
m.chai.expect(error).to.be.an.instanceof(Error); m.chai.expect(error).to.be.an.instanceof(Error);
m.chai.expect(error.message).to.equal('Invalid setting key: 1234'); m.chai.expect(error.message).to.equal('Invalid setting key: 1234');
@ -200,7 +206,7 @@ describe('Browser: settings', function() {
}); });
}); });
it('should throw if setting an object', function(done) { it('should throw if setting an object', function (done) {
settings.set('foo', { settings.set('foo', {
setting: 1 setting: 1
}).asCallback((error) => { }).asCallback((error) => {
@ -210,7 +216,7 @@ describe('Browser: settings', function() {
}); });
}); });
it('should throw if setting an array', function(done) { it('should throw if setting an array', function (done) {
settings.set('foo', [ 1, 2, 3 ]).asCallback((error) => { settings.set('foo', [ 1, 2, 3 ]).asCallback((error) => {
m.chai.expect(error).to.be.an.instanceof(Error); m.chai.expect(error).to.be.an.instanceof(Error);
m.chai.expect(error.message).to.equal('Invalid setting value: 1,2,3 for foo'); m.chai.expect(error.message).to.equal('Invalid setting value: 1,2,3 for foo');
@ -218,7 +224,7 @@ describe('Browser: settings', function() {
}); });
}); });
it('should set the key to undefined if no value', function() { it('should set the key to undefined if no value', function () {
return settings.set('foo', 'bar').then(() => { return settings.set('foo', 'bar').then(() => {
m.chai.expect(settings.get('foo')).to.equal('bar'); m.chai.expect(settings.get('foo')).to.equal('bar');
return settings.set('foo'); return settings.set('foo');
@ -227,7 +233,7 @@ describe('Browser: settings', function() {
}); });
}); });
it('should store the setting to the local machine', function() { it('should store the setting to the local machine', function () {
return localSettings.readAll().then((data) => { return localSettings.readAll().then((data) => {
m.chai.expect(data.foo).to.be.undefined; m.chai.expect(data.foo).to.be.undefined;
return settings.set('foo', 'bar'); return settings.set('foo', 'bar');
@ -236,7 +242,7 @@ describe('Browser: settings', function() {
}); });
}); });
it('should not store invalid settings to the local machine', function() { it('should not store invalid settings to the local machine', function () {
return localSettings.readAll().then((data) => { return localSettings.readAll().then((data) => {
m.chai.expect(data.foo).to.be.undefined; m.chai.expect(data.foo).to.be.undefined;
@ -252,7 +258,7 @@ describe('Browser: settings', function() {
}); });
}); });
it('should not change the application state if storing to the local machine results in an error', function(done) { it('should not change the application state if storing to the local machine results in an error', function (done) {
settings.set('foo', 'bar').then(() => { settings.set('foo', 'bar').then(() => {
m.chai.expect(settings.get('foo')).to.equal('bar'); m.chai.expect(settings.get('foo')).to.equal('bar');
@ -268,15 +274,11 @@ describe('Browser: settings', function() {
}); });
}).catch(done); }).catch(done);
}); });
}); });
describe('.getAll()', function() { describe('.getAll()', function () {
it('should initial return all default values', function () {
it('should initial return all default values', function() {
m.chai.expect(settings.getAll()).to.deep.equal(DEFAULT_SETTINGS); m.chai.expect(settings.getAll()).to.deep.equal(DEFAULT_SETTINGS);
}); });
}); });
}); });

View File

@ -1,3 +1,19 @@
/*
* Copyright 2017 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'; 'use strict';
const m = require('mochainon'); const m = require('mochainon');
@ -5,21 +21,19 @@ const os = require('os');
const drivelist = require('drivelist'); const drivelist = require('drivelist');
const driveScanner = require('../../../lib/gui/modules/drive-scanner'); const driveScanner = require('../../../lib/gui/modules/drive-scanner');
describe('Browser: driveScanner', function() { describe('Browser: driveScanner', function () {
describe('given no available drives', function () {
describe('given no available drives', function() { beforeEach(function () {
beforeEach(function() {
this.drivelistStub = m.sinon.stub(drivelist, 'list'); this.drivelistStub = m.sinon.stub(drivelist, 'list');
this.drivelistStub.yields(null, []); this.drivelistStub.yields(null, []);
}); });
afterEach(function() { afterEach(function () {
this.drivelistStub.restore(); this.drivelistStub.restore();
}); });
it('should emit an empty array', function(done) { it('should emit an empty array', function (done) {
driveScanner.once('drives', function(drives) { driveScanner.once('drives', function (drives) {
m.chai.expect(drives).to.deep.equal([]); m.chai.expect(drives).to.deep.equal([]);
driveScanner.stop(); driveScanner.stop();
done(); done();
@ -27,12 +41,10 @@ describe('Browser: driveScanner', function() {
driveScanner.start(); driveScanner.start();
}); });
}); });
describe('given only system available drives', function() { describe('given only system available drives', function () {
beforeEach(function () {
beforeEach(function() {
this.drivelistStub = m.sinon.stub(drivelist, 'list'); this.drivelistStub = m.sinon.stub(drivelist, 'list');
this.drivelistStub.yields(null, [ { this.drivelistStub.yields(null, [ {
device: '/dev/sda', device: '/dev/sda',
@ -47,12 +59,12 @@ describe('Browser: driveScanner', function() {
} ]); } ]);
}); });
afterEach(function() { afterEach(function () {
this.drivelistStub.restore(); this.drivelistStub.restore();
}); });
it('should emit an empty array', function(done) { it('should emit an empty array', function (done) {
driveScanner.once('drives', function(drives) { driveScanner.once('drives', function (drives) {
m.chai.expect(drives).to.deep.equal([]); m.chai.expect(drives).to.deep.equal([]);
driveScanner.stop(); driveScanner.stop();
done(); done();
@ -60,23 +72,20 @@ describe('Browser: driveScanner', function() {
driveScanner.start(); driveScanner.start();
}); });
}); });
describe('given linux', function() { describe('given linux', function () {
beforeEach(function () {
beforeEach(function() {
this.osPlatformStub = m.sinon.stub(os, 'platform'); this.osPlatformStub = m.sinon.stub(os, 'platform');
this.osPlatformStub.returns('linux'); this.osPlatformStub.returns('linux');
}); });
afterEach(function() { afterEach(function () {
this.osPlatformStub.restore(); this.osPlatformStub.restore();
}); });
describe('given available drives', function() { describe('given available drives', function () {
beforeEach(function () {
beforeEach(function() {
this.drivelistStub = m.sinon.stub(drivelist, 'list'); this.drivelistStub = m.sinon.stub(drivelist, 'list');
this.drivelistStub.yields(null, [ this.drivelistStub.yields(null, [
{ {
@ -118,12 +127,12 @@ describe('Browser: driveScanner', function() {
]); ]);
}); });
afterEach(function() { afterEach(function () {
this.drivelistStub.restore(); this.drivelistStub.restore();
}); });
it('should emit the non removable drives', function(done) { it('should emit the non removable drives', function (done) {
driveScanner.once('drives', function(drives) { driveScanner.once('drives', function (drives) {
m.chai.expect(drives).to.deep.equal([ m.chai.expect(drives).to.deep.equal([
{ {
device: '/dev/sdb', device: '/dev/sdb',
@ -157,25 +166,21 @@ describe('Browser: driveScanner', function() {
driveScanner.start(); driveScanner.start();
}); });
}); });
}); });
describe('given windows', function() { describe('given windows', function () {
beforeEach(function () {
beforeEach(function() {
this.osPlatformStub = m.sinon.stub(os, 'platform'); this.osPlatformStub = m.sinon.stub(os, 'platform');
this.osPlatformStub.returns('win32'); this.osPlatformStub.returns('win32');
}); });
afterEach(function() { afterEach(function () {
this.osPlatformStub.restore(); this.osPlatformStub.restore();
}); });
describe('given available drives', function() { describe('given available drives', function () {
beforeEach(function () {
beforeEach(function() {
this.drivelistStub = m.sinon.stub(drivelist, 'list'); this.drivelistStub = m.sinon.stub(drivelist, 'list');
this.drivelistStub.yields(null, [ this.drivelistStub.yields(null, [
{ {
@ -213,12 +218,12 @@ describe('Browser: driveScanner', function() {
]); ]);
}); });
afterEach(function() { afterEach(function () {
this.drivelistStub.restore(); this.drivelistStub.restore();
}); });
it('should emit the non removable drives', function(done) { it('should emit the non removable drives', function (done) {
driveScanner.once('drives', function(drives) { driveScanner.once('drives', function (drives) {
m.chai.expect(drives).to.deep.equal([ m.chai.expect(drives).to.deep.equal([
{ {
device: '\\\\.\\PHYSICALDRIVE2', device: '\\\\.\\PHYSICALDRIVE2',
@ -248,12 +253,10 @@ describe('Browser: driveScanner', function() {
driveScanner.start(); driveScanner.start();
}); });
}); });
describe('given a drive with a single drive letters', function() { describe('given a drive with a single drive letters', function () {
beforeEach(function () {
beforeEach(function() {
this.drivelistStub = m.sinon.stub(drivelist, 'list'); this.drivelistStub = m.sinon.stub(drivelist, 'list');
this.drivelistStub.yields(null, [ this.drivelistStub.yields(null, [
{ {
@ -271,12 +274,12 @@ describe('Browser: driveScanner', function() {
]); ]);
}); });
afterEach(function() { afterEach(function () {
this.drivelistStub.restore(); this.drivelistStub.restore();
}); });
it('should use the drive letter as the name', function(done) { it('should use the drive letter as the name', function (done) {
driveScanner.once('drives', function(drives) { driveScanner.once('drives', function (drives) {
m.chai.expect(drives).to.have.length(1); m.chai.expect(drives).to.have.length(1);
m.chai.expect(drives[0].displayName).to.equal('F:'); m.chai.expect(drives[0].displayName).to.equal('F:');
driveScanner.stop(); driveScanner.stop();
@ -285,12 +288,10 @@ describe('Browser: driveScanner', function() {
driveScanner.start(); driveScanner.start();
}); });
}); });
describe('given a drive with multiple drive letters', function() { describe('given a drive with multiple drive letters', function () {
beforeEach(function () {
beforeEach(function() {
this.drivesListStub = m.sinon.stub(drivelist, 'list'); this.drivesListStub = m.sinon.stub(drivelist, 'list');
this.drivesListStub.yields(null, [ this.drivesListStub.yields(null, [
{ {
@ -314,12 +315,12 @@ describe('Browser: driveScanner', function() {
]); ]);
}); });
afterEach(function() { afterEach(function () {
this.drivesListStub.restore(); this.drivesListStub.restore();
}); });
it('should join all the mountpoints in `name`', function(done) { it('should join all the mountpoints in `name`', function (done) {
driveScanner.once('drives', function(drives) { driveScanner.once('drives', function (drives) {
m.chai.expect(drives).to.have.length(1); m.chai.expect(drives).to.have.length(1);
m.chai.expect(drives[0].displayName).to.equal('F:, G:, H:'); m.chai.expect(drives[0].displayName).to.equal('F:, G:, H:');
driveScanner.stop(); driveScanner.stop();
@ -328,24 +329,21 @@ describe('Browser: driveScanner', function() {
driveScanner.start(); driveScanner.start();
}); });
}); });
}); });
describe('given an error when listing the drives', function() { describe('given an error when listing the drives', function () {
beforeEach(function () {
beforeEach(function() {
this.drivesListStub = m.sinon.stub(drivelist, 'list'); this.drivesListStub = m.sinon.stub(drivelist, 'list');
this.drivesListStub.yields(new Error('scan error')); this.drivesListStub.yields(new Error('scan error'));
}); });
afterEach(function() { afterEach(function () {
this.drivesListStub.restore(); this.drivesListStub.restore();
}); });
it('should emit the error', function(done) { it('should emit the error', function (done) {
driveScanner.on('error', function(error) { driveScanner.on('error', function (error) {
m.chai.expect(error).to.be.an.instanceof(Error); m.chai.expect(error).to.be.an.instanceof(Error);
m.chai.expect(error.message).to.equal('scan error'); m.chai.expect(error.message).to.equal('scan error');
driveScanner.stop(); driveScanner.stop();
@ -354,7 +352,5 @@ describe('Browser: driveScanner', function() {
driveScanner.start(); driveScanner.start();
}); });
}); });
}); });

View File

@ -1,3 +1,19 @@
/*
* Copyright 2017 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'; 'use strict';
const m = require('mochainon'); const m = require('mochainon');
@ -5,29 +21,25 @@ const angular = require('angular');
const flashState = require('../../../lib/shared/models/flash-state'); const flashState = require('../../../lib/shared/models/flash-state');
require('angular-mocks'); require('angular-mocks');
describe('Browser: ImageWriter', function() { describe('Browser: ImageWriter', function () {
beforeEach(angular.mock.module( beforeEach(angular.mock.module(
require('../../../lib/gui/modules/image-writer') require('../../../lib/gui/modules/image-writer')
)); ));
describe('ImageWriterService', function() { describe('ImageWriterService', function () {
let $q; let $q;
let $rootScope; let $rootScope;
let ImageWriterService; let ImageWriterService;
beforeEach(angular.mock.inject(function(_$q_, _$rootScope_, _ImageWriterService_) { beforeEach(angular.mock.inject(function (_$q_, _$rootScope_, _ImageWriterService_) {
$q = _$q_; $q = _$q_;
$rootScope = _$rootScope_; $rootScope = _$rootScope_;
ImageWriterService = _ImageWriterService_; ImageWriterService = _ImageWriterService_;
})); }));
describe('.flash()', function() { describe('.flash()', function () {
describe('given a successful write', function () {
describe('given a successful write', function() { beforeEach(function () {
beforeEach(function() {
this.performWriteStub = m.sinon.stub(ImageWriterService, 'performWrite'); this.performWriteStub = m.sinon.stub(ImageWriterService, 'performWrite');
this.performWriteStub.returns($q.resolve({ this.performWriteStub.returns($q.resolve({
cancelled: false, cancelled: false,
@ -35,11 +47,11 @@ describe('Browser: ImageWriter', function() {
})); }));
}); });
afterEach(function() { afterEach(function () {
this.performWriteStub.restore(); this.performWriteStub.restore();
}); });
it('should set flashing to false when done', function() { it('should set flashing to false when done', function () {
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234' sourceChecksum: '1234'
@ -50,7 +62,7 @@ describe('Browser: ImageWriter', function() {
m.chai.expect(flashState.isFlashing()).to.be.false; m.chai.expect(flashState.isFlashing()).to.be.false;
}); });
it('should prevent writing more than once', function() { it('should prevent writing more than once', function () {
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234' sourceChecksum: '1234'
@ -62,11 +74,11 @@ describe('Browser: ImageWriter', function() {
m.chai.expect(this.performWriteStub).to.have.been.calledOnce; m.chai.expect(this.performWriteStub).to.have.been.calledOnce;
}); });
it('should reject the second flash attempt', function() { it('should reject the second flash attempt', function () {
ImageWriterService.flash('foo.img', '/dev/disk2'); ImageWriterService.flash('foo.img', '/dev/disk2');
let rejectError = null; let rejectError = null;
ImageWriterService.flash('foo.img', '/dev/disk2').catch(function(error) { ImageWriterService.flash('foo.img', '/dev/disk2').catch(function (error) {
rejectError = error; rejectError = error;
}); });
@ -75,43 +87,41 @@ describe('Browser: ImageWriter', function() {
m.chai.expect(rejectError).to.be.an.instanceof(Error); m.chai.expect(rejectError).to.be.an.instanceof(Error);
m.chai.expect(rejectError.message).to.equal('There is already a flash in progress'); m.chai.expect(rejectError.message).to.equal('There is already a flash in progress');
}); });
}); });
describe('given an unsuccessful write', function() { describe('given an unsuccessful write', function () {
beforeEach(function () {
beforeEach(function() {
this.performWriteStub = m.sinon.stub(ImageWriterService, 'performWrite'); this.performWriteStub = m.sinon.stub(ImageWriterService, 'performWrite');
this.error = new Error('write error'); this.error = new Error('write error');
this.error.code = 'FOO'; this.error.code = 'FOO';
this.performWriteStub.returns($q.reject(this.error)); this.performWriteStub.returns($q.reject(this.error));
}); });
afterEach(function() { afterEach(function () {
this.performWriteStub.restore(); this.performWriteStub.restore();
}); });
it('should set flashing to false when done', function() { it('should set flashing to false when done', function () {
ImageWriterService.flash('foo.img', '/dev/disk2').catch(angular.noop); ImageWriterService.flash('foo.img', '/dev/disk2').catch(angular.noop);
$rootScope.$apply(); $rootScope.$apply();
m.chai.expect(flashState.isFlashing()).to.be.false; m.chai.expect(flashState.isFlashing()).to.be.false;
}); });
it('should set the error code in the flash results', function() { it('should set the error code in the flash results', function () {
ImageWriterService.flash('foo.img', '/dev/disk2').catch(angular.noop); ImageWriterService.flash('foo.img', '/dev/disk2').catch(angular.noop);
$rootScope.$apply(); $rootScope.$apply();
const flashResults = flashState.getFlashResults(); const flashResults = flashState.getFlashResults();
m.chai.expect(flashResults.errorCode).to.equal('FOO'); m.chai.expect(flashResults.errorCode).to.equal('FOO');
}); });
it('should be rejected with the error', function() { it('should be rejected with the error', function () {
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234' sourceChecksum: '1234'
}); });
let rejection; let rejection;
ImageWriterService.flash('foo.img', '/dev/disk2').catch(function(error) { ImageWriterService.flash('foo.img', '/dev/disk2').catch(function (error) {
rejection = error; rejection = error;
}); });
@ -120,11 +130,7 @@ describe('Browser: ImageWriter', function() {
m.chai.expect(rejection).to.be.an.instanceof(Error); m.chai.expect(rejection).to.be.an.instanceof(Error);
m.chai.expect(rejection.message).to.equal('write error'); m.chai.expect(rejection.message).to.equal('write error');
}); });
}); });
}); });
}); });
}); });

View File

@ -20,26 +20,24 @@ const m = require('mochainon');
const angular = require('angular'); const angular = require('angular');
require('angular-mocks'); require('angular-mocks');
describe('Browser: OSDropzone', function() { describe('Browser: OSDropzone', function () {
beforeEach(angular.mock.module( beforeEach(angular.mock.module(
require('../../../lib/gui/os/dropzone/dropzone') require('../../../lib/gui/os/dropzone/dropzone')
)); ));
describe('osDropzone', function() { describe('osDropzone', function () {
let $compile; let $compile;
let $rootScope; let $rootScope;
let $timeout; let $timeout;
beforeEach(angular.mock.inject(function(_$compile_, _$rootScope_, _$timeout_) { beforeEach(angular.mock.inject(function (_$compile_, _$rootScope_, _$timeout_) {
$compile = _$compile_; $compile = _$compile_;
$rootScope = _$rootScope_; $rootScope = _$rootScope_;
$timeout = _$timeout_; $timeout = _$timeout_;
})); }));
it('should pass the file back to the callback as $file', function(done) { it('should pass the file back to the callback as $file', function (done) {
$rootScope.onDropZone = function(file) { $rootScope.onDropZone = function (file) {
m.chai.expect(file).to.deep.equal('/foo/bar'); m.chai.expect(file).to.deep.equal('/foo/bar');
done(); done();
}; };
@ -62,8 +60,8 @@ describe('Browser: OSDropzone', function() {
$timeout.flush(); $timeout.flush();
}); });
it('should pass undefined to the callback if not passing $file', function(done) { it('should pass undefined to the callback if not passing $file', function (done) {
$rootScope.onDropZone = function(file) { $rootScope.onDropZone = function (file) {
m.chai.expect(file).to.be.undefined; m.chai.expect(file).to.be.undefined;
done(); done();
}; };
@ -85,7 +83,5 @@ describe('Browser: OSDropzone', function() {
$rootScope.$digest(); $rootScope.$digest();
$timeout.flush(); $timeout.flush();
}); });
}); });
}); });

View File

@ -21,29 +21,27 @@ const angular = require('angular');
const electron = require('electron'); const electron = require('electron');
require('angular-mocks'); require('angular-mocks');
describe('Browser: OSOpenExternal', function() { describe('Browser: OSOpenExternal', function () {
beforeEach(angular.mock.module( beforeEach(angular.mock.module(
require('../../../lib/gui/os/open-external/open-external') require('../../../lib/gui/os/open-external/open-external')
)); ));
describe('osOpenExternal', function() { describe('osOpenExternal', function () {
let $compile; let $compile;
let $rootScope; let $rootScope;
beforeEach(angular.mock.inject(function(_$compile_, _$rootScope_) { beforeEach(angular.mock.inject(function (_$compile_, _$rootScope_) {
$compile = _$compile_; $compile = _$compile_;
$rootScope = _$rootScope_; $rootScope = _$rootScope_;
})); }));
it('should set the element cursor to pointer', function() { it('should set the element cursor to pointer', function () {
const element = $compile('<span os-open-external="https://resin.io">Resin.io</span>')($rootScope); const element = $compile('<span os-open-external="https://resin.io">Resin.io</span>')($rootScope);
$rootScope.$digest(); $rootScope.$digest();
m.chai.expect(element.css('cursor')).to.equal('pointer'); m.chai.expect(element.css('cursor')).to.equal('pointer');
}); });
it('should call Electron shell.openExternal with the attribute value', function() { it('should call Electron shell.openExternal with the attribute value', function () {
const shellExternalStub = m.sinon.stub(electron.shell, 'openExternal'); const shellExternalStub = m.sinon.stub(electron.shell, 'openExternal');
const element = $compile('<span os-open-external="https://resin.io">Resin.io</span>')($rootScope); const element = $compile('<span os-open-external="https://resin.io">Resin.io</span>')($rootScope);
element.triggerHandler('click'); element.triggerHandler('click');
@ -52,7 +50,7 @@ describe('Browser: OSOpenExternal', function() {
shellExternalStub.restore(); shellExternalStub.restore();
}); });
it('should not call Electron shell.openExternal if the attribute value is not defined', function() { it('should not call Electron shell.openExternal if the attribute value is not defined', function () {
const shellExternalStub = m.sinon.stub(electron.shell, 'openExternal'); const shellExternalStub = m.sinon.stub(electron.shell, 'openExternal');
const element = $compile('<span os-open-external>Resin.io</span>')($rootScope); const element = $compile('<span os-open-external>Resin.io</span>')($rootScope);
element.triggerHandler('click'); element.triggerHandler('click');
@ -60,7 +58,5 @@ describe('Browser: OSOpenExternal', function() {
m.chai.expect(shellExternalStub).to.not.have.been.called; m.chai.expect(shellExternalStub).to.not.have.been.called;
shellExternalStub.restore(); shellExternalStub.restore();
}); });
}); });
}); });

View File

@ -19,13 +19,10 @@
const m = require('mochainon'); const m = require('mochainon');
const windowProgress = require('../../../lib/gui/os/window-progress'); const windowProgress = require('../../../lib/gui/os/window-progress');
describe('Browser: WindowProgress', function() { describe('Browser: WindowProgress', function () {
describe('windowProgress', function () {
describe('windowProgress', function() { describe('given a stubbed current window', function () {
beforeEach(function () {
describe('given a stubbed current window', function() {
beforeEach(function() {
this.setProgressBarSpy = m.sinon.spy(); this.setProgressBarSpy = m.sinon.spy();
windowProgress.currentWindow = { windowProgress.currentWindow = {
@ -33,48 +30,41 @@ describe('Browser: WindowProgress', function() {
}; };
}); });
describe('.set()', function() { describe('.set()', function () {
it('should translate 0-100 percentages to 0-1 ranges', function () {
it('should translate 0-100 percentages to 0-1 ranges', function() {
windowProgress.set(85); windowProgress.set(85);
m.chai.expect(this.setProgressBarSpy).to.have.been.calledWith(0.85); m.chai.expect(this.setProgressBarSpy).to.have.been.calledWith(0.85);
}); });
it('should set 0 given 0', function() { it('should set 0 given 0', function () {
windowProgress.set(0); windowProgress.set(0);
m.chai.expect(this.setProgressBarSpy).to.have.been.calledWith(0); m.chai.expect(this.setProgressBarSpy).to.have.been.calledWith(0);
}); });
it('should set 1 given 100', function() { it('should set 1 given 100', function () {
windowProgress.set(100); windowProgress.set(100);
m.chai.expect(this.setProgressBarSpy).to.have.been.calledWith(1); m.chai.expect(this.setProgressBarSpy).to.have.been.calledWith(1);
}); });
it('should throw if given a percentage higher than 100', function() { it('should throw if given a percentage higher than 100', function () {
m.chai.expect(function() { m.chai.expect(function () {
windowProgress.set(101); windowProgress.set(101);
}).to.throw('Invalid percentage: 101'); }).to.throw('Invalid percentage: 101');
}); });
it('should throw if given a percentage less than 0', function() { it('should throw if given a percentage less than 0', function () {
m.chai.expect(function() { m.chai.expect(function () {
windowProgress.set(-1); windowProgress.set(-1);
}).to.throw('Invalid percentage: -1'); }).to.throw('Invalid percentage: -1');
}); });
}); });
describe('.clear()', function() { describe('.clear()', function () {
it('should set -1', function () {
it('should set -1', function() {
windowProgress.clear(); windowProgress.clear();
m.chai.expect(this.setProgressBarSpy).to.have.been.calledWith(-1); m.chai.expect(this.setProgressBarSpy).to.have.been.calledWith(-1);
}); });
}); });
}); });
}); });
}); });

View File

@ -1,3 +1,19 @@
/*
* Copyright 2017 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'; 'use strict';
const m = require('mochainon'); const m = require('mochainon');
@ -11,23 +27,20 @@ const availableDrives = require('../../../lib/shared/models/available-drives');
const selectionState = require('../../../lib/shared/models/selection-state'); const selectionState = require('../../../lib/shared/models/selection-state');
require('angular-mocks'); require('angular-mocks');
describe('Browser: MainPage', function() { describe('Browser: MainPage', function () {
beforeEach(angular.mock.module( beforeEach(angular.mock.module(
require('../../../lib/gui/pages/main/main') require('../../../lib/gui/pages/main/main')
)); ));
describe('MainController', function() { describe('MainController', function () {
let $controller; let $controller;
beforeEach(angular.mock.inject(function(_$controller_) { beforeEach(angular.mock.inject(function (_$controller_) {
$controller = _$controller_; $controller = _$controller_;
})); }));
describe('.shouldDriveStepBeDisabled()', function() { describe('.shouldDriveStepBeDisabled()', function () {
it('should return true if there is no drive', function () {
it('should return true if there is no drive', function() {
const controller = $controller('MainController', { const controller = $controller('MainController', {
$scope: {} $scope: {}
}); });
@ -37,7 +50,7 @@ describe('Browser: MainPage', function() {
m.chai.expect(controller.shouldDriveStepBeDisabled()).to.be.true; m.chai.expect(controller.shouldDriveStepBeDisabled()).to.be.true;
}); });
it('should return false if there is a drive', function() { it('should return false if there is a drive', function () {
const controller = $controller('MainController', { const controller = $controller('MainController', {
$scope: {} $scope: {}
}); });
@ -56,12 +69,10 @@ describe('Browser: MainPage', function() {
m.chai.expect(controller.shouldDriveStepBeDisabled()).to.be.false; m.chai.expect(controller.shouldDriveStepBeDisabled()).to.be.false;
}); });
}); });
describe('.shouldFlashStepBeDisabled()', function() { describe('.shouldFlashStepBeDisabled()', function () {
it('should return true if there is no selected drive nor image', function () {
it('should return true if there is no selected drive nor image', function() {
const controller = $controller('MainController', { const controller = $controller('MainController', {
$scope: {} $scope: {}
}); });
@ -71,7 +82,7 @@ describe('Browser: MainPage', function() {
m.chai.expect(controller.shouldFlashStepBeDisabled()).to.be.true; m.chai.expect(controller.shouldFlashStepBeDisabled()).to.be.true;
}); });
it('should return true if there is a selected image but no drive', function() { it('should return true if there is a selected image but no drive', function () {
const controller = $controller('MainController', { const controller = $controller('MainController', {
$scope: {} $scope: {}
}); });
@ -92,7 +103,7 @@ describe('Browser: MainPage', function() {
m.chai.expect(controller.shouldFlashStepBeDisabled()).to.be.true; m.chai.expect(controller.shouldFlashStepBeDisabled()).to.be.true;
}); });
it('should return true if there is a selected drive but no image', function() { it('should return true if there is a selected drive but no image', function () {
const controller = $controller('MainController', { const controller = $controller('MainController', {
$scope: {} $scope: {}
}); });
@ -113,7 +124,7 @@ describe('Browser: MainPage', function() {
m.chai.expect(controller.shouldFlashStepBeDisabled()).to.be.true; m.chai.expect(controller.shouldFlashStepBeDisabled()).to.be.true;
}); });
it('should return false if there is a selected drive and a selected image', function() { it('should return false if there is a selected drive and a selected image', function () {
const controller = $controller('MainController', { const controller = $controller('MainController', {
$scope: {} $scope: {}
}); });
@ -145,20 +156,17 @@ describe('Browser: MainPage', function() {
m.chai.expect(controller.shouldFlashStepBeDisabled()).to.be.false; m.chai.expect(controller.shouldFlashStepBeDisabled()).to.be.false;
}); });
}); });
}); });
describe('ImageSelectionController', function() { describe('ImageSelectionController', function () {
let $controller; let $controller;
beforeEach(angular.mock.inject(function(_$controller_) { beforeEach(angular.mock.inject(function (_$controller_) {
$controller = _$controller_; $controller = _$controller_;
})); }));
it('should contain all available extensions in mainSupportedExtensions and extraSupportedExtensions', function() { it('should contain all available extensions in mainSupportedExtensions and extraSupportedExtensions', function () {
const $scope = {}; const $scope = {};
const controller = $controller('ImageSelectionController', { const controller = $controller('ImageSelectionController', {
$scope $scope
@ -168,9 +176,8 @@ describe('Browser: MainPage', function() {
m.chai.expect(_.sortBy(extensions)).to.deep.equal(_.sortBy(supportedFormats.getAllExtensions())); m.chai.expect(_.sortBy(extensions)).to.deep.equal(_.sortBy(supportedFormats.getAllExtensions()));
}); });
describe('.getImageBasename()', function() { describe('.getImageBasename()', function () {
it('should return the basename of the selected image', function () {
it('should return the basename of the selected image', function() {
const controller = $controller('ImageSelectionController', { const controller = $controller('ImageSelectionController', {
$scope: {} $scope: {}
}); });
@ -191,7 +198,7 @@ describe('Browser: MainPage', function() {
selectionState.removeImage(); selectionState.removeImage();
}); });
it('should return an empty string if no selected image', function() { it('should return an empty string if no selected image', function () {
const controller = $controller('ImageSelectionController', { const controller = $controller('ImageSelectionController', {
$scope: {} $scope: {}
}); });
@ -199,22 +206,18 @@ describe('Browser: MainPage', function() {
selectionState.removeImage(); selectionState.removeImage();
m.chai.expect(controller.getImageBasename()).to.equal(''); m.chai.expect(controller.getImageBasename()).to.equal('');
}); });
}); });
}); });
describe('FlashController', function() { describe('FlashController', function () {
let $controller; let $controller;
beforeEach(angular.mock.inject(function(_$controller_) { beforeEach(angular.mock.inject(function (_$controller_) {
$controller = _$controller_; $controller = _$controller_;
})); }));
describe('.getProgressButtonLabel()', function() { describe('.getProgressButtonLabel()', function () {
it('should return "Flash!" given a clean state', function () {
it('should return "Flash!" given a clean state', function() {
const controller = $controller('FlashController', { const controller = $controller('FlashController', {
$scope: {} $scope: {}
}); });
@ -223,13 +226,12 @@ describe('Browser: MainPage', function() {
m.chai.expect(controller.getProgressButtonLabel()).to.equal('Flash!'); m.chai.expect(controller.getProgressButtonLabel()).to.equal('Flash!');
}); });
describe('given there is a flash in progress', function() { describe('given there is a flash in progress', function () {
beforeEach(function () {
beforeEach(function() {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
}); });
it('should report 0% if percentage == 0 but speed != 0', function() { it('should report 0% if percentage == 0 but speed != 0', function () {
const controller = $controller('FlashController', { const controller = $controller('FlashController', {
$scope: {} $scope: {}
}); });
@ -246,7 +248,7 @@ describe('Browser: MainPage', function() {
}); });
}); });
it('should handle percentage == 0, type = write, unmountOnSuccess', function() { it('should handle percentage == 0, type = write, unmountOnSuccess', function () {
const controller = $controller('FlashController', { const controller = $controller('FlashController', {
$scope: {} $scope: {}
}); });
@ -263,7 +265,7 @@ describe('Browser: MainPage', function() {
}); });
}); });
it('should handle percentage == 0, type = write, !unmountOnSuccess', function() { it('should handle percentage == 0, type = write, !unmountOnSuccess', function () {
const controller = $controller('FlashController', { const controller = $controller('FlashController', {
$scope: {} $scope: {}
}); });
@ -280,7 +282,7 @@ describe('Browser: MainPage', function() {
}); });
}); });
it('should handle percentage == 0, type = check, unmountOnSuccess', function() { it('should handle percentage == 0, type = check, unmountOnSuccess', function () {
const controller = $controller('FlashController', { const controller = $controller('FlashController', {
$scope: {} $scope: {}
}); });
@ -297,7 +299,7 @@ describe('Browser: MainPage', function() {
}); });
}); });
it('should handle percentage == 0, type = check, !unmountOnSuccess', function() { it('should handle percentage == 0, type = check, !unmountOnSuccess', function () {
const controller = $controller('FlashController', { const controller = $controller('FlashController', {
$scope: {} $scope: {}
}); });
@ -314,7 +316,7 @@ describe('Browser: MainPage', function() {
}); });
}); });
it('should handle percentage == 50, type = write, unmountOnSuccess', function() { it('should handle percentage == 50, type = write, unmountOnSuccess', function () {
const controller = $controller('FlashController', { const controller = $controller('FlashController', {
$scope: {} $scope: {}
}); });
@ -331,7 +333,7 @@ describe('Browser: MainPage', function() {
}); });
}); });
it('should handle percentage == 50, type = write, !unmountOnSuccess', function() { it('should handle percentage == 50, type = write, !unmountOnSuccess', function () {
const controller = $controller('FlashController', { const controller = $controller('FlashController', {
$scope: {} $scope: {}
}); });
@ -348,7 +350,7 @@ describe('Browser: MainPage', function() {
}); });
}); });
it('should handle percentage == 50, type = check, unmountOnSuccess', function() { it('should handle percentage == 50, type = check, unmountOnSuccess', function () {
const controller = $controller('FlashController', { const controller = $controller('FlashController', {
$scope: {} $scope: {}
}); });
@ -365,7 +367,7 @@ describe('Browser: MainPage', function() {
}); });
}); });
it('should handle percentage == 50, type = check, !unmountOnSuccess', function() { it('should handle percentage == 50, type = check, !unmountOnSuccess', function () {
const controller = $controller('FlashController', { const controller = $controller('FlashController', {
$scope: {} $scope: {}
}); });
@ -382,7 +384,7 @@ describe('Browser: MainPage', function() {
}); });
}); });
it('should handle percentage == 100, type = write, unmountOnSuccess', function() { it('should handle percentage == 100, type = write, unmountOnSuccess', function () {
const controller = $controller('FlashController', { const controller = $controller('FlashController', {
$scope: {} $scope: {}
}); });
@ -399,7 +401,7 @@ describe('Browser: MainPage', function() {
}); });
}); });
it('should handle percentage == 100, type = write, !unmountOnSuccess', function() { it('should handle percentage == 100, type = write, !unmountOnSuccess', function () {
const controller = $controller('FlashController', { const controller = $controller('FlashController', {
$scope: {} $scope: {}
}); });
@ -416,7 +418,7 @@ describe('Browser: MainPage', function() {
}); });
}); });
it('should handle percentage == 100, type = check, unmountOnSuccess', function() { it('should handle percentage == 100, type = check, unmountOnSuccess', function () {
const controller = $controller('FlashController', { const controller = $controller('FlashController', {
$scope: {} $scope: {}
}); });
@ -433,7 +435,7 @@ describe('Browser: MainPage', function() {
}); });
}); });
it('should handle percentage == 100, type = check, !unmountOnSuccess', function() { it('should handle percentage == 100, type = check, !unmountOnSuccess', function () {
const controller = $controller('FlashController', { const controller = $controller('FlashController', {
$scope: {} $scope: {}
}); });
@ -449,11 +451,7 @@ describe('Browser: MainPage', function() {
m.chai.expect(controller.getProgressButtonLabel()).to.equal('Finishing...'); m.chai.expect(controller.getProgressButtonLabel()).to.equal('Finishing...');
}); });
}); });
}); });
}); });
}); });
}); });

View File

@ -1,3 +1,19 @@
/*
* Copyright 2017 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'; 'use strict';
const m = require('mochainon'); const m = require('mochainon');
@ -5,23 +21,20 @@ const angular = require('angular');
require('angular-mocks'); require('angular-mocks');
const units = require('../../../lib/shared/units'); const units = require('../../../lib/shared/units');
describe('Browser: ByteSize', function() { describe('Browser: ByteSize', function () {
beforeEach(angular.mock.module( beforeEach(angular.mock.module(
require('../../../lib/gui/utils/byte-size/byte-size') require('../../../lib/gui/utils/byte-size/byte-size')
)); ));
describe('ClosestUnitFilter', function() { describe('ClosestUnitFilter', function () {
let closestUnitFilter; let closestUnitFilter;
beforeEach(angular.mock.inject(function(_closestUnitFilter_) { beforeEach(angular.mock.inject(function (_closestUnitFilter_) {
closestUnitFilter = _closestUnitFilter_; closestUnitFilter = _closestUnitFilter_;
})); }));
it('should expose lib/shared/units.js bytesToGigabytes()', function() { it('should expose lib/shared/units.js bytesToGigabytes()', function () {
m.chai.expect(closestUnitFilter).to.equal(units.bytesToClosestUnit); m.chai.expect(closestUnitFilter).to.equal(units.bytesToClosestUnit);
}); });
}); });
}); });

View File

@ -21,8 +21,7 @@ const angular = require('angular');
const packageJSON = require('../../../package.json'); const packageJSON = require('../../../package.json');
require('angular-mocks'); require('angular-mocks');
describe('Browser: ManifestBind', function() { describe('Browser: ManifestBind', function () {
beforeEach(angular.mock.module( beforeEach(angular.mock.module(
require('../../../lib/gui/utils/manifest-bind/manifest-bind') require('../../../lib/gui/utils/manifest-bind/manifest-bind')
)); ));
@ -30,56 +29,51 @@ describe('Browser: ManifestBind', function() {
let $compile; let $compile;
let $rootScope; let $rootScope;
beforeEach(angular.mock.inject(function(_$compile_, _$rootScope_) { beforeEach(angular.mock.inject(function (_$compile_, _$rootScope_) {
$compile = _$compile_; $compile = _$compile_;
$rootScope = _$rootScope_; $rootScope = _$rootScope_;
})); }));
describe('ManifestBindService', function() { describe('ManifestBindService', function () {
let ManifestBindService; let ManifestBindService;
beforeEach(angular.mock.inject(function(_ManifestBindService_) { beforeEach(angular.mock.inject(function (_ManifestBindService_) {
ManifestBindService = _ManifestBindService_; ManifestBindService = _ManifestBindService_;
})); }));
it('should be able to fetch top level properties', function() { it('should be able to fetch top level properties', function () {
const value = ManifestBindService.get('version'); const value = ManifestBindService.get('version');
m.chai.expect(value).to.equal(packageJSON.version); m.chai.expect(value).to.equal(packageJSON.version);
}); });
it('should be able to fetch nested properties', function() { it('should be able to fetch nested properties', function () {
const value = ManifestBindService.get('repository.type'); const value = ManifestBindService.get('repository.type');
m.chai.expect(value).to.equal(packageJSON.repository.type); m.chai.expect(value).to.equal(packageJSON.repository.type);
}); });
it('should return undefined if the property does not exist', function() { it('should return undefined if the property does not exist', function () {
const value = ManifestBindService.get('foo.bar'); const value = ManifestBindService.get('foo.bar');
m.chai.expect(value).to.be.undefined; m.chai.expect(value).to.be.undefined;
}); });
}); });
describe('manifestBind', function() { describe('manifestBind', function () {
it('should bind to top level properties', function () {
it('should bind to top level properties', function() {
const element = $compile('<span manifest-bind="version"></span>')($rootScope); const element = $compile('<span manifest-bind="version"></span>')($rootScope);
$rootScope.$digest(); $rootScope.$digest();
m.chai.expect(element.html()).to.equal(packageJSON.version); m.chai.expect(element.html()).to.equal(packageJSON.version);
}); });
it('should bind to nested properties', function() { it('should bind to nested properties', function () {
const element = $compile('<span manifest-bind="repository.type"></span>')($rootScope); const element = $compile('<span manifest-bind="repository.type"></span>')($rootScope);
$rootScope.$digest(); $rootScope.$digest();
m.chai.expect(element.html()).to.equal(packageJSON.repository.type); m.chai.expect(element.html()).to.equal(packageJSON.repository.type);
}); });
it('should throw if the property does not exist', function() { it('should throw if the property does not exist', function () {
m.chai.expect(function() { m.chai.expect(function () {
$compile('<span manifest-bind="foo.bar"></span>')($rootScope); $compile('<span manifest-bind="foo.bar"></span>')($rootScope);
}).to.throw('ManifestBind: Unknown property `foo.bar`'); }).to.throw('ManifestBind: Unknown property `foo.bar`');
}); });
}); });
}); });

View File

@ -23,33 +23,28 @@ const utils = require('../../../lib/image-stream/utils');
const tester = require('../tester'); const tester = require('../tester');
const ZIP_PATH = path.join(__dirname, '..', 'data', 'zip'); const ZIP_PATH = path.join(__dirname, '..', 'data', 'zip');
describe('ImageStream: Archive hooks: ZIP', function() { describe('ImageStream: Archive hooks: ZIP', function () {
this.timeout(tester.DEFAULT_IMAGE_TESTS_TIMEOUT); this.timeout(tester.DEFAULT_IMAGE_TESTS_TIMEOUT);
describe('.getEntries()', function() { describe('.getEntries()', function () {
describe('given an empty zip', function () {
describe('given an empty zip', function() { beforeEach(function () {
beforeEach(function() {
this.zip = path.join(ZIP_PATH, 'zip-directory-empty.zip'); this.zip = path.join(ZIP_PATH, 'zip-directory-empty.zip');
}); });
it('should become an empty array', function() { it('should become an empty array', function () {
return zipHooks.getEntries(this.zip).then((entries) => { return zipHooks.getEntries(this.zip).then((entries) => {
m.chai.expect(entries).to.deep.equal([]); m.chai.expect(entries).to.deep.equal([]);
}); });
}); });
}); });
describe('given a zip with multiple files in it', function() { describe('given a zip with multiple files in it', function () {
beforeEach(function () {
beforeEach(function() {
this.zip = path.join(ZIP_PATH, 'zip-directory-multiple-images.zip'); this.zip = path.join(ZIP_PATH, 'zip-directory-multiple-images.zip');
}); });
it('should become all entries', function() { it('should become all entries', function () {
return zipHooks.getEntries(this.zip).then((entries) => { return zipHooks.getEntries(this.zip).then((entries) => {
m.chai.expect(entries).to.deep.equal([ m.chai.expect(entries).to.deep.equal([
{ {
@ -63,16 +58,14 @@ describe('ImageStream: Archive hooks: ZIP', function() {
]); ]);
}); });
}); });
}); });
describe('given a zip with nested files in it', function() { describe('given a zip with nested files in it', function () {
beforeEach(function () {
beforeEach(function() {
this.zip = path.join(ZIP_PATH, 'zip-directory-nested-misc.zip'); this.zip = path.join(ZIP_PATH, 'zip-directory-nested-misc.zip');
}); });
it('should become all entries', function() { it('should become all entries', function () {
return zipHooks.getEntries(this.zip).then((entries) => { return zipHooks.getEntries(this.zip).then((entries) => {
m.chai.expect(entries).to.deep.equal([ m.chai.expect(entries).to.deep.equal([
{ {
@ -86,18 +79,15 @@ describe('ImageStream: Archive hooks: ZIP', function() {
]); ]);
}); });
}); });
}); });
}); });
describe('.extractFile()', function() { describe('.extractFile()', function () {
beforeEach(function () {
beforeEach(function() {
this.zip = path.join(ZIP_PATH, 'zip-directory-nested-misc.zip'); this.zip = path.join(ZIP_PATH, 'zip-directory-nested-misc.zip');
}); });
it('should be able to extract a top-level file', function() { it('should be able to extract a top-level file', function () {
const fileName = 'zip-directory-nested-misc/foo'; const fileName = 'zip-directory-nested-misc/foo';
return zipHooks.getEntries(this.zip).then((entries) => { return zipHooks.getEntries(this.zip).then((entries) => {
return zipHooks.extractFile(this.zip, entries, fileName); return zipHooks.extractFile(this.zip, entries, fileName);
@ -106,7 +96,7 @@ describe('ImageStream: Archive hooks: ZIP', function() {
}); });
}); });
it('should be able to extract a nested file', function() { it('should be able to extract a nested file', function () {
const fileName = 'zip-directory-nested-misc/hello/there/bar'; const fileName = 'zip-directory-nested-misc/hello/there/bar';
return zipHooks.getEntries(this.zip).then((entries) => { return zipHooks.getEntries(this.zip).then((entries) => {
return zipHooks.extractFile(this.zip, entries, fileName); return zipHooks.extractFile(this.zip, entries, fileName);
@ -115,7 +105,7 @@ describe('ImageStream: Archive hooks: ZIP', function() {
}); });
}); });
it('should throw if the entry does not exist', function() { it('should throw if the entry does not exist', function () {
const fileName = 'zip-directory-nested-misc/xxxxxxxxxxxxxxxx'; const fileName = 'zip-directory-nested-misc/xxxxxxxxxxxxxxxx';
return zipHooks.getEntries(this.zip).then((entries) => { return zipHooks.getEntries(this.zip).then((entries) => {
return zipHooks.extractFile(this.zip, entries, fileName); return zipHooks.extractFile(this.zip, entries, fileName);
@ -125,7 +115,7 @@ describe('ImageStream: Archive hooks: ZIP', function() {
}); });
}); });
it('should throw if the entry is a directory', function() { it('should throw if the entry is a directory', function () {
const fileName = 'zip-directory-nested-misc/hello'; const fileName = 'zip-directory-nested-misc/hello';
return zipHooks.getEntries(this.zip).then((entries) => { return zipHooks.getEntries(this.zip).then((entries) => {
return zipHooks.extractFile(this.zip, entries, fileName); return zipHooks.extractFile(this.zip, entries, fileName);
@ -134,7 +124,5 @@ describe('ImageStream: Archive hooks: ZIP', function() {
m.chai.expect(error.message).to.equal(`Invalid entry: ${fileName}`); m.chai.expect(error.message).to.equal(`Invalid entry: ${fileName}`);
}); });
}); });
}); });
}); });

View File

@ -25,29 +25,25 @@ const BZ2_PATH = path.join(DATA_PATH, 'bz2');
const imageStream = require('../../lib/image-stream/index'); const imageStream = require('../../lib/image-stream/index');
const tester = require('./tester'); const tester = require('./tester');
describe('ImageStream: BZ2', function() { describe('ImageStream: BZ2', function () {
this.timeout(tester.DEFAULT_IMAGE_TESTS_TIMEOUT); this.timeout(tester.DEFAULT_IMAGE_TESTS_TIMEOUT);
describe('compression method', function() { describe('compression method', function () {
describe('bzip2 level 9', function () {
describe('bzip2 level 9', function() {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(BZ2_PATH, 'etcher-test-9.img.bz2'), path.join(BZ2_PATH, 'etcher-test-9.img.bz2'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
}); });
describe('bzip2 level 1', function() { describe('bzip2 level 1', function () {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(BZ2_PATH, 'etcher-test.img.bz2'), path.join(BZ2_PATH, 'etcher-test.img.bz2'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
}); });
}); });
describe('.getImageMetadata()', function() { describe('.getImageMetadata()', function () {
it('should return the correct metadata', function () {
it('should return the correct metadata', function() {
const image = path.join(BZ2_PATH, 'etcher-test.img.bz2'); const image = path.join(BZ2_PATH, 'etcher-test.img.bz2');
const expectedSize = fs.statSync(image).size; const expectedSize = fs.statSync(image).size;
@ -69,7 +65,5 @@ describe('ImageStream: BZ2', function() {
}); });
}); });
}); });
}); });
}); });

View File

@ -23,13 +23,10 @@ const IMAGES_PATH = path.join(DATA_PATH, 'images');
const errors = require('../../lib/shared/errors'); const errors = require('../../lib/shared/errors');
const imageStream = require('../../lib/image-stream/index'); const imageStream = require('../../lib/image-stream/index');
describe('ImageStream: Directory', function() { describe('ImageStream: Directory', function () {
describe('.getFromFilePath()', function () {
describe('.getFromFilePath()', function() { describe('given a directory', function () {
it('should be rejected with an error', function (done) {
describe('given a directory', function() {
it('should be rejected with an error', function(done) {
imageStream.getFromFilePath(IMAGES_PATH).catch((error) => { imageStream.getFromFilePath(IMAGES_PATH).catch((error) => {
m.chai.expect(error).to.be.an.instanceof(Error); m.chai.expect(error).to.be.an.instanceof(Error);
m.chai.expect(errors.getTitle(error)).to.equal('Invalid image'); m.chai.expect(errors.getTitle(error)).to.equal('Invalid image');
@ -38,14 +35,11 @@ describe('ImageStream: Directory', function() {
done(); done();
}); });
}); });
}); });
}); });
describe('.getImageMetadata()', function() { describe('.getImageMetadata()', function () {
it('should be rejected with an error', function (done) {
it('should be rejected with an error', function(done) {
imageStream.getImageMetadata(IMAGES_PATH).catch((error) => { imageStream.getImageMetadata(IMAGES_PATH).catch((error) => {
m.chai.expect(error).to.be.an.instanceof(Error); m.chai.expect(error).to.be.an.instanceof(Error);
m.chai.expect(errors.getTitle(error)).to.equal('Invalid image'); m.chai.expect(errors.getTitle(error)).to.equal('Invalid image');
@ -54,7 +48,5 @@ describe('ImageStream: Directory', function() {
done(); done();
}); });
}); });
}); });
}); });

View File

@ -25,60 +25,53 @@ const DMG_PATH = path.join(DATA_PATH, 'dmg');
const imageStream = require('../../lib/image-stream/index'); const imageStream = require('../../lib/image-stream/index');
const tester = require('./tester'); const tester = require('./tester');
describe('ImageStream: DMG', function() { describe('ImageStream: DMG', function () {
this.timeout(tester.DEFAULT_IMAGE_TESTS_TIMEOUT); this.timeout(tester.DEFAULT_IMAGE_TESTS_TIMEOUT);
describe('compression method', function() { describe('compression method', function () {
describe('NONE', function () {
describe('NONE', function() {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(DMG_PATH, 'etcher-test-raw.dmg'), path.join(DMG_PATH, 'etcher-test-raw.dmg'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
}); });
describe('UDCO (ADC)', function() { describe('UDCO (ADC)', function () {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(DMG_PATH, 'etcher-test-adc.dmg'), path.join(DMG_PATH, 'etcher-test-adc.dmg'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
}); });
describe('UDZO (ZLIB)', function() { describe('UDZO (ZLIB)', function () {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(DMG_PATH, 'etcher-test-zlib.dmg'), path.join(DMG_PATH, 'etcher-test-zlib.dmg'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
}); });
describe('UDBZ (BZIP2)', function() { describe('UDBZ (BZIP2)', function () {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(DMG_PATH, 'etcher-test-bz2.dmg'), path.join(DMG_PATH, 'etcher-test-bz2.dmg'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
}); });
// NOTE: Skipped, as LZFSE is not supported by `udif` module yet // NOTE: Skipped, as LZFSE is not supported by `udif` module yet
describe.skip('ULFO (LZFSE)', function() { describe.skip('ULFO (LZFSE)', function () {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(DMG_PATH, 'etcher-test-lzfse.dmg'), path.join(DMG_PATH, 'etcher-test-lzfse.dmg'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
}); });
}); });
context('zlib compressed', function() { context('zlib compressed', function () {
describe('.getFromFilePath()', function () {
describe('.getFromFilePath()', function() { describe('given an dmg image', function () {
describe('given an dmg image', function() {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(DMG_PATH, 'etcher-test-zlib.dmg'), path.join(DMG_PATH, 'etcher-test-zlib.dmg'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
}); });
}); });
describe('.getImageMetadata()', function() { describe('.getImageMetadata()', function () {
it('should return the correct metadata', function () {
it('should return the correct metadata', function() {
const image = path.join(DMG_PATH, 'etcher-test-zlib.dmg'); const image = path.join(DMG_PATH, 'etcher-test-zlib.dmg');
const uncompressedSize = fs.statSync(path.join(IMAGES_PATH, 'etcher-test.img')).size; const uncompressedSize = fs.statSync(path.join(IMAGES_PATH, 'etcher-test.img')).size;
@ -99,26 +92,20 @@ describe('ImageStream: DMG', function() {
}); });
}); });
}); });
}); });
}); });
context('uncompressed', function() { context('uncompressed', function () {
describe('.getFromFilePath()', function () {
describe('.getFromFilePath()', function() { describe('given an dmg image', function () {
describe('given an dmg image', function() {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(DMG_PATH, 'etcher-test-raw.dmg'), path.join(DMG_PATH, 'etcher-test-raw.dmg'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
}); });
}); });
describe('.getImageMetadata()', function() { describe('.getImageMetadata()', function () {
it('should return the correct metadata', function () {
it('should return the correct metadata', function() {
const image = path.join(DMG_PATH, 'etcher-test-raw.dmg'); const image = path.join(DMG_PATH, 'etcher-test-raw.dmg');
const uncompressedSize = fs.statSync(path.join(IMAGES_PATH, 'etcher-test.img')).size; const uncompressedSize = fs.statSync(path.join(IMAGES_PATH, 'etcher-test.img')).size;
@ -139,19 +126,14 @@ describe('ImageStream: DMG', function() {
}); });
}); });
}); });
}); });
}); });
context('invalid', function() { context('invalid', function () {
describe('given an invalid dmg file', function () {
describe('given an invalid dmg file', function() {
tester.expectError( tester.expectError(
path.join(DATA_PATH, 'unrecognized', 'invalid.dmg'), path.join(DATA_PATH, 'unrecognized', 'invalid.dmg'),
'Invalid image', 'Invalid footer'); 'Invalid image', 'Invalid footer');
}); });
}); });
}); });

View File

@ -25,23 +25,19 @@ const GZ_PATH = path.join(DATA_PATH, 'gz');
const imageStream = require('../../lib/image-stream/index'); const imageStream = require('../../lib/image-stream/index');
const tester = require('./tester'); const tester = require('./tester');
describe('ImageStream: GZ', function() { describe('ImageStream: GZ', function () {
this.timeout(tester.DEFAULT_IMAGE_TESTS_TIMEOUT); this.timeout(tester.DEFAULT_IMAGE_TESTS_TIMEOUT);
describe('.getFromFilePath()', function() { describe('.getFromFilePath()', function () {
describe('given a gz image', function () {
describe('given a gz image', function() {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(GZ_PATH, 'etcher-test.img.gz'), path.join(GZ_PATH, 'etcher-test.img.gz'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
}); });
}); });
describe('.getImageMetadata()', function() { describe('.getImageMetadata()', function () {
it('should return the correct metadata', function () {
it('should return the correct metadata', function() {
const image = path.join(GZ_PATH, 'etcher-test.img.gz'); const image = path.join(GZ_PATH, 'etcher-test.img.gz');
const uncompressedSize = fs.statSync(path.join(IMAGES_PATH, 'etcher-test.img')).size; const uncompressedSize = fs.statSync(path.join(IMAGES_PATH, 'etcher-test.img')).size;
const compressedSize = fs.statSync(path.join(GZ_PATH, 'etcher-test.img.gz')).size; const compressedSize = fs.statSync(path.join(GZ_PATH, 'etcher-test.img.gz')).size;
@ -64,7 +60,5 @@ describe('ImageStream: GZ', function() {
}); });
}); });
}); });
}); });
}); });

View File

@ -24,25 +24,20 @@ const IMAGES_PATH = path.join(DATA_PATH, 'images');
const imageStream = require('../../lib/image-stream/index'); const imageStream = require('../../lib/image-stream/index');
const tester = require('./tester'); const tester = require('./tester');
describe('ImageStream: IMG', function() { describe('ImageStream: IMG', function () {
this.timeout(tester.DEFAULT_IMAGE_TESTS_TIMEOUT); this.timeout(tester.DEFAULT_IMAGE_TESTS_TIMEOUT);
describe('.getFromFilePath()', function() { describe('.getFromFilePath()', function () {
describe('given an img image', function () {
describe('given an img image', function() {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(IMAGES_PATH, 'etcher-test.img'), path.join(IMAGES_PATH, 'etcher-test.img'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
}); });
}); });
describe('.getImageMetadata()', function() { describe('.getImageMetadata()', function () {
context('Master Boot Record', function () {
context('Master Boot Record', function() { it('should return the correct metadata', function () {
it('should return the correct metadata', function() {
const image = path.join(IMAGES_PATH, 'etcher-test.img'); const image = path.join(IMAGES_PATH, 'etcher-test.img');
const expectedSize = fs.statSync(image).size; const expectedSize = fs.statSync(image).size;
@ -63,12 +58,10 @@ describe('ImageStream: IMG', function() {
}); });
}); });
}); });
}); });
context('GUID Partition Table', function() { context('GUID Partition Table', function () {
it('should return the correct metadata', function () {
it('should return the correct metadata', function() {
const image = path.join(IMAGES_PATH, 'etcher-gpt-test.img.gz'); const image = path.join(IMAGES_PATH, 'etcher-gpt-test.img.gz');
const uncompressedSize = 134217728; const uncompressedSize = 134217728;
const expectedSize = fs.statSync(image).size; const expectedSize = fs.statSync(image).size;
@ -91,9 +84,6 @@ describe('ImageStream: IMG', function() {
}); });
}); });
}); });
}); });
}); });
}); });

View File

@ -20,36 +20,32 @@ const m = require('mochainon');
const _ = require('lodash'); const _ = require('lodash');
const imageStream = require('../../lib/image-stream/index'); const imageStream = require('../../lib/image-stream/index');
describe('ImageStream', function() { describe('ImageStream', function () {
describe('.supportedFileTypes', function () {
describe('.supportedFileTypes', function() { it('should be an array', function () {
it('should be an array', function() {
m.chai.expect(_.isArray(imageStream.supportedFileTypes)).to.be.true; m.chai.expect(_.isArray(imageStream.supportedFileTypes)).to.be.true;
}); });
it('should not be empty', function() { it('should not be empty', function () {
m.chai.expect(_.isEmpty(imageStream.supportedFileTypes)).to.be.false; m.chai.expect(_.isEmpty(imageStream.supportedFileTypes)).to.be.false;
}); });
it('should contain only strings', function() { it('should contain only strings', function () {
m.chai.expect(_.every(_.map(imageStream.supportedFileTypes, function(fileType) { m.chai.expect(_.every(_.map(imageStream.supportedFileTypes, function (fileType) {
return _.isString(fileType.extension) && _.isString(fileType.type); return _.isString(fileType.extension) && _.isString(fileType.type);
}))).to.be.true; }))).to.be.true;
}); });
it('should not contain empty strings', function() { it('should not contain empty strings', function () {
m.chai.expect(_.every(_.map(imageStream.supportedFileTypes, function(fileType) { m.chai.expect(_.every(_.map(imageStream.supportedFileTypes, function (fileType) {
return !_.isEmpty(fileType.extension) && !_.isEmpty(fileType.type); return !_.isEmpty(fileType.extension) && !_.isEmpty(fileType.type);
}))).to.be.true; }))).to.be.true;
}); });
it('should not contain a leading period in any file type extension', function() { it('should not contain a leading period in any file type extension', function () {
m.chai.expect(_.every(_.map(imageStream.supportedFileTypes, function(fileType) { m.chai.expect(_.every(_.map(imageStream.supportedFileTypes, function (fileType) {
return _.first(fileType.extension) !== '.'; return _.first(fileType.extension) !== '.';
}))).to.be.true; }))).to.be.true;
}); });
}); });
}); });

View File

@ -24,23 +24,19 @@ const IMAGES_PATH = path.join(DATA_PATH, 'images');
const imageStream = require('../../lib/image-stream/index'); const imageStream = require('../../lib/image-stream/index');
const tester = require('./tester'); const tester = require('./tester');
describe('ImageStream: ISO', function() { describe('ImageStream: ISO', function () {
this.timeout(tester.DEFAULT_IMAGE_TESTS_TIMEOUT); this.timeout(tester.DEFAULT_IMAGE_TESTS_TIMEOUT);
describe('.getFromFilePath()', function() { describe('.getFromFilePath()', function () {
describe('given an iso image', function () {
describe('given an iso image', function() {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(IMAGES_PATH, 'etcher-test.iso'), path.join(IMAGES_PATH, 'etcher-test.iso'),
path.join(IMAGES_PATH, 'etcher-test.iso')); path.join(IMAGES_PATH, 'etcher-test.iso'));
}); });
}); });
describe('.getImageMetadata()', function() { describe('.getImageMetadata()', function () {
it('should return the correct metadata', function () {
it('should return the correct metadata', function() {
const image = path.join(IMAGES_PATH, 'etcher-test.iso'); const image = path.join(IMAGES_PATH, 'etcher-test.iso');
const expectedSize = fs.statSync(image).size; const expectedSize = fs.statSync(image).size;
@ -61,7 +57,5 @@ describe('ImageStream: ISO', function() {
}); });
}); });
}); });
}); });
}); });

View File

@ -34,19 +34,16 @@ const testMetadataProperty = (archivePath, propertyName, expectedValue) => {
}); });
}; };
describe('ImageStream: Metadata ZIP', function() { describe('ImageStream: Metadata ZIP', function () {
this.timeout(10000); this.timeout(10000);
describe('given an archive with an invalid `manifest.json`', function() { describe('given an archive with an invalid `manifest.json`', function () {
tester.expectError( tester.expectError(
path.join(ZIP_PATH, 'etcher-test-invalid-manifest.zip'), path.join(ZIP_PATH, 'etcher-test-invalid-manifest.zip'),
'Invalid archive manifest.json'); 'Invalid archive manifest.json');
describe('.getImageMetadata()', function() { describe('.getImageMetadata()', function () {
it('should be rejected with an error', function () {
it('should be rejected with an error', function() {
const image = path.join(ZIP_PATH, 'etcher-test-invalid-manifest.zip'); const image = path.join(ZIP_PATH, 'etcher-test-invalid-manifest.zip');
return imageStream.getImageMetadata(image).catch((error) => { return imageStream.getImageMetadata(image).catch((error) => {
@ -54,61 +51,56 @@ describe('ImageStream: Metadata ZIP', function() {
m.chai.expect(error.message).to.equal('Invalid archive manifest.json'); m.chai.expect(error.message).to.equal('Invalid archive manifest.json');
}); });
}); });
}); });
}); });
describe('given an archive with a `manifest.json`', function() { describe('given an archive with a `manifest.json`', function () {
const archive = path.join(ZIP_PATH, 'etcher-test-with-manifest.zip'); const archive = path.join(ZIP_PATH, 'etcher-test-with-manifest.zip');
tester.extractFromFilePath( tester.extractFromFilePath(
archive, archive,
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
it('should read the manifest name property', function() { it('should read the manifest name property', function () {
return testMetadataProperty(archive, 'name', 'Etcher Test'); return testMetadataProperty(archive, 'name', 'Etcher Test');
}); });
it('should read the manifest version property', function() { it('should read the manifest version property', function () {
return testMetadataProperty(archive, 'version', '1.0.0'); return testMetadataProperty(archive, 'version', '1.0.0');
}); });
it('should read the manifest url property', function() { it('should read the manifest url property', function () {
return testMetadataProperty(archive, 'url', 'https://www.example.com'); return testMetadataProperty(archive, 'url', 'https://www.example.com');
}); });
it('should read the manifest supportUrl property', function() { it('should read the manifest supportUrl property', function () {
const expectedValue = 'https://www.example.com/support/'; const expectedValue = 'https://www.example.com/support/';
return testMetadataProperty(archive, 'supportUrl', expectedValue); return testMetadataProperty(archive, 'supportUrl', expectedValue);
}); });
it('should read the manifest releaseNotesUrl property', function() { it('should read the manifest releaseNotesUrl property', function () {
const expectedValue = 'http://downloads.example.com/release_notes.txt'; const expectedValue = 'http://downloads.example.com/release_notes.txt';
return testMetadataProperty(archive, 'releaseNotesUrl', expectedValue); return testMetadataProperty(archive, 'releaseNotesUrl', expectedValue);
}); });
it('should read the manifest checksumType property', function() { it('should read the manifest checksumType property', function () {
return testMetadataProperty(archive, 'checksumType', 'md5'); return testMetadataProperty(archive, 'checksumType', 'md5');
}); });
it('should read the manifest checksum property', function() { it('should read the manifest checksum property', function () {
return testMetadataProperty(archive, 'checksum', 'add060b285d512f56c175b76b7ef1bee'); return testMetadataProperty(archive, 'checksum', 'add060b285d512f56c175b76b7ef1bee');
}); });
it('should read the manifest bytesToZeroOutFromTheBeginning property', function() { it('should read the manifest bytesToZeroOutFromTheBeginning property', function () {
return testMetadataProperty(archive, 'bytesToZeroOutFromTheBeginning', 512); return testMetadataProperty(archive, 'bytesToZeroOutFromTheBeginning', 512);
}); });
it('should read the manifest recommendedDriveSize property', function() { it('should read the manifest recommendedDriveSize property', function () {
return testMetadataProperty(archive, 'recommendedDriveSize', 4294967296); return testMetadataProperty(archive, 'recommendedDriveSize', 4294967296);
}); });
}); });
describe('given an archive with a `logo.svg`', function() { describe('given an archive with a `logo.svg`', function () {
const archive = path.join(ZIP_PATH, 'etcher-test-with-logo.zip'); const archive = path.join(ZIP_PATH, 'etcher-test-with-logo.zip');
const logo = [ const logo = [
@ -118,14 +110,12 @@ describe('ImageStream: Metadata ZIP', function() {
'' ''
].join('\n'); ].join('\n');
it('should read the logo contents', function() { it('should read the logo contents', function () {
return testMetadataProperty(archive, 'logo', logo); return testMetadataProperty(archive, 'logo', logo);
}); });
}); });
describe('given an archive with a bmap file', function() { describe('given an archive with a bmap file', function () {
const archive = path.join(ZIP_PATH, 'etcher-test-with-bmap.zip'); const archive = path.join(ZIP_PATH, 'etcher-test-with-bmap.zip');
const bmap = [ const bmap = [
@ -143,14 +133,12 @@ describe('ImageStream: Metadata ZIP', function() {
'' ''
].join('\n'); ].join('\n');
it('should read the bmap contents', function() { it('should read the bmap contents', function () {
return testMetadataProperty(archive, 'bmap', bmap); return testMetadataProperty(archive, 'bmap', bmap);
}); });
}); });
describe('given an archive with instructions', function() { describe('given an archive with instructions', function () {
const archive = path.join(ZIP_PATH, 'etcher-test-with-instructions.zip'); const archive = path.join(ZIP_PATH, 'etcher-test-with-instructions.zip');
const instructions = [ const instructions = [
@ -160,10 +148,8 @@ describe('ImageStream: Metadata ZIP', function() {
'' ''
].join('\n'); ].join('\n');
it('should read the instruction contents', function() { it('should read the instruction contents', function () {
return testMetadataProperty(archive, 'instructions', instructions); return testMetadataProperty(archive, 'instructions', instructions);
}); });
}); });
}); });

View File

@ -21,87 +21,83 @@ const path = require('path');
const DATA_PATH = path.join(__dirname, 'data'); const DATA_PATH = path.join(__dirname, 'data');
const mime = require('../../lib/image-stream/mime'); const mime = require('../../lib/image-stream/mime');
describe('ImageStream: MIME', function() { describe('ImageStream: MIME', function () {
describe('.getMimeTypeFromFileName()', function () {
describe('.getMimeTypeFromFileName()', function() { it('should resolve application/x-bzip2 for a bz2 archive', function () {
it('should resolve application/x-bzip2 for a bz2 archive', function() {
const file = path.join(DATA_PATH, 'bz2', 'etcher-test.img.bz2'); const file = path.join(DATA_PATH, 'bz2', 'etcher-test.img.bz2');
return mime.getMimeTypeFromFileName(file).then((type) => { return mime.getMimeTypeFromFileName(file).then((type) => {
m.chai.expect(type).to.equal('application/x-bzip2'); m.chai.expect(type).to.equal('application/x-bzip2');
}); });
}); });
it('should resolve application/x-xz for a xz archive', function() { it('should resolve application/x-xz for a xz archive', function () {
const file = path.join(DATA_PATH, 'xz', 'etcher-test.img.xz'); const file = path.join(DATA_PATH, 'xz', 'etcher-test.img.xz');
return mime.getMimeTypeFromFileName(file).then((type) => { return mime.getMimeTypeFromFileName(file).then((type) => {
m.chai.expect(type).to.equal('application/x-xz'); m.chai.expect(type).to.equal('application/x-xz');
}); });
}); });
it('should resolve application/gzip for a gz archive', function() { it('should resolve application/gzip for a gz archive', function () {
const file = path.join(DATA_PATH, 'gz', 'etcher-test.img.gz'); const file = path.join(DATA_PATH, 'gz', 'etcher-test.img.gz');
return mime.getMimeTypeFromFileName(file).then((type) => { return mime.getMimeTypeFromFileName(file).then((type) => {
m.chai.expect(type).to.equal('application/gzip'); m.chai.expect(type).to.equal('application/gzip');
}); });
}); });
it('should resolve application/zip for a zip archive', function() { it('should resolve application/zip for a zip archive', function () {
const file = path.join(DATA_PATH, 'zip', 'zip-directory-etcher-only.zip'); const file = path.join(DATA_PATH, 'zip', 'zip-directory-etcher-only.zip');
return mime.getMimeTypeFromFileName(file).then((type) => { return mime.getMimeTypeFromFileName(file).then((type) => {
m.chai.expect(type).to.equal('application/zip'); m.chai.expect(type).to.equal('application/zip');
}); });
}); });
it('should resolve application/octet-stream for an uncompressed image', function() { it('should resolve application/octet-stream for an uncompressed image', function () {
const file = path.join(DATA_PATH, 'images', 'etcher-test.img'); const file = path.join(DATA_PATH, 'images', 'etcher-test.img');
return mime.getMimeTypeFromFileName(file).then((type) => { return mime.getMimeTypeFromFileName(file).then((type) => {
m.chai.expect(type).to.equal('application/octet-stream'); m.chai.expect(type).to.equal('application/octet-stream');
}); });
}); });
it('should resolve application/x-iso9660-image for an uncompressed iso', function() { it('should resolve application/x-iso9660-image for an uncompressed iso', function () {
const file = path.join(DATA_PATH, 'images', 'etcher-test.iso'); const file = path.join(DATA_PATH, 'images', 'etcher-test.iso');
return mime.getMimeTypeFromFileName(file).then((type) => { return mime.getMimeTypeFromFileName(file).then((type) => {
m.chai.expect(type).to.equal('application/x-iso9660-image'); m.chai.expect(type).to.equal('application/x-iso9660-image');
}); });
}); });
it('should resolve application/x-apple-diskimage for a compressed Apple disk image', function() { it('should resolve application/x-apple-diskimage for a compressed Apple disk image', function () {
const file = path.join(DATA_PATH, 'dmg', 'etcher-test-zlib.dmg'); const file = path.join(DATA_PATH, 'dmg', 'etcher-test-zlib.dmg');
return mime.getMimeTypeFromFileName(file).then((type) => { return mime.getMimeTypeFromFileName(file).then((type) => {
m.chai.expect(type).to.equal('application/x-apple-diskimage'); m.chai.expect(type).to.equal('application/x-apple-diskimage');
}); });
}); });
it('should resolve application/x-apple-diskimage for an uncompressed Apple disk image', function() { it('should resolve application/x-apple-diskimage for an uncompressed Apple disk image', function () {
const file = path.join(DATA_PATH, 'dmg', 'etcher-test-raw.dmg'); const file = path.join(DATA_PATH, 'dmg', 'etcher-test-raw.dmg');
return mime.getMimeTypeFromFileName(file).then((type) => { return mime.getMimeTypeFromFileName(file).then((type) => {
m.chai.expect(type).to.equal('application/x-apple-diskimage'); m.chai.expect(type).to.equal('application/x-apple-diskimage');
}); });
}); });
it('should resolve application/octet-stream for an unrecognized file type', function() { it('should resolve application/octet-stream for an unrecognized file type', function () {
const file = path.join(DATA_PATH, 'unrecognized', 'random.rpi-sdcard'); const file = path.join(DATA_PATH, 'unrecognized', 'random.rpi-sdcard');
return mime.getMimeTypeFromFileName(file).then((type) => { return mime.getMimeTypeFromFileName(file).then((type) => {
m.chai.expect(type).to.equal('application/octet-stream'); m.chai.expect(type).to.equal('application/octet-stream');
}); });
}); });
it('should resolve the correct MIME type given an invalid extension', function() { it('should resolve the correct MIME type given an invalid extension', function () {
const file = path.join(DATA_PATH, 'unrecognized', 'xz-with-invalid-extension.foo'); const file = path.join(DATA_PATH, 'unrecognized', 'xz-with-invalid-extension.foo');
return mime.getMimeTypeFromFileName(file).then((type) => { return mime.getMimeTypeFromFileName(file).then((type) => {
m.chai.expect(type).to.equal('application/x-xz'); m.chai.expect(type).to.equal('application/x-xz');
}); });
}); });
it('should resolve the correct MIME type given no extension', function() { it('should resolve the correct MIME type given no extension', function () {
const file = path.join(DATA_PATH, 'unrecognized', 'xz-without-extension'); const file = path.join(DATA_PATH, 'unrecognized', 'xz-without-extension');
return mime.getMimeTypeFromFileName(file).then((type) => { return mime.getMimeTypeFromFileName(file).then((type) => {
m.chai.expect(type).to.equal('application/x-xz'); m.chai.expect(type).to.equal('application/x-xz');
}); });
}); });
}); });
}); });

View File

@ -28,13 +28,13 @@ const doFilesContainTheSameData = (file1, file2) => {
return Bluebird.props({ return Bluebird.props({
file1: fs.readFileAsync(file1), file1: fs.readFileAsync(file1),
file2: fs.readFileAsync(file2) file2: fs.readFileAsync(file2)
}).then(function(data) { }).then(function (data) {
return _.isEqual(data.file1, data.file2); return _.isEqual(data.file1, data.file2);
}); });
}; };
const deleteIfExists = (file) => { const deleteIfExists = (file) => {
return Bluebird.try(function() { return Bluebird.try(function () {
if (fileExists(file)) { if (fileExists(file)) {
return fs.unlinkAsync(file); return fs.unlinkAsync(file);
} }
@ -45,8 +45,8 @@ const deleteIfExists = (file) => {
exports.DEFAULT_IMAGE_TESTS_TIMEOUT = 20000; exports.DEFAULT_IMAGE_TESTS_TIMEOUT = 20000;
exports.expectError = function(file, errorMessage, errorDetail) { exports.expectError = function (file, errorMessage, errorDetail) {
it('should be rejected with an error', function() { it('should be rejected with an error', function () {
return imageStream.getFromFilePath(file).catch((error) => { return imageStream.getFromFilePath(file).catch((error) => {
m.chai.expect(error).to.be.an.instanceof(Error); m.chai.expect(error).to.be.an.instanceof(Error);
m.chai.expect(error.message).to.equal(errorMessage); m.chai.expect(error.message).to.equal(errorMessage);
@ -59,11 +59,11 @@ exports.expectError = function(file, errorMessage, errorDetail) {
}); });
}; };
exports.extractFromFilePath = function(file, image) { exports.extractFromFilePath = function (file, image) {
it('should be able to extract the image', function() { it('should be able to extract the image', function () {
const output = tmp.tmpNameSync(); const output = tmp.tmpNameSync();
return imageStream.getFromFilePath(file).then(function(results) { return imageStream.getFromFilePath(file).then(function (results) {
m.chai.expect(results.path).to.equal(file); m.chai.expect(results.path).to.equal(file);
m.chai.expect(_.isString(results.extension)).to.be.true; m.chai.expect(_.isString(results.extension)).to.be.true;
m.chai.expect(_.isEmpty(_.trim(results.extension))).to.be.false; m.chai.expect(_.isEmpty(_.trim(results.extension))).to.be.false;
@ -83,11 +83,11 @@ exports.extractFromFilePath = function(file, image) {
stream.on('error', reject); stream.on('error', reject);
stream.on('close', resolve); stream.on('close', resolve);
}); });
}).then(function() { }).then(function () {
return doFilesContainTheSameData(image, output); return doFilesContainTheSameData(image, output);
}).then(function(areEqual) { }).then(function (areEqual) {
m.chai.expect(areEqual).to.be.true; m.chai.expect(areEqual).to.be.true;
}).finally(function() { }).finally(function () {
return deleteIfExists(output); return deleteIfExists(output);
}); });
}); });

View File

@ -20,21 +20,15 @@ const m = require('mochainon');
const StreamReadable = require('stream').Readable; const StreamReadable = require('stream').Readable;
const utils = require('../../lib/image-stream/utils'); const utils = require('../../lib/image-stream/utils');
describe('ImageStream: Utils', function() { describe('ImageStream: Utils', function () {
describe('.extractStream()', function () {
describe('.extractStream()', function() { describe('given a stream that emits data', function () {
beforeEach(function () {
describe('given a stream that emits data', function() {
beforeEach(function() {
this.stream = new StreamReadable(); this.stream = new StreamReadable();
/* eslint-disable no-underscore-dangle */ /* eslint-disable no-underscore-dangle */
this.stream._read = function () {
this.stream._read = function() {
/* eslint-enable no-underscore-dangle */ /* eslint-enable no-underscore-dangle */
this.push(Buffer.from('Hello', 'utf8')); this.push(Buffer.from('Hello', 'utf8'));
this.push(Buffer.from(' ', 'utf8')); this.push(Buffer.from(' ', 'utf8'));
this.push(Buffer.from('World', 'utf8')); this.push(Buffer.from('World', 'utf8'));
@ -42,38 +36,30 @@ describe('ImageStream: Utils', function() {
}; };
}); });
it('should yield the stream data', function() { it('should yield the stream data', function () {
return utils.extractStream(this.stream).then((data) => { return utils.extractStream(this.stream).then((data) => {
m.chai.expect(data.toString()).to.equal('Hello World'); m.chai.expect(data.toString()).to.equal('Hello World');
}); });
}); });
}); });
describe('given a stream that throws an error', function() { describe('given a stream that throws an error', function () {
beforeEach(function () {
beforeEach(function() {
this.stream = new StreamReadable(); this.stream = new StreamReadable();
/* eslint-disable no-underscore-dangle */ /* eslint-disable no-underscore-dangle */
this.stream._read = function () {
this.stream._read = function() {
/* eslint-enable no-underscore-dangle */ /* eslint-enable no-underscore-dangle */
this.emit('error', new Error('stream error')); this.emit('error', new Error('stream error'));
}; };
}); });
it('should be rejected with the error', function() { it('should be rejected with the error', function () {
return utils.extractStream(this.stream).catch((error) => { return utils.extractStream(this.stream).catch((error) => {
m.chai.expect(error).to.be.an.instanceof(Error); m.chai.expect(error).to.be.an.instanceof(Error);
m.chai.expect(error.message).to.equal('stream error'); m.chai.expect(error.message).to.equal('stream error');
}); });
}); });
}); });
}); });
}); });

View File

@ -25,23 +25,19 @@ const XZ_PATH = path.join(DATA_PATH, 'xz');
const imageStream = require('../../lib/image-stream/index'); const imageStream = require('../../lib/image-stream/index');
const tester = require('./tester'); const tester = require('./tester');
describe('ImageStream: XZ', function() { describe('ImageStream: XZ', function () {
this.timeout(tester.DEFAULT_IMAGE_TESTS_TIMEOUT); this.timeout(tester.DEFAULT_IMAGE_TESTS_TIMEOUT);
describe('.getFromFilePath()', function() { describe('.getFromFilePath()', function () {
describe('given a xz image', function () {
describe('given a xz image', function() {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(XZ_PATH, 'etcher-test.img.xz'), path.join(XZ_PATH, 'etcher-test.img.xz'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
}); });
}); });
describe('.getImageMetadata()', function() { describe('.getImageMetadata()', function () {
it('should return the correct metadata', function () {
it('should return the correct metadata', function() {
const image = path.join(XZ_PATH, 'etcher-test.img.xz'); const image = path.join(XZ_PATH, 'etcher-test.img.xz');
const compressedSize = fs.statSync(image).size; const compressedSize = fs.statSync(image).size;
const uncompressedSize = fs.statSync(path.join(IMAGES_PATH, 'etcher-test.img')).size; const uncompressedSize = fs.statSync(path.join(IMAGES_PATH, 'etcher-test.img')).size;
@ -64,7 +60,5 @@ describe('ImageStream: XZ', function() {
}); });
}); });
}); });
}); });
}); });

View File

@ -25,53 +25,49 @@ const ZIP_PATH = path.join(DATA_PATH, 'zip');
const imageStream = require('../../lib/image-stream/index'); const imageStream = require('../../lib/image-stream/index');
const tester = require('./tester'); const tester = require('./tester');
describe('ImageStream: ZIP', function() { describe('ImageStream: ZIP', function () {
this.timeout(tester.DEFAULT_IMAGE_TESTS_TIMEOUT); this.timeout(tester.DEFAULT_IMAGE_TESTS_TIMEOUT);
describe('.getFromFilePath()', function() { describe('.getFromFilePath()', function () {
describe('given an empty zip directory', function () {
describe('given an empty zip directory', function() {
tester.expectError( tester.expectError(
path.join(ZIP_PATH, 'zip-directory-empty.zip'), path.join(ZIP_PATH, 'zip-directory-empty.zip'),
'Invalid archive image'); 'Invalid archive image');
}); });
describe('given a zip directory containing only misc files', function() { describe('given a zip directory containing only misc files', function () {
tester.expectError( tester.expectError(
path.join(ZIP_PATH, 'zip-directory-no-image-only-misc.zip'), path.join(ZIP_PATH, 'zip-directory-no-image-only-misc.zip'),
'Invalid archive image'); 'Invalid archive image');
}); });
describe('given a zip with an unsupported compression method', function() { describe('given a zip with an unsupported compression method', function () {
tester.expectError( tester.expectError(
path.join(ZIP_PATH, 'zip-deflate64.zip'), path.join(ZIP_PATH, 'zip-deflate64.zip'),
'unsupported compression method: 9'); 'unsupported compression method: 9');
}); });
describe('given a zip directory containing multiple images', function() { describe('given a zip directory containing multiple images', function () {
tester.expectError( tester.expectError(
path.join(ZIP_PATH, 'zip-directory-multiple-images.zip'), path.join(ZIP_PATH, 'zip-directory-multiple-images.zip'),
'Invalid archive image'); 'Invalid archive image');
}); });
describe('given a zip directory containing only an image', function() { describe('given a zip directory containing only an image', function () {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(ZIP_PATH, 'zip-directory-etcher-test-only.zip'), path.join(ZIP_PATH, 'zip-directory-etcher-test-only.zip'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
}); });
describe('given a zip directory containing an image and other misc files', function() { describe('given a zip directory containing an image and other misc files', function () {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(ZIP_PATH, 'zip-directory-etcher-test-and-misc.zip'), path.join(ZIP_PATH, 'zip-directory-etcher-test-and-misc.zip'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
}); });
}); });
describe('compression method', function() { describe('compression method', function () {
context('DEFLATE', function () {
context('DEFLATE', function() {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(ZIP_PATH, 'zip-deflate.zip'), path.join(ZIP_PATH, 'zip-deflate.zip'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
@ -79,35 +75,33 @@ describe('ImageStream: ZIP', function() {
// NOTE: These tests are intentionally skipped, as the // NOTE: These tests are intentionally skipped, as the
// zip library we're currently using only supports deflate // zip library we're currently using only supports deflate
context.skip('DEFLATE64', function() { context.skip('DEFLATE64', function () {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(ZIP_PATH, 'zip-deflate64.zip'), path.join(ZIP_PATH, 'zip-deflate64.zip'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
}); });
context.skip('PPMD', function() { context.skip('PPMD', function () {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(ZIP_PATH, 'zip-ppmd.zip'), path.join(ZIP_PATH, 'zip-ppmd.zip'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
}); });
context.skip('BZIP2', function() { context.skip('BZIP2', function () {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(ZIP_PATH, 'zip-bzip2.zip'), path.join(ZIP_PATH, 'zip-bzip2.zip'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
}); });
context.skip('LZMA', function() { context.skip('LZMA', function () {
tester.extractFromFilePath( tester.extractFromFilePath(
path.join(ZIP_PATH, 'zip-lzma.zip'), path.join(ZIP_PATH, 'zip-lzma.zip'),
path.join(IMAGES_PATH, 'etcher-test.img')); path.join(IMAGES_PATH, 'etcher-test.img'));
}); });
}); });
describe('.getImageMetadata()', function() { describe('.getImageMetadata()', function () {
it('should return the correct metadata', function () {
it('should return the correct metadata', function() {
const image = path.join(ZIP_PATH, 'zip-directory-etcher-test-only.zip'); const image = path.join(ZIP_PATH, 'zip-directory-etcher-test-only.zip');
const expectedSize = fs.statSync(path.join(IMAGES_PATH, 'etcher-test.img')).size; const expectedSize = fs.statSync(path.join(IMAGES_PATH, 'etcher-test.img')).size;
@ -129,7 +123,5 @@ describe('ImageStream: ZIP', function() {
}); });
}); });
}); });
}); });
}); });

View File

@ -1,3 +1,19 @@
/*
* Copyright 2017 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'; 'use strict';
const m = require('mochainon'); const m = require('mochainon');
@ -5,11 +21,9 @@ const _ = require('lodash');
const path = require('path'); const path = require('path');
const constraints = require('../../lib/shared/drive-constraints'); const constraints = require('../../lib/shared/drive-constraints');
describe('Shared: DriveConstraints', function() { describe('Shared: DriveConstraints', function () {
describe('.isDriveLocked()', function () {
describe('.isDriveLocked()', function() { it('should return true if the drive is protected', function () {
it('should return true if the drive is protected', function() {
const result = constraints.isDriveLocked({ const result = constraints.isDriveLocked({
device: '/dev/disk2', device: '/dev/disk2',
name: 'USB Drive', name: 'USB Drive',
@ -20,7 +34,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.true; m.chai.expect(result).to.be.true;
}); });
it('should return false if the drive is not protected', function() { it('should return false if the drive is not protected', function () {
const result = constraints.isDriveLocked({ const result = constraints.isDriveLocked({
device: '/dev/disk2', device: '/dev/disk2',
name: 'USB Drive', name: 'USB Drive',
@ -31,7 +45,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.false; m.chai.expect(result).to.be.false;
}); });
it('should return false if we don\'t know if the drive is protected', function() { it('should return false if we don\'t know if the drive is protected', function () {
const result = constraints.isDriveLocked({ const result = constraints.isDriveLocked({
device: '/dev/disk2', device: '/dev/disk2',
name: 'USB Drive', name: 'USB Drive',
@ -41,17 +55,15 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.false; m.chai.expect(result).to.be.false;
}); });
it('should return false if the drive is undefined', function() { it('should return false if the drive is undefined', function () {
const result = constraints.isDriveLocked(undefined); const result = constraints.isDriveLocked(undefined);
m.chai.expect(result).to.be.false; m.chai.expect(result).to.be.false;
}); });
}); });
describe('.isSystemDrive()', function() { describe('.isSystemDrive()', function () {
it('should return true if the drive is a system drive', function () {
it('should return true if the drive is a system drive', function() {
const result = constraints.isSystemDrive({ const result = constraints.isSystemDrive({
device: '/dev/disk2', device: '/dev/disk2',
name: 'USB Drive', name: 'USB Drive',
@ -63,7 +75,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.true; m.chai.expect(result).to.be.true;
}); });
it('should default to `false` if the `system` property is `undefined`', function() { it('should default to `false` if the `system` property is `undefined`', function () {
const result = constraints.isSystemDrive({ const result = constraints.isSystemDrive({
device: '/dev/disk2', device: '/dev/disk2',
name: 'USB Drive', name: 'USB Drive',
@ -74,7 +86,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.false; m.chai.expect(result).to.be.false;
}); });
it('should return false if the drive is a removable drive', function() { it('should return false if the drive is a removable drive', function () {
const result = constraints.isSystemDrive({ const result = constraints.isSystemDrive({
device: '/dev/disk2', device: '/dev/disk2',
name: 'USB Drive', name: 'USB Drive',
@ -86,17 +98,15 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.false; m.chai.expect(result).to.be.false;
}); });
it('should return false if the drive is undefined', function() { it('should return false if the drive is undefined', function () {
const result = constraints.isSystemDrive(undefined); const result = constraints.isSystemDrive(undefined);
m.chai.expect(result).to.be.false; m.chai.expect(result).to.be.false;
}); });
}); });
describe('.isSourceDrive()', function() { describe('.isSourceDrive()', function () {
it('should return false if no image', function () {
it('should return false if no image', function() {
const result = constraints.isSourceDrive({ const result = constraints.isSourceDrive({
device: '/dev/disk2', device: '/dev/disk2',
name: 'USB Drive', name: 'USB Drive',
@ -108,7 +118,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.false; m.chai.expect(result).to.be.false;
}); });
it('should return false if no drive', function() { it('should return false if no drive', function () {
const result = constraints.isSourceDrive(undefined, { const result = constraints.isSourceDrive(undefined, {
path: '/Volumes/Untitled/image.img' path: '/Volumes/Untitled/image.img'
}); });
@ -116,7 +126,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.false; m.chai.expect(result).to.be.false;
}); });
it('should return false if there are no mount points', function() { it('should return false if there are no mount points', function () {
const result = constraints.isSourceDrive({ const result = constraints.isSourceDrive({
device: '/dev/disk2', device: '/dev/disk2',
name: 'USB Drive', name: 'USB Drive',
@ -130,18 +140,17 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.false; m.chai.expect(result).to.be.false;
}); });
describe('given Windows paths', function() { describe('given Windows paths', function () {
beforeEach(function () {
beforeEach(function() {
this.separator = path.sep; this.separator = path.sep;
path.sep = '\\'; path.sep = '\\';
}); });
afterEach(function() { afterEach(function () {
path.sep = this.separator; path.sep = this.separator;
}); });
it('should return true if the image lives directly inside a mount point of the drive', function() { it('should return true if the image lives directly inside a mount point of the drive', function () {
const result = constraints.isSourceDrive({ const result = constraints.isSourceDrive({
mountpoints: [ mountpoints: [
{ {
@ -158,7 +167,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.true; m.chai.expect(result).to.be.true;
}); });
it('should return true if the image lives inside a mount point of the drive', function() { it('should return true if the image lives inside a mount point of the drive', function () {
const result = constraints.isSourceDrive({ const result = constraints.isSourceDrive({
mountpoints: [ mountpoints: [
{ {
@ -175,7 +184,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.true; m.chai.expect(result).to.be.true;
}); });
it('should return false if the image does not live inside a mount point of the drive', function() { it('should return false if the image does not live inside a mount point of the drive', function () {
const result = constraints.isSourceDrive({ const result = constraints.isSourceDrive({
mountpoints: [ mountpoints: [
{ {
@ -192,7 +201,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.false; m.chai.expect(result).to.be.false;
}); });
it('should return false if the image is in a mount point that is a substring of the image mount point', function() { it('should return false if the image is in a mount point that is a substring of the image mount point', function () {
const result = constraints.isSourceDrive({ const result = constraints.isSourceDrive({
mountpoints: [ mountpoints: [
{ {
@ -205,21 +214,19 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.false; m.chai.expect(result).to.be.false;
}); });
}); });
describe('given UNIX paths', function() { describe('given UNIX paths', function () {
beforeEach(function () {
beforeEach(function() {
this.separator = path.sep; this.separator = path.sep;
path.sep = '/'; path.sep = '/';
}); });
afterEach(function() { afterEach(function () {
path.sep = this.separator; path.sep = this.separator;
}); });
it('should return true if the mount point is / and the image lives directly inside it', function() { it('should return true if the mount point is / and the image lives directly inside it', function () {
const result = constraints.isSourceDrive({ const result = constraints.isSourceDrive({
mountpoints: [ mountpoints: [
{ {
@ -233,7 +240,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.true; m.chai.expect(result).to.be.true;
}); });
it('should return true if the image lives directly inside a mount point of the drive', function() { it('should return true if the image lives directly inside a mount point of the drive', function () {
const result = constraints.isSourceDrive({ const result = constraints.isSourceDrive({
mountpoints: [ mountpoints: [
{ {
@ -250,7 +257,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.true; m.chai.expect(result).to.be.true;
}); });
it('should return true if the image lives inside a mount point of the drive', function() { it('should return true if the image lives inside a mount point of the drive', function () {
const result = constraints.isSourceDrive({ const result = constraints.isSourceDrive({
mountpoints: [ mountpoints: [
{ {
@ -267,7 +274,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.true; m.chai.expect(result).to.be.true;
}); });
it('should return false if the image does not live inside a mount point of the drive', function() { it('should return false if the image does not live inside a mount point of the drive', function () {
const result = constraints.isSourceDrive({ const result = constraints.isSourceDrive({
mountpoints: [ mountpoints: [
{ {
@ -284,7 +291,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.false; m.chai.expect(result).to.be.false;
}); });
it('should return false if the image is in a mount point that is a substring of the image mount point', function() { it('should return false if the image is in a mount point that is a substring of the image mount point', function () {
const result = constraints.isSourceDrive({ const result = constraints.isSourceDrive({
mountpoints: [ mountpoints: [
{ {
@ -297,14 +304,11 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.false; m.chai.expect(result).to.be.false;
}); });
}); });
}); });
describe('.isDriveLargeEnough()', function() { describe('.isDriveLargeEnough()', function () {
beforeEach(function () {
beforeEach(function() {
this.drive = { this.drive = {
device: '/dev/disk1', device: '/dev/disk1',
name: 'USB Drive', name: 'USB Drive',
@ -313,11 +317,9 @@ describe('Shared: DriveConstraints', function() {
}; };
}); });
describe('given the final image size estimation flag is false', function() { describe('given the final image size estimation flag is false', function () {
describe('given the original size is less than the drive size', function () {
describe('given the original size is less than the drive size', function() { beforeEach(function () {
beforeEach(function() {
this.image = { this.image = {
path: path.join(__dirname, 'rpi.img'), path: path.join(__dirname, 'rpi.img'),
size: { size: {
@ -329,26 +331,24 @@ describe('Shared: DriveConstraints', function() {
}; };
}); });
it('should return true if the final size is less than the drive size', function() { it('should return true if the final size is less than the drive size', function () {
this.image.size.final.value = this.drive.size - 1; this.image.size.final.value = this.drive.size - 1;
m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true; m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true;
}); });
it('should return true if the final size is equal to the drive size', function() { it('should return true if the final size is equal to the drive size', function () {
this.image.size.final.value = this.drive.size; this.image.size.final.value = this.drive.size;
m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true; m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true;
}); });
it('should return false if the final size is greater than the drive size', function() { it('should return false if the final size is greater than the drive size', function () {
this.image.size.final.value = this.drive.size + 1; this.image.size.final.value = this.drive.size + 1;
m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.false; m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.false;
}); });
}); });
describe('given the original size is equal to the drive size', function() { describe('given the original size is equal to the drive size', function () {
beforeEach(function () {
beforeEach(function() {
this.image = { this.image = {
path: path.join(__dirname, 'rpi.img'), path: path.join(__dirname, 'rpi.img'),
size: { size: {
@ -360,26 +360,24 @@ describe('Shared: DriveConstraints', function() {
}; };
}); });
it('should return true if the final size is less than the drive size', function() { it('should return true if the final size is less than the drive size', function () {
this.image.size.final.value = this.drive.size - 1; this.image.size.final.value = this.drive.size - 1;
m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true; m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true;
}); });
it('should return true if the final size is equal to the drive size', function() { it('should return true if the final size is equal to the drive size', function () {
this.image.size.final.value = this.drive.size; this.image.size.final.value = this.drive.size;
m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true; m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true;
}); });
it('should return false if the final size is greater than the drive size', function() { it('should return false if the final size is greater than the drive size', function () {
this.image.size.final.value = this.drive.size + 1; this.image.size.final.value = this.drive.size + 1;
m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.false; m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.false;
}); });
}); });
describe('given the original size is greater than the drive size', function() { describe('given the original size is greater than the drive size', function () {
beforeEach(function () {
beforeEach(function() {
this.image = { this.image = {
path: path.join(__dirname, 'rpi.img'), path: path.join(__dirname, 'rpi.img'),
size: { size: {
@ -391,30 +389,26 @@ describe('Shared: DriveConstraints', function() {
}; };
}); });
it('should return true if the final size is less than the drive size', function() { it('should return true if the final size is less than the drive size', function () {
this.image.size.final.value = this.drive.size - 1; this.image.size.final.value = this.drive.size - 1;
m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true; m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true;
}); });
it('should return true if the final size is equal to the drive size', function() { it('should return true if the final size is equal to the drive size', function () {
this.image.size.final.value = this.drive.size; this.image.size.final.value = this.drive.size;
m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true; m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true;
}); });
it('should return false if the final size is greater than the drive size', function() { it('should return false if the final size is greater than the drive size', function () {
this.image.size.final.value = this.drive.size + 1; this.image.size.final.value = this.drive.size + 1;
m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.false; m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.false;
}); });
}); });
}); });
describe('given the final image size estimation flag is true', function() { describe('given the final image size estimation flag is true', function () {
describe('given the original size is less than the drive size', function () {
describe('given the original size is less than the drive size', function() { beforeEach(function () {
beforeEach(function() {
this.image = { this.image = {
path: path.join(__dirname, 'rpi.img'), path: path.join(__dirname, 'rpi.img'),
size: { size: {
@ -426,26 +420,24 @@ describe('Shared: DriveConstraints', function() {
}; };
}); });
it('should return true if the final size is less than the drive size', function() { it('should return true if the final size is less than the drive size', function () {
this.image.size.final.value = this.drive.size - 1; this.image.size.final.value = this.drive.size - 1;
m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true; m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true;
}); });
it('should return true if the final size is equal to the drive size', function() { it('should return true if the final size is equal to the drive size', function () {
this.image.size.final.value = this.drive.size; this.image.size.final.value = this.drive.size;
m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true; m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true;
}); });
it('should return true if the final size is greater than the drive size', function() { it('should return true if the final size is greater than the drive size', function () {
this.image.size.final.value = this.drive.size + 1; this.image.size.final.value = this.drive.size + 1;
m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true; m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true;
}); });
}); });
describe('given the original size is equal to the drive size', function() { describe('given the original size is equal to the drive size', function () {
beforeEach(function () {
beforeEach(function() {
this.image = { this.image = {
path: path.join(__dirname, 'rpi.img'), path: path.join(__dirname, 'rpi.img'),
size: { size: {
@ -457,26 +449,24 @@ describe('Shared: DriveConstraints', function() {
}; };
}); });
it('should return true if the final size is less than the drive size', function() { it('should return true if the final size is less than the drive size', function () {
this.image.size.final.value = this.drive.size - 1; this.image.size.final.value = this.drive.size - 1;
m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true; m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true;
}); });
it('should return true if the final size is equal to the drive size', function() { it('should return true if the final size is equal to the drive size', function () {
this.image.size.final.value = this.drive.size; this.image.size.final.value = this.drive.size;
m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true; m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true;
}); });
it('should return true if the final size is greater than the drive size', function() { it('should return true if the final size is greater than the drive size', function () {
this.image.size.final.value = this.drive.size + 1; this.image.size.final.value = this.drive.size + 1;
m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true; m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.true;
}); });
}); });
describe('given the original size is greater than the drive size', function() { describe('given the original size is greater than the drive size', function () {
beforeEach(function () {
beforeEach(function() {
this.image = { this.image = {
path: path.join(__dirname, 'rpi.img'), path: path.join(__dirname, 'rpi.img'),
size: { size: {
@ -488,26 +478,24 @@ describe('Shared: DriveConstraints', function() {
}; };
}); });
it('should return false if the final size is less than the drive size', function() { it('should return false if the final size is less than the drive size', function () {
this.image.size.final.value = this.drive.size - 1; this.image.size.final.value = this.drive.size - 1;
m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.false; m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.false;
}); });
it('should return false if the final size is equal to the drive size', function() { it('should return false if the final size is equal to the drive size', function () {
this.image.size.final.value = this.drive.size; this.image.size.final.value = this.drive.size;
m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.false; m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.false;
}); });
it('should return false if the final size is greater than the drive size', function() { it('should return false if the final size is greater than the drive size', function () {
this.image.size.final.value = this.drive.size + 1; this.image.size.final.value = this.drive.size + 1;
m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.false; m.chai.expect(constraints.isDriveLargeEnough(this.drive, this.image)).to.be.false;
}); });
}); });
}); });
it('should return false if the drive is undefined', function() { it('should return false if the drive is undefined', function () {
const result = constraints.isDriveLargeEnough(undefined, { const result = constraints.isDriveLargeEnough(undefined, {
path: path.join(__dirname, 'rpi.img'), path: path.join(__dirname, 'rpi.img'),
size: { size: {
@ -522,7 +510,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.false; m.chai.expect(result).to.be.false;
}); });
it('should return true if the image is undefined', function() { it('should return true if the image is undefined', function () {
const result = constraints.isDriveLargeEnough({ const result = constraints.isDriveLargeEnough({
device: '/dev/disk1', device: '/dev/disk1',
name: 'USB Drive', name: 'USB Drive',
@ -533,16 +521,14 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.true; m.chai.expect(result).to.be.true;
}); });
it('should return false if the drive and image are undefined', function() { it('should return false if the drive and image are undefined', function () {
const result = constraints.isDriveLargeEnough(undefined, undefined); const result = constraints.isDriveLargeEnough(undefined, undefined);
m.chai.expect(result).to.be.true; m.chai.expect(result).to.be.true;
}); });
}); });
describe('.isDriveSizeRecommended()', function() { describe('.isDriveSizeRecommended()', function () {
it('should return true if the drive size is greater than the recommended size ', function () {
it('should return true if the drive size is greater than the recommended size ', function() {
const result = constraints.isDriveSizeRecommended({ const result = constraints.isDriveSizeRecommended({
device: '/dev/disk1', device: '/dev/disk1',
name: 'USB Drive', name: 'USB Drive',
@ -557,7 +543,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.true; m.chai.expect(result).to.be.true;
}); });
it('should return true if the drive size is equal to recommended size', function() { it('should return true if the drive size is equal to recommended size', function () {
const result = constraints.isDriveSizeRecommended({ const result = constraints.isDriveSizeRecommended({
device: '/dev/disk1', device: '/dev/disk1',
name: 'USB Drive', name: 'USB Drive',
@ -572,7 +558,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.true; m.chai.expect(result).to.be.true;
}); });
it('should return false if the drive size is less than the recommended size', function() { it('should return false if the drive size is less than the recommended size', function () {
const result = constraints.isDriveSizeRecommended({ const result = constraints.isDriveSizeRecommended({
device: '/dev/disk1', device: '/dev/disk1',
name: 'USB Drive', name: 'USB Drive',
@ -587,7 +573,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.false; m.chai.expect(result).to.be.false;
}); });
it('should return true if the recommended drive size is undefined', function() { it('should return true if the recommended drive size is undefined', function () {
const result = constraints.isDriveSizeRecommended({ const result = constraints.isDriveSizeRecommended({
device: '/dev/disk1', device: '/dev/disk1',
name: 'USB Drive', name: 'USB Drive',
@ -601,7 +587,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.true; m.chai.expect(result).to.be.true;
}); });
it('should return false if the drive is undefined', function() { it('should return false if the drive is undefined', function () {
const result = constraints.isDriveSizeRecommended(undefined, { const result = constraints.isDriveSizeRecommended(undefined, {
path: path.join(__dirname, 'rpi.img'), path: path.join(__dirname, 'rpi.img'),
size: 1000000000, size: 1000000000,
@ -611,7 +597,7 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.false; m.chai.expect(result).to.be.false;
}); });
it('should return true if the image is undefined', function() { it('should return true if the image is undefined', function () {
const result = constraints.isDriveSizeRecommended({ const result = constraints.isDriveSizeRecommended({
device: '/dev/disk1', device: '/dev/disk1',
name: 'USB Drive', name: 'USB Drive',
@ -622,16 +608,14 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.be.true; m.chai.expect(result).to.be.true;
}); });
it('should return false if the drive and image are undefined', function() { it('should return false if the drive and image are undefined', function () {
const result = constraints.isDriveSizeRecommended(undefined, undefined); const result = constraints.isDriveSizeRecommended(undefined, undefined);
m.chai.expect(result).to.be.true; m.chai.expect(result).to.be.true;
}); });
}); });
describe('.isDriveValid()', function() { describe('.isDriveValid()', function () {
beforeEach(function () {
beforeEach(function() {
if (process.platform === 'win32') { if (process.platform === 'win32') {
this.mountpoint = 'E:\\foo'; this.mountpoint = 'E:\\foo';
} else { } else {
@ -650,13 +634,12 @@ describe('Shared: DriveConstraints', function() {
}; };
}); });
describe('given the drive is locked', function() { describe('given the drive is locked', function () {
beforeEach(function () {
beforeEach(function() {
this.drive.protected = true; this.drive.protected = true;
}); });
it('should return false if the drive is not large enough and is a source drive', function() { it('should return false if the drive is not large enough and is a source drive', function () {
m.chai.expect(constraints.isDriveValid(this.drive, { m.chai.expect(constraints.isDriveValid(this.drive, {
path: path.join(this.mountpoint, 'rpi.img'), path: path.join(this.mountpoint, 'rpi.img'),
size: { size: {
@ -669,7 +652,7 @@ describe('Shared: DriveConstraints', function() {
})).to.be.false; })).to.be.false;
}); });
it('should return false if the drive is not large enough and is not a source drive', function() { it('should return false if the drive is not large enough and is not a source drive', function () {
m.chai.expect(constraints.isDriveValid(this.drive, { m.chai.expect(constraints.isDriveValid(this.drive, {
path: path.resolve(this.mountpoint, '../bar/rpi.img'), path: path.resolve(this.mountpoint, '../bar/rpi.img'),
size: { size: {
@ -682,7 +665,7 @@ describe('Shared: DriveConstraints', function() {
})).to.be.false; })).to.be.false;
}); });
it('should return false if the drive is large enough and is a source drive', function() { it('should return false if the drive is large enough and is a source drive', function () {
m.chai.expect(constraints.isDriveValid(this.drive, { m.chai.expect(constraints.isDriveValid(this.drive, {
path: path.join(this.mountpoint, 'rpi.img'), path: path.join(this.mountpoint, 'rpi.img'),
size: { size: {
@ -695,7 +678,7 @@ describe('Shared: DriveConstraints', function() {
})).to.be.false; })).to.be.false;
}); });
it('should return false if the drive is large enough and is not a source drive', function() { it('should return false if the drive is large enough and is not a source drive', function () {
m.chai.expect(constraints.isDriveValid(this.drive, { m.chai.expect(constraints.isDriveValid(this.drive, {
path: path.resolve(this.mountpoint, '../bar/rpi.img'), path: path.resolve(this.mountpoint, '../bar/rpi.img'),
size: { size: {
@ -707,16 +690,14 @@ describe('Shared: DriveConstraints', function() {
} }
})).to.be.false; })).to.be.false;
}); });
}); });
describe('given the drive is not locked', function() { describe('given the drive is not locked', function () {
beforeEach(function () {
beforeEach(function() {
this.drive.protected = false; this.drive.protected = false;
}); });
it('should return false if the drive is not large enough and is a source drive', function() { it('should return false if the drive is not large enough and is a source drive', function () {
m.chai.expect(constraints.isDriveValid(this.drive, { m.chai.expect(constraints.isDriveValid(this.drive, {
path: path.join(this.mountpoint, 'rpi.img'), path: path.join(this.mountpoint, 'rpi.img'),
size: { size: {
@ -729,7 +710,7 @@ describe('Shared: DriveConstraints', function() {
})).to.be.false; })).to.be.false;
}); });
it('should return false if the drive is not large enough and is not a source drive', function() { it('should return false if the drive is not large enough and is not a source drive', function () {
m.chai.expect(constraints.isDriveValid(this.drive, { m.chai.expect(constraints.isDriveValid(this.drive, {
path: path.resolve(this.mountpoint, '../bar/rpi.img'), path: path.resolve(this.mountpoint, '../bar/rpi.img'),
size: { size: {
@ -742,7 +723,7 @@ describe('Shared: DriveConstraints', function() {
})).to.be.false; })).to.be.false;
}); });
it('should return false if the drive is large enough and is a source drive', function() { it('should return false if the drive is large enough and is a source drive', function () {
m.chai.expect(constraints.isDriveValid(this.drive, { m.chai.expect(constraints.isDriveValid(this.drive, {
path: path.join(this.mountpoint, 'rpi.img'), path: path.join(this.mountpoint, 'rpi.img'),
size: { size: {
@ -755,7 +736,7 @@ describe('Shared: DriveConstraints', function() {
})).to.be.false; })).to.be.false;
}); });
it('should return true if the drive is large enough and is not a source drive', function() { it('should return true if the drive is large enough and is not a source drive', function () {
m.chai.expect(constraints.isDriveValid(this.drive, { m.chai.expect(constraints.isDriveValid(this.drive, {
path: path.resolve(this.mountpoint, '../bar/rpi.img'), path: path.resolve(this.mountpoint, '../bar/rpi.img'),
size: { size: {
@ -767,14 +748,11 @@ describe('Shared: DriveConstraints', function() {
} }
})).to.be.true; })).to.be.true;
}); });
}); });
}); });
describe('.getDriveImageCompatibilityStatuses', function() { describe('.getDriveImageCompatibilityStatuses', function () {
beforeEach(function () {
beforeEach(function() {
if (process.platform === 'win32') { if (process.platform === 'win32') {
this.mountpoint = 'E:'; this.mountpoint = 'E:';
this.separator = '\\'; this.separator = '\\';
@ -808,7 +786,6 @@ describe('Shared: DriveConstraints', function() {
}); });
const expectStatusTypesAndMessagesToBe = (resultList, expectedTuples) => { const expectStatusTypesAndMessagesToBe = (resultList, expectedTuples) => {
// Sort so that order doesn't matter // Sort so that order doesn't matter
const expectedTuplesSorted = _.sortBy(_.map(expectedTuples, (tuple) => { const expectedTuplesSorted = _.sortBy(_.map(expectedTuples, (tuple) => {
return { return {
@ -822,8 +799,7 @@ describe('Shared: DriveConstraints', function() {
}; };
describe('given there are no errors or warnings', () => { describe('given there are no errors or warnings', () => {
it('should return an empty list', function () {
it('should return an empty list', function() {
const result = constraints.getDriveImageCompatibilityStatuses(this.drive, { const result = constraints.getDriveImageCompatibilityStatuses(this.drive, {
path: '/mnt/disk2/rpi.img', path: '/mnt/disk2/rpi.img',
size: 1000000000 size: 1000000000
@ -831,12 +807,10 @@ describe('Shared: DriveConstraints', function() {
m.chai.expect(result).to.deep.equal([]); m.chai.expect(result).to.deep.equal([]);
}); });
}); });
describe('given the drive contains the image', () => { describe('given the drive contains the image', () => {
it('should return the contains-image error', function () {
it('should return the contains-image error', function() {
this.image.path = path.join(this.mountpoint, 'rpi.img'); this.image.path = path.join(this.mountpoint, 'rpi.img');
const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image); const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image);
@ -844,12 +818,10 @@ describe('Shared: DriveConstraints', function() {
expectStatusTypesAndMessagesToBe(result, expectedTuples); expectStatusTypesAndMessagesToBe(result, expectedTuples);
}); });
}); });
describe('given the drive is a system drive', () => { describe('given the drive is a system drive', () => {
it('should return the system drive warning', function () {
it('should return the system drive warning', function() {
this.drive.system = true; this.drive.system = true;
const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image); const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image);
@ -857,12 +829,10 @@ describe('Shared: DriveConstraints', function() {
expectStatusTypesAndMessagesToBe(result, expectedTuples); expectStatusTypesAndMessagesToBe(result, expectedTuples);
}); });
}); });
describe('given the drive is too small', () => { describe('given the drive is too small', () => {
it('should return the too small error', function () {
it('should return the too small error', function() {
this.image.size.final.value = this.drive.size + 1; this.image.size.final.value = this.drive.size + 1;
const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image); const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image);
@ -870,12 +840,10 @@ describe('Shared: DriveConstraints', function() {
expectStatusTypesAndMessagesToBe(result, expectedTuples); expectStatusTypesAndMessagesToBe(result, expectedTuples);
}); });
}); });
describe('given the drive is locked', () => { describe('given the drive is locked', () => {
it('should return the locked drive error', function () {
it('should return the locked drive error', function() {
this.drive.protected = true; this.drive.protected = true;
const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image); const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image);
@ -883,12 +851,10 @@ describe('Shared: DriveConstraints', function() {
expectStatusTypesAndMessagesToBe(result, expectedTuples); expectStatusTypesAndMessagesToBe(result, expectedTuples);
}); });
}); });
describe('given the drive is smaller than the recommended size', () => { describe('given the drive is smaller than the recommended size', () => {
it('should return the smaller than recommended size warning', function () {
it('should return the smaller than recommended size warning', function() {
this.image.recommendedDriveSize = this.drive.size + 1; this.image.recommendedDriveSize = this.drive.size + 1;
const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image); const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image);
@ -896,32 +862,26 @@ describe('Shared: DriveConstraints', function() {
expectStatusTypesAndMessagesToBe(result, expectedTuples); expectStatusTypesAndMessagesToBe(result, expectedTuples);
}); });
}); });
describe('given the image is null', () => { describe('given the image is null', () => {
it('should return an empty list', function () {
it('should return an empty list', function() {
const result = constraints.getDriveImageCompatibilityStatuses(this.drive, null); const result = constraints.getDriveImageCompatibilityStatuses(this.drive, null);
m.chai.expect(result).to.deep.equal([]); m.chai.expect(result).to.deep.equal([]);
}); });
}); });
describe('given the drive is null', () => { describe('given the drive is null', () => {
it('should return an empty list', function () {
it('should return an empty list', function() {
const result = constraints.getDriveImageCompatibilityStatuses(null, this.image); const result = constraints.getDriveImageCompatibilityStatuses(null, this.image);
m.chai.expect(result).to.deep.equal([]); m.chai.expect(result).to.deep.equal([]);
}); });
}); });
describe('given a locked drive and image is null', () => { describe('given a locked drive and image is null', () => {
it('should return locked drive error', function () {
it('should return locked drive error', function() {
this.drive.protected = true; this.drive.protected = true;
const result = constraints.getDriveImageCompatibilityStatuses(this.drive, null); const result = constraints.getDriveImageCompatibilityStatuses(this.drive, null);
@ -929,12 +889,10 @@ describe('Shared: DriveConstraints', function() {
expectStatusTypesAndMessagesToBe(result, expectedTuples); expectStatusTypesAndMessagesToBe(result, expectedTuples);
}); });
}); });
describe('given a system drive and image is null', () => { describe('given a system drive and image is null', () => {
it('should return system drive warning', function () {
it('should return system drive warning', function() {
this.drive.system = true; this.drive.system = true;
const result = constraints.getDriveImageCompatibilityStatuses(this.drive, null); const result = constraints.getDriveImageCompatibilityStatuses(this.drive, null);
@ -942,12 +900,10 @@ describe('Shared: DriveConstraints', function() {
expectStatusTypesAndMessagesToBe(result, expectedTuples); expectStatusTypesAndMessagesToBe(result, expectedTuples);
}); });
}); });
describe('given the drive contains the image and the drive is locked', () => { describe('given the drive contains the image and the drive is locked', () => {
it('should return the contains-image drive error by precedence', function () {
it('should return the contains-image drive error by precedence', function() {
this.drive.protected = true; this.drive.protected = true;
this.image.path = path.join(this.mountpoint, 'rpi.img'); this.image.path = path.join(this.mountpoint, 'rpi.img');
@ -956,12 +912,10 @@ describe('Shared: DriveConstraints', function() {
expectStatusTypesAndMessagesToBe(result, expectedTuples); expectStatusTypesAndMessagesToBe(result, expectedTuples);
}); });
}); });
describe('given a locked and too small drive', () => { describe('given a locked and too small drive', () => {
it('should return the locked error by precedence', function () {
it('should return the locked error by precedence', function() {
this.drive.protected = true; this.drive.protected = true;
const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image); const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image);
@ -969,12 +923,10 @@ describe('Shared: DriveConstraints', function() {
expectStatusTypesAndMessagesToBe(result, expectedTuples); expectStatusTypesAndMessagesToBe(result, expectedTuples);
}); });
}); });
describe('given a too small and system drive', () => { describe('given a too small and system drive', () => {
it('should return the too small drive error by precedence', function () {
it('should return the too small drive error by precedence', function() {
this.image.size.final.value = this.drive.size + 1; this.image.size.final.value = this.drive.size + 1;
this.drive.system = true; this.drive.system = true;
@ -983,12 +935,10 @@ describe('Shared: DriveConstraints', function() {
expectStatusTypesAndMessagesToBe(result, expectedTuples); expectStatusTypesAndMessagesToBe(result, expectedTuples);
}); });
}); });
describe('given a system drive and not recommended drive size', () => { describe('given a system drive and not recommended drive size', () => {
it('should return both warnings', function () {
it('should return both warnings', function() {
this.drive.system = true; this.drive.system = true;
this.image.recommendedDriveSize = this.drive.size + 1; this.image.recommendedDriveSize = this.drive.size + 1;
@ -997,8 +947,6 @@ describe('Shared: DriveConstraints', function() {
expectStatusTypesAndMessagesToBe(result, expectedTuples); expectStatusTypesAndMessagesToBe(result, expectedTuples);
}); });
}); });
}); });
}); });

View File

@ -20,94 +20,90 @@ const m = require('mochainon');
const _ = require('lodash'); const _ = require('lodash');
const errors = require('../../lib/shared/errors'); const errors = require('../../lib/shared/errors');
describe('Shared: Errors', function() { describe('Shared: Errors', function () {
describe('.HUMAN_FRIENDLY', function () {
describe('.HUMAN_FRIENDLY', function() { it('should be a plain object', function () {
it('should be a plain object', function() {
m.chai.expect(_.isPlainObject(errors.HUMAN_FRIENDLY)).to.be.true; m.chai.expect(_.isPlainObject(errors.HUMAN_FRIENDLY)).to.be.true;
}); });
it('should contain title and description function properties', function() { it('should contain title and description function properties', function () {
m.chai.expect(_.every(_.map(errors.HUMAN_FRIENDLY, (error) => { m.chai.expect(_.every(_.map(errors.HUMAN_FRIENDLY, (error) => {
return _.isFunction(error.title) && _.isFunction(error.description); return _.isFunction(error.title) && _.isFunction(error.description);
}))).to.be.true; }))).to.be.true;
}); });
}); });
describe('.getTitle()', function() { describe('.getTitle()', function () {
it('should accept a string', function () {
it('should accept a string', function() {
const error = 'This is an error'; const error = 'This is an error';
m.chai.expect(errors.getTitle(error)).to.equal('This is an error'); m.chai.expect(errors.getTitle(error)).to.equal('This is an error');
}); });
it('should accept a number 0', function() { it('should accept a number 0', function () {
const error = 0; const error = 0;
m.chai.expect(errors.getTitle(error)).to.equal('0'); m.chai.expect(errors.getTitle(error)).to.equal('0');
}); });
it('should accept a number 1', function() { it('should accept a number 1', function () {
const error = 1; const error = 1;
m.chai.expect(errors.getTitle(error)).to.equal('1'); m.chai.expect(errors.getTitle(error)).to.equal('1');
}); });
it('should accept a number -1', function() { it('should accept a number -1', function () {
const error = -1; const error = -1;
m.chai.expect(errors.getTitle(error)).to.equal('-1'); m.chai.expect(errors.getTitle(error)).to.equal('-1');
}); });
it('should accept an array', function() { it('should accept an array', function () {
const error = [ 0, 1, 2 ]; const error = [ 0, 1, 2 ];
m.chai.expect(errors.getTitle(error)).to.equal('0,1,2'); m.chai.expect(errors.getTitle(error)).to.equal('0,1,2');
}); });
it('should return a generic error message if the error is an empty object', function() { it('should return a generic error message if the error is an empty object', function () {
const error = {}; const error = {};
m.chai.expect(errors.getTitle(error)).to.equal('An error ocurred'); m.chai.expect(errors.getTitle(error)).to.equal('An error ocurred');
}); });
it('should return a generic error message if the error is undefined', function() { it('should return a generic error message if the error is undefined', function () {
const error = undefined; const error = undefined;
m.chai.expect(errors.getTitle(error)).to.equal('An error ocurred'); m.chai.expect(errors.getTitle(error)).to.equal('An error ocurred');
}); });
it('should return a generic error message if the error is null', function() { it('should return a generic error message if the error is null', function () {
const error = null; const error = null;
m.chai.expect(errors.getTitle(error)).to.equal('An error ocurred'); m.chai.expect(errors.getTitle(error)).to.equal('An error ocurred');
}); });
it('should return the error message', function() { it('should return the error message', function () {
const error = new Error('This is an error'); const error = new Error('This is an error');
m.chai.expect(errors.getTitle(error)).to.equal('This is an error'); m.chai.expect(errors.getTitle(error)).to.equal('This is an error');
}); });
it('should return the error code if there is no message', function() { it('should return the error code if there is no message', function () {
const error = new Error(); const error = new Error();
error.code = 'MYERROR'; error.code = 'MYERROR';
m.chai.expect(errors.getTitle(error)).to.equal('Error code: MYERROR'); m.chai.expect(errors.getTitle(error)).to.equal('Error code: MYERROR');
}); });
it('should prioritise the message over the code', function() { it('should prioritise the message over the code', function () {
const error = new Error('Foo bar'); const error = new Error('Foo bar');
error.code = 'MYERROR'; error.code = 'MYERROR';
m.chai.expect(errors.getTitle(error)).to.equal('Foo bar'); m.chai.expect(errors.getTitle(error)).to.equal('Foo bar');
}); });
it('should prioritise the code over the message if the message is an empty string', function() { it('should prioritise the code over the message if the message is an empty string', function () {
const error = new Error(''); const error = new Error('');
error.code = 'MYERROR'; error.code = 'MYERROR';
m.chai.expect(errors.getTitle(error)).to.equal('Error code: MYERROR'); m.chai.expect(errors.getTitle(error)).to.equal('Error code: MYERROR');
}); });
it('should prioritise the code over the message if the message is a blank string', function() { it('should prioritise the code over the message if the message is a blank string', function () {
const error = new Error(' '); const error = new Error(' ');
error.code = 'MYERROR'; error.code = 'MYERROR';
m.chai.expect(errors.getTitle(error)).to.equal('Error code: MYERROR'); m.chai.expect(errors.getTitle(error)).to.equal('Error code: MYERROR');
}); });
it('should understand an error-like object with a code', function() { it('should understand an error-like object with a code', function () {
const error = { const error = {
code: 'MYERROR' code: 'MYERROR'
}; };
@ -115,7 +111,7 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.getTitle(error)).to.equal('Error code: MYERROR'); m.chai.expect(errors.getTitle(error)).to.equal('Error code: MYERROR');
}); });
it('should understand an error-like object with a message', function() { it('should understand an error-like object with a message', function () {
const error = { const error = {
message: 'Hello world' message: 'Hello world'
}; };
@ -123,7 +119,7 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.getTitle(error)).to.equal('Hello world'); m.chai.expect(errors.getTitle(error)).to.equal('Hello world');
}); });
it('should understand an error-like object with a message and a code', function() { it('should understand an error-like object with a message and a code', function () {
const error = { const error = {
message: 'Hello world', message: 'Hello world',
code: 'MYERROR' code: 'MYERROR'
@ -132,111 +128,109 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.getTitle(error)).to.equal('Hello world'); m.chai.expect(errors.getTitle(error)).to.equal('Hello world');
}); });
it('should display an error code 0', function() { it('should display an error code 0', function () {
const error = new Error(); const error = new Error();
error.code = 0; error.code = 0;
m.chai.expect(errors.getTitle(error)).to.equal('Error code: 0'); m.chai.expect(errors.getTitle(error)).to.equal('Error code: 0');
}); });
it('should display an error code 1', function() { it('should display an error code 1', function () {
const error = new Error(); const error = new Error();
error.code = 1; error.code = 1;
m.chai.expect(errors.getTitle(error)).to.equal('Error code: 1'); m.chai.expect(errors.getTitle(error)).to.equal('Error code: 1');
}); });
it('should display an error code -1', function() { it('should display an error code -1', function () {
const error = new Error(); const error = new Error();
error.code = -1; error.code = -1;
m.chai.expect(errors.getTitle(error)).to.equal('Error code: -1'); m.chai.expect(errors.getTitle(error)).to.equal('Error code: -1');
}); });
it('should not display an empty string error code', function() { it('should not display an empty string error code', function () {
const error = new Error(); const error = new Error();
error.code = ''; error.code = '';
m.chai.expect(errors.getTitle(error)).to.equal('An error ocurred'); m.chai.expect(errors.getTitle(error)).to.equal('An error ocurred');
}); });
it('should not display a blank string error code', function() { it('should not display a blank string error code', function () {
const error = new Error(); const error = new Error();
error.code = ' '; error.code = ' ';
m.chai.expect(errors.getTitle(error)).to.equal('An error ocurred'); m.chai.expect(errors.getTitle(error)).to.equal('An error ocurred');
}); });
it('should return a generic error message if no information was found', function() { it('should return a generic error message if no information was found', function () {
const error = new Error(); const error = new Error();
m.chai.expect(errors.getTitle(error)).to.equal('An error ocurred'); m.chai.expect(errors.getTitle(error)).to.equal('An error ocurred');
}); });
it('should return a generic error message if no code and the message is empty', function() { it('should return a generic error message if no code and the message is empty', function () {
const error = new Error(''); const error = new Error('');
m.chai.expect(errors.getTitle(error)).to.equal('An error ocurred'); m.chai.expect(errors.getTitle(error)).to.equal('An error ocurred');
}); });
it('should return a generic error message if no code and the message is blank', function() { it('should return a generic error message if no code and the message is blank', function () {
const error = new Error(' '); const error = new Error(' ');
m.chai.expect(errors.getTitle(error)).to.equal('An error ocurred'); m.chai.expect(errors.getTitle(error)).to.equal('An error ocurred');
}); });
it('should rephrase an ENOENT error', function() { it('should rephrase an ENOENT error', function () {
const error = new Error('ENOENT error'); const error = new Error('ENOENT error');
error.path = '/foo/bar'; error.path = '/foo/bar';
error.code = 'ENOENT'; error.code = 'ENOENT';
m.chai.expect(errors.getTitle(error)).to.equal('No such file or directory: /foo/bar'); m.chai.expect(errors.getTitle(error)).to.equal('No such file or directory: /foo/bar');
}); });
it('should rephrase an EPERM error', function() { it('should rephrase an EPERM error', function () {
const error = new Error('EPERM error'); const error = new Error('EPERM error');
error.code = 'EPERM'; error.code = 'EPERM';
m.chai.expect(errors.getTitle(error)).to.equal('You\'re not authorized to perform this operation'); m.chai.expect(errors.getTitle(error)).to.equal('You\'re not authorized to perform this operation');
}); });
it('should rephrase an EACCES error', function() { it('should rephrase an EACCES error', function () {
const error = new Error('EACCES error'); const error = new Error('EACCES error');
error.code = 'EACCES'; error.code = 'EACCES';
m.chai.expect(errors.getTitle(error)).to.equal('You don\'t have access to this resource'); m.chai.expect(errors.getTitle(error)).to.equal('You don\'t have access to this resource');
}); });
it('should rephrase an ENOMEM error', function() { it('should rephrase an ENOMEM error', function () {
const error = new Error('ENOMEM error'); const error = new Error('ENOMEM error');
error.code = 'ENOMEM'; error.code = 'ENOMEM';
m.chai.expect(errors.getTitle(error)).to.equal('Your system ran out of memory'); m.chai.expect(errors.getTitle(error)).to.equal('Your system ran out of memory');
}); });
}); });
describe('.getDescription()', function() { describe('.getDescription()', function () {
it('should return an empty string if the error is a string', function () {
it('should return an empty string if the error is a string', function() {
const error = 'My error'; const error = 'My error';
m.chai.expect(errors.getDescription(error)).to.equal(''); m.chai.expect(errors.getDescription(error)).to.equal('');
}); });
it('should return an empty string if the error is a number', function() { it('should return an empty string if the error is a number', function () {
const error = 0; const error = 0;
m.chai.expect(errors.getDescription(error)).to.equal(''); m.chai.expect(errors.getDescription(error)).to.equal('');
}); });
it('should return an empty string if the error is an array', function() { it('should return an empty string if the error is an array', function () {
const error = [ 1, 2, 3 ]; const error = [ 1, 2, 3 ];
m.chai.expect(errors.getDescription(error)).to.equal(''); m.chai.expect(errors.getDescription(error)).to.equal('');
}); });
it('should return an empty string if the error is undefined', function() { it('should return an empty string if the error is undefined', function () {
const error = undefined; const error = undefined;
m.chai.expect(errors.getDescription(error)).to.equal(''); m.chai.expect(errors.getDescription(error)).to.equal('');
}); });
it('should return an empty string if the error is null', function() { it('should return an empty string if the error is null', function () {
const error = null; const error = null;
m.chai.expect(errors.getDescription(error)).to.equal(''); m.chai.expect(errors.getDescription(error)).to.equal('');
}); });
it('should return an empty string if the error is an empty object', function() { it('should return an empty string if the error is an empty object', function () {
const error = {}; const error = {};
m.chai.expect(errors.getDescription(error)).to.equal(''); m.chai.expect(errors.getDescription(error)).to.equal('');
}); });
it('should understand an error-like object with a description', function() { it('should understand an error-like object with a description', function () {
const error = { const error = {
description: 'My description' description: 'My description'
}; };
@ -244,7 +238,7 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.getDescription(error)).to.equal('My description'); m.chai.expect(errors.getDescription(error)).to.equal('My description');
}); });
it('should understand an error-like object with a stack', function() { it('should understand an error-like object with a stack', function () {
const error = { const error = {
stack: 'My stack' stack: 'My stack'
}; };
@ -252,7 +246,7 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.getDescription(error)).to.equal('My stack'); m.chai.expect(errors.getDescription(error)).to.equal('My stack');
}); });
it('should understand an error-like object with a description and a stack', function() { it('should understand an error-like object with a description and a stack', function () {
const error = { const error = {
description: 'My description', description: 'My description',
stack: 'My stack' stack: 'My stack'
@ -261,7 +255,7 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.getDescription(error)).to.equal('My description'); m.chai.expect(errors.getDescription(error)).to.equal('My description');
}); });
it('should stringify and beautify an object without any known property', function() { it('should stringify and beautify an object without any known property', function () {
const error = { const error = {
name: 'John Doe', name: 'John Doe',
job: 'Developer' job: 'Developer'
@ -275,72 +269,71 @@ describe('Shared: Errors', function() {
].join('\n')); ].join('\n'));
}); });
it('should return the stack for a basic error', function() { it('should return the stack for a basic error', function () {
const error = new Error('Foo'); const error = new Error('Foo');
m.chai.expect(errors.getDescription(error)).to.equal(error.stack); m.chai.expect(errors.getDescription(error)).to.equal(error.stack);
}); });
it('should prefer a description property to a stack', function() { it('should prefer a description property to a stack', function () {
const error = new Error('Foo'); const error = new Error('Foo');
error.description = 'My description'; error.description = 'My description';
m.chai.expect(errors.getDescription(error)).to.equal('My description'); m.chai.expect(errors.getDescription(error)).to.equal('My description');
}); });
it('should return the stack if the description is an empty string', function() { it('should return the stack if the description is an empty string', function () {
const error = new Error('Foo'); const error = new Error('Foo');
error.description = ''; error.description = '';
m.chai.expect(errors.getDescription(error)).to.equal(error.stack); m.chai.expect(errors.getDescription(error)).to.equal(error.stack);
}); });
it('should return the stack if the description is a blank string', function() { it('should return the stack if the description is a blank string', function () {
const error = new Error('Foo'); const error = new Error('Foo');
error.description = ' '; error.description = ' ';
m.chai.expect(errors.getDescription(error)).to.equal(error.stack); m.chai.expect(errors.getDescription(error)).to.equal(error.stack);
}); });
it('should get a generic description for ENOENT', function() { it('should get a generic description for ENOENT', function () {
const error = new Error('Foo'); const error = new Error('Foo');
error.code = 'ENOENT'; error.code = 'ENOENT';
m.chai.expect(errors.getDescription(error)).to.equal('The file you\'re trying to access doesn\'t exist'); m.chai.expect(errors.getDescription(error)).to.equal('The file you\'re trying to access doesn\'t exist');
}); });
it('should get a generic description for EPERM', function() { it('should get a generic description for EPERM', function () {
const error = new Error('Foo'); const error = new Error('Foo');
error.code = 'EPERM'; error.code = 'EPERM';
m.chai.expect(errors.getDescription(error)).to.equal('Please ensure you have necessary permissions for this task'); m.chai.expect(errors.getDescription(error)).to.equal('Please ensure you have necessary permissions for this task');
}); });
it('should get a generic description for EACCES', function() { it('should get a generic description for EACCES', function () {
const error = new Error('Foo'); const error = new Error('Foo');
error.code = 'EACCES'; error.code = 'EACCES';
const message = 'Please ensure you have necessary permissions to access this resource'; const message = 'Please ensure you have necessary permissions to access this resource';
m.chai.expect(errors.getDescription(error)).to.equal(message); m.chai.expect(errors.getDescription(error)).to.equal(message);
}); });
it('should get a generic description for ENOMEM', function() { it('should get a generic description for ENOMEM', function () {
const error = new Error('Foo'); const error = new Error('Foo');
error.code = 'ENOMEM'; error.code = 'ENOMEM';
const message = 'Please make sure your system has enough available memory for this task'; const message = 'Please make sure your system has enough available memory for this task';
m.chai.expect(errors.getDescription(error)).to.equal(message); m.chai.expect(errors.getDescription(error)).to.equal(message);
}); });
it('should prefer a description property than a code description', function() { it('should prefer a description property than a code description', function () {
const error = new Error('Foo'); const error = new Error('Foo');
error.code = 'ENOMEM'; error.code = 'ENOMEM';
error.description = 'Memory error'; error.description = 'Memory error';
m.chai.expect(errors.getDescription(error)).to.equal('Memory error'); m.chai.expect(errors.getDescription(error)).to.equal('Memory error');
}); });
describe('given userFriendlyDescriptionsOnly is false', function() { describe('given userFriendlyDescriptionsOnly is false', function () {
it('should return the stack for a basic error', function () {
it('should return the stack for a basic error', function() {
const error = new Error('Foo'); const error = new Error('Foo');
m.chai.expect(errors.getDescription(error, { m.chai.expect(errors.getDescription(error, {
userFriendlyDescriptionsOnly: false userFriendlyDescriptionsOnly: false
})).to.equal(error.stack); })).to.equal(error.stack);
}); });
it('should return the stack if the description is an empty string', function() { it('should return the stack if the description is an empty string', function () {
const error = new Error('Foo'); const error = new Error('Foo');
error.description = ''; error.description = '';
m.chai.expect(errors.getDescription(error, { m.chai.expect(errors.getDescription(error, {
@ -348,26 +341,24 @@ describe('Shared: Errors', function() {
})).to.equal(error.stack); })).to.equal(error.stack);
}); });
it('should return the stack if the description is a blank string', function() { it('should return the stack if the description is a blank string', function () {
const error = new Error('Foo'); const error = new Error('Foo');
error.description = ' '; error.description = ' ';
m.chai.expect(errors.getDescription(error, { m.chai.expect(errors.getDescription(error, {
userFriendlyDescriptionsOnly: false userFriendlyDescriptionsOnly: false
})).to.equal(error.stack); })).to.equal(error.stack);
}); });
}); });
describe('given userFriendlyDescriptionsOnly is true', function() { describe('given userFriendlyDescriptionsOnly is true', function () {
it('should return an empty string for a basic error', function () {
it('should return an empty string for a basic error', function() {
const error = new Error('Foo'); const error = new Error('Foo');
m.chai.expect(errors.getDescription(error, { m.chai.expect(errors.getDescription(error, {
userFriendlyDescriptionsOnly: true userFriendlyDescriptionsOnly: true
})).to.equal(''); })).to.equal('');
}); });
it('should return an empty string if the description is an empty string', function() { it('should return an empty string if the description is an empty string', function () {
const error = new Error('Foo'); const error = new Error('Foo');
error.description = ''; error.description = '';
m.chai.expect(errors.getDescription(error, { m.chai.expect(errors.getDescription(error, {
@ -375,21 +366,18 @@ describe('Shared: Errors', function() {
})).to.equal(''); })).to.equal('');
}); });
it('should return an empty string if the description is a blank string', function() { it('should return an empty string if the description is a blank string', function () {
const error = new Error('Foo'); const error = new Error('Foo');
error.description = ' '; error.description = ' ';
m.chai.expect(errors.getDescription(error, { m.chai.expect(errors.getDescription(error, {
userFriendlyDescriptionsOnly: true userFriendlyDescriptionsOnly: true
})).to.equal(''); })).to.equal('');
}); });
}); });
}); });
describe('.createError()', function() { describe('.createError()', function () {
it('should not be a user error', function () {
it('should not be a user error', function() {
const error = errors.createError({ const error = errors.createError({
title: 'Foo', title: 'Foo',
description: 'Something happened' description: 'Something happened'
@ -398,7 +386,7 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.isUserError(error)).to.be.false; m.chai.expect(errors.isUserError(error)).to.be.false;
}); });
it('should be a user error if `options.report` is false', function() { it('should be a user error if `options.report` is false', function () {
const error = errors.createError({ const error = errors.createError({
title: 'Foo', title: 'Foo',
description: 'Something happened', description: 'Something happened',
@ -408,7 +396,7 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.isUserError(error)).to.be.true; m.chai.expect(errors.isUserError(error)).to.be.true;
}); });
it('should be a user error if `options.report` evaluates to false', function() { it('should be a user error if `options.report` evaluates to false', function () {
const error = errors.createError({ const error = errors.createError({
title: 'Foo', title: 'Foo',
description: 'Something happened', description: 'Something happened',
@ -418,7 +406,7 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.isUserError(error)).to.be.true; m.chai.expect(errors.isUserError(error)).to.be.true;
}); });
it('should not be a user error if `options.report` is true', function() { it('should not be a user error if `options.report` is true', function () {
const error = errors.createError({ const error = errors.createError({
title: 'Foo', title: 'Foo',
description: 'Something happened', description: 'Something happened',
@ -428,7 +416,7 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.isUserError(error)).to.be.false; m.chai.expect(errors.isUserError(error)).to.be.false;
}); });
it('should not be a user error if `options.report` evaluates to true', function() { it('should not be a user error if `options.report` evaluates to true', function () {
const error = errors.createError({ const error = errors.createError({
title: 'Foo', title: 'Foo',
description: 'Something happened', description: 'Something happened',
@ -438,7 +426,7 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.isUserError(error)).to.be.false; m.chai.expect(errors.isUserError(error)).to.be.false;
}); });
it('should be an instance of Error', function() { it('should be an instance of Error', function () {
const error = errors.createError({ const error = errors.createError({
title: 'Foo', title: 'Foo',
description: 'Something happened' description: 'Something happened'
@ -447,7 +435,7 @@ describe('Shared: Errors', function() {
m.chai.expect(error).to.be.an.instanceof(Error); m.chai.expect(error).to.be.an.instanceof(Error);
}); });
it('should correctly add both a title and a description', function() { it('should correctly add both a title and a description', function () {
const error = errors.createError({ const error = errors.createError({
title: 'Foo', title: 'Foo',
description: 'Something happened' description: 'Something happened'
@ -457,7 +445,7 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.getDescription(error)).to.equal('Something happened'); m.chai.expect(errors.getDescription(error)).to.equal('Something happened');
}); });
it('should correctly add only a title', function() { it('should correctly add only a title', function () {
const error = errors.createError({ const error = errors.createError({
title: 'Foo' title: 'Foo'
}); });
@ -466,7 +454,7 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.getDescription(error)).to.equal(error.stack); m.chai.expect(errors.getDescription(error)).to.equal(error.stack);
}); });
it('should ignore an empty description', function() { it('should ignore an empty description', function () {
const error = errors.createError({ const error = errors.createError({
title: 'Foo', title: 'Foo',
description: '' description: ''
@ -475,7 +463,7 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.getDescription(error)).to.equal(error.stack); m.chai.expect(errors.getDescription(error)).to.equal(error.stack);
}); });
it('should ignore a blank description', function() { it('should ignore a blank description', function () {
const error = errors.createError({ const error = errors.createError({
title: 'Foo', title: 'Foo',
description: ' ' description: ' '
@ -484,13 +472,13 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.getDescription(error)).to.equal(error.stack); m.chai.expect(errors.getDescription(error)).to.equal(error.stack);
}); });
it('should throw if no title', function() { it('should throw if no title', function () {
m.chai.expect(() => { m.chai.expect(() => {
errors.createError({}); errors.createError({});
}).to.throw('Invalid error title: undefined'); }).to.throw('Invalid error title: undefined');
}); });
it('should throw if there is a description but no title', function() { it('should throw if there is a description but no title', function () {
m.chai.expect(() => { m.chai.expect(() => {
errors.createError({ errors.createError({
description: 'foo' description: 'foo'
@ -498,7 +486,7 @@ describe('Shared: Errors', function() {
}).to.throw('Invalid error title: undefined'); }).to.throw('Invalid error title: undefined');
}); });
it('should throw if title is empty', function() { it('should throw if title is empty', function () {
m.chai.expect(() => { m.chai.expect(() => {
errors.createError({ errors.createError({
title: '' title: ''
@ -506,19 +494,17 @@ describe('Shared: Errors', function() {
}).to.throw('Invalid error title: '); }).to.throw('Invalid error title: ');
}); });
it('should throw if title is blank', function() { it('should throw if title is blank', function () {
m.chai.expect(() => { m.chai.expect(() => {
errors.createError({ errors.createError({
title: ' ' title: ' '
}); });
}).to.throw('Invalid error title: '); }).to.throw('Invalid error title: ');
}); });
}); });
describe('.createUserError()', function() { describe('.createUserError()', function () {
it('should be a user error', function () {
it('should be a user error', function() {
const error = errors.createUserError({ const error = errors.createUserError({
title: 'Foo', title: 'Foo',
description: 'Something happened' description: 'Something happened'
@ -527,7 +513,7 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.isUserError(error)).to.be.true; m.chai.expect(errors.isUserError(error)).to.be.true;
}); });
it('should be an instance of Error', function() { it('should be an instance of Error', function () {
const error = errors.createUserError({ const error = errors.createUserError({
title: 'Foo', title: 'Foo',
description: 'Something happened' description: 'Something happened'
@ -536,7 +522,7 @@ describe('Shared: Errors', function() {
m.chai.expect(error).to.be.an.instanceof(Error); m.chai.expect(error).to.be.an.instanceof(Error);
}); });
it('should correctly add both a title and a description', function() { it('should correctly add both a title and a description', function () {
const error = errors.createUserError({ const error = errors.createUserError({
title: 'Foo', title: 'Foo',
description: 'Something happened' description: 'Something happened'
@ -546,7 +532,7 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.getDescription(error)).to.equal('Something happened'); m.chai.expect(errors.getDescription(error)).to.equal('Something happened');
}); });
it('should correctly add only a title', function() { it('should correctly add only a title', function () {
const error = errors.createUserError({ const error = errors.createUserError({
title: 'Foo' title: 'Foo'
}); });
@ -555,7 +541,7 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.getDescription(error)).to.equal(error.stack); m.chai.expect(errors.getDescription(error)).to.equal(error.stack);
}); });
it('should ignore an empty description', function() { it('should ignore an empty description', function () {
const error = errors.createUserError({ const error = errors.createUserError({
title: 'Foo', title: 'Foo',
description: '' description: ''
@ -564,7 +550,7 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.getDescription(error)).to.equal(error.stack); m.chai.expect(errors.getDescription(error)).to.equal(error.stack);
}); });
it('should ignore a blank description', function() { it('should ignore a blank description', function () {
const error = errors.createUserError({ const error = errors.createUserError({
title: 'Foo', title: 'Foo',
description: ' ' description: ' '
@ -573,13 +559,13 @@ describe('Shared: Errors', function() {
m.chai.expect(errors.getDescription(error)).to.equal(error.stack); m.chai.expect(errors.getDescription(error)).to.equal(error.stack);
}); });
it('should throw if no title', function() { it('should throw if no title', function () {
m.chai.expect(() => { m.chai.expect(() => {
errors.createUserError({}); errors.createUserError({});
}).to.throw('Invalid error title: undefined'); }).to.throw('Invalid error title: undefined');
}); });
it('should throw if title is empty', function() { it('should throw if title is empty', function () {
m.chai.expect(() => { m.chai.expect(() => {
errors.createUserError({ errors.createUserError({
title: '' title: ''
@ -587,7 +573,7 @@ describe('Shared: Errors', function() {
}).to.throw('Invalid error title: '); }).to.throw('Invalid error title: ');
}); });
it('should throw if there is a description but no title', function() { it('should throw if there is a description but no title', function () {
m.chai.expect(() => { m.chai.expect(() => {
errors.createUserError({ errors.createUserError({
description: 'foo' description: 'foo'
@ -595,30 +581,26 @@ describe('Shared: Errors', function() {
}).to.throw('Invalid error title: undefined'); }).to.throw('Invalid error title: undefined');
}); });
it('should throw if title is blank', function() { it('should throw if title is blank', function () {
m.chai.expect(() => { m.chai.expect(() => {
errors.createUserError({ errors.createUserError({
title: ' ' title: ' '
}); });
}).to.throw('Invalid error title: '); }).to.throw('Invalid error title: ');
}); });
}); });
describe('.isUserError()', function() { describe('.isUserError()', function () {
_.each([ _.each([
0, 0,
'', '',
false false
], (value) => { ], (value) => {
it(`should return true if report equals ${value}`, function () {
it(`should return true if report equals ${value}`, function() {
const error = new Error('foo bar'); const error = new Error('foo bar');
error.report = value; error.report = value;
m.chai.expect(errors.isUserError(error)).to.be.true; m.chai.expect(errors.isUserError(error)).to.be.true;
}); });
}); });
_.each([ _.each([
@ -629,20 +611,16 @@ describe('Shared: Errors', function() {
3, 3,
'foo' 'foo'
], (value) => { ], (value) => {
it(`should return false if report equals ${value}`, function () {
it(`should return false if report equals ${value}`, function() {
const error = new Error('foo bar'); const error = new Error('foo bar');
error.report = value; error.report = value;
m.chai.expect(errors.isUserError(error)).to.be.false; m.chai.expect(errors.isUserError(error)).to.be.false;
}); });
}); });
}); });
describe('.toJSON()', function() { describe('.toJSON()', function () {
it('should convert a simple error', function () {
it('should convert a simple error', function() {
const error = new Error('My error'); const error = new Error('My error');
m.chai.expect(errors.toJSON(error)).to.deep.equal({ m.chai.expect(errors.toJSON(error)).to.deep.equal({
code: undefined, code: undefined,
@ -653,7 +631,7 @@ describe('Shared: Errors', function() {
}); });
}); });
it('should convert an error with a description', function() { it('should convert an error with a description', function () {
const error = new Error('My error'); const error = new Error('My error');
error.description = 'My description'; error.description = 'My description';
@ -666,7 +644,7 @@ describe('Shared: Errors', function() {
}); });
}); });
it('should convert an error with a code', function() { it('should convert an error with a code', function () {
const error = new Error('My error'); const error = new Error('My error');
error.code = 'ENOENT'; error.code = 'ENOENT';
@ -679,7 +657,7 @@ describe('Shared: Errors', function() {
}); });
}); });
it('should convert an error with a description and a code', function() { it('should convert an error with a description and a code', function () {
const error = new Error('My error'); const error = new Error('My error');
error.description = 'My description'; error.description = 'My description';
error.code = 'ENOENT'; error.code = 'ENOENT';
@ -693,7 +671,7 @@ describe('Shared: Errors', function() {
}); });
}); });
it('should convert an error with a report value', function() { it('should convert an error with a report value', function () {
const error = new Error('My error'); const error = new Error('My error');
error.report = true; error.report = true;
@ -706,7 +684,7 @@ describe('Shared: Errors', function() {
}); });
}); });
it('should convert an error without a message', function() { it('should convert an error without a message', function () {
const error = new Error(); const error = new Error();
m.chai.expect(errors.toJSON(error)).to.deep.equal({ m.chai.expect(errors.toJSON(error)).to.deep.equal({
@ -717,18 +695,16 @@ describe('Shared: Errors', function() {
report: undefined report: undefined
}); });
}); });
}); });
describe('.fromJSON()', function() { describe('.fromJSON()', function () {
it('should return an Error object', function () {
it('should return an Error object', function() {
const error = new Error('My error'); const error = new Error('My error');
const result = errors.fromJSON(errors.toJSON(error)); const result = errors.fromJSON(errors.toJSON(error));
m.chai.expect(result).to.be.an.instanceof(Error); m.chai.expect(result).to.be.an.instanceof(Error);
}); });
it('should convert a simple JSON error', function() { it('should convert a simple JSON error', function () {
const error = new Error('My error'); const error = new Error('My error');
const result = errors.fromJSON(errors.toJSON(error)); const result = errors.fromJSON(errors.toJSON(error));
@ -739,7 +715,7 @@ describe('Shared: Errors', function() {
m.chai.expect(result.report).to.equal(error.report); m.chai.expect(result.report).to.equal(error.report);
}); });
it('should convert a JSON error with a description', function() { it('should convert a JSON error with a description', function () {
const error = new Error('My error'); const error = new Error('My error');
error.description = 'My description'; error.description = 'My description';
const result = errors.fromJSON(errors.toJSON(error)); const result = errors.fromJSON(errors.toJSON(error));
@ -751,7 +727,7 @@ describe('Shared: Errors', function() {
m.chai.expect(result.report).to.equal(error.report); m.chai.expect(result.report).to.equal(error.report);
}); });
it('should convert a JSON error with a code', function() { it('should convert a JSON error with a code', function () {
const error = new Error('My error'); const error = new Error('My error');
error.code = 'ENOENT'; error.code = 'ENOENT';
const result = errors.fromJSON(errors.toJSON(error)); const result = errors.fromJSON(errors.toJSON(error));
@ -763,7 +739,7 @@ describe('Shared: Errors', function() {
m.chai.expect(result.report).to.equal(error.report); m.chai.expect(result.report).to.equal(error.report);
}); });
it('should convert a JSON error with a report value', function() { it('should convert a JSON error with a report value', function () {
const error = new Error('My error'); const error = new Error('My error');
error.report = false; error.report = false;
const result = errors.fromJSON(errors.toJSON(error)); const result = errors.fromJSON(errors.toJSON(error));
@ -774,7 +750,5 @@ describe('Shared: Errors', function() {
m.chai.expect(result.stack).to.equal(error.stack); m.chai.expect(result.stack).to.equal(error.stack);
m.chai.expect(result.report).to.equal(error.report); m.chai.expect(result.report).to.equal(error.report);
}); });
}); });
}); });

View File

@ -20,10 +20,8 @@ const m = require('mochainon');
const _ = require('lodash'); const _ = require('lodash');
const fileExtensions = require('../../lib/shared/file-extensions'); const fileExtensions = require('../../lib/shared/file-extensions');
describe('Shared: fileExtensions', function() { describe('Shared: fileExtensions', function () {
describe('.getFileExtensions()', function () {
describe('.getFileExtensions()', function() {
_.forEach([ _.forEach([
// No extension // No extension
@ -87,59 +85,53 @@ describe('Shared: fileExtensions', function() {
} }
], (testCase) => { ], (testCase) => {
it(`should return ${testCase.extensions} for ${testCase.file}`, function() { it(`should return ${testCase.extensions} for ${testCase.file}`, function () {
m.chai.expect(fileExtensions.getFileExtensions(testCase.file)).to.deep.equal(testCase.extensions); m.chai.expect(fileExtensions.getFileExtensions(testCase.file)).to.deep.equal(testCase.extensions);
}); });
}); });
it('should always return lowercase extensions', function() { it('should always return lowercase extensions', function () {
const filePath = 'foo.IMG.gZ'; const filePath = 'foo.IMG.gZ';
m.chai.expect(fileExtensions.getFileExtensions(filePath)).to.deep.equal([ m.chai.expect(fileExtensions.getFileExtensions(filePath)).to.deep.equal([
'img', 'img',
'gz' 'gz'
]); ]);
}); });
}); });
describe('.getLastFileExtension()', function() { describe('.getLastFileExtension()', function () {
it('should return undefined if the file path has no extension', function () {
it('should return undefined if the file path has no extension', function() {
m.chai.expect(fileExtensions.getLastFileExtension('foo')).to.be.undefined; m.chai.expect(fileExtensions.getLastFileExtension('foo')).to.be.undefined;
}); });
it('should return the extension if there is only one extension', function() { it('should return the extension if there is only one extension', function () {
m.chai.expect(fileExtensions.getLastFileExtension('foo.img')).to.equal('img'); m.chai.expect(fileExtensions.getLastFileExtension('foo.img')).to.equal('img');
}); });
it('should return the last extension if there are two extensions', function() { it('should return the last extension if there are two extensions', function () {
m.chai.expect(fileExtensions.getLastFileExtension('foo.img.gz')).to.equal('gz'); m.chai.expect(fileExtensions.getLastFileExtension('foo.img.gz')).to.equal('gz');
}); });
it('should return the last extension if there are three extensions', function() { it('should return the last extension if there are three extensions', function () {
m.chai.expect(fileExtensions.getLastFileExtension('foo.bar.img.gz')).to.equal('gz'); m.chai.expect(fileExtensions.getLastFileExtension('foo.bar.img.gz')).to.equal('gz');
}); });
}); });
describe('.getPenultimateFileExtension()', function() { describe('.getPenultimateFileExtension()', function () {
it('should return undefined in the file path has no extension', function () {
it('should return undefined in the file path has no extension', function() {
m.chai.expect(fileExtensions.getPenultimateFileExtension('foo')).to.be.undefined; m.chai.expect(fileExtensions.getPenultimateFileExtension('foo')).to.be.undefined;
}); });
it('should return undefined if there is only one extension', function() { it('should return undefined if there is only one extension', function () {
m.chai.expect(fileExtensions.getPenultimateFileExtension('foo.img')).to.be.undefined; m.chai.expect(fileExtensions.getPenultimateFileExtension('foo.img')).to.be.undefined;
}); });
it('should return the penultimate extension if there are two extensions', function() { it('should return the penultimate extension if there are two extensions', function () {
m.chai.expect(fileExtensions.getPenultimateFileExtension('foo.img.gz')).to.equal('img'); m.chai.expect(fileExtensions.getPenultimateFileExtension('foo.img.gz')).to.equal('img');
}); });
it('should return the penultimate extension if there are three extensions', function() { it('should return the penultimate extension if there are three extensions', function () {
m.chai.expect(fileExtensions.getPenultimateFileExtension('foo.bar.img.gz')).to.equal('img'); m.chai.expect(fileExtensions.getPenultimateFileExtension('foo.bar.img.gz')).to.equal('img');
}); });
}); });
}); });

View File

@ -20,16 +20,14 @@ const m = require('mochainon');
const _ = require('lodash'); const _ = require('lodash');
const messages = require('../../lib/shared/messages'); const messages = require('../../lib/shared/messages');
describe('Shared: Messages', function() { describe('Shared: Messages', function () {
it('should contain object properties', function () {
it('should contain object properties', function() {
m.chai.expect(_.every(_.map(messages, _.isPlainObject))).to.be.true; m.chai.expect(_.every(_.map(messages, _.isPlainObject))).to.be.true;
}); });
it('should contain function properties in each category', function() { it('should contain function properties in each category', function () {
_.each(messages, (category) => { _.each(messages, (category) => {
m.chai.expect(_.every(_.map(category, _.isFunction))).to.be.true; m.chai.expect(_.every(_.map(category, _.isFunction))).to.be.true;
}); });
}); });
}); });

View File

@ -21,30 +21,27 @@ const path = require('path');
const availableDrives = require('../../../lib/shared/models/available-drives'); const availableDrives = require('../../../lib/shared/models/available-drives');
const selectionState = require('../../../lib/shared/models/selection-state'); const selectionState = require('../../../lib/shared/models/selection-state');
describe('Model: availableDrives', function() { describe('Model: availableDrives', function () {
describe('availableDrives', function () {
describe('availableDrives', function() { it('should have no drives by default', function () {
it('should have no drives by default', function() {
m.chai.expect(availableDrives.getDrives()).to.deep.equal([]); m.chai.expect(availableDrives.getDrives()).to.deep.equal([]);
}); });
describe('.setDrives()', function() { describe('.setDrives()', function () {
it('should throw if no drives', function () {
it('should throw if no drives', function() { m.chai.expect(function () {
m.chai.expect(function() {
availableDrives.setDrives(); availableDrives.setDrives();
}).to.throw('Missing drives'); }).to.throw('Missing drives');
}); });
it('should throw if drives is not an array', function() { it('should throw if drives is not an array', function () {
m.chai.expect(function() { m.chai.expect(function () {
availableDrives.setDrives(123); availableDrives.setDrives(123);
}).to.throw('Invalid drives: 123'); }).to.throw('Invalid drives: 123');
}); });
it('should throw if drives is not an array of objects', function() { it('should throw if drives is not an array of objects', function () {
m.chai.expect(function() { m.chai.expect(function () {
availableDrives.setDrives([ availableDrives.setDrives([
123, 123,
123, 123,
@ -52,22 +49,17 @@ describe('Model: availableDrives', function() {
]); ]);
}).to.throw('Invalid drives: 123,123,123'); }).to.throw('Invalid drives: 123,123,123');
}); });
}); });
describe('given no drives', function() { describe('given no drives', function () {
describe('.hasAvailableDrives()', function () {
describe('.hasAvailableDrives()', function() { it('should return false', function () {
it('should return false', function() {
m.chai.expect(availableDrives.hasAvailableDrives()).to.be.false; m.chai.expect(availableDrives.hasAvailableDrives()).to.be.false;
}); });
}); });
describe('.setDrives()', function() { describe('.setDrives()', function () {
it('should be able to set drives', function () {
it('should be able to set drives', function() {
const drives = [ const drives = [
{ {
device: '/dev/sdb', device: '/dev/sdb',
@ -82,14 +74,13 @@ describe('Model: availableDrives', function() {
m.chai.expect(availableDrives.getDrives()).to.deep.equal(drives); m.chai.expect(availableDrives.getDrives()).to.deep.equal(drives);
}); });
describe('given no selected image and no selected drive', function() { describe('given no selected image and no selected drive', function () {
beforeEach(function () {
beforeEach(function() {
selectionState.removeDrive(); selectionState.removeDrive();
selectionState.removeImage(); selectionState.removeImage();
}); });
it('should auto-select a single valid available drive', function() { it('should auto-select a single valid available drive', function () {
m.chai.expect(selectionState.hasDrive()).to.be.false; m.chai.expect(selectionState.hasDrive()).to.be.false;
availableDrives.setDrives([ availableDrives.setDrives([
@ -106,12 +97,10 @@ describe('Model: availableDrives', function() {
m.chai.expect(selectionState.hasDrive()).to.be.true; m.chai.expect(selectionState.hasDrive()).to.be.true;
m.chai.expect(selectionState.getDrive().device).to.equal('/dev/sdb'); m.chai.expect(selectionState.getDrive().device).to.equal('/dev/sdb');
}); });
}); });
describe('given a selected image and no selected drive', function() { describe('given a selected image and no selected drive', function () {
beforeEach(function () {
beforeEach(function() {
if (process.platform === 'win32') { if (process.platform === 'win32') {
this.imagePath = 'E:\\bar\\foo.img'; this.imagePath = 'E:\\bar\\foo.img';
} else { } else {
@ -133,11 +122,11 @@ describe('Model: availableDrives', function() {
}); });
}); });
afterEach(function() { afterEach(function () {
selectionState.removeImage(); selectionState.removeImage();
}); });
it('should not auto-select when there are multiple valid available drives', function() { it('should not auto-select when there are multiple valid available drives', function () {
m.chai.expect(selectionState.hasDrive()).to.be.false; m.chai.expect(selectionState.hasDrive()).to.be.false;
availableDrives.setDrives([ availableDrives.setDrives([
@ -162,7 +151,7 @@ describe('Model: availableDrives', function() {
m.chai.expect(selectionState.hasDrive()).to.be.false; m.chai.expect(selectionState.hasDrive()).to.be.false;
}); });
it('should auto-select a single valid available drive', function() { it('should auto-select a single valid available drive', function () {
m.chai.expect(selectionState.hasDrive()).to.be.false; m.chai.expect(selectionState.hasDrive()).to.be.false;
availableDrives.setDrives([ availableDrives.setDrives([
@ -186,7 +175,7 @@ describe('Model: availableDrives', function() {
}); });
}); });
it('should not auto-select a single too small drive', function() { it('should not auto-select a single too small drive', function () {
m.chai.expect(selectionState.hasDrive()).to.be.false; m.chai.expect(selectionState.hasDrive()).to.be.false;
availableDrives.setDrives([ availableDrives.setDrives([
@ -203,7 +192,7 @@ describe('Model: availableDrives', function() {
m.chai.expect(selectionState.hasDrive()).to.be.false; m.chai.expect(selectionState.hasDrive()).to.be.false;
}); });
it('should not auto-select a single drive that doesn\'t meet the recommended size', function() { it('should not auto-select a single drive that doesn\'t meet the recommended size', function () {
m.chai.expect(selectionState.hasDrive()).to.be.false; m.chai.expect(selectionState.hasDrive()).to.be.false;
availableDrives.setDrives([ availableDrives.setDrives([
@ -220,7 +209,7 @@ describe('Model: availableDrives', function() {
m.chai.expect(selectionState.hasDrive()).to.be.false; m.chai.expect(selectionState.hasDrive()).to.be.false;
}); });
it('should not auto-select a single protected drive', function() { it('should not auto-select a single protected drive', function () {
m.chai.expect(selectionState.hasDrive()).to.be.false; m.chai.expect(selectionState.hasDrive()).to.be.false;
availableDrives.setDrives([ availableDrives.setDrives([
@ -237,7 +226,7 @@ describe('Model: availableDrives', function() {
m.chai.expect(selectionState.hasDrive()).to.be.false; m.chai.expect(selectionState.hasDrive()).to.be.false;
}); });
it('should not auto-select a source drive', function() { it('should not auto-select a source drive', function () {
m.chai.expect(selectionState.hasDrive()).to.be.false; m.chai.expect(selectionState.hasDrive()).to.be.false;
availableDrives.setDrives([ availableDrives.setDrives([
@ -258,7 +247,7 @@ describe('Model: availableDrives', function() {
m.chai.expect(selectionState.hasDrive()).to.be.false; m.chai.expect(selectionState.hasDrive()).to.be.false;
}); });
it('should not auto-select a single system drive', function() { it('should not auto-select a single system drive', function () {
m.chai.expect(selectionState.hasDrive()).to.be.false; m.chai.expect(selectionState.hasDrive()).to.be.false;
availableDrives.setDrives([ availableDrives.setDrives([
@ -274,16 +263,12 @@ describe('Model: availableDrives', function() {
m.chai.expect(selectionState.hasDrive()).to.be.false; m.chai.expect(selectionState.hasDrive()).to.be.false;
}); });
}); });
}); });
}); });
describe('given drives', function() { describe('given drives', function () {
beforeEach(function () {
beforeEach(function() {
this.drives = [ this.drives = [
{ {
device: '/dev/sdb', device: '/dev/sdb',
@ -306,9 +291,8 @@ describe('Model: availableDrives', function() {
availableDrives.setDrives(this.drives); availableDrives.setDrives(this.drives);
}); });
describe('given one of the drives was selected', function() { describe('given one of the drives was selected', function () {
beforeEach(function () {
beforeEach(function() {
availableDrives.setDrives([ availableDrives.setDrives([
{ {
device: '/dev/sdc', device: '/dev/sdc',
@ -323,11 +307,11 @@ describe('Model: availableDrives', function() {
selectionState.setDrive('/dev/sdc'); selectionState.setDrive('/dev/sdc');
}); });
afterEach(function() { afterEach(function () {
selectionState.removeDrive(); selectionState.removeDrive();
}); });
it('should be deleted if its not contained in the available drives anymore', function() { it('should be deleted if its not contained in the available drives anymore', function () {
m.chai.expect(selectionState.hasDrive()).to.be.true; m.chai.expect(selectionState.hasDrive()).to.be.true;
// We have to provide at least two drives, otherwise, // We have to provide at least two drives, otherwise,
@ -354,39 +338,32 @@ describe('Model: availableDrives', function() {
m.chai.expect(selectionState.hasDrive()).to.be.false; m.chai.expect(selectionState.hasDrive()).to.be.false;
}); });
}); });
describe('.hasAvailableDrives()', function() { describe('.hasAvailableDrives()', function () {
it('should return true', function () {
it('should return true', function() {
const hasDrives = availableDrives.hasAvailableDrives(); const hasDrives = availableDrives.hasAvailableDrives();
m.chai.expect(hasDrives).to.be.true; m.chai.expect(hasDrives).to.be.true;
}); });
}); });
describe('.setDrives()', function() { describe('.setDrives()', function () {
it('should keep the same drives if equal', function () {
it('should keep the same drives if equal', function() {
availableDrives.setDrives(this.drives); availableDrives.setDrives(this.drives);
m.chai.expect(availableDrives.getDrives()).to.deep.equal(this.drives); m.chai.expect(availableDrives.getDrives()).to.deep.equal(this.drives);
}); });
it('should return empty array given an empty array', function() { it('should return empty array given an empty array', function () {
availableDrives.setDrives([]); availableDrives.setDrives([]);
m.chai.expect(availableDrives.getDrives()).to.deep.equal([]); m.chai.expect(availableDrives.getDrives()).to.deep.equal([]);
}); });
it('should consider drives with different $$hashKey the same', function() { it('should consider drives with different $$hashKey the same', function () {
this.drives[0].$$haskey = 1234; this.drives[0].$$haskey = 1234;
availableDrives.setDrives(this.drives); availableDrives.setDrives(this.drives);
m.chai.expect(availableDrives.getDrives()).to.deep.equal(this.drives); m.chai.expect(availableDrives.getDrives()).to.deep.equal(this.drives);
}); });
}); });
}); });
}); });
}); });

View File

@ -19,17 +19,14 @@
const m = require('mochainon'); const m = require('mochainon');
const flashState = require('../../../lib/shared/models/flash-state'); const flashState = require('../../../lib/shared/models/flash-state');
describe('Model: flashState', function() { describe('Model: flashState', function () {
beforeEach(function () {
beforeEach(function() {
flashState.resetState(); flashState.resetState();
}); });
describe('flashState', function() { describe('flashState', function () {
describe('.resetState()', function () {
describe('.resetState()', function() { it('should be able to reset the progress state', function () {
it('should be able to reset the progress state', function() {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
flashState.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
@ -46,7 +43,7 @@ describe('Model: flashState', function() {
}); });
}); });
it('should be able to reset the progress state', function() { it('should be able to reset the progress state', function () {
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234' sourceChecksum: '1234'
@ -56,42 +53,38 @@ describe('Model: flashState', function() {
m.chai.expect(flashState.getFlashResults()).to.deep.equal({}); m.chai.expect(flashState.getFlashResults()).to.deep.equal({});
}); });
it('should unset the flashing flag', function() { it('should unset the flashing flag', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
flashState.resetState(); flashState.resetState();
m.chai.expect(flashState.isFlashing()).to.be.false; m.chai.expect(flashState.isFlashing()).to.be.false;
}); });
it('should unset the flash uuid', function() { it('should unset the flash uuid', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
flashState.resetState(); flashState.resetState();
m.chai.expect(flashState.getFlashUuid()).to.be.undefined; m.chai.expect(flashState.getFlashUuid()).to.be.undefined;
}); });
}); });
describe('.isFlashing()', function() { describe('.isFlashing()', function () {
it('should return false by default', function () {
it('should return false by default', function() {
m.chai.expect(flashState.isFlashing()).to.be.false; m.chai.expect(flashState.isFlashing()).to.be.false;
}); });
it('should return true if flashing', function() { it('should return true if flashing', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(flashState.isFlashing()).to.be.true; m.chai.expect(flashState.isFlashing()).to.be.true;
}); });
}); });
describe('.setProgressState()', function() { describe('.setProgressState()', function () {
it('should not allow setting the state if flashing is false', function () {
it('should not allow setting the state if flashing is false', function() {
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234' sourceChecksum: '1234'
}); });
m.chai.expect(function() { m.chai.expect(function () {
flashState.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 50, percentage: 50,
@ -101,9 +94,9 @@ describe('Model: flashState', function() {
}).to.throw('Can\'t set the flashing state when not flashing'); }).to.throw('Can\'t set the flashing state when not flashing');
}); });
it('should throw if type is missing', function() { it('should throw if type is missing', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function () {
flashState.setProgressState({ flashState.setProgressState({
percentage: 50, percentage: 50,
eta: 15, eta: 15,
@ -112,9 +105,9 @@ describe('Model: flashState', function() {
}).to.throw('Missing state type'); }).to.throw('Missing state type');
}); });
it('should throw if type is not a string', function() { it('should throw if type is not a string', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function () {
flashState.setProgressState({ flashState.setProgressState({
type: 1234, type: 1234,
percentage: 50, percentage: 50,
@ -124,9 +117,9 @@ describe('Model: flashState', function() {
}).to.throw('Invalid state type: 1234'); }).to.throw('Invalid state type: 1234');
}); });
it('should not throw if percentage is 0', function() { it('should not throw if percentage is 0', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function () {
flashState.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 0, percentage: 0,
@ -136,9 +129,9 @@ describe('Model: flashState', function() {
}).to.not.throw('Missing state percentage'); }).to.not.throw('Missing state percentage');
}); });
it('should throw if percentage is missing', function() { it('should throw if percentage is missing', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function () {
flashState.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
eta: 15, eta: 15,
@ -147,9 +140,9 @@ describe('Model: flashState', function() {
}).to.throw('Missing state percentage'); }).to.throw('Missing state percentage');
}); });
it('should throw if percentage is not a number', function() { it('should throw if percentage is not a number', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function () {
flashState.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: '50', percentage: '50',
@ -159,9 +152,9 @@ describe('Model: flashState', function() {
}).to.throw('Invalid state percentage: 50'); }).to.throw('Invalid state percentage: 50');
}); });
it('should throw if percentage is outside maximum bound', function() { it('should throw if percentage is outside maximum bound', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function () {
flashState.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 101, percentage: 101,
@ -171,9 +164,9 @@ describe('Model: flashState', function() {
}).to.throw('Invalid state percentage: 101'); }).to.throw('Invalid state percentage: 101');
}); });
it('should throw if percentage is outside minimum bound', function() { it('should throw if percentage is outside minimum bound', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function () {
flashState.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: -1, percentage: -1,
@ -183,9 +176,9 @@ describe('Model: flashState', function() {
}).to.throw('Invalid state percentage: -1'); }).to.throw('Invalid state percentage: -1');
}); });
it('should throw if eta is missing', function() { it('should throw if eta is missing', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function () {
flashState.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 50, percentage: 50,
@ -194,9 +187,9 @@ describe('Model: flashState', function() {
}).to.throw('Missing state eta'); }).to.throw('Missing state eta');
}); });
it('should not throw if eta is equal to zero', function() { it('should not throw if eta is equal to zero', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function () {
flashState.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 50, percentage: 50,
@ -206,9 +199,9 @@ describe('Model: flashState', function() {
}).to.not.throw('Missing state eta'); }).to.not.throw('Missing state eta');
}); });
it('should throw if eta is not a number', function() { it('should throw if eta is not a number', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function () {
flashState.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 50, percentage: 50,
@ -218,9 +211,9 @@ describe('Model: flashState', function() {
}).to.throw('Invalid state eta: 15'); }).to.throw('Invalid state eta: 15');
}); });
it('should throw if speed is missing', function() { it('should throw if speed is missing', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function () {
flashState.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 50, percentage: 50,
@ -229,9 +222,9 @@ describe('Model: flashState', function() {
}).to.throw('Missing state speed'); }).to.throw('Missing state speed');
}); });
it('should not throw if speed is 0', function() { it('should not throw if speed is 0', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function () {
flashState.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 50, percentage: 50,
@ -240,12 +233,10 @@ describe('Model: flashState', function() {
}); });
}).to.not.throw('Missing state speed'); }).to.not.throw('Missing state speed');
}); });
}); });
describe('.getFlashResults()', function() { describe('.getFlashResults()', function () {
it('should get the flash results', function () {
it('should get the flash results', function() {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
const expectedResults = { const expectedResults = {
@ -257,12 +248,10 @@ describe('Model: flashState', function() {
const results = flashState.getFlashResults(); const results = flashState.getFlashResults();
m.chai.expect(results).to.deep.equal(expectedResults); m.chai.expect(results).to.deep.equal(expectedResults);
}); });
}); });
describe('.getFlashState()', function() { describe('.getFlashState()', function () {
it('should initially return an empty state', function () {
it('should initially return an empty state', function() {
flashState.resetState(); flashState.resetState();
const currentFlashState = flashState.getFlashState(); const currentFlashState = flashState.getFlashState();
m.chai.expect(currentFlashState).to.deep.equal({ m.chai.expect(currentFlashState).to.deep.equal({
@ -271,7 +260,7 @@ describe('Model: flashState', function() {
}); });
}); });
it('should return the current flash state', function() { it('should return the current flash state', function () {
const state = { const state = {
type: 'write', type: 'write',
percentage: 50, percentage: 50,
@ -284,18 +273,16 @@ describe('Model: flashState', function() {
const currentFlashState = flashState.getFlashState(); const currentFlashState = flashState.getFlashState();
m.chai.expect(currentFlashState).to.deep.equal(state); m.chai.expect(currentFlashState).to.deep.equal(state);
}); });
}); });
describe('.unsetFlashingFlag()', function() { describe('.unsetFlashingFlag()', function () {
it('should throw if no flashing results', function () {
it('should throw if no flashing results', function() { m.chai.expect(function () {
m.chai.expect(function() {
flashState.unsetFlashingFlag(); flashState.unsetFlashingFlag();
}).to.throw('Missing results'); }).to.throw('Missing results');
}); });
it('should be able to set a string error code', function() { it('should be able to set a string error code', function () {
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234', sourceChecksum: '1234',
@ -305,7 +292,7 @@ describe('Model: flashState', function() {
m.chai.expect(flashState.getLastFlashErrorCode()).to.equal('EBUSY'); m.chai.expect(flashState.getLastFlashErrorCode()).to.equal('EBUSY');
}); });
it('should be able to set a number error code', function() { it('should be able to set a number error code', function () {
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234', sourceChecksum: '1234',
@ -315,8 +302,8 @@ describe('Model: flashState', function() {
m.chai.expect(flashState.getLastFlashErrorCode()).to.equal(123); m.chai.expect(flashState.getLastFlashErrorCode()).to.equal(123);
}); });
it('should throw if errorCode is not a number not a string', function() { it('should throw if errorCode is not a number not a string', function () {
m.chai.expect(function() { m.chai.expect(function () {
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234', sourceChecksum: '1234',
@ -327,7 +314,7 @@ describe('Model: flashState', function() {
}).to.throw('Invalid results errorCode: [object Object]'); }).to.throw('Invalid results errorCode: [object Object]');
}); });
it('should default cancelled to false', function() { it('should default cancelled to false', function () {
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
sourceChecksum: '1234' sourceChecksum: '1234'
}); });
@ -340,8 +327,8 @@ describe('Model: flashState', function() {
}); });
}); });
it('should throw if cancelled is not boolean', function() { it('should throw if cancelled is not boolean', function () {
m.chai.expect(function() { m.chai.expect(function () {
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: 'false', cancelled: 'false',
sourceChecksum: '1234' sourceChecksum: '1234'
@ -349,8 +336,8 @@ describe('Model: flashState', function() {
}).to.throw('Invalid results cancelled: false'); }).to.throw('Invalid results cancelled: false');
}); });
it('should throw if cancelled is true and sourceChecksum exists', function() { it('should throw if cancelled is true and sourceChecksum exists', function () {
m.chai.expect(function() { m.chai.expect(function () {
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: true, cancelled: true,
sourceChecksum: '1234' sourceChecksum: '1234'
@ -358,7 +345,7 @@ describe('Model: flashState', function() {
}).to.throw('The sourceChecksum value can\'t exist if the flashing was cancelled'); }).to.throw('The sourceChecksum value can\'t exist if the flashing was cancelled');
}); });
it('should be able to set flashing to false', function() { it('should be able to set flashing to false', function () {
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234' sourceChecksum: '1234'
@ -367,7 +354,7 @@ describe('Model: flashState', function() {
m.chai.expect(flashState.isFlashing()).to.be.false; m.chai.expect(flashState.isFlashing()).to.be.false;
}); });
it('should reset the flashing state', function() { it('should reset the flashing state', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
flashState.setProgressState({ flashState.setProgressState({
@ -393,7 +380,7 @@ describe('Model: flashState', function() {
}); });
}); });
it('should not reset the flash uuid', function() { it('should not reset the flash uuid', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
const uuidBeforeUnset = flashState.getFlashUuid(); const uuidBeforeUnset = flashState.getFlashUuid();
@ -405,17 +392,15 @@ describe('Model: flashState', function() {
const uuidAfterUnset = flashState.getFlashUuid(); const uuidAfterUnset = flashState.getFlashUuid();
m.chai.expect(uuidBeforeUnset).to.equal(uuidAfterUnset); m.chai.expect(uuidBeforeUnset).to.equal(uuidAfterUnset);
}); });
}); });
describe('.setFlashingFlag()', function() { describe('.setFlashingFlag()', function () {
it('should be able to set flashing to true', function () {
it('should be able to set flashing to true', function() {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(flashState.isFlashing()).to.be.true; m.chai.expect(flashState.isFlashing()).to.be.true;
}); });
it('should reset the flash results', function() { it('should reset the flash results', function () {
const expectedResults = { const expectedResults = {
cancelled: false, cancelled: false,
sourceChecksum: '1234' sourceChecksum: '1234'
@ -427,17 +412,15 @@ describe('Model: flashState', function() {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(flashState.getFlashResults()).to.deep.equal({}); m.chai.expect(flashState.getFlashResults()).to.deep.equal({});
}); });
}); });
describe('.wasLastFlashCancelled()', function() { describe('.wasLastFlashCancelled()', function () {
it('should return false given a pristine state', function () {
it('should return false given a pristine state', function() {
flashState.resetState(); flashState.resetState();
m.chai.expect(flashState.wasLastFlashCancelled()).to.be.false; m.chai.expect(flashState.wasLastFlashCancelled()).to.be.false;
}); });
it('should return false if !cancelled', function() { it('should return false if !cancelled', function () {
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
sourceChecksum: '1234', sourceChecksum: '1234',
cancelled: false cancelled: false
@ -446,24 +429,22 @@ describe('Model: flashState', function() {
m.chai.expect(flashState.wasLastFlashCancelled()).to.be.false; m.chai.expect(flashState.wasLastFlashCancelled()).to.be.false;
}); });
it('should return true if cancelled', function() { it('should return true if cancelled', function () {
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: true cancelled: true
}); });
m.chai.expect(flashState.wasLastFlashCancelled()).to.be.true; m.chai.expect(flashState.wasLastFlashCancelled()).to.be.true;
}); });
}); });
describe('.getLastFlashSourceChecksum()', function() { describe('.getLastFlashSourceChecksum()', function () {
it('should return undefined given a pristine state', function () {
it('should return undefined given a pristine state', function() {
flashState.resetState(); flashState.resetState();
m.chai.expect(flashState.getLastFlashSourceChecksum()).to.be.undefined; m.chai.expect(flashState.getLastFlashSourceChecksum()).to.be.undefined;
}); });
it('should return the last flash source checksum', function() { it('should return the last flash source checksum', function () {
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
sourceChecksum: '1234', sourceChecksum: '1234',
cancelled: false cancelled: false
@ -472,24 +453,22 @@ describe('Model: flashState', function() {
m.chai.expect(flashState.getLastFlashSourceChecksum()).to.equal('1234'); m.chai.expect(flashState.getLastFlashSourceChecksum()).to.equal('1234');
}); });
it('should return undefined if the last flash was cancelled', function() { it('should return undefined if the last flash was cancelled', function () {
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: true cancelled: true
}); });
m.chai.expect(flashState.getLastFlashSourceChecksum()).to.be.undefined; m.chai.expect(flashState.getLastFlashSourceChecksum()).to.be.undefined;
}); });
}); });
describe('.getLastFlashErrorCode()', function() { describe('.getLastFlashErrorCode()', function () {
it('should return undefined given a pristine state', function () {
it('should return undefined given a pristine state', function() {
flashState.resetState(); flashState.resetState();
m.chai.expect(flashState.getLastFlashErrorCode()).to.be.undefined; m.chai.expect(flashState.getLastFlashErrorCode()).to.be.undefined;
}); });
it('should return the last flash error code', function() { it('should return the last flash error code', function () {
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
sourceChecksum: '1234', sourceChecksum: '1234',
cancelled: false, cancelled: false,
@ -499,7 +478,7 @@ describe('Model: flashState', function() {
m.chai.expect(flashState.getLastFlashErrorCode()).to.equal('ENOSPC'); m.chai.expect(flashState.getLastFlashErrorCode()).to.equal('ENOSPC');
}); });
it('should return undefined if the last flash did not report an error code', function() { it('should return undefined if the last flash did not report an error code', function () {
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
sourceChecksum: '1234', sourceChecksum: '1234',
cancelled: false cancelled: false
@ -507,24 +486,22 @@ describe('Model: flashState', function() {
m.chai.expect(flashState.getLastFlashErrorCode()).to.be.undefined; m.chai.expect(flashState.getLastFlashErrorCode()).to.be.undefined;
}); });
}); });
describe('.getFlashUuid()', function() { describe('.getFlashUuid()', function () {
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/; const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
it('should be initially undefined', function() { it('should be initially undefined', function () {
m.chai.expect(flashState.getFlashUuid()).to.be.undefined; m.chai.expect(flashState.getFlashUuid()).to.be.undefined;
}); });
it('should be a valid uuid if the flashing flag is set', function() { it('should be a valid uuid if the flashing flag is set', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
const uuid = flashState.getFlashUuid(); const uuid = flashState.getFlashUuid();
m.chai.expect(UUID_REGEX.test(uuid)).to.be.true; m.chai.expect(UUID_REGEX.test(uuid)).to.be.true;
}); });
it('should return different uuids every time the flashing flag is set', function() { it('should return different uuids every time the flashing flag is set', function () {
flashState.setFlashingFlag(); flashState.setFlashingFlag();
const uuid1 = flashState.getFlashUuid(); const uuid1 = flashState.getFlashUuid();
flashState.unsetFlashingFlag({ flashState.unsetFlashingFlag({
@ -553,9 +530,6 @@ describe('Model: flashState', function() {
m.chai.expect(uuid2).to.not.equal(uuid3); m.chai.expect(uuid2).to.not.equal(uuid3);
m.chai.expect(uuid3).to.not.equal(uuid1); m.chai.expect(uuid3).to.not.equal(uuid1);
}); });
}); });
}); });
}); });

View File

@ -22,66 +22,62 @@ const path = require('path');
const availableDrives = require('../../../lib/shared/models/available-drives'); const availableDrives = require('../../../lib/shared/models/available-drives');
const selectionState = require('../../../lib/shared/models/selection-state'); const selectionState = require('../../../lib/shared/models/selection-state');
describe('Model: selectionState', function() { describe('Model: selectionState', function () {
describe('given a clean state', function () {
describe('given a clean state', function() { beforeEach(function () {
beforeEach(function() {
selectionState.clear(); selectionState.clear();
}); });
it('getDrive() should return undefined', function() { it('getDrive() should return undefined', function () {
const drive = selectionState.getDrive(); const drive = selectionState.getDrive();
m.chai.expect(drive).to.be.undefined; m.chai.expect(drive).to.be.undefined;
}); });
it('getImage() should return undefined', function() { it('getImage() should return undefined', function () {
m.chai.expect(selectionState.getImage()).to.be.undefined; m.chai.expect(selectionState.getImage()).to.be.undefined;
}); });
it('getImagePath() should return undefined', function() { it('getImagePath() should return undefined', function () {
m.chai.expect(selectionState.getImagePath()).to.be.undefined; m.chai.expect(selectionState.getImagePath()).to.be.undefined;
}); });
it('getImageSize() should return undefined', function() { it('getImageSize() should return undefined', function () {
m.chai.expect(selectionState.getImageSize()).to.be.undefined; m.chai.expect(selectionState.getImageSize()).to.be.undefined;
}); });
it('getImageUrl() should return undefined', function() { it('getImageUrl() should return undefined', function () {
m.chai.expect(selectionState.getImageUrl()).to.be.undefined; m.chai.expect(selectionState.getImageUrl()).to.be.undefined;
}); });
it('getImageName() should return undefined', function() { it('getImageName() should return undefined', function () {
m.chai.expect(selectionState.getImageName()).to.be.undefined; m.chai.expect(selectionState.getImageName()).to.be.undefined;
}); });
it('getImageLogo() should return undefined', function() { it('getImageLogo() should return undefined', function () {
m.chai.expect(selectionState.getImageLogo()).to.be.undefined; m.chai.expect(selectionState.getImageLogo()).to.be.undefined;
}); });
it('getImageSupportUrl() should return undefined', function() { it('getImageSupportUrl() should return undefined', function () {
m.chai.expect(selectionState.getImageSupportUrl()).to.be.undefined; m.chai.expect(selectionState.getImageSupportUrl()).to.be.undefined;
}); });
it('getImageRecommendedDriveSize() should return undefined', function() { it('getImageRecommendedDriveSize() should return undefined', function () {
m.chai.expect(selectionState.getImageRecommendedDriveSize()).to.be.undefined; m.chai.expect(selectionState.getImageRecommendedDriveSize()).to.be.undefined;
}); });
it('hasDrive() should return false', function() { it('hasDrive() should return false', function () {
const hasDrive = selectionState.hasDrive(); const hasDrive = selectionState.hasDrive();
m.chai.expect(hasDrive).to.be.false; m.chai.expect(hasDrive).to.be.false;
}); });
it('hasImage() should return false', function() { it('hasImage() should return false', function () {
const hasImage = selectionState.hasImage(); const hasImage = selectionState.hasImage();
m.chai.expect(hasImage).to.be.false; m.chai.expect(hasImage).to.be.false;
}); });
}); });
describe('given a drive', function() { describe('given a drive', function () {
beforeEach(function () {
beforeEach(function() {
availableDrives.setDrives([ availableDrives.setDrives([
{ {
device: '/dev/disk2', device: '/dev/disk2',
@ -100,9 +96,8 @@ describe('Model: selectionState', function() {
selectionState.setDrive('/dev/disk2'); selectionState.setDrive('/dev/disk2');
}); });
describe('.getDrive()', function() { describe('.getDrive()', function () {
it('should return the drive', function () {
it('should return the drive', function() {
const drive = selectionState.getDrive(); const drive = selectionState.getDrive();
m.chai.expect(drive).to.deep.equal({ m.chai.expect(drive).to.deep.equal({
device: '/dev/disk2', device: '/dev/disk2',
@ -111,21 +106,17 @@ describe('Model: selectionState', function() {
protected: false protected: false
}); });
}); });
}); });
describe('.hasDrive()', function() { describe('.hasDrive()', function () {
it('should return true', function () {
it('should return true', function() {
const hasDrive = selectionState.hasDrive(); const hasDrive = selectionState.hasDrive();
m.chai.expect(hasDrive).to.be.true; m.chai.expect(hasDrive).to.be.true;
}); });
}); });
describe('.setDrive()', function() { describe('.setDrive()', function () {
it('should override the drive', function () {
it('should override the drive', function() {
selectionState.setDrive('/dev/disk5'); selectionState.setDrive('/dev/disk5');
const drive = selectionState.getDrive(); const drive = selectionState.getDrive();
m.chai.expect(drive).to.deep.equal({ m.chai.expect(drive).to.deep.equal({
@ -135,26 +126,20 @@ describe('Model: selectionState', function() {
protected: false protected: false
}); });
}); });
}); });
describe('.removeDrive()', function() { describe('.removeDrive()', function () {
it('should clear the drive', function () {
it('should clear the drive', function() {
selectionState.removeDrive(); selectionState.removeDrive();
const drive = selectionState.getDrive(); const drive = selectionState.getDrive();
m.chai.expect(drive).to.be.undefined; m.chai.expect(drive).to.be.undefined;
}); });
}); });
}); });
describe('given no drive', function() { describe('given no drive', function () {
describe('.setDrive()', function () {
describe('.setDrive()', function() { it('should be able to set a drive', function () {
it('should be able to set a drive', function() {
availableDrives.setDrives([ availableDrives.setDrives([
{ {
device: '/dev/disk5', device: '/dev/disk5',
@ -174,7 +159,7 @@ describe('Model: selectionState', function() {
}); });
}); });
it('should throw if drive is write protected', function() { it('should throw if drive is write protected', function () {
availableDrives.setDrives([ availableDrives.setDrives([
{ {
device: '/dev/disk1', device: '/dev/disk1',
@ -184,12 +169,12 @@ describe('Model: selectionState', function() {
} }
]); ]);
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setDrive('/dev/disk1'); selectionState.setDrive('/dev/disk1');
}).to.throw('The drive is write-protected'); }).to.throw('The drive is write-protected');
}); });
it('should throw if the drive is not available', function() { it('should throw if the drive is not available', function () {
availableDrives.setDrives([ availableDrives.setDrives([
{ {
device: '/dev/disk1', device: '/dev/disk1',
@ -199,24 +184,21 @@ describe('Model: selectionState', function() {
} }
]); ]);
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setDrive('/dev/disk5'); selectionState.setDrive('/dev/disk5');
}).to.throw('The drive is not available: /dev/disk5'); }).to.throw('The drive is not available: /dev/disk5');
}); });
it('should throw if device is not a string', function() { it('should throw if device is not a string', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setDrive(123); selectionState.setDrive(123);
}).to.throw('Invalid drive: 123'); }).to.throw('Invalid drive: 123');
}); });
}); });
}); });
describe('given an image', function() { describe('given an image', function () {
beforeEach(function () {
beforeEach(function() {
this.image = { this.image = {
path: 'foo.img', path: 'foo.img',
extension: 'img', extension: 'img',
@ -237,9 +219,8 @@ describe('Model: selectionState', function() {
selectionState.setImage(this.image); selectionState.setImage(this.image);
}); });
describe('.setDrive()', function() { describe('.setDrive()', function () {
it('should throw if drive is not large enough', function () {
it('should throw if drive is not large enough', function() {
availableDrives.setDrives([ availableDrives.setDrives([
{ {
device: '/dev/disk2', device: '/dev/disk2',
@ -249,96 +230,76 @@ describe('Model: selectionState', function() {
} }
]); ]);
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setDrive('/dev/disk2'); selectionState.setDrive('/dev/disk2');
}).to.throw('The drive is not large enough'); }).to.throw('The drive is not large enough');
}); });
}); });
describe('.getImage()', function() { describe('.getImage()', function () {
it('should return the image', function () {
it('should return the image', function() {
m.chai.expect(selectionState.getImage()).to.deep.equal(this.image); m.chai.expect(selectionState.getImage()).to.deep.equal(this.image);
}); });
}); });
describe('.getImagePath()', function() { describe('.getImagePath()', function () {
it('should return the image path', function () {
it('should return the image path', function() {
const imagePath = selectionState.getImagePath(); const imagePath = selectionState.getImagePath();
m.chai.expect(imagePath).to.equal('foo.img'); m.chai.expect(imagePath).to.equal('foo.img');
}); });
}); });
describe('.getImageSize()', function() { describe('.getImageSize()', function () {
it('should return the image size', function () {
it('should return the image size', function() {
const imageSize = selectionState.getImageSize(); const imageSize = selectionState.getImageSize();
m.chai.expect(imageSize).to.equal(999999999); m.chai.expect(imageSize).to.equal(999999999);
}); });
}); });
describe('.getImageUrl()', function() { describe('.getImageUrl()', function () {
it('should return the image url', function () {
it('should return the image url', function() {
const imageUrl = selectionState.getImageUrl(); const imageUrl = selectionState.getImageUrl();
m.chai.expect(imageUrl).to.equal('https://www.raspbian.org'); m.chai.expect(imageUrl).to.equal('https://www.raspbian.org');
}); });
}); });
describe('.getImageName()', function() { describe('.getImageName()', function () {
it('should return the image name', function () {
it('should return the image name', function() {
const imageName = selectionState.getImageName(); const imageName = selectionState.getImageName();
m.chai.expect(imageName).to.equal('Raspbian'); m.chai.expect(imageName).to.equal('Raspbian');
}); });
}); });
describe('.getImageLogo()', function() { describe('.getImageLogo()', function () {
it('should return the image logo', function () {
it('should return the image logo', function() {
const imageLogo = selectionState.getImageLogo(); const imageLogo = selectionState.getImageLogo();
m.chai.expect(imageLogo).to.equal('<svg><text fill="red">Raspbian</text></svg>'); m.chai.expect(imageLogo).to.equal('<svg><text fill="red">Raspbian</text></svg>');
}); });
}); });
describe('.getImageSupportUrl()', function() { describe('.getImageSupportUrl()', function () {
it('should return the image support url', function () {
it('should return the image support url', function() {
const imageSupportUrl = selectionState.getImageSupportUrl(); const imageSupportUrl = selectionState.getImageSupportUrl();
m.chai.expect(imageSupportUrl).to.equal('https://www.raspbian.org/forums/'); m.chai.expect(imageSupportUrl).to.equal('https://www.raspbian.org/forums/');
}); });
}); });
describe('.getImageRecommendedDriveSize()', function() { describe('.getImageRecommendedDriveSize()', function () {
it('should return the image recommended drive size', function () {
it('should return the image recommended drive size', function() {
const imageRecommendedDriveSize = selectionState.getImageRecommendedDriveSize(); const imageRecommendedDriveSize = selectionState.getImageRecommendedDriveSize();
m.chai.expect(imageRecommendedDriveSize).to.equal(1000000000); m.chai.expect(imageRecommendedDriveSize).to.equal(1000000000);
}); });
}); });
describe('.hasImage()', function() { describe('.hasImage()', function () {
it('should return true', function () {
it('should return true', function() {
const hasImage = selectionState.hasImage(); const hasImage = selectionState.hasImage();
m.chai.expect(hasImage).to.be.true; m.chai.expect(hasImage).to.be.true;
}); });
}); });
describe('.setImage()', function() { describe('.setImage()', function () {
it('should override the image', function () {
it('should override the image', function() {
selectionState.setImage({ selectionState.setImage({
path: 'bar.img', path: 'bar.img',
extension: 'img', extension: 'img',
@ -356,12 +317,10 @@ describe('Model: selectionState', function() {
const imageSize = selectionState.getImageSize(); const imageSize = selectionState.getImageSize();
m.chai.expect(imageSize).to.equal(999999999); m.chai.expect(imageSize).to.equal(999999999);
}); });
}); });
describe('.removeImage()', function() { describe('.removeImage()', function () {
it('should clear the image', function () {
it('should clear the image', function() {
selectionState.removeImage(); selectionState.removeImage();
const imagePath = selectionState.getImagePath(); const imagePath = selectionState.getImagePath();
@ -369,16 +328,12 @@ describe('Model: selectionState', function() {
const imageSize = selectionState.getImageSize(); const imageSize = selectionState.getImageSize();
m.chai.expect(imageSize).to.be.undefined; m.chai.expect(imageSize).to.be.undefined;
}); });
}); });
}); });
describe('given no image', function() { describe('given no image', function () {
describe('.setImage()', function () {
describe('.setImage()', function() { it('should be able to set an image', function () {
it('should be able to set an image', function() {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img', path: 'foo.img',
extension: 'img', extension: 'img',
@ -397,7 +352,7 @@ describe('Model: selectionState', function() {
m.chai.expect(imageSize).to.equal(999999999); m.chai.expect(imageSize).to.equal(999999999);
}); });
it('should be able to set an image with an archive extension', function() { it('should be able to set an image with an archive extension', function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.zip', path: 'foo.zip',
extension: 'img', extension: 'img',
@ -415,8 +370,8 @@ describe('Model: selectionState', function() {
m.chai.expect(imagePath).to.equal('foo.zip'); m.chai.expect(imagePath).to.equal('foo.zip');
}); });
it('should throw if no path', function() { it('should throw if no path', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
extension: 'img', extension: 'img',
size: { size: {
@ -430,8 +385,8 @@ describe('Model: selectionState', function() {
}).to.throw('Missing image path'); }).to.throw('Missing image path');
}); });
it('should throw if path is not a string', function() { it('should throw if path is not a string', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 123, path: 123,
extension: 'img', extension: 'img',
@ -446,8 +401,8 @@ describe('Model: selectionState', function() {
}).to.throw('Invalid image path: 123'); }).to.throw('Invalid image path: 123');
}); });
it('should throw if no extension', function() { it('should throw if no extension', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img', path: 'foo.img',
size: { size: {
@ -461,8 +416,8 @@ describe('Model: selectionState', function() {
}).to.throw('Missing image extension'); }).to.throw('Missing image extension');
}); });
it('should throw if extension is not a string', function() { it('should throw if extension is not a string', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img', path: 'foo.img',
extension: 1, extension: 1,
@ -477,8 +432,8 @@ describe('Model: selectionState', function() {
}).to.throw('Invalid image extension: 1'); }).to.throw('Invalid image extension: 1');
}); });
it('should throw if the extension doesn\'t match the path and there is no archive extension', function() { it('should throw if the extension doesn\'t match the path and there is no archive extension', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img', path: 'foo.img',
extension: 'iso', extension: 'iso',
@ -493,8 +448,8 @@ describe('Model: selectionState', function() {
}).to.throw('Missing image archive extension'); }).to.throw('Missing image archive extension');
}); });
it('should throw if the extension doesn\'t match the path and the archive extension is not a string', function() { it('should throw if the extension doesn\'t match the path and the archive extension is not a string', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img', path: 'foo.img',
extension: 'iso', extension: 'iso',
@ -510,8 +465,8 @@ describe('Model: selectionState', function() {
}).to.throw('Invalid image archive extension: 1'); }).to.throw('Invalid image archive extension: 1');
}); });
it('should throw if the archive extension doesn\'t match the last path extension in a compressed image', function() { it('should throw if the archive extension doesn\'t match the last path extension in a compressed image', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img.xz', path: 'foo.img.xz',
extension: 'img', extension: 'img',
@ -527,8 +482,8 @@ describe('Model: selectionState', function() {
}).to.throw('Image archive extension mismatch: gz and xz'); }).to.throw('Image archive extension mismatch: gz and xz');
}); });
it('should throw if the extension is not recognised in an uncompressed image', function() { it('should throw if the extension is not recognised in an uncompressed image', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.ifg', path: 'foo.ifg',
extension: 'ifg', extension: 'ifg',
@ -543,8 +498,8 @@ describe('Model: selectionState', function() {
}).to.throw('Invalid image extension: ifg'); }).to.throw('Invalid image extension: ifg');
}); });
it('should throw if the extension is not recognised in a compressed image', function() { it('should throw if the extension is not recognised in a compressed image', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.ifg.gz', path: 'foo.ifg.gz',
extension: 'ifg', extension: 'ifg',
@ -560,8 +515,8 @@ describe('Model: selectionState', function() {
}).to.throw('Invalid image extension: ifg'); }).to.throw('Invalid image extension: ifg');
}); });
it('should throw if the archive extension is not recognised', function() { it('should throw if the archive extension is not recognised', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img.ifg', path: 'foo.img.ifg',
extension: 'img', extension: 'img',
@ -577,8 +532,8 @@ describe('Model: selectionState', function() {
}).to.throw('Invalid image archive extension: ifg'); }).to.throw('Invalid image archive extension: ifg');
}); });
it('should throw if no size', function() { it('should throw if no size', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img', path: 'foo.img',
extension: 'img' extension: 'img'
@ -586,8 +541,8 @@ describe('Model: selectionState', function() {
}).to.throw('Missing image size'); }).to.throw('Missing image size');
}); });
it('should throw if size is not a plain object', function() { it('should throw if size is not a plain object', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img', path: 'foo.img',
extension: 'img', extension: 'img',
@ -596,8 +551,8 @@ describe('Model: selectionState', function() {
}).to.throw('Invalid image size: 999999999'); }).to.throw('Invalid image size: 999999999');
}); });
it('should throw if the original size is not a number', function() { it('should throw if the original size is not a number', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img', path: 'foo.img',
extension: 'img', extension: 'img',
@ -612,8 +567,8 @@ describe('Model: selectionState', function() {
}).to.throw('Invalid original image size: 999999999'); }).to.throw('Invalid original image size: 999999999');
}); });
it('should throw if the original size is a float number', function() { it('should throw if the original size is a float number', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img', path: 'foo.img',
extension: 'img', extension: 'img',
@ -628,8 +583,8 @@ describe('Model: selectionState', function() {
}).to.throw('Invalid original image size: 999999999.999'); }).to.throw('Invalid original image size: 999999999.999');
}); });
it('should throw if the original size is negative', function() { it('should throw if the original size is negative', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img', path: 'foo.img',
extension: 'img', extension: 'img',
@ -644,8 +599,8 @@ describe('Model: selectionState', function() {
}).to.throw('Invalid original image size: -1'); }).to.throw('Invalid original image size: -1');
}); });
it('should throw if the final size is not a number', function() { it('should throw if the final size is not a number', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img', path: 'foo.img',
extension: 'img', extension: 'img',
@ -660,8 +615,8 @@ describe('Model: selectionState', function() {
}).to.throw('Invalid final image size: 999999999'); }).to.throw('Invalid final image size: 999999999');
}); });
it('should throw if the final size is a float number', function() { it('should throw if the final size is a float number', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img', path: 'foo.img',
extension: 'img', extension: 'img',
@ -676,8 +631,8 @@ describe('Model: selectionState', function() {
}).to.throw('Invalid final image size: 999999999.999'); }).to.throw('Invalid final image size: 999999999.999');
}); });
it('should throw if the final size is negative', function() { it('should throw if the final size is negative', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img', path: 'foo.img',
extension: 'img', extension: 'img',
@ -692,8 +647,8 @@ describe('Model: selectionState', function() {
}).to.throw('Invalid final image size: -1'); }).to.throw('Invalid final image size: -1');
}); });
it('should throw if the final size estimation flag is not a boolean', function() { it('should throw if the final size estimation flag is not a boolean', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img', path: 'foo.img',
extension: 'img', extension: 'img',
@ -708,8 +663,8 @@ describe('Model: selectionState', function() {
}).to.throw('Invalid final image size estimation flag: false'); }).to.throw('Invalid final image size estimation flag: false');
}); });
it('should throw if url is defined but it\'s not a string', function() { it('should throw if url is defined but it\'s not a string', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img', path: 'foo.img',
extension: 'img', extension: 'img',
@ -725,8 +680,8 @@ describe('Model: selectionState', function() {
}).to.throw('Invalid image url: 1234'); }).to.throw('Invalid image url: 1234');
}); });
it('should throw if name is defined but it\'s not a string', function() { it('should throw if name is defined but it\'s not a string', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img', path: 'foo.img',
extension: 'img', extension: 'img',
@ -742,8 +697,8 @@ describe('Model: selectionState', function() {
}).to.throw('Invalid image name: 1234'); }).to.throw('Invalid image name: 1234');
}); });
it('should throw if logo is defined but it\'s not a string', function() { it('should throw if logo is defined but it\'s not a string', function () {
m.chai.expect(function() { m.chai.expect(function () {
selectionState.setImage({ selectionState.setImage({
path: 'foo.img', path: 'foo.img',
extension: 'img', extension: 'img',
@ -759,7 +714,7 @@ describe('Model: selectionState', function() {
}).to.throw('Invalid image logo: 1234'); }).to.throw('Invalid image logo: 1234');
}); });
it('should de-select a previously selected not-large-enough drive', function() { it('should de-select a previously selected not-large-enough drive', function () {
availableDrives.setDrives([ availableDrives.setDrives([
{ {
device: '/dev/disk1', device: '/dev/disk1',
@ -788,7 +743,7 @@ describe('Model: selectionState', function() {
selectionState.removeImage(); selectionState.removeImage();
}); });
it('should de-select a previously selected not-recommended drive', function() { it('should de-select a previously selected not-recommended drive', function () {
availableDrives.setDrives([ availableDrives.setDrives([
{ {
device: '/dev/disk1', device: '/dev/disk1',
@ -818,7 +773,7 @@ describe('Model: selectionState', function() {
selectionState.removeImage(); selectionState.removeImage();
}); });
it('should de-select a previously selected source drive', function() { it('should de-select a previously selected source drive', function () {
const imagePath = _.attempt(() => { const imagePath = _.attempt(() => {
if (process.platform === 'win32') { if (process.platform === 'win32') {
return 'E:\\bar\\foo.img'; return 'E:\\bar\\foo.img';
@ -859,14 +814,11 @@ describe('Model: selectionState', function() {
m.chai.expect(selectionState.hasDrive()).to.be.false; m.chai.expect(selectionState.hasDrive()).to.be.false;
selectionState.removeImage(); selectionState.removeImage();
}); });
}); });
}); });
describe('given a drive', function() { describe('given a drive', function () {
beforeEach(function () {
beforeEach(function() {
availableDrives.setDrives([ availableDrives.setDrives([
{ {
device: '/dev/disk1', device: '/dev/disk1',
@ -891,9 +843,8 @@ describe('Model: selectionState', function() {
}); });
}); });
describe('.clear()', function() { describe('.clear()', function () {
it('should clear all selections', function () {
it('should clear all selections', function() {
m.chai.expect(selectionState.hasDrive()).to.be.true; m.chai.expect(selectionState.hasDrive()).to.be.true;
m.chai.expect(selectionState.hasImage()).to.be.true; m.chai.expect(selectionState.hasImage()).to.be.true;
@ -902,51 +853,45 @@ describe('Model: selectionState', function() {
m.chai.expect(selectionState.hasDrive()).to.be.false; m.chai.expect(selectionState.hasDrive()).to.be.false;
m.chai.expect(selectionState.hasImage()).to.be.false; m.chai.expect(selectionState.hasImage()).to.be.false;
}); });
}); });
describe('given the preserveImage option', function() { describe('given the preserveImage option', function () {
beforeEach(function () {
beforeEach(function() {
selectionState.clear({ selectionState.clear({
preserveImage: true preserveImage: true
}); });
}); });
it('getDrive() should return undefined', function() { it('getDrive() should return undefined', function () {
const drive = selectionState.getDrive(); const drive = selectionState.getDrive();
m.chai.expect(drive).to.be.undefined; m.chai.expect(drive).to.be.undefined;
}); });
it('getImagePath() should return the image path', function() { it('getImagePath() should return the image path', function () {
const imagePath = selectionState.getImagePath(); const imagePath = selectionState.getImagePath();
m.chai.expect(imagePath).to.equal('foo.img'); m.chai.expect(imagePath).to.equal('foo.img');
}); });
it('getImageSize() should return the image size', function() { it('getImageSize() should return the image size', function () {
const imageSize = selectionState.getImageSize(); const imageSize = selectionState.getImageSize();
m.chai.expect(imageSize).to.equal(999999999); m.chai.expect(imageSize).to.equal(999999999);
}); });
it('hasDrive() should return false', function() { it('hasDrive() should return false', function () {
const hasDrive = selectionState.hasDrive(); const hasDrive = selectionState.hasDrive();
m.chai.expect(hasDrive).to.be.false; m.chai.expect(hasDrive).to.be.false;
}); });
it('hasImage() should return true', function() { it('hasImage() should return true', function () {
const hasImage = selectionState.hasImage(); const hasImage = selectionState.hasImage();
m.chai.expect(hasImage).to.be.true; m.chai.expect(hasImage).to.be.true;
}); });
}); });
}); });
describe('.isCurrentDrive()', function() { describe('.isCurrentDrive()', function () {
describe('given a selected drive', function () {
describe('given a selected drive', function() { beforeEach(function () {
beforeEach(function() {
availableDrives.setDrives([ availableDrives.setDrives([
{ {
device: '/dev/sdb', device: '/dev/sdb',
@ -962,43 +907,37 @@ describe('Model: selectionState', function() {
selectionState.setDrive('/dev/sdb'); selectionState.setDrive('/dev/sdb');
}); });
it('should return false if an undefined value is passed', function() { it('should return false if an undefined value is passed', function () {
m.chai.expect(selectionState.isCurrentDrive()).to.be.false; m.chai.expect(selectionState.isCurrentDrive()).to.be.false;
}); });
it('should return true given the exact same drive', function() { it('should return true given the exact same drive', function () {
m.chai.expect(selectionState.isCurrentDrive('/dev/sdb')).to.be.true; m.chai.expect(selectionState.isCurrentDrive('/dev/sdb')).to.be.true;
}); });
it('should return false if it is not the current drive', function() { it('should return false if it is not the current drive', function () {
m.chai.expect(selectionState.isCurrentDrive('/dev/sdc')).to.be.false; m.chai.expect(selectionState.isCurrentDrive('/dev/sdc')).to.be.false;
}); });
}); });
describe('given no selected drive', function() { describe('given no selected drive', function () {
beforeEach(function () {
beforeEach(function() {
selectionState.removeDrive(); selectionState.removeDrive();
}); });
it('should return false if an undefined value is passed', function() { it('should return false if an undefined value is passed', function () {
m.chai.expect(selectionState.isCurrentDrive()).to.be.false; m.chai.expect(selectionState.isCurrentDrive()).to.be.false;
}); });
it('should return false for anything', function() { it('should return false for anything', function () {
m.chai.expect(selectionState.isCurrentDrive('/dev/sdb')).to.be.false; m.chai.expect(selectionState.isCurrentDrive('/dev/sdb')).to.be.false;
}); });
}); });
}); });
describe('.toggleSetDrive()', function() { describe('.toggleSetDrive()', function () {
describe('given a selected drive', function () {
describe('given a selected drive', function() { beforeEach(function () {
beforeEach(function() {
this.drive = { this.drive = {
device: '/dev/sdb', device: '/dev/sdb',
description: 'DataTraveler 2.0', description: 'DataTraveler 2.0',
@ -1022,13 +961,13 @@ describe('Model: selectionState', function() {
selectionState.setDrive(this.drive.device); selectionState.setDrive(this.drive.device);
}); });
it('should be able to remove the drive', function() { it('should be able to remove the drive', function () {
m.chai.expect(selectionState.hasDrive()).to.be.true; m.chai.expect(selectionState.hasDrive()).to.be.true;
selectionState.toggleSetDrive(this.drive.device); selectionState.toggleSetDrive(this.drive.device);
m.chai.expect(selectionState.hasDrive()).to.be.false; m.chai.expect(selectionState.hasDrive()).to.be.false;
}); });
it('should be able to replace the drive', function() { it('should be able to replace the drive', function () {
const drive = { const drive = {
device: '/dev/disk2', device: '/dev/disk2',
name: 'USB Drive', name: 'USB Drive',
@ -1041,16 +980,14 @@ describe('Model: selectionState', function() {
m.chai.expect(selectionState.getDrive()).to.deep.equal(drive); m.chai.expect(selectionState.getDrive()).to.deep.equal(drive);
m.chai.expect(selectionState.getDrive()).to.not.deep.equal(this.drive); m.chai.expect(selectionState.getDrive()).to.not.deep.equal(this.drive);
}); });
}); });
describe('given no selected drive', function() { describe('given no selected drive', function () {
beforeEach(function () {
beforeEach(function() {
selectionState.removeDrive(); selectionState.removeDrive();
}); });
it('should set the drive', function() { it('should set the drive', function () {
const drive = { const drive = {
device: '/dev/disk2', device: '/dev/disk2',
name: 'USB Drive', name: 'USB Drive',
@ -1062,9 +999,6 @@ describe('Model: selectionState', function() {
selectionState.toggleSetDrive(drive.device); selectionState.toggleSetDrive(drive.device);
m.chai.expect(selectionState.getDrive()).to.deep.equal(drive); m.chai.expect(selectionState.getDrive()).to.deep.equal(drive);
}); });
}); });
}); });
}); });

View File

@ -20,30 +20,27 @@ const m = require('mochainon');
const os = require('os'); const os = require('os');
const permissions = require('../../lib/shared/permissions'); const permissions = require('../../lib/shared/permissions');
describe('Shared: permissions', function() { describe('Shared: permissions', function () {
describe('.getEnvironmentCommandPrefix()', function () {
describe('.getEnvironmentCommandPrefix()', function() { describe('given windows', function () {
beforeEach(function () {
describe('given windows', function() {
beforeEach(function() {
this.osPlatformStub = m.sinon.stub(os, 'platform'); this.osPlatformStub = m.sinon.stub(os, 'platform');
this.osPlatformStub.returns('win32'); this.osPlatformStub.returns('win32');
}); });
afterEach(function() { afterEach(function () {
this.osPlatformStub.restore(); this.osPlatformStub.restore();
}); });
it('should return an empty array if no environment', function() { it('should return an empty array if no environment', function () {
m.chai.expect(permissions.getEnvironmentCommandPrefix()).to.deep.equal([]); m.chai.expect(permissions.getEnvironmentCommandPrefix()).to.deep.equal([]);
}); });
it('should return an empty array if the environment is an empty object', function() { it('should return an empty array if the environment is an empty object', function () {
m.chai.expect(permissions.getEnvironmentCommandPrefix({})).to.deep.equal([]); m.chai.expect(permissions.getEnvironmentCommandPrefix({})).to.deep.equal([]);
}); });
it('should create an environment command prefix out of one variable', function() { it('should create an environment command prefix out of one variable', function () {
m.chai.expect(permissions.getEnvironmentCommandPrefix({ m.chai.expect(permissions.getEnvironmentCommandPrefix({
FOO: 'bar' FOO: 'bar'
})).to.deep.equal([ })).to.deep.equal([
@ -54,7 +51,7 @@ describe('Shared: permissions', function() {
]); ]);
}); });
it('should create an environment command prefix out of many variables', function() { it('should create an environment command prefix out of many variables', function () {
m.chai.expect(permissions.getEnvironmentCommandPrefix({ m.chai.expect(permissions.getEnvironmentCommandPrefix({
FOO: 'bar', FOO: 'bar',
BAR: 'baz', BAR: 'baz',
@ -73,7 +70,7 @@ describe('Shared: permissions', function() {
]); ]);
}); });
it('should ignore undefined and null variable values', function() { it('should ignore undefined and null variable values', function () {
m.chai.expect(permissions.getEnvironmentCommandPrefix({ m.chai.expect(permissions.getEnvironmentCommandPrefix({
FOO: null, FOO: null,
BAR: 'qux', BAR: 'qux',
@ -86,7 +83,7 @@ describe('Shared: permissions', function() {
]); ]);
}); });
it('should stringify number values', function() { it('should stringify number values', function () {
m.chai.expect(permissions.getEnvironmentCommandPrefix({ m.chai.expect(permissions.getEnvironmentCommandPrefix({
FOO: 1, FOO: 1,
BAR: 0, BAR: 0,
@ -104,29 +101,27 @@ describe('Shared: permissions', function() {
'call' 'call'
]); ]);
}); });
}); });
describe('given linux', function() { describe('given linux', function () {
beforeEach(function () {
beforeEach(function() {
this.osPlatformStub = m.sinon.stub(os, 'platform'); this.osPlatformStub = m.sinon.stub(os, 'platform');
this.osPlatformStub.returns('linux'); this.osPlatformStub.returns('linux');
}); });
afterEach(function() { afterEach(function () {
this.osPlatformStub.restore(); this.osPlatformStub.restore();
}); });
it('should return an empty array if no environment', function() { it('should return an empty array if no environment', function () {
m.chai.expect(permissions.getEnvironmentCommandPrefix()).to.deep.equal([]); m.chai.expect(permissions.getEnvironmentCommandPrefix()).to.deep.equal([]);
}); });
it('should return an empty array if the environment is an empty object', function() { it('should return an empty array if the environment is an empty object', function () {
m.chai.expect(permissions.getEnvironmentCommandPrefix({})).to.deep.equal([]); m.chai.expect(permissions.getEnvironmentCommandPrefix({})).to.deep.equal([]);
}); });
it('should create an environment command prefix out of one variable', function() { it('should create an environment command prefix out of one variable', function () {
m.chai.expect(permissions.getEnvironmentCommandPrefix({ m.chai.expect(permissions.getEnvironmentCommandPrefix({
FOO: 'bar' FOO: 'bar'
})).to.deep.equal([ })).to.deep.equal([
@ -135,7 +130,7 @@ describe('Shared: permissions', function() {
]); ]);
}); });
it('should create an environment command prefix out of many variables', function() { it('should create an environment command prefix out of many variables', function () {
m.chai.expect(permissions.getEnvironmentCommandPrefix({ m.chai.expect(permissions.getEnvironmentCommandPrefix({
FOO: 'bar', FOO: 'bar',
BAR: 'baz', BAR: 'baz',
@ -148,7 +143,7 @@ describe('Shared: permissions', function() {
]); ]);
}); });
it('should ignore undefined and null variable values', function() { it('should ignore undefined and null variable values', function () {
m.chai.expect(permissions.getEnvironmentCommandPrefix({ m.chai.expect(permissions.getEnvironmentCommandPrefix({
FOO: null, FOO: null,
BAR: 'qux', BAR: 'qux',
@ -159,7 +154,7 @@ describe('Shared: permissions', function() {
]); ]);
}); });
it('should stringify number values', function() { it('should stringify number values', function () {
m.chai.expect(permissions.getEnvironmentCommandPrefix({ m.chai.expect(permissions.getEnvironmentCommandPrefix({
FOO: 1, FOO: 1,
BAR: 0, BAR: 0,
@ -171,29 +166,27 @@ describe('Shared: permissions', function() {
'BAZ=-1' 'BAZ=-1'
]); ]);
}); });
}); });
describe('given darwin', function() { describe('given darwin', function () {
beforeEach(function () {
beforeEach(function() {
this.osPlatformStub = m.sinon.stub(os, 'platform'); this.osPlatformStub = m.sinon.stub(os, 'platform');
this.osPlatformStub.returns('darwin'); this.osPlatformStub.returns('darwin');
}); });
afterEach(function() { afterEach(function () {
this.osPlatformStub.restore(); this.osPlatformStub.restore();
}); });
it('should return an empty array if no environment', function() { it('should return an empty array if no environment', function () {
m.chai.expect(permissions.getEnvironmentCommandPrefix()).to.deep.equal([]); m.chai.expect(permissions.getEnvironmentCommandPrefix()).to.deep.equal([]);
}); });
it('should return an empty array if the environment is an empty object', function() { it('should return an empty array if the environment is an empty object', function () {
m.chai.expect(permissions.getEnvironmentCommandPrefix({})).to.deep.equal([]); m.chai.expect(permissions.getEnvironmentCommandPrefix({})).to.deep.equal([]);
}); });
it('should create an environment command prefix out of one variable', function() { it('should create an environment command prefix out of one variable', function () {
m.chai.expect(permissions.getEnvironmentCommandPrefix({ m.chai.expect(permissions.getEnvironmentCommandPrefix({
FOO: 'bar' FOO: 'bar'
})).to.deep.equal([ })).to.deep.equal([
@ -202,7 +195,7 @@ describe('Shared: permissions', function() {
]); ]);
}); });
it('should create an environment command prefix out of many variables', function() { it('should create an environment command prefix out of many variables', function () {
m.chai.expect(permissions.getEnvironmentCommandPrefix({ m.chai.expect(permissions.getEnvironmentCommandPrefix({
FOO: 'bar', FOO: 'bar',
BAR: 'baz', BAR: 'baz',
@ -215,7 +208,7 @@ describe('Shared: permissions', function() {
]); ]);
}); });
it('should ignore undefined and null variable values', function() { it('should ignore undefined and null variable values', function () {
m.chai.expect(permissions.getEnvironmentCommandPrefix({ m.chai.expect(permissions.getEnvironmentCommandPrefix({
FOO: null, FOO: null,
BAR: 'qux', BAR: 'qux',
@ -226,7 +219,7 @@ describe('Shared: permissions', function() {
]); ]);
}); });
it('should stringify number values', function() { it('should stringify number values', function () {
m.chai.expect(permissions.getEnvironmentCommandPrefix({ m.chai.expect(permissions.getEnvironmentCommandPrefix({
FOO: 1, FOO: 1,
BAR: 0, BAR: 0,
@ -238,9 +231,6 @@ describe('Shared: permissions', function() {
'BAZ=-1' 'BAZ=-1'
]); ]);
}); });
}); });
}); });
}); });

View File

@ -20,113 +20,97 @@ const m = require('mochainon');
const _ = require('lodash'); const _ = require('lodash');
const release = require('../../lib/shared/release'); const release = require('../../lib/shared/release');
describe('Shared: Release', function() { describe('Shared: Release', function () {
describe('.RELEASE_TYPE', function () {
describe('.RELEASE_TYPE', function() { it('should be a plain object', function () {
it('should be a plain object', function() {
m.chai.expect(_.isPlainObject(release.RELEASE_TYPE)).to.be.true; m.chai.expect(_.isPlainObject(release.RELEASE_TYPE)).to.be.true;
}); });
it('should contain keys with different values', function() { it('should contain keys with different values', function () {
const keys = _.keys(release.RELEASE_TYPE); const keys = _.keys(release.RELEASE_TYPE);
const uniqueValues = _.uniq(_.values(release.RELEASE_TYPE)); const uniqueValues = _.uniq(_.values(release.RELEASE_TYPE));
m.chai.expect(_.size(keys)).to.equal(_.size(uniqueValues)); m.chai.expect(_.size(keys)).to.equal(_.size(uniqueValues));
}); });
}); });
describe('.getReleaseType()', function() { describe('.getReleaseType()', function () {
it('should return the unknown release type if the version is not valid semver', function () {
it('should return the unknown release type if the version is not valid semver', function() {
const releaseType = release.getReleaseType('foo.bar'); const releaseType = release.getReleaseType('foo.bar');
m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.UNKNOWN); m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.UNKNOWN);
}); });
describe('given the version has a short git commit hash build number', function() { describe('given the version has a short git commit hash build number', function () {
it('should return the snapshot release type', function () {
it('should return the snapshot release type', function() {
const releaseType = release.getReleaseType('1.0.0+6374412'); const releaseType = release.getReleaseType('1.0.0+6374412');
m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.SNAPSHOT); m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.SNAPSHOT);
}); });
it('should return the snapshot release type if the version has a pre release tag', function() { it('should return the snapshot release type if the version has a pre release tag', function () {
const releaseType = release.getReleaseType('1.0.0-beta.19+6374412'); const releaseType = release.getReleaseType('1.0.0-beta.19+6374412');
m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.SNAPSHOT); m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.SNAPSHOT);
}); });
}); });
describe('given the version has a long git commit hash build number', function() { describe('given the version has a long git commit hash build number', function () {
it('should return the snapshot release type', function () {
it('should return the snapshot release type', function() {
const releaseType = release.getReleaseType('1.0.0+6374412554b034799bfc6e13b4e39c3f5e6386e6'); const releaseType = release.getReleaseType('1.0.0+6374412554b034799bfc6e13b4e39c3f5e6386e6');
m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.SNAPSHOT); m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.SNAPSHOT);
}); });
it('should return the snapshot release type if the version has a pre release tag', function() { it('should return the snapshot release type if the version has a pre release tag', function () {
const releaseType = release.getReleaseType('1.0.0-beta.19+6374412554b034799bfc6e13b4e39c3f5e6386e6'); const releaseType = release.getReleaseType('1.0.0-beta.19+6374412554b034799bfc6e13b4e39c3f5e6386e6');
m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.SNAPSHOT); m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.SNAPSHOT);
}); });
}); });
describe('given the version has no build number', function() { describe('given the version has no build number', function () {
it('should return the production release type', function () {
it('should return the production release type', function() {
const releaseType = release.getReleaseType('1.0.0'); const releaseType = release.getReleaseType('1.0.0');
m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.PRODUCTION); m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.PRODUCTION);
}); });
it('should return the production release type if the version has a pre release tag', function() { it('should return the production release type if the version has a pre release tag', function () {
const releaseType = release.getReleaseType('1.0.0-beta.19'); const releaseType = release.getReleaseType('1.0.0-beta.19');
m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.PRODUCTION); m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.PRODUCTION);
}); });
}); });
describe('given a build number that is not a git commit hash', function() { describe('given a build number that is not a git commit hash', function () {
it('should return the unknown release type', function () {
it('should return the unknown release type', function() {
const releaseType = release.getReleaseType('1.0.0+foo'); const releaseType = release.getReleaseType('1.0.0+foo');
m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.UNKNOWN); m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.UNKNOWN);
}); });
it('should return the unknown release type if the version has a pre release tag', function() { it('should return the unknown release type if the version has a pre release tag', function () {
const releaseType = release.getReleaseType('1.0.0-beta.19+foo'); const releaseType = release.getReleaseType('1.0.0-beta.19+foo');
m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.UNKNOWN); m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.UNKNOWN);
}); });
}); });
}); });
describe('.isStableRelease()', function() { describe('.isStableRelease()', function () {
it('should return true if given a production stable version', function () {
it('should return true if given a production stable version', function() {
m.chai.expect(release.isStableRelease('1.0.0')).to.be.true; m.chai.expect(release.isStableRelease('1.0.0')).to.be.true;
}); });
it('should return false if given a production release candidate version', function() { it('should return false if given a production release candidate version', function () {
m.chai.expect(release.isStableRelease('1.0.0-rc.2')).to.be.false; m.chai.expect(release.isStableRelease('1.0.0-rc.2')).to.be.false;
}); });
it('should return false if given a production beta version', function() { it('should return false if given a production beta version', function () {
m.chai.expect(release.isStableRelease('1.0.0-beta.1')).to.be.false; m.chai.expect(release.isStableRelease('1.0.0-beta.1')).to.be.false;
}); });
it('should return true if given a snapshot stable version', function() { it('should return true if given a snapshot stable version', function () {
m.chai.expect(release.isStableRelease('1.0.0+6374412')).to.be.true; m.chai.expect(release.isStableRelease('1.0.0+6374412')).to.be.true;
}); });
it('should return false if given a snapshot release candidate version', function() { it('should return false if given a snapshot release candidate version', function () {
m.chai.expect(release.isStableRelease('1.0.0-rc.2+6374412')).to.be.false; m.chai.expect(release.isStableRelease('1.0.0-rc.2+6374412')).to.be.false;
}); });
it('should return false if given a snapshot beta version', function() { it('should return false if given a snapshot beta version', function () {
m.chai.expect(release.isStableRelease('1.0.0-beta.1+6374412')).to.be.false; m.chai.expect(release.isStableRelease('1.0.0-beta.1+6374412')).to.be.false;
}); });
}); });
}); });

View File

@ -20,78 +20,72 @@ const m = require('mochainon');
const _ = require('lodash'); const _ = require('lodash');
const robot = require('../../lib/shared/robot'); const robot = require('../../lib/shared/robot');
describe('Shared: Robot', function() { describe('Shared: Robot', function () {
describe('.COMMAND', function () {
describe('.COMMAND', function() { it('should be a plain object', function () {
it('should be a plain object', function() {
m.chai.expect(_.isPlainObject(robot.COMMAND)).to.be.true; m.chai.expect(_.isPlainObject(robot.COMMAND)).to.be.true;
}); });
it('should only contain string values', function() { it('should only contain string values', function () {
m.chai.expect(_.every(_.values(robot.COMMAND), _.isString)).to.be.true; m.chai.expect(_.every(_.values(robot.COMMAND), _.isString)).to.be.true;
}); });
it('should contain only unique values', function() { it('should contain only unique values', function () {
const numberOfKeys = _.size(_.keys(robot.COMMAND)); const numberOfKeys = _.size(_.keys(robot.COMMAND));
m.chai.expect(_.size(_.uniq(_.values(robot.COMMAND)))).to.equal(numberOfKeys); m.chai.expect(_.size(_.uniq(_.values(robot.COMMAND)))).to.equal(numberOfKeys);
}); });
}); });
describe('.isEnabled()', function() { describe('.isEnabled()', function () {
it('should return false if ETCHER_CLI_ROBOT is not set', function () {
it('should return false if ETCHER_CLI_ROBOT is not set', function() {
m.chai.expect(robot.isEnabled({})).to.be.false; m.chai.expect(robot.isEnabled({})).to.be.false;
}); });
it('should return true if ETCHER_CLI_ROBOT=1', function() { it('should return true if ETCHER_CLI_ROBOT=1', function () {
m.chai.expect(robot.isEnabled({ m.chai.expect(robot.isEnabled({
ETCHER_CLI_ROBOT: 1 ETCHER_CLI_ROBOT: 1
})).to.be.true; })).to.be.true;
}); });
it('should return false if ETCHER_CLI_ROBOT=0', function() { it('should return false if ETCHER_CLI_ROBOT=0', function () {
m.chai.expect(robot.isEnabled({ m.chai.expect(robot.isEnabled({
ETCHER_CLI_ROBOT: 0 ETCHER_CLI_ROBOT: 0
})).to.be.false; })).to.be.false;
}); });
it('should return true if ETCHER_CLI_ROBOT="true"', function() { it('should return true if ETCHER_CLI_ROBOT="true"', function () {
m.chai.expect(robot.isEnabled({ m.chai.expect(robot.isEnabled({
ETCHER_CLI_ROBOT: 'true' ETCHER_CLI_ROBOT: 'true'
})).to.be.true; })).to.be.true;
}); });
it('should return false if ETCHER_CLI_ROBOT="false"', function() { it('should return false if ETCHER_CLI_ROBOT="false"', function () {
m.chai.expect(robot.isEnabled({ m.chai.expect(robot.isEnabled({
ETCHER_CLI_ROBOT: 'false' ETCHER_CLI_ROBOT: 'false'
})).to.be.false; })).to.be.false;
}); });
it('should return true if ETCHER_CLI_ROBOT=true', function() { it('should return true if ETCHER_CLI_ROBOT=true', function () {
m.chai.expect(robot.isEnabled({ m.chai.expect(robot.isEnabled({
ETCHER_CLI_ROBOT: true ETCHER_CLI_ROBOT: true
})).to.be.true; })).to.be.true;
}); });
it('should return false if ETCHER_CLI_ROBOT=false', function() { it('should return false if ETCHER_CLI_ROBOT=false', function () {
m.chai.expect(robot.isEnabled({ m.chai.expect(robot.isEnabled({
ETCHER_CLI_ROBOT: false ETCHER_CLI_ROBOT: false
})).to.be.false; })).to.be.false;
}); });
}); });
describe('.buildMessage()', function() { describe('.buildMessage()', function () {
it('should build a message without data', function () {
it('should build a message without data', function() {
const message = robot.buildMessage('hello'); const message = robot.buildMessage('hello');
const result = '{"command":"hello","data":{}}'; const result = '{"command":"hello","data":{}}';
m.chai.expect(message).to.equal(result); m.chai.expect(message).to.equal(result);
}); });
it('should build a message with data', function() { it('should build a message with data', function () {
const message = robot.buildMessage('hello', { const message = robot.buildMessage('hello', {
foo: 1, foo: 1,
bar: 2 bar: 2
@ -100,112 +94,108 @@ describe('Shared: Robot', function() {
m.chai.expect(message).to.equal(result); m.chai.expect(message).to.equal(result);
}); });
it('should throw if data is defined but it not an object', function() { it('should throw if data is defined but it not an object', function () {
m.chai.expect(() => { m.chai.expect(() => {
robot.buildMessage('hello', 'world'); robot.buildMessage('hello', 'world');
}).to.throw('Invalid data: world'); }).to.throw('Invalid data: world');
}); });
}); });
describe('.isMessage()', function() { describe('.isMessage()', function () {
it('should return true if message is an empty object', function () {
it('should return true if message is an empty object', function() {
m.chai.expect(robot.isMessage('{}')).to.be.true; m.chai.expect(robot.isMessage('{}')).to.be.true;
}); });
it('should return true if message is an object', function() { it('should return true if message is an object', function () {
m.chai.expect(robot.isMessage('{"command":"foo"}')).to.be.true; m.chai.expect(robot.isMessage('{"command":"foo"}')).to.be.true;
}); });
it('should return false if message is an invalid object', function() { it('should return false if message is an invalid object', function () {
m.chai.expect(robot.isMessage('{"command":\\foo"}')).to.be.false; m.chai.expect(robot.isMessage('{"command":\\foo"}')).to.be.false;
}); });
it('should return false if message is an unquoted string', function() { it('should return false if message is an unquoted string', function () {
m.chai.expect(robot.isMessage('foo')).to.be.false; m.chai.expect(robot.isMessage('foo')).to.be.false;
}); });
it('should return false if message is an quoted string', function() { it('should return false if message is an quoted string', function () {
m.chai.expect(robot.isMessage('"foo"')).to.be.false; m.chai.expect(robot.isMessage('"foo"')).to.be.false;
}); });
it('should return false if message is an empty string', function() { it('should return false if message is an empty string', function () {
m.chai.expect(robot.isMessage('')).to.be.false; m.chai.expect(robot.isMessage('')).to.be.false;
}); });
it('should return false if message is undefined', function() { it('should return false if message is undefined', function () {
m.chai.expect(robot.isMessage(undefined)).to.be.false; m.chai.expect(robot.isMessage(undefined)).to.be.false;
}); });
it('should return false if message is null', function() { it('should return false if message is null', function () {
m.chai.expect(robot.isMessage(null)).to.be.false; m.chai.expect(robot.isMessage(null)).to.be.false;
}); });
it('should return false if message is a positive integer string', function() { it('should return false if message is a positive integer string', function () {
m.chai.expect(robot.isMessage('5')).to.be.false; m.chai.expect(robot.isMessage('5')).to.be.false;
}); });
it('should return false if message is a negative integer string', function() { it('should return false if message is a negative integer string', function () {
m.chai.expect(robot.isMessage('-3')).to.be.false; m.chai.expect(robot.isMessage('-3')).to.be.false;
}); });
it('should return false if message is a zero string', function() { it('should return false if message is a zero string', function () {
m.chai.expect(robot.isMessage('0')).to.be.false; m.chai.expect(robot.isMessage('0')).to.be.false;
}); });
it('should return false if message is a positive float string', function() { it('should return false if message is a positive float string', function () {
m.chai.expect(robot.isMessage('5.3')).to.be.false; m.chai.expect(robot.isMessage('5.3')).to.be.false;
}); });
it('should return false if message is a negative float string', function() { it('should return false if message is a negative float string', function () {
m.chai.expect(robot.isMessage('-2.1')).to.be.false; m.chai.expect(robot.isMessage('-2.1')).to.be.false;
}); });
it('should return false if message is a positive integer', function() { it('should return false if message is a positive integer', function () {
m.chai.expect(robot.isMessage(5)).to.be.false; m.chai.expect(robot.isMessage(5)).to.be.false;
}); });
it('should return false if message is a negative integer', function() { it('should return false if message is a negative integer', function () {
m.chai.expect(robot.isMessage(-3)).to.be.false; m.chai.expect(robot.isMessage(-3)).to.be.false;
}); });
it('should return false if message is zero', function() { it('should return false if message is zero', function () {
m.chai.expect(robot.isMessage(0)).to.be.false; m.chai.expect(robot.isMessage(0)).to.be.false;
}); });
it('should return false if message is a positive float', function() { it('should return false if message is a positive float', function () {
m.chai.expect(robot.isMessage(5.3)).to.be.false; m.chai.expect(robot.isMessage(5.3)).to.be.false;
}); });
it('should return false if message is a negative float', function() { it('should return false if message is a negative float', function () {
m.chai.expect(robot.isMessage(-2.1)).to.be.false; m.chai.expect(robot.isMessage(-2.1)).to.be.false;
}); });
it('should return false if message is an array', function() { it('should return false if message is an array', function () {
m.chai.expect(robot.isMessage([ 'foo' ])).to.be.false; m.chai.expect(robot.isMessage([ 'foo' ])).to.be.false;
}); });
it('should return false if message is an array string', function() { it('should return false if message is an array string', function () {
m.chai.expect(robot.isMessage('["foo"]')).to.be.false; m.chai.expect(robot.isMessage('["foo"]')).to.be.false;
}); });
it('should return true for a message built with .buildMessage()', function() { it('should return true for a message built with .buildMessage()', function () {
m.chai.expect(robot.isMessage(robot.buildMessage('foo', { m.chai.expect(robot.isMessage(robot.buildMessage('foo', {
message: 'bar' message: 'bar'
}))).to.be.true; }))).to.be.true;
}); });
it('should return true for a message built with .buildErrorMessage()', function() { it('should return true for a message built with .buildErrorMessage()', function () {
const error = new Error('foo'); const error = new Error('foo');
m.chai.expect(robot.isMessage(robot.buildErrorMessage(error))).to.be.true; m.chai.expect(robot.isMessage(robot.buildErrorMessage(error))).to.be.true;
}); });
}); });
describe('.buildErrorMessage()', function() { describe('.buildErrorMessage()', function () {
it('should build a message from a simple error', function () {
it('should build a message from a simple error', function() {
const error = new Error('foo'); const error = new Error('foo');
const message = robot.buildErrorMessage(error); const message = robot.buildErrorMessage(error);
@ -218,7 +208,7 @@ describe('Shared: Robot', function() {
}); });
}); });
it('should save the error description', function() { it('should save the error description', function () {
const error = new Error('foo'); const error = new Error('foo');
error.description = 'error description'; error.description = 'error description';
const message = robot.buildErrorMessage(error); const message = robot.buildErrorMessage(error);
@ -233,7 +223,7 @@ describe('Shared: Robot', function() {
}); });
}); });
it('should save the error code', function() { it('should save the error code', function () {
const error = new Error('foo'); const error = new Error('foo');
error.code = 'MYERROR'; error.code = 'MYERROR';
const message = robot.buildErrorMessage(error); const message = robot.buildErrorMessage(error);
@ -248,18 +238,16 @@ describe('Shared: Robot', function() {
}); });
}); });
it('should handle a string error', function() { it('should handle a string error', function () {
const message = JSON.parse(robot.buildErrorMessage('foo')); const message = JSON.parse(robot.buildErrorMessage('foo'));
m.chai.expect(message.data.message).to.equal('foo'); m.chai.expect(message.data.message).to.equal('foo');
m.chai.expect(message.data.stack).to.be.a.string; m.chai.expect(message.data.stack).to.be.a.string;
m.chai.expect(_.isEmpty(message.data.stack)).to.be.false; m.chai.expect(_.isEmpty(message.data.stack)).to.be.false;
}); });
}); });
describe('.parseMessage()', function() { describe('.parseMessage()', function () {
it('should parse a valid message', function () {
it('should parse a valid message', function() {
const message = robot.buildMessage('foo', { const message = robot.buildMessage('foo', {
bar: 1 bar: 1
}); });
@ -272,7 +260,7 @@ describe('Shared: Robot', function() {
}); });
}); });
it('should parse a valid without data', function() { it('should parse a valid without data', function () {
const message = robot.buildMessage('foo'); const message = robot.buildMessage('foo');
m.chai.expect(robot.parseMessage(message)).to.deep.equal({ m.chai.expect(robot.parseMessage(message)).to.deep.equal({
command: 'foo', command: 'foo',
@ -280,29 +268,27 @@ describe('Shared: Robot', function() {
}); });
}); });
it('should throw if input is not valid JSON', function() { it('should throw if input is not valid JSON', function () {
m.chai.expect(() => { m.chai.expect(() => {
robot.parseMessage('Hello world\nFoo Bar'); robot.parseMessage('Hello world\nFoo Bar');
}).to.throw('Invalid message'); }).to.throw('Invalid message');
}); });
it('should throw if input has no command', function() { it('should throw if input has no command', function () {
m.chai.expect(() => { m.chai.expect(() => {
robot.parseMessage('{"data":{"foo":"bar"}}'); robot.parseMessage('{"data":{"foo":"bar"}}');
}).to.throw('Invalid message'); }).to.throw('Invalid message');
}); });
it('should throw if input has no data', function() { it('should throw if input has no data', function () {
m.chai.expect(() => { m.chai.expect(() => {
robot.parseMessage('{"command":"foo"}'); robot.parseMessage('{"command":"foo"}');
}).to.throw('Invalid message'); }).to.throw('Invalid message');
}); });
}); });
describe('.getCommand()', function() { describe('.getCommand()', function () {
it('should get the command of a message', function () {
it('should get the command of a message', function() {
const message = robot.parseMessage(robot.buildMessage('hello', { const message = robot.parseMessage(robot.buildMessage('hello', {
foo: 1, foo: 1,
bar: 2 bar: 2
@ -310,12 +296,10 @@ describe('Shared: Robot', function() {
m.chai.expect(robot.getCommand(message)).to.equal('hello'); m.chai.expect(robot.getCommand(message)).to.equal('hello');
}); });
}); });
describe('.getData()', function() { describe('.getData()', function () {
it('should get the data of a message', function () {
it('should get the data of a message', function() {
const message = robot.parseMessage(robot.buildMessage('hello', { const message = robot.parseMessage(robot.buildMessage('hello', {
foo: 1, foo: 1,
bar: 2 bar: 2
@ -327,42 +311,38 @@ describe('Shared: Robot', function() {
}); });
}); });
it('should return an empty object if the message has no data', function() { it('should return an empty object if the message has no data', function () {
m.chai.expect(robot.getData({ m.chai.expect(robot.getData({
command: 'foo' command: 'foo'
})).to.deep.equal({}); })).to.deep.equal({});
}); });
}); });
describe('.recomposeErrorMessage()', function() { describe('.recomposeErrorMessage()', function () {
it('should return an instance of Error', function () {
it('should return an instance of Error', function() {
const error = new Error('Foo bar'); const error = new Error('Foo bar');
const message = robot.parseMessage(robot.buildErrorMessage(error)); const message = robot.parseMessage(robot.buildErrorMessage(error));
m.chai.expect(robot.recomposeErrorMessage(message)).to.be.an.instanceof(Error); m.chai.expect(robot.recomposeErrorMessage(message)).to.be.an.instanceof(Error);
}); });
it('should be able to recompose an error object', function() { it('should be able to recompose an error object', function () {
const error = new Error('Foo bar'); const error = new Error('Foo bar');
const message = robot.parseMessage(robot.buildErrorMessage(error)); const message = robot.parseMessage(robot.buildErrorMessage(error));
m.chai.expect(robot.recomposeErrorMessage(message)).to.deep.equal(error); m.chai.expect(robot.recomposeErrorMessage(message)).to.deep.equal(error);
}); });
it('should be able to recompose an error object with a code', function() { it('should be able to recompose an error object with a code', function () {
const error = new Error('Foo bar'); const error = new Error('Foo bar');
error.code = 'FOO'; error.code = 'FOO';
const message = robot.parseMessage(robot.buildErrorMessage(error)); const message = robot.parseMessage(robot.buildErrorMessage(error));
m.chai.expect(robot.recomposeErrorMessage(message)).to.deep.equal(error); m.chai.expect(robot.recomposeErrorMessage(message)).to.deep.equal(error);
}); });
it('should be able to recompose an error object with a description', function() { it('should be able to recompose an error object with a description', function () {
const error = new Error('Foo bar'); const error = new Error('Foo bar');
error.description = 'My description'; error.description = 'My description';
const message = robot.parseMessage(robot.buildErrorMessage(error)); const message = robot.parseMessage(robot.buildErrorMessage(error));
m.chai.expect(robot.recomposeErrorMessage(message)).to.deep.equal(error); m.chai.expect(robot.recomposeErrorMessage(message)).to.deep.equal(error);
}); });
}); });
}); });

View File

@ -23,34 +23,30 @@ const nock = require('nock');
const s3Packages = require('../../lib/shared/s3-packages'); const s3Packages = require('../../lib/shared/s3-packages');
const release = require('../../lib/shared/release'); const release = require('../../lib/shared/release');
describe('Shared: s3Packages', function() { describe('Shared: s3Packages', function () {
describe('.getBucketUrlFromReleaseType()', function () {
describe('.getBucketUrlFromReleaseType()', function() { it('should return the production URL if given a production release type', function () {
it('should return the production URL if given a production release type', function() {
const bucketUrl = s3Packages.getBucketUrlFromReleaseType(release.RELEASE_TYPE.PRODUCTION); const bucketUrl = s3Packages.getBucketUrlFromReleaseType(release.RELEASE_TYPE.PRODUCTION);
m.chai.expect(bucketUrl).to.equal(s3Packages.BUCKET_URL.PRODUCTION); m.chai.expect(bucketUrl).to.equal(s3Packages.BUCKET_URL.PRODUCTION);
}); });
it('should return the snapshot URL if given a snapshot release type', function() { it('should return the snapshot URL if given a snapshot release type', function () {
const bucketUrl = s3Packages.getBucketUrlFromReleaseType(release.RELEASE_TYPE.SNAPSHOT); const bucketUrl = s3Packages.getBucketUrlFromReleaseType(release.RELEASE_TYPE.SNAPSHOT);
m.chai.expect(bucketUrl).to.equal(s3Packages.BUCKET_URL.SNAPSHOT); m.chai.expect(bucketUrl).to.equal(s3Packages.BUCKET_URL.SNAPSHOT);
}); });
it('should return null if given an unknown release type', function() { it('should return null if given an unknown release type', function () {
const bucketUrl = s3Packages.getBucketUrlFromReleaseType(release.RELEASE_TYPE.UNKNOWN); const bucketUrl = s3Packages.getBucketUrlFromReleaseType(release.RELEASE_TYPE.UNKNOWN);
m.chai.expect(bucketUrl).to.be.null; m.chai.expect(bucketUrl).to.be.null;
}); });
}); });
describe('.getRemoteVersions()', function() { describe('.getRemoteVersions()', function () {
beforeEach(function () {
beforeEach(function() {
s3Packages.getRemoteVersions.cache.clear(); s3Packages.getRemoteVersions.cache.clear();
}); });
it('should be rejected if url is null', function(done) { it('should be rejected if url is null', function (done) {
s3Packages.getRemoteVersions(null).catch((error) => { s3Packages.getRemoteVersions(null).catch((error) => {
m.chai.expect(error).to.be.an.instanceof(Error); m.chai.expect(error).to.be.an.instanceof(Error);
m.chai.expect(error.message).to.equal('Invalid bucket url: null'); m.chai.expect(error.message).to.equal('Invalid bucket url: null');
@ -58,9 +54,8 @@ describe('Shared: s3Packages', function() {
}); });
}); });
describe('given an empty bucket', function() { describe('given an empty bucket', function () {
beforeEach(function () {
beforeEach(function() {
nock(s3Packages.BUCKET_URL.PRODUCTION).get('/').reply(200, ` nock(s3Packages.BUCKET_URL.PRODUCTION).get('/').reply(200, `
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Name>resin-production-downloads</Name> <Name>resin-production-downloads</Name>
@ -72,22 +67,20 @@ describe('Shared: s3Packages', function() {
`); `);
}); });
afterEach(function() { afterEach(function () {
nock.cleanAll(); nock.cleanAll();
}); });
it('should resolve an empty array', function(done) { it('should resolve an empty array', function (done) {
s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => { s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
m.chai.expect(versions).to.deep.equal([]); m.chai.expect(versions).to.deep.equal([]);
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given many versions', function() { describe('given many versions', function () {
beforeEach(function () {
beforeEach(function() {
nock(s3Packages.BUCKET_URL.PRODUCTION).get('/').reply(200, ` nock(s3Packages.BUCKET_URL.PRODUCTION).get('/').reply(200, `
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Name>resin-production-downloads</Name> <Name>resin-production-downloads</Name>
@ -211,11 +204,11 @@ describe('Shared: s3Packages', function() {
`); `);
}); });
afterEach(function() { afterEach(function () {
nock.cleanAll(); nock.cleanAll();
}); });
it('should resolve all the available versions', function(done) { it('should resolve all the available versions', function (done) {
s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => { s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
m.chai.expect(versions).to.deep.equal([ m.chai.expect(versions).to.deep.equal([
'1.0.0-beta.17', '1.0.0-beta.17',
@ -224,12 +217,10 @@ describe('Shared: s3Packages', function() {
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given a version is being uploaded', function() { describe('given a version is being uploaded', function () {
beforeEach(function () {
beforeEach(function() {
nock(s3Packages.BUCKET_URL.PRODUCTION).get('/').reply(200, ` nock(s3Packages.BUCKET_URL.PRODUCTION).get('/').reply(200, `
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Name>resin-production-downloads</Name> <Name>resin-production-downloads</Name>
@ -346,11 +337,11 @@ describe('Shared: s3Packages', function() {
`); `);
}); });
afterEach(function() { afterEach(function () {
nock.cleanAll(); nock.cleanAll();
}); });
it('should resolve all the entirely available versions', function(done) { it('should resolve all the entirely available versions', function (done) {
s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => { s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
m.chai.expect(versions).to.deep.equal([ m.chai.expect(versions).to.deep.equal([
'1.0.0-beta.17' '1.0.0-beta.17'
@ -358,12 +349,10 @@ describe('Shared: s3Packages', function() {
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given other programs in the bucket', function() { describe('given other programs in the bucket', function () {
beforeEach(function () {
beforeEach(function() {
nock(s3Packages.BUCKET_URL.PRODUCTION).get('/').reply(200, ` nock(s3Packages.BUCKET_URL.PRODUCTION).get('/').reply(200, `
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Name>resin-production-downloads</Name> <Name>resin-production-downloads</Name>
@ -487,11 +476,11 @@ describe('Shared: s3Packages', function() {
`); `);
}); });
afterEach(function() { afterEach(function () {
nock.cleanAll(); nock.cleanAll();
}); });
it('should not consider the other packages', function(done) { it('should not consider the other packages', function (done) {
s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => { s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
m.chai.expect(versions).to.deep.equal([ m.chai.expect(versions).to.deep.equal([
'1.0.0-beta.17' '1.0.0-beta.17'
@ -499,12 +488,10 @@ describe('Shared: s3Packages', function() {
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given only other programs in the bucket', function() { describe('given only other programs in the bucket', function () {
beforeEach(function () {
beforeEach(function() {
nock(s3Packages.BUCKET_URL.PRODUCTION).get('/').reply(200, ` nock(s3Packages.BUCKET_URL.PRODUCTION).get('/').reply(200, `
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Name>resin-production-downloads</Name> <Name>resin-production-downloads</Name>
@ -565,41 +552,37 @@ describe('Shared: s3Packages', function() {
`); `);
}); });
afterEach(function() { afterEach(function () {
nock.cleanAll(); nock.cleanAll();
}); });
it('should resolve an empty array', function(done) { it('should resolve an empty array', function (done) {
s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => { s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
m.chai.expect(versions).to.deep.equal([]); m.chai.expect(versions).to.deep.equal([]);
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given an unsuccessful request', function() { describe('given an unsuccessful request', function () {
beforeEach(function () {
beforeEach(function() {
nock(s3Packages.BUCKET_URL.PRODUCTION).get('/').reply(500); nock(s3Packages.BUCKET_URL.PRODUCTION).get('/').reply(500);
}); });
afterEach(function() { afterEach(function () {
nock.cleanAll(); nock.cleanAll();
}); });
it('should be rejected with an error', function(done) { it('should be rejected with an error', function (done) {
s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).catch((error) => { s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).catch((error) => {
m.chai.expect(error).to.be.an.instanceof(Error); m.chai.expect(error).to.be.an.instanceof(Error);
done(); done();
}); });
}); });
}); });
describe('given ENOTFOUND', function() { describe('given ENOTFOUND', function () {
beforeEach(function () {
beforeEach(function() {
const error = new Error('ENOTFOUND'); const error = new Error('ENOTFOUND');
error.code = 'ENOTFOUND'; error.code = 'ENOTFOUND';
@ -607,22 +590,20 @@ describe('Shared: s3Packages', function() {
this.requestGetAsyncStub.returns(Bluebird.reject(error)); this.requestGetAsyncStub.returns(Bluebird.reject(error));
}); });
afterEach(function() { afterEach(function () {
this.requestGetAsyncStub.restore(); this.requestGetAsyncStub.restore();
}); });
it('should resolve an empty array', function(done) { it('should resolve an empty array', function (done) {
s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => { s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
m.chai.expect(versions).to.deep.equal([]); m.chai.expect(versions).to.deep.equal([]);
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given ETIMEDOUT', function() { describe('given ETIMEDOUT', function () {
beforeEach(function () {
beforeEach(function() {
const error = new Error('ETIMEDOUT'); const error = new Error('ETIMEDOUT');
error.code = 'ETIMEDOUT'; error.code = 'ETIMEDOUT';
@ -630,22 +611,20 @@ describe('Shared: s3Packages', function() {
this.requestGetAsyncStub.returns(Bluebird.reject(error)); this.requestGetAsyncStub.returns(Bluebird.reject(error));
}); });
afterEach(function() { afterEach(function () {
this.requestGetAsyncStub.restore(); this.requestGetAsyncStub.restore();
}); });
it('should resolve an empty array', function(done) { it('should resolve an empty array', function (done) {
s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => { s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
m.chai.expect(versions).to.deep.equal([]); m.chai.expect(versions).to.deep.equal([]);
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given EHOSTDOWN', function() { describe('given EHOSTDOWN', function () {
beforeEach(function () {
beforeEach(function() {
const error = new Error('EHOSTDOWN'); const error = new Error('EHOSTDOWN');
error.code = 'EHOSTDOWN'; error.code = 'EHOSTDOWN';
@ -653,22 +632,20 @@ describe('Shared: s3Packages', function() {
this.requestGetAsyncStub.returns(Bluebird.reject(error)); this.requestGetAsyncStub.returns(Bluebird.reject(error));
}); });
afterEach(function() { afterEach(function () {
this.requestGetAsyncStub.restore(); this.requestGetAsyncStub.restore();
}); });
it('should resolve an empty array', function(done) { it('should resolve an empty array', function (done) {
s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => { s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
m.chai.expect(versions).to.deep.equal([]); m.chai.expect(versions).to.deep.equal([]);
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given ECONNRESET', function() { describe('given ECONNRESET', function () {
beforeEach(function () {
beforeEach(function() {
const error = new Error('ECONNRESET'); const error = new Error('ECONNRESET');
error.code = 'ECONNRESET'; error.code = 'ECONNRESET';
@ -676,22 +653,20 @@ describe('Shared: s3Packages', function() {
this.requestGetAsyncStub.returns(Bluebird.reject(error)); this.requestGetAsyncStub.returns(Bluebird.reject(error));
}); });
afterEach(function() { afterEach(function () {
this.requestGetAsyncStub.restore(); this.requestGetAsyncStub.restore();
}); });
it('should resolve an empty array', function(done) { it('should resolve an empty array', function (done) {
s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => { s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
m.chai.expect(versions).to.deep.equal([]); m.chai.expect(versions).to.deep.equal([]);
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given ECONNREFUSED', function() { describe('given ECONNREFUSED', function () {
beforeEach(function () {
beforeEach(function() {
const error = new Error('ECONNREFUSED'); const error = new Error('ECONNREFUSED');
error.code = 'ECONNREFUSED'; error.code = 'ECONNREFUSED';
@ -699,22 +674,20 @@ describe('Shared: s3Packages', function() {
this.requestGetAsyncStub.returns(Bluebird.reject(error)); this.requestGetAsyncStub.returns(Bluebird.reject(error));
}); });
afterEach(function() { afterEach(function () {
this.requestGetAsyncStub.restore(); this.requestGetAsyncStub.restore();
}); });
it('should resolve an empty array', function(done) { it('should resolve an empty array', function (done) {
s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => { s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
m.chai.expect(versions).to.deep.equal([]); m.chai.expect(versions).to.deep.equal([]);
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given EACCES', function() { describe('given EACCES', function () {
beforeEach(function () {
beforeEach(function() {
const error = new Error('EACCES'); const error = new Error('EACCES');
error.code = 'EACCES'; error.code = 'EACCES';
@ -722,22 +695,20 @@ describe('Shared: s3Packages', function() {
this.requestGetAsyncStub.returns(Bluebird.reject(error)); this.requestGetAsyncStub.returns(Bluebird.reject(error));
}); });
afterEach(function() { afterEach(function () {
this.requestGetAsyncStub.restore(); this.requestGetAsyncStub.restore();
}); });
it('should resolve an empty array', function(done) { it('should resolve an empty array', function (done) {
s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => { s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
m.chai.expect(versions).to.deep.equal([]); m.chai.expect(versions).to.deep.equal([]);
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given UNABLE_TO_VERIFY_LEAF_SIGNATURE', function() { describe('given UNABLE_TO_VERIFY_LEAF_SIGNATURE', function () {
beforeEach(function () {
beforeEach(function() {
const error = new Error('UNABLE_TO_VERIFY_LEAF_SIGNATURE'); const error = new Error('UNABLE_TO_VERIFY_LEAF_SIGNATURE');
error.code = 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'; error.code = 'UNABLE_TO_VERIFY_LEAF_SIGNATURE';
@ -745,165 +716,141 @@ describe('Shared: s3Packages', function() {
this.requestGetAsyncStub.returns(Bluebird.reject(error)); this.requestGetAsyncStub.returns(Bluebird.reject(error));
}); });
afterEach(function() { afterEach(function () {
this.requestGetAsyncStub.restore(); this.requestGetAsyncStub.restore();
}); });
it('should resolve an empty array', function(done) { it('should resolve an empty array', function (done) {
s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => { s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
m.chai.expect(versions).to.deep.equal([]); m.chai.expect(versions).to.deep.equal([]);
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
}); });
describe('.getLatestVersion()', function() { describe('.getLatestVersion()', function () {
describe('given a valid production ETCHER_FAKE_S3_LATEST_VERSION environment variable', function () {
describe('given a valid production ETCHER_FAKE_S3_LATEST_VERSION environment variable', function() { beforeEach(function () {
beforeEach(function() {
process.env.ETCHER_FAKE_S3_LATEST_VERSION = '9.9.9'; process.env.ETCHER_FAKE_S3_LATEST_VERSION = '9.9.9';
}); });
afterEach(function() { afterEach(function () {
Reflect.deleteProperty(process.env, 'ETCHER_FAKE_S3_LATEST_VERSION'); Reflect.deleteProperty(process.env, 'ETCHER_FAKE_S3_LATEST_VERSION');
}); });
describe('given a production release type', function() { describe('given a production release type', function () {
it('should resolve the variable', function (done) {
it('should resolve the variable', function(done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => { s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => {
m.chai.expect(latestVersion).to.equal('9.9.9'); m.chai.expect(latestVersion).to.equal('9.9.9');
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given a snapshot release type', function() { describe('given a snapshot release type', function () {
it('should resolve undefined', function (done) {
it('should resolve undefined', function(done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.SNAPSHOT).then((latestVersion) => { s3Packages.getLatestVersion(release.RELEASE_TYPE.SNAPSHOT).then((latestVersion) => {
m.chai.expect(latestVersion).to.be.undefined; m.chai.expect(latestVersion).to.be.undefined;
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
}); });
describe('given a valid snapshot ETCHER_FAKE_S3_LATEST_VERSION environment variable', function() { describe('given a valid snapshot ETCHER_FAKE_S3_LATEST_VERSION environment variable', function () {
beforeEach(function () {
beforeEach(function() {
process.env.ETCHER_FAKE_S3_LATEST_VERSION = '9.9.9+7b47334'; process.env.ETCHER_FAKE_S3_LATEST_VERSION = '9.9.9+7b47334';
}); });
afterEach(function() { afterEach(function () {
Reflect.deleteProperty(process.env, 'ETCHER_FAKE_S3_LATEST_VERSION'); Reflect.deleteProperty(process.env, 'ETCHER_FAKE_S3_LATEST_VERSION');
}); });
describe('given a snapshot release type', function() { describe('given a snapshot release type', function () {
it('should resolve the variable', function (done) {
it('should resolve the variable', function(done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.SNAPSHOT).then((latestVersion) => { s3Packages.getLatestVersion(release.RELEASE_TYPE.SNAPSHOT).then((latestVersion) => {
m.chai.expect(latestVersion).to.equal('9.9.9+7b47334'); m.chai.expect(latestVersion).to.equal('9.9.9+7b47334');
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given a production release type', function() { describe('given a production release type', function () {
it('should resolve undefined', function (done) {
it('should resolve undefined', function(done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => { s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => {
m.chai.expect(latestVersion).to.be.undefined; m.chai.expect(latestVersion).to.be.undefined;
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
}); });
describe('given an invalid ETCHER_FAKE_S3_LATEST_VERSION environment variable', function() { describe('given an invalid ETCHER_FAKE_S3_LATEST_VERSION environment variable', function () {
beforeEach(function () {
beforeEach(function() {
process.env.ETCHER_FAKE_S3_LATEST_VERSION = 'foo'; process.env.ETCHER_FAKE_S3_LATEST_VERSION = 'foo';
}); });
afterEach(function() { afterEach(function () {
Reflect.deleteProperty(process.env, 'ETCHER_FAKE_S3_LATEST_VERSION'); Reflect.deleteProperty(process.env, 'ETCHER_FAKE_S3_LATEST_VERSION');
}); });
it('should resolve undefined', function(done) { it('should resolve undefined', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => { s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => {
m.chai.expect(latestVersion).to.be.undefined; m.chai.expect(latestVersion).to.be.undefined;
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given an invalid release type', function() { describe('given an invalid release type', function () {
it('should be rejected with an error', function (done) {
it('should be rejected with an error', function(done) {
s3Packages.getLatestVersion('foobar').catch((error) => { s3Packages.getLatestVersion('foobar').catch((error) => {
m.chai.expect(error).to.be.an.instanceof(Error); m.chai.expect(error).to.be.an.instanceof(Error);
m.chai.expect(error.message).to.equal('No bucket URL found for release type: foobar'); m.chai.expect(error.message).to.equal('No bucket URL found for release type: foobar');
done(); done();
}); });
}); });
}); });
describe('given no remote versions', function() { describe('given no remote versions', function () {
beforeEach(function () {
beforeEach(function() {
this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions'); this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions');
this.getRemoteVersionsStub.returns(Bluebird.resolve([])); this.getRemoteVersionsStub.returns(Bluebird.resolve([]));
}); });
afterEach(function() { afterEach(function () {
this.getRemoteVersionsStub.restore(); this.getRemoteVersionsStub.restore();
}); });
it('should resolve undefined', function(done) { it('should resolve undefined', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => { s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => {
m.chai.expect(latestVersion).to.be.undefined; m.chai.expect(latestVersion).to.be.undefined;
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given a single version', function() { describe('given a single version', function () {
beforeEach(function () {
beforeEach(function() {
this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions'); this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions');
this.getRemoteVersionsStub.returns(Bluebird.resolve([ '0.5.0' ])); this.getRemoteVersionsStub.returns(Bluebird.resolve([ '0.5.0' ]));
}); });
afterEach(function() { afterEach(function () {
this.getRemoteVersionsStub.restore(); this.getRemoteVersionsStub.restore();
}); });
it('should resolve the version', function(done) { it('should resolve the version', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => { s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => {
m.chai.expect(latestVersion).to.equal('0.5.0'); m.chai.expect(latestVersion).to.equal('0.5.0');
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given multiple versions', function() { describe('given multiple versions', function () {
beforeEach(function () {
beforeEach(function() {
this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions'); this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions');
this.getRemoteVersionsStub.returns(Bluebird.resolve([ this.getRemoteVersionsStub.returns(Bluebird.resolve([
'2.1.0', '2.1.0',
@ -913,22 +860,20 @@ describe('Shared: s3Packages', function() {
])); ]));
}); });
afterEach(function() { afterEach(function () {
this.getRemoteVersionsStub.restore(); this.getRemoteVersionsStub.restore();
}); });
it('should resolve the latest version', function(done) { it('should resolve the latest version', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => { s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => {
m.chai.expect(latestVersion).to.equal('2.1.0'); m.chai.expect(latestVersion).to.equal('2.1.0');
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given a greater production version in a snapshot bucket', function() { describe('given a greater production version in a snapshot bucket', function () {
beforeEach(function () {
beforeEach(function() {
this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions'); this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions');
this.getRemoteVersionsStub.returns(Bluebird.resolve([ this.getRemoteVersionsStub.returns(Bluebird.resolve([
'1.0.0+abb6139', '1.0.0+abb6139',
@ -936,22 +881,20 @@ describe('Shared: s3Packages', function() {
])); ]));
}); });
afterEach(function() { afterEach(function () {
this.getRemoteVersionsStub.restore(); this.getRemoteVersionsStub.restore();
}); });
it('should ignore production versions', function(done) { it('should ignore production versions', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.SNAPSHOT).then((latestVersion) => { s3Packages.getLatestVersion(release.RELEASE_TYPE.SNAPSHOT).then((latestVersion) => {
m.chai.expect(latestVersion).to.equal('1.0.0+abb6139'); m.chai.expect(latestVersion).to.equal('1.0.0+abb6139');
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given a greater snapshot version in a production bucket', function() { describe('given a greater snapshot version in a production bucket', function () {
beforeEach(function () {
beforeEach(function() {
this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions'); this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions');
this.getRemoteVersionsStub.returns(Bluebird.resolve([ this.getRemoteVersionsStub.returns(Bluebird.resolve([
'1.0.0', '1.0.0',
@ -959,22 +902,20 @@ describe('Shared: s3Packages', function() {
])); ]));
}); });
afterEach(function() { afterEach(function () {
this.getRemoteVersionsStub.restore(); this.getRemoteVersionsStub.restore();
}); });
it('should ignore snapshot versions', function(done) { it('should ignore snapshot versions', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => { s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => {
m.chai.expect(latestVersion).to.equal('1.0.0'); m.chai.expect(latestVersion).to.equal('1.0.0');
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given production v1, v2, and v3 remote versions', function() { describe('given production v1, v2, and v3 remote versions', function () {
beforeEach(function () {
beforeEach(function() {
this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions'); this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions');
this.getRemoteVersionsStub.returns(Bluebird.resolve([ this.getRemoteVersionsStub.returns(Bluebird.resolve([
'3.0.1', '3.0.1',
@ -990,11 +931,11 @@ describe('Shared: s3Packages', function() {
])); ]));
}); });
afterEach(function() { afterEach(function () {
this.getRemoteVersionsStub.restore(); this.getRemoteVersionsStub.restore();
}); });
it('should be able to resolve the latest v1 version with a semver range', function(done) { it('should be able to resolve the latest v1 version with a semver range', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, { s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
range: '<2.0.0' range: '<2.0.0'
}).then((latestVersion) => { }).then((latestVersion) => {
@ -1003,7 +944,7 @@ describe('Shared: s3Packages', function() {
}).catch(done); }).catch(done);
}); });
it('should be able to resolve the latest v2 version with a semver range', function(done) { it('should be able to resolve the latest v2 version with a semver range', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, { s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
range: '>=2.0.0 <3.0.0' range: '>=2.0.0 <3.0.0'
}).then((latestVersion) => { }).then((latestVersion) => {
@ -1012,7 +953,7 @@ describe('Shared: s3Packages', function() {
}).catch(done); }).catch(done);
}); });
it('should be able to resolve the latest v3 version with a semver range', function(done) { it('should be able to resolve the latest v3 version with a semver range', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, { s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
range: '>=3.0.0' range: '>=3.0.0'
}).then((latestVersion) => { }).then((latestVersion) => {
@ -1021,7 +962,7 @@ describe('Shared: s3Packages', function() {
}).catch(done); }).catch(done);
}); });
it('should resolve the latest version if includeUnstableChannel is true', function(done) { it('should resolve the latest version if includeUnstableChannel is true', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, { s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
includeUnstableChannel: true includeUnstableChannel: true
}).then((latestVersion) => { }).then((latestVersion) => {
@ -1030,7 +971,7 @@ describe('Shared: s3Packages', function() {
}).catch(done); }).catch(done);
}); });
it('should resolve the latest version if includeUnstableChannel is false', function(done) { it('should resolve the latest version if includeUnstableChannel is false', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, { s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
includeUnstableChannel: false includeUnstableChannel: false
}).then((latestVersion) => { }).then((latestVersion) => {
@ -1038,12 +979,10 @@ describe('Shared: s3Packages', function() {
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given unstable and stable versions where the last version is stable', function() { describe('given unstable and stable versions where the last version is stable', function () {
beforeEach(function () {
beforeEach(function() {
this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions'); this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions');
this.getRemoteVersionsStub.returns(Bluebird.resolve([ this.getRemoteVersionsStub.returns(Bluebird.resolve([
'3.0.1', '3.0.1',
@ -1055,11 +994,11 @@ describe('Shared: s3Packages', function() {
])); ]));
}); });
afterEach(function() { afterEach(function () {
this.getRemoteVersionsStub.restore(); this.getRemoteVersionsStub.restore();
}); });
it('should resolve the latest stable version if includeUnstableChannel is false', function(done) { it('should resolve the latest stable version if includeUnstableChannel is false', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, { s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
includeUnstableChannel: false includeUnstableChannel: false
}).then((latestVersion) => { }).then((latestVersion) => {
@ -1068,7 +1007,7 @@ describe('Shared: s3Packages', function() {
}).catch(done); }).catch(done);
}); });
it('should resolve the latest stable version if includeUnstableChannel is true', function(done) { it('should resolve the latest stable version if includeUnstableChannel is true', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, { s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
includeUnstableChannel: true includeUnstableChannel: true
}).then((latestVersion) => { }).then((latestVersion) => {
@ -1076,12 +1015,10 @@ describe('Shared: s3Packages', function() {
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given unstable and stable versions where the last version is unstable', function() { describe('given unstable and stable versions where the last version is unstable', function () {
beforeEach(function () {
beforeEach(function() {
this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions'); this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions');
this.getRemoteVersionsStub.returns(Bluebird.resolve([ this.getRemoteVersionsStub.returns(Bluebird.resolve([
'3.0.2-beta.1', '3.0.2-beta.1',
@ -1094,11 +1031,11 @@ describe('Shared: s3Packages', function() {
])); ]));
}); });
afterEach(function() { afterEach(function () {
this.getRemoteVersionsStub.restore(); this.getRemoteVersionsStub.restore();
}); });
it('should resolve the latest stable version if includeUnstableChannel is false', function(done) { it('should resolve the latest stable version if includeUnstableChannel is false', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, { s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
includeUnstableChannel: false includeUnstableChannel: false
}).then((latestVersion) => { }).then((latestVersion) => {
@ -1107,7 +1044,7 @@ describe('Shared: s3Packages', function() {
}).catch(done); }).catch(done);
}); });
it('should resolve the latest unstable version if includeUnstableChannel is true', function(done) { it('should resolve the latest unstable version if includeUnstableChannel is true', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, { s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
includeUnstableChannel: true includeUnstableChannel: true
}).then((latestVersion) => { }).then((latestVersion) => {
@ -1115,12 +1052,10 @@ describe('Shared: s3Packages', function() {
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given pre-release production remote versions', function() { describe('given pre-release production remote versions', function () {
beforeEach(function () {
beforeEach(function() {
this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions'); this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions');
this.getRemoteVersionsStub.returns(Bluebird.resolve([ this.getRemoteVersionsStub.returns(Bluebird.resolve([
'2.0.0-beta.3', '2.0.0-beta.3',
@ -1134,11 +1069,11 @@ describe('Shared: s3Packages', function() {
])); ]));
}); });
afterEach(function() { afterEach(function () {
this.getRemoteVersionsStub.restore(); this.getRemoteVersionsStub.restore();
}); });
it('should be able to resolve the latest v2 pre-release version with a non pre-release semver range', function(done) { it('should be able to resolve the latest v2 pre-release version with a non pre-release semver range', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, { s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
range: '>=2.0.0', range: '>=2.0.0',
includeUnstableChannel: true includeUnstableChannel: true
@ -1148,7 +1083,7 @@ describe('Shared: s3Packages', function() {
}).catch(done); }).catch(done);
}); });
it('should resolve undefined if includeUnstableChannel is false', function(done) { it('should resolve undefined if includeUnstableChannel is false', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, { s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
includeUnstableChannel: false includeUnstableChannel: false
}).then((latestVersion) => { }).then((latestVersion) => {
@ -1156,12 +1091,10 @@ describe('Shared: s3Packages', function() {
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
describe('given pre-release snapshot remote versions', function() { describe('given pre-release snapshot remote versions', function () {
beforeEach(function () {
beforeEach(function() {
this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions'); this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions');
this.getRemoteVersionsStub.returns(Bluebird.resolve([ this.getRemoteVersionsStub.returns(Bluebird.resolve([
'2.0.0-beta.3+5370ef2', '2.0.0-beta.3+5370ef2',
@ -1175,11 +1108,11 @@ describe('Shared: s3Packages', function() {
])); ]));
}); });
afterEach(function() { afterEach(function () {
this.getRemoteVersionsStub.restore(); this.getRemoteVersionsStub.restore();
}); });
it('should be able to resolve the latest v2 pre-release version with a non pre-release semver range', function(done) { it('should be able to resolve the latest v2 pre-release version with a non pre-release semver range', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.SNAPSHOT, { s3Packages.getLatestVersion(release.RELEASE_TYPE.SNAPSHOT, {
range: '>=2.0.0', range: '>=2.0.0',
includeUnstableChannel: true includeUnstableChannel: true
@ -1189,7 +1122,7 @@ describe('Shared: s3Packages', function() {
}).catch(done); }).catch(done);
}); });
it('should resolve undefined if includeUnstableChannel is false', function(done) { it('should resolve undefined if includeUnstableChannel is false', function (done) {
s3Packages.getLatestVersion(release.RELEASE_TYPE.SNAPSHOT, { s3Packages.getLatestVersion(release.RELEASE_TYPE.SNAPSHOT, {
includeUnstableChannel: false includeUnstableChannel: false
}).then((latestVersion) => { }).then((latestVersion) => {
@ -1197,9 +1130,6 @@ describe('Shared: s3Packages', function() {
done(); done();
}).catch(done); }).catch(done);
}); });
}); });
}); });
}); });

View File

@ -20,38 +20,30 @@ const m = require('mochainon');
const _ = require('lodash'); const _ = require('lodash');
const supportedFormats = require('../../lib/shared/supported-formats'); const supportedFormats = require('../../lib/shared/supported-formats');
describe('Shared: SupportedFormats', function() { describe('Shared: SupportedFormats', function () {
describe('.getCompressedExtensions()', function () {
describe('.getCompressedExtensions()', function() { it('should return the supported compressed extensions', function () {
it('should return the supported compressed extensions', function() {
const extensions = supportedFormats.getCompressedExtensions(); const extensions = supportedFormats.getCompressedExtensions();
m.chai.expect(extensions).to.deep.equal([ 'gz', 'bz2', 'xz' ]); m.chai.expect(extensions).to.deep.equal([ 'gz', 'bz2', 'xz' ]);
}); });
}); });
describe('.getNonCompressedExtensions()', function() { describe('.getNonCompressedExtensions()', function () {
it('should return the supported non compressed extensions', function () {
it('should return the supported non compressed extensions', function() {
const extensions = supportedFormats.getNonCompressedExtensions(); const extensions = supportedFormats.getNonCompressedExtensions();
m.chai.expect(extensions).to.deep.equal([ 'img', 'iso', 'dsk', 'hddimg', 'raw', 'dmg', 'sdcard', 'rpi-sdimg' ]); m.chai.expect(extensions).to.deep.equal([ 'img', 'iso', 'dsk', 'hddimg', 'raw', 'dmg', 'sdcard', 'rpi-sdimg' ]);
}); });
}); });
describe('.getArchiveExtensions()', function() { describe('.getArchiveExtensions()', function () {
it('should return the supported archive extensions', function () {
it('should return the supported archive extensions', function() {
const extensions = supportedFormats.getArchiveExtensions(); const extensions = supportedFormats.getArchiveExtensions();
m.chai.expect(extensions).to.deep.equal([ 'zip', 'etch' ]); m.chai.expect(extensions).to.deep.equal([ 'zip', 'etch' ]);
}); });
}); });
describe('.getAllExtensions()', function() { describe('.getAllExtensions()', function () {
it('should return the union of all compressed, uncompressed, and archive extensions', function () {
it('should return the union of all compressed, uncompressed, and archive extensions', function() {
const archiveExtensions = supportedFormats.getArchiveExtensions(); const archiveExtensions = supportedFormats.getArchiveExtensions();
const compressedExtensions = supportedFormats.getCompressedExtensions(); const compressedExtensions = supportedFormats.getCompressedExtensions();
const nonCompressedExtensions = supportedFormats.getNonCompressedExtensions(); const nonCompressedExtensions = supportedFormats.getNonCompressedExtensions();
@ -59,11 +51,9 @@ describe('Shared: SupportedFormats', function() {
const extensions = supportedFormats.getAllExtensions(); const extensions = supportedFormats.getAllExtensions();
m.chai.expect(extensions).to.deep.equal(expected); m.chai.expect(extensions).to.deep.equal(expected);
}); });
}); });
describe('.isSupportedImage()', function() { describe('.isSupportedImage()', function () {
_.forEach([ _.forEach([
// Type: 'archive' // Type: 'archive'
@ -85,58 +75,58 @@ describe('Shared: SupportedFormats', function() {
'path/to/filename.sdcard' 'path/to/filename.sdcard'
], (filename) => { ], (filename) => {
it(`should return true for ${filename}`, function() { it(`should return true for ${filename}`, function () {
const isSupported = supportedFormats.isSupportedImage(filename); const isSupported = supportedFormats.isSupportedImage(filename);
m.chai.expect(isSupported).to.be.true; m.chai.expect(isSupported).to.be.true;
}); });
}); });
it('should return false if the file has no extension', function() { it('should return false if the file has no extension', function () {
const isSupported = supportedFormats.isSupportedImage('/path/to/foo'); const isSupported = supportedFormats.isSupportedImage('/path/to/foo');
m.chai.expect(isSupported).to.be.false; m.chai.expect(isSupported).to.be.false;
}); });
it('should return false if the extension is not included in .getAllExtensions()', function() { it('should return false if the extension is not included in .getAllExtensions()', function () {
const isSupported = supportedFormats.isSupportedImage('/path/to/foo.jpg'); const isSupported = supportedFormats.isSupportedImage('/path/to/foo.jpg');
m.chai.expect(isSupported).to.be.false; m.chai.expect(isSupported).to.be.false;
}); });
it('should return true if the extension is included in .getAllExtensions()', function() { it('should return true if the extension is included in .getAllExtensions()', function () {
const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions()); const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions());
const imagePath = `/path/to/foo.${nonCompressedExtension}`; const imagePath = `/path/to/foo.${nonCompressedExtension}`;
const isSupported = supportedFormats.isSupportedImage(imagePath); const isSupported = supportedFormats.isSupportedImage(imagePath);
m.chai.expect(isSupported).to.be.true; m.chai.expect(isSupported).to.be.true;
}); });
it('should ignore casing when determining extension validity', function() { it('should ignore casing when determining extension validity', function () {
const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions()); const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions());
const imagePath = `/path/to/foo.${_.toUpper(nonCompressedExtension)}`; const imagePath = `/path/to/foo.${_.toUpper(nonCompressedExtension)}`;
const isSupported = supportedFormats.isSupportedImage(imagePath); const isSupported = supportedFormats.isSupportedImage(imagePath);
m.chai.expect(isSupported).to.be.true; m.chai.expect(isSupported).to.be.true;
}); });
it('should not consider an extension before a non compressed extension', function() { it('should not consider an extension before a non compressed extension', function () {
const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions()); const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions());
const imagePath = `/path/to/foo.1234.${nonCompressedExtension}`; const imagePath = `/path/to/foo.1234.${nonCompressedExtension}`;
const isSupported = supportedFormats.isSupportedImage(imagePath); const isSupported = supportedFormats.isSupportedImage(imagePath);
m.chai.expect(isSupported).to.be.true; m.chai.expect(isSupported).to.be.true;
}); });
it('should return true if the extension is supported and the file name includes dots', function() { it('should return true if the extension is supported and the file name includes dots', function () {
const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions()); const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions());
const imagePath = `/path/to/foo.1.2.3-bar.${nonCompressedExtension}`; const imagePath = `/path/to/foo.1.2.3-bar.${nonCompressedExtension}`;
const isSupported = supportedFormats.isSupportedImage(imagePath); const isSupported = supportedFormats.isSupportedImage(imagePath);
m.chai.expect(isSupported).to.be.true; m.chai.expect(isSupported).to.be.true;
}); });
it('should return true if the extension is only a supported archive extension', function() { it('should return true if the extension is only a supported archive extension', function () {
const archiveExtension = _.first(supportedFormats.getArchiveExtensions()); const archiveExtension = _.first(supportedFormats.getArchiveExtensions());
const imagePath = `/path/to/foo.${archiveExtension}`; const imagePath = `/path/to/foo.${archiveExtension}`;
const isSupported = supportedFormats.isSupportedImage(imagePath); const isSupported = supportedFormats.isSupportedImage(imagePath);
m.chai.expect(isSupported).to.be.true; m.chai.expect(isSupported).to.be.true;
}); });
it('should return true if the extension is a supported one plus a supported compressed extensions', function() { it('should return true if the extension is a supported one plus a supported compressed extensions', function () {
const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions()); const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions());
const compressedExtension = _.first(supportedFormats.getCompressedExtensions()); const compressedExtension = _.first(supportedFormats.getCompressedExtensions());
const imagePath = `/path/to/foo.${nonCompressedExtension}.${compressedExtension}`; const imagePath = `/path/to/foo.${nonCompressedExtension}.${compressedExtension}`;
@ -144,59 +134,59 @@ describe('Shared: SupportedFormats', function() {
m.chai.expect(isSupported).to.be.true; m.chai.expect(isSupported).to.be.true;
}); });
it('should return false if the extension is an unsupported one plus a supported compressed extensions', function() { it('should return false if the extension is an unsupported one plus a supported compressed extensions', function () {
const compressedExtension = _.first(supportedFormats.getCompressedExtensions()); const compressedExtension = _.first(supportedFormats.getCompressedExtensions());
const imagePath = `/path/to/foo.jpg.${compressedExtension}`; const imagePath = `/path/to/foo.jpg.${compressedExtension}`;
const isSupported = supportedFormats.isSupportedImage(imagePath); const isSupported = supportedFormats.isSupportedImage(imagePath);
m.chai.expect(isSupported).to.be.false; m.chai.expect(isSupported).to.be.false;
}); });
it('should return false if the file has no extension', function() { it('should return false if the file has no extension', function () {
const isSupported = supportedFormats.isSupportedImage('/path/to/foo'); const isSupported = supportedFormats.isSupportedImage('/path/to/foo');
m.chai.expect(isSupported).to.be.false; m.chai.expect(isSupported).to.be.false;
}); });
it('should return false if the extension is not included in .getAllExtensions()', function() { it('should return false if the extension is not included in .getAllExtensions()', function () {
const isSupported = supportedFormats.isSupportedImage('/path/to/foo.jpg'); const isSupported = supportedFormats.isSupportedImage('/path/to/foo.jpg');
m.chai.expect(isSupported).to.be.false; m.chai.expect(isSupported).to.be.false;
}); });
it('should return true if the extension is included in .getAllExtensions()', function() { it('should return true if the extension is included in .getAllExtensions()', function () {
const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions()); const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions());
const imagePath = `/path/to/foo.${nonCompressedExtension}`; const imagePath = `/path/to/foo.${nonCompressedExtension}`;
const isSupported = supportedFormats.isSupportedImage(imagePath); const isSupported = supportedFormats.isSupportedImage(imagePath);
m.chai.expect(isSupported).to.be.true; m.chai.expect(isSupported).to.be.true;
}); });
it('should ignore casing when determining extension validity', function() { it('should ignore casing when determining extension validity', function () {
const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions()); const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions());
const imagePath = `/path/to/foo.${_.toUpper(nonCompressedExtension)}`; const imagePath = `/path/to/foo.${_.toUpper(nonCompressedExtension)}`;
const isSupported = supportedFormats.isSupportedImage(imagePath); const isSupported = supportedFormats.isSupportedImage(imagePath);
m.chai.expect(isSupported).to.be.true; m.chai.expect(isSupported).to.be.true;
}); });
it('should not consider an extension before a non compressed extension', function() { it('should not consider an extension before a non compressed extension', function () {
const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions()); const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions());
const imagePath = `/path/to/foo.1234.${nonCompressedExtension}`; const imagePath = `/path/to/foo.1234.${nonCompressedExtension}`;
const isSupported = supportedFormats.isSupportedImage(imagePath); const isSupported = supportedFormats.isSupportedImage(imagePath);
m.chai.expect(isSupported).to.be.true; m.chai.expect(isSupported).to.be.true;
}); });
it('should return true if the extension is supported and the file name includes dots', function() { it('should return true if the extension is supported and the file name includes dots', function () {
const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions()); const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions());
const imagePath = `/path/to/foo.1.2.3-bar.${nonCompressedExtension}`; const imagePath = `/path/to/foo.1.2.3-bar.${nonCompressedExtension}`;
const isSupported = supportedFormats.isSupportedImage(imagePath); const isSupported = supportedFormats.isSupportedImage(imagePath);
m.chai.expect(isSupported).to.be.true; m.chai.expect(isSupported).to.be.true;
}); });
it('should return true if the extension is only a supported archive extension', function() { it('should return true if the extension is only a supported archive extension', function () {
const archiveExtension = _.first(supportedFormats.getArchiveExtensions()); const archiveExtension = _.first(supportedFormats.getArchiveExtensions());
const imagePath = `/path/to/foo.${archiveExtension}`; const imagePath = `/path/to/foo.${archiveExtension}`;
const isSupported = supportedFormats.isSupportedImage(imagePath); const isSupported = supportedFormats.isSupportedImage(imagePath);
m.chai.expect(isSupported).to.be.true; m.chai.expect(isSupported).to.be.true;
}); });
it('should return true if the extension is a supported one plus a supported compressed extensions', function() { it('should return true if the extension is a supported one plus a supported compressed extensions', function () {
const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions()); const nonCompressedExtension = _.first(supportedFormats.getNonCompressedExtensions());
const compressedExtension = _.first(supportedFormats.getCompressedExtensions()); const compressedExtension = _.first(supportedFormats.getCompressedExtensions());
const imagePath = `/path/to/foo.${nonCompressedExtension}.${compressedExtension}`; const imagePath = `/path/to/foo.${nonCompressedExtension}.${compressedExtension}`;
@ -204,43 +194,35 @@ describe('Shared: SupportedFormats', function() {
m.chai.expect(isSupported).to.be.true; m.chai.expect(isSupported).to.be.true;
}); });
it('should return false if the extension is an unsupported one plus a supported compressed extensions', function() { it('should return false if the extension is an unsupported one plus a supported compressed extensions', function () {
const compressedExtension = _.first(supportedFormats.getCompressedExtensions()); const compressedExtension = _.first(supportedFormats.getCompressedExtensions());
const imagePath = `/path/to/foo.jpg.${compressedExtension}`; const imagePath = `/path/to/foo.jpg.${compressedExtension}`;
const isSupported = supportedFormats.isSupportedImage(imagePath); const isSupported = supportedFormats.isSupportedImage(imagePath);
m.chai.expect(isSupported).to.be.false; m.chai.expect(isSupported).to.be.false;
}); });
}); });
describe('.looksLikeWindowsImage()', function() { describe('.looksLikeWindowsImage()', function () {
_.each([ _.each([
'C:\\path\\to\\en_windows_10_multiple_editions_version_1607_updated_jan_2017_x64_dvd_9714399.iso', 'C:\\path\\to\\en_windows_10_multiple_editions_version_1607_updated_jan_2017_x64_dvd_9714399.iso',
'/path/to/en_windows_10_multiple_editions_version_1607_updated_jan_2017_x64_dvd_9714399.iso', '/path/to/en_windows_10_multiple_editions_version_1607_updated_jan_2017_x64_dvd_9714399.iso',
'/path/to/Win10_1607_SingleLang_English_x32.iso', '/path/to/Win10_1607_SingleLang_English_x32.iso',
'/path/to/en_winxp_pro_x86_build2600_iso.img' '/path/to/en_winxp_pro_x86_build2600_iso.img'
], (imagePath) => { ], (imagePath) => {
it(`should return true if filename is ${imagePath}`, function () {
it(`should return true if filename is ${imagePath}`, function() {
const looksLikeWindowsImage = supportedFormats.looksLikeWindowsImage(imagePath); const looksLikeWindowsImage = supportedFormats.looksLikeWindowsImage(imagePath);
m.chai.expect(looksLikeWindowsImage).to.be.true; m.chai.expect(looksLikeWindowsImage).to.be.true;
}); });
}); });
_.each([ _.each([
'C:\\path\\to\\2017-01-11-raspbian-jessie.img', 'C:\\path\\to\\2017-01-11-raspbian-jessie.img',
'/path/to/2017-01-11-raspbian-jessie.img' '/path/to/2017-01-11-raspbian-jessie.img'
], (imagePath) => { ], (imagePath) => {
it(`should return false if filename is ${imagePath}`, function () {
it(`should return false if filename is ${imagePath}`, function() {
const looksLikeWindowsImage = supportedFormats.looksLikeWindowsImage(imagePath); const looksLikeWindowsImage = supportedFormats.looksLikeWindowsImage(imagePath);
m.chai.expect(looksLikeWindowsImage).to.be.false; m.chai.expect(looksLikeWindowsImage).to.be.false;
}); });
}); });
}); });
}); });

View File

@ -19,49 +19,43 @@
const m = require('mochainon'); const m = require('mochainon');
const units = require('../../lib/shared/units'); const units = require('../../lib/shared/units');
describe('Shared: Units', function() { describe('Shared: Units', function () {
describe('.bytesToClosestUnit()', function () {
describe('.bytesToClosestUnit()', function() { it('should convert bytes to terabytes', function () {
it('should convert bytes to terabytes', function() {
m.chai.expect(units.bytesToClosestUnit(1000000000000)).to.equal('1 TB'); m.chai.expect(units.bytesToClosestUnit(1000000000000)).to.equal('1 TB');
m.chai.expect(units.bytesToClosestUnit(2987801405440)).to.equal('2.99 TB'); m.chai.expect(units.bytesToClosestUnit(2987801405440)).to.equal('2.99 TB');
m.chai.expect(units.bytesToClosestUnit(999900000000000)).to.equal('999.9 TB'); m.chai.expect(units.bytesToClosestUnit(999900000000000)).to.equal('999.9 TB');
}); });
it('should convert bytes to gigabytes', function() { it('should convert bytes to gigabytes', function () {
m.chai.expect(units.bytesToClosestUnit(1000000000)).to.equal('1 GB'); m.chai.expect(units.bytesToClosestUnit(1000000000)).to.equal('1 GB');
m.chai.expect(units.bytesToClosestUnit(7801405440)).to.equal('7.8 GB'); m.chai.expect(units.bytesToClosestUnit(7801405440)).to.equal('7.8 GB');
m.chai.expect(units.bytesToClosestUnit(999900000000)).to.equal('999.9 GB'); m.chai.expect(units.bytesToClosestUnit(999900000000)).to.equal('999.9 GB');
}); });
it('should convert bytes to megabytes', function() { it('should convert bytes to megabytes', function () {
m.chai.expect(units.bytesToClosestUnit(1000000)).to.equal('1 MB'); m.chai.expect(units.bytesToClosestUnit(1000000)).to.equal('1 MB');
m.chai.expect(units.bytesToClosestUnit(801405440)).to.equal('801.41 MB'); m.chai.expect(units.bytesToClosestUnit(801405440)).to.equal('801.41 MB');
m.chai.expect(units.bytesToClosestUnit(999900000)).to.equal('999.9 MB'); m.chai.expect(units.bytesToClosestUnit(999900000)).to.equal('999.9 MB');
}); });
it('should convert bytes to kilobytes', function() { it('should convert bytes to kilobytes', function () {
m.chai.expect(units.bytesToClosestUnit(1000)).to.equal('1 kB'); m.chai.expect(units.bytesToClosestUnit(1000)).to.equal('1 kB');
m.chai.expect(units.bytesToClosestUnit(5440)).to.equal('5.44 kB'); m.chai.expect(units.bytesToClosestUnit(5440)).to.equal('5.44 kB');
m.chai.expect(units.bytesToClosestUnit(999900)).to.equal('999.9 kB'); m.chai.expect(units.bytesToClosestUnit(999900)).to.equal('999.9 kB');
}); });
it('should keep bytes as bytes', function() { it('should keep bytes as bytes', function () {
m.chai.expect(units.bytesToClosestUnit(1)).to.equal('1 B'); m.chai.expect(units.bytesToClosestUnit(1)).to.equal('1 B');
m.chai.expect(units.bytesToClosestUnit(8)).to.equal('8 B'); m.chai.expect(units.bytesToClosestUnit(8)).to.equal('8 B');
m.chai.expect(units.bytesToClosestUnit(999)).to.equal('999 B'); m.chai.expect(units.bytesToClosestUnit(999)).to.equal('999 B');
}); });
}); });
describe('.bytesToMegabytes()', function() { describe('.bytesToMegabytes()', function () {
it('should convert bytes to megabytes', function () {
it('should convert bytes to megabytes', function() {
m.chai.expect(units.bytesToMegabytes(1.2e+7)).to.equal(12); m.chai.expect(units.bytesToMegabytes(1.2e+7)).to.equal(12);
m.chai.expect(units.bytesToMegabytes(332000)).to.equal(0.332); m.chai.expect(units.bytesToMegabytes(332000)).to.equal(0.332);
}); });
}); });
}); });

View File

@ -19,116 +19,110 @@
const m = require('mochainon'); const m = require('mochainon');
const utils = require('../../lib/shared/utils'); const utils = require('../../lib/shared/utils');
describe('Shared: Utils', function() { describe('Shared: Utils', function () {
describe('.isValidPercentage()', function () {
describe('.isValidPercentage()', function() { it('should return false if percentage is not a number', function () {
it('should return false if percentage is not a number', function() {
m.chai.expect(utils.isValidPercentage('50')).to.be.false; m.chai.expect(utils.isValidPercentage('50')).to.be.false;
}); });
it('should return false if percentage is null', function() { it('should return false if percentage is null', function () {
m.chai.expect(utils.isValidPercentage(null)).to.be.false; m.chai.expect(utils.isValidPercentage(null)).to.be.false;
}); });
it('should return false if percentage is undefined', function() { it('should return false if percentage is undefined', function () {
m.chai.expect(utils.isValidPercentage(undefined)).to.be.false; m.chai.expect(utils.isValidPercentage(undefined)).to.be.false;
}); });
it('should return false if percentage is an integer less than 0', function() { it('should return false if percentage is an integer less than 0', function () {
m.chai.expect(utils.isValidPercentage(-1)).to.be.false; m.chai.expect(utils.isValidPercentage(-1)).to.be.false;
}); });
it('should return false if percentage is a float less than 0', function() { it('should return false if percentage is a float less than 0', function () {
m.chai.expect(utils.isValidPercentage(-0.1)).to.be.false; m.chai.expect(utils.isValidPercentage(-0.1)).to.be.false;
}); });
it('should return true if percentage is 0', function() { it('should return true if percentage is 0', function () {
m.chai.expect(utils.isValidPercentage(0)).to.be.true; m.chai.expect(utils.isValidPercentage(0)).to.be.true;
}); });
it('should return true if percentage is an integer greater than 0, but less than 100', function() { it('should return true if percentage is an integer greater than 0, but less than 100', function () {
m.chai.expect(utils.isValidPercentage(50)).to.be.true; m.chai.expect(utils.isValidPercentage(50)).to.be.true;
}); });
it('should return true if percentage is a float greater than 0, but less than 100', function() { it('should return true if percentage is a float greater than 0, but less than 100', function () {
m.chai.expect(utils.isValidPercentage(49.55)).to.be.true; m.chai.expect(utils.isValidPercentage(49.55)).to.be.true;
}); });
it('should return true if percentage is 100', function() { it('should return true if percentage is 100', function () {
m.chai.expect(utils.isValidPercentage(100)).to.be.true; m.chai.expect(utils.isValidPercentage(100)).to.be.true;
}); });
it('should return false if percentage is an integer greater than 100', function() { it('should return false if percentage is an integer greater than 100', function () {
m.chai.expect(utils.isValidPercentage(101)).to.be.false; m.chai.expect(utils.isValidPercentage(101)).to.be.false;
}); });
it('should return false if percentage is a float greater than 100', function() { it('should return false if percentage is a float greater than 100', function () {
m.chai.expect(utils.isValidPercentage(100.001)).to.be.false; m.chai.expect(utils.isValidPercentage(100.001)).to.be.false;
}); });
}); });
describe('.percentageToFloat()', function() { describe('.percentageToFloat()', function () {
it('should throw an error if given a string percentage', function () {
it('should throw an error if given a string percentage', function() { m.chai.expect(function () {
m.chai.expect(function() {
utils.percentageToFloat('50'); utils.percentageToFloat('50');
}).to.throw('Invalid percentage: 50'); }).to.throw('Invalid percentage: 50');
}); });
it('should throw an error if given a null percentage', function() { it('should throw an error if given a null percentage', function () {
m.chai.expect(function() { m.chai.expect(function () {
utils.percentageToFloat(null); utils.percentageToFloat(null);
}).to.throw('Invalid percentage: null'); }).to.throw('Invalid percentage: null');
}); });
it('should throw an error if given an undefined percentage', function() { it('should throw an error if given an undefined percentage', function () {
m.chai.expect(function() { m.chai.expect(function () {
utils.percentageToFloat(undefined); utils.percentageToFloat(undefined);
}).to.throw('Invalid percentage: undefined'); }).to.throw('Invalid percentage: undefined');
}); });
it('should throw an error if given an integer percentage < 0', function() { it('should throw an error if given an integer percentage < 0', function () {
m.chai.expect(function() { m.chai.expect(function () {
utils.percentageToFloat(-1); utils.percentageToFloat(-1);
}).to.throw('Invalid percentage: -1'); }).to.throw('Invalid percentage: -1');
}); });
it('should throw an error if given a float percentage < 0', function() { it('should throw an error if given a float percentage < 0', function () {
m.chai.expect(function() { m.chai.expect(function () {
utils.percentageToFloat(-0.1); utils.percentageToFloat(-0.1);
}).to.throw('Invalid percentage: -0.1'); }).to.throw('Invalid percentage: -0.1');
}); });
it('should covert a 0 percentage to 0', function() { it('should covert a 0 percentage to 0', function () {
m.chai.expect(utils.percentageToFloat(0)).to.equal(0); m.chai.expect(utils.percentageToFloat(0)).to.equal(0);
}); });
it('should covert an integer percentage to a float', function() { it('should covert an integer percentage to a float', function () {
m.chai.expect(utils.percentageToFloat(50)).to.equal(0.5); m.chai.expect(utils.percentageToFloat(50)).to.equal(0.5);
}); });
it('should covert an float percentage to a float', function() { it('should covert an float percentage to a float', function () {
m.chai.expect(utils.percentageToFloat(46.54)).to.equal(0.4654); m.chai.expect(utils.percentageToFloat(46.54)).to.equal(0.4654);
}); });
it('should covert a 100 percentage to 1', function() { it('should covert a 100 percentage to 1', function () {
m.chai.expect(utils.percentageToFloat(100)).to.equal(1); m.chai.expect(utils.percentageToFloat(100)).to.equal(1);
}); });
it('should throw an error if given an integer percentage > 100', function() { it('should throw an error if given an integer percentage > 100', function () {
m.chai.expect(function() { m.chai.expect(function () {
utils.percentageToFloat(101); utils.percentageToFloat(101);
}).to.throw('Invalid percentage: 101'); }).to.throw('Invalid percentage: 101');
}); });
it('should throw an error if given a float percentage > 100', function() { it('should throw an error if given a float percentage > 100', function () {
m.chai.expect(function() { m.chai.expect(function () {
utils.percentageToFloat(100.01); utils.percentageToFloat(100.01);
}).to.throw('Invalid percentage: 100.01'); }).to.throw('Invalid percentage: 100.01');
}); });
}); });
}); });