from __future__ import nested_scopes

import unittest
import sys
sys.path.insert(1, "..")
from rpy import *

class ModeConversionTestCase(unittest.TestCase):
    def setUp(self):
        set_default_mode(NO_DEFAULT)
        
    def testAs_pyArgs(self):
        self.failUnlessRaises(ValueError, lambda: r.seq.as_py(4))
        self.failUnlessRaises(ValueError, lambda: r.seq.as_py(-2))
        self.failUnlessRaises(TypeError, lambda: r.seq.as_py('foo'))
        
    def testAs_py(self):
        try:
            r.c.autoconvert(NO_CONVERSION)
            a = r.c(4)
            self.failUnless(a.as_py() == 4)
            self.failUnless(a.as_py(PROC_CONVERSION) == 4)
            self.failUnless(a.as_py(BASIC_CONVERSION) == 4)
            self.failUnless(r['=='](a.as_py(NO_CONVERSION), a))
        finally:
            r.c.autoconvert(PROC_CONVERSION)

    def testAs_pyDefaultArg(self):
        set_default_mode(NO_CONVERSION)
        a = r.seq(1,3)
        b = r.t_test([1,2,3])
        self.failUnless(type(a.as_py()) == type(a))
        set_default_mode(BASIC_CONVERSION)
        self.failUnless(a.as_py() == [1,2,3])
        class_table['htest'] = lambda o: 5
        set_default_mode(PROC_CONVERSION)
        self.failUnless(b.as_py() == 5)
        set_default_mode(NO_DEFAULT)
        
    def testDefaultModes(self):
        set_default_mode(PROC_CONVERSION)
        self.failUnless(get_default_mode() == PROC_CONVERSION)
        set_default_mode(CLASS_CONVERSION)
        self.failUnless(get_default_mode() == CLASS_CONVERSION)
        set_default_mode(BASIC_CONVERSION)
        self.failUnless(get_default_mode() == BASIC_CONVERSION)
        set_default_mode(NO_CONVERSION)
        self.failUnless(get_default_mode() == NO_CONVERSION)
        set_default_mode(NO_DEFAULT)
        self.failUnless(get_default_mode() == NO_DEFAULT)

    def testBadModes(self):
        self.failUnlessRaises(ValueError, lambda: set_default_mode(-2))
        self.failUnlessRaises(ValueError, lambda: set_default_mode(4))
        
    def testNoDefaultMode(self):
        set_default_mode(NO_DEFAULT)
        r.t_test.autoconvert(CLASS_CONVERSION)
        r.array.autoconvert(NO_CONVERSION)
        r.seq.autoconvert(BASIC_CONVERSION)
        self.failUnless(type(r.array(1,3)) == type(r.array))
        self.failUnless(r.seq(1,3) == [1,2,3])
        class_table['htest'] = lambda o: 5
        self.failUnless(r.t_test([1,2,3]) == 5)

    def testIndividualConversions(self):
        set_default_mode(NO_CONVERSION)
        r.c.autoconvert(BASIC_CONVERSION)
        r.seq.autoconvert(PROC_CONVERSION)
        self.failUnless(type(r.c(4)) == type(r.c))
        self.failUnless(type(r.seq(1,3)) == type(r.seq))
        set_default_mode(NO_DEFAULT)
        self.failUnless(r.c.autoconvert() == BASIC_CONVERSION)
        self.failUnless(r.seq.autoconvert() == PROC_CONVERSION)

    def testClassTable(self):
        def f(o):
            if len(r['[['](o, 1)) > 2:
                return 5
            else:
                return 'bar'
        class_table.clear()
        class_table['htest'] = lambda o: 'htest'
        class_table['data.frame'] = f
        set_default_mode(CLASS_CONVERSION)
        self.failUnless(r.t_test([1,2,3]) == 'htest')
        self.failUnless(r.as_data_frame([1,2,3]) == 5)
        self.failUnless(r.as_data_frame([1,2]) == 'bar')
        set_default_mode(NO_DEFAULT)

    def testMultipleClassTable(self):
        set_default_mode(NO_CONVERSION)
        f = r.class__(r.c(4), 'foo')
        g = r.class__(r.c(4), ('bar', 'foo'))
        class_table['foo'] = lambda o: 'foo'
        class_table['bar'] = lambda o: 'bar'
        class_table[('bar', 'foo')] = lambda o: 5
        set_default_mode(CLASS_CONVERSION)
        self.failUnless(f.as_py() == 'foo')
        self.failUnless(g.as_py() == 5)
        del class_table[('bar','foo')]
        self.failUnless(g.as_py() == 'bar')
        del class_table['bar']
        self.failUnless(g.as_py() == 'foo')
        set_default_mode(NO_DEFAULT)
        class_table.clear()
        proc_table.clear()
        
    def testProcTable(self):
        def f(o):
            return r['$'](o, 'alternative')
        def t(o):
            e = r.attr(o, 'names')
            if e =='alternative' or \
               (type(e)==type([]) and 'alternative' in e):
                return 1
            return 0
        proc_table.clear()
        class_table.clear()
        proc_table[t] = f
        set_default_mode(NO_DEFAULT)
        r.t_test.autoconvert(PROC_CONVERSION)
        self.failUnless(r.t_test([1,2,3]) == 'two.sided')
        proc_table.clear()
        class_table.clear()

    
def main():
    unittest.main(__name__)
    
if __name__ == '__main__':
    main()


syntax highlighted by Code2HTML, v. 0.9.1