diff --git a/.gitignore b/.gitignore index cb66783b5..cf44158b6 100644 --- a/.gitignore +++ b/.gitignore @@ -124,7 +124,9 @@ site/ *.cd2 *.chd *.col +*.cso *.cue +*.dax *.dvd *.gb *.gba @@ -159,6 +161,7 @@ site/ *.zim *.z64 *.zip +*.zso # ROM pack excess *.bmp diff --git a/docs/alternatives.md b/docs/alternatives.md index 85075bbff..95f22a200 100644 --- a/docs/alternatives.md +++ b/docs/alternatives.md @@ -18,7 +18,8 @@ There are a few different popular ROM managers that have similar features: | DATs: fixdat creation | ✅ [Fixdat docs](dats/fixdats.md) | ✅ | ✅ | ❌ | | DATs: combine multiple | ✅ | ❌ | ✅ | ❌ | | Archives: extraction formats | ✅ many formats ([reading archives docs](input/reading-archives.md)) | ✅ `.zip`, `.7z`, `.rar` | ⚠️ `.zip`, `.7z` | ⚠️ `.zip`, `.7z` | -| Archives: `.chd` support | ⚠️ via chdman (bundled) | ⚠️ via chdman | ✅ v1-5 natively | ⚠️ v1-4 natively | +| Archives: `.chd` support | ⚠️ via `chdman` (bundled) | ⚠️ via `chdman` | ✅ v1-5 natively | ⚠️ v1-4 natively | +| Archives: `.cso` & `.zso` support | ⚠️ via `maxcso` (bundled) | ❌ | ❌ | ❌ | | Archives: `.nkit.iso` support | ⚠️ matching but no extraction [GameCube docs](usage/console/gamecube.md#nkit) | ❌ | ❌ | ❌ | | Archives: creation formats | ❌ `.zip` only by design ([writing archives docs](output/writing-archives.md)) | ✅ `.zip`, `.7z`, `.rar` | ⚠️ `.zip` (TorrentZip), `.7z` | ⚠️ `.zip`, `.7z` | | Archives: automatic extension correction | ✅ | ❌ | ❌ | ❌ | diff --git a/docs/input/reading-archives.md b/docs/input/reading-archives.md index 48e228832..c70a1f84e 100644 --- a/docs/input/reading-archives.md +++ b/docs/input/reading-archives.md @@ -7,18 +7,19 @@ Igir supports scanning the contents of archives for ROMs, DATs, and ROM patches. Igir supports most common archive formats: | Extension | Contains file CRC32s | Igir can extract without a third-party binary | Igir can checksum without temporary files | -|------------------------------------------------------------------|----------------------|-------------------------------------------------|---------------------------------------------| -| `.7z` | ✅ | ❌ `7za` | ❌ | -| `.chd` | ❌ SHA1 | ❌ `chdman` | ❌ | -| `.gz`, `.gzip` | ❌ CRC16 | ❌ `7za` | ❌ | -| `.nkit.iso` ([GameCube docs](../usage/console/gamecube.md#nkit)) | ✅ | ❌ no extraction support | ✅ | -| `.rar` | ✅ | ✅ | ❌ | -| `.tar` | ❌ | ✅ | ✅ ≤64MiB | -| `.tar.gz`, `.tgz` | ❌ | ✅ | ✅ ≤64MiB | -| `.z01` | ✅ | ❌ `7za` | ❌ | -| `.zip` (including zip64) | ✅ | ✅ | ✅ ≤64MiB | -| `.zip.001` | ✅ | ❌ `7za` | ❌ | -| `.zipx` | ✅ | ❌ `7za` | ❌ | +|------------------------------------------------------------------|----------------------|-----------------------------------------------|-------------------------------------------| +| `.7z` | ✅ | ❌ `7za` | ❌ | +| `.chd` | ❌ SHA1 | ❌ `chdman` | ❌ | +| `.cso`, `.zso`, `.dax` | ❌ | ❌ `maxcso` | ⚠️ CRC32 only | +| `.gz`, `.gzip` | ❌ CRC16 | ❌ `7za` | ❌ | +| `.nkit.iso` ([GameCube docs](../usage/console/gamecube.md#nkit)) | ✅ | ❌ no extraction support | ✅ | +| `.rar` | ✅ | ✅ | ❌ | +| `.tar` | ❌ | ✅ | ✅ ≤64MiB | +| `.tar.gz`, `.tgz` | ❌ | ✅ | ✅ ≤64MiB | +| `.z01` | ✅ | ❌ `7za` | ❌ | +| `.zip` (including zip64) | ✅ | ✅ | ✅ ≤64MiB | +| `.zip.001` | ✅ | ❌ `7za` | ❌ | +| `.zipx` | ✅ | ❌ `7za` | ❌ | **You should prefer archive formats that have CRC32 checksum information for each file.** diff --git a/package-lock.json b/package-lock.json index c778d9ee3..af5be1f93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "graceful-fs": "4.2.11", "is-admin": "4.0.0", "junk": "4.0.1", + "maxcso": "0.1130.5", "micromatch": "4.0.7", "moment": "2.30.1", "node-disk-info": "1.3.0", @@ -8972,6 +8973,23 @@ "tmpl": "1.0.5" } }, + "node_modules/maxcso": { + "version": "0.1130.5", + "resolved": "https://registry.npmjs.org/maxcso/-/maxcso-0.1130.5.tgz", + "integrity": "sha512-b1kr06+gGUSAaC8Sf8sxkvnAs4blT3hpV021iGA08zN2yYzM3PX/eaTj5qP2VOalpV1ngqlCdQpSvWzfooeA6Q==", + "dependencies": { + "which": "^4.0.0" + }, + "bin": { + "maxcso": "dist/src/bin.js" + }, + "engines": { + "node": ">=16.6.0" + }, + "funding": { + "url": "https://github.com/sponsors/emmercm" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", diff --git a/package.json b/package.json index d7f5e6a8c..83a8e07c6 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,7 @@ "graceful-fs": "4.2.11", "is-admin": "4.0.0", "junk": "4.0.1", + "maxcso": "0.1130.5", "micromatch": "4.0.7", "moment": "2.30.1", "node-disk-info": "1.3.0", diff --git a/package.ts b/package.ts index eb9cd9bae..68ed4c15c 100644 --- a/package.ts +++ b/package.ts @@ -89,6 +89,9 @@ const fileFilter = (filters: FileFilter[]): string[] => { // Only include the exact chdman bin we need { exclude: 'node_modules/{**/,}chdman/bin/*/*/chdman*' }, { include: `node_modules/{**/,}chdman/bin/${process.platform}/${process.arch}/chdman*` }, + // Only include the exact maxcso bin we need + { exclude: 'node_modules/{**/,}maxcso/bin/*/*/maxcso*' }, + { include: `node_modules/{**/,}maxcso/bin/${process.platform}/${process.arch}/maxcso*` }, ])); const includeSize = (await Promise.all([...include].map(async (file) => { if (await FsPoly.isDirectory(file)) { diff --git a/src/modules/candidateGenerator.ts b/src/modules/candidateGenerator.ts index f20f77804..3f3d046d9 100644 --- a/src/modules/candidateGenerator.ts +++ b/src/modules/candidateGenerator.ts @@ -318,16 +318,15 @@ export default class CandidateGenerator extends Module { // Filter to the Archives that contain every ROM in this Game const archivesWithEveryRom = [...inputArchivesToRoms.entries()] .filter(([archive, roms]) => { - if (roms.map((rom) => rom.hashCode()).join(',') === game.getRoms().map((rom) => rom.hashCode()).join(',')) { + if (roms.map((rom) => rom.hashCode()).join(',') === gameRoms.map((rom) => rom.hashCode()).join(',')) { return true; } // If there is a CHD with every .bin file, and we're raw-copying it, then assume its .cue // file is accurate return archive instanceof Chd - && !game.getRoms().some((rom) => this.options.shouldZipRom(rom)) - && !game.getRoms().some((rom) => this.options.shouldExtractRom(rom)) - && CandidateGenerator.onlyCueFilesMissingFromChd(game, roms) - && this.options.getAllowExcessSets(); + && !gameRoms.some((rom) => this.options.shouldZipRom(rom)) + && !gameRoms.some((rom) => this.options.shouldExtractRom(rom)) + && CandidateGenerator.onlyCueFilesMissingFromChd(game, roms); }) .map(([archive]) => archive); @@ -358,7 +357,7 @@ export default class CandidateGenerator extends Module { if ( // The Game has zero or one ROM, therefore, we don't really care where the file comes from, // and we should respect any previous sorting of the input files - game.getRoms().length <= 1 + gameRoms.length <= 1 // No input archive contains every ROM from this Game || archiveWithEveryRom === undefined // We're extracting files, therefore, we don't really care where the file comes from, and we @@ -374,10 +373,19 @@ export default class CandidateGenerator extends Module { // For each of this Game's ROMs, find the matching ArchiveEntry from this Archive return new Map(romsAndInputFiles.map(([rom, inputFiles]) => { this.progressBar.logTrace(`${dat.getNameShort()}: ${game.getName()}: preferring input archive that contains every ROM: ${archiveWithEveryRom.getFilePath()}`); - const archiveEntry = inputFiles.find(( - inputFile, - ) => inputFile.getFilePath() === archiveWithEveryRom.getFilePath()) as File; - return [rom, archiveEntry]; + let archiveEntry = inputFiles + .find((inputFile) => inputFile.getFilePath() === archiveWithEveryRom.getFilePath()); + + if (!archiveEntry + && rom.getName().toLowerCase().endsWith('.cue') + && archiveWithEveryRom instanceof Chd + ) { + // We assumed this CHD was fine above, find its .cue file + archiveEntry = (filesByPath.get(archiveWithEveryRom.getFilePath()) ?? []) + .find((file) => file.getExtractedFilePath().toLowerCase().endsWith('.cue')); + } + + return [rom, archiveEntry as File]; })); } diff --git a/src/modules/romIndexer.ts b/src/modules/romIndexer.ts index 5cd42e482..b3cd54f84 100644 --- a/src/modules/romIndexer.ts +++ b/src/modules/romIndexer.ts @@ -3,6 +3,8 @@ import path from 'node:path'; import ProgressBar, { ProgressBarSymbol } from '../console/progressBar.js'; import FsPoly from '../polyfill/fsPoly.js'; import ArchiveEntry from '../types/files/archives/archiveEntry.js'; +import Chd from '../types/files/archives/chd/chd.js'; +import Maxcso from '../types/files/archives/maxcso/maxcso.js'; import Rar from '../types/files/archives/rar.js'; import SevenZip from '../types/files/archives/sevenZip/sevenZip.js'; import Tar from '../types/files/archives/tar.js'; @@ -97,6 +99,10 @@ export default class ROMIndexer extends Module { return 3; } if (file.getArchive() instanceof SevenZip) { return 4; + } if (file.getArchive() instanceof Maxcso) { + return 5; + } if (file.getArchive() instanceof Chd) { + return 6; } return 99; } diff --git a/src/polyfill/fsPoly.ts b/src/polyfill/fsPoly.ts index d88f32db8..f986f60c9 100644 --- a/src/polyfill/fsPoly.ts +++ b/src/polyfill/fsPoly.ts @@ -253,11 +253,11 @@ export default class FsPoly { } // Backoff with jitter - if (attempt >= 3) { + if (attempt >= 5) { throw error; } await new Promise((resolve) => { - setTimeout(resolve, Math.random() * (2 ** (attempt - 1) * 100)); + setTimeout(resolve, Math.random() * (2 ** (attempt - 1) * 10)); }); // Attempt to resolve Windows' "EBUSY: resource busy or locked" diff --git a/src/types/files/archives/chd/chdGdiParser.ts b/src/types/files/archives/chd/chdGdiParser.ts index e142c78cb..451d9218c 100644 --- a/src/types/files/archives/chd/chdGdiParser.ts +++ b/src/types/files/archives/chd/chdGdiParser.ts @@ -23,7 +23,7 @@ export default class ChdGdiParser { checksumBitmask: number, ): Promise[]> { const tempDir = await FsPoly.mkdtemp(path.join(Temp.getTempDir(), 'chd-gdi')); - const gdiFilePath = path.join(tempDir, 'track.gdi'); + const gdiFilePath = path.join(tempDir, `${path.parse(archive.getFilePath()).name}.gdi`); let binRawFilePaths: string[] = []; try { diff --git a/src/types/files/archives/maxcso/cso.ts b/src/types/files/archives/maxcso/cso.ts new file mode 100644 index 000000000..8e649c7fc --- /dev/null +++ b/src/types/files/archives/maxcso/cso.ts @@ -0,0 +1,18 @@ +import Archive from '../archive.js'; +import Maxcso from './maxcso.js'; + +export default class Cso extends Maxcso { + // eslint-disable-next-line class-methods-use-this + protected new(filePath: string): Archive { + return new Cso(filePath); + } + + static getExtensions(): string[] { + return ['.cso']; + } + + // eslint-disable-next-line class-methods-use-this + getExtension(): string { + return Cso.getExtensions()[0]; + } +} diff --git a/src/types/files/archives/maxcso/dax.ts b/src/types/files/archives/maxcso/dax.ts new file mode 100644 index 000000000..73107cffc --- /dev/null +++ b/src/types/files/archives/maxcso/dax.ts @@ -0,0 +1,18 @@ +import Archive from '../archive.js'; +import Maxcso from './maxcso.js'; + +export default class Dax extends Maxcso { + // eslint-disable-next-line class-methods-use-this + protected new(filePath: string): Archive { + return new Dax(filePath); + } + + static getExtensions(): string[] { + return ['.dax']; + } + + // eslint-disable-next-line class-methods-use-this + getExtension(): string { + return Dax.getExtensions()[0]; + } +} diff --git a/src/types/files/archives/maxcso/maxcso.ts b/src/types/files/archives/maxcso/maxcso.ts new file mode 100644 index 000000000..34f1071ab --- /dev/null +++ b/src/types/files/archives/maxcso/maxcso.ts @@ -0,0 +1,28 @@ +import path from 'node:path'; + +import maxcso from 'maxcso'; + +import Archive from '../archive.js'; +import ArchiveEntry from '../archiveEntry.js'; + +export default abstract class Maxcso extends Archive { + async getArchiveEntries(checksumBitmask: number): Promise[]> { + const entryPath = `${path.parse(this.getFilePath()).name}.iso`; + const size = (await maxcso.header(this.getFilePath())).uncompressedSize; + const crc32 = await maxcso.uncompressedCrc32(this.getFilePath()); + + return [await ArchiveEntry.entryOf({ + archive: this, + entryPath, + size: Number(size), + crc32, + }, checksumBitmask)]; + } + + async extractEntryToFile(entryPath: string, extractedFilePath: string): Promise { + return maxcso.decompress({ + inputFilename: this.getFilePath(), + outputFilename: extractedFilePath, + }); + } +} diff --git a/src/types/files/archives/maxcso/zso.ts b/src/types/files/archives/maxcso/zso.ts new file mode 100644 index 000000000..3dd463737 --- /dev/null +++ b/src/types/files/archives/maxcso/zso.ts @@ -0,0 +1,18 @@ +import Archive from '../archive.js'; +import Maxcso from './maxcso.js'; + +export default class Zso extends Maxcso { + // eslint-disable-next-line class-methods-use-this + protected new(filePath: string): Archive { + return new Zso(filePath); + } + + static getExtensions(): string[] { + return ['.zso']; + } + + // eslint-disable-next-line class-methods-use-this + getExtension(): string { + return Zso.getExtensions()[0]; + } +} diff --git a/src/types/files/archives/sevenZip/sevenZip.ts b/src/types/files/archives/sevenZip/sevenZip.ts index 28c5d5b60..0b003d3c3 100644 --- a/src/types/files/archives/sevenZip/sevenZip.ts +++ b/src/types/files/archives/sevenZip/sevenZip.ts @@ -31,17 +31,23 @@ export default class SevenZip extends Archive { async getArchiveEntries(checksumBitmask: number): Promise[]> { /** * WARN(cemmer): even with the above mutex, {@link _7z.list} will still sometimes return no - * entries. Most archives contain at least one file, so assume this is wrong and attempt - * again up to 3 times total. + * entries. This seems to happen more on older Node.js versions (v16, v18) and specific OSes + * (Linux). Most archives contain at least one file, so assume this is wrong and attempt again + * up to 5 times total. */ - for (let attempt = 1; attempt <= 3; attempt += 1) { + const maxAttempts = 5; + for (let attempt = 1; attempt <= maxAttempts; attempt += 1) { const archiveEntries = await this.getArchiveEntriesNotCached(checksumBitmask); if (archiveEntries.length > 0) { return archiveEntries; } + // Backoff with jitter + if (attempt >= maxAttempts) { + break; + } await new Promise((resolve) => { - setTimeout(resolve, Math.random() * (2 ** (attempt - 1) * 100)); + setTimeout(resolve, Math.random() * (2 ** (attempt - 1) * 10)); }); } diff --git a/src/types/files/fileCache.ts b/src/types/files/fileCache.ts index b0021d764..35a154c8e 100644 --- a/src/types/files/fileCache.ts +++ b/src/types/files/fileCache.ts @@ -202,6 +202,12 @@ export default class FileCache { } static async getOrComputeFileHeader(file: File): Promise { + if (!this.enabled) { + return file.createReadStream( + async (stream) => ROMHeader.headerFromFileStream(stream), + ); + } + // NOTE(cemmer): we're explicitly not catching ENOENT errors here, we want it to bubble up const stats = await FsPoly.stat(file.getFilePath()); const cacheKey = this.getCacheKey(file.toString(), ValueType.ROM_HEADER); @@ -236,6 +242,12 @@ export default class FileCache { } static async getOrComputeFileSignature(file: File): Promise { + if (!this.enabled) { + return file.createReadStream( + async (stream) => FileSignature.signatureFromFileStream(stream), + ); + } + // NOTE(cemmer): we're explicitly not catching ENOENT errors here, we want it to bubble up const stats = await FsPoly.stat(file.getFilePath()); const cacheKey = this.getCacheKey(file.toString(), ValueType.FILE_SIGNATURE); diff --git a/src/types/files/fileFactory.ts b/src/types/files/fileFactory.ts index 2cbef6e57..b1ce2773d 100644 --- a/src/types/files/fileFactory.ts +++ b/src/types/files/fileFactory.ts @@ -3,6 +3,9 @@ import Archive from './archives/archive.js'; import ArchiveEntry from './archives/archiveEntry.js'; import ArchiveFile from './archives/archiveFile.js'; import Chd from './archives/chd/chd.js'; +import Cso from './archives/maxcso/cso.js'; +import Dax from './archives/maxcso/dax.js'; +import Zso from './archives/maxcso/zso.js'; import NkitIso from './archives/nkitIso.js'; import Rar from './archives/rar.js'; import Gzip from './archives/sevenZip/gzip.js'; @@ -94,6 +97,12 @@ export default class FileFactory { archive = new ZipX(filePath); } else if (Chd.getExtensions().some((ext) => fileExt.toLowerCase().endsWith(ext))) { archive = new Chd(filePath); + } else if (Cso.getExtensions().some((ext) => fileExt.toLowerCase().endsWith(ext))) { + archive = new Cso(filePath); + } else if (Dax.getExtensions().some((ext) => fileExt.toLowerCase().endsWith(ext))) { + archive = new Dax(filePath); + } else if (Zso.getExtensions().some((ext) => fileExt.toLowerCase().endsWith(ext))) { + archive = new Zso(filePath); } else if (NkitIso.getExtensions().some((ext) => fileExt.toLowerCase().endsWith(ext))) { archive = new NkitIso(filePath); } else { @@ -145,6 +154,9 @@ export default class FileFactory { ...ZipSpanned.getExtensions(), ...ZipX.getExtensions(), // Compressed images + ...Cso.getExtensions(), + ...Dax.getExtensions(), + ...Zso.getExtensions(), ...Chd.getExtensions(), ...NkitIso.getExtensions(), ].some((ext) => filePath.toLowerCase().endsWith(ext)); diff --git a/src/types/files/fileSignature.ts b/src/types/files/fileSignature.ts index abe3787d6..2ca6ae54b 100644 --- a/src/types/files/fileSignature.ts +++ b/src/types/files/fileSignature.ts @@ -86,6 +86,8 @@ export default class FileSignature { // @see https://docs.fileformat.com/disc-and-media/cso/ cso: new FileSignature('.cso', [{ value: Buffer.from('CISO') }]), + dax: new FileSignature('.dax', [{ value: Buffer.from('DAX') }]), + // @see https://en.wikipedia.org/wiki/List_of_file_signatures isz: new FileSignature('.isz', [{ value: Buffer.from('IsZ!') }]), diff --git a/src/types/indexedFiles.ts b/src/types/indexedFiles.ts index 10d0c7792..4b3322506 100644 --- a/src/types/indexedFiles.ts +++ b/src/types/indexedFiles.ts @@ -153,22 +153,22 @@ export default class IndexedFiles { * Find file(s) in the index based some search criteria. */ findFiles(file: File | ROM): File[] | undefined { - const { sha256 } = file; + const sha256 = file.sha256?.replace(/[^0-9a-f]/ig, ''); if (sha256 && this.sha256.has(sha256)) { return this.sha256.get(sha256); } - const { sha1 } = file; + const sha1 = file.sha1?.replace(/[^0-9a-f]/ig, ''); if (sha1 && this.sha1.has(sha1)) { return this.sha1.get(sha1); } - const { md5 } = file; + const md5 = file.md5?.replace(/[^0-9a-f]/ig, ''); if (md5 && this.md5.has(md5)) { return this.md5.get(md5); } - const { crc32 } = file; + const crc32 = file.crc32?.replace(/[^0-9a-f]/ig, ''); if (crc32) { const crc32WithSize = `${crc32}|${file.getSize()}`; if (this.crc32.has(crc32WithSize)) { diff --git a/test/endToEndTest.sh b/test/endToEndTest.sh index 5727ab66e..94bf4ee84 100755 --- a/test/endToEndTest.sh +++ b/test/endToEndTest.sh @@ -1,9 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -here="${PWD}" # shellcheck disable=SC2064 -trap "cd \"${here}\"" EXIT +trap "cd \"${PWD}\"" EXIT # @param {string} $1 Directory to start from # @param {string} $2 Filename @@ -24,14 +23,17 @@ parent_find() { cd "$(parent_find . "package.json")" test_igir() { + echo "--------------------------------------------------" temp="$(mktemp -d)" ./dist/index.js "$@" \ --dat test/fixtures/dats/* \ --input test/fixtures/roms/* \ + --input-exclude test/fixtures/roms/discs/* \ --output "${temp}" - ls "${temp}"/* &> /dev/null + ls -al "${temp}"/* rm -rf "${temp}" } test_igir copy test +test_igir copy extract test test_igir copy zip test diff --git a/test/fixtures/dats/one.dat b/test/fixtures/dats/one.dat index 1d3e67d66..7f25415ef 100644 --- a/test/fixtures/dats/one.dat +++ b/test/fixtures/dats/one.dat @@ -64,6 +64,10 @@ + + UMD + + GameCube NKit ISO diff --git a/test/fixtures/roms/cso/UMD.cso b/test/fixtures/roms/cso/UMD.cso new file mode 100644 index 000000000..0f734ace3 Binary files /dev/null and b/test/fixtures/roms/cso/UMD.cso differ diff --git a/test/fixtures/roms/cso/UMD.zso b/test/fixtures/roms/cso/UMD.zso new file mode 100644 index 000000000..b1c07832b Binary files /dev/null and b/test/fixtures/roms/cso/UMD.zso differ diff --git a/test/fixtures/roms/discs/UMD.iso b/test/fixtures/roms/discs/UMD.iso new file mode 100644 index 000000000..93333c28b Binary files /dev/null and b/test/fixtures/roms/discs/UMD.iso differ diff --git a/test/igir.test.ts b/test/igir.test.ts index b8f6ad209..15054418e 100644 --- a/test/igir.test.ts +++ b/test/igir.test.ts @@ -149,6 +149,7 @@ describe('with explicit DATs', () => { commands: ['copy', 'test'], dat: [path.join(inputTemp, 'dats', '*')], input: [path.join(inputTemp, 'roms')], + inputExclude: [path.join(inputTemp, 'roms', 'discs')], // test archive scanning + matching output: outputTemp, dirDatName: true, dirGameSubdir: GameSubdirMode[GameSubdirMode.MULTIPLE].toLowerCase(), @@ -165,14 +166,14 @@ describe('with explicit DATs', () => { [path.join('Headerless', 'allpads.nes'), '6339abe6'], [path.join('Headerless', 'color_test.nes'), 'c9c1b7aa'], [`${path.join('Headerless', 'speed_test_v51.sfc.gz')}|speed_test_v51.sfc`, '8beffd94'], - [path.join('One', 'CD-ROM', 'CD-ROM (Track 1).bin'), '49ca35fb'], - [path.join('One', 'CD-ROM', 'CD-ROM (Track 2).bin'), '0316f720'], - [path.join('One', 'CD-ROM', 'CD-ROM (Track 3).bin'), 'a320af40'], - [path.join('One', 'CD-ROM', 'CD-ROM.cue'), '4ce39e73'], + [`${path.join('One', 'CD-ROM.chd')}|CD-ROM (Track 1).bin`, '49ca35fb'], + [`${path.join('One', 'CD-ROM.chd')}|CD-ROM (Track 2).bin`, '0316f720'], + [`${path.join('One', 'CD-ROM.chd')}|CD-ROM (Track 3).bin`, 'a320af40'], + [`${path.join('One', 'CD-ROM.chd')}|CD-ROM.cue`, 'xxxxxxxx'], [path.join('One', 'Fizzbuzz.nes'), '370517b5'], [path.join('One', 'Foobar.lnx'), 'b22c9747'], [`${path.join('One', 'GameCube NKit ISO.nkit.iso')}|GameCube NKit ISO.iso`, '5bc2ce5b'], - [`${path.join('One', 'GD-ROM.chd')}|track.gdi`, 'f16f621c'], + [`${path.join('One', 'GD-ROM.chd')}|GD-ROM.gdi`, 'f16f621c'], [`${path.join('One', 'GD-ROM.chd')}|track01.bin`, '9796ed9a'], [`${path.join('One', 'GD-ROM.chd')}|track02.raw`, 'abc178d5'], [`${path.join('One', 'GD-ROM.chd')}|track03.bin`, '61a363f1'], @@ -185,6 +186,7 @@ describe('with explicit DATs', () => { [path.join('One', 'Three Four Five', 'Five.rom'), '3e5daf67'], [path.join('One', 'Three Four Five', 'Four.rom'), '1cf3ca74'], [path.join('One', 'Three Four Five', 'Three.rom'), 'ff46c5d8'], + [`${path.join('One', 'UMD.cso')}|UMD.iso`, 'e90f7cf5'], [path.join('Patchable', '0F09A40.rom'), '2f943e86'], [path.join('Patchable', '3708F2C.rom'), '20891c9f'], [path.join('Patchable', '612644F.rom'), 'f7591b29'], @@ -220,14 +222,14 @@ describe('with explicit DATs', () => { }); expect(result.outputFilesAndCrcs).toEqual([ - [path.join('CD-ROM', 'CD-ROM (Track 1).bin'), '49ca35fb'], - [path.join('CD-ROM', 'CD-ROM (Track 2).bin'), '0316f720'], - [path.join('CD-ROM', 'CD-ROM (Track 3).bin'), 'a320af40'], - [path.join('CD-ROM', 'CD-ROM.cue'), '4ce39e73'], + ['CD-ROM.chd|CD-ROM (Track 1).bin', '49ca35fb'], + ['CD-ROM.chd|CD-ROM (Track 2).bin', '0316f720'], + ['CD-ROM.chd|CD-ROM (Track 3).bin', 'a320af40'], + ['CD-ROM.chd|CD-ROM.cue', 'xxxxxxxx'], // Fizzbuzz.nes is explicitly missing! ['Foobar.lnx', 'b22c9747'], ['GameCube NKit ISO.nkit.iso|GameCube NKit ISO.iso', '5bc2ce5b'], - ['GD-ROM.chd|track.gdi', 'f16f621c'], + ['GD-ROM.chd|GD-ROM.gdi', 'f16f621c'], ['GD-ROM.chd|track01.bin', '9796ed9a'], ['GD-ROM.chd|track02.raw', 'abc178d5'], ['GD-ROM.chd|track03.bin', '61a363f1'], @@ -240,6 +242,7 @@ describe('with explicit DATs', () => { [path.join('Three Four Five', 'Five.rom'), '3e5daf67'], [path.join('Three Four Five', 'Four.rom'), '1cf3ca74'], [path.join('Three Four Five', 'Three.rom'), 'ff46c5d8'], + ['UMD.iso', 'e90f7cf5'], ]); expect(result.cwdFilesAndCrcs).toHaveLength(0); expect(result.movedFiles).toHaveLength(0); @@ -254,7 +257,7 @@ describe('with explicit DATs', () => { path.join(outputTemp, 'one.rom'), path.join(outputTemp, 'rom', 'two.rom'), path.join(outputTemp, 'zip', 'three.zip'), - path.join(outputTemp, 'cso', 'four.cso'), + path.join(outputTemp, 'cso', 'four.rvz'), ]; await Promise.all(junkFiles.map(async (junkFile) => { await fsPoly.touch(junkFile); @@ -279,19 +282,20 @@ describe('with explicit DATs', () => { [`${path.join('-', 'One', 'Three Four Five', '2048')}|`, 'xxxxxxxx'], // hard disk [`${path.join('-', 'One', 'Three Four Five', '4096')}|`, 'xxxxxxxx'], // hard disk [`${path.join('7z', 'Headered', 'diagnostic_test_cartridge.a78.7z')}|diagnostic_test_cartridge.a78`, 'f6cc9b1c'], - [path.join('bin', 'One', 'CD-ROM', 'CD-ROM (Track 1).bin'), '49ca35fb'], - [path.join('bin', 'One', 'CD-ROM', 'CD-ROM (Track 2).bin'), '0316f720'], - [path.join('bin', 'One', 'CD-ROM', 'CD-ROM (Track 3).bin'), 'a320af40'], - [`${path.join('chd', 'One', 'GD-ROM.chd')}|track.gdi`, 'f16f621c'], + [`${path.join('chd', 'One', 'CD-ROM.chd')}|CD-ROM (Track 1).bin`, '49ca35fb'], + [`${path.join('chd', 'One', 'CD-ROM.chd')}|CD-ROM (Track 2).bin`, '0316f720'], + [`${path.join('chd', 'One', 'CD-ROM.chd')}|CD-ROM (Track 3).bin`, 'a320af40'], + [`${path.join('chd', 'One', 'CD-ROM.chd')}|CD-ROM.cue`, 'xxxxxxxx'], + [`${path.join('chd', 'One', 'GD-ROM.chd')}|GD-ROM.gdi`, 'f16f621c'], [`${path.join('chd', 'One', 'GD-ROM.chd')}|track01.bin`, '9796ed9a'], [`${path.join('chd', 'One', 'GD-ROM.chd')}|track02.raw`, 'abc178d5'], [`${path.join('chd', 'One', 'GD-ROM.chd')}|track03.bin`, '61a363f1'], [`${path.join('chd', 'One', 'GD-ROM.chd')}|track04.bin`, 'fc5ff5a0'], - [path.join('cso', 'four.cso'), '00000000'], // explicitly not deleted, there were no input files with the extension "cso" - [path.join('cue', 'One', 'CD-ROM', 'CD-ROM.cue'), '4ce39e73'], + [path.join('cso', 'four.rvz'), '00000000'], // explicitly not deleted, there were no input files with the extension "cso" [`${path.join('gz', 'Headerless', 'speed_test_v51.sfc.gz')}|speed_test_v51.sfc`, '8beffd94'], [`${path.join('gz', 'Patchable', 'Best.gz')}|best.rom`, '1e3d78cf'], [`${path.join('iso', 'One', 'GameCube NKit ISO.nkit.iso')}|GameCube NKit ISO.iso`, '5bc2ce5b'], + [path.join('iso', 'One', 'UMD.iso'), 'e90f7cf5'], [path.join('lnx', 'One', 'Foobar.lnx'), 'b22c9747'], [path.join('lnx', 'smdb', 'Hardware Target Game Database', 'Dummy', 'Foobar.lnx'), 'b22c9747'], [path.join('nes', 'Headered', 'allpads.nes'), '9180a163'], @@ -417,6 +421,7 @@ describe('with explicit DATs', () => { dat: [path.join(inputTemp, 'dats', '*')], datExclude: [path.join(inputTemp, 'dats', 'headerless.*')], input: [path.join(inputTemp, 'roms')], + inputExclude: [path.join(inputTemp, 'roms', 'discs')], // test archive scanning + matching output: outputTemp, datCombine: true, dirDatName: true, @@ -434,10 +439,6 @@ describe('with explicit DATs', () => { [path.join('igir combined', 'Before.rom'), '0361b321'], [path.join('igir combined', 'Best.rom'), '1e3d78cf'], [path.join('igir combined', 'C01173E.rom'), 'dfaebe28'], - [path.join('igir combined', 'CD-ROM', 'CD-ROM (Track 1).bin'), '49ca35fb'], - [path.join('igir combined', 'CD-ROM', 'CD-ROM (Track 2).bin'), '0316f720'], - [path.join('igir combined', 'CD-ROM', 'CD-ROM (Track 3).bin'), 'a320af40'], - [path.join('igir combined', 'CD-ROM', 'CD-ROM.cue'), '4ce39e73'], [path.join('igir combined', 'color_test.nes'), 'c9c1b7aa'], [path.join('igir combined', 'diagnostic_test_cartridge.a78'), 'f6cc9b1c'], [path.join('igir combined', 'fds_joypad_test.fds'), '1e58456d'], @@ -465,21 +466,15 @@ describe('with explicit DATs', () => { [path.join('igir combined', 'Three Four Five', 'Five.rom'), '3e5daf67'], [path.join('igir combined', 'Three Four Five', 'Four.rom'), '1cf3ca74'], [path.join('igir combined', 'Three Four Five', 'Three.rom'), 'ff46c5d8'], + [path.join('igir combined', 'UMD.iso'), 'e90f7cf5'], ]); expect(result.cwdFilesAndCrcs).toHaveLength(0); expect(result.movedFiles).toEqual([ path.join('chd', '2048.chd'), path.join('chd', '4096.chd'), - path.join('discs', 'CD-ROM (Track 1).bin'), - path.join('discs', 'CD-ROM (Track 2).bin'), - path.join('discs', 'CD-ROM (Track 3).bin'), - path.join('discs', 'CD-ROM.cue'), - path.join('discs', 'GD-ROM.gdi'), - path.join('discs', 'track01.bin'), - path.join('discs', 'track02.raw'), - path.join('discs', 'track03.bin'), - path.join('discs', 'track04.bin'), - path.join('foobar.lnx'), + path.join('chd', 'GD-ROM.chd'), + path.join('cso', 'UMD.cso'), + 'foobar.lnx', path.join('headered', 'LCDTestROM.lnx.rar'), path.join('headered', 'allpads.nes'), path.join('headered', 'color_test.nintendoentertainmentsystem'), @@ -622,6 +617,7 @@ describe('with explicit DATs', () => { [`${path.join('One', 'Three Four Five.zip')}|Three.rom`, 'ff46c5d8'], [`${path.join('One', 'Three Four Five', '2048')}|`, 'xxxxxxxx'], // hard disk [`${path.join('One', 'Three Four Five', '4096')}|`, 'xxxxxxxx'], // hard disk + [`${path.join('One', 'UMD.zip')}|UMD.iso`, 'e90f7cf5'], [`${path.join('Patchable', '0F09A40.zip')}|0F09A40.rom`, '2f943e86'], [`${path.join('Patchable', '3708F2C.zip')}|3708F2C.rom`, '20891c9f'], [`${path.join('Patchable', '612644F.zip')}|612644F.rom`, 'f7591b29'], @@ -650,7 +646,7 @@ describe('with explicit DATs', () => { commands: ['copy', 'zip', 'test'], dat: [path.join(inputTemp, 'dats', '*')], input: [path.join(inputTemp, 'roms')], - inputExclude: [path.join(inputTemp, 'roms', 'nkit')], + inputExclude: [path.join(inputTemp, 'roms', 'nkit')], // will throw an error, preventing everything output: outputTemp, zipDatName: true, fixExtension: FixExtension[FixExtension.NEVER].toLowerCase(), @@ -692,6 +688,7 @@ describe('with explicit DATs', () => { [`One.zip|${path.join('Three Four Five', 'Five.rom')}`, '3e5daf67'], [`One.zip|${path.join('Three Four Five', 'Four.rom')}`, '1cf3ca74'], [`One.zip|${path.join('Three Four Five', 'Three.rom')}`, 'ff46c5d8'], + ['One.zip|UMD.iso', 'e90f7cf5'], ['Patchable.zip|0F09A40.rom', '2f943e86'], ['Patchable.zip|3708F2C.rom', '20891c9f'], ['Patchable.zip|612644F.rom', 'f7591b29'], @@ -732,14 +729,14 @@ describe('with explicit DATs', () => { [`${path.join('Headered', 'speed_test_v51.smc')} -> ${path.join('', 'headered', 'speed_test_v51.smc')}`, '9adca6cc'], [`${path.join('Headerless', 'color_test.nes')} -> ${path.join('', 'headered', 'color_test.nintendoentertainmentsystem')}`, 'c9c1b7aa'], [`${path.join('Headerless', 'speed_test_v51.sfc.gz')}|speed_test_v51.sfc -> ${path.join('', 'headerless', 'speed_test_v51.sfc.gz')}|speed_test_v51.sfc`, '8beffd94'], - [`${path.join('One', 'CD-ROM', 'CD-ROM (Track 1).bin')} -> ${path.join('', 'discs', 'CD-ROM (Track 1).bin')}`, '49ca35fb'], - [`${path.join('One', 'CD-ROM', 'CD-ROM (Track 2).bin')} -> ${path.join('', 'discs', 'CD-ROM (Track 2).bin')}`, '0316f720'], - [`${path.join('One', 'CD-ROM', 'CD-ROM (Track 3).bin')} -> ${path.join('', 'discs', 'CD-ROM (Track 3).bin')}`, 'a320af40'], - [`${path.join('One', 'CD-ROM', 'CD-ROM.cue')} -> ${path.join('', 'discs', 'CD-ROM.cue')}`, '4ce39e73'], + [`${path.join('One', 'CD-ROM.chd')}|CD-ROM (Track 1).bin -> ${path.join('', 'chd', 'CD-ROM.chd')}|CD-ROM (Track 1).bin`, '49ca35fb'], + [`${path.join('One', 'CD-ROM.chd')}|CD-ROM (Track 2).bin -> ${path.join('', 'chd', 'CD-ROM.chd')}|CD-ROM (Track 2).bin`, '0316f720'], + [`${path.join('One', 'CD-ROM.chd')}|CD-ROM (Track 3).bin -> ${path.join('', 'chd', 'CD-ROM.chd')}|CD-ROM (Track 3).bin`, 'a320af40'], + [`${path.join('One', 'CD-ROM.chd')}|CD-ROM.cue -> ${path.join('', 'chd', 'CD-ROM.chd')}|CD-ROM.cue`, 'xxxxxxxx'], [`${path.join('One', 'Fizzbuzz.nes')} -> ${path.join('', 'raw', 'fizzbuzz.nes')}`, '370517b5'], [`${path.join('One', 'Foobar.lnx')} -> ${path.join('', 'foobar.lnx')}`, 'b22c9747'], [`${path.join('One', 'GameCube NKit ISO.nkit.iso')}|GameCube NKit ISO.iso -> ${path.join('', 'nkit', '5bc2ce5b.nkit.iso')}|GameCube NKit ISO.iso`, '5bc2ce5b'], - [`${path.join('One', 'GD-ROM.chd')}|track.gdi -> ${path.join('', 'chd', 'GD-ROM.chd')}|track.gdi`, 'f16f621c'], + [`${path.join('One', 'GD-ROM.chd')}|GD-ROM.gdi -> ${path.join('', 'chd', 'GD-ROM.chd')}|GD-ROM.gdi`, 'f16f621c'], [`${path.join('One', 'GD-ROM.chd')}|track01.bin -> ${path.join('', 'chd', 'GD-ROM.chd')}|track01.bin`, '9796ed9a'], [`${path.join('One', 'GD-ROM.chd')}|track02.raw -> ${path.join('', 'chd', 'GD-ROM.chd')}|track02.raw`, 'abc178d5'], [`${path.join('One', 'GD-ROM.chd')}|track03.bin -> ${path.join('', 'chd', 'GD-ROM.chd')}|track03.bin`, '61a363f1'], @@ -752,6 +749,7 @@ describe('with explicit DATs', () => { [`${path.join('One', 'Three Four Five', 'Five.rom')} -> ${path.join('', 'raw', 'five.rom')}`, '3e5daf67'], [`${path.join('One', 'Three Four Five', 'Four.rom')} -> ${path.join('', 'raw', 'four.rom')}`, '1cf3ca74'], [`${path.join('One', 'Three Four Five', 'Three.rom')} -> ${path.join('', 'raw', 'three.rom')}`, 'ff46c5d8'], + [`${path.join('One', 'UMD.iso')} -> ${path.join('', 'discs', 'UMD.iso')}`, 'e90f7cf5'], [`${path.join('Patchable', '0F09A40.rom')} -> ${path.join('', 'patchable', '0F09A40.rom')}`, '2f943e86'], [`${path.join('Patchable', '3708F2C.rom')} -> ${path.join('', 'patchable', '3708F2C.rom')}`, '20891c9f'], [`${path.join('Patchable', '612644F.rom')} -> ${path.join('', 'patchable', '612644F.rom')}`, 'f7591b29'], @@ -821,6 +819,7 @@ describe('with explicit DATs', () => { [path.join('One', 'Three Four Five', 'Five.rom'), '3e5daf67'], [path.join('One', 'Three Four Five', 'Four.rom'), '1cf3ca74'], [path.join('One', 'Three Four Five', 'Three.rom'), 'ff46c5d8'], + [path.join('One', 'UMD.iso'), 'e90f7cf5'], [path.join('Patchable', '04C896D-GBA.rom'), 'b13eb478'], [path.join('Patchable', '0F09A40.rom'), '2f943e86'], [path.join('Patchable', '3708F2C.rom'), '20891c9f'], @@ -946,6 +945,7 @@ describe('with inferred DATs', () => { const result = await runIgir({ commands: ['copy', 'test'], input: [path.join(inputTemp, 'roms')], + inputExclude: [path.join(inputTemp, 'roms', 'discs')], // test archive scanning + matching output: outputTemp, fixExtension: FixExtension[FixExtension.AUTO].toLowerCase(), }); @@ -963,14 +963,10 @@ describe('with inferred DATs', () => { ['before.rom', '0361b321'], ['best.gz|best.rom', '1e3d78cf'], ['C01173E.rom', 'dfaebe28'], - ['CD-ROM (Track 1).bin', '49ca35fb'], - ['CD-ROM (Track 2).bin', '0316f720'], - ['CD-ROM (Track 3).bin', 'a320af40'], ['CD-ROM.chd|CD-ROM (Track 1).bin', '49ca35fb'], ['CD-ROM.chd|CD-ROM (Track 2).bin', '0316f720'], ['CD-ROM.chd|CD-ROM (Track 3).bin', 'a320af40'], ['CD-ROM.chd|CD-ROM.cue', 'xxxxxxxx'], - ['CD-ROM.cue', '4ce39e73'], ['color_test.nes', 'c9c1b7aa'], ['diagnostic_test_cartridge.a78.7z|diagnostic_test_cartridge.a78', 'f6cc9b1c'], ['empty.rom', '00000000'], @@ -981,7 +977,7 @@ describe('with inferred DATs', () => { ['four.rom', '1cf3ca74'], ['fourfive.zip|five.rom', '3e5daf67'], ['fourfive.zip|four.rom', '1cf3ca74'], - ['GD-ROM.chd|track.gdi', 'f16f621c'], + ['GD-ROM.chd|GD-ROM.gdi', 'f16f621c'], ['GD-ROM.chd|track01.bin', '9796ed9a'], ['GD-ROM.chd|track02.raw', 'abc178d5'], ['GD-ROM.chd|track03.bin', '61a363f1'], @@ -997,6 +993,7 @@ describe('with inferred DATs', () => { ['speed_test_v51.smc', '9adca6cc'], ['three.rom', 'ff46c5d8'], ['two.rom', '96170874'], + ['UMD.cso|UMD.iso', 'e90f7cf5'], ['unknown.rom', '377a7727'], ]); expect(result.cwdFilesAndCrcs).toHaveLength(0); @@ -1026,10 +1023,7 @@ describe('with inferred DATs', () => { const result = await runIgir({ commands: ['move', 'extract', 'test'], input: [path.join(inputTemp, 'roms')], - inputExclude: [ - path.join(inputTemp, 'roms', 'chd'), - path.join(inputTemp, 'roms', 'nkit'), - ], + inputExclude: [path.join(inputTemp, 'roms', 'discs')], // test archive scanning + matching output: outputTemp, dirGameSubdir: GameSubdirMode[GameSubdirMode.MULTIPLE].toLowerCase(), fixExtension: FixExtension[FixExtension.AUTO].toLowerCase(), @@ -1037,7 +1031,9 @@ describe('with inferred DATs', () => { expect(result.outputFilesAndCrcs).toEqual([ ['0F09A40.rom', '2f943e86'], + ['2048.rom', 'd774f042'], ['3708F2C.rom', '20891c9f'], + ['4096.rom', '2e19ca09'], ['612644F.rom', 'f7591b29'], ['65D1206.rom', '20323455'], ['92C85C9.rom', '06692159'], @@ -1045,10 +1041,6 @@ describe('with inferred DATs', () => { ['before.rom', '0361b321'], ['best.rom', '1e3d78cf'], ['C01173E.rom', 'dfaebe28'], - [path.join('CD-ROM', 'CD-ROM (Track 1).bin'), '49ca35fb'], - [path.join('CD-ROM', 'CD-ROM (Track 2).bin'), '0316f720'], - [path.join('CD-ROM', 'CD-ROM (Track 3).bin'), 'a320af40'], - [path.join('CD-ROM', 'CD-ROM.cue'), '4ce39e73'], ['color_test.nes', 'c9c1b7aa'], ['diagnostic_test_cartridge.a78', 'f6cc9b1c'], ['empty.rom', '00000000'], @@ -1059,7 +1051,7 @@ describe('with inferred DATs', () => { ['four.rom', '1cf3ca74'], [path.join('fourfive', 'five.rom'), '3e5daf67'], [path.join('fourfive', 'four.rom'), '1cf3ca74'], - [path.join('GD-ROM', 'GD-ROM.gdi'), 'f16f621c'], + [path.join('GD-ROM', 'GD-ROM.gdi'), 'f16f621c'], // TODO(cemmer) [path.join('GD-ROM', 'track01.bin'), '9796ed9a'], [path.join('GD-ROM', 'track02.raw'), 'abc178d5'], [path.join('GD-ROM', 'track03.bin'), '61a363f1'], @@ -1075,21 +1067,15 @@ describe('with inferred DATs', () => { ['speed_test_v51.smc', '9adca6cc'], ['three.rom', 'ff46c5d8'], ['two.rom', '96170874'], + ['UMD.iso', 'e90f7cf5'], ['unknown.rom', '377a7727'], ]); expect(result.cwdFilesAndCrcs).toHaveLength(0); expect(result.movedFiles).toEqual([ - path.join('discs', 'CD-ROM (Track 1).bin'), - path.join('discs', 'CD-ROM (Track 2).bin'), - path.join('discs', 'CD-ROM (Track 3).bin'), - path.join('discs', 'CD-ROM.cue'), - path.join('discs', 'GD-ROM.gdi'), - path.join('discs', 'track01.bin'), - path.join('discs', 'track02.raw'), - path.join('discs', 'track03.bin'), - path.join('discs', 'track04.bin'), - path.join('empty.rom'), - path.join('foobar.lnx'), + path.join('chd', 'GD-ROM.chd'), + path.join('cso', 'UMD.cso'), + 'empty.rom', + 'foobar.lnx', path.join('headered', 'LCDTestROM.lnx.rar'), path.join('headered', 'allpads.nes'), path.join('headered', 'color_test.nintendoentertainmentsystem'), @@ -1126,7 +1112,6 @@ describe('with inferred DATs', () => { input: [path.join(inputTemp, 'roms')], inputExclude: [ // Note: need to exclude some ROMs to prevent duplicate output paths - path.join(inputTemp, 'roms', 'discs'), // de-conflict chds & discs path.join(inputTemp, 'roms', 'headerless'), // de-conflict headered & headerless ], output: outputTemp, @@ -1147,7 +1132,7 @@ describe('with inferred DATs', () => { ['CD-ROM.zip|CD-ROM (Track 1).bin', '49ca35fb'], ['CD-ROM.zip|CD-ROM (Track 2).bin', '0316f720'], ['CD-ROM.zip|CD-ROM (Track 3).bin', 'a320af40'], - ['CD-ROM.zip|CD-ROM.cue', '03924922'], // doesn't match the DAT CRC + ['CD-ROM.zip|CD-ROM.cue', '4ce39e73'], ['color_test.zip|color_test.nintendoentertainmentsystem', 'c9c1b7aa'], ['diagnostic_test_cartridge.zip|diagnostic_test_cartridge.a78', 'f6cc9b1c'], ['empty.zip|empty.rom', '00000000'], @@ -1158,7 +1143,7 @@ describe('with inferred DATs', () => { ['four.zip|four.rom', '1cf3ca74'], ['fourfive.zip|five.rom', '3e5daf67'], ['fourfive.zip|four.rom', '1cf3ca74'], - ['GD-ROM.zip|track.gdi', 'f16f621c'], + ['GD-ROM.zip|GD-ROM.gdi', 'f16f621c'], ['GD-ROM.zip|track01.bin', '9796ed9a'], ['GD-ROM.zip|track02.raw', 'abc178d5'], ['GD-ROM.zip|track03.bin', '61a363f1'], @@ -1173,6 +1158,7 @@ describe('with inferred DATs', () => { ['speed_test_v51.zip|speed_test_v51.smc', '9adca6cc'], ['three.zip|three.rom', 'ff46c5d8'], ['two.zip|two.rom', '96170874'], + ['UMD.zip|UMD.iso', 'e90f7cf5'], ['unknown.zip|unknown.rom', '377a7727'], ]); expect(result.cwdFilesAndCrcs).toHaveLength(0); @@ -1186,6 +1172,10 @@ describe('with inferred DATs', () => { const result = await runIgir({ commands: ['link', 'test'], input: [path.join(inputTemp, 'roms')], + inputExclude: [ + // Note: need to exclude some ROMs to prevent duplicate output paths + path.join(inputTemp, 'roms', 'discs'), // de-conflict chd & discs + ], output: outputTemp, fixExtension: FixExtension[FixExtension.AUTO].toLowerCase(), symlink: true, @@ -1205,14 +1195,10 @@ describe('with inferred DATs', () => { [`before.rom -> ${path.join('..', 'input', 'roms', 'patchable', 'before.rom')}`, '0361b321'], [`best.gz|best.rom -> ${path.join('..', 'input', 'roms', 'patchable', 'best.gz')}|best.rom`, '1e3d78cf'], [`C01173E.rom -> ${path.join('..', 'input', 'roms', 'patchable', 'C01173E.rom')}`, 'dfaebe28'], - [`CD-ROM (Track 1).bin -> ${path.join('..', 'input', 'roms', 'discs', 'CD-ROM (Track 1).bin')}`, '49ca35fb'], - [`CD-ROM (Track 2).bin -> ${path.join('..', 'input', 'roms', 'discs', 'CD-ROM (Track 2).bin')}`, '0316f720'], - [`CD-ROM (Track 3).bin -> ${path.join('..', 'input', 'roms', 'discs', 'CD-ROM (Track 3).bin')}`, 'a320af40'], - [`CD-ROM.chd|CD-ROM (Track 1).bin -> ${path.join('..', 'input', 'roms', 'chd', 'CD-ROM.chd|CD-ROM (Track 1).bin')}`, '49ca35fb'], - [`CD-ROM.chd|CD-ROM (Track 2).bin -> ${path.join('..', 'input', 'roms', 'chd', 'CD-ROM.chd|CD-ROM (Track 2).bin')}`, '0316f720'], - [`CD-ROM.chd|CD-ROM (Track 3).bin -> ${path.join('..', 'input', 'roms', 'chd', 'CD-ROM.chd|CD-ROM (Track 3).bin')}`, 'a320af40'], - [`CD-ROM.chd|CD-ROM.cue -> ${path.join('..', 'input', 'roms', 'chd', 'CD-ROM.chd|CD-ROM.cue')}`, 'xxxxxxxx'], - [`CD-ROM.cue -> ${path.join('..', 'input', 'roms', 'discs', 'CD-ROM.cue')}`, '4ce39e73'], + [`CD-ROM.chd|CD-ROM (Track 1).bin -> ${path.join('..', 'input', 'roms', 'chd', 'CD-ROM.chd')}|CD-ROM (Track 1).bin`, '49ca35fb'], + [`CD-ROM.chd|CD-ROM (Track 2).bin -> ${path.join('..', 'input', 'roms', 'chd', 'CD-ROM.chd')}|CD-ROM (Track 2).bin`, '0316f720'], + [`CD-ROM.chd|CD-ROM (Track 3).bin -> ${path.join('..', 'input', 'roms', 'chd', 'CD-ROM.chd')}|CD-ROM (Track 3).bin`, 'a320af40'], + [`CD-ROM.chd|CD-ROM.cue -> ${path.join('..', 'input', 'roms', 'chd', 'CD-ROM.chd')}|CD-ROM.cue`, 'xxxxxxxx'], [`color_test.nes -> ${path.join('..', 'input', 'roms', 'headered', 'color_test.nintendoentertainmentsystem')}`, 'c9c1b7aa'], [`diagnostic_test_cartridge.a78.7z|diagnostic_test_cartridge.a78 -> ${path.join('..', 'input', 'roms', 'headered', 'diagnostic_test_cartridge.a78.7z')}|diagnostic_test_cartridge.a78`, 'f6cc9b1c'], [`empty.rom -> ${path.join('..', 'input', 'roms', 'empty.rom')}`, '00000000'], @@ -1223,7 +1209,7 @@ describe('with inferred DATs', () => { [`four.rom -> ${path.join('..', 'input', 'roms', 'raw', 'four.rom')}`, '1cf3ca74'], [`fourfive.zip|five.rom -> ${path.join('..', 'input', 'roms', 'zip', 'fourfive.zip')}|five.rom`, '3e5daf67'], [`fourfive.zip|four.rom -> ${path.join('..', 'input', 'roms', 'zip', 'fourfive.zip')}|four.rom`, '1cf3ca74'], - [`GD-ROM.chd|track.gdi -> ${path.join('..', 'input', 'roms', 'chd', 'GD-ROM.chd|track.gdi')}`, 'f16f621c'], + [`GD-ROM.chd|GD-ROM.gdi -> ${path.join('..', 'input', 'roms', 'chd', 'GD-ROM.chd|GD-ROM.gdi')}`, 'f16f621c'], [`GD-ROM.chd|track01.bin -> ${path.join('..', 'input', 'roms', 'chd', 'GD-ROM.chd|track01.bin')}`, '9796ed9a'], [`GD-ROM.chd|track02.raw -> ${path.join('..', 'input', 'roms', 'chd', 'GD-ROM.chd|track02.raw')}`, 'abc178d5'], [`GD-ROM.chd|track03.bin -> ${path.join('..', 'input', 'roms', 'chd', 'GD-ROM.chd|track03.bin')}`, '61a363f1'], @@ -1239,6 +1225,7 @@ describe('with inferred DATs', () => { [`speed_test_v51.smc -> ${path.join('..', 'input', 'roms', 'headered', 'speed_test_v51.smc')}`, '9adca6cc'], [`three.rom -> ${path.join('..', 'input', 'roms', 'raw', 'three.rom')}`, 'ff46c5d8'], [`two.rom -> ${path.join('..', 'input', 'roms', 'raw', 'two.rom')}`, '96170874'], + [`UMD.cso|UMD.iso -> ${path.join('..', 'input', 'roms', 'cso', 'UMD.cso')}|UMD.iso`, 'e90f7cf5'], [`unknown.rom -> ${path.join('..', 'input', 'roms', 'raw', 'unknown.rom')}`, '377a7727'], ]); expect(result.cwdFilesAndCrcs).toHaveLength(0); @@ -1283,7 +1270,11 @@ describe('with inferred DATs', () => { const result = await runIgir({ commands: ['dir2dat'], input: [path.join(inputTemp, 'roms')], - inputExclude: [path.join(inputTemp, 'roms', 'nkit')], + inputExclude: [ + // Note: need to exclude some ROMs to prevent duplicate output paths + path.join(inputTemp, 'roms', 'discs'), // de-conflict chd & discs + path.join(inputTemp, 'roms', 'nkit'), // will throw an error, preventing everything + ], output: outputTemp, dirDatName: true, fixExtension: FixExtension[FixExtension.AUTO].toLowerCase(), @@ -1324,8 +1315,10 @@ describe('with inferred DATs', () => { 'CD-ROM (Track 2).bin', 'CD-ROM (Track 3).bin', 'CD-ROM.cue', + 'GD-ROM.gdi', 'KDULVQN.rom', 'LCDTestROM.lnx', + 'UMD.iso', 'allpads.nes', 'before.rom', 'best.rom', @@ -1341,7 +1334,6 @@ describe('with inferred DATs', () => { 'speed_test_v51.sfc', 'speed_test_v51.smc', 'three.rom', - 'track.gdi', 'track01.bin', 'track02.raw', 'track03.bin', diff --git a/test/modules/candidateWriter.test.ts b/test/modules/candidateWriter.test.ts index e6042b80e..c4fc8c9f8 100644 --- a/test/modules/candidateWriter.test.ts +++ b/test/modules/candidateWriter.test.ts @@ -438,7 +438,7 @@ describe('zip', () => { test.each([ [ '**/!(header*)/*', - ['0F09A40.zip', '2048.zip', '3708F2C.zip', '4096.zip', '612644F.zip', '65D1206.zip', '92C85C9.zip', 'C01173E.zip', 'CD-ROM.zip', 'GD-ROM.zip', 'KDULVQN.zip', 'before.zip', 'best.zip', 'empty.zip', 'five.zip', 'fizzbuzz.zip', 'foobar.zip', 'four.zip', 'fourfive.zip', 'loremipsum.zip', 'one.zip', 'onetwothree.zip', 'three.zip', 'two.zip', 'unknown.zip'], + ['0F09A40.zip', '2048.zip', '3708F2C.zip', '4096.zip', '612644F.zip', '65D1206.zip', '92C85C9.zip', 'C01173E.zip', 'CD-ROM.zip', 'GD-ROM.zip', 'KDULVQN.zip', 'UMD.zip', 'before.zip', 'best.zip', 'empty.zip', 'five.zip', 'fizzbuzz.zip', 'foobar.zip', 'four.zip', 'fourfive.zip', 'loremipsum.zip', 'one.zip', 'onetwothree.zip', 'three.zip', 'two.zip', 'unknown.zip'], ], [ '7z/*', @@ -488,7 +488,7 @@ describe('zip', () => { test.each([ [ '**/!(header*)/*', - ['0F09A40.zip', '2048.zip', '3708F2C.zip', '4096.zip', '612644F.zip', '65D1206.zip', '92C85C9.zip', 'C01173E.zip', 'CD-ROM.zip', 'GD-ROM.zip', 'KDULVQN.zip', 'before.zip', 'best.zip', 'empty.zip', 'five.zip', 'fizzbuzz.zip', 'foobar.zip', 'four.zip', 'fourfive.zip', 'loremipsum.zip', 'one.zip', 'onetwothree.zip', 'three.zip', 'two.zip', 'unknown.zip'], + ['0F09A40.zip', '2048.zip', '3708F2C.zip', '4096.zip', '612644F.zip', '65D1206.zip', '92C85C9.zip', 'C01173E.zip', 'CD-ROM.zip', 'GD-ROM.zip', 'KDULVQN.zip', 'UMD.zip', 'before.zip', 'best.zip', 'empty.zip', 'five.zip', 'fizzbuzz.zip', 'foobar.zip', 'four.zip', 'fourfive.zip', 'loremipsum.zip', 'one.zip', 'onetwothree.zip', 'three.zip', 'two.zip', 'unknown.zip'], ['patchable/0F09A40.rom', 'patchable/3708F2C.rom', 'patchable/612644F.rom', 'patchable/65D1206.rom', 'patchable/92C85C9.rom', 'patchable/C01173E.rom', 'patchable/KDULVQN.rom', 'patchable/before.rom', 'patchable/best.gz', 'raw/empty.rom', 'raw/fizzbuzz.nes', 'raw/foobar.lnx', 'raw/loremipsum.rom', 'raw/one.rom', 'raw/three.rom', 'raw/two.rom', 'raw/unknown.rom'], ], [ @@ -595,6 +595,7 @@ describe('zip', () => { ['ROMWriter Test.zip|speed_test_v51.smc', '9adca6cc'], ['ROMWriter Test.zip|three.rom', 'ff46c5d8'], ['ROMWriter Test.zip|two.rom', '96170874'], + ['ROMWriter Test.zip|UMD.iso', 'e90f7cf5'], ['ROMWriter Test.zip|unknown.rom', '377a7727'], ]], ['raw/*', [ @@ -887,8 +888,8 @@ describe('extract', () => { '**/!(header*)/*', ['0F09A40.rom', '2048.rom', '3708F2C.rom', '4096.rom', '612644F.rom', '65D1206.rom', '92C85C9.rom', 'C01173E.rom', path.join('CD-ROM', 'CD-ROM (Track 1).bin'), path.join('CD-ROM', 'CD-ROM (Track 2).bin'), path.join('CD-ROM', 'CD-ROM (Track 3).bin'), path.join('CD-ROM', 'CD-ROM.cue'), - path.join('GD-ROM', 'track.gdi'), path.join('GD-ROM', 'track01.bin'), path.join('GD-ROM', 'track02.raw'), path.join('GD-ROM', 'track03.bin'), path.join('GD-ROM', 'track04.bin'), - 'KDULVQN.rom', 'before.rom', 'best.rom', 'empty.rom', 'five.rom', 'fizzbuzz.nes', 'foobar.lnx', 'four.rom', path.join('fourfive', 'five.rom'), path.join('fourfive', 'four.rom'), 'loremipsum.rom', 'one.rom', path.join('onetwothree', 'one.rom'), path.join('onetwothree', 'three.rom'), path.join('onetwothree', 'two.rom'), 'three.rom', + path.join('GD-ROM', 'GD-ROM.gdi'), path.join('GD-ROM', 'track01.bin'), path.join('GD-ROM', 'track02.raw'), path.join('GD-ROM', 'track03.bin'), path.join('GD-ROM', 'track04.bin'), + 'KDULVQN.rom', 'UMD.iso', 'before.rom', 'best.rom', 'empty.rom', 'five.rom', 'fizzbuzz.nes', 'foobar.lnx', 'four.rom', path.join('fourfive', 'five.rom'), path.join('fourfive', 'four.rom'), 'loremipsum.rom', 'one.rom', path.join('onetwothree', 'one.rom'), path.join('onetwothree', 'three.rom'), path.join('onetwothree', 'two.rom'), 'three.rom', 'two.rom', 'unknown.rom'], ], [ @@ -944,8 +945,8 @@ describe('extract', () => { '**/!(header*)/*', ['0F09A40.rom', '2048.rom', '3708F2C.rom', '4096.rom', '612644F.rom', '65D1206.rom', '92C85C9.rom', 'C01173E.rom', path.join('CD-ROM', 'CD-ROM (Track 1).bin'), path.join('CD-ROM', 'CD-ROM (Track 2).bin'), path.join('CD-ROM', 'CD-ROM (Track 3).bin'), path.join('CD-ROM', 'CD-ROM.cue'), - path.join('GD-ROM', 'track.gdi'), path.join('GD-ROM', 'track01.bin'), path.join('GD-ROM', 'track02.raw'), path.join('GD-ROM', 'track03.bin'), path.join('GD-ROM', 'track04.bin'), - 'KDULVQN.rom', 'before.rom', 'best.rom', 'empty.rom', 'five.rom', 'fizzbuzz.nes', 'foobar.lnx', 'four.rom', path.join('fourfive', 'five.rom'), path.join('fourfive', 'four.rom'), 'loremipsum.rom', 'one.rom', path.join('onetwothree', 'one.rom'), path.join('onetwothree', 'three.rom'), path.join('onetwothree', 'two.rom'), 'three.rom', + path.join('GD-ROM', 'GD-ROM.gdi'), path.join('GD-ROM', 'track01.bin'), path.join('GD-ROM', 'track02.raw'), path.join('GD-ROM', 'track03.bin'), path.join('GD-ROM', 'track04.bin'), + 'KDULVQN.rom', 'UMD.iso', 'before.rom', 'best.rom', 'empty.rom', 'five.rom', 'fizzbuzz.nes', 'foobar.lnx', 'four.rom', path.join('fourfive', 'five.rom'), path.join('fourfive', 'four.rom'), 'loremipsum.rom', 'one.rom', path.join('onetwothree', 'one.rom'), path.join('onetwothree', 'three.rom'), path.join('onetwothree', 'two.rom'), 'three.rom', 'two.rom', 'unknown.rom'], ['patchable/0F09A40.rom', 'patchable/3708F2C.rom', 'patchable/612644F.rom', 'patchable/65D1206.rom', 'patchable/92C85C9.rom', 'patchable/C01173E.rom', 'patchable/KDULVQN.rom', 'patchable/before.rom', 'patchable/best.gz', 'raw/empty.rom', 'raw/fizzbuzz.nes', 'raw/foobar.lnx', 'raw/loremipsum.rom', 'raw/one.rom', 'raw/three.rom', 'raw/two.rom', 'raw/unknown.rom'], ], @@ -1253,9 +1254,9 @@ describe('raw', () => { [ '**/!(header*)/*', ['0F09A40.rom', '2048.chd', '3708F2C.rom', '4096.chd', '612644F.rom', '65D1206.rom', '92C85C9.rom', 'C01173E.rom', - 'CD-ROM (Track 1).bin', 'CD-ROM (Track 2).bin', 'CD-ROM (Track 3).bin', 'CD-ROM.chd', 'CD-ROM.cue', + 'CD-ROM.chd', 'GD-ROM.chd', - 'KDULVQN.rom', 'before.rom', 'best.gz', 'empty.rom', 'five.rom', 'fizzbuzz.nes', 'foobar.lnx', 'four.rom', 'fourfive.zip', 'loremipsum.rom', 'one.rom', 'onetwothree.zip', 'three.rom', + 'KDULVQN.rom', 'UMD.iso', 'before.rom', 'best.gz', 'empty.rom', 'five.rom', 'fizzbuzz.nes', 'foobar.lnx', 'four.rom', 'fourfive.zip', 'loremipsum.rom', 'one.rom', 'onetwothree.zip', 'three.rom', 'two.rom', 'unknown.rom'], ], [ @@ -1307,9 +1308,9 @@ describe('raw', () => { [ '**/!(header*)/*', ['0F09A40.rom', '2048.chd', '3708F2C.rom', '4096.chd', '612644F.rom', '65D1206.rom', '92C85C9.rom', 'C01173E.rom', - 'CD-ROM (Track 1).bin', 'CD-ROM (Track 2).bin', 'CD-ROM (Track 3).bin', 'CD-ROM.chd', 'CD-ROM.cue', + 'CD-ROM.chd', 'GD-ROM.chd', - 'KDULVQN.rom', 'before.rom', 'best.gz', 'empty.rom', 'five.rom', 'fizzbuzz.nes', 'foobar.lnx', 'four.rom', 'fourfive.zip', 'loremipsum.rom', 'one.rom', 'onetwothree.zip', 'three.rom', + 'KDULVQN.rom', 'UMD.iso', 'before.rom', 'best.gz', 'empty.rom', 'five.rom', 'fizzbuzz.nes', 'foobar.lnx', 'four.rom', 'fourfive.zip', 'loremipsum.rom', 'one.rom', 'onetwothree.zip', 'three.rom', 'two.rom', 'unknown.rom'], ['patchable/0F09A40.rom', 'patchable/3708F2C.rom', 'patchable/612644F.rom', 'patchable/65D1206.rom', 'patchable/92C85C9.rom', 'patchable/C01173E.rom', 'patchable/KDULVQN.rom', 'patchable/before.rom', 'patchable/best.gz', 'raw/empty.rom', 'raw/fizzbuzz.nes', 'raw/foobar.lnx', 'raw/loremipsum.rom', 'raw/one.rom', 'raw/three.rom', 'raw/two.rom', 'raw/unknown.rom'], ], diff --git a/test/modules/datGameInferrer.test.ts b/test/modules/datGameInferrer.test.ts index 42cba418d..6e7700d7a 100644 --- a/test/modules/datGameInferrer.test.ts +++ b/test/modules/datGameInferrer.test.ts @@ -5,10 +5,11 @@ import ProgressBarFake from '../console/progressBarFake.js'; test.each([ // One input path - [['test/fixtures/roms/**/*'], { roms: 34 }], + [['test/fixtures/roms/**/*'], { roms: 35 }], [['test/fixtures/roms/7z/*'], { '7z': 5 }], [['test/fixtures/roms/chd/*'], { chd: 4 }], - [['test/fixtures/roms/discs/*'], { discs: 2 }], + [['test/fixtures/roms/cso/*'], { cso: 1 }], + [['test/fixtures/roms/discs/*'], { discs: 3 }], [['test/fixtures/roms/gz/*'], { gz: 7 }], [['test/fixtures/roms/headered/*'], { headered: 6 }], [['test/fixtures/roms/headerless/*'], { headerless: 1 }], diff --git a/test/modules/dir2DatCreator.test.ts b/test/modules/dir2DatCreator.test.ts index 58413e580..f3e61d6a4 100644 --- a/test/modules/dir2DatCreator.test.ts +++ b/test/modules/dir2DatCreator.test.ts @@ -1,5 +1,7 @@ import 'jest-extended'; +import path from 'node:path'; + import CandidateGenerator from '../../src/modules/candidateGenerator.js'; import DATGameInferrer from '../../src/modules/datGameInferrer.js'; import DATScanner from '../../src/modules/datScanner.js'; @@ -97,7 +99,7 @@ it('should use the candidates for games and ROMs', async () => { // Given some input ROMs const options = new Options({ commands: ['dir2dat'], - input: ['test/fixtures/roms'], + input: [path.join('test', 'fixtures', 'roms')], }); const files = await new ROMScanner(options, new ProgressBarFake()).scan(); diff --git a/test/modules/romScanner.test.ts b/test/modules/romScanner.test.ts index a207df77b..3c51ebcd7 100644 --- a/test/modules/romScanner.test.ts +++ b/test/modules/romScanner.test.ts @@ -33,7 +33,7 @@ it('should not throw on bad archives', async () => { describe('multiple files', () => { it('should scan multiple files with no exclusions', async () => { - const expectedRomFiles = 91; + const expectedRomFiles = 94; await expect(createRomScanner(['test/fixtures/roms']).scan()).resolves.toHaveLength(expectedRomFiles); await expect(createRomScanner(['test/fixtures/roms/*', 'test/fixtures/roms/**/*']).scan()).resolves.toHaveLength(expectedRomFiles); await expect(createRomScanner(['test/fixtures/roms/**/*']).scan()).resolves.toHaveLength(expectedRomFiles); @@ -41,7 +41,7 @@ describe('multiple files', () => { }); test.each([ - [{ input: [path.join('test', 'fixtures', 'roms')] }, 132], + [{ input: [path.join('test', 'fixtures', 'roms')] }, 137], [{ input: [path.join('test', 'fixtures', 'roms', '7z')] }, 12], [{ input: [path.join('test', 'fixtures', 'roms', 'gz')] }, 14], [{ input: [path.join('test', 'fixtures', 'roms', 'rar')] }, 12], @@ -54,9 +54,9 @@ describe('multiple files', () => { }); it('should scan multiple files with some file exclusions', async () => { - await expect(createRomScanner(['test/fixtures/roms/**/*'], ['test/fixtures/roms/**/*.rom']).scan()).resolves.toHaveLength(74); - await expect(createRomScanner(['test/fixtures/roms/**/*'], ['test/fixtures/roms/**/*.rom', 'test/fixtures/roms/**/*.rom']).scan()).resolves.toHaveLength(74); - await expect(createRomScanner(['test/fixtures/roms/**/*'], ['test/fixtures/roms/**/*.rom', 'test/fixtures/roms/**/*.zip']).scan()).resolves.toHaveLength(63); + await expect(createRomScanner(['test/fixtures/roms/**/*'], ['test/fixtures/roms/**/*.rom']).scan()).resolves.toHaveLength(77); + await expect(createRomScanner(['test/fixtures/roms/**/*'], ['test/fixtures/roms/**/*.rom', 'test/fixtures/roms/**/*.rom']).scan()).resolves.toHaveLength(77); + await expect(createRomScanner(['test/fixtures/roms/**/*'], ['test/fixtures/roms/**/*.rom', 'test/fixtures/roms/**/*.zip']).scan()).resolves.toHaveLength(66); }); it('should scan multiple files with every file excluded', async () => { diff --git a/test/types/files/archives/archive.test.ts b/test/types/files/archives/archive.test.ts index d54735842..6d04d38f1 100644 --- a/test/types/files/archives/archive.test.ts +++ b/test/types/files/archives/archive.test.ts @@ -5,6 +5,9 @@ import fsPoly from '../../../../src/polyfill/fsPoly.js'; import Archive from '../../../../src/types/files/archives/archive.js'; import ArchiveEntry from '../../../../src/types/files/archives/archiveEntry.js'; import Chd from '../../../../src/types/files/archives/chd/chd.js'; +import Cso from '../../../../src/types/files/archives/maxcso/cso.js'; +import Dax from '../../../../src/types/files/archives/maxcso/dax.js'; +import Zso from '../../../../src/types/files/archives/maxcso/zso.js'; import NkitIso from '../../../../src/types/files/archives/nkitIso.js'; import Rar from '../../../../src/types/files/archives/rar.js'; import Gzip from '../../../../src/types/files/archives/sevenZip/gzip.js'; @@ -28,6 +31,9 @@ describe('getArchiveEntries', () => { ...ZipSpanned.getExtensions(), ...ZipX.getExtensions(), // Compressed images + ...Cso.getExtensions(), + ...Dax.getExtensions(), + ...Zso.getExtensions(), ...Chd.getExtensions(), ...NkitIso.getExtensions(), ])])('should throw when the file doesn\'t exist: %s', async (extension) => {