
#Originally submitted by Erik Kruus <kruus.erik@uqam.ca>

import os, sys
from Ods.System import test_util
from Ft.Ods.MetaData import Expression
from Ft.Ods.MetaData import ConstOperand
from Ft.Ods import Database

Test_odl_string = '''
module Test {
const string TEST="test";
const long xlong = 6;
const long xneg = -6;
const long xmul0 = 6*2+3;
const long xmul1 = 6*(2+3);
const long xmul2 = -6*-2;
const long xdiv  = 6/2;
const long xmod  = 7%3;
const long xadd1 = 6+2;
const long xadd2 = 6+2*3;
const long xadd3 = 2*3+6;
const long xshi1 = 4<<1;
const long xshi2 = 4>>1;
const long xshi3 = 1+2<<2*2;
const long xand  = 7&5;
const long xxor  = 7^1;
const long xor   = 64|1;
const long xneg1 = ~0;
};'''


DBNAME=os.environ.get("ODS_TEST_DB","ods:test")

def Test(tester):
    try:
        _Test(tester)
    finally:
        if os.path.exists('Test'):
            from distutils import dir_util
            dir_util.remove_tree('Test')

def _Test(tester):

    tester.startGroup("borrowed ek_2001-05-30")
    test_util.DbInit(DBNAME,Test_odl_string)

    tester.startTest('Testing Generated syntax')
    try:
        import Test
        reload(Test)
    except:
        tester.error('Error in syntax', 1)


    tester.testDone()

    
    db = Database.Database()
    db.open(DBNAME)
    try:
        tx = db.new()
        tx.begin()
        tester.startTest("Test Generated Expression Object")
        
        t=db.schema().resolve("ODLMetaObjects::Test::TEST")
        tester.compare('const string TEST = "test"',t._4ods_getOdl(''))
        x=db.schema().resolve("ODLMetaObjects::Test::xdiv")
        tester.compare('long',x.type._4ods_getOdl(''))
        tester.compare('xdiv',x.name)
        tester.compare(3,x.value())
        tester.compare('/',x.the_Value.operator)
        tester.compare('6',x.the_Value.the_operands[0]._4ods_getOdl(''))
        tester.compare('2',x.the_Value.the_operands[1]._4ods_getOdl(''))
        tester.compare('6 / 2',x.the_Value._4ods_getOdl(''))
        tester.compare('const long xdiv = 6 / 2',x._4ods_getOdl(''))
        m=db.schema().resolve("ODLMetaObjects::Test")
        tester.compare(expected_1,m._4ods_getOdl(''),diff=1)
        tester.testDone()

        tester.startTest("more hefty tests")
        for name,value,odl in [('xlong',6,'const long xlong = 6'),
                               ('xneg',-6,'const long xneg = -6'),
                               ('xmul0',15,'const long xmul0 = 6 * 2 + 3'),
                               ('xmul1',30,'const long xmul1 = 6 * ( 2 + 3 )'),
                               ('xmul2',12,'const long xmul2 = -6 * -2'),
                               ('xdiv',3,'const long xdiv = 6 / 2'),
                               ('xmod',1,'const long xmod = 7 % 3'),
                               ('xadd1',8,'const long xadd1 = 6 + 2'),
                               ('xadd2',12,'const long xadd2 = 6 + 2 * 3'),
                               ('xadd3',12,'const long xadd3 = 2 * 3 + 6'),
                               ('xshi1',8,'const long xshi1 = 4 << 1'),
                               ('xshi2',2,'const long xshi2 = 4 >> 1'),
                               ('xshi3',48,'const long xshi3 = 1 + 2 << 2 * 2'),
                               ('xand',5,'const long xand = 7 & 5'),
                               ('xxor',6,'const long xxor = 7 ^ 1'),
                               ('xor',65,'const long xor = 64 | 1'),
                               ('xneg1',-1,'const long xneg1 = ~0')
                               ]:


            tester.startTest(odl)
            so = db.schema().resolve("ODLMetaObjects::Test::"+name)
            tester.compare(name,so.name)
            tester.compare(value,so.value())
            tester.compare(odl,so._4ods_getOdl(''))
            tester.testDone()

        tester.testDone()


        tester.startTest("Build from hand")

        ex = Expression.Expression(db,None)
        ex.__dict__['operator'] = "-"
        exco = ConstOperand.ConstOperand(db,None)
        exco.form_references(db.schema().resolve("ODLMetaObjects::Test::xlong"))
        ex.add_the_operands(exco)
        tester.compare(1,len(ex.the_operands))
        tester.compare('-',ex.operator)
        tester.compare(6,ex.the_operands[0].value())
        tester.compare(-6,ex.value())
        tx.abort()
    finally:
        db.close()

    tester.testDone()
    tester.groupDone()

expected_1="""module Test {
  const string TEST = "test";
  const long xlong = 6;
  const long xneg = -6;
  const long xmul0 = 6 * 2 + 3;
  const long xmul1 = 6 * ( 2 + 3 );
  const long xmul2 = -6 * -2;
  const long xdiv = 6 / 2;
  const long xmod = 7 % 3;
  const long xadd1 = 6 + 2;
  const long xadd2 = 6 + 2 * 3;
  const long xadd3 = 2 * 3 + 6;
  const long xshi1 = 4 << 1;
  const long xshi2 = 4 >> 1;
  const long xshi3 = 1 + 2 << 2 * 2;
  const long xand = 7 & 5;
  const long xxor = 7 ^ 1;
  const long xor = 64 | 1;
  const long xneg1 = ~0;
};
"""

