Porting over unit tests for ViewDataDictionary.Eval
Partial fix for #453
This commit is contained in:
parent
df8f84b772
commit
bd82e584f0
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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]
|
||||||
|
|
|
||||||
|
|
@ -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; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue