Skip to content

Fix TryParseFeetInches when current locale uses ' as number separator - #794

Closed
pgrawehr wants to merge 6 commits into
angularsen:masterfrom
pgrawehr:ParserFix
Closed

Fix TryParseFeetInches when current locale uses ' as number separator#794
pgrawehr wants to merge 6 commits into
angularsen:masterfrom
pgrawehr:ParserFix

Conversation

@pgrawehr

Copy link
Copy Markdown
Contributor

My current locale (de-CH) uses ' (an apostrophe) as thousands separator. This broke the unit test for the TryParseFeetInches method, because the input string 1'1" is ambiguous. Therefore I now removed the separator as valid input in a feet-inches combination. It's pretty unlikely that someone will need to parse 1,345'21".

@codecov-commenter

codecov-commenter commented May 26, 2020

Copy link
Copy Markdown

Codecov Report

Merging #794 into master will increase coverage by 1.90%.
The diff coverage is 100.00%.

Impacted file tree graph

@@ Coverage Diff @@## master #794 +/- ##
==========================================
+ Coverage 78.60% 80.51% +1.90% 
==========================================
Files 280 280 Lines 41834 41850 +16 ==========================================
+ Hits 32884 33695 +811 + Misses 8950 8155 -795 
Impacted FilesCoverage Δ
UnitsNet/CustomCode/Quantities/Length.extra.cs86.95% <100.00%> (+0.43%)⬆️
UnitsNet/CustomCode/QuantityParser.cs97.05% <100.00%> (+0.18%)⬆️
UnitsNet/QuantityFormatter.cs94.44% <0.00%> (-2.11%)⬇️
...tensions/GeneratedCode/NumberToAreaExtensions.g.cs100.00% <0.00%> (ø)
...tensions/GeneratedCode/NumberToMassExtensions.g.cs100.00% <0.00%> (ø)
...ensions/GeneratedCode/NumberToAngleExtensions.g.cs100.00% <0.00%> (ø)
...ensions/GeneratedCode/NumberToForceExtensions.g.cs100.00% <0.00%> (ø)
...ensions/GeneratedCode/NumberToLevelExtensions.g.cs100.00% <0.00%> (ø)
...ensions/GeneratedCode/NumberToPowerExtensions.g.cs100.00% <0.00%> (ø)
...ensions/GeneratedCode/NumberToRatioExtensions.g.cs100.00% <0.00%> (ø)
... and 195 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3b36fd9...310db24. Read the comment docs.

@angularsenangularsen left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Very nice, looks good to me. Just a couple minor comments.

Comment threadUnitsNet/CustomCode/Quantities/Length.extra.cs Outdated
Comment threadUnitsNet.Tests/QuantityIFormattableTests.cs
@tmilnthorp

Copy link
Copy Markdown
Collaborator

I'm not so certain that just ignoring it is a good idea. Looks like we're missing a couple tests though - for your case as well as a number separated by a '

When the thousands separator is ' (i.e. de-CH language settings)
parsing 1'1" feet failed.
@pgrawehr

Copy link
Copy Markdown
ContributorAuthor

I'm not so certain that just ignoring it is a good idea. Looks like we're missing a couple tests though - for your case as well as a number separated by a '

What test cases are you thinking of? If the number is i.e. embedded in quotes, then I think it's ok to have parsing fail, as quotes are not part of a number (except in the case where the quote is one of the valid separators).

@tmilnthorp

Copy link
Copy Markdown
Collaborator

I added an example here: #799. I'm confused now though because it passes :)

@pgrawehr

Copy link
Copy Markdown
ContributorAuthor

@tmilnthorp : And I'm confused now because my updated test fails :-/

Output:

Error Message:
Assert.Equal() Failure
� (pos 1)
Expected: 2'012.12 øC
Actual: 2'012.12 øC
� (pos 1)
Stack Trace:
at UnitsNet.Tests.QuantityIFormattableTests.FormatStringWorksWithSuppliedLocale() in C:\projects\unitsnet\UnitsNet.Tests\QuantityIFormattableTests.cs:line 90

The strings are exactly the same to me...

I'll check what's going on with your PR.

@angularsen

angularsen commented May 28, 2020 via email

Copy link
Copy Markdown
Owner

@tmilnthorp

Copy link
Copy Markdown
Collaborator

Oh man. There's the right single quotation mark U+2019 and an apostrophe U+0027.

Sometimes, I feel like I know nothing 😆

@angularsen

angularsen commented May 28, 2020

Copy link
Copy Markdown
Owner

To be fair, xUnit COULD have been nice enough to help identify this by providing the character values when there is a single character off.

Comment threadUnitsNet.Tests/QuantityIFormattableTests.cs
Comment threadUnitsNet.Tests/QuantityIFormattableTests.cs
@pgrawehr

Copy link
Copy Markdown
ContributorAuthor

$"{temperature}".ToString(myCulture)

The reason is: It's defined that way: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#interpolated-strings

The type of $"..." is string, unless you immediatelly assign it to FormattableString. So the type of the expression is derived from the left-hand-side of the assigment.


// This does not work. Looks like a compiler bug to me.
// string f2 = $"{t:g}".ToString(c);
// Assert.Equal("2'012.12 °C", f2.ToString(c)); // Actual value is formatted according to CurrentUiCulture.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

The commented code does not work, because these two statements are equivalent:

stringf2=$"{t:g}".ToString(c);stringf2=t.ToString("g").ToString(c);

LINQPad sample

when CurrentUICulture is Norwegian and thousand separator is comma ,.

Temperaturet=Temperature.FromDegreesCelsius(2012.1234);CultureInfoc=newCultureInfo("de-CH",false);FormattableStringf=$"{t:g}";stringf2=$"{t:g}".ToString(c);stringf3=t.ToString("g").ToString(c);varexpected="2"+c.NumberFormat.NumberGroupSeparator+"012"+c.NumberFormat.NumberDecimalSeparator+"12 °C";(expected==f.ToString(c).Dump()).Dump();(expected==f2.ToString(c).Dump()).Dump();// Actual value is formatted according to CurrentUiCulture.(expected==f3.ToString(c).Dump()).Dump();// Actual value is formatted according to CurrentUiCulture.

Output:

2’012.12 °C
True
2,012.12 °C
False
2,012.12 °C
False

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Remove the commented code from this PR.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

As you've seen

FormattableString f = $"{t:g}";
string result = f.ToString(c);

is not equivalent to

string result = $"{t:g}".ToString(c);

which is what confused me (as this would be the case for every other expression).

I'll remove it, since the problem has nothing to do with this lib, but is a (weird but documented) feature of the CLR.

// This succeeds if only feet or inches are given, not both
if (TryParse(str, formatProvider, out result))
// Do not allow thousands separator here, since it may be equal to the unit abbreviation (').
if (TryParse(str, formatProvider, NumberStyles.Float, out result))

@angularsenangularsenMay 30, 2020

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

As @tmilnthorp pointed out earlier, we should have unit tests that covers the new behavior for feet-inches. It should test what happens if you try to parse strings like these, with a culture that has apostrophe character as thousand separator. We could also test cultures with other thousand separators, like nb-NO Norwegian that has . as separator (instead of , in US English).

1'500' 4"
1'5002′−4″
1'500 ft 4 in
1'5002′ 4″

My intuition tells me we should get an exception when parsing these, because the thousand separator is no longer allowed and in the first case the feet symbol is even listed twice.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I'll do that, but I feel we should somehow merge @tmilnthorp s PR with this one, otherwise it gets confusing.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I guess we can wait for #799 to merge first to reuse the combinatorial parameter refactoring that is about to be added there.

@angularsenangularsenJun 1, 2020

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

#799 was abandoned, please see #803 for supporting thousand separators in regex instead of not allowing them. I think that may be a better solution to this problem.

@tmilnthorptmilnthorp mentioned this pull request Jun 1, 2020
@stale

staleBot commented Aug 1, 2020

Copy link
Copy Markdown

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stalestaleBot added the wontfix label Aug 1, 2020
@stalestaleBot closed this Aug 8, 2020
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@pgrawehr@codecov-commenter@tmilnthorp@angularsen