2026-04-01 17:43:00 -07:00
const { afterEach , beforeEach , describe , expect , mock , test } = require ( "bun:test" )
import { existsSync , mkdirSync , mkdtempSync , readFileSync , rmSync , writeFileSync } from "node:fs"
import { tmpdir } from "node:os"
import { join } from "node:path"
import { getOpenCodeConfigDir } from "../../shared"
const { clearPluginExtendedConfigCache , loadPluginExtendedConfig } = await import ( "./config-loader" )
describe ( "loadPluginExtendedConfig" , ( ) = > {
const originalDateNow = Date . now
let originalWorkingDirectory = ""
let tempDirectory = ""
let userConfigPath = ""
let projectConfigPath = ""
let originalUserConfig : string | null = null
let mockedNow = 0
beforeEach ( ( ) = > {
//#given
originalWorkingDirectory = process . cwd ( )
tempDirectory = mkdtempSync ( join ( tmpdir ( ) , "omo-cc-plugin-project-config-" ) )
userConfigPath = join ( getOpenCodeConfigDir ( { binary : "opencode" } ) , "opencode-cc-plugin.json" )
projectConfigPath = join ( tempDirectory , ".opencode" , "opencode-cc-plugin.json" )
mkdirSync ( getOpenCodeConfigDir ( { binary : "opencode" } ) , { recursive : true } )
mkdirSync ( join ( tempDirectory , ".opencode" ) , { recursive : true } )
originalUserConfig = existsSync ( userConfigPath )
? readFileSync ( userConfigPath , "utf8" )
: null
process . chdir ( tempDirectory )
mockedNow = 1 _000
Date . now = ( ) = > mockedNow
clearPluginExtendedConfigCache ( )
} )
afterEach ( ( ) = > {
clearPluginExtendedConfigCache ( )
Date . now = originalDateNow
process . chdir ( originalWorkingDirectory )
rmSync ( tempDirectory , { recursive : true , force : true } )
if ( originalUserConfig === null ) {
rmSync ( userConfigPath , { force : true } )
} else {
writeFileSync ( userConfigPath , originalUserConfig )
}
} )
test ( "#given cached extended config #when files change within ttl #then cached config is reused" , async ( ) = > {
//#given
writeConfigFile ( userConfigPath , [ "user-first" ] )
writeConfigFile ( projectConfigPath , [ "project-first" ] )
//#when
const firstResult = await loadPluginExtendedConfig ( )
writeConfigFile ( userConfigPath , [ "user-second" ] )
writeConfigFile ( projectConfigPath , [ "project-second" ] )
mockedNow += 5 _000
const secondResult = await loadPluginExtendedConfig ( )
//#then
expect ( firstResult ) . toEqual ( {
disabledHooks : {
Stop : [ "project-first" ] ,
} ,
} )
expect ( secondResult ) . toEqual ( firstResult )
} )
test ( "#given cached extended config #when ttl expires or cache clears #then updated config is reloaded" , async ( ) = > {
//#given
writeConfigFile ( userConfigPath , [ "user-first" ] )
writeConfigFile ( projectConfigPath , [ "project-first" ] )
await loadPluginExtendedConfig ( )
//#when
writeConfigFile ( userConfigPath , [ "user-second" ] )
writeConfigFile ( projectConfigPath , [ "project-second" ] )
mockedNow += 31 _000
const ttlReloaded = await loadPluginExtendedConfig ( )
writeConfigFile ( userConfigPath , [ "user-third" ] )
writeConfigFile ( projectConfigPath , [ "project-third" ] )
clearPluginExtendedConfigCache ( )
const manuallyReloaded = await loadPluginExtendedConfig ( )
//#then
expect ( ttlReloaded ) . toEqual ( {
disabledHooks : {
Stop : [ "project-second" ] ,
} ,
} )
expect ( manuallyReloaded ) . toEqual ( {
disabledHooks : {
Stop : [ "project-third" ] ,
} ,
} )
} )
2026-04-05 11:23:01 +09:00
test ( "#given OPENCODE_CONFIG_DIR points at a profile dir after module import #when loading extended config #then it reads the profile config file" , async ( ) = > {
//#given
const profileConfigDir = join ( tempDirectory , ".config" , "opencode" , "profiles" , "today" )
const profileConfigPath = join ( profileConfigDir , "opencode-cc-plugin.json" )
mkdirSync ( profileConfigDir , { recursive : true } )
process . env . OPENCODE_CONFIG_DIR = profileConfigDir
writeConfigFile ( profileConfigPath , [ "profile-stop" ] )
//#when
clearPluginExtendedConfigCache ( )
const result = await loadPluginExtendedConfig ( )
//#then
expect ( result ) . toEqual ( {
disabledHooks : {
Stop : [ "profile-stop" ] ,
} ,
} )
} )
2026-04-01 17:43:00 -07:00
} )
function writeConfigFile ( filePath : string , stopPatterns : string [ ] ) : void {
writeFileSync (
filePath ,
JSON . stringify ( {
disabledHooks : {
Stop : stopPatterns ,
} ,
} ) ,
)
}
export { }