Skip to content

Commit

Permalink
Merge pull request #837 from EdwardCooke/ec-792-testsinnonenglish
Browse files Browse the repository at this point in the history
Fix tests running in cultures using different cultures

+semver:feature
  • Loading branch information
EdwardCooke committed Aug 24, 2023
2 parents 58206f3 + 5df001d commit a6845eb
Show file tree
Hide file tree
Showing 16 changed files with 216 additions and 72 deletions.
6 changes: 5 additions & 1 deletion .dockerignore
@@ -1 +1,5 @@
.git
.git
Dockerfile.NonEnglish
Dockerfile
bin
obj
7 changes: 3 additions & 4 deletions Dockerfile
Expand Up @@ -16,7 +16,7 @@ RUN apt install -y wget
RUN wget https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
RUN dpkg -i packages-microsoft-prod.deb
RUN apt update
RUN apt install -y dotnet-sdk-3.1
RUN apt install -y dotnet-sdk-3.1 dotnet-sdk-6.0

FROM builder AS build
WORKDIR /src
Expand Down Expand Up @@ -46,10 +46,9 @@ RUN dotnet build -c Release --framework net70 YamlDotNet/YamlDotNet.csproj -o /o

RUN dotnet pack -c Release YamlDotNet/YamlDotNet.csproj -o /output/package /p:Version=$PACKAGE_VERSION

RUN dotnet test -c Release YamlDotNet.sln --framework net70 --logger:"trx;LogFileName=/output/tests.net60.trx" --logger:"console;Verbosity=detailed"
RUN dotnet test -c Release YamlDotNet.sln --framework net60 --logger:"trx;LogFileName=/output/tests.net60.trx" --logger:"console;Verbosity=detailed"
RUN dotnet test -c Release YamlDotNet.Test/YamlDotNet.Test.csproj --framework net70 --logger:"trx;LogFileName=/output/tests.net70.trx" --logger:"console;Verbosity=detailed"
RUN dotnet test -c Release YamlDotNet.Test/YamlDotNet.Test.csproj --framework net60 --logger:"trx;LogFileName=/output/tests.net60.trx" --logger:"console;Verbosity=detailed"
RUN dotnet test -c Release YamlDotNet.Test/YamlDotNet.Test.csproj --framework netcoreapp3.1 --logger:"trx;LogFileName=/output/tests.netcoreapp3.1.trx" --logger:"console;Verbosity=detailed"
RUN dotnet test -c Release YamlDotNet.Test/YamlDotNet.Test.csproj --framework net47 --logger:"trx;LogFileName=/output/tests.net47.trx" --logger:"console;Verbosity=detailed"

FROM alpine
VOLUME /output
Expand Down
73 changes: 73 additions & 0 deletions Dockerfile.NonEnglish
@@ -0,0 +1,73 @@
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS builder
RUN apt update && \
apt install -y \
apt-transport-https \
gnupg \
ca-certificates \
curl

RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
# yes, we're using the bullseye (debian 11) image, however mono only has buster, but it still works for bullseye
RUN echo "deb https://download.mono-project.com/repo/debian stable-buster main" > /etc/apt/sources.list.d/mono-official-stable.list
RUN apt update
RUN apt install -y mono-complete

# install dot net 3.1 for running netstandard2.1 tests
RUN apt install -y wget
RUN wget https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
RUN dpkg -i packages-microsoft-prod.deb
RUN apt update
RUN apt install -y dotnet-sdk-3.1 dotnet-sdk-6.0


FROM builder AS build
WORKDIR /src
ARG PACKAGE_VERSION=1.0.0

COPY YamlDotNet.sln YamlDotNet.sln
COPY YamlDotNet/YamlDotNet.csproj YamlDotNet/YamlDotNet.csproj
COPY YamlDotNet.AotTest/YamlDotNet.AotTest.csproj YamlDotNet.AotTest/YamlDotNet.AotTest.csproj
COPY YamlDotNet.Benchmark/YamlDotNet.Benchmark.csproj YamlDotNet.Benchmark/YamlDotNet.Benchmark.csproj
COPY YamlDotNet.Samples/YamlDotNet.Samples.csproj YamlDotNet.Samples/YamlDotNet.Samples.csproj
COPY YamlDotNet.Test/YamlDotNet.Test.csproj YamlDotNet.Test/YamlDotNet.Test.csproj
COPY YamlDotNet.Analyzers.StaticGenerator/YamlDotNet.Analyzers.StaticGenerator.csproj YamlDotNet.Analyzers.StaticGenerator/YamlDotNet.Analyzers.StaticGenerator.csproj
COPY YamlDotNet.Core7AoTCompileTest/YamlDotNet.Core7AoTCompileTest.csproj YamlDotNet.Core7AoTCompileTest/YamlDotNet.Core7AoTCompileTest.csproj

RUN dotnet restore YamlDotNet.sln

COPY . .

RUN dotnet build -c Release --framework net35 YamlDotNet/YamlDotNet.csproj -o /output/net35
RUN dotnet build -c Release --framework net40 YamlDotNet/YamlDotNet.csproj -o /output/net40
RUN dotnet build -c Release --framework net45 YamlDotNet/YamlDotNet.csproj -o /output/net45
RUN dotnet build -c Release --framework net47 YamlDotNet/YamlDotNet.csproj -o /output/net47
RUN dotnet build -c Release --framework netstandard2.0 YamlDotNet/YamlDotNet.csproj -o /output/netstandard2.0
RUN dotnet build -c Release --framework netstandard2.1 YamlDotNet/YamlDotNet.csproj -o /output/netstandard2.1
RUN dotnet build -c Release --framework net60 YamlDotNet/YamlDotNet.csproj -o /output/net60
RUN dotnet build -c Release --framework net70 YamlDotNet/YamlDotNet.csproj -o /output/net70

RUN dotnet pack -c Release YamlDotNet/YamlDotNet.csproj -o /output/package /p:Version=$PACKAGE_VERSION

ARG LOCALE_LANGUAGE="en"
ARG LOCALE_COUNTRY="DK"
ARG LOCALE_LOCALE="${LOCALE_LANGUAGE}_${LOCALE_COUNTRY}"
ARG LOCALE_ENCODING="UTF-8"

ENV LANG="${LOCALE_LANGUAGE}_${LOCALE_COUNTRY}.${LOCALE_ENCODING}"
ENV LANGUAGE="${LOCALE_LANGUAGE}_${LOCALE_COUNTRY}:${LOCALE_LANGUAGE}"
ENV LC_ALL="${LOCALE_LANGUAGE}_${LOCALE_COUNTRY}.${LOCALE_ENCODING}"

RUN echo -n "${LC_ALL}" > /etc/locale.gen && \
printenv && \
apt install -y locales && \
locale-gen

RUN dotnet test -c Release YamlDotNet.Test/YamlDotNet.Test.csproj --framework net70 --logger:"trx;LogFileName=/output/tests.net70.trx" --logger:"console;Verbosity=detailed"
RUN dotnet test -c Release YamlDotNet.Test/YamlDotNet.Test.csproj --framework net60 --logger:"trx;LogFileName=/output/tests.net60.trx" --logger:"console;Verbosity=detailed"
RUN dotnet test -c Release YamlDotNet.Test/YamlDotNet.Test.csproj --framework netcoreapp3.1 --logger:"trx;LogFileName=/output/tests.netcoreapp3.1.trx" --logger:"console;Verbosity=detailed"

FROM alpine
VOLUME /output
WORKDIR /libraries
COPY --from=build /output /libraries
CMD [ "cp", "-r", "/libraries", "/output" ]
6 changes: 6 additions & 0 deletions YamlDotNet.Core7AoTCompileTest/Program.cs
Expand Up @@ -18,6 +18,9 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#pragma warning disable CS8604 // Possible null reference argument.
#pragma warning disable CS8618 // Possible null reference argument.
#pragma warning disable CS8602 // Possible null reference argument.

using System;
using System.Collections;
Expand Down Expand Up @@ -208,3 +211,6 @@ public enum MyTestEnum
Z = 1,
}

#pragma warning restore CS8604 // Possible null reference argument.
#pragma warning restore CS8618 // Possible null reference argument.
#pragma warning restore CS8602 // Possible null reference argument.
2 changes: 1 addition & 1 deletion YamlDotNet.Samples/UseTypeConverters.cs
Expand Up @@ -48,7 +48,7 @@ public void Main()
var serializer = new SerializerBuilder()
.WithTypeConverter(new DateTimeOffsetConverter())
.Build();
var o = new { Hello = new DateTimeOffset(DateTime.Now, new TimeSpan(-6, 0, 0)) };
var o = new { Hello = DateTime.UtcNow };
var yaml = serializer.Serialize(o);
output.WriteLine(yaml);
}
Expand Down
2 changes: 1 addition & 1 deletion YamlDotNet.Test/Serialization/DeserializerTest.cs
Expand Up @@ -278,7 +278,7 @@ public static IEnumerable<object[]> DeserializeScalarEdgeCases_TestCases
public void DeserializeScalarEdgeCases(IConvertible value, Type type)
{
var deserializer = new DeserializerBuilder().Build();
var result = deserializer.Deserialize(value.ToString(), type);
var result = deserializer.Deserialize(value.ToString(YamlFormatter.Default.NumberFormat), type);

result.Should().Be(value);
}
Expand Down
13 changes: 13 additions & 0 deletions YamlDotNet/Serialization/BuilderSkeleton.cs
Expand Up @@ -42,6 +42,7 @@ public abstract class BuilderSkeleton<TBuilder>
internal bool ignoreFields;
internal bool includeNonPublicProperties = false;
internal Settings settings;
internal YamlFormatter yamlFormatter = YamlFormatter.Default;

internal BuilderSkeleton(ITypeResolver typeResolver)
{
Expand Down Expand Up @@ -295,6 +296,18 @@ public TBuilder WithoutTypeInspector(Type inspectorType)
return Self;
}

/// <summary>
/// Override the default yaml formatter with the one passed in
/// </summary>
/// <param name="formatter"><seealso cref="YamlFormatter"/>to use when serializing and deserializing objects.</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public TBuilder WithYamlFormatter(YamlFormatter formatter)
{
yamlFormatter = formatter ?? throw new ArgumentNullException(nameof(formatter));
return Self;
}

protected IEnumerable<IYamlTypeConverter> BuildTypeConverters()
{
return typeConverterFactories.BuildComponentList();
Expand Down
2 changes: 1 addition & 1 deletion YamlDotNet/Serialization/DeserializerBuilder.cs
Expand Up @@ -92,7 +92,7 @@ public DeserializerBuilder()
{ typeof(YamlSerializableNodeDeserializer), _ => new YamlSerializableNodeDeserializer(objectFactory.Value) },
{ typeof(TypeConverterNodeDeserializer), _ => new TypeConverterNodeDeserializer(BuildTypeConverters()) },
{ typeof(NullNodeDeserializer), _ => new NullNodeDeserializer() },
{ typeof(ScalarNodeDeserializer), _ => new ScalarNodeDeserializer(attemptUnknownTypeDeserialization, typeConverter) },
{ typeof(ScalarNodeDeserializer), _ => new ScalarNodeDeserializer(attemptUnknownTypeDeserialization, typeConverter, yamlFormatter) },
{ typeof(ArrayNodeDeserializer), _ => new ArrayNodeDeserializer() },
{ typeof(DictionaryNodeDeserializer), _ => new DictionaryNodeDeserializer(objectFactory.Value, duplicateKeyChecking) },
{ typeof(CollectionNodeDeserializer), _ => new CollectionNodeDeserializer(objectFactory.Value) },
Expand Down
20 changes: 14 additions & 6 deletions YamlDotNet/Serialization/EventEmitters/JsonEventEmitter.cs
Expand Up @@ -27,8 +27,16 @@ namespace YamlDotNet.Serialization.EventEmitters
{
public sealed class JsonEventEmitter : ChainedEventEmitter
{
public JsonEventEmitter(IEventEmitter nextEmitter)
private readonly YamlFormatter formatter;

public JsonEventEmitter(IEventEmitter nextEmitter, YamlFormatter formatter)
: base(nextEmitter)
{
this.formatter = formatter;
}

public JsonEventEmitter(IEventEmitter nextEmitter)
: this(nextEmitter, YamlFormatter.Default)
{
}

Expand All @@ -53,7 +61,7 @@ public override void Emit(ScalarEventInfo eventInfo, IEmitter emitter)
switch (typeCode)
{
case TypeCode.Boolean:
eventInfo.RenderedValue = YamlFormatter.FormatBoolean(value);
eventInfo.RenderedValue = formatter.FormatBoolean(value);
break;

case TypeCode.Byte:
Expand All @@ -72,13 +80,13 @@ public override void Emit(ScalarEventInfo eventInfo, IEmitter emitter)
break;
}

eventInfo.RenderedValue = YamlFormatter.FormatNumber(value);
eventInfo.RenderedValue = formatter.FormatNumber(value);
break;

case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
eventInfo.RenderedValue = YamlFormatter.FormatNumber(value);
eventInfo.RenderedValue = formatter.FormatNumber(value);
break;

case TypeCode.String:
Expand All @@ -88,7 +96,7 @@ public override void Emit(ScalarEventInfo eventInfo, IEmitter emitter)
break;

case TypeCode.DateTime:
eventInfo.RenderedValue = YamlFormatter.FormatDateTime(value);
eventInfo.RenderedValue = formatter.FormatDateTime(value);
break;

case TypeCode.Empty:
Expand All @@ -98,7 +106,7 @@ public override void Emit(ScalarEventInfo eventInfo, IEmitter emitter)
default:
if (eventInfo.Source.Type == typeof(TimeSpan))
{
eventInfo.RenderedValue = YamlFormatter.FormatTimeSpan(value);
eventInfo.RenderedValue = formatter.FormatTimeSpan(value);
break;
}

Expand Down
59 changes: 31 additions & 28 deletions YamlDotNet/Serialization/EventEmitters/TypeAssigningEventEmitter.cs
Expand Up @@ -21,6 +21,8 @@

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices.ComTypes;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using YamlDotNet.Core;
using YamlDotNet.Serialization.Schemas;
Expand Down Expand Up @@ -66,22 +68,14 @@ public sealed class TypeAssigningEventEmitter : ChainedEventEmitter
+ @")$";

private readonly ScalarStyle defaultScalarStyle = ScalarStyle.Any;
private readonly YamlFormatter formatter;

public TypeAssigningEventEmitter(IEventEmitter nextEmitter, bool requireTagWhenStaticAndActualTypesAreDifferent, IDictionary<Type, TagName> tagMappings, bool quoteNecessaryStrings, bool quoteYaml1_1Strings, ScalarStyle defaultScalarStyle)
: this(nextEmitter, requireTagWhenStaticAndActualTypesAreDifferent, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings)
{
this.defaultScalarStyle = defaultScalarStyle;
}

public TypeAssigningEventEmitter(IEventEmitter nextEmitter, bool requireTagWhenStaticAndActualTypesAreDifferent, IDictionary<Type, TagName> tagMappings, bool quoteNecessaryStrings, ScalarStyle defaultScalarStyle)
: this(nextEmitter, requireTagWhenStaticAndActualTypesAreDifferent, tagMappings, quoteNecessaryStrings)
public TypeAssigningEventEmitter(IEventEmitter nextEmitter, bool requireTagWhenStaticAndActualTypesAreDifferent, IDictionary<Type, TagName> tagMappings, bool quoteNecessaryStrings, bool quoteYaml1_1Strings, ScalarStyle defaultScalarStyle, YamlFormatter formatter)
: base(nextEmitter)
{
this.defaultScalarStyle = defaultScalarStyle;
}

public TypeAssigningEventEmitter(IEventEmitter nextEmitter, bool requireTagWhenStaticAndActualTypesAreDifferent, IDictionary<Type, TagName> tagMappings, bool quoteNecessaryStrings, bool quoteYaml1_1Strings)
: this(nextEmitter, requireTagWhenStaticAndActualTypesAreDifferent, tagMappings)
{
this.formatter = formatter;
this.tagMappings = tagMappings;
this.quoteNecessaryStrings = quoteNecessaryStrings;

var specialStringValuePattern = quoteYaml1_1Strings
Expand All @@ -94,23 +88,32 @@ public TypeAssigningEventEmitter(IEventEmitter nextEmitter, bool requireTagWhenS
#endif
}

public TypeAssigningEventEmitter(IEventEmitter nextEmitter, bool requireTagWhenStaticAndActualTypesAreDifferent, IDictionary<Type, TagName> tagMappings, bool quoteNecessaryStrings)
: this(nextEmitter, requireTagWhenStaticAndActualTypesAreDifferent, tagMappings)
public TypeAssigningEventEmitter(IEventEmitter nextEmitter, bool requireTagWhenStaticAndActualTypesAreDifferent, IDictionary<Type, TagName> tagMappings, bool quoteNecessaryStrings, bool quoteYaml1_1Strings, ScalarStyle defaultScalarStyle)
: this(nextEmitter, requireTagWhenStaticAndActualTypesAreDifferent, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings, defaultScalarStyle, YamlFormatter.Default)
{
this.quoteNecessaryStrings = quoteNecessaryStrings;
}

#if NET40
isSpecialStringValue_Regex = new Regex(SpecialStrings_Pattern);
#else
isSpecialStringValue_Regex = new Regex(SpecialStrings_Pattern, RegexOptions.Compiled);
#endif
public TypeAssigningEventEmitter(IEventEmitter nextEmitter, bool requireTagWhenStaticAndActualTypesAreDifferent, IDictionary<Type, TagName> tagMappings, bool quoteNecessaryStrings, ScalarStyle defaultScalarStyle)
: this(nextEmitter, requireTagWhenStaticAndActualTypesAreDifferent, tagMappings, quoteNecessaryStrings, false, defaultScalarStyle, YamlFormatter.Default)
{
}

public TypeAssigningEventEmitter(IEventEmitter nextEmitter, bool requireTagWhenStaticAndActualTypesAreDifferent, IDictionary<Type, TagName> tagMappings, bool quoteNecessaryStrings, bool quoteYaml1_1Strings)
: this(nextEmitter, requireTagWhenStaticAndActualTypesAreDifferent, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings, ScalarStyle.Any)
{
}

public TypeAssigningEventEmitter(IEventEmitter nextEmitter, bool requireTagWhenStaticAndActualTypesAreDifferent, IDictionary<Type, TagName> tagMappings, bool quoteNecessaryStrings)
: this(nextEmitter, requireTagWhenStaticAndActualTypesAreDifferent, tagMappings, quoteNecessaryStrings, false)
{
}

public TypeAssigningEventEmitter(IEventEmitter nextEmitter, bool requireTagWhenStaticAndActualTypesAreDifferent, IDictionary<Type, TagName> tagMappings)
: base(nextEmitter)
{
this.requireTagWhenStaticAndActualTypesAreDifferent = requireTagWhenStaticAndActualTypesAreDifferent;
this.tagMappings = tagMappings ?? throw new ArgumentNullException(nameof(tagMappings));
formatter = YamlFormatter.Default;
}

public override void Emit(ScalarEventInfo eventInfo, IEmitter emitter)
Expand All @@ -130,7 +133,7 @@ public override void Emit(ScalarEventInfo eventInfo, IEmitter emitter)
{
case TypeCode.Boolean:
eventInfo.Tag = JsonSchema.Tags.Bool;
eventInfo.RenderedValue = YamlFormatter.FormatBoolean(value);
eventInfo.RenderedValue = formatter.FormatBoolean(value);
break;

case TypeCode.Byte:
Expand Down Expand Up @@ -159,23 +162,23 @@ public override void Emit(ScalarEventInfo eventInfo, IEmitter emitter)
else
{
eventInfo.Tag = JsonSchema.Tags.Int;
eventInfo.RenderedValue = YamlFormatter.FormatNumber(value);
eventInfo.RenderedValue = formatter.FormatNumber(value);
}
break;

case TypeCode.Single:
eventInfo.Tag = JsonSchema.Tags.Float;
eventInfo.RenderedValue = YamlFormatter.FormatNumber((float)value);
eventInfo.RenderedValue = formatter.FormatNumber((float)value);
break;

case TypeCode.Double:
eventInfo.Tag = JsonSchema.Tags.Float;
eventInfo.RenderedValue = YamlFormatter.FormatNumber((double)value);
eventInfo.RenderedValue = formatter.FormatNumber((double)value);
break;

case TypeCode.Decimal:
eventInfo.Tag = JsonSchema.Tags.Float;
eventInfo.RenderedValue = YamlFormatter.FormatNumber(value);
eventInfo.RenderedValue = formatter.FormatNumber(value);
break;

case TypeCode.String:
Expand All @@ -196,7 +199,7 @@ public override void Emit(ScalarEventInfo eventInfo, IEmitter emitter)

case TypeCode.DateTime:
eventInfo.Tag = DefaultSchema.Tags.Timestamp;
eventInfo.RenderedValue = YamlFormatter.FormatDateTime(value);
eventInfo.RenderedValue = formatter.FormatDateTime(value);
break;

case TypeCode.Empty:
Expand All @@ -207,7 +210,7 @@ public override void Emit(ScalarEventInfo eventInfo, IEmitter emitter)
default:
if (eventInfo.Source.Type == typeof(TimeSpan))
{
eventInfo.RenderedValue = YamlFormatter.FormatTimeSpan(value);
eventInfo.RenderedValue = formatter.FormatTimeSpan(value);
break;
}

Expand Down

0 comments on commit a6845eb

Please sign in to comment.