NAME=t/undoredo
FILE=malloc://1024
CMDS=<<EOF
echo No seeks.
sh ; %v $$
echo

echo But try undo/redo.
shu
shr
sh
shr
shr
shu
shu
shu
shr
sh
echo

echo First seeks.
s 0x10 ; sh ; %v $$
s 0x20 ; sh ; %v $$
s 0x30 ; sh ; %v $$
s 0x40 ; sh ; %v $$
echo

echo Undo all seeks (and some more).
shu ; sh ; %v $$ ; echo
shu ; sh ; %v $$ ; echo
shu ; sh ; %v $$ ; echo
shu ; sh ; %v $$ ; echo
# Test if more undos break something.
shu ; sh ; %v $$ ; echo
shu ; sh ; %v $$ ; echo

echo Then redo them (and some more).
shr ; sh ; %v $$ ; echo
shr ; sh ; %v $$ ; echo
shr ; sh ; %v $$ ; echo
shr ; sh ; %v $$ ; echo
# Test if more undos break something.
shr ; sh ; %v $$ ; echo
shr ; sh ; %v $$ ; echo

echo Undo some seeks and then seek somewhere else.
shu ; shu
sh ; %v $$ ; echo
s 0x50
sh ; %v $$ ; echo
# Redo now does nothing.
shr ; shr ; shr
sh ; %v $$ ; echo

echo Undo all seeks again and perform a single seek with undo/redo.
shu ; shu ; shu
sh ; %v $$ ; echo
s 0x100
sh ; %v $$ ; echo
shu ; shr
sh ; %v $$ ; echo
EOF
EXPECT=<<EOF
No seeks.
0x0  # current seek
0x0

But try undo/redo.
0x0  # current seek
0x0  # current seek

First seeks.
0x0 
0x10  # current seek
0x10
0x0 
0x10 
0x20  # current seek
0x20
0x0 
0x10 
0x20 
0x30  # current seek
0x30
0x0 
0x10 
0x20 
0x30 
0x40  # current seek
0x40

Undo all seeks (and some more).
0x0 
0x10 
0x20 
0x30  # current seek
0x40  # redo
0x30

0x0 
0x10 
0x20  # current seek
0x30  # redo
0x40  # redo
0x20

0x0 
0x10  # current seek
0x20  # redo
0x30  # redo
0x40  # redo
0x10

0x0  # current seek
0x10  # redo
0x20  # redo
0x30  # redo
0x40  # redo
0x0

0x0  # current seek
0x10  # redo
0x20  # redo
0x30  # redo
0x40  # redo
0x0

0x0  # current seek
0x10  # redo
0x20  # redo
0x30  # redo
0x40  # redo
0x0

Then redo them (and some more).
0x0 
0x10  # current seek
0x20  # redo
0x30  # redo
0x40  # redo
0x10

0x0 
0x10 
0x20  # current seek
0x30  # redo
0x40  # redo
0x20

0x0 
0x10 
0x20 
0x30  # current seek
0x40  # redo
0x30

0x0 
0x10 
0x20 
0x30 
0x40  # current seek
0x40

0x0 
0x10 
0x20 
0x30 
0x40  # current seek
0x40

0x0 
0x10 
0x20 
0x30 
0x40  # current seek
0x40

Undo some seeks and then seek somewhere else.
0x0 
0x10 
0x20  # current seek
0x30  # redo
0x40  # redo
0x20

0x0 
0x10 
0x20 
0x50  # current seek
0x50

0x0 
0x10 
0x20 
0x50  # current seek
0x50

Undo all seeks again and perform a single seek with undo/redo.
0x0  # current seek
0x10  # redo
0x20  # redo
0x50  # redo
0x0

0x0 
0x100  # current seek
0x100

0x0 
0x100  # current seek
0x100

EOF
RUN

NAME=basic json
FILE=malloc://1024
CMDS=<<EOF
shj
sd +10
shj
sd +10
shu
shj
shu
shj
echo undo at the start of list
shu
shj
echo redo to the end
shr; shr
shj
echo one more past the end
shr
shj
EOF
EXPECT=<<EOF
[{"offset":0,"cursor":0,"current":true}]
[{"offset":0,"cursor":0,"current":false},{"offset":10,"cursor":0,"current":true}]
[{"offset":0,"cursor":0,"current":false},{"offset":10,"cursor":0,"current":true},{"offset":20,"cursor":0,"current":false}]
[{"offset":0,"cursor":0,"current":true},{"offset":10,"cursor":0,"current":false},{"offset":20,"cursor":0,"current":false}]
undo at the start of list
[{"offset":0,"cursor":0,"current":true},{"offset":10,"cursor":0,"current":false},{"offset":20,"cursor":0,"current":false}]
redo to the end
[{"offset":0,"cursor":0,"current":false},{"offset":10,"cursor":0,"current":false},{"offset":20,"cursor":0,"current":true}]
one more past the end
[{"offset":0,"cursor":0,"current":false},{"offset":10,"cursor":0,"current":false},{"offset":20,"cursor":0,"current":true}]
EOF
RUN

NAME=uninitialized bug
FILE=malloc://1024
CMDS=<<EOF
sd +10
echo should produce two identical results
sd +1
shj
shu
sd +1
shj
echo 0 0, or 22 23 but not 0 22
sd +10
sd +1
shj
shu
sd +2
shj
EOF
EXPECT=<<EOF
should produce two identical results
[{"offset":0,"cursor":0,"current":false},{"offset":10,"cursor":0,"current":false},{"offset":11,"cursor":0,"current":true}]
[{"offset":0,"cursor":0,"current":false},{"offset":10,"cursor":0,"current":false},{"offset":11,"cursor":0,"current":true}]
0 0, or 22 23 but not 0 22
[{"offset":0,"cursor":0,"current":false},{"offset":10,"cursor":0,"current":false},{"offset":11,"cursor":0,"current":false},{"offset":21,"cursor":0,"current":false},{"offset":22,"cursor":0,"current":true}]
[{"offset":0,"cursor":0,"current":false},{"offset":10,"cursor":0,"current":false},{"offset":11,"cursor":0,"current":false},{"offset":21,"cursor":0,"current":false},{"offset":23,"cursor":0,"current":true}]
EOF
RUN

NAME=duplicate push
FILE=malloc://1024
CMDS=<<EOF
s 0x0
s 0x0
s 0x1
s 0x2
# shouldn't contain multiple 0 at the start
shj
# regression test for deduplication not working on buffer edge
60sd +1
s 0x0
s 0x0
s 0x01
s 0x02
sh~:-6..
EOF
EXPECT=<<EOF
[{"offset":0,"cursor":0,"current":false},{"offset":1,"cursor":0,"current":false},{"offset":2,"cursor":0,"current":true}]
0x3c 
0x3d 
0x3e 
0x0 
0x1 
0x2  # current seek
EOF
RUN