Projet

Général

Profil

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

Nicolas Roche, 25 février 2019 17:21

Télécharger (10 ko)

Voir les différences:

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

 tests/test_formdata.py            | 96 +++++++++++++++++++++++++++++++
 tests/test_templates.py           | 64 +++++++++++++++++++++
 wcs/qommon/templatetags/qommon.py | 24 ++++++++
 3 files changed, 184 insertions(+)
tests/test_formdata.py
583 583
        fields.MapField(id='7', label='map', varname='map'),
584 584
        fields.DateField(id='8', label='date2', varname='datefield2'),
585 585
        fields.StringField(id='9', label='string2', varname='datestring'),
586
        fields.StringField(id='10', label='number1', varname='term1'),
587
        fields.StringField(id='11', label='number2', varname='term2'),
586 588
    ]
587 589
    formdef.workflow_roles = {'_receiver': role.id}
588 590
    formdef.geolocations = {'base': 'Base'}
......
603 605
        '7': '2;4',  # map
604 606
        '8': time.strptime('2018-08-31', '%Y-%m-%d'),
605 607
        '9': '2018-07-31',
608
        '10': '3',
609
        '11': '4',
606 610
    }
607 611
    formdata.data['5'].receive(['hello world'])
608 612
    formdata.geolocations = {'base': {'lat': 1, 'lon': 2}}
......
1336 1340

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

  
1344
def test_decimal_conditions_django(pub, variable_test_data):
1345
    for condition_value in (
1346
            'form_var_foo_foo|decimal == 0',
1347
            'form_var_boolfield|decimal == 0',
1348
            'form_var_boolfield2|decimal == 0',
1349
            'form_var_datefield|decimal == 0',
1350
            'form_var_datefield|decimal == 0',
1351
            'form_var_filefield|decimal == 0',
1352
            'form_var_foo_foo_baz_baz|decimal == 0',
1353
            'form_var_map|decimal == 0',
1354
            'form_var_datefield2|decimal == 0',
1355
            'form_var_datestring|decimal == 0',
1356
            'form_var_term1|decimal == 3',
1357
            'form_var_term2|decimal == 4',
1358
            ):
1359
        condition = Condition({'type': 'django', 'value': condition_value})
1360
        assert condition.evaluate() is True
1361
    assert False
1362

  
1363
def test_lazy_formdata_mathematics_filters(pub):
1364
    formdef = FormDef()
1365
    formdef.name = 'foobar'
1366
    formdef.url_name = 'foobar'
1367
    formdef.fields = [
1368
        fields.StringField(id='0', label='term1', varname='term1'),
1369
        fields.StringField(id='1', label='term2', varname='term2')
1370
    ]
1371
    formdef.store()
1372
    formdata = formdef.data_class()()
1373
    formdata.data = {'0': '3', '1': '4'}
1374
    formdata.store()
1375
    pub.substitutions.feed(formdata)
1376
    for mode in (None, 'lazy'):
1377
        context = pub.substitutions.get_context_variables(mode=mode)
1378

  
1379
        tmpl = Template('{{ form_var_term1|decimal }}')
1380
        assert tmpl.render(context) == '3'
1381

  
1382
        tmpl = Template('{{ form_var_term1|add:form_var_term2 }}')
1383
        assert tmpl.render(context) == '7'
1384

  
1385
        tmpl = Template('{{ form_var_term1|subtract:form_var_term2 }}')
1386
        assert tmpl.render(context) == '-1'
1387

  
1388
        tmpl = Template('{{ form_var_term1|multiply:form_var_term2 }}')
1389
        assert tmpl.render(context) == '12'
1390

  
1391
        tmpl = Template('{{ form_var_term1|divide:form_var_term2 }}')
1392
        assert tmpl.render(context) == '0.75'
1393

  
1394
def test_mathematic_conditions_django(pub, variable_test_data):
1395
    for true_condition_value in (
1396
            # reminder
1397
            'form_var_term1 == 3',
1398
            'form_var_term2 == 4',
1399

  
1400
            # add
1401
            'form_var_term1|add:form_var_term2 == 7',
1402
            'form_var_term1|add:form_var_term2 == 7.0',
1403
            'form_var_term1|add:form_var_term2 == "7"|decimal',
1404
            'form_var_term1|add:form_var_term2 > 6',
1405

  
1406
            # subtract
1407
            'form_var_term1|subtract:form_var_term2 == -1',
1408
            'form_var_term1|subtract:form_var_term2 == -1.0',
1409
            'form_var_term1|subtract:form_var_term2 == "-1"|decimal',
1410
            'form_var_term1|subtract:form_var_term2 < 0',
1411

  
1412
            # multiply
1413
            'form_var_term1|multiply:form_var_term2 == 12',
1414
            'form_var_term1|multiply:form_var_term2 == 12.0',
1415
            'form_var_term1|multiply:form_var_term2 == "12"|decimal',
1416
            'form_var_term1|multiply:form_var_term2 > 10',
1417

  
1418
            # divide
1419
            'form_var_term1|divide:form_var_term2 == 0.75',
1420
            'form_var_term1|divide:form_var_term2 == 0.750',
1421
            'form_var_term1|divide:form_var_term2 == "0.75"|decimal',
1422
            'form_var_term1|divide:form_var_term2 > 0.5',
1423
            ):
1424
        condition = Condition({'type': 'django', 'value': true_condition_value})
1425
        assert condition.evaluate() is True
1426

  
1427
    for false_condition_value in (
1428
            'form_var_term1|add:form_var_term2 > 8',
1429
            'form_var_term1|subtract:form_var_term2 > 0',
1430
            'form_var_term1|multiply:form_var_term2 > 20',
1431
            'form_var_term1|divide:form_var_term2 > 1',
1432
            ):
1433
        condition = Condition({'type': 'django', 'value': false_condition_value})
1434
        assert condition.evaluate() is False
tests/test_templates.py
323 323
    assert tmpl.render() == 'hello'
324 324
    tmpl = Template('{% if 3|decimal|decimal == 3 %}hello{% endif %}')
325 325
    assert tmpl.render() == 'hello'
326

  
327
def test_mathematics_templatetag():
328
    tmpl = Template('{{ term1|add:term2 }}')
329

  
330
    # using string: convert to number or 0
331
    assert tmpl.render({'term1': '1.1', 'term2': 0}) == '1.1'
332
    assert tmpl.render({'term1': 'not a number', 'term2': 1.2}) == '1.2'
333
    assert tmpl.render({'term1': 0.3, 'term2': "1"}) == '1.3'
334
    assert tmpl.render({'term1': 1.4, 'term2': "not a number"}) == '1.4'
335

  
336
    # add
337
    assert tmpl.render({'term1': 4, 'term2': -0.9}) == '3.1'
338
    assert tmpl.render({'term1': '4', 'term2': -0.8}) == '3.2'
339
    assert tmpl.render({'term1': 4, 'term2': '-0.7'}) == '3.3'
340
    assert tmpl.render({'term1': '4', 'term2': '-0.6'}) == '3.4'
341
    assert tmpl.render({'term1': '', 'term2': 3.5}) == '3.5'
342
    assert tmpl.render({'term1': 3.6, 'term2': ''}) == '3.6'
343
    assert tmpl.render({'term1': '', 'term2': ''}) == '0'
344
    assert tmpl.render({'term1': 0, 'term2': ''}) == '0'
345
    assert tmpl.render({'term1': '', 'term2': 0}) == '0'
346
    assert tmpl.render({'term1': 0, 'term2': 0}) == '0'
347

  
348
    # subtract
349
    tmpl = Template('{{ term1|subtract:term2 }}')
350
    assert tmpl.render({'term1': 5.1, 'term2': 1}) == '4.1'
351
    assert tmpl.render({'term1': '5.2', 'term2': 1}) == '4.2'
352
    assert tmpl.render({'term1': 5.3, 'term2': '1'}) == '4.3'
353
    assert tmpl.render({'term1': '5.4', 'term2': '1'}) == '4.4'
354
    assert tmpl.render({'term1': '', 'term2': -4.5}) == '4.5'
355
    assert tmpl.render({'term1': 4.6, 'term2': ''}) == '4.6'
356
    assert tmpl.render({'term1': '', 'term2': ''}) == '0'
357
    assert tmpl.render({'term1': 0, 'term2': ''}) == '0'
358
    assert tmpl.render({'term1': '', 'term2': 0}) == '0'
359
    assert tmpl.render({'term1': 0, 'term2': 0}) == '0'
360

  
361
    # multiply
362
    tmpl = Template('{{ term1|multiply:term2 }}')
363
    assert tmpl.render({'term1': '3', 'term2': '2'}) == '6'
364
    assert tmpl.render({'term1': 2.5, 'term2': 2}) == '5.0'
365
    assert tmpl.render({'term1': '2.5', 'term2': 2}) == '5.0'
366
    assert tmpl.render({'term1': 2.5, 'term2': '2'}) == '5.0'
367
    assert tmpl.render({'term1': '2.5', 'term2': '2'}) == '5.0'
368
    assert tmpl.render({'term1': '', 'term2': '2'}) == '0'
369
    assert tmpl.render({'term1': 2.5, 'term2': ''}) == '0.0'
370
    assert tmpl.render({'term1': '', 'term2': ''}) == '0'
371
    assert tmpl.render({'term1': 0, 'term2': ''}) == '0'
372
    assert tmpl.render({'term1': '', 'term2': 0}) == '0'
373
    assert tmpl.render({'term1': 0, 'term2': 0}) == '0'
374

  
375
    # divide
376
    tmpl = Template('{{ term1|divide:term2 }}')
377
    assert tmpl.render({'term1': 16, 'term2': 2}) == '8'
378
    assert tmpl.render({'term1': 6, 'term2': 0.75}) == '8'
379
    assert tmpl.render({'term1': '6', 'term2': 0.75}) == '8'
380
    assert tmpl.render({'term1': 6, 'term2': '0.75'}) == '8'
381
    assert tmpl.render({'term1': '6', 'term2': '0.75'}) == '8'
382
    assert tmpl.render({'term1': '', 'term2': '2'}) == '0'
383
    assert tmpl.render({'term1': 6, 'term2': ''}) == ''
384
    assert tmpl.render({'term1': '', 'term2': ''}) == ''
385
    assert tmpl.render({'term1': 0, 'term2': ''}) == ''
386
    assert tmpl.render({'term1': '', 'term2': 0}) == ''
387
    assert tmpl.render({'term1': 0, 'term2': 0}) == ''
388
    tmpl = Template('{{ term1|divide:term2|decimal:2 }}')
389
    assert tmpl.render({'term1': 2, 'term2': 3}) == '0.67'
wcs/qommon/templatetags/qommon.py
16 16

  
17 17
import datetime
18 18
from decimal import Decimal
19
from decimal import InvalidOperation as DecimalInvalidOperation
20
from decimal import DivisionByZero as DecimalDivisionByZero
19 21

  
20 22
from django import template
21 23
from django.template import defaultfilters
......
227 229
    }
228 230
    token.store()
229 231
    return '---===BUTTON:%s:%s===---' % (token.id, label)
232

  
233
@register.filter
234
def add(term1, term2):
235
    '''replace the "add" native django filter'''
236
    return parse_decimal(term1) + parse_decimal(term2)
237

  
238
@register.filter
239
def subtract(term1, term2):
240
    return parse_decimal(term1) - parse_decimal(term2)
241

  
242
@register.filter
243
def multiply(term1, term2):
244
    return parse_decimal(term1) * parse_decimal(term2)
245

  
246
@register.filter
247
def divide(term1, term2):
248
    try:
249
        return parse_decimal(term1) / parse_decimal(term2)
250
    except DecimalInvalidOperation:
251
        return ''
252
    except DecimalDivisionByZero:
253
        return ''
230
-