mirror of
https://github.com/balena-io/etcher.git
synced 2025-04-24 07:17:18 +00:00
refactor(GUI): make OSWindowProgress a simple CommonJS module (#1253)
There is no need to tie this module to Angular by using an Angular service. Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
This commit is contained in:
parent
55021376b5
commit
64c8eb594b
@ -32,6 +32,7 @@ const EXIT_CODES = require('../shared/exit-codes');
|
||||
const messages = require('../shared/messages');
|
||||
const packageJSON = require('../../package.json');
|
||||
const flashState = require('./models/flash-state');
|
||||
const windowProgress = require('./os/window-progress');
|
||||
|
||||
const Store = require('./models/store');
|
||||
|
||||
@ -60,7 +61,6 @@ const app = angular.module('Etcher', [
|
||||
require('./pages/settings/settings'),
|
||||
|
||||
// OS
|
||||
require('./os/window-progress/window-progress'),
|
||||
require('./os/open-external/open-external'),
|
||||
require('./os/dropzone/dropzone'),
|
||||
require('./os/dialog/dialog'),
|
||||
@ -129,7 +129,7 @@ app.run((AnalyticsService, ErrorService, UpdateNotifierService, SelectionStateMo
|
||||
|
||||
});
|
||||
|
||||
app.run((AnalyticsService, OSWindowProgressService) => {
|
||||
app.run((AnalyticsService) => {
|
||||
Store.subscribe(() => {
|
||||
const currentFlashState = flashState.getFlashState();
|
||||
|
||||
@ -150,7 +150,7 @@ app.run((AnalyticsService, OSWindowProgressService) => {
|
||||
`(eta ${currentFlashState.eta}s)`
|
||||
].join(' '));
|
||||
|
||||
OSWindowProgressService.set(currentFlashState.percentage);
|
||||
windowProgress.set(currentFlashState.percentage);
|
||||
});
|
||||
});
|
||||
|
||||
|
63
lib/gui/os/window-progress.js
Normal file
63
lib/gui/os/window-progress.js
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2016 resin.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const electron = require('electron');
|
||||
const utils = require('../../shared/utils');
|
||||
|
||||
/**
|
||||
* @summary A reference to the current renderer Electron window
|
||||
* @type {Object}
|
||||
* @protected
|
||||
*
|
||||
* @description
|
||||
* We expose this property to `this` for testability purposes.
|
||||
*/
|
||||
exports.currentWindow = electron.remote.getCurrentWindow();
|
||||
|
||||
/**
|
||||
* @summary Set operating system window progress
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @description
|
||||
* Show progress inline in operating system task bar
|
||||
*
|
||||
* @param {Number} percentage - percentage
|
||||
*
|
||||
* @example
|
||||
* windowProgress.set(85);
|
||||
*/
|
||||
exports.set = (percentage) => {
|
||||
exports.currentWindow.setProgressBar(utils.percentageToFloat(percentage));
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Clear the window progress bar
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @example
|
||||
* windowProgress.clear();
|
||||
*/
|
||||
exports.clear = () => {
|
||||
|
||||
// Passing 0 or null/undefined doesn't work.
|
||||
const ELECTRON_PROGRESS_BAR_RESET_VALUE = -1;
|
||||
|
||||
exports.currentWindow.setProgressBar(ELECTRON_PROGRESS_BAR_RESET_VALUE);
|
||||
};
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 resin.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const electron = require('electron');
|
||||
const errors = require('../../../../shared/errors');
|
||||
|
||||
module.exports = function() {
|
||||
|
||||
/**
|
||||
* @summary A reference to the current renderer Electron window
|
||||
* @type {Object}
|
||||
* @protected
|
||||
*
|
||||
* @description
|
||||
* We expose this property to `this` for testability purposes.
|
||||
*/
|
||||
this.currentWindow = electron.remote.getCurrentWindow();
|
||||
|
||||
/**
|
||||
* @summary Set operating system window progress
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @description
|
||||
* Show progress inline in operating system task bar
|
||||
*
|
||||
* @param {Number} percentage - percentage
|
||||
*
|
||||
* @example
|
||||
* OSWindowProgressService.set(85);
|
||||
*/
|
||||
this.set = (percentage) => {
|
||||
const PERCENTAGE_MINIMUM = 0;
|
||||
const PERCENTAGE_MAXIMUM = 100;
|
||||
|
||||
if (percentage > PERCENTAGE_MAXIMUM || percentage < PERCENTAGE_MINIMUM) {
|
||||
throw errors.createError(`Invalid window progress percentage: ${percentage}`);
|
||||
}
|
||||
|
||||
this.currentWindow.setProgressBar(percentage / PERCENTAGE_MAXIMUM);
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Clear the operating system window progress bar
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @example
|
||||
* OSWindowProgressService.clear();
|
||||
*/
|
||||
this.clear = () => {
|
||||
|
||||
// Passing 0 or null/undefined doesn't work.
|
||||
const ELECTRON_PROGRESS_BAR_RESET_VALUE = -1;
|
||||
|
||||
this.currentWindow.setProgressBar(ELECTRON_PROGRESS_BAR_RESET_VALUE);
|
||||
};
|
||||
|
||||
};
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 resin.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* The purpose of this module is to provide an easy way
|
||||
* to interact with the operating system's window progress
|
||||
* functionality, as described in Electron docs.
|
||||
*
|
||||
* @module Etcher.OS.WindowProgress
|
||||
*/
|
||||
|
||||
const angular = require('angular');
|
||||
const MODULE_NAME = 'Etcher.OS.WindowProgress';
|
||||
const OSWindowProgress = angular.module(MODULE_NAME, []);
|
||||
OSWindowProgress.service('OSWindowProgressService', require('./services/window-progress'));
|
||||
|
||||
module.exports = MODULE_NAME;
|
@ -19,6 +19,7 @@
|
||||
const messages = require('../../../../shared/messages');
|
||||
const settings = require('../../../models/settings');
|
||||
const flashState = require('../../../models/flash-state');
|
||||
const windowProgress = require('../../../os/window-progress');
|
||||
|
||||
module.exports = function(
|
||||
$state,
|
||||
@ -27,8 +28,7 @@ module.exports = function(
|
||||
AnalyticsService,
|
||||
FlashErrorModalService,
|
||||
ErrorService,
|
||||
OSNotificationService,
|
||||
OSWindowProgressService
|
||||
OSNotificationService
|
||||
) {
|
||||
|
||||
/**
|
||||
@ -105,7 +105,7 @@ module.exports = function(
|
||||
|
||||
})
|
||||
.finally(() => {
|
||||
OSWindowProgressService.clear();
|
||||
windowProgress.clear();
|
||||
DriveScannerService.start();
|
||||
});
|
||||
};
|
||||
|
@ -39,7 +39,6 @@ const MainPage = angular.module(MODULE_NAME, [
|
||||
require('../../components/flash-error-modal/flash-error-modal'),
|
||||
require('../../components/progress-button/progress-button'),
|
||||
|
||||
require('../../os/window-progress/window-progress'),
|
||||
require('../../os/notification/notification'),
|
||||
require('../../os/dialog/dialog'),
|
||||
require('../../os/open-external/open-external'),
|
||||
|
78
lib/shared/utils.js
Normal file
78
lib/shared/utils.js
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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';
|
||||
|
||||
const _ = require('lodash');
|
||||
const errors = require('./errors');
|
||||
|
||||
/**
|
||||
* @summary Minimum percentage value
|
||||
* @constant
|
||||
* @private
|
||||
* @type {Number}
|
||||
*/
|
||||
const PERCENTAGE_MINIMUM = 0;
|
||||
|
||||
/**
|
||||
* @summary Maximum percentage value
|
||||
* @constant
|
||||
* @private
|
||||
* @type {Number}
|
||||
*/
|
||||
const PERCENTAGE_MAXIMUM = 100;
|
||||
|
||||
/**
|
||||
* @summary Check if a percentage is valid
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @param {Number} percentage - percentage
|
||||
* @returns {Boolean} whether the percentage is valid
|
||||
*
|
||||
* @example
|
||||
* if (utils.isValidPercentage(85)) {
|
||||
* console.log('The percentage is valid');
|
||||
* }
|
||||
*/
|
||||
exports.isValidPercentage = (percentage) => {
|
||||
return _.every([
|
||||
_.isNumber(percentage),
|
||||
percentage >= PERCENTAGE_MINIMUM,
|
||||
percentage <= PERCENTAGE_MAXIMUM
|
||||
]);
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Convert a percentage to a float
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @param {Number} percentage - percentage
|
||||
* @returns {Number} float percentage
|
||||
*
|
||||
* @example
|
||||
* const value = utils.percentageToFloat(50);
|
||||
* console.log(value);
|
||||
* > 0.5
|
||||
*/
|
||||
exports.percentageToFloat = (percentage) => {
|
||||
if (!exports.isValidPercentage(percentage)) {
|
||||
throw errors.createError(`Invalid percentage: ${percentage}`);
|
||||
}
|
||||
|
||||
return percentage / PERCENTAGE_MAXIMUM;
|
||||
};
|
@ -17,29 +17,18 @@
|
||||
'use strict';
|
||||
|
||||
const m = require('mochainon');
|
||||
const angular = require('angular');
|
||||
require('angular-mocks');
|
||||
const windowProgress = require('../../../lib/gui/os/window-progress');
|
||||
|
||||
describe('Browser: OSWindowProgress', function() {
|
||||
describe('Browser: WindowProgress', function() {
|
||||
|
||||
beforeEach(angular.mock.module(
|
||||
require('../../../lib/gui/os/window-progress/window-progress')
|
||||
));
|
||||
|
||||
describe('OSWindowProgressService', function() {
|
||||
|
||||
let OSWindowProgressService;
|
||||
|
||||
beforeEach(angular.mock.inject(function(_OSWindowProgressService_) {
|
||||
OSWindowProgressService = _OSWindowProgressService_;
|
||||
}));
|
||||
describe('windowProgress', function() {
|
||||
|
||||
describe('given a stubbed current window', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
this.setProgressBarSpy = m.sinon.spy();
|
||||
|
||||
OSWindowProgressService.currentWindow = {
|
||||
windowProgress.currentWindow = {
|
||||
setProgressBar: this.setProgressBarSpy
|
||||
};
|
||||
});
|
||||
@ -47,30 +36,30 @@ describe('Browser: OSWindowProgress', function() {
|
||||
describe('.set()', function() {
|
||||
|
||||
it('should translate 0-100 percentages to 0-1 ranges', function() {
|
||||
OSWindowProgressService.set(85);
|
||||
windowProgress.set(85);
|
||||
m.chai.expect(this.setProgressBarSpy).to.have.been.calledWith(0.85);
|
||||
});
|
||||
|
||||
it('should set 0 given 0', function() {
|
||||
OSWindowProgressService.set(0);
|
||||
windowProgress.set(0);
|
||||
m.chai.expect(this.setProgressBarSpy).to.have.been.calledWith(0);
|
||||
});
|
||||
|
||||
it('should set 1 given 100', function() {
|
||||
OSWindowProgressService.set(100);
|
||||
windowProgress.set(100);
|
||||
m.chai.expect(this.setProgressBarSpy).to.have.been.calledWith(1);
|
||||
});
|
||||
|
||||
it('should throw if given a percentage higher than 100', function() {
|
||||
m.chai.expect(function() {
|
||||
OSWindowProgressService.set(101);
|
||||
}).to.throw('Invalid window progress percentage: 101');
|
||||
windowProgress.set(101);
|
||||
}).to.throw('Invalid percentage: 101');
|
||||
});
|
||||
|
||||
it('should throw if given a percentage less than 0', function() {
|
||||
m.chai.expect(function() {
|
||||
OSWindowProgressService.set(-1);
|
||||
}).to.throw('Invalid window progress percentage: -1');
|
||||
windowProgress.set(-1);
|
||||
}).to.throw('Invalid percentage: -1');
|
||||
});
|
||||
|
||||
});
|
||||
@ -78,7 +67,7 @@ describe('Browser: OSWindowProgress', function() {
|
||||
describe('.clear()', function() {
|
||||
|
||||
it('should set -1', function() {
|
||||
OSWindowProgressService.clear();
|
||||
windowProgress.clear();
|
||||
m.chai.expect(this.setProgressBarSpy).to.have.been.calledWith(-1);
|
||||
});
|
||||
|
||||
|
134
tests/shared/utils.spec.js
Normal file
134
tests/shared/utils.spec.js
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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';
|
||||
|
||||
const m = require('mochainon');
|
||||
const utils = require('../../lib/shared/utils');
|
||||
|
||||
describe('Shared: Utils', function() {
|
||||
|
||||
describe('.isValidPercentage()', function() {
|
||||
|
||||
it('should return false if percentage is not a number', function() {
|
||||
m.chai.expect(utils.isValidPercentage('50')).to.be.false;
|
||||
});
|
||||
|
||||
it('should return false if percentage is null', function() {
|
||||
m.chai.expect(utils.isValidPercentage(null)).to.be.false;
|
||||
});
|
||||
|
||||
it('should return false if percentage is undefined', function() {
|
||||
m.chai.expect(utils.isValidPercentage(undefined)).to.be.false;
|
||||
});
|
||||
|
||||
it('should return false if percentage is an integer less than 0', function() {
|
||||
m.chai.expect(utils.isValidPercentage(-1)).to.be.false;
|
||||
});
|
||||
|
||||
it('should return false if percentage is a float less than 0', function() {
|
||||
m.chai.expect(utils.isValidPercentage(-0.1)).to.be.false;
|
||||
});
|
||||
|
||||
it('should return true if percentage is 0', function() {
|
||||
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() {
|
||||
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() {
|
||||
m.chai.expect(utils.isValidPercentage(49.55)).to.be.true;
|
||||
});
|
||||
|
||||
it('should return true if percentage is 100', function() {
|
||||
m.chai.expect(utils.isValidPercentage(100)).to.be.true;
|
||||
});
|
||||
|
||||
it('should return false if percentage is an integer greater than 100', function() {
|
||||
m.chai.expect(utils.isValidPercentage(101)).to.be.false;
|
||||
});
|
||||
|
||||
it('should return false if percentage is a float greater than 100', function() {
|
||||
m.chai.expect(utils.isValidPercentage(100.001)).to.be.false;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('.percentageToFloat()', function() {
|
||||
|
||||
it('should throw an error if given a string percentage', function() {
|
||||
m.chai.expect(function() {
|
||||
utils.percentageToFloat('50');
|
||||
}).to.throw('Invalid percentage: 50');
|
||||
});
|
||||
|
||||
it('should throw an error if given a null percentage', function() {
|
||||
m.chai.expect(function() {
|
||||
utils.percentageToFloat(null);
|
||||
}).to.throw('Invalid percentage: null');
|
||||
});
|
||||
|
||||
it('should throw an error if given an undefined percentage', function() {
|
||||
m.chai.expect(function() {
|
||||
utils.percentageToFloat(undefined);
|
||||
}).to.throw('Invalid percentage: undefined');
|
||||
});
|
||||
|
||||
it('should throw an error if given an integer percentage < 0', function() {
|
||||
m.chai.expect(function() {
|
||||
utils.percentageToFloat(-1);
|
||||
}).to.throw('Invalid percentage: -1');
|
||||
});
|
||||
|
||||
it('should throw an error if given a float percentage < 0', function() {
|
||||
m.chai.expect(function() {
|
||||
utils.percentageToFloat(-0.1);
|
||||
}).to.throw('Invalid percentage: -0.1');
|
||||
});
|
||||
|
||||
it('should covert a 0 percentage to 0', function() {
|
||||
m.chai.expect(utils.percentageToFloat(0)).to.equal(0);
|
||||
});
|
||||
|
||||
it('should covert an integer percentage to a float', function() {
|
||||
m.chai.expect(utils.percentageToFloat(50)).to.equal(0.5);
|
||||
});
|
||||
|
||||
it('should covert an float percentage to a float', function() {
|
||||
m.chai.expect(utils.percentageToFloat(46.54)).to.equal(0.4654);
|
||||
});
|
||||
|
||||
it('should covert a 100 percentage to 1', function() {
|
||||
m.chai.expect(utils.percentageToFloat(100)).to.equal(1);
|
||||
});
|
||||
|
||||
it('should throw an error if given an integer percentage > 100', function() {
|
||||
m.chai.expect(function() {
|
||||
utils.percentageToFloat(101);
|
||||
}).to.throw('Invalid percentage: 101');
|
||||
});
|
||||
|
||||
it('should throw an error if given a float percentage > 100', function() {
|
||||
m.chai.expect(function() {
|
||||
utils.percentageToFloat(100.01);
|
||||
}).to.throw('Invalid percentage: 100.01');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user