@@ -112,6 +112,18 @@ const writeCache = (data: object, mtimeMs?: number) => writeCacheText(JSON.strin
112112const provided = < A , E > ( state : Ref . Ref < MockState > , eff : Effect . Effect < A , E , ModelsDev . Service > ) =>
113113 eff . pipe ( Effect . provide ( buildLayer ( state ) ) )
114114
115+ const withFetch = < A , E , R > ( effect : Effect . Effect < A , E , R > ) =>
116+ Effect . acquireUseRelease (
117+ Effect . sync ( ( ) => {
118+ Flag . OPENCODE_DISABLE_MODELS_FETCH = false
119+ } ) ,
120+ ( ) => effect ,
121+ ( ) =>
122+ Effect . sync ( ( ) => {
123+ Flag . OPENCODE_DISABLE_MODELS_FETCH = true
124+ } ) ,
125+ )
126+
115127beforeEach ( async ( ) => {
116128 await rm ( cacheFile , { force : true } )
117129} )
@@ -159,16 +171,7 @@ describe("ModelsDev Service", () => {
159171 yield * writeCacheText ( "{" )
160172 const state = yield * Ref . make ( { ...initialState , body : JSON . stringify ( fixture2 ) } )
161173 const context = yield * Layer . build ( buildLayer ( state ) )
162- const result = yield * Effect . acquireUseRelease (
163- Effect . sync ( ( ) => {
164- Flag . OPENCODE_DISABLE_MODELS_FETCH = false
165- } ) ,
166- ( ) => ModelsDev . Service . use ( ( s ) => s . get ( ) ) . pipe ( Effect . provide ( context ) ) ,
167- ( ) =>
168- Effect . sync ( ( ) => {
169- Flag . OPENCODE_DISABLE_MODELS_FETCH = true
170- } ) ,
171- )
174+ const result = yield * withFetch ( ModelsDev . Service . use ( ( s ) => s . get ( ) ) . pipe ( Effect . provide ( context ) ) )
172175 expect ( result ) . toEqual ( fixture2 )
173176 expect ( yield * Effect . promise ( ( ) => readFile ( cacheFile , "utf8" ) ) ) . toBe ( JSON . stringify ( fixture2 ) )
174177 const final = yield * Ref . get ( state )
@@ -180,21 +183,34 @@ describe("ModelsDev Service", () => {
180183 Effect . gen ( function * ( ) {
181184 const state = yield * Ref . make ( { ...initialState , status : 503 } )
182185 const context = yield * Layer . build ( buildLayer ( state ) )
183- const result = yield * Effect . acquireUseRelease (
184- Effect . sync ( ( ) => {
185- Flag . OPENCODE_DISABLE_MODELS_FETCH = false
186- } ) ,
187- ( ) => ModelsDev . Service . use ( ( s ) => s . get ( ) ) . pipe ( Effect . provide ( context ) ) ,
188- ( ) =>
189- Effect . sync ( ( ) => {
190- Flag . OPENCODE_DISABLE_MODELS_FETCH = true
191- } ) ,
192- )
186+ const result = yield * withFetch ( ModelsDev . Service . use ( ( s ) => s . get ( ) ) . pipe ( Effect . provide ( context ) ) )
193187 expect ( result ) . toEqual ( { } )
194188 expect ( ( yield * Ref . get ( state ) ) . calls . length ) . toBe ( 3 )
195189 } ) ,
196190 )
197191
192+ it . live ( "get() returns an empty catalog when the response is malformed JSON" , ( ) =>
193+ Effect . gen ( function * ( ) {
194+ const state = yield * Ref . make ( { ...initialState , body : "{" } )
195+ const context = yield * Layer . build ( buildLayer ( state ) )
196+ const result = yield * withFetch ( ModelsDev . Service . use ( ( s ) => s . get ( ) ) . pipe ( Effect . provide ( context ) ) )
197+ expect ( result ) . toEqual ( { } )
198+ expect ( ( yield * Ref . get ( state ) ) . calls . length ) . toBe ( 1 )
199+ expect ( yield * Effect . promise ( ( ) => Bun . file ( cacheFile ) . exists ( ) ) ) . toBe ( false )
200+ } ) ,
201+ )
202+
203+ it . live ( "get() returns an empty catalog when the response has an invalid shape" , ( ) =>
204+ Effect . gen ( function * ( ) {
205+ const state = yield * Ref . make ( { ...initialState , body : JSON . stringify ( { acme : { } } ) } )
206+ const context = yield * Layer . build ( buildLayer ( state ) )
207+ const result = yield * withFetch ( ModelsDev . Service . use ( ( s ) => s . get ( ) ) . pipe ( Effect . provide ( context ) ) )
208+ expect ( result ) . toEqual ( { } )
209+ expect ( ( yield * Ref . get ( state ) ) . calls . length ) . toBe ( 1 )
210+ expect ( yield * Effect . promise ( ( ) => Bun . file ( cacheFile ) . exists ( ) ) ) . toBe ( false )
211+ } ) ,
212+ )
213+
198214 it . live ( "get() is single-flight under concurrent calls" , ( ) =>
199215 Effect . gen ( function * ( ) {
200216 yield * writeCache ( fixture )
0 commit comments