]> SALOME platform Git repositories - modules/eficas.git/commitdiff
Salome HOME
CCAR: mise a niveau avec Aster stabilise : mecanique de validation et regles de sensi...
authorChristian Caremoli <>
Fri, 19 May 2006 15:22:52 +0000 (15:22 +0000)
committerChristian Caremoli <>
Fri, 19 May 2006 15:22:52 +0000 (15:22 +0000)
39 files changed:
Accas/A_FACT.py
Accas/A_SENSIBILITE.py [new file with mode: 0644]
Accas/A_VALIDATOR.py
Accas/__init__.py
Editeur/Objecttreeitem.py
Editeur/compomclist.py
Extensions/param2.py
Extensions/parametre.py
Ihm/I_ASSD.py
Ihm/I_MCSIMP.py
Ihm/I_OBJECT.py
Ihm/I_VALIDATOR.py
Noyau/N_ASSD.py
Noyau/N_CO.py
Noyau/N_ETAPE.py
Noyau/N_FACT.py
Noyau/N_GEOM.py
Noyau/N_JDC.py
Noyau/N_MACRO_ETAPE.py
Noyau/N_OBJECT.py
Noyau/N_SENSIBILITE.py [new file with mode: 0644]
Noyau/N_VALIDATOR.py
Tests/HTMLTestRunner.py
Tests/config.py
Tests/testelem/cata1.py
Tests/testelem/cata5.py
Tests/testelem/testfact1.py
Tests/testelem/testjdc1.py
Tests/testelem/testjdc2.py
Tests/testelem/testoper1.py
Tests/testelem/testposition1.py
Tests/testelem/testsimp1.py
Tests/testelem/testsimp2.py
Tests/testelem/testsimp3.py
Tests/testelem/testsimp4.py
Tests/testelem/testvalidator1.py
Tests/testelem/testvalidator2.py
Validation/V_MCCOMPO.py
Validation/V_MCSIMP.py

index 4831aaa1da8d6ec6ccd7f1579e0ca619b683c5cf..9db138b7ac0aa16d333276bf447bc185de6bca46 100644 (file)
@@ -30,3 +30,9 @@ class FACT(N_FACT.FACT,I_ENTITE.ENTITE):
       I_ENTITE.ENTITE.__init__(self)
       N_FACT.FACT.__init__(self,*tup,**args)
 
+from Noyau import N_OBJECT
+from Ihm import I_OBJECT
+
+class ErrorObj(I_OBJECT.ErrorObj,N_OBJECT.ErrorObj):pass
+N_OBJECT.ErrorObj=ErrorObj
+
diff --git a/Accas/A_SENSIBILITE.py b/Accas/A_SENSIBILITE.py
new file mode 100644 (file)
index 0000000..f6581ee
--- /dev/null
@@ -0,0 +1,9 @@
+
+from Ihm import I_REGLE
+
+from Noyau import N_SENSIBILITE 
+
+class REUSE_SENSIBLE(I_REGLE.REGLE,N_SENSIBILITE.REUSE_SENSIBLE):pass
+class CONCEPT_SENSIBLE(I_REGLE.REGLE,N_SENSIBILITE.CONCEPT_SENSIBLE):pass
+class DERIVABLE(I_REGLE.REGLE,N_SENSIBILITE.DERIVABLE):pass
+
index 2f0d29787596e8ead479558a17531b0b9ddbe35d..580836d0e7a6959429f0351d370473dbf624b3fa 100644 (file)
@@ -1,46 +1,2 @@
 # -*- coding: utf-8 -*-
-import types
-from Noyau import N_VALIDATOR
-from Ihm import I_VALIDATOR
-from Ihm.I_VALIDATOR import ValidException
-
-class FunctionVal(I_VALIDATOR.FunctionVal,N_VALIDATOR.FunctionVal):pass
-class OrVal(I_VALIDATOR.OrVal,N_VALIDATOR.OrVal):pass
-class AndVal(I_VALIDATOR.AndVal,N_VALIDATOR.AndVal):pass
-class NoRepeat(I_VALIDATOR.NoRepeat,N_VALIDATOR.NoRepeat):pass
-class LongStr(I_VALIDATOR.LongStr,N_VALIDATOR.LongStr):pass
-class OrdList(I_VALIDATOR.OrdList,N_VALIDATOR.OrdList):pass
-class RangeVal(I_VALIDATOR.RangeVal,N_VALIDATOR.RangeVal):pass
-class EnumVal(I_VALIDATOR.EnumVal,N_VALIDATOR.EnumVal):pass
-class TypeVal(I_VALIDATOR.TypeVal,N_VALIDATOR.TypeVal):pass
-class PairVal(I_VALIDATOR.PairVal,N_VALIDATOR.PairVal):pass
-class CardVal(I_VALIDATOR.CardVal,N_VALIDATOR.CardVal):pass
-class InstanceVal(I_VALIDATOR.InstanceVal,N_VALIDATOR.InstanceVal):pass
-
-def do_liste(validators):
-    """
-       Convertit une arborescence de validateurs en OrVal ou AndVal
-       validators est une liste de validateurs ou de listes ou de tuples
-    """
-    valids=[]
-    for validator in validators:
-        if type(validator) == types.FunctionType:
-           valids.append(FunctionVal(validator))
-        elif type(validator) == types.TupleType:
-           valids.append(OrVal(do_liste(validator)))
-        elif type(validator) == types.ListType:
-           valids.append(AndVal(do_liste(validator)))
-        else:
-           valids.append(validator)
-    return valids
-
-def validatorFactory(validator):
-    if type(validator) == types.FunctionType:
-       return FunctionVal(validator)
-    elif type(validator) == types.TupleType:
-       return OrVal(do_liste(validator))
-    elif type(validator) == types.ListType:
-       return AndVal(do_liste(validator))
-    else:
-       return validator
-
+from Ihm.I_VALIDATOR import *
index 1eb50497f05a8ba86f2ba3d84a5f757c17e3e418..8ba10bf6c3ef9f3aac6207d9109ad3bfa0f83560 100644 (file)
@@ -1,7 +1,7 @@
-# -*- coding: utf-8 -*-
+# -*- coding: iso-8859-1 -*-
 #            CONFIGURATION MANAGEMENT OF EDF VERSION
 # ======================================================================
-# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# COPYRIGHT (C) 1991 - 2001  EDF R&D                  WWW.CODE-ASTER.ORG
 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
-#
-#
 # ======================================================================
+
+
 """
-   Ce package contient les classes qui seront effectivement utilisées dans les applications. 
-   C'est dans ce package que sont réalisées les combinaisons de classes de base
-   avec les classes MIXIN qui implémentent les fonctionnalités qui ont été séparées
-   du noyau pour des raisons de modularité afin de faciliter la maintenance et
-   l'extensibilité.
+   Ce package contient les classes qui seront effectivement utilisees dans les applications.
+   C'est dans ce package que sont realisees les combinaisons de classes de base
+   avec les classes MIXIN qui implementent les fonctionnalites qui ont ete separees
+   du noyau pour des raisons de modularite afin de faciliter la maintenance et
+   l'extensibilite.
 
-   De plus toutes les classes utilisables par les applications sont remontées au
-   niveau du package afin de rendre le plus indépendant possible l'utilisation des
-   classes et leur implémentation.
+   De plus toutes les classes utilisables par les applications sont remontees au
+   niveau du package afin de rendre le plus independant possible l'utilisation des
+   classes et leur implementation.
 """
+
+# permet de se proteger de l'oubli de carte coding
+# ce warning deviendra fatal en python 2.4
+import warnings
+warnings.filterwarnings('error','Non-ASCII character.*pep-0263',DeprecationWarning)
+
 from A_JDC_CATA import JDC_CATA
 from A_OPER import OPER
 from A_PROC import PROC
@@ -61,7 +67,6 @@ from A_ENSEMBLE import ENSEMBLE
 from A_A_CLASSER import A_CLASSER
 
 from A_ASSD import ASSD,assd
-#from A_ASSD import LASSD
 from A_ASSD import GEOM,geom
 # Pour le moment on laisse fonction (ceinture et bretelles)
 from A_ASSD import FONCTION, fonction
@@ -73,11 +78,10 @@ from Noyau.N__F import _F
 from Noyau.N_Exception import AsException
 from Noyau.N_utils import AsType
 
-#from Noyau.N_VALIDATOR import Valid,RangeVal,OrdList,NoRepeat,LongStr,EnumVal,CardVal,TypeVal,InstanceVal,OrVal,AndVal
-from A_VALIDATOR import OrdList,NoRepeat,LongStr,OrVal,AndVal
+from A_VALIDATOR import OrVal,AndVal
+from A_VALIDATOR import OrdList,NoRepeat,LongStr,Compulsory
 from A_VALIDATOR import RangeVal, EnumVal, TypeVal, PairVal
 from A_VALIDATOR import CardVal, InstanceVal
-from A_VALIDATOR import ValidException
 
 # On remplace la factory des validateurs initialement dans Noyau par celle
 # de A_VALIDATOR
@@ -85,6 +89,7 @@ import A_VALIDATOR
 import Noyau.N_ENTITE
 Noyau.N_ENTITE.ENTITE.factories['validator']=A_VALIDATOR.validatorFactory
 
+from A_SENSIBILITE import CONCEPT_SENSIBLE, REUSE_SENSIBLE, DERIVABLE
 
 from Extensions.niveau import NIVEAU
 from Extensions.etape_niveau import ETAPE_NIVEAU
index b53635cb15d6debf8f4df90c80d70b10b6cd9373..21998b578ea53a6e5d76bbdc22def68cafbfb1f8 100644 (file)
@@ -365,7 +365,10 @@ class ObjectTreeItem(TreeItem,Delegate):
 
     def get_fr(self):
         """ Retourne le fr de l'objet pointé par self """
-        return self.object.get_fr()
+        try:
+            return self.object.get_fr()
+        except:
+            return ""
 
     def get_docu(self):
         """ Retourne la clé de doc de l'objet pointé par self """
index 46c66f61f7584900971a2189d13938d8ff4c7842..ae92e03a005044987458ee9fe448207e015a091d 100644 (file)
@@ -21,6 +21,8 @@
 import types
 from Tkinter import *
 import Pmw
+
+from Noyau.N_OBJECT import ErrorObj
 import Objecttreeitem
 import panels
 import traceback
@@ -44,7 +46,9 @@ class MCLISTPanel(panels.Panel):
         self.node.parent.append_child(self.node.item.get_nom())
 
 import compofact
+import compoerror
 import treewidget
+
 class Node(treewidget.Node):
     def doPaste(self,node_selected):
         objet_a_copier = self.item.get_copie_objet()
@@ -105,6 +109,8 @@ class MCListTreeItem(Objecttreeitem.SequenceTreeItem,compofact.FACTTreeItem):
         """
         if len(self._object) > 1:
            return MCLISTPanel(jdcdisplay,pane,node)
+        elif isinstance(self._object.data[0],ErrorObj):
+           return compoerror.ERRORPanel(jdcdisplay,pane,node)
         else:
            return compofact.FACTPanel(jdcdisplay,pane,node)
 
index 5d307aace04e7d17d2f8f18184f422c6318ca7d1..23dd105c6b2a786d8a2c95c8613d9f3de90e9c63 100644 (file)
@@ -69,7 +69,7 @@ class Binop(Formula):
               result=result.eval()
         return result
     def __adapt__(self,validator):
-        return validator(self.eval())
+        return validator.adapt(self.eval())
 
 original_sqrt=math.sqrt
 original_ceil=math.ceil
@@ -97,7 +97,7 @@ class Unop(Formula):
     def eval(self):
         return self.opmap[self._op](self._arg.eval())
     def __adapt__(self,validator):
-        return validator(self.eval())
+        return validator.adapt(self.eval())
 
 class Unop2(Unop):
     def __init__(self, nom, op, arg):
@@ -129,7 +129,7 @@ class Constant(Formula):
     def eval(self): return self._value
     def __str__(self): return str(self._value)
     def __adapt__(self,validator):
-        return validator(self._value)
+        return validator.adapt(self._value)
 
 class Variable(Formula):
     def __init__(self,name,value):
@@ -139,7 +139,7 @@ class Variable(Formula):
     def __repr__(self): return "Variable('%s',%s)" % (self._name, self._value)
     def __str__(self): return self._name
     def __adapt__(self,validator):
-        return validator(self._value)
+        return validator.adapt(self._value)
 
 def cos(f): return Unop('ncos', f)
 def sin(f): return Unop('nsin', f)
index f94e20368e8590d54b22770c92e91a3f8d22b0ff..540254437bae05344bf05b85b6a2c936622a5d41 100644 (file)
@@ -335,7 +335,7 @@ class PARAMETRE(N_OBJECT.OBJECT,I_OBJECT.OBJECT,Formula) :
          return self.valeur
 
   def __adapt__(self,validator):
-      return validator(self.eval())
+      return validator.adapt(self.eval())
 
 class COMBI_PARAMETRE :
   def __init__(self,chainevaleur,valeur):
index 15b7e162ae69abb44db521f30e535db43c69d6a8..d7ade31b7ee92b139418904c4081dbea0eca13a1 100644 (file)
@@ -19,7 +19,8 @@
 #
 # ======================================================================
 
-from I_VALIDATOR import ValidException
+#from I_VALIDATOR import ValidException
+from Noyau.N_VALIDATOR import ValError
 
 class ASSD:
    def __repr__(self):
@@ -46,6 +47,7 @@ class CO(ASSD):
          if valeur.etape == valeur._etape:
              # le concept est bien produit par l'etape
              return valeur
-      raise ValidException("Pas un concept CO")
+      raise ValError("Pas un concept CO")
+      #raise ValidException("Pas un concept CO")
    __convert__=classmethod(__convert__)
 
index b25a31bf095815ba8f9895fa1e109c19582f6ff2..0723393f15dde88a899dcfa0341e511b768e08c0 100644 (file)
@@ -48,7 +48,7 @@ from Extensions import param2
 import I_OBJECT
 import CONNECTOR
 
-from I_VALIDATOR import ValidException
+#from I_VALIDATOR import ValidException
 
 class MCSIMP(I_OBJECT.OBJECT):
 
@@ -798,7 +798,7 @@ class MCSIMP(I_OBJECT.OBJECT):
          if cr == 'oui': self.cr.fatal(str(e))
          return 0
 
-  def isvalid(self,cr='non'):
+  def isvalid_BAK(self,cr='non'):
       """
          Cette méthode retourne un indicateur de validité de l'objet de type MCSIMP
 
index 99a54efb12cd08cb5ffe0241d88fd8c50eb13294..d7d7c164c3d797909b254ff0448a8de2675ba81f 100644 (file)
@@ -155,3 +155,6 @@ class OBJECT:
 
   #def __del__(self):
   #   print "__del__",self
+
+class ErrorObj(OBJECT):pass
+
index 23c34f7c6e6606712d7639ded22be2677147aec0..1c94ece7beab94ebd76aaea9850da3f5ee0d0108 100644 (file)
@@ -1,260 +1 @@
-# -*- coding: utf-8 -*-
-"""
-   Ce module contient des classes permettant de définir des validateurs
-   pour EFICAS. Ces classes constituent un complément à des classes existantes
-   dans Noyau/N_VALIDATOR.py ou de nouvelles classes de validation.
-   Ces classes complémentaires ne servent que pour l'IHM d'EFICAS.
-   Elles servent essentiellement à ajouter des comportements spécifiques
-   IHM aux classes existantes dans le Noyau.
-   Ces comportements pourront etre rapatries dans le Noyau quand leur
-   interface sera stabilisée.
-"""
-class ValidException(Exception):pass
-
-import types
-from I_MCSIMP import ValidException
-
-class Valid:
-   """
-        Cette classe est la classe mere de toutes les classes complémentaires
-        que l'on trouve dans Ihm.
-   """
-
-class ListVal(Valid):
-   """
-       Cette classe sert de classe mère pour tous les validateurs qui acceptent
-       des listes.
-   """
-   def is_list(self):
-       return 1
-
-   def get_into(self,liste_courante=None,into_courant=None):
-       """
-          Cette méthode get_into effectue un traitement général qui consiste
-          a filtrer la liste de choix into_courant, si elle existe, en ne
-          conservant que les valeurs valides (appel de la méthode valid).
-       """
-       if into_courant is None:
-          return None
-       else:
-          liste_choix=[]
-          for e in into_courant:
-              if self.verif(e):
-                 liste_choix.append(e)
-          return liste_choix
-
-   def convert(self,valeur):
-       """
-          Méthode verif pour les validateurs de listes. Cette méthode
-          fait appel à la méthode verif_item sur chaque élément de la
-          liste. Si valeur est un paramètre, on utilise sa valeur effective
-          valeur.valeur.
-       """
-       if type(valeur) in (types.ListType,types.TupleType):
-          for val in valeur:
-              self.convert_item(val)
-          return valeur
-       else:
-          return self.convert_item(valeur)
-
-
-class RangeVal(ListVal):
-      def convert_item(self,valeur):
-          if valeur > self.low and valeur < self.high:return valeur
-          raise ValidException("%s devrait etre comprise entre %s et %s" %(valeur,self.low,self.high))
-
-
-class CardVal(Valid):
-      def convert(self,valeur):
-          if type(valeur) in (types.ListType,types.TupleType):
-             l=len(valeur)
-          elif valeur is None:
-             l=0
-          else:
-             l=1
-          if self.max != '**' and l > self.max:raise ValidException("%s devrait etre de longueur inferieure a %s" %(valeur,self.max))
-          if self.min != '**' and l < self.min:raise ValidException("%s devrait etre de longueur superieure a %s" %(valeur,self.min))
-          return valeur
-
-
-class PairVal(ListVal):
-      def convert(self,valeur):
-          if type(valeur) in (types.ListType,types.TupleType):
-             for val in valeur:
-                if val % 2 != 0:raise ValidException("%s contient des valeurs non paires" % repr(valeur))
-          else:
-             if valeur % 2 != 0:raise ValidException("%s n'est pas pair" % repr(valeur))
-          return valeur
-
-
-
-class EnumVal(ListVal):
-      def convert_item(self,valeur):
-          if valeur in self.into:return valeur
-          raise ValidException("%s contient des valeurs hors des choix possibles: %s " %(valeur,self.into))
-
-          
-class NoRepeat(ListVal):
-      """
-          Verification d'absence de doublons dans la liste.
-      """
-      def __init__(self):
-          self.cata_info=""
-
-      def info(self):
-          return ": pas de présence de doublon dans la liste"
-
-      def info_erreur_liste(self):
-          return "Les doublons ne sont pas permis"
-
-      def verif_item(self,valeur):
-          return 1
-
-      def verif(self,valeur):
-          if type(valeur) in (types.ListType,types.TupleType):
-             liste=list(valeur)
-             for val in liste:
-                if liste.count(val)!=1 : return 0
-             return 1
-          else:
-             return 1
-
-      def convert_item(self,valeur):
-          if valeur in self.liste : raise ValidException("%s est un doublon" % valeur)
-          return valeur
-          
-      def convert(self,valeur):
-          adapt = getattr(valeur, '__adapt__', None)
-          if adapt is not None:
-             # l'objet valeur peut se verifier lui meme
-             return adapt(self.convert)
-
-          if type(valeur) == types.TupleType and not valeur[0] in ('RI','MP') or type(valeur) == types.ListType:
-            # Cas d'une liste de valeurs
-            # on s'arrete a la premiere erreur
-            self.liste=[]
-            for val in valeur:
-               adapt = getattr(val, '__adapt__', None)
-               if adapt is not None: 
-                  v=adapt(self.convert_item)
-               else:
-                  v=self.convert_item(val)
-               self.liste.append(v)
-          return valeur
-
-      def get_into(self,liste_courante=None,into_courant=None):
-          """
-          Methode get_into spécifique pour validateur NoRepeat, on retourne
-          une liste de choix qui ne contient aucune valeur de into_courant
-          déjà contenue dans liste_courante
-          """
-          if into_courant is None:
-             liste_choix=None
-          else:
-             liste_choix=[]
-             for e in into_courant:
-                 if e in liste_choix: continue
-                 if liste_courante is not None and e in liste_courante: continue
-                 liste_choix.append(e)
-          return liste_choix
-
-
-class LongStr(ListVal):
-      """
-          Verification de la longueur d une chaine
-      """
-      def __init__(self,low,high):
-          self.low=low
-          self.high=high
-          self.cata_info=""
-
-      def info(self):
-          return "longueur de la chaine entre %s et %s" %(self.low,self.high)
-
-      def info_erreur_item(self):
-          return "Longueur de la chaine incorrecte"
-
-      def verif_item(self,valeur):
-          low=self.low
-          high=self.high
-          if valeur[0]=="'" and valeur[-1]=="'" :
-             low=low+2
-             high=high+2
-          if len(valeur) < low :return 0
-          if len(valeur) > high:return 0
-          return 1
-
-      def convert(self,valeur):
-          adapt = getattr(valeur, '__adapt__', None)
-          if adapt is not None:
-             # l'objet valeur peut se verifier lui meme
-             return adapt(self.convert)
-
-          if type(valeur) == types.TupleType and not valeur[0] in ('RI','MP') or type(valeur) == types.ListType:
-            # Cas d'une liste de valeurs
-            # on s'arrete a la premiere erreur
-            for val in valeur:
-               self.convert_item(val)
-            return valeur
-          else:
-            return self.convert_item(valeur)
-
-      def convert_item(self,valeur):
-          low=self.low
-          high=self.high
-          if valeur[0]=="'" and valeur[-1]=="'" :
-             low=low+2
-             high=high+2
-          if len(valeur) < low or len(valeur) > high :
-             raise ValidException("%s n'est pas de la bonne longueur" % repr(valeur))
-          return valeur
-
-
-
-class OrdList(ListVal):
-      def convert(self,valeur):
-          if type(valeur) in (types.ListType,types.TupleType):
-             if self.ord=='croissant':
-                var=valeur[0]
-                for val in valeur[1:]:
-                   if val<var:raise ValidException("%s n'est pas par valeurs croissantes" % repr(valeur))
-                   var=val
-                return valeur
-             elif self.ord=='decroissant':
-                var=valeur[0]
-                for val in valeur[1:]:
-                   if val>var:raise ValidException("%s n'est pas par valeurs decroissantes" % repr(valeur))
-                   var=val
-                return valeur
-          else:
-             return valeur
-
-
-CoercableFuncs = { types.IntType:     int,
-                   types.LongType:    long,
-                   types.FloatType:   float,
-                   types.ComplexType: complex,
-                   types.UnicodeType: unicode }
-
-class TypeVal(ListVal):
-      def convert_item(self,valeur):
-          return   self.coerce(valeur)
-
-class InstanceVal(ListVal):pass
-
-class FunctionVal(Valid):pass
-
-class OrVal(Valid):
-      def convert(self,valeur):
-          for validator in self.validators:
-              try:
-                 return validator.verif(valeur)
-              except:
-                 pass
-          raise ValidException("%s n'est pas du bon type" % valeur)
-
-class AndVal(Valid):
-      def convert(self,valeur):
-          for validator in self.validators:
-              valeur=validator.convert(valeur)
-          return valeur
+from Noyau.N_VALIDATOR import *
index cae723c5fd2a848d6f4eb5577743de4e31824a5c..c8920fbcb1dd94bf659094fd1ef36a83aef70c92 100644 (file)
@@ -1,4 +1,4 @@
-#@ MODIF N_ASSD Noyau  DATE 22/02/2005   AUTEUR DURAND C.DURAND 
+#@ MODIF N_ASSD Noyau  DATE 16/05/2006   AUTEUR DURAND C.DURAND 
 # -*- coding: iso-8859-1 -*-
 #            CONFIGURATION MANAGEMENT OF EDF VERSION
 # ======================================================================
@@ -61,13 +61,6 @@ class ASSD:
    def __getitem__(self,key):
       return self.etape[key]
 
-   def is_object(valeur):
-      """
-          Indique si valeur est d'un type conforme à la classe (retourne 1) 
-          ou non conforme (retourne 0)
-      """
-      return 0
-
    def get_name(self):
       """
           Retourne le nom de self, éventuellement en le demandant au JDC
@@ -111,13 +104,17 @@ class ASSD:
           if key[0]=='_':del d[key]
       return d
 
-class assd(ASSD):
-   def is_object(valeur):
+   def par_lot(self):
       """
-          Indique si valeur est d'un type conforme à la classe (1) 
-          ou non conforme (0)
-          La classe assd est utilisée pour valider tout objet
+           Retourne True si l'ASSD est créée en mode PAR_LOT='OUI'.
       """
-      return 1
-
+      if not hasattr(self, 'jdc') or self.jdc == None:
+         val = None
+      else:
+         val = self.jdc.par_lot
+      return val == 'OUI'
 
+class assd(ASSD):
+   def __convert__(cls,valeur):
+      return valeur
+   __convert__=classmethod(__convert__)
index 3f7a3ac76b486a5ff20a8a5470769bc7eb20524d..60750a87bb9aab39b3d1c4ae1ed137452dc93965 100644 (file)
@@ -1,4 +1,4 @@
-#@ MODIF N_CO Noyau  DATE 22/02/2005   AUTEUR DURAND C.DURAND 
+#@ MODIF N_CO Noyau  DATE 16/05/2006   AUTEUR DURAND C.DURAND 
 # -*- coding: iso-8859-1 -*-
 #            CONFIGURATION MANAGEMENT OF EDF VERSION
 # ======================================================================
@@ -23,6 +23,7 @@
 
 from N_ASSD import ASSD
 from N_Exception import AsException
+from N_VALIDATOR import ValError
 import N_utils
 
 class CO(ASSD):
@@ -40,15 +41,11 @@ class CO(ASSD):
     else:
        self.nom=nom
 
-  def is_object(valeur):
-    """
-          Indique si valeur est d'un type conforme à la classe (retourne 1)
-          ou non conforme (retourne 0)
-    """
-    if hasattr(valeur,'_etape') :
-       # valeur est un concept CO qui a ete transforme par type_sdprod
-       if valeur.etape == valeur._etape:
-           # le concept est bien produit par l'etape
-           return 1
-    return 0
-
+  def __convert__(cls,valeur):
+      if hasattr(valeur,'_etape') :
+         # valeur est un concept CO qui a ete transforme par type_sdprod
+         if valeur.etape == valeur._etape:
+             # le concept est bien produit par l'etape
+             return valeur
+      raise ValError("Pas un concept CO")
+  __convert__=classmethod(__convert__)
index 377ce7523aa6d5cd963dc8a2e40fb194ea7f5837..dde08f5b508a397ff31ff813fae0773dcc5dc7ec 100644 (file)
@@ -1,4 +1,4 @@
-#@ MODIF N_ETAPE Noyau  DATE 22/02/2005   AUTEUR DURAND C.DURAND 
+#@ MODIF N_ETAPE Noyau  DATE 10/05/2006   AUTEUR MCOURTOI M.COURTOIS 
 # -*- coding: iso-8859-1 -*-
 #            CONFIGURATION MANAGEMENT OF EDF VERSION
 # ======================================================================
@@ -117,7 +117,6 @@ class ETAPE(N_MCCOMPO.MCCOMPO):
            le nommage du concept.
 
       """
-      if not self.isactif():return
       self.sdnom=nom
       try:
          if self.parent:
@@ -356,6 +355,8 @@ class ETAPE(N_MCCOMPO.MCCOMPO):
      self.etape=self
      for mocle in self.mc_liste:
         mocle.reparent(self)
+     if self.sd and self.reuse == None :
+        self.sd.jdc=self.jdc
 
    def get_cmd(self,nomcmd):
       """
@@ -393,3 +394,11 @@ class ETAPE(N_MCCOMPO.MCCOMPO):
              new_sd.nom = self.sd.nom
        new_etape.copy_intern(self)
        return new_etape
+
+   def reset_jdc(self,new_jdc):
+       """
+          Reinitialise le nommage du concept de l'etape lors d'un changement de jdc
+       """
+       if self.sd and self.reuse == None :
+           self.parent.NommerSdprod(self.sd,self.sd.nom)
+
index c92c59348e22987a0e55a73e61e8c5394867b8af..e5e3b4280ce21ec21f4583d0a005a301cfc2f610 100644 (file)
@@ -1,4 +1,4 @@
-#@ MODIF N_FACT Noyau  DATE 14/09/2004   AUTEUR MCOURTOI M.COURTOIS 
+#@ MODIF N_FACT Noyau  DATE 16/05/2006   AUTEUR DURAND C.DURAND 
 # -*- coding: iso-8859-1 -*-
 #            CONFIGURATION MANAGEMENT OF EDF VERSION
 # ======================================================================
@@ -30,6 +30,9 @@ import types
 import N_ENTITE
 import N_MCFACT
 import N_MCLIST
+from N__F import _F
+
+import N_OBJECT 
 
 class FACT(N_ENTITE.ENTITE):
    """
@@ -115,7 +118,7 @@ class FACT(N_ENTITE.ENTITE):
         elif type(self.defaut) == types.TupleType:
           val=self.defaut
               # Est ce utile ? Le défaut pourrait etre uniquement un dict
-        elif type(self.defaut) == types.DictType or isinstance(self.defaut,N_MCFACT._F):
+        elif type(self.defaut) == types.DictType or isinstance(self.defaut,_F):
           val=self.defaut
         else:
           # On ne devrait jamais passer par la
@@ -127,11 +130,16 @@ class FACT(N_ENTITE.ENTITE):
       l.init(nom = nom,parent=parent)
       if type(val) in (types.TupleType,types.ListType) :
          for v in val:
-            objet=self.class_instance(nom=nom,definition=self,val=v,parent=parent)
-            l.append(objet)
-      else:
+            if type(v) == types.DictType or isinstance(v, _F):
+               objet=self.class_instance(nom=nom,definition=self,val=v,parent=parent)
+               l.append(objet)
+            else:
+               l.append(N_OBJECT.ErrorObj(self,v,parent,nom))
+      elif type(val) == types.DictType or isinstance(val, _F):
          objet=self.class_instance(nom=nom,definition=self,val=val,parent=parent)
          l.append(objet)
+      else:
+         l.append(N_OBJECT.ErrorObj(self,val,parent,nom))
 
       return l
 
index 70158ae9253e5f2b570d7f81f4dbadb2ffd0d12d..0fc610d72b4f29bff93af98d4a0b53493b43b373 100644 (file)
@@ -1,4 +1,4 @@
-#@ MODIF N_GEOM Noyau  DATE 14/09/2004   AUTEUR MCOURTOI M.COURTOIS 
+#@ MODIF N_GEOM Noyau  DATE 16/05/2006   AUTEUR DURAND C.DURAND 
 # -*- coding: iso-8859-1 -*-
 #            CONFIGURATION MANAGEMENT OF EDF VERSION
 # ======================================================================
@@ -55,15 +55,9 @@ class GEOM(ASSD):
    def get_name(self):
       return self.nom
 
-   def is_object(valeur):
-      """
-          Indique si valeur est d'un type conforme à la classe (1) 
-          ou non conforme (0)
-          La classe GEOM est utilisée pour tous les objets géométriques
-          Elle valide tout objet
-      """
-      return 1
-
+   def __convert__(cls,valeur):
+      return valeur
+   __convert__=classmethod(__convert__)
 
 class geom(GEOM):pass
 
index b4f4539c95ca962a2bd8208602826d4143610920..5c39d0726a3f9086a72e7dfd92ce9008fdd01c36 100644 (file)
@@ -1,4 +1,4 @@
-#@ MODIF N_JDC Noyau  DATE 05/09/2005   AUTEUR DURAND C.DURAND 
+#@ MODIF N_JDC Noyau  DATE 10/05/2006   AUTEUR MCOURTOI M.COURTOIS 
 # -*- coding: iso-8859-1 -*-
 #            CONFIGURATION MANAGEMENT OF EDF VERSION
 # ======================================================================
@@ -412,7 +412,7 @@ NONE = None
       # courante pendant le processus de construction des étapes.
       # Si on insère des commandes (par ex, dans EFICAS), il faut préalablement
       # remettre ce pointeur à 0
-      if etape is not None:
+      if etape:
          index_etape=self.etapes.index(etape)
       else:
          index_etape=len(self.etapes)
@@ -448,3 +448,11 @@ NONE = None
           if hasattr(cata,nomcmd):
              return getattr(cata,nomcmd)
 
+   def append_reset(self,etape):
+       """
+          Ajoute une etape provenant d'un autre jdc a la liste des etapes
+          et remet à jour la parenté de l'étape et des concepts
+       """
+       self.etapes.append(etape)
+       etape.reparent(self)
+       etape.reset_jdc(self)
index 87c14e47e98dde6455c1ea1878f2669caf22ad98..43ff1d7d58bb9859e1ffda795179f7ef02ad62c6 100644 (file)
@@ -1,4 +1,4 @@
-#@ MODIF N_MACRO_ETAPE Noyau  DATE 31/05/2005   AUTEUR DURAND C.DURAND 
+#@ MODIF N_MACRO_ETAPE Noyau  DATE 10/05/2006   AUTEUR MCOURTOI M.COURTOIS 
 # -*- coding: iso-8859-1 -*-
 #            CONFIGURATION MANAGEMENT OF EDF VERSION
 # ======================================================================
@@ -114,7 +114,6 @@ class MACRO_ETAPE(N_ETAPE.ETAPE):
            création et le nommage du concept.
 
       """
-      if not self.isactif():return
       self.sdnom=nom
       try:
          # On positionne la macro self en tant que current_step pour que les 
@@ -643,9 +642,22 @@ Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co
           new_etp.copy_intern(etp)
           self.etapes.append(new_etp)
 
-
-
-
-
-
-
+   def reset_jdc(self,new_jdc):
+       """
+          Reinitialise l'etape avec un nouveau jdc parent new_jdc
+       """
+       if self.sd and self.reuse == None :
+           self.parent.NommerSdprod(self.sd,self.sd.nom)
+       for concept in self.sdprods:
+           self.parent.NommerSdprod(concept,concept.nom)
+
+   def reparent(self,parent):
+       """
+         Cette methode sert a reinitialiser la parente de l'objet
+       """
+       N_ETAPE.ETAPE.reparent(self,parent)
+       #on ne change pas la parenté des concepts. On s'assure uniquement que le jdc en référence est le bon
+       for concept in self.sdprods:
+           concept.jdc=self.jdc
+       for e in self.etapes:
+           e.reparent(self)
index 5f6061a354ff91ea51affe98576f26b2068833d5..45c96cf2492bdfea6eec756171c2d48bcb7ecc23 100644 (file)
@@ -1,4 +1,4 @@
-#@ MODIF N_OBJECT Noyau  DATE 14/09/2004   AUTEUR MCOURTOI M.COURTOIS 
+#@ MODIF N_OBJECT Noyau  DATE 16/05/2006   AUTEUR DURAND C.DURAND 
 # -*- coding: iso-8859-1 -*-
 #            CONFIGURATION MANAGEMENT OF EDF VERSION
 # ======================================================================
@@ -25,6 +25,7 @@
     Ce module contient la classe OBJECT classe mère de tous les objets
     servant à controler les valeurs par rapport aux définitions
 """
+from N_CR import CR
 
 class OBJECT:
    """
@@ -99,3 +100,32 @@ class OBJECT:
       self.parent=parent
       self.jdc=parent.jdc
 
+class ErrorObj(OBJECT):
+    """Classe pour objets errones : emule le comportement d'un objet tel mcsimp ou mcfact
+    """
+    def __init__(self,definition,valeur,parent,nom="err"):
+        self.nom=nom
+        self.definition=definition
+        self.valeur=valeur
+        self.parent=parent
+        self.mc_liste=[]
+        if parent :
+            self.jdc = self.parent.jdc
+            #self.niveau = self.parent.niveau
+            #self.etape = self.parent.etape
+        else:
+            # Pas de parent
+            self.jdc = None
+            #self.niveau = None
+            #self.etape = None
+    def isvalid(self,cr='non'):
+        return 0
+
+    def report(self):
+      """ génère le rapport de validation de self """
+      self.cr=CR()
+      self.cr.debut = "Mot-clé invalide : "+self.nom
+      self.cr.fin = "Fin Mot-clé invalide : "+self.nom
+      self.cr.fatal("Type non autorisé pour le mot-clé %s : '%s'" % (self.nom,self.valeur))
+      return self.cr
+
diff --git a/Noyau/N_SENSIBILITE.py b/Noyau/N_SENSIBILITE.py
new file mode 100644 (file)
index 0000000..ba405c0
--- /dev/null
@@ -0,0 +1,180 @@
+#@ MODIF N_SENSIBILITE Noyau  DATE 10/05/2006   AUTEUR MCOURTOI M.COURTOIS 
+# -*- coding: iso-8859-1 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2006  EDF R&D                  WWW.CODE-ASTER.ORG
+# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY  
+# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY  
+# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR     
+# (AT YOUR OPTION) ANY LATER VERSION.                                                  
+#                                                                       
+# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT   
+# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF            
+# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU      
+# GENERAL PUBLIC LICENSE FOR MORE DETAILS.                              
+#                                                                       
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE     
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,         
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.        
+# ======================================================================
+
+"""
+   Ce module contient les règles nécessaires aux commandes sensibles
+   pour renseigner l'attribut etape.sd.sensi, gérer le caractère réentrant
+   sur présence de la sensibilité.
+"""
+
+from types import TupleType, ListType
+EnumTypes = (TupleType, ListType)
+
+from N_REGLE import REGLE
+
+# -----------------------------------------------------------------------------
+class CONCEPT_SENSIBLE(REGLE):
+   """Règle permettant de renseigner au niveau du catalogue comment sera
+   rempli le concept (valeur nominale ou dérivée(s) ou les deux...).
+   """
+   def __init__(self, mode, mocle='SENSIBILITE'):
+      """Constructeur.
+         mode : manière dont la commande rempli le concept
+            'ENSEMBLE' : concept nominal ET dérivées en une seule passe
+            'SEPARE'   : concept nominal OU dérivée (une ou plusieurs)
+         mocle : mot-clé contenant les paramètres sensibles.
+      """
+      REGLE.__init__(self)
+      self.mocle = mocle
+      self._modes = { 'ENSEMBLE' : 0, 'SEPARE' : 1 }
+      self.mode = self._modes.get(mode, self._modes['ENSEMBLE'])
+
+   def gettext(self):
+      """Pour EFICAS
+      """
+      return ''
+
+   def verif(self, args):
+      """Retourne texte + 1 si ok, 0 si nook.
+      On stocke dans sd.sensi l'étape courante, c'est-à-dire celle qui
+      renseigne le concept si cela n'a pas déjà été fait (car verif est
+      appelé à chaque validation).
+      """
+      obj = args["self"]
+      etape = obj.etape
+      id_etape = '%s_%s' % (etape.id, id(etape))
+      if etape.sd == None:
+          return '',1
+      if not hasattr(etape.sd,"sensi"):
+         etape.sd.sensi = {}
+      # si ENSEMBLE, la sd nominale est forcément produite
+      if self.mode == self._modes['ENSEMBLE'] and not etape.sd.sensi.has_key('nominal'):
+         etape.sd.sensi['nominal'] = id_etape
+      # liste des paramètres sensibles
+      valeur = obj[self.mocle]
+      if valeur == None:
+         # pas de sensibilité, la sd nominale est produite
+         if not etape.sd.sensi.has_key('nominal'):
+            etape.sd.sensi['nominal'] = id_etape
+         return '', 1
+      if not type(valeur) in EnumTypes:
+         valeur = [valeur,]
+      for v in valeur:
+         if not etape.sd.sensi.has_key(v.get_name()):
+            etape.sd.sensi[v.get_name()] = id_etape
+      return '', 1
+
+
+# -----------------------------------------------------------------------------
+class REUSE_SENSIBLE(REGLE):
+   """Limite le caractère réentrant de la commande.
+   On autorisera reuse seulement si le concept (au sens fortran) n'a pas déjà
+   été calculé (d'après sd.sensi). Ce sera interdit dans les cas suivants :
+      - sd nominale calculée et SENSIBILITE absent
+      - PS1 dans SENSIBILITE et sd dérivée par rapport à PS1 calculée
+   """
+   def __init__(self, mocle='SENSIBILITE'):
+      """Constructeur.
+         mocle : mot-clé SENSIBILITE.
+      """
+      REGLE.__init__(self)
+      self.mocle = mocle
+
+   def gettext(self):
+      """Pour EFICAS
+      """
+      return ''
+
+   def verif(self,args):
+      """Retourne texte + 1 si ok, 0 si nook = reuse interdit.
+      Comme CONCEPT_SENSIBLE est appelé avant (et à chaque validation),
+      on regarde si sd.sensi[ps] a été renseigné par une étape précédente.
+      """
+      obj = args["self"]
+      etape = obj.etape
+      id_etape = '%s_%s' % (etape.id, id(etape))
+      sd = etape.sd
+      # si la commande n'est pas réentrante, rien à faire
+      if etape.reuse is not None:
+         valeur = obj[self.mocle]
+         if valeur is None:
+            if not hasattr(sd, 'sensi') or sd.sensi.get('nominal', id_etape) != id_etape:
+               # pas de sensibilite et concept nominal déjà calculé : reuse interdit
+               text = "Commande non réentrante en l'absence de sensibilité."
+               return text, 0
+         else:
+            if not type(valeur) in EnumTypes:
+               valeur = [valeur,]
+            for ps in valeur:
+               if hasattr(sd, 'sensi') and sd.sensi.get(ps.nom, id_etape) != id_etape:
+                  # concept dérivé par rapport à ps déjà calculé : reuse interdit
+                  text = "Commande non réentrante : dérivée par rapport à %s déjà calculée" % ps.nom
+                  return text, 0
+      return '', 1
+
+
+# -----------------------------------------------------------------------------
+class DERIVABLE(REGLE):
+   """Déclare que le concept fourni derrière un mot-clé est dérivable.
+   Sa présence ne suffit pas à le valider, il faut encore que son attribut
+   '.sensi' soit cohérent avec le contenu du mot-clé SENSIBILITE (ou l'absence
+   de celui-ci).
+   """
+   def __init__(self, mocle):
+      """Constructeur.
+         mocle : mot-clé dérivable.
+      """
+      REGLE.__init__(self)
+      self.mocle = mocle
+
+   def gettext(self):
+      """Pour EFICAS
+      """
+      return ''
+
+   def verif(self,args):
+      """
+      """
+      obj = args["self"]
+      try:
+         concept = obj[self.mocle]
+      except IndexError:
+         return '', 1
+      if not type(concept) in EnumTypes:
+         concept = [concept,]
+      l_ps = obj["SENSIBILITE"]
+      for co in concept:
+         if not l_ps:
+            # pas de sensibilité
+            if hasattr(co,"sensi") and not co.sensi.get('nominal'):
+               text = "%s ne contient que des valeurs dérivées, utilisez le mot cle SENSIBILITE" %\
+                     co.nom
+               return text, 0
+         else:
+            # sensibilité spécifiée
+            if not type(l_ps) in EnumTypes:
+               l_ps = [l_ps,]
+            for ps in l_ps:
+               if not hasattr(co,"sensi") or not co.sensi.get(ps.nom):
+                  text = "La dérivée de %s par rapport à %s n'est pas disponible." %\
+                        (co.nom, ps.nom)
+                  return text, 0
+      return '', 1
+
index d4fe3916752471aa9fe67fdba62e08c9b038d0fe..8781509ec20155218ff4e1ce283ddf6d8e6c44a9 100644 (file)
@@ -1,4 +1,4 @@
-#@ MODIF N_VALIDATOR Noyau  DATE 20/09/2004   AUTEUR DURAND C.DURAND 
+#@ MODIF N_VALIDATOR Noyau  DATE 16/05/2006   AUTEUR DURAND C.DURAND 
 # -*- coding: iso-8859-1 -*-
 #            CONFIGURATION MANAGEMENT OF EDF VERSION
 # ======================================================================
    Ce module contient toutes les classes necessaires pour
    implanter le concept de validateur dans Accas
 """
-import types,exceptions
-
-class ValError ( exceptions.Exception ):
-      pass
+import types
+import string
+import traceback
+
+class ValError(Exception):pass
+
+def cls_mro(cls):
+    if hasattr(cls,"__mro__"):return cls.__mro__
+    mro=[cls]
+    for base in cls.__bases__:
+        mro.extend(cls_mro(base))
+    return mro
+
+class Protocol:
+    def __init__(self,name):
+        self.registry = {}
+        self.name = name
+        self.args={}
+
+    def register(self, T, A):
+        self.registry[T] = A
+
+    def adapt(self, obj):
+        # (a) verifier si l'objet peut s'adapter au protocole
+        adapt = getattr(obj, '__adapt__', None)
+        if adapt is not None:
+            # on demande à l'objet obj de réaliser lui-meme l'adaptation
+            return adapt(self)
+
+        # (b) verifier si un adapteur est enregistré (si oui l'utiliser)
+        if self.registry:
+            for T in cls_mro(obj.__class__):
+                if T in self.registry:
+                    return self.registry[T](obj,self,**self.args)
+
+        # (c) utiliser l'adapteur par defaut
+        return self.default(obj,**self.args)
+
+    def default(self,obj,**args):
+        raise TypeError("Can't adapt %s to %s" %
+                        (obj.__class__.__name__, self.name))
+
+class PProtocol(Protocol):
+    """Verificateur de protocole paramétré (classe de base)"""
+    #Protocole paramétré. Le registre est unique pour toutes les instances. La methode register est une methode de classe
+    registry={}
+    def __init__(self,name,**args):
+        self.name = name
+        self.args=args
+    def register(cls, T, A):
+        cls.registry[T] = A
+    register=classmethod(register)
+
+class ListProtocol(Protocol):
+    """Verificateur de protocole liste : convertit un objet quelconque en liste pour validation ultérieure"""
+    def default(self,obj):
+        if type(obj) == types.TupleType :
+            if obj[0] in ('RI','MP'):
+                #il s'agit d'un complexe ancienne mode. La cardinalite vaut 1
+                return (obj,)
+            else:
+                return obj
+        elif type(obj) == types.ListType :
+            return obj
+        elif obj == None :
+            # pas de valeur affecte. La cardinalite vaut 0
+            return obj
+        elif type(obj) == types.StringType :
+            #il s'agit d'une chaine. La cardinalite vaut 1
+            return (obj,)
+        else:
+            try:
+                # si l'objet supporte len, on a la cardinalite
+                length=len(obj)
+                return obj
+            except:
+                # sinon elle vaut 1
+                return (obj,)
+
+listProto=ListProtocol("list")
+
+class TypeProtocol(PProtocol):
+    """Verificateur de type parmi une liste de types possibles"""
+    #pas de registre par instance. Registre unique pour toutes les instances de TypeProtocol
+    registry={}
+    def __init__(self,name,typ=None):
+        PProtocol.__init__(self,name,typ=typ)
+        self.typ=typ
+
+    def default(self,obj,typ):
+        for type_permis in typ:
+            if type_permis == 'R':
+                if type(obj) in (types.IntType,types.FloatType,types.LongType):return obj
+            elif type_permis == 'I':
+                if type(obj) in (types.IntType,types.LongType):return obj
+            elif type_permis == 'C':
+                if self.is_complexe(obj):return obj
+            elif type_permis == 'TXM':
+                if type(obj)==types.StringType:return obj
+            elif type_permis == 'shell':
+                if type(obj)==types.StringType:return obj
+            elif type(type_permis) == types.ClassType:
+                if self.is_object_from(obj,type_permis):return obj
+            elif type(type_permis) == types.InstanceType:
+                try:
+                    if type_permis.__convert__(obj) : return obj
+                except:
+                    pass
+            else:
+                print "Type non encore géré %s" %`type_permis`
+
+        raise ValError("%s n'est pas d'un type autorisé: %s" % (repr(obj),typ))
+
+    def is_complexe(self,valeur):
+        """ Retourne 1 si valeur est un complexe, 0 sinon """
+        if type(valeur) in (types.ComplexType,types.IntType,types.FloatType,types.LongType):
+            # Pour permettre l'utilisation de complexes Python
+            return 1
+        elif type(valeur) != types.TupleType :
+            # On n'autorise pas les listes pour les complexes
+            return 0
+        elif len(valeur) != 3:
+            return 0
+        else:
+            # Un complexe doit etre un tuple de longueur 3 avec 'RI' ou 'MP' comme premiere
+            # valeur suivie de 2 reels.
+            if string.strip(valeur[0]) in ('RI','MP'):
+                try:
+                    v1=reelProto.adapt(valeur[1]),reelProto.adapt(valeur[2])
+                    return 1
+                except:
+                    return 0
+            else:
+                return 0
 
-class Valid:
+    def is_object_from(self,objet,classe):
+        """
+           Retourne 1 si objet est une instance de la classe classe, 0 sinon
+        """
+        convert = getattr(classe, '__convert__', None)
+        if convert is not None:
+            # classe verifie les valeurs
+            try:
+                v=  convert(objet)
+                return v is not None
+            except:
+                return 0
+        # On accepte les instances de la classe et des classes derivees
+        return type(objet) == types.InstanceType and isinstance(objet,classe)
+
+reelProto=TypeProtocol("reel",typ=('R',))
+
+class CardProtocol(PProtocol):
+    """Verificateur de cardinalité """
+    #pas de registre par instance. Registre unique pour toutes les instances
+    registry={}
+    def __init__(self,name,min=1,max=1):
+        PProtocol.__init__(self,name,min=min,max=max)
+
+    def default(self,obj,min,max):
+        length=len(obj)
+        if length < min or length >max:
+            raise ValError("Nombre d'arguments de %s incorrect (min = %s, max = %s)" % (repr(obj),min,max) )
+        return obj
+
+class IntoProtocol(PProtocol):
+    """Verificateur de choix possibles : liste discrète ou intervalle"""
+    #pas de registre par instance. Registre unique pour toutes les instances
+    registry={}
+    def __init__(self,name,into=None,val_min='**',val_max='**'):
+        PProtocol.__init__(self,name,into=into,val_min=val_min,val_max=val_max)
+        self.val_min=val_min
+        self.val_max=val_max
+
+    def default(self,obj,into,val_min,val_max):
+        if into:
+            if obj not in into:
+                raise ValError("La valeur : %s  ne fait pas partie des choix possibles %s" % (repr(obj),into) )
+        else:
+            #on est dans le cas d'un ensemble continu de valeurs possibles (intervalle)
+            if type(obj) in (types.IntType,types.FloatType,types.LongType) :
+                if val_min == '**': val_min = obj -1
+                if val_max == '**': val_max = obj +1
+                if obj < val_min or obj > val_max :
+                    raise ValError("La valeur : %s est en dehors du domaine de validité [ %s , %s ]" % (repr(obj),self.val_min,self.val_max) )
+        return obj
+
+class MinStr:
+    #exemple de classe pour verificateur de type
+    #on utilise des instances de classe comme type (typ=MinStr(3,6), par exemple)
+    def __init__(self,min,max):
+        self.min=min
+        self.max=max
+
+    def __convert__(self,valeur):
+        if type(valeur) == types.StringType and self.min <= len(valeur) <= self.max:return valeur
+        raise ValError("%s n'est pas une chaine de longueur comprise entre %s et %s" % (valeur,self.min,self.max))
+
+    def __repr__(self):
+        return "TXM de longueur entre %s et %s" %(self.min,self.max)
+
+class Valid(PProtocol):
    """
         Cette classe est la classe mere des validateurs Accas
         Elle doit etre derivee 
@@ -37,12 +233,9 @@ class Valid:
         @ivar cata_info: raison de la validite ou de l'invalidite du validateur meme
         @type cata_info: C{string}
    """
-   def __init__(self,*tup,**args):
-       """ 
-           Cette methode sert a initialiser les attributs du validateur 
-       """
-       self.cata_info=""
-       raise "Must be implemented"
+   registry={}
+   def __init__(self,**args):
+       PProtocol.__init__(self,"valid",**args)
 
    def info(self):
        """
@@ -173,22 +366,6 @@ class Valid:
        """
        return into_courant
 
-   def is_param(self,valeur):
-       """
-           Cette méthode indique si valeur est un objet de type PARAMETRE
-           dont on cherchera à evaluer la valeur (valeur.valeur)
-       """
-       #return type(valeur) == types.InstanceType and valeur.__class__.__name__ in ('PARAMETRE',)
-       return 0
-
-   def is_unknown(self,valeur):
-       """
-           Cette méthode indique si valeur est un objet de type inconnu
-           c'est à dire pas de type PARAMETRE
-       """
-       return type(valeur) == types.InstanceType and valeur.__class__.__name__ not in (
-                    'entier','reel','chaine', 'complexe','liste','PARAMETRE_EVAL','PARAMETRE')
-
 class ListVal(Valid):
    """
        Cette classe sert de classe mère pour tous les validateurs qui acceptent
@@ -212,6 +389,19 @@ class ListVal(Valid):
                  liste_choix.append(e)
           return liste_choix
 
+   def convert(self,valeur):
+       """
+          Méthode convert pour les validateurs de listes. Cette méthode
+          fait appel à la méthode convert_item sur chaque élément de la
+          liste.
+       """
+       if type(valeur) in (types.ListType,types.TupleType):
+          for val in valeur:
+              self.convert_item(val)
+          return valeur
+       else:
+          return self.convert_item(valeur)
+
    def verif(self,valeur):
        """
           Méthode verif pour les validateurs de listes. Cette méthode
@@ -219,8 +409,6 @@ class ListVal(Valid):
           liste. Si valeur est un paramètre, on utilise sa valeur effective
           valeur.valeur.
        """
-       if self.is_param(valeur):
-          valeur=valeur.valeur
        if type(valeur) in (types.ListType,types.TupleType):
           for val in valeur:
               if not self.verif_item(val):
@@ -229,164 +417,58 @@ class ListVal(Valid):
        else:
           return self.verif_item(valeur)
 
-class RangeVal(ListVal):
-      """
-          Exemple de classe validateur : verification qu'une valeur
-          est dans un intervalle.
-          Pour une liste on verifie que tous les elements sont 
-          dans l'intervalle
-          Susceptible de remplacer les attributs "vale_min" "vale_max"
-          dans les catalogues
-      """
-      def __init__(self,low,high):
-          self.low=low
-          self.high=high
-          self.cata_info="%s doit etre inferieur a %s" %(low,high)
-
-      def info(self):
-          return "valeur dans l'intervalle %s , %s" %(self.low,self.high)
-
-      def verif_item(self,valeur):
-          return valeur > self.low and valeur < self.high
-
-      def info_erreur_item(self) :
-          return "La valeur doit etre comprise entre %s et %s" % (self.low,
-                                                                  self.high)
-
-      def verif_cata(self):
-          if self.low > self.high : return 0
-          return 1
-
-class CardVal(Valid):
+class Compulsory(ListVal):
       """
-          Exemple de classe validateur : verification qu'une liste est
-          d'une longueur superieur a un minimum (min) et inferieure
-          a un maximum (max).
-          Susceptible de remplacer les attributs "min" "max" dans les
-          catalogues
+          Validateur operationnel
+          Verification de la présence obligatoire d'un élément dans une liste
       """
-      def __init__(self,min='**',max='**'):
-          self.min=min
-          self.max=max  
-          self.cata_info="%s doit etre inferieur a %s" % (min,max)
+      registry={}
+      def __init__(self,elem=()):
+          if type(elem) not in (types.ListType,types.TupleType): elem=(elem,)
+          Valid.__init__(self,elem=elem)
+          self.elem=elem
+          self.cata_info=""
 
       def info(self):
-          return "longueur de liste comprise entre  %s et %s" % (self.min,self.max)
-
-      def info_erreur_liste(self):
-          return "Le cardinal de la liste doit etre compris entre %s et %s" % (self.min,self.max)
+          return "valeur %s obligatoire" % `self.elem`
 
-      def is_list(self):
-          return self.max == '**' or self.max > 1
-
-      def get_into(self,liste_courante=None,into_courant=None):
-          if into_courant is None:
-             return None
-          elif liste_courante is None:
-             return into_courant
-          elif self.max == '**':
-             return into_courant
-          elif len(liste_courante) < self.max:
-             return into_courant
-          else:
-             return []
+      def default(self,valeur,elem):
+          return valeur
 
       def verif_item(self,valeur):
           return 1
 
-      def verif(self,valeur):
-          if type(valeur) in (types.ListType,types.TupleType):
-             if self.max != '**' and len(valeur) > self.max:return 0
-             if self.min != '**' and len(valeur) < self.min:return 0
-             return 1
-          else:
-             if self.max != '**' and 1 > self.max:return 0
-             if self.min != '**' and 1 < self.min:return 0
-             return 1
+      def convert(self,valeur):
+          elem=list(self.elem)
+          for val in valeur:
+              v=self.adapt(val)
+              if v in elem:elem.remove(v)
+          if elem:
+              raise ValError("%s ne contient pas les elements obligatoires : %s " %(valeur,elem))
+          return valeur
 
-      def verif_cata(self):
-          if self.min != '**' and self.max != '**' and self.min > self.max : return 0
+      def has_into(self):
           return 1
 
-      def valide_liste_partielle(self,liste_courante=None):
-          validite=1
-          if liste_courante != None :
-             if len(liste_courante) > self.max :
-                validite=0
-          return validite
-
-class PairVal(ListVal):
-      """
-          Exemple de classe validateur : verification qu'une valeur
-          est paire.
-          Pour une liste on verifie que tous les elements sont
-          pairs
-      """
-      def __init__(self):
-          self.cata_info=""
-
-      def info(self):
-          return "valeur paire"
-
-      def info_erreur_item(self):
-          return "La valeur saisie doit etre paire"
-
-      def verif_item(self,valeur):
-          if type(valeur) == types.InstanceType:
-             if self.is_param(valeur):
-                valeur=valeur.valeur
-             else:
-                return 0
-          return valeur % 2 == 0
-
       def verif(self,valeur):
-          if type(valeur) in (types.ListType,types.TupleType):
-             for val in valeur:
-                if val % 2 != 0:return 0
-             return 1
+          if type(valeur) not in (types.ListType,types.TupleType):
+             liste=list(valeur)
           else:
-             if valeur % 2 != 0:return 0
-             return 1
-
-class EnumVal(ListVal):
-      """
-          Exemple de classe validateur : verification qu'une valeur
-          est prise dans une liste de valeurs.
-          Susceptible de remplacer l attribut "into" dans les catalogues
-      """
-      def __init__(self,into=()):
-          if type(into) not in (types.ListType,types.TupleType): into=(into,)
-          self.into=into
-          self.cata_info=""
-
-      def info(self):
-          return "valeur dans %s" % `self.into`
-
-      def verif_item(self,valeur):
-          if valeur not in self.into:return 0
-          return 1
-
-      def has_into(self):
+             liste=valeur
+          for val in self.elem :
+             if val not in liste : return 0
           return 1
 
-      def get_into(self,liste_courante=None,into_courant=None):
-          if into_courant is None:
-             liste_choix= list(self.into)
-          else:
-             liste_choix=[]
-             for e in into_courant:
-                 if e in self.into:
-                    liste_choix.append(e)
-          return liste_choix
-
       def info_erreur_item(self):
           return "La valeur n'est pas dans la liste des choix possibles"
 
 class NoRepeat(ListVal):
       """
+          Validateur operationnel
           Verification d'absence de doublons dans la liste.
       """
       def __init__(self):
+          Valid.__init__(self)
           self.cata_info=""
 
       def info(self):
@@ -395,6 +477,17 @@ class NoRepeat(ListVal):
       def info_erreur_liste(self):
           return "Les doublons ne sont pas permis"
 
+      def default(self,valeur):
+          if valeur in self.liste : raise ValError("%s est un doublon" % valeur)
+          return valeur
+
+      def convert(self,valeur):
+          self.liste=[]
+          for val in valeur:
+              v=self.adapt(val)
+              self.liste.append(v)
+          return valeur
+
       def verif_item(self,valeur):
           return 1
 
@@ -425,9 +518,11 @@ class NoRepeat(ListVal):
 
 class LongStr(ListVal):
       """
+          Validateur operationnel
           Verification de la longueur d une chaine
       """
       def __init__(self,low,high):
+          ListVal.__init__(self,low=low,high=high)
           self.low=low
           self.high=high
           self.cata_info=""
@@ -438,21 +533,35 @@ class LongStr(ListVal):
       def info_erreur_item(self):
           return "Longueur de la chaine incorrecte"
 
+      def convert(self,valeur):
+          for val in valeur:
+              v=self.adapt(val)
+          return valeur
+
       def verif_item(self,valeur):
-          low=self.low
-          high=self.high
+          try:
+             self.adapt(valeur)
+             return 1
+          except:
+             return 0
+
+      def default(self,valeur,low,high):
+          if type(valeur) != types.StringType :
+             raise ValError("%s n'est pas une string" % repr(valeur))
           if valeur[0]=="'" and valeur[-1]=="'" :
              low=low+2
              high=high+2
-          if len(valeur) < low :return 0
-          if len(valeur) > high:return 0
-          return 1
+          if len(valeur) < low or len(valeur) > high :
+             raise ValError("%s n'est pas de la bonne longueur" % repr(valeur))
+          return valeur
 
 class OrdList(ListVal):
       """
+          Validateur operationnel
           Verification qu'une liste est croissante ou decroissante
       """
       def __init__(self,ord):
+          ListVal.__init__(self,ord=ord)
           self.ord=ord
           self.cata_info=""
 
@@ -462,22 +571,22 @@ class OrdList(ListVal):
       def info_erreur_liste(self) :
           return "La liste doit etre en ordre "+self.ord
 
-      def verif(self,valeur):
-          if type(valeur) in (types.ListType,types.TupleType):
-             if self.ord=='croissant':
-                var=valeur[0]
-                for val in valeur[1:]:
-                   if val<var:return 0
-                   var=val
-                return 1
-             elif self.ord=='decroissant':
-                var=valeur[0]
-                for val in valeur[1:]:
-                   if val>var:return 0
-                   var=val
-                return 1
-          else:
-             return 1
+      def convert(self,valeur):
+          self.val=None
+          self.liste=valeur
+          for v in valeur:
+              self.adapt(v)
+          return valeur
+
+      def default(self,valeur,ord):
+          if self.ord=='croissant':
+              if self.val is not None and valeur<self.val:
+                  raise ValError("%s n'est pas par valeurs croissantes" % repr(self.liste))
+          elif self.ord=='decroissant':
+              if self.val is not None and valeur > self.val:
+                  raise ValError("%s n'est pas par valeurs decroissantes" % repr(self.liste))
+          self.val=valeur
+          return valeur
 
       def verif_item(self,valeur):
           return 1
@@ -502,160 +611,61 @@ class OrdList(ListVal):
                  liste_choix.append(e)
              return liste_choix
 
-CoercableFuncs = { types.IntType:     int,
-                   types.LongType:    long,
-                   types.FloatType:   float,
-                   types.ComplexType: complex,
-                   types.UnicodeType: unicode }
-
-class TypeVal(ListVal):
+class OrVal(Valid):
       """
-          Cette classe est un validateur qui controle qu'une valeur
-          est bien du type Python attendu.
-          Pour une liste on verifie que tous les elements sont du bon type.
+          Validateur operationnel
+          Cette classe est un validateur qui controle une liste de validateurs
+          Elle verifie qu'au moins un des validateurs de la liste valide la valeur
       """
-      def __init__(self, aType):
-          if type(aType) != types.TypeType:
-             aType=type(aType)
-          self.aType=aType
-          try:
-             self.coerce=CoercableFuncs[ aType ]
-          except:
-             self.coerce = self.identity
+      def __init__(self,validators=()):
+          if type(validators) not in (types.ListType,types.TupleType):
+             validators=(validators,)
+          self.validators=[]
+          for validator in validators:
+              if type(validator) == types.FunctionType:
+                 self.validators.append(FunctionVal(validator))
+              else:
+                 self.validators.append(validator)
+          self.cata_info=""
 
       def info(self):
-          return "valeur de %s" % self.aType
-
-      def identity ( self, value ):
-          if type( value ) == self.aType:
-             return value
-          raise ValError
+          return "\n ou ".join([v.info() for v in self.validators])
 
-      def verif_item(self,valeur):
-          try:
-             self.coerce(valeur)
-          except:
-             return 0
-          return 1
+      def convert(self,valeur):
+          for validator in self.validators:
+              try:
+                 return validator.convert(valeur)
+              except:
+                 pass
+          raise ValError("%s n'est pas du bon type" % repr(valeur))
 
-class InstanceVal(ListVal):
-      """
-          Cette classe est un validateur qui controle qu'une valeur est
-          bien une instance (au sens Python) d'une classe
-          Pour une liste on verifie chaque element de la liste
-      """
-      def __init__(self,aClass):
-          if type(aClass) == types.InstanceType:
-             aClass=aClass.__class__
-          self.aClass=aClass
+      def info_erreur_item(self):
+          l=[]
+          for v in self.validators:
+              err=v.info_erreur_item()
+              if err != " " : l.append(err)
+          chaine=" \n ou ".join(l)
+          return chaine
 
-      def info(self):
-          return "valeur d'instance de %s" % self.aClass.__name__
+      def info_erreur_liste(self):
+          l=[]
+          for v in self.validators:
+              err=v.info_erreur_liste()
+              if err != " " : l.append(err)
+          chaine=" \n ou ".join(l)
+          return chaine
 
-      def verif_item(self,valeur):
-          if not isinstance(valeur,self.aClass): return 0
-          return 1
-
-def ImpairVal(valeur):
-    """
-        Cette fonction est un validateur. Elle verifie que la valeur passee
-        est bien un nombre impair.
-    """
-    if type(valeur) in (types.ListType,types.TupleType):
-       for val in valeur:
-           if val % 2 != 1:return 0
-       return 1
-    else:
-       if valeur % 2 != 1:return 0
-       return 1
-
-ImpairVal.info="valeur impaire"
-    
-class F1Val(Valid):
-      """
-          Cette classe est un validateur de dictionnaire (mot cle facteur ?). Elle verifie
-          que la somme des cles A et B vaut une valeur donnee
-          en parametre du validateur
-      """
-      def __init__(self,somme=10):
-          self.somme=somme
-          self.cata_info=""
-
-      def info(self):
-          return "valeur %s pour la somme des cles A et B " % self.somme
-
-      def verif(self,valeur):
-          if type(valeur) in (types.ListType,types.TupleType):
-             for val in valeur:
-                if not val.has_key("A"):return 0
-                if not val.has_key("B"):return 0
-                if val["A"]+val["B"]  != self.somme:return 0
-             return 1
-          else:
-             if not valeur.has_key("A"):return 0
-             if not valeur.has_key("B"):return 0
-             if valeur["A"]+valeur["B"]  != self.somme:return 0
-             return 1
-
-class FunctionVal(Valid):
-      """
-          Cette classe est un validateur qui est initialise avec une fonction
-      """
-      def __init__(self,function):
-          self.function=function
-
-      def info(self):
-          return self.function.info
-
-      def verif(self,valeur):
-          return self.function(valeur)
-
-class OrVal(Valid):
-      """
-          Cette classe est un validateur qui controle une liste de validateurs
-          Elle verifie qu'au moins un des validateurs de la liste valide la valeur
-      """
-      def __init__(self,validators=()):
-          if type(validators) not in (types.ListType,types.TupleType): 
-             validators=(validators,)
-          self.validators=[]
-          for validator in validators:
-              if type(validator) == types.FunctionType:
-                 self.validators.append(FunctionVal(validator))
-              else:
-                 self.validators.append(validator)
-          self.cata_info=""
-
-      def info(self):
-          return "\n ou ".join([v.info() for v in self.validators])
-
-      def info_erreur_item(self):
-          l=[]
-          for v in self.validators:
-              err=v.info_erreur_item()
-              if err != " " : l.append(err)
-          chaine=" \n ou ".join(l)
-          return chaine
-
-      def info_erreur_liste(self):
-          l=[]
-          for v in self.validators:
-              err=v.info_erreur_liste()
-              if err != " " : l.append(err)
-          chaine=" \n ou ".join(l)
-          return chaine
-
-      def is_list(self):
-          """
-             Si plusieurs validateurs sont reliés par un OU
-             il suffit qu'un seul des validateurs attende une liste
-             pour qu'on considère que leur union attend une liste.
-          """
-          for validator in self.validators:
-              v=validator.is_list()
-              if v :
-                 return 1
-          return 0
+      def is_list(self):
+          """
+             Si plusieurs validateurs sont reliés par un OU
+             il suffit qu'un seul des validateurs attende une liste
+             pour qu'on considère que leur union attend une liste.
+          """
+          for validator in self.validators:
+              v=validator.is_list()
+              if v :
+                 return 1
+          return 0
 
       def verif(self,valeur):
           for validator in self.validators:
@@ -728,11 +738,12 @@ class OrVal(Valid):
 
 class AndVal(Valid):
       """
+          Validateur operationnel
           Cette classe est un validateur qui controle une liste de validateurs
           Elle verifie que tous les validateurs de la liste valident la valeur
       """
       def __init__(self,validators=()):
-          if type(validators) not in (types.ListType,types.TupleType): 
+          if type(validators) not in (types.ListType,types.TupleType):
              validators=(validators,)
           self.validators=[]
           for validator in validators:
@@ -745,6 +756,11 @@ class AndVal(Valid):
       def info(self):
           return "\n et ".join([v.info() for v in self.validators])
 
+      def convert(self,valeur):
+          for validator in self.validators:
+              valeur=validator.convert(valeur)
+          return valeur
+
       def info_erreur_item(self):
           chaine=""
           a=1
@@ -878,3 +894,301 @@ def validatorFactory(validator):
        return AndVal(do_liste(validator))
     else:
        return validator
+
+# Ci-dessous : exemples de validateur (peu testés)
+
+class RangeVal(ListVal):
+      """
+          Exemple de classe validateur : verification qu'une valeur
+          est dans un intervalle.
+          Pour une liste on verifie que tous les elements sont 
+          dans l'intervalle
+          Susceptible de remplacer les attributs "vale_min" "vale_max"
+          dans les catalogues
+      """
+      def __init__(self,low,high):
+          self.low=low
+          self.high=high
+          self.cata_info="%s doit etre inferieur a %s" %(low,high)
+
+      def info(self):
+          return "valeur dans l'intervalle %s , %s" %(self.low,self.high)
+
+      def convert_item(self,valeur):
+          if valeur > self.low and valeur < self.high:return valeur
+          raise ValError("%s devrait etre comprise entre %s et %s" %(valeur,self.low,self.high))
+
+      def verif_item(self,valeur):
+          return valeur > self.low and valeur < self.high
+
+      def info_erreur_item(self) :
+          return "La valeur doit etre comprise entre %s et %s" % (self.low,
+                                                                  self.high)
+
+      def verif_cata(self):
+          if self.low > self.high : return 0
+          return 1
+
+class CardVal(Valid):
+      """
+          Exemple de classe validateur : verification qu'une liste est
+          d'une longueur superieur a un minimum (min) et inferieure
+          a un maximum (max).
+          Susceptible de remplacer les attributs "min" "max" dans les
+          catalogues
+      """
+      def __init__(self,min='**',max='**'):
+          self.min=min
+          self.max=max  
+          self.cata_info="%s doit etre inferieur a %s" % (min,max)
+
+      def info(self):
+          return "longueur de liste comprise entre  %s et %s" % (self.min,self.max)
+
+      def info_erreur_liste(self):
+          return "Le cardinal de la liste doit etre compris entre %s et %s" % (self.min,self.max)
+
+      def is_list(self):
+          return self.max == '**' or self.max > 1
+
+      def get_into(self,liste_courante=None,into_courant=None):
+          if into_courant is None:
+             return None
+          elif liste_courante is None:
+             return into_courant
+          elif self.max == '**':
+             return into_courant
+          elif len(liste_courante) < self.max:
+             return into_courant
+          else:
+             return []
+
+      def convert(self,valeur):
+          if type(valeur) in (types.ListType,types.TupleType):
+             l=len(valeur)
+          elif valeur is None:
+             l=0
+          else:
+             l=1
+          if self.max != '**' and l > self.max:raise ValError("%s devrait etre de longueur inferieure a %s" %(valeur,self.max))
+          if self.min != '**' and l < self.min:raise ValError("%s devrait etre de longueur superieure a %s" %(valeur,self.min))
+          return valeur
+
+      def verif_item(self,valeur):
+          return 1
+
+      def verif(self,valeur):
+          if type(valeur) in (types.ListType,types.TupleType):
+             if self.max != '**' and len(valeur) > self.max:return 0
+             if self.min != '**' and len(valeur) < self.min:return 0
+             return 1
+          else:
+             if self.max != '**' and 1 > self.max:return 0
+             if self.min != '**' and 1 < self.min:return 0
+             return 1
+
+      def verif_cata(self):
+          if self.min != '**' and self.max != '**' and self.min > self.max : return 0
+          return 1
+
+      def valide_liste_partielle(self,liste_courante=None):
+          validite=1
+          if liste_courante != None :
+             if len(liste_courante) > self.max :
+                validite=0
+          return validite
+
+class PairVal(ListVal):
+      """
+          Exemple de classe validateur : verification qu'une valeur
+          est paire.
+          Pour une liste on verifie que tous les elements sont
+          pairs
+      """
+      def __init__(self):
+          ListVal.__init__(self)
+          self.cata_info=""
+
+      def info(self):
+          return "valeur paire"
+
+      def info_erreur_item(self):
+          return "La valeur saisie doit etre paire"
+
+      def convert(self,valeur):
+          for val in valeur:
+             v=self.adapt(val)
+             if v % 2 != 0:raise ValError("%s contient des valeurs non paires" % repr(valeur))
+          return valeur
+
+      def default(self,valeur):
+          return valeur
+
+      def verif_item(self,valeur):
+          if type(valeur) == types.InstanceType:
+             return 0
+          return valeur % 2 == 0
+
+      def verif(self,valeur):
+          if type(valeur) in (types.ListType,types.TupleType):
+             for val in valeur:
+                if val % 2 != 0:return 0
+             return 1
+          else:
+             if valeur % 2 != 0:return 0
+             return 1
+
+class EnumVal(ListVal):
+      """
+          Exemple de classe validateur : verification qu'une valeur
+          est prise dans une liste de valeurs.
+          Susceptible de remplacer l attribut "into" dans les catalogues
+      """
+      def __init__(self,into=()):
+          if type(into) not in (types.ListType,types.TupleType): into=(into,)
+          self.into=into
+          self.cata_info=""
+
+      def info(self):
+          return "valeur dans %s" % `self.into`
+
+      def convert_item(self,valeur):
+          if valeur in self.into:return valeur
+          raise ValError("%s contient des valeurs hors des choix possibles: %s " %(valeur,self.into))
+
+      def verif_item(self,valeur):
+          if valeur not in self.into:return 0
+          return 1
+
+      def has_into(self):
+          return 1
+
+      def get_into(self,liste_courante=None,into_courant=None):
+          if into_courant is None:
+             liste_choix= list(self.into)
+          else:
+             liste_choix=[]
+             for e in into_courant:
+                 if e in self.into:
+                    liste_choix.append(e)
+          return liste_choix
+
+      def info_erreur_item(self):
+          return "La valeur n'est pas dans la liste des choix possibles"
+
+def ImpairVal(valeur):
+    """
+          Exemple de validateur
+        Cette fonction est un validateur. Elle verifie que la valeur passee
+        est bien un nombre impair.
+    """
+    if type(valeur) in (types.ListType,types.TupleType):
+       for val in valeur:
+           if val % 2 != 1:return 0
+       return 1
+    else:
+       if valeur % 2 != 1:return 0
+       return 1
+
+ImpairVal.info="valeur impaire"
+    
+class F1Val(Valid):
+      """
+          Exemple de validateur
+          Cette classe est un validateur de dictionnaire (mot cle facteur ?). Elle verifie
+          que la somme des cles A et B vaut une valeur donnee
+          en parametre du validateur
+      """
+      def __init__(self,somme=10):
+          self.somme=somme
+          self.cata_info=""
+
+      def info(self):
+          return "valeur %s pour la somme des cles A et B " % self.somme
+
+      def verif(self,valeur):
+          if type(valeur) in (types.ListType,types.TupleType):
+             for val in valeur:
+                if not val.has_key("A"):return 0
+                if not val.has_key("B"):return 0
+                if val["A"]+val["B"]  != self.somme:return 0
+             return 1
+          else:
+             if not valeur.has_key("A"):return 0
+             if not valeur.has_key("B"):return 0
+             if valeur["A"]+valeur["B"]  != self.somme:return 0
+             return 1
+
+class FunctionVal(Valid):
+      """
+          Exemple de validateur
+          Cette classe est un validateur qui est initialise avec une fonction
+      """
+      def __init__(self,function):
+          self.function=function
+
+      def info(self):
+          return self.function.info
+
+      def verif(self,valeur):
+          return self.function(valeur)
+
+CoercableFuncs = { types.IntType:     int,
+                   types.LongType:    long,
+                   types.FloatType:   float,
+                   types.ComplexType: complex,
+                   types.UnicodeType: unicode }
+
+class TypeVal(ListVal):
+      """
+          Exemple de validateur
+          Cette classe est un validateur qui controle qu'une valeur
+          est bien du type Python attendu.
+          Pour une liste on verifie que tous les elements sont du bon type.
+      """
+      def __init__(self, aType):
+          if type(aType) != types.TypeType:
+             aType=type(aType)
+          self.aType=aType
+          try:
+             self.coerce=CoercableFuncs[ aType ]
+          except:
+             self.coerce = self.identity
+
+      def info(self):
+          return "valeur de %s" % self.aType
+
+      def identity ( self, value ):
+          if type( value ) == self.aType:
+             return value
+          raise ValError
+
+      def convert_item(self,valeur):
+          return   self.coerce(valeur)
+
+      def verif_item(self,valeur):
+          try:
+             self.coerce(valeur)
+          except:
+             return 0
+          return 1
+
+class InstanceVal(ListVal):
+      """
+          Exemple de validateur
+          Cette classe est un validateur qui controle qu'une valeur est
+          bien une instance (au sens Python) d'une classe
+          Pour une liste on verifie chaque element de la liste
+      """
+      def __init__(self,aClass):
+          if type(aClass) == types.InstanceType:
+             aClass=aClass.__class__
+          self.aClass=aClass
+
+      def info(self):
+          return "valeur d'instance de %s" % self.aClass.__name__
+
+      def verif_item(self,valeur):
+          if not isinstance(valeur,self.aClass): return 0
+          return 1
+
index e59a8efa2fdb2b2a0596080fcdbefd1019d88aae..8da592f229edcc1c40d02fbce9d6a6d1f525b753 100644 (file)
@@ -1,5 +1,41 @@
 """
-Copyright (c) 2004, Wai Yip Tung
+A TestRunner for use with the Python unit testing framework. It
+generates a HTML report to show the result at a glance.
+
+The simplest way to use this is to invoke its main method. E.g.
+
+    import unittest
+    import HTMLTestRunner
+
+    ... define your tests ...
+
+    if __name__ == '__main__':
+        HTMLTestRunner.main()
+
+
+To customize the report, instantiates a HTMLTestRunner object and set
+the parameters. HTMLTestRunner is a counterpart to unittest's
+TextTestRunner. E.g.
+
+    # output to a file
+    fp = file('my_report.html', 'wb')
+    runner = HTMLTestRunner.HTMLTestRunner(
+                stream=fp,
+                title='My unit test',
+                report_attrs=[('Version','1.2.3')],
+                description='This demonstrates the report output by HTMLTestRunner.'
+                )
+
+    # Use an external stylesheet.
+    # See the Template_mixin class for more customizable options
+    runner.STYLESHEET_TMPL = '<link rel="stylesheet" href="my_stylesheet.css" type="text/css">'
+
+    # run the test
+    runner.run(my_test_suite)
+
+
+------------------------------------------------------------------------
+Copyright (c) 2004-2006, Wai Yip Tung
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -11,9 +47,9 @@ met:
 * Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
-* Neither the name of the Wai Yip Tung nor the names of its
-  contributors may be used to endorse or promote products derived from
-  this software without specific prior written permission.
+* Neither the name Wai Yip Tung nor the names of its contributors may be
+  used to endorse or promote products derived from this software without
+  specific prior written permission.
 
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -26,38 +62,28 @@ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"""
 
-A TestRunner for use with the Python unit testing framework. It
-generates a HTML report to show the result at a glance.
-
-The simplest way to use this is to invoke its main method. E.g.
-
-    import unittest
-    import HTMLTestRunner
+# URL: http://tungwaiyip.info/software/HTMLTestRunner.html
 
-    ... define your tests ...
+__author__ = "Wai Yip Tung"
+__version__ = "0.8.0"
 
-    if __name__ == '__main__':
-        HTMLTestRunner.main()
 
-It defines the class HTMLTestRunner, which is a counterpart of unittest's
-TextTestRunner. You can also instantiates a HTMLTestRunner object for
-finer control.
 """
+Changes in 0.8.0
+* Define Template_mixin class for customization.
+* Workaround a IE 6 bug that it does not treat <script> block as CDATA.
 
-# URL: http://tungwaiyip.info/software
-
-__author__ = "Wai Yip Tung"
-__version__ = "0.7"
-
+Changes in 0.7.1
+* Back port to Python 2.3. Thank you Frank Horowitz.
+* Fix missing scroll bars in detail log. Thank you Podi.
+"""
 
-# TOOD: need to make sure all HTML and JavaScript blocks are properly escaped!
-# TODO: allow link to custom CSS
 # TODO: color stderr
 # TODO: simplify javascript using ,ore than 1 class in the class attribute?
 
 import datetime
-import string
 import StringIO
 import sys
 import time
@@ -98,65 +124,65 @@ stderr_redirector = OutputRedirector(sys.stderr)
 # ----------------------------------------------------------------------
 # Template
 
-STATUS = {
-0: 'pass',
-1: 'fail',
-2: 'error',
-}
-
+class Template_mixin(object):
+    """
+    Define a HTML template for report customerization and generation.
+
+    Overall structure of an HTML report
+
+    HTML
+    +------------------------+
+    |<html>                  |
+    |  <head>                |
+    |                        |
+    |   STYLESHEET           |
+    |   +----------------+   |
+    |   |                |   |
+    |   +----------------+   |
+    |                        |
+    |  </head>               |
+    |                        |
+    |  <body>                |
+    |                        |
+    |   HEADING              |
+    |   +----------------+   |
+    |   |                |   |
+    |   +----------------+   |
+    |                        |
+    |   REPORT               |
+    |   +----------------+   |
+    |   |                |   |
+    |   +----------------+   |
+    |                        |
+    |   ENDING               |
+    |   +----------------+   |
+    |   |                |   |
+    |   +----------------+   |
+    |                        |
+    |  </body>               |
+    |</html>                 |
+    +------------------------+
+    """
 
-CSS = """
-<style>
-body        { font-family: verdana, arial, helvetica, sans-serif; font-size: 80%; }
-table       { font-size: 100%; }
-pre         { }
-h1          { }
-.heading    {
-    margin-top: 0ex;
-    margin-bottom: 1ex;
-}
-#show_detail_line {
-    margin-top: 3ex;
-    margin-bottom: 1ex;
-}
-#result_table {
-    width: 80%;
-    border-collapse: collapse;
-    border: medium solid #777;
-}
-#result_table td {
-    border: thin solid #777;
-    padding: 2px;
-}
-#header_row {
-    font-weight: bold;
-    color: white;
-    background-color: #777;
-}
-#total_row  { font-weight: bold; }
-.passClass  { background-color: #6c6; }
-.failClass  { background-color: #c60; }
-.errorClass { background-color: #c00; }
-.passCase   { color: #6c6; }
-.failCase   { color: #c60; font-weight: bold; }
-.errorCase  { color: #c00; font-weight: bold; }
-.hiddenRow  { display: none; }
-.testcase   { margin-left: 2em; }
-#btm_filler { margin-top: 50%; }
-</style>
-"""
+    STATUS = {
+    0: 'pass',
+    1: 'fail',
+    2: 'error',
+    }
 
-# currently not used
-CSS_LINK = '<link rel="stylesheet" href="$url" type="text/css">\n'
+    DEFAULT_TITLE = 'Unit Test Report'
+    DEFAULT_DESCRIPTION = ''
 
+    # ------------------------------------------------------------------------
+    # HTML Template
 
-HTML_TMPL = string.Template(r"""
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+    HTML_TMPL = r"""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html>
 <head>
-    <title>$title</title>
+    <title>%(title)s</title>
+    <meta name="generator" content="%(generator)s">
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-    $css
+    %(stylesheet)s
 </head>
 <body>
 <script>
@@ -214,13 +240,20 @@ function showClassDetail(cid, count) {
     }
 }
 
+function html_escape(s) {
+    s = s.replace(/&/g,'&amp;');
+    s = s.replace(/</g,'&lt;');
+    s = s.replace(/>/g,'&gt;');
+    return s;
+}
+
 function showOutput(id, name) {
-    w = window.open("", //url
+    var w = window.open("", //url
                     name,
-                    "resizable,status,width=800,height=450");
+                    "resizable,scrollbars,status,width=800,height=450");
     d = w.document;
     d.write("<pre>");
-    d.write(output_list[id]);
+    d.write(html_escape(output_list[id]));
     d.write("\n");
     d.write("<a href='javascript:window.close()'>close</a>\n");
     d.write("</pre>\n");
@@ -229,9 +262,107 @@ function showOutput(id, name) {
 
 </script>
 
-<h1>$description</h1>
-<p class='heading'><strong>Time:</strong> $time</p>
-<p class='heading'><strong>Status:</strong> $status</p>
+%(heading)s
+%(report)s
+%(ending)s
+
+</body>
+</html>
+"""
+    # variables: (title, generator, stylesheet, heading, report, ending)
+
+
+    # ------------------------------------------------------------------------
+    # Stylesheet
+    #
+    # alternatively use a <link> for external style sheet, e.g.
+    #   <link rel="stylesheet" href="$url" type="text/css">
+
+    STYLESHEET_TMPL = """
+<style>
+body        { font-family: verdana, arial, helvetica, sans-serif; font-size: 80%; }
+table       { font-size: 100%; }
+pre         { }
+
+/* -- heading ---------------------------------------------------------------------- */
+h1 {
+}
+.heading {
+    margin-top: 0ex;
+    margin-bottom: 1ex;
+}
+
+.heading .attribute {
+    margin-top: 1ex;
+    margin-bottom: 0;
+}
+
+.heading .description {
+    margin-top: 4ex;
+    margin-bottom: 6ex;
+}
+
+/* -- report ------------------------------------------------------------------------ */
+#show_detail_line {
+    margin-top: 3ex;
+    margin-bottom: 1ex;
+}
+#result_table {
+    width: 80%;
+    border-collapse: collapse;
+    border: medium solid #777;
+}
+#header_row {
+    font-weight: bold;
+    color: white;
+    background-color: #777;
+}
+#result_table td {
+    border: thin solid #777;
+    padding: 2px;
+}
+#total_row  { font-weight: bold; }
+.passClass  { background-color: #6c6; }
+.failClass  { background-color: #c60; }
+.errorClass { background-color: #c00; }
+.passCase   { color: #6c6; }
+.failCase   { color: #c60; font-weight: bold; }
+.errorCase  { color: #c00; font-weight: bold; }
+.hiddenRow  { display: none; }
+.testcase   { margin-left: 2em; }
+
+
+/* -- ending ---------------------------------------------------------------------- */
+#ending {
+}
+
+</style>
+"""
+
+
+
+    # ------------------------------------------------------------------------
+    # Heading
+    #
+
+    HEADING_TMPL = """<div class='heading'>
+<h1>%(title)s</h1>
+%(parameters)s
+<p class='description'>%(description)s</p>
+</div>
+
+""" # variables: (title, parameters, description)
+
+    HEADING_ATTRIBUTE_TMPL = """<p class='attribute'><strong>%(name)s:</strong> %(value)s</p>
+""" # variables: (name, value)
+
+
+
+    # ------------------------------------------------------------------------
+    # Report
+    #
+
+    REPORT_TMPL = """
 <p id='show_detail_line'>Show
 <a href='javascript:showCase(0)'>Summary</a>
 <a href='javascript:showCase(1)'>Failed</a>
@@ -254,52 +385,76 @@ function showOutput(id, name) {
     <td>Error</td>
     <td>View</td>
 </tr>
-$tests
+%(test_list)s
 <tr id='total_row'>
     <td>Total</td>
-    <td>$count</td>
-    <td>$Pass</td>
-    <td>$fail</td>
-    <td>$error</td>
+    <td>%(count)s</td>
+    <td>%(Pass)s</td>
+    <td>%(fail)s</td>
+    <td>%(error)s</td>
     <td>&nbsp;</td>
 </tr>
 </table>
-<div id='btm_filler' />
-</body>
-</html>
-""")
-
-CLASS_TMPL = string.Template(r"""
-<tr class='$style'>
-    <td>$name</td>
-    <td>$count</td>
-    <td>$Pass</td>
-    <td>$fail</td>
-    <td>$error</td>
-    <td><a href="javascript:showClassDetail('$cid',$count)">Detail</a></td>
+""" # variables: (test_list, count, Pass, fail, error)
+
+
+    REPORT_CLASS_TMPL = r"""
+<tr class='%(style)s'>
+    <td>%(name)s</td>
+    <td>%(count)s</td>
+    <td>%(Pass)s</td>
+    <td>%(fail)s</td>
+    <td>%(error)s</td>
+    <td><a href="javascript:showClassDetail('%(cid)s',%(count)s)">Detail</a></td>
 </tr>
-""")
+""" # variables: (style, name, count, Pass, fail, error, cid)
+
 
-TEST_TMPL = string.Template(r"""
-<tr id='$tid' class='$Class'>
-    <td class='$style'><div class='testcase'>$name<div></td>
-    <td colspan='5' align='center'><a href="javascript:showOutput('$tid', '$name')">$status</a></td>
+    REPORT_TEST_WITH_OUTPUT_TMPL = r"""
+<tr id='%(tid)s' class='%(Class)s'>
+    <td class='%(style)s'><div class='testcase'>%(name)s<div></td>
+    <td colspan='5' align='center'><a href="javascript:showOutput('%(tid)s', '%(name)s')">%(status)s</a></td>
 </tr>
-""")
+""" # variables: (tid, Class, style, name, status)
+
 
-TEST_TMPL_NO_OUTPUT = string.Template(r"""
-<tr id='$tid' class='$Class'>
-    <td class='$style'><div class='testcase'>$name<div></td>
-    <td colspan='5' align='center'>$status</td>
+    REPORT_TEST_NO_OUTPUT_TMPL = r"""
+<tr id='%(tid)s' class='%(Class)s'>
+    <td class='%(style)s'><div class='testcase'>%(name)s<div></td>
+    <td colspan='5' align='center'>%(status)s</td>
 </tr>
-""")
+""" # variables: (tid, Class, style, name, status)
 
-TEST_OUTPUT_TMPL = string.Template(r"""
-<script>output_list['$id'] = '$output';</script>
-""")
 
+    REPORT_TEST_OUTPUT_TMPL = r"""
+<script>output_list['%(id)s'] = '%(output)s';</script>
+""" # variables: (id, output)
+
+
+
+    # ------------------------------------------------------------------------
+    # ENDING
+    #
+
+    ENDING_TMPL = """<div id='ending'>&nbsp;</div>"""
+
+# -------------------- The end of the Template class -------------------
+
+
+
+def jsEscapeString(s):
+    """ Escape s for use as a Javascript String """
+    return s.replace('\\','\\\\') \
+        .replace('\r', '\\r') \
+        .replace('\n', '\\n') \
+        .replace('"', '\\"') \
+        .replace("'", "\\'") \
+        .replace("&", '\\x26') \
+        .replace("<", '\\x3C') \
+        .replace(">", '\\x3E')
+    # Note: non-ascii unicode characters do not need to be encoded
+    # Note: previously we encode < as &lt;, etc. However IE6 fail to treat <script> block as CDATA.
 
-# ----------------------------------------------------------------------
 
 TestResult = unittest.TestResult
 
@@ -311,6 +466,9 @@ class _TestResult(TestResult):
         TestResult.__init__(self)
         self.stdout0 = None
         self.stderr0 = None
+        self.success_count = 0
+        self.failure_count = 0
+        self.error_count = 0
         self.verbosity = verbosity
 
         # result is a list of result in 4 tuple
@@ -356,6 +514,7 @@ class _TestResult(TestResult):
 
 
     def addSuccess(self, test):
+        self.success_count += 1
         TestResult.addSuccess(self, test)
         output = self.complete_output()
         self.result.append((0, test, output, ''))
@@ -367,9 +526,11 @@ class _TestResult(TestResult):
             sys.stderr.write('.')
 
     def addError(self, test, err):
+        self.error_count += 1
         TestResult.addError(self, test, err)
+        _, _exc_str = self.errors[-1]
         output = self.complete_output()
-        self.result.append((2, test, output, self._exc_info_to_string(err, test)))
+        self.result.append((2, test, output, _exc_str))
         if self.verbosity > 1:
             sys.stderr.write('E  ')
             sys.stderr.write(str(test))
@@ -378,9 +539,11 @@ class _TestResult(TestResult):
             sys.stderr.write('E')
 
     def addFailure(self, test, err):
+        self.failure_count += 1
         TestResult.addFailure(self, test, err)
+        _, _exc_str = self.failures[-1]
         output = self.complete_output()
-        self.result.append((1, test, output, self._exc_info_to_string(err, test)))
+        self.result.append((1, test, output, _exc_str))
         if self.verbosity > 1:
             sys.stderr.write('F  ')
             sys.stderr.write(str(test))
@@ -389,21 +552,31 @@ class _TestResult(TestResult):
             sys.stderr.write('F')
 
 
-class HTMLTestRunner:
+class HTMLTestRunner(Template_mixin):
     """
     """
-    def __init__(self, stream=sys.stdout, descriptions=1, verbosity=1, description='Test'):
-        # unittest itself has no good mechanism for user to define a
-        # description neither in TestCase nor TestSuite. Allow user to
-        # pass in the description as a parameter.
-
-        # note: this is different from unittest.TextTestRunner's
-        # 'descrpitions' parameter, which is an integer flag.
-
+    def __init__(self, stream=sys.stdout, verbosity=1, title=None, report_attrs=[], description=None):
+        """
+        @param stream - output stream, default to stdout
+        @param verbosity
+        @param title - use in title and heading
+        @param report_attrs - list of (name, value) to show in report
+        @param description - test description
+        """
         self.stream = stream
-        self.startTime = datetime.datetime.now()
-        self.description = description
         self.verbosity = verbosity
+        if title is None:
+            self.title = self.DEFAULT_TITLE
+        else:
+            self.title = title
+        if description is None:
+            self.description = self.DEFAULT_DESCRIPTION
+        else:
+            self.description = description
+        self.report_attrs = report_attrs
+
+        self.startTime = datetime.datetime.now()
+
 
     def run(self, test):
         "Run the given test case or test suite."
@@ -414,6 +587,7 @@ class HTMLTestRunner:
         print >>sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime)
         return result
 
+
     def sortResult(self, result_list):
         # unittest does not seems to run in any particular order.
         # Here at least we want to group them together by class.
@@ -428,22 +602,81 @@ class HTMLTestRunner:
         r = [(cls, rmap[cls]) for cls in classes]
         return r
 
+
+    def getReportAttributes(self, result):
+        """
+        Add a few system generated attributes on top of users defined.
+        Override this to add other dynamic custom attributes.
+
+        @return list of (name, value).
+        """
+        startTime = str(self.startTime)[:19]
+        duration = str(self.stopTime - self.startTime)
+        status = []
+        if result.success_count: status.append('Success %s' % result.success_count)
+        if result.failure_count: status.append('Failure %s' % result.failure_count)
+        if result.error_count:   status.append('Error %s'   % result.error_count  )
+        if status:
+            status = ' '.join(status)
+        else:
+            status = 'none'
+
+        return [('Start Time', startTime),
+                 ('Duration', duration),
+                 ('Status', status),
+                ] + self.report_attrs
+
+
     def generateReport(self, test, result):
+        report_attrs = self.getReportAttributes(result)
+        generator = 'HTMLTestRunner %s' % __version__
+        stylesheet = self._generate_stylesheet()
+        heading = self._generate_heading(report_attrs)
+        report = self._generate_report(result)
+        ending = self._generate_ending()
+        output = self.HTML_TMPL % dict(
+            title = saxutils.escape(self.title),
+            generator = generator,
+            stylesheet = stylesheet,
+            heading = heading,
+            report = report,
+            ending = ending,
+        )
+        self.stream.write(output.encode('utf8'))
+
+
+    def _generate_stylesheet(self):
+        return self.STYLESHEET_TMPL
+
+
+    def _generate_heading(self, report_attrs):
+        a_lines = []
+        for name, value in report_attrs:
+            line = self.HEADING_ATTRIBUTE_TMPL % dict(
+                    name = saxutils.escape(name),
+                    value = saxutils.escape(value),
+                )
+            a_lines.append(line)
+        heading = self.HEADING_TMPL % dict(
+            title = saxutils.escape(self.title),
+            parameters = ''.join(a_lines),
+            description = saxutils.escape(self.description),
+        )
+        return heading
+
+
+    def _generate_report(self, result):
         rows = []
-        npAll = nfAll = neAll = 0
         sortedResult = self.sortResult(result.result)
         for cid, (cls, cls_results) in enumerate(sortedResult):
-            # update counts
+            # subtotal for a class
             np = nf = ne = 0
             for n,t,o,e in cls_results:
                 if n == 0: np += 1
                 elif n == 1: nf += 1
                 else: ne += 1
-            npAll += np
-            nfAll += nf
-            neAll += ne
 
-            row = CLASS_TMPL.safe_substitute(
+            row = self.REPORT_CLASS_TMPL % dict(
                 style = ne > 0 and 'errorClass' or nf > 0 and 'failClass' or 'passClass',
                 name = "%s.%s" % (cls.__module__, cls.__name__),
                 count = np+nf+ne,
@@ -455,57 +688,58 @@ class HTMLTestRunner:
             rows.append(row)
 
             for tid, (n,t,o,e) in enumerate(cls_results):
-                # e.g. 'pt1.1', 'ft1.1', etc
-                has_output = bool(o or e)
-                tid = (n == 0 and 'p' or 'f') + 't%s.%s' % (cid+1,tid+1)
-                name = t.id().split('.')[-1]
-                tmpl = has_output and TEST_TMPL or TEST_TMPL_NO_OUTPUT
-                row = tmpl.safe_substitute(
-                    tid = tid,
-                    Class = (n == 0 and 'hiddenRow' or ''),
-                    style = n == 2 and 'errorCase' or (n == 1 and 'failCase' or ''),
-                    name = name,
-                    status = STATUS[n],
-                )
-                rows.append(row)
-                if has_output:
-                    # o and e should be byte string because they are collected from stdout and stderr?
-                    if isinstance(o,str):
-# TODO: some problem with 'string_escape': it escape \n and mess up formating
-#                        uo = unicode(o.encode('string_escape'))
-                        uo = o.decode('latin-1')
-                    else:
-                        uo = o
-                    if isinstance(e,str):
-# TODO: some problem with 'string_escape': it escape \n and mess up formating
-#                        ue = unicode(e.encode('string_escape'))
-                        ue = e.decode('latin-1')
-                    else:
-                        ue = e
-                    row = TEST_OUTPUT_TMPL.safe_substitute(
-                        id = tid,
-                        output = saxutils.escape(uo+ue) \
-                            .replace("'", '&apos;') \
-                            .replace('"', '&quot;') \
-                            .replace('\\','\\\\') \
-                            .replace('\r','\\r') \
-                            .replace('\n','\\n'),
-                    )
-                    rows.append(row)
-
-        report = HTML_TMPL.safe_substitute(
-            title = self.description,
-            css = CSS,
-            description = self.description,
-            time = str(self.startTime)[:19],
-            status = result.wasSuccessful() and 'Passed' or 'Failed',
-            tests = ''.join(rows),
-            count = str(npAll+nfAll+neAll),
-            Pass = str(npAll),
-            fail = str(nfAll),
-            error = str(neAll),
+                self._generate_report_test(rows, cid, tid, n, t, o, e)
+
+        report = self.REPORT_TMPL % dict(
+            test_list = ''.join(rows),
+            count = str(result.success_count+result.failure_count+result.error_count),
+            Pass = str(result.success_count),
+            fail = str(result.failure_count),
+            error = str(result.error_count),
+        )
+        return report
+
+
+    def _generate_report_test(self, rows, cid, tid, n, t, o, e):
+        # e.g. 'pt1.1', 'ft1.1', etc
+        has_output = bool(o or e)
+        tid = (n == 0 and 'p' or 'f') + 't%s.%s' % (cid+1,tid+1)
+        name = t.id().split('.')[-1]
+        tmpl = has_output and self.REPORT_TEST_WITH_OUTPUT_TMPL or self.REPORT_TEST_NO_OUTPUT_TMPL
+        row = tmpl % dict(
+            tid = tid,
+            Class = (n == 0 and 'hiddenRow' or ''),
+            style = n == 2 and 'errorCase' or (n == 1 and 'failCase' or ''),
+            name = name,
+            status = self.STATUS[n],
         )
-        self.stream.write(report.encode('utf8'))
+        rows.append(row)
+        if not has_output:
+            return
+
+        # o and e should be byte string because they are collected from stdout and stderr?
+        if isinstance(o,str):
+            # TODO: some problem with 'string_escape': it escape \n and mess up formating
+            # uo = unicode(o.encode('string_escape'))
+            uo = o.decode('latin-1')
+        else:
+            uo = o
+        if isinstance(e,str):
+            # TODO: some problem with 'string_escape': it escape \n and mess up formating
+            # ue = unicode(e.encode('string_escape'))
+            ue = e.decode('latin-1')
+        else:
+            ue = e
+
+        row = self.REPORT_TEST_OUTPUT_TMPL % dict(
+            id = tid,
+            output = jsEscapeString(uo+ue),
+        )
+        rows.append(row)
+
+
+    def _generate_ending(self):
+        return self.ENDING_TMPL
 
 
 ##############################################################################
index 195b32e3d246c07a5fe43296c2dda60446e06932..b67110925a550aaedfb1d59a7d1bdfdd27dcc060 100644 (file)
@@ -2,5 +2,7 @@
 import sys
 sys.path.insert(0,"../Aster")
 import prefs
-ASTERDIR="/local/chris/ASTER/instals/STA8.2/astest"
+#ASTERDIR="/local/chris/ASTER/instals/STA8.2/astest"
+ASTERDIR="/local/chris/ASTER/instals/NEW8/astest"
+sys.path.insert(0,prefs.CODE_PATH)
 
index fcbb0a1d9b18782043a74c9e6c59a9205cbbcd02..684f51a4d5947ba5e2d05a8764c01f1b3e6ba7d0 100644 (file)
@@ -73,4 +73,9 @@ OP6=OPER(nom='OP6',op=6,sd_prod=op6_prod,
                          )
         )
 
+OP7=OPER(nom='OP7',op=7,sd_prod=concept,
+            FILTRE  =FACT(statut='o',min=01,max='**',
+                          MODE  =SIMP(statut='o',typ=(concept,concept2) ),
+                         )
+        )
 
index aeb209477392d040e414e383982d9260b348bde7..7060a7ea4e18c70bf0614ad6681af8f5dd1854ca 100644 (file)
@@ -183,3 +183,22 @@ def debut(self,PAR_LOT):
 
 DEBUT=MACRO(nom='DEBUT',op=debut,sd_prod=debut_sdprod,PAR_LOT=SIMP(typ='TXM',defaut='OUI'))
 
+class entier   (ASSD):
+   def __init__(self,valeur=None,**args):
+      ASSD.__init__(self,**args)
+      self.valeur=valeur
+
+   def __adapt__(self,validator):
+      if validator.name == "list":
+          #validateur liste,cardinalité
+          return (self,)
+      elif validator.name == "type":
+          #validateur type
+          return validator.adapt(self.valeur or 0)
+      else:
+          #validateur into et valid
+          return self
+
+   def __repr__(self):
+      return "<concept entier>"
+
index c3e698969439b1b8e51a8cd243d41021ec9c1c70..664332c257ff9702ba8b2c0413b2a7b2e5cd5a54 100644 (file)
@@ -36,18 +36,20 @@ Fin Mot cle Facteur :mcs1
 
    def testType1(self):
       """Verification de type"""
-      self.assertRaises(AttributeError,self.cata,1,'mcs1',None)
+      #Ne leve plus d'exception
+      #self.assertRaises(AttributeError,self.cata,1,'mcs1',None)
       o=self.cata({'a':1.},'mcs1',None)
       cr=o.report()
       expected_cr="""Mot cle Facteur :mcs1
    Mot-clé simple : a
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-      ! 1.0 n'est pas d'un type autorisé !
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+      ! 1.0 n'est pas d'un type autorisé: ('I',) !
+      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Fin Mot-clé simple : a
 Fin Mot cle Facteur :mcs1
 """
-      self.assertEqual(str(cr) , expected_cr)
+      msg="le rapport d'erreur est incorrect.\n expected =\n%s\n got =\n%s " % (expected_cr,str(cr))
+      self.assertEqual(str(cr) , expected_cr,msg=msg)
 
    def test031(self):
        cata=FACT(min=2,max=3,a=SIMP(typ='I',statut='o'),)
@@ -84,6 +86,11 @@ Fin Mot cle Facteur :mcs1
              ({},1),
              ({'xx':{}},1),
              ({'xx':{'a':1}},1),
+             ({'xx':"error"},0),
+             ({'xx':("error","err2","err3")},0),
+             ({'xx':({'a':1},"err2","err3")},0),
+             ({'xx':("err1",{'a':1},"err3")},0),
+             ({'xx':("err1",{'a':1},"err3","err4")},0),
              )
        for valeur,valid in liste:
            o=cata(valeur,'mcf',None)
index b915b2e1c5412648a38aa29117fd94e779d7a283..9482a823a694f0b124f17a691d6659b65ca9a929 100644 (file)
@@ -433,9 +433,9 @@ FIN();
       ! Concept retourné non défini !
       !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       Mot-clé simple : VALE
-         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-         ! 'sin(1.,2)' n'est pas d'un type autorisé !
-         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+         ! 'sin(1.,2)' n'est pas d'un type autorisé: ('R',) !
+         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       Fin Mot-clé simple : VALE
    Fin Etape : DEFI_LIST_REEL
    Etape : DEFI_LIST_REEL    ligne : ...
@@ -443,9 +443,9 @@ FIN();
       ! Concept retourné non défini !
       !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       Mot-clé simple : VALE
-         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-         ! 'aaa(1.)' n'est pas d'un type autorisé !
-         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+         ! 'aaa(1.)' n'est pas d'un type autorisé: ('R',) !
+         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       Fin Mot-clé simple : VALE
    Fin Etape : DEFI_LIST_REEL
 FIN CR validation :SansNom
index 8cebe098c0c9729dde1f26169f0c0a22f60681bc..89430d9600ead7979ab38ca6e89a11c468db1047 100644 (file)
@@ -28,7 +28,7 @@ co1=OP5(MATR=co0)
    Etape : OP5    ligne : 5    fichier : 'bidon'
       Mot-clé simple : MATR
          !!!!!!...
-         ! ... n'est pas d'un type autorisé !
+         ! ... n'est pas d'un type autorisé... !
          !!!!!!...
       Fin Mot-clé simple : MATR
    Fin Etape : OP5
@@ -47,7 +47,7 @@ co2=OP2(MATR=co0)
    Etape : OP2    ligne : 5    fichier : 'bidon'
       Mot-clé simple : MATR
          !!!!...
-         ! ... n'est pas d'un type autorisé !
+         ! ... n'est pas d'un type autorisé... !
          !!!!...
       Fin Mot-clé simple : MATR
    Fin Etape : OP2
@@ -79,7 +79,7 @@ co2=OP10(MATR=CO("xx"))
    Etape : OP10    ligne : 2    fichier : 'bidon'
       Mot-clé simple : MATR
          !!!!...
-         ! ... n'est pas d'un type autorisé !
+         ! ... n'est pas d'un type autorisé... !
          !!!!...
       Fin Mot-clé simple : MATR
    Fin Etape : OP10
@@ -102,7 +102,7 @@ co2=OP22(MATR=xx)
    Etape : OP22    ligne : 3    fichier : 'bidon'
       Mot-clé simple : MATR
          !!!!!!!!...
-         ! ... n'est pas d'un type autorisé !
+         ! ... n'est pas d'un type autorisé... !
          !!!!!!!...
       Fin Mot-clé simple : MATR
    Fin Etape : OP22
index b777a6de99cdcbbf841d5b0b63ecce2b0003b761..d4137e3e5e30c34b8c8914a1c65365dc4f811c51 100644 (file)
@@ -1,6 +1,6 @@
 # coding=utf-8
 import cata1
-from cata1 import OP1,OP2,OP3,OP4,OP5,OP6
+from cata1 import OP1,OP2,OP3,OP4,OP5,OP6,OP7
 from Accas import AsException,ASSD,OPER,SIMP,FACT,BLOC,_F
 
 class concept(ASSD):pass
@@ -74,13 +74,13 @@ class TestOperCase(unittest.TestCase):
       OP10 = OPER(nom='OP10',op=10,sd_prod=concept,
                    a=SIMP(typ='I'),
                    c=SIMP(statut='o',typ='TXM',position='global',
-           into=("TABLEAU","AGRAF"),
- ),
-           b=FACT(statut='o',max='**',
-   b_forme=BLOC(condition="c == 'TABLEAU'",
-                d=SIMP(statut='f',typ='TXM'),
-),
-),
+                           into=("TABLEAU","AGRAF"),
                        ),
+                   b=FACT(statut='o',max='**',
+                          b_forme=BLOC(condition="c == 'TABLEAU'",
+                                       d=SIMP(statut='f',typ='TXM'),
+                                      ),
+                         ),
                  )
 
       co1=OP10(a=1,c="TABLEAU",b=_F(d='rr'))
@@ -164,6 +164,15 @@ class TestOperCase(unittest.TestCase):
       co1.etape.supprime()
 
    def test15(self):
+      """ Test mot cle facteur incorrect
+      """
+      co1=OP7(FILTRE="coucou")
+      cr=co1.etape.report()
+      msg="erreur sur le test " +'\n'+str(cr)
+      self.assertEqual(co1.etape.isvalid(),0,msg=msg)
+      co1.etape.supprime()
+
+   def test16(self):
       OP10 = OPER(nom='OP10',op=10,sd_prod=concept,
                    a=SIMP(statut='o',typ='R',val_min=0,val_max=1,max=5),
                  )
index dbe752ab70047f80d3cd03c967dc0ed71434821d..96e906c494c18c17868c0e19b153c661a768deb8 100644 (file)
@@ -23,13 +23,13 @@ class TestCase(unittest.TestCase):
       OP10 = OPER(nom='OP10',op=10,sd_prod=concept,
                    a=SIMP(typ='I'),
                    c=SIMP(statut='o',typ='TXM',position='global',
-                   into=("TABLEAU","AGRAF"),
-             ),
-               b=FACT(statut='o',max='**',
-           b_forme=BLOC(condition="c == 'TABLEAU'",
-                        d=SIMP(statut='f',typ='TXM'),
-                ),
-            ),
+                          into=("TABLEAU","AGRAF"),
+                         ),
+                   b=FACT(statut='o',max='**',
+                          b_forme=BLOC(condition="c == 'TABLEAU'",
+                                       d=SIMP(statut='f',typ='TXM'),
+                                      ),
+                         ),
                  )
       co1=OP10(a=1,c="TABLEAU",b=_F(d='rr'))
       msg=co1.etape.report()
@@ -41,15 +41,15 @@ class TestCase(unittest.TestCase):
       OP10 = OPER(nom='OP10',op=10,sd_prod=concept,
                    a=SIMP(typ='I'),
                    c=SIMP(statut='o',typ='TXM',position='global_jdc',
-                   into=("TABLEAU","AGRAF"),
-             ),
+                          into=("TABLEAU","AGRAF"),
+                         ),
                  )
       OP11 = OPER(nom='OP11',op=10,sd_prod=concept,
-               b=FACT(statut='o',max='**',
-           b_forme=BLOC(condition="c == 'TABLEAU'",
-                        d=SIMP(statut='f',typ='TXM'),
-                ),
-            ),
+                  b=FACT(statut='o',max='**',
+                         b_forme=BLOC(condition="c == 'TABLEAU'",
+                                      d=SIMP(statut='f',typ='TXM'),
+                                     ),
+                        ),
                  )
       co1=OP10(a=1,c="TABLEAU",)
       co2=OP11(b=_F(d='rr'))
index c25917ed5b3da4877381e249c58f57e681827d03..18ad2b5887be63bbc941645d9e5cc819e0fb144f 100644 (file)
@@ -1,9 +1,8 @@
 # coding=utf-8
 import types
-from Accas import SIMP,ASSD
+from Accas import SIMP,ASSD,geom,assd
 class maillage(ASSD):pass
 class maillage_sdaster(ASSD):pass
-from Accas import ValidException
 
 import unittest
 
@@ -241,10 +240,32 @@ Fin Mot-cl
        for valeur,valid in liste:
            o=cata(valeur,'mcs',None)
            self.assertEqual(o.isvalid(),valid,
-        "erreur sur le test %s %s" % (valeur,valid)+'\n'+str(o.report()))
+                "erreur sur le test %s %s" % (valeur,valid)+'\n'+str(o.report()))
            if valid: self.assertEqual(o.get_valeur(),valeur)
 
    def test014(self):
+       cata=SIMP(typ=geom,statut='o')
+       liste=((1,1),
+              ("aaaa",1),
+            )
+       for valeur,valid in liste:
+           o=cata(valeur,'mcs',None)
+           self.assertEqual(o.isvalid(),valid,
+                "erreur sur le test %s %s" % (valeur,valid)+'\n'+str(o.report()))
+           if valid: self.assertEqual(o.get_valeur(),valeur)
+
+   def test015(self):
+       cata=SIMP(typ=assd,statut='o')
+       liste=((1,1),
+              ("aaaa",1),
+            )
+       for valeur,valid in liste:
+           o=cata(valeur,'mcs',None)
+           self.assertEqual(o.isvalid(),valid,
+                "erreur sur le test %s %s" % (valeur,valid)+'\n'+str(o.report()))
+           if valid: self.assertEqual(o.get_valeur(),valeur)
+
+   def test016(self):
        class LongStr:
          def __init__(self,min,max):
             self.min=min
@@ -265,3 +286,4 @@ Fin Mot-cl
            self.assertEqual(o.isvalid(),valid,
                      "erreur sur le test %s %s" % (valeur,valid)+'\n'+str(o.report()))
            if valid: self.assertEqual(o.get_valeur(),valeur)
+
index 4c0aae2053c0491d7e6f1a506482aa1477fe9393..b04f74353966c7d196f9d0f561a71c08413f1408 100644 (file)
@@ -30,11 +30,12 @@ class TestSimpCase(unittest.TestCase):
            msg="erreur sur le test %s %s" % (valeur,valid)+'\n'+str(o.report())
            self.assertEqual(o.isvalid(),valid,msg=msg)
 
-   def futuretest003(self):
+   def test003(self):
        cata=SIMP(statut='o',typ='R',max=3)
        class mylist(list):pass
        liste=((1,1),(mylist((0.,1.)),1), (1.,1),(mylist((0.,1.)),1), (('RI',1,0),0),
               (1+0j,0), ("('RI',1,0)",0), ("toto",0), (None,0),
+              (mylist(("aaaa",1.)),0), (mylist((0.,1.,2.,3.)),0), 
              )
        for valeur,valid in liste:
            o=cata(valeur,'mcs',None)
index 3d6caeec8b42f617c7237ec41c251ed618c813af..e7e1fa622c551c9d3095cb310a2ec1576d5e74f8 100644 (file)
 # coding=utf-8
-from Accas import SIMP,ASSD
-from Extensions.param2 import Variable,cos
+from Accas import *
 
 import unittest
+import compare
+OK="""Mot-clé simple : mcs
+Fin Mot-clé simple : mcs
+"""
+class myparam:
+    def __init__(self,valeur):
+        self.valeur=valeur
+    def __adapt__(self,protocol):
+        return protocol.adapt(self.valeur)
 
-class TestSimpCase(unittest.TestCase):
+from Noyau.N_VALIDATOR import listProto,TypeProtocol,IntoProtocol
+class param:
+    def __init__(self,valeur):
+        self.valeur=valeur
+
+def hasvaleur(obj,protocol,**args):
+    return protocol.adapt(obj.valeur)
+
+listProto.register(param,hasvaleur)
+TypeProtocol.register(param,hasvaleur)
+IntoProtocol.register(param,hasvaleur)
+
+
+class TestValidCase(unittest.TestCase):
    def setUp(self):
        pass
 
    def tearDown(self):
        pass
 
-   def test001(self):
-       a=Variable("n",25.6)
-       self.assertEqual(repr(a),"Variable('n',25.6)")
-       self.assertEqual(str(a),"n")
-       self.assertEqual(a.eval(),25.6)
-       b=-a
-       self.assertEqual(str(b),"-(n)")
-       self.assertEqual(b.eval(),-25.6)
-       b=-a*100+3/2
-       self.assertEqual(str(b),'((-(n) * 100) + 1)')
-       self.assertEqual(b.eval(),-2559)
-       b=a/10
-       self.assertEqual(str(b),'(n / 10)')
-       self.assertEqual(b.eval(),2.56)
-       c=Variable('q',[1,a,3])
-       d=c[1]/3
-       self.assertEqual(str(d),'(q[1] / 3)')
-       self.assertEqual(d.eval(),25.6/3)
-       f=cos(d)
-       self.assertEqual(str(f),'cos((q[1] / 3))')
-       self.assertEqual(f.eval(),-0.628288791022798)
-       g=a**2
-       self.assertEqual(str(g),'(n ** 2)')
-       self.assertEqual(g.eval(),655.36000000000013)
-       h=2*Variable("x",2)
-       g=a**h
-       self.assertEqual(str(g),'(n ** (2 * x))')
-       self.assertEqual(g.eval(),429496.72960000008)
+   def _test(self,cata,liste):
+       for valeur,report in liste:
+           o=cata(valeur,'mcs',None)
+           msg=""
+           rep=str(o.report())
+           valid=compare.check(rep,report)
+           if not valid:
+              msg="le rapport d'erreur est incorrect.\n valeur = %s\n expected =\n%s\n got =\n%s " % (valeur,report,rep)
+              print msg
+           self.assert_(valid,msg=msg)
 
-   def test003(self):
-       """ Validation d'un parametre (instance de la classe Variable)
-       """
-       cata=SIMP(statut='o',typ='R',max=3)
-       liste=((1,1),(Variable('x',(0.,1.)),1), (1.,1),(Variable('x',(0.,1.)),1), (('RI',1,0),0),
-              (1+0j,0), ("('RI',1,0)",0), ("toto",0), (None,0),
+   def test010(self):
+       """Test de listes de string"""
+       cata=SIMP(statut='o',typ='TXM',min=1,max=6)
+       liste=(
+              ("aa",OK),("aaa",OK),
+              (("aaaa","aaaaa","axyzaa","bbbbaaa","zzz"),OK),
+              (("aaaa","aaaa","axyz","bbbb","zzz"),OK),
+              (("aaaa","axyz","bbbb","zzz"),OK),
+              ("aaaa",OK),("aaaaa",OK),
+              ("axyzaa",OK),("bbbbaaa",OK),
              )
-       for valeur,valid in liste:
-           o=cata(valeur,'mcs',None)
-           #print o.val,o.valeur
-           msg="erreur sur le test %s %s" % (valeur,valid)+'\n'+str(o.report())
-           self.assertEqual(o.isvalid(),valid,msg=msg)
+       self._test(cata,liste)
 
-   def test004(self):
-       cata=SIMP(typ='C',statut='o',max=10)
-       liste=((1,1),("a",0), (1.,1),(('RI',1.,0.),1), (('RI',1,0),1), (1+0j,1),
-              (('RI',Variable('x',1.),0.),1),
-              (Variable('x',1.),1),
-              (Variable('x',1.)+0j,1),
-              ((Variable('x',1.)+0j,1.,0.,Variable('x',1.+2j),Variable('x',Variable('y',1.)+2j)),1),
-              ("('RI',1,0)",0), ("toto",0), (None,0),
-              (Variable('x',(1,2,2+5j)),1),
-              (Variable('x',(1,2,2+5j,5,6,7,8,9,10,11,12)),0),
-              (Variable('x',(1,2,2+5j,5,6,Variable('y',1+4j),8,9,10,11,12)),0),
-              (Variable('x',(1,"aaaa",2+5j,5,6,Variable('y',1+4j),8,9,10,11,12)),0),
-              (1+Variable('x',1.)*1j,1),
+   def test011(self):
+       """Test de listes de string avec into"""
+       cata=SIMP(statut='o',typ='TXM',min=1,max=6,into =( "TUTU","TATA","CCCC"))
+       liste=(
+              ("TUTU",OK),("TATA",OK),
+              (("TUTU","TATA","CCCC"),OK),
+              (("TUTU","TATA","CCCC","TUTU","TATA","CCCC"),OK),
+              (("TUTU","TATA","CCCC","TUTU","TATA","CCCC","TUTU","TATA","CCCC"),
+"""Mot-clé simple : mcs
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Nombre d'arguments de ('TUTU', 'TATA', 'CCCC', 'TUTU', 'TATA', 'CCCC', 'TUTU', !
+   ! 'TATA', 'CCCC') incorrect (min = 1, max = 6)                                   !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Fin Mot-clé simple : mcs
+"""),
+              (("TUTU","TATA","CCCC","TUTU","TATA",1,"TUTU","TATA","CCCC"),
+"""Mot-clé simple : mcs
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! 1 n'est pas d'un type autorisé: ('TXM',) !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! La valeur : 1  ne fait pas partie des choix possibles ('TUTU', 'TATA', 'CCCC') !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Nombre d'arguments de ('TUTU', 'TATA', 'CCCC', 'TUTU', 'TATA', 1, 'TUTU', 'TATA', !
+   !  'CCCC') incorrect (min = 1, max = 6)                                             !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Fin Mot-clé simple : mcs
+"""),
              )
-       for valeur,valid in liste:
-           o=cata(valeur,'mcs',None)
-           self.assertEqual(o.isvalid(),valid,"erreur sur le test %s %s" % (valeur,valid)+'\n'+str(o.report()))
-           if valid: self.assertEqual(o.get_valeur(),valeur)
+       self._test(cata,liste)
 
-   def test005(self):
-       t=Variable('t',None)
-       assert len(t) == 0
+   def test016(self):
+       """Test de listes d'entiers """
+       cata=SIMP(statut='o',typ='I',min=1,max=6)
+       liste=( ((2,),OK),(None,
+"""Mot-clé simple : mcs
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé :  mcs  obligatoire non valorisé !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! None n'est pas une valeur autorisée !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Fin Mot-clé simple : mcs
+"""),
+               ((1,3,5),OK),
+               ((2,4,6),OK),
+               ((2,4,4),OK),
+               (myparam((2,4,4)),OK),
+               (myparam((2,4.5,4)),
+"""Mot-clé simple : mcs
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! 4.5 n'est pas d'un type autorisé: ('I',) !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Fin Mot-clé simple : mcs
+"""),
+               (myparam((2,myparam(4.5),4)),
+"""Mot-clé simple : mcs
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! 4.5 n'est pas d'un type autorisé: ('I',) !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Fin Mot-clé simple : mcs
+"""),
+               (param((2,4,4)),OK),
+               (param((2,4.5,4)),
+"""Mot-clé simple : mcs
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! 4.5 n'est pas d'un type autorisé: ('I',) !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Fin Mot-clé simple : mcs
+"""),
+               (param((2,param(4.5),4)),
+"""Mot-clé simple : mcs
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! 4.5 n'est pas d'un type autorisé: ('I',) !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Fin Mot-clé simple : mcs
+"""),
+             )
+       self._test(cata,liste)
index 19554c20662e2955fc1e7eaec8f5507934cd2909..6519dabda45a0eab1300810f84fe6ecb67243c44 100644 (file)
@@ -17,13 +17,12 @@ class TestMCSimpCase(unittest.TestCase):
       o=cata((1,2,'aa','bb',7,'cc'),'mcs1',None)
       cr=o.report()
       expected_cr="""Mot-clé simple : mcs1
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! 'aa' n'est pas d'un type autorisé !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Nombre d'arguments de (1, 2, 'aa', 'bb', 7, 'cc') incorrect pour mcs1 (min = 1, !
-   ! max = 5)                                                                        !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! 'aa' n'est pas d'un type autorisé: ('I',) !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Nombre d'arguments de (1, 2, 'aa', 'bb', 7, 'cc') incorrect (min = 1, max = 5) !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Fin Mot-clé simple : mcs1
 """
       self.assertEqual(str(cr) , expected_cr,msg='Erreur :\n%s\n!=\n%s' % (str(cr),expected_cr))
@@ -33,9 +32,9 @@ Fin Mot-cl
       o=cata((1,2,'aa','bb',7,'cc'),'mcs1',None)
       cr=o.report()
       expected_cr="""Mot-clé simple : mcs1
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! 'aa' n'est pas d'un type autorisé !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! 'aa' n'est pas d'un type autorisé: ('I',) !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Fin Mot-clé simple : mcs1
 """
       self.assertEqual(str(cr) , expected_cr,msg='Erreur :\n%s\n!=\n%s' % (str(cr),expected_cr))
@@ -45,9 +44,9 @@ Fin Mot-cl
       o=cata((1,2,7,3,4,5,6),'mcs1',None)
       cr=o.report()
       expected_cr="""Mot-clé simple : mcs1
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! La valeur : 3  n'est pas permise pour le mot-clé : mcs1 !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! La valeur : 3  ne fait pas partie des choix possibles (1, 2, 7) !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Fin Mot-clé simple : mcs1
 """
       self.assertEqual(str(cr) , expected_cr,msg='Erreur :\n%s\n!=\n%s' % (str(cr),expected_cr))
@@ -57,9 +56,9 @@ Fin Mot-cl
       o=cata((1,2,7,3,4,5,6),'mcs1',None)
       cr=o.report()
       expected_cr="""Mot-clé simple : mcs1
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! La valeur : 7  du mot-clé  mcs1  est en dehors du domaine de validité [ 6 , 6 ] !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! La valeur : 7 est en dehors du domaine de validité [ ** , 6 ] !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Fin Mot-clé simple : mcs1
 """
       self.assertEqual(str(cr) , expected_cr,msg='Erreur :\n%s\n!=\n%s' % (str(cr),expected_cr))
@@ -69,13 +68,12 @@ Fin Mot-cl
       o=cata((1,2,7,3,4,5,6),'mcs1',None)
       cr=o.report()
       expected_cr="""Mot-clé simple : mcs1
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! La valeur : 7  du mot-clé  mcs1  est en dehors du domaine de validité [ 6 , 6 ] !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Nombre d'arguments de (1, 2, 7, 3, 4, 5, 6) incorrect pour mcs1 (min = 1, max = !
-   ! 6)                                                                              !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! La valeur : 7 est en dehors du domaine de validité [ ** , 6 ] !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Nombre d'arguments de (1, 2, 7, 3, 4, 5, 6) incorrect (min = 1, max = 6) !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Fin Mot-clé simple : mcs1
 """
       self.assertEqual(str(cr) , expected_cr,msg='Erreur :\n%s\n!=\n%s' % (str(cr),expected_cr))
@@ -85,16 +83,15 @@ Fin Mot-cl
       o=cata((1,2,7,"aa",4,"bb",6),'mcs1',None)
       cr=o.report()
       expected_cr="""Mot-clé simple : mcs1
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! 'aa' n'est pas d'un type autorisé !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! La valeur : 7  du mot-clé  mcs1  est en dehors du domaine de validité [ 6 , 6 ] !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Nombre d'arguments de (1, 2, 7, 'aa', 4, 'bb', 6) incorrect pour mcs1 (min = 1, !
-   ! max = 6)                                                                        !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! 'aa' n'est pas d'un type autorisé: ('R',) !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! La valeur : 7 est en dehors du domaine de validité [ ** , 6 ] !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Nombre d'arguments de (1, 2, 7, 'aa', 4, 'bb', 6) incorrect (min = 1, max = 6) !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Fin Mot-clé simple : mcs1
 """
       self.assertEqual(str(cr) , expected_cr,msg='Erreur :\n%s\n!=\n%s' % (str(cr),expected_cr))
index 1a57431c2feb0f3a778120a59bf64dd482ec02b0..7390fef70db7af2330a4fb55142de885840738fc 100644 (file)
@@ -3,6 +3,25 @@ from Accas import *
 
 import unittest
 
+class myparam:
+    def __init__(self,valeur):
+        self.valeur=valeur
+    def __adapt__(self,protocol):
+        return protocol.adapt(self.valeur)
+
+from Noyau.N_VALIDATOR import listProto,TypeProtocol,IntoProtocol
+class param:
+    def __init__(self,valeur):
+        self.valeur=valeur
+
+def hasvaleur(obj,protocol,**args):
+    return protocol.adapt(obj.valeur)
+
+listProto.register(param,hasvaleur)
+TypeProtocol.register(param,hasvaleur)
+IntoProtocol.register(param,hasvaleur)
+OrdList.register(param,hasvaleur)
+
 class TestValidCase(unittest.TestCase):
    def setUp(self):
        pass
@@ -40,6 +59,7 @@ class TestValidCase(unittest.TestCase):
               (("aaaa","axyz","bbbb","zzz"),1),
               ("aaaa",1),("aaaaa",1),
               ("axyzaa",0),("bbbbaaa",0),
+              (("aaaa",param("axyz"),"bbbb","zzz"),1),
              )
        self._test(cata,liste)
 
@@ -58,6 +78,17 @@ class TestValidCase(unittest.TestCase):
               ((3,1),0),
               ((1,3,2),0),
               ((1.,2.),0),
+              (myparam((1.,2.)),0),
+              (myparam((1,2)),1),
+              (myparam((1,2,3,4,5)),1),
+              (myparam((1,2,myparam(3),4,5)),1),
+              (myparam((1,2,myparam(6),4,5)),0),
+              (param((1.,2.)),0),
+              (param((1,2)),1),
+              (param((1,2,3,4,5)),1),
+              (param((1,2,myparam(3),4,5)),1),
+              (param((1,2,param(3),4,5)),1),
+              (param((1,2,param(6),4,5)),0),
              )
        self._test(cata,liste)
 
@@ -120,6 +151,10 @@ class TestValidCase(unittest.TestCase):
               (("aaaa","axyz","bbbb","zzz"),1),
               ("aaaa",1),("aaaaa",1),
               ("axyzaa",1),("bbbbaaa",1),
+              (("aaaa",param("aaaaa"),"axyzaa","bbbbaaa","zzz"),1),
+              (("aaaa",param("aaaa"),"axyzaa","bbbbaaa","zzz"),0),
+              (("aaaa",myparam("aaaaa"),"axyzaa","bbbbaaa","zzz"),1),
+              (("aaaa",myparam("aaaa"),"axyzaa","bbbbaaa","zzz"),0),
              )
        self._test(cata,liste)
 
@@ -137,6 +172,8 @@ class TestValidCase(unittest.TestCase):
        cata=SIMP(statut='o',typ='I',min=1,max=1,into =( 1,2,3),validators=PairVal())
        liste=(
               (2,1),(1,0),(3,0),(4,0),
+              (param(2),1),(param(3),0),
+              (myparam(2),1),(myparam(3),0),
              )
        self._test(cata,liste)
 
index a8eb78f0118a2648b2b47f085d854bd79027ab71..f78f84331910d6dc3a7a9aab82bc0311ee0e1af5 100644 (file)
@@ -7,6 +7,7 @@ import compare
 OK="""Mot-clé simple : mcs
 Fin Mot-clé simple : mcs
 """
+from cata5 import entier
 
 class TestValidCase(unittest.TestCase):
    def setUp(self):
@@ -23,7 +24,6 @@ class TestValidCase(unittest.TestCase):
            valid=compare.check(rep,report)
            if not valid:
               msg="le rapport d'erreur est incorrect.\n valeur = %s\n expected =\n%s\n got =\n%s " % (valeur,report,rep)
-              #print msg
            self.assert_(valid,msg=msg)
 
    def test001(self):
@@ -31,31 +31,35 @@ class TestValidCase(unittest.TestCase):
        cata=SIMP(typ='TXM',validators=LongStr(3,5))
        liste=(("aa",
 """Mot-clé simple : mcs
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Mot-clé :  mcs devrait avoir  longueur de la chaine entre 3 et 5 !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : 'aa' n'est pas de la bonne longueur !
+   ! Critere de validite: longueur de la chaine entre 3 et 5    !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Fin Mot-clé simple : mcs
 """),("aaa",OK),
               ("aaaa",OK),("aaaaa",OK),
               ("axyzaa",
 """Mot-clé simple : mcs
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Mot-clé :  mcs devrait avoir  longueur de la chaine entre 3 et 5 !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : 'axyzaa' n'est pas de la bonne longueur !
+   ! Critere de validite: longueur de la chaine entre 3 et 5        !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Fin Mot-clé simple : mcs
 """),("bbbbaaa",
 """Mot-clé simple : mcs
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Mot-clé :  mcs devrait avoir  longueur de la chaine entre 3 et 5 !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : 'bbbbaaa' n'est pas de la bonne longueur !
+   ! Critere de validite: longueur de la chaine entre 3 et 5         !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Fin Mot-clé simple : mcs
 """),
               (Variable('x',"aaa"),OK),
               (Variable('x',"aaaaaaaaaaaa"),
 """Mot-clé simple : mcs
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Mot-clé :  mcs devrait avoir  longueur de la chaine entre 3 et 5 !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : 'aaaaaaaaaaaa' n'est pas de la bonne longueur !
+   ! Critere de validite: longueur de la chaine entre 3 et 5              !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Fin Mot-clé simple : mcs
 """),
              )
@@ -68,9 +72,10 @@ Fin Mot-cl
               (("aaaa","aaaaa","axyzaa","bbbbaaa","zzz"),OK),
               (("aaaa","aaaa","axyz","bbbb","zzz"),
 """Mot-clé simple : mcs
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Mot-clé :  mcs devrait avoir  : pas de présence de doublon dans la liste !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : aaaa est un doublon                      !
+   ! Critere de validite: : pas de présence de doublon dans la liste !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Fin Mot-clé simple : mcs
 """),
               (("aaaa","axyz","bbbb","zzz"),OK),
@@ -79,17 +84,19 @@ Fin Mot-cl
               (("aaa",Variable('x',"bbb")),OK),
               (("aaa",Variable('x',"aaa")),
 """Mot-clé simple : mcs
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Mot-clé :  mcs devrait avoir  : pas de présence de doublon dans la liste !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : aaa est un doublon                       !
+   ! Critere de validite: : pas de présence de doublon dans la liste !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Fin Mot-clé simple : mcs
 """),
               (Variable('x',("aaa","bbb")),OK),
               (Variable('x',("aaa","bbb","bbb")),
 """Mot-clé simple : mcs
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Mot-clé :  mcs devrait avoir  : pas de présence de doublon dans la liste !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : bbb est un doublon                       !
+   ! Critere de validite: : pas de présence de doublon dans la liste !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Fin Mot-clé simple : mcs
 """),
              )
@@ -102,16 +109,17 @@ Fin Mot-cl
               (("TUTU","TATA","CCCC"),OK),
               (("TUTU","TATA","CCCC","TUTU","TATA","CCCC"),
 """Mot-clé simple : mcs
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Mot-clé :  mcs devrait avoir  : pas de présence de doublon dans la liste !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : TUTU est un doublon                      !
+   ! Critere de validite: : pas de présence de doublon dans la liste !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Fin Mot-clé simple : mcs
 """),
               (("TUTU","TATA","CCCC","TUTU","TATA","CCCC","TUTU","TATA","CCCC"),
 """Mot-clé simple : mcs
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ! Nombre d'arguments de ('TUTU', 'TATA', 'CCCC', 'TUTU', 'TATA', 'CCCC', 'TUTU', !
-   ! 'TATA', 'CCCC') incorrect pour mcs (min = 1, max = 6)                          !
+   ! 'TATA', 'CCCC') incorrect (min = 1, max = 6)                                   !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Fin Mot-clé simple : mcs
 """),
@@ -132,20 +140,184 @@ Fin Mot-cl
 Fin Mot-clé simple : mcs
 """),((1,3,5),
 """Mot-clé simple : mcs
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Mot-clé :  mcs devrait avoir  : pas de présence de doublon dans la liste !
-   !  et valeur paire                                                         !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : (1, 3, 5) contient des valeurs non paires !
+   ! Critere de validite: : pas de présence de doublon dans la liste  !
+   !  et valeur paire                                                 !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Fin Mot-clé simple : mcs
 """),
                ((2,4,6),OK),
                ((2,4,4),
 """Mot-clé simple : mcs
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Mot-clé :  mcs devrait avoir  : pas de présence de doublon dans la liste !
-   !  et valeur paire                                                         !
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : 4 est un doublon                         !
+   ! Critere de validite: : pas de présence de doublon dans la liste !
+   !  et valeur paire                                                !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Fin Mot-clé simple : mcs
 """),
              )
        self._test(cata,liste)
+
+   def test017(self):
+       """Test du validateur NoRepeat avec objet entier """
+       cata=SIMP(statut='o',typ='I',min=1,max=6,validators=NoRepeat())
+       i=entier()
+       liste=( (i,OK),
+               ((i,i),OK),
+               ((1,i,i),OK),
+               ((i,1,i,i),OK),
+               ((1,1,i,i),
+"""Mot-clé simple : mcs
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : 1 est un doublon                         !
+   ! Critere de validite: : pas de présence de doublon dans la liste !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Fin Mot-clé simple : mcs
+""" ),
+               )
+       self._test(cata,liste)
+
+   def test018(self):
+       """Test du validateur OrdList('croissant') avec objet entier """
+       cata=SIMP(statut='o',typ='I',min=1,max=6,validators=OrdList('croissant'))
+       i=entier()
+       liste=( (i,OK),
+               ((i,i),OK),
+               ((1,i,i),OK),
+               ((i,1,i,i),OK),
+               ((2,1,i,i),
+"""Mot-clé simple : mcs
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : (2, 1, <concept entier>, <concept entier>) n'est pas par !
+   ! valeurs croissantes                                                             !
+   ! Critere de validite: liste croissant                                            !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Fin Mot-clé simple : mcs
+"""),
+               )
+       self._test(cata,liste)
+
+   def test019(self):
+       """Test du validateur Compulsory avec objet entier """
+       cata=SIMP(statut='o',typ='I',min=1,max=6,validators=Compulsory((5,6,7)))
+       i=entier()
+       liste=( ((5,6,7),OK),
+               ((5,6,7,i),OK),
+               ((i,5,6,7,i),OK),
+               ((i,5,7,i),
+"""Mot-clé simple : mcs
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : (<concept entier>, 5, 7, <concept entier>) ne contient !
+   ! pas les elements obligatoires : [6]                                           !
+   ! Critere de validite: valeur (5, 6, 7) obligatoire                             !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Fin Mot-clé simple : mcs
+""" ),
+               )
+       self._test(cata,liste)
+
+   def test020(self):
+       """Test du validateur NoRepeat OU Compulsory avec objet entier """
+       cata=SIMP(statut='o',typ='I',min=1,max=6,validators=(NoRepeat(),Compulsory((5,6,7))))
+       i=entier()
+       liste=( ((5,6,7),OK),
+               ((5,6,7,i),OK),
+               ((i,5,6,7,i),OK),
+               ((i,5,7,i), OK ),
+               )
+       self._test(cata,liste)
+
+   def test021(self):
+       """Test du validateur NoRepeat ET Compulsory avec objet entier """
+       cata=SIMP(statut='o',typ='I',min=1,max=6,validators=[NoRepeat(),Compulsory((5,6,7))])
+       i=entier()
+       liste=( ((5,6,7),OK),
+               ((5,6,7,i),OK),
+               ((i,5,6,7,i),OK),
+               ((i,5,7,i),
+"""Mot-clé simple : mcs
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : (<concept entier>, 5, 7, <concept entier>) ne contient !
+   ! pas les elements obligatoires : [6]                                           !
+   ! Critere de validite: : pas de présence de doublon dans la liste               !
+   !  et valeur (5, 6, 7) obligatoire                                              !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Fin Mot-clé simple : mcs
+""" ),
+               )
+       self._test(cata,liste)
+
+   def test022(self):
+       """Test du validateur Compulsory(5,6,7) ET OrdList('croissant') avec objet entier """
+       cata=SIMP(statut='o',typ='I',min=1,max=6,validators=[Compulsory((5,6,7)),OrdList('croissant')])
+       i=entier()
+       liste=( ((5,6,7),OK),
+               ((5,6,7,i),OK),
+               ((i,5,6,7,i),OK),
+               ((i,5,7,i),
+"""Mot-clé simple : mcs
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : (<concept entier>, 5, 7, <concept entier>) ne contient !
+   ! pas les elements obligatoires : [6]                                           !
+   ! Critere de validite: valeur (5, 6, 7) obligatoire                             !
+   !  et liste croissant                                                           !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Fin Mot-clé simple : mcs
+""" ),
+               ((i,5,7,i,6),
+"""Mot-clé simple : mcs
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : (<concept entier>, 5, 7, <concept entier>, 6) n'est pas !
+   ! par valeurs croissantes                                                        !
+   ! Critere de validite: valeur (5, 6, 7) obligatoire                              !
+   !  et liste croissant                                                            !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Fin Mot-clé simple : mcs
+""" ),
+               )
+       self._test(cata,liste)
+
+   def test023(self):
+       """Test du validateur Compulsory(5,6,7) ET OrdList('croissant') ET NoRepeat() avec objet entier """
+       cata=SIMP(statut='o',typ='I',min=1,max=6,validators=[Compulsory((5,6,7)),OrdList('croissant'),NoRepeat()])
+       i=entier()
+       liste=( ((5,6,7),OK),
+               ((5,6,7,i),OK),
+               ((i,5,6,7,i),OK),
+               ((i,5,7,i),
+"""Mot-clé simple : mcs
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : (<concept entier>, 5, 7, <concept entier>) ne contient !
+   ! pas les elements obligatoires : [6]                                           !
+   ! Critere de validite: valeur (5, 6, 7) obligatoire                             !
+   !  et liste croissant                                                           !
+   !  et : pas de présence de doublon dans la liste                                !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Fin Mot-clé simple : mcs
+""" ),
+               ((i,5,7,i,6),
+"""Mot-clé simple : mcs
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : (<concept entier>, 5, 7, <concept entier>, 6) n'est pas !
+   ! par valeurs croissantes                                                        !
+   ! Critere de validite: valeur (5, 6, 7) obligatoire                              !
+   !  et liste croissant                                                            !
+   !  et : pas de présence de doublon dans la liste                                 !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Fin Mot-clé simple : mcs
+""" ),
+               ((i,5,i,6,7,7),
+"""Mot-clé simple : mcs
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! Mot-clé mcs invalide : 7 est un doublon           !
+   ! Critere de validite: valeur (5, 6, 7) obligatoire !
+   !  et liste croissant                               !
+   !  et : pas de présence de doublon dans la liste    !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Fin Mot-clé simple : mcs
+""" ),
+               ((i,5,6,7,i,8),OK),
+               )
+       self._test(cata,liste)
index d751135273ff6937163580bd3a4c1ab37b503faf..e55e8d7de0a4488d91c19c25cbc177d1e2e70122 100644 (file)
@@ -1,4 +1,4 @@
-#@ MODIF V_MCCOMPO Validation  DATE 14/09/2004   AUTEUR MCOURTOI M.COURTOIS 
+#@ MODIF V_MCCOMPO Validation  DATE 10/05/2006   AUTEUR MCOURTOI M.COURTOIS 
 # -*- coding: iso-8859-1 -*-
 #            CONFIGURATION MANAGEMENT OF EDF VERSION
 # ======================================================================
@@ -117,6 +117,8 @@ class MCCOMPO:
         if not v.defaut : continue
         if not dico.has_key(k):
           dico[k]=v(nom=k,val=None,parent=self)
+      #on ajoute l'objet detenteur de regles pour des validations plus sophistiquees (a manipuler avec precaution)
+      dico["self"]=self
       return dico
 
 
index 99e48aa8a34c65ccaa57642064a0ea2fe92fc9fa..8e69333d7e7faf81e6dbc9e19c62007428a89eae 100644 (file)
@@ -1,4 +1,4 @@
-#@ MODIF V_MCSIMP Validation  DATE 19/09/2005   AUTEUR DURAND C.DURAND 
+#@ MODIF V_MCSIMP Validation  DATE 16/05/2006   AUTEUR DURAND C.DURAND 
 # -*- coding: iso-8859-1 -*-
 #            CONFIGURATION MANAGEMENT OF EDF VERSION
 # ======================================================================
@@ -35,6 +35,8 @@ import traceback
 # Modules EFICAS
 from Noyau import N_CR
 from Noyau.N_Exception import AsException
+from Noyau.N_VALIDATOR import ValError,TypeProtocol,CardProtocol,IntoProtocol
+from Noyau.N_VALIDATOR import listProto
 
 class MCSIMP:
    """
@@ -59,6 +61,9 @@ class MCSIMP:
    
    def __init__(self):
       self.state='undetermined'
+      self.typeProto=TypeProtocol("type",typ=self.definition.type)
+      self.intoProto=IntoProtocol("into",into=self.definition.into,val_min=self.definition.val_min,val_max=self.definition.val_max)
+      self.cardProto=CardProtocol("card",min=self.definition.min,max=self.definition.max)
 
    def get_valid(self):
        if hasattr(self,'valid'):
@@ -96,22 +101,61 @@ class MCSIMP:
             self.cr.fatal(string.join(("Mot-clé : ",self.nom," obligatoire non valorisé")))
           valid = 0
 
-        if v is None:
+        lval=listProto.adapt(v)
+        if lval is None:
            valid=0
            if cr == 'oui' :
               self.cr.fatal("None n'est pas une valeur autorisée")
         else:
            # type,into ...
-           valid = self.verif_type(val=v,cr=cr)*self.verif_into(cr=cr)*self.verif_card(cr=cr)
-           #
-           # On verifie les validateurs s'il y en a et si necessaire (valid == 1)
-           #
-           if valid and self.definition.validators and not self.definition.validators.verif(self.valeur):
-              if cr == 'oui' :
-                 self.cr.fatal(string.join(("Mot-clé : ",self.nom,"devrait avoir ",self.definition.validators.info())))
-              valid=0
-           # fin des validateurs
-           #
+           #typeProto=TypeProtocol("type",typ=self.definition.type)
+           #intoProto=IntoProtocol("into",into=self.definition.into,val_min=self.definition.val_min,val_max=self.definition.val_max)
+           #cardProto=CardProtocol("card",min=self.definition.min,max=self.definition.max)
+           #typeProto=self.definition.typeProto
+           #intoProto=self.definition.intoProto
+           #cardProto=self.definition.cardProto
+           typeProto=self.typeProto
+           intoProto=self.intoProto
+           cardProto=self.cardProto
+           if cr == 'oui' :
+               #un cr est demandé : on collecte tous les types d'erreur
+               try:
+                   for val in lval:
+                       typeProto.adapt(val)
+               except ValError,e:
+                   valid=0
+                   self.cr.fatal(str(e))
+               try:
+                   for val in lval:
+                       intoProto.adapt(val)
+               except ValError,e:
+                   valid=0
+                   self.cr.fatal(str(e))
+               try:
+                   cardProto.adapt(lval)
+               except ValError,e:
+                   valid=0
+                   self.cr.fatal(str(e))
+               #
+               # On verifie les validateurs s'il y en a et si necessaire (valid == 1)
+               #
+               if valid and self.definition.validators:
+                   try:
+                       self.definition.validators.convert(lval)
+                   except ValError,e:
+                       self.cr.fatal(string.join(("Mot-clé",self.nom,"invalide :",str(e),"\nCritere de validite:",self.definition.validators.info())))
+                       valid=0
+           else:
+               #si pas de cr demande, on sort a la toute premiere erreur 
+               try:
+                   for val in lval:
+                       typeProto.adapt(val)
+                       intoProto.adapt(val)
+                   cardProto.adapt(lval)
+                   if self.definition.validators:
+                       self.definition.validators.convert(lval)
+               except ValError,e:
+                   valid=0
 
         self.set_valid(valid)
         return self.valid
@@ -121,259 +165,6 @@ class MCSIMP:
       """
       return self.definition.statut=='o'
 
-   def verif_card(self,cr='non'):
-      """ 
-         un mot-clé simple ne peut etre répété :
-           la cardinalité ici s'entend par la vérification que le nombre d'arguments de self.valeur
-           est bien compris entre self.min et self.max dans le cas où il s'agit d'une liste
-      """
-      card = 1
-      min=self.definition.min
-      max=self.definition.max
-
-      if type(self.valeur) == types.TupleType and not self.valeur[0] in ('RI','MP') or type(self.valeur) == types.ListType:
-        length=len(self.valeur)
-      else:
-        if self.valeur == None :
-           length=0
-        else:
-           length=1
-
-      if length < min or length >max:
-         if cr == 'oui':
-            self.cr.fatal("Nombre d'arguments de %s incorrect pour %s (min = %s, max = %s)" %(`self.valeur`,self.nom,min,max))
-         card = 0
-      return card
-
-   def verif_type(self,val=None,cr='non'):
-      """
-        FONCTION :
-         Cette methode verifie que le type de l'argument val est en conformite avec celui 
-         qui est declare dans la definition du mot cle simple.
-         Elle a plusieurs modes de fonctionnement liés à la valeur de cr.
-         Si cr vaut 'oui' : elle remplit le compte-rendu self.cr sinon elle ne le remplit pas.
-        PARAMETRE DE RETOUR :
-         Cette méthode retourne une valeur booléenne qui vaut 1 si le type de val est correct ou 0 sinon
-         
-      """
-      valeur = val
-      if valeur == None :
-        if cr == 'oui':
-          self.cr.fatal("None n'est pas une valeur autorisée")
-        return 0
-
-      if type(valeur) == types.TupleType and not valeur[0] in ('RI','MP') or type(valeur) == types.ListType:
-        # Ici on a identifié une liste de valeurs
-        for val in valeur:
-            if not self.verif_type(val=val,cr=cr) : return 0
-        return 1
-
-      # Ici, valeur est un scalaire ...il faut tester sur tous les types ou les valeurs possibles
-
-      for type_permis in self.definition.type:
-          if self.compare_type(valeur,type_permis) : return 1
-
-      # si on sort de la boucle précédente par ici c'est que l'on n'a trouvé aucun type valable --> valeur refusée
-      if cr =='oui':
-          self.cr.fatal("%s n'est pas d'un type autorisé" %`valeur`)
-      return 0
-
-   def verif_into(self,cr='non'):
-      """
-      Vérifie si la valeur de self est bien dans l'ensemble discret de valeurs
-      donné dans le catalogue derrière l'attribut into ou vérifie que valeur est bien compris
-      entre val_min et val_max
-      """
-      if self.definition.into == None :
-        #on est dans le cas d'un ensemble continu de valeurs possibles (intervalle)
-        if self.definition.val_min == '**' and self.definition.val_max == '**':
-           # L'intervalle est infini, on ne fait pas de test
-           return 1
-        if type(self.valeur) == types.TupleType and not self.valeur[0] in ('RI','MP') or type(self.valeur) == types.ListType:
-          # Cas d'une liste de valeurs
-          test = 1
-          for val in self.valeur :
-            if type(val) != types.StringType and type(val) != types.InstanceType:
-              test = test*self.isinintervalle(val,cr=cr)
-          return test
-        else :
-          # Cas d'un scalaire
-          val = self.valeur
-          if type(val)!=types.StringType and type(val)!=types.InstanceType:
-            return self.isinintervalle(self.valeur,cr=cr)
-          else :
-            return 1
-      else :
-        # on est dans le cas d'un ensemble discret de valeurs possibles (into)
-        if type(self.valeur) == types.TupleType and not self.valeur[0] in ('RI','MP') or type(self.valeur) == types.ListType:
-          # Cas d'une liste de valeur
-          for e in self.valeur:
-            if e not in self.definition.into:
-              if cr=='oui':
-                self.cr.fatal(string.join(("La valeur :",`e`," n'est pas permise pour le mot-clé :",self.nom)))
-              return 0
-        else:
-          if self.valeur not in self.definition.into:
-            if cr=='oui':
-              self.cr.fatal(string.join(("La valeur :",`self.valeur`," n'est pas permise pour le mot-clé :",self.nom)))
-            return 0
-        return 1
-
-   def is_complexe(self,valeur):
-      """ Retourne 1 si valeur est un complexe, 0 sinon """
-      if type(valeur) == types.InstanceType :
-        #XXX je n'y touche pas pour ne pas tout casser mais il serait
-        #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('C'), par exemple
-        if valeur.__class__.__name__ in ('complexe','PARAMETRE_EVAL'):
-          return 1
-        elif valeur.__class__.__name__ in ('PARAMETRE',):
-          # il faut tester si la valeur du parametre est un complexe
-          return self.is_complexe(valeur.valeur)
-        else:
-          return 0
-      elif type(valeur) in (types.ComplexType,types.IntType,types.FloatType,types.LongType):
-      # Pour permettre l'utilisation de complexes Python
-        return 1
-      elif type(valeur) != types.TupleType :
-        # On n'autorise pas les listes pour les complexes
-        return 0
-      elif len(valeur) != 3:return 0
-      else:
-          # Un complexe doit etre un tuple de longueur 3 avec 'RI' ou 'MP' comme premiere
-          # valeur suivie de 2 reels.
-          try:
-             if string.strip(valeur[0]) in ('RI','MP') and self.is_reel(valeur[1]) and self.is_reel(valeur[2]):
-                return 1
-          except:
-             return 0
-
-   def is_reel(self,valeur):
-      """
-      Retourne 1 si valeur est un reel, 0 sinon
-      """
-      if type(valeur) == types.InstanceType :
-        #XXX je n'y touche pas pour ne pas tout casser mais il serait
-        #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('R'), par exemple
-        #XXX ou valeur.is_reel()
-        #XXX ou encore valeur.compare(self.is_reel)
-        if valeur.__class__.__name__ in ('reel','PARAMETRE_EVAL') :
-          return 1
-        elif valeur.__class__.__name__ in ('PARAMETRE',):
-          # il faut tester si la valeur du parametre est un réel
-          return self.is_reel(valeur.valeur)
-        else:
-          return 0
-      elif type(valeur) not in (types.IntType,types.FloatType,types.LongType):
-        # ce n'est pas un réel
-        return 0
-      else:
-        return 1
-
-   def is_entier(self,valeur):
-      """ Retourne 1 si valeur est un entier, 0 sinon """
-      if type(valeur) == types.InstanceType :
-        #XXX je n'y touche pas pour ne pas tout casser mais il serait
-        #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('I'), par exemple
-        if valeur.__class__.__name__ in ('entier','PARAMETRE_EVAL') :
-          return 1
-        elif valeur.__class__.__name__ in ('PARAMETRE',):
-          # il faut tester si la valeur du parametre est un entier
-          return self.is_entier(valeur.valeur)
-        else:
-          return 0
-      elif type(valeur) not in (types.IntType,types.LongType):
-        # ce n'est pas un entier
-        return 0
-      else:
-        return 1
-
-   def is_shell(self,valeur):
-      """ 
-          Retourne 1 si valeur est un shell, 0 sinon
-          Pour l'instant aucune vérification n'est faite
-          On impose juste que valeur soit une string
-      """
-      if type(valeur) != types.StringType:
-        return 0
-      else:
-        return 1
-
-   def is_object_from(self,objet,classe):
-      """
-           Retourne 1 si objet est une instance de la classe classe, 0 sinon
-      """
-      if type(objet) != types.InstanceType :
-        return 0
-
-      if isinstance(objet,classe) :
-        # On accepte les instances de la classe et des classes derivees 
-        return 1
-
-      return 0
-
-   def compare_type(self,valeur,type_permis):
-      """
-          Fonction booléenne qui retourne 1 si valeur est du type type_permis, 0 sinon
-      """
-      if type(valeur) == types.InstanceType and valeur.__class__.__name__ == 'PARAMETRE':
-        if type(valeur.valeur) == types.TupleType :
-          # on a à faire à un PARAMETRE qui définit une liste d'items
-          # --> on teste sur la première car on n'accepte que les liste homogènes
-          valeur = valeur.valeur[0]
-      if type_permis == 'R':
-        return self.is_reel(valeur)
-      elif type_permis == 'I':
-        return self.is_entier(valeur)
-      elif type_permis == 'C':
-        return self.is_complexe(valeur)
-      elif type_permis == 'shell':
-        return self.is_shell(valeur)
-      elif type_permis == 'TXM':
-        if type(valeur) != types.InstanceType:
-          return type(valeur)==types.StringType
-        else:
-          #XXX je n'y touche pas pour ne pas tout casser mais il serait
-          #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('TXM'), par exemple
-          if valeur.__class__.__name__ == 'chaine' :
-            return 1
-          elif valeur.__class__.__name__ == 'PARAMETRE':
-            # il faut tester si la valeur du parametre est une string
-            return type(valeur.valeur)==types.StringType
-          else:
-            return 0
-      elif type(type_permis) == types.ClassType:
-        # on ne teste pas certains objets de type GEOM , assd, ...
-        # On appelle la méthode de classe is_object de type_permis.
-        # Comme valeur peut etre de n'importe quel type on utilise la fonction (is_object.im_func)
-        # et non pas la methode (is_object) ce qui risquerait de provoquer des erreurs
-        if type_permis.is_object.im_func(valeur):
-          return 1
-        else :
-          return self.is_object_from(valeur,type_permis)
-      else:
-        print "Type non encore géré %s" %`type_permis`
-        print self.nom,self.parent.nom,self.jdc.fichier
-
-   def isinintervalle(self,valeur,cr='non'):
-      """
-      Booléenne qui retourne 1 si la valeur passée en argument est comprise dans
-      le domaine de définition donné dans le catalogue, 0 sinon.
-      """
-      if type(valeur) not in (types.IntType,types.FloatType,types.LongType) :
-        return 1
-      else :
-        min = self.definition.val_min
-        max = self.definition.val_max
-        if min == '**': min = valeur -1
-        if max == '**': max = valeur +1
-        if valeur < min or valeur > max :
-          if cr=='oui':
-            self.cr.fatal(string.join(("La valeur :",`valeur`," du mot-clé ",self.nom,\
-                                       " est en dehors du domaine de validité [",`min`,",",`max`,"]")))
-          return 0
-        else :
-          return 1
-
    def init_modif_up(self):
       """
          Propage l'état modifié au parent s'il existe et n'est l'objet