# Part of the A-A-P recipe executive: unit-Testing 

# Copyright (C) 2002-2003 Stichting NLnet Labs
# Permission to copy and use this file is specified in the file COPYING.
# If this file is missing you can find it here: http://www.a-a-p.org/COPYING

import sys
import string

# Although the docs say Python looks in the current dir for modules, it needs
# to be told explicitly.
sys.path.insert(0, ".")

import Process
from Process import assert_var_name
from Error import *
from Util import *

# Setup Internationalisation (defines _())
i18n_init()

try:
    import unittest
except ImportError:
    print "--------------------------"
    print "Could not import the unittest module.\n"

    while 1:
        r = raw_input('Do you want to download the unittest module now?\n'
                "y: Yes      (requires an internet connection)\n"
                "c: Continue (install it yourself first)\n"
                "n: No       (abort testing)\n"
                "Choice: ")
        if r:
            if r[0] == "y" or r[0] == 'Y':
                from CopyMove import remote_copy_move

                # Obtain unittest.py from the A-A-P web server.
                failed = remote_copy_move([], {}, 1, 
                    [{"name" : "http://www.a-a-p.org/packages/unittest.py"}],
                    {"name" : "unittest.py"},
                                    {}, 0, errmsg = 1)
                if failed:
                    print "Sorry, downloading unittest.py didn't work"
                    sys.exit(1)
                break
            if r[0] == "c" or r[0] == 'C':
                break
            if r[0] == "n" or r[0] == 'N':
                sys.exit(1)
        continue

    import unittest


# Test assert_var_name()

class Grabwrite:
    def __init__(self):
	self.file = sys.stdout
	self.written = ''
    def write(self, arg):
	self.written = self.written + arg
    def __getattr__(self, attr):
	return getattr(self.file, attr)

class varnameTestCase(unittest.TestCase):
    def testLegalVarnames(self):
        for name in ["foo", "_f19_AZ_", "1234", "a",
            "this_is_a_long_name"+2000*"x"]:
            assert_var_name([], name)

    def testIllegalVarnames(self):
        for name in ["foo#", "-f19", ",ddd" ]:
            # assert that calling "assert_var_name" with params ([], name) 
            # will cause an UserError:
            self.assertRaises(UserError, assert_var_name, [], name)


class utilTestCase(unittest.TestCase):
    def testIsWhite(self):
        for str in [" ", "\t"]:
            self.failUnless(is_white(str), 
                    msg = "str '%s' should be detected as whitespace" % str)
        for str in ["f", "\n", "_", "", ]:
            self.failIf(is_white(str), 
                    msg = "str '%s' should not be detected as whitespace" % str)
    def testSkipWhite(self):
        for str, start, ret in [ ("  x", 0, 2), (" xx", 1, 1), (" x", 2, 2),
                    ("89 \t4", 2, 4), ("  _  ", 2, 2), ("", 0, 0)]:
            n = skip_white(str, start)
            self.failUnlessEqual(n, ret, 
                    msg = "skip_white(%s, %d) returned %d instead of %d" % (str, start, n, ret))

    def testSkipToWhite(self):
        for str, start, ret in [ ("xx  ", 0, 2), ("x x", 1, 1), (" x", 2, 2),
                    ("89\t 4", 0, 2), (" a__  ", 1, 4), ("", 0, 0)]:
            n = skip_to_white(str, start)
            self.failUnlessEqual(n, ret, 
                    msg = "skip_to_white(%s, %d) returned %d instead of %d"
                                    % (str, start, n, ret))

    def testGetToken(self):
        for str, start, rets, reti in [
            ("xx  ", 0, "xx", 2),
            ("x x", 1, " ", 2),
            (" \t x", 0, " \t ", 3),
            (" 'as df' ", 1, "'as df'", 8),
            ("'a s'\"d f\" ' ", 0, "'a s'\"d f\"", 10),
            ("x \"a\ts\"\t'd'", 2, "\"a\ts\"", 7),
            ]:
            s, i = get_token(str, start)
            self.failIf(s != rets or i != reti, 
                    msg = "get_token('%s', %d) returned '%s', %d instead of '%s', %d"
                            % (str, start, s, i, rets, reti))

    def testCheckExists(self):
        self.assertRaises(UserError, check_exists, [], "test.aap")
        check_exists([], "notatest.aax")

    def testVarchar(self):
        for c, res in [('a', 1), ('z', 1), ('0', 1), ('9', 1), ('_', 1), ('A', 1),
                ('Z', 1), ('-', 0), ('+', 0), ('@', 0), ('\t', 0), (' ', 0),
                ('&', 0), ('$', 0), ('\033', 0), ('\n', 0)]:
            self.failUnlessEqual(varchar(c), res,
                    msg = "varchar(%s) returned %d instead of %d" % (c, varchar(c), res))

    def testUnquote(self):
        for inp, res, m in [('a b c', 'a b c', ''),
                ('a "b" c', 'a b c', ''),
                ("a 'b' c", 'a b c', ''),
                ("a '\"b' c", 'a "b c', ''),
                ('"a \'b\' c"', "a 'b' c", ''),
                ('"a \'b"\' c"', "a 'b c\"", 'Missing quote'),
                ]:
            grab = Grabwrite()
            sys.stdout = grab
            got = unquote(globals(), inp)
            sys.stdout = grab.file
            self.failUnlessEqual(got, res, 
                    msg = "unquote(%s) returned =%s= instead of =%s=" % (inp, got, res))
            # Only compare empty vs non-empty, translations get in the way.
            self.failIf((grab.written != '') != (m!= ''),
                    msg = 'unquote(%s) gave message "%s" instead of "%s"'
                                    % (inp, grab.written, m))
        
    def testShortenName(self):
        cwd = os.getcwd()
        os_sep_save = os.sep
        os.sep = "/"
        for name, dir, res in [
                    ("/foo/bar", "/foo", "bar"),
                    ("/foo/bar", "/foo/bar", "../bar"),
                    ("/foo/burp/bar", "/foo/bar", "../burp/bar"),
                    (cwd, cwd, ""),
                    (cwd, cwd + "/foo", ".."),
                    ("/foo/bar", "/foo/bar/burp", "../../bar"),
                ]:
            got = shorten_name(name, dir)
            self.failUnlessEqual(got, res,
                    msg = "shorten_name(%s, %s) returned =%s= instead of =%s=" % (name, dir, got, res))
        os.sep = os_sep_save


class RecPythonTestCase(unittest.TestCase):
     def testSufreplace(self):
         from RecPython import sufreplace
         # these calls should work
         for suffrom, sufto, var, expected in [
                 (".x", ".y", "huhu.x", "huhu.y"),
                 (".cpp", ".o", "huhu.cpp", "huhu.o"),
                 ("", ".foo", "huhu huhu.cpp", "huhu huhu.foo"),
                 (None, ".foo", "huhu huhu.cpp huhu.x/huhu huhu.x/huhu.x", "huhu.foo huhu.foo huhu.x/huhu.foo huhu.x/huhu.foo"),
                 (".c", ".o", "huhu.c/spp.k", "huhu.c/spp.k"),
                 (".c", ".o", "huhu.c  ba.x foo.c bar.k", "huhu.o ba.x foo.o bar.k"),
                 (".c", ".o", "huhu.c", "huhu.o"),
                 (".123456789", ".Z", "huhu.123456789", "huhu.Z"),
                 ]:
             result = sufreplace(suffrom, sufto, var)
             self.failUnlessEqual(result, expected,
                     msg = ("sufreplace('%s', '%s', '%s') = '%s' != '%s'"
                                    % (suffrom, sufto, var, result, expected)))

         # these calls should raise
         for suffrom, sufto, var in [
                 ("x", "y", "huhu"),       # first arg doesn't start with dot
                 (".(?)", ".y", "huhu.x")  # invalid regexp
                 ]:
             # print 'Calling sufreplace("%s", "%s", "%s")' % (suffrom, sufto, var)
             self.assertRaises(UserError, sufreplace, suffrom, sufto, var)

     def testSufadd(self):
         from RecPython import sufadd
         # these calls should work
         for suf, var, all, expected in [
                 (".y", "huhu.x", None, "huhu.x"),
                 (".y", "huhu.x", 0, "huhu.x"),
                 (".y", "huhu.x", 1, "huhu.x.y"),
                 (".foo", "huhu huhu.x/asdf asdf.xx", None,
                                           "huhu.foo huhu.x/asdf.foo asdf.xx"),
                 (".foo", "huhu huhu.x/asdf asdf.xx", 0,
                                           "huhu.foo huhu.x/asdf.foo asdf.xx"),
                 (".foo", "huhu huhu.x/asdf asdf.xx", 9,
                                       "huhu.foo huhu.x/asdf.foo asdf.xx.foo"),
                 ]:
             if all == None:
                 result = sufadd(suf, var)
                 allstr = ''
             else:
                 result = sufadd(suf, var, all)
                 allstr = ", '%s'" % all
             self.failUnlessEqual(result, expected,
                     msg = ("sufall('%s', '%s'%s) = '%s' != '%s'"
                                    % (suf, var, allstr, result, expected)))

         # these calls should raise
         for suf, var, all in [
                 ("x", "huhu", 1),       # first arg doesn't start with dot
                 ("", "huhu", 0),        # first arg is empty
                 ]:
             # print 'Calling sufadd("%s", "%s", "%s")' % (suffrom, sufto, var)
             self.assertRaises(UserError, sufadd, suf, var, all)



if __name__ == "__main__":
    unittest.main()

# vim: set sw=4 et sts=4 tw=79 fo+=l:
