#!/bin/sh
#
# Regression tester for SRC.
#
# Use -b to test with a specified back end, rcs or sccs
# Use -p to test with a specified Python interpreter
# Use -e to rest with an alternate src version
# Use -t to put test files and masters at a fixed location, not removing on exit

# Set the umask for a bit of defensiveness
umask 0077

# Set the PATH to include the current directory, so the repository
# head version of src can always be tested.
PATH="$(pwd)":$PATH

backend="rcs"
python="python"
testmode=no

while getopts b:p:e:t opt
do
    case $opt in
	b) backend=$OPTARG;;
	p) python=$OPTARG;;
	e) src=$OPTARG;;
	t) testmode=yes;;
    esac
done
shift $(($OPTIND - 1))

$backend >/dev/null 2>&1
if [ "$?" = 127 ]
then
    echo "srctest: backend ${backend} is missing."
    exit 1
fi

if [ -z "$src" ]
then
    src="${python} ${PWD}/src"
fi

check() {
    case $? in
	0) echo "srctest ($python $backend): $1 succeeded";;
	*) echo "srctest ($python $backend): $1 failed"; exit 1;;
    esac
}

historify () {
    case $backend in
	rcs) history=.src/$1,v ;;
	sccs) history=SCCS/s.$1 ;;
    esac
}

if [ $testmode = yes ]
then
    SANDBOX=/tmp/srctest
    echo "Test files and masters will not be removed on exit."
    rm -fr $SANDBOX
else
    # Needs to not be a subdirectory of here, or git gets confused.  Use
    # -u so that src's initialization will be tested.
    SANDBOX=$(mktemp -u /tmp/src_XXXXXXXX)
    trap "rm -fr $SANDBOX" 0 1 2 15
fi

if [ ! -d $SANDBOX ]
then
     mkdir $SANDBOX
fi
check "scratch directory creation: $SANDBOX"

if [ "$SANDBOX" = "" ]
then
    echo "srctest refuses to destroy the world."
fi

cd $SANDBOX; rm -fr *

TESTOPTS="-T $* $backend"

DIFFOPTS="--label Expected --label Actual -u"


COLUMNS=73
export COLUMNS

cat >testfile1 <<EOF
Now is the time
EOF
cp testfile1 testrev1

$src $TESTOPTS commit -m "First comment" testfile1 #>/dev/null
check "commit with -m option"

$src $TESTOPTS cat testfile1 | diff -u testfile1 - >/dev/null
check "content check after first commit"

cat >testfile1 <<EOF
Now is the time
for all good men
EOF
cp testfile1 testrev2

cat >testfile4 <<EOF
@@ -1,2 +1,3 @@
 Now is the time
+for all good men
 
EOF

# (read; read; cat) removes header lines containing variable date information
$src $TESTOPTS diff testfile1 | (read discard; read discard; cat) >testfile5
diff -u testfile4 testfile5
check "nonempty diff"

! $src $TESTOPTS diff -@ testfile1 2>diff.err &&
    grep unexpected diff.err >/dev/null
check "bogus diff option"

sleep 1	# Force commit to have different timestamp
echo "Second comment" | $src $TESTOPTS commit - testfile1 >/dev/null
check "commit with -"

$src $TESTOPTS cat testfile1 | diff $DIFFOPTS testfile1 -
check "content check after second commit"

cat >testfile2 <<EOF
= testfile1 ============================================================
2     * 1970-01-02T00:01:00Z Second comment
1     - 1970-01-02T00:00:00Z First comment
EOF

$src $TESTOPTS list testfile1 >testfile3
diff $DIFFOPTS testfile2 testfile3
check "list test"

cat >testfile2 <<EOF
= testfile1 ============================================================
2    | 1970-01-02T00:01:00Z | trunk
Second comment
------------------------------------------------------------------------
1    | 1970-01-02T00:00:00Z | trunk
First comment
------------------------------------------------------------------------
EOF

$src $TESTOPTS log testfile1 >testfile3
diff $DIFFOPTS testfile2 testfile3
check "2-commit log test"

cat >testfile1 <<EOF
Now is the time
for all good men
to come to the aid of foo
EOF
cp testfile1 testrev3

sleep 1	# Force commit to have different timestamp
cat >testfile4 <<EOF
'Third' comment

Multiline test.

EOF
$src $TESTOPTS commit -f testfile4 testfile1 >/dev/null
check "commit with -f"

cat >testfile4 <<EOF
= testfile1 ============================================================
3    | 1970-01-02T00:02:00Z | trunk
'Third' comment

Multiline test.
------------------------------------------------------------------------
2    | 1970-01-02T00:01:00Z | trunk
Second comment
------------------------------------------------------------------------
1    | 1970-01-02T00:00:00Z | trunk
First comment
------------------------------------------------------------------------
EOF

$src $TESTOPTS log testfile1 >testfile5
diff $DIFFOPTS testfile4 testfile5
check "3-commit log test"

cat >testfile14 <<EOF
= testfile1 ============================================================
3    | 1970-01-02T00:02:00Z | trunk
'Third' comment

Multiline test.

diff r2/testfile1 r3/testfile1
--- testfile1 (r2)
+++ testfile1 (r3)
@@ -1,3 +1,4 @@
 Now is the time
 for all good men
+to come to the aid of foo
 
------------------------------------------------------------------------
2    | 1970-01-02T00:01:00Z | trunk
Second comment

diff r1/testfile1 r2/testfile1
--- testfile1 (r1)
+++ testfile1 (r2)
@@ -1,2 +1,3 @@
 Now is the time
+for all good men
 
------------------------------------------------------------------------
1    | 1970-01-02T00:00:00Z | trunk
First comment

diff /dev/null r1/testfile1
--- /dev/null
+++ testfile1 (r1)
@@ -1 +1,2 @@
+Now is the time
 
------------------------------------------------------------------------
EOF

$src $TESTOPTS log --patch testfile1 >testfile15
diff $DIFFOPTS testfile14 testfile15
check "log --patch"

cat >testfile6 <<EOF
= testfile1 ============================================================
src: testfile1 has no 5 revision
EOF

$src $TESTOPTS list 5 testfile1 >testfile7 2>&1
diff $DIFFOPTS testfile6 testfile7
check "oob revision spec check"

for rev in 1 2 3
do
    $src $TESTOPTS checkout $rev testfile1 >/dev/null
    check "revision $rev checkout test"
    diff $DIFFOPTS testrev${rev} testfile1
    check "revision $rev content test"
done

$src $TESTOPTS tag create sampletag
check "tag set to default tip revision"

cat >testfile8 <<EOF
= testfile1 ==========================================================
   3	sampletag
EOF
$src $TESTOPTS tag list >testfile9
diff $DIFFOPTS testfile8 testfile9
check "tag list check"

$src $TESTOPTS tag create basetag 1
check "tag set to revision 1"

cat >testfile10 <<EOF
= testfile1 ==========================================================
   1	basetag
   3	sampletag
EOF
$src $TESTOPTS tag -l >testfile11
diff $DIFFOPTS testfile10 testfile11
check "second tag list check"

$src $TESTOPTS tag delete sampletag
check "tag deletion: sampletag"

cat >testfile12 <<EOF
= testfile1 ==========================================================
   1	basetag
EOF
$src $TESTOPTS tag >testfile13
diff $DIFFOPTS testfile12 testfile13
check "tag list check after deletion"

# Alas, we have to do this or the fast-export regression will fail.
# We don't know how to be perfectly canonical about tags yet.
$src $TESTOPTS tag delete basetag
check "tag deletion: basetag"

test_export () {
    testname="$1"
    shift
    srcfi=$testname-src.fi
    gitfi=$testname-git.fi
    mkdir foo
    $src $TESTOPTS fast-export "$@" >$srcfi 2>export.err
    grep jrh $srcfi >/dev/null
    check "fast-export: $testname"
    cat $srcfi | (cd foo >/dev/null; git init --quiet; git fast-import --quiet)
    (cd foo >/dev/null; git fast-export --all) >$gitfi
    diff $DIFFOPTS $srcfi $gitfi
    check "fast-export roundtrip: $testname"
    rm -fr foo
}

test_export filename testfile1

# Test multiple-file fast-export.
echo flower power >testfile14
$src $TESTOPTS commit -m "Alfred E. Newman" testfile14 >/dev/null
test_export filenames testfile1 testfile14
historify testfile14
rm -f $history

test_export revspec-filename -- testfile1
grep refs/heads/master revspec-filename-src.fi >/dev/null &&
    ! grep refs/heads/testfile1/master revspec-filename-src.fi >/dev/null
check "fast-export revspec/filename distinction"

rm -f testfile1
test_export not-checked-out testfile1
check "fast-export consults history only"
$src $TESTOPTS checkout testfile1 >/dev/null

if [ "$backend" = "sccs" ]
then
    echo "srctest ($python $backend): skipping fast-import checks: RCS-only"
elif ! command -v rcs-fast-import >/dev/null 2>&1
then
    echo "srctest ($python $backend): skipping fast-import checks: rcs-fast-import missing"
else
    mkdir RCS
    ! $src $TESTOPTS fast-import -p <filename-git.fi >/dev/null 2>err &&
	grep 'existing RCS' err >/dev/null
    check "fast-import don't clobber RCS"
    rm -fr RCS

    historify testfile1
    rm -f $history
    $src $TESTOPTS fast-import -p <filename-git.fi >/dev/null 2>&1 &&
	test -f $history
    check "fast-import"

    $src $TESTOPTS fast-export testfile1 >testfile1.fi &&
	diff -u filename-git.fi testfile1.fi
    check "fast-import roundtrip"
fi

$src $TESTOPTS move testfile1 newname1
check "move command"
historify newname1
if [ -e newname1 -a -e $history ]
then
    echo "srctest ($python $backend): content move succeeded"
else
    echo "srctest ($python $backend): content move failed"
    exit 1
fi

$src $TESTOPTS copy newname1 newname2
check "copy command"
historify newname2
if [ -e newname2 -a -e $history ]
then
    echo "srctest ($python $backend): content copy succeeded"
else
    echo "srctest ($python $backend): content copy failed"
    exit 1
fi

cat >testfile16 <<EOF
newname1
newname2
EOF
$src $TESTOPTS ls | diff $DIFFOPTS testfile16 -
check "ls"

$src $TESTOPTS commit -m "Another sample" testfile16
$src $TESTOPTS status testfile16 | grep "^=" >/dev/null
check "= status check after first commit"

echo "Add a second line" >>testfile16
$src $TESTOPTS status testfile16 | grep "^M" >/dev/null
check "M status check after modification"

rm testfile16
$src $TESTOPTS status testfile16 | grep "^!" >/dev/null
check "! status check after deletion"

$src $TESTOPTS checkout testfile16
$src $TESTOPTS status testfile16 | grep "^=" >/dev/null
check "= status check after restoration"

historify testfile16
rm -f $history
$src $TESTOPTS status testfile16 | grep "^?" >/dev/null
check "? status check after master deletion"

$src $TESTOPTS amend -m "Amended comment" newname1
check "amend"

$src $TESTOPTS list 3 newname1 | grep "Amended comment" >/dev/null
check "amended comment content"

cat >testfile17 <<EOF
=	newname1
=	newname2
EOF
$src $TESTOPTS status | diff $DIFFOPTS testfile17 - >/dev/null
check "unadorned status command"

if [ "$backend" = "sccs" ]
then
    echo "srctest ($python $backend): skipping tag and branch tests"
else
    # Introduce a test history with some branchiness, so
    # we can test traversal across branch joins. Also has tags.
    cat >.src/sample,v <<EOF
head	1.4;
branch	1.3.1.4.1;
access;
symbols
	GLARB:1.4
	GORP:1.3.1.4
	sample:1.3.1.4.0.1
	muggle:1.3.0.1;
locks
	esr:1.3.1.4.1.5;
comment	@# @;
expand	@b@;


1.4
date	2014.11.11.03.26.53;	author esr;	state Exp;
branches;
next	1.3;

1.3
date	2014.11.10.23.48.49;	author esr;	state Exp;
branches
	1.3.1.1;
next	1.2;

1.2
date	2014.11.10.23.48.11;	author esr;	state Exp;
branches;
next	1.1;

1.1
date	2014.11.10.23.47.08;	author esr;	state Exp;
branches;
next	;

1.3.1.1
date	2014.11.11.04.23.47;	author esr;	state Exp;
branches;
next	1.3.1.2;

1.3.1.2
date	2014.11.11.06.39.47;	author esr;	state Exp;
branches;
next	1.3.1.3;

1.3.1.3
date	2014.11.11.06.48.00;	author esr;	state Exp;
branches;
next	1.3.1.4;

1.3.1.4
date	2014.11.12.03.36.45;	author esr;	state Exp;
branches
	1.3.1.4.1.1;
next	;

1.3.1.4.1.1
date	2014.11.13.04.04.55;	author esr;	state Exp;
branches;
next	1.3.1.4.1.2;

1.3.1.4.1.2
date	2014.11.13.04.23.04;	author esr;	state Exp;
branches;
next	1.3.1.4.1.3;

1.3.1.4.1.3
date	2014.11.13.04.26.23;	author esr;	state Exp;
branches;
next	1.3.1.4.1.4;

1.3.1.4.1.4
date	2014.11.13.04.30.39;	author esr;	state Exp;
branches;
next	1.3.1.4.1.5;

1.3.1.4.1.5
date	2014.11.13.04.31.02;	author esr;	state Exp;
branches;
next	;


desc
@@


1.4
log
@On a branch?
@
text
@Now is the time
For all good men.
To come to the aid of foo.
This should be branch text.
@


1.3
log
@Third comment.
@
text
@d4 1
@


1.3.1.1
log
@Totally unfubared.
@
text
@a3 2

Again, this should be branch text.
@


1.3.1.2
log
@Still utterly fubar
@
text
@d5 1
a5 1
Yet again, this should be branch text.
@


1.3.1.3
log
@Totally chenille.
@
text
@a5 2

Revision 7.
@


1.3.1.4
log
@Utterly fubar
@
text
@d4 4
a7 2
This should be branch text.
Try a comment with a hyphen.
@


1.3.1.4.1.1
log
@All fixed up.
@
text
@a5 1
Test of commit comments.
@


1.3.1.4.1.2
log
@It' all good.
@
text
@a6 1
Glotch.
@


1.3.1.4.1.3
log
@No good.
@
text
@a7 1
Random modification.
@


1.3.1.4.1.4
log
@That's good.
@
text
@a4 1
jjjj
d7 1
@


1.3.1.4.1.5
log
@I see you
@
text
@d5 1
a5 1
jjjjjjjjkkk
@


1.2
log
@Second comment.
@
text
@d3 1
@


1.1
log
@First comment.
@
text
@d2 1
@
EOF

cat >sampledot <<EOF
digraph {
	1 [shape=box,width=5,label=<<table cellspacing="0" border="0" cellborder="0"><tr><td><font color="blue">1</font></td><td>First comment.</td></tr></table>>];
	1 -> 2;
	2 [shape=box,width=5,label=<<table cellspacing="0" border="0" cellborder="0"><tr><td><font color="blue">2</font></td><td>Second comment.</td></tr></table>>];
	2 -> 3;
	3 [shape=box,width=5,label=<<table cellspacing="0" border="0" cellborder="0"><tr><td><font color="blue">3</font></td><td>Third comment.</td></tr></table>>];
	3 -> 4;
	4 [shape=box,width=5,label=<<table cellspacing="0" border="0" cellborder="0"><tr><td><font color="blue">4</font></td><td>On a branch?</td></tr></table>>];
	"trunk" [shape=oval,width=2];
	"4" -> "trunk" [style=dotted];
	3 -> 5;
	5 [shape=box,width=5,label=<<table cellspacing="0" border="0" cellborder="0"><tr><td><font color="blue">5</font></td><td>Totally unfubared.</td></tr></table>>];
	5 -> 6;
	6 [shape=box,width=5,label=<<table cellspacing="0" border="0" cellborder="0"><tr><td><font color="blue">6</font></td><td>Still utterly fubar</td></tr></table>>];
	6 -> 7;
	7 [shape=box,width=5,label=<<table cellspacing="0" border="0" cellborder="0"><tr><td><font color="blue">7</font></td><td>Totally chenille.</td></tr></table>>];
	7 -> 8;
	8 [shape=box,width=5,label=<<table cellspacing="0" border="0" cellborder="0"><tr><td><font color="blue">8</font></td><td>Utterly fubar</td></tr></table>>];
	"muggle" [shape=oval,width=2];
	"8" -> "muggle" [style=dotted];
	8 -> 9;
	9 [shape=box,width=5,label=<<table cellspacing="0" border="0" cellborder="0"><tr><td><font color="blue">9</font></td><td>All fixed up.</td></tr></table>>];
	9 -> 10;
	10 [shape=box,width=5,label=<<table cellspacing="0" border="0" cellborder="0"><tr><td><font color="blue">10</font></td><td>It' all good.</td></tr></table>>];
	10 -> 11;
	11 [shape=box,width=5,label=<<table cellspacing="0" border="0" cellborder="0"><tr><td><font color="blue">11</font></td><td>No good.</td></tr></table>>];
	11 -> 12;
	12 [shape=box,width=5,label=<<table cellspacing="0" border="0" cellborder="0"><tr><td><font color="blue">12</font></td><td>That's good.</td></tr></table>>];
	12 -> 13;
	13 [shape=box,width=5,label=<<table cellspacing="0" border="0" cellborder="0"><tr><td><font color="blue">13</font></td><td>I see you</td></tr></table>>];
	"sample" [shape=oval,width=2];
	"13" -> "sample" [style=dotted];
	{rank=same; "GLARB"; "4"}
	"GLARB" -> "4" [style=dotted];
	{rank=same; "GORP"; "8"}
	"GORP" -> "8" [style=dotted];
}
EOF

    $src $TESTOPTS visualize sample >tryit
    diff $DIFFOPTS sampledot tryit
    check "dot visualization"

    cat >statuslog <<EOF
=	newname1
=	newname2
EOF

    cat >sample.seqlog <<EOF
= sample ===============================================================
6    | 1970-01-02T00:05:00Z | muggle
Still utterly fubar
------------------------------------------------------------------------
5    | 1970-01-02T00:04:00Z | muggle
Totally unfubared.
------------------------------------------------------------------------
4    | 1970-01-02T00:03:00Z | trunk
On a branch?
------------------------------------------------------------------------
3    | 1970-01-02T00:02:00Z | trunk
Third comment.
------------------------------------------------------------------------
2    | 1970-01-02T00:01:00Z | trunk
Second comment.
------------------------------------------------------------------------
EOF

    $src $TESTOPTS log 6-2 sample >tryit
    diff $DIFFOPTS sample.seqlog tryit
    check "traversal by -"

    cat >sample.branchlog <<EOF
= sample ===============================================================
6    | 1970-01-02T00:05:00Z | muggle
Still utterly fubar
------------------------------------------------------------------------
5    | 1970-01-02T00:04:00Z | muggle
Totally unfubared.
------------------------------------------------------------------------
3    | 1970-01-02T00:02:00Z | trunk
Third comment.
------------------------------------------------------------------------
2    | 1970-01-02T00:01:00Z | trunk
Second comment.
------------------------------------------------------------------------
EOF

    $src $TESTOPTS log 6..2 sample >tryit
    diff $DIFFOPTS sample.branchlog tryit
    check "traversal by .."

    cat >sample.branchlog-p <<EOF
= sample ===============================================================
5    | 1970-01-02T00:04:00Z | muggle
Totally unfubared.

diff r3/sample r5/sample
--- sample (r3)
+++ sample (r5)
@@ -2,3 +2,5 @@
 For all good men.
 To come to the aid of foo.
 
+Again, this should be branch text.
+
------------------------------------------------------------------------
EOF

    $src $TESTOPTS log --patch 5 sample >tryit
    diff $DIFFOPTS sample.branchlog-p tryit
    check "branchy log --patch"

    cat >sample.taglog <<EOF
= sample ===============================================================
4     - 1970-01-02T00:03:00Z On a branch?
EOF

    $src $TESTOPTS list @GLARB sample >tryit
    diff $DIFFOPTS sample.taglog tryit
    check "named-tag lookup with @"

    $src $TESTOPTS rename tag GLARB GROTTY sample
    check "tag renaming"

    cat >changes <<EOF
= sample =============================================================
   8	GORP
   4	GROTTY
EOF

    $src $TESTOPTS tag -l sample >tryit
    diff $DIFFOPTS tryit changes
    check "tag list after rename"

    cat >branchlist <<EOF
= sample =============================================================
   0	trunk
   3	muggle
   8	sample
EOF

    $src $TESTOPTS branch -l sample >tryit
    check "branch list"

    $src $TESTOPTS branch -l sample >tryit
    diff $DIFFOPTS branchlist tryit
    check "branch list content"

    cat >branchlog <<EOF
= sample ===============================================================
4     - 1970-01-02T00:03:00Z On a branch?
EOF

    $src $TESTOPTS list @trunk sample >branchlog
    check "branch name resolution"

    $src $TESTOPTS list @trunk sample >tryit
    diff $DIFFOPTS branchlog tryit
    check "branch name resolved content"

    cat >statuslog <<EOF
=	newname1
=	newname2
EOF

    $src $TESTOPTS status newname1 newname2 >tryit
    diff $DIFFOPTS statuslog tryit
    check "status before ignore"

    echo "newname1" >.srcignore

    cat >statuslog <<EOF
I	newname1
=	newname2
EOF

    $src $TESTOPTS status newname1 newname2 >tryit
    diff $DIFFOPTS statuslog tryit
    check "status after ignore"

    $src $TESTOPTS branch delete trunk sample
    check "branch delete"

    cat >newlist <<EOF
= sample =============================================================
   0	trunk
   3	muggle
   7	sample
EOF

    $src $TESTOPTS branch -l sample >tryit
    diff $DIFFOPTS newlist tryit
    check "branch list check after delete"

    cat >newlog <<EOF
= sample ===============================================================
12   | 1970-01-02T00:11:00Z | sample
I see you
------------------------------------------------------------------------
11   | 1970-01-02T00:10:00Z | sample
That's good.
------------------------------------------------------------------------
10   | 1970-01-02T00:09:00Z | sample
No good.
------------------------------------------------------------------------
9    | 1970-01-02T00:08:00Z | sample
It' all good.
------------------------------------------------------------------------
8    | 1970-01-02T00:07:00Z | sample
All fixed up.
------------------------------------------------------------------------
7    | 1970-01-02T00:06:00Z | muggle
Utterly fubar
------------------------------------------------------------------------
6    | 1970-01-02T00:05:00Z | muggle
Totally chenille.
------------------------------------------------------------------------
5    | 1970-01-02T00:04:00Z | muggle
Still utterly fubar
------------------------------------------------------------------------
4    | 1970-01-02T00:03:00Z | muggle
Totally unfubared.
------------------------------------------------------------------------
3    | 1970-01-02T00:02:00Z | trunk
Third comment.
------------------------------------------------------------------------
2    | 1970-01-02T00:01:00Z | trunk
Second comment.
------------------------------------------------------------------------
1    | 1970-01-02T00:00:00Z | trunk
First comment.
------------------------------------------------------------------------
EOF

    $src $TESTOPTS log sample >tryit 
    diff $DIFFOPTS newlog tryit
    check "content after branch deletion"
fi
  
echo "Random content for numeric file" >23
$src $TESTOPTS commit -m "I don't know why you say goodbye" -- 23 >/dev/null
check "commit of file with numeric name"

cat >randomcontent <<EOF
Random content for numeric file
EOF

$src $TESTOPTS cat -- 23 >tryit
diff $DIFFOPTS randomcontent tryit
check "cat of file with numeric name"

# Eric Sunshine writes:
#
# The test itself is working properly. The problem is that stock SCCS
# does not preserve executable permission on files under its control, so
# the test is correctly failing.
#
# The GNU version of SCCS does provide an 'x' flag[1] for compatibility
# with SCO OpenServer which enables executable permission preservation.
# However, I haven't convinced myself that it would make sense to put in
# the work to add executable-preservation support to the SCCS backend
# for these special cases (GNU CSSC and SCO OpenServer).
#
# [1]: https://www.gnu.org/software/cssc/manual/Flags.html#Flag
#
if [ "$backend" = sccs ]
then
    echo "srctest ($python $backend): skipping exec-bit propagation test"
else
    echo "Should not be executable" >exectest
    $src $TESTOPTS commit -m "First comment on exectest" exectest >/dev/null
    check "first commit of exectest"
    chmod a+x exectest
    echo "Should be executable" >exectest
    $src $TESTOPTS commit -m "Second comment on exectest" exectest >/dev/null
    check "second commit of exectest"
    ls -l exectest | grep '^...x' >/dev/null
    check "propagation of exec bit"
fi

cat >diffall.expect <<EOF
--- newname1 (r3)
+++ newname1 (workfile)
@@ -1,4 +1,5 @@
 Now is the time
 for all good men
 to come to the aid of foo
+more stuff
 
--- newname2 (r3)
+++ newname2 (workfile)
@@ -1,4 +1,5 @@
 Now is the time
 for all good men
 to come to the aid of foo
+and even more
 
EOF

echo "more stuff" >>newname1
echo "and even more" >>newname2
$src $TESTOPTS diff >diffall.actual &&
    diff $DIFFOPTS diffall.expect diffall.actual &&
    $src $TESTOPTS checkout newname1 newname2 >/dev/null
check "default file list"

cat >limit.list <<EOF
= newname2 =============================================================
3     * 1970-01-02T00:02:00Z 'Third' comment
2     - 1970-01-02T00:01:00Z Second comment
EOF
cat >limit.log <<EOF
= newname2 =============================================================
3    | 1970-01-02T00:02:00Z | trunk
'Third' comment

Multiline test.
------------------------------------------------------------------------
2    | 1970-01-02T00:01:00Z | trunk
Second comment
------------------------------------------------------------------------
EOF
for i in list log
do
    for j in -2 '-l 2'
    do
	$src $TESTOPTS $i $j newname2 >limit.expect
	diff limit.$i limit.expect
	check "$i $j"
    done
done

# Test for Tom Willemse's multi-commit bug.
echo "test 1" > file1
echo "test 2" > file2
$src $TESTOPTS commit -m "Initial commit" file1 file2 >/dev/null
check "multi-file registration"
echo "test 1 line 2" >> file1
echo "test 2 line 2" >> file2
$src $TESTOPTS commit -m "Second commit" file1 file2 >/dev/null
check "multi-file commit"

# Test the edit logic
cat >modify <<'EOF'
echo "Different first line" >modified$$
cat $1 >>modified$$
mv modified$$ $1
EOF
chmod a+x modify
echo "test 1 line 3" >> file1
EDITOR="./modify" $src $TESTOPTS commit file1
check "edit logic"

cat >binary <<EOF
This file contains an 0xD3 (Meta-S) after the colon:Ó
EOF
cat >binary.chk <<EOF
This file contains an 0xD3 (Meta-S) after the colon:Ó
Additional content line.
EOF
$src $TESTOPTS commit -m "Test file containing binary byte." binary
echo "Additional content line." >>binary
$src $TESTOPTS commit -m "Binary file after modification." binary
cmp binary binary.chk
check "binary content in checkouts and commits"

if [ "$backend" = "sccs" ]
then
    echo "srctest ($python $backend): skipping binary cat test"
else
    $src $TESTOPTS cat binary >catted
    cmp binary catted
    check "binary content in cat"
fi

cat >newline <<EOF
This file contains a DOS newline 0x0D after the colon:
EOF
cat >newline.chk <<EOF
This file contains a DOS newline 0x0D after the colon:
Additional content line.
EOF
$src $TESTOPTS commit -m "Test file containing DOS newline." newline
echo "Additional content line." >>newline
$src $TESTOPTS commit -m "DOS newline file after modification." newline
cmp newline newline.chk
check "newline preservation in checkouts and commits"

if [ "$backend" = "sccs" ]
then
    echo "srctest ($python $backend): skipping newline cat test"
else
    $src $TESTOPTS cat newline >ncatted
    cmp newline ncatted
    check "newline content in cat"
fi

cat >padcomment <<'EOF'
printf "\n\n\n\n" >modified$$
cat $1 >>modified$$
mv modified$$ $1
EOF
chmod a+x padcomment
echo gommelgor >padfile
$src $TESTOPTS commit -m pingle padfile
for i in commit amend
do
    echo "more stuff" >>padfile
    EDITOR="./padcomment" $src $TESTOPTS $i padfile >padout
    grep cancelled padout >/dev/null
    check "whitespace-only $i cancel"
    $src $TESTOPTS checkout padfile
done

cat >clonemsg <<'EOF'
echo "I think I'm a clone now" >modified$$
cat $1 >>modified$$
mv modified$$ $1
cp $1 clonedmsg
EOF
chmod a+x clonemsg
echo gommelgor >diffledore
$src $TESTOPTS commit -m pingle diffledore
for i in commit amend
do
    test $i = commit && echo "more stuff" >>diffledore
    EDITOR="./clonemsg" $src $TESTOPTS $i diffledore >/dev/null
    grep -F -e 'Changes to be committed' clonedmsg >/dev/null &&
    grep -F -e '@@ ' clonedmsg >/dev/null &&
    grep -F -e '+++ ' clonedmsg >/dev/null &&
    grep -F -e '--- ' clonedmsg >/dev/null
    check "$i diff in boilerplate"
done

cat >dontinvoke <<'EOF'
echo "panic!" >>nochanges
EOF
chmod a+x dontinvoke
echo "bingleby" >canttouchthis
$src $TESTOPTS commit -m pingle canttouchthis
EDITOR="./dontinvoke" $src $TESTOPTS commit canttouchthis >>nochanges
grep 'no changes to commit' nochanges >/dev/null &&
    ! grep panic nochanges >/dev/null
check "nothing to commit"

cat >ignore.ws <<EOF
Mary had a little lamb,
whose fleece was white as snow.
Everywhere that Mary went,
the lamb was sure to go.
EOF
$src $TESTOPTS commit -m initial ignore.ws
cat >ignore.ws <<EOF
Gary had a little lamb,
whose    fleece was    white as snow.
Everywhere that Gary went,
    the lamb was sure to go.
EOF
sleep 1	# Force commit to have different timestamp
$src $TESTOPTS commit -m 's/Mary/Gary/ & whitespace' ignore.ws
cat >ignore.expect-b <<EOF
--- ignore.ws (r1)
+++ ignore.ws (r2)
@@ -1,4 +1,4 @@
-Mary had a little lamb,
+Gary had a little lamb,
 whose fleece was white as snow.
-Everywhere that Mary went,
-the lamb was sure to go.
+Everywhere that Gary went,
+    the lamb was sure to go.

EOF
cat >ignore.expect-w <<EOF
--- ignore.ws (r1)
+++ ignore.ws (r2)
@@ -1,4 +1,4 @@
-Mary had a little lamb,
+Gary had a little lamb,
 whose fleece was white as snow.
-Everywhere that Mary went,
+Everywhere that Gary went,
 the lamb was sure to go.

EOF
for i in -b -w
do
    $src $TESTOPTS diff -u $i 1-2 ignore.ws >ignore.actual$i
    diff ignore.expect$i ignore.actual$i
    check "diff $i"
done

if [ "$backend" = "sccs" ]
then
    echo "srctest ($python $backend): skipping commit date tie-breaking tests"
else
    # Introduce a test history with all commits having same date so we can
    # test native revision ID tie-breaking.
    cat >.src/tiebreak,v <<EOF
head	1.11;
access;
symbols
	refs/heads/master:1.11;
locks
	sunshine:1.11; strict;
comment	@# @;


1.11
date	2017.11.21.06.45.15;	author sunshine;	state Exp;
branches;
next	1.10;

1.10
date	2017.11.21.06.45.15;	author sunshine;	state Exp;
branches;
next	1.9;

1.9
date	2017.11.21.06.45.15;	author sunshine;	state Exp;
branches;
next	1.8;

1.8
date	2017.11.21.06.45.15;	author sunshine;	state Exp;
branches;
next	1.7;

1.7
date	2017.11.21.06.45.15;	author sunshine;	state Exp;
branches;
next	1.6;

1.6
date	2017.11.21.06.45.15;	author sunshine;	state Exp;
branches;
next	1.5;

1.5
date	2017.11.21.06.45.15;	author sunshine;	state Exp;
branches;
next	1.4;

1.4
date	2017.11.21.06.45.15;	author sunshine;	state Exp;
branches;
next	1.3;

1.3
date	2017.11.21.06.45.15;	author sunshine;	state Exp;
branches;
next	1.2;

1.2
date	2017.11.21.06.45.15;	author sunshine;	state Exp;
branches;
next	1.1;

1.1
date	2017.11.21.06.45.15;	author sunshine;	state Exp;
branches;
next	;


desc
@@


1.11
log
@Author: Eric Sunshine <sunshine@@sunshineco.com>
Author-Date: Mon 20 Nov 2017 21:37:42 -0500
Committer: Roy G. Biv <spectrum@@color.com>
Committer-Date: Tue 21 Nov 2017 01:45:15 +0000
Mark: :22
Parents: :20

eleventh
@
text
@eleventh
@


1.10
log
@Author: Eric Sunshine <sunshine@@sunshineco.com>
Author-Date: Mon 20 Nov 2017 21:30:40 -0500
Committer: Roy G. Biv <spectrum@@color.com>
Committer-Date: Tue 21 Nov 2017 01:45:15 +0000
Mark: :20
Parents: :18

tenth
@
text
@d1 1
a1 1
tenth
@


1.9
log
@Author: Eric Sunshine <sunshine@@sunshineco.com>
Author-Date: Mon 20 Nov 2017 21:27:29 -0500
Committer: Roy G. Biv <spectrum@@color.com>
Committer-Date: Tue 21 Nov 2017 01:45:15 +0000
Mark: :18
Parents: :16

ninth
@
text
@d1 1
a1 1
ninth
@


1.8
log
@Author: Eric Sunshine <sunshine@@sunshineco.com>
Author-Date: Mon 20 Nov 2017 21:25:22 -0500
Committer: Roy G. Biv <spectrum@@color.com>
Committer-Date: Tue 21 Nov 2017 01:45:15 +0000
Mark: :16
Parents: :14

eighth
@
text
@d1 1
a1 1
eighth
@


1.7
log
@Author: Eric Sunshine <sunshine@@sunshineco.com>
Author-Date: Mon 20 Nov 2017 23:02:46 -0500
Committer: Roy G. Biv <spectrum@@color.com>
Committer-Date: Tue 21 Nov 2017 01:45:15 +0000
Mark: :14
Parents: :12

seventh
@
text
@d1 1
a1 1
seventh
@


1.6
log
@Author: Eric Sunshine <sunshine@@sunshineco.com>
Author-Date: Mon 20 Nov 2017 22:56:46 -0500
Committer: Roy G. Biv <spectrum@@color.com>
Committer-Date: Tue 21 Nov 2017 01:45:15 +0000
Mark: :12
Parents: :10

sixth
@
text
@d1 1
a1 1
sixth
@


1.5
log
@Author: Eric Sunshine <sunshine@@sunshineco.com>
Author-Date: Fri 03 Nov 2017 13:30:17 -0500
Committer: Roy G. Biv <spectrum@@color.com>
Committer-Date: Tue 21 Nov 2017 01:45:15 +0000
Mark: :10
Parents: :8

fifth
@
text
@d1 1
a1 1
fifth
@


1.4
log
@Author: Eric Sunshine <sunshine@@sunshineco.com>
Author-Date: Fri 03 Nov 2017 13:28:35 -0500
Committer: Roy G. Biv <spectrum@@color.com>
Committer-Date: Tue 21 Nov 2017 01:45:15 +0000
Mark: :8
Parents: :6

fourth
@
text
@d1 1
a1 1
fourth
@


1.3
log
@Author: Eric Sunshine <sunshine@@sunshineco.com>
Author-Date: Fri 03 Nov 2017 13:26:41 -0500
Committer: Roy G. Biv <spectrum@@color.com>
Committer-Date: Tue 21 Nov 2017 01:45:15 +0000
Mark: :6
Parents: :4

third
@
text
@d1 1
a1 1
third
@


1.2
log
@Author: Eric Sunshine <sunshine@@sunshineco.com>
Author-Date: Fri 03 Nov 2017 13:25:01 -0500
Committer: Roy G. Biv <spectrum@@color.com>
Committer-Date: Tue 21 Nov 2017 01:45:15 +0000
Mark: :4
Parents: :2

second
@
text
@d1 1
a1 1
second
@


1.1
log
@Author: Eric Sunshine <sunshine@@sunshineco.com>
Author-Date: Fri 03 Nov 2017 13:12:48 -0500
Committer: Roy G. Biv <spectrum@@color.com>
Committer-Date: Tue 21 Nov 2017 01:45:15 +0000
Mark: :2

first
@
text
@d1 1
a1 1
first
@
EOF

    cat >tiebreak.expect <<EOF
= tiebreak =============================================================
11    * 1970-01-02T00:10:00Z eleventh
10    - 1970-01-02T00:09:00Z tenth
9     - 1970-01-02T00:08:00Z ninth
8     - 1970-01-02T00:07:00Z eighth
7     - 1970-01-02T00:06:00Z seventh
6     - 1970-01-02T00:05:00Z sixth
5     - 1970-01-02T00:04:00Z fifth
4     - 1970-01-02T00:03:00Z fourth
3     - 1970-01-02T00:02:00Z third
2     - 1970-01-02T00:01:00Z second
1     - 1970-01-02T00:00:00Z first
EOF

    $src $TESTOPTS list tiebreak >tiebreak.actual
    diff tiebreak.expect tiebreak.actual
    check "same date tie-breaking"

    cat >noheaders.expect <<EOF
= tiebreak =============================================================
11   | 1970-01-02T00:10:00Z | trunk
eleventh
------------------------------------------------------------------------
10   | 1970-01-02T00:09:00Z | trunk
tenth
------------------------------------------------------------------------
EOF

    $src $TESTOPTS log -2 tiebreak >noheaders.actual
    diff noheaders.expect noheaders.actual
    check "log suppresses headers"

    cat >logheaders.expect <<EOF
= tiebreak =============================================================
11   | 1970-01-02T00:10:00Z | trunk
Author: Eric Sunshine <sunshine@sunshineco.com>
Author-Date: 2017-11-21T02:37:42Z
Author-Date-Offset: -18000
Committer: Roy G. Biv <spectrum@color.com>
Committer-Date: 2017-11-21T01:45:15Z
Committer-Date-Offset: 0
Mark: :22
Parents: :20

eleventh
------------------------------------------------------------------------
10   | 1970-01-02T00:09:00Z | trunk
Author: Eric Sunshine <sunshine@sunshineco.com>
Author-Date: 2017-11-21T02:30:40Z
Author-Date-Offset: -18000
Committer: Roy G. Biv <spectrum@color.com>
Committer-Date: 2017-11-21T01:45:15Z
Committer-Date-Offset: 0
Mark: :20
Parents: :18

tenth
------------------------------------------------------------------------
EOF

    $src $TESTOPTS log -v -v -2 tiebreak >logheaders.actual
    diff logheaders.expect logheaders.actual
    check "log -v -v shows all headers"

    cat >summaryheaders.expect <<EOF
= tiebreak =============================================================
11   | 1970-01-02T00:10:00Z | trunk
Author: Eric Sunshine <sunshine@sunshineco.com> 2017-11-21T02:37:42Z
Committer: Roy G. Biv <spectrum@color.com> 2017-11-21T01:45:15Z

eleventh
------------------------------------------------------------------------
10   | 1970-01-02T00:09:00Z | trunk
Author: Eric Sunshine <sunshine@sunshineco.com> 2017-11-21T02:30:40Z
Committer: Roy G. Biv <spectrum@color.com> 2017-11-21T01:45:15Z

tenth
------------------------------------------------------------------------
EOF

    $src $TESTOPTS log -v -2 tiebreak >summaryheaders.actual
    diff summaryheaders.expect summaryheaders.actual
    check "log -v shows summarized headers"

    cat >authordate.expect <<EOF
= tiebreak =============================================================
11    * 2017-11-21T02:37:42Z eleventh
10    - 2017-11-21T02:30:40Z tenth
= tiebreak =============================================================
11   | 2017-11-21T02:37:42Z | trunk
eleventh
------------------------------------------------------------------------
10   | 2017-11-21T02:30:40Z | trunk
tenth
------------------------------------------------------------------------
EOF

    $src ${TESTOPTS#-T} list -2 tiebreak >authordate.actual
    $src ${TESTOPTS#-T} log -2 tiebreak >>authordate.actual
    diff authordate.expect authordate.actual
    check "author date from RFC 822 header"

    cat >rfc822export.expect <<EOF
author Eric Sunshine <sunshine@sunshineco.com> 1509732768 -0500
committer Roy G. Biv <spectrum@color.com> 1511228715 +0000
EOF

    $src ${TESTOPTS#-T} fast-export 1 tiebreak |
	grep -E 'author|committer' >rfc822export.actual
    diff rfc822export.expect rfc822export.actual
    check "fast-export: consult RFC 822 headers"
fi

# Now for the srcify test
rm -fr .src RCS SCCS
    cat >srcifyfile <<EOF
Today is not that day.
EOF
historify srcifyfile
if [ "$backend" = "rcs" ]
then
    mkdir RCS && rcs -q -U -kb -i srcifyfile </dev/null
else
    mkdir SCCS && sccs admin -fb -i srcifyfile -y"Sample commit" <srcifyfile 2>/dev/null
fi
$src $TESTOPTS srcify && ls $history >/dev/null && ls srcifyfile >/dev/null
check "srcify command"

echo "srctest ($python $backend): all tests succeeded"

rm -fr $SANDBOX

# end
