1+ import { test , describe , beforeEach , afterEach } from 'node:test' ;
2+ import assert from 'node:assert' ;
3+ import fs from 'fs' ;
4+ import path from 'path' ;
5+
6+ // Helper function that replicates loadConfig logic for testing
7+ function loadConfig ( cwd ) {
8+ const DEFAULTS = {
9+ includePatterns : [ '*' ] ,
10+ format : '[${ticket}] ${msg}' ,
11+ fallbackFormat : '[${seg0}] ${msg}' ,
12+ exclude : [ 'merge' , 'squash' , 'revert' ]
13+ } ;
14+
15+ try {
16+ const pkg = JSON . parse ( fs . readFileSync ( path . join ( cwd , 'package.json' ) , 'utf-8' ) ) ;
17+ const pkgCfg = pkg . commitFromBranch ;
18+ const cfg = ( pkgCfg ?? { } ) ;
19+ const include = cfg . includePattern ?? '*' ;
20+
21+ return {
22+ includePatterns : Array . isArray ( include ) ? include : [ include ] ,
23+ format : cfg . format ?? DEFAULTS . format ,
24+ fallbackFormat : cfg . fallbackFormat ?? DEFAULTS . fallbackFormat ,
25+ exclude : ( cfg . exclude ?? DEFAULTS . exclude ) . map ( String )
26+ } ;
27+ } catch {
28+ return { ...DEFAULTS } ;
29+ }
30+ }
31+
32+ describe ( 'loadConfig' , ( ) => {
33+ let tempDir ;
34+
35+ beforeEach ( ( ) => {
36+ tempDir = fs . mkdtempSync ( path . join ( process . cwd ( ) , 'config-test-' ) ) ;
37+ } ) ;
38+
39+ afterEach ( ( ) => {
40+ if ( tempDir && fs . existsSync ( tempDir ) ) {
41+ fs . rmSync ( tempDir , { recursive : true , force : true } ) ;
42+ }
43+ } ) ;
44+
45+ test ( 'should return defaults when no package.json exists' , ( ) => {
46+ const config = loadConfig ( tempDir ) ;
47+
48+ assert . deepStrictEqual ( config , {
49+ includePatterns : [ '*' ] ,
50+ format : '[${ticket}] ${msg}' ,
51+ fallbackFormat : '[${seg0}] ${msg}' ,
52+ exclude : [ 'merge' , 'squash' , 'revert' ]
53+ } ) ;
54+ } ) ;
55+
56+ test ( 'should return defaults when package.json has no config' , ( ) => {
57+ const packageJson = {
58+ name : 'test-package' ,
59+ version : '1.0.0'
60+ } ;
61+ fs . writeFileSync (
62+ path . join ( tempDir , 'package.json' ) ,
63+ JSON . stringify ( packageJson , null , 2 )
64+ ) ;
65+
66+ const config = loadConfig ( tempDir ) ;
67+
68+ assert . deepStrictEqual ( config , {
69+ includePatterns : [ '*' ] ,
70+ format : '[${ticket}] ${msg}' ,
71+ fallbackFormat : '[${seg0}] ${msg}' ,
72+ exclude : [ 'merge' , 'squash' , 'revert' ]
73+ } ) ;
74+ } ) ;
75+
76+ test ( 'should load custom config from package.json' , ( ) => {
77+ const packageJson = {
78+ name : 'test-package' ,
79+ version : '1.0.0' ,
80+ commitFromBranch : {
81+ includePattern : [ 'feature/*' , 'hotfix/*' ] ,
82+ format : '${ticket}: ${msg}' ,
83+ fallbackFormat : '${branch} - ${msg}' ,
84+ exclude : [ 'merge' ]
85+ }
86+ } ;
87+ fs . writeFileSync (
88+ path . join ( tempDir , 'package.json' ) ,
89+ JSON . stringify ( packageJson , null , 2 )
90+ ) ;
91+
92+ const config = loadConfig ( tempDir ) ;
93+
94+ assert . deepStrictEqual ( config , {
95+ includePatterns : [ 'feature/*' , 'hotfix/*' ] ,
96+ format : '${ticket}: ${msg}' ,
97+ fallbackFormat : '${branch} - ${msg}' ,
98+ exclude : [ 'merge' ]
99+ } ) ;
100+ } ) ;
101+
102+ test ( 'should handle single includePattern as string' , ( ) => {
103+ const packageJson = {
104+ name : 'test-package' ,
105+ version : '1.0.0' ,
106+ commitFromBranch : {
107+ includePattern : 'feature/*'
108+ }
109+ } ;
110+ fs . writeFileSync (
111+ path . join ( tempDir , 'package.json' ) ,
112+ JSON . stringify ( packageJson , null , 2 )
113+ ) ;
114+
115+ const config = loadConfig ( tempDir ) ;
116+
117+ assert . deepStrictEqual ( config . includePatterns , [ 'feature/*' ] ) ;
118+ } ) ;
119+
120+ test ( 'should merge partial config with defaults' , ( ) => {
121+ const packageJson = {
122+ name : 'test-package' ,
123+ version : '1.0.0' ,
124+ commitFromBranch : {
125+ format : 'CUSTOM: ${msg}'
126+ }
127+ } ;
128+ fs . writeFileSync (
129+ path . join ( tempDir , 'package.json' ) ,
130+ JSON . stringify ( packageJson , null , 2 )
131+ ) ;
132+
133+ const config = loadConfig ( tempDir ) ;
134+
135+ assert . strictEqual ( config . format , 'CUSTOM: ${msg}' ) ;
136+ assert . strictEqual ( config . fallbackFormat , '[${seg0}] ${msg}' ) ; // should use default
137+ assert . deepStrictEqual ( config . exclude , [ 'merge' , 'squash' , 'revert' ] ) ; // should use default
138+ } ) ;
139+
140+ test ( 'should handle malformed package.json gracefully' , ( ) => {
141+ fs . writeFileSync (
142+ path . join ( tempDir , 'package.json' ) ,
143+ '{ invalid json }'
144+ ) ;
145+
146+ const config = loadConfig ( tempDir ) ;
147+
148+ assert . deepStrictEqual ( config , {
149+ includePatterns : [ '*' ] ,
150+ format : '[${ticket}] ${msg}' ,
151+ fallbackFormat : '[${seg0}] ${msg}' ,
152+ exclude : [ 'merge' , 'squash' , 'revert' ]
153+ } ) ;
154+ } ) ;
155+ } ) ;
0 commit comments