Skip to content

Conversation

@QuncCccccc
Copy link
Contributor

@QuncCccccc QuncCccccc commented Nov 21, 2025

This PR is to add a more clear error description when there is a special white space NNBSP(\u202f). This whitespace character is used to connect time and "am"/"pm".

In this PR, I only updated the description in _MatchesSemanticsData and still not sure if it's necessary to create another custom matcher class to ignore special whitespace. I think it's valid to directly update users' test results since the expected results have indeed changed.

This is my experiment for the whitespace change when we update generated_date_localization.dart: cl/831625146
I went through all Scuba diffs and all results look expected. Once this is landed, we can use the CL change (except the image change) as g3fix to update the date localizations.

Fixes #177479

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I signed the [CLA].
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • I followed the [breaking change policy] and added [Data Driven Fixes] where supported.
  • All existing and new tests are passing.

@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests or get an explicit test exemption before merging.

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. If you believe this PR qualifies for a test exemption, contact "@test-exemption-reviewer" in the #hackers channel in Discord (don't just cc them here, they won't see it!). The test exemption team is a small volunteer group, so all reviewers should feel empowered to ask for tests, without delegating that responsibility entirely to the test exemption group.

@github-actions github-actions bot added a: tests "flutter test", flutter_test, or one of our tests framework flutter/packages/flutter repository. See also f: labels. labels Nov 21, 2025
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request aims to improve error messages for tests involving the narrow no-break space character (\u202f). The changes introduce helper methods to handle string comparisons and provide more specific feedback when a mismatch is due to this special whitespace. While the refactoring is a good idea, I've found a critical logical bug in the implementation that would cause test matchers to pass incorrectly. I've also identified a medium-severity issue regarding type safety and code clarity. I've provided suggestions to fix both issues.

@QuncCccccc QuncCccccc force-pushed the add_error_description_for_NBSP branch from 95743d1 to 60b6c2b Compare November 21, 2025 06:12
@Piinks Piinks requested review from Piinks and dkwingsmt December 9, 2025 23:22
@dkwingsmt
Copy link
Contributor

What is the result of this fix supposed to be? We should have a unit test to verify and demonstrate the result. And also I'm questioning the design, if I understand correctly.

@chunhtai chunhtai self-requested a review December 16, 2025 19:00
@QuncCccccc
Copy link
Contributor Author

What is the result of this fix supposed to be?

It is just to show a more clear error description in semantics check when nbsp('\u202f') is used in text. When we run date_localization script, a bunch of \u202f showing up but the error description only shows an empty space " " which is exactly the same as the normal empty space and it causes difficulty to debug. So we need to find a way to distinguish them.

Sorry I missed a unit test! Added one!

@QuncCccccc QuncCccccc force-pushed the add_error_description_for_NBSP branch from cf3cbd7 to c447b67 Compare December 18, 2025 19:35
@dkwingsmt
Copy link
Contributor

dkwingsmt commented Dec 18, 2025

Note: I was skeptical of the design of the error messages, because I thought it would be better to show the original nbsp character in the expected string and instead explain the details with appended descriptions, such as "where the 5th character is \nbsp", so that the shown expected string itself is true and copiable.

I talked with Qun, and understands now that it is intentional that the expected string contains the escaped string, so that maintainers can simply copy the entire string to the source file.

The design looks good to me. I'll make a full review after the checks are green.

@dkwingsmt
Copy link
Contributor

@QuncCccccc Another question: Will this change handle the case where the expected string uses spaces and the actual string uses nbsp?

@QuncCccccc
Copy link
Contributor Author

Yes, in the unit test, we set the actual value to be "AAA\u202fBBB", and expected to be "AAA BBB", the error description shows the value should be "AAA\u202fBBB". If we reverse the actual and expected, like setting actual to be "AAA BBB", and set expected to be "AAA\u202fBBB", then the description will say the value should be "AAA BBB", and developers can still just copy and paste the message. Does that make sense? I can talk about it offline anytime:)!

final String actualWithNBSP = actual.replaceAll('\u202f', r'\u202f');
return failWithDescription(matchState, '$prefixText was $actualWithNBSP');
}
return failWithDescription(matchState, '$prefixText was $actual');
Copy link
Contributor

@chunhtai chunhtai Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not also apply final String actualWithNBSP = actual.replaceAll('\u202f', r'\u202f'); here?

expect('another\u202fString' , 'some String');

will first show 'another String', and then developer copy over they will see 'another\u202fString' which is unecessary two step correction

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah it makes sense! Updated!

if (expected!.string != actual!.string) {
return _checkStringMismatch(matchState, prefixText, expected.string, actual.string);
}
return failWithDescription(matchState, '$prefixText was: $actual');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same should consider add final String actualWithNBSP = actual.replaceAll('\u202f', r'\u202f')
otherwise if the expect string are correctly using \u202f they error message will display string without the \u202f

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated! Thanks!

@dkwingsmt
Copy link
Contributor

Yes, in the unit test, we set the actual value to be "AAA\u202fBBB", and expected to be "AAA BBB", the error description shows the value should be "AAA\u202fBBB". If we reverse the actual and expected, like setting actual to be "AAA BBB", and set expected to be "AAA\u202fBBB", then the description will say the value should be "AAA BBB", and developers can still just copy and paste the message. Does that make sense? I can talk about it offline anytime:)!

Sounds good. Can you add a unit test for it?

@QuncCccccc
Copy link
Contributor Author

Can you add a unit test for it?

Done.

@QuncCccccc QuncCccccc requested a review from chunhtai December 18, 2025 23:08
Copy link
Contributor

@chunhtai chunhtai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment on lines 2708 to 2710
final String actualStringWithNBSP = actual.string.replaceAll('\u202f', r'\u202f');
final actualWithNBSP = AttributedString(actualStringWithNBSP, attributes: actual.attributes);
return failWithDescription(matchState, '$prefixText was: $actualWithNBSP');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Rename it with "escaped", a more common way to call this process

Suggested change
final String actualStringWithNBSP = actual.string.replaceAll('\u202f', r'\u202f');
final actualWithNBSP = AttributedString(actualStringWithNBSP, attributes: actual.attributes);
return failWithDescription(matchState, '$prefixText was: $actualWithNBSP');
final String actualStringEscaped = actual.string.replaceAll('\u202f', r'\u202f');
final actualEscaped = AttributedString(actualStringEscaped, attributes: actual.attributes);
return failWithDescription(matchState, '$prefixText was: $actualEscaped');

Comment on lines 2699 to 2700
final String actualWithNBSP = actual.replaceAll('\u202f', r'\u202f');
return failWithDescription(matchState, '$prefixText was $actualWithNBSP');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Rename it with "escaped", a more common way to call this process

Suggested change
final String actualWithNBSP = actual.replaceAll('\u202f', r'\u202f');
return failWithDescription(matchState, '$prefixText was $actualWithNBSP');
final String actualEscaped = actual.replaceAll('\u202f', r'\u202f');
return failWithDescription(matchState, '$prefixText was $actualEscaped');

isA<TestFailure>().having(
(TestFailure e) => e.message,
'message',
contains(r'label was label 0'),
Copy link
Contributor

@dkwingsmt dkwingsmt Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will the error message in this case show a "space" in both expected and actual, since I think you only escaped one of them? In that case this PR is not solving this problem completely, but I'll leave it to you to decide whether it's acceptable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see! I think it makes sense. :) I updated the error description for both actual and expected, so it now contains 202f regardless of whether it's in actual or expected.

Copy link
Contributor

@dkwingsmt dkwingsmt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thank you for the cleanup!

@QuncCccccc QuncCccccc added the autosubmit Merge PR when tree becomes green via auto submit App label Dec 22, 2025
@auto-submit auto-submit bot added this pull request to the merge queue Dec 22, 2025
Merged via the queue into flutter:master with commit 08e122f Dec 22, 2025
70 checks passed
@flutter-dashboard flutter-dashboard bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Dec 22, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 23, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 23, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 23, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 23, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 23, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 23, 2025
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Dec 23, 2025
Manual roll Flutter from 57c3f8b to 6ff7f30 (83 revisions)

Manual roll requested by stuartmorgan@google.com

flutter/flutter@57c3f8b...6ff7f30

2025-12-23 engine-flutter-autoroll@skia.org Roll Packages from f28cf2e to 5e3a766 (3 revisions) (flutter/flutter#180232)
2025-12-23 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from CmFPyvSc-K8_WDd5p... to 5EgkVbjGVZmCFPdtR... (flutter/flutter#180230)
2025-12-23 engine-flutter-autoroll@skia.org Roll Skia from db7ec9a14905 to bdb147ae3040 (2 revisions) (flutter/flutter#180222)
2025-12-23 bruno.leroux@gmail.com Add SnackBarTheme (flutter/flutter#180001)
2025-12-23 engine-flutter-autoroll@skia.org Roll Skia from 0b1ba3920f1c to db7ec9a14905 (1 revision) (flutter/flutter#180219)
2025-12-23 engine-flutter-autoroll@skia.org Roll Dart SDK from 31e9f619e18a to 94b05f717ba3 (1 revision) (flutter/flutter#180216)
2025-12-23 engine-flutter-autoroll@skia.org Roll Skia from a3e4f7b9d5f3 to 0b1ba3920f1c (1 revision) (flutter/flutter#180214)
2025-12-23 engine-flutter-autoroll@skia.org Roll Skia from b8517d1e25f7 to a3e4f7b9d5f3 (2 revisions) (flutter/flutter#180211)
2025-12-23 dkwingsmt@users.noreply.github.com [Engine] iOS style blurring (flutter/flutter#175458)
2025-12-23 engine-flutter-autoroll@skia.org Roll Dart SDK from 2243e91acaf2 to 31e9f619e18a (1 revision) (flutter/flutter#180210)
2025-12-22 36861262+QuncCccccc@users.noreply.github.com Add error description for nbsp character(\u202f) (flutter/flutter#178895)
2025-12-22 engine-flutter-autoroll@skia.org Roll Skia from 98c01ea504d7 to b8517d1e25f7 (1 revision) (flutter/flutter#180207)
2025-12-22 116356835+AbdeMohlbi@users.noreply.github.com Small clean up in `LocalizationPlugin` (flutter/flutter#180053)
2025-12-22 engine-flutter-autoroll@skia.org Roll Skia from c5beca8fa90b to 98c01ea504d7 (2 revisions) (flutter/flutter#180202)
2025-12-22 engine-flutter-autoroll@skia.org Roll Dart SDK from cff33b09b24d to 2243e91acaf2 (1 revision) (flutter/flutter#180199)
2025-12-22 116356835+AbdeMohlbi@users.noreply.github.com Remove usages of Android's `AsyncTask` in favor of `java.util.concurrent` (flutter/flutter#180050)
2025-12-22 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from 18ZvfJB61p7Z8HAaC... to CmFPyvSc-K8_WDd5p... (flutter/flutter#180193)
2025-12-22 engine-flutter-autoroll@skia.org Roll Skia from 7b7083ed9d57 to c5beca8fa90b (5 revisions) (flutter/flutter#180187)
2025-12-22 engine-flutter-autoroll@skia.org Roll Dart SDK from 38812d17127d to cff33b09b24d (1 revision) (flutter/flutter#180185)
2025-12-22 engine-flutter-autoroll@skia.org Roll Skia from 0eef18a0e2e6 to 7b7083ed9d57 (1 revision) (flutter/flutter#180184)
2025-12-22 engine-flutter-autoroll@skia.org Roll Dart SDK from 66c8013acbff to 38812d17127d (1 revision) (flutter/flutter#180179)
2025-12-21 engine-flutter-autoroll@skia.org Roll Skia from 6fbc6c75b9bb to 0eef18a0e2e6 (2 revisions) (flutter/flutter#180176)
2025-12-21 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from kGnnY1-fTWwYAnk8e... to 18ZvfJB61p7Z8HAaC... (flutter/flutter#180173)
2025-12-21 engine-flutter-autoroll@skia.org Roll Skia from 1a4ca755288a to 6fbc6c75b9bb (1 revision) (flutter/flutter#180167)
2025-12-20 engine-flutter-autoroll@skia.org Roll Skia from 2ad7452bd9d1 to 1a4ca755288a (1 revision) (flutter/flutter#180160)
2025-12-20 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from oe10epXkqGnv21AbZ... to kGnnY1-fTWwYAnk8e... (flutter/flutter#180158)
2025-12-20 engine-flutter-autoroll@skia.org Roll Skia from b01ad49ea807 to 2ad7452bd9d1 (1 revision) (flutter/flutter#180155)
2025-12-20 engine-flutter-autoroll@skia.org Roll Dart SDK from 8fb1c0c0a8ae to 66c8013acbff (1 revision) (flutter/flutter#180154)
2025-12-20 737941+loic-sharma@users.noreply.github.com Remove unnecessary RadioGroup migration TODOs (flutter/flutter#180105)
2025-12-20 98614782+auto-submit[bot]@users.noreply.github.com Reverts "[reland] Unify canvas creation and Surface code in Skwasm and CanvasKit (#179473)" (flutter/flutter#180152)
2025-12-20 engine-flutter-autoroll@skia.org Roll Skia from 3cc7e81928f0 to b01ad49ea807 (1 revision) (flutter/flutter#180151)
2025-12-20 engine-flutter-autoroll@skia.org Roll Dart SDK from ac95c6e8a31d to 8fb1c0c0a8ae (1 revision) (flutter/flutter#180148)
2025-12-19 137456488+flutter-pub-roller-bot@users.noreply.github.com Roll pub packages (flutter/flutter#180146)
2025-12-19 engine-flutter-autoroll@skia.org Roll Skia from fa4434632ce6 to 3cc7e81928f0 (4 revisions) (flutter/flutter#180142)
2025-12-19 1961493+harryterkelsen@users.noreply.github.com [reland] Unify canvas creation and Surface code in Skwasm and CanvasKit (flutter/flutter#179473)
2025-12-19 engine-flutter-autoroll@skia.org Roll Skia from ae5dd72b3591 to fa4434632ce6 (2 revisions) (flutter/flutter#180136)
2025-12-19 45459898+RamonFarizel@users.noreply.github.com Semantics headingLeveldoc update (flutter/flutter#179999)
2025-12-19 matt.kosarek@canonical.com Fix an issue where the semantics announce event may be encoded as either an int32_t or an int64_t depending on its value (flutter/flutter#180071)
2025-12-19 bkonyi@google.com [ Web ] Pass `--enable-experimental-ffi` when compiling WASM tests (flutter/flutter#180127)
2025-12-19 engine-flutter-autoroll@skia.org Roll Dart SDK from cfc117d10d36 to ac95c6e8a31d (1 revision) (flutter/flutter#180130)
2025-12-19 58529443+srujzs@users.noreply.github.com Pass canaryFeatures to BuildSettings (flutter/flutter#180108)
2025-12-19 engine-flutter-autoroll@skia.org Roll Skia from fe2be289c9fe to ae5dd72b3591 (1 revision) (flutter/flutter#180129)
2025-12-19 engine-flutter-autoroll@skia.org Roll Packages from 6f392aa to f28cf2e (1 revision) (flutter/flutter#180124)
2025-12-19 94012149+richardexfo@users.noreply.github.com Set text input purpose and hints on Linux platform (flutter/flutter#180013)
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: tests "flutter test", flutter_test, or one of our tests framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve error message on string matching

3 participants