Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Commit

Permalink
Add Encode() and Raw() overrides to IHtmlHelper<TModel>
Browse files Browse the repository at this point in the history
- #2392
- `dynamic` does not work correctly when inherited from a base `interface`
  • Loading branch information
dougbu committed Jun 17, 2015
1 parent 4fe3fba commit 8b5931d
Show file tree
Hide file tree
Showing 2 changed files with 250 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/Microsoft.AspNet.Mvc.Extensions/Rendering/IHtmlHelperOfT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,12 @@ HtmlString EditorFor<TResult>(
string htmlFieldName,
object additionalViewData);

/// <inheritdoc cref="IHtmlHelper.Encode(object)"/>
new string Encode(object value);

/// <inheritdoc cref="IHtmlHelper.Encode(string)"/>
new string Encode(string value);

/// <summary>
/// Returns an &lt;input&gt; element of type "hidden" for the specified <paramref name="expression"/>.
/// </summary>
Expand Down Expand Up @@ -333,6 +339,12 @@ HtmlString RadioButtonFor<TResult>(
[NotNull] object value,
object htmlAttributes);

/// <inheritdoc cref="IHtmlHelper.Raw(object)"/>
new HtmlString Raw(object value);

/// <inheritdoc cref="IHtmlHelper.Raw(string)"/>
new HtmlString Raw(string value);

/// <summary>
/// Returns a &lt;textarea&gt; element for the specified <paramref name="expression"/>.
/// </summary>
Expand Down
238 changes: 238 additions & 0 deletions test/Microsoft.AspNet.Mvc.Extensions.Test/Rendering/HtmlHelperTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,98 @@ public static TheoryData<object, KeyValuePair<string, object>> IgnoreCaseTestDat
}
}

// value, expectedString
public static TheoryData<object, string> EncodeDynamicTestData
{
get
{
var data = new TheoryData<object, string>
{
{ null, string.Empty },
// Dynamic implementation calls the string overload when possible.
{ string.Empty, string.Empty },
{ "<\">", "HtmlEncode[[<\">]]" },
{ "<br />", "HtmlEncode[[<br />]]" },
{ "<b>bold</b>", "HtmlEncode[[<b>bold</b>]]" },
{ new ObjectWithToStringOverride(), "HtmlEncode[[<b>boldFromObject</b>]]" },
};

return data;
}
}

// value, expectedString
public static TheoryData<object, string> EncodeObjectTestData
{
get
{
var data = new TheoryData<object, string>
{
{ null, string.Empty },
// Object overload does not special case the empty string.
{ string.Empty, "HtmlEncode[[]]" },
{ "<\">", "HtmlEncode[[<\">]]" },
{ "<br />", "HtmlEncode[[<br />]]" },
{ "<b>bold</b>", "HtmlEncode[[<b>bold</b>]]" },
{ new ObjectWithToStringOverride(), "HtmlEncode[[<b>boldFromObject</b>]]" },
};

return data;
}
}

// value, expectedString
public static TheoryData<string, string> EncodeStringTestData
{
get
{
return new TheoryData<string, string>
{
{ null, string.Empty },
// String overload does not encode the empty string.
{ string.Empty, string.Empty },
{ "<\">", "HtmlEncode[[<\">]]" },
{ "<br />", "HtmlEncode[[<br />]]" },
{ "<b>bold</b>", "HtmlEncode[[<b>bold</b>]]" },
};
}
}

// value, expectedString
public static TheoryData<object, string> RawObjectTestData
{
get
{
var data = new TheoryData<object, string>
{
{ new ObjectWithToStringOverride(), "<b>boldFromObject</b>" },
};

foreach (var item in RawStringTestData)
{
data.Add(item[0], (string)item[1]);
}

return data;
}
}

// value, expectedString
public static TheoryData<string, string> RawStringTestData
{
get
{
return new TheoryData<string, string>
{
{ null, null },
{ string.Empty, string.Empty },
{ "<\">", "<\">" },
{ "<br />", "<br />" },
{ "<b>bold</b>", "<b>bold</b>" },
};
}
}

[Theory]
[MemberData(nameof(IgnoreCaseTestData))]
public void AnonymousObjectToHtmlAttributes_IgnoresPropertyCase(object htmlAttributeObject,
Expand All @@ -54,5 +146,151 @@ public void AnonymousObjectToHtmlAttributes_IgnoresPropertyCase(object htmlAttri
var entry = Assert.Single(result);
Assert.Equal(expectedEntry, entry);
}

[Theory]
[MemberData(nameof(EncodeDynamicTestData))]
public void EncodeDynamic_ReturnsExpectedString(object value, string expectedString)
{
// Arrange
// Important to preserve these particular variable types. Otherwise may end up testing different runtime
// (not compiler) behaviors.
dynamic dynamicValue = value;
IHtmlHelper<DefaultTemplatesUtilities.ObjectTemplateModel> helper =
DefaultTemplatesUtilities.GetHtmlHelper();

// Act
var result = helper.Encode(dynamicValue);

// Assert
Assert.Equal(expectedString, result);
}

[Theory]
[MemberData(nameof(EncodeDynamicTestData))]
public void EncodeDynamic_ReturnsExpectedString_WithBaseHelper(object value, string expectedString)
{
// Arrange
// Important to preserve these particular variable types. Otherwise may end up testing different runtime
// (not compiler) behaviors.
dynamic dynamicValue = value;
IHtmlHelper helper = DefaultTemplatesUtilities.GetHtmlHelper();

// Act
var result = helper.Encode(dynamicValue);

// Assert
Assert.Equal(expectedString, result);
}

[Theory]
[MemberData(nameof(EncodeObjectTestData))]
public void EncodeObject_ReturnsExpectedString(object value, string expectedString)
{
// Arrange
// Important to preserve this particular variable type and the (object) type of the value parameter.
// Otherwise may end up testing different runtime (not compiler) behaviors.
IHtmlHelper<DefaultTemplatesUtilities.ObjectTemplateModel> helper =
DefaultTemplatesUtilities.GetHtmlHelper();

// Act
var result = helper.Encode(value);

// Assert
Assert.Equal(expectedString, result);
}

[Theory]
[MemberData(nameof(EncodeStringTestData))]
public void EncodeString_ReturnsExpectedString(string value, string expectedString)
{
// Arrange
// Important to preserve this particular variable type and the (string) type of the value parameter.
// Otherwise may end up testing different runtime (not compiler) behaviors.
IHtmlHelper<DefaultTemplatesUtilities.ObjectTemplateModel> helper =
DefaultTemplatesUtilities.GetHtmlHelper();

// Act
var result = helper.Encode(value);

// Assert
Assert.Equal(expectedString, result);
}

[Theory]
[MemberData(nameof(RawObjectTestData))]
public void RawDynamic_ReturnsExpectedString(object value, string expectedString)
{
// Arrange
// Important to preserve these particular variable types. Otherwise may end up testing different runtime
// (not compiler) behaviors.
dynamic dynamicValue = value;
IHtmlHelper<DefaultTemplatesUtilities.ObjectTemplateModel> helper =
DefaultTemplatesUtilities.GetHtmlHelper();

// Act
var result = helper.Raw(dynamicValue);

// Assert
Assert.Equal(expectedString, result.ToString());
}

[Theory]
[MemberData(nameof(RawObjectTestData))]
public void RawDynamic_ReturnsExpectedString_WithBaseHelper(object value, string expectedString)
{
// Arrange
// Important to preserve these particular variable types. Otherwise may end up testing different runtime
// (not compiler) behaviors.
dynamic dynamicValue = value;
IHtmlHelper helper = DefaultTemplatesUtilities.GetHtmlHelper();

// Act
var result = helper.Raw(dynamicValue);

// Assert
Assert.Equal(expectedString, result.ToString());
}

[Theory]
[MemberData(nameof(RawObjectTestData))]
public void RawObject_ReturnsExpectedString(object value, string expectedString)
{
// Arrange
// Important to preserve this particular variable type and the (object) type of the value parameter.
// Otherwise may end up testing different runtime (not compiler) behaviors.
IHtmlHelper<DefaultTemplatesUtilities.ObjectTemplateModel> helper =
DefaultTemplatesUtilities.GetHtmlHelper();

// Act
var result = helper.Raw(value);

// Assert
Assert.Equal(expectedString, result.ToString());
}

[Theory]
[MemberData(nameof(RawStringTestData))]
public void RawString_ReturnsExpectedString(string value, string expectedString)
{
// Arrange
// Important to preserve this particular variable type and the (string) type of the value parameter.
// Otherwise may end up testing different runtime (not compiler) behaviors.
IHtmlHelper<DefaultTemplatesUtilities.ObjectTemplateModel> helper =
DefaultTemplatesUtilities.GetHtmlHelper();

// Act
var result = helper.Raw(value);

// Assert
Assert.Equal(expectedString, result.ToString());
}

private class ObjectWithToStringOverride
{
public override string ToString()
{
return "<b>boldFromObject</b>";
}
}
}
}

0 comments on commit 8b5931d

Please sign in to comment.