Skip to content

Implemented ShouldRenderFileStream. #30

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
Sep 4, 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
44 changes: 44 additions & 0 deletions BREAKING_CHANGES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Version 2.0.0

## ShouldRenderFileStream Method

The following overload of the `ShouldRenderFileStream` method has been *replaced*:

public FileStreamResult ShouldRenderFileStream(string contentType = null)

We place emphasis on the word "replace" because it is important to note that this overload has not been removed but replaced - you will not encounter a compile-time error if you upgrade, but you will encounter a logical error when you run your existing test.

### Reason

The aforementioned overload has been replaced in order to enable an overload that takes a stream for comparison in a way that is consistent with the existing convention.

### Fix

Use a [named argument](http://msdn.microsoft.com/en-gb/library/dd264739.aspx).

As where you would have previously done this:

ShouldRenderFileStream("application/json");

You must now do this:

ShouldRenderFileStream(contentType: "application/json");


## ShouldRenderFileMethod

The `ShouldRenderFile` method has been removed.

### Reason

The `ShouldRenderFile` method was ambiguous because it had the possibility to be interperted to test for a `FileResult` when in fact, it tested for a `FileContentResult`.

It is for this reason that we introduced two unequivocal methods namely, `ShouldRenderAnyFile` and `ShouldRenderFileContents`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Might be worth mentioning the other ShouldRenferFile* methods here for completeness.


### Fix

Use the `ShouldRenderFileContents` method instead:

ShouldRenderAnyFile()
ShouldRenderAnyFile(contentType: "application/json")

2 changes: 1 addition & 1 deletion NextVersion.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.1.0
2.0.0
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is my first time practicing Semantic Versioning.

If I understood correctly, a breaking change (see BREAKING_CHANGES.MD) no matter how small should result in the major version being bumped and a major version bump results in the minor and patch versions being reset to 0.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct :)

While we are at it let's delete that method we marked [Obsolete] at the same time, also while we are at it can you put the release notes to mention the breaking changes file like I did in Seleno:

Also, we should have a think if there are any other breaking changes we want to make so they can all be made at once.

Also, having a readme.txt file in the root package will pop it open - we can include mention of the breaking changes file and other files like I've done in ChameleonForms:

Let me know if this doesn't make sense and I'll try and explain better :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While we are at it let's delete that method we marked [Obsolete] at the same time

That is some good thinking man.

Also, having a readme.txt file in the root package will pop it open - we can include mention of the breaking changes file and other files like I've done in ChameleonForms:

So I added a readme.txt to the package root but I have some questions:

  • Should I link the readme.txt between both projects?
  • Could you please direct me on the exact path to use in the NuSpec? Looks like <file src="readme.txt" target="" /> is correct but I am not sure.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd link it between the projects yeah, let me know when it's pushed and I'll check it.

Pretty sure what you have above is right. You can download nuget.exe and run nuget pack on the nuspec to check it (make sure you've done a release build), just open up the .nupkg file it generates in your zip viewer of choice (I use 7zip) and check readme.txt is in the root of the package..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the tip.

I think I confirmed that the aforementioned path: <file src="readme.txt" target="" /> works, but only for the normal project.

In hindsight that path clearly won't work for the Mvc3 project because linked files are not copied to the physical directory.

We could use MSBuild to change that I guess?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try <file src="../FluentMvcTesting/readme.txt" target="" />

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is not quite correct but I think I got it.

Check out the latest push, I think are good now.

Let me know.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep looks good!

Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="FluentMVCTesting.Mvc3.nuspec" />
<None Include="packages.config" />
<None Include="TestStack.FluentMVCTesting.Mvc3.nuspec" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI These changes were a good candidate for a separate PR since it's a separate logical change and could be merged in a lot quicker since it's such a simple change. No big deal though - it's already in here, just good food for thought :) by the way - if you get a spare moment at some point feel free to check out my presentation about pull requests: https://github.com/robdmoore/PushBetterSoftwareWithPullRequestsPresentation

It's focussed on commercial development, but there are still some good general tips in there :)

</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Expand All @@ -105,4 +105,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
<dependencies>
<dependency id="Microsoft.AspNet.Mvc" version="3.0" />
</dependencies>
<releaseNotes>
For breaking changes from previous versions see
https://github.com/TestStack/TestStack.FluentMVCTesting/blob/master/BREAKING_CHANGES.md
</releaseNotes>
<frameworkAssemblies>
<frameworkAssembly assemblyName="System.Web" targetFramework="net40" />
</frameworkAssemblies>
Expand All @@ -40,5 +44,6 @@
<file src="bin\Release\TestStack.FluentMVCTesting.Mvc3.dll" target="lib\NET40" />
<file src="bin\Release\TestStack.FluentMVCTesting.Mvc3.pdb" target="lib\NET40" />
<file src="..\TestStack.FluentMvcTesting\**\*.cs" exclude="..\TestStack.FluentMvcTesting\obj\**\*.*" target="src" />
<file src="..\TestStack.FluentMvcTesting\readme.txt" target="" />
</files>
</package>
221 changes: 200 additions & 21 deletions TestStack.FluentMVCTesting.Tests/ControllerResultTestTests.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ class ControllerResultTestController : Controller
public const string JsonValue = "json";
public const string FileName = "NamedFile";
public static byte[] BinaryFileContents = { 1 };
public static string TextualFileContents = "textual content";
public static string TextualFileContent = "textual content";
public static byte[] EmptyFileBuffer = { };
public static readonly Stream EmptyStreamContents = new MemoryStream(EmptyFileBuffer);
public static readonly Stream BinaryStreamContents = new MemoryStream(BinaryFileContents);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not really too concerned about this anymore, but I did notice that because these types have internal state (unlike constant primitive types) they can cause test pollution.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what you mean by test pollution in this case?


#endregion

#region Empty, Null and Random Results
Expand Down Expand Up @@ -174,14 +178,30 @@ public ActionResult TextualFile()

public ActionResult TextualFile(Encoding encoding)
{
var encodedContents = encoding.GetBytes(TextualFileContents);
var encodedContents = encoding.GetBytes(TextualFileContent);
return File(encodedContents, FileContentType);
}

public ActionResult EmptyStream()
{
var content = new MemoryStream();
return File(content, FileContentType);
return File(EmptyStreamContents, FileContentType);
}

public ActionResult BinaryStream()
{
return File(BinaryStreamContents, FileContentType);
}

public ActionResult TextualStream()
{
return TextualStream(Encoding.UTF8);
}

public ActionResult TextualStream(Encoding encoding)
{
var encondedContent = encoding.GetBytes(TextualFileContent);
var stream = new MemoryStream(encondedContent);
return File(stream, FileContentType);
}

public ActionResult EmptyFilePath()
Expand Down
4 changes: 3 additions & 1 deletion TestStack.FluentMVCTesting.sln
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
# Visual Studio 2013
VisualStudioVersion = 12.0.30501.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestStack.FluentMVCTesting", "TestStack.FluentMVCTesting\TestStack.FluentMVCTesting.csproj", "{152CA00F-18D3-4CF5-8CA0-2C5B70CBEA19}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestStack.FluentMVCTesting.Tests", "TestStack.FluentMVCTesting.Tests\TestStack.FluentMVCTesting.Tests.csproj", "{4DCC907C-A08A-4139-BB6B-2D34B21F318B}"
Expand Down
102 changes: 67 additions & 35 deletions TestStack.FluentMvcTesting/ControllerResultTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
Expand Down Expand Up @@ -216,30 +217,42 @@ public ViewResultTest ShouldRenderDefaultPartialView()

#region File Results

public FileResult ShouldRenderAnyFile(string contentType = null)
private static void EnsureContentTypeIsSame(string actual, string expected)
{
ValidateActionReturnType<FileResult>();

var fileResult = (FileResult)_actionResult;
if (expected == null) return;
if (actual != expected)
{
throw new ActionResultAssertionException(string.Format(
"Expected file to be of content type '{0}', but instead was given '{1}'.", expected, actual));
}
}

if (contentType != null && fileResult.ContentType != contentType)
private static byte[] ConvertStreamToArray(Stream stream)
{
using (var memoryStream = new MemoryStream())
{
throw new ActionResultAssertionException(string.Format("Expected file to be of content type '{0}', but instead was given '{1}'.", contentType, fileResult.ContentType));
stream.CopyTo(memoryStream);
stream.Position = 0;
return memoryStream.ToArray();
}
}

public FileResult ShouldRenderAnyFile(string contentType = null)
{
ValidateActionReturnType<FileResult>();
var fileResult = (FileResult)_actionResult;

EnsureContentTypeIsSame(fileResult.ContentType, contentType);

return fileResult;
}

public FileContentResult ShouldRenderFileContents(byte[] contents = null, string contentType = null)
{
ValidateActionReturnType<FileContentResult>();

var fileResult = (FileContentResult) _actionResult;

if (contentType != null && fileResult.ContentType != contentType)
{
throw new ActionResultAssertionException(string.Format("Expected file to be of content type '{0}', but instead was given '{1}'.", contentType, fileResult.ContentType));
}
EnsureContentTypeIsSame(fileResult.ContentType, contentType);

if (contents != null && !fileResult.FileContents.SequenceEqual(contents))
{
Expand All @@ -255,52 +268,72 @@ public FileContentResult ShouldRenderFileContents(byte[] contents = null, string
public FileContentResult ShouldRenderFileContents(string contents, string contentType = null, Encoding encoding = null)
{
ValidateActionReturnType<FileContentResult>();

var fileResult = (FileContentResult)_actionResult;

if (contentType != null && fileResult.ContentType != contentType)
{
throw new ActionResultAssertionException(
string.Format("Expected file to be of content type '{0}', but instead was given '{1}'.", contentType,
fileResult.ContentType));
}
EnsureContentTypeIsSame(fileResult.ContentType, contentType);

if (encoding == null)
encoding = Encoding.UTF8;

var reconstitutedText = encoding.GetString(fileResult.FileContents);
if (contents != reconstitutedText)
{
throw new ActionResultAssertionException(string.Format("Expected file contents to be \"{0}\", but instead was \"{1}\".", contents, reconstitutedText));
throw new ActionResultAssertionException(string.Format(
"Expected file contents to be \"{0}\", but instead was \"{1}\".",
contents,
reconstitutedText));
}

return fileResult;
}

[Obsolete("Obsolete: Use ShouldRenderFileContents instead.")]
public FileContentResult ShouldRenderFile(string contentType = null)
public FileStreamResult ShouldRenderFileStream(byte[] content, string contentType = null)
{
ValidateActionReturnType<FileContentResult>();
var reconstitutedStream = new MemoryStream(content);
return ShouldRenderFileStream(reconstitutedStream, contentType);
}

var fileResult = (FileContentResult)_actionResult;
public FileStreamResult ShouldRenderFileStream(Stream stream = null, string contentType = null)
{
ValidateActionReturnType<FileStreamResult>();
var fileResult = (FileStreamResult)_actionResult;

EnsureContentTypeIsSame(fileResult.ContentType, contentType);

if (contentType != null && fileResult.ContentType != contentType)
if (stream != null)
{
throw new ActionResultAssertionException(string.Format("Expected file to be of content type '{0}', but instead was given '{1}'.", contentType, fileResult.ContentType));
byte[] expected = ConvertStreamToArray(stream);
byte[] actual = ConvertStreamToArray(fileResult.FileStream);

if (!expected.SequenceEqual(actual))
{
throw new ActionResultAssertionException(string.Format(
"Expected file contents to be equal to [{0}], but instead was given [{1}].",
string.Join(", ", expected),
string.Join(", ", actual)));
}
}

return fileResult;
}

public FileStreamResult ShouldRenderFileStream(string contentType = null)
public FileStreamResult ShouldRenderFileStream(string contents, string contentType = null, Encoding encoding = null)
{
ValidateActionReturnType<FileStreamResult>();

var fileResult = (FileStreamResult)_actionResult;

if (contentType != null && fileResult.ContentType != contentType)
EnsureContentTypeIsSame(fileResult.ContentType, contentType);

if (encoding == null)
encoding = Encoding.UTF8;

var reconstitutedText = encoding.GetString(ConvertStreamToArray(fileResult.FileStream));
if (contents != reconstitutedText)
{
throw new ActionResultAssertionException(string.Format("Expected file to be of content type '{0}', but instead was given '{1}'.", contentType, fileResult.ContentType));
throw new ActionResultAssertionException(string.Format(
"Expected file contents to be \"{0}\", but instead was \"{1}\".",
contents,
reconstitutedText));
}

return fileResult;
Expand All @@ -309,17 +342,16 @@ public FileStreamResult ShouldRenderFileStream(string contentType = null)
public FilePathResult ShouldRenderFilePath(string fileName = null, string contentType = null)
{
ValidateActionReturnType<FilePathResult>();

var fileResult = (FilePathResult)_actionResult;

if (contentType != null && fileResult.ContentType != contentType)
{
throw new ActionResultAssertionException(string.Format("Expected file to be of content type '{0}', but instead was given '{1}'.", contentType, fileResult.ContentType));
}
EnsureContentTypeIsSame(fileResult.ContentType, contentType);

if (fileName != null && fileName != fileResult.FileName)
{
throw new ActionResultAssertionException(string.Format("Expected file name to be '{0}', but instead was given '{1}'.", fileName, fileResult.FileName));
throw new ActionResultAssertionException(string.Format(
"Expected file name to be '{0}', but instead was given '{1}'.",
fileName,
fileResult.FileName));
}

return fileResult;
Expand Down
7 changes: 5 additions & 2 deletions TestStack.FluentMvcTesting/TestStack.FluentMVCTesting.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,11 @@
<Compile Include="ViewResultTest.cs" />
</ItemGroup>
<ItemGroup>
<None Include="FluentMVCTesting.nuspec" />
<None Include="packages.config" />
<None Include="TestStack.FluentMVCTesting.nuspec" />
</ItemGroup>
<ItemGroup>
<Content Include="readme.txt" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Expand All @@ -94,4 +97,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
5 changes: 5 additions & 0 deletions TestStack.FluentMvcTesting/TestStack.FluentMVCTesting.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
<dependencies>
<dependency id="Microsoft.AspNet.Mvc" version="4.0" />
</dependencies>
<releaseNotes>
For breaking changes from previous versions see
https://github.com/TestStack/TestStack.FluentMVCTesting/blob/master/BREAKING_CHANGES.md
</releaseNotes>
<frameworkAssemblies>
<frameworkAssembly assemblyName="System.Web" targetFramework="net40" />
</frameworkAssemblies>
Expand All @@ -40,5 +44,6 @@
<file src="bin\Release\TestStack.FluentMVCTesting.dll" target="lib\NET40" />
<file src="bin\Release\TestStack.FluentMVCTesting.pdb" target="lib\NET40" />
<file src="**\*.cs" exclude="obj\**\*.*" target="src" />
<file src="readme.txt" target="" />
</files>
</package>
6 changes: 6 additions & 0 deletions TestStack.FluentMvcTesting/readme.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FluentMVCTesting
==============

* For the project homepage including the current README, see https://github.com/TestStack/TestStack.FluentMVCTesting
* To check for potential breaking changes in this release, see https://github.com/TestStack/TestStack.FluentMVCTesting/blob/master/BREAKING_CHANGES.md
* If you need to raise an issue or check for an existing issue, see https://github.com/TestStack/TestStack.FluentMVCTesting/issues