public void ShouldTranslateAMultipleVariableBlockWithNoReturnValue()
        {
            var countOneVariable      = Expression.Variable(typeof(int), "countOne");
            var countTwoVariable      = Expression.Variable(typeof(int), "countTwo");
            var countThreeVariable    = Expression.Variable(typeof(byte), "countThree");
            var assignOneToCountOne   = Expression.Assign(countOneVariable, Expression.Constant(1));
            var assignTwoToCountTwo   = Expression.Assign(countTwoVariable, Expression.Constant(2));
            var sumCounts             = Expression.Add(countOneVariable, countTwoVariable);
            var castSumToBye          = Expression.Convert(sumCounts, typeof(byte));
            var assignSumToCountThree = Expression.Assign(countThreeVariable, castSumToBye);

            var countBlock = Expression.Block(
                new[] { countOneVariable, countTwoVariable, countThreeVariable },
                assignOneToCountOne,
                assignTwoToCountTwo,
                assignSumToCountThree);

            var translated = ToReadableString(countBlock);

            const string EXPECTED = @"
var countOne = 1;
var countTwo = 2;
var countThree = (byte)(countOne + countTwo);";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldTranslateALabelWithABlockDefaultValue()
        {
            var returnLabelTarget = Expression.Label(typeof(int), "Return");

            var intVariable         = Expression.Variable(typeof(int), "i");
            var variableInit        = Expression.Assign(intVariable, Expression.Constant(0));
            var variablePlusOne     = Expression.Add(intVariable, Expression.Constant(1));
            var variableAdditionOne = Expression.Assign(intVariable, variablePlusOne);
            var variablePlusTwo     = Expression.Add(intVariable, Expression.Constant(2));
            var variableAdditionTwo = Expression.Assign(intVariable, variablePlusTwo);

            var variableBlock = Expression.Block(variableAdditionTwo, intVariable);

            var returnVariableBlock = Expression.Label(returnLabelTarget, variableBlock);

            var returnBlock = Expression.Block(
                new[] { intVariable },
                variableInit,
                variableAdditionOne,
                returnVariableBlock);

            const string EXPECTED   = @"
var i = 0;
i = i + 1;

return 
{
    i = i + 2;

    return i;
};";
            var          translated = ToReadableString(returnBlock);

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldTranslateANestedQuotedLambda()
        {
            var intA                = Expression.Parameter(typeof(int), "a");
            var intB                = Expression.Parameter(typeof(int), "b");
            var addition            = Expression.Add(intA, intB);
            var additionInnerLambda = Expression.Lambda(addition, intB);
            var quotedInnerLambda   = Expression.Quote(additionInnerLambda);
            var additionOuterLambda = Expression.Lambda(quotedInnerLambda, intA);

            var translated = ToReadableString(additionOuterLambda);

            translated.ShouldBe("a => b => a + b");
        }
        public void ShouldTranslateAMultiLineCheckedSubtractionAssignment()
        {
            var intVariable = Expression.Variable(typeof(int), "i");

            var consoleRead = CreateLambda(() => Console.Read());

            var variableOne = Expression.Variable(typeof(int), "one");
            var variableTwo = Expression.Variable(typeof(int), "two");

            var variableOneAssignment = Expression.Assign(variableOne, consoleRead.Body);
            var variableTwoAssignment = Expression.Assign(variableTwo, consoleRead.Body);

            var variableOnePlusTwo = Expression.Add(variableOne, variableTwo);

            var valueBlock = Expression.Block(
                new[] { variableOne, variableTwo },
                variableOneAssignment,
                variableTwoAssignment,
                variableOnePlusTwo);

            var substractOneAndAssign = Expression.SubtractAssignChecked(intVariable, valueBlock);

            var translated = ToReadableString(substractOneAndAssign);

            const string EXPECTED = @"
checked
{
    i -=
    {
        var one = Console.Read();
        var two = Console.Read();

        return (one + two);
    }
}";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldTranslateACheckedMultiplicationExpression()
        {
            var consoleRead = CreateLambda(() => Console.Read());

            var variableOne = Expression.Variable(typeof(int), "one");
            var variableTwo = Expression.Variable(typeof(int), "two");

            var variableOneAssignment = Expression.Assign(variableOne, consoleRead.Body);
            var variableTwoAssignment = Expression.Assign(variableTwo, consoleRead.Body);

            var variableOnePlusTwo = Expression.Add(variableOne, variableTwo);

            var valueOneBlock = Expression.Block(
                new[] { variableOne, variableTwo },
                variableOneAssignment,
                variableTwoAssignment,
                variableOnePlusTwo);

            var intVariable           = Expression.Parameter(typeof(int), "i");
            var checkedMultiplication = Expression.MultiplyChecked(valueOneBlock, intVariable);

            var translated = ToReadableString(checkedMultiplication);

            const string EXPECTED = @"
checked
{
    {
        var one = Console.Read();
        var two = Console.Read();

        return (one + two);
    } * i
}";

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