-- EditTest.mesa
-- written by Bill Paxton, April 1981
-- last edit by Bill Paxton, 28-Jul-81 10:48:57

DIRECTORY
TextEdit,
EditSpan,
RopeReader,
RunReader,
TextLooks,
TextNode,
UndoEvent;

EditTest: DEFINITIONS 
	IMPORTS TextEdit, RopeReader, RunReader =
BEGIN
OPEN
	looksI:TextLooks,
	spanI:EditSpan,
	roperdrI:RopeReader,
	runrdrI:RunReader,
	editI:TextEdit,
	nodeI:TextNode;

Offset: TYPE = nodeI.Offset;
Node: TYPE = nodeI.RefTextNode;
Ref: TYPE = nodeI.Ref;
Span: TYPE = nodeI.Span;
Location: TYPE = nodeI.Location;
Place: TYPE = spanI.Place;
Rope: TYPE = editI.Rope;
Runs: TYPE = looksI.Runs;
Looks: TYPE = looksI.Looks;
Event: TYPE = UndoEvent.Ref;

TextSpan: PROC [node: Node, start, len: Offset] RETURNS [Span] = INLINE {
	RETURN [[[node,start],[node,start+len-1]]] };

TextLoc: PROC [node: Node, where: Offset] RETURNS [Location] = INLINE {
	RETURN [[node,where]] };

ReplaceText, DeleteText, CopyText, MoveText, MoveTextOnto, TransposeText, ReplaceByChar,
	InsertChar, AppendChar, ReplaceByString, InsertString, AppendString, ReplaceByRope,
	InsertRope, AppendRope, AdjustLengths, Find, BackwardsFind,
	ChangeLooks, AddLooks, RemoveLooks, SetLooks, ClearLooks,
	PutGet, PutGetRope, GetBigFile, PutGetTree, PutGetToRope, PutGetToStream: PROC;

ReplaceNodes, DeleteNodes, CopyNodes, MoveNodes, MoveNodesOnto, TransposeNodes,
	SplitNode, MergeNodes, NestNodes, UnNestNodes, InsertNode: PROC;
	
DeleteFromNode, InsertStringInNode, AdjustLength: PROC [Node];
Choose: PROC [min,max: Offset] RETURNS [Offset];
ChooseTwo: PROC [min,max: Offset] RETURNS [first,second: Offset];
ChooseNAT: PROC [min,max: NAT] RETURNS [NAT];
ChooseTwoNATs: PROC [min,max: NAT] RETURNS [first,second: NAT];
RandomBoolean: PROC RETURNS [BOOLEAN];
OneInN: PROC [n: NAT] RETURNS [BOOLEAN];
PickNode: PROC RETURNS [Node];
PickNodes: PROC RETURNS [source,dest: Node];
PickOne: PROC [node: Node] RETURNS [loc: Offset];
PickTwo: PROC [node: Node] RETURNS [start, end: Offset];
PickLooks: PROC RETURNS [Looks];
PickRope: PROC RETURNS [Rope];

LocateSpan: PROC [span: Span] RETURNS [start, len, size: Offset];
LocateNode: PROC [node: Ref] RETURNS [loc, size: Offset];
PickTree: PROC RETURNS [tree: Ref];
PickTrees: PROC RETURNS [tree1, tree2: Ref];
PickPlace: PROC RETURNS [Place];
PickNodeSpan: PROC [tree: Ref] RETURNS [span: Span, start, len, size: Offset];
PickNodeLoc: PROC [tree: Ref] RETURNS [dest: Location, loc, size: Offset];
FindTreeNode: PROC [tree: Ref, loc: Offset] RETURNS [node: Ref];
FindFirstNode: PROC [tree: Ref, loc: Offset] RETURNS [first: Ref];
FindLastNode: PROC [first: Ref, len: Offset] RETURNS [last: Ref];
TreeSize: PROC [tree: Ref] RETURNS [size: Offset];
AdjustTree: PROC [tree: Ref, size: Offset];
DeleteFromTree, InsertInTree: PROC [tree: Ref, size, num: Offset] RETURNS [newsize: Offset];

CheckSize: PROC [node: Node, size: Offset] = INLINE { IF editI.Size[node] # size THEN ERROR };

alpha, beta: Node;
alphaTree, betaTree: Ref;
numEdits: NAT;
runrdr1, runrdr2: runrdrI.Ref;
roperdr1, roperdr2: roperdrI.Ref;
event, undoEvent: Event;

BeforeUndo: PROC [n1, n2: Node ← NIL];
TestUndo: PROC; -- checks that Undo of edit works; checks Undo of the Undo also.

CheckRopes: PROC [
	rope1: Rope, start1: Offset, rope2: Rope, start2, len: Offset] = INLINE {
	IF ~roperdrI.EqSubstrs[rope1,rope2,start1,start2,len,roperdr1,roperdr2] 
		THEN ERROR };

CheckRuns: PROC [
	runs1: Runs, start1: Offset, runs2: Runs, start2, len: Offset] = INLINE {
	IF ~runrdrI.EqSubstrs[runs1,runs2,start1,start2,len,runrdr1,runrdr2] 
		THEN ERROR };
RunMode: TYPE = {textOnly, nodesOnly, both};
Run: PROC [shuffle: NAT ← 0, numberOfTests: NAT ← LAST[NAT],
	mode: RunMode ← both];
	
END.