提交 2ed069e1 编写于 作者: C CyrusNajmabadi

Add serialization tests.

上级 e4163b02
......@@ -26,8 +26,9 @@ internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProvider
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedMethods, CSharpCodeStyleOptions.NeverWithNoneEnforcement);
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public void TestOptionSerialization()
public void TestOptionSerialization1()
{
// Verify that bool-options can migrate to ExpressionBodyPreference-options.
var option = new CodeStyleOption<bool>(false, NotificationOption.None);
var serialized = option.ToXElement();
var deserialized = CodeStyleOption<ExpressionBodyPreference>.FromXElement(serialized);
......@@ -41,6 +42,30 @@ public void TestOptionSerialization()
Assert.Equal(ExpressionBodyPreference.WhenPossible, deserialized.Value);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public void TestOptionSerialization2()
{
// Verify that ExpressionBodyPreference-options can migrate to bool-options.
var option = new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.Never, NotificationOption.None);
var serialized = option.ToXElement();
var deserialized = CodeStyleOption<bool>.FromXElement(serialized);
Assert.Equal(false, deserialized.Value);
option = new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.WhenPossible, NotificationOption.None);
serialized = option.ToXElement();
deserialized = CodeStyleOption<bool>.FromXElement(serialized);
Assert.Equal(true, deserialized.Value);
// This new values can't actually translate back to a bool. So we'll just get the default
// value for this option.
option = new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.WhenOnSingleLine, NotificationOption.None);
serialized = option.ToXElement();
deserialized = CodeStyleOption<bool>.FromXElement(serialized);
Assert.Equal(default(bool), deserialized.Value);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestUseExpressionBody1()
......
......@@ -108,11 +108,9 @@ private static object ParseExpressionBodyPreference(string value, ExpressionBody
return boolValue ? ExpressionBodyPreference.WhenPossible : ExpressionBodyPreference.Never;
}
switch (value)
if (value == "when_on_single_line")
{
case "never": return ExpressionBodyPreference.Never;
case "when_possible": return ExpressionBodyPreference.WhenPossible;
case "when_on_single_line": return ExpressionBodyPreference.WhenOnSingleLine;
return ExpressionBodyPreference.WhenOnSingleLine;
}
return @default;
......
......@@ -2,7 +2,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Roslyn.Utilities;
......@@ -22,6 +21,10 @@ internal interface ICodeStyleOption
/// bool-CodeStyleOption is then deserialized into an enum-CodeStyleOption then 'false'
/// values will be migrated to have the 0-value of the enum, and 'true' values will be
/// migrated to have the 1-value of the enum.
///
/// Similarly, enum-type code options will serialize out in a way that is compatible with
/// hosts that expect the value to be a boolean. Specifically, if the enum value is 0 or 1
/// then those values will write back as false/true.
/// </summary>
public class CodeStyleOption<T> : ICodeStyleOption, IEquatable<CodeStyleOption<T>>
{
......@@ -37,6 +40,8 @@ public CodeStyleOption(T value, NotificationOption notification)
public T Value { get; set; }
private int EnumValueAsInt32 => (int)(object)Value;
public NotificationOption Notification { get; set; }
public XElement ToXElement() =>
......@@ -52,15 +57,19 @@ private object GetValueForSerialization()
{
return Value;
}
else if (IsZeroOrOneValueOfEnum())
{
return EnumValueAsInt32 == 1;
}
else
{
return (int)(object)Value;
return EnumValueAsInt32;
}
}
private string GetTypeNameForSerialization()
{
if (typeof(T) == typeof(bool))
if (typeof(T) == typeof(bool) || IsZeroOrOneValueOfEnum())
{
return nameof(Boolean);
}
......@@ -70,6 +79,12 @@ private string GetTypeNameForSerialization()
}
}
private bool IsZeroOrOneValueOfEnum()
{
var intVal = EnumValueAsInt32;
return intVal == 0 || intVal == 1;
}
public static CodeStyleOption<T> FromXElement(XElement element)
{
var typeAttribute = element.Attribute("Type");
......@@ -124,7 +139,7 @@ public static CodeStyleOption<T> FromXElement(XElement element)
// a CodeStyleOption<SomeEnumType>.
return v => Convert(bool.Parse(v));
case nameof(Int32):
return v => (T)(object)int.Parse(v);
return v => Convert(int.Parse(v));
default:
throw new ArgumentException(nameof(type));
}
......@@ -132,18 +147,26 @@ public static CodeStyleOption<T> FromXElement(XElement element)
private static T Convert(bool b)
{
// If we had a bool and we wanted a bool, then just return this
// value.
// If we had a bool and we wanted a bool, then just return this value.
if (typeof(T) == typeof(bool))
{
return (T)(object)b;
}
// Map booleans to the 1/0 value of the enum.
return b ? (T)(object)1 : (T)(object)0;
}
private static T Convert(int i)
{
// We got an int, but we wanted a bool. Map 0 to false, 1 to true, and anything else to default.
if (typeof(T) == typeof(bool))
{
return (T)(object)(i == 1);
}
var enumValues = (T[])Enum.GetValues(typeof(T));
return b
? enumValues.First(v => (int)(object)v == 0)
: enumValues.First(v => (int)(object)v == 1);
// If had an int and we wanted an enum, then just return this value.
return (T)(object)(i);
}
public bool Equals(CodeStyleOption<T> other)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册