#!/bin/sh
# Sets up the test tree.
#
# The way the test tree works is each object can have a t directory under
# it, that is itself a mooix object (but has no parent.lnk in the source
# tree). These test objects become the parents of the objects they are
# subdirectories of, and the object's parents become their parents. All the
# test_* methods are then run for each real object.
#
# Thus an object like concrete/container will have a parent of
# concrete/container/t, which will have a parent of concrete/thing, which
# will have a parent of concrete/thing/t. When the testing gets to
# concrete/container, it will run all the test_* methods of
# concrete/container/t and any inherited from concrete/thing/t.
#
# Sometimes tests need throwaway objects to manipulate. These are placed
# under the t/ directory, and are not tested. Note that if these objects
# need to be owned by the object running a test, their owner should point
# to "../..".
set -e

clean_tree () {
	TREE=$1

	# Put the parent links back and delete the test objects.
	for testobj in $(find $TREE -name t); do\
		if [ -L $testobj/../parent ]; then
			rm -f $testobj/../parent
		fi
		if [ -e $testobj/parent ]; then
			mv $testobj/parent $testobj/../parent
		fi
		rm -rf $testobj
	done
}

case $1 in
setup)
	SRC=$2
	DEST=$3

	if [ ! -d $DEST ]; then
		echo "$DEST does not exist!" >&2
		exit 1
	fi

	# Idempotency: delete any test objects currently in the tree and
	# put links back.
	clean_tree $DEST
	
	# Copy test objects into the tree.
	(cd $SRC && tar cf - $(find . -type d -name t) -X Excludes) | \
	(cd $DEST && tar xpf -)
	
	# Redirect parent symlinks to test objects.
	for testobj in $(find $DEST -type d -name t); do
		if [ -L $testobj/../parent ]; then
			# The links should already be absolute of course.
			mv $testobj/../parent $testobj/parent
		fi
		ln -s t $testobj/../parent
	done
	
	# Turn all symlinks absolute, as mooix requires.
	find $DEST -type l | \
	perl -MCwd=abs_path -e '
		while (<>) {
			chomp;
			my ($dir)=m/(.*)\//;
			chdir($dir) || die "chdir $dir $!";
			my $path=abs_path(readlink($_));
			next if $path eq readlink($_);
			unlink($_) || next;
			symlink($path, $_) || die "symlink $path $_ $!";
		}
	'
;;
clean)
	TREE=$2

	clean_tree $TREE
;;
*)
	echo "Usage: testtree [setup src treedir|teardown treedir]" >&2
	exit 1
;;
esac
