# coding=utf-8

from nose.tools import eq_, ok_
from collections import OrderedDict


class DataTestCase(object):
    def __init__(self, case):
        self._case = case
        self._id = self._case['id']
        self.caseSetup()

    def caseSetup(self):
        pass

    def checkPointValue(self, point):
        testLabel = '###%s#%s' % (point, self._id)
        expected = self._case[point]
        method = getattr(self, '_'+point)
        actual = method()
        print '    %s Expected:%s Actual:%s' % (testLabel,expected,actual)
        eq_(expected, actual, testLabel)

    def points(self):
        return []

    def checkAllPointValues(self):
        for point in self.points():
            self.checkPointValue(point)



class DataTestSuite(object):
    dataClass = None

    def test_generator(self):
        cases = self.getCases()
        for case in cases:
            print 'Creating %s(%s,...)' % (self.dataClass.__name__, id)
            dataTestCase = self.dataClass(case)
            fun = lambda: dataTestCase.checkAllPointValues()
            yield fun

    def getCases(self):
        if hasattr(self,'cases'):
            return self.cases
        else:
            return []



@@ -79,16 +79,17 @@
 dDict%0A%0A%0A
+%0A
 class Da
@@ -138,16 +138,38 @@
  case):%0A
+        self._ = None%0A
         
@@ -246,16 +246,152 @@
 eSetup()
+%0A        if self._ is None:%0A            raise NotImplementedError(%0A                'Subclasses of DataTestCase must set _ in caseSetup')
 %0A%0A    de
@@ -508,24 +508,67 @@
 , self._id)%0A
+        actual = self.evaluatePoint(point)%0A
         expe
@@ -583,20 +583,26 @@
 elf.
-_case%5B
+getExpected(
 point
-%5D
+)
 %0A   
@@ -610,40 +610,94 @@
     
-method = getattr(s
+if expected == 'XXX':%0A            print '    DEF   %25s: found %25s ' %25 (testLab
 el
-f
 , 
-'_'+point
+actual
 )%0A  
@@ -706,48 +706,217 @@
     
-actual = method()%0A        print '    %25s 
+else:%0A            if expected == actual:%0A                print '    OK    %25s: same %25s ' %25 (testLabel,expected)%0A            else:%0A                print '    ERROR %25s:' %25 testLabel%0A                print ' '*10+'
 Expe
@@ -924,133 +924,1291 @@
 ted:
+ 
 %25s
- 
+' %25 expected%0A                print ' '*10+'
 Actual:
+   
 %25s' %25 
-(testLabel,expected,actual)%0A        eq_(expected, actual, testLabel)%0A%0A    def points(self):%0A        return %5B%5D
+actual%0A            eq_(expected, actual, testLabel)%0A%0A    def getExpected(self, point):%0A        if ((point not in self._case or self._case%5Bpoint%5D == 'XXX')%0A            or ('XXX'in self._case)):%0A            return 'XXX'%0A        else:%0A            return self._case%5Bpoint%5D%0A%0A    def evaluatePoint(self, point):%0A        # (1) try to see if there is a method with the name _point on the%0A        # data class%0A        if hasattr(self, '_' + point):%0A            method = getattr(self, '_' + point)%0A            if method.im_self is not None:%0A                actual = method()%0A                return actual%0A        # (2) check to see if there is something with this name on the%0A        # object _%0A        if hasattr(self._, point):%0A            value = getattr(self._, point)%0A            if hasattr(value,'im_self') and value.im_self is not None:%0A                # This is a method, call it%0A                return value()%0A            else:%0A                # This is most probably not a method but an attribute%0A                return value%0A        raise Exception('ERROR IN TEST: No value on _ for field %25s' %25 point)%0A%0A    def points(self):%0A        raise NotImplementedError(%0A            'DataTestCase subclass must implement points()')
 %0A%0A  
@@ -2352,25 +2352,24 @@
 t):%0A    
-dataClass
+DataTest
  = None%0A
@@ -2490,50 +2490,37 @@
 ing 
-%25s(%25s,...)' %25 (self.dataClass.__name__, id
+DataTest(%22%25s%22)' %25 (case%5B'id'%5D
 )%0A  
@@ -2553,17 +2553,16 @@
 elf.
-dataClass
+DataTest
 (cas

improve output, definition of point are now optional