Skip to content

Commit

Permalink
CI: increase test coverage (#1130)
Browse files Browse the repository at this point in the history
  • Loading branch information
emmercm authored May 10, 2024
1 parent 362aaae commit d0a11ac
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 18 deletions.
11 changes: 0 additions & 11 deletions src/types/dats/dat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,17 +107,6 @@ export default abstract class DAT {
return FsPoly.makeLegal(filename.trim());
}

/**
* Is this a {@link LogiqxDAT} that only contains BIOS files.
*/
isBiosDat(): boolean {
return (this.getGames().length > 0 && this.getGames().every((game) => game.isBios()))
// Redump-style DAT names
|| this.getName().match(/(\W|^)BIOS(\W|$)/i) !== null
// libretro-style DAT comments
|| (this.getHeader().getComment() ?? '').match(/(\W|^)BIOS(\W|$)/i) !== null;
}

/**
* Does a DAT explicitly contain headered ROMs. It is possible for a DAT to be both non-headered
* and non-headerless.
Expand Down
22 changes: 22 additions & 0 deletions test/driveSemaphore.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import DriveSemaphore from '../src/driveSemaphore.js';

describe('map', () => {
it('should handle thrown errors', async () => {
await expect(
new DriveSemaphore().map(
['file'],
() => { throw new Error('error'); },
),
).rejects.toThrow('error');
});

it('should handle thrown literals', async () => {
await expect(
new DriveSemaphore().map(
['file'],
// eslint-disable-next-line @typescript-eslint/no-throw-literal
() => { throw 'message'; },
),
).rejects.toThrow('message');
});
});
14 changes: 14 additions & 0 deletions test/modules/argumentsParser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,13 @@ describe('options', () => {
expect(argumentsParser.parse([...dummyCommandAndRequiredArgs, '--filter-language', 'EN,it']).getFilterLanguage()).toEqual(new Set(['EN', 'IT']));
expect(argumentsParser.parse([...dummyCommandAndRequiredArgs, '--filter-language', 'en,IT,JA']).getFilterLanguage()).toEqual(new Set(['EN', 'IT', 'JA']));
expect(argumentsParser.parse([...dummyCommandAndRequiredArgs, '--filter-language', 'EN,en']).getFilterLanguage()).toEqual(new Set(['EN']));

expect(() => argumentsParser.parse([...dummyCommandAndRequiredArgs, '--language-filter'])).toThrow(/not enough arguments/i);
expect(argumentsParser.parse([...dummyCommandAndRequiredArgs, '-L', 'EN']).getFilterLanguage()).toEqual(new Set(['EN']));
expect(argumentsParser.parse([...dummyCommandAndRequiredArgs, '--language-filter', 'EN']).getFilterLanguage()).toEqual(new Set(['EN']));
expect(argumentsParser.parse([...dummyCommandAndRequiredArgs, '--language-filter', 'EN,it']).getFilterLanguage()).toEqual(new Set(['EN', 'IT']));
expect(argumentsParser.parse([...dummyCommandAndRequiredArgs, '--language-filter', 'en,IT,JA']).getFilterLanguage()).toEqual(new Set(['EN', 'IT', 'JA']));
expect(argumentsParser.parse([...dummyCommandAndRequiredArgs, '--language-filter', 'EN,en']).getFilterLanguage()).toEqual(new Set(['EN']));
});

it('should parse "filter-region"', () => {
Expand All @@ -852,6 +859,13 @@ describe('options', () => {
expect(argumentsParser.parse([...dummyCommandAndRequiredArgs, '--filter-region', 'USA,eur']).getFilterRegion()).toEqual(new Set(['USA', 'EUR']));
expect(argumentsParser.parse([...dummyCommandAndRequiredArgs, '--filter-region', 'usa,EUR,JPN']).getFilterRegion()).toEqual(new Set(['USA', 'EUR', 'JPN']));
expect(argumentsParser.parse([...dummyCommandAndRequiredArgs, '--filter-region', 'USA,usa']).getFilterRegion()).toEqual(new Set(['USA']));

expect(() => argumentsParser.parse([...dummyCommandAndRequiredArgs, '--region-filter'])).toThrow(/not enough arguments/i);
expect(argumentsParser.parse([...dummyCommandAndRequiredArgs, '-R', 'USA']).getFilterRegion()).toEqual(new Set(['USA']));
expect(argumentsParser.parse([...dummyCommandAndRequiredArgs, '--region-filter', 'USA']).getFilterRegion()).toEqual(new Set(['USA']));
expect(argumentsParser.parse([...dummyCommandAndRequiredArgs, '--region-filter', 'USA,eur']).getFilterRegion()).toEqual(new Set(['USA', 'EUR']));
expect(argumentsParser.parse([...dummyCommandAndRequiredArgs, '--region-filter', 'usa,EUR,JPN']).getFilterRegion()).toEqual(new Set(['USA', 'EUR', 'JPN']));
expect(argumentsParser.parse([...dummyCommandAndRequiredArgs, '--region-filter', 'USA,usa']).getFilterRegion()).toEqual(new Set(['USA']));
});

it('should parse "no-bios"', () => {
Expand Down
15 changes: 15 additions & 0 deletions test/modules/datMergerSplitter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2292,3 +2292,18 @@ describe('FinalBurn Neo Neo Geo e544671', () => {
]);
});
});

test.each([
[MergeMode.NONMERGED],
[MergeMode.SPLIT],
[MergeMode.MERGED],
])('should handle invalid romOf attributes: %s', () => {
// TODO(cemmer)
});

test.each([
[MergeMode.SPLIT],
[MergeMode.MERGED],
])('should handle invalid cloneOf attributes: %s', () => {
// TODO(cemmer)
});
26 changes: 20 additions & 6 deletions test/modules/directoryCleaner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Constants from '../../src/constants.js';
import DirectoryCleaner from '../../src/modules/directoryCleaner.js';
import fsPoly from '../../src/polyfill/fsPoly.js';
import File from '../../src/types/files/file.js';
import Options from '../../src/types/options.js';
import Options, { OptionsProps } from '../../src/types/options.js';
import ProgressBarFake from '../console/progressBarFake.js';

const ROM_FIXTURES_DIR = path.join('test', 'fixtures', 'roms');
Expand All @@ -16,6 +16,7 @@ const ROM_FIXTURES_DIR = path.join('test', 'fixtures', 'roms');
* so it's fine if we implement some workarounds here.
*/
async function runOutputCleaner(
optionsProps: OptionsProps,
cleanExclude: string[],
writtenFilePathsToExclude: string[],
): Promise<string[]> {
Expand All @@ -31,6 +32,7 @@ async function runOutputCleaner(

await new DirectoryCleaner(
new Options({
...optionsProps,
commands: ['move', 'clean'],
cleanExclude: cleanExclude.map((filePath) => path.join(tempDir, filePath)),
}),
Expand All @@ -50,20 +52,20 @@ it('should delete nothing if nothing written', async () => {
const existingFiles = (await fsPoly.walk(ROM_FIXTURES_DIR))
.map((filePath) => filePath.replace(/^test[\\/]fixtures[\\/]roms[\\/]/, ''))
.sort();
const filesRemaining = await runOutputCleaner([], []);
const filesRemaining = await runOutputCleaner({}, [], []);
expect(filesRemaining).toEqual(existingFiles);
});

it('should delete nothing if no excess files', async () => {
const existingFiles = (await fsPoly.walk(ROM_FIXTURES_DIR))
.map((filePath) => filePath.replace(/^test[\\/]fixtures[\\/]roms[\\/]/, ''))
.sort();
const filesRemaining = await runOutputCleaner([], existingFiles);
const filesRemaining = await runOutputCleaner({}, [], existingFiles);
expect(filesRemaining).toEqual(existingFiles);
});

it('should delete some if all unmatched and some excluded', async () => {
const filesRemaining = await runOutputCleaner([
const filesRemaining = await runOutputCleaner({}, [
path.join('**', 'foobar.*'),
], [
'non-existent file',
Expand All @@ -79,7 +81,7 @@ it('should delete some if all unmatched and some excluded', async () => {
});

it('should delete some if some matched and nothing excluded', async () => {
const filesRemaining = await runOutputCleaner([], [
const filesRemaining = await runOutputCleaner({}, [], [
path.join('7z', 'empty.7z'),
path.join('raw', 'fizzbuzz.nes'),
path.join('zip', 'foobar.zip'),
Expand All @@ -93,11 +95,23 @@ it('should delete some if some matched and nothing excluded', async () => {
});

it('should delete everything if all unmatched and nothing excluded', async () => {
await expect(runOutputCleaner([], [
await expect(runOutputCleaner({}, [], [
'non-existent file',
])).resolves.toHaveLength(0);
});

it('should delete nothing if all unmatched but doing a dry run', async () => {
const existingFiles = (await fsPoly.walk(ROM_FIXTURES_DIR))
.map((filePath) => filePath.replace(/^test[\\/]fixtures[\\/]roms[\\/]/, ''))
.sort();
const filesRemaining = await runOutputCleaner({
cleanDryRun: true,
}, [], [
'non-existent file',
]);
expect(filesRemaining).toEqual(existingFiles);
});

it('should delete hard links', async () => {
const tempDir = await fsPoly.mkdtemp(Constants.GLOBAL_TEMP_DIR);
try {
Expand Down
2 changes: 1 addition & 1 deletion test/modules/romScanner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('multiple files', () => {
const scannedRealFiles = (await createRomScanner(['test/fixtures/roms']).scan())
.sort((a, b) => a.getFilePath().localeCompare(b.getFilePath()));

// Given some symlinked files
// Given some hard linked files
const tempDir = await fsPoly.mkdtemp(Constants.GLOBAL_TEMP_DIR);
try {
const filesDir = path.join(tempDir, 'files');
Expand Down
28 changes: 28 additions & 0 deletions test/polyfill/fsPoly.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,31 @@ describe('realpath', () => {
await expect(fsPoly.realpath('.')).resolves.toEqual(process.cwd());
});
});

describe('touch', () => {
it('should mkdir and touch', async () => {
const tempDir = await fsPoly.mkdtemp(Constants.GLOBAL_TEMP_DIR);
await fsPoly.rm(tempDir, { recursive: true });
const tempFile = await fsPoly.mktemp(path.join(tempDir, 'temp'));
try {
await fsPoly.touch(tempFile);
await expect(fsPoly.exists(tempFile)).resolves.toEqual(true);
} finally {
await fsPoly.rm(tempDir, { recursive: true, force: true });
}
});
});

describe('touchSync', () => {
it('should mkdir and touch', async () => {
const tempDir = await fsPoly.mkdtemp(Constants.GLOBAL_TEMP_DIR);
await fsPoly.rm(tempDir, { recursive: true });
const tempFile = await fsPoly.mktemp(path.join(tempDir, 'temp'));
try {
fsPoly.touchSync(tempFile);
await expect(fsPoly.exists(tempFile)).resolves.toEqual(true);
} finally {
await fsPoly.rm(tempDir, { recursive: true, force: true });
}
});
});
28 changes: 28 additions & 0 deletions test/types/cache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,34 @@ describe('set', () => {
});
});

describe('delete', () => {
it('should delete a single key', async () => {
const cache = new Cache<string>();

await cache.set('key', 'value');
await expect(cache.has('key')).resolves.toEqual(true);

await cache.delete('key');
await expect(cache.has('key')).resolves.toEqual(false);
});

it('should delete regex-matched keys', async () => {
const cache = new Cache<string>();

await cache.set('key1', 'value');
await expect(cache.has('key1')).resolves.toEqual(true);
await cache.set('key2', 'value');
await expect(cache.has('key2')).resolves.toEqual(true);
await cache.set('key3', 'value');
await expect(cache.has('key3')).resolves.toEqual(true);

await cache.delete(/key[12]/);
await expect(cache.has('key1')).resolves.toEqual(false);
await expect(cache.has('key2')).resolves.toEqual(false);
await expect(cache.has('key3')).resolves.toEqual(true);
});
});

describe('load', () => {
it('should not throw on nonexistent file', async () => {
const tempFile = await FsPoly.mktemp(path.join(Constants.GLOBAL_TEMP_DIR, 'cache'));
Expand Down
3 changes: 3 additions & 0 deletions test/types/indexedFiles.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import ROM from '../../src/types/dats/rom.js';
import File from '../../src/types/files/file.js';
import ROMHeader from '../../src/types/files/romHeader.js';
import IndexedFiles from '../../src/types/indexedFiles.js';

describe('findFiles', () => {
Expand All @@ -14,6 +15,7 @@ describe('findFiles', () => {
size: 2,
crc32: '22222222',
md5: '22222222222222222222222222222222',
fileHeader: ROMHeader.headerFromFilename('two.lnx'),
}),
File.fileOf({
filePath: 'three',
Expand All @@ -36,6 +38,7 @@ describe('findFiles', () => {
size: 6,
sha1: '6666666666666666666666666666666666666666',
sha256: '6666666666666666666666666666666666666666666666666666666666666666',
fileHeader: ROMHeader.headerFromFilename('six.nes'),
}),
File.fileOf({
filePath: 'seven',
Expand Down

0 comments on commit d0a11ac

Please sign in to comment.