QGIS/tests/src/python/test_qgsexpression.py
2017-07-05 23:21:06 +02:00

236 lines
7.9 KiB
Python

# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsExpression.
.. note:: 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.
"""
__author__ = 'Nathan Woodrow'
__date__ = '4/11/2012'
__copyright__ = 'Copyright 2012, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import qgis # NOQA
from qgis.PyQt.QtCore import QVariant
from qgis.testing import unittest
from qgis.utils import qgsfunction
from qgis.core import QgsExpression, QgsFeatureRequest
class TestQgsExpressionCustomFunctions(unittest.TestCase):
@qgsfunction(1, 'testing', register=False)
def testfun(values, feature, parent):
""" Function help """
return "Testing_%s" % values[0]
@qgsfunction(args="auto", group='testing', register=False)
def autocount(value1, value2, value3, feature, parent):
pass
@qgsfunction(args="auto", group='testing', register=False)
def expandargs(value1, value2, value3, feature, parent):
return value1, value2, value3
@qgsfunction(args=0, group='testing', register=False)
def special(values, feature, parent):
return "test"
@qgsfunction(1, 'testing', register=False)
def sqrt(values, feature, parent):
pass
@qgsfunction(1, 'testing', register=False, usesgeometry=True)
def geomtest(values, feature, parent):
pass
@qgsfunction(args=0, group='testing', register=False)
def no_referenced_columns_set(values, feature, parent):
return 1
@qgsfunction(args=0, group='testing', register=False, referenced_columns=['a', 'b'])
def referenced_columns_set(values, feature, parent):
return 2
def tearDown(self):
QgsExpression.unregisterFunction('testfun')
def testCanBeRegistered(self):
QgsExpression.registerFunction(self.testfun)
index = QgsExpression.functionIndex('testfun')
self.assertNotEqual(index, -1)
def testAutoCountsCorrectArgs(self):
function = self.autocount
args = function.params()
self.assertEqual(args, 3)
def testAutoArgsAreExpanded(self):
function = self.expandargs
args = function.params()
self.assertEqual(args, 3)
values = [1, 2, 3]
exp = QgsExpression("")
result = function.func(values, None, exp)
# Make sure there is no eval error
self.assertEqual(exp.evalErrorString(), "")
self.assertEqual(result, (1, 2, 3))
def testCanUnregisterFunction(self):
QgsExpression.registerFunction(self.testfun)
index = QgsExpression.functionIndex('testfun')
self.assertNotEqual(index, -1)
error = QgsExpression.unregisterFunction('testfun')
self.assertTrue(error)
index = QgsExpression.functionIndex('testfun')
self.assertEqual(index, -1)
def testCanEvaluateFunction(self):
QgsExpression.registerFunction(self.testfun)
exp = QgsExpression('testfun(1)')
result = exp.evaluate()
self.assertEqual('Testing_1', result)
def testZeroArgFunctionsTakeNoArgs(self):
QgsExpression.registerFunction(self.special)
special = self.special
self.assertEqual(special.name(), 'special')
exp = QgsExpression('special()')
result = exp.evaluate()
self.assertEqual('test', result)
def testDecoratorPreservesAttributes(self):
func = self.testfun
self.assertEqual(func.name(), 'testfun')
self.assertEqual(func.group(), 'testing')
self.assertEqual(func.params(), 1)
def testCantReregister(self):
QgsExpression.registerFunction(self.testfun)
success = QgsExpression.registerFunction(self.testfun)
self.assertFalse(success)
def testCanReregisterAfterUnregister(self):
QgsExpression.registerFunction(self.testfun)
QgsExpression.unregisterFunction("testfun")
success = QgsExpression.registerFunction(self.testfun)
self.assertTrue(success)
def testCantOverrideBuiltinsWithRegister(self):
success = QgsExpression.registerFunction(self.sqrt)
self.assertFalse(success)
def testCanRegisterGeometryFunction(self):
success = QgsExpression.registerFunction(self.geomtest)
self.assertTrue(success)
def testReferencedColumnsNoSet(self):
QgsExpression.registerFunction(self.no_referenced_columns_set)
exp = QgsExpression('no_referenced_columns_set()')
self.assertEqual(exp.referencedColumns(),
{QgsFeatureRequest.ALL_ATTRIBUTES})
def testReferencedColumnsSet(self):
QgsExpression.registerFunction(self.referenced_columns_set)
exp = QgsExpression('referenced_columns_set()')
self.assertEqual(set(exp.referencedColumns()), set(['a', 'b']))
def testCantOverrideBuiltinsWithUnregister(self):
success = QgsExpression.unregisterFunction("sqrt")
self.assertFalse(success)
def testDump(self):
for txt in [
"id",
"idä",
"\"id abc\"",
"\"id abc\"",
" abc ",
" /* co */ da ",
]:
self.assertEqual(txt, QgsExpression(txt).expression())
def testBlockComment(self):
expressions = {
"'test' /* comment */": 'test',
"/* comment */'test'": 'test',
"/* comment */'test*/'": 'test*/',
"/** comment */'test*/'": 'test*/',
"/* comment **/'test*/' /* comment */": 'test*/',
"'test/*'/* comment */": 'test/*',
"""/**
comment
**/
'test*/'""": 'test*/',
"""'test*/'
/**
comment
**/""": 'test*/'
}
for e, exp_res in list(expressions.items()):
exp = QgsExpression(e)
result = exp.evaluate()
self.assertEqual(exp_res, result)
def testComment(self):
expressions = {
"'test' -- comment\n": 'test',
"'test--'\n": 'test--',
"'--test'\n": '--test',
"'test' -- comment": 'test',
"'test--'": 'test--',
"'--test'": '--test',
}
for e, exp_res in list(expressions.items()):
exp = QgsExpression(e)
result = exp.evaluate()
self.assertEqual(exp_res, result)
def testValid(self):
e = QgsExpression()
self.assertFalse(e.isValid())
e.setExpression('asdf||#@¼')
self.assertFalse(e.isValid())
e.setExpression('1')
self.assertTrue(e.isValid())
def testCreateFieldEqualityExpression(self):
e = QgsExpression()
# test when value is null
field = "myfield"
value = QVariant()
res = '"myfield" IS NULL'
self.assertEqual(e.createFieldEqualityExpression(field, value), res)
# test when value is null and field name has a quote
field = "my'field"
value = QVariant()
res = '"my\'field" IS NULL'
self.assertEqual(e.createFieldEqualityExpression(field, value), res)
# test when field name has a quote and value is an int
field = "my'field"
value = 5
res = '"my\'field" = 5'
self.assertEqual(e.createFieldEqualityExpression(field, value), res)
# test when field name has a quote and value is a string
field = "my'field"
value = '5'
res = '"my\'field" = \'5\''
self.assertEqual(e.createFieldEqualityExpression(field, value), res)
# test when field name has a quote and value is a boolean
field = "my'field"
value = True
res = '"my\'field" = TRUE'
self.assertEqual(e.createFieldEqualityExpression(field, value), res)
if __name__ == "__main__":
unittest.main()