-- Test2Impl.mesa -- written by Bill Paxton, April 1981 -- last edit by Bill Paxton, 29-Jun-81 15:59:27 -- This module provides random testing for editing Text nodes DIRECTORY EditTest, TextEdit, RopeEdit, TextNode, RunReader, RopeReader, Rope, RopeInline; Test2Impl: PROGRAM IMPORTS EditTest, TextEdit, RopeEdit, RunReader, RopeReader, Rope EXPORTS EditTest = BEGIN OPEN rI:Rope, EditTest, editI:TextEdit, ropeI:RopeEdit, nodeI:TextNode, runrdrI:RunReader, roperdrI:RopeReader; -- ***** Text Edit operations ReplaceByChar: PUBLIC PROC = { dest: Node ← PickNode[]; destStart, destEnd, destLen, oldSize, oldPos, newPos, resultStart, resultLen: Offset; newRope, oldRope: Rope; newRuns, oldRuns: Runs; inherit: BOOLEAN ← RandomBoolean[]; looks: Looks; IF ~inherit THEN looks ← PickLooks[]; [destStart,destEnd] ← PickTwo[dest]; oldSize ← editI.Size[dest]; oldRope ← editI.GetRope[dest]; oldRuns ← editI.GetRuns[dest]; BeforeUndo[dest]; [resultStart,resultLen] ← editI.ReplaceByChar[dest,'#, destStart,destLen←destEnd-destStart,inherit,looks,event]; newRope ← editI.GetRope[dest]; newRuns ← editI.GetRuns[dest]; IF resultStart # destStart OR resultLen # 1 THEN ERROR; CheckSize[dest,oldSize+1-destLen]; CheckRopes[newRope,0,oldRope,0,destStart]; IF editI.FetchChar[dest,destStart] # '# THEN ERROR; oldPos ← destStart+destLen; newPos ← destStart+1; CheckRopes[newRope,newPos,oldRope,oldPos,oldSize-oldPos]; CheckRuns[newRuns,0,oldRuns,0,destStart]; IF ~inherit AND editI.FetchLooks[dest,destStart] # looks THEN ERROR; CheckRuns[newRuns,newPos,oldRuns,oldPos,oldSize-oldPos]; TestUndo[]; AdjustLength[dest] }; InsertChar: PUBLIC PROC = { dest: Node ← PickNode[]; destLoc: Offset ← PickOne[dest]; oldSize, loc, oldPos, newPos, resultStart, resultLen: Offset; newRope, oldRope: Rope; newRuns, oldRuns: Runs; inherit: BOOLEAN ← RandomBoolean[]; looks: Looks; num: NAT ← ChooseNAT[1,20]; -- number of chars to insert IF ~inherit THEN looks ← PickLooks[]; oldSize ← editI.Size[dest]; oldRope ← editI.GetRope[dest]; oldRuns ← editI.GetRuns[dest]; loc ← destLoc; FOR i:NAT IN [0..num) DO [resultStart,resultLen] ← editI.InsertChar[dest,'z-i,loc,inherit,looks]; IF resultStart # loc OR resultLen # 1 THEN ERROR; loc ← loc+1; ENDLOOP; newRope ← editI.GetRope[dest]; newRuns ← editI.GetRuns[dest]; CheckSize[dest,oldSize+num]; CheckRopes[newRope,0,oldRope,0,destLoc]; loc ← destLoc; FOR i:NAT IN [0..num) DO IF editI.FetchChar[dest,loc] # 'z-i THEN ERROR; IF ~inherit AND editI.FetchLooks[dest,loc] # looks THEN ERROR; loc ← loc+1; ENDLOOP; oldPos ← destLoc; newPos ← destLoc+num; CheckRopes[newRope,newPos,oldRope,oldPos,oldSize-oldPos]; CheckRuns[newRuns,0,oldRuns,0,destLoc]; CheckRuns[newRuns,newPos,oldRuns,oldPos,oldSize-oldPos]; AdjustLength[dest] }; AppendChar: PUBLIC PROC = { dest: Node ← PickNode[]; inherit: BOOLEAN ← RandomBoolean[]; looks: Looks; loc, oldSize, resultStart, resultLen: Offset; newRope, oldRope: Rope; newRuns, oldRuns: Runs; num: NAT ← ChooseNAT[1,20]; -- number of chars to append IF ~inherit THEN looks ← PickLooks[]; oldSize ← editI.Size[dest]; oldRope ← editI.GetRope[dest]; oldRuns ← editI.GetRuns[dest]; FOR i:NAT IN [0..num) DO loc: Offset ← editI.Size[dest]; [resultStart,resultLen] ← editI.AppendChar[dest,'Z-i,inherit,looks]; IF resultStart # loc OR resultLen # 1 THEN ERROR; ENDLOOP; newRope ← editI.GetRope[dest]; newRuns ← editI.GetRuns[dest]; CheckSize[dest,oldSize+num]; CheckRopes[newRope,0,oldRope,0,oldSize]; loc ← oldSize; FOR i:NAT IN [0..num) DO IF editI.FetchChar[dest,loc] # 'Z-i THEN ERROR; IF ~inherit AND editI.FetchLooks[dest,loc] # looks THEN ERROR; loc ← loc+1; ENDLOOP; CheckRuns[newRuns,0,oldRuns,0,oldSize]; AdjustLength[dest] }; string: REF READONLY TEXT ← "1234567890123456789012345678901234567890"; stringRope: Rope ← rI.FromString[string]; ReplaceByString: PUBLIC PROC = { dest: Node ← PickNode[]; destStart, destEnd, destLen, oldSize, oldPos, newPos, resultStart, resultLen: Offset; newRope, oldRope: Rope; newRuns, oldRuns: Runs; inherit: BOOLEAN ← RandomBoolean[]; looks: Looks; strStart, strEnd, strLen: NAT; oldSize ← editI.Size[dest]; oldRope ← editI.GetRope[dest]; oldRuns ← editI.GetRuns[dest]; IF ~inherit THEN looks ← PickLooks[]; [destStart,destEnd] ← PickTwo[dest]; [strStart,strEnd] ← ChooseTwoNATs[0,string.length]; BeforeUndo[dest]; [resultStart,resultLen] ← editI.ReplaceByString[dest,string,strStart, strLen←strEnd-strStart,destStart,destLen←destEnd-destStart,inherit,looks,event]; newRope ← editI.GetRope[dest]; newRuns ← editI.GetRuns[dest]; IF resultStart # destStart OR resultLen # strLen THEN ERROR; CheckSize[dest,oldSize+strLen-destLen]; CheckRopes[newRope,0,oldRope,0,destStart]; CheckRopes[newRope,destStart,stringRope,strStart,strLen]; oldPos ← destStart+destLen; newPos ← destStart+strLen; CheckRopes[newRope,newPos,oldRope,oldPos,oldSize-oldPos]; CheckRuns[newRuns,0,oldRuns,0,destStart]; IF ~inherit AND strLen>0 AND editI.FetchLooks[dest,destStart] # looks THEN ERROR; CheckRuns[newRuns,newPos,oldRuns,oldPos,oldSize-oldPos]; TestUndo[]; AdjustLength[dest] }; InsertString: PUBLIC PROC = { dest: Node ← PickNode[]; InsertStringInNode[dest]; AdjustLength[dest] }; InsertStringInNode: PUBLIC PROC [dest: Node] = { oldSize, resultStart, resultLen: Offset; destLoc: Offset ← PickOne[dest]; inherit: BOOLEAN ← RandomBoolean[]; newRope, oldRope: Rope; newRuns, oldRuns: Runs; looks: Looks; strStart, strEnd, strLen: NAT; IF ~inherit THEN looks ← PickLooks[]; [strStart,strEnd] ← ChooseTwoNATs[0,string.length]; oldSize ← editI.Size[dest]; oldRope ← editI.GetRope[dest]; oldRuns ← editI.GetRuns[dest]; [resultStart,resultLen] ← editI.InsertString[dest,string,strStart,strLen←strEnd-strStart, destLoc,inherit,looks]; newRope ← editI.GetRope[dest]; newRuns ← editI.GetRuns[dest]; IF resultStart # destLoc OR resultLen # strLen THEN ERROR; CheckSize[dest,oldSize+strLen]; CheckRopes[newRope,0,oldRope,0,destLoc]; CheckRopes[newRope,destLoc,stringRope,strStart,strLen]; CheckRopes[newRope,destLoc+strLen,oldRope,destLoc,oldSize-destLoc]; CheckRuns[newRuns,0,oldRuns,0,destLoc]; IF ~inherit AND strLen>0 AND editI.FetchLooks[dest,destLoc] # looks THEN ERROR; CheckRuns[newRuns,destLoc+strLen,oldRuns,destLoc,oldSize-destLoc] }; AppendString: PUBLIC PROC = { dest: Node ← PickNode[]; inherit: BOOLEAN ← RandomBoolean[]; looks: Looks; oldSize, resultStart, resultLen: Offset; newRope, oldRope: Rope; newRuns, oldRuns: Runs; strStart, strEnd, strLen: NAT; IF ~inherit THEN looks ← PickLooks[]; [strStart,strEnd] ← ChooseTwoNATs[0,string.length]; oldSize ← editI.Size[dest]; oldRope ← editI.GetRope[dest]; oldRuns ← editI.GetRuns[dest]; [resultStart,resultLen] ← editI.AppendString[dest,string,strStart,strLen←strEnd-strStart, inherit,looks]; newRope ← editI.GetRope[dest]; newRuns ← editI.GetRuns[dest]; IF resultStart # oldSize OR resultLen # strLen THEN ERROR; CheckSize[dest,oldSize+strLen]; CheckRopes[newRope,0,oldRope,0,oldSize]; CheckRopes[newRope,oldSize,stringRope,strStart,strLen]; CheckRuns[newRuns,0,oldRuns,0,oldSize]; IF ~inherit AND strLen>0 AND editI.FetchLooks[dest,oldSize] # looks THEN ERROR; AdjustLength[dest] }; ReplaceByRope: PUBLIC PROC = { dest: Node ← PickNode[]; rope: Rope ← PickRope[]; newRope, oldRope: Rope; newRuns, oldRuns: Runs; destStart, destEnd, destLen, oldSize, oldPos, newPos, ropeLen, resultStart, resultLen: Offset; inherit: BOOLEAN ← RandomBoolean[]; looks: Looks; [destStart,destEnd] ← PickTwo[dest]; IF ~inherit THEN looks ← PickLooks[]; oldSize ← editI.Size[dest]; oldRope ← editI.GetRope[dest]; oldRuns ← editI.GetRuns[dest]; ropeLen ← ropeI.Size[rope]; BeforeUndo[dest]; [resultStart,resultLen] ← editI.ReplaceByRope[dest,rope, destStart,destLen←destEnd-destStart,inherit,looks,event]; newRope ← editI.GetRope[dest]; newRuns ← editI.GetRuns[dest]; IF resultStart # destStart OR resultLen # ropeLen THEN ERROR; CheckSize[dest,oldSize+ropeLen-destLen]; CheckRopes[newRope,0,oldRope,0,destStart]; CheckRopes[newRope,destStart,rope,0,ropeLen]; oldPos ← destStart+destLen; newPos ← destStart+ropeLen; CheckRopes[newRope,newPos,oldRope,oldPos,oldSize-oldPos]; CheckRuns[newRuns,0,oldRuns,0,destStart]; IF ~inherit AND ropeLen>0 AND editI.FetchLooks[dest,destStart] # looks THEN ERROR; CheckRuns[newRuns,newPos,oldRuns,oldPos,oldSize-oldPos]; TestUndo[]; AdjustLength[dest] }; InsertRope: PUBLIC PROC = { dest: Node ← PickNode[]; destLoc: Offset ← PickOne[dest]; oldSize, ropeLen, resultStart, resultLen: Offset; rope: Rope ← PickRope[]; newRope, oldRope: Rope; newRuns, oldRuns: Runs; inherit: BOOLEAN ← RandomBoolean[]; looks: Looks; IF ~inherit THEN looks ← PickLooks[]; oldSize ← editI.Size[dest]; oldRope ← editI.GetRope[dest]; oldRuns ← editI.GetRuns[dest]; ropeLen ← ropeI.Size[rope]; [resultStart,resultLen] ← editI.InsertRope[dest,rope,destLoc,inherit,looks]; newRope ← editI.GetRope[dest]; newRuns ← editI.GetRuns[dest]; IF resultStart # destLoc OR resultLen # ropeLen THEN ERROR; CheckSize[dest,oldSize+ropeLen]; CheckRopes[newRope,0,oldRope,0,destLoc]; CheckRopes[newRope,destLoc,rope,0,ropeLen]; CheckRopes[newRope,destLoc+ropeLen,oldRope,destLoc,oldSize-destLoc]; CheckRuns[newRuns,0,oldRuns,0,destLoc]; IF ~inherit AND ropeLen>0 AND editI.FetchLooks[dest,destLoc] # looks THEN ERROR; CheckRuns[newRuns,destLoc+ropeLen,oldRuns,destLoc,oldSize-destLoc]; AdjustLength[dest] }; AppendRope: PUBLIC PROC = { dest: Node ← PickNode[]; rope: Rope ← PickRope[]; oldSize, ropeLen, resultStart, resultLen: Offset; newRope, oldRope: Rope; newRuns, oldRuns: Runs; inherit: BOOLEAN ← RandomBoolean[]; looks: Looks; IF ~inherit THEN looks ← PickLooks[]; oldSize ← editI.Size[dest]; oldRope ← editI.GetRope[dest]; oldRuns ← editI.GetRuns[dest]; ropeLen ← ropeI.Size[rope]; [resultStart,resultLen] ← editI.AppendRope[dest,rope,inherit,looks]; newRope ← editI.GetRope[dest]; newRuns ← editI.GetRuns[dest]; IF resultStart # oldSize OR resultLen # ropeLen THEN ERROR; CheckSize[dest,oldSize+ropeLen]; CheckRopes[newRope,0,oldRope,0,oldSize]; CheckRopes[newRope,oldSize,rope,0,ropeLen]; CheckRuns[newRuns,0,oldRuns,0,oldSize]; IF ~inherit AND ropeLen>0 AND editI.FetchLooks[dest,oldSize] # looks THEN ERROR; AdjustLength[dest] }; END.