mirror of
https://github.com/balena-io/etcher.git
synced 2025-04-24 15:27:17 +00:00
Decompress images before flashing, remove trim setting, trim ext partitions
Changelog-entry: Decompress images before flashing, remove trim setting, trim ext partitions Change-type: patch
This commit is contained in:
parent
e6125b893d
commit
ee62b9a4c7
@ -89,30 +89,43 @@ analytics.logEvent('Application start', {
|
||||
applicationSessionUuid,
|
||||
});
|
||||
|
||||
const debouncedLog = _.debounce(console.log, 1000, { maxWait: 1000 });
|
||||
|
||||
function pluralize(word: string, quantity: number) {
|
||||
return `${quantity} ${word}${quantity === 1 ? '' : 's'}`;
|
||||
}
|
||||
|
||||
observe(() => {
|
||||
if (!flashState.isFlashing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentFlashState = flashState.getFlashState();
|
||||
const stateType =
|
||||
!currentFlashState.flashing && currentFlashState.verifying
|
||||
? `Verifying ${currentFlashState.verifying}`
|
||||
: `Flashing ${currentFlashState.flashing}`;
|
||||
windowProgress.set(currentFlashState);
|
||||
|
||||
let eta = '';
|
||||
if (currentFlashState.eta !== undefined) {
|
||||
eta = `eta in ${currentFlashState.eta.toFixed(0)}s`;
|
||||
}
|
||||
let active = '';
|
||||
if (currentFlashState.type !== 'decompressing') {
|
||||
active = pluralize('device', currentFlashState.active);
|
||||
}
|
||||
// NOTE: There is usually a short time period between the `isFlashing()`
|
||||
// property being set, and the flashing actually starting, which
|
||||
// might cause some non-sense flashing state logs including
|
||||
// `undefined` values.
|
||||
analytics.logDebug(
|
||||
`${stateType} devices, ` +
|
||||
`${currentFlashState.percentage}% at ${currentFlashState.speed} MB/s ` +
|
||||
`(total ${currentFlashState.totalSpeed} MB/s) ` +
|
||||
`eta in ${currentFlashState.eta}s ` +
|
||||
`with ${currentFlashState.failed} failed devices`,
|
||||
);
|
||||
|
||||
windowProgress.set(currentFlashState);
|
||||
debouncedLog(outdent({ newline: ' ' })`
|
||||
${_.capitalize(currentFlashState.type)}
|
||||
${active},
|
||||
${currentFlashState.percentage}%
|
||||
at
|
||||
${(currentFlashState.speed || 0).toFixed(2)}
|
||||
MB/s
|
||||
(total ${(currentFlashState.speed * currentFlashState.active).toFixed(2)} MB/s)
|
||||
${eta}
|
||||
with
|
||||
${pluralize('failed device', currentFlashState.failed)}
|
||||
`);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -14,39 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import * as Color from 'color';
|
||||
import * as React from 'react';
|
||||
import { ProgressBar } from 'rendition';
|
||||
import { css, default as styled, keyframes } from 'styled-components';
|
||||
import { default as styled } from 'styled-components';
|
||||
|
||||
import { StepButton, StepSelection } from '../../styled-components';
|
||||
import { colors } from '../../theme';
|
||||
|
||||
const darkenForegroundStripes = 0.18;
|
||||
const desaturateForegroundStripes = 0.2;
|
||||
const progressButtonStripesForegroundColor = Color(colors.primary.background)
|
||||
.darken(darkenForegroundStripes)
|
||||
.desaturate(desaturateForegroundStripes)
|
||||
.string();
|
||||
|
||||
const desaturateBackgroundStripes = 0.05;
|
||||
const progressButtonStripesBackgroundColor = Color(colors.primary.background)
|
||||
.desaturate(desaturateBackgroundStripes)
|
||||
.string();
|
||||
|
||||
const ProgressButtonStripes = keyframes`
|
||||
0% {
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: 20px 20px;
|
||||
}
|
||||
`;
|
||||
|
||||
const ProgressButtonStripesRule = css`
|
||||
${ProgressButtonStripes} 1s linear infinite;
|
||||
`;
|
||||
import { StepButton } from '../../styled-components';
|
||||
|
||||
const FlashProgressBar = styled(ProgressBar)`
|
||||
> div {
|
||||
@ -54,6 +26,10 @@ const FlashProgressBar = styled(ProgressBar)`
|
||||
height: 48px;
|
||||
color: white !important;
|
||||
text-shadow: none !important;
|
||||
transition-duration: 0s;
|
||||
> div {
|
||||
transition-duration: 0s;
|
||||
}
|
||||
}
|
||||
|
||||
width: 200px;
|
||||
@ -61,40 +37,11 @@ const FlashProgressBar = styled(ProgressBar)`
|
||||
font-size: 16px;
|
||||
line-height: 48px;
|
||||
|
||||
background: ${Color(colors.warning.background)
|
||||
.darken(darkenForegroundStripes)
|
||||
.string()};
|
||||
`;
|
||||
|
||||
const FlashProgressBarValidating = styled(FlashProgressBar)`
|
||||
// Notice that we add 0.01 to certain gradient stop positions.
|
||||
// That workarounds a Chrome rendering issue where diagonal
|
||||
// lines look spiky.
|
||||
// See https://github.com/balena-io/etcher/issues/472
|
||||
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
0 0,
|
||||
100% 100%,
|
||||
color-stop(0.25, ${progressButtonStripesForegroundColor}),
|
||||
color-stop(0.26, ${progressButtonStripesBackgroundColor}),
|
||||
color-stop(0.5, ${progressButtonStripesBackgroundColor}),
|
||||
color-stop(0.51, ${progressButtonStripesForegroundColor}),
|
||||
color-stop(0.75, ${progressButtonStripesForegroundColor}),
|
||||
color-stop(0.76, ${progressButtonStripesBackgroundColor}),
|
||||
to(${progressButtonStripesBackgroundColor})
|
||||
);
|
||||
|
||||
background-color: white;
|
||||
|
||||
animation: ${ProgressButtonStripesRule};
|
||||
overflow: hidden;
|
||||
|
||||
background-size: 20px 20px;
|
||||
background: #2f3033;
|
||||
`;
|
||||
|
||||
interface ProgressButtonProps {
|
||||
striped: boolean;
|
||||
type: 'decompressing' | 'flashing' | 'verifying';
|
||||
active: boolean;
|
||||
percentage: number;
|
||||
label: string;
|
||||
@ -102,45 +49,35 @@ interface ProgressButtonProps {
|
||||
callback: () => any;
|
||||
}
|
||||
|
||||
const colors = {
|
||||
decompressing: '#00aeef',
|
||||
flashing: '#da60ff',
|
||||
verifying: '#1ac135',
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Progress Button component
|
||||
*/
|
||||
export class ProgressButton extends React.Component<ProgressButtonProps> {
|
||||
public render() {
|
||||
if (this.props.active) {
|
||||
if (this.props.striped) {
|
||||
return (
|
||||
<StepSelection>
|
||||
<FlashProgressBarValidating
|
||||
primary
|
||||
emphasized
|
||||
value={this.props.percentage}
|
||||
>
|
||||
{this.props.label}
|
||||
</FlashProgressBarValidating>
|
||||
</StepSelection>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<StepSelection>
|
||||
<FlashProgressBar warning emphasized value={this.props.percentage}>
|
||||
{this.props.label}
|
||||
</FlashProgressBar>
|
||||
</StepSelection>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<StepSelection>
|
||||
<StepButton
|
||||
primary
|
||||
onClick={this.props.callback}
|
||||
disabled={this.props.disabled}
|
||||
<FlashProgressBar
|
||||
background={colors[this.props.type]}
|
||||
value={this.props.percentage}
|
||||
>
|
||||
{this.props.label}
|
||||
</StepButton>
|
||||
</StepSelection>
|
||||
</FlashProgressBar>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<StepButton
|
||||
primary
|
||||
onClick={this.props.callback}
|
||||
disabled={this.props.disabled}
|
||||
>
|
||||
{this.props.label}
|
||||
</StepButton>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -87,10 +87,6 @@ const settingsList: Setting[] = [
|
||||
name: 'validateWriteOnSuccess',
|
||||
label: 'Validate write on success',
|
||||
},
|
||||
{
|
||||
name: 'trim',
|
||||
label: 'Trim ext{2,3,4} partitions before writing (raw images only)',
|
||||
},
|
||||
{
|
||||
name: 'updatesEnabled',
|
||||
label: 'Auto-updates enabled',
|
||||
|
@ -375,7 +375,7 @@ export class SourceSelector extends React.Component<
|
||||
analytics.logEvent('Unsupported protocol', { path: imagePath });
|
||||
return;
|
||||
}
|
||||
source = new sourceDestination.Http(imagePath);
|
||||
source = new sourceDestination.Http({ url: imagePath });
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -85,13 +85,6 @@ export function setProgressState(
|
||||
return _.round(bytesToMegabytes(state.speed), PRECISION);
|
||||
}
|
||||
|
||||
return null;
|
||||
}),
|
||||
totalSpeed: _.attempt(() => {
|
||||
if (_.isFinite(state.totalSpeed)) {
|
||||
return _.round(bytesToMegabytes(state.totalSpeed), PRECISION);
|
||||
}
|
||||
|
||||
return null;
|
||||
}),
|
||||
});
|
||||
|
@ -29,13 +29,14 @@ export const DEFAULT_SETTINGS: _.Dictionary<any> = {
|
||||
errorReporting: true,
|
||||
unmountOnSuccess: true,
|
||||
validateWriteOnSuccess: true,
|
||||
trim: false,
|
||||
updatesEnabled:
|
||||
packageJSON.updates.enabled &&
|
||||
!_.includes(['rpm', 'deb'], packageJSON.packageType),
|
||||
lastSleptUpdateNotifier: null,
|
||||
lastSleptUpdateNotifierVersion: null,
|
||||
desktopNotifications: true,
|
||||
autoBlockmapping: true,
|
||||
decompressFirst: true,
|
||||
};
|
||||
|
||||
let settings = _.cloneDeep(DEFAULT_SETTINGS);
|
||||
|
@ -45,7 +45,7 @@ function verifyNoNilFields(
|
||||
/**
|
||||
* @summary FLASH_STATE fields that can't be nil
|
||||
*/
|
||||
const flashStateNoNilFields = ['speed', 'totalSpeed'];
|
||||
const flashStateNoNilFields = ['speed'];
|
||||
|
||||
/**
|
||||
* @summary SELECT_IMAGE fields that can't be nil
|
||||
@ -65,14 +65,11 @@ const DEFAULT_STATE = Immutable.fromJS({
|
||||
isFlashing: false,
|
||||
flashResults: {},
|
||||
flashState: {
|
||||
flashing: 0,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
active: 0,
|
||||
failed: 0,
|
||||
percentage: 0,
|
||||
speed: null,
|
||||
averageSpeed: null,
|
||||
totalSpeed: null,
|
||||
},
|
||||
lastAverageFlashingSpeed: null,
|
||||
});
|
||||
@ -234,17 +231,7 @@ function storeReducer(
|
||||
|
||||
verifyNoNilFields(action.data, flashStateNoNilFields, 'flash');
|
||||
|
||||
if (
|
||||
!_.every(
|
||||
_.pick(action.data, [
|
||||
'flashing',
|
||||
'verifying',
|
||||
'successful',
|
||||
'failed',
|
||||
]),
|
||||
_.isFinite,
|
||||
)
|
||||
) {
|
||||
if (!_.every(_.pick(action.data, ['active', 'failed']), _.isFinite)) {
|
||||
throw errors.createError({
|
||||
title: 'State quantity field(s) not finite number',
|
||||
});
|
||||
@ -266,7 +253,7 @@ function storeReducer(
|
||||
}
|
||||
|
||||
let ret = state.set('flashState', Immutable.fromJS(action.data));
|
||||
if (action.data.flashing) {
|
||||
if (action.data.type === 'flashing') {
|
||||
ret = ret.set('lastAverageFlashingSpeed', action.data.averageSpeed);
|
||||
}
|
||||
return ret;
|
||||
|
@ -168,7 +168,6 @@ export function performWrite(
|
||||
flashInstanceUuid: flashState.getFlashUuid(),
|
||||
unmountOnSuccess: settings.get('unmountOnSuccess'),
|
||||
validateWriteOnSuccess: settings.get('validateWriteOnSuccess'),
|
||||
trim: settings.get('trim'),
|
||||
};
|
||||
|
||||
ipc.server.on('fail', ({ error }: { error: Error & { code: string } }) => {
|
||||
@ -196,8 +195,9 @@ export function performWrite(
|
||||
source,
|
||||
SourceType: source.SourceType.name,
|
||||
validateWriteOnSuccess: settings.get('validateWriteOnSuccess'),
|
||||
trim: settings.get('trim'),
|
||||
autoBlockmapping: settings.get('autoBlockmapping'),
|
||||
unmountOnSuccess: settings.get('unmountOnSuccess'),
|
||||
decompressFirst: settings.get('decompressFirst'),
|
||||
});
|
||||
});
|
||||
|
||||
@ -273,7 +273,6 @@ export async function flash(
|
||||
flashInstanceUuid: flashState.getFlashUuid(),
|
||||
unmountOnSuccess: settings.get('unmountOnSuccess'),
|
||||
validateWriteOnSuccess: settings.get('validateWriteOnSuccess'),
|
||||
trim: settings.get('trim'),
|
||||
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid,
|
||||
};
|
||||
@ -318,6 +317,8 @@ export async function flash(
|
||||
errors: results.errors,
|
||||
devices: results.devices,
|
||||
status: 'finished',
|
||||
bytesWritten: results.bytesWritten,
|
||||
sourceMetadata: results.sourceMetadata,
|
||||
};
|
||||
analytics.logEvent('Done', eventData);
|
||||
}
|
||||
@ -336,7 +337,6 @@ export function cancel() {
|
||||
flashInstanceUuid: flashState.getFlashUuid(),
|
||||
unmountOnSuccess: settings.get('unmountOnSuccess'),
|
||||
validateWriteOnSuccess: settings.get('validateWriteOnSuccess'),
|
||||
trim: settings.get('trim'),
|
||||
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid,
|
||||
status: 'cancel',
|
||||
|
@ -15,16 +15,15 @@
|
||||
*/
|
||||
|
||||
import { bytesToClosestUnit } from '../../../shared/units';
|
||||
import * as settings from '../models/settings';
|
||||
// import * as settings from '../models/settings';
|
||||
|
||||
export interface FlashState {
|
||||
flashing: number;
|
||||
verifying: number;
|
||||
successful: number;
|
||||
active: number;
|
||||
failed: number;
|
||||
percentage?: number;
|
||||
speed: number;
|
||||
position: number;
|
||||
type?: 'decompressing' | 'flashing' | 'verifying';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -36,45 +35,47 @@ export interface FlashState {
|
||||
*
|
||||
* @example
|
||||
* const status = progressStatus.fromFlashState({
|
||||
* flashing: 1,
|
||||
* verifying: 0,
|
||||
* successful: 0,
|
||||
* type: 'flashing'
|
||||
* active: 1,
|
||||
* failed: 0,
|
||||
* percentage: 55,
|
||||
* speed: 2049
|
||||
* speed: 2049,
|
||||
* })
|
||||
*
|
||||
* console.log(status)
|
||||
* // '55% Flashing'
|
||||
*/
|
||||
export function fromFlashState(state: FlashState): string {
|
||||
const isFlashing = Boolean(state.flashing);
|
||||
const isValidating = !isFlashing && Boolean(state.verifying);
|
||||
const shouldValidate = settings.get('validateWriteOnSuccess');
|
||||
const shouldUnmount = settings.get('unmountOnSuccess');
|
||||
|
||||
if (state.percentage === 0 && !state.speed) {
|
||||
if (isValidating) {
|
||||
return 'Validating...';
|
||||
}
|
||||
|
||||
export function fromFlashState({
|
||||
type,
|
||||
percentage,
|
||||
position,
|
||||
}: FlashState): string {
|
||||
if (type === undefined) {
|
||||
return 'Starting...';
|
||||
} else if (state.percentage === 100) {
|
||||
if ((isValidating || !shouldValidate) && shouldUnmount) {
|
||||
return 'Unmounting...';
|
||||
} else if (type === 'decompressing') {
|
||||
if (percentage == null) {
|
||||
return 'Decompressing...';
|
||||
} else {
|
||||
return `${percentage}% Decompressing`;
|
||||
}
|
||||
|
||||
return 'Finishing...';
|
||||
} else if (isFlashing) {
|
||||
if (state.percentage != null) {
|
||||
return `${state.percentage}% Flashing`;
|
||||
} else if (type === 'flashing') {
|
||||
if (percentage != null) {
|
||||
if (percentage < 100) {
|
||||
return `${percentage}% Flashing`;
|
||||
} else {
|
||||
return 'Finishing...';
|
||||
}
|
||||
} else {
|
||||
return `${bytesToClosestUnit(position)} flashed`;
|
||||
}
|
||||
} else if (type === 'verifying') {
|
||||
if (percentage == null) {
|
||||
return 'Validating...';
|
||||
} else if (percentage < 100) {
|
||||
return `${percentage}% Validating`;
|
||||
} else {
|
||||
return 'Finishing...';
|
||||
}
|
||||
return `${bytesToClosestUnit(state.position)} flashed`;
|
||||
} else if (isValidating) {
|
||||
return `${state.percentage}% Validating`;
|
||||
} else if (!isFlashing && !isValidating) {
|
||||
return 'Failed';
|
||||
}
|
||||
|
||||
throw new Error(`Invalid state: ${JSON.stringify(state)}`);
|
||||
return 'Failed';
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import { scanner as driveScanner } from '../../modules/drive-scanner';
|
||||
import * as imageWriter from '../../modules/image-writer';
|
||||
import * as progressStatus from '../../modules/progress-status';
|
||||
import * as notification from '../../os/notification';
|
||||
import { StepSelection } from '../../styled-components';
|
||||
|
||||
const COMPLETED_PERCENTAGE = 100;
|
||||
const SPEED_PRECISION = 2;
|
||||
@ -243,14 +244,16 @@ export const Flash = ({
|
||||
</div>
|
||||
|
||||
<div className="space-vertical-large">
|
||||
<ProgressButton
|
||||
striped={state.type === 'verifying'}
|
||||
active={isFlashing}
|
||||
percentage={state.percentage}
|
||||
label={getProgressButtonLabel()}
|
||||
disabled={Boolean(flashErrorCode) || shouldFlashStepBeDisabled}
|
||||
callback={tryFlash}
|
||||
></ProgressButton>
|
||||
<StepSelection>
|
||||
<ProgressButton
|
||||
type={state.type}
|
||||
active={isFlashing}
|
||||
percentage={state.percentage}
|
||||
label={getProgressButtonLabel()}
|
||||
disabled={Boolean(flashErrorCode) || shouldFlashStepBeDisabled}
|
||||
callback={tryFlash}
|
||||
/>
|
||||
</StepSelection>
|
||||
|
||||
{isFlashing && (
|
||||
<button
|
||||
|
@ -17,6 +17,7 @@
|
||||
import { delay } from 'bluebird';
|
||||
import { Drive as DrivelistDrive } from 'drivelist';
|
||||
import * as sdk from 'etcher-sdk';
|
||||
import { cleanupTmpFiles } from 'etcher-sdk/build/tmp';
|
||||
import * as _ from 'lodash';
|
||||
import * as ipc from 'node-ipc';
|
||||
|
||||
@ -77,6 +78,7 @@ interface WriteResult {
|
||||
successful: number;
|
||||
};
|
||||
errors: Array<Error & { device: string }>;
|
||||
sourceMetadata: sdk.sourceDestination.Metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,38 +86,42 @@ interface WriteResult {
|
||||
* @param {SourceDestination} source - source
|
||||
* @param {SourceDestination[]} destinations - destinations
|
||||
* @param {Boolean} verify - whether to validate the writes or not
|
||||
* @param {Boolean} trim - whether to trim ext partitions before writing
|
||||
* @param {Boolean} autoBlockmapping - whether to trim ext partitions before writing
|
||||
* @param {Function} onProgress - function to call on progress
|
||||
* @param {Function} onFail - function to call on fail
|
||||
* @returns {Promise<{ bytesWritten, devices, errors} >}
|
||||
*/
|
||||
async function writeAndValidate(
|
||||
source: sdk.sourceDestination.SourceDestination,
|
||||
destinations: sdk.sourceDestination.BlockDevice[],
|
||||
verify: boolean,
|
||||
trim: boolean,
|
||||
onProgress: sdk.multiWrite.OnProgressFunction,
|
||||
onFail: sdk.multiWrite.OnFailFunction,
|
||||
): Promise<WriteResult> {
|
||||
let innerSource: sdk.sourceDestination.SourceDestination = await source.getInnerSource();
|
||||
if (trim && (await innerSource.canRead())) {
|
||||
innerSource = new sdk.sourceDestination.ConfiguredSource({
|
||||
source: innerSource,
|
||||
shouldTrimPartitions: trim,
|
||||
createStreamFromDisk: true,
|
||||
});
|
||||
}
|
||||
async function writeAndValidate({
|
||||
source,
|
||||
destinations,
|
||||
verify,
|
||||
autoBlockmapping,
|
||||
decompressFirst,
|
||||
onProgress,
|
||||
onFail,
|
||||
}: {
|
||||
source: sdk.sourceDestination.SourceDestination;
|
||||
destinations: sdk.sourceDestination.BlockDevice[];
|
||||
verify: boolean;
|
||||
autoBlockmapping: boolean;
|
||||
decompressFirst: boolean;
|
||||
onProgress: sdk.multiWrite.OnProgressFunction;
|
||||
onFail: sdk.multiWrite.OnFailFunction;
|
||||
}): Promise<WriteResult> {
|
||||
const {
|
||||
sourceMetadata,
|
||||
failures,
|
||||
bytesWritten,
|
||||
} = await sdk.multiWrite.pipeSourceToDestinations(
|
||||
innerSource,
|
||||
} = await sdk.multiWrite.decompressThenFlash({
|
||||
source,
|
||||
destinations,
|
||||
onFail,
|
||||
onProgress,
|
||||
verify,
|
||||
32,
|
||||
);
|
||||
trim: autoBlockmapping,
|
||||
numBuffers: 32,
|
||||
decompressFirst,
|
||||
});
|
||||
const result: WriteResult = {
|
||||
bytesWritten,
|
||||
devices: {
|
||||
@ -123,6 +129,7 @@ async function writeAndValidate(
|
||||
successful: destinations.length - failures.size,
|
||||
},
|
||||
errors: [],
|
||||
sourceMetadata,
|
||||
};
|
||||
for (const [destination, error] of failures) {
|
||||
const err = error as Error & { device: string };
|
||||
@ -137,12 +144,15 @@ interface WriteOptions {
|
||||
destinations: DrivelistDrive[];
|
||||
unmountOnSuccess: boolean;
|
||||
validateWriteOnSuccess: boolean;
|
||||
trim: boolean;
|
||||
autoBlockmapping: boolean;
|
||||
decompressFirst: boolean;
|
||||
source: SourceOptions;
|
||||
SourceType: string;
|
||||
}
|
||||
|
||||
ipc.connectTo(IPC_SERVER_ID, () => {
|
||||
// Remove leftover tmp files older than 1 hour
|
||||
cleanupTmpFiles(Date.now() - 60 * 60 * 1000);
|
||||
process.once('uncaughtException', handleError);
|
||||
|
||||
// Gracefully exit on the following cases. If the parent
|
||||
@ -219,7 +229,8 @@ ipc.connectTo(IPC_SERVER_ID, () => {
|
||||
log(`Devices: ${destinations.join(', ')}`);
|
||||
log(`Umount on success: ${options.unmountOnSuccess}`);
|
||||
log(`Validate on success: ${options.validateWriteOnSuccess}`);
|
||||
log(`Trim: ${options.trim}`);
|
||||
log(`Auto blockmapping: ${options.autoBlockmapping}`);
|
||||
log(`Decompress first: ${options.decompressFirst}`);
|
||||
const dests = _.map(options.destinations, destination => {
|
||||
return new sdk.sourceDestination.BlockDevice({
|
||||
drive: destination,
|
||||
@ -235,17 +246,18 @@ ipc.connectTo(IPC_SERVER_ID, () => {
|
||||
path: options.imagePath,
|
||||
});
|
||||
} else {
|
||||
source = new Http(options.imagePath);
|
||||
source = new Http({ url: options.imagePath });
|
||||
}
|
||||
try {
|
||||
const results = await writeAndValidate(
|
||||
const results = await writeAndValidate({
|
||||
source,
|
||||
dests,
|
||||
options.validateWriteOnSuccess,
|
||||
options.trim,
|
||||
destinations: dests,
|
||||
verify: options.validateWriteOnSuccess,
|
||||
autoBlockmapping: options.autoBlockmapping,
|
||||
decompressFirst: options.decompressFirst,
|
||||
onProgress,
|
||||
onFail,
|
||||
);
|
||||
});
|
||||
log(`Finish: ${results.bytesWritten}`);
|
||||
results.errors = _.map(results.errors, error => {
|
||||
return toJSON(error);
|
||||
|
58
npm-shrinkwrap.json
generated
58
npm-shrinkwrap.json
generated
@ -1600,12 +1600,11 @@
|
||||
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.18.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz",
|
||||
"integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==",
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
|
||||
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
|
||||
"requires": {
|
||||
"follow-redirects": "1.5.10",
|
||||
"is-buffer": "^2.0.2"
|
||||
"follow-redirects": "1.5.10"
|
||||
}
|
||||
},
|
||||
"babel-code-frame": {
|
||||
@ -1860,9 +1859,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"buffer": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.5.0.tgz",
|
||||
"integrity": "sha512-9FTEDjLjwoAkEwyMGDjYJQN2gfRgOKBKRfiglhvibGbpeeU/pQn1bJxQqm32OD/AIeEuHxU9roxXxg34Byp/Ww==",
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
|
||||
"integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
|
||||
"requires": {
|
||||
"base64-js": "^1.0.2",
|
||||
"ieee754": "^1.1.4"
|
||||
@ -2469,6 +2468,11 @@
|
||||
"resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
|
||||
"integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
|
||||
},
|
||||
"check-disk-space": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/check-disk-space/-/check-disk-space-2.1.0.tgz",
|
||||
"integrity": "sha512-f0nx9oJF/AVF8nhSYlF1EBvMNnO+CXyLwKhPvN1943iOMI9TWhQigLZm80jAf0wzQhwKkzA8XXjyvuVUeGGcVQ=="
|
||||
},
|
||||
"check-error": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
|
||||
@ -2838,15 +2842,6 @@
|
||||
"object-visit": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"color": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color/-/color-2.0.1.tgz",
|
||||
"integrity": "sha512-ubUCVVKfT7r2w2D3qtHakj8mbmKms+tThR8gI8zEYCbUBl8/voqFGt3kgBqGwXAopgXybnkuOq+qMYCRrp4cXw==",
|
||||
"requires": {
|
||||
"color-convert": "^1.9.1",
|
||||
"color-string": "^1.5.2"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
@ -5412,14 +5407,15 @@
|
||||
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
|
||||
},
|
||||
"etcher-sdk": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/etcher-sdk/-/etcher-sdk-3.0.1.tgz",
|
||||
"integrity": "sha512-Jd30W0OfKNwbQZ4NdsNLCItyPYNP3hIugJrG/V5uzBtpL4R+gldMrUopkJ1L0x59d9NwWavQ/CqM6gxrv3tVlw==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/etcher-sdk/-/etcher-sdk-4.0.0.tgz",
|
||||
"integrity": "sha512-yzvZEoZkGO+QnpSRF7VTsNAMxnXTgdWoPOUUg62DVRrCJSIFOBrRYHfCfSCih20qHNlQnFuWKjJgFiDdMjfKJA==",
|
||||
"requires": {
|
||||
"@ronomon/direct-io": "^3.0.1",
|
||||
"axios": "^0.18.0",
|
||||
"axios": "^0.19.2",
|
||||
"blockmap": "^4.0.1",
|
||||
"bluebird": "^3.5.1",
|
||||
"check-disk-space": "^2.1.0",
|
||||
"crc": "^3.8.0",
|
||||
"debug": "^3.1.0",
|
||||
"drivelist": "^8.0.4",
|
||||
@ -8364,9 +8360,9 @@
|
||||
}
|
||||
},
|
||||
"lzma-native": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-6.0.0.tgz",
|
||||
"integrity": "sha512-rf5f4opPymsPHotgY2d0cUP3kbVxERSxWDGEbi2gnbnxuWGokFrBaQ02Oe9pssIwsgp0r0PnbSNg7VPY3AYe7w==",
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-6.0.1.tgz",
|
||||
"integrity": "sha512-O6oWF0xe1AFvOCjU8uOZBZ/lhjaMNwHfVNaqVMqmoQXlRwBcFWpCAToiZOdXcKVMdo/5s/D0a2QgA5laMErxHQ==",
|
||||
"requires": {
|
||||
"node-addon-api": "^1.6.0",
|
||||
"node-pre-gyp": "^0.11.0",
|
||||
@ -9320,9 +9316,9 @@
|
||||
}
|
||||
},
|
||||
"node-abi": {
|
||||
"version": "2.15.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.15.0.tgz",
|
||||
"integrity": "sha512-FeLpTS0F39U7hHZU1srAK4Vx+5AHNVOTP+hxBNQknR/54laTHSFIJkDWDqiquY1LeLUgTfPN7sLPhMubx0PLAg==",
|
||||
"version": "2.16.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.16.0.tgz",
|
||||
"integrity": "sha512-+sa0XNlWDA6T+bDLmkCUYn6W5k5W6BPRL6mqzSCs6H/xUgtl4D5x2fORKDzopKiU6wsyn/+wXlRXwXeSp+mtoA==",
|
||||
"requires": {
|
||||
"semver": "^5.4.1"
|
||||
}
|
||||
@ -9503,9 +9499,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "6.14.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.14.9.tgz",
|
||||
"integrity": "sha512-leP/gxHunuazPdZaCvsCefPQxinqUDsCxCR5xaDUrY2MkYxQRFZZwU5e7GojyYsGB7QVtCi7iVEl/hoFXQYc+w=="
|
||||
"version": "6.14.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.14.10.tgz",
|
||||
"integrity": "sha512-pF4HjZGSog75kGq7B1InK/wt/N08BuPATo+7HRfv7gZUzccebwv/fmWVGs/j6LvSiLWpCuGGhql51M/wcQsNzA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -14484,4 +14480,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -57,11 +57,10 @@
|
||||
"bindings": "^1.3.0",
|
||||
"bluebird": "^3.7.2",
|
||||
"bootstrap-sass": "^3.3.6",
|
||||
"color": "^2.0.1",
|
||||
"d3": "^4.13.0",
|
||||
"debug": "^3.1.0",
|
||||
"electron-updater": "4.0.6",
|
||||
"etcher-sdk": "^3.0.1",
|
||||
"etcher-sdk": "^4.0.0",
|
||||
"flexboxgrid": "^6.3.0",
|
||||
"immutable": "^3.8.1",
|
||||
"inactivity-timer": "^1.0.0",
|
||||
|
@ -28,16 +28,12 @@ describe('Model: flashState', function() {
|
||||
it('should be able to reset the progress state', function() {
|
||||
flashState.setFlashingFlag();
|
||||
flashState.setProgressState({
|
||||
flashing: 2,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
type: 'flashing',
|
||||
percentage: 50,
|
||||
eta: 15,
|
||||
speed: 100000000000,
|
||||
averageSpeed: 100000000000,
|
||||
totalSpeed: 200000000000,
|
||||
bytes: 0,
|
||||
position: 0,
|
||||
active: 0,
|
||||
@ -46,14 +42,11 @@ describe('Model: flashState', function() {
|
||||
flashState.resetState();
|
||||
|
||||
expect(flashState.getFlashState()).to.deep.equal({
|
||||
flashing: 0,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
active: 0,
|
||||
failed: 0,
|
||||
percentage: 0,
|
||||
speed: null,
|
||||
averageSpeed: null,
|
||||
totalSpeed: null,
|
||||
});
|
||||
});
|
||||
|
||||
@ -100,16 +93,12 @@ describe('Model: flashState', function() {
|
||||
|
||||
expect(function() {
|
||||
flashState.setProgressState({
|
||||
flashing: 2,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
type: 'flashing',
|
||||
percentage: 50,
|
||||
eta: 15,
|
||||
speed: 100000000000,
|
||||
averageSpeed: 100000000000,
|
||||
totalSpeed: 200000000000,
|
||||
bytes: 0,
|
||||
position: 0,
|
||||
active: 0,
|
||||
@ -121,16 +110,12 @@ describe('Model: flashState', function() {
|
||||
flashState.setFlashingFlag();
|
||||
expect(function() {
|
||||
flashState.setProgressState({
|
||||
flashing: 2,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
type: 'flashing',
|
||||
percentage: 0,
|
||||
eta: 15,
|
||||
speed: 100000000000,
|
||||
averageSpeed: 100000000000,
|
||||
totalSpeed: 200000000000,
|
||||
bytes: 0,
|
||||
position: 0,
|
||||
active: 0,
|
||||
@ -142,16 +127,12 @@ describe('Model: flashState', function() {
|
||||
flashState.setFlashingFlag();
|
||||
expect(function() {
|
||||
flashState.setProgressState({
|
||||
flashing: 2,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
type: 'flashing',
|
||||
percentage: 101,
|
||||
eta: 15,
|
||||
speed: 0,
|
||||
averageSpeed: 0,
|
||||
totalSpeed: 1,
|
||||
bytes: 0,
|
||||
position: 0,
|
||||
active: 0,
|
||||
@ -163,16 +144,12 @@ describe('Model: flashState', function() {
|
||||
flashState.setFlashingFlag();
|
||||
expect(function() {
|
||||
flashState.setProgressState({
|
||||
flashing: 2,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
type: 'flashing',
|
||||
percentage: -1,
|
||||
eta: 15,
|
||||
speed: 0,
|
||||
averageSpeed: 0,
|
||||
totalSpeed: 1,
|
||||
bytes: 0,
|
||||
position: 0,
|
||||
active: 0,
|
||||
@ -184,16 +161,12 @@ describe('Model: flashState', function() {
|
||||
flashState.setFlashingFlag();
|
||||
expect(function() {
|
||||
flashState.setProgressState({
|
||||
flashing: 2,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
type: 'flashing',
|
||||
percentage: 50,
|
||||
eta: 0,
|
||||
speed: 100000000000,
|
||||
averageSpeed: 100000000000,
|
||||
totalSpeed: 200000000000,
|
||||
bytes: 0,
|
||||
position: 0,
|
||||
active: 0,
|
||||
@ -205,9 +178,6 @@ describe('Model: flashState', function() {
|
||||
flashState.setFlashingFlag();
|
||||
expect(function() {
|
||||
flashState.setProgressState({
|
||||
flashing: 2,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
type: 'flashing',
|
||||
percentage: 50,
|
||||
@ -215,7 +185,6 @@ describe('Model: flashState', function() {
|
||||
eta: '15',
|
||||
speed: 100000000000,
|
||||
averageSpeed: 100000000000,
|
||||
totalSpeed: 200000000000,
|
||||
bytes: 0,
|
||||
position: 0,
|
||||
active: 0,
|
||||
@ -228,15 +197,11 @@ describe('Model: flashState', function() {
|
||||
expect(function() {
|
||||
// @ts-ignore
|
||||
flashState.setProgressState({
|
||||
flashing: 2,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
type: 'flashing',
|
||||
percentage: 50,
|
||||
eta: 15,
|
||||
averageSpeed: 0,
|
||||
totalSpeed: 1,
|
||||
bytes: 0,
|
||||
position: 0,
|
||||
active: 0,
|
||||
@ -248,16 +213,12 @@ describe('Model: flashState', function() {
|
||||
flashState.setFlashingFlag();
|
||||
expect(function() {
|
||||
flashState.setProgressState({
|
||||
flashing: 2,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
type: 'flashing',
|
||||
percentage: 50,
|
||||
eta: 15,
|
||||
speed: 0,
|
||||
averageSpeed: 0,
|
||||
totalSpeed: 1,
|
||||
bytes: 0,
|
||||
position: 0,
|
||||
active: 0,
|
||||
@ -265,61 +226,15 @@ describe('Model: flashState', function() {
|
||||
}).to.not.throw('Missing flash fields: speed');
|
||||
});
|
||||
|
||||
it('should throw if totalSpeed is missing', function() {
|
||||
flashState.setFlashingFlag();
|
||||
expect(function() {
|
||||
// @ts-ignore
|
||||
flashState.setProgressState({
|
||||
flashing: 2,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
type: 'flashing',
|
||||
percentage: 50,
|
||||
eta: 15,
|
||||
speed: 1,
|
||||
averageSpeed: 1,
|
||||
bytes: 0,
|
||||
position: 0,
|
||||
active: 0,
|
||||
});
|
||||
}).to.throw('Missing flash fields: totalSpeed');
|
||||
});
|
||||
|
||||
it('should not throw if totalSpeed is 0', function() {
|
||||
flashState.setFlashingFlag();
|
||||
expect(function() {
|
||||
flashState.setProgressState({
|
||||
flashing: 2,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
type: 'flashing',
|
||||
percentage: 50,
|
||||
eta: 15,
|
||||
speed: 0,
|
||||
averageSpeed: 0,
|
||||
totalSpeed: 0,
|
||||
bytes: 0,
|
||||
position: 0,
|
||||
active: 0,
|
||||
});
|
||||
}).to.not.throw('Missing flash fields: totalSpeed');
|
||||
});
|
||||
|
||||
it('should floor the percentage number', function() {
|
||||
flashState.setFlashingFlag();
|
||||
flashState.setProgressState({
|
||||
flashing: 2,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
type: 'flashing',
|
||||
percentage: 50.253559459485,
|
||||
eta: 15,
|
||||
speed: 0,
|
||||
averageSpeed: 0,
|
||||
totalSpeed: 1,
|
||||
bytes: 0,
|
||||
position: 0,
|
||||
active: 0,
|
||||
@ -344,7 +259,6 @@ describe('Model: flashState', function() {
|
||||
eta: 0,
|
||||
speed: 0,
|
||||
averageSpeed: 0,
|
||||
totalSpeed: 0,
|
||||
bytes: 0,
|
||||
position: 0,
|
||||
active: 0,
|
||||
@ -357,15 +271,11 @@ describe('Model: flashState', function() {
|
||||
expect(() => {
|
||||
flashState.setFlashingFlag();
|
||||
flashState.setProgressState({
|
||||
flashing: 0,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
percentage: 0,
|
||||
eta: 0,
|
||||
speed: 0,
|
||||
averageSpeed: 0,
|
||||
totalSpeed: 0,
|
||||
bytes: 0,
|
||||
position: 0,
|
||||
active: 0,
|
||||
@ -395,28 +305,21 @@ describe('Model: flashState', function() {
|
||||
flashState.resetState();
|
||||
const currentFlashState = flashState.getFlashState();
|
||||
expect(currentFlashState).to.deep.equal({
|
||||
flashing: 0,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
active: 0,
|
||||
failed: 0,
|
||||
percentage: 0,
|
||||
speed: null,
|
||||
averageSpeed: null,
|
||||
totalSpeed: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the current flash state', function() {
|
||||
const state = {
|
||||
flashing: 1,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
percentage: 50,
|
||||
eta: 15,
|
||||
speed: 0,
|
||||
averageSpeed: 0,
|
||||
totalSpeed: 0,
|
||||
bytes: 0,
|
||||
position: 0,
|
||||
active: 0,
|
||||
@ -427,15 +330,11 @@ describe('Model: flashState', function() {
|
||||
flashState.setProgressState(state);
|
||||
const currentFlashState = flashState.getFlashState();
|
||||
expect(currentFlashState).to.deep.equal({
|
||||
flashing: 1,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
percentage: 50,
|
||||
eta: 15,
|
||||
speed: 0,
|
||||
averageSpeed: 0,
|
||||
totalSpeed: 0,
|
||||
bytes: 0,
|
||||
position: 0,
|
||||
active: 0,
|
||||
@ -532,30 +431,22 @@ describe('Model: flashState', function() {
|
||||
flashState.setFlashingFlag();
|
||||
|
||||
flashState.setProgressState({
|
||||
flashing: 2,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
type: 'flashing',
|
||||
percentage: 50,
|
||||
eta: 15,
|
||||
speed: 100000000000,
|
||||
averageSpeed: 100000000000,
|
||||
totalSpeed: 200000000000,
|
||||
bytes: 0,
|
||||
position: 0,
|
||||
active: 0,
|
||||
active: 2,
|
||||
});
|
||||
|
||||
expect(flashState.getFlashState()).to.not.deep.equal({
|
||||
flashing: 2,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
percentage: 0,
|
||||
speed: 0,
|
||||
averageSpeed: 0,
|
||||
totalSpeed: 0,
|
||||
});
|
||||
|
||||
flashState.unsetFlashingFlag({
|
||||
@ -564,14 +455,11 @@ describe('Model: flashState', function() {
|
||||
});
|
||||
|
||||
expect(flashState.getFlashState()).to.deep.equal({
|
||||
flashing: 0,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
active: 0,
|
||||
failed: 0,
|
||||
percentage: 0,
|
||||
speed: null,
|
||||
averageSpeed: null,
|
||||
totalSpeed: null,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -23,9 +23,8 @@ describe('Browser: progressStatus', function() {
|
||||
describe('.fromFlashState()', function() {
|
||||
beforeEach(function() {
|
||||
this.state = {
|
||||
flashing: 1,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
active: 1,
|
||||
type: 'flashing',
|
||||
failed: 0,
|
||||
percentage: 0,
|
||||
eta: 15,
|
||||
@ -42,31 +41,29 @@ describe('Browser: progressStatus', function() {
|
||||
|
||||
it('should handle percentage == 0, flashing, unmountOnSuccess', function() {
|
||||
this.state.speed = 0;
|
||||
expect(progressStatus.fromFlashState(this.state)).to.equal('Starting...');
|
||||
expect(progressStatus.fromFlashState(this.state)).to.equal('0% Flashing');
|
||||
});
|
||||
|
||||
it('should handle percentage == 0, flashing, !unmountOnSuccess', function() {
|
||||
this.state.speed = 0;
|
||||
settings.set('unmountOnSuccess', false);
|
||||
expect(progressStatus.fromFlashState(this.state)).to.equal('Starting...');
|
||||
expect(progressStatus.fromFlashState(this.state)).to.equal('0% Flashing');
|
||||
});
|
||||
|
||||
it('should handle percentage == 0, verifying, unmountOnSuccess', function() {
|
||||
this.state.speed = 0;
|
||||
this.state.flashing = 0;
|
||||
this.state.verifying = 1;
|
||||
this.state.type = 'verifying';
|
||||
expect(progressStatus.fromFlashState(this.state)).to.equal(
|
||||
'Validating...',
|
||||
'0% Validating',
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle percentage == 0, verifying, !unmountOnSuccess', function() {
|
||||
this.state.speed = 0;
|
||||
this.state.flashing = 0;
|
||||
this.state.verifying = 1;
|
||||
this.state.type = 'verifying';
|
||||
settings.set('unmountOnSuccess', false);
|
||||
expect(progressStatus.fromFlashState(this.state)).to.equal(
|
||||
'Validating...',
|
||||
'0% Validating',
|
||||
);
|
||||
});
|
||||
|
||||
@ -86,18 +83,16 @@ describe('Browser: progressStatus', function() {
|
||||
});
|
||||
|
||||
it('should handle percentage == 50, verifying, unmountOnSuccess', function() {
|
||||
this.state.flashing = 0;
|
||||
this.state.verifying = 1;
|
||||
this.state.percentage = 50;
|
||||
this.state.type = 'verifying';
|
||||
expect(progressStatus.fromFlashState(this.state)).to.equal(
|
||||
'50% Validating',
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle percentage == 50, verifying, !unmountOnSuccess', function() {
|
||||
this.state.flashing = 0;
|
||||
this.state.verifying = 1;
|
||||
this.state.percentage = 50;
|
||||
this.state.type = 'verifying';
|
||||
settings.set('unmountOnSuccess', false);
|
||||
expect(progressStatus.fromFlashState(this.state)).to.equal(
|
||||
'50% Validating',
|
||||
@ -115,7 +110,7 @@ describe('Browser: progressStatus', function() {
|
||||
this.state.percentage = 100;
|
||||
settings.set('validateWriteOnSuccess', false);
|
||||
expect(progressStatus.fromFlashState(this.state)).to.equal(
|
||||
'Unmounting...',
|
||||
'Finishing...',
|
||||
);
|
||||
});
|
||||
|
||||
@ -129,17 +124,14 @@ describe('Browser: progressStatus', function() {
|
||||
});
|
||||
|
||||
it('should handle percentage == 100, verifying, unmountOnSuccess', function() {
|
||||
this.state.flashing = 0;
|
||||
this.state.verifying = 1;
|
||||
this.state.percentage = 100;
|
||||
this.state.type = 'verifying';
|
||||
expect(progressStatus.fromFlashState(this.state)).to.equal(
|
||||
'Unmounting...',
|
||||
'Finishing...',
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle percentage == 100, validatinf, !unmountOnSuccess', function() {
|
||||
this.state.flashing = 0;
|
||||
this.state.verifying = 1;
|
||||
this.state.percentage = 100;
|
||||
settings.set('unmountOnSuccess', false);
|
||||
expect(progressStatus.fromFlashState(this.state)).to.equal(
|
||||
|
@ -30,9 +30,8 @@ describe('Browser: WindowProgress', function() {
|
||||
windowProgress.currentWindow.setTitle = this.setTitleSpy;
|
||||
|
||||
this.state = {
|
||||
flashing: 1,
|
||||
verifying: 0,
|
||||
successful: 0,
|
||||
active: 1,
|
||||
type: 'flashing',
|
||||
failed: 0,
|
||||
percentage: 85,
|
||||
speed: 100,
|
||||
@ -79,8 +78,7 @@ describe('Browser: WindowProgress', function() {
|
||||
});
|
||||
|
||||
it('should set the verifying title', function() {
|
||||
this.state.flashing = 0;
|
||||
this.state.verifying = 1;
|
||||
this.state.type = 'verifying';
|
||||
windowProgress.set(this.state);
|
||||
assert.calledWith(this.setTitleSpy, ' – 85% Validating');
|
||||
});
|
||||
@ -89,7 +87,7 @@ describe('Browser: WindowProgress', function() {
|
||||
this.state.percentage = 0;
|
||||
this.state.speed = 0;
|
||||
windowProgress.set(this.state);
|
||||
assert.calledWith(this.setTitleSpy, ' – Starting...');
|
||||
assert.calledWith(this.setTitleSpy, ' – 0% Flashing');
|
||||
});
|
||||
|
||||
it('should set the finishing title', function() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user