@@ -16,6 +16,10 @@ function makeTmp(): string {
1616 ) ;
1717}
1818
19+ async function writeJson ( path : string , value : unknown ) : Promise < void > {
20+ await writeFile ( path , JSON . stringify ( value ) ) ;
21+ }
22+
1923test ( "profilesDir returns ~/.corbits/profiles" , ( ) => {
2024 const result = profilesDir ( "/home/user" ) ;
2125 expect ( result ) . toBe ( "/home/user/.corbits/profiles" ) ;
@@ -35,7 +39,7 @@ test("loadProfile parses valid profile", async () => {
3539 const dir = makeTmp ( ) ;
3640 await mkdir ( dir , { recursive : true } ) ;
3741 const path = join ( dir , "profile.json" ) ;
38- await writeFile ( path , JSON . stringify ( { model : "claude-opus-4-8" } ) ) ;
42+ await writeJson ( path , { model : "claude-opus-4-8" } ) ;
3943 const result = await loadProfile ( path ) ;
4044 expect ( result ) . toEqual ( { model : "claude-opus-4-8" } ) ;
4145} ) ;
@@ -44,10 +48,9 @@ test("loadProfile parses systemPromptExtensions", async () => {
4448 const dir = makeTmp ( ) ;
4549 await mkdir ( dir , { recursive : true } ) ;
4650 const path = join ( dir , "profile.json" ) ;
47- await writeFile (
48- path ,
49- JSON . stringify ( { systemPromptExtensions : [ "no-destructive-migrations" ] } ) ,
50- ) ;
51+ await writeJson ( path , {
52+ systemPromptExtensions : [ "no-destructive-migrations" ] ,
53+ } ) ;
5154 const result = await loadProfile ( path ) ;
5255 expect ( result ) . toEqual ( {
5356 systemPromptExtensions : [ "no-destructive-migrations" ] ,
@@ -58,15 +61,15 @@ test("loadProfile rejects unknown keys", async () => {
5861 const dir = makeTmp ( ) ;
5962 await mkdir ( dir , { recursive : true } ) ;
6063 const path = join ( dir , "profile.json" ) ;
61- await writeFile ( path , JSON . stringify ( { model : "x" , unknownKey : true } ) ) ;
64+ await writeJson ( path , { model : "x" , unknownKey : true } ) ;
6265 await expect ( loadProfile ( path ) ) . rejects . toThrow ( / u n k n o w n K e y m u s t b e r e m o v e d / ) ;
6366} ) ;
6467
6568test ( "loadProfile rejects non-array systemPromptExtensions" , async ( ) => {
6669 const dir = makeTmp ( ) ;
6770 await mkdir ( dir , { recursive : true } ) ;
6871 const path = join ( dir , "profile.json" ) ;
69- await writeFile ( path , JSON . stringify ( { systemPromptExtensions : "bad" } ) ) ;
72+ await writeJson ( path , { systemPromptExtensions : "bad" } ) ;
7073 await expect ( loadProfile ( path ) ) . rejects . toThrow ( / s y s t e m P r o m p t E x t e n s i o n s / ) ;
7174} ) ;
7275
@@ -101,10 +104,7 @@ test("resolveProfile loads a valid named profile", async () => {
101104 await mkdir ( cwd , { recursive : true } ) ;
102105 const namedDir = join ( home , ".corbits" , "profiles" ) ;
103106 await mkdir ( namedDir , { recursive : true } ) ;
104- await writeFile (
105- join ( namedDir , "work.json" ) ,
106- JSON . stringify ( { model : "named-model" } ) ,
107- ) ;
107+ await writeJson ( join ( namedDir , "work.json" ) , { model : "named-model" } ) ;
108108 const result = await resolveProfile ( cwd , "work" , home ) ;
109109 expect ( result . model ) . toBe ( "named-model" ) ;
110110 expect ( result . profile ) . toBe ( "work" ) ;
@@ -114,13 +114,10 @@ test("resolveProfile applies project profile fields", async () => {
114114 const cwd = makeTmp ( ) ;
115115 const dir = join ( cwd , ".corbits" ) ;
116116 await mkdir ( dir , { recursive : true } ) ;
117- await writeFile (
118- join ( dir , "profile.json" ) ,
119- JSON . stringify ( {
120- model : "claude-sonnet" ,
121- systemPromptExtensions : [ "ext1" ] ,
122- } ) ,
123- ) ;
117+ await writeJson ( join ( dir , "profile.json" ) , {
118+ model : "claude-sonnet" ,
119+ systemPromptExtensions : [ "ext1" ] ,
120+ } ) ;
124121 const result = await resolveProfile ( cwd ) ;
125122 expect ( result . model ) . toBe ( "claude-sonnet" ) ;
126123 expect ( result . systemPromptExtensions ) . toEqual ( [ "ext1" ] ) ;
@@ -132,10 +129,7 @@ test("resolveProfile throws when a named profile key points at a missing file",
132129 const dir = join ( cwd , ".corbits" ) ;
133130 await mkdir ( dir , { recursive : true } ) ;
134131 const name = "no-such-named-profile" ;
135- await writeFile (
136- join ( dir , "profile.json" ) ,
137- JSON . stringify ( { profile : name } ) ,
138- ) ;
132+ await writeJson ( join ( dir , "profile.json" ) , { profile : name } ) ;
139133 const missingPath = join ( profilesDir ( home ) , `${ name } .json` ) ;
140134 await expect ( resolveProfile ( cwd , undefined , home ) ) . rejects . toThrow (
141135 missingPath ,
@@ -147,25 +141,19 @@ test("resolveProfile: project profile fields override named profile fields", asy
147141 const cwd = makeTmp ( ) ;
148142 const namedDir = join ( home , ".corbits" , "profiles" ) ;
149143 await mkdir ( namedDir , { recursive : true } ) ;
150- await writeFile (
144+ await writeJson (
151145 join ( namedDir , "work.json" ) ,
152- JSON . stringify ( { model : "base-model" , systemPromptExtensions : [ "ext1" ] } ) ,
146+ { model : "base-model" , systemPromptExtensions : [ "ext1" ] } ,
153147 ) ;
154148 const localDir = join ( cwd , ".corbits" ) ;
155149 await mkdir ( localDir , { recursive : true } ) ;
156- await writeFile (
150+ await writeJson (
157151 join ( localDir , "profile.json" ) ,
158- JSON . stringify ( { profile : "work" , model : "override-model" } ) ,
152+ { profile : "work" , model : "override-model" } ,
159153 ) ;
160154
161- // We can't easily inject profilesDir home in resolveProfile without additional plumbing,
162- // so test the merge logic directly via the exported functions.
163- // Project profile model should win over named profile model.
164- const projectProfile = await loadProfile ( join ( localDir , "profile.json" ) ) ;
165- const namedProfile = await loadProfile ( join ( namedDir , "work.json" ) ) ;
166- const merged = { ...namedProfile } ;
167- if ( projectProfile ?. model !== undefined ) merged . model = projectProfile . model ;
168- expect ( merged . model ) . toBe ( "override-model" ) ;
169- // systemPromptExtensions not in project profile so named profile value survives
170- expect ( merged . systemPromptExtensions ) . toEqual ( [ "ext1" ] ) ;
155+ const result = await resolveProfile ( cwd , undefined , home ) ;
156+ expect ( result . model ) . toBe ( "override-model" ) ;
157+ expect ( result . systemPromptExtensions ) . toEqual ( [ "ext1" ] ) ;
158+ expect ( result . profile ) . toBe ( "work" ) ;
171159} ) ;
0 commit comments