Porting over unit tests for ViewDataDictionary.Eval

Partial fix for #453
This commit is contained in:
Pranav K 2014-10-17 15:30:19 -07:00
parent df8f84b772
commit bd82e584f0
4 changed files with 354 additions and 7 deletions

View File

@ -443,7 +443,7 @@ namespace Microsoft.AspNet.Mvc.Core
} }
/// <summary> /// <summary>
/// The value cannot be null or empty. /// Value cannot be null or empty.
/// </summary> /// </summary>
internal static string ArgumentCannotBeNullOrEmpty internal static string ArgumentCannotBeNullOrEmpty
{ {
@ -451,7 +451,7 @@ namespace Microsoft.AspNet.Mvc.Core
} }
/// <summary> /// <summary>
/// The value cannot be null or empty. /// Value cannot be null or empty.
/// </summary> /// </summary>
internal static string FormatArgumentCannotBeNullOrEmpty() internal static string FormatArgumentCannotBeNullOrEmpty()
{ {

View File

@ -199,7 +199,7 @@
<value>The action descriptor must be of type '{0}'.</value> <value>The action descriptor must be of type '{0}'.</value>
</data> </data>
<data name="ArgumentCannotBeNullOrEmpty" xml:space="preserve"> <data name="ArgumentCannotBeNullOrEmpty" xml:space="preserve">
<value>The value cannot be null or empty.</value> <value>Value cannot be null or empty.</value>
</data> </data>
<data name="PropertyOfTypeCannotBeNull" xml:space="preserve"> <data name="PropertyOfTypeCannotBeNull" xml:space="preserve">
<value>The '{0}' property of '{1}' must not be null.</value> <value>The '{0}' property of '{1}' must not be null.</value>

View File

@ -96,8 +96,8 @@ namespace Microsoft.AspNet.Mvc.Test
var controller = new Controller(); var controller = new Controller();
// Act & Assert // Act & Assert
ExceptionAssert.ThrowsArgument( ExceptionAssert.ThrowsArgumentNullOrEmpty(
() => controller.Redirect(url: url), "url", "The value cannot be null or empty"); () => controller.Redirect(url: url), "url");
} }
[Theory] [Theory]
@ -109,8 +109,8 @@ namespace Microsoft.AspNet.Mvc.Test
var controller = new Controller(); var controller = new Controller();
// Act & Assert // Act & Assert
ExceptionAssert.ThrowsArgument( ExceptionAssert.ThrowsArgumentNullOrEmpty(
() => controller.RedirectPermanent(url: url), "url", "The value cannot be null or empty"); () => controller.RedirectPermanent(url: url), "url");
} }
[Fact] [Fact]

View File

@ -2,7 +2,10 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Testing;
using Moq; using Moq;
using Xunit; using Xunit;
@ -156,6 +159,343 @@ namespace Microsoft.AspNet.Mvc.Core
Assert.IsType<CopyOnWriteDictionary<string, object>>(viewData.Data); Assert.IsType<CopyOnWriteDictionary<string, object>>(viewData.Data);
} }
public static TheoryData<object, string, object> Eval_EvaluatesExpressionsData
{
get
{
return new TheoryData<object, string, object>
{
{
new { Foo = "Bar" },
"Foo",
"Bar"
},
{
new { Foo = new Dictionary<string, object> { { "Bar", "Baz" } } },
"Foo.Bar",
"Baz"
},
{
new { Foo = new { Bar = "Baz" } },
"Foo.Bar",
"Baz"
}
};
}
}
[Theory]
[MemberData(nameof(Eval_EvaluatesExpressionsData))]
public void Eval_EvaluatesExpressions(object model, string expression, object expected)
{
// Arrange
var viewData = GetViewDataDictionary(model);
// Act
var result = viewData.Eval(expression);
// Assert
Assert.Equal(expected, result);
}
[Fact]
public void EvalReturnsNullIfExpressionDoesNotMatch()
{
// Arrange
var model = new { Foo = new { Biz = "Baz" } };
var viewData = GetViewDataDictionary(model);
// Act
var result = viewData.Eval("Foo.Bar");
// Assert
Assert.Null(result);
}
[Fact]
public void EvalEvaluatesDictionaryThenModel()
{
// Arrange
var model = new { Foo = "NotBar" };
var viewData = GetViewDataDictionary(model);
viewData.Add("Foo", "Bar");
// Act
var result = viewData.Eval("Foo");
// Assert
Assert.Equal("Bar", result);
}
[Fact]
public void EvalReturnsValueJustAdded()
{
// Arrange
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
viewData.Add("Foo", "Blah");
// Act
var result = viewData.Eval("Foo");
// Assert
Assert.Equal("Blah", result);
}
[Fact]
public void EvalWithCompoundExpressionReturnsIndexedValue()
{
// Arrange
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
viewData.Add("Foo.Bar", "Baz");
// Act
var result = viewData.Eval("Foo.Bar");
// Assert
Assert.Equal("Baz", result);
}
[Fact]
public void EvalWithCompoundExpressionReturnsPropertyOfAddedObject()
{
// Arrange
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
viewData.Add("Foo", new { Bar = "Baz" });
// Act
var result = viewData.Eval("Foo.Bar");
// Assert
Assert.Equal("Baz", result);
}
[Fact]
public void EvalWithCompoundIndexExpressionReturnsEval()
{
// Arrange
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
viewData.Add("Foo.Bar", new { Baz = "Quux" });
// Act
var result = viewData.Eval("Foo.Bar.Baz");
// Assert
Assert.Equal("Quux", result);
}
[Fact]
public void EvalWithCompoundIndexAndCompoundExpressionReturnsValue()
{
// Arrange
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
viewData.Add("Foo.Bar", new { Baz = new { Blah = "Quux" } });
// Act
var result = viewData.Eval("Foo.Bar.Baz.Blah");
// Assert
Assert.Equal("Quux", result);
}
// Make sure that dict["foo.bar"] gets chosen before dict["foo"]["bar"]
[Fact]
public void EvalChoosesValueInDictionaryOverOtherValue()
{
// Arrange
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider())
{
{ "Foo", new { Bar = "Not Baz" } },
{ "Foo.Bar", "Baz" }
};
// Act
var result = viewData.Eval("Foo.Bar");
// Assert
Assert.Equal("Baz", result);
}
// Make sure that dict["foo.bar"]["baz"] gets chosen before dict["foo"]["bar"]["baz"]
[Fact]
public void EvalChoosesCompoundValueInDictionaryOverOtherValues()
{
// Arrange
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider())
{
{ "Foo", new { Bar = new { Baz = "Not Quux" } } },
{ "Foo.Bar", new { Baz = "Quux" } }
};
// Act
var result = viewData.Eval("Foo.Bar.Baz");
// Assert
Assert.Equal("Quux", result);
}
// Make sure that dict["foo.bar"]["baz"] gets chosen before dict["foo"]["bar.baz"]
[Fact]
public void EvalChoosesCompoundValueInDictionaryOverOtherValuesWithCompoundProperty()
{
// Arrange
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider())
{
{ "Foo", new Person() },
{ "Foo.Bar", new { Baz = "Quux" } }
};
// Act
var result = viewData.Eval("Foo.Bar.Baz");
// Assert
Assert.Equal("Quux", result);
}
[Theory]
[InlineData(null)]
[InlineData("")]
public void EvalThrowsIfExpressionIsNullOrEmpty(string expression)
{
// Arrange
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
// Act & Assert
ExceptionAssert.ThrowsArgumentNullOrEmpty(() => viewData.Eval(expression), "expression");
}
[Fact]
public void EvalWithCompoundExpressionAndDictionarySubExpressionChoosesDictionaryValue()
{
// Arrange
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
viewData.Add("Foo", new Dictionary<string, object> { { "Bar", "Baz" } });
// Act
var result = viewData.Eval("Foo.Bar");
// Assert
Assert.Equal("Baz", result);
}
[Fact]
public void EvalWithDictionaryAndNoMatchReturnsNull()
{
// Arrange
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
viewData.Add("Foo", new Dictionary<string, object> { { "NotBar", "Baz" } });
// Act
var result = viewData.Eval("Foo.Bar");
// Assert
Assert.Null(result);
}
[Fact]
public void EvalWithNestedDictionariesEvalCorrectly()
{
// Arrange
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
viewData.Add("Foo", new Dictionary<string, object> { { "Bar", new Hashtable { { "Baz", "Quux" } } } });
// Act
var result = viewData.Eval("Foo.Bar.Baz");
// Assert
Assert.Equal("Quux", result);
}
[Fact]
public void EvalFormatWithNullValueReturnsEmptyString()
{
// Arrange
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
// Act
var formattedValue = viewData.Eval("foo", "for{0}mat");
// Assert
Assert.Empty(formattedValue);
}
[Fact]
public void EvalFormatWithEmptyFormatReturnsViewData()
{
// Arrange
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
viewData["foo"] = "value";
// Act
var formattedValue = viewData.Eval("foo", string.Empty);
// Assert
Assert.Equal("value", formattedValue);
}
[Fact]
public void EvalFormatWithFormatReturnsFormattedViewData()
{
// Arrange
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
viewData["foo"] = "value";
// Act
var formattedValue = viewData.Eval("foo", "for{0}mat");
// Assert
Assert.Equal("forvaluemat", formattedValue);
}
[Fact]
public void EvalPropertyNamedModel()
{
// Arrange
var model = new TheQueryStringParam
{
Name = "The Name",
Value = "The Value",
Model = "The Model",
};
var viewData = GetViewDataDictionary(model);
viewData["Title"] = "Home Page";
viewData["Message"] = "Welcome to ASP.NET MVC!";
// Act
var result = viewData.Eval("Model");
// Assert
Assert.Equal("The Model", result);
}
[Fact]
public void EvalSubPropertyNamedValueInModel()
{
// Arrange
var model = new TheQueryStringParam
{
Name = "The Name",
Value = "The Value",
Model = "The Model",
};
var viewData = GetViewDataDictionary(model);
viewData["Title"] = "Home Page";
viewData["Message"] = "Welcome to ASP.NET MVC!";
// Act
var result = viewData.Eval("Value");
// Assert
Assert.Equal("The Value", result);
}
private static ViewDataDictionary GetViewDataDictionary(object model)
{
return new ViewDataDictionary(new EmptyModelMetadataProvider())
{
Model = model
};
}
private class TestModel private class TestModel
{ {
} }
@ -178,5 +518,12 @@ namespace Microsoft.AspNet.Mvc.Core
SetModel(value); SetModel(value);
} }
} }
private class TheQueryStringParam
{
public string Name { get; set; }
public string Value { get; set; }
public string Model { get; set; }
}
} }
} }