#! /usr/bin/env python
# -*- coding: iso-8859-1 -*-
#-----------------------------------------------------------------------------
# Modeling Framework: an Object-Relational Bridge for python
#
# Copyright (c) 2001-2004 Sbastien Bigaret <sbigaret@users.sourceforge.net>
# All rights reserved.
#
# This file is part of the Modeling Framework.
#
# This code is distributed under a "3-clause BSD"-style license;
# see the LICENSE file for details.
#-----------------------------------------------------------------------------
"""Tests for Qualifiers"""
import unittest
if __name__ == "__main__":
import utils, sys
utils.fixpath()
from Modeling.KeyValueCoding import KeyValueCoding
from Modeling.Qualifier import *
# Classes for tests
from testPackages.AuthorBook.Writer import Writer
from testPackages.AuthorBook.Book import Book
## Tests begin here
class TestOperatorQualifiers(unittest.TestCase):
"Empty for now"
def test_01_Equal(self):
"[Qualifier] QualifierOperatorEqual"
self.failUnless(QualifierOperatorEqual('test1', 'test1'), '1/')
self.failUnless(QualifierOperatorEqual(1, 1), '2/')
self.failIf(QualifierOperatorEqual('test1', '1'), '3/')
self.failIf(QualifierOperatorEqual(1, 2), '4/')
def test_02_NotEqual(self):
"[Qualifier] QualifierOperatorNotEqual"
self.failUnless(QualifierOperatorNotEqual('test1', 'test2'), '1/')
self.failUnless(QualifierOperatorNotEqual(1, 2), '2/')
self.failIf(QualifierOperatorNotEqual('test1', 'test1'), '3/')
self.failIf(QualifierOperatorNotEqual(1, 1), '4/')
def test_03_GreaterThan(self):
"[Qualifier] QualifierOperatorGreaterThan"
self.failUnless(QualifierOperatorGreaterThan('test2', 'test1'), '1/')
self.failUnless(QualifierOperatorGreaterThan(2, 1), '2/')
self.failIf(QualifierOperatorGreaterThan('test1', 'zywv'), '3/')
self.failIf(QualifierOperatorGreaterThan(0, 1), '4/')
def test_04_GreaterThanOrEqualTo(self):
"[Qualifier] QualifierOperatorGreaterThanOrEqualTo"
self.failUnless(QualifierOperatorGreaterThanOrEqualTo('zxy', 'abc'), '1/')
self.failUnless(QualifierOperatorGreaterThanOrEqualTo('zxy', 'zxy'), '2/')
self.failIf(QualifierOperatorGreaterThanOrEqualTo('abc', 'zxy'), '3/')
self.failUnless(QualifierOperatorGreaterThanOrEqualTo(2, 1), '4/')
self.failUnless(QualifierOperatorGreaterThanOrEqualTo(2, 2), '5/')
self.failIf(QualifierOperatorGreaterThanOrEqualTo(2, 4), '6/')
def test_05_LessThan(self):
"[Qualifier] QualifierOperatorLessThan"
self.failUnless(QualifierOperatorLessThan('test1', 'test2'), '1/')
self.failUnless(QualifierOperatorLessThan(1, 2), '2/')
self.failIf(QualifierOperatorLessThan('zywv', 'test1'), '3/')
self.failIf(QualifierOperatorLessThan(1, 0), '4/')
def test_06_LessThanOrEqualTo(self):
"[Qualifier] QualifierOperatorLessThanOrEqualTo"
self.failUnless(QualifierOperatorLessThanOrEqualTo('abc', 'zxy'), '1/')
self.failUnless(QualifierOperatorLessThanOrEqualTo('abc', 'abc'), '2/')
self.failIf(QualifierOperatorLessThanOrEqualTo('zxy', 'abc'), '3/')
self.failUnless(QualifierOperatorLessThanOrEqualTo(1, 2), '4/')
self.failUnless(QualifierOperatorLessThanOrEqualTo(2, 2), '5/')
self.failIf(QualifierOperatorLessThanOrEqualTo(4, 2), '6/')
def test_07_Contains(self):
"[Qualifier] QualifierOperatorContains"
self.failUnless(QualifierOperatorContains('John Cleese', 'John'))
self.failUnless(QualifierOperatorContains('John Cleese', 'hn C'))
self.failIf(QualifierOperatorContains('John Cleese', 'john'))
def test_08_Like(self):
"[Qualifier] QualifierOperatorLike"
self.failUnless(QualifierOperatorLike('John Cleese', 'John*'))
self.failUnless(QualifierOperatorLike('John Cleese', '*ohn*'))
self.failUnless(QualifierOperatorLike('John Cleese', '*John*'))
self.failUnless(QualifierOperatorLike('John Cleese', '*ohn Cleese'))
self.failUnless(QualifierOperatorLike('John', 'Jo?n'))
self.failUnless(QualifierOperatorLike(123, '1?3'))
self.failIf(QualifierOperatorLike('John', 'jo?n'))
self.failIf(QualifierOperatorLike(54352, '54?352'))
self.failUnless(QualifierOperatorLike('John Cleese', '*ohn C?e?s*'))
def test_09_CaseInsensitiveLike(self):
"[Qualifier] QualifierOperatorLike"
self.failUnless(QualifierOperatorCaseInsensitiveLike('John Cleese',
'JOhN*'))
self.failUnless(QualifierOperatorCaseInsensitiveLike('John Cleese',
'*OHN*'))
self.failUnless(QualifierOperatorCaseInsensitiveLike('John Cleese',
'*ohn CLeESe'))
self.failUnless(QualifierOperatorCaseInsensitiveLike('John', 'Jo?N'))
self.failUnless(QualifierOperatorCaseInsensitiveLike('John Cleese',
'*OHN C?E?S*'))
self.failIf(QualifierOperatorLike('John', 'jo?n'))
class TestQualifiers(unittest.TestCase):
def test_01_KeyComparisonQualifier(self):
"[Qualifier] KeyComparisonQualifier"
actor=Writer()
boss=Writer()
actor.setBoss(boss)
boss.age=35
qual=KeyComparisonQualifier('age', QualifierOperatorLessThanOrEqualTo,
'boss.age')
self.failUnless(qual.evaluateWithObject(actor), 'KeyComp.Qual. 1')
def test_02_KeyValueQualifier(self):
"[Qualifier] KeyValueQualifier"
actor=Writer()
kvqual=KeyValueQualifier('lastName', QualifierOperatorEqual, 'Cleese')
self.failUnless(kvqual.evaluateWithObject(actor), 'KeyValueQ. 1/3')
kvqual=KeyValueQualifier('firstName', QualifierOperatorLike, '*John*')
self.failUnless(kvqual.evaluateWithObject(actor), 'KeyValueQ. 2/3')
kvqual=KeyValueQualifier('book.title', QualifierOperatorLike, 'Flying*')
self.failUnless(kvqual.evaluateWithObject(actor), 'KeyValueQ. 3/3')
kvqual=KeyValueQualifier('book.title', QualifierOperatorLike, '*book*')
self.failIf(kvqual.evaluateWithObject(actor), 'KeyValueQ. 3/3')
def test_03_NotQualifier(self):
"[Qualifier] NotQualifier"
actor=Writer()
boss=Writer()
actor.setBoss(boss)
boss.age=35
qual=KeyComparisonQualifier('age', QualifierOperatorLessThanOrEqualTo,
'boss.age')
notQual=NotQualifier(qual)
self.failIf(notQual.evaluateWithObject(actor), 'NotQualifier 1')
qual=KeyValueQualifier('book.title', QualifierOperatorLike, '*circus*')
notQual=NotQualifier(qual)
self.failUnless(notQual.evaluateWithObject(actor), 'NotQualifier 2')
def test_04_AndQualifier(self):
"[Qualifier] AndQualifier"
actor=Writer()
boss=Writer()
actor.setBoss(boss)
boss.age=35
# simple test
qual1=KeyComparisonQualifier('age', QualifierOperatorLessThanOrEqualTo,
'boss.age')
qual2=KeyValueQualifier('book.title',
QualifierOperatorCaseInsensitiveLike,
'flying circus diary')
qual=AndQualifier((qual1, qual2))
self.failUnless(qual.evaluateWithObject(actor))
# Tests that it exits immediately: if 'boss.boss.name' is evaluated an
# exception is raised, hence this should not raise
qual1=KeyComparisonQualifier('age', QualifierOperatorGreaterThan,
'boss.age')
qual2=KeyValueQualifier('boss.name',
QualifierOperatorCaseInsensitiveLike,
'John Doe')
qual=AndQualifier((qual1, qual2))
self.failIf(qual.evaluateWithObject(actor))
def test_05_OrQualifier(self):
"[Qualifier] OrQualifier"
actor=Writer()
boss=Writer()
actor.setBoss(boss)
boss.age=35
# simple test
qual1=KeyComparisonQualifier('age', QualifierOperatorGreaterThan,
'boss.age')
qual2=KeyValueQualifier('book.title',
QualifierOperatorCaseInsensitiveLike,
'flying circus diary')
qual=OrQualifier((qual1, qual2))
self.failUnless(qual.evaluateWithObject(actor), 'OrQualifier 1')
# Tests that it exits immediately: if 'boss.boss.name' is evaluated an
# exception is raised, hence this should not raise
qual1=KeyComparisonQualifier('age', QualifierOperatorLessThan,
'boss.age')
qual2=KeyValueQualifier('boss.name',
QualifierOperatorCaseInsensitiveLike,
'John Doe')
qual=OrQualifier((qual1, qual2))
self.failUnless(qual.evaluateWithObject(actor), 'OrQualifier 2')
## The following tests uses module functions, so they'd better be triggered
## after they have been tested (cf. testSuite())
def test2_06_allQualifierKeys(self):
"[Qualifier] allQualifierKeys"
qual=qualifierWithQualifierFormat('NOT( (age<=30 OR age>70) AND book.title=="Quai des brumes")')
keys=list(qual.allQualifierKeys())
keys.sort()
self.assertEqual(keys, ['age', 'book.title'])
def test2_07_validateKeysWithRootClassDescription(self):
"[Qualifier] validateKeysWithRootClassDescription"
import os
from Modeling import ModelSet,Model,EntityClassDescription
# load a model
modelSet=ModelSet.ModelSet()
xmlmodelPath=os.getcwd()+'/xmlmodels/model_AuthorBook.xml'
modelSet.addModelFromXML({'file': xmlmodelPath})
# make a class description
classDesc=EntityClassDescription.EntityClassDescription(modelSet.entityNamed('Writer'))
# tests
qual=qualifierWithQualifierFormat('NOT( (age<=30 OR age>70) AND book.title=="Quai des brumes")')
self.failIf(qual.validateKeysWithRootClassDescription(classDesc))
class TestModuleFunctions(unittest.TestCase):
"Tests the functions of module Qualifier"
def setUp(self):
self.john=Writer('John', 'Cleese', age=30, bookName='Flying Circus Diary')
self.jean=Writer('Jean', 'Gabin', age=70, bookName='Quai des brumes')
self.douglas=Writer('Douglas', 'Adams', age=12,bookName='Hitchhiker Guide')
self.victor=Writer('Victor', 'Hugo', age=143, bookName='Les Miserables')
self.dummy=Writer('Dummy', '', age=None, bookName='dummy for dummies')
self.authors=(self.john, self.jean, self.douglas, self.victor, self.dummy)
def test_01_filteredArrayWithQualifier(self):
"[Qualifier] filteredArrayWithQualifier"
qual=KeyValueQualifier('age', QualifierOperatorGreaterThanOrEqualTo, 70)
senior_authors=filteredArrayWithQualifier(self.authors, qual)
self.failUnless(len(senior_authors)==2 and \
self.jean in senior_authors and \
self.victor in senior_authors)
def test_02_qualifierToMatchAllValues(self):
"[Qualifier] qualifierToMatchAllValues"
dict={'age': 70, 'firstName': 'Jean'}
qual=qualifierToMatchAllValues(dict)
res=filteredArrayWithQualifier(self.authors, qual)
self.failUnless(len(res)==1 and self.jean in res )
def test_03_qualifierToMatchAnyValues(self):
"[Qualifier] qualifierToMatchAnyValues"
dict={'age': 70,'firstName': 'Douglas','book.title':'Flying Circus Diary'}
qual=qualifierToMatchAnyValues(dict)
res=filteredArrayWithQualifier(self.authors, qual)
self.failUnless(len(res)==3 and self.jean in res and \
self.douglas in res and self.john in res)
def test_04_qualifierWithQualifierFormat(self):
"[Qualifier] qualifierWithQualifierFormat"
# valid expressions
juniorOrSenior=qualifierWithQualifierFormat("age<=30 OR age>70")
res=filteredArrayWithQualifier(self.authors, juniorOrSenior)
self.failUnless(len(res)==4 and self.douglas in res and self.dummy in res \
and self.john in res and self.victor in res)
quaiDesBrumes=qualifierWithQualifierFormat('book.title=="Quai des brumes"')
res=filteredArrayWithQualifier(self.authors, quaiDesBrumes)
self.failUnless(len(res)==1 and self.jean in res)
quaiDesBrumes=qualifierWithQualifierFormat('book.title like "*des*"')
res=filteredArrayWithQualifier(self.authors, quaiDesBrumes)
self.failUnless(len(res)==1 and self.jean in res)
m_s=qualifierWithQualifierFormat('book.title caseInsensitiveLike "*m?s*"')
res=filteredArrayWithQualifier(self.authors, m_s)
self.failUnless(len(res)==2 and self.jean in res and self.victor in res)
m_s=qualifierWithQualifierFormat('book.title ilike "*m?s*"')
res=filteredArrayWithQualifier(self.authors, m_s)
self.failUnless(len(res)==2 and self.jean in res and self.victor in res)
# invalid expression
self.failUnlessRaises(ValueError, qualifierWithQualifierFormat,
"age<=30 AND OR age>70")
self.failUnlessRaises(ValueError, qualifierWithQualifierFormat,
"age<=30 AND (age>70")
self.failUnlessRaises(ValueError, qualifierWithQualifierFormat,
"age=30 AND age>70")
def test_05_qualifierWithQualifierFormat2(self):
"[Qualifier] qualifierWithQualifierFormat w/ empty value"
books=[a.book for a in self.authors]
emptyTitle=qualifierWithQualifierFormat('title == ""')
res=filteredArrayWithQualifier(books, emptyTitle)
self.failIf(res)
def test_06_qualifierWithQualifierFormat3(self):
"[Qualifier] qualifierWithQualifierFormat w/ None/NULL"
ageIsNone=qualifierWithQualifierFormat('age == NULL')
res=filteredArrayWithQualifier(self.authors, ageIsNone)
self.failUnless(res and len(res)==1 and self.dummy in res)
def test_07_qualifierWithQualifierFormat4(self):
"[Qualifier] qualifierWithQualifierFormat w/ Upper-Case Key"
ageIsNone=qualifierWithQualifierFormat('AGE == NULL')
def getAGE(self):
return self.age
Writer.getAGE=getAGE
res=filteredArrayWithQualifier(self.authors, ageIsNone)
self.failUnless(res and len(res)==1 and self.dummy in res)
del Writer.getAGE
def test_08_operator_in_not_in(self):
"[Qualifier] IN and NOT IN operators"
m_s=qualifierWithQualifierFormat('age IN [ 30, 70 ]')
res=filteredArrayWithQualifier(self.authors, m_s)
self.failUnless(len(res)==2 and self.jean in res and self.john in res)
m_s=qualifierWithQualifierFormat('age IN [ 30 ]') # single item
res=filteredArrayWithQualifier(self.authors, m_s)
self.failUnless(len(res)==1 and self.john in res)
m_s=qualifierWithQualifierFormat('age NOT IN [ 30, 70 ]')
res=filteredArrayWithQualifier(self.authors, m_s)
self.failUnless(len(res)==3 and self.douglas in res and self.victor in res and self.dummy in res)
def test_09_empty_qualifier_string(self):
"[Qualifier] Empty qualifier string" # bug #854630
q=qualifierWithQualifierFormat('')
self.assertEqual(None, q)
q=qualifierWithQualifierFormat(None)
self.assertEqual(None, q)
def test_10_attributes_names_and_operators_names(self):
"[Qualifier] Attributes' names beginning w/ AND,OR,NOT,IN"
# bug #938096
q=qualifierWithQualifierFormat('orbit == 1')
self.failUnless(isinstance(q, KeyValueQualifier))
q=qualifierWithQualifierFormat('and_factors in [ "and", "AND"]')
self.failUnless(isinstance(q, KeyValueQualifier))
q=qualifierWithQualifierFormat('notification == "warning"')
self.failUnless(isinstance(q, KeyValueQualifier))
q=qualifierWithQualifierFormat('NOTIFICATION == "WARNING"')
self.failUnless(isinstance(q, KeyValueQualifier))
q=qualifierWithQualifierFormat('inside != "outside"')
self.failUnless(isinstance(q, KeyValueQualifier))
def test_11_andornot(self):
"[Qualifier] attributes'names beginning w/ AND, OR, NOT are valid!"
q=qualifierWithQualifierFormat('orbit == 1')
self.failUnless(isinstance(q, KeyValueQualifier))
q=qualifierWithQualifierFormat('notification == "warning"')
self.failUnless(isinstance(q, KeyValueQualifier))
q=qualifierWithQualifierFormat('NOTIFICATION == "WARNING"')
self.failUnless(isinstance(q, KeyValueQualifier))
def test_12_syntax_error_detection(self):
"[Qualifier] detection of syntax errors / bug #1032577"
self.assertRaises(ValueError,
qualifierWithQualifierFormat,
'name like "you" AND isActive=1')
# Build the test suite
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestOperatorQualifiers, "test_"))
suite.addTest(unittest.makeSuite(TestQualifiers, "test_"))
suite.addTest(unittest.makeSuite(TestModuleFunctions, "test_"))
suite.addTest(unittest.makeSuite(TestQualifiers, "test2_"))
return suite
if __name__ == "__main__":
errs = utils.run_suite(test_suite())
sys.exit(errs and 1 or 0)
|