fix(unparser): format values with parser ParsingCulture for round-trip
FormatCommandLine wrote option and value arguments using the ambient thread culture via value.ToString(), while the parser reads them back with ParserSettings.ParsingCulture (invariant by default). On threads whose culture uses a comma decimal separator (for example de-DE) a double 1.5 was unparsed as "1,5" and reparsed as 15, and a sequence [1.5, 2.5] became "1,5,2,5" and reparsed as four elements [1,5,2,5], so the format/parse round-trip was broken. Format IFormattable values (numeric and date/time types) with the parser ParsingCulture instead of the current thread culture, for both scalar and separator-joined sequence values. Other types keep their default string representation, so behaviour on invariant/en-US is unchanged. Add round-trip tests under de-DE for a scalar double and a comma-separated double sequence.
This commit is contained in:
1 parent
6340b0ba56
commit
91e0d866bc
3 files changed
+104
-9
No files matched your search
@@ -0,0 +1,12 @@
|
||||
// Copyright 2005-2015 Giacomo Stelluti Scala & Contributors. All rights reserved. See License.md in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CommandLine.Tests.Fakes
|
||||
{
|
||||
class Options_With_Double_Sequence
|
||||
{
|
||||
[Option("dbls", Separator = ',')]
|
||||
public IEnumerable<double> DoubleSequence { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Xunit;
|
||||
using FluentAssertions;
|
||||
using CommandLine.Tests.Fakes;
|
||||
@@ -154,6 +156,66 @@ namespace CommandLine.Tests.Unit
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Parsing culture round-trip
|
||||
|
||||
[Fact]
|
||||
public static void UnParsing_scalar_double_uses_parsing_culture_so_it_round_trips_on_comma_decimal_cultures()
|
||||
{
|
||||
var originalCulture = Thread.CurrentThread.CurrentCulture;
|
||||
try
|
||||
{
|
||||
// A culture that uses ',' as the decimal separator (e.g. de-DE) would,
|
||||
// when the ambient thread culture is used, format 1.5 as "1,5", which the
|
||||
// invariant-culture parser reparses as 15 - breaking the round-trip.
|
||||
Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE");
|
||||
var parser = new Parser();
|
||||
var options = new Simple_Options_With_Double_Value { DoubleValue = 1.5 };
|
||||
|
||||
var commandLine = parser.FormatCommandLine(options);
|
||||
|
||||
commandLine.Should().Contain("1.5");
|
||||
commandLine.Should().NotContain("1,5");
|
||||
|
||||
var reparsed = parser.ParseArguments<Simple_Options_With_Double_Value>(commandLine.SplitArgs());
|
||||
reparsed.Tag.Should().Be(ParserResultType.Parsed);
|
||||
((Parsed<Simple_Options_With_Double_Value>)reparsed).Value.DoubleValue.Should().Be(1.5);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.CurrentThread.CurrentCulture = originalCulture;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void UnParsing_double_sequence_uses_parsing_culture_so_it_round_trips_on_comma_decimal_cultures()
|
||||
{
|
||||
var originalCulture = Thread.CurrentThread.CurrentCulture;
|
||||
try
|
||||
{
|
||||
// With a comma-decimal ambient culture each element would be formatted as
|
||||
// "1,5"/"2,5"; joined by the ',' sequence separator this yields "1,5,2,5",
|
||||
// which the parser reparses as four elements [1,5,2,5] instead of [1.5,2.5].
|
||||
Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE");
|
||||
var parser = new Parser();
|
||||
var options = new Options_With_Double_Sequence { DoubleSequence = new[] { 1.5, 2.5 } };
|
||||
|
||||
var commandLine = parser.FormatCommandLine(options);
|
||||
|
||||
commandLine.Should().Be("--dbls 1.5,2.5");
|
||||
|
||||
var reparsed = parser.ParseArguments<Options_With_Double_Sequence>(commandLine.SplitArgs());
|
||||
reparsed.Tag.Should().Be(ParserResultType.Parsed);
|
||||
((Parsed<Options_With_Double_Sequence>)reparsed).Value.DoubleSequence
|
||||
.Should().Equal(new[] { 1.5, 2.5 });
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.CurrentThread.CurrentCulture = originalCulture;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PR 550
|
||||
|
||||
[Fact]
|
||||
|
||||
Reference in new issue
Block a user