char-slop/berry
multipurpose self-modifiable agentic harness
git clone https://git.t4t.associates/char-slop/berry
806cc3c
main
1import { assertEquals } from "@std/assert" ; 2import { pairs , pieces , trailing , wordChanges } from "./model.ts" ; 3import type { FileDiff } from "./types.ts" ; 4 5const file = ( hunks :FileDiff [ "hunks" ]) :FileDiff => ({ 6path :"f.ts" , 7from :null , 8status :"modified" , 9modes :{ old :null , new :null }, 10binary :false , 11 hunks, 12}); 13 14const shape = ( file :FileDiff , context ?:number ) => 15pieces ( file , context ). map (( piece ) => 16piece . kind === "gap" 17 ?`gap ${ piece . count } ` 18 :` ${ piece . kind } ${ 19piece . lines . map (( l ) => ` ${ l . mark } ${ l . old ?? "_" } / ${ l . new ?? "_" } ` ). join ( " " ) 20} ` 21); 22 23Deno . test ( "a whole file folds its long unchanged stretches, keeping context beside each change" , () => { 24const lines = Array . from ({ length :20 }, ( _ , i ) => ` ${ i + 1 } ` ); 25lines . splice ( 9 , 1 , "-10" , "+ten" ); 26assertEquals ( shape ( file ([{ old :1 , new :1 , lines}]), 2 ), [ 27"fold 1/1 2/2 3/3 4/4 5/5 6/6 7/7" , 28"lines 8/8 9/9 -10/_ +_/10 11/11 12/12" , 29"fold 13/13 14/14 15/15 16/16 17/17 18/18 19/19 20/20" , 30]); 31}); 32 33Deno . test ( "short unchanged stretches stay open, and lines a patch leaves out are counted" , () => { 34const near = file ([ 35{ old :3 , new :3 , lines :[ " 3" , "-4" , "+four" , " 5" , " 6" , " 7" , " 8" , " 9" , "+new" , " 10" ] }, 36{ old :20 , new :21 , lines :[ " 20" , "-21" , "\\ No newline at end of file" ] }, 37]); 38assertEquals ( shape ( near , 3 ), [ 39"gap 2" , 40"lines 3/3 -4/_ +_/4 5/5 6/6 7/7 8/8 9/9 +_/10 10/11" , 41"gap 9" , 42"lines 20/21 -21/_" , 43]); 44const last = pieces ( near ). at ( - 1 ) ! ; 45assertEquals ( last . kind === "lines" && last . lines . at ( - 1 ) ! . newline , false ); 46}); 47 48Deno . test ( "side by side, removals sit beside the additions that replace them" , () => { 49const [ piece ] = pieces ( file ([{ old :1 , new :1 , lines :[ " a" , "-b" , "-c" , "+B" , " d" , "+e" ] }])); 50const rows = pairs ( piece . kind === "lines" ?piece . lines :[]). map (({ old, new :neu }) => 51` ${ old ?. text ?? "·" } | ${ neu ?. text ?? "·" } ` 52); 53assertEquals ( rows , [ "a|a" , "b|B" , "c|·" , "d|d" , "·|e" ]); 54}); 55 56Deno . test ( "within a changed line, only the words that changed are marked" , () => { 57assertEquals ( wordChanges ( "const total = a + b;" , "const sum = a + b;" ), { 58old :[[ 6 , 11 ]], 59new :[[ 6 , 9 ]], 60}); 61assertEquals ( wordChanges ( "f(x)" , "f(x, y)" ), { old :[], new :[[ 3 , 6 ]] }); 62// lines with little in common are just different lines 63assertEquals ( wordChanges ( "import { a } from 'b';" , "return value * 2;" ), null ); 64assertEquals ( trailing ( "let x = 1; \r" ), [ 10 , 12 ]); 65assertEquals ( trailing ( "let x = 1;" ), null ); 66});