Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix culture and line endings issues in tests #7778

Closed
wants to merge 9 commits into from

Conversation

volanavlad
Copy link

Fix some tests failures:

  • Due to bad line endings in xml resources. Replaced to xml entities 


  • If current culture is not invariant some tests fail due to exception messages are localized while assert strings are not. So it would be better to have localized strings in tests.

@dnfclas
Copy link

dnfclas commented Dec 17, 2019

CLA assistant check
All CLA requirements met.

@skofman1
Copy link
Contributor

Thanks for the contribution @volanavlad ! Can you please open an issue with the problem that you are fixing. We will work with you on merging this fix.

@zhhyu zhhyu self-assigned this Dec 17, 2019
@zhhyu zhhyu added this to the S163 - 2019.12.09 milestone Dec 17, 2019
@volanavlad
Copy link
Author

volanavlad commented Dec 17, 2019

Here is the issue: #7779

@joelverhagen
Copy link
Member

Regarding the newline changes, could this perhaps be due to Git configuration? I think there is a setting that tells give to checkout text files with \r\n but check-in \n -- this is the setting I have on my machine. Perhaps you have a setting that checks out \n?

I am surprised to see \n in there for your case and I am wondering if that is even related to your locale.

@volanavlad
Copy link
Author

You are right - issues are due to git settings and default OS UI culture.
But I think it is wrong to require windows line endings and En culture for all contributers while it can be easily fixed.
It annoys to have test errors while you need simply to check that your changes do not make new issues.

@joelverhagen
Copy link
Member

Regarding the line ending setting - totally agree this is a bad experience. Let's fix it! If we switch to XML entities in the RESX file will that get clobbered by the Visual Studio RESX editor when we make a change to the string?

@volanavlad
Copy link
Author

I have just tested it.
Visual Studio 2019 designer replaces XML entities to \r\n back :-(
But you can see it in commit diff and revert manually.

@joelverhagen
Copy link
Member

Could you make the change on the test side?

@volanavlad
Copy link
Author

Yes. I can move assert string to resx. So git setting will apply both to checked and actual strings. Test will work fine in both cases.

…estMethodFacts.IngestsAdvisory

use DateTimeOffset according to WithdrawnAt property definition
…softTeamSubscriptionFacts.TestSecurityPolicyService

issue NuGet#7779
@volanavlad
Copy link
Author

Fixed in commit '9ee4a940851e505d27ecb52d956b9ea4741f3159'

@volanavlad
Copy link
Author

+new issue fixed: #7783

@volanavlad
Copy link
Author

Sorry
It is very strange!
May be some internal string representations differs?

NuGetGallery.Security.MicrosoftTeamSubscriptionFacts.Policies_ReturnsMicrosoftTeamSubscriptionPolicies
Source: MicrosoftTeamSubscriptionFacts.cs line 15
Duration: 3 sec

Message:
Assert.Equal() Failure
↓ (pos 957)
Expected: ···or more information.\r\nPolicy violations: {0}"}
Actual: ···or more information.\r\nPolicy violations: {0}"}
↑ (pos 957)
Stack Trace:
Assert.Equal(String expected, String actual, Boolean ignoreCase, Boolean ignoreLineEndingDifferences, Boolean ignoreWhiteSpaceDifferences) line 244
Assert.Equal(String expected, String actual) line 174
MicrosoftTeamSubscriptionFacts.Policies_ReturnsMicrosoftTeamSubscriptionPolicies() line 48

@volanavlad
Copy link
Author

volanavlad commented Dec 18, 2019

It is json string in policy.Value
So it is escaped.

OK

Wait for next commit please.

…omplianceForPush

And emulate in test the same behavior as ResX file newline converted to json string
@volanavlad
Copy link
Author

fixed

@@ -215,7 +215,7 @@ public void ThrowsWhenInvalidMinClientVersion(bool strict)

// Act & Assert
var ex = Assert.Throws<ArgumentException>(() => PackageMetadata.FromNuspecReader(nuspec, strict));
Assert.Equal("'bad' is not a valid version string.\r\nParameter name: value", ex.Message);
Assert.Equal($"'bad' is not a valid version string.\r\n{TestStrings.Parameter_name}: value", ex.Message);
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of supporting localization here, would it be simpler to check the param name separately? In other words:

  1. Assert that the message begins with 'bad' is not a valid version string.
  2. Assert that the ex.ParamName is "value"

I'm concerned that supporting all locales will be tough 😅

Copy link
Contributor

Choose a reason for hiding this comment

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

As an alternative, see my comment below: #7778 (comment)

@loic-sharma
Copy link
Contributor

If current culture is not invariant some tests fail due to exception messages are localized while assert strings are not. So it would be better to have localized strings in tests.

Why is it better to have localized strings in tests? Wouldn't it be easier to set the current culture to invariant instead of localizing the tests? It seems like we could add something like this to our unit tests:

CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;

@volanavlad
Copy link
Author

Why is it better to have localized strings in tests? Wouldn't it be easier to set the current culture to invariant instead of localizing the tests? It seems like we could add something like this to our u

CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;

I started with this idea. But it requires much more refactoring of test code. For example - it is quite strange to change current ui culture in the middle of the test (i.e. inside assert function like tests/NuGetGallery.Facts/TestUtils/ContractAssert.cs ThrowsArgException() )
So you need to implement some base test classes with cuture set in constructor and inherit failed test from it.
But there are existing inheritance - so you need to check it... etc...
Moreover there are some use cases where it is not enought to set culture in current thread only - you to ensure that async context is well too....
I think it is much easy to have localized strings where it is needed.

@loic-sharma
Copy link
Contributor

I started with this idea. But it requires much more refactoring of test code. For example - it is quite strange to change current ui culture in the middle of the test (i.e. inside assert function like tests/NuGetGallery.Facts/TestUtils/ContractAssert.cs ThrowsArgException() )

Ah that's a good point. What do you think of creating a new attribute for unit tests that require localization? Something like:

public class InvariantCultureFactAttribute : FactAttribute
{
    public InvariantCultureFactAttribute()
    {
        CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
    }
}

Then the affected tests can look like:

[InvariantCultureFact]
public void MyTest()
{
    // The current culture is invariant now
}

This way we don't need to refactor too much code 😊

Moreover there are some use cases where it is not enought to set culture in current thread only - you to ensure that async context is well too....

Oof, that's tricky... For these tests that require multiple threads, I think it'd be best if we remove the assertions that require localization.

@zhhyu zhhyu removed this from the S164 - 2019.12.30 milestone Jan 17, 2020
@zhhyu
Copy link
Contributor

zhhyu commented Jan 21, 2020

Hi, @volanavlad. We are working on this problem, and seeking the best solution. Feel free to follow up this PR or the issue. Thanks!

@agr
Copy link
Contributor

agr commented Jan 25, 2020

I don't think introducing localization is the way to go: yes, it will fix it for Russian in the short term, but I imagine other languages would have the same issues as well, and we don't want to end up supporting a dozen of localisations just for the sake of tests.

I installed the Russian language pack in Windows and managed to reproduce the test failures due to exception text localization. All but two failures are due to, in my opinion, a bit too strict Assert.Equals(expectedMessage, ex.Message), which can be replaced with Assert.StartsWith(expectedStart, ex.Message) which would not include the new line characters and the "Parameter name" tail of the message (which gets localized).

Out of the remaining two, ThrowsForEmptyAndNonEmptyDuplicatesWhenDuplicateMetadataElementsDetectedAndParsingIsNotStrict should be fixed by setting current thread's UI culture carefully, since if we are expecting certain exception text, we have to eliminate the possible variability. Alternatively, we can file an issue against corefx to introduce a special type of exception for duplicate keys in a dictionary, but I have a feeling that is unlikely to get addressed.

Lastly, WillShowViewWithErrorsIfPackageIdIsBreaksParsing is potentially the tricky one since it seems the actual service code (the one being tested) needs improvement to not bubble service exceptions to the user, but use custom error message instead.

@zhhyu zhhyu removed their assignment Feb 10, 2020
@zhhyu
Copy link
Contributor

zhhyu commented Jun 10, 2020

Hi, @volanavlad! We have a recent fix for this issue: #8021.
Feel free to have a try on the latest master or dev branch, and see whether the issue still exists. If it still exists, feel free to leave the comment here. Thanks!

@skofman1 skofman1 closed this Apr 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants