made draw commit more readable, included more helper functions and interfaces, added in-source test suite to renderer

This commit is contained in:
Austin Fulbright
2024-08-10 06:08:57 -04:00
parent 2218929416
commit a93b8324ad

View File

@@ -9,6 +9,9 @@ import type { GitGraphDiagramConfig } from '../../config.type.js';
let allCommitsDict = new Map();
const LAYOUT_OFFSET = 10;
const COMMIT_STEP = 40;
const commitType: CommitType = {
NORMAL: 0,
REVERSE: 1,
@@ -29,6 +32,10 @@ interface CommitPosition {
y: number;
}
interface CommitPositionOffset extends CommitPosition {
posWithOffset: number;
}
const branchPos = new Map<string, BranchPosition>();
const commitPos = new Map<string, CommitPosition>();
let lanes: number[] = [];
@@ -93,9 +100,7 @@ const findClosestParent = (parents: string[], useBTLogic = false): string | unde
const setParallelBTPos = (
sortedKeys: string[],
commits: Map<string, Commit>,
defaultPos: number,
commitStep: number,
layoutOffset: number
defaultPos: number
) => {
let curPos = defaultPos;
let maxPosition = defaultPos;
@@ -108,12 +113,12 @@ const setParallelBTPos = (
}
if (hasParents(commit)) {
curPos = calculateCommitPosition(commit, commitStep, maxPosition);
curPos = calculateCommitPosition(commit);
maxPosition = Math.max(curPos, maxPosition);
} else {
roots.push(commit);
}
setCommitPosition(commit, curPos, layoutOffset);
setCommitPosition(commit, curPos);
});
curPos = maxPosition;
@@ -125,7 +130,7 @@ const setParallelBTPos = (
const hasParents = (commit: Commit): boolean => commit.parents?.length > 0;
const findClosestParentPos = (commit: Commit): number => {
const closestParent = findClosestParent(commit.parents.filter((p) => p !== null) as string[]);
const closestParent = findClosestParent(commit.parents.filter((p) => p !== null));
if (!closestParent) {
throw new Error(`Closest parent not found for commit ${commit.id}`);
}
@@ -137,19 +142,19 @@ const findClosestParentPos = (commit: Commit): number => {
return closestParentPos;
};
const calculateCommitPosition = (commit: Commit, commitStep: number): number => {
const calculateCommitPosition = (commit: Commit): number => {
const closestParentPos = findClosestParentPos(commit);
return closestParentPos + commitStep;
return closestParentPos + COMMIT_STEP;
};
const setCommitPosition = (commit: Commit, curPos: number, layoutOffset: number) => {
const setCommitPosition = (commit: Commit, curPos: number) => {
const branch = branchPos.get(commit.branch);
if (!branch) {
throw new Error(`Branch not found for commit ${commit.id}`);
}
const x = branch.pos;
const y = curPos + layoutOffset;
const y = curPos + LAYOUT_OFFSET;
commitPos.set(commit.id, { x, y });
};
@@ -167,8 +172,7 @@ const setRootPosition = (commit: Commit, curPos: number, defaultPos: number) =>
const drawCommitBullet = (
gBullets: d3.Selection<SVGGElement, unknown, HTMLElement, any>,
commit: Commit,
x: number,
y: number,
commitPosition: CommitPositionOffset,
typeClass: string,
branchIndex: number,
commitSymbolType: number
@@ -176,8 +180,8 @@ const drawCommitBullet = (
if (commitSymbolType === commitType.HIGHLIGHT) {
gBullets
.append('rect')
.attr('x', x - 10)
.attr('y', y - 10)
.attr('x', commitPosition.x - 10)
.attr('y', commitPosition.y - 10)
.attr('width', 20)
.attr('height', 20)
.attr(
@@ -186,8 +190,8 @@ const drawCommitBullet = (
);
gBullets
.append('rect')
.attr('x', x - 6)
.attr('y', y - 6)
.attr('x', commitPosition.x - 6)
.attr('y', commitPosition.y - 6)
.attr('width', 12)
.attr('height', 12)
.attr(
@@ -197,50 +201,50 @@ const drawCommitBullet = (
} else if (commitSymbolType === commitType.CHERRY_PICK) {
gBullets
.append('circle')
.attr('cx', x)
.attr('cy', y)
.attr('cx', commitPosition.x)
.attr('cy', commitPosition.y)
.attr('r', 10)
.attr('class', `commit ${commit.id} ${typeClass}`);
gBullets
.append('circle')
.attr('cx', x - 3)
.attr('cy', y + 2)
.attr('cx', commitPosition.x - 3)
.attr('cy', commitPosition.y + 2)
.attr('r', 2.75)
.attr('fill', '#fff')
.attr('class', `commit ${commit.id} ${typeClass}`);
gBullets
.append('circle')
.attr('cx', x + 3)
.attr('cy', y + 2)
.attr('cx', commitPosition.x + 3)
.attr('cy', commitPosition.y + 2)
.attr('r', 2.75)
.attr('fill', '#fff')
.attr('class', `commit ${commit.id} ${typeClass}`);
gBullets
.append('line')
.attr('x1', x + 3)
.attr('y1', y + 1)
.attr('x2', x)
.attr('y2', y - 5)
.attr('x1', commitPosition.x + 3)
.attr('y1', commitPosition.y + 1)
.attr('x2', commitPosition.x)
.attr('y2', commitPosition.y - 5)
.attr('stroke', '#fff')
.attr('class', `commit ${commit.id} ${typeClass}`);
gBullets
.append('line')
.attr('x1', x - 3)
.attr('y1', y + 1)
.attr('x2', x)
.attr('y2', y - 5)
.attr('x1', commitPosition.x - 3)
.attr('y1', commitPosition.y + 1)
.attr('x2', commitPosition.x)
.attr('y2', commitPosition.y - 5)
.attr('stroke', '#fff')
.attr('class', `commit ${commit.id} ${typeClass}`);
} else {
const circle = gBullets.append('circle');
circle.attr('cx', x);
circle.attr('cy', y);
circle.attr('cx', commitPosition.x);
circle.attr('cy', commitPosition.y);
circle.attr('r', commit.type === commitType.MERGE ? 9 : 10);
circle.attr('class', `commit ${commit.id} commit${branchIndex % THEME_COLOR_LIMIT}`);
if (commit.type === commitType.MERGE) {
const circle2 = gBullets.append('circle');
circle2.attr('cx', x);
circle2.attr('cy', y);
circle2.attr('cx', commitPosition.x);
circle2.attr('cy', commitPosition.y);
circle2.attr('r', 6);
circle2.attr(
'class',
@@ -250,7 +254,10 @@ const drawCommitBullet = (
if (commitSymbolType === commitType.REVERSE) {
const cross = gBullets.append('path');
cross
.attr('d', `M ${x - 5},${y - 5}L${x + 5},${y + 5}M${x - 5},${y + 5}L${x + 5},${y - 5}`)
.attr(
'd',
`M ${commitPosition.x - 5},${commitPosition.y - 5}L${commitPosition.x + 5},${commitPosition.y + 5}M${commitPosition.x - 5},${commitPosition.y + 5}L${commitPosition.x + 5},${commitPosition.y - 5}`
)
.attr('class', `commit ${typeClass} ${commit.id} commit${branchIndex % THEME_COLOR_LIMIT}`);
}
}
@@ -259,10 +266,8 @@ const drawCommitBullet = (
const drawCommitLabel = (
gLabels: d3.Selection<SVGGElement, unknown, HTMLElement, any>,
commit: Commit,
x: number,
y: number,
commitPosition: CommitPositionOffset,
pos: number,
posWithOffset: number,
gitGraphConfig: GitGraphDiagramConfig
) => {
if (
@@ -274,34 +279,52 @@ const drawCommitLabel = (
const labelBkg = wrapper.insert('rect').attr('class', 'commit-label-bkg');
const text = wrapper
.append('text')
.attr('x', x)
.attr('y', y + 25)
.attr('x', commitPosition.x)
.attr('y', commitPosition.y + 25)
.attr('class', 'commit-label')
.text(commit.id);
const bbox = text.node()?.getBBox();
if (bbox) {
labelBkg
.attr('x', posWithOffset - bbox.width / 2 - 2)
.attr('y', y + 13.5)
.attr('x', commitPosition.posWithOffset - bbox.width / 2 - 2)
.attr('y', commitPosition.y + 13.5)
.attr('width', bbox.width + 4)
.attr('height', bbox.height + 4);
if (dir === 'TB' || dir === 'BT') {
labelBkg.attr('x', x - (bbox.width + 4)).attr('y', y - 12);
text.attr('x', x - (bbox.width + 2)).attr('y', y + bbox.height - 12);
labelBkg.attr('x', commitPosition.x - (bbox.width + 4)).attr('y', commitPosition.y - 12);
text
.attr('x', commitPosition.x - (bbox.width + 2))
.attr('y', commitPosition.y + bbox.height - 12);
}
if (gitGraphConfig.rotateCommitLabel) {
if (dir === 'TB' || dir === 'BT') {
text.attr('transform', 'rotate(' + -45 + ', ' + x + ', ' + y + ')');
labelBkg.attr('transform', 'rotate(' + -45 + ', ' + x + ', ' + y + ')');
text.attr(
'transform',
'rotate(' + -45 + ', ' + commitPosition.x + ', ' + commitPosition.y + ')'
);
labelBkg.attr(
'transform',
'rotate(' + -45 + ', ' + commitPosition.x + ', ' + commitPosition.y + ')'
);
} else {
const r_x = -7.5 - ((bbox.width + 10) / 25) * 9.5;
const r_y = 10 + (bbox.width / 25) * 8.5;
wrapper.attr(
'transform',
'translate(' + r_x + ', ' + r_y + ') rotate(' + -45 + ', ' + pos + ', ' + y + ')'
'translate(' +
r_x +
', ' +
r_y +
') rotate(' +
-45 +
', ' +
pos +
', ' +
commitPosition.y +
')'
);
}
}
@@ -312,11 +335,8 @@ const drawCommitLabel = (
const drawCommitTags = (
gLabels: d3.Selection<SVGGElement, unknown, HTMLElement, any>,
commit: Commit,
x: number,
y: number,
pos: number,
posWithOffset: number,
layoutOffset: number
commitPosition: CommitPositionOffset,
pos: number
) => {
if (commit.tags.length > 0) {
let yOffset = 0;
@@ -329,7 +349,7 @@ const drawCommitTags = (
const hole = gLabels.append('circle');
const tag = gLabels
.append('text')
.attr('y', y - 16 - yOffset)
.attr('y', commitPosition.y - 16 - yOffset)
.attr('class', 'tag-label')
.text(tagValue);
const tagBbox = tag.node()?.getBBox();
@@ -339,7 +359,7 @@ const drawCommitTags = (
maxTagBboxWidth = Math.max(maxTagBboxWidth, tagBbox.width);
maxTagBboxHeight = Math.max(maxTagBboxHeight, tagBbox.height);
tag.attr('x', posWithOffset - tagBbox.width / 2);
tag.attr('x', commitPosition.posWithOffset - tagBbox.width / 2);
tagElements.push({
tag,
@@ -353,16 +373,16 @@ const drawCommitTags = (
for (const { tag, hole, rect, yOffset } of tagElements) {
const h2 = maxTagBboxHeight / 2;
const ly = y - 19.2 - yOffset;
const ly = commitPosition.y - 19.2 - yOffset;
rect.attr('class', 'tag-label-bkg').attr(
'points',
`
${pos - maxTagBboxWidth / 2 - 2},${ly + 2}
${pos - maxTagBboxWidth / 2 - 2},${ly - 2}
${posWithOffset - maxTagBboxWidth / 2 - 4},${ly - h2 - 2}
${posWithOffset + maxTagBboxWidth / 2 + 4},${ly - h2 - 2}
${posWithOffset + maxTagBboxWidth / 2 + 4},${ly + h2 + 2}
${posWithOffset - maxTagBboxWidth / 2 - 4},${ly + h2 + 2}`
${commitPosition.posWithOffset - maxTagBboxWidth / 2 - 4},${ly - h2 - 2}
${commitPosition.posWithOffset + maxTagBboxWidth / 2 + 4},${ly - h2 - 2}
${commitPosition.posWithOffset + maxTagBboxWidth / 2 + 4},${ly + h2 + 2}
${commitPosition.posWithOffset - maxTagBboxWidth / 2 - 4},${ly + h2 + 2}`
);
hole
@@ -379,22 +399,22 @@ const drawCommitTags = (
.attr(
'points',
`
${x},${yOrigin + 2}
${x},${yOrigin - 2}
${x + layoutOffset},${yOrigin - h2 - 2}
${x + layoutOffset + maxTagBboxWidth + 4},${yOrigin - h2 - 2}
${x + layoutOffset + maxTagBboxWidth + 4},${yOrigin + h2 + 2}
${x + layoutOffset},${yOrigin + h2 + 2}`
${commitPosition.x},${yOrigin + 2}
${commitPosition.x},${yOrigin - 2}
${commitPosition.x + LAYOUT_OFFSET},${yOrigin - h2 - 2}
${commitPosition.x + LAYOUT_OFFSET + maxTagBboxWidth + 4},${yOrigin - h2 - 2}
${commitPosition.x + LAYOUT_OFFSET + maxTagBboxWidth + 4},${yOrigin + h2 + 2}
${commitPosition.x + LAYOUT_OFFSET},${yOrigin + h2 + 2}`
)
.attr('transform', 'translate(12,12) rotate(45, ' + x + ',' + pos + ')');
.attr('transform', 'translate(12,12) rotate(45, ' + commitPosition.x + ',' + pos + ')');
hole
.attr('cx', x + 2)
.attr('cx', commitPosition.x + 2)
.attr('cy', yOrigin)
.attr('transform', 'translate(12,12) rotate(45, ' + x + ',' + pos + ')');
.attr('transform', 'translate(12,12) rotate(45, ' + commitPosition.x + ',' + pos + ')');
tag
.attr('x', x + 5)
.attr('x', commitPosition.x + 5)
.attr('y', yOrigin + 3)
.attr('transform', 'translate(14,14) rotate(45, ' + x + ',' + pos + ')');
.attr('transform', 'translate(14,14) rotate(45, ' + commitPosition.x + ',' + pos + ')');
}
}
}
@@ -421,30 +441,23 @@ const getCommitClassType = (commit: Commit): string => {
const calculatePosition = (
commit: Commit,
dir: string,
isParallelCommits: boolean,
pos: number,
commitStep: number,
layoutOffset: number,
commitPos: Map<string, CommitPosition>
): number => {
const defaultCommitPosition = { x: 0, y: defaultPos }; // Default position if commit is not found
const defaultCommitPosition = { x: 0, y: 0 }; // Default position if commit is not found
if (isParallelCommits) {
if (commit.parents.length > 0) {
const closestParent =
dir === 'BT' ? findClosestParent(commit.parents) : findClosestParent(commit.parents);
// Check if closestParent is defined
const closestParent = findClosestParent(commit.parents);
if (closestParent) {
const parentPosition = commitPos.get(closestParent) ?? defaultCommitPosition;
if (dir === 'TB') {
return parentPosition.y + commitStep;
return parentPosition.y + COMMIT_STEP;
} else if (dir === 'BT') {
const currentPosition = commitPos.get(commit.id) ?? defaultCommitPosition;
return currentPosition.y - commitStep;
return currentPosition.y - COMMIT_STEP;
} else {
return parentPosition.x + commitStep;
return parentPosition.x + COMMIT_STEP;
}
}
} else {
@@ -452,14 +465,26 @@ const calculatePosition = (
return defaultPos;
} else if (dir === 'BT') {
const currentPosition = commitPos.get(commit.id) ?? defaultCommitPosition;
return currentPosition.y - commitStep;
return currentPosition.y - COMMIT_STEP;
} else {
return 0;
}
}
}
return 0;
};
return dir === 'TB' && isParallelCommits ? pos : pos + layoutOffset;
const getCommitPosition = (
commit: Commit,
pos: number,
isParallelCommits: boolean
): CommitPositionOffset => {
const posWithOffset = dir === 'BT' && isParallelCommits ? pos : pos + LAYOUT_OFFSET;
const y = dir === 'TB' || dir === 'BT' ? posWithOffset : branchPos.get(commit.branch)?.pos;
const x = dir === 'TB' || dir === 'BT' ? branchPos.get(commit.branch)?.pos : posWithOffset;
if (x === undefined || y === undefined) {
throw new Error(`Position were undefined for commit ${commit.id}`);
}
return { x, y, posWithOffset };
};
const drawCommits = (
@@ -476,8 +501,6 @@ const drawCommits = (
let pos = dir === 'TB' || dir === 'BT' ? defaultPos : 0;
const keys = [...commits.keys()];
const isParallelCommits = gitGraphConfig?.parallelCommits ?? false;
const layoutOffset = 10;
const commitStep = 40;
const sortKeys = (a: string, b: string) => {
const seqA = commits.get(a)?.seq;
@@ -487,12 +510,10 @@ const drawCommits = (
let sortedKeys = keys.sort(sortKeys);
if (dir === 'BT' && !isParallelCommits) {
sortedKeys = sortedKeys.reverse();
if (dir === 'BT') {
if (isParallelCommits) {
setParallelBTPos(sortedKeys, commits, pos);
}
if (dir === 'BT' && isParallelCommits) {
setParallelBTPos(sortedKeys, commits, pos, commitStep, layoutOffset);
sortedKeys = sortedKeys.reverse();
}
@@ -500,41 +521,30 @@ const drawCommits = (
const commit = commits.get(key);
if (!commit) {
throw new Error(`Commit not found for key ${key}`);
} else {
pos = calculatePosition(
commit,
dir,
isParallelCommits,
pos,
commitStep,
layoutOffset,
commitPos
);
const posWithOffset = dir === 'BT' && isParallelCommits ? pos : pos + layoutOffset;
const y = dir === 'TB' || dir === 'BT' ? posWithOffset : branchPos.get(commit.branch)?.pos;
const x = dir === 'TB' || dir === 'BT' ? branchPos.get(commit.branch)?.pos : posWithOffset;
if (x === undefined || y === undefined) {
throw new Error(`Position were undefined for commit ${commit.id}`);
}
if (isParallelCommits) {
pos = calculatePosition(commit, dir, pos, commitPos);
}
const commitPosition = getCommitPosition(commit, pos, isParallelCommits);
// Don't draw the commits now but calculate the positioning which is used by the branch lines etc.
if (modifyGraph) {
const typeClass = getCommitClassType(commit);
const commitSymbolType = commit.customType ?? commit.type;
const branchIndex = branchPos.get(commit.branch)?.index ?? 0;
drawCommitBullet(gBullets, commit, x, y, typeClass, branchIndex, commitSymbolType);
drawCommitLabel(gLabels, commit, x, y, pos, posWithOffset, gitGraphConfig);
drawCommitTags(gLabels, commit, x, y, pos, posWithOffset, layoutOffset);
drawCommitBullet(gBullets, commit, commitPosition, typeClass, branchIndex, commitSymbolType);
drawCommitLabel(gLabels, commit, commitPosition, pos, gitGraphConfig);
drawCommitTags(gLabels, commit, commitPosition, pos);
}
if (dir === 'TB' || dir === 'BT') {
commitPos.set(commit.id, { x: x, y: posWithOffset });
commitPos.set(commit.id, { x: commitPosition.x, y: commitPosition.posWithOffset });
} else {
commitPos.set(commit.id, { x: posWithOffset, y: y });
commitPos.set(commit.id, { x: commitPosition.posWithOffset, y: commitPosition.y });
}
pos = dir === 'BT' && isParallelCommits ? pos + commitStep : pos + commitStep + layoutOffset;
pos = dir === 'BT' && isParallelCommits ? pos + COMMIT_STEP : pos + COMMIT_STEP + LAYOUT_OFFSET;
if (pos > maxPos) {
maxPos = pos;
}
}
});
};
@@ -904,65 +914,269 @@ const drawBranches = (
});
};
const setBranchPosition = function (
name: string,
pos: number,
index: number,
bbox: DOMRect,
rotateCommitLabel: boolean
): number {
branchPos.set(name, { pos, index });
pos += 50 + (rotateCommitLabel ? 40 : 0) + (dir === 'TB' || dir === 'BT' ? bbox.width / 2 : 0);
return pos;
};
export const draw: DrawDefinition = function (txt, id, ver, diagObj) {
clear();
const conf = getConfig();
const gitGraphConfig = conf.gitGraph;
// try {
log.debug('in gitgraph renderer', txt + '\n', 'id:', id, ver);
if (!gitGraphConfig) {
throw new Error('GitGraph config not found');
}
const rotateCommitLabel = gitGraphConfig.rotateCommitLabel ?? false;
const db = diagObj.db as GitGraphDB;
allCommitsDict = db.getCommits();
const branches = db.getBranchesAsObjArray();
dir = db.getDirection();
const diagram = select(`[id="${id}"]`);
// Position branches
let pos = 0;
branches.forEach((branch, index) => {
const labelElement = drawText(branch.name);
const g = diagram.append('g');
const branchLabel = g.insert('g').attr('class', 'branchLabel');
const label = branchLabel.insert('g').attr('class', 'label branch-label');
// @ts-ignore: TODO Fix ts errors
label.node().appendChild(labelElement);
const bbox = labelElement.getBBox();
branchPos.set(branch.name, { pos, index });
pos +=
50 +
// @ts-ignore: TODO Fix ts errors
(gitGraphConfig.rotateCommitLabel ? 40 : 0) +
(dir === 'TB' || dir === 'BT' ? bbox.width / 2 : 0);
pos = setBranchPosition(branch.name, pos, index, bbox, rotateCommitLabel);
label.remove();
branchLabel.remove();
g.remove();
});
drawCommits(diagram, allCommitsDict, false);
// @ts-ignore: TODO Fix ts errors
if (gitGraphConfig.showBranches) {
drawBranches(diagram, branches);
}
drawArrows(diagram, allCommitsDict);
drawCommits(diagram, allCommitsDict, true);
utils.insertTitle(
diagram,
'gitTitleText',
// @ts-ignore: TODO Fix ts errors
gitGraphConfig.titleTopMargin,
gitGraphConfig.titleTopMargin ?? 0,
db.getDiagramTitle()
);
// Setup the view box and size of the svg element
setupGraphViewbox(
undefined,
diagram,
// @ts-ignore: TODO Fix ts errors
gitGraphConfig.diagramPadding,
// @ts-ignore: TODO Fix ts errors
gitGraphConfig.useMaxWidth ?? conf.useMaxWidth
);
setupGraphViewbox(undefined, diagram, gitGraphConfig.diagramPadding, gitGraphConfig.useMaxWidth);
};
export default {
draw,
};
if (import.meta.vitest) {
const { it, expect, describe } = import.meta.vitest;
describe('drawText', () => {
it('should drawText', () => {
const svgLabel = drawText('main');
expect(svgLabel).toBeDefined();
expect(svgLabel.children[0].innerHTML).toBe('main');
});
});
describe('drawBranchPositions', () => {
const bbox: DOMRect = {
x: 0,
y: 0,
width: 10,
height: 10,
top: 0,
right: 0,
bottom: 0,
left: 0,
toJSON: () => '',
};
it('should setBranchPositions LR with two branches', () => {
dir = 'LR';
const pos = setBranchPosition('main', 0, 0, bbox, true);
expect(pos).toBe(90);
expect(branchPos.get('main')).toEqual({ pos: 0, index: 0 });
const posNext = setBranchPosition('develop', pos, 1, bbox, true);
expect(posNext).toBe(180);
expect(branchPos.get('develop')).toEqual({ pos: pos, index: 1 });
});
it('should setBranchPositions TB with two branches', () => {
dir = 'TB';
bbox.width = 34.9921875;
const pos = setBranchPosition('main', 0, 0, bbox, true);
expect(pos).toBe(107.49609375);
expect(branchPos.get('main')).toEqual({ pos: 0, index: 0 });
bbox.width = 56.421875;
const posNext = setBranchPosition('develop', pos, 1, bbox, true);
expect(posNext).toBe(225.70703125);
expect(branchPos.get('develop')).toEqual({ pos: pos, index: 1 });
});
});
/*
describe('drawCommits', () => {
dir = 'TB';
const commits = new Map<string, Commit>([
[
'commitZero',
{
id: 'ZERO',
message: '',
seq: 0,
type: commitType.NORMAL,
tags: [],
parents: [],
branch: 'main',
},
],
[
'commitA',
{
id: 'A',
message: '',
seq: 1,
type: commitType.NORMAL,
tags: [],
parents: ['ZERO'],
branch: 'feature',
},
],
[
'commitB',
{
id: 'B',
message: '',
seq: 2,
type: commitType.NORMAL,
tags: [],
parents: ['A'],
branch: 'feature',
},
],
[
'commitM',
{
id: 'M',
message: 'merged branch feature into main',
seq: 3,
type: commitType.MERGE,
tags: [],
parents: ['ZERO', 'B'],
branch: 'main',
customId: true,
},
],
[
'commitC',
{
id: 'C',
message: '',
seq: 4,
type: commitType.NORMAL,
tags: [],
parents: ['ZERO'],
branch: 'release',
},
],
[
'commit5_8928ea0',
{
id: '5-8928ea0',
message: 'cherry-picked [object Object] into release',
seq: 5,
type: commitType.CHERRY_PICK,
tags: [],
parents: ['C', 'M'],
branch: 'release',
},
],
[
'commitD',
{
id: 'D',
message: '',
seq: 6,
type: commitType.NORMAL,
tags: [],
parents: ['5-8928ea0'],
branch: 'release',
},
],
[
'commit7_ed848ba',
{
id: '7-ed848ba',
message: 'cherry-picked [object Object] into release',
seq: 7,
type: commitType.CHERRY_PICK,
tags: [],
parents: ['D', 'M'],
branch: 'release',
},
],
]);
branchPos.set('main', { pos: 0, index: 0 });
branchPos.set('feature', { pos: 107.49609375, index: 1 });
branchPos.set('release', { pos: 224.03515625, index: 2 });
commits.forEach((commit) => {
it(`should draw commit ${commit.id}`, () => {
const commitPosition = getCommitPosition(commit, 0, false);
expect(commitPosition).toBeDefined();
});
it(`should draw commit ${commit.id} with position`, () => {
const commitPosition = getCommitPosition(commit, 0, false);
expect(commitPosition.x).toBeDefined();
expect(commitPosition.y).toBeDefined();
expect(commitPosition.posWithOffset).toBeDefined();
}
it(`should draw commit ${commit.id} bullet`, () => {
const gBullets = svg.append('g').attr('class', 'commit-bullets');
const typeClass = getCommitClassType(commit);
const branchIndex = branchPos.get(commit.branch)?.index ?? 0;
drawCommitBullet(gBullets, commit, commitPosition, typeClass, branchIndex, commit.type);
}
it(`should draw commit ${commit.id} label`, () => {
const gLabels = svg.append('g').attr('class', 'commit-labels');
drawCommitLabel(gLabels, commit, commitPosition, 0, gitGraphConfig);
}
});
*/
describe('drawBranches', () => {
it('should drawBranches', () => {
expect(true).toBe(true);
});
});
describe('drawArrows', () => {
it('should drawArrows', () => {
expect(true).toBe(true);
});
});
it('add', () => {
commitPos.set('parent1', { x: 1, y: 1 });
commitPos.set('parent2', { x: 2, y: 2 });
commitPos.set('parent3', { x: 3, y: 3 });
dir = 'LR';
const parents = ['parent1', 'parent2', 'parent3'];
const closestParent = findClosestParent(parents);
expect(closestParent).toBe('parent3');
commitPos.clear();
});
}