Skip to content

Commit 1aceb60

Browse files
Copilotwarengonzaga
andcommitted
🧪 test: update tests for convention system and fix linting issues
Co-authored-by: warengonzaga <15052701+warengonzaga@users.noreply.github.com>
1 parent 3f9f61a commit 1aceb60

6 files changed

Lines changed: 111 additions & 32 deletions

File tree

source/cli.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import process from 'node:process';
33
import {Command} from 'commander';
44
import packageJSON from '../package.json';
5-
import {showBanner, showWarning} from './utils/ui.js';
5+
import {showBanner, showWarning, showSuccess, showError} from './utils/ui.js';
66
import {commitCommand} from './commands/commit.js';
77
import {
88
authenticateWithCopilot,
@@ -11,8 +11,7 @@ import {
1111
logout,
1212
} from './commands/auth.js';
1313
import {showConfig, resetConfig} from './commands/config.js';
14-
import {setConvention, getConvention} from './utils/config-manager.js';
15-
import {showSuccess, showError} from './utils/ui.js';
14+
import {setConvention} from './utils/config-manager.js';
1615

1716
const program = new Command();
1817

source/commands/auth.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import {execa} from 'execa';
21
import process from 'node:process';
2+
import {execa} from 'execa';
33
import {
44
setAuthMode,
55
setToken,
@@ -19,7 +19,7 @@ import {
1919
* Handles GitHub Copilot and OpenAI authentication
2020
*/
2121

22-
export async function authenticateWithCopilot(token = null) {
22+
export async function authenticateWithCopilot() {
2323
try {
2424
console.log('🔐 Setting up GitHub Copilot authentication...\n');
2525

source/commands/commit.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,14 @@ export async function processFilesInteractively(aiProvider, options = {}) {
142142

143143
while (!fileProcessed) {
144144
try {
145-
const message = await aiProvider.generateCommitMessage(
146-
diff,
147-
file,
148-
{...options, convention: currentConvention},
149-
);
145+
const message = await aiProvider.generateCommitMessage(diff, file, {
146+
...options,
147+
convention: currentConvention,
148+
});
150149

151150
const result = await confirmCommit(message, file, currentConvention);
152151

152+
// eslint-disable-next-line unicorn/prefer-switch
153153
if (result.action === 'accept') {
154154
const success = await commit(result.message);
155155
if (success) {
@@ -190,6 +190,7 @@ export async function processFilesInteractively(aiProvider, options = {}) {
190190
}
191191
/* eslint-enable no-await-in-loop */
192192

193+
/* eslint-disable no-await-in-loop */
193194
export async function processFile(filePath, aiProvider, options = {}) {
194195
showInfo(`Processing single file: ${filePath}`);
195196
console.log('');
@@ -217,11 +218,10 @@ export async function processFile(filePath, aiProvider, options = {}) {
217218
showInfo('Generating commit message...');
218219

219220
try {
220-
const message = await aiProvider.generateCommitMessage(
221-
diff,
222-
filePath,
223-
{...options, convention: currentConvention},
224-
);
221+
const message = await aiProvider.generateCommitMessage(diff, filePath, {
222+
...options,
223+
convention: currentConvention,
224+
});
225225

226226
const result = await confirmCommit(message, filePath, currentConvention);
227227

@@ -258,3 +258,4 @@ export async function processFile(filePath, aiProvider, options = {}) {
258258
showWarning('Maximum regeneration attempts reached.');
259259
await unstageFile(filePath);
260260
}
261+
/* eslint-enable no-await-in-loop */

source/utils/commit-conventions.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ export const CONVENTIONS = {
22
clean: {
33
name: 'Clean Commit',
44
description: 'wgtechlabs Clean Commit format with emojis',
5-
buildPrompt: (diff, filePath) => `You are an expert at writing git commit messages following the "Clean Commit" format.
5+
buildPrompt: (
6+
diff,
7+
filePath,
8+
) => `You are an expert at writing git commit messages following the "Clean Commit" format.
69
710
**Clean Commit Format:**
811
<emoji> <type>: <description>
@@ -40,7 +43,10 @@ Generate a single commit message following Clean Commit format. Return ONLY the
4043
conventional: {
4144
name: 'Conventional Commits',
4245
description: 'Standard Conventional Commits specification',
43-
buildPrompt: (diff, filePath) => `You are an expert at writing git commit messages following the "Conventional Commits" specification.
46+
buildPrompt: (
47+
diff,
48+
filePath,
49+
) => `You are an expert at writing git commit messages following the "Conventional Commits" specification.
4450
4551
**Format:**
4652
<type>(<scope>): <description>
@@ -76,7 +82,10 @@ Generate a single commit message following Conventional Commits format. Return O
7682
gitmoji: {
7783
name: 'Gitmoji',
7884
description: 'Gitmoji commit convention with emojis',
79-
buildPrompt: (diff, filePath) => `You are an expert at writing git commit messages using the "Gitmoji" convention.
85+
buildPrompt: (
86+
diff,
87+
filePath,
88+
) => `You are an expert at writing git commit messages using the "Gitmoji" convention.
8089
8190
**Format:**
8291
:<emoji-code>: <description>
@@ -113,7 +122,10 @@ Generate a single commit message using Gitmoji format. Return ONLY the commit me
113122
simple: {
114123
name: 'Simple',
115124
description: 'Plain descriptive commit messages',
116-
buildPrompt: (diff, filePath) => `You are an expert at writing clear, concise git commit messages.
125+
buildPrompt: (
126+
diff,
127+
filePath,
128+
) => `You are an expert at writing clear, concise git commit messages.
117129
118130
**Format:**
119131
Simple descriptive message in imperative mood

source/utils/ui.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import chalk from 'chalk';
22
import figlet from 'figlet';
33
import inquirer from 'inquirer';
4-
import {
5-
listConventions,
6-
getConvention,
7-
} from '../utils/commit-conventions.js';
4+
import {listConventions, getConvention} from '../utils/commit-conventions.js';
85

96
/**
107
* UI utilities for magic-commit terminal interface
@@ -72,7 +69,10 @@ export async function confirmCommit(
7269
choices: [
7370
{name: '✅ Accept and commit', value: 'accept'},
7471
{name: '✏️ Edit message', value: 'edit'},
75-
{name: '🔄 Regenerate with different convention', value: 'change-convention'},
72+
{
73+
name: '🔄 Regenerate with different convention',
74+
value: 'change-convention',
75+
},
7676
{name: '⏭️ Skip this file', value: 'skip'},
7777
],
7878
},

test.js

Lines changed: 75 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,14 @@ import {
55
setToken,
66
getAuthMode,
77
getToken,
8+
setConvention,
9+
getConvention,
810
clearAll,
911
} from './source/utils/config-manager.js';
12+
import {
13+
getConvention as getConventionDetails,
14+
listConventions,
15+
} from './source/utils/commit-conventions.js';
1016

1117
test('config manager stores and retrieves auth mode', t => {
1218
clearAll();
@@ -33,18 +39,79 @@ test('config manager stores and retrieves tokens', t => {
3339
t.is(getToken('github'), undefined);
3440
});
3541

36-
test('AIProvider builds Clean Commit prompt correctly', t => {
37-
const provider = new AIProvider({authMode: 'openai'});
42+
test('config manager stores and retrieves convention', t => {
43+
clearAll();
44+
t.is(getConvention(), 'clean'); // Default
45+
46+
setConvention('conventional');
47+
t.is(getConvention(), 'conventional');
48+
49+
setConvention('gitmoji');
50+
t.is(getConvention(), 'gitmoji');
51+
52+
clearAll();
53+
t.is(getConvention(), 'clean'); // Back to default
54+
});
55+
56+
test('convention system returns correct convention details', t => {
57+
const cleanConv = getConventionDetails('clean');
58+
t.is(cleanConv.name, 'Clean Commit');
59+
t.true(cleanConv.description.includes('emoji'));
60+
61+
const conventionalConv = getConventionDetails('conventional');
62+
t.is(conventionalConv.name, 'Conventional Commits');
63+
64+
const gitmojiConv = getConventionDetails('gitmoji');
65+
t.is(gitmojiConv.name, 'Gitmoji');
66+
67+
const simpleConv = getConventionDetails('simple');
68+
t.is(simpleConv.name, 'Simple');
69+
});
70+
71+
test('convention system lists all conventions', t => {
72+
const conventions = listConventions();
73+
t.is(conventions.length, 4);
74+
t.true(conventions.some(c => c.value === 'clean'));
75+
t.true(conventions.some(c => c.value === 'conventional'));
76+
t.true(conventions.some(c => c.value === 'gitmoji'));
77+
t.true(conventions.some(c => c.value === 'simple'));
78+
});
79+
80+
test('convention system builds prompts correctly', t => {
3881
const diff = 'test diff content';
3982
const filePath = 'test.js';
4083

41-
const prompt = provider.buildCleanCommitPrompt(diff, filePath);
84+
// Test Clean Commit
85+
const cleanConv = getConventionDetails('clean');
86+
const cleanPrompt = cleanConv.buildPrompt(diff, filePath);
87+
t.true(cleanPrompt.includes('Clean Commit'));
88+
t.true(cleanPrompt.includes('test diff content'));
89+
t.true(cleanPrompt.includes('test.js'));
90+
t.true(cleanPrompt.includes('📦'));
91+
92+
// Test Conventional Commits
93+
const conventionalConv = getConventionDetails('conventional');
94+
const conventionalPrompt = conventionalConv.buildPrompt(diff, filePath);
95+
t.true(conventionalPrompt.includes('Conventional Commits'));
96+
t.true(conventionalPrompt.includes('feat:'));
97+
t.true(conventionalPrompt.includes('fix:'));
98+
99+
// Test Gitmoji
100+
const gitmojiConv = getConventionDetails('gitmoji');
101+
const gitmojiPrompt = gitmojiConv.buildPrompt(diff, filePath);
102+
t.true(gitmojiPrompt.includes('Gitmoji'));
103+
t.true(gitmojiPrompt.includes(':sparkles:'));
104+
105+
// Test Simple
106+
const simpleConv = getConventionDetails('simple');
107+
const simplePrompt = simpleConv.buildPrompt(diff, filePath);
108+
t.true(simplePrompt.includes('imperative mood'));
109+
t.true(simplePrompt.includes('test diff content'));
110+
});
42111

43-
t.true(prompt.includes('Clean Commit'));
44-
t.true(prompt.includes('test diff content'));
45-
t.true(prompt.includes('test.js'));
46-
t.true(prompt.includes('📦'));
47-
t.true(prompt.includes('🔧'));
112+
test('convention system defaults to clean for unknown convention', t => {
113+
const unknownConv = getConventionDetails('unknown-convention');
114+
t.is(unknownConv.name, 'Clean Commit'); // Should fallback to clean
48115
});
49116

50117
test('AIProvider generates fallback message for large diffs', t => {

0 commit comments

Comments
 (0)