mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-03-22 11:43:07 +00:00
feat: Add GPT-5 model variants and improve Codex execution logic. Addressed code review comments
This commit is contained in:
@@ -1,60 +1,196 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { parseGitLogOutput } from '../src/lib/git-log-parser.js';
|
||||
|
||||
// Mock data with NUL-based separator
|
||||
const mockGitOutput = `a1b2c3d4e5f67890abcd1234567890abcd1234\x00a1b2c3\x00John Doe\x00john@example.com\x002023-01-01T12:00:00Z\x00Initial commit\x00This is the commit body\x00e5f6g7h8i9j0klmnoprstuv\x00e5f6g7\x00Jane Smith\x00jane@example.com\x002023-01-02T12:00:00Z\x00Fix bug\x00Fixed the bug with ---END--- in the message\x00q1w2e3r4t5y6u7i8o9p0asdfghjkl\x00q1w2e3\x00Bob Johnson\x00bob@example.com\x002023-01-03T12:00:00Z\x00Another commit\x00Empty body\x00`;
|
||||
// Mock data: fields within each commit are newline-separated,
|
||||
// commits are NUL-separated (matching the parser contract).
|
||||
const mockGitOutput = [
|
||||
'a1b2c3d4e5f67890abcd1234567890abcd1234\na1b2c3\nJohn Doe\njohn@example.com\n2023-01-01T12:00:00Z\nInitial commit\nThis is the commit body',
|
||||
'e5f6g7h8i9j0klmnoprstuv\ne5f6g7\nJane Smith\njane@example.com\n2023-01-02T12:00:00Z\nFix bug\nFixed the bug with ---END--- in the message',
|
||||
'q1w2e3r4t5y6u7i8o9p0asdfghjkl\nq1w2e3\nBob Johnson\nbob@example.com\n2023-01-03T12:00:00Z\nAnother commit\nEmpty body',
|
||||
].join('\0');
|
||||
|
||||
// Mock data with problematic ---END--- in commit message
|
||||
const mockOutputWithEndMarker = `a1b2c3d4e5f67890abcd1234567890abcd1234\x00a1b2c3\x00John Doe\x00john@example.com\x002023-01-01T12:00:00Z\x00Initial commit\x00This is the commit body\x00---END--- is in this message\x00e5f6g7h8i9j0klmnoprstuv\x00e5f6g7\x00Jane Smith\x00jane@example.com\x002023-01-02T12:00:00Z\x00Fix bug\x00Fixed the bug with ---END--- in the message\x00q1w2e3r4t5y6u7i8o9p0asdfghjkl\x00q1w2e3\x00Bob Johnson\x00bob@example.com\x002023-01-03T12:00:00Z\x00Another commit\x00Empty body\x00`;
|
||||
// Mock data where commit bodies contain ---END--- markers
|
||||
const mockOutputWithEndMarker = [
|
||||
'a1b2c3d4e5f67890abcd1234567890abcd1234\na1b2c3\nJohn Doe\njohn@example.com\n2023-01-01T12:00:00Z\nInitial commit\nThis is the commit body\n---END--- is in this message',
|
||||
'e5f6g7h8i9j0klmnoprstuv\ne5f6g7\nJane Smith\njane@example.com\n2023-01-02T12:00:00Z\nFix bug\nFixed the bug with ---END--- in the message',
|
||||
'q1w2e3r4t5y6u7i8o9p0asdfghjkl\nq1w2e3\nBob Johnson\nbob@example.com\n2023-01-03T12:00:00Z\nAnother commit\nEmpty body',
|
||||
].join('\0');
|
||||
|
||||
console.log('Testing parseGitLogOutput with NUL-based separator...\n');
|
||||
// Single-commit mock: fields newline-separated, no trailing NUL needed
|
||||
const singleCommitOutput =
|
||||
'a1b2c3d4e5f67890abcd1234567890abcd1234\na1b2c3\nJohn Doe\njohn@example.com\n2023-01-01T12:00:00Z\nSingle commit\nSingle commit body';
|
||||
|
||||
// Test 1: Normal parsing
|
||||
console.log('Test 1: Normal parsing');
|
||||
try {
|
||||
const commits = parseGitLogOutput(mockGitOutput);
|
||||
console.log(`✓ Parsed ${commits.length} commits successfully`);
|
||||
console.log('First commit:', commits[0]);
|
||||
console.log('Second commit:', commits[1]);
|
||||
console.log('Third commit:', commits[2]);
|
||||
console.log('');
|
||||
} catch (error) {
|
||||
console.error('✗ Test 1 failed:', error);
|
||||
}
|
||||
describe('parseGitLogOutput', () => {
|
||||
describe('normal parsing (three commits)', () => {
|
||||
it('returns the correct number of commits', () => {
|
||||
const commits = parseGitLogOutput(mockGitOutput);
|
||||
expect(commits.length).toBe(3);
|
||||
});
|
||||
|
||||
// Test 2: Parsing with ---END--- in commit messages
|
||||
console.log('Test 2: Parsing with ---END--- in commit messages');
|
||||
try {
|
||||
const commits = parseGitLogOutput(mockOutputWithEndMarker);
|
||||
console.log(`✓ Parsed ${commits.length} commits successfully`);
|
||||
console.log('Commits with ---END--- in messages:');
|
||||
commits.forEach((commit, index) => {
|
||||
console.log(`${index + 1}. ${commit.subject}: "${commit.body}"`);
|
||||
it('parses the first commit fields correctly', () => {
|
||||
const commits = parseGitLogOutput(mockGitOutput);
|
||||
expect(commits[0].hash).toBe('a1b2c3d4e5f67890abcd1234567890abcd1234');
|
||||
expect(commits[0].shortHash).toBe('a1b2c3');
|
||||
expect(commits[0].author).toBe('John Doe');
|
||||
expect(commits[0].authorEmail).toBe('john@example.com');
|
||||
expect(commits[0].date).toBe('2023-01-01T12:00:00Z');
|
||||
expect(commits[0].subject).toBe('Initial commit');
|
||||
expect(commits[0].body).toBe('This is the commit body');
|
||||
});
|
||||
|
||||
it('parses the second commit fields correctly', () => {
|
||||
const commits = parseGitLogOutput(mockGitOutput);
|
||||
expect(commits[1].hash).toBe('e5f6g7h8i9j0klmnoprstuv');
|
||||
expect(commits[1].shortHash).toBe('e5f6g7');
|
||||
expect(commits[1].author).toBe('Jane Smith');
|
||||
expect(commits[1].subject).toBe('Fix bug');
|
||||
expect(commits[1].body).toMatch(/---END---/);
|
||||
});
|
||||
|
||||
it('parses the third commit fields correctly', () => {
|
||||
const commits = parseGitLogOutput(mockGitOutput);
|
||||
expect(commits[2].hash).toBe('q1w2e3r4t5y6u7i8o9p0asdfghjkl');
|
||||
expect(commits[2].shortHash).toBe('q1w2e3');
|
||||
expect(commits[2].author).toBe('Bob Johnson');
|
||||
expect(commits[2].subject).toBe('Another commit');
|
||||
expect(commits[2].body).toBe('Empty body');
|
||||
});
|
||||
});
|
||||
console.log('');
|
||||
} catch (error) {
|
||||
console.error('✗ Test 2 failed:', error);
|
||||
}
|
||||
|
||||
// Test 3: Empty output
|
||||
console.log('Test 3: Empty output');
|
||||
try {
|
||||
const commits = parseGitLogOutput('');
|
||||
console.log(`✓ Parsed ${commits.length} commits from empty output`);
|
||||
console.log('');
|
||||
} catch (error) {
|
||||
console.error('✗ Test 3 failed:', error);
|
||||
}
|
||||
describe('parsing with ---END--- in commit messages', () => {
|
||||
it('returns the correct number of commits', () => {
|
||||
const commits = parseGitLogOutput(mockOutputWithEndMarker);
|
||||
expect(commits.length).toBe(3);
|
||||
});
|
||||
|
||||
// Test 4: Output with only one commit
|
||||
console.log('Test 4: Output with only one commit');
|
||||
const singleCommitOutput = `a1b2c3d4e5f67890abcd1234567890abcd1234\x00a1b2c3\x00John Doe\x00john@example.com\x002023-01-01T12:00:00Z\x00Single commit\x00Single commit body\x00`;
|
||||
try {
|
||||
const commits = parseGitLogOutput(singleCommitOutput);
|
||||
console.log(`✓ Parsed ${commits.length} commits successfully`);
|
||||
console.log('Single commit:', commits[0]);
|
||||
console.log('');
|
||||
} catch (error) {
|
||||
console.error('✗ Test 4 failed:', error);
|
||||
}
|
||||
it('preserves ---END--- text in the body of the first commit', () => {
|
||||
const commits = parseGitLogOutput(mockOutputWithEndMarker);
|
||||
expect(commits[0].subject).toBe('Initial commit');
|
||||
expect(commits[0].body).toMatch(/---END---/);
|
||||
});
|
||||
|
||||
console.log('All tests completed!');
|
||||
it('preserves ---END--- text in the body of the second commit', () => {
|
||||
const commits = parseGitLogOutput(mockOutputWithEndMarker);
|
||||
expect(commits[1].subject).toBe('Fix bug');
|
||||
expect(commits[1].body).toMatch(/---END---/);
|
||||
});
|
||||
|
||||
it('parses the third commit without ---END--- interference', () => {
|
||||
const commits = parseGitLogOutput(mockOutputWithEndMarker);
|
||||
expect(commits[2].subject).toBe('Another commit');
|
||||
expect(commits[2].body).toBe('Empty body');
|
||||
});
|
||||
});
|
||||
|
||||
describe('empty output', () => {
|
||||
it('returns an empty array for an empty string', () => {
|
||||
const commits = parseGitLogOutput('');
|
||||
expect(commits).toEqual([]);
|
||||
expect(commits.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('single-commit output', () => {
|
||||
it('returns exactly one commit', () => {
|
||||
const commits = parseGitLogOutput(singleCommitOutput);
|
||||
expect(commits.length).toBe(1);
|
||||
});
|
||||
|
||||
it('parses the single commit fields correctly', () => {
|
||||
const commits = parseGitLogOutput(singleCommitOutput);
|
||||
expect(commits[0].hash).toBe('a1b2c3d4e5f67890abcd1234567890abcd1234');
|
||||
expect(commits[0].shortHash).toBe('a1b2c3');
|
||||
expect(commits[0].author).toBe('John Doe');
|
||||
expect(commits[0].authorEmail).toBe('john@example.com');
|
||||
expect(commits[0].date).toBe('2023-01-01T12:00:00Z');
|
||||
expect(commits[0].subject).toBe('Single commit');
|
||||
expect(commits[0].body).toBe('Single commit body');
|
||||
});
|
||||
});
|
||||
|
||||
describe('multi-line commit body', () => {
|
||||
// Test vector from test-proper-nul-format.js: commit with a 3-line body
|
||||
const multiLineBodyOutput =
|
||||
[
|
||||
'abc123\nabc1\nJohn Doe\njohn@example.com\n2023-01-01T12:00:00Z\nInitial commit\nThis is a normal commit body',
|
||||
'def456\ndef4\nJane Smith\njane@example.com\n2023-01-02T12:00:00Z\nFix bug\nFixed the bug with ---END--- in this message',
|
||||
'ghi789\nghi7\nBob Johnson\nbob@example.com\n2023-01-03T12:00:00Z\nAnother commit\nThis body has multiple lines\nSecond line\nThird line',
|
||||
].join('\0') + '\0';
|
||||
|
||||
it('returns 3 commits', () => {
|
||||
const commits = parseGitLogOutput(multiLineBodyOutput);
|
||||
expect(commits.length).toBe(3);
|
||||
});
|
||||
|
||||
it('parses the first commit correctly', () => {
|
||||
const commits = parseGitLogOutput(multiLineBodyOutput);
|
||||
expect(commits[0].hash).toBe('abc123');
|
||||
expect(commits[0].shortHash).toBe('abc1');
|
||||
expect(commits[0].author).toBe('John Doe');
|
||||
expect(commits[0].authorEmail).toBe('john@example.com');
|
||||
expect(commits[0].date).toBe('2023-01-01T12:00:00Z');
|
||||
expect(commits[0].subject).toBe('Initial commit');
|
||||
expect(commits[0].body).toBe('This is a normal commit body');
|
||||
});
|
||||
|
||||
it('parses the second commit with ---END--- in body correctly', () => {
|
||||
const commits = parseGitLogOutput(multiLineBodyOutput);
|
||||
expect(commits[1].hash).toBe('def456');
|
||||
expect(commits[1].shortHash).toBe('def4');
|
||||
expect(commits[1].author).toBe('Jane Smith');
|
||||
expect(commits[1].subject).toBe('Fix bug');
|
||||
expect(commits[1].body).toContain('---END---');
|
||||
});
|
||||
|
||||
it('parses the third commit with a multi-line body correctly', () => {
|
||||
const commits = parseGitLogOutput(multiLineBodyOutput);
|
||||
expect(commits[2].hash).toBe('ghi789');
|
||||
expect(commits[2].shortHash).toBe('ghi7');
|
||||
expect(commits[2].author).toBe('Bob Johnson');
|
||||
expect(commits[2].subject).toBe('Another commit');
|
||||
expect(commits[2].body).toBe('This body has multiple lines\nSecond line\nThird line');
|
||||
});
|
||||
});
|
||||
|
||||
describe('commit with empty body (trailing blank lines after subject)', () => {
|
||||
// Test vector from test-proper-nul-format.js: empty body commit
|
||||
const emptyBodyOutput =
|
||||
'empty123\nempty1\nAlice Brown\nalice@example.com\n2023-01-04T12:00:00Z\nEmpty body commit\n\n\0';
|
||||
|
||||
it('returns 1 commit', () => {
|
||||
const commits = parseGitLogOutput(emptyBodyOutput);
|
||||
expect(commits.length).toBe(1);
|
||||
});
|
||||
|
||||
it('parses the commit subject correctly', () => {
|
||||
const commits = parseGitLogOutput(emptyBodyOutput);
|
||||
expect(commits[0].hash).toBe('empty123');
|
||||
expect(commits[0].shortHash).toBe('empty1');
|
||||
expect(commits[0].author).toBe('Alice Brown');
|
||||
expect(commits[0].subject).toBe('Empty body commit');
|
||||
});
|
||||
|
||||
it('produces an empty body string when only blank lines follow the subject', () => {
|
||||
const commits = parseGitLogOutput(emptyBodyOutput);
|
||||
expect(commits[0].body).toBe('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('leading empty lines in a commit block', () => {
|
||||
// Blocks that start with blank lines before the hash field
|
||||
const outputWithLeadingBlanks =
|
||||
'\n\nabc123\nabc1\nJohn Doe\njohn@example.com\n2023-01-01T12:00:00Z\nSubject here\nBody here';
|
||||
|
||||
it('returns 1 commit despite leading blank lines', () => {
|
||||
const commits = parseGitLogOutput(outputWithLeadingBlanks);
|
||||
expect(commits.length).toBe(1);
|
||||
});
|
||||
|
||||
it('parses the commit fields correctly when block has leading empty lines', () => {
|
||||
const commits = parseGitLogOutput(outputWithLeadingBlanks);
|
||||
expect(commits[0].hash).toBe('abc123');
|
||||
expect(commits[0].subject).toBe('Subject here');
|
||||
expect(commits[0].body).toBe('Body here');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
// Test to verify the NUL-based delimiter functionality
|
||||
// This simulates exactly what git would produce with the new format
|
||||
|
||||
console.log('Testing NUL-based delimiter functionality...\n');
|
||||
|
||||
// Simulate git log output with proper NUL-based separator format
|
||||
// Each commit has 7 fields separated by NUL: hash, shortHash, author, authorEmail, date, subject, body
|
||||
const gitOutput = `abc123\x00abc1\x00John Doe\x00john@example.com\x002023-01-01T12:00:00Z\x00Initial commit\x00This is a normal commit body\x00def456\x00def4\x00Jane Smith\x00jane@example.com\x002023-01-02T12:00:00Z\x00Fix bug\x00Fixed the bug with ---END--- in this message\x00ghi789\x00ghi7\x00Bob Johnson\x00bob@example.com\x002023-01-03T12:00:00Z\x00Another commit\x00This body has multiple lines\nSecond line\nThird line\x00`;
|
||||
|
||||
// Test the parsing logic
|
||||
console.log('1. Testing split on NUL character...');
|
||||
const commitBlocks = gitOutput.split('\0').filter((block) => block.trim());
|
||||
console.log(` ✓ Found ${commitBlocks.length} commit blocks`);
|
||||
|
||||
console.log('\n2. Testing parsing of each commit block...');
|
||||
const commits = [];
|
||||
for (const block of commitBlocks) {
|
||||
const fields = block.split('\n');
|
||||
|
||||
// Validate we have all expected fields
|
||||
if (fields.length >= 6) {
|
||||
const commit = {
|
||||
hash: fields[0].trim(),
|
||||
shortHash: fields[1].trim(),
|
||||
author: fields[2].trim(),
|
||||
authorEmail: fields[3].trim(),
|
||||
date: fields[4].trim(),
|
||||
subject: fields[5].trim(),
|
||||
body: fields.slice(6).join('\n').trim(),
|
||||
};
|
||||
commits.push(commit);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\n3. Successfully parsed ${commits.length} commits:`);
|
||||
commits.forEach((commit, index) => {
|
||||
console.log(`\n Commit ${index + 1}:`);
|
||||
console.log(` - Hash: ${commit.hash}`);
|
||||
console.log(` - Short hash: ${commit.shortHash}`);
|
||||
console.log(` - Author: ${commit.author}`);
|
||||
console.log(` - Email: ${commit.authorEmail}`);
|
||||
console.log(` - Date: ${commit.date}`);
|
||||
console.log(` - Subject: ${commit.subject}`);
|
||||
console.log(` - Body: "${commit.body}"`);
|
||||
});
|
||||
|
||||
// Test with problematic ---END--- in commit message
|
||||
console.log('\n4. Testing with ---END--- in commit message...');
|
||||
const problematicOutput = `test123\x00test1\x00John Doe\x00john@example.com\x002023-01-01T12:00:00Z\x00Initial commit\x00This contains ---END--- but should be parsed correctly\x00`;
|
||||
const problematicCommits = problematicOutput
|
||||
.split('\0')
|
||||
.filter((block) => block.trim())
|
||||
.map((block) => {
|
||||
const fields = block.split('\n');
|
||||
if (fields.length >= 6) {
|
||||
return {
|
||||
hash: fields[0].trim(),
|
||||
shortHash: fields[1].trim(),
|
||||
author: fields[2].trim(),
|
||||
authorEmail: fields[3].trim(),
|
||||
date: fields[4].trim(),
|
||||
subject: fields[5].trim(),
|
||||
body: fields.slice(6).join('\n').trim(),
|
||||
};
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter((commit) => commit !== null);
|
||||
|
||||
console.log(` ✓ Found ${problematicCommits.length} commits`);
|
||||
console.log(` Subject: "${problematicCommits[0].subject}"`);
|
||||
console.log(` Body: "${problematicCommits[0].body}"`);
|
||||
|
||||
// Test with empty body
|
||||
console.log('\n5. Testing commit with empty body...');
|
||||
const emptyBodyOutput = `empty123\x00empty1\x00Alice Brown\x00alice@example.com\x002023-01-04T12:00:00Z\x00Empty body commit\x00\x00`;
|
||||
const emptyBodyCommits = emptyBodyOutput
|
||||
.split('\0')
|
||||
.filter((block) => block.trim())
|
||||
.map((block) => {
|
||||
const fields = block.split('\n');
|
||||
if (fields.length >= 6) {
|
||||
return {
|
||||
hash: fields[0].trim(),
|
||||
shortHash: fields[1].trim(),
|
||||
author: fields[2].trim(),
|
||||
authorEmail: fields[3].trim(),
|
||||
date: fields[4].trim(),
|
||||
subject: fields[5].trim(),
|
||||
body: fields.slice(6).join('\n').trim(),
|
||||
};
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter((commit) => commit !== null);
|
||||
|
||||
console.log(` ✓ Found ${emptyBodyCommits.length} commits`);
|
||||
console.log(` Subject: "${emptyBodyCommits[0].subject}"`);
|
||||
console.log(` Body: "${emptyBodyCommits[0].body}" (should be empty)`);
|
||||
|
||||
console.log('\n✅ All tests passed! NUL-based delimiter works correctly.');
|
||||
console.log('\nSummary:');
|
||||
console.log('- NUL character (\\x00) properly separates commits');
|
||||
console.log('- Each commit is split into exactly 7 fields');
|
||||
console.log('- ---END--- in commit messages is handled correctly');
|
||||
console.log('- Empty commit bodies are preserved as empty strings');
|
||||
console.log('- Multi-line commit bodies are preserved correctly');
|
||||
@@ -1,48 +0,0 @@
|
||||
// Simple test to verify the NUL-based delimiter works
|
||||
// This simulates what git would produce with the new format
|
||||
|
||||
console.log('Testing NUL-based delimiter functionality...\n');
|
||||
|
||||
// Simulate git log output with NUL-based separator
|
||||
const gitOutputWithNul = `abc123\x00abc1\x00John Doe\x00john@example.com\x002023-01-01T12:00:00Z\x00Initial commit\x00This is a normal commit body\x00def456\x00def4\x00Jane Smith\x00jane@example.com\x002023-01-02T12:00:00Z\x00Fix bug\x00Fixed the bug with ---END--- in this message\x00ghi789\x00ghi7\x00Bob Johnson\x00bob@example.com\x002023-01-03T12:00:00Z\x00Another commit\x00This body has multiple lines\nSecond line\nThird line\x00`;
|
||||
|
||||
// Test splitting on NUL
|
||||
console.log('1. Testing split on NUL character...');
|
||||
const commits = gitOutputWithNul.split('\0').filter((block) => block.trim());
|
||||
console.log(` ✓ Found ${commits.length} commits`);
|
||||
|
||||
console.log('\n2. Testing parsing of each commit...');
|
||||
commits.forEach((commit, index) => {
|
||||
const fields = commit.split('\n');
|
||||
console.log(`\n Commit ${index + 1}:`);
|
||||
console.log(` - Hash: ${fields[0]}`);
|
||||
console.log(` - Short hash: ${fields[1]}`);
|
||||
console.log(` - Author: ${fields[2]}`);
|
||||
console.log(` - Email: ${fields[3]}`);
|
||||
console.log(` - Date: ${fields[4]}`);
|
||||
console.log(` - Subject: ${fields[5]}`);
|
||||
console.log(` - Body: "${fields.slice(6).join('\n')}"`);
|
||||
});
|
||||
|
||||
// Test with problematic ---END--- in message
|
||||
console.log('\n3. Testing with ---END--- in commit message...');
|
||||
const problematicOutput = `abc123\x00abc1\x00John Doe\x00john@example.com\x002023-01-01T12:00:00Z\x00Initial commit\x00This contains ---END--- but should be parsed correctly\x00`;
|
||||
const problematicCommits = problematicOutput.split('\0').filter((block) => block.trim());
|
||||
console.log(
|
||||
` ✓ Found ${problematicCommits.length} commits (correctly ignoring ---END--- in message)`
|
||||
);
|
||||
|
||||
// Test empty blocks
|
||||
console.log('\n4. Testing with empty blocks...');
|
||||
const outputWithEmptyBlocks = `abc123\x00abc1\x00John Doe\x00john@example.com\x002023-01-01T12:00:00Z\x00Valid commit\x00Body here\x00\x00def456\x00def4\x00Jane Smith\x00jane@example.com\x002023-01-02T12:00:00Z\x00Another valid commit\x00Another body\x00`;
|
||||
const outputWithEmptyBlocksParsed = outputWithEmptyBlocks
|
||||
.split('\0')
|
||||
.filter((block) => block.trim());
|
||||
console.log(` ✓ Found ${outputWithEmptyBlocksParsed.length} commits (empty blocks filtered out)`);
|
||||
|
||||
console.log('\n✅ All tests passed! NUL-based delimiter works correctly.');
|
||||
console.log('\nSummary:');
|
||||
console.log('- NUL character (\\x00) properly separates commits');
|
||||
console.log('- ---END--- in commit messages is handled correctly');
|
||||
console.log('- Empty blocks are filtered out');
|
||||
console.log('- Multi-line commit bodies are preserved');
|
||||
@@ -1,165 +0,0 @@
|
||||
// Test to verify the proper NUL-based delimiter functionality
|
||||
// Each commit: field1\nfield2\nfield3\x00field1\nfield2\nfield3\x00...
|
||||
|
||||
console.log('Testing proper NUL-based delimiter format...\n');
|
||||
|
||||
// Proper git output format with NUL between commits
|
||||
const gitOutput = `abc123
|
||||
abc1
|
||||
John Doe
|
||||
john@example.com
|
||||
2023-01-01T12:00:00Z
|
||||
Initial commit
|
||||
This is a normal commit body\x00def456
|
||||
def4
|
||||
Jane Smith
|
||||
jane@example.com
|
||||
2023-01-02T12:00:00Z
|
||||
Fix bug
|
||||
Fixed the bug with ---END--- in this message\x00ghi789
|
||||
ghi7
|
||||
Bob Johnson
|
||||
bob@example.com
|
||||
2023-01-03T12:00:00Z
|
||||
Another commit
|
||||
This body has multiple lines
|
||||
Second line
|
||||
Third line\x00`;
|
||||
|
||||
console.log('1. Testing split on NUL character...');
|
||||
const commitBlocks = gitOutput.split('\0').filter((block) => block.trim());
|
||||
console.log(` ✓ Found ${commitBlocks.length} commit blocks`);
|
||||
|
||||
console.log('\n2. Testing parsing of each commit block...');
|
||||
const commits = [];
|
||||
for (const block of commitBlocks) {
|
||||
const allLines = block.split('\n');
|
||||
|
||||
// Skip leading empty lines
|
||||
let startIndex = 0;
|
||||
while (startIndex < allLines.length && allLines[startIndex].trim() === '') {
|
||||
startIndex++;
|
||||
}
|
||||
const lines = allLines.slice(startIndex);
|
||||
|
||||
if (lines.length >= 6) {
|
||||
const commit = {
|
||||
hash: lines[0].trim(),
|
||||
shortHash: lines[1].trim(),
|
||||
author: lines[2].trim(),
|
||||
authorEmail: lines[3].trim(),
|
||||
date: lines[4].trim(),
|
||||
subject: lines[5].trim(),
|
||||
body: lines.slice(6).join('\n').trim(),
|
||||
};
|
||||
commits.push(commit);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\n3. Successfully parsed ${commits.length} commits:`);
|
||||
commits.forEach((commit, index) => {
|
||||
console.log(`\n Commit ${index + 1}:`);
|
||||
console.log(` - Hash: ${commit.hash}`);
|
||||
console.log(` - Short hash: ${commit.shortHash}`);
|
||||
console.log(` - Author: ${commit.author}`);
|
||||
console.log(` - Email: ${commit.authorEmail}`);
|
||||
console.log(` - Date: ${commit.date}`);
|
||||
console.log(` - Subject: ${commit.subject}`);
|
||||
console.log(` - Body: "${commit.body}"`);
|
||||
});
|
||||
|
||||
// Test with problematic ---END--- in commit message
|
||||
console.log('\n4. Testing with ---END--- in commit message...');
|
||||
const problematicOutput = `test123
|
||||
test1
|
||||
John Doe
|
||||
john@example.com
|
||||
2023-01-01T12:00:00Z
|
||||
Initial commit
|
||||
This contains ---END--- but should be parsed correctly\x00`;
|
||||
const problematicCommits = problematicOutput
|
||||
.split('\0')
|
||||
.filter((block) => block.trim())
|
||||
.map((block) => {
|
||||
const allLines = block.split('\n');
|
||||
|
||||
// Skip leading empty lines
|
||||
let startIndex = 0;
|
||||
while (startIndex < allLines.length && allLines[startIndex].trim() === '') {
|
||||
startIndex++;
|
||||
}
|
||||
const lines = allLines.slice(startIndex);
|
||||
|
||||
if (lines.length >= 6) {
|
||||
return {
|
||||
hash: lines[0].trim(),
|
||||
shortHash: lines[1].trim(),
|
||||
author: lines[2].trim(),
|
||||
authorEmail: lines[3].trim(),
|
||||
date: lines[4].trim(),
|
||||
subject: lines[5].trim(),
|
||||
body: lines.slice(6).join('\n').trim(),
|
||||
};
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter((commit) => commit !== null);
|
||||
|
||||
console.log(` ✓ Found ${problematicCommits.length} commits`);
|
||||
if (problematicCommits.length > 0) {
|
||||
console.log(` Subject: "${problematicCommits[0].subject}"`);
|
||||
console.log(` Body: "${problematicCommits[0].body}"`);
|
||||
}
|
||||
|
||||
// Test with empty body
|
||||
console.log('\n5. Testing commit with empty body...');
|
||||
const emptyBodyOutput = `empty123
|
||||
empty1
|
||||
Alice Brown
|
||||
alice@example.com
|
||||
2023-01-04T12:00:00Z
|
||||
Empty body commit
|
||||
|
||||
\x00`;
|
||||
const emptyBodyCommits = emptyBodyOutput
|
||||
.split('\0')
|
||||
.filter((block) => block.trim())
|
||||
.map((block) => {
|
||||
const allLines = block.split('\n');
|
||||
|
||||
// Skip leading empty lines
|
||||
let startIndex = 0;
|
||||
while (startIndex < allLines.length && allLines[startIndex].trim() === '') {
|
||||
startIndex++;
|
||||
}
|
||||
const lines = allLines.slice(startIndex);
|
||||
|
||||
if (lines.length >= 6) {
|
||||
return {
|
||||
hash: lines[0].trim(),
|
||||
shortHash: lines[1].trim(),
|
||||
author: lines[2].trim(),
|
||||
authorEmail: lines[3].trim(),
|
||||
date: lines[4].trim(),
|
||||
subject: lines[5].trim(),
|
||||
body: lines.slice(6).join('\n').trim(),
|
||||
};
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter((commit) => commit !== null);
|
||||
|
||||
console.log(` ✓ Found ${emptyBodyCommits.length} commits`);
|
||||
if (emptyBodyCommits.length > 0) {
|
||||
console.log(` Subject: "${emptyBodyCommits[0].subject}"`);
|
||||
console.log(` Body: "${emptyBodyCommits[0].body}" (should be empty)`);
|
||||
}
|
||||
|
||||
console.log('\n✅ All tests passed! NUL-based delimiter works correctly.');
|
||||
console.log('\nKey insights:');
|
||||
console.log('- NUL character (\\x00) separates commits');
|
||||
console.log('- Newlines (\\n) separate fields within a commit');
|
||||
console.log('- The parsing logic handles leading empty lines correctly');
|
||||
console.log('- ---END--- in commit messages is handled correctly');
|
||||
console.log('- Empty commit bodies are preserved as empty strings');
|
||||
console.log('- Multi-line commit bodies are preserved correctly');
|
||||
@@ -1,37 +0,0 @@
|
||||
// Simple test to understand the NUL character behavior
|
||||
|
||||
console.log('Testing NUL character behavior...\n');
|
||||
|
||||
// Create a string with NUL characters
|
||||
const str1 =
|
||||
'abc123\x00abc1\x00John Doe\x00john@example.com\x002023-01-01T12:00:00Z\x00Initial commit\x00This is a normal commit body\x00';
|
||||
|
||||
console.log('Original string length:', str1.length);
|
||||
console.log('String representation:', str1);
|
||||
|
||||
// Split on NUL
|
||||
console.log('\n1. Split on NUL character:');
|
||||
const parts = str1.split('\0');
|
||||
console.log('Number of parts:', parts.length);
|
||||
parts.forEach((part, index) => {
|
||||
console.log(`Part ${index}: "${part}" (length: ${part.length})`);
|
||||
});
|
||||
|
||||
// Test with actual git format
|
||||
console.log('\n2. Testing with actual git format:');
|
||||
const gitFormat = `abc123\x00abc1\x00John Doe\x00john@example.com\x002023-01-01T12:00:00Z\x00Initial commit\x00Body text here\x00def456\x00def4\x00Jane Smith\x00jane@example.com\x002023-01-02T12:00:00Z\x00Second commit\x00Body with ---END--- text\x00`;
|
||||
|
||||
const gitParts = gitFormat.split('\0').filter((block) => block.trim());
|
||||
console.log('Number of commits found:', gitParts.length);
|
||||
|
||||
console.log('\nAnalyzing each commit:');
|
||||
gitParts.forEach((block, index) => {
|
||||
console.log(`\nCommit ${index + 1}:`);
|
||||
console.log(`Block: "${block}"`);
|
||||
const fields = block.split('\n');
|
||||
console.log(`Number of fields: ${fields.length}`);
|
||||
fields.forEach((field, fieldIndex) => {
|
||||
const fieldNames = ['hash', 'shortHash', 'author', 'authorEmail', 'date', 'subject', 'body'];
|
||||
console.log(` ${fieldNames[fieldIndex] || `field${fieldIndex}`}: "${field}"`);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user