@@ -10,25 +10,57 @@ import {
1010
1111describe ( 'Color utilities' , ( ) => {
1212 describe ( 'getColorPalette' , ( ) => {
13- it ( 'should return exactly 10 colors' , ( ) => {
13+ it ( 'should return exactly 40 colors' , ( ) => {
1414 const palette = getColorPalette ( )
15- expect ( palette ) . toHaveLength ( 10 )
15+ expect ( palette ) . toHaveLength ( 40 )
1616 } )
1717
1818 it ( 'should return colors matching terminal palette from bash script' , ( ) => {
1919 const palette = getColorPalette ( )
2020 // From bash/new-branch-workflow.sh lines 111-122
2121 const expectedColors : RgbColor [ ] = [
22- { r : 220 , g : 235 , b : 248 } , // Soft blue
23- { r : 248 , g : 220 , b : 235 } , // Soft pink
24- { r : 220 , g : 248 , b : 235 } , // Soft green
25- { r : 248 , g : 240 , b : 220 } , // Soft cream
26- { r : 240 , g : 220 , b : 248 } , // Soft lavender
27- { r : 220 , g : 240 , b : 248 } , // Soft cyan
28- { r : 235 , g : 235 , b : 235 } , // Soft grey
29- { r : 228 , g : 238 , b : 248 } , // Soft ice blue
30- { r : 248 , g : 228 , b : 238 } , // Soft rose
31- { r : 228 , g : 248 , b : 238 } , // Soft mint
22+ // First 10 colors preserved for backward compatibility
23+ { r : 220 , g : 235 , b : 248 } , // 0: Soft blue
24+ { r : 248 , g : 220 , b : 235 } , // 1: Soft pink
25+ { r : 220 , g : 248 , b : 235 } , // 2: Soft green
26+ { r : 248 , g : 240 , b : 220 } , // 3: Soft cream
27+ { r : 240 , g : 220 , b : 248 } , // 4: Soft lavender
28+ { r : 220 , g : 240 , b : 248 } , // 5: Soft cyan
29+ { r : 235 , g : 235 , b : 235 } , // 6: Soft grey
30+ { r : 228 , g : 238 , b : 248 } , // 7: Soft ice blue
31+ { r : 248 , g : 228 , b : 238 } , // 8: Soft rose
32+ { r : 228 , g : 248 , b : 238 } , // 9: Soft mint
33+ // 30 new colors (indices 10-39)
34+ { r : 235 , g : 245 , b : 250 } , // 10: Pale sky blue
35+ { r : 250 , g : 235 , b : 245 } , // 11: Pale orchid
36+ { r : 235 , g : 250 , b : 245 } , // 12: Pale seafoam
37+ { r : 250 , g : 245 , b : 235 } , // 13: Pale peach
38+ { r : 245 , g : 235 , b : 250 } , // 14: Pale periwinkle
39+ { r : 235 , g : 245 , b : 235 } , // 15: Pale sage
40+ { r : 245 , g : 250 , b : 235 } , // 16: Pale lemon
41+ { r : 245 , g : 235 , b : 235 } , // 17: Pale blush
42+ { r : 235 , g : 235 , b : 250 } , // 18: Pale lavender blue
43+ { r : 250 , g : 235 , b : 235 } , // 19: Pale coral
44+ { r : 235 , g : 250 , b : 250 } , // 20: Pale aqua
45+ { r : 240 , g : 248 , b : 255 } , // 21: Alice blue
46+ { r : 255 , g : 240 , b : 248 } , // 22: Lavender blush
47+ { r : 240 , g : 255 , b : 248 } , // 23: Honeydew tint
48+ { r : 255 , g : 248 , b : 240 } , // 24: Antique white
49+ { r : 248 , g : 240 , b : 255 } , // 25: Magnolia
50+ { r : 240 , g : 248 , b : 240 } , // 26: Mint cream tint
51+ { r : 248 , g : 255 , b : 240 } , // 27: Ivory tint
52+ { r : 248 , g : 240 , b : 240 } , // 28: Misty rose tint
53+ { r : 240 , g : 240 , b : 255 } , // 29: Ghost white tint
54+ { r : 255 , g : 245 , b : 238 } , // 30: Seashell
55+ { r : 245 , g : 255 , b : 250 } , // 31: Azure mist
56+ { r : 250 , g : 245 , b : 255 } , // 32: Lilac mist
57+ { r : 255 , g : 250 , b : 245 } , // 33: Snow peach
58+ { r : 238 , g : 245 , b : 255 } , // 34: Powder blue
59+ { r : 255 , g : 238 , b : 245 } , // 35: Pink lace
60+ { r : 245 , g : 255 , b : 238 } , // 36: Pale lime
61+ { r : 238 , g : 255 , b : 245 } , // 37: Pale turquoise
62+ { r : 245 , g : 238 , b : 255 } , // 38: Pale violet
63+ { r : 255 , g : 245 , b : 255 } , // 39: Pale magenta
3264 ]
3365 expect ( palette ) . toEqual ( expectedColors )
3466 } )
@@ -150,7 +182,7 @@ describe('Color utilities', () => {
150182 expect ( ( ) => generateColorFromBranchName ( '功能/my-branch' ) ) . not . toThrow ( )
151183 } )
152184
153- it ( 'should always return color index in range [0, 9 ]' , ( ) => {
185+ it ( 'should always return color index in range [0, 39 ]' , ( ) => {
154186 const testBranches = [
155187 'main' ,
156188 'develop' ,
@@ -164,7 +196,7 @@ describe('Color utilities', () => {
164196 testBranches . forEach ( ( branch ) => {
165197 const color = generateColorFromBranchName ( branch )
166198 expect ( color . index ) . toBeGreaterThanOrEqual ( 0 )
167- expect ( color . index ) . toBeLessThanOrEqual ( 9 )
199+ expect ( color . index ) . toBeLessThanOrEqual ( 39 )
168200 } )
169201 } )
170202
@@ -195,7 +227,7 @@ describe('Color utilities', () => {
195227 // We can verify our implementation produces same index
196228 const color = generateColorFromBranchName ( 'feature/test-branch' )
197229 expect ( color . index ) . toBeGreaterThanOrEqual ( 0 )
198- expect ( color . index ) . toBeLessThanOrEqual ( 9 )
230+ expect ( color . index ) . toBeLessThanOrEqual ( 39 )
199231 // Color should be from palette
200232 const palette = getColorPalette ( )
201233 expect ( color . rgb ) . toEqual ( palette [ color . index ] )
@@ -230,7 +262,7 @@ describe('Color utilities', () => {
230262
231263 // Index in range
232264 expect ( color . index ) . toBeGreaterThanOrEqual ( 0 )
233- expect ( color . index ) . toBeLessThanOrEqual ( 9 )
265+ expect ( color . index ) . toBeLessThanOrEqual ( 39 )
234266
235267 // RGB values valid
236268 expect ( color . rgb . r ) . toBeGreaterThanOrEqual ( 0 )
@@ -268,4 +300,55 @@ describe('Color utilities', () => {
268300 )
269301 } )
270302 } )
303+
304+ describe ( '40-color palette expansion' , ( ) => {
305+ it ( 'should maintain first 10 colors for backward compatibility' , ( ) => {
306+ // Verify first 10 colors unchanged to preserve existing branch colors
307+ const palette = getColorPalette ( )
308+ const originalColors : RgbColor [ ] = [
309+ { r : 220 , g : 235 , b : 248 } , // Soft blue
310+ { r : 248 , g : 220 , b : 235 } , // Soft pink
311+ { r : 220 , g : 248 , b : 235 } , // Soft green
312+ { r : 248 , g : 240 , b : 220 } , // Soft cream
313+ { r : 240 , g : 220 , b : 248 } , // Soft lavender
314+ { r : 220 , g : 240 , b : 248 } , // Soft cyan
315+ { r : 235 , g : 235 , b : 235 } , // Soft grey
316+ { r : 228 , g : 238 , b : 248 } , // Soft ice blue
317+ { r : 248 , g : 228 , b : 238 } , // Soft rose
318+ { r : 228 , g : 248 , b : 238 } , // Soft mint
319+ ]
320+ originalColors . forEach ( ( expected , index ) => {
321+ expect ( palette [ index ] ) . toEqual ( expected )
322+ } )
323+ } )
324+
325+ it ( 'should have all 40 colors be visually distinct' , ( ) => {
326+ // Test that no two colors are too similar (Euclidean distance threshold)
327+ const palette = getColorPalette ( )
328+ for ( let i = 0 ; i < palette . length ; i ++ ) {
329+ for ( let j = i + 1 ; j < palette . length ; j ++ ) {
330+ const distance = Math . sqrt (
331+ Math . pow ( palette [ i ] . r - palette [ j ] . r , 2 ) +
332+ Math . pow ( palette [ i ] . g - palette [ j ] . g , 2 ) +
333+ Math . pow ( palette [ i ] . b - palette [ j ] . b , 2 )
334+ )
335+ // Minimum distance threshold to ensure visual distinction
336+ // For subtle colors (RGB >= 220), we allow smaller distances since the color space is constrained
337+ // A distance of 3+ ensures colors are not identical or too similar
338+ expect ( distance ) . toBeGreaterThanOrEqual ( 3 )
339+ }
340+ }
341+ } )
342+
343+ it ( 'should maintain subtlety constraint for all 40 colors' , ( ) => {
344+ // This already exists but confirms it works for expanded palette
345+ const palette = getColorPalette ( )
346+ expect ( palette ) . toHaveLength ( 40 )
347+ palette . forEach ( ( color ) => {
348+ expect ( color . r ) . toBeGreaterThanOrEqual ( 220 )
349+ expect ( color . g ) . toBeGreaterThanOrEqual ( 220 )
350+ expect ( color . b ) . toBeGreaterThanOrEqual ( 220 )
351+ } )
352+ } )
353+ } )
271354} )
0 commit comments