from unittest import TestCase, TestSuite, main, makeSuite
from kjbuckets import kjSet

import inspect
import moppy.searchreplace as sr
import moppy.tests.testfixtures as tf
import moppy.tests.tstpkg1 as tstpkg1
import moppy.tests.tstpkg1.subpkg1.testtypes2 as tt2
import moppy.mop as mop

def times3(someNum):
    return someNum * 3
            
class ClassEquals(object):
    def __init__(self, cls):
        self.cls = cls
    def __call__(self, other):
        return self.cls == other

class Test(TestCase):
    
    
    def testFunctionTypes(self):
        assert(1 == sr.isClassMethod(tf.A.clsMeth))
        assert(0 == sr.isClassMethod(tf.A.instMeth))
        
    def testFindParent1(self):
        mod = sr.getmodule(tf.A)
        parent = sr.recurseGetParentObject(mod, tf.A.instMeth)
        self.assertEquals(parent, tf.A)

    def testFindParent2(self):
        mod = sr.getmodule(tt2.AllTypes2)
        parent = sr.recurseGetParentObject(mod, tt2.AllTypes2.instMeth)
        self.assertEquals(parent, tt2.AllTypes2)

    def testFindModule1(self):
        nameFilter = [sr.STD_IGNORE]
        mf = sr.ModuleNameFilter("moppy.tests.tstpkg1.subpkg1*")
        ctx = sr.SearchContext(nameFilter, [mf])
        rs = sr.recurseSelectMembers(tstpkg1, ctx)
        #assert(tstpkg1.subpkg1.testtypes2 in rs)
        #print "findModule1 rs: ",rs
        assert(tt2 in rs)
        assert(tt2.AllTypes2 in rs)
        assert(tf.A not in rs)

    def testFindObject1(self):
        nameFilter = [sr.STD_IGNORE]
        mf = sr.ModuleNameFilter("moppy.tests.tstpkg1.subpkg1*")
        of = sr.ObjectComparatorFilter(inspect.ismethod)
        ctx = sr.SearchContext(nameFilter, [mf,of])
        ctx.debugWalk = True
        rs = sr.recurseSelectMembers(tstpkg1, ctx)
        assert(tt2.AllTypes2.instMeth in rs)
        assert(tf.A not in rs)
        
    def testFindObject2(self):
        mf = sr.ModuleNameFilter("moppy.tests.tstpkg1.subpkg1*")
        of = sr.ObjectComparatorFilter(inspect.ismethod)
        nf = sr.ObjectNameFilter("instMe*")
        objectFilter = [mf,of]
        nameFilter = [sr.STD_IGNORE, nf]
        ctx = sr.SearchContext(nameFilter, objectFilter)
        rs = sr.recurseSelectMembers(tstpkg1, ctx)
        assert(tt2.AllTypes2.instMeth in rs)
        assert(tt2.AllTypes3.instMeth in rs)
        assert(len(rs) == 2)

    def testFindObject3(self):
        mf = sr.ModuleNameFilter("moppy.tests.tstpkg1.subpkg1*")
        of = sr.ObjectComparatorFilter(inspect.ismethod)
        cf = sr.ClassFilter(ClassEquals(tt2.AllTypes2))
        nf = sr.ObjectNameFilter("instMe*")
        objectFilter = [mf,of,cf]
        nameFilter = [sr.STD_IGNORE, nf]
        ctx = sr.SearchContext(nameFilter, objectFilter)
        rs = sr.recurseSelectMembers(tstpkg1, ctx)
        assert(tt2.AllTypes2.instMeth in rs)
        assert(len(rs) == 1)

    def testSelectionCriteria1(self):
        ctx = sr.SearchContext([],[])
        ctx.currentObj = tf.A
        ctx.currentName = "A"
        selection = mop.SelectionCriteria()
        selection.AND(sr.ClassNameCriteria("moppy.tests.testfixtures.A"))
        assert(selection.match(ctx))

    def testSelectionCriteria2(self):
        ctx = sr.SearchContext([],[])
        ctx.parentObj = tf.A
        ctx.parentName = "A"
        ctx.currentObj = tf.A.instMeth
        ctx.currentName = "instMeth"
        selection = mop.SelectionCriteria()
        selection.AND(sr.ClassMemberCriteria("moppy.tests.testfixtures.A"))
        assert(selection.match(ctx))

def testSuite():
    return makeSuite(Test)


if __name__=='__main__':
    main(defaultTest='testSuite')