Skip to content

Commit 56b8895

Browse files
committed
Test coverage for partial trust environments
1 parent 54ddb25 commit 56b8895

File tree

3 files changed

+158
-2
lines changed

3 files changed

+158
-2
lines changed

ReadableExpressions.UnitTests/ReadableExpressions.UnitTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
<Compile Include="..\VersionInfo.cs">
6161
<Link>VersionInfo.cs</Link>
6262
</Compile>
63+
<Compile Include="WhenUsingPartialTrust.cs" />
6364
<Compile Include="WhenTranslatingStringConcatenation.cs" />
6465
<Compile Include="WhenTranslatingComments.cs" />
6566
<Compile Include="WhenTranslatingDynamicOperations.cs" />
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
namespace AgileObjects.ReadableExpressions.UnitTests
2+
{
3+
using System;
4+
using System.Linq.Expressions;
5+
using System.Security;
6+
using System.Security.Policy;
7+
using Microsoft.CSharp.RuntimeBinder;
8+
using Microsoft.VisualStudio.TestTools.UnitTesting;
9+
10+
[TestClass]
11+
public class WhenUsingPartialTrust
12+
{
13+
[TestMethod]
14+
public void ShouldTranslateASimpleAssignment()
15+
{
16+
ExecuteInPartialTrust(helper =>
17+
{
18+
var translated = helper.TranslateSimpleAssignment();
19+
20+
Assert.AreEqual("i = 0", translated);
21+
});
22+
}
23+
24+
[TestMethod]
25+
public void ShouldTranslateADynamicExpression()
26+
{
27+
ExecuteInPartialTrust(helper =>
28+
{
29+
var translated = helper.TranslateDynamicExpression();
30+
31+
Assert.AreEqual("obj => obj.Length", translated);
32+
});
33+
}
34+
35+
[TestMethod]
36+
public void ShouldTranslateAValueTypeTypeEqualExpression()
37+
{
38+
ExecuteInPartialTrust(helper =>
39+
{
40+
var translated = helper.TranslateIntTypeEqualExpression();
41+
42+
Assert.AreEqual("(i TypeOf typeof(long))", translated);
43+
});
44+
}
45+
46+
[TestMethod]
47+
public void ShouldTranslateAnObjectTypeEqualExpression()
48+
{
49+
ExecuteInPartialTrust(helper =>
50+
{
51+
var translated = helper.TranslateObjectTypeEqualExpression();
52+
53+
Assert.AreEqual("(o is string)", translated);
54+
});
55+
}
56+
57+
private static void ExecuteInPartialTrust(Action<TranslationHelper> testAction)
58+
{
59+
AppDomain partialTrustDomain = null;
60+
61+
try
62+
{
63+
var evidence = new Evidence();
64+
evidence.AddHostEvidence(new Zone(SecurityZone.Internet));
65+
66+
var permissions = new NamedPermissionSet(
67+
"PartialTrust",
68+
SecurityManager.GetStandardSandbox(evidence));
69+
70+
partialTrustDomain = AppDomain.CreateDomain(
71+
"PartialTrust",
72+
evidence,
73+
new AppDomainSetup { ApplicationBase = "." },
74+
permissions);
75+
76+
var helperType = typeof(TranslationHelper);
77+
78+
var helper = (TranslationHelper)partialTrustDomain
79+
.CreateInstanceAndUnwrap(helperType.Assembly.FullName, helperType.FullName);
80+
81+
testAction.Invoke(helper);
82+
}
83+
finally
84+
{
85+
if (partialTrustDomain != null)
86+
{
87+
AppDomain.Unload(partialTrustDomain);
88+
}
89+
}
90+
}
91+
}
92+
93+
public class TranslationHelper : MarshalByRefObject
94+
{
95+
public string TranslateSimpleAssignment()
96+
{
97+
var intVariable = Expression.Variable(typeof(int), "i");
98+
var assignment = Expression.Assign(intVariable, Expression.Constant(0));
99+
100+
return assignment.ToReadableString();
101+
}
102+
103+
public string TranslateDynamicExpression()
104+
{
105+
var lengthGetterSiteBinder = Binder.GetMember(
106+
CSharpBinderFlags.None,
107+
"Length",
108+
typeof(WhenTranslatingDynamicOperations),
109+
new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
110+
111+
var dynamicParameter = Expression.Parameter(typeof(object), "obj");
112+
113+
var dynamicLengthGetter = Expression.Dynamic(
114+
lengthGetterSiteBinder,
115+
typeof(object),
116+
dynamicParameter);
117+
118+
var dynamicLengthLambda = Expression
119+
.Lambda<Func<object, object>>(dynamicLengthGetter, dynamicParameter);
120+
121+
dynamicLengthLambda.Compile();
122+
123+
return dynamicLengthLambda.ToReadableString();
124+
}
125+
126+
public string TranslateIntTypeEqualExpression()
127+
{
128+
var intVariable = Expression.Variable(typeof(int), "i");
129+
var intIsLong = Expression.TypeEqual(intVariable, typeof(long));
130+
131+
return intIsLong.ToReadableString();
132+
}
133+
134+
public string TranslateObjectTypeEqualExpression()
135+
{
136+
var objectVariable = Expression.Variable(typeof(object), "o");
137+
var objectIsString = Expression.TypeEqual(objectVariable, typeof(string));
138+
139+
return objectIsString.ToReadableString();
140+
}
141+
}
142+
}

ReadableExpressions/Translators/TypeEqualExpressionTranslator.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,18 @@ public override string Translate(Expression expression, TranslationContext conte
3636
return FallbackTranslation(expression, context);
3737
}
3838

39-
var reducedTypeEqualExpression = (Expression)_reduceTypeEqualMethod.Invoke(expression, null);
39+
Expression reducedTypeEqualExpression;
40+
41+
try
42+
{
43+
reducedTypeEqualExpression = (Expression)_reduceTypeEqualMethod.Invoke(expression, null);
44+
}
45+
catch
46+
{
47+
// Unable to invoke the non-public ReduceTypeEqual method:
48+
return FallbackTranslation(expression, context);
49+
}
50+
4051
var translated = context.Translate(reducedTypeEqualExpression).Unterminated();
4152

4253
return translated;
@@ -47,7 +58,9 @@ private static string FallbackTranslation(Expression expression, TranslationCont
4758
var typeBinary = (TypeBinaryExpression)expression;
4859
var operand = context.Translate(typeBinary.Expression);
4960

50-
return $"({operand} TypeOf {typeBinary.TypeOperand.GetFriendlyName()})";
61+
return typeBinary.TypeOperand.IsClass()
62+
? $"({operand} is {typeBinary.TypeOperand.GetFriendlyName()})"
63+
: $"({operand} TypeOf typeof({typeBinary.TypeOperand.GetFriendlyName()}))";
5164
}
5265
}
5366
}

0 commit comments

Comments
 (0)