public void StructWithProperties()
        {
            string code = @"
namespace FooBar
{
    [StructGenerators.GenerateEquality]
    public partial class MyClass
    {
        private string P1 {get;}
        public string P2 {get; private set;}
        public string P3 {get; init;}
        public int P4 => 42;
        private static string StaticProperty {get;}
    }
}
";

            var generatorTestHelper = new GeneratorTestHelper <EqualityGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("Equals");
            output.Should().Contain("P1");
            output.Should().Contain("P2");
            output.Should().Contain("P3");
            output.Should().NotContain("P4");
            output.Should().NotContain("_staticS");
        }
        public void StructWithDoubleAndCustomStruct()
        {
            // BTW, the C# compiler devs explicitly decided not to go with this pattern for records to avoid code bloat.
            string code = @"
public class S1
{
     public static bool operator ==(S1 left, S1 right) => true;
    public static bool operator !=(S1 left, S1 right) => true;
}

public class S2
{
}

[StructGenerators.GenerateEquality]
public partial class MyClass
{
    private readonly double _v;
    private readonly S1 _s1;
    private readonly S2 _s2;
}
";

            var generatorTestHelper = new GeneratorTestHelper <EqualityGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("(left._v, left._s1) == (right._v, right._s1) && (left._s2).Equals((right._s2))");
        }
Example #3
0
        public void StructWith5Fields()
        {
            string code = @"
namespace X {
        [StructGenerators.GenerateToString]
    public partial struct MyStruct
    {
        private readonly int _t1;
        private readonly int _t2;
        private readonly int _t3;
        private readonly int _t4;
        private readonly int _t5;
        private static string _staticS;

        public void FoOBar()
        {
            //this.ToString
        }
    }
}
        ";

            var generatorTestHelper = new GeneratorTestHelper <ToStringGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("ToString()");
        }
Example #4
0
        public void WithMethodsGeneratedAllNonPrivateFieldsAndProperties()
        {
            string code = @"
namespace FooBar
{
    [StructGenerators.StructRecord]
    public partial struct MyStruct
    {
        private readonly string _NotIncluded;
        public readonly string _S;
        public string S {get;}
        public string S2 {get; private set;}
        public string S3 {get; init;}
        private string NotIncludedProp {get; init;}
        private string NotIncludedProp2 => string.Empty;
        private string NotIncludedProp3 { get => string.Empty;}
    }
}
";

            var generatorTestHelper = new GeneratorTestHelper <StructRecordGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().NotContain("WithNotIncluded");
            output.Should().Contain("WithS(");
            output.Should().Contain("WithS2(");
            output.Should().Contain("WithS3(");
            output.Should().Contain("With_S(");
        }
Example #5
0
        public void StructWithNoFieldsShouldCompile()
        {
            string code = @"
[StructGenerators.StructRecord]
public partial struct MyStruct
{
}
";

            var generatorTestHelper = new GeneratorTestHelper <StructRecordGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("private bool PrintMembers(StringBuilder");
        }
        public void PrintTypeNameIsFalseByDefault()
        {
            string code = @"
[StructGenerators.GenerateToString]
public partial struct MyStruct
{
}
";

            var generatorTestHelper = new GeneratorTestHelper <ToStringGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain(@"// sb.Append(""MyStruct "");");
        }
Example #7
0
        public void SealedClassWithNoFields()
        {
            string code = @"
[StructGenerators.GenerateToString]
public sealed partial class MyStruct
{
}
";

            var generatorTestHelper = new GeneratorTestHelper <ToStringGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("private bool PrintMembers(StringBuilder");
        }
        public void StructWithNoFields()
        {
            string code = @"
[StructGenerators.GenerateEquality]
public partial struct MyStruct
{
}
";

            var generatorTestHelper = new GeneratorTestHelper <EqualityGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("Equals");
            output.Should().Contain("42");
        }
Example #9
0
        public void Record()
        {
            string code = @"
[StructGenerators.GenerateToString]
public partial record MyRecord
{
}
";

            var generatorTestHelper = new GeneratorTestHelper <ToStringGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain(@"sb.Append(""MyRecord "");");
            output.Should().Contain("virtual bool PrintMembers(StringBuilder sb)");
        }
Example #10
0
        public void StructWithOneField()
        {
            string code = @"
[StructGenerators.GenerateToString]
public partial struct MyStruct
{
    private readonly string _s;
}
";

            var generatorTestHelper = new GeneratorTestHelper <ToStringGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("sb.Append((object)_s)");
        }
Example #11
0
        public void StructWithNoFields()
        {
            string code = @"
[StructGenerators.GenerateToString]
public partial struct MyStruct
{
}
";

            var generatorTestHelper = new GeneratorTestHelper <ToStringGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain(@"sb.Append(""MyStruct "");");
            output.Should().Contain("private bool PrintMembers(StringBuilder");
        }
Example #12
0
        public void ReferenceTypeFieldShouldHaveCast()
        {
            string code = @"
[StructGenerators.GenerateToString]
public partial struct MyStruct
{
    private readonly string _s;
}
";

            var generatorTestHelper = new GeneratorTestHelper <ToStringGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("(object)_s");
        }
        public void SkipIsRespected()
        {
            string code = @"
[StructGenerators.GenerateToString]
public partial struct MyStruct
{
    [StructGenerators.ToStringBehavior(Skip = true)]
    public int[] S2 => null;
}
";

            var generatorTestHelper = new GeneratorTestHelper <ToStringGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().NotContain("PrintCollection");
        }
Example #14
0
        public void StructAlreadyHasToString()
        {
            string code = @"
        [StructGenerators.StructRecord]
        public partial struct MyStruct
        {
            private readonly string _s;
            public override string ToString() => string.Empty;
        }
        ";

            var generatorTestHelper = new GeneratorTestHelper <StructRecordGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().NotContain("ToString()");
        }
Example #15
0
        public void TestExistingClone()
        {
            string code = @"
[StructGenerators.StructRecord]
public partial struct MyStruct
{
    public int X;
    public MyStruct Clone() => default;
}
";

            var generatorTestHelper = new GeneratorTestHelper <StructRecordGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("WithX(");
        }
        public void StructWithOneField()
        {
            string code = @"
[StructGenerators.GenerateEquality]
public partial class MyClass
{
    private readonly string _s;
}
";

            var generatorTestHelper = new GeneratorTestHelper <EqualityGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("Equals");
            output.Should().Contain("_s");
            output.Should().NotContain("42");
        }
        public void ClassWithNoFields()
        {
            string code = @"
[StructGenerators.GenerateEquality]
public partial class MyClass
{
}
";

            var generatorTestHelper = new GeneratorTestHelper <EqualityGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("EqualityContract");
            output.Should().Contain("EqualityContract != other.EqualityContract");
            output.Should().Contain("Equals");
            output.Should().Contain("42");
        }
Example #18
0
        public void RecordWithPrimaryConstructor()
        {
            string code = @"
[StructGenerators.GenerateToString]
public partial record MyRecord(int Property1)
{
}
";

            var generatorTestHelper = new GeneratorTestHelper <ToStringGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain(@"sb.Append(""MyRecord "");");
            output.Should().Contain("virtual bool PrintMembers(StringBuilder sb)");
            output.Should().Contain("Property1");
            output.Should().NotContain("EqualityContract");
        }
Example #19
0
        public void TestExistingConstructor()
        {
            string code = @"
[StructGenerators.StructRecord]
public partial struct MyStruct
{
    public readonly int X;
    public readonly string S;
    public MyStruct(int x, string s) {X = x; S = s;}
}
";

            var generatorTestHelper = new GeneratorTestHelper <StructRecordGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("WithX(");
        }
        public void RespectTheLimits()
        {
            string code = @"
[StructGenerators.GenerateToString(MaxStringLength = 142)]
public partial struct MyStruct
{
    [StructGenerators.ToStringBehavior(CollectionCountLimit = 99)]
    private readonly string[] _s;
}
";

            var generatorTestHelper = new GeneratorTestHelper <ToStringGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain(", limit: 99");
            output.Should().Contain("142");
        }
Example #21
0
        public void StructWithOneFieldAndStatic()
        {
            string code = @"
        [StructGenerators.StructRecord]
        public partial struct MyStruct
        {
            private readonly string _s;
            private static string _staticS;
        }
        ";

            var generatorTestHelper = new GeneratorTestHelper <StructRecordGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("Append((object)_s)");
            output.Should().NotContain("_staticS.ToString()");
        }
        public void StructAlreadyHasGetHashCode()
        {
            // TODO: this test can do a better job and detect exactly what is going on.
            // This should be fine: the generated code should just skip it.
            string code = @"
[StructGenerators.GenerateEquality]
public partial class MyClass
{
    private readonly string _s;
    public override int GetHashCode() => 42;
}
";

            var generatorTestHelper = new GeneratorTestHelper <EqualityGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().NotContain("GetHashCode");
        }
Example #23
0
        public void StructAlreadyHasToString()
        {
            // TODO: this test can do a better job and detect exactly what is going on.
            // This should be fine: the generated code should just skip it.
            string code = @"
        [StructGenerators.GenerateToString]
        public partial struct MyStruct
        {
            private readonly string _s;
            public override string ToString() => string.Empty;
        }
        ";

            var generatorTestHelper = new GeneratorTestHelper <ToStringGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().NotContain("ToString()");
        }
Example #24
0
        public void StructEqualityAndToStringShouldNotCollide()
        {
            string code = @"
[StructGenerators.ToStringGenerator]
[StructGenerators.GenerateEquality]
public partial struct MyStruct
{
    public readonly int X;
    public MyStruct(int x) {X = x;}
}
";

            var generatorTestHelper = new GeneratorTestHelper <EqualityGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("Equals");
            output.Should().Contain("ToString");
        }
Example #25
0
        public void CloneMethodShouldBeGenerated()
        {
            string code = @"
        [StructGenerators.StructRecord]
        public partial struct MyStruct
        {
            public readonly int _t1;
            public readonly int _t2;
            public readonly int _t3;
            public readonly int _t4;
            private readonly int _t5;
            private static string _staticS;
        }
        ";

            var generatorTestHelper = new GeneratorTestHelper <StructRecordGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("Clone()");
        }
        public void LegacyCollectionToStringBehavior()
        {
            string code = @"
[StructGenerators.GenerateToString]
public partial struct MyStruct
{
    private readonly string[] _s;
    
    public string[] S => _s;

    [StructGenerators.ToStringBehavior(CollectionsBehavior = StructGenerators.CollectionsBehavior.PrintContent)]
    public int[] S2 => null;
}
";

            var generatorTestHelper = new GeneratorTestHelper <ToStringGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("behavior: CollectionsBehavior.PrintContent");
            output.Should().Contain("limit: 100");
        }
        public void GenericStructWithOneFieldAndStatic()
        {
            string code = @"
[StructGenerators.GenerateEquality]
public partial class MyClass<T1, T2, T3, T4, T5>
{
    private readonly T1 _t1;
    private readonly T2 _t2;
    private readonly T3 _t3;
    private readonly T4 _t4;
    private readonly T5 _t5;
    private static string _staticS;
}
";

            var generatorTestHelper = new GeneratorTestHelper <EqualityGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("Equals");
            output.Should().NotContain("42");
            output.Should().NotContain("_staticS");
        }
        public void SkipFieldsAndProperties()
        {
            string code = @"
[StructGenerators.GenerateToString]
public partial struct MyStruct
{
    [StructGenerators.ToStringBehavior(Skip = true)]
    private readonly string _s;
    
    [StructGenerators.ToStringBehavior(Skip = true)]
    public string S => _s;

    public string Y => _s;
}
";

            var generatorTestHelper = new GeneratorTestHelper <ToStringGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().NotContain("Append((object)_s)");
            output.Should().NotContain("Append((object)S)");
            output.Should().Contain("Append((object)Y)");
        }
Example #29
0
        public void GenericStructWithOneFieldAndStatic()
        {
            string code = @"
        [StructGenerators.StructRecord]
        public partial struct MyStruct<T1, T2, T3, T4, T5>
        {
            public readonly T1 _t1;
            public readonly T2 _t2;
            public readonly T3 _t3;
            public readonly T4 _t4;
            public readonly T5 _t5;
            private static string _staticS;
        }
        ";

            var generatorTestHelper = new GeneratorTestHelper <StructRecordGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("ToString()");
            output.Should().Contain("_t1?.ToString()");
            output.Should().Contain("_t5?.ToString()");
            output.Should().NotContain("_staticS.ToString()");
            output.Should().NotContain("$$TYPE_NAME$$");
        }
Example #30
0
        public void GenericStructWithOneFieldAndStatic()
        {
            string code = @"
        [StructGenerators.GenerateToString]
        public partial struct MyStruct<T1, T2, T3, T4, T5>
        {
            private readonly T1 _t1;
            private readonly T2 _t2;
            private readonly T3 _t3;
            private readonly T4 _t4;
            private readonly T5 _t5;
            private static string _staticS;
        }
        ";

            var generatorTestHelper = new GeneratorTestHelper <ToStringGenerator>();
            var output = generatorTestHelper.GetGeneratedOutput(code);

            output.Should().Contain("ToString()");
            // No casts for generics! This will cause boxing if T1 is value type, I guess.
            output.Should().Contain("Append(_t1?.ToString())");
            output.Should().Contain("Append(_t5?.ToString())");
            output.Should().NotContain("Append(_staticS)");
        }