Skip to content

Commit

Permalink
feat: add view-hierarchy hash to cache. (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
asafkorem authored Sep 29, 2024
1 parent 66da2a1 commit eec9f5d
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 8 deletions.
12 changes: 10 additions & 2 deletions src/actions/StepPerformer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { CodeEvaluator } from '@/utils/CodeEvaluator';
import { SnapshotManager } from '@/utils/SnapshotManager';
import { PromptHandler, TestingFrameworkAPICatalog } from '@/types';
import * as fs from 'fs';
import * as crypto from 'crypto';

// Mock the 'fs' module to prevent actual file system operations during tests
jest.mock('fs');
jest.mock('crypto');

describe('StepPerformer', () => {
let stepPerformer: StepPerformer;
Expand Down Expand Up @@ -91,11 +92,18 @@ describe('StepPerformer', () => {
mockPromptHandler.runPrompt.mockResolvedValue(promptResult);
mockCodeEvaluator.evaluate.mockResolvedValue(codeEvaluationResult);

const viewHierarchyHash = 'hash';
(crypto.createHash as jest.Mock).mockReturnValue({
update: jest.fn().mockReturnValue({
digest: jest.fn().mockReturnValue(viewHierarchyHash),
}),
});

// Adjust fs mocks based on cacheExists
if (cacheExists) {
(fs.existsSync as jest.Mock).mockReturnValue(true);
const cacheData = {};
const cacheKey = JSON.stringify({ step: 'tap button', previous: [] });
const cacheKey = JSON.stringify({ step: 'tap button', previous: [], viewHierarchyHash });
// @ts-ignore
cacheData[cacheKey] = promptResult;
(fs.readFileSync as jest.Mock).mockReturnValue(JSON.stringify(cacheData));
Expand Down
12 changes: 7 additions & 5 deletions src/actions/StepPerformer.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { PromptCreator } from '@/utils/PromptCreator';
import { CodeEvaluator } from '@/utils/CodeEvaluator';
import { SnapshotManager } from '@/utils/SnapshotManager';
import {CodeEvaluationResult, PreviousStep, PromptHandler} from '@/types';
import {CodeEvaluationResult, PreviousStep, PromptHandler, TestingFrameworkDriver} from '@/types';
import * as fs from 'fs';
import * as path from 'path';
import * as crypto from 'crypto';

export class StepPerformer {
private cache: Map<string, any> = new Map();
Expand All @@ -20,8 +21,9 @@ export class StepPerformer {
this.cacheFilePath = path.resolve(process.cwd(), cacheFileName);
}

private getCacheKey(step: string, previous: PreviousStep[]): string {
return JSON.stringify({ step, previous });
private generateCacheKey(step: string, previous: PreviousStep[], viewHierarchy: string): string {
const viewHierarchyHash = crypto.createHash('md5').update(viewHierarchy).digest('hex');
return JSON.stringify({ step, previous, viewHierarchyHash });
}

private loadCacheFromFile(): void {
Expand Down Expand Up @@ -61,7 +63,7 @@ export class StepPerformer {
const isSnapshotImageAttached =
snapshot != null && this.promptHandler.isSnapshotImageSupported();

const cacheKey = this.getCacheKey(step, previous);
const cacheKey = this.generateCacheKey(step, previous, viewHierarchy);

if (this.cache.has(cacheKey)) {
const cachedPromptResult = this.cache.get(cacheKey);
Expand Down Expand Up @@ -96,7 +98,7 @@ export class StepPerformer {
result: undefined,
}];

const retryCacheKey = this.getCacheKey(step, newPrevious);
const retryCacheKey = this.generateCacheKey(step, newPrevious, viewHierarchy);

if (this.cache.has(retryCacheKey)) {
const cachedRetryPromptResult = this.cache.get(retryCacheKey);
Expand Down
10 changes: 9 additions & 1 deletion src/integration tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import { Copilot } from "@/Copilot";
import { PromptHandler, TestingFrameworkDriver } from "@/types";
import fs from 'fs';
import path from 'path';
import * as crypto from 'crypto';

jest.mock('fs');
jest.mock('path');
jest.mock('crypto');

describe('Copilot Integration Tests', () => {
let mockFrameworkDriver: jest.Mocked<TestingFrameworkDriver>;
Expand Down Expand Up @@ -37,6 +39,12 @@ describe('Copilot Integration Tests', () => {
mockFs.readFileSync.mockReturnValue('{}');
mockFs.writeFileSync.mockImplementation(() => {});
mockPath.resolve.mockImplementation((...paths) => paths.join('/'));

(crypto.createHash as jest.Mock).mockReturnValue({
update: jest.fn().mockReturnValue({
digest: jest.fn().mockReturnValue('hash'),
}),
});
});

afterEach(() => {
Expand Down Expand Up @@ -245,7 +253,7 @@ describe('Copilot Integration Tests', () => {
it('should read from existing cache file', async () => {
mockFs.existsSync.mockReturnValue(true);
mockFs.readFileSync.mockReturnValue(JSON.stringify({
'{"step":"Cached action","previous":[]}': '// Cached action code'
'{"step":"Cached action","previous":[],"viewHierarchyHash":"hash"}': '// Cached action code'
}));

await copilot.perform('Cached action');
Expand Down

0 comments on commit eec9f5d

Please sign in to comment.