Test var model error (#2217)

* [varLib.models] Add test for modeling rounding error

Tests https://github.com/fonttools/fonttools/pull/2214

If you flip demo to True, it does a slower test and demos the new error as well
as the error the old code was producing (ie. rounding deltas post-modeling).

Indeed, the new error is always capped by 0.5 as expected, whereas the old one
was unbounded. Here's the worst-case error of the bad code:

...
240     0.42    4.8
...

240 is just the line number. 0.42 is new error. 4.8 is old error.

* turn test_modeling_error into a parametrized pytest test

Like the other test methods in the same module, all those whose name starts with 'test_' are automatically discovered and run by pytest which is our default test runner. So there is no need to call the test method itself in the top-level module scope. One simply runs the test via pytest. To execute this specific test method one can do 'pytest Tests/varLib/models_test.py::test_modeling_error'.

* use pytest markers to mark specific test as 'slow'

So that one can optionally deselect tests marked with specific marker by passing -m option (e.g. to deselect 'slow' tests, pytest -m 'not slow' ...).

https://docs.pytest.org/en/stable/mark.html#registering-marks
https://docs.pytest.org/en/stable/example/parametrize.html#set-marks-or-test-id-for-individual-parametrized-test

* [varLib/models_test] Comment out non-test code

Co-authored-by: Cosimo Lupo <clupo@google.com>
This commit is contained in:
Behdad Esfahbod 2022-08-15 10:30:45 -06:00 committed by GitHub
parent 9716b1c455
commit 03d264756b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 0 deletions

View File

@ -34,6 +34,40 @@ def test_supportScalar():
assert supportScalar({'wght':2.5}, {'wght':(0,2,4)}) == 0.75
@pytest.mark.parametrize(
"numLocations, numSamples", [
pytest.param(127, 509, marks=pytest.mark.slow),
(31, 251),
]
)
def test_modeling_error(numLocations, numSamples):
# https://github.com/fonttools/fonttools/issues/2213
locations = [{'axis': float(i)/numLocations} for i in range(numLocations)]
masterValues = [100. if i else 0. for i in range(numLocations)]
model = VariationModel(locations)
for i in range(numSamples):
loc = {'axis': float(i)/numSamples}
scalars = model.getScalars(loc)
deltas_float = model.getDeltas(masterValues)
deltas_round = model.getDeltas(masterValues, round=round)
expected = model.interpolateFromDeltasAndScalars(deltas_float, scalars)
actual = model.interpolateFromDeltasAndScalars(deltas_round, scalars)
err = abs(actual - expected)
assert err <= .5, (i, err)
# This is how NOT to round deltas.
#deltas_late_round = [round(d) for d in deltas_float]
#bad = model.interpolateFromDeltasAndScalars(deltas_late_round, scalars)
#err_bad = abs(bad - expected)
#if err != err_bad:
# print("{:d} {:.2} {:.2}".format(i, err, err_bad))
class VariationModelTest(object):
@pytest.mark.parametrize(

View File

@ -52,6 +52,8 @@ filterwarnings =
ignore:writePlist:DeprecationWarning:plistlib_test
ignore:some_function:DeprecationWarning:fontTools.ufoLib.utils
ignore::DeprecationWarning:fontTools.varLib.designspace
markers =
slow: marks tests as slow (deselect with '-m "not slow"')
[tool:interrogate]
ignore-semiprivate = true