char-slop/berry
multipurpose self-modifiable agentic harness
git clone https://git.t4t.associates/char-slop/berry
481a657
main
1import { assertEquals } from "@std/assert" ; 2import type { View } from "@berry/api/web.ts" ; 3import { viewContext , withDom } from "@berry/util/dom.ts" ; 4import { extensionView , viewHref , viewRoute } from "./views.ts" ; 5 6Deno . test ( "a view opens with its route, follows it and new entries, and is disposed as it closes" , () => 7withDom (() => { 8const events :string [] = []; 9const factory = ( name :string ) => () :View => { 10events . push ( ` ${ name } :create` ); 11const element = document . createElement ( "section" ); 12return { 13 element, 14update :({ route, latest}) => 15events . push ( ` ${ name } : ${ route } @ ${ latest } : ${ element . isConnected ? "shown" : "unshown" } ` ), 16dispose :() => events . push ( ` ${ name } :dispose` ), 17}; 18}; 19const diff = { name :"diff" , create :factory ( "diff" ) }; 20const context = viewContext ({ tid :"test" , latest :1 }); 21const pane = extensionView (); 22document . body . append ( pane . element ); 23assertEquals ( pane . element . hidden , true ); 24 25pane . update ( diff , context ); 26assertEquals ( pane . element . hidden , false ); 27// a conversation draws again as it streams, without anything the view shows changing 28pane . update ( diff , { ...context }); 29pane . update ( diff , { ...context , route :"abc" }); 30pane . update ( diff , { ...context , route :"abc" , latest :2 }); 31pane . update ({ name :"diff" , create :factory ( "reloaded" ) }, context ); 32pane . update ( null , context ); 33assertEquals ( pane . element . hidden , true ); 34assertEquals ( pane . element . childNodes . length , 0 ); 35 36pane . update ({ name :"diff" , create :null }, context ); 37pane . dispose (); 38 39assertEquals ( events , [ 40"diff:create" , 41"diff:@1:unshown" , 42"diff:abc@1:shown" , 43"diff:abc@2:shown" , 44"diff:dispose" , 45"reloaded:create" , 46"reloaded:@1:unshown" , 47"reloaded:dispose" , 48]); 49})); 50 51Deno . test ( "a view's route survives its address, whatever it holds" , () => { 52for ( const route of [ "" , "abc" , "a b/c%d" , "x/#y?z" , "ünï/cødé" ]) { 53const href = viewHref ( "3mxd6epszps5d" , "diff" , route ); 54const escaped = href . match ( / ^#\/3mxd6epszps5d\/diff\/?(.*)$ / ) ! [ 1 ]; 55assertEquals ( viewRoute ( escaped ), route ); 56} 57}); 58 59Deno . test ( "flush reaches the open view, and is a no-op without one" , () => 60withDom ( async () => { 61const pane = extensionView (); 62document . body . append ( pane . element ); 63assertEquals ( await pane . flush (), undefined ); 64let flushed = 0 ; 65const element = document . createElement ( "section" ); 66const view :View = { 67 element, 68update :() => {}, 69flush :() => { 70flushed ++ ; 71return Promise . resolve (); 72}, 73}; 74const context = viewContext ({ tid :"test" , latest :1 }); 75pane . update ({ name :"diff" , create :() => view }, context ); 76await pane . flush (); 77assertEquals ( flushed , 1 ); 78pane . update ( null , context ); 79assertEquals ( await pane . flush (), undefined ); 80pane . dispose (); 81}));