from __future__ import nested_scopes

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

idx = r['[[']
idx.autoconvert(1)

def to_r(obj):
    r.list.autoconvert(0)
    idx.autoconvert(0)
    o = idx(r.list(obj),1)
    idx.autoconvert(1)
    return o

class ArrayTestCase(unittest.TestCase):

    def setUp(self):
        self.py = [[[0,6,12,18],[2,8,14,20],[4,10,16,22]],
                   [[1,7,13,19],[3,9,15,21],[5,11,17,23]]]
        set_default_mode(NO_DEFAULT)
        try:
            r.array.autoconvert(0)
            self.ra = r.array(range(24),dim=(2,3,4))
        finally:
            r.array.autoconvert(1)

    def testConversionToPy(self):
        self.failUnless(self.py == self.ra.as_py(),
                        'wrong conversion to Python')

    def testConversionToR(self):
        py_c = to_r(self.py)
        self.failUnless(r.all_equal(self.ra, py_c),
                        'R array not equal')
        
    def testDimensions(self):
        self.failUnless(r.dim(self.ra) == [len(self.py), len(self.py[0]),
                                           len(self.py[0][0])],
                        'wrong dimensions')

    def testElements(self):
        self.failUnless(self.py[0][0][0] == idx(self.ra, 1,1,1) and
                        self.py[1][2][3] == idx(self.ra, 2,3,4) and
                        self.py[1][1][2] == idx(self.ra, 2,2,3) and
                        self.py[1][0][3] == idx(self.ra, 2,1,4),
                        'Numeric array not equal')

    def testPyOutOfBounds(self):
        self.failUnlessRaises(IndexError, lambda: self.py[5][5][5])
                           
    def testROutOfBounds(self):
        self.failUnlessRaises(RException, lambda: idx(self.ra, 5,5,5))

    def testBigArray(self):
        a = r.array(range(100000), dim=(100,1000))
        self.failUnless(a[10][10] and a[80][900])
        
if __name__ == '__main__':
    unittest.main()
