# -*- coding: iso-8859-1 -*-
from __future__ import division # 1/2 == .5 (par defaut, 1/2 == 0)

from customtest import *

import ALL, objet, tests_unitaires

class MetaTestGeolib(CustomTest):
    @property
    def classes(self):
        classes = set(key.rsplit(".")[-1] for key, value in ALL.__dict__.iteritems() if type(value) == type(ALL.Objet) and issubclass(value, ALL.Objet) and not key.endswith("_generique"))
        classes_de_base = set(key.rsplit(".")[-1] for key, value in objet.__dict__.iteritems() if type(value) == type(ALL.Objet) and issubclass(value, ALL.Objet))
        classes.difference_update(classes_de_base)
        return classes

    def test_toutes_classes(self):
        u"On vérifie que toutes les classes de geolib soient bien testées."
        classes = self.classes
        classes_testees = set()
        for key, value in tests_unitaires.__dict__.iteritems():
            if type(value) == type(tests_unitaires.CustomTest) and issubclass(value, tests_unitaires.CustomTest):
                for nom in value.__dict__.keys():
                    if nom.startswith("test_"):
                        classes_testees.add(nom[5:])


        classes.difference_update(classes_testees)

        classes.remove("Variable")

        if len(classes):
            print u"Certaines classes ne sont pas testées :"
            print classes

        classes.difference_update(set(['Widget', 'PointTangence', 'Bouton', 'Extremite', 'Cote', 'Sommet', 'Point_droite', 'Point_pondere', 'Champ', 'PrevisualisationPolygone','Variable_en_travaux']))
        # 'Variable_en_travaux' à enlever

        self.assert_(len(classes) == 0)

    def assert_heritage(self, classe, classe_parente):
        test = issubclass(classe, classe_parente)
        if not test:
            print u"ERREUR: la classe %s N'hérite PAS de %s" %(classe, classe_parente)
        self.assert_(test)

    def assert_not_heritage(self, classe, classe_parente):
        test = issubclass(classe, classe_parente)
        if test:
            print u"ERREUR: la classe %s hérite de %s" %(classe, classe_parente)
        self.assert_(not test)


    def test_heritages(self):
        u"""On vérifie que les objets ont une méthode '_get_coordonnees' ssi ils descendent de la classe 'Objet_avec_coordonnees'.

        De même, les objets ont une méthode '_get_equation' et '_get_val' ssi ils descendent respectivement des classes
        'Objet_avec_equation' et 'Objet_avec_valeur'."""

        for classe in  ALL.__dict__.itervalues():
            if isinstance(classe, type) and issubclass(classe, ALL.Objet):
#                print classe
                if hasattr(classe, "_get_equation"):
                    self.assert_heritage(classe, ALL.Objet_avec_equation)
##                    self.assert_("exact" in classe._get_equation.func_code.co_varnames)
                else:
                    self.assert_not_heritage(classe, ALL.Objet_avec_equation)
                if hasattr(classe, "_get_coordonnees"):
                    self.assert_heritage(classe, ALL.Objet_avec_coordonnees)
##                    self.assert_("exact" in classe._get_coordonnees.func_code.co_varnames)
                else:
                    self.assert_not_heritage(classe, ALL.Objet_avec_coordonnees)
                if hasattr(classe, "_get_valeur"):
                    self.assert_heritage(classe, ALL.Objet_avec_valeur)
##                    self.assert_("exact" in classe._get_valeur.func_code.co_varnames)
                else:
                    self.assert_not_heritage(classe, ALL.Objet_avec_valeur)

    def test_methode_image_par(self):
        noms = self.classes
        non_transformable = (ALL.Variable, ALL.Label_generique, ALL.Angle_libre, ALL.Angle_vectoriel, ALL.Point_pondere, ALL.Vecteur_libre, ALL.Vecteur_unitaire, ALL.Somme_vecteurs, ALL.Transformation_generique)
        non_transformable_actuellement = (ALL.Widget, ALL.Courbe, ALL.Interpolation_generique, ALL.Fonction, ALL.Texte)
        for classe in ALL.__dict__.itervalues():
            if isinstance(classe, type) and issubclass(classe, ALL.Objet) and classe.__name__.rsplit(".")[-1] in noms and not hasattr(classe, "image_par"):
                if not issubclass(classe, non_transformable) and not issubclass(classe, non_transformable_actuellement):
                    print "ATTENTION: " + str(classe) + " n'a pas d'attribut 'image_par' !"
                    self.assert_(hasattr(classe, "image_par"))



    def test_arguments(self):
        u"""On vérifie que l'attribut '.nom' des arguments correspondent bien à leur noms réels.

        Le nom doit être de la forme '_nomClasse__nomArgument'."""

        for classe in ALL.__dict__.itervalues():
            if isinstance(classe, type) and issubclass(classe, ALL.Objet):
                for key, value in vars(classe).iteritems():
                    if isinstance(value, ALL.BaseArgument) and key[0] == "_":
                        self.assert_(key == value.nom)


#    def test_presence_methodes(self):
#        attributs_ou_methodes_obligatoires = [
#                                 ]
#        for classe in ALL.__dict__.itervalues():
#            if isinstance(classe, type) and issubclass(classe, ALL.Objet):
#                for attr in attributs_ou_methodes_obligatoires:
#                    if not hasattr(classe, attr):
#                        print u"ERREUR: La classe %s doit posséder l'attribut ou la méthode '%s' !" %(classe, attr)
#                        self.assert_(hasattr(classe, attr))
