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 ShouldTranslateAVariableBlockLambdaWithAReturnExpression() { var listVariable = Expression.Variable(typeof(List <int>), "list"); var createList = CreateLambda(() => new List <int> { 1, 2, 3 }); var listAssignment = Expression.Assign(listVariable, createList.Body); var toArrayMethod = typeof(Enumerable).GetPublicStaticMethod("ToArray"); var typedToArrayMethod = toArrayMethod.MakeGenericMethod(typeof(int)); var listToArray = Expression.Call(typedToArrayMethod, listVariable); var listBlock = Expression.Block(new[] { listVariable }, listAssignment, listToArray); var listLambda = Expression.Lambda <Func <int[]> >(listBlock); var translated = ToReadableString(listLambda); const string EXPECTED = @"() => { var list = new List<int> { 1, 2, 3 }; return list.ToArray(); }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateAMultipleLineIfStatementTest() { var intVariable = Expression.Variable(typeof(int), "i"); var one = Expression.Constant(1); var intVariableLessThanOne = Expression.LessThan(intVariable, one); var returnLabel = Expression.Label(typeof(bool), "Return"); var returnTrue = Expression.Return(returnLabel, Expression.Constant(true)); var ifLessThanOneReturnTrue = Expression.IfThen(intVariableLessThanOne, returnTrue); var five = Expression.Constant(5); var intVariableMoreThanFive = Expression.GreaterThan(intVariable, five); var returnMoreThanFive = Expression.Label(returnLabel, intVariableMoreThanFive); var testBlock = Expression.Block(ifLessThanOneReturnTrue, returnMoreThanFive); var writeHello = CreateLambda(() => Console.WriteLine("Hello")); var writeVariable = Expression.Variable(writeHello.Type, "write"); var assignWrite = Expression.Assign(writeVariable, writeHello); var ifTestPassesThenWrite = Expression.IfThen(testBlock, assignWrite); var translated = ToReadableString(ifTestPassesThenWrite); const string EXPECTED = @" if ({ if (i < 1) { return true; } return i > 5; }) { write = () => Console.WriteLine(""Hello""); }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldVarAssignVariablesInSiblingBlocks() { var intVariable1 = Expression.Variable(typeof(int), "i"); var assignVariable1 = Expression.Assign(intVariable1, Expression.Constant(1)); var variable1Block = Expression.Block(new[] { intVariable1 }, assignVariable1); var intVariable2 = Expression.Variable(typeof(int), "j"); var assignVariable2 = Expression.Assign(intVariable2, Expression.Constant(2)); var variable2Block = Expression.Block(new[] { intVariable2 }, assignVariable2); var assign1Or2 = Expression.IfThenElse( Expression.Constant(true), variable1Block, variable2Block); var translated = ToReadableString(assign1Or2); const string EXPECTED = @" if (true) { var i = 1; } else { var j = 2; }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldNotVarAssignAVariableAssignedInATryButUsedInACatch() { var exceptionFactory = CreateLambda((int number) => new Exception(number.ToString())); var intVariable = exceptionFactory.Parameters.First(); var newException = exceptionFactory.Body; var assignment = Expression.Assign(intVariable, Expression.Constant(10)); var assignmentBlock = Expression.Block(assignment, Expression.Default(typeof(void))); var catchBlock = Expression.Catch(typeof(Exception), Expression.Throw(newException)); var tryCatch = Expression.TryCatch(assignmentBlock, catchBlock); var tryCatchBlock = Expression.Block(new[] { intVariable }, tryCatch); var translated = ToReadableString(tryCatchBlock); const string EXPECTED = @" int number; try { number = 10; } catch { throw new Exception(number.ToString()); }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldNotVarAssignAnOuterBlockDeclaredVariable() { var nameVariable = Expression.Variable(typeof(string), "name"); var writeNameTwiceVariable = Expression.Variable(typeof(Action), "writeNameTwice"); var writeLine = CreateLambda(() => Console.WriteLine(default(string))); var writeLineMethod = ((MethodCallExpression)writeLine.Body).Method; var writeLineCall = Expression.Call(writeLineMethod, nameVariable); var writeNameTwice = Expression.Block(writeLineCall, writeLineCall); var writeNameTwiceLambda = Expression.Lambda(writeNameTwice); var writeNameTwiceAssignment = Expression.Assign(writeNameTwiceVariable, writeNameTwiceLambda); var nameAssignment = Expression.Assign(nameVariable, Expression.Constant("Alice")); var writeNameTwiceCall = Expression.Invoke(writeNameTwiceVariable); var block = Expression.Block( new[] { nameVariable, writeNameTwiceVariable }, Expression.Block(writeNameTwiceAssignment), Expression.Block(nameAssignment, writeNameTwiceCall)); var translated = ToReadableString(block); const string EXPECTED = @" string name; Action writeNameTwice = () => { Console.WriteLine(name); Console.WriteLine(name); }; name = ""Alice""; writeNameTwice.Invoke();"; translated.ShouldBe(EXPECTED.TrimStart()); }
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 ShouldDeclareAVariableIfUsedBeforeInitialisation() { var nameVariable = Expression.Variable(typeof(string), "name"); var getNameVariable = Expression.Variable(typeof(Func <string>), "getName"); var getNameLambda = Expression.Lambda(nameVariable); var getNameAssignment = Expression.Assign(getNameVariable, getNameLambda); var nameAssignment = Expression.Assign(nameVariable, Expression.Constant("Fred")); var getNameCall = Expression.Invoke(getNameVariable); var block = Expression.Block( new[] { nameVariable, getNameVariable }, getNameAssignment, nameAssignment, getNameCall); var translated = ToReadableString(block); const string EXPECTED = @" string name; Func<string> getName = () => name; name = ""Fred""; return getName.Invoke();"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldAssignTheResultOfATryCatch() { var intVariable = Expression.Variable(typeof(int), "i"); var read = CreateLambda(() => Console.Read()); var returnDefault = Expression.Catch(typeof(IOException), Expression.Default(typeof(int))); var readOrDefault = Expression.TryCatch(read.Body, returnDefault); var assignReadOrDefault = Expression.Assign(intVariable, readOrDefault); var translated = ToReadableString(assignReadOrDefault); const string EXPECTED = @" i = { try { return Console.Read(); } catch (IOException) { return default(int); } }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateAVariableBlockLambdaWithAReturnValue() { var countVariable = Expression.Variable(typeof(ushort), "count"); var countEqualsZero = Expression.Assign(countVariable, Expression.Constant((ushort)0)); var incrementCount = Expression.Increment(countVariable); var returnCount = countVariable; var countBlock = Expression.Block( new[] { countVariable }, countEqualsZero, incrementCount, returnCount); var countLambda = Expression.Lambda <Func <ushort> >(countBlock); var translated = ToReadableString(countLambda); const string EXPECTED = @"() => { var count = 0; ++count; return count; }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldNameAnUnnamedVariable() { var intVariable = Expression.Variable(typeof(int)); var assignDefaultToInt = Expression.Assign(intVariable, Expression.Default(typeof(int))); var translated = ToReadableString(assignDefaultToInt); translated.ShouldBe("@int = default(int)"); }
public void ShouldTranslateAnAssignment() { var intVariable = Expression.Variable(typeof(int), "i"); var assignDefaultToInt = Expression.Assign(intVariable, Expression.Default(typeof(int))); var translated = ToReadableString(assignDefaultToInt); translated.ShouldBe("i = default(int)"); }
public void ShouldNotWrapAnAssignmentValueInParentheses() { var intVariable = Expression.Variable(typeof(int), "i"); var oneMultipliedByTwo = Expression.Multiply(Expression.Constant(1), Expression.Constant(2)); var assignment = Expression.Assign(intVariable, oneMultipliedByTwo); var translated = ToReadableString(assignment); translated.ShouldBe("i = 1 * 2"); }
public void ShouldTranslateAnExtensionAssignment() { var value = new ExtensionExpression(typeof(int)); var extensionVariable = Expression.Variable(value.Type, "ext"); var assignment = Expression.Assign(extensionVariable, value); var translated = ToReadableString(assignment); translated.ShouldBe("ext = " + value); }
public void ShouldUseFriendlyNamesForArrays() { var intArrayVariable = Expression.Variable(typeof(int[]), "ints"); var assignNull = Expression.Assign(intArrayVariable, Expression.Default(intArrayVariable.Type)); var assignNullBlock = Expression.Block(new[] { intArrayVariable }, assignNull); var translated = ToReadableString(assignNullBlock); translated.ShouldBe("var ints = default(int[]);"); }
public void ShouldNameAnUnnamedParameter() { var stringParameter = Expression.Parameter(typeof(string), string.Empty); var stringVariable = Expression.Variable(typeof(string), " "); var assignVariableToParameter = Expression.Assign(stringVariable, stringParameter); var translated = ToReadableString(assignVariableToParameter); translated.ShouldBe("string1 = string2"); }
public void ShouldTranslateANegatedBooleanAssignment() { var boolVariable1 = Expression.Variable(typeof(bool), "isItNot"); var boolVariable2 = Expression.Variable(typeof(bool), "isIt"); var assignBool = Expression.Assign(boolVariable1, Expression.IsFalse(boolVariable2)); var negated = Expression.Not(assignBool); var translated = ToReadableString(negated); translated.ShouldBe("!(isItNot = !isIt)"); }
public void ShouldTranslateAnAssignmentResultAssignment() { var intVariable1 = Expression.Variable(typeof(int), "i"); var intVariable2 = Expression.Variable(typeof(int), "j"); var assignVariable2 = Expression.Assign(intVariable2, Expression.Constant(1)); var setVariableOneToAssignmentResult = Expression.Assign(intVariable1, assignVariable2); var translated = ToReadableString(setVariableOneToAssignmentResult); translated.ShouldBe("i = j = 1"); }
public void ShouldTranslateDbNullValue() { var dbParameter = Expression.Variable(typeof(DbParameter), "param"); var parameterValue = Expression.Property(dbParameter, "Value"); var dbNull = Expression.Constant(DBNull.Value, typeof(DBNull)); var setParamToDbNull = Expression.Assign(parameterValue, dbNull); var translated = ToReadableString(setParamToDbNull); translated.ShouldBe("param.Value = DBNull.Value"); }
public void ShouldTranslateImplicitOperatorUse() { var adderToString = CreateLambda <string>(() => new CustomAdder()); var stringVariable = Expression.Variable(typeof(string), "str"); var assignment = Expression.Assign(stringVariable, adderToString.Body); var translated = ToReadableString(assignment); translated.ShouldBe("str = new CustomAdder()"); }
public void ShouldTranslateExplicitOperatorUse() { var adderToString = CreateLambda(() => (int)new CustomAdder()); var intVariable = Expression.Variable(typeof(int), "i"); var assignment = Expression.Assign(intVariable, adderToString.Body); var translated = ToReadableString(assignment); translated.ShouldBe("i = (int)new CustomAdder()"); }
public void ShouldAssignAMultiplicationToStringResult() { var timesThreeToString = CreateLambda((int i) => (i * 3).ToString()); var stringVariable = Expression.Variable(typeof(string), "value"); var stringAssignment = Expression.Assign(stringVariable, timesThreeToString.Body); var translated = ToReadableString(stringAssignment); translated.ShouldBe("value = (i * 3).ToString()"); }
public void ShouldNotVarAssignAVariableOfNonImpliedType() { var intsVariable = Expression.Variable(typeof(IEnumerable <int>), "ints"); var newArray = Expression.NewArrayBounds(typeof(int), Expression.Constant(2)); var assignment = Expression.Assign(intsVariable, newArray); var block = Expression.Block(new[] { intsVariable }, assignment); var translated = ToReadableString(block); translated.ShouldBe("IEnumerable<int> ints = new int[2];"); }
public void ShouldNotRemoveParenthesesFromACastObjectChainedMethodCall() { var intArrayConverter = CreateLambda( (IList <int> ints) => ((int[])ints).ToString().Split(',')); var stringArrayVariable = Expression.Variable(typeof(string[]), "strings"); var assignment = Expression.Assign(stringArrayVariable, intArrayConverter.Body); var translated = ToReadableString(assignment); translated.ShouldBe("strings = ((int[])ints).ToString().Split(',')"); }
public void ShouldTranslateImplicitMethodOperatorUse() { var stringVariable = Expression.Variable(typeof(string), "str"); var stringOperator = typeof(CustomAdder).GetImplicitOperator(o => o.To <string>()); var adderInstance = Expression.New(typeof(CustomAdder).GetPublicInstanceConstructor()); var operatorCall = Expression.Call(stringOperator, adderInstance); var assignment = Expression.Assign(stringVariable, operatorCall); var translated = ToReadableString(assignment); translated.ShouldBe("str = new CustomAdder()"); }
public void ShouldTranslateExplicitMethodOperatorUse() { var intVariable = Expression.Variable(typeof(int), "i"); var intOperator = typeof(CustomAdder).GetExplicitOperator(o => o.To <int>()); var adderInstance = Expression.New(typeof(CustomAdder).GetPublicInstanceConstructor()); var operatorCall = Expression.Call(intOperator, adderInstance); var assignment = Expression.Assign(intVariable, operatorCall); var translated = ToReadableString(assignment); translated.ShouldBe("i = (int)new CustomAdder()"); }
public void ShouldNotRemoveParenthesesFromALambdaInvokeResultAssignment() { var intsAdder = CreateLambda((int a, int b) => a + b); var one = Expression.Constant(1); var two = Expression.Constant(2); var lambdaInvocation = Expression.Invoke(intsAdder, one, two); var result = Expression.Variable(typeof(int), "result"); var assignInvokeResult = Expression.Assign(result, lambdaInvocation); const string EXPECTED = "result = ((a, b) => a + b).Invoke(1, 2)"; var translated = ToReadableString(assignInvokeResult); translated.ShouldBe(EXPECTED); }
private static Expression GetReturnStatementBlock(out ParameterExpression existingInts) { existingInts = Expression.Variable(typeof(List <int>), "ints"); var existingIntsEnumerator = Expression.Variable(typeof(List <int> .Enumerator), "enumerator"); var getEnumeratorMethod = existingInts.Type.GetPublicInstanceMethod("GetEnumerator"); var getEnumeratorCall = Expression.Call(existingInts, getEnumeratorMethod); var enumeratorAssignment = Expression.Assign(existingIntsEnumerator, getEnumeratorCall); var enumeratorMoveNextMethod = existingIntsEnumerator.Type.GetPublicInstanceMethod("MoveNext"); var enumeratorMoveNextCall = Expression.Call(existingIntsEnumerator, enumeratorMoveNextMethod); var enumeratorItem = Expression.Variable(typeof(int), "item"); var enumeratorCurrent = Expression.Property(existingIntsEnumerator, "Current"); var itemAssignment = Expression.Assign(enumeratorItem, enumeratorCurrent); var intsAddMethod = existingInts.Type.GetPublicInstanceMethod("Add"); var intsAddCall = Expression.Call(existingInts, intsAddMethod, enumeratorItem); var addItemBlock = Expression.Block( new[] { enumeratorItem }, itemAssignment, intsAddCall); var loopBreakTarget = Expression.Label(typeof(void), "LoopBreak"); var conditionallyAddItems = Expression.Condition( Expression.IsTrue(enumeratorMoveNextCall), addItemBlock, Expression.Break(loopBreakTarget)); var addItemsLoop = Expression.Loop(conditionallyAddItems, loopBreakTarget); var populateExistingInts = Expression.Block( new[] { existingIntsEnumerator }, enumeratorAssignment, addItemsLoop); var conditionFalseBlock = Expression.Block( populateExistingInts, existingInts); var valueConditional = Expression.Condition( Expression.Equal(existingInts, Expression.Default(existingInts.Type)), Expression.New(conditionFalseBlock.Type), conditionFalseBlock); return(valueConditional); }
public void ShouldTranslateMultilineBlockSingleMethodArguments() { var intVariable = Expression.Variable(typeof(int), "i"); var variableInit = Expression.Assign(intVariable, Expression.Constant(3)); var variableMultiplyFive = Expression.Multiply(intVariable, Expression.Constant(5)); var variableAdditionOne = Expression.Assign(intVariable, variableMultiplyFive); var variableDivideThree = Expression.Divide(intVariable, Expression.Constant(3)); var variableAdditionTwo = Expression.Assign(intVariable, variableDivideThree); var argumentBlock = Expression.Block( new[] { intVariable }, variableInit, variableAdditionOne, variableAdditionTwo, intVariable); var catchBlock = Expression.Catch( typeof(Exception), Expression.Block(ReadableExpression.Comment("So what!"), Expression.Constant(0))); var tryCatch = Expression.TryCatch(argumentBlock, catchBlock); var collectionVariable = Expression.Variable(typeof(ICollection <int>), "ints"); var addMethod = collectionVariable.Type.GetPublicInstanceMethod("Add"); var addMethodCall = Expression.Call(collectionVariable, addMethod, tryCatch); const string EXPECTED = @" ints.Add( { try { var i = 3; i = i * 5; i = i / 3; return i; } catch { // So what! return 0; } })"; var translated = ToReadableString(addMethodCall); translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldIgnoreABlankLabelTargetLine() { var intVariable = Expression.Variable(typeof(int), "i"); var intAssignment = Expression.Assign(intVariable, Expression.Constant(0)); var labelTarget = Expression.Label(typeof(void), "LabelTarget"); var intAssignmentBlock = Expression.Block( new[] { intVariable }, intAssignment, Expression.Label(labelTarget)); var translated = ToReadableString(intAssignmentBlock); translated.ShouldBe("var i = 0;"); }