use utf8;
use Test::More;

sub ord_string {    # Convert packed ords to printable string
    use charnames ();
    return "'" . join("", map { '\N{' . charnames::viacode($_) . '}' }
                                                unpack "U*", shift) .  "'";
    #return "'" . join(" ", map { sprintf "%04X", $_ } unpack "U*", shift) .  "'";
}

sub Test_N {
    my ($source, $nfc, $nfd, $nfkc, $nfkd) = @_;
    my $display_source = ord_string($source);
    my $display_nfc = ord_string($nfc);
    my $display_nfd = ord_string($nfd);
    my $display_nfkc = ord_string($nfkc);
    my $display_nfkd = ord_string($nfkd);

    use Unicode::Normalize;
    #    NFC
    #      nfc ==  toNFC(source) ==  toNFC(nfc) ==  toNFC(nfd)
    #      nfkc ==  toNFC(nfkc) ==  toNFC(nfkd)
    #
    #    NFD
    #      nfd ==  toNFD(source) ==  toNFD(nfc) ==  toNFD(nfd)
    #      nfkd ==  toNFD(nfkc) ==  toNFD(nfkd)
    #
    #    NFKC
    #      nfkc == toNFKC(source) == toNFKC(nfc) == toNFKC(nfd) ==
    #      toNFKC(nfkc) == toNFKC(nfkd)
    #
    #    NFKD
    #      nfkd == toNFKD(source) == toNFKD(nfc) == toNFKD(nfd) ==
    #      toNFKD(nfkc) == toNFKD(nfkd)

    is(NFC($source), $nfc, "NFC($display_source) eq $display_nfc");
    is(NFC($nfc), $nfc, "NFC($display_nfc) eq $display_nfc");
    is(NFC($nfd), $nfc, "NFC($display_nfd) eq $display_nfc");
    is(NFC($nfkc), $nfkc, "NFC($display_nfkc) eq $display_nfkc");
    is(NFC($nfkd), $nfkc, "NFC($display_nfkd) eq $display_nfkc");

    is(NFD($source), $nfd, "NFD($display_source) eq $display_nfd");
    is(NFD($nfc), $nfd, "NFD($display_nfc) eq $display_nfd");
    is(NFD($nfd), $nfd, "NFD($display_nfd) eq $display_nfd");
    is(NFD($nfkc), $nfkd, "NFD($display_nfkc) eq $display_nfkd");
    is(NFD($nfkd), $nfkd, "NFD($display_nfkd) eq $display_nfkd");

    is(NFKC($source), $nfkc, "NFKC($display_source) eq $display_nfkc");
    is(NFKC($nfc), $nfkc, "NFKC($display_nfc) eq $display_nfkc");
    is(NFKC($nfd), $nfkc, "NFKC($display_nfd) eq $display_nfkc");
    is(NFKC($nfkc), $nfkc, "NFKC($display_nfkc) eq $display_nfkc");
    is(NFKC($nfkd), $nfkc, "NFKC($display_nfkd) eq $display_nfkc");

    is(NFKD($source), $nfkd, "NFKD($display_source) eq $display_nfkd");
    is(NFKD($nfc), $nfkd, "NFKD($display_nfc) eq $display_nfkd");
    is(NFKD($nfd), $nfkd, "NFKD($display_nfd) eq $display_nfkd");
    is(NFKD($nfkc), $nfkd, "NFKD($display_nfkc) eq $display_nfkd");
    is(NFKD($nfkd), $nfkd, "NFKD($display_nfkd) eq $display_nfkd");
}
Test_N(q