From e4416750b93cc3d0099139686928cf7c7231889e Mon Sep 17 00:00:00 2001 From: Jason Ginchereau Date: Fri, 17 Oct 2025 10:08:40 -1000 Subject: [PATCH 1/3] Fix issues flagged by dotnet format --- src/NodeApi.DotNetHost/JSMarshaller.cs | 15 ++++-- src/NodeApi.DotNetHost/TypeExporter.cs | 16 +++--- src/NodeApi.Generator/ExpressionExtensions.cs | 12 ++--- src/NodeApi.Generator/Program.cs | 2 +- src/NodeApi.Generator/SourceBuilder.cs | 3 +- src/NodeApi.Generator/StringExtensions.cs | 4 +- .../TypeDefinitionsGenerator.cs | 52 +++++++++++-------- src/NodeApi/DotNetHost/NativeHost.cs | 3 +- src/NodeApi/JSError.cs | 2 +- src/NodeApi/JSException.cs | 2 +- test/HostedClrTests.cs | 5 +- test/JSProjectTests.cs | 2 +- test/NativeAotTests.cs | 3 +- test/NodejsEmbeddingTests.cs | 5 +- test/TestBuilder.cs | 7 +-- 15 files changed, 78 insertions(+), 55 deletions(-) diff --git a/src/NodeApi.DotNetHost/JSMarshaller.cs b/src/NodeApi.DotNetHost/JSMarshaller.cs index aa8ec644..754ec010 100644 --- a/src/NodeApi.DotNetHost/JSMarshaller.cs +++ b/src/NodeApi.DotNetHost/JSMarshaller.cs @@ -2203,7 +2203,8 @@ private LambdaExpression BuildConvertFromJSValueExpression(Type toType) { statements = new[] { Expression.Default(typeof(ValueTuple)) }; } - else if (genericTypeDefinition?.Name.StartsWith("ValueTuple`") == true) + else if (genericTypeDefinition?.Name.StartsWith( + "ValueTuple`", StringComparison.Ordinal) == true) { /* * new ValueTuple((T1)value[0], (T2)value[1], ...) @@ -2323,7 +2324,8 @@ Expression TupleItem(int index) => InlineOrInvoke( { statements = BuildFromJSToCollectionClassExpressions(toType, valueParameter); } - else if (toType.IsGenericType && toType.Name.StartsWith("Tuple`")) + else if (toType.IsGenericType && + toType.Name.StartsWith("Tuple`", StringComparison.Ordinal)) { /* * new Tuple((T1)value[0], (T2)value[1], ...) @@ -2527,7 +2529,8 @@ private LambdaExpression BuildConvertToJSValueExpression(Type fromType) typeof(JSValue)), }; } - else if (genericTypeDefinition?.Name.StartsWith("ValueTuple`") == true) + else if (genericTypeDefinition?.Name.StartsWith( + "ValueTuple`", StringComparison.Ordinal) == true) { /* * new JSArray(new JSValue[] { (JSValue)value.Item1, (JSValue)value.Item2... }) @@ -2646,7 +2649,8 @@ Expression TupleItem(int index) => InlineOrInvoke( statements = BuildToJSFromCollectionClassExpressions( fromType, variables, valueExpression); } - else if (fromType.IsGenericType && fromType.Name.StartsWith("Tuple`") == true) + else if (fromType.IsGenericType && + fromType.Name.StartsWith("Tuple`", StringComparison.Ordinal) == true) { /* * new JSArray(new JSValue[] { (JSValue)value.Item1, (JSValue)value.Item2... }) @@ -3673,7 +3677,8 @@ private static bool IsTypedArrayType(Type elementType) private string FullMethodName(MethodInfo method, string? prefix = null) { string name = method.Name; - if (name.StartsWith("get_") || name.StartsWith("set_")) + if (name.StartsWith("get_", StringComparison.Ordinal) || + name.StartsWith("set_", StringComparison.Ordinal)) { prefix ??= name.Substring(0, 4); name = name.Substring(4); diff --git a/src/NodeApi.DotNetHost/TypeExporter.cs b/src/NodeApi.DotNetHost/TypeExporter.cs index 5e186526..222b7b4c 100644 --- a/src/NodeApi.DotNetHost/TypeExporter.cs +++ b/src/NodeApi.DotNetHost/TypeExporter.cs @@ -308,7 +308,8 @@ private static bool IsExtensionTargetTypeSupported(Type targetType, string exten targetType == typeof(object) || targetType == typeof(string) || targetType == typeof(Type) || - targetType.Name == nameof(Task) || targetType.Name.StartsWith(nameof(Task) + '`')) + targetType.Name == nameof(Task) || + targetType.Name.StartsWith(nameof(Task) + '`', StringComparison.Ordinal)) { TraceDebug($"Target type '{targetType.FormatName()}' not supported for " + $"extension method '{extensionMethodName}'."); @@ -323,8 +324,9 @@ private static bool IsExtensionTargetTypeSupported(Type targetType, string exten else if ((targetType.GetInterface(nameof(System.Collections.IEnumerable)) != null && (targetType.Namespace == typeof(System.Collections.IEnumerable).Namespace || targetType.Namespace == typeof(IEnumerable<>).Namespace)) || - targetType.Name.StartsWith("IAsyncEnumerable`") || - targetType.Name == nameof(Tuple) || targetType.Name.StartsWith(nameof(Tuple) + '`')) + targetType.Name.StartsWith("IAsyncEnumerable`", StringComparison.Ordinal) || + targetType.Name == nameof(Tuple) || + targetType.Name.StartsWith(nameof(Tuple) + '`', StringComparison.Ordinal)) { TraceDebug($"Collection target type '{targetType.FormatName()}' not supported for " + $"extension method '{extensionMethodName}'."); @@ -996,9 +998,11 @@ private static bool IsSupportedType(Type type) if (type.IsPointer || type == typeof(void) || type.Namespace == "System.Reflection" || - (type.Namespace?.StartsWith("System.Collections.") == true && !type.IsGenericType) || - (type.Namespace?.StartsWith("System.Threading.") == true && type != typeof(Task) && - !(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Task<>)))) + (type.Namespace?.StartsWith("System.Collections.", StringComparison.Ordinal) == true && + !type.IsGenericType) || + (type.Namespace?.StartsWith("System.Threading.", StringComparison.Ordinal) == true && + type != typeof(Task) && + !(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Task<>)))) { return false; } diff --git a/src/NodeApi.Generator/ExpressionExtensions.cs b/src/NodeApi.Generator/ExpressionExtensions.cs index 96fa26f3..88bf2a72 100644 --- a/src/NodeApi.Generator/ExpressionExtensions.cs +++ b/src/NodeApi.Generator/ExpressionExtensions.cs @@ -63,7 +63,7 @@ private static string ToCS( lambda.Parameters.Select((p) => p.Name!))]), ParameterExpression parameter => - (parameter.IsByRef && parameter.Name?.StartsWith(OutParameterPrefix) == true) ? + (parameter.IsByRef && parameter.Name?.StartsWith(OutParameterPrefix, StringComparison.Ordinal) == true) ? parameter.Name.Substring(OutParameterPrefix.Length) : parameter.Name ?? "_", BlockExpression block => FormatBlock(block, path, variables), @@ -128,13 +128,13 @@ member.Expression is ParameterExpression parameterExpression && call.Arguments.Take(call.Arguments.Count - 1), path, variables, "[]") + " = " + ToCS(call.Arguments.Last(), path, variables) : #if !STRING_AS_SPAN - call.Method.Name.StartsWith("get_") ? + call.Method.Name.StartsWith("get_", StringComparison.Ordinal) ? (call.Method.IsStatic ? FormatType(call.Method.DeclaringType!) + "." + call.Method.Name.Substring(4): WithParentheses(call.Object!, path, variables) + "." + call.Method.Name.Substring(4)) : - call.Method.Name.StartsWith("set_") ? + call.Method.Name.StartsWith("set_", StringComparison.Ordinal) ? (call.Method.IsStatic ? FormatType(call.Method.DeclaringType!) + "." + call.Method.Name.Substring(4) : @@ -142,13 +142,13 @@ member.Expression is ParameterExpression parameterExpression && "." + call.Method.Name.Substring(4)) + " = " + ToCS(call.Arguments.Single(), path, variables) : #else - call.Method.Name.StartsWith("get_") ? + call.Method.Name.StartsWith("get_", StringComparison.Ordinal) ? (call.Method.IsStatic ? string.Concat(FormatType(call.Method.DeclaringType!), ".", call.Method.Name.AsSpan(4)) : string.Concat(WithParentheses(call.Object!, path, variables), ".", call.Method.Name.AsSpan(4))) : - call.Method.Name.StartsWith("set_") ? + call.Method.Name.StartsWith("set_", StringComparison.Ordinal) ? (call.Method.IsStatic ? string.Concat(FormatType(call.Method.DeclaringType!), ".", call.Method.Name.AsSpan(4)) : @@ -215,7 +215,7 @@ private static string ToCS(this ParameterExpression parameter) if (parameter.IsByRef) { - if (name.StartsWith(OutParameterPrefix)) + if (name.StartsWith(OutParameterPrefix, StringComparison.Ordinal)) { prefix = "out "; name = name.Substring(OutParameterPrefix.Length); diff --git a/src/NodeApi.Generator/Program.cs b/src/NodeApi.Generator/Program.cs index c41f8039..00828fe7 100644 --- a/src/NodeApi.Generator/Program.cs +++ b/src/NodeApi.Generator/Program.cs @@ -417,7 +417,7 @@ private static void ResolveSystemAssemblies( s_targetFramework = s_targetFramework.Substring(0, s_targetFramework.IndexOf('-')); } - if (s_targetFramework.StartsWith("net4")) + if (s_targetFramework.StartsWith("net4", StringComparison.Ordinal)) { if (targetingPacks.Count > 0) { diff --git a/src/NodeApi.Generator/SourceBuilder.cs b/src/NodeApi.Generator/SourceBuilder.cs index a7904ea3..5e71ee38 100644 --- a/src/NodeApi.Generator/SourceBuilder.cs +++ b/src/NodeApi.Generator/SourceBuilder.cs @@ -87,7 +87,8 @@ private void AppendLine(string line) { IncreaseIndent(); } - else if (line.EndsWith('(') || line.EndsWith('?') || line.EndsWith("=>")) + else if (line.EndsWith('(') || line.EndsWith('?') || + line.EndsWith("=>", StringComparison.Ordinal)) { // The "extra" indent persists until the end of the set of lines appended together // (before the split) or until a line ending with a semicolon." diff --git a/src/NodeApi.Generator/StringExtensions.cs b/src/NodeApi.Generator/StringExtensions.cs index f9dbec7f..baebef4b 100644 --- a/src/NodeApi.Generator/StringExtensions.cs +++ b/src/NodeApi.Generator/StringExtensions.cs @@ -13,9 +13,9 @@ internal static class StringExtensions { public static bool Contains(this string s, char c) => s.Contains(c.ToString()); - public static bool StartsWith(this string s, char c) => s.StartsWith(c.ToString()); + public static bool StartsWith(this string s, char c) => s.StartsWith(c.ToString(), StringComparison.Ordinal); - public static bool EndsWith(this string s, char c) => s.EndsWith(c.ToString()); + public static bool EndsWith(this string s, char c) => s.EndsWith(c.ToString(), StringComparison.Ordinal); } #endif diff --git a/src/NodeApi.Generator/TypeDefinitionsGenerator.cs b/src/NodeApi.Generator/TypeDefinitionsGenerator.cs index f4498064..d08865e3 100644 --- a/src/NodeApi.Generator/TypeDefinitionsGenerator.cs +++ b/src/NodeApi.Generator/TypeDefinitionsGenerator.cs @@ -375,7 +375,8 @@ public TypeDefinitionsGenerator( _assembly = assembly; _referenceAssemblies = referenceAssemblies; _imports = new HashSet(); - _isSystemAssembly = assembly.GetName().Name!.StartsWith("System."); + _isSystemAssembly = assembly.GetName().Name!.StartsWith( + "System.", StringComparison.Ordinal); } public bool ExportAll { get; set; } @@ -1030,7 +1031,8 @@ private static bool HasExplicitInterfaceImplementations(Type type, Type interfac foreach (MethodInfo method in type.GetMethods( BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { - if (method.IsFinal && method.IsPrivate && method.Name.StartsWith(methodNamePrefix)) + if (method.IsFinal && method.IsPrivate && + method.Name.StartsWith(methodNamePrefix, StringComparison.Ordinal)) { return true; } @@ -1137,9 +1139,11 @@ private static bool IsExtensionTargetTypeSupported(Type targetType) (targetType.Namespace == typeof(System.Collections.IEnumerable).Namespace || targetType.Namespace == typeof(Collection<>).Namespace || targetType.Namespace == typeof(IEnumerable<>).Namespace)) || - targetType.Name.StartsWith("IAsyncEnumerable`") || - targetType.Name == nameof(Tuple) || targetType.Name.StartsWith(nameof(Tuple) + '`') || - targetType.Name == nameof(Task) || targetType.Name.StartsWith(nameof(Task) + '`')) + targetType.Name.StartsWith("IAsyncEnumerable`", StringComparison.Ordinal) || + targetType.Name == nameof(Tuple) || + targetType.Name.StartsWith(nameof(Tuple) + '`', StringComparison.Ordinal) || + targetType.Name == nameof(Task) || + targetType.Name.StartsWith(nameof(Task) + '`', StringComparison.Ordinal)) { return false; } @@ -1185,7 +1189,7 @@ private void ExportTypeMember(ref SourceBuilder s, MemberInfo member, bool asExt string modifiers = (isStatic ? "static " : "") + (property.SetMethod == null ? "readonly " : ""); string optionalToken = string.Empty; - if (propertyType.EndsWith(UndefinedTypeSuffix)) + if (propertyType.EndsWith(UndefinedTypeSuffix, StringComparison.Ordinal)) { propertyType = propertyType.Substring( 0, propertyType.Length - UndefinedTypeSuffix.Length); @@ -1380,9 +1384,10 @@ private bool IsExcluded(MethodBase method) } // Exclude old style Begin/End async methods, as they always have Task-based alternatives. - if ((method.Name.StartsWith("Begin") && + if ((method.Name.StartsWith("Begin", StringComparison.Ordinal) && (method as MethodInfo)?.ReturnType.FullName == typeof(IAsyncResult).FullName) || - (method.Name.StartsWith("End") && methodParams.Length == 1 && + (method.Name.StartsWith("End", StringComparison.Ordinal) && + methodParams.Length == 1 && methodParams[0].ParameterType.FullName == typeof(IAsyncResult).FullName)) { return true; @@ -1527,13 +1532,13 @@ private string GetTSType(ParameterInfo parameter) if (parameter.Position < 0 && method != null) { if (parameter.ParameterType.FullName == typeof(bool).FullName && - parameter.Member.Name.StartsWith("Try") && + parameter.Member.Name.StartsWith("Try", StringComparison.Ordinal) && method.GetParameters().Count((p) => p.IsOut) == 1) { // A method with Try* pattern simply returns the out-value or undefined // instead of an object with the bool and out-value properties. tsType = GetTSType(method.GetParameters().Last()); - if (!tsType.EndsWith(UndefinedTypeSuffix)) + if (!tsType.EndsWith(UndefinedTypeSuffix, StringComparison.Ordinal)) { tsType += UndefinedTypeSuffix; } @@ -1549,7 +1554,7 @@ private string GetTSType(ParameterInfo parameter) { string propertyType = GetTSType(p); string optionalToken = string.Empty; - if (propertyType.EndsWith(UndefinedTypeSuffix)) + if (propertyType.EndsWith(UndefinedTypeSuffix, StringComparison.Ordinal)) { propertyType = propertyType.Substring( 0, propertyType.Length - UndefinedTypeSuffix.Length); @@ -1721,7 +1726,8 @@ private string GetTSType( { tsType = "() => void"; } - else if (type.IsGenericType && type.Name.StartsWith(nameof(Action) + "`")) + else if (type.IsGenericType && + type.Name.StartsWith(nameof(Action) + "`", StringComparison.Ordinal)) { NullabilityInfo[]? typeArgsNullability = nullability?.GenericTypeArguments; string[] parameters = type.GetGenericArguments().Select((t, i) => @@ -1729,7 +1735,8 @@ private string GetTSType( .ToArray(); tsType = $"({string.Join(", ", parameters)}) => void"; } - else if (type.IsGenericType && type.Name.StartsWith("Func`")) + else if (type.IsGenericType && + type.Name.StartsWith("Func`", StringComparison.Ordinal)) { Type[] typeArgs = type.GetGenericArguments(); NullabilityInfo[]? typeArgsNullability = nullability?.GenericTypeArguments; @@ -1742,7 +1749,8 @@ private string GetTSType( allowTypeParams); tsType = $"({string.Join(", ", parameters)}) => {returnType}"; } - else if (type.IsGenericType && type.Name.StartsWith("Predicate`")) + else if (type.IsGenericType && + type.Name.StartsWith("Predicate`", StringComparison.Ordinal)) { Type typeArg = type.GetGenericArguments()[0]; NullabilityInfo[]? typeArgsNullability = nullability?.GenericTypeArguments; @@ -1851,7 +1859,7 @@ private string GetTSType( { string elementType = GetTSType(typeArgs[0], typeArgsNullability?[0], allowTypeParams); - if (elementType.EndsWith(UndefinedTypeSuffix)) + if (elementType.EndsWith(UndefinedTypeSuffix, StringComparison.Ordinal)) { elementType = $"({elementType})"; } @@ -1862,7 +1870,7 @@ private string GetTSType( { string elementType = GetTSType(typeArgs[1], typeArgsNullability?[0], allowTypeParams); - if (elementType.EndsWith(UndefinedTypeSuffix)) + if (elementType.EndsWith(UndefinedTypeSuffix, StringComparison.Ordinal)) { elementType = $"({elementType})"; } @@ -1873,7 +1881,7 @@ private string GetTSType( { string elementType = GetTSType(typeArgs[0], typeArgsNullability?[0], allowTypeParams); - if (elementType.EndsWith(UndefinedTypeSuffix)) + if (elementType.EndsWith(UndefinedTypeSuffix, StringComparison.Ordinal)) { elementType = $"({elementType})"; } @@ -1935,8 +1943,8 @@ private string GetTSType( string valueTSType = GetTSType(typeArgs[1], typeArgsNullability?[1], allowTypeParams); tsType = $"[{keyTSType}, {valueTSType}]"; } - else if (typeDefinitionName.StartsWith("System.Tuple`") || - typeDefinitionName.StartsWith("System.ValueTuple`")) + else if (typeDefinitionName.StartsWith("System.Tuple`", StringComparison.Ordinal) || + typeDefinitionName.StartsWith("System.ValueTuple`", StringComparison.Ordinal)) { IEnumerable itemTSTypes = typeArgs.Select((typeArg, index) => GetTSType(typeArg, typeArgsNullability?[index], allowTypeParams)); @@ -1960,7 +1968,7 @@ private string GetTSType( #if !(NETFRAMEWORK || NETSTANDARD) !type.IsGenericTypeParameter && !type.IsGenericMethodParameter && #endif - !tsType.EndsWith(UndefinedTypeSuffix)) + !tsType.EndsWith(UndefinedTypeSuffix, StringComparison.Ordinal)) { tsType += UndefinedTypeSuffix; } @@ -2022,7 +2030,7 @@ static string GetOptionalToken(ParameterInfo parameter, ref string parameterType { if (parameter.IsOptional) { - if (parameterType.EndsWith(UndefinedTypeSuffix)) + if (parameterType.EndsWith(UndefinedTypeSuffix, StringComparison.Ordinal)) { parameterType = parameterType.Substring( 0, parameterType.Length - UndefinedTypeSuffix.Length); @@ -2042,7 +2050,7 @@ static string GetOptionalToken(ParameterInfo parameter, ref string parameterType else if (parameters.Length == 1) { string parameterType = GetTSType(parameters[0]); - if (parameterType.StartsWith("...")) + if (parameterType.StartsWith("...", StringComparison.Ordinal)) { return $"...{TSIdentifier(parameters[0].Name)}: {parameterType.Substring(3)}"; } diff --git a/src/NodeApi/DotNetHost/NativeHost.cs b/src/NodeApi/DotNetHost/NativeHost.cs index 90311305..b3c7c654 100644 --- a/src/NodeApi/DotNetHost/NativeHost.cs +++ b/src/NodeApi/DotNetHost/NativeHost.cs @@ -122,7 +122,8 @@ private JSValue InitializeManagedHost(JSCallbackArgs args) try { JSValue exports; - if (!targetFramework.Contains('.') && targetFramework.StartsWith("net") && + if (!targetFramework.Contains('.') && + targetFramework.StartsWith("net", StringComparison.Ordinal) && targetFramework.Length >= 5) { // .NET Framework diff --git a/src/NodeApi/JSError.cs b/src/NodeApi/JSError.cs index 7a6b2563..33437ae9 100644 --- a/src/NodeApi/JSError.cs +++ b/src/NodeApi/JSError.cs @@ -333,7 +333,7 @@ private static JSValue GetErrorStack(JSCallbackArgs args) } // Normalize indentation to 4 spaces, as used by JS. (.NET traces indent with 3 spaces.) - if (jsStack.StartsWith(" at ")) + if (jsStack.StartsWith(" at ", StringComparison.Ordinal)) { dotnetStack = dotnetStack.Replace(" at ", " at "); } diff --git a/src/NodeApi/JSException.cs b/src/NodeApi/JSException.cs index dbed356a..163581b8 100644 --- a/src/NodeApi/JSException.cs +++ b/src/NodeApi/JSException.cs @@ -92,7 +92,7 @@ public override string? StackTrace // Normalize indentation to 3 spaces, as used by .NET. // (JS traces indent with 4 spaces.) - if (jsStack.StartsWith(" at ")) + if (jsStack.StartsWith(" at ", StringComparison.Ordinal)) { jsStack = jsStack.Replace(" at ", " at "); } diff --git a/test/HostedClrTests.cs b/test/HostedClrTests.cs index 7f6d94ad..4c85a3a4 100644 --- a/test/HostedClrTests.cs +++ b/test/HostedClrTests.cs @@ -21,10 +21,11 @@ public class HostedClrTests #if NETFRAMEWORK // The .NET Framework host does not yet support multiple instances of a module. public static IEnumerable TestCases { get; } = ListTestCases((testCaseName) => - !testCaseName.StartsWith("projects/") && !testCaseName.Contains("/multi_instance")); + !testCaseName.StartsWith("projects/", StringComparison.Ordinal) && + !testCaseName.Contains("/multi_instance")); #else public static IEnumerable TestCases { get; } = ListTestCases((testCaseName) => - !testCaseName.StartsWith("projects/")); + !testCaseName.StartsWith("projects/", StringComparison.Ordinal)); #endif [Theory] diff --git a/test/JSProjectTests.cs b/test/JSProjectTests.cs index 54d2964b..1b47dd14 100644 --- a/test/JSProjectTests.cs +++ b/test/JSProjectTests.cs @@ -22,7 +22,7 @@ public class JSProjectTests private const string DefaultFrameworkTarget = "net8.0"; public static IEnumerable TestCases { get; } = ListTestCases( - (testCaseName) => testCaseName.StartsWith("projects/") && + (testCaseName) => testCaseName.StartsWith("projects/", StringComparison.Ordinal) && (!testCaseName.Contains("-dynamic") || IsCurrentTargetFramework(Path.GetFileName(testCaseName)))); diff --git a/test/NativeAotTests.cs b/test/NativeAotTests.cs index a6611282..5ce4b411 100644 --- a/test/NativeAotTests.cs +++ b/test/NativeAotTests.cs @@ -17,7 +17,8 @@ public class NativeAotTests private static readonly Dictionary s_builtTestModules = new(); public static IEnumerable TestCases { get; } = ListTestCases((testCaseName) => - !testCaseName.Contains("/dynamic_") && !testCaseName.StartsWith("projects/")); + !testCaseName.Contains("/dynamic_") && + !testCaseName.StartsWith("projects/", StringComparison.Ordinal)); [Theory] [MemberData(nameof(TestCases))] diff --git a/test/NodejsEmbeddingTests.cs b/test/NodejsEmbeddingTests.cs index b2703916..6e4191c8 100644 --- a/test/NodejsEmbeddingTests.cs +++ b/test/NodejsEmbeddingTests.cs @@ -251,12 +251,13 @@ public void ErrorPropagation() .ToArray(); // The first line of the stack trace should refer to the JS function that threw. - Assert.StartsWith("at throwError ", stackLines[0]); + Assert.StartsWith("at throwError ", stackLines[0], StringComparison.Ordinal); // The stack trace should include lines that refer to the .NET method that called JS. Assert.Contains( stackLines, - (line) => line.StartsWith($"at {typeof(NodejsEmbeddingTests).FullName}.")); + (line) => line.StartsWith( + $"at {typeof(NodejsEmbeddingTests).FullName}.", StringComparison.Ordinal)); } [Fact] diff --git a/test/TestBuilder.cs b/test/TestBuilder.cs index 9f88895b..0764c63a 100644 --- a/test/TestBuilder.cs +++ b/test/TestBuilder.cs @@ -75,8 +75,9 @@ public static IEnumerable ListTestCases(Predicate? filter = nu foreach (string jsFile in Directory.GetFiles(modulePath, "*.js") .Concat(Directory.GetFiles(modulePath, "*.ts"))) { - if (jsFile.EndsWith(".d.ts")) continue; - else if (jsFile.EndsWith(".js") && File.Exists(Path.ChangeExtension(jsFile, ".ts"))) continue; + if (jsFile.EndsWith(".d.ts", StringComparison.Ordinal)) continue; + else if (jsFile.EndsWith(".js", StringComparison.Ordinal) && + File.Exists(Path.ChangeExtension(jsFile, ".ts"))) continue; string testCaseName = Path.GetFileNameWithoutExtension(jsFile); if (filter == null || filter(moduleName + "/" + testCaseName)) { @@ -321,7 +322,7 @@ public static void RunNodeTestCase( for (int i = 0; i < logLines.Length; i++) { // Scan for a line that looks like a node error or an assertion with filename:#. - if (logLines[i].StartsWith("node:") || + if (logLines[i].StartsWith("node:", StringComparison.Ordinal) || logLines[i].Contains(jsFileName + ":")) { string assertion = string.Join(Environment.NewLine, logLines.Skip(i)); From decf7f25f484d47d536e0678ae4ed653c0cc46fb Mon Sep 17 00:00:00 2001 From: Jason Ginchereau Date: Fri, 17 Oct 2025 10:42:55 -1000 Subject: [PATCH 2/3] Fix 2 more places --- src/NodeApi.Generator/SymbolExtensions.cs | 2 +- test/TestBuilder.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NodeApi.Generator/SymbolExtensions.cs b/src/NodeApi.Generator/SymbolExtensions.cs index 718bd5ff..6fac3bcd 100644 --- a/src/NodeApi.Generator/SymbolExtensions.cs +++ b/src/NodeApi.Generator/SymbolExtensions.cs @@ -329,7 +329,7 @@ private static Type BuildSymbolicObjectType( foreach (AttributeData attribute in typeSymbol.GetAttributes()) { if (attribute.AttributeClass!.ContainingNamespace.ToString()!.StartsWith( - typeof(JSExportAttribute).Namespace!)) + typeof(JSExportAttribute).Namespace!, StringComparison.Ordinal)) { Type attributeType = attribute.AttributeClass.AsType(); ConstructorInfo constructor = attributeType.GetConstructor( diff --git a/test/TestBuilder.cs b/test/TestBuilder.cs index 0764c63a..56ab9183 100644 --- a/test/TestBuilder.cs +++ b/test/TestBuilder.cs @@ -260,7 +260,7 @@ private static void WriteCurrentFrameworkGlobalJson(string workingDirectory) { // Append the .NET preview version to the SDK version requested in global.json. sdkVersion += RuntimeInformation.FrameworkDescription.Substring( - RuntimeInformation.FrameworkDescription.IndexOf("-preview.")); + RuntimeInformation.FrameworkDescription.IndexOf("-preview.", StringComparison.Ordinal) +); } string globalJson = $$""" From e1e44756ed6d3261a9941371cd9c146178bdbade Mon Sep 17 00:00:00 2001 From: Jason Ginchereau Date: Fri, 17 Oct 2025 10:59:29 -1000 Subject: [PATCH 3/3] Fix typo --- test/TestBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/TestBuilder.cs b/test/TestBuilder.cs index 56ab9183..d24a1d28 100644 --- a/test/TestBuilder.cs +++ b/test/TestBuilder.cs @@ -260,7 +260,7 @@ private static void WriteCurrentFrameworkGlobalJson(string workingDirectory) { // Append the .NET preview version to the SDK version requested in global.json. sdkVersion += RuntimeInformation.FrameworkDescription.Substring( - RuntimeInformation.FrameworkDescription.IndexOf("-preview.", StringComparison.Ordinal) +); + RuntimeInformation.FrameworkDescription.IndexOf("-preview.", StringComparison.Ordinal)); } string globalJson = $$"""