Skip to content

Commit

Permalink
chore: Introduce a CultureSwitcher to make culture-based testing simpler
Browse files Browse the repository at this point in the history
  • Loading branch information
jskeet committed Sep 25, 2023
1 parent f85f792 commit c075454
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 13 deletions.
18 changes: 5 additions & 13 deletions Src/Support/Google.Apis.Tests/Apis/Utils/UtilitiesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,19 +129,11 @@ public void GetStringFromDateTimeOffset_MillisecondHandling(int tickOfSecond, st
[Fact]
public void DateTimeOffsetConversionsAreInvariant()
{
var originalCulture = Thread.CurrentThread.CurrentCulture;
try
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("da-DK");
var dto = new DateTimeOffset(2023, 6, 13, 15, 54, 13, 500, TimeSpan.Zero);
string text = "2023-06-13T15:54:13.500Z";
Assert.Equal(text, Utilities.GetStringFromDateTimeOffset(dto));
Assert.Equal(dto, Utilities.GetDateTimeOffsetFromString(text));
}
finally
{
Thread.CurrentThread.CurrentCulture = originalCulture;
}
using var _ = new CultureSwitcher("da-DK");
var dto = new DateTimeOffset(2023, 6, 13, 15, 54, 13, 500, TimeSpan.Zero);
string text = "2023-06-13T15:54:13.500Z";
Assert.Equal(text, Utilities.GetStringFromDateTimeOffset(dto));
Assert.Equal(dto, Utilities.GetDateTimeOffsetFromString(text));
}

// Local time of 2023-06-13T15:54:13, with variable UTC offset.
Expand Down
60 changes: 60 additions & 0 deletions Src/Support/Google.Apis.Tests/CultureSwitcher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
Copyright 2023 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

using System;
using System.Globalization;

namespace Google.Apis.Tests;

/// <summary>
/// Disposable class to help test code in different cultures.
/// On construction, this changes the current thread's current culture
/// to the specified one (and remembers the original culture). On disposal,
/// the original culture is restored.
/// </summary>
internal class CultureSwitcher : IDisposable
{
private readonly CultureInfo _originalCulture;

/// <summary>
/// Creates a new instance based on the name of the culture to switch to.
/// </summary>
internal CultureSwitcher(string name) : this(new CultureInfo(name))
{
}

/// <summary>
/// Creates a new instance switching to the specified culture.
/// </summary>
internal CultureSwitcher(CultureInfo newCulture)
{
_originalCulture = CultureInfo.CurrentCulture;
SetCulture(newCulture);
}

public void Dispose() => SetCulture(_originalCulture);

private void SetCulture(CultureInfo culture)
{
// CultureInfo.CurrentCulture is the preferred way to set this,
// but it was read-only on .NET Framework before v4.6.
#if NET452
System.Threading.Thread.CurrentThread.CurrentCulture = culture;
#else
CultureInfo.CurrentCulture = culture;
#endif
}
}

0 comments on commit c075454

Please sign in to comment.