This commit is contained in:
Erick Zhao 2024-06-17 15:15:20 -07:00 коммит произвёл GitHub
Родитель dfe5236357
Коммит 03e27e5a1d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
8 изменённых файлов: 170 добавлений и 24 удалений

Просмотреть файл

@ -27,13 +27,21 @@ const templateApp = async (
export default async () => {
await fs.remove(appsDir);
await fs.mkdirp(appsDir);
await templateApp('Asar.app', 'arm64', async (appPath) => {
await templateApp('Arm64Asar.app', 'arm64', async (appPath) => {
await fs.copy(
path.resolve(asarsDir, 'app.asar'),
path.resolve(appPath, 'Contents', 'Resources', 'app.asar'),
);
});
// contains `extra-file.txt`
await templateApp('Arm64AsarExtraFile.app', 'arm64', async (appPath) => {
await fs.copy(
path.resolve(asarsDir, 'app2.asar'),
path.resolve(appPath, 'Contents', 'Resources', 'app.asar'),
);
});
await templateApp('X64Asar.app', 'x64', async (appPath) => {
await fs.copy(
path.resolve(asarsDir, 'app.asar'),
@ -41,13 +49,21 @@ export default async () => {
);
});
await templateApp('NoAsar.app', 'arm64', async (appPath) => {
await templateApp('Arm64NoAsar.app', 'arm64', async (appPath) => {
await fs.copy(
path.resolve(asarsDir, 'app'),
path.resolve(appPath, 'Contents', 'Resources', 'app'),
);
});
// contains `extra-file.txt`
await templateApp('Arm64NoAsarExtraFile.app', 'arm64', async (appPath) => {
await fs.copy(
path.resolve(asarsDir, 'app2'),
path.resolve(appPath, 'Contents', 'Resources', 'app'),
);
});
await templateApp('X64NoAsar.app', 'x64', async (appPath) => {
await fs.copy(
path.resolve(asarsDir, 'app'),

Просмотреть файл

@ -8,11 +8,13 @@ const appsPath = path.resolve(__dirname, 'fixtures', 'apps');
describe('asar-utils', () => {
describe('detectAsarMode', () => {
it('should correctly detect an asar enabled app', async () => {
expect(await detectAsarMode(path.resolve(appsPath, 'Asar.app'))).toBe(AsarMode.HAS_ASAR);
expect(await detectAsarMode(path.resolve(appsPath, 'Arm64Asar.app'))).toBe(AsarMode.HAS_ASAR);
});
it('should correctly detect an app without an asar', async () => {
expect(await detectAsarMode(path.resolve(appsPath, 'NoAsar.app'))).toBe(AsarMode.NO_ASAR);
expect(await detectAsarMode(path.resolve(appsPath, 'Arm64NoAsar.app'))).toBe(
AsarMode.NO_ASAR,
);
});
});

Просмотреть файл

@ -10,8 +10,8 @@ describe('file-utils', () => {
let noAsarFiles: AppFile[];
beforeAll(async () => {
asarFiles = await getAllAppFiles(path.resolve(appsPath, 'Asar.app'));
noAsarFiles = await getAllAppFiles(path.resolve(appsPath, 'NoAsar.app'));
asarFiles = await getAllAppFiles(path.resolve(appsPath, 'Arm64Asar.app'));
noAsarFiles = await getAllAppFiles(path.resolve(appsPath, 'Arm64NoAsar.app'));
});
it('should correctly identify plist files', async () => {

Двоичные данные
test/fixtures/asars/app2.asar поставляемый Normal file

Двоичный файл не отображается.

1
test/fixtures/asars/app2/extra-file.txt поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
erick was here!

2
test/fixtures/asars/app2/index.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,2 @@
console.log('I am an app.asar', process.arch);
process.exit(0);

4
test/fixtures/asars/app2/package.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,4 @@
{
"name": "app",
"main": "index.js"
}

Просмотреть файл

@ -2,9 +2,10 @@ import { spawn } from '@malept/cross-spawn-promise';
import * as fs from 'fs-extra';
import * as path from 'path';
import { makeUniversalApp } from '../src/index';
import { makeUniversalApp } from '../dist/cjs/index';
const appsPath = path.resolve(__dirname, 'fixtures', 'apps');
const appsOutPath = path.resolve(__dirname, 'fixtures', 'apps', 'out');
async function ensureUniversal(app: string) {
const exe = path.resolve(app, 'Contents', 'MacOS', 'Electron');
@ -14,27 +15,147 @@ async function ensureUniversal(app: string) {
expect(result2).toContain('x64');
}
// See `jest.setup.ts` for app fixture setup process
describe('makeUniversalApp', () => {
it('should correctly merge two identical asars', async () => {
const out = path.resolve(appsPath, 'MergedAsar.app');
await makeUniversalApp({
x64AppPath: path.resolve(appsPath, 'X64Asar.app'),
arm64AppPath: path.resolve(appsPath, 'Asar.app'),
outAppPath: out,
afterEach(async () => {
await fs.emptyDir(appsOutPath);
});
it('throws an error if asar is only detected in one arch', async () => {
const out = path.resolve(appsOutPath, 'Error.app');
await expect(
makeUniversalApp({
x64AppPath: path.resolve(appsPath, 'X64Asar.app'),
arm64AppPath: path.resolve(appsPath, 'Arm64NoAsar.app'),
outAppPath: out,
}),
).rejects.toThrow(
'Both the x64 and arm64 versions of your application need to have been built with the same asar settings (enabled vs disabled)',
);
});
it.todo('works for lipo binary resources');
describe('force', () => {
it('throws an error if `out` bundle already exists and `force` is `false`', async () => {
const out = path.resolve(appsOutPath, 'Error.app');
await fs.mkdirp(out);
await expect(
makeUniversalApp({
x64AppPath: path.resolve(appsPath, 'X64Asar.app'),
arm64AppPath: path.resolve(appsPath, 'Arm64Asar.app'),
outAppPath: out,
}),
).rejects.toThrow(/The out path ".*" already exists and force is not set to true/);
});
await ensureUniversal(out);
// Only a single asar as they were identical
expect(
(await fs.readdir(path.resolve(out, 'Contents', 'Resources'))).filter((p) =>
p.endsWith('asar'),
),
).toEqual(['app.asar']);
}, 60000);
it('packages successfully if `out` bundle already exists and `force` is `true`', async () => {
const out = path.resolve(appsOutPath, 'Error.app');
await fs.mkdirp(out);
await makeUniversalApp({
x64AppPath: path.resolve(appsPath, 'X64Asar.app'),
arm64AppPath: path.resolve(appsPath, 'Arm64Asar.app'),
outAppPath: out,
force: true,
});
await ensureUniversal(out);
// Only a single asar as they were identical
expect(
(await fs.readdir(path.resolve(out, 'Contents', 'Resources'))).filter((p) =>
p.endsWith('asar'),
),
).toEqual(['app.asar']);
}, 60000);
});
describe('asar mode', () => {
it('should correctly merge two identical asars', async () => {
const out = path.resolve(appsOutPath, 'MergedAsar.app');
await makeUniversalApp({
x64AppPath: path.resolve(appsPath, 'X64Asar.app'),
arm64AppPath: path.resolve(appsPath, 'Arm64Asar.app'),
outAppPath: out,
});
await ensureUniversal(out);
// Only a single asar as they were identical
expect(
(await fs.readdir(path.resolve(out, 'Contents', 'Resources'))).filter((p) =>
p.endsWith('asar'),
),
).toEqual(['app.asar']);
}, 60000);
it('should create a shim if asars are different between architectures', async () => {
const out = path.resolve(appsOutPath, 'ShimmedAsar.app');
await makeUniversalApp({
x64AppPath: path.resolve(appsPath, 'X64Asar.app'),
arm64AppPath: path.resolve(appsPath, 'Arm64AsarExtraFile.app'),
outAppPath: out,
});
await ensureUniversal(out);
// We have three asars including the arch-agnostic shim
expect(
(await fs.readdir(path.resolve(out, 'Contents', 'Resources')))
.filter((p) => p.endsWith('asar'))
.sort(),
).toEqual(['app.asar', 'app-x64.asar', 'app-arm64.asar'].sort());
}, 60000);
it('should merge two different asars when `mergeASARs` is enabled', async () => {
const out = path.resolve(appsOutPath, 'MergedAsar.app');
await makeUniversalApp({
x64AppPath: path.resolve(appsPath, 'X64Asar.app'),
arm64AppPath: path.resolve(appsPath, 'Arm64AsarExtraFile.app'),
outAppPath: out,
mergeASARs: true,
singleArchFiles: 'extra-file.txt',
});
await ensureUniversal(out);
// Only a single merged asar
expect(
(await fs.readdir(path.resolve(out, 'Contents', 'Resources'))).filter((p) =>
p.endsWith('asar'),
),
).toEqual(['app.asar']);
}, 60000);
it('throws an error if `mergeASARs` is enabled and `singleArchFiles` is missing a unique file', async () => {
const out = path.resolve(appsOutPath, 'Error.app');
await expect(
makeUniversalApp({
x64AppPath: path.resolve(appsPath, 'X64Asar.app'),
arm64AppPath: path.resolve(appsPath, 'Arm64AsarExtraFile.app'),
outAppPath: out,
mergeASARs: true,
singleArchFiles: 'bad-rule',
}),
).rejects.toThrow(/Detected unique file "extra-file\.txt"/);
}, 60000);
it.todo('should not inject ElectronAsarIntegrity into `infoPlistsToIgnore`');
});
describe('no asar mode', () => {
it('should correctly merge two identical app folders', async () => {
const out = path.resolve(appsOutPath, 'MergedNoAsar.app');
await makeUniversalApp({
x64AppPath: path.resolve(appsPath, 'X64NoAsar.app'),
arm64AppPath: path.resolve(appsPath, 'Arm64NoAsar.app'),
outAppPath: out,
});
await ensureUniversal(out);
// Only a single app folder as they were identical
expect(
(await fs.readdir(path.resolve(out, 'Contents', 'Resources'))).filter((p) =>
p.startsWith('app'),
),
).toEqual(['app']);
}, 60000);
it.todo('should shim two different app folders');
});
// TODO: Add tests for
// * different asar files
// * identical app dirs
// * different app dirs
// * different app dirs with different macho files
// * identical app dirs with universal macho files
});