Skip to content

Commit

Permalink
fix indexing problem
Browse files Browse the repository at this point in the history
  • Loading branch information
shubhbapna committed Feb 1, 2024
1 parent 5ede73b commit ce71d84
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 7 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,6 @@ Schema for `mockSteps`

**Important Notes**:
- Please use `MockGithub` to run the workflow in a clean safe github repository so that any changes made to the Workflow file are done in the test environment and not to the actual file.
- Using `before` or `after` will cause changes in the indexing of the steps which will impact the subsequent mock steps that use `before`, `after` or `index`.

#### Run result

Expand Down
17 changes: 11 additions & 6 deletions src/step-mocker/step-mocker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,24 @@ export class StepMocker {
async mock(mockSteps: MockStep) {
const filePath = this.getWorkflowPath();
const workflow = await this.readWorkflowFile(filePath);
for (const job of Object.keys(mockSteps)) {
for (const mockStep of mockSteps[job]) {
const { step, stepIndex } = this.locateStep(workflow, job, mockStep);
for (const jobId of Object.keys(mockSteps)) {
const stepsToAdd = [];
for (const mockStep of mockSteps[jobId]) {
const { step, stepIndex } = this.locateStep(workflow, jobId, mockStep);
if (step) {
if (isStepIdentifierUsingBeforeOrAfter(mockStep)) {
this.addStep(workflow, job, stepIndex, mockStep);
// need to adjust the step index if there were elements added previously
const adjustIndex: number = stepsToAdd.filter(s => s.stepIndex < stepIndex).length;
// we will only actually add the steps at the end so as to avoid indexing errors in subsequent add steps
stepsToAdd.push({jobId, stepIndex: stepIndex + adjustIndex, mockStep});
} else {
this.updateStep(workflow, job, stepIndex, mockStep);
this.updateStep(workflow, jobId, stepIndex, mockStep);
}
} else {
throw new Error("Could not find step");
}
}
stepsToAdd.forEach(s => this.addStep(workflow, s.jobId, s.stepIndex, s.mockStep));
}
return this.writeWorkflowFile(filePath, workflow);
}
Expand All @@ -62,7 +67,7 @@ export class StepMocker {
? workflow.jobs[jobId].steps.length
: indexToInsertAt + 1;
}
workflow.jobs[jobId].steps.splice(indexToInsertAt, 0, mockStep.mockWith);
workflow.jobs[jobId].steps.splice(indexToInsertAt, 0, {...mockStep.mockWith});
}
}

Expand Down
102 changes: 102 additions & 0 deletions test/unit/step-mocker/step-mocker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -367,4 +367,106 @@ describe("update step", () => {
},
});
});
});

describe("add step", () => {
beforeEach(() => {
existsSyncMock.mockReturnValueOnce(true);
writeFileSyncMock.mockReturnValueOnce(undefined);
});
test.each([
["index", 0, 0],
["name", "secrets", 0]
])("step found using before: %p", async (_title, before, index) => {
const data = await readFile(path.join(resources, "steps.yaml"), "utf8");
readFileSyncMock.mockReturnValueOnce(data);
const stepMocker = new StepMocker("workflow.yaml", __dirname);
const mockWith = {
name: "added new step",
run: "echo new step"
};
await stepMocker.mock({
name: [
{
before,
mockWith,
},
],
});
const outputWorkflow = parse(data) as GithubWorkflow;
outputWorkflow.jobs["name"].steps.splice(index, 0, mockWith);
expect(writeFileSyncMock).toHaveBeenLastCalledWith(
path.join(__dirname, "workflow.yaml"),
stringify(outputWorkflow),
"utf8"
);
});

test.each([
["index", 3, 4],
["name", "secrets", 2]
])("step found using after: %p", async (_title, after, index) => {
const data = await readFile(path.join(resources, "steps.yaml"), "utf8");
readFileSyncMock.mockReturnValueOnce(data);
const stepMocker = new StepMocker("workflow.yaml", __dirname);
const mockWith = {
name: "added new step",
run: "echo new step"
};
await stepMocker.mock({
name: [
{
after,
mockWith,
},
],
});
const outputWorkflow = parse(data) as GithubWorkflow;
outputWorkflow.jobs["name"].steps.splice(index, 0, mockWith);
expect(writeFileSyncMock).toHaveBeenLastCalledWith(
path.join(__dirname, "workflow.yaml"),
stringify(outputWorkflow),
"utf8"
);
});

test("multiple add steps with indexing", async () => {
const data = await readFile(path.join(resources, "steps.yaml"), "utf8");
readFileSyncMock.mockReturnValueOnce(data);
const stepMocker = new StepMocker("workflow.yaml", __dirname);
const mockWith = {
name: "added new step",
run: "echo new step"
};
await stepMocker.mock({
name: [
{
after: 1,
mockWith
},
{
before: 0,
mockWith,
},
{
before: 2,
mockWith
},
{
index: 3,
mockWith: "echo updated"
}
],
});
const outputWorkflow = parse(data) as GithubWorkflow;
outputWorkflow.jobs["name"].steps[ outputWorkflow.jobs["name"].steps.length - 1].run = "echo updated";
outputWorkflow.jobs["name"].steps.splice(0, 0, {...mockWith});
outputWorkflow.jobs["name"].steps.splice(3, 0, {...mockWith});
outputWorkflow.jobs["name"].steps.splice(3, 0, {...mockWith});
expect(writeFileSyncMock).toHaveBeenLastCalledWith(
path.join(__dirname, "workflow.yaml"),
stringify(outputWorkflow),
"utf8"
);
});
});

0 comments on commit ce71d84

Please sign in to comment.