Skip to content

Remove StringUtil class and update tests references #4819#4827

Merged
manfred-brands merged 4 commits intonunit:mainfrom
yergios:main
Sep 21, 2024
Merged

Remove StringUtil class and update tests references #4819#4827
manfred-brands merged 4 commits intonunit:mainfrom
yergios:main

Conversation

@yergios
Copy link
Copy Markdown
Contributor

@yergios yergios commented Sep 14, 2024

Fixes #4819

Proceeded to removing the whole internal StringUtil class and replaced its methods references at the tests for built-in System.StringComparison.

mr-sergito and others added 2 commits September 14, 2024 23:59
- Removed the legacy internal StringUtil class, including Compare and
  StringEqual methods.
- Updated references in tests to use System.StringComparison instead.
@yergios

This comment has been minimized.

Copy link
Copy Markdown
Member

@manfred-brands manfred-brands left a comment

Choose a reason for hiding this comment

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

In my opinion path comparison should be using Ordinal comparison.
But I would like a second opinion before I request changes. @OsirisTerje ?

Comment thread src/NUnitFramework/framework/Constraints/PathConstraint.cs Outdated
Comment thread src/NUnitFramework/framework/Constraints/SamePathConstraint.cs Outdated
Comment thread src/NUnitFramework/framework/Constraints/SamePathOrUnderConstraint.cs Outdated
@stevenaw
Copy link
Copy Markdown
Member

stevenaw commented Sep 15, 2024

I would typically be cautious about changing the comparison, however after a bit of investigation it would seem that the current recommendations are for these comparisons to be ordinal (https://learn.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings).

I did find this mono issue from a few years back where it's alluded that this culture-specific comparison may be a relic of older Windows versions. In the thread it's then suggested that, at the time, mono should not make that change "blindly" on their end and that instead caution should be taken (mono/mono#10230 (comment)).

All that is to say I'm also curious @OsirisTerje 's thoughts on the matter.

EDIT: Also, if it's not an easy decision on our end then it might also be worth not holding up the PR over as I'm sure @mr-sergito is eager to land their first PR :)

Copy link
Copy Markdown
Member

@stevenaw stevenaw left a comment

Choose a reason for hiding this comment

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

Thanks @mr-sergito ! The changes look great. I have left one minor suggestion outside of the Ordinal vs culture discussion to help avoid duplication while still allowing us to remove the StringUtil class.


// path 2 is longer than path 1: see if initial parts match
if (!StringUtil.StringsEqual(path1, path2.Substring(0, length1), caseInsensitive))
StringComparison comparisonType = caseInsensitive
Copy link
Copy Markdown
Member

@stevenaw stevenaw Sep 15, 2024

Choose a reason for hiding this comment

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

One suggestion: As SamePathConstraint and SamePathOrUnderConstraint both inherit from PathConstraint it may help avoid duplication if we exposed a protected property or method here in PathConstraint to encapsulate the case-sensitivity check and return a StringComparison for use.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Hey @stevenaw ! Thanks for the review, I'll make this improvement right away.

@OsirisTerje
Copy link
Copy Markdown
Member

Being a Norwegian we do have locale issues. We should not use CurrentCulture, as that may change dependent upon locale installation. Since this is for Paths, Ordinal would be the preferred. Imho.

But, since this is a PathConstraint and part of the framework, may it have some effects on someones tests if we change it? We don't have any issues for the PathConstraint itself (open nor closed) as far as I can see.

@manfred-brands
Copy link
Copy Markdown
Member

But, since this is a PathConstraint and part of the framework, may it have some effects on someones tests if we change it? We don't have any issues for the PathConstraint itself (open nor closed) as far as I can see.

We currently have a non-consistent system due to changes in culture comparison in .net 6

Using the German culture (de-DE), .NET Framework treats 'ss' as being equal to 'ß'. But .NET 6+ does not, neither does the file system. The below test passes in the first, fails in the latter.

[Test]
[SetCulture("de-DE")]
public void PathNameComparison()
{
    Assert.That("Grass", Is.SamePath("Graß"));
}

But when creating files with those two names, regardless of Framework, I get two files:

[Test]
[SetCulture("de-DE")]
public void PathContentComparison()
{
    const string Contents = "Written";
    const string OtherContents = "But not really";
    File.WriteAllText("Graß", OtherContents);
    File.WriteAllText("Grass", Contents);
    string content = File.ReadAllText("Graß");
    Assert.That(content, Is.EqualTo(Contents));
}

To me this means two things:

  1. Even though we used CurrentCulture we have no tests for this (special non-ascii characters) as otherwise we would have notice .NET core difference.
  2. File System is not Culture aware (but then my OS is en-AU)

So I think we should use Ordinal(IgnoreCase) file file system comparison.

@stevenaw
Copy link
Copy Markdown
Member

stevenaw commented Sep 18, 2024

I'm alright with converting these to ordinal too. I haven't been able to find any evidence of a present or historical OS filesystem which relies on culture. Based on that, we can likely infer that any path-related tests which rely on culture are rare at best, and any that do would likely not accurately test the underlying system.

Lastly, I have to wonder if the culture comparisons in this helper were originally added for other reasons. Some .net functions like StartsWith(string) and EndsWith(string) are themselves culture-aware and so it's possible the culture check were originally added in the NUnit helper to accurately test the corresponding assertion. I haven't done the code archeology to confirm, but it could explain how culture comparisons also came to be used on path-specific use cases.

In summary, and based on the reactions to @manfred-brands comment above, I think the team agrees we should convert these to ordinal 🙂

mr-sergito added 2 commits September 18, 2024 20:24
Changes suggested after PR review.
- Replacing path-related comparisons from CurrentCulture to Ordinal.
- Encapsulation of case-sensitivity check to reduce code duplication.
@yergios
Copy link
Copy Markdown
Contributor Author

yergios commented Sep 18, 2024

Thanks everyone for the insights! I honestly didn't know that much about string comparisons, it has been interesting.

I've made the suggested changes regarding string comparisons on path-related tests.

stevenaw
stevenaw previously approved these changes Sep 19, 2024
Copy link
Copy Markdown
Member

@stevenaw stevenaw left a comment

Choose a reason for hiding this comment

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

This looks great to me, thanks for your contribution @mr-sergito !

@manfred-brands I'll wait a few days to merge to allow you the chance to review if you wanted given you helped shape direction of this too

@stevenaw stevenaw dismissed their stale review September 19, 2024 21:23

Forgot to run CI

@stevenaw
Copy link
Copy Markdown
Member

stevenaw commented Sep 19, 2024

Looks like a test failure on the Mac agent. I'm having a hard time seeing the failure on my phone but I'll try again from a computer later on. Seems related to a "custom teardown action"?

Copy link
Copy Markdown
Member

@stevenaw stevenaw left a comment

Choose a reason for hiding this comment

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

CI is happy again

Copy link
Copy Markdown
Member

@manfred-brands manfred-brands left a comment

Choose a reason for hiding this comment

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

I also have no further change requests.
Thanks again @mr-sergito for your cooperation.

@manfred-brands manfred-brands merged commit af7b941 into nunit:main Sep 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove StringUtil.Compare() and update references in the tests

4 participants