This commit upgrades TypeScript to the latest version 5.3 and introduces `verbatimModuleSyntax` in line with the official Vue guide recommendatinos (vuejs/docs#2592). By enforcing `import type` for type-only imports, this commit improves code clarity and supports tooling optimization, ensuring imports are only bundled when necessary for runtime. Changes: - Bump TypeScript to 5.3.3 across the project. - Adjust import statements to utilize `import type` where applicable, promoting cleaner and more efficient code.
127 lines
3.7 KiB
TypeScript
127 lines
3.7 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { FileSaverDialog, type SaveAsFunction, type WindowOpenFunction } from '@/infrastructure/Dialog/Browser/FileSaverDialog';
|
|
import { FileType } from '@/presentation/common/Dialog';
|
|
import { expectExists } from '@tests/shared/Assertions/ExpectExists';
|
|
|
|
describe('FileSaverDialog', () => {
|
|
describe('saveFile', () => {
|
|
describe('saving file with correct mime type', () => {
|
|
const testCases: ReadonlyArray<{
|
|
readonly fileType: FileType;
|
|
readonly expectedMimeType: string;
|
|
}> = [
|
|
{ fileType: FileType.BatchFile, expectedMimeType: 'application/bat' },
|
|
{ fileType: FileType.ShellScript, expectedMimeType: 'text/x-shellscript' },
|
|
];
|
|
testCases.forEach(({ fileType, expectedMimeType }) => {
|
|
it(`correct mimeType for ${FileType[fileType]}`, () => {
|
|
// arrange
|
|
let actualMimeType: string | undefined;
|
|
const saveAsSpy: SaveAsFunction = (blob) => {
|
|
actualMimeType = blob.type;
|
|
};
|
|
|
|
// act
|
|
new SaveFileTestSetup()
|
|
.withFileType(fileType)
|
|
.withSaveAs(saveAsSpy)
|
|
.saveFile();
|
|
|
|
// assert
|
|
expect(actualMimeType).to.equal(expectedMimeType);
|
|
});
|
|
});
|
|
});
|
|
it('blob contains correct file contents', async () => {
|
|
// arrange
|
|
const expectedFileContents = 'expected file contents';
|
|
let actualBlob: Blob | undefined;
|
|
const saveAsSpy: SaveAsFunction = (blob) => {
|
|
actualBlob = blob;
|
|
};
|
|
|
|
// act
|
|
new SaveFileTestSetup()
|
|
.withSaveAs(saveAsSpy)
|
|
.withFileContents(expectedFileContents)
|
|
.saveFile();
|
|
|
|
// assert
|
|
expectExists(actualBlob);
|
|
const actualFileContents = await actualBlob.text();
|
|
expect(actualFileContents).to.equal(expectedFileContents);
|
|
});
|
|
it('opens new window on save failure', () => {
|
|
// arrange
|
|
const fileContents = 'test file contents';
|
|
const failingSaveAs: SaveAsFunction = () => {
|
|
throw new Error('injected fail');
|
|
};
|
|
let calledArgs: Parameters<WindowOpenFunction> | undefined;
|
|
const windowOpenSpy: WindowOpenFunction = (...args) => {
|
|
calledArgs = args;
|
|
};
|
|
|
|
// act
|
|
new SaveFileTestSetup()
|
|
.withSaveAs(failingSaveAs)
|
|
.withFileType(FileType.BatchFile)
|
|
.withFileContents(fileContents)
|
|
.withWindowOpen(windowOpenSpy)
|
|
.saveFile();
|
|
|
|
// assert
|
|
expectExists(calledArgs);
|
|
const [url, target, features] = calledArgs;
|
|
const mimeType = 'application/bat';
|
|
expect(url).to.equal(`data:${mimeType},${encodeURIComponent(fileContents)}`);
|
|
expect(target).to.equal('_blank');
|
|
expect(features).to.equal('');
|
|
});
|
|
});
|
|
});
|
|
|
|
class SaveFileTestSetup {
|
|
private saveAs: SaveAsFunction = () => {};
|
|
|
|
private windowOpen: WindowOpenFunction = () => {};
|
|
|
|
private fileContents: string = `${SaveFileTestSetup.name} file contents`;
|
|
|
|
private filename: string = `${SaveFileTestSetup.name} filename`;
|
|
|
|
private fileType: FileType = FileType.BatchFile;
|
|
|
|
public withSaveAs(saveAs: SaveAsFunction): this {
|
|
this.saveAs = saveAs;
|
|
return this;
|
|
}
|
|
|
|
public withFileContents(fileContents: string): this {
|
|
this.fileContents = fileContents;
|
|
return this;
|
|
}
|
|
|
|
public withFileType(fileType: FileType): this {
|
|
this.fileType = fileType;
|
|
return this;
|
|
}
|
|
|
|
public withWindowOpen(windowOpen: WindowOpenFunction): this {
|
|
this.windowOpen = windowOpen;
|
|
return this;
|
|
}
|
|
|
|
public saveFile() {
|
|
const dialog = new FileSaverDialog(
|
|
this.saveAs,
|
|
this.windowOpen,
|
|
);
|
|
return dialog.saveFile(
|
|
this.fileContents,
|
|
this.filename,
|
|
this.fileType,
|
|
);
|
|
}
|
|
}
|