refactor(GUI): remove angular dependency from drive scanner (#1512)

Remove the Angular dependency from DriveScanner and with it the service,
exposing it through the module directly.
This commit is contained in:
Benedict Aas 2017-06-15 16:26:03 +01:00 committed by Juan Cruz Viotti
parent 9c1f9a54b1
commit 0f600c3cc2
5 changed files with 330 additions and 359 deletions

View File

@ -41,6 +41,7 @@ const analytics = require('./modules/analytics');
const updateNotifier = require('./components/update-notifier'); const updateNotifier = require('./components/update-notifier');
const availableDrives = require('./models/available-drives'); const availableDrives = require('./models/available-drives');
const selectionState = require('./models/selection-state'); const selectionState = require('./models/selection-state');
const driveScanner = require('./modules/drive-scanner');
const Store = require('./models/store'); const Store = require('./models/store');
@ -51,7 +52,6 @@ const app = angular.module('Etcher', [
// Etcher modules // Etcher modules
require('./modules/error'), require('./modules/error'),
require('./modules/drive-scanner'),
// Components // Components
require('./components/svg-icon'), require('./components/svg-icon'),
@ -176,8 +176,8 @@ app.run(() => {
}); });
}); });
app.run(($timeout, DriveScannerService, ErrorService) => { app.run(($timeout, ErrorService) => {
DriveScannerService.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
@ -188,18 +188,18 @@ app.run(($timeout, DriveScannerService, ErrorService) => {
}); });
}); });
DriveScannerService.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
// spamming our error reporting service. // spamming our error reporting service.
DriveScannerService.stop(); driveScanner.stop();
return ErrorService.reportException(error); return ErrorService.reportException(error);
}); });
DriveScannerService.start(); driveScanner.start();
}); });
app.run(($window, WarningModalService, ErrorService, OSDialogService) => { app.run(($window, WarningModalService, ErrorService, OSDialogService) => {

View File

@ -16,22 +16,13 @@
'use strict'; 'use strict';
/**
* @module Etcher.Modules.DriveScanner
*/
const Rx = require('rx'); const Rx = require('rx');
const os = require('os'); const os = require('os');
const _ = require('lodash'); const _ = require('lodash');
const angular = require('angular');
const EventEmitter = require('events').EventEmitter; const EventEmitter = require('events').EventEmitter;
const drivelist = require('drivelist'); const drivelist = require('drivelist');
const settings = require('../models/settings'); const settings = require('../models/settings');
const MODULE_NAME = 'Etcher.Modules.DriveScanner';
const driveScanner = angular.module(MODULE_NAME, []);
driveScanner.factory('DriveScannerService', () => {
const DRIVE_SCANNER_INTERVAL_MS = 2000; const DRIVE_SCANNER_INTERVAL_MS = 2000;
const DRIVE_SCANNER_FIRST_SCAN_DELAY_MS = 0; const DRIVE_SCANNER_FIRST_SCAN_DELAY_MS = 0;
const emitter = new EventEmitter(); const emitter = new EventEmitter();
@ -82,11 +73,11 @@ driveScanner.factory('DriveScannerService', () => {
* For example: * For example:
* *
* ``` * ```
* DriveScannerService.on('drives', (drives) => { * driveScanner.on('drives', (drives) => {
* console.log(drives); * console.log(drives);
* }); * });
* *
* DriveScannerService.on('error', (error) => { * driveScanner.on('error', (error) => {
* throw error; * throw error;
* }); * });
* ``` * ```
@ -103,7 +94,7 @@ driveScanner.factory('DriveScannerService', () => {
* @public * @public
* *
* @example * @example
* DriveScannerService.start(); * driveScanner.start();
*/ */
emitter.start = () => { emitter.start = () => {
availableDrives.resume(); availableDrives.resume();
@ -115,13 +106,10 @@ driveScanner.factory('DriveScannerService', () => {
* @public * @public
* *
* @example * @example
* DriveScannerService.stop(); * driveScanner.stop();
*/ */
emitter.stop = () => { emitter.stop = () => {
availableDrives.pause(); availableDrives.pause();
}; };
return emitter; module.exports = emitter;
});
module.exports = MODULE_NAME;

View File

@ -19,13 +19,13 @@
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'); const flashState = require('../../../models/flash-state');
const driveScanner = require('../../../modules/drive-scanner');
const utils = require('../../../../shared/utils'); const utils = require('../../../../shared/utils');
const notification = require('../../../os/notification'); const notification = require('../../../os/notification');
const path = require('path'); const path = require('path');
module.exports = function( module.exports = function(
$state, $state,
DriveScannerService,
ImageWriterService, ImageWriterService,
FlashErrorModalService, FlashErrorModalService,
ErrorService ErrorService
@ -58,7 +58,7 @@ module.exports = function(
// Stop scanning drives when flashing // Stop scanning drives when flashing
// otherwise Windows throws EPERM // otherwise Windows throws EPERM
DriveScannerService.stop(); driveScanner.stop();
const iconPath = '../../assets/icon.png'; const iconPath = '../../assets/icon.png';
@ -101,7 +101,7 @@ module.exports = function(
}) })
.finally(() => { .finally(() => {
DriveScannerService.start(); driveScanner.start();
}); });
}; };

View File

@ -43,7 +43,6 @@ const MainPage = angular.module(MODULE_NAME, [
require('../../os/open-external/open-external'), require('../../os/open-external/open-external'),
require('../../os/dropzone/dropzone'), require('../../os/dropzone/dropzone'),
require('../../modules/drive-scanner'),
require('../../modules/image-writer'), require('../../modules/image-writer'),
require('../../modules/error'), require('../../modules/error'),

View File

@ -2,43 +2,30 @@
const m = require('mochainon'); const m = require('mochainon');
const os = require('os'); const os = require('os');
const angular = require('angular');
const drivelist = require('drivelist'); const drivelist = require('drivelist');
require('angular-mocks'); const driveScanner = require('../../../lib/gui/modules/drive-scanner');
describe('Browser: DriveScanner', function() { describe('Browser: driveScanner', function() {
beforeEach(angular.mock.module(
require('../../../lib/gui/modules/drive-scanner')
));
describe('DriveScannerService', function() {
let DriveScannerService;
beforeEach(angular.mock.inject(function(_DriveScannerService_) {
DriveScannerService = _DriveScannerService_;
}));
describe('given no available drives', function() { describe('given no available drives', function() {
beforeEach(function() { beforeEach(function() {
this.drivesListStub = m.sinon.stub(drivelist, 'list'); this.drivelistStub = m.sinon.stub(drivelist, 'list');
this.drivesListStub.yields(null, []); this.drivelistStub.yields(null, []);
}); });
afterEach(function() { afterEach(function() {
this.drivesListStub.restore(); this.drivelistStub.restore();
}); });
it('should emit an empty array', function(done) { it('should emit an empty array', function(done) {
DriveScannerService.on('drives', function(drives) { driveScanner.once('drives', function(drives) {
m.chai.expect(drives).to.deep.equal([]); m.chai.expect(drives).to.deep.equal([]);
DriveScannerService.stop(); driveScanner.stop();
done(); done();
}); });
DriveScannerService.start(); driveScanner.start();
}); });
}); });
@ -46,9 +33,8 @@ describe('Browser: DriveScanner', function() {
describe('given only system available drives', function() { describe('given only system available drives', function() {
beforeEach(function() { beforeEach(function() {
this.drivesListStub = m.sinon.stub(drivelist, 'list'); this.drivelistStub = m.sinon.stub(drivelist, 'list');
this.drivesListStub.yields(null, [ this.drivelistStub.yields(null, [ {
{
device: '/dev/sda', device: '/dev/sda',
description: 'WDC WD10JPVX-75J', description: 'WDC WD10JPVX-75J',
size: '931.5G', size: '931.5G',
@ -58,22 +44,21 @@ describe('Browser: DriveScanner', function() {
} }
], ],
system: true system: true
} } ]);
]);
}); });
afterEach(function() { afterEach(function() {
this.drivesListStub.restore(); this.drivelistStub.restore();
}); });
it('should emit an empty array', function(done) { it('should emit an empty array', function(done) {
DriveScannerService.on('drives', function(drives) { driveScanner.once('drives', function(drives) {
m.chai.expect(drives).to.deep.equal([]); m.chai.expect(drives).to.deep.equal([]);
DriveScannerService.stop(); driveScanner.stop();
done(); done();
}); });
DriveScannerService.start(); driveScanner.start();
}); });
}); });
@ -92,8 +77,8 @@ describe('Browser: DriveScanner', function() {
describe('given available drives', function() { describe('given available drives', function() {
beforeEach(function() { beforeEach(function() {
this.drivesListStub = m.sinon.stub(drivelist, 'list'); this.drivelistStub = m.sinon.stub(drivelist, 'list');
this.drivesListStub.yields(null, [ this.drivelistStub.yields(null, [
{ {
device: '/dev/sda', device: '/dev/sda',
description: 'WDC WD10JPVX-75J', description: 'WDC WD10JPVX-75J',
@ -131,11 +116,11 @@ describe('Browser: DriveScanner', function() {
}); });
afterEach(function() { afterEach(function() {
this.drivesListStub.restore(); this.drivelistStub.restore();
}); });
it('should emit the non removable drives', function(done) { it('should emit the non removable drives', function(done) {
DriveScannerService.on('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',
@ -163,11 +148,11 @@ describe('Browser: DriveScanner', function() {
} }
]); ]);
DriveScannerService.stop(); driveScanner.stop();
done(); done();
}); });
DriveScannerService.start(); driveScanner.start();
}); });
}); });
@ -188,8 +173,8 @@ describe('Browser: DriveScanner', function() {
describe('given available drives', function() { describe('given available drives', function() {
beforeEach(function() { beforeEach(function() {
this.drivesListStub = m.sinon.stub(drivelist, 'list'); this.drivelistStub = m.sinon.stub(drivelist, 'list');
this.drivesListStub.yields(null, [ this.drivelistStub.yields(null, [
{ {
device: '\\\\.\\PHYSICALDRIVE1', device: '\\\\.\\PHYSICALDRIVE1',
description: 'WDC WD10JPVX-75J', description: 'WDC WD10JPVX-75J',
@ -223,11 +208,11 @@ describe('Browser: DriveScanner', function() {
}); });
afterEach(function() { afterEach(function() {
this.drivesListStub.restore(); this.drivelistStub.restore();
}); });
it('should emit the non removable drives', function(done) { it('should emit the non removable drives', function(done) {
DriveScannerService.on('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',
@ -251,11 +236,11 @@ describe('Browser: DriveScanner', function() {
} }
]); ]);
DriveScannerService.stop(); driveScanner.stop();
done(); done();
}); });
DriveScannerService.start(); driveScanner.start();
}); });
}); });
@ -263,8 +248,8 @@ describe('Browser: DriveScanner', function() {
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.drivesListStub = m.sinon.stub(drivelist, 'list'); this.drivelistStub = m.sinon.stub(drivelist, 'list');
this.drivesListStub.yields(null, [ this.drivelistStub.yields(null, [
{ {
device: '\\\\.\\PHYSICALDRIVE3', device: '\\\\.\\PHYSICALDRIVE3',
description: 'Bar', description: 'Bar',
@ -280,18 +265,18 @@ describe('Browser: DriveScanner', function() {
}); });
afterEach(function() { afterEach(function() {
this.drivesListStub.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) {
DriveScannerService.on('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].name).to.equal('F:'); m.chai.expect(drives[0].name).to.equal('F:');
DriveScannerService.stop(); driveScanner.stop();
done(); done();
}); });
DriveScannerService.start(); driveScanner.start();
}); });
}); });
@ -326,14 +311,14 @@ describe('Browser: DriveScanner', function() {
}); });
it('should join all the mountpoints in `name`', function(done) { it('should join all the mountpoints in `name`', function(done) {
DriveScannerService.on('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].name).to.equal('F:, G:, H:'); m.chai.expect(drives[0].name).to.equal('F:, G:, H:');
DriveScannerService.stop(); driveScanner.stop();
done(); done();
}); });
DriveScannerService.start(); driveScanner.start();
}); });
}); });
@ -352,17 +337,16 @@ describe('Browser: DriveScanner', function() {
}); });
it('should emit the error', function(done) { it('should emit the error', function(done) {
DriveScannerService.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');
DriveScannerService.stop(); driveScanner.stop();
done(); done();
}); });
DriveScannerService.start(); driveScanner.start();
}); });
}); });
}); });
});