1
0
Fork 0
mirror of https://github.com/yweber/lodel2.git synced 2025-10-26 09:39:01 +01:00

Written some tests for filtered queries + query re modifications

- the re for filter spliting is modified to better handle operators
- added leading & trailing space to some operators
This commit is contained in:
Yann 2016-05-20 14:48:53 +02:00
commit f402902b5b
5 changed files with 146 additions and 5 deletions

Binary file not shown.

View file

@ -98,10 +98,10 @@ class LeFilteredQuery(LeQuery):
'!=',
'<',
'>',
'in',
'not in',
'like',
'not like']
' in ',
' not in ',
' like ',
' not like ']
##@brief Regular expression to process filters
_query_re = None
@ -235,6 +235,7 @@ a relational field, but %s.%s was present in the filter"
if not matches:
raise ValueError("The query_filter '%s' seems to be invalid"%query_filter)
result = (matches.group('field'), re.sub(r'\s', ' ', matches.group('operator'), count=0), matches.group('value').strip())
result = [r.strip() for r in result]
for r in result:
if len(r) == 0:
raise ValueError("The query_filter '%s' seems to be invalid"%query_filter)
@ -248,7 +249,7 @@ a relational field, but %s.%s was present in the filter"
for operator in cls._query_operators[1:]:
op_re_piece += '|(%s)'%operator.replace(' ', '\s')
op_re_piece += ')'
cls._query_re = re.compile('^\s*(?P<field>(((superior)|(subordinate))\.)?[a-z_][a-z0-9\-_]*)\s*'+op_re_piece+'\s*(?P<value>[^<>=!].*)\s*$', flags=re.IGNORECASE)
cls._query_re = re.compile('^\s*(?P<field>(((superior)|(subordinate))\.)?[a-z_][a-z0-9\-_]*)\s*'+op_re_piece+'\s*(?P<value>.*)\s*$', flags=re.IGNORECASE)
pass
@classmethod

View file

View file

@ -0,0 +1,114 @@
import unittest
import tests.loader_utils
from tests.leapi.query.utils import dyncode_module as dyncode
from lodel.leapi.leobject import LeApiDataCheckError
from lodel.leapi.query import LeDeleteQuery, LeUpdateQuery, LeGetQuery
class LeGetQueryTestCase(unittest.TestCase):
def test_init_default(self):
""" Testing GetQuery instanciation default values"""
tclass_list = [ dyncode.Object,
dyncode.Entry,
dyncode.Person,
dyncode.Text,
dyncode.Section,
dyncode.Publication,
dyncode.Text_Person,
]
for tclass in tclass_list:
get_q = LeGetQuery(tclass, [])
qinfos = get_q.dump_infos()
self.assertEqual( set(qinfos['field_list']),
set(tclass.fieldnames(True)))
self.assertEqual( qinfos['limit'],
None)
self.assertEqual( qinfos['offset'],
0)
self.assertEqual( qinfos['group'],
None)
self.assertEqual( qinfos['order'],
None)
self.assertEqual( qinfos['query_filter'],
([],[]))
self.assertEqual( qinfos['target_class'],
tclass)
class LeFilteredQueryTestCase(unittest.TestCase):
q_classes = [ LeDeleteQuery, LeUpdateQuery, LeGetQuery ]
def test_filters(self):
""" Testing FilteredQuery filters handling """
test_datas = [ ( 'lodel_id = 42',
( [('lodel_id','=','42')],
[])),
( 'lodel_id <= 42',
( [('lodel_id','<=','42')],
[])),
( ['lodel_id <= 42'],
( [('lodel_id','<=','42')],
[])),
( ('lodel_id <= 42',),
( [('lodel_id','<=','42')],
[])),
( ['lodel_id <= 42','lodel_id >= 33'],
( [ ('lodel_id','<=','42'),
('lodel_id', '>=','33')],
[])),
]
for q_class in self.q_classes:
for q_filter_arg, e_qfilter in test_datas:
get_q = q_class(dyncode.Publication, q_filter_arg)
self.assertEqual( get_q.dump_infos()['query_filter'],
e_qfilter)
def test_invalid_filters(self):
""" Testing invalid filters detection """
invalid_filters = ( 'lodel_id',
'',
'"',
"'",
"not_exists != bar",
"lodel_id # bar",
"lodel_id ind 42,43",
"lodel_id llike 42",
('lodel_id', '', '42'),
)
for invalid_filter in invalid_filters:
for q_class in self.q_classes:
with self.assertRaises( LeApiDataCheckError,
msg="for filter '%s'" % (invalid_filter,)):
q_class(dyncode.Publication, invalid_filter)
def test_filters_operators(self):
""" Testing FilteredQuery filters operator recognition """
ops = [ '=',
'<=',
'>=',
'!=',
'<',
'>',
'in',
'not in',
'like',
'not like']
values = ( '42',
'not in',
'in',
'like',
'=',
'!=',
"'",
'"',
'"hello world !"')
for q_class in self.q_classes:
for op in ops:
for v in values:
get_q = q_class( dyncode.Publication,
'lodel_id %s %s' % (op,v))
self.assertEqual( get_q.dump_infos()['query_filter'],
([('lodel_id',op,v)],[]))

View file

@ -0,0 +1,26 @@
#
# Importing this file trigger dynamic code generation & load
#
# To use dynamic code import utils.dyncode_module as dyncode
import tempfile
import os
from importlib.machinery import SourceFileLoader
from lodel.leapi.lefactory import dyncode_from_em
from lodel.editorial_model.translator import picklefile
def init_dyncode():
f_handler, dyncode_file = tempfile.mkstemp( prefix="lodel2_tests",
suffix="_dyncode")
os.close(f_handler)
model = picklefile.load('tests/editorial_model.pickle')
source_code = dyncode_from_em(model)
with os.fdopen(os.open(dyncode_file, os.O_WRONLY), 'w') as dynfd:
dynfd.write(source_code)
dyncode_module = SourceFileLoader("lodel.dyncode", dyncode_file).load_module()
os.unlink(dyncode_file)
return dyncode_module
dyncode_module = init_dyncode()