from sancho.unittest import TestScenario, parse_args, run_scenarios
from quixote import _py_htmltext

tested_modules = [ "quixote.html" ]

class Wrapper:
    def __init__ (self, s):
        self.s = s

    def __repr__ (self):
        return self.s

    def __str__ (self):
        return self.s

class Broken:
    def __str__(self):
        raise RuntimeError, 'eieee'

    def __repr__(self):
        raise RuntimeError, 'eieee'

markupchars = '<>&"'
quotedchars = '&lt;&gt;&amp;&quot;'

class HTMLTest (TestScenario):

    def setup (self):
        global htmltext, escape, htmlescape
        htmltext = _py_htmltext.htmltext
        escape = _py_htmltext._escape_string
        htmlescape = _py_htmltext.htmlescape

    def shutdown (self):
        pass


    def check_init (self):
        self.test_val("str(htmltext('foo'))", 'foo')
        self.test_val("str(htmltext(markupchars))", markupchars)
        self.test_val("str(htmltext(None))", 'None')
        self.test_val("str(htmltext(1))", '1')
        self.test_exc("htmltext(Broken())", RuntimeError)

    def check_escape (self):
        self.test_val("htmlescape(markupchars)", quotedchars)
        self.test_bool("isinstance(htmlescape(markupchars), htmltext)")
        self.test_val("escape(markupchars)", quotedchars)
        self.test_bool("isinstance(escape(markupchars), str)")
        self.test_val("htmlescape(htmlescape(markupchars))", quotedchars)
        self.test_exc("escape(1)", TypeError)

    def check_cmp (self):
        s = htmltext("foo")
        self.test_bool("s == 'foo'")
        self.test_bool("s != 'bar'")
        self.test_bool("s == htmltext('foo')")
        self.test_bool("s != htmltext('bar')")
        self.test_bool("htmltext('1') != 1")
        self.test_bool("1 != s")

    def check_len (self):
        self.test_val("len(htmltext('foo'))", 3)
        self.test_val("len(htmltext(markupchars))", len(markupchars))
        self.test_val("len(htmlescape(markupchars))", len(quotedchars))

    def check_hash (self):
        self.test_val("hash(htmltext('foo'))", hash('foo'))
        self.test_val("hash(htmltext(markupchars))", hash(markupchars))
        self.test_val("hash(htmlescape(markupchars))", hash(quotedchars))

    def check_concat (self):
        s = htmltext("foo")
        self.test_val("s + 'bar'", "foobar")
        self.test_val("'bar' + s", "barfoo")
        self.test_val("s + htmltext('bar')", "foobar")
        self.test_val("s + markupchars", "foo" + quotedchars)
        self.test_bool("isinstance(s + markupchars, htmltext)")
        self.test_val("markupchars + s", quotedchars + "foo")
        self.test_bool("isinstance(markupchars + s, htmltext)")
        self.test_exc("s + 1", TypeError)
        self.test_exc("1 + s", TypeError)

    def check_repeat (self):
        s = htmltext('a')
        self.test_val("s * 3", "aaa")
        self.test_bool("isinstance(s * 3, htmltext)")
        self.test_val("htmlescape(markupchars) * 3", quotedchars * 3)
        self.test_exc("s * 'a'", TypeError)
        self.test_exc("'a' * s", TypeError)
        self.test_exc("s * s", TypeError)

    def check_format (self):
        s_fmt = htmltext('%s')
        self.test_val("s_fmt % 'foo'", "foo")
        self.test_bool("isinstance(s_fmt % 'foo', htmltext)")
        self.test_val("s_fmt % markupchars", quotedchars)
        self.test_val("s_fmt % None", "None")
        self.test_val("htmltext('%r') % Wrapper(markupchars)", quotedchars)
        self.test_val("htmltext('%s%s') % ('foo', htmltext(markupchars))",
                      "foo" + markupchars)
        self.test_val("htmltext('%d') % 10", "10")
        self.test_val("htmltext('%.1f') % 10", "10.0")
        self.test_exc("s_fmt % Broken()", RuntimeError)
        self.test_exc("htmltext('%r') % Broken()", RuntimeError)
        self.test_exc("s_fmt % (1, 2)", TypeError)

    def check_dict_format (self):
        self.test_val("htmltext('%(a)s %(a)r %(b)s') % "
                      " {'a': 'foo&', 'b': htmltext('bar&')}",
                      "foo&amp; 'foo&amp;' bar&")
        self.test_val("htmltext('%(a)s') % {'a': 'foo&'}", "foo&amp;")
        self.test_bool("isinstance(htmltext('%(a)s') % {'a': 'a'}, htmltext)")
        self.test_val("htmltext('%s') % {'a': 'foo&'}", "{'a': 'foo&amp;'}")
        self.test_exc("htmltext('%(a)s') % 1", TypeError)
        self.test_exc("htmltext('%(a)s') % {}", KeyError)

    def check_join (self):
        self.test_val("htmltext(' ').join(['foo', 'bar'])", "foo bar")
        self.test_val("htmltext(' ').join(['foo', markupchars])",
                      "foo " + quotedchars)
        self.test_val("htmlescape(markupchars).join(['foo', 'bar'])",
                      "foo" + quotedchars + "bar")
        self.test_val("htmltext(' ').join([htmltext(markupchars), 'bar'])",
                      markupchars + " bar")
        self.test_bool("isinstance(htmltext('').join([]), htmltext)")
        self.test_exc("htmltext('').join(1)", TypeError)
        self.test_exc("htmltext('').join([1])", TypeError)

    def check_startswith (self):
        self.test_bool("htmltext('foo').startswith('fo')")
        self.test_bool("htmlescape(markupchars).startswith(markupchars[:3])")
        self.test_bool("htmltext(markupchars).startswith("
                       "  htmltext(markupchars[:3]))")
        self.test_exc("htmltext('').startswith(1)", TypeError)

    def check_endswith (self):
        self.test_bool("htmltext('foo').endswith('oo')")
        self.test_bool("htmlescape(markupchars).endswith(markupchars[-3:])")
        self.test_bool("htmltext(markupchars).endswith("
                       "  htmltext(markupchars[-3:]))")
        self.test_exc("htmltext('').endswith(1)", TypeError)

    def check_replace (self):
        self.test_val("htmlescape('&').replace('&', 'foo')", "foo")
        self.test_val("htmltext('&').replace(htmltext('&'), 'foo')", "foo")
        self.test_val("htmltext('foo').replace('foo', htmltext('&'))", "&")
        self.test_bool("isinstance(htmltext('a').replace('a', 'b'), htmltext)")
        self.test_exc("htmltext('').replace(1, 'a')", TypeError)

    def check_lower (self):
        self.test_val("htmltext('aB').lower()", "ab")
        self.test_bool("isinstance(htmltext('a').lower(), htmltext)")

    def check_upper (self):
        self.test_val("htmltext('aB').upper()", "AB")
        self.test_bool("isinstance(htmltext('a').upper(), htmltext)")

    def check_capitalize (self):
        self.test_val("htmltext('aB').capitalize()", "Ab")
        self.test_bool("isinstance(htmltext('a').capitalize(), htmltext)")


try:
    from quixote import _c_htmltext
except ImportError:
    _c_htmltext = None

if _c_htmltext:
    class CHTMLTest(HTMLTest):
        def setup (self):
            # using globals like this is a bit of a hack since it assumes
            # Sancho tests each class individually, oh well
            global htmltext, escape, htmlescape
            htmltext = _c_htmltext.htmltext
            escape = _c_htmltext._escape_string
            htmlescape = _c_htmltext.htmlescape

if __name__ == "__main__":
    (scenarios, options) = parse_args()
    run_scenarios (scenarios, options)
