Conversation
felipesanches
left a comment
There was a problem hiding this comment.
thanks, @simoncozens!
It looks good, but there are a few important things I would like to see before merging this. As discussed last Friday, I won't anymore merge PRs with new checks lacking rationale / request URL / good code-tests.
Your code-tests are good, but lack keywords, which makes them error-prone.
And the checks currently lack rationale and request metadata fields.
| # Do shaping results match expectations? | ||
|
|
||
|
|
||
| @check(id="com.google.fonts/check/shaping/regression") |
There was a problem hiding this comment.
please add rationale using this as a template:
@check(
id = 'com.google.fonts/check/shaping/regression',
rationale = """
Lalalalalalalalala lalala lalala lala la lalala alala.
Lelele lelelele lelelele lelelel eleleele.
""",
misc_metadata = {
'request': 'https://github.com/googlefonts/fontbakery/pull/3223'
}
)| msg = f"{shaping_text} produced '{forbidden}'" | ||
| report_items.append(create_report_item(vharfbuzz, msg, text=shaping_text, buf1=buf)) | ||
|
|
||
| yield FAIL, (msg + ".\n" + "\n".join(report_items)) |
There was a problem hiding this comment.
please give it a keyword by using the Message class
| # Are there any collisions? | ||
|
|
||
|
|
||
| @check(id="com.google.fonts/check/shaping/collides") |
There was a problem hiding this comment.
please add rationale & misc_metadata['request'] = Pull request URL
| yield FAIL, (msg + ".\n" + "\n".join(report_items)) | ||
|
|
||
|
|
||
| # Are there any collisions? |
There was a problem hiding this comment.
cleanup this loose comment. Maybe this fits as part of the description/rationale
| return params | ||
|
|
||
|
|
||
| # This is a very generic "do something with shaping" test runner. |
There was a problem hiding this comment.
check runner! In FontBakery lingo we use the word "test" to refer to automated code-tests while "check" means "font checking routines"
|
|
||
| # This is a very generic "do something with shaping" test runner. | ||
| # It'll be given concrete meaning later. | ||
| def run_a_set_of_tests( |
There was a problem hiding this comment.
run_a_set_of_checks (or even better run_a_set_of_shaping_checks?)
There was a problem hiding this comment.
Hm. I'm not sure I agree. I understand that within fontbakery "tests" are what we do to the fontbakery codebase and "checks" are what we run. But this profile defines three checks (com.google.fonts/check/shaping/regression, etc.) and each of the checks runs a test suite. It's not true that the three checks run more checks. We're selling this as test-driven-development, which is a well-established terminology, so I think I want to keep the "test" wording here.
There was a problem hiding this comment.
ok. I see. I think it is a bit confusing. But I see your point. I think I'll accept this for now and think better, maybe reevaluate later.
Note: for some reason I have reviewed this PR from bottom to top, so you will see another message from me below that was written before I saw your comment here.
There was a problem hiding this comment.
at least add shaping to the function name. So... for now, run_a_set_of_shaping_tests and we may later better discuss terminology
| try: | ||
| shaping_input_doc = json.loads(shaping_file.read_text()) | ||
| except Exception as e: | ||
| yield FAIL, (f"{shaping_file}: Invalid JSON: {e}.") |
There was a problem hiding this comment.
all non-PASS log-messages should have keywords so that we can unambiguously exercise them on code-tests. Please use the Message class for that.
| yield FAIL, (header + "\n" + "\n".join(report_items)) | ||
|
|
||
|
|
||
| # Are there any naughty glyphs? |
There was a problem hiding this comment.
cleanup this. Move into description/rationale
|
|
||
| ttFont = TTFont(TEST_FILE("slabo/Slabo13px.ttf")) | ||
| assert_results_contain( | ||
| check(wrap_args(config, ttFont)), FAIL, None, "Slabo: A!=664,V!=691" |
There was a problem hiding this comment.
here's an exemple of a place where we should be refering to a specific FAIL message by its keyword. By not having a keyword and using None we risk falsely detecting this as a successful code-test run while the actual FAIL message emitted by the check being tested may come from some other code-path.
Please always use keywords!
|
Thank you, this is super helpful! I’m going to (in a separate PR) clean up all the other places where bare strings are used instead of messages because I’m sure other people will cut-and-paste checks just like I did. |
Thanks! I'll be immensely grateful for that! |
when doing so, please follow this code-style, so that I don't have to do it afterwards: if "<html>" in description or "</html>" in description:
yield FAIL,\
Message("html-tag",
f"{descfile} should not have an <html> tag,"
f" since it should only be a snippet that will"
f" later be included in the Google Fonts"
f" font family specimen webpage.") |
The previous version worked nicely when generating standalone HTML reports, but needed tweaking to play well within the context of a bigger fontbakery report.
| the fontbakery configuration file. For more information about write | ||
| test files and how to configure fontbakery to read the test suites, | ||
| see https://simoncozens.github.io/tdd-for-otl/ | ||
| """, |
There was a problem hiding this comment.
Each paragraph in a rationale should be a single line. Do not perform manual line breaking. Fontbakery itself will do the text-layout math to better display the text block on each od the specialized reporters.
So here it should be:
@check(
id = 'com.google.fonts/check/shaping/collides',
rationale = """
Fonts with complex layout rules can benefit from regression checks to ensure that the rules are behaving as designed. This checks runs a test suite and reports instances where the glyphs collide in unexpected ways.
Test suites should be written by the font engineer and referenced in the fontbakery configuration file. For more information about writing test files and how to configure fontbakery to read the test suites, see https://simoncozens.github.io/tdd-for-otl/
""",I'm a bit annoyed by the word "test" and the expression "test suite" used here though... I understand it, but I'd rather use some other expression to avoid confusion keeping in mind the arbitrary definition of "tests" versus "checks" adopted in fontbakery jargon.
There was a problem hiding this comment.
the same same single-line per rationale paragraph style should be adopted in all checks included in this PR
|
|
||
| # This is a very generic "do something with shaping" test runner. | ||
| # It'll be given concrete meaning later. | ||
| def run_a_set_of_tests( |
There was a problem hiding this comment.
ok. I see. I think it is a bit confusing. But I see your point. I think I'll accept this for now and think better, maybe reevaluate later.
Note: for some reason I have reviewed this PR from bottom to top, so you will see another message from me below that was written before I saw your comment here.
| """, | ||
| misc_metadata={"request": "https://github.com/googlefonts/fontbakery/pull/3223"}, | ||
| ) | ||
| @check(id="com.google.fonts/check/shaping/forbidden") |
There was a problem hiding this comment.
Is there a second @check here? Or is it something weird about the GitHub PR review UI? I'm a bit confused. It looks like you forgot to remove the original @checkline when adding the rationale in this line.
|
|
||
| # This is a very generic "do something with shaping" test runner. | ||
| # It'll be given concrete meaning later. | ||
| def run_a_set_of_tests( |
There was a problem hiding this comment.
at least add shaping to the function name. So... for now, run_a_set_of_shaping_tests and we may later better discuss terminology
| 'beziers', | ||
| 'cmarkgfm' | ||
| 'cmarkgfm', | ||
| 'vharfbuzz', |
There was a problem hiding this comment.
Thoughts about making the new dependencies extras_requires packages so that they are optional? Maybe under a title like [shaping]? How well does vharfbuzz and anything else new that might be compiled here play with cross-platform installations of fontbakery?
There was a problem hiding this comment.
@chrissimpkins, I've seen your comments a few seconds after merging the PR, sorry.
If we do this, then we must ensure that the checks auto-skip (instead of resulting in an ERROR) if those modules cannot be imported successfully. But, if possible, I'd like to keep this in the default installation, otherwise I fear that a huge number of people will simply never run these checks.
There was a problem hiding this comment.
My plan was to cut a new fontbakery release after merging this PR. But your comment makes me want to better evaluate the cross-platform support of these new dependencies before committing to a new release.
|
thanks, @simoncozens |
Definitely agree Simon. I'd be interested in helping with this effort. In addition to the documentation, what is your thought about adding a simple set of templates that a user can grab and use to begin building out their shaping test suite? |
|
Yes, I was discussing this with Ben today. I think we found that because of differing glyph name conventions in different fonts (and different approaches to shaping), it's not really possible to provide a generic set of templates that users can just pick up and run with. However, it would be possible to give of set of inputs that they might want to use to provide coverage of major shaping requirements of script, and also to provide a little python script that they can run when they are happy with a particular rendering, which loads the test suite so far and then rewrites the expectations for that rendering. i.e., we give them: and if they like the output of ကြှ, they run |
|
Also note that I have a blog post at https://simoncozens.github.io/tdd-for-otl/ which is referenced in the rationale. But yes, we should provide some useful shaping files. I'll work on another PR. |
This would be incredibly valuable. My suggestion was much simpler though. Rather than providing any input text runs, do we want to provide the formatted JSON template that allows a user to grab the config file and begin entering text runs on their own? This seems like the initial hurdle to use. |
This will be a helpful article for the community. It would be good to see mention of Nikolaus's contribution to the shaping test idea and implementation. |
|
I've added a reference to Nikolaus' version. |
Description
OK, now we have a configuration file, I think this is a nice clean PR and good to go. The functionality that it adds is very powerful and non-obvious without example JSON files, so I think it may need extra documentation somewhere. Should I add something to the user manual, do we think?
To Do
CHANGELOG.md