Skip to content

Beginnings of #25. #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Oct 31, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 174 additions & 0 deletions TestStack.FluentMVCTesting.Tests/Internal/ExpressionInspectorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
using NUnit.Framework;
using System;
using System.Linq.Expressions;
using TestStack.FluentMVCTesting.Internal;

namespace TestStack.FluentMVCTesting.Tests.Internal
{
[TestFixture]
public class ExpressionInspectorShould
{
[Test]
public void Correctly_parse_equality_comparison_with_string_operands()
{
Expression<Func<string, bool>> func = text => text == "any";
ExpressionInspector sut = new ExpressionInspector();
var actual = sut.Inspect(func);
Assert.AreEqual("text => (text == \"any\")", actual);
}

[Test]
public void Correctly_parse_equality_comparison_with_int_operands()
{
Expression<Func<int, bool>> func = number => number == 5;
ExpressionInspector sut = new ExpressionInspector();
var actual = sut.Inspect(func);
Assert.AreEqual("number => (number == 5)", actual);
}

[Test]
public void Correctly_parse_equality_comparison_with_property_operand()
{
Expression<Func<PostViewModel, bool>> func = post => post.Title == "A";
ExpressionInspector sut = new ExpressionInspector();
var actual = sut.Inspect(func);
Assert.AreEqual("post => (post.Title == \"A\")", actual);
}

[Test]
public void Correctly_parse_equality_comparison_with_two_property_operands()
{
Expression<Func<PostViewModel, bool>> func = post =>
post.Title == post.Slug;
ExpressionInspector sut = new ExpressionInspector();
var actual = sut.Inspect(func);
Assert.AreEqual("post => (post.Title == post.Slug)", actual);
}

[Test]
public void Correctly_parse_equality_comparison_with_captured_constant_operand()
{
const int Number = 5;
Expression<Func<int, bool>> func = number => number == Number;
ExpressionInspector sut = new ExpressionInspector();
var actual = sut.Inspect(func);
Assert.AreEqual(string.Concat("number => (number == ", Number, ")"), actual);
}

[Test]
public void Correctly_parse_inequality_comparison()
{
Expression<Func<int, bool>> func = number => number != 5;
ExpressionInspector sut = new ExpressionInspector();
var actual = sut.Inspect(func);
Assert.AreEqual("number => (number != 5)", actual);
}

[Test]
public void Correctly_parse_relational_comparison()
{
Expression<Func<int, bool>> func = number => number < 5;
ExpressionInspector sut = new ExpressionInspector();
var actual = sut.Inspect(func);
Assert.AreEqual("number => (number < 5)", actual);
}

[Test]
public void Correctly_parse_expression_whose_source_text_contains_parentheses()
{
Expression<Func<PostViewModel, bool>> func = post => post.Title.Contains("");
ExpressionInspector sut = new ExpressionInspector();
var actual = sut.Inspect(func);
Assert.AreEqual("post => post.Title.Contains(\"\")", actual);
}

[Test]
public void Correctly_parse_null_coalescing_operator()
{
Expression<Func<string, bool>> func =
text => text == ("" ?? "a");
ExpressionInspector sut = new ExpressionInspector();
var actual = sut.Inspect(func);
Assert.AreEqual("text => (text == (\"\" ?? \"a\"))", actual);
}

[Test]
public void Correctly_parse_conditional_or_operator()
{
Expression<Func<string, bool>> func =
text => text == "any" || text.Length == 3;
ExpressionInspector sut = new ExpressionInspector();
var actual = sut.Inspect(func);
Assert.AreEqual("text => ((text == \"any\") || (text.Length == 3))", actual);
}

[Test]
public void Correctly_parse_two_conditional_or_operators()
{
Expression<Func<string, bool>> func =
text => text == "any" || text.Length == 3 || text.Length == 9;
ExpressionInspector sut = new ExpressionInspector();
var actual = sut.Inspect(func);
Assert.AreEqual(
"text => (((text == \"any\") || (text.Length == 3)) || (text.Length == 9))", actual);
}

[Test]
public void Correctly_parse_conditional_and_operator()
{
Expression<Func<string, bool>> func =
text => text == "any" && text.Length == 3;
ExpressionInspector sut = new ExpressionInspector();
var actual = sut.Inspect(func);
Assert.AreEqual("text => ((text == \"any\") && (text.Length == 3))", actual);
}

[Test]
public void Correctly_parse_logical_and_operator()
{
Expression<Func<string, bool>> func =
text => text == "any" & text.Length == 3;
ExpressionInspector sut = new ExpressionInspector();
var actual = sut.Inspect(func);
Assert.AreEqual("text => ((text == \"any\") & (text.Length == 3))", actual);
}

[Test]
public void Correctly_parse_logical_or_operator()
{
Expression<Func<string, bool>> func =
text => text == "any" | text.Length == 3;
ExpressionInspector sut = new ExpressionInspector();
var actual = sut.Inspect(func);
Assert.AreEqual("text => ((text == \"any\") | (text.Length == 3))", actual);
}

[Test]
public void Not_mistake_property_called_OrElse_for_conditional_or_operator()
{
Expression<Func<PostViewModel, bool>> func =
post => post.Title == "" || post.OrElse == "";
ExpressionInspector sut = new ExpressionInspector();
var actual = sut.Inspect(func);
Assert.AreEqual("post => ((post.Title == \"\") || (post.OrElse == \"\"))", actual);
}

[Test]
public void Correctly_parse_logical_xor_operator()
{
Expression<Func<string, bool>> func =
text => text == "any" ^ text.Length == 3;
ExpressionInspector sut = new ExpressionInspector();
var actual = sut.Inspect(func);
Assert.AreEqual("text => ((text == \"any\") ^ (text.Length == 3))", actual);
}
}

public class PostViewModel
{
public string Title { get; set; }
public string Slug { get; set; }

public string OrElse { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
<Compile Include="ControllerResultTestTests\ShouldReturnEmptyResultTests.cs" />
<Compile Include="ControllerResultTestTests\ShouldReturnJsonTests.cs" />
<Compile Include="ControllerResultTestTests\ShouldReturnContentTests.cs" />
<Compile Include="Internal\ExpressionInspectorTests.cs" />
<Compile Include="RouteValueDictionaryExtensionsTests.cs" />
<Compile Include="TempDataResultTest.cs" />
<Compile Include="TestControllers\AsyncController.cs" />
Expand Down
26 changes: 23 additions & 3 deletions TestStack.FluentMVCTesting.Tests/ViewResultTestTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Web.Mvc;
using System.Text.RegularExpressions;
using System.Web.Mvc;
using NUnit.Framework;

namespace TestStack.FluentMVCTesting.Tests
Expand Down Expand Up @@ -71,7 +72,26 @@ public void Check_for_invalid_model_using_predicate()
var exception = Assert.Throws<ViewResultModelAssertionException>(() =>
_viewResultTest.WithModel<TestViewModel>(m => m.Property1 == null)
);
Assert.That(exception.Message, Is.EqualTo("Expected view model to pass the given condition, but it failed."));
Assert.That(exception.Message, Is.EqualTo(string.Format("Expected view model {{\"Property1\":\"{0}\",\"Property2\":{1}}} to pass the given condition (m => (m.Property1 == null)), but it failed.", _model.Property1, _model.Property2)));
}

[Test]
public void Check_for_invalid_model_using_predicate_with_conditional_or()
{
var exception = Assert.Throws<ViewResultModelAssertionException>(() =>
_viewResultTest.WithModel<TestViewModel>(m => m.Property1 == null || m.Property2 == 1)
);
Assert.That(exception.Message, Is.EqualTo(string.Format("Expected view model {{\"Property1\":\"{0}\",\"Property2\":{1}}} to pass the given condition (m => ((m.Property1 == null) || (m.Property2 == 1))), but it failed.", _model.Property1, _model.Property2)));
}

[Test]
public void Check_for_invalid_model_using_predicate_with_primitive_operand()
{
_viewResult.ViewData.Model = "abc";
var exception = Assert.Throws<ViewResultModelAssertionException>(() =>
_viewResultTest.WithModel<string>(m => m == "ab")
);
Assert.That(exception.Message, Is.EqualTo(string.Format("Expected view model \"{0}\" to pass the given condition (m => (m == \"ab\")), but it failed.", _viewResult.ViewData.Model)));
}

[Test]
Expand All @@ -94,7 +114,7 @@ public void Run_any_assertions_on_the_model()
}
}

class InvalidViewModel {}
class InvalidViewModel { }
public class TestViewModel
{
public string Property1 { get; set; }
Expand Down
16 changes: 16 additions & 0 deletions TestStack.FluentMvcTesting/Internal/ExpressionInspector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Linq.Expressions;

namespace TestStack.FluentMVCTesting.Internal
{
internal class ExpressionInspector
{
internal string Inspect(LambdaExpression expression)
{
return expression.ToString()
.Replace(" OrElse ", " || ")
.Replace(" AndAlso ", " && ")
.Replace(" Or ", " | ")
.Replace(" And ", " & ");
}
}
}
3 changes: 3 additions & 0 deletions TestStack.FluentMvcTesting/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,6 @@
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: InternalsVisibleTo("TestStack.FluentMVCTesting.Tests")]
[assembly: InternalsVisibleTo("TestStack.FluentMVCTesting.Mvc3.Tests")]
[assembly: InternalsVisibleTo("TestStack.FluentMVCTesting.Mvc4.Tests")]
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
<Compile Include="ControllerResultTest\ShouldReturnContent.cs" />
<Compile Include="ControllerResultTest\ShouldReturnEmptyResult.cs" />
<Compile Include="ControllerResultTest\ShouldReturnJson.cs" />
<Compile Include="Internal\ExpressionInspector.cs" />
<Compile Include="RouteValueDictionaryExtension.cs" />
<Compile Include="ControllerExtensions.cs" />
<Compile Include="ControllerResultTest\ControllerResultTest.cs" />
Expand Down
19 changes: 16 additions & 3 deletions TestStack.FluentMvcTesting/ViewResultTest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
using System;
using System.Linq.Expressions;
using System.Text.RegularExpressions;
using System.Web.Helpers;
using System.Web.Mvc;
using TestStack.FluentMVCTesting.Internal;

namespace TestStack.FluentMVCTesting
{
Expand Down Expand Up @@ -37,13 +41,22 @@ public ModelTest<TModel> WithModel<TModel>(TModel expectedModel) where TModel :
return test;
}

public ModelTest<TModel> WithModel<TModel>(Func<TModel, bool> predicate) where TModel : class
public ModelTest<TModel> WithModel<TModel>(Expression<Func<TModel, bool>> predicate) where TModel : class
{
var test = WithModel<TModel>();

var model = _viewResult.Model as TModel;
if (!predicate(model))
throw new ViewResultModelAssertionException("Expected view model to pass the given condition, but it failed.");

var inspector = new ExpressionInspector();
var modelLex = Json.Encode(model);
var predicateLex = inspector.Inspect(predicate);
var compiledPredicate = predicate.Compile();

if (!compiledPredicate(model))
throw new ViewResultModelAssertionException(string.Format(
"Expected view model {0} to pass the given condition ({1}), but it failed.",
modelLex,
predicateLex));

return test;
}
Expand Down