2025-09-24 17:31:48 -07:00
/ * *
* Virtual Filesystem Tests
*
* REAL tests for production VFS implementation
* These tests demonstrate that VFS actually works
* /
import { describe , it , expect , beforeEach , afterEach } from 'vitest'
refactor(8.0): remove dead, unreachable, and unwired modules
Pre-GA dead-code sweep. A deterministic import-reachability walk from the
package's real entry points (the exports map, the CLI bin, the conversation
surface) found 34 source modules that nothing reachable imports — they
compile and ship as dist output that no consumer or internal path can ever
reach. All were superseded duplicates, abandoned parallel implementations,
or built-but-never-wired features:
- superseded duplicates of live modules: an older "unified" entry, a
standalone neural-import variant, a static NLP processor + its matcher,
a parallel API-types module, a duplicate progress-types module
- an abandoned import path (orchestrator + entity deduplicator + barrels)
left behind when ingestion moved to the coordinator
- unwired feature modules (instance pool, import presets, cached
embeddings, relationship-confidence scorer) reachable only from tests
- dead leaf utilities (write buffer, deleted-items index, bounded
registry, two crypto shims, a cache manager, a structured logger, a
stale v5 type-migration helper, a browser-only FS type shim) and
several dead re-export barrels
- a CLI catalog command wired into no command
Also removed two tests that only exercised deleted modules, repointed two
VFS tests off a deleted barrel onto the implementation module, and deleted
one example that demoed removed features.
Verified: clean build (both tsc passes), unit 1505 + integration 607 green,
and a re-run of the reachability walk reports zero remaining orphans.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 15:18:40 -07:00
import { VirtualFileSystem } from '../../src/vfs/VirtualFileSystem.js'
2025-09-24 17:31:48 -07:00
import { Brainy } from '../../src/brainy.js'
import { VFSErrorCode } from '../../src/vfs/types.js'
describe ( 'VirtualFileSystem - Production Tests' , ( ) = > {
let vfs : VirtualFileSystem
let brain : Brainy
beforeEach ( async ( ) = > {
// Create a fresh Brainy instance with in-memory storage for each test
feat(8.0)!: flip requireSubtype default to true (BRAINY-8.0-SUBTYPE-CONTRACT § C-1)
Brainy 8.0 makes subtype required by default on every public write path
(`add`, `addMany`, `update`, `relate`, `relateMany`, `updateRelation`,
import). Per the locked C-1 contract, every entity and relation gets a
non-empty subtype string by the time the storage layer sees it.
OPT-OUT REMAINS FULLY SUPPORTED
The runtime flag is still consumer-controlled. Three opt-out paths
cover migration / legacy fixtures / typed escape:
- `new Brainy({ requireSubtype: false })` — last-resort: turn off the
contract entirely. Recommended only for migration windows or test
fixtures that legitimately can't supply a subtype.
- `new Brainy({ requireSubtype: { except: [NounType.Thing, ...] } })` —
per-type allowlist: strict everywhere except the listed types.
- `brain.requireSubtype(type, options)` — per-type registration with
optional vocabulary. Composes with the brain-wide flag.
Default is now `true`. Opt-out is explicit and documented; nothing
silently degrades.
TEST SWEEP
Bulk-applied `requireSubtype: false` to every `new Brainy({...})` call
site across 120 test files. Three sed patterns covered the shapes:
- `new Brainy({` → `new Brainy({ requireSubtype: false,`
- `new Brainy<T>({` → `new Brainy<T>({ requireSubtype: false,`
- `new Brainy()` → `new Brainy({ requireSubtype: false })`
tests/helpers/test-factory.ts → createTestConfig() defaults
`requireSubtype: false` so test files using the helper inherit the
opt-out without per-site edits.
The test sites that DO exercise subtype semantics (the
subtype-and-facets suite, the strict-mode-self-test suite, the verb-
subtype-and-enforcement suite, etc.) already pass real subtypes — they
were the 7.30.x acceptance tests for this contract. Those tests
continue to pass unchanged.
CHANGES
src/brainy.ts
- normalizeConfig() — `requireSubtype` default `false` → `true`.
Comment refreshed to document the three opt-out paths.
tests/* (120 files)
- Bulk-edited brain construction sites. No functional test changes; the
opt-out preserves the test author's original intent.
tests/helpers/test-factory.ts
- createTestConfig() base config gains `requireSubtype: false`.
NO-OP for consumers who were already passing subtype on every write.
For consumers who weren't, the upgrade path is one of the three opt-out
forms above. Migration recipe documented in 8.0 release notes (next
commit).
VERIFICATION
- npx tsc --noEmit: clean
- npm test: 1408 / 1409 (same pre-existing race-condition outstanding;
no other regressions from the flip)
2026-06-09 14:58:25 -07:00
brain = new Brainy ( { requireSubtype : false ,
2025-09-24 17:31:48 -07:00
storage : { type : 'memory' } ,
silent : true // Reduce test output
} )
await brain . init ( )
// Create VFS on top of Brainy
2025-11-02 11:38:12 -08:00
vfs = brain . vfs
2025-09-24 17:31:48 -07:00
await vfs . init ( )
} )
afterEach ( async ( ) = > {
if ( vfs ) {
await vfs . close ( )
}
if ( brain ) {
await brain . close ( )
}
} )
describe ( 'Core File Operations' , ( ) = > {
it ( 'should write and read a file' , async ( ) = > {
const content = 'Hello, VFS World!'
const path = '/test.txt'
// Write file
await vfs . writeFile ( path , content )
// Read file
const result = await vfs . readFile ( path )
expect ( result . toString ( ) ) . toBe ( content )
// Verify file exists
const exists = await vfs . exists ( path )
expect ( exists ) . toBe ( true )
} )
it ( 'should handle binary files' , async ( ) = > {
const binaryData = Buffer . from ( [ 0x00 , 0x01 , 0x02 , 0xFF ] )
const path = '/binary.dat'
await vfs . writeFile ( path , binaryData )
const result = await vfs . readFile ( path )
expect ( Buffer . compare ( result , binaryData ) ) . toBe ( 0 )
} )
it ( 'should update existing files' , async ( ) = > {
const path = '/update-test.txt'
await vfs . writeFile ( path , 'original' )
await vfs . writeFile ( path , 'updated' )
const content = await vfs . readFile ( path )
expect ( content . toString ( ) ) . toBe ( 'updated' )
} )
it ( 'should append to files' , async ( ) = > {
const path = '/append-test.txt'
await vfs . writeFile ( path , 'Hello' )
await vfs . appendFile ( path , ' World' )
const content = await vfs . readFile ( path )
expect ( content . toString ( ) ) . toBe ( 'Hello World' )
} )
it ( 'should delete files' , async ( ) = > {
const path = '/delete-me.txt'
await vfs . writeFile ( path , 'temporary' )
expect ( await vfs . exists ( path ) ) . toBe ( true )
await vfs . unlink ( path )
expect ( await vfs . exists ( path ) ) . toBe ( false )
} )
it ( 'should handle file metadata' , async ( ) = > {
const path = '/metadata-test.json'
const content = JSON . stringify ( { key : 'value' } )
await vfs . writeFile ( path , content )
const stats = await vfs . stat ( path )
expect ( stats . isFile ( ) ) . toBe ( true )
expect ( stats . size ) . toBe ( content . length )
expect ( stats . path ) . toBe ( path )
} )
} )
describe ( 'Directory Operations' , ( ) = > {
it ( 'should create directories' , async ( ) = > {
const path = '/my-directory'
await vfs . mkdir ( path )
const exists = await vfs . exists ( path )
expect ( exists ) . toBe ( true )
const stats = await vfs . stat ( path )
expect ( stats . isDirectory ( ) ) . toBe ( true )
} )
it ( 'should create nested directories recursively' , async ( ) = > {
const path = '/level1/level2/level3'
await vfs . mkdir ( path , { recursive : true } )
expect ( await vfs . exists ( '/level1' ) ) . toBe ( true )
expect ( await vfs . exists ( '/level1/level2' ) ) . toBe ( true )
expect ( await vfs . exists ( path ) ) . toBe ( true )
} )
it ( 'should list directory contents' , async ( ) = > {
const dir = '/list-test'
await vfs . mkdir ( dir )
// Create some files
await vfs . writeFile ( ` ${ dir } /file1.txt ` , 'content1' )
await vfs . writeFile ( ` ${ dir } /file2.txt ` , 'content2' )
await vfs . mkdir ( ` ${ dir } /subdir ` )
// List directory
const contents = await vfs . readdir ( dir ) as string [ ]
expect ( contents ) . toContain ( 'file1.txt' )
expect ( contents ) . toContain ( 'file2.txt' )
expect ( contents ) . toContain ( 'subdir' )
expect ( contents ) . toHaveLength ( 3 )
} )
it ( 'should list directory with file types' , async ( ) = > {
const dir = '/typed-list'
await vfs . mkdir ( dir )
await vfs . writeFile ( ` ${ dir } /doc.txt ` , 'text' )
await vfs . mkdir ( ` ${ dir } /folder ` )
const entries = await vfs . readdir ( dir , { withFileTypes : true } )
expect ( entries ) . toHaveLength ( 2 )
const file = entries . find ( e = > e . name === 'doc.txt' )
const folder = entries . find ( e = > e . name === 'folder' )
expect ( file ? . type ) . toBe ( 'file' )
expect ( folder ? . type ) . toBe ( 'directory' )
} )
it ( 'should remove empty directories' , async ( ) = > {
const path = '/empty-dir'
await vfs . mkdir ( path )
expect ( await vfs . exists ( path ) ) . toBe ( true )
await vfs . rmdir ( path )
expect ( await vfs . exists ( path ) ) . toBe ( false )
} )
it ( 'should recursively remove directories' , async ( ) = > {
const dir = '/recursive-delete'
await vfs . mkdir ( ` ${ dir } /sub1/sub2 ` , { recursive : true } )
await vfs . writeFile ( ` ${ dir } /file.txt ` , 'content' )
await vfs . writeFile ( ` ${ dir } /sub1/file2.txt ` , 'content2' )
await vfs . rmdir ( dir , { recursive : true } )
expect ( await vfs . exists ( dir ) ) . toBe ( false )
} )
} )
describe ( 'Path Resolution' , ( ) = > {
it ( 'should resolve absolute paths' , async ( ) = > {
await vfs . mkdir ( '/absolute/path' , { recursive : true } )
await vfs . writeFile ( '/absolute/path/file.txt' , 'content' )
const resolved = await vfs . resolvePath ( '/absolute/path/file.txt' )
expect ( resolved ) . toBe ( '/absolute/path/file.txt' )
} )
it ( 'should normalize paths with multiple slashes' , async ( ) = > {
await vfs . mkdir ( '/normal' , { recursive : true } )
await vfs . writeFile ( '/normal/file.txt' , 'content' )
// Multiple slashes should work
const content = await vfs . readFile ( '//normal///file.txt' )
expect ( content . toString ( ) ) . toBe ( 'content' )
} )
it ( 'should handle deep nesting' , async ( ) = > {
const deepPath = '/a/b/c/d/e/f/g/h/i/j/k/file.txt'
const dirPath = '/a/b/c/d/e/f/g/h/i/j/k'
await vfs . mkdir ( dirPath , { recursive : true } )
await vfs . writeFile ( deepPath , 'deep content' )
const content = await vfs . readFile ( deepPath )
expect ( content . toString ( ) ) . toBe ( 'deep content' )
} )
} )
describe ( 'Semantic Search (Triple Intelligence)' , ( ) = > {
beforeEach ( async ( ) = > {
// Create test files with different content
await vfs . mkdir ( '/search-test' , { recursive : true } )
await vfs . writeFile ( '/search-test/auth.js' , `
function authenticate ( username , password ) {
// User authentication logic
return checkCredentials ( username , password )
}
` )
await vfs . writeFile ( '/search-test/login.html' , `
< form >
< input type = "text" name = "username" / >
< input type = "password" name = "password" / >
< button > Sign In < / button >
< / form >
` )
await vfs . writeFile ( '/search-test/readme.md' , `
# Project Documentation
This project implements a secure authentication system .
` )
await vfs . writeFile ( '/search-test/config.json' , `
{
"database" : "postgres://localhost/myapp" ,
"port" : 3000
}
` )
} )
it ( 'should search files by semantic meaning' , async ( ) = > {
2025-10-07 11:51:17 -07:00
// Skip in unit test mode (mocked embeddings don't match file content)
if ( ( globalThis as any ) . __BRAINY_UNIT_TEST__ ) {
console . log ( '⏭️ Skipping semantic search test in unit mode' )
return
}
2025-09-24 17:31:48 -07:00
// Search for authentication-related files
const results = await vfs . search ( 'user authentication security' , {
path : '/search-test'
} )
// Should find auth.js and login.html as most relevant
expect ( results . length ) . toBeGreaterThan ( 0 )
const paths = results . map ( r = > r . path )
expect ( paths ) . toContain ( '/search-test/auth.js' )
expect ( paths ) . toContain ( '/search-test/login.html' )
} )
} )
describe ( 'Extended Attributes' , ( ) = > {
it ( 'should store and retrieve custom attributes' , async ( ) = > {
const path = '/attributed-file.txt'
await vfs . writeFile ( path , 'content' )
// Get initial attributes
const attrs = await vfs . listxattr ( path )
expect ( attrs ) . toEqual ( [ ] )
// Set custom attribute
await vfs . setxattr ( path , 'project' , 'alpha' )
await vfs . setxattr ( path , 'priority' , 'high' )
// Get specific attribute
const project = await vfs . getxattr ( path , 'project' )
expect ( project ) . toBe ( 'alpha' )
// List all attributes
const allAttrs = await vfs . listxattr ( path )
expect ( allAttrs ) . toContain ( 'project' )
expect ( allAttrs ) . toContain ( 'priority' )
} )
it ( 'should handle todos on files' , async ( ) = > {
const path = '/todo-file.js'
await vfs . writeFile ( path , 'function incomplete() {}' )
// Get initial todos (should be empty)
const todos = await vfs . getTodos ( path )
expect ( todos ) . toBeUndefined ( )
// Add a todo
await vfs . addTodo ( path , {
id : '1' ,
task : 'Complete implementation' ,
priority : 'high' ,
status : 'pending'
} )
// Verify todo was added
const updatedTodos = await vfs . getTodos ( path )
expect ( updatedTodos ) . toHaveLength ( 1 )
expect ( updatedTodos ! [ 0 ] . task ) . toBe ( 'Complete implementation' )
} )
} )
describe ( 'Error Handling' , ( ) = > {
it ( 'should throw ENOENT for non-existent files' , async ( ) = > {
await expect ( vfs . readFile ( '/does-not-exist.txt' ) )
. rejects
. toThrow ( 'No such file or directory' )
} )
it ( 'should throw EISDIR when reading a directory' , async ( ) = > {
await vfs . mkdir ( '/is-directory' )
await expect ( vfs . readFile ( '/is-directory' ) )
. rejects
. toThrow ( 'Is a directory' )
} )
it ( 'should throw ENOTDIR when listing a file' , async ( ) = > {
await vfs . writeFile ( '/is-file.txt' , 'content' )
await expect ( vfs . readdir ( '/is-file.txt' ) )
. rejects
. toThrow ( 'Not a directory' )
} )
it ( 'should throw ENOTEMPTY when removing non-empty directory' , async ( ) = > {
await vfs . mkdir ( '/non-empty' )
await vfs . writeFile ( '/non-empty/file.txt' , 'content' )
await expect ( vfs . rmdir ( '/non-empty' ) )
. rejects
. toThrow ( 'Directory not empty' )
} )
it ( 'should throw EEXIST when creating existing directory' , async ( ) = > {
await vfs . mkdir ( '/already-exists' )
await expect ( vfs . mkdir ( '/already-exists' ) )
. rejects
. toThrow ( 'Directory exists' )
} )
} )
describe ( 'Performance' , ( ) = > {
it ( 'should handle many files efficiently' , async ( ) = > {
const dir = '/performance-test'
await vfs . mkdir ( dir )
const startWrite = Date . now ( )
// Create 100 files
const promises = [ ]
for ( let i = 0 ; i < 100 ; i ++ ) {
promises . push (
vfs . writeFile ( ` ${ dir } /file- ${ i } .txt ` , ` Content ${ i } ` )
)
}
await Promise . all ( promises )
const writeTime = Date . now ( ) - startWrite
console . log ( ` Written 100 files in ${ writeTime } ms ` )
// List directory
const startList = Date . now ( )
const files = await vfs . readdir ( dir )
const listTime = Date . now ( ) - startList
expect ( files ) . toHaveLength ( 100 )
console . log ( ` Listed 100 files in ${ listTime } ms ` )
// Performance assertions
2025-11-05 17:01:44 -08:00
expect ( writeTime ) . toBeLessThan ( 5500 ) // v5.4.0: Type-first storage takes slightly longer
2025-09-24 17:31:48 -07:00
expect ( listTime ) . toBeLessThan ( 100 ) // Should list 100 files in < 100ms
} )
it ( 'should cache paths for fast repeated access' , async ( ) = > {
const path = '/cached/file.txt'
await vfs . mkdir ( '/cached' )
await vfs . writeFile ( path , 'cached content' )
2026-06-23 16:02:07 -07:00
// Prime the path cache + verify the content round-trips.
expect ( ( await vfs . readFile ( path ) ) . toString ( ) ) . toBe ( 'cached content' )
// Cached repeated access is sub-millisecond. Average many reads so the result
// doesn't hinge on Date.now()'s millisecond rounding of a single sub-ms op — the
// old cold-vs-warm compare spuriously failed when both rounded to 0/1ms. A
// generous absolute bound still catches a regression to per-read disk/index work.
const ITERATIONS = 100
const start = performance . now ( )
for ( let i = 0 ; i < ITERATIONS ; i ++ ) await vfs . readFile ( path )
const avgWarmMs = ( performance . now ( ) - start ) / ITERATIONS
expect ( avgWarmMs ) . toBeLessThan ( 5 )
2025-09-24 17:31:48 -07:00
} )
} )
describe ( 'Real-World Scenarios' , ( ) = > {
it ( 'should handle a code project structure' , async ( ) = > {
// Create a typical project structure
const project = '/my-project'
await vfs . mkdir ( ` ${ project } /src/components ` , { recursive : true } )
await vfs . mkdir ( ` ${ project } /src/utils ` , { recursive : true } )
await vfs . mkdir ( ` ${ project } /tests ` , { recursive : true } )
await vfs . mkdir ( ` ${ project } /docs ` , { recursive : true } )
// Add files
await vfs . writeFile ( ` ${ project } /package.json ` , JSON . stringify ( {
name : 'my-project' ,
version : '1.0.0'
} ) )
await vfs . writeFile ( ` ${ project } /README.md ` , '# My Project' )
await vfs . writeFile ( ` ${ project } /src/index.js ` , `
import App from './components/App'
export default App
` )
await vfs . writeFile ( ` ${ project } /src/components/App.js ` , `
2025-10-01 13:50:21 -07:00
// React component
2025-09-24 17:31:48 -07:00
export default function App() {
return 'Hello World'
}
` )
// Verify structure
const srcFiles = await vfs . readdir ( ` ${ project } /src ` )
expect ( srcFiles ) . toContain ( 'components' )
expect ( srcFiles ) . toContain ( 'utils' )
expect ( srcFiles ) . toContain ( 'index.js' )
2025-10-07 11:51:17 -07:00
// Skip semantic search in unit test mode
if ( ( globalThis as any ) . __BRAINY_UNIT_TEST__ ) {
console . log ( '⏭️ Skipping semantic search test in unit mode' )
return
}
2025-09-24 17:31:48 -07:00
// Search for components
const components = await vfs . search ( 'react component' , {
path : project
} )
expect ( components . length ) . toBeGreaterThan ( 0 )
} )
it ( 'should support file relationships' , async ( ) = > {
// Create related files
await vfs . writeFile ( '/code/user-model.js' , 'class User {}' )
await vfs . writeFile ( '/tests/user-model.test.js' , 'test User' )
await vfs . writeFile ( '/docs/user-api.md' , '# User API' )
// Add relationships
await vfs . addRelationship (
'/tests/user-model.test.js' ,
'/code/user-model.js' ,
'references' // Test file references the code it tests
)
await vfs . addRelationship (
'/docs/user-api.md' ,
'/code/user-model.js' ,
'references' // Documentation references the code it documents
)
// Query relationships
const relationships = await vfs . getRelationships ( '/code/user-model.js' )
expect ( relationships . length ) . toBe ( 2 )
} )
} )
} )
describe ( 'VirtualFileSystem - Watch System' , ( ) = > {
let vfs : VirtualFileSystem
let brain : Brainy
beforeAll ( async ( ) = > {
feat(8.0)!: flip requireSubtype default to true (BRAINY-8.0-SUBTYPE-CONTRACT § C-1)
Brainy 8.0 makes subtype required by default on every public write path
(`add`, `addMany`, `update`, `relate`, `relateMany`, `updateRelation`,
import). Per the locked C-1 contract, every entity and relation gets a
non-empty subtype string by the time the storage layer sees it.
OPT-OUT REMAINS FULLY SUPPORTED
The runtime flag is still consumer-controlled. Three opt-out paths
cover migration / legacy fixtures / typed escape:
- `new Brainy({ requireSubtype: false })` — last-resort: turn off the
contract entirely. Recommended only for migration windows or test
fixtures that legitimately can't supply a subtype.
- `new Brainy({ requireSubtype: { except: [NounType.Thing, ...] } })` —
per-type allowlist: strict everywhere except the listed types.
- `brain.requireSubtype(type, options)` — per-type registration with
optional vocabulary. Composes with the brain-wide flag.
Default is now `true`. Opt-out is explicit and documented; nothing
silently degrades.
TEST SWEEP
Bulk-applied `requireSubtype: false` to every `new Brainy({...})` call
site across 120 test files. Three sed patterns covered the shapes:
- `new Brainy({` → `new Brainy({ requireSubtype: false,`
- `new Brainy<T>({` → `new Brainy<T>({ requireSubtype: false,`
- `new Brainy()` → `new Brainy({ requireSubtype: false })`
tests/helpers/test-factory.ts → createTestConfig() defaults
`requireSubtype: false` so test files using the helper inherit the
opt-out without per-site edits.
The test sites that DO exercise subtype semantics (the
subtype-and-facets suite, the strict-mode-self-test suite, the verb-
subtype-and-enforcement suite, etc.) already pass real subtypes — they
were the 7.30.x acceptance tests for this contract. Those tests
continue to pass unchanged.
CHANGES
src/brainy.ts
- normalizeConfig() — `requireSubtype` default `false` → `true`.
Comment refreshed to document the three opt-out paths.
tests/* (120 files)
- Bulk-edited brain construction sites. No functional test changes; the
opt-out preserves the test author's original intent.
tests/helpers/test-factory.ts
- createTestConfig() base config gains `requireSubtype: false`.
NO-OP for consumers who were already passing subtype on every write.
For consumers who weren't, the upgrade path is one of the three opt-out
forms above. Migration recipe documented in 8.0 release notes (next
commit).
VERIFICATION
- npx tsc --noEmit: clean
- npm test: 1408 / 1409 (same pre-existing race-condition outstanding;
no other regressions from the flip)
2026-06-09 14:58:25 -07:00
brain = new Brainy ( { requireSubtype : false , storage : { type : 'memory' } , silent : true } )
2025-09-24 17:31:48 -07:00
await brain . init ( )
vfs = new VirtualFileSystem ( brain )
await vfs . init ( )
} )
afterAll ( async ( ) = > {
if ( vfs ) {
await vfs . close ( )
}
if ( brain ) {
await brain . close ( )
}
} )
it ( 'should watch for file changes' , async ( ) = > {
const path = '/watched-file.txt'
const events : Array < { type : string , path : string | null } > = [ ]
// Set up watcher
const watcher = vfs . watch ( path , ( eventType , filename ) = > {
events . push ( { type : eventType , path : filename } )
} )
// Trigger events
await vfs . writeFile ( path , 'initial' ) // Create
await vfs . writeFile ( path , 'updated' ) // Change
await vfs . unlink ( path ) // Delete
// Verify events were triggered
expect ( events ) . toHaveLength ( 3 )
expect ( events [ 0 ] . type ) . toBe ( 'rename' ) // Create is a rename event
expect ( events [ 1 ] . type ) . toBe ( 'change' )
expect ( events [ 2 ] . type ) . toBe ( 'rename' ) // Delete is a rename event
// Clean up
watcher . close ( )
} )
} )