Files
self/scripts/tests/checkPackageVersions.test.mjs
Justin Hernandez 20fa5c5adc [SELF-700] feat: add mock document generator demo (#995)
* feat: add mock document generator demo

* feat: add mock document generator

* fixes

* chore: refresh workflow cache

* update lock

* build

* updates

* more fixes

* code rabbit feedback

* compiles

* save wip

* updates

* merge with dev and fixes

* fix: align hoisting and demo Jest resolver (#1003)

* chore(app): map common src paths and declare svg flag module

* ci fix

* update lock

* save wip

* chore: address yarn lock issues (#1004)

* address yarn lock issues

* fix postinstall

* fix ci

* use metro js proxy

* android build working for /app

* save wip

* fix merge

* pipeline fixes

* format

* fix pipelines

* bump limit and split

* fix pipeline issues

* chore: decouple demo app build (#1013)

* chore: decouple demo app build

* chore: move demo app to workspace

* chore: unpublish demo workspace

* fix mobile sdk tests

* updates

* remove polyfills

* update merge

* update resolutions

* update resolutions

* fix merge

* fix paths

* save wip

* save wip fixes rd2

* working android

* update lock

* save wip ios building

* fix merge

* readd public key

* fixes

* ci fixes

* fixes

* fix web building

* fix ci

* fix tests

* update lock

* fix ci rd2

* formatting and fix ci

* fix

* finalize ci fixes

* fix tests and metro config paths for building

* save wip

* install missing package for pipeline

* fix wip app building

* wip react config

* save working emulator compile

* first round of pr fixes and feedback

* clean up demo app artifacts from sdk

* Add Gradle wrapper files for mobile-sdk-demo Android build

- Added gradlew, gradlew.bat, and gradle/wrapper/ directory
- Updated .gitignore to allow committing Gradle wrapper files
- Fixes Android build error: spawn ./gradlew ENOENT

* codex feedback and fixes

* fix tests

* file renames

* revert back to dev

* add types

* coderabbit fixes

* fix tests

* fix tests

* fix test

* fixes

* fix wip coderabbit issues

* coderabbit suggestions rd 2

* fix ci pipelines and addresss warnings

* cr fixes

* convert kebab to camelCase

* save wip fixes

* update reinstall and lock files

* fixes

* remove file

* fix lint

* fix polyfill fallback issues

* ensure that mock document is not on ofac list

* prettier
2025-09-27 13:59:47 -07:00

321 lines
8.7 KiB
JavaScript

#!/usr/bin/env node
import { test, describe, expect, beforeAll, afterAll } from 'vitest';
import { promises as fs } from 'fs';
import path from 'path';
import { execSync } from 'child_process';
import { fileURLToPath } from 'url';
// Resolve paths relative to this test file
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const testDir = path.join(__dirname, 'fixtures');
const scriptPath = path.resolve(__dirname, '..', 'check-package-versions.mjs');
describe('check-package-versions', () => {
beforeAll(async () => {
// Create test fixtures directory
await fs.mkdir(testDir, { recursive: true });
});
afterAll(async () => {
// Cleanup
await fs.rm(testDir, { recursive: true, force: true });
});
test('should pass when all versions are consistent', async () => {
// Create consistent package.json files
const consistentPkg = {
name: 'test-package',
version: '1.0.0',
dependencies: {
ethers: '^6.13.5',
'node-forge': '^1.3.1',
'poseidon-lite': '^0.3.0',
snarkjs: '^0.7.5',
react: '^18.3.1',
'react-native': '0.76.9',
'@tamagui/config': '1.126.14',
'@tamagui/lucide-icons': '1.126.14',
typescript: '^5.9.2',
prettier: '^3.5.3',
'@types/node': '^22.0.0',
},
engines: { node: '>=22 <23' },
};
await fs.mkdir(path.join(testDir, 'pkg1'), { recursive: true });
await fs.mkdir(path.join(testDir, 'pkg2'), { recursive: true });
await fs.writeFile(
path.join(testDir, 'pkg1', 'package.json'),
JSON.stringify(consistentPkg, null, 2),
);
await fs.writeFile(
path.join(testDir, 'pkg2', 'package.json'),
JSON.stringify(consistentPkg, null, 2),
);
// Run script in test directory
const result = execSync(`node ${scriptPath}`, {
cwd: testDir,
encoding: 'utf8',
});
expect(result).toContain(
'✅ All package versions are consistent across the monorepo!',
);
});
test('should detect other package mismatches', async () => {
await fs.mkdir(path.join(testDir, 'pkg1'), { recursive: true });
await fs.mkdir(path.join(testDir, 'pkg2'), { recursive: true });
const pkg1 = {
dependencies: {
prettier: '^3.5.3',
typescript: '^5.9.2',
},
};
const pkg2 = {
dependencies: {
prettier: '^3.3.3',
typescript: '^5.8.0',
},
};
await fs.writeFile(
path.join(testDir, 'pkg1', 'package.json'),
JSON.stringify(pkg1, null, 2),
);
await fs.writeFile(
path.join(testDir, 'pkg2', 'package.json'),
JSON.stringify(pkg2, null, 2),
);
try {
execSync(`node ${scriptPath}`, {
cwd: testDir,
encoding: 'utf8',
});
expect.fail('Should have thrown an error');
} catch (error) {
expect(error.status).toBe(1);
expect(error.stdout).toContain('📦 OTHER VERSION MISMATCHES:');
expect(error.stdout).toContain('prettier:');
expect(error.stdout).toContain('typescript:');
}
});
test('should fail when critical packages have different versions', async () => {
const pkg1 = {
name: 'test-package-1',
dependencies: {
ethers: '^6.11.0',
'node-forge': '^1.3.1',
},
};
const pkg2 = {
name: 'test-package-2',
dependencies: {
ethers: '^6.13.5',
'node-forge': 'github:remicolin/forge',
},
};
await fs.mkdir(path.join(testDir, 'pkg1'), { recursive: true });
await fs.mkdir(path.join(testDir, 'pkg2'), { recursive: true });
await fs.writeFile(
path.join(testDir, 'pkg1', 'package.json'),
JSON.stringify(pkg1, null, 2),
);
await fs.writeFile(
path.join(testDir, 'pkg2', 'package.json'),
JSON.stringify(pkg2, null, 2),
);
try {
execSync(`node ${scriptPath}`, {
cwd: testDir,
encoding: 'utf8',
});
expect.fail('Should have thrown an error');
} catch (error) {
expect(error.status).toBe(1);
expect(error.stdout).toContain('🚨 CRITICAL VERSION MISMATCHES:');
expect(error.stdout).toContain('ethers:');
expect(error.stdout).toContain('node-forge:');
}
});
test('should detect workflow version mismatches', async () => {
// Create workflow with different Node.js version
const workflowContent = `
name: Test
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v4
with:
node-version: 20
`;
await fs.mkdir(path.join(testDir, '.github', 'workflows'), {
recursive: true,
});
await fs.writeFile(
path.join(testDir, '.github', 'workflows', 'test.yml'),
workflowContent,
);
// Create package.json with Node 22 engine
const pkg = {
engines: { node: '>=22 <23' },
};
await fs.writeFile(
path.join(testDir, 'package.json'),
JSON.stringify(pkg, null, 2),
);
try {
execSync(`node ${scriptPath}`, {
cwd: testDir,
encoding: 'utf8',
});
expect.fail('Should have thrown an error');
} catch (error) {
expect(error.status).toBe(1);
expect(error.stdout).toContain('Expected: >=22 <23');
expect(error.stdout).toContain('Found: 20');
}
});
test('should detect React Native ecosystem inconsistencies', async () => {
await fs.mkdir(path.join(testDir, 'pkg1'), { recursive: true });
await fs.mkdir(path.join(testDir, 'pkg2'), { recursive: true });
const pkg1 = {
dependencies: {
react: '^18.3.1',
'react-native': '0.76.9',
},
};
const pkg2 = {
dependencies: {
react: '^18.0.0',
'react-native': '0.74.0',
},
};
await fs.writeFile(
path.join(testDir, 'pkg1', 'package.json'),
JSON.stringify(pkg1, null, 2),
);
await fs.writeFile(
path.join(testDir, 'pkg2', 'package.json'),
JSON.stringify(pkg2, null, 2),
);
try {
execSync(`node ${scriptPath}`, {
cwd: testDir,
encoding: 'utf8',
});
expect.fail('Should have thrown an error');
} catch (error) {
expect(error.status).toBe(1);
expect(error.stdout).toContain('react:');
expect(error.stdout).toContain('react-native:');
}
});
test('should detect Tamagui version inconsistencies', async () => {
await fs.mkdir(path.join(testDir, 'pkg1'), { recursive: true });
await fs.mkdir(path.join(testDir, 'pkg2'), { recursive: true });
const pkg1 = {
dependencies: {
'@tamagui/config': '1.126.14',
'@tamagui/lucide-icons': '1.126.14',
},
};
const pkg2 = {
dependencies: {
'@tamagui/config': '1.129.3',
'@tamagui/lucide-icons': '1.129.3',
},
};
await fs.writeFile(
path.join(testDir, 'pkg1', 'package.json'),
JSON.stringify(pkg1, null, 2),
);
await fs.writeFile(
path.join(testDir, 'pkg2', 'package.json'),
JSON.stringify(pkg2, null, 2),
);
try {
execSync(`node ${scriptPath}`, {
cwd: testDir,
encoding: 'utf8',
});
expect.fail('Should have thrown an error');
} catch (error) {
expect(error.status).toBe(1);
expect(error.stdout).toContain('@tamagui/config:');
expect(error.stdout).toContain('@tamagui/lucide-icons:');
}
});
test('should handle missing files gracefully', async () => {
// Clean up any leftover files from previous tests
await fs.rm(testDir, { recursive: true, force: true });
await fs.mkdir(testDir, { recursive: true });
// Empty directory should not crash
const result = execSync(`node ${scriptPath}`, {
cwd: testDir,
encoding: 'utf8',
});
expect(result).toContain(
'✅ All package versions are consistent across the monorepo!',
);
});
test('should provide helpful fix instructions', async () => {
await fs.mkdir(path.join(testDir, 'pkg1'), { recursive: true });
await fs.mkdir(path.join(testDir, 'pkg2'), { recursive: true });
const pkg1 = {
dependencies: { ethers: '^6.11.0' },
};
const pkg2 = {
dependencies: { ethers: '^6.13.5' },
};
await fs.writeFile(
path.join(testDir, 'pkg1', 'package.json'),
JSON.stringify(pkg1, null, 2),
);
await fs.writeFile(
path.join(testDir, 'pkg2', 'package.json'),
JSON.stringify(pkg2, null, 2),
);
try {
execSync(`node ${scriptPath}`, {
cwd: testDir,
encoding: 'utf8',
});
expect.fail('Should have thrown an error');
} catch (error) {
expect(error.status).toBe(1);
expect(error.stdout).toContain('📋 Mismatched Packages:');
expect(error.stdout).toContain('🚨 Critical:');
expect(error.stdout).toContain('• ethers:');
}
});
});