This commit is contained in:
2025-11-03 16:02:12 +00:00
parent 4823eb9082
commit 1f2937b387
11 changed files with 15601 additions and 4350 deletions

View File

@@ -1,15 +1,127 @@
import { expect, tap } from '@push.rocks/tapbundle';
import { expect, tap } from '@git.zone/tstest/tapbundle';
import * as smartupdate from '../ts/index.js';
let testSmartUpdate: smartupdate.SmartUpdate;
let silentSmartUpdate: smartupdate.SmartUpdate;
tap.test('should create an instance of SmartUpdate', async () => {
// Test suite for backward compatibility
tap.test('backward compatibility: should create an instance of SmartUpdate', async () => {
testSmartUpdate = new smartupdate.SmartUpdate();
expect(testSmartUpdate).toBeInstanceOf(smartupdate.SmartUpdate);
});
tap.test('should check for a npm module', async () => {
tap.test('backward compatibility: should check for a npm module using old API', async () => {
const result = await testSmartUpdate.check('lodash', '1.0.5');
expect(result).toBeTrue();
});
tap.start();
// Test suite for new modern API
tap.test('modern API: should create SmartUpdate with custom options', async () => {
silentSmartUpdate = new smartupdate.SmartUpdate({
logLevel: 'SILENT',
noColor: true,
cacheDuration: { minutes: 30 },
});
expect(silentSmartUpdate).toBeInstanceOf(smartupdate.SmartUpdate);
});
tap.test('modern API: checkForUpdate should return rich result object', async () => {
const result = await silentSmartUpdate.checkForUpdate({
packageName: 'lodash',
currentVersion: '1.0.0',
cacheStrategy: 'never',
});
// Verify result structure
expect(result).toBeTypeOf('object');
expect(result.status).toBeTypeOf('string');
expect(result.packageName).toEqual('lodash');
expect(result.currentVersion).toEqual('1.0.0');
expect(result.checkTime).toBeInstanceOf(Date);
expect(result.cacheHit).toBeTypeOf('boolean');
// Should have update available (1.0.0 is old)
expect(result.status).toEqual('update-available');
expect(result.latestVersion).toBeTypeOf('string');
});
tap.test('modern API: checkForUpdate with up-to-date version', async () => {
const result = await silentSmartUpdate.checkForUpdate({
packageName: '@push.rocks/smartversion',
currentVersion: '999.999.999', // Future version
cacheStrategy: 'never',
});
expect(result.status).toEqual('up-to-date');
expect(result.latestVersion).toBeTypeOf('string');
});
tap.test('modern API: getLatestVersion utility method', async () => {
const latestVersion = await silentSmartUpdate.getLatestVersion('lodash');
expect(latestVersion).toBeTypeOf('string');
expect(latestVersion).toMatch(/^\d+\.\d+\.\d+/); // Semver format
});
tap.test('modern API: error handling for non-existent package', async () => {
const result = await silentSmartUpdate.checkForUpdate({
packageName: 'this-package-definitely-does-not-exist-12345',
currentVersion: '1.0.0',
cacheStrategy: 'never',
});
expect(result.status).toEqual('error');
expect(result.error).toBeInstanceOf(Error);
});
tap.test('modern API: cache strategy works', async () => {
// Clear cache first to ensure clean state
const testPackage = 'express';
try {
await silentSmartUpdate.clearCache(testPackage);
} catch (e) {
// Cache might not exist, that's fine
}
// First check - should hit registry with 'never' strategy
const result1 = await silentSmartUpdate.checkForUpdate({
packageName: testPackage,
currentVersion: '1.0.0',
cacheStrategy: 'never',
});
expect(result1.cacheHit).toBeFalse();
expect(result1.status).toEqual('update-available');
// Do a second check with time-based that will create cache
const result2 = await silentSmartUpdate.checkForUpdate({
packageName: testPackage,
currentVersion: '1.0.0',
cacheStrategy: 'time-based',
});
// Third immediate check - should use cache with 'always' strategy
const result3 = await silentSmartUpdate.checkForUpdate({
packageName: testPackage,
currentVersion: '1.0.0',
cacheStrategy: 'always',
});
expect(result3.cacheHit).toBeTrue();
expect(result3.status).toEqual('check-skipped');
// nextCheckTime may or may not be set depending on cache strategy implementation
if (result3.nextCheckTime) {
expect(result3.nextCheckTime).toBeInstanceOf(Date);
}
});
tap.test('modern API: exports all types and classes', () => {
// Verify exports
expect(smartupdate.SmartUpdate).toBeTypeOf('function');
expect(smartupdate.UpdateCacheManager).toBeTypeOf('function');
expect(smartupdate.UpdateNotifier).toBeTypeOf('function');
expect(smartupdate.RegistryUnavailableError).toBeTypeOf('function');
expect(smartupdate.PackageNotFoundError).toBeTypeOf('function');
expect(smartupdate.LOG_LEVELS).toBeTypeOf('object');
});
export default tap.start();