Projet

Général

Profil

0001-templatetags-add-mathematics-filters-27709.patch

Nicolas Roche, 21 février 2019 17:11

Télécharger (6,85 ko)

Voir les différences:

Subject: [PATCH] templatetags: add mathematics filters (#27709)

 tests/test_formdata.py            | 82 ++++++++++++++++++++++++++++++-
 wcs/qommon/templatetags/qommon.py | 56 +++++++++++++++++++++
 2 files changed, 137 insertions(+), 1 deletion(-)
tests/test_formdata.py
7 7

  
8 8
from quixote import cleanup
9 9
from quixote.http_request import Upload
10
from qommon.template import Template
10
from qommon.template import Template, TemplateError
11 11
from qommon.form import PicklableUpload
12 12
from wcs.qommon.http_request import HTTPRequest
13 13
from wcs import fields, formdef
......
1336 1336

  
1337 1337
        tmpl = Template('{{ 4.12|decimal:form_var_arg }}')
1338 1338
        assert tmpl.render(context) == '4.120'
1339

  
1340
def test_mathematics_filters(pub, variable_test_data):
1341
    formdef = FormDef.select()[0]
1342
    formdata = formdef.data_class().select()[0]
1343
    for mode in (None, 'lazy'):
1344
        pub.substitutions.reset()
1345
        pub.substitutions.feed(formdef)
1346
        with pub.substitutions.temporary_feed(formdata, force_mode=mode):
1347
            # string as param
1348
            assert WorkflowStatusItem.compute('{{ "1,1"|add:0 }}', raises=True) == '1.1'
1349
            assert WorkflowStatusItem.compute('{{ "not a number"|add:1.2 }}', raises=True) == '1.2'
1350

  
1351
            # strings as arg
1352
            assert WorkflowStatusItem.compute('{{ 0.3|add:"1" }}', raises=True) == '1.3'
1353
            assert WorkflowStatusItem.compute('{{ 1.4|add:"not a number" }}', raises=True) == '1.4'
1354

  
1355
            # add
1356
            assert WorkflowStatusItem.compute('{{ 4|add:-0.9 }}', raises=True) == '3.1'
1357
            assert WorkflowStatusItem.compute('{{ 3.2|add:"" }}', raises=True) == '3.2'
1358
            assert WorkflowStatusItem.compute('{{ ""|add:3.3 }}', raises=True) == '3.3'
1359
            assert WorkflowStatusItem.compute('{{ 0|add:0 }}', raises=True) == '0'
1360
            assert WorkflowStatusItem.compute('{{ ""|add:0 }}', raises=True) == '0'
1361
            assert WorkflowStatusItem.compute('{{ 0|add:"" }}', raises=True) == '0'
1362

  
1363
            # subtract
1364
            assert WorkflowStatusItem.compute('{{ 5|subtract:0.9 }}', raises=True) == '4.1'
1365
            assert WorkflowStatusItem.compute('{{ 4.2|subtract:"" }}', raises=True) == '4.2'
1366
            assert WorkflowStatusItem.compute('{{ ""|subtract:-4.3 }}', raises=True) == '4.3'
1367

  
1368
            # multiply
1369
            assert WorkflowStatusItem.compute('{{ 2.5|multiply:2 }}', raises=True) == '5.0'
1370
            assert WorkflowStatusItem.compute('{{ "3"|multiply:"2" }}', raises=True) == '6'
1371
            assert WorkflowStatusItem.compute('{{ 5|multiply:"" }}', raises=True) == ''
1372
            assert WorkflowStatusItem.compute('{{ ""|multiply:"5.2"}}', raises=True) == ''
1373

  
1374
            # divide
1375
            assert WorkflowStatusItem.compute('{{ 2|divide:3|decimal:2 }}', raises=True) == '0.67'
1376
            assert WorkflowStatusItem.compute('{{ 6|divide:"" }}', raises=True) == ''
1377
            assert WorkflowStatusItem.compute('{{ ""|divide:6}}', raises=True) == ''
1378

  
1379
            # no arg
1380
            with pytest.raises(Exception, match=r'.*Could not find variable at start.*'):
1381
                WorkflowStatusItem.compute('{{ |add:2}}', raises=True)
1382

  
1383
            # no param
1384
            with pytest.raises(Exception, match=r'.*add requires 2 arguments, 1 provided'):
1385
                WorkflowStatusItem.compute('{{ 0|add }}', raises=True)
1386
            with pytest.raises(Exception, match=r'.*add requires 2 arguments, 1 provided'):
1387
                WorkflowStatusItem.compute('{{ 0|add: }}', raises=True)
1388

  
1389
def test_lazy_formdata_mathematics_filters(pub):
1390
    formdef = FormDef()
1391
    formdef.name = 'foobar'
1392
    formdef.url_name = 'foobar'
1393
    formdef.fields = [
1394
        fields.StringField(id='0', label='term1', varname='term1'),
1395
        fields.StringField(id='1', label='term2', varname='term2')
1396
    ]
1397
    formdef.store()
1398
    formdata = formdef.data_class()()
1399
    formdata.data = {'0': '3', '1': '4'}
1400
    formdata.store()
1401
    pub.substitutions.feed(formdata)
1402
    for mode in (None, 'lazy'):
1403
        context = pub.substitutions.get_context_variables(mode=mode)
1404

  
1405
        tmpl = Template('{{ form_var_term1|decimal }}')
1406
        assert tmpl.render(context) == '3'
1407

  
1408
        tmpl = Template('{{ form_var_term1|add:form_var_term2 }}')
1409
        assert tmpl.render(context) == '7'
1410

  
1411
        tmpl = Template('{{ form_var_term1|subtract:form_var_term2 }}')
1412
        assert tmpl.render(context) == '-1'
1413

  
1414
        tmpl = Template('{{ form_var_term1|multiply:form_var_term2 }}')
1415
        assert tmpl.render(context) == '12'
1416

  
1417
        tmpl = Template('{{ form_var_term1|divide:form_var_term2 }}')
1418
        assert tmpl.render(context) == '0.75'
wcs/qommon/templatetags/qommon.py
229 229
    }
230 230
    token.store()
231 231
    return '---===BUTTON:%s:%s===---' % (token.id, label)
232

  
233
@register.filter
234
def add(value, arg):
235
    '''replace the "add" native django filter'''
236
    if hasattr(value, 'get_value'):
237
        value = value.get_value()  # unlazy
238
    if hasattr(arg, 'get_value'):
239
        arg = arg.get_value()  # unlazy
240
    value = parse_decimal(value)
241
    arg = parse_decimal(arg)
242
    if value is None:
243
        value = Decimal(0)
244
    if arg is None:
245
        arg = Decimal(0)
246
    return value + arg
247

  
248
@register.filter
249
def subtract(value, arg):
250
    if hasattr(value, 'get_value'):
251
        value = value.get_value()  # unlazy
252
    if hasattr(arg, 'get_value'):
253
        arg = arg.get_value()  # unlazy
254
    value = parse_decimal(value)
255
    arg = parse_decimal(arg)
256
    if value is None:
257
        value = Decimal(0)
258
    if arg is None:
259
        arg = Decimal(0)
260
    return value - arg
261

  
262
@register.filter
263
def multiply(value, arg):
264
    if hasattr(value, 'get_value'):
265
        value = value.get_value()  # unlazy
266
    if hasattr(arg, 'get_value'):
267
        arg = arg.get_value()  # unlazy
268
    value = parse_decimal(value)
269
    arg = parse_decimal(arg)
270
    if value is None or arg is None:
271
        return ''
272
    return value * arg
273

  
274
@register.filter
275
def divide(value, arg):
276
    if hasattr(value, 'get_value'):
277
        value = value.get_value()  # unlazy
278
    if hasattr(arg, 'get_value'):
279
        arg = arg.get_value()  # unlazy
280
    value = parse_decimal(value)
281
    arg = parse_decimal(arg)
282
    if value is None or arg is None:
283
        return ''
284
    try:
285
        return value / arg
286
    except ZeroDivisionError:
287
        return ''
232
-