#!/usr/bin/ruby

var hash = :(
              red    => 1, blue   => 2, green  => 3,
              orange => 4, yellow => 5, purple => 6,
              black  => 7, grey   => 8, white  => 9
            );

var array = <red blue green>;

#
## Array ~~ Hash
#
if (array ~~ hash) {
    say "some array elements in hash keys";
}
else {
    die "a ~~ h error";
}

#
## Any ~~ Array
#
if ("red" ~~ array) {
    say "red in array";
}
else {
    die "s ~~ a error";
}

#
## Regex ~~ Hash
#
if (/e$/ ~~ hash) {
    say "some keys end in e";
}
else {
    die "r ~~ h error";
}

#
## Hash ~~ Array
#

if (:(a => 1, b => 2) ~~ ["a", "b", "c"]) {
    say "all hash-keys contained in array";
}
else {
    die "h ~~ a error";
}

#
## Array ~~ Array
#
var arr1 = [3,2];
var arr2 = [3,2];

if (arr1 ~~ arr2) {
    say "equal arrays";
}
else {
    die "a ~~ a error";
}

arr1.append(0);
arr1 ~~ arr2 && die "a ~~ a error(2)";

#
## String ~~ String
#

if ("Xena" ~~ "Xena") {
    say "string 'Xena' equals 'Xena'";
}
else {
    die "s ~~ s error";
}

#
## Array ~~ Regex
#

var a = ['a', [[['z'],'foo','z']], 'c'];

unshift(a, a)

assert(a.match(/^a/))
assert(a.match(/^foo/))
assert(a.match(/^c/))
assert(!a.match(/^d/))

assert(a ~~ /^a/)
assert(a ~~ /^foo/)
assert(a ~~ /^c/)
assert(!(a ~~ /^d/))

assert(a ~~ /^a/)
assert(a ~~ /^foo/)
assert(a ~~ /^z/)
assert(a ~~ /^c/)
assert(!(a ~~ /^d/))

assert(/^a/ ~~ a)
assert(/^foo/ ~~ a)
assert(/^z/ ~~ a)
assert(/^c/ ~~ a)
assert(!(/^d/ ~~ a))

assert (Pair ~~ Pair)
assert (Pair().class ~~ Pair.class)
assert !(Pair.class ~~ "a")

assert !("Pair" ~~ Pair)
assert !(Pair ~~ "a")
assert !("a" ~~ Pair)
assert !(1 ~~ Pair)

assert ([1,2] ~~ Array)
assert (Array ~~ [1,2])

assert ("" ~~ String)
assert (// ~~ Regex)

assert (Pair(1,2) ~~ Array)         # Pair is a subclass of Array
assert !(Array ~~ Pair(1,2))        # Array is not a subclass of Pair

assert !(nil ~~ Array)
assert (Array ~~ Array)
assert !(Array() ~~ nil)

#
## Hash ~~ Regex
#

assert(:(a => 1, b => 2) ~~ /^b/)
assert(/^b/ ~~ :(a => 1, b => 2))

assert(!(:(a => 1, b => 2) ~~ /^c/))
assert(!(/^c/ ~~ :(a => 1, b => 2)))

#
## Pair ~~ Array
#

assert(Pair(1,2) ~~ [42, Pair(1,2), 99])
assert(1 ~~ Pair(1,2))
assert(2 ~~ Pair(1,2))
assert([1,2] ~~ Pair([1,2],42))

#
## nil
#

assert(nil ~~ [2,nil,3])
assert(nil !~ [2,3,4])
assert(nil ~~ nil)
assert(nil !~ "")
assert("" !~ nil)
assert([2,nil,3] ~~ nil)
assert(!([2,nil,4] !~ nil))
assert([2,3,4] !~ nil)
assert(!(nil ~~ 0))
assert(0 !~ nil)