#!/bin/bash
. ./Common

#
# Note: the hierarchy dump differs in some details from the input format.
# Its main purpose is to aid with debugging, not to produce a syntactically
# valid representation of the currently loaded hierarchy.
#

###############################################################################

tst "hierarchy: name rule" -dh <<EOF
Animal=* {
	Cat:	{ X=* };
	Dog:	{ Y=* };
};
EOF

expect <<EOF
Animal=* {
    Cat: { X=* }
    Dog: { Y=* }
}
EOF

#------------------------------------------------------------------------------

tst "hierarchy: name set rule" -dh <<EOF
<predation> = mouse<cat<dog;
p = <predation> {
	mouse:	{ X=* };
	cat:	{ Y=* };
	dog:	{ Z=* };
};
EOF

expect <<EOF
p=<predation> {
    mouse: { X=* }
    cat: { Y=* }
    dog: { Z=* }
}
EOF

#------------------------------------------------------------------------------

tst_fail "hierarchy: name set rule (invalid value)" <<EOF
<predation> = mouse<cat<dog;
p = <predation> {
	mouse:	{ X=* };
	cat:	{ Y=* };
	boat:	{ Z=* };
};
EOF

expect <<EOF
h:6: invalid value in selection
EOF

#------------------------------------------------------------------------------

tst "hierarchy: name set rule (duplicate entry)" -dh <<EOF
<predation> = mouse<cat<dog;
p = <predation> {
	mouse:	{ X=* };
	cat:	{ Y=* };
	cat:	{ Z=* };
};
EOF

expect <<EOF
h:6: warning: unreachable condition
p=<predation> {
    mouse: { X=* }
    cat: { Y=* }
    cat: { Z=* }
}
EOF

#------------------------------------------------------------------------------

tst "hierarchy: absolute value rule (with unit)" -dh <<EOF
<predation> = mouse<cat<dog;
N=#R {
	10R:	{ X=* };
	10k:	{ Y=* };
	1.2R:	{ Z=* };
};
EOF

expect <<EOF
N=#R {
    10R: { X=* }
    10000R: { Y=* }
    1.2R: { Z=* }
}
EOF

#------------------------------------------------------------------------------

tst "hierarchy: absolute value rule (without unit)" -dh <<EOF
<predation> = mouse<cat<dog;
N=## {
	2:	{ X=* };
	5k:	{ Y=* };
	3.1:	{ Z=* };
};
EOF

expect <<EOF
N=## {
    2: { X=* }
    5000: { Y=* }
    3.1: { Z=* }
}
EOF

#------------------------------------------------------------------------------

tst_fail "hierarchy: absolute value rule (different unit)" <<EOF
<predation> = mouse<cat<dog;
N=#R {
	1.0A:	{ X=* };
};
EOF

expect <<EOF
h:4: invalid value in selection
EOF

#------------------------------------------------------------------------------

tst_fail "hierarchy: absolute value rule (letter-as-decimal syntax)" <<EOF
<predation> = mouse<cat<dog;
N=#R {
	1k2:	{ X=* };
};
EOF

expect <<EOF
h:4: invalid value in selection
EOF

#------------------------------------------------------------------------------

tst "hierarchy: relative value rule (percent)" -dh <<EOF
{ V=#R }
TOL=%V {
	1%:	{ X=* };
	1.2%:	{ Y=* };
};
EOF

expect <<EOF
{ V=#R }
TOL=%R {
    -1/+1%: { X=* }
    -1.2/+1.2%: { Y=* }
}
EOF

#------------------------------------------------------------------------------

tst "hierarchy: relative value rule (absolute, with unit)" -dh <<EOF
{ V=#R }
TOL=%V {
	1R:	{ X=* };
	1kR:	{ Y=* };
};
EOF

expect <<EOF
{ V=#R }
TOL=%R {
    -1/+1R: { X=* }
    -1000/+1000R: { Y=* }
}
EOF

#------------------------------------------------------------------------------

tst "hierarchy: relative value rule (absolute, without unit)" -dh <<EOF
{ V=## }
TOL=%V {
	1:	{ X=* };
	1k:	{ Y=* };
};
EOF

expect <<EOF
{ V=## }
TOL=%# {
    -1/+1: { X=* }
    -1000/+1000: { Y=* }
}
EOF

#------------------------------------------------------------------------------

tst "hierarchy: relative value rule (plus/minus percent)" -dh <<EOF
{ V=#R }
TOL=%V {
	+10/-20%:	{ X=* };
};
EOF

expect <<EOF
{ V=#R }
TOL=%R {
    -20/+10%: { X=* }
}
EOF

#------------------------------------------------------------------------------

tst "hierarchy: relative value rule (minus/plus percent)" -dh <<EOF
{ V=#R }
TOL=%V {
	-10/+20%:	{ X=* };
};
EOF

expect <<EOF
{ V=#R }
TOL=%R {
    -10/+20%: { X=* }
}
EOF

#------------------------------------------------------------------------------

tst "hierarchy: relative value rule (implicit minus/plus percent)" -dh <<EOF
{ V=#R }
TOL=%V {
	10/20%:	{ X=* };
};
EOF

expect <<EOF
{ V=#R }
TOL=%R {
    -10/+20%: { X=* }
}
EOF

#------------------------------------------------------------------------------

tst "hierarchy: relative value rule (plus/minus absolute)" -dh <<EOF
{ V=#R }
TOL=%V {
	+10/-20R:	{ X=* };
};
EOF

expect <<EOF
{ V=#R }
TOL=%R {
    -20/+10R: { X=* }
}
EOF

#------------------------------------------------------------------------------

tst "hierarchy: relative value rule (minus/plus absolute)" -dh <<EOF
{ V=#R }
TOL=%V {
	-5/+10R:	{ X=* };
};
EOF

expect <<EOF
{ V=#R }
TOL=%R {
    -5/+10R: { X=* }
}
EOF

#------------------------------------------------------------------------------

tst "hierarchy: relative value rule (implicit minus/plus absolute)" -dh <<EOF
{ V=#R }
TOL=%V {
	0/10R:	{ X=* };
};
EOF

expect <<EOF
{ V=#R }
TOL=%R {
    -0/+10R: { X=* }
}
EOF

#------------------------------------------------------------------------------

tst_fail "hierarchy: relative value rule (unknown field)" <<EOF
{ V=#R }
TOL=%X {
	10%:	{ Y=* };
};
EOF

expect <<EOF
h:2: unknown field "X"
EOF

###############################################################################