public void ShouldIncludeAReturnKeywordForAnObjectInitStatement()
        {
            var exception             = Expression.Variable(typeof(Exception), "ex");
            var newAddress            = Expression.New(typeof(Address).GetConstructors().First());
            var line1Property         = newAddress.Type.GetMember("Line1").First();
            var line1Value            = Expression.Constant("Over here");
            var line1Init             = Expression.Bind(line1Property, line1Value);
            var addressInit           = Expression.MemberInit(newAddress, line1Init);
            var rethrow               = Expression.Rethrow(newAddress.Type);
            var globalCatchAndRethrow = Expression.Catch(exception, rethrow);
            var tryCatch              = Expression.TryCatch(addressInit, globalCatchAndRethrow);

            var tryCatchBlock = Expression.Block(tryCatch);

            var translated = ToReadableString(tryCatchBlock);

            const string EXPECTED = @"
try
{
    return new WhenTranslatingBlocks.Address
    {
        Line1 = ""Over here""
    };
}
catch
{
    throw;
}";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldTranslateANewExpressionWithAMultiLineInitialisationValue()
        {
            var writeWat = CreateLambda(() => Console.WriteLine("Wat"));
            var read     = CreateLambda <long>(() => Console.Read());

            var newMemoryStream  = Expression.New(typeof(MemoryStream));
            var positionProperty = newMemoryStream.Type.GetPublicInstanceProperty(nameof(MemoryStream.Position));
            var valueBlock       = Expression.Block(writeWat.Body, writeWat.Body, read.Body);
            var positionInit     = Expression.Bind(positionProperty, valueBlock);
            var memoryStreamInit = Expression.MemberInit(newMemoryStream, positionInit);

            var translated = ToReadableString(memoryStreamInit);

            const string EXPECTED = @"
new MemoryStream
{
    Position = 
    {
        Console.WriteLine(""Wat"");
        Console.WriteLine(""Wat"");

        return ((long)Console.Read());
    }
}";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldNotLeaveDoubleBlankLinesBetweenInitAndIfStatements()
        {
            var writeWat = CreateLambda(() => Console.WriteLine("Wat"));
            var read     = CreateLambda <long>(() => Console.Read());

            var newMemoryStream  = Expression.New(typeof(MemoryStream));
            var positionProperty = newMemoryStream.Type.GetProperty("Position");
            var valueBlock       = Expression.Block(writeWat.Body, read.Body);
            // ReSharper disable once AssignNullToNotNullAttribute
            var positionInit     = Expression.Bind(positionProperty, valueBlock);
            var memoryStreamInit = Expression.MemberInit(newMemoryStream, positionInit);

            var intVariable             = Expression.Variable(typeof(int), "i");
            var one                     = Expression.Constant(1);
            var intVariableEqualsOne    = Expression.Equal(intVariable, one);
            var doNothing               = Expression.Default(typeof(void));
            var ifIntEqualsOneDoNothing = Expression.IfThen(intVariableEqualsOne, doNothing);

            var block = Expression.Block(memoryStreamInit, ifIntEqualsOneDoNothing);

            const string EXPECTED = @"
new MemoryStream
{
    Position = 
    {
        Console.WriteLine(""Wat"");

        return ((long)Console.Read());
    }
};

if (i == 1)
{
}";

            var translated = ToReadableString(block);

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldTranslateAMemberInitReturnValue()
        {
            var company    = Expression.Variable(typeof(Company), "c");
            var ceo        = Expression.Variable(typeof(Employee), "ceo");
            var ceoAddress = Expression.Property(ceo, "Address");

            var assignCeo = Expression.Assign(ceo, Expression.Property(company, "Ceo"));

            var newAddress = Expression.MemberInit(
                Expression.New(typeof(Address).GetPublicInstanceConstructor()),
                Expression.Bind(
                    typeof(Address).GetPublicInstanceMember("Line1"),
                    Expression.Property(ceoAddress, "Line1")));

            var newEmployee = Expression.MemberInit(
                Expression.New(typeof(Employee).GetPublicInstanceConstructor()),
                Expression.Bind(
                    typeof(Employee).GetPublicInstanceMember("Address"),
                    newAddress)
                );

            var block = Expression.Block(assignCeo, newEmployee);

            var translated = ToReadableString(block);

            const string EXPECTED = @"
var ceo = c.Ceo;

return new WhenTranslatingBlocks.Employee
{
    Address = new WhenTranslatingBlocks.Address
    {
        Line1 = ceo.Address.Line1
    }
};";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldTerminateAMultipleLineMemberInitAssignment()
        {
            var writeWat = CreateLambda(() => Console.WriteLine("Wat"));
            var read     = CreateLambda <long>(() => Console.Read());

            var newMemoryStream  = Expression.New(typeof(MemoryStream));
            var positionProperty = newMemoryStream.Type.GetProperty("Position");
            var valueBlock       = Expression.Block(writeWat.Body, read.Body);
            // ReSharper disable once AssignNullToNotNullAttribute
            var positionInit     = Expression.Bind(positionProperty, valueBlock);
            var memoryStreamInit = Expression.MemberInit(newMemoryStream, positionInit);

            var streamVariable = Expression.Variable(typeof(Stream), "stream");

            var assignStream = Expression.Assign(streamVariable, memoryStreamInit);

            var streamIsNull = Expression.Equal(streamVariable, Expression.Default(typeof(Stream)));

            var ifNullAssign = Expression.IfThen(streamIsNull, assignStream);

            var translated = ToReadableString(ifNullAssign);

            const string EXPECTED = @"
if (stream == null)
{
    stream = new MemoryStream
    {
        Position = 
        {
            Console.WriteLine(""Wat"");

            return ((long)Console.Read());
        }
    };
}";

            translated.ShouldBe(EXPECTED.TrimStart());
        }