refactor(GUI): remove Angular from FlashStateModel and rename (#1264)

We remove the usage of Angular from 'FlashStateModel' and its usage
throughout the project comes under the new 'flashState' moniker.


Depends: https://github.com/resin-io/etcher/pull/1261
This commit is contained in:
Benedict Aas 2017-04-10 19:30:21 +01:00 committed by Juan Cruz Viotti
parent 07dad2a0ef
commit b28c345ba0
13 changed files with 332 additions and 358 deletions

View File

@ -31,6 +31,7 @@ const Bluebird = require('bluebird');
const EXIT_CODES = require('../shared/exit-codes'); const EXIT_CODES = require('../shared/exit-codes');
const messages = require('../shared/messages'); const messages = require('../shared/messages');
const packageJSON = require('../../package.json'); const packageJSON = require('../../package.json');
const flashState = require('./models/flash-state');
const Store = require('./models/store'); const Store = require('./models/store');
@ -46,7 +47,6 @@ const app = angular.module('Etcher', [
// Models // Models
require('./models/selection-state'), require('./models/selection-state'),
require('./models/flash-state'),
require('./models/drives'), require('./models/drives'),
// Components // Components
@ -129,9 +129,9 @@ app.run((AnalyticsService, ErrorService, UpdateNotifierService, SelectionStateMo
}); });
app.run((AnalyticsService, OSWindowProgressService, FlashStateModel) => { app.run((AnalyticsService, OSWindowProgressService) => {
Store.subscribe(() => { Store.subscribe(() => {
const flashState = FlashStateModel.getFlashState(); const currentFlashState = flashState.getFlashState();
// There is usually a short time period between the `isFlashing()` // There is usually a short time period between the `isFlashing()`
// property being set, and the flashing actually starting, which // property being set, and the flashing actually starting, which
@ -140,17 +140,17 @@ app.run((AnalyticsService, OSWindowProgressService, FlashStateModel) => {
// //
// We use the presence of `.eta` to determine that the actual // We use the presence of `.eta` to determine that the actual
// writing started. // writing started.
if (!FlashStateModel.isFlashing() || !flashState.eta) { if (!flashState.isFlashing() || !flashState.eta) {
return; return;
} }
AnalyticsService.logDebug([ AnalyticsService.logDebug([
`Progress (${flashState.type}):`, `Progress (${currentFlashState.type}):`,
`${flashState.percentage}% at ${flashState.speed} MB/s`, `${currentFlashState.percentage}% at ${currentFlashState.speed} MB/s`,
`(eta ${flashState.eta}s)` `(eta ${currentFlashState.eta}s)`
].join(' ')); ].join(' '));
OSWindowProgressService.set(flashState.percentage); OSWindowProgressService.set(currentFlashState.percentage);
}); });
}); });
@ -180,13 +180,13 @@ app.run(($timeout, DriveScannerService, DrivesModel, ErrorService) => {
DriveScannerService.start(); DriveScannerService.start();
}); });
app.run(($window, AnalyticsService, WarningModalService, ErrorService, FlashStateModel, OSDialogService) => { app.run(($window, AnalyticsService, WarningModalService, ErrorService, OSDialogService) => {
let popupExists = false; let popupExists = false;
$window.addEventListener('beforeunload', (event) => { $window.addEventListener('beforeunload', (event) => {
if (!FlashStateModel.isFlashing() || popupExists) { if (!flashState.isFlashing() || popupExists) {
AnalyticsService.logEvent('Close application', { AnalyticsService.logEvent('Close application', {
isFlashing: FlashStateModel.isFlashing() isFlashing: flashState.isFlashing()
}); });
return; return;
} }

View File

@ -24,7 +24,6 @@ const angular = require('angular');
const MODULE_NAME = 'Etcher.Components.FlashErrorModal'; const MODULE_NAME = 'Etcher.Components.FlashErrorModal';
const FlashErrorModal = angular.module(MODULE_NAME, [ const FlashErrorModal = angular.module(MODULE_NAME, [
require('../warning-modal/warning-modal'), require('../warning-modal/warning-modal'),
require('../../models/flash-state'),
require('../../models/selection-state'), require('../../models/selection-state'),
require('../../modules/analytics') require('../../modules/analytics')
]); ]);

View File

@ -16,7 +16,9 @@
'use strict'; 'use strict';
module.exports = function(WarningModalService, FlashStateModel, SelectionStateModel, AnalyticsService) { const flashState = require('../../../models/flash-state');
module.exports = function(WarningModalService, SelectionStateModel, AnalyticsService) {
/** /**
* @summary Open the flash error modal * @summary Open the flash error modal
@ -34,7 +36,7 @@ module.exports = function(WarningModalService, FlashStateModel, SelectionStateMo
confirmationLabel: 'Retry', confirmationLabel: 'Retry',
description: message description: message
}).then((confirmed) => { }).then((confirmed) => {
FlashStateModel.resetState(); flashState.resetState();
if (confirmed) { if (confirmed) {
AnalyticsService.logEvent('Restart after failure'); AnalyticsService.logEvent('Restart after failure');

View File

@ -20,212 +20,203 @@
* @module Etcher.Models.FlashState * @module Etcher.Models.FlashState
*/ */
const angular = require('angular');
const _ = require('lodash'); const _ = require('lodash');
const Store = require('./store'); const Store = require('./store');
const MODULE_NAME = 'Etcher.Models.FlashState';
const FlashState = angular.module(MODULE_NAME, []);
const units = require('../../shared/units'); const units = require('../../shared/units');
FlashState.service('FlashStateModel', function() { /**
* @summary Reset flash state
* @function
* @public
*
* @example
* flashState.resetState();
*/
exports.resetState = () => {
Store.dispatch({
type: Store.Actions.RESET_FLASH_STATE
});
};
/** /**
* @summary Reset flash state * @summary Check if currently flashing
* @function * @function
* @public * @private
* *
* @example * @returns {Boolean} whether is flashing or not
* FlashStateModel.resetState(); *
*/ * @example
this.resetState = () => { * if (flashState.isFlashing()) {
Store.dispatch({ * console.log('We\'re currently flashing');
type: Store.Actions.RESET_FLASH_STATE * }
}); */
}; exports.isFlashing = () => {
return Store.getState().toJS().isFlashing;
};
/** /**
* @summary Check if currently flashing * @summary Set the flashing flag
* @function * @function
* @private * @private
* *
* @returns {Boolean} whether is flashing or not * @description
* * This function is extracted for testing purposes.
* @example *
* if (FlashStateModel.isFlashing()) { * The flag is used to signify that we're going to
* console.log('We\'re currently flashing'); * start a flash process.
* } *
*/ * @example
this.isFlashing = () => { * flashState.setFlashingFlag();
return Store.getState().toJS().isFlashing; */
}; exports.setFlashingFlag = () => {
Store.dispatch({
type: Store.Actions.SET_FLASHING_FLAG
});
};
/** /**
* @summary Set the flashing flag * @summary Unset the flashing flag
* @function * @function
* @private * @private
* *
* @description * @description
* This function is extracted for testing purposes. * This function is extracted for testing purposes.
* *
* The flag is used to signify that we're going to * The flag is used to signify that the write process ended.
* start a flash process. *
* * @param {Object} results - flash results
* @example *
* FlashStateModel.setFlashingFlag(); * @example
*/ * flashState.unsetFlashingFlag({
this.setFlashingFlag = () => { * cancelled: false,
Store.dispatch({ * sourceChecksum: 'a1b45d'
type: Store.Actions.SET_FLASHING_FLAG * });
}); */
}; exports.unsetFlashingFlag = (results) => {
Store.dispatch({
type: Store.Actions.UNSET_FLASHING_FLAG,
data: results
});
};
/** /**
* @summary Unset the flashing flag * @summary Set the flashing state
* @function * @function
* @private * @private
* *
* @description * @description
* This function is extracted for testing purposes. * This function is extracted for testing purposes.
* *
* The flag is used to signify that the write process ended. * @param {Object} state - flashing state
* *
* @param {Object} results - flash results * @example
* * flashState.setProgressState({
* @example * type: 'write',
* FlashStateModel.unsetFlashingFlag({ * percentage: 50,
* cancelled: false, * eta: 15,
* sourceChecksum: 'a1b45d' * speed: 100000000000
* }); * });
*/ */
this.unsetFlashingFlag = (results) => { exports.setProgressState = (state) => {
Store.dispatch({ Store.dispatch({
type: Store.Actions.UNSET_FLASHING_FLAG, type: Store.Actions.SET_FLASH_STATE,
data: results data: {
}); type: state.type,
}; percentage: state.percentage,
eta: state.eta,
/** speed: _.attempt(() => {
* @summary Set the flashing state if (_.isNumber(state.speed) && !_.isNaN(state.speed)) {
* @function
* @private
*
* @description
* This function is extracted for testing purposes.
*
* @param {Object} state - flashing state
*
* @example
* FlashStateModel.setProgressState({
* type: 'write',
* percentage: 50,
* eta: 15,
* speed: 100000000000
* });
*/
this.setProgressState = (state) => {
Store.dispatch({
type: Store.Actions.SET_FLASH_STATE,
data: {
type: state.type,
percentage: state.percentage,
eta: state.eta,
speed: _.attempt(() => { // Preserve only two decimal places
if (_.isNumber(state.speed) && !_.isNaN(state.speed)) { const PRECISION = 2;
return _.round(units.bytesToMegabytes(state.speed), PRECISION);
// Preserve only two decimal places }
const PRECISION = 2;
return _.round(units.bytesToMegabytes(state.speed), PRECISION);
} return null;
})
}
});
};
return null; /**
}) * @summary Get the flash results
} * @function
}); * @private
}; *
* @returns {Object} flash results
*
* @example
* const results = flashState.getFlashResults();
*/
exports.getFlashResults = () => {
return Store.getState().toJS().flashResults;
};
/** /**
* @summary Get the flash results * @summary Get the current flash state
* @function * @function
* @private * @public
* *
* @returns {Object} flash results * @returns {Object} flash state
* *
* @example * @example
* const results = FlashStateModel.getFlashResults(); * const flashState = flashState.getFlashState();
*/ */
this.getFlashResults = () => { exports.getFlashState = () => {
return Store.getState().toJS().flashResults; return Store.getState().get('flashState').toJS();
}; };
/** /**
* @summary Get the current flash state * @summary Determine if the last flash was cancelled
* @function * @function
* @public * @public
* *
* @returns {Object} flash state * @description
* * This function returns false if there was no last flash.
* @example *
* const flashState = FlashStateModel.getFlashState(); * @returns {Boolean} whether the last flash was cancelled
*/ *
this.getFlashState = () => { * @example
return Store.getState().get('flashState').toJS(); * if (flashState.wasLastFlashCancelled()) {
}; * console.log('The last flash was cancelled');
* }
*/
exports.wasLastFlashCancelled = () => {
return _.get(exports.getFlashResults(), [ 'cancelled' ], false);
};
/** /**
* @summary Determine if the last flash was cancelled * @summary Get last flash source checksum
* @function * @function
* @public * @public
* *
* @description * @description
* This function returns false if there was no last flash. * This function returns undefined if there was no last flash.
* *
* @returns {Boolean} whether the last flash was cancelled * @returns {(String|Undefined)} the last flash source checksum
* *
* @example * @example
* if (FlashStateModel.wasLastFlashCancelled()) { * const checksum = flashState.getLastFlashSourceChecksum();
* console.log('The last flash was cancelled'); */
* } exports.getLastFlashSourceChecksum = () => {
*/ return exports.getFlashResults().sourceChecksum;
this.wasLastFlashCancelled = () => { };
return _.get(this.getFlashResults(), [ 'cancelled' ], false);
};
/** /**
* @summary Get last flash source checksum * @summary Get last flash error code
* @function * @function
* @public * @public
* *
* @description * @description
* This function returns undefined if there was no last flash. * This function returns undefined if there was no last flash.
* *
* @returns {(String|Undefined)} the last flash source checksum * @returns {(String|Undefined)} the last flash error code
* *
* @example * @example
* const checksum = FlashStateModel.getLastFlashSourceChecksum(); * const errorCode = flashState.getLastFlashErrorCode();
*/ */
this.getLastFlashSourceChecksum = () => { exports.getLastFlashErrorCode = () => {
return this.getFlashResults().sourceChecksum; return exports.getFlashResults().errorCode;
}; };
/**
* @summary Get last flash error code
* @function
* @public
*
* @description
* This function returns undefined if there was no last flash.
*
* @returns {(String|Undefined)} the last flash error code
*
* @example
* const errorCode = FlashStateModel.getLastFlashErrorCode();
*/
this.getLastFlashErrorCode = () => {
return this.getFlashResults().errorCode;
};
});
module.exports = MODULE_NAME;

View File

@ -23,14 +23,14 @@
const angular = require('angular'); const angular = require('angular');
const childWriter = require('../../child-writer'); const childWriter = require('../../child-writer');
const settings = require('../models/settings'); const settings = require('../models/settings');
const flashState = require('../models/flash-state');
const MODULE_NAME = 'Etcher.Modules.ImageWriter'; const MODULE_NAME = 'Etcher.Modules.ImageWriter';
const imageWriter = angular.module(MODULE_NAME, [ const imageWriter = angular.module(MODULE_NAME, [
require('../models/selection-state'), require('../models/selection-state')
require('../models/flash-state')
]); ]);
imageWriter.service('ImageWriterService', function($q, $rootScope, SelectionStateModel, FlashStateModel) { imageWriter.service('ImageWriterService', function($q, $rootScope) {
/** /**
* @summary Perform write operation * @summary Perform write operation
@ -86,11 +86,11 @@ imageWriter.service('ImageWriterService', function($q, $rootScope, SelectionStat
* }); * });
*/ */
this.flash = (image, drive) => { this.flash = (image, drive) => {
if (FlashStateModel.isFlashing()) { if (flashState.isFlashing()) {
return $q.reject(new Error('There is already a flash in progress')); return $q.reject(new Error('There is already a flash in progress'));
} }
FlashStateModel.setFlashingFlag(); flashState.setFlashingFlag();
return this.performWrite(image, drive, (state) => { return this.performWrite(image, drive, (state) => {
@ -99,11 +99,11 @@ imageWriter.service('ImageWriterService', function($q, $rootScope, SelectionStat
// `.getFlashState()` will not return // `.getFlashState()` will not return
// the latest updated progress state. // the latest updated progress state.
$rootScope.$apply(() => { $rootScope.$apply(() => {
FlashStateModel.setProgressState(state); flashState.setProgressState(state);
}); });
}).then(FlashStateModel.unsetFlashingFlag).catch((error) => { }).then(flashState.unsetFlashingFlag).catch((error) => {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
errorCode: error.code errorCode: error.code
}); });

View File

@ -17,8 +17,9 @@
'use strict'; 'use strict';
const settings = require('../../../models/settings'); const settings = require('../../../models/settings');
const flashState = require('../../../models/flash-state');
module.exports = function($state, FlashStateModel, SelectionStateModel, AnalyticsService) { module.exports = function($state, SelectionStateModel, AnalyticsService) {
/** /**
* @summary Settings model * @summary Settings model
@ -32,7 +33,7 @@ module.exports = function($state, FlashStateModel, SelectionStateModel, Analytic
* @type {String} * @type {String}
* @public * @public
*/ */
this.checksum = FlashStateModel.getLastFlashSourceChecksum(); this.checksum = flashState.getLastFlashSourceChecksum();
/** /**
* @summary Restart the flashing process * @summary Restart the flashing process

View File

@ -31,7 +31,6 @@ const MODULE_NAME = 'Etcher.Pages.Finish';
const FinishPage = angular.module(MODULE_NAME, [ const FinishPage = angular.module(MODULE_NAME, [
require('angular-ui-router'), require('angular-ui-router'),
require('../../modules/analytics'), require('../../modules/analytics'),
require('../../models/flash-state'),
require('../../models/selection-state') require('../../models/selection-state')
]); ]);

View File

@ -18,10 +18,10 @@
const messages = require('../../../../shared/messages'); const messages = require('../../../../shared/messages');
const settings = require('../../../models/settings'); const settings = require('../../../models/settings');
const flashState = require('../../../models/flash-state');
module.exports = function( module.exports = function(
$state, $state,
FlashStateModel,
DriveScannerService, DriveScannerService,
ImageWriterService, ImageWriterService,
AnalyticsService, AnalyticsService,
@ -52,7 +52,7 @@ module.exports = function(
* }); * });
*/ */
this.flashImageToDrive = (image, drive) => { this.flashImageToDrive = (image, drive) => {
if (FlashStateModel.isFlashing()) { if (flashState.isFlashing()) {
return; return;
} }
@ -67,7 +67,7 @@ module.exports = function(
}); });
ImageWriterService.flash(image.path, drive).then(() => { ImageWriterService.flash(image.path, drive).then(() => {
if (FlashStateModel.wasLastFlashCancelled()) { if (flashState.wasLastFlashCancelled()) {
return; return;
} }
@ -121,26 +121,26 @@ module.exports = function(
* const label = FlashController.getProgressButtonLabel(); * const label = FlashController.getProgressButtonLabel();
*/ */
this.getProgressButtonLabel = () => { this.getProgressButtonLabel = () => {
const flashState = FlashStateModel.getFlashState(); const currentFlashState = flashState.getFlashState();
const isChecking = flashState.type === 'check'; const isChecking = currentFlashState.type === 'check';
const PERCENTAGE_MINIMUM = 0; const PERCENTAGE_MINIMUM = 0;
const PERCENTAGE_MAXIMUM = 100; const PERCENTAGE_MAXIMUM = 100;
if (!FlashStateModel.isFlashing()) { if (!flashState.isFlashing()) {
return 'Flash!'; return 'Flash!';
} else if (flashState.percentage === PERCENTAGE_MINIMUM && !flashState.speed) { } else if (currentFlashState.percentage === PERCENTAGE_MINIMUM && !currentFlashState.speed) {
return 'Starting...'; return 'Starting...';
} else if (flashState.percentage === PERCENTAGE_MAXIMUM) { } else if (currentFlashState.percentage === PERCENTAGE_MAXIMUM) {
if (isChecking && settings.get('unmountOnSuccess')) { if (isChecking && settings.get('unmountOnSuccess')) {
return 'Unmounting...'; return 'Unmounting...';
} }
return 'Finishing...'; return 'Finishing...';
} else if (isChecking) { } else if (isChecking) {
return `${flashState.percentage}% Validating...`; return `${currentFlashState.percentage}% Validating...`;
} }
return `${flashState.percentage}%`; return `${currentFlashState.percentage}%`;
}; };
}; };

View File

@ -17,11 +17,11 @@
'use strict'; 'use strict';
const settings = require('../../../models/settings'); const settings = require('../../../models/settings');
const flashState = require('../../../models/flash-state');
module.exports = function( module.exports = function(
SelectionStateModel, SelectionStateModel,
DrivesModel, DrivesModel,
FlashStateModel,
TooltipModalService, TooltipModalService,
ErrorService, ErrorService,
OSOpenExternalService, OSOpenExternalService,
@ -31,7 +31,7 @@ module.exports = function(
// Expose several modules to the template for convenience // Expose several modules to the template for convenience
this.selection = SelectionStateModel; this.selection = SelectionStateModel;
this.drives = DrivesModel; this.drives = DrivesModel;
this.state = FlashStateModel; this.state = flashState;
this.settings = settings; this.settings = settings;
this.external = OSOpenExternalService; this.external = OSOpenExternalService;

View File

@ -50,7 +50,6 @@ const MainPage = angular.module(MODULE_NAME, [
require('../../modules/analytics'), require('../../modules/analytics'),
require('../../modules/error'), require('../../modules/error'),
require('../../models/selection-state'), require('../../models/selection-state'),
require('../../models/flash-state'),
require('../../models/supported-formats'), require('../../models/supported-formats'),
require('../../models/drives'), require('../../models/drives'),

View File

@ -1,50 +1,39 @@
'use strict'; 'use strict';
const m = require('mochainon'); const m = require('mochainon');
const angular = require('angular'); const flashState = require('../../../lib/gui/models/flash-state');
require('angular-mocks');
describe('Browser: FlashStateModel', function() { describe('Browser: flashState', function() {
beforeEach(angular.mock.module( describe('flashState', function() {
require('../../../lib/gui/models/flash-state')
));
describe('FlashStateModel', function() {
let FlashStateModel;
beforeEach(angular.mock.inject(function(_FlashStateModel_) {
FlashStateModel = _FlashStateModel_;
}));
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() {
FlashStateModel.setFlashingFlag(); flashState.setFlashingFlag();
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 50, percentage: 50,
eta: 15, eta: 15,
speed: 100000000000 speed: 100000000000
}); });
FlashStateModel.resetState(); flashState.resetState();
m.chai.expect(FlashStateModel.getFlashState()).to.deep.equal({ m.chai.expect(flashState.getFlashState()).to.deep.equal({
percentage: 0, percentage: 0,
speed: 0 speed: 0
}); });
}); });
it('should be able to reset the progress state', function() { it('should be able to reset the progress state', function() {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234' sourceChecksum: '1234'
}); });
FlashStateModel.resetState(); flashState.resetState();
m.chai.expect(FlashStateModel.getFlashResults()).to.deep.equal({}); m.chai.expect(flashState.getFlashResults()).to.deep.equal({});
}); });
}); });
@ -52,12 +41,12 @@ describe('Browser: FlashStateModel', function() {
describe('.isFlashing()', function() { describe('.isFlashing()', function() {
it('should return false by default', function() { it('should return false by default', function() {
m.chai.expect(FlashStateModel.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() {
FlashStateModel.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(FlashStateModel.isFlashing()).to.be.true; m.chai.expect(flashState.isFlashing()).to.be.true;
}); });
}); });
@ -65,13 +54,13 @@ describe('Browser: FlashStateModel', function() {
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() {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234' sourceChecksum: '1234'
}); });
m.chai.expect(function() { m.chai.expect(function() {
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 50, percentage: 50,
eta: 15, eta: 15,
@ -81,9 +70,9 @@ describe('Browser: FlashStateModel', function() {
}); });
it('should throw if type is missing', function() { it('should throw if type is missing', function() {
FlashStateModel.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function() {
FlashStateModel.setProgressState({ flashState.setProgressState({
percentage: 50, percentage: 50,
eta: 15, eta: 15,
speed: 100000000000 speed: 100000000000
@ -92,9 +81,9 @@ describe('Browser: FlashStateModel', function() {
}); });
it('should throw if type is not a string', function() { it('should throw if type is not a string', function() {
FlashStateModel.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function() {
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 1234, type: 1234,
percentage: 50, percentage: 50,
eta: 15, eta: 15,
@ -104,9 +93,9 @@ describe('Browser: FlashStateModel', function() {
}); });
it('should not throw if percentage is 0', function() { it('should not throw if percentage is 0', function() {
FlashStateModel.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function() {
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 0, percentage: 0,
eta: 15, eta: 15,
@ -116,9 +105,9 @@ describe('Browser: FlashStateModel', function() {
}); });
it('should throw if percentage is missing', function() { it('should throw if percentage is missing', function() {
FlashStateModel.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function() {
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
eta: 15, eta: 15,
speed: 100000000000 speed: 100000000000
@ -127,9 +116,9 @@ describe('Browser: FlashStateModel', function() {
}); });
it('should throw if percentage is not a number', function() { it('should throw if percentage is not a number', function() {
FlashStateModel.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function() {
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: '50', percentage: '50',
eta: 15, eta: 15,
@ -139,9 +128,9 @@ describe('Browser: FlashStateModel', function() {
}); });
it('should throw if eta is missing', function() { it('should throw if eta is missing', function() {
FlashStateModel.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function() {
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 50, percentage: 50,
speed: 100000000000 speed: 100000000000
@ -150,9 +139,9 @@ describe('Browser: FlashStateModel', function() {
}); });
it('should not throw if eta is equal to zero', function() { it('should not throw if eta is equal to zero', function() {
FlashStateModel.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function() {
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 50, percentage: 50,
eta: 0, eta: 0,
@ -162,9 +151,9 @@ describe('Browser: FlashStateModel', function() {
}); });
it('should throw if eta is not a number', function() { it('should throw if eta is not a number', function() {
FlashStateModel.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function() {
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 50, percentage: 50,
eta: '15', eta: '15',
@ -174,9 +163,9 @@ describe('Browser: FlashStateModel', function() {
}); });
it('should throw if speed is missing', function() { it('should throw if speed is missing', function() {
FlashStateModel.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function() {
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 50, percentage: 50,
eta: 15 eta: 15
@ -185,9 +174,9 @@ describe('Browser: FlashStateModel', function() {
}); });
it('should not throw if speed is 0', function() { it('should not throw if speed is 0', function() {
FlashStateModel.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(function() { m.chai.expect(function() {
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 50, percentage: 50,
eta: 15, eta: 15,
@ -201,15 +190,15 @@ describe('Browser: FlashStateModel', function() {
describe('.getFlashResults()', function() { describe('.getFlashResults()', function() {
it('should get the flash results', function() { it('should get the flash results', function() {
FlashStateModel.setFlashingFlag(); flashState.setFlashingFlag();
const expectedResults = { const expectedResults = {
cancelled: false, cancelled: false,
sourceChecksum: '1234' sourceChecksum: '1234'
}; };
FlashStateModel.unsetFlashingFlag(expectedResults); flashState.unsetFlashingFlag(expectedResults);
const results = FlashStateModel.getFlashResults(); const results = flashState.getFlashResults();
m.chai.expect(results).to.deep.equal(expectedResults); m.chai.expect(results).to.deep.equal(expectedResults);
}); });
@ -218,9 +207,9 @@ describe('Browser: FlashStateModel', function() {
describe('.getFlashState()', function() { describe('.getFlashState()', function() {
it('should initially return an empty state', function() { it('should initially return an empty state', function() {
FlashStateModel.resetState(); flashState.resetState();
const flashState = FlashStateModel.getFlashState(); const currentFlashState = flashState.getFlashState();
m.chai.expect(flashState).to.deep.equal({ m.chai.expect(currentFlashState).to.deep.equal({
percentage: 0, percentage: 0,
speed: 0 speed: 0
}); });
@ -234,10 +223,10 @@ describe('Browser: FlashStateModel', function() {
speed: 0 speed: 0
}; };
FlashStateModel.setFlashingFlag(); flashState.setFlashingFlag();
FlashStateModel.setProgressState(state); flashState.setProgressState(state);
const flashState = FlashStateModel.getFlashState(); const currentFlashState = flashState.getFlashState();
m.chai.expect(flashState).to.deep.equal(state); m.chai.expect(currentFlashState).to.deep.equal(state);
}); });
}); });
@ -246,33 +235,33 @@ describe('Browser: FlashStateModel', 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() {
FlashStateModel.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() {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234', sourceChecksum: '1234',
errorCode: 'EBUSY' errorCode: 'EBUSY'
}); });
m.chai.expect(FlashStateModel.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() {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234', sourceChecksum: '1234',
errorCode: 123 errorCode: 123
}); });
m.chai.expect(FlashStateModel.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() {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234', sourceChecksum: '1234',
errorCode: { errorCode: {
@ -283,11 +272,11 @@ describe('Browser: FlashStateModel', function() {
}); });
it('should default cancelled to false', function() { it('should default cancelled to false', function() {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
sourceChecksum: '1234' sourceChecksum: '1234'
}); });
const flashResults = FlashStateModel.getFlashResults(); const flashResults = flashState.getFlashResults();
m.chai.expect(flashResults).to.deep.equal({ m.chai.expect(flashResults).to.deep.equal({
cancelled: false, cancelled: false,
@ -297,7 +286,7 @@ describe('Browser: FlashStateModel', 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() {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: 'false', cancelled: 'false',
sourceChecksum: '1234' sourceChecksum: '1234'
}); });
@ -306,7 +295,7 @@ describe('Browser: FlashStateModel', function() {
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() {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: true, cancelled: true,
sourceChecksum: '1234' sourceChecksum: '1234'
}); });
@ -314,35 +303,35 @@ describe('Browser: FlashStateModel', function() {
}); });
it('should be able to set flashing to false', function() { it('should be able to set flashing to false', function() {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234' sourceChecksum: '1234'
}); });
m.chai.expect(FlashStateModel.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() {
FlashStateModel.setFlashingFlag(); flashState.setFlashingFlag();
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 50, percentage: 50,
eta: 15, eta: 15,
speed: 100000000000 speed: 100000000000
}); });
m.chai.expect(FlashStateModel.getFlashState()).to.not.deep.equal({ m.chai.expect(flashState.getFlashState()).to.not.deep.equal({
percentage: 0, percentage: 0,
speed: 0 speed: 0
}); });
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234' sourceChecksum: '1234'
}); });
m.chai.expect(FlashStateModel.getFlashState()).to.deep.equal({ m.chai.expect(flashState.getFlashState()).to.deep.equal({
percentage: 0, percentage: 0,
speed: 0 speed: 0
}); });
@ -353,8 +342,8 @@ describe('Browser: FlashStateModel', function() {
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() {
FlashStateModel.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(FlashStateModel.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() {
@ -363,11 +352,11 @@ describe('Browser: FlashStateModel', function() {
sourceChecksum: '1234' sourceChecksum: '1234'
}; };
FlashStateModel.unsetFlashingFlag(expectedResults); flashState.unsetFlashingFlag(expectedResults);
const results = FlashStateModel.getFlashResults(); const results = flashState.getFlashResults();
m.chai.expect(results).to.deep.equal(expectedResults); m.chai.expect(results).to.deep.equal(expectedResults);
FlashStateModel.setFlashingFlag(); flashState.setFlashingFlag();
m.chai.expect(FlashStateModel.getFlashResults()).to.deep.equal({}); m.chai.expect(flashState.getFlashResults()).to.deep.equal({});
}); });
}); });
@ -375,25 +364,25 @@ describe('Browser: FlashStateModel', function() {
describe('.wasLastFlashCancelled()', function() { describe('.wasLastFlashCancelled()', function() {
it('should return false given a pristine state', function() { it('should return false given a pristine state', function() {
FlashStateModel.resetState(); flashState.resetState();
m.chai.expect(FlashStateModel.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() {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
sourceChecksum: '1234', sourceChecksum: '1234',
cancelled: false cancelled: false
}); });
m.chai.expect(FlashStateModel.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() {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: true cancelled: true
}); });
m.chai.expect(FlashStateModel.wasLastFlashCancelled()).to.be.true; m.chai.expect(flashState.wasLastFlashCancelled()).to.be.true;
}); });
}); });
@ -401,25 +390,25 @@ describe('Browser: FlashStateModel', function() {
describe('.getLastFlashSourceChecksum()', function() { describe('.getLastFlashSourceChecksum()', function() {
it('should return undefined given a pristine state', function() { it('should return undefined given a pristine state', function() {
FlashStateModel.resetState(); flashState.resetState();
m.chai.expect(FlashStateModel.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() {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
sourceChecksum: '1234', sourceChecksum: '1234',
cancelled: false cancelled: false
}); });
m.chai.expect(FlashStateModel.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() {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: true cancelled: true
}); });
m.chai.expect(FlashStateModel.getLastFlashSourceChecksum()).to.be.undefined; m.chai.expect(flashState.getLastFlashSourceChecksum()).to.be.undefined;
}); });
}); });
@ -427,27 +416,27 @@ describe('Browser: FlashStateModel', function() {
describe('.getLastFlashErrorCode()', function() { describe('.getLastFlashErrorCode()', function() {
it('should return undefined given a pristine state', function() { it('should return undefined given a pristine state', function() {
FlashStateModel.resetState(); flashState.resetState();
m.chai.expect(FlashStateModel.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() {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
sourceChecksum: '1234', sourceChecksum: '1234',
cancelled: false, cancelled: false,
errorCode: 'ENOSPC' errorCode: 'ENOSPC'
}); });
m.chai.expect(FlashStateModel.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() {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
sourceChecksum: '1234', sourceChecksum: '1234',
cancelled: false cancelled: false
}); });
m.chai.expect(FlashStateModel.getLastFlashErrorCode()).to.be.undefined; m.chai.expect(flashState.getLastFlashErrorCode()).to.be.undefined;
}); });
}); });

View File

@ -2,6 +2,7 @@
const m = require('mochainon'); const m = require('mochainon');
const angular = require('angular'); const angular = require('angular');
const flashState = require('../../../lib/gui/models/flash-state');
require('angular-mocks'); require('angular-mocks');
describe('Browser: ImageWriter', function() { describe('Browser: ImageWriter', function() {
@ -10,22 +11,16 @@ describe('Browser: ImageWriter', function() {
require('../../../lib/gui/modules/image-writer') require('../../../lib/gui/modules/image-writer')
)); ));
beforeEach(angular.mock.module(
require('../../../lib/gui/models/flash-state')
));
describe('ImageWriterService', function() { describe('ImageWriterService', function() {
let $q; let $q;
let $rootScope; let $rootScope;
let ImageWriterService; let ImageWriterService;
let FlashStateModel;
beforeEach(angular.mock.inject(function(_$q_, _$rootScope_, _ImageWriterService_, _FlashStateModel_) { beforeEach(angular.mock.inject(function(_$q_, _$rootScope_, _ImageWriterService_) {
$q = _$q_; $q = _$q_;
$rootScope = _$rootScope_; $rootScope = _$rootScope_;
ImageWriterService = _ImageWriterService_; ImageWriterService = _ImageWriterService_;
FlashStateModel = _FlashStateModel_;
})); }));
describe('.flash()', function() { describe('.flash()', function() {
@ -45,18 +40,18 @@ describe('Browser: ImageWriter', function() {
}); });
it('should set flashing to false when done', function() { it('should set flashing to false when done', function() {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234' sourceChecksum: '1234'
}); });
ImageWriterService.flash('foo.img', '/dev/disk2'); ImageWriterService.flash('foo.img', '/dev/disk2');
$rootScope.$apply(); $rootScope.$apply();
m.chai.expect(FlashStateModel.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() {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234' sourceChecksum: '1234'
}); });
@ -99,18 +94,18 @@ describe('Browser: ImageWriter', function() {
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(FlashStateModel.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 = FlashStateModel.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() {
FlashStateModel.unsetFlashingFlag({ flashState.unsetFlashingFlag({
cancelled: false, cancelled: false,
sourceChecksum: '1234' sourceChecksum: '1234'
}); });

View File

@ -5,6 +5,7 @@ const _ = require('lodash');
const path = require('path'); const path = require('path');
const angular = require('angular'); const angular = require('angular');
const settings = require('../../../lib/gui/models/settings'); const settings = require('../../../lib/gui/models/settings');
const flashState = require('../../../lib/gui/models/flash-state');
require('angular-mocks'); require('angular-mocks');
describe('Browser: MainPage', function() { describe('Browser: MainPage', function() {
@ -207,11 +208,9 @@ describe('Browser: MainPage', function() {
describe('FlashController', function() { describe('FlashController', function() {
let $controller; let $controller;
let FlashStateModel;
beforeEach(angular.mock.inject(function(_$controller_, _FlashStateModel_) { beforeEach(angular.mock.inject(function(_$controller_) {
$controller = _$controller_; $controller = _$controller_;
FlashStateModel = _FlashStateModel_;
})); }));
describe('.getProgressButtonLabel()', function() { describe('.getProgressButtonLabel()', function() {
@ -221,14 +220,14 @@ describe('Browser: MainPage', function() {
$scope: {} $scope: {}
}); });
FlashStateModel.resetState(); flashState.resetState();
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() {
FlashStateModel.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() {
@ -236,7 +235,7 @@ describe('Browser: MainPage', function() {
$scope: {} $scope: {}
}); });
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 0, percentage: 0,
eta: 15, eta: 15,
@ -252,7 +251,7 @@ describe('Browser: MainPage', function() {
$scope: {} $scope: {}
}); });
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 0, percentage: 0,
eta: 15, eta: 15,
@ -268,7 +267,7 @@ describe('Browser: MainPage', function() {
$scope: {} $scope: {}
}); });
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 0, percentage: 0,
eta: 15, eta: 15,
@ -284,7 +283,7 @@ describe('Browser: MainPage', function() {
$scope: {} $scope: {}
}); });
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'check', type: 'check',
percentage: 0, percentage: 0,
eta: 15, eta: 15,
@ -300,7 +299,7 @@ describe('Browser: MainPage', function() {
$scope: {} $scope: {}
}); });
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'check', type: 'check',
percentage: 0, percentage: 0,
eta: 15, eta: 15,
@ -316,7 +315,7 @@ describe('Browser: MainPage', function() {
$scope: {} $scope: {}
}); });
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 50, percentage: 50,
eta: 15, eta: 15,
@ -332,7 +331,7 @@ describe('Browser: MainPage', function() {
$scope: {} $scope: {}
}); });
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 50, percentage: 50,
eta: 15, eta: 15,
@ -348,7 +347,7 @@ describe('Browser: MainPage', function() {
$scope: {} $scope: {}
}); });
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'check', type: 'check',
percentage: 50, percentage: 50,
eta: 15, eta: 15,
@ -364,7 +363,7 @@ describe('Browser: MainPage', function() {
$scope: {} $scope: {}
}); });
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'check', type: 'check',
percentage: 50, percentage: 50,
eta: 15, eta: 15,
@ -380,7 +379,7 @@ describe('Browser: MainPage', function() {
$scope: {} $scope: {}
}); });
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 100, percentage: 100,
eta: 15, eta: 15,
@ -396,7 +395,7 @@ describe('Browser: MainPage', function() {
$scope: {} $scope: {}
}); });
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'write', type: 'write',
percentage: 100, percentage: 100,
eta: 15, eta: 15,
@ -412,7 +411,7 @@ describe('Browser: MainPage', function() {
$scope: {} $scope: {}
}); });
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'check', type: 'check',
percentage: 100, percentage: 100,
eta: 15, eta: 15,
@ -428,7 +427,7 @@ describe('Browser: MainPage', function() {
$scope: {} $scope: {}
}); });
FlashStateModel.setProgressState({ flashState.setProgressState({
type: 'check', type: 'check',
percentage: 100, percentage: 100,
eta: 15, eta: 15,