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

Make source generators culture invariant #249

Merged
merged 1 commit into from
May 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

using System.Collections.Immutable;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using CommunityToolkit.Mvvm.SourceGenerators.ComponentModel.Models;
using CommunityToolkit.Mvvm.SourceGenerators.Diagnostics;
Expand Down Expand Up @@ -756,7 +757,7 @@ public static string GetGeneratedPropertyName(IFieldSymbol fieldSymbol)
propertyName = propertyName.TrimStart('_');
}

return $"{char.ToUpper(propertyName[0])}{propertyName.Substring(1)}";
return $"{char.ToUpper(propertyName[0], CultureInfo.InvariantCulture)}{propertyName.Substring(1)}";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using CommunityToolkit.Mvvm.SourceGenerators.Diagnostics;
using CommunityToolkit.Mvvm.SourceGenerators.Extensions;
Expand Down Expand Up @@ -358,7 +359,7 @@ public static (string FieldName, string PropertyName) GetGeneratedFieldAndProper

propertyName += "Command";

string fieldName = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1)}";
string fieldName = $"{char.ToLower(propertyName[0], CultureInfo.InvariantCulture)}{propertyName.Substring(1)}";

return (fieldName, propertyName);
}
Expand Down
19 changes: 19 additions & 0 deletions tests/CommunityToolkit.Mvvm.UnitTests/Test_ICommandAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,16 @@ public async Task Test_ICommandAttribute_TaskOfTReturns()
Assert.AreEqual("Hello world", await (Task<string>)greetWithParamAndCommandTask);
}

// See https://github.com/CommunityToolkit/dotnet/issues/230
[TestMethod]
public void Test_ICommandAttribute_CultureAwareCommandName()
{
ModelWithCultureAwareCommandName model = new();

// This just needs to ensure it compiles, really
model.InitializeCommand.Execute(null);
}

#region Region
public class Region
{
Expand Down Expand Up @@ -787,4 +797,13 @@ private async Task<string> GreetWithParamAndTokenAsync(object _, CancellationTok
return "Hello world";
}
}

partial class ModelWithCultureAwareCommandName
{
// This starts with "I" to ensure it's converted to lowercase using invariant culture
[ICommand]
private void Initialize()
{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,23 @@ public void Test_ObservableProperty_WithBaseViewModelWithObservableObjectAttribu
CollectionAssert.AreEqual(new[] { nameof(model.MyProperty), nameof(model.OtherProperty) }, propertyNames);
}

// See https://github.com/CommunityToolkit/dotnet/issues/230
[TestMethod]
public void Test_ObservableProperty_ModelWithCultureAwarePropertyName()
{
ModelWithCultureAwarePropertyName model = new();

List<string?> propertyNames = new();

model.PropertyChanged += (s, e) => propertyNames.Add(e.PropertyName);

model.InputFolder = 42;

Assert.AreEqual(model.InputFolder, 42);

CollectionAssert.AreEqual(new[] { nameof(model.InputFolder) }, propertyNames);
}

public abstract partial class BaseViewModel : ObservableObject
{
public string? Content { get; set; }
Expand Down Expand Up @@ -965,4 +982,13 @@ partial class ModelWithMultipleGenericParameters<T, U> : ObservableObject, IValu
[ObservableProperty]
private List<T>? list;
}

[ObservableObject]
partial class ModelWithCultureAwarePropertyName
{
// This starts with "i" as it's one of the characters that can change when converted to uppercase.
// For instance, when using the Turkish language pack, this would become "İnputFolder" if done wrong.
[ObservableProperty]
private int _inputFolder;
}
}