import sys
from numpy.testing import *
import numpy as np

types = [np.bool_, np.byte, np.ubyte, np.short, np.ushort, np.intc, np.uintc,
         np.int_, np.uint, np.longlong, np.ulonglong,
         np.single, np.double, np.longdouble, np.csingle,
         np.cdouble, np.clongdouble]

# This compares scalarmath against ufuncs.

class TestTypes(TestCase):
    def test_types(self, level=1):
        for atype in types:
            a = atype(1)
            assert a == 1, "error with %r: got %r" % (atype,a)

    def test_type_add(self, level=1):
        # list of types
        for k, atype in enumerate(types):
            vala = atype(3)
            val1 = np.array([3],dtype=atype)
            for l, btype in enumerate(types):
                valb = btype(1)
                val2 = np.array([1],dtype=btype)
                val = vala + valb
                valo = val1 + val2
                assert val.dtype.num == valo.dtype.num and \
                       val.dtype.char == valo.dtype.char, \
                       "error with (%d,%d)" % (k,l)

    def test_type_subtract(self, level=1):
        # list of types
        for k, atype in enumerate(types):
            vala = atype(3)
            val1 = np.array([3],dtype=atype)
            for l, btype in enumerate(types):
                valb = btype(1)
                val2 = np.array([1],dtype=btype)
                val = vala - valb
                valo = val1 - val2
                assert val.dtype.num == valo.dtype.num and \
                       val.dtype.char == valo.dtype.char, \
                       "error with (%d,%d)" % (k,l)

    def test_type_multiply(self, level=1):
        # list of types
        for k, atype in enumerate(types):
            vala = atype(3)
            val1 = np.array([3],dtype=atype)
            for l, btype in enumerate(types):
                valb = btype(1)
                val2 = np.array([1],dtype=btype)
                val = vala * valb
                valo = val1 * val2
                assert val.dtype.num == valo.dtype.num and \
                       val.dtype.char == valo.dtype.char, \
                       "error with (%d,%d)" % (k,l)

    def test_type_divide(self, level=1):
        # Choose more interesting operands for this operation.
        # list of types
        for k, atype in enumerate(types):
            vala = atype(6)
            val1 = np.array([6],dtype=atype)
            for l, btype in enumerate(types):
                valb = btype(2)
                val2 = np.array([2],dtype=btype)
                val = vala / valb
                valo = val1 / val2
                assert val.dtype.num == valo.dtype.num and \
                       val.dtype.char == valo.dtype.char, \
                       "error with (%d,%d)" % (k,l)

    def test_type_remainder(self, level=1):
        # Choose more interesting operands for this operation.
        # list of types
        for k, atype in enumerate(types):
            vala = atype(6)
            val1 = np.array([6],dtype=atype)
            for l, btype in enumerate(types):
                valb = btype(2)
                val2 = np.array([2],dtype=btype)

                try:
                    val = vala % valb
                    valo = val1 % val2
                except TypeError, e:
                    # Some combos just don't work, like byte % complex.  We
                    # just don't worry about classifying the cases here, and
                    # instead just ignore these types of problems.  <grin>
                    pass

                assert val.dtype.num == valo.dtype.num and \
                       val.dtype.char == valo.dtype.char, \
                       "error with (%d,%d)" % (k,l)

    def test_type_negative(self, level=1):
        # Uhh, "negate" ???  Or maybe "unary minus".

        # But shouldn't this fail for unsigned types?  Hmmm...

        # list of types
        # NOTE: unary operators don't require the double loop over types,
        # since there's only one operand.
        for k, atype in enumerate(types):
            vala = atype(3)
            val1 = np.array([3],dtype=atype)

            val = -vala
            valo = -val1

            assert val.dtype.num == valo.dtype.num and \
                   val.dtype.char == valo.dtype.char, \
                   "error with (%d)" % (k)

    def test_type_positive(self, level=1):
        # Otherwise known as "unary plus".
        # list of types
        # NOTE: unary operators don't require the double loop over types,
        # since there's only one operand.
        for k, atype in enumerate(types):
            vala = atype(3)
            val1 = np.array([3],dtype=atype)

            val = +vala