Skip to content

Commit

Permalink
chore: Change the default behavior to cache saving
Browse files Browse the repository at this point in the history
- The parameter of the 'end' function changed from "saveToCache" to "isCacheDisabled"
- Test were modified accordingly
  • Loading branch information
LironMShemen committed Dec 10, 2024
1 parent fd20a0e commit d08c588
Show file tree
Hide file tree
Showing 8 changed files with 16,404 additions and 45 deletions.
4 changes: 2 additions & 2 deletions src/Copilot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,15 @@ describe('Copilot', () => {
});

describe('end', () => {
it('end with false should not save to cache', async () => {
it('end with disable cache=true should not save to cache', async () => {
mockCache();

Copilot.init(mockConfig);
const instance = Copilot.getInstance();
instance.start();

await instance.performStep(INTENT);
instance.end(false);
instance.end(true);

expect(mockedCacheFile).toBeUndefined();
});
Expand Down
8 changes: 3 additions & 5 deletions src/Copilot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,13 @@ export class Copilot {
private previousSteps: PreviousStep[] = [];
private stepPerformer: StepPerformer;
private cacheHandler: CacheHandler;
//private isTestSuiteSuccessful: boolean;
private isRunning: boolean = false;

private constructor(config: Config) {
this.promptCreator = new PromptCreator(config.frameworkDriver.apiCatalog);
this.codeEvaluator = new CodeEvaluator();
this.snapshotManager = new SnapshotManager(config.frameworkDriver);
this.cacheHandler = new CacheHandler();
//this.isTestSuiteSuccessful = true;
this.stepPerformer = new StepPerformer(
config.frameworkDriver.apiCatalog.context,
this.promptCreator,
Expand Down Expand Up @@ -90,16 +88,16 @@ export class Copilot {

/**
* Ends the Copilot test flow and optionally saves the temporary cache to the main cache.
* @param saveToCache - boolean flag indicating whether the temporary cache data should be saved to the main cache.
* @param isCacheDisabled - boolean flag indicating whether the temporary cache data should be saved to the main cache.
*/
end(saveToCache: boolean = true): void {
end(isCacheDisabled: boolean = false): void {
if (!this.isRunning) {
throw new CopilotError('Copilot is not running. Please call the `start()` method before ending the test flow.');
}

this.isRunning = false;

if (saveToCache)
if (!isCacheDisabled)
this.cacheHandler.flushTemporaryCache();
}

Expand Down
5 changes: 4 additions & 1 deletion src/actions/StepPerformer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {PromptHandler, TestingFrameworkAPICatalog} from '@/types';
import * as fs from 'fs';
import * as crypto from 'crypto';
import mock = jest.mock;
import copilot from "../index";

jest.mock('fs');
jest.mock('crypto');
Expand Down Expand Up @@ -283,6 +284,8 @@ describe('StepPerformer', () => {
expect(mockPromptCreator.createPrompt).toHaveBeenCalled();
expect(mockPromptHandler.runPrompt).toHaveBeenCalled();
expect(mockCodeEvaluator.evaluate).toHaveBeenCalledWith('generated code', mockContext);
expect(fs.writeFileSync).toHaveBeenCalled(); // Need to save cache
expect(mockCacheHandler.addToTemporaryCache).toHaveBeenCalled();

//expect(fs.writeFileSync).toHaveBeenCalled(); // Need to save cache
});
});
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ const copilot: CopilotFacade = {
start: () => {
Copilot.getInstance().start();
},
end: (saveToCache?: boolean) => {
Copilot.getInstance().end(saveToCache);
end: (isCacheDisabled?: boolean) => {
Copilot.getInstance().end(isCacheDisabled);
},
perform: async (...steps: string[]) => {
const copilotInstance = Copilot.getInstance();
Expand Down
48 changes: 23 additions & 25 deletions src/integration tests/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import copilot from "@/index";
import fs from 'fs';
import { Copilot } from "@/Copilot";
import { PromptHandler, TestingFrameworkDriver } from "@/types";
import * as crypto from 'crypto';
Expand Down Expand Up @@ -28,14 +29,6 @@ describe('Copilot Integration Tests', () => {
isSnapshotImageSupported: jest.fn().mockReturnValue(true)
};

// mockFs = fs as jest.Mocked<typeof fs>;
// mockPath = path as jest.Mocked<typeof path>;
//
// mockFs.existsSync.mockReturnValue(false);
// mockFs.readFileSync.mockReturnValue('{}');
// mockFs.writeFileSync.mockImplementation(() => {});
// mockPath.resolve.mockImplementation((...paths) => paths.join('/'));

mockCache();

(crypto.createHash as jest.Mock).mockReturnValue({
Expand Down Expand Up @@ -250,7 +243,7 @@ describe('Copilot Integration Tests', () => {
mockPromptHandler.runPrompt.mockResolvedValue('// Perform action');

await copilot.perform('Perform action');
copilot.end(true)
copilot.end(false)

expect(mockedCacheFile).toEqual({
'{"step":"Perform action","previous":[],"viewHierarchyHash":"hash"}': '// Perform action'
Expand Down Expand Up @@ -278,22 +271,27 @@ describe('Copilot Integration Tests', () => {
});
});

// it('should handle fs.readFileSync errors', async () => {
// mockFs.existsSync.mockReturnValue(true);
// mockFs.readFileSync.mockImplementation(() => { throw new Error('Read error'); });
// mockPromptHandler.runPrompt.mockResolvedValue('// New action code');
//
// await copilot.perform('Action with read error');
//
// expect(mockPromptHandler.runPrompt).toHaveBeenCalled();
// });

// it('should handle fs.writeFileSync errors', async () => {
// mockFs.writeFileSync.mockImplementation(() => { throw new Error('Write error'); });
// mockPromptHandler.runPrompt.mockResolvedValue('// Action code');
//
// await expect(copilot.perform('Action with write error')).resolves.not.toThrow();
// });
it('should handle fs.readFileSync errors', async () => {
mockCache({}); // Set up an initial mocked file
(fs.readFileSync as jest.Mock).mockImplementation(() => {
throw new Error('Read error');
});
mockPromptHandler.runPrompt.mockResolvedValue('// New action code');

await copilot.perform('Action with read error');

expect(mockPromptHandler.runPrompt).toHaveBeenCalled();
});

it('should handle fs.writeFileSync errors', async () => {
mockCache(undefined); // No mocked file exists
(fs.writeFileSync as jest.Mock).mockImplementation(() => {
throw new Error('Write error');
});
mockPromptHandler.runPrompt.mockResolvedValue('// Action code');

await expect(copilot.perform('Action with write error')).resolves.not.toThrow();
});
});

describe('Feature Support', () => {
Expand Down
6 changes: 3 additions & 3 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ export interface CopilotFacade {

/**
* Finalizes the test flow and optionally saves temporary cache data to the main cache.
* If `saveToCache` is true, the temporary cache will be saved. True is the default value.
* @param saveToCache
* If `isCacheDisabled` is true, the temporary cache will not be saved. False is the default value.
* @param isCacheDisabled
* @note This must be called after the test flow is complete.
*/
end: (saveToCache?: boolean) => void;
end: (isCacheDisabled?: boolean) => void;

/**
* Performs a testing operation or series of testing operations in the app based on the given `steps`.
Expand Down
35 changes: 28 additions & 7 deletions src/utils/__snapshots__/PromptCreator.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,18 @@ Your task is to generate the minimal executable code to perform the following in
Please follow these steps carefully:
1. Analyze the provided intent, the view hierarchy, and the snapshot image to understand the required action.
2. Determine if the intent can be fully validated visually using the snapshot image.
3. If the intent can be visually analyzed and passes the visual check, return only comments explaining the successful visual assertion.
4. If the visual assertion fails, return code that throws an informative error explaining the failure.
5. If visual validation is not possible, proceed to generate the minimal executable code required to perform the intent.
6. If you cannot generate the relevant code due to ambiguity or invalid intent, return code that throws an informative error explaining the problem in one sentence.
7. Wrap the generated code with backticks, without any additional formatting.
8. Do not provide any additional code beyond the minimal executable code required to perform the intent.
2. Assess the positions of elements within the screen layout. Ensure that tests accurately reflect their intended locations, such as whether an element is centered or positioned relative to others. Tests should fail if the actual locations do not align with the expected configuration.
3. Determine if the intent can be fully validated visually using the snapshot image.
4. If the intent can be visually analyzed and passes the visual check, return only comments explaining the successful visual assertion.
5. If the visual assertion fails, return code that throws an informative error explaining the failure.
6. If visual validation is not possible, proceed to generate the minimal executable code required to perform the intent.
7. If you cannot generate the relevant code due to ambiguity or invalid intent, return code that throws an informative error explaining the problem in one sentence.
8. Wrap the generated code with backticks, without any additional formatting.
9. Do not provide any additional code beyond the minimal executable code required to perform the intent.
### Verify the prompt
Before generating the code, please review the provided context and instructions to ensure they are clear and unambiguous. If you encounter any issues or have questions, please throw an informative error explaining the problem.
### Examples
Expand Down Expand Up @@ -134,6 +139,10 @@ Generate the minimal executable code to perform the following intent: "expect bu
<View><Button testID="submit" title="Submit" /></View>
\`\`\`
### Snapshot image
No snapshot image is attached for this intent.
## Available Testing Framework API
### Actions
Expand Down Expand Up @@ -210,6 +219,10 @@ Please follow these steps carefully:
4. Wrap the generated code with backticks, without any additional formatting.
5. Do not provide any additional code beyond the minimal executable code required to perform the intent.
### Verify the prompt
Before generating the code, please review the provided context and instructions to ensure they are clear and unambiguous. If you encounter any issues or have questions, please throw an informative error explaining the problem.
### Examples
#### Example of throwing an informative error:
Expand Down Expand Up @@ -238,6 +251,10 @@ Generate the minimal executable code to perform the following intent: "tap butto
<View><Button testID="submit" title="Submit" /></View>
\`\`\`
### Snapshot image
No snapshot image is attached for this intent.
### Previous intents
#### Step 1
Expand Down Expand Up @@ -331,6 +348,10 @@ Please follow these steps carefully:
4. Wrap the generated code with backticks, without any additional formatting.
5. Do not provide any additional code beyond the minimal executable code required to perform the intent.
### Verify the prompt
Before generating the code, please review the provided context and instructions to ensure they are clear and unambiguous. If you encounter any issues or have questions, please throw an informative error explaining the problem.
### Examples
#### Example of throwing an informative error:
Expand Down
Loading

0 comments on commit d08c588

Please sign in to comment.