fixed the rest of the concerns, refactored portions of the gitGraphParser test to handle async actions

This commit is contained in:
Austin Fulbright
2024-08-05 13:53:51 -04:00
parent 9ed38ccf3a
commit 2a38d46fd9
4 changed files with 378 additions and 447 deletions

View File

@@ -44,7 +44,6 @@ function getID() {
return random({ length: 7 });
}
/**
* @param list - list of items
* @param fn - function to get the key
@@ -88,7 +87,7 @@ export const commit = function (msg: string, id: string, type: number, tags?: st
msg = common.sanitizeText(msg, config);
tags = tags?.map((tag) => common.sanitizeText(tag, config));
const newCommit: Commit = {
id: id ? id : state.records.seq + '-' + getId(),
id: id ? id : state.records.seq + '-' + getID(),
message: msg,
seq: state.records.seq++,
type: type ?? commitType.NORMAL,
@@ -109,12 +108,12 @@ export const branch = function (name: string, order?: number) {
throw new Error(
`Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using "checkout ${name}")`
);
}
state.records.branches.set(name, state.records.head != null ? state.records.head.id : null);
state.records.branchConfig.set(name, { name, order });
checkout(name);
log.debug('in createBranch');
}
state.records.branches.set(name, state.records.head != null ? state.records.head.id : null);
state.records.branchConfig.set(name, { name, order });
checkout(name);
log.debug('in createBranch');
};
export const merge = (
@@ -123,9 +122,10 @@ export const merge = (
overrideType?: number,
customTags?: string[]
): void => {
otherBranch = common.sanitizeText(otherBranch, getConfig());
const config = getConfig();
otherBranch = common.sanitizeText(otherBranch, config);
if (customId) {
customId = common.sanitizeText(customId, getConfig());
customId = common.sanitizeText(customId, config);
}
const currentBranchCheck: string | null | undefined = state.records.branches.get(
state.records.currBranch
@@ -150,7 +150,8 @@ export const merge = (
expected: ['branch abc'],
};
throw error;
} else if (currentCommit === undefined || !currentCommit) {
}
if (currentCommit === undefined || !currentCommit) {
const error: any = new Error(
`Incorrect usage of "merge". Current branch (${state.records.currBranch})has no commits`
);
@@ -162,7 +163,8 @@ export const merge = (
expected: ['commit'],
};
throw error;
} else if (!state.records.branches.has(otherBranch)) {
}
if (!state.records.branches.has(otherBranch)) {
const error: any = new Error(
'Incorrect usage of "merge". Branch to be merged (' + otherBranch + ') does not exist'
);
@@ -174,7 +176,8 @@ export const merge = (
expected: [`branch ${otherBranch}`],
};
throw error;
} else if (otherCommit === undefined || !otherCommit) {
}
if (otherCommit === undefined || !otherCommit) {
const error: any = new Error(
'Incorrect usage of "merge". Branch to be merged (' + otherBranch + ') has no commits'
);
@@ -186,7 +189,8 @@ export const merge = (
expected: ['"commit"'],
};
throw error;
} else if (currentCommit === otherCommit) {
}
if (currentCommit === otherCommit) {
const error: any = new Error('Incorrect usage of "merge". Both branches have same head');
error.hash = {
text: `merge ${otherBranch}`,
@@ -196,7 +200,8 @@ export const merge = (
expected: ['branch abc'],
};
throw error;
} else if (customId && state.records.commits.has(customId)) {
}
if (customId && state.records.commits.has(customId)) {
const error: any = new Error(
'Incorrect usage of "merge". Commit with id:' +
customId +
@@ -218,7 +223,7 @@ export const merge = (
const verifiedBranch: string = otherBranchCheck ? otherBranchCheck : ''; //figure out a cleaner way to do this
const commit: Commit = {
id: customId ? customId : state.records.seq + '-' + getId(),
id: customId ? customId : state.records.seq + '-' + getID(),
message: `merged branch ${otherBranch} into ${state.records.currBranch}`,
seq: state.records.seq++,
parents: [state.records.head == null ? null : state.records.head.id, verifiedBranch],
@@ -242,12 +247,13 @@ export const cherryPick = function (
parentCommitId: string
) {
log.debug('Entering cherryPick:', sourceId, targetId, tags);
sourceId = common.sanitizeText(sourceId, getConfig());
targetId = common.sanitizeText(targetId, getConfig());
const config = getConfig();
sourceId = common.sanitizeText(sourceId, config);
targetId = common.sanitizeText(targetId, config);
tags = tags?.map((tag) => common.sanitizeText(tag, config));
parentCommitId = common.sanitizeText(parentCommitId, getConfig());
parentCommitId = common.sanitizeText(parentCommitId, config);
if (!sourceId || !state.records.commits.has(sourceId)) {
const error: any = new Error(
@@ -293,8 +299,6 @@ export const cherryPick = function (
error.hash = {
text: `cherryPick ${sourceId} ${targetId}`,
token: `cherryPick ${sourceId} ${targetId}`,
line: '1',
loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 },
expected: ['cherry-pick abc'],
};
throw error;
@@ -307,8 +311,6 @@ export const cherryPick = function (
error.hash = {
text: `cherryPick ${sourceId} ${targetId}`,
token: `cherryPick ${sourceId} ${targetId}`,
line: '1',
loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 },
expected: ['cherry-pick abc'],
};
throw error;
@@ -323,13 +325,12 @@ export const cherryPick = function (
text: `cherryPick ${sourceId} ${targetId}`,
token: `cherryPick ${sourceId} ${targetId}`,
line: '1',
loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 },
expected: ['cherry-pick abc'],
};
throw error;
}
const commit = {
id: state.records.seq + '-' + getId(),
id: state.records.seq + '-' + getID(),
message: `cherry-picked ${sourceCommit?.message} into ${state.records.currBranch}`,
seq: state.records.seq++,
parents: [state.records.head == null ? null : state.records.head.id, sourceCommit.id],
@@ -365,8 +366,6 @@ export const checkout = function (branch: string) {
expected: [`branch ${branch}`],
};
throw error;
//branches[branch] = head != null ? head.id : null;
//log.debug('in createBranch');
} else {
state.records.currBranch = branch;
const id = state.records.branches.get(state.records.currBranch);
@@ -378,25 +377,6 @@ export const checkout = function (branch: string) {
}
};
// export const reset = function (commitRef) {
// log.debug('in reset', commitRef);
// const ref = commitRef.split(':')[0];
// let parentCount = parseInt(commitRef.split(':')[1]);
// let commit = ref === 'HEAD' ? head : commits.get(branches.get(ref));
// log.debug(commit, parentCount);
// while (parentCount > 0) {
// commit = commits.get(commit.parent);
// parentCount--;
// if (!commit) {
// const err = 'Critical error - unique parent commit not found during reset';
// log.error(err);
// throw err;
// }
// }
// head = commit;
// branches[curBranch] = commit.id;
// };
/**
* @param arr - array
* @param key - key

View File

@@ -1,129 +1,92 @@
import gitGraphAst from './gitGraphAst.js';
import { parser } from './parser/gitGraph.jison';
import db from './gitGraphAst.js';
import { parser } from './gitGraphParser.js';
describe('when parsing a gitGraph', function () {
beforeEach(function () {
parser.yy = gitGraphAst;
parser.yy.clear();
db.clear();
});
it('should handle a gitGraph definition', function () {
const str = 'gitGraph:\n' + 'commit\n';
parser.parse(str);
const commits = parser.yy.getCommits();
it('should handle a gitGraph definition', async () => {
const str = `gitGraph:\n commit\n`;
await parser.parse(str);
const commits = db.getCommits();
expect(commits.size).toBe(1);
expect(parser.yy.getCurrentBranch()).toBe('main');
expect(parser.yy.getDirection()).toBe('LR');
expect(parser.yy.getBranches().size).toBe(1);
expect(db.getCurrentBranch()).toBe('main');
expect(db.getDirection()).toBe('LR');
expect(db.getBranches().size).toBe(1);
});
it('should handle a gitGraph definition with empty options', function () {
const str = 'gitGraph:\n' + 'options\n' + ' end\n' + 'commit\n';
parser.parse(str);
const commits = parser.yy.getCommits();
expect(parser.yy.getOptions()).toEqual({});
expect(commits.size).toBe(1);
expect(parser.yy.getCurrentBranch()).toBe('main');
expect(parser.yy.getDirection()).toBe('LR');
expect(parser.yy.getBranches().size).toBe(1);
});
it('should handle a gitGraph definition with valid options', function () {
const str = 'gitGraph:\n' + 'options\n' + '{"key": "value"}\n' + 'end\n' + 'commit\n';
parser.parse(str);
const commits = parser.yy.getCommits();
expect(parser.yy.getOptions().key).toBe('value');
expect(commits.size).toBe(1);
expect(parser.yy.getCurrentBranch()).toBe('main');
expect(parser.yy.getDirection()).toBe('LR');
expect(parser.yy.getBranches().size).toBe(1);
});
it('should not fail on a gitGraph with malformed json', function () {
const str = 'gitGraph:\n' + 'options\n' + '{"key": "value"\n' + 'end\n' + 'commit\n';
parser.parse(str);
const commits = parser.yy.getCommits();
expect(commits.size).toBe(1);
expect(parser.yy.getCurrentBranch()).toBe('main');
expect(parser.yy.getDirection()).toBe('LR');
expect(parser.yy.getBranches().size).toBe(1);
});
it('should handle set direction top to bottom', function () {
it('should handle set direction top to bottom', async () => {
const str = 'gitGraph TB:\n' + 'commit\n';
parser.parse(str);
const commits = parser.yy.getCommits();
await parser.parse(str);
const commits = db.getCommits();
expect(commits.size).toBe(1);
expect(parser.yy.getCurrentBranch()).toBe('main');
expect(parser.yy.getDirection()).toBe('TB');
expect(parser.yy.getBranches().size).toBe(1);
expect(db.getCurrentBranch()).toBe('main');
expect(db.getDirection()).toBe('TB');
expect(db.getBranches().size).toBe(1);
});
it('should handle set direction bottom to top', function () {
it('should handle set direction bottom to top', async () => {
const str = 'gitGraph BT:\n' + 'commit\n';
parser.parse(str);
const commits = parser.yy.getCommits();
await parser.parse(str);
const commits = db.getCommits();
expect(commits.size).toBe(1);
expect(parser.yy.getCurrentBranch()).toBe('main');
expect(parser.yy.getDirection()).toBe('BT');
expect(parser.yy.getBranches().size).toBe(1);
expect(db.getCurrentBranch()).toBe('main');
expect(db.getDirection()).toBe('BT');
expect(db.getBranches().size).toBe(1);
});
it('should checkout a branch', function () {
it('should checkout a branch', async () => {
const str = 'gitGraph:\n' + 'branch new\n' + 'checkout new\n';
parser.parse(str);
const commits = parser.yy.getCommits();
await parser.parse(str);
const commits = db.getCommits();
expect(commits.size).toBe(0);
expect(parser.yy.getCurrentBranch()).toBe('new');
expect(db.getCurrentBranch()).toBe('new');
});
it('should switch a branch', function () {
it('should switch a branch', async () => {
const str = 'gitGraph:\n' + 'branch new\n' + 'switch new\n';
parser.parse(str);
const commits = parser.yy.getCommits();
await parser.parse(str);
const commits = db.getCommits();
expect(commits.size).toBe(0);
expect(parser.yy.getCurrentBranch()).toBe('new');
expect(db.getCurrentBranch()).toBe('new');
});
it('should add commits to checked out branch', function () {
it('should add commits to checked out branch', async () => {
const str = 'gitGraph:\n' + 'branch new\n' + 'checkout new\n' + 'commit\n' + 'commit\n';
parser.parse(str);
const commits = parser.yy.getCommits();
await parser.parse(str);
const commits = db.getCommits();
expect(commits.size).toBe(2);
expect(parser.yy.getCurrentBranch()).toBe('new');
const branchCommit = parser.yy.getBranches().get('new');
expect(db.getCurrentBranch()).toBe('new');
const branchCommit = db.getBranches().get('new');
expect(branchCommit).not.toBeNull();
expect(commits.get(branchCommit).parent).not.toBeNull();
});
it('should handle commit with args', function () {
it('should handle commit with args', async () => {
const str = 'gitGraph:\n' + 'commit "a commit"\n';
parser.parse(str);
const commits = parser.yy.getCommits();
await parser.parse(str);
const commits = db.getCommits();
expect(commits.size).toBe(1);
const key = commits.keys().next().value;
expect(commits.get(key).message).toBe('a commit');
expect(parser.yy.getCurrentBranch()).toBe('main');
expect(db.getCurrentBranch()).toBe('main');
});
// Reset has been commented out in JISON
it.skip('should reset a branch', function () {
it.skip('should reset a branch', async () => {
const str =
'gitGraph:\n' +
'commit\n' +
@@ -133,16 +96,16 @@ describe('when parsing a gitGraph', function () {
'commit\n' +
'reset main\n';
parser.parse(str);
await parser.parse(str);
const commits = parser.yy.getCommits();
const commits = db.getCommits();
expect(commits.size).toBe(3);
expect(parser.yy.getCurrentBranch()).toBe('newbranch');
expect(parser.yy.getBranches().get('newbranch')).toEqual(parser.yy.getBranches().get('main'));
expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches().get('newbranch'));
expect(db.getCurrentBranch()).toBe('newbranch');
expect(db.getBranches().get('newbranch')).toEqual(db.getBranches().get('main'));
expect(db.getHead().id).toEqual(db.getBranches().get('newbranch'));
});
it.skip('reset can take an argument', function () {
it.skip('reset can take an argument', async () => {
const str =
'gitGraph:\n' +
'commit\n' +
@@ -152,16 +115,16 @@ describe('when parsing a gitGraph', function () {
'commit\n' +
'reset main^\n';
parser.parse(str);
await parser.parse(str);
const commits = parser.yy.getCommits();
const commits = db.getCommits();
expect(commits.size).toBe(3);
expect(parser.yy.getCurrentBranch()).toBe('newbranch');
const main = commits.get(parser.yy.getBranches().get('main'));
expect(parser.yy.getHead().id).toEqual(main.parent);
expect(db.getCurrentBranch()).toBe('newbranch');
const main = commits.get(db.getBranches().get('main'));
expect(db.getHead().id).toEqual(main.parent);
});
it.skip('should handle fast forwardable merges', function () {
it.skip('should handle fast forwardable merges', async () => {
const str =
'gitGraph:\n' +
'commit\n' +
@@ -172,16 +135,16 @@ describe('when parsing a gitGraph', function () {
'checkout main\n' +
'merge newbranch\n';
parser.parse(str);
await parser.parse(str);
const commits = parser.yy.getCommits();
const commits = db.getCommits();
expect(commits.size).toBe(4);
expect(parser.yy.getCurrentBranch()).toBe('main');
expect(parser.yy.getBranches().get('newbranch')).toEqual(parser.yy.getBranches().get('main'));
expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches().get('newbranch'));
expect(db.getCurrentBranch()).toBe('main');
expect(db.getBranches().get('newbranch')).toEqual(db.getBranches().get('main'));
expect(db.getHead().id).toEqual(db.getBranches().get('newbranch'));
});
it('should handle cases when merge is a noop', function () {
it('should handle cases when merge is a noop', async () => {
const str =
'gitGraph:\n' +
'commit\n' +
@@ -191,18 +154,16 @@ describe('when parsing a gitGraph', function () {
'commit\n' +
'merge main\n';
parser.parse(str);
await parser.parse(str);
const commits = parser.yy.getCommits();
const commits = db.getCommits();
expect(commits.size).toBe(4);
expect(parser.yy.getCurrentBranch()).toBe('newbranch');
expect(parser.yy.getBranches().get('newbranch')).not.toEqual(
parser.yy.getBranches().get('main')
);
expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches().get('newbranch'));
expect(db.getCurrentBranch()).toBe('newbranch');
expect(db.getBranches().get('newbranch')).not.toEqual(db.getBranches().get('main'));
expect(db.getHead().id).toEqual(db.getBranches().get('newbranch'));
});
it('should handle merge with 2 parents', function () {
it('should handle merge with 2 parents', async () => {
const str =
'gitGraph:\n' +
'commit\n' +
@@ -214,18 +175,16 @@ describe('when parsing a gitGraph', function () {
'commit\n' +
'merge newbranch\n';
parser.parse(str);
await parser.parse(str);
const commits = parser.yy.getCommits();
const commits = db.getCommits();
expect(commits.size).toBe(5);
expect(parser.yy.getCurrentBranch()).toBe('main');
expect(parser.yy.getBranches().get('newbranch')).not.toEqual(
parser.yy.getBranches().get('main')
);
expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches().get('main'));
expect(db.getCurrentBranch()).toBe('main');
expect(db.getBranches().get('newbranch')).not.toEqual(db.getBranches().get('main'));
expect(db.getHead().id).toEqual(db.getBranches().get('main'));
});
it.skip('should handle ff merge when history walk has two parents (merge commit)', function () {
it.skip('should handle ff merge when history walk has two parents (merge commit)', async () => {
const str =
'gitGraph:\n' +
'commit\n' +
@@ -240,18 +199,18 @@ describe('when parsing a gitGraph', function () {
'checkout newbranch\n' +
'merge main\n';
parser.parse(str);
await parser.parse(str);
const commits = parser.yy.getCommits();
const commits = db.getCommits();
expect(commits.size).toBe(7);
expect(parser.yy.getCurrentBranch()).toBe('newbranch');
expect(parser.yy.getBranches().get('newbranch')).toEqual(parser.yy.getBranches().get('main'));
expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches().get('main'));
expect(db.getCurrentBranch()).toBe('newbranch');
expect(db.getBranches().get('newbranch')).toEqual(db.getBranches().get('main'));
expect(db.getHead().id).toEqual(db.getBranches().get('main'));
parser.yy.prettyPrint();
db.prettyPrint();
});
it('should generate an array of known branches', function () {
it('should generate an array of known branches', async () => {
const str =
'gitGraph:\n' +
'commit\n' +
@@ -261,8 +220,8 @@ describe('when parsing a gitGraph', function () {
'commit\n' +
'branch b2\n';
parser.parse(str);
const branches = gitGraphAst.getBranchesAsObjArray();
await parser.parse(str);
const branches = db.getBranchesAsObjArray();
expect(branches).toHaveLength(3);
expect(branches[0]).toHaveProperty('name', 'main');

File diff suppressed because it is too large Load Diff

View File

@@ -26,7 +26,7 @@ hidden terminal SINGLE_LINE_COMMENT: /[\t ]*%%[^\n\r]*/;
entry GitGraph:
NEWLINE*
'gitGraph' Direction? ':'?
('gitGraph' | 'gitGraph' ':' | 'gitGraph:' | ('gitGraph' Direction ':'))
NEWLINE*
(
NEWLINE*