Skip to content

Commit

Permalink
feat: improve file cache handling and normalize paths
Browse files Browse the repository at this point in the history
This commit improves the file cache handling by introducing the `normalizePath` function to ensure consistent path representation. It also updates the cache entries to use ISO string format for `created` and `modified` dates. Additionally, the commit fixes the e2e test for cross-platform compatibility.
  • Loading branch information
gmickel committed Jul 21, 2024
1 parent cb9609d commit a87735d
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 18 deletions.
39 changes: 24 additions & 15 deletions src/utils/file-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import crypto from 'node:crypto';
import path from 'node:path';
import fs from 'fs-extra';
import type { FileInfo } from '../core/file-processor';
import { normalizePath } from './normalize-path';

interface CacheEntry {
hash: string;
Expand Down Expand Up @@ -36,8 +37,17 @@ export class FileCache {
const content = await fs.readFile(this.cacheFile, 'utf-8');
try {
this.cache = JSON.parse(content, (key, value) => {
if (key === 'created' || key === 'modified') {
return new Date(value);
if (typeof value === 'object' && value !== null) {
if (value.type === 'Date') {
return new Date(value.value);
}
if (value.created && value.modified) {
value.created = new Date(value.created);
value.modified = new Date(value.modified);
}
}
if (key === 'path') {
return normalizePath(value);
}
return value;
});
Expand Down Expand Up @@ -72,19 +82,18 @@ export class FileCache {
await fs.ensureDir(path.dirname(this.cacheFile));
const tempFile = `${this.cacheFile}.tmp`;

// Stringify cache items individually
const cacheEntries = Object.entries(this.cache)
.map(([key, value]) => {
try {
return `"${key}":${JSON.stringify(value)}`;
} catch (error) {
console.warn(`Failed to stringify cache entry for ${key}:`, error);
return null;
}
})
.filter(Boolean);

const cacheString = `{${cacheEntries.join(',')}}`;
const cacheString = JSON.stringify(this.cache, (key, value) => {
if (value instanceof Date) {
return { type: 'Date', value: value.toISOString() };
}
if (key === 'created' || key === 'modified') {
return { type: 'Date', value: new Date(value).toISOString() };
}
if (key === 'path') {
return normalizePath(value);
}
return value;
});

await fs.writeFile(tempFile, cacheString, 'utf-8');
await fs.rename(tempFile, this.cacheFile);
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/cli-commands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,5 +279,5 @@ describe('CLI Commands', () => {
await fs.remove(testDir1);
await fs.remove(testDir2);
}
});
}, 30000);
});
27 changes: 25 additions & 2 deletions tests/unit/file-cache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import fs from 'fs-extra';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import type { FileInfo } from '../../src/core/file-processor';
import { FileCache } from '../../src/utils/file-cache';
import { normalizePath } from '../../src/utils/normalize-path';

describe('FileCache', () => {
const TEST_DIR = path.join(os.tmpdir(), 'file-cache-test');
Expand Down Expand Up @@ -82,7 +83,7 @@ describe('FileCache', () => {
});

it('should persist cache to disk and load it', async () => {
const testFile = path.join(TEST_DIR, 'persist.txt');
const testFile = normalizePath(path.join(TEST_DIR, 'persist.txt'));
await fs.writeFile(testFile, 'persist test');

const fileInfo: FileInfo = {
Expand All @@ -102,7 +103,29 @@ describe('FileCache', () => {
const newFileCache = new FileCache(CACHE_FILE);
const retrieved = await newFileCache.get(testFile);

expect(retrieved).toEqual(fileInfo);
expect(retrieved).toBeDefined();
expect(retrieved).not.toBeNull();

if (retrieved) {
expect(normalizePath(retrieved.path)).toEqual(
normalizePath(fileInfo.path),
);
expect(retrieved.content).toEqual(fileInfo.content);
expect(retrieved.size).toEqual(fileInfo.size);
expect(retrieved.language).toEqual(fileInfo.language);
expect(retrieved.created).toBeInstanceOf(Date);
expect(retrieved.modified).toBeInstanceOf(Date);
expect(retrieved.created.getTime()).toBeCloseTo(
fileInfo.created.getTime(),
-3,
);
expect(retrieved.modified.getTime()).toBeCloseTo(
fileInfo.modified.getTime(),
-3,
);
} else {
throw new Error('Retrieved cache item is null');
}
});

it('should clear the cache', async () => {
Expand Down

0 comments on commit a87735d

Please sign in to comment.