Skip to content

Commit

Permalink
Test that MSBuild task provides enough CassetteSettings to enable CSS…
Browse files Browse the repository at this point in the history
… URL rewriting.
  • Loading branch information
andrewdavey committed Feb 3, 2012
1 parent 66f0c8f commit 4f8cba9
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 39 deletions.
95 changes: 61 additions & 34 deletions src/Cassette.IntegrationTests/MSBuild/CreateBundles.cs
@@ -1,32 +1,66 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text.RegularExpressions;
using Cassette.Configuration;
using Cassette.IntegrationTests;
using Cassette.Manifests;
using Cassette.Stylesheets;
using Should;
using Xunit;

namespace Cassette.MSBuild
{
public class CreateBundles_Tests
public class GivenConfigurationClassInAssembly_WhenExecute : IDisposable
{
readonly TempDirectory path;
readonly string manifestFilename;

public GivenConfigurationClassInAssembly_WhenExecute()
{
path = new TempDirectory();

var assemblyPath = Path.Combine(path, "Test.dll");
Configuration.GenerateAssembly(assemblyPath);

File.WriteAllText(Path.Combine(path, "test.css"), "p { background-image: url(test.png); }");
File.WriteAllText(Path.Combine(path, "test.png"), "");

using (var container = new AppDomainInstance<CreateBundles>())
{
var task = container.Value;
task.Assembly = assemblyPath;
manifestFilename = Path.Combine(path, "cassette.xml");
task.SourceDir = path;
task.Output = manifestFilename;
task.Execute();
}
}

[Fact]
public void ManifestFileSavedToOutput()
{
File.Exists(manifestFilename).ShouldBeTrue();
}

[Fact]
public void GivenConfigurationClassInAssembly_WhenExecute_ThenManifestFileSavedToOutput()
public void CssUrlIsRewrittenToBeApplicationRooted()
{
var bundles = LoadBundlesFromManifestFile();
var content = bundles.First().OpenStream().ReadToEnd();

Regex.IsMatch(content, @"url\(/_cassette/file/test_[a-z0-9]+\.png\)").ShouldBeTrue();
}

IEnumerable<Bundle> LoadBundlesFromManifestFile()
{
using (var path = new TempDirectory())
using (var file = File.OpenRead(manifestFilename))
{
var assemblyPath = Path.Combine(path, "Test.dll");
Configuration.GenerateAssembly(assemblyPath);

using (var container = new AppDomainInstance<CreateBundles>())
{
var task = container.Value;
task.Assembly = assemblyPath;
task.Output = Path.Combine(path, "cassette.xml");
task.Execute();
}

File.Exists(Path.Combine(path, "cassette.xml")).ShouldBeTrue();
var reader = new CassetteManifestReader(file);
return reader.Read().CreateBundles();
}
}

Expand All @@ -53,10 +87,11 @@ public void Dispose()
}
}

class Configuration : ICassetteConfiguration
public class Configuration : ICassetteConfiguration
{
public void Configure(BundleCollection bundles, CassetteSettings settings)
{
bundles.Add<StylesheetBundle>("~");
}

public static void GenerateAssembly(string fullAssemblyPath)
Expand All @@ -67,34 +102,26 @@ public static void GenerateAssembly(string fullAssemblyPath)

var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save);
var module = assembly.DefineDynamicModule(assemblyName.Name, filename);
GenerateConfigurationClass(module);
AddSubClassOfConfiguration(module);
assembly.Save(filename);

File.Copy(filename, fullAssemblyPath);
File.Delete(filename);

var parentAssembly = typeof(Configuration).Assembly.Location;
File.Copy(parentAssembly, Path.Combine(Path.GetDirectoryName(fullAssemblyPath), Path.GetFileName(parentAssembly)));
}

static void GenerateConfigurationClass(ModuleBuilder module)
static void AddSubClassOfConfiguration(ModuleBuilder module)
{
var type = module.DefineType("Configuration", TypeAttributes.Public);
type.AddInterfaceImplementation(typeof(ICassetteConfiguration));
GenerateConfigureMethod(type);
var type = module.DefineType("TestConfiguration", TypeAttributes.Public | TypeAttributes.Class, typeof(Configuration));
type.CreateType();
}
}

static void GenerateConfigureMethod(TypeBuilder type)
{
const string name = "Configure";
var method = type.DefineMethod(
name,
MethodAttributes.Public | MethodAttributes.Virtual,
null,
new[] { typeof(BundleCollection), typeof(CassetteSettings) }
);
var bytes = typeof(Configuration).GetMethod(name).GetMethodBody().GetILAsByteArray();
method.CreateMethodBody(bytes, bytes.Length);
type.DefineMethodOverride(method, typeof(ICassetteConfiguration).GetMethod(name));
}
public void Dispose()
{
path.Dispose();
}
}
}
8 changes: 6 additions & 2 deletions src/Cassette.MSBuild/CreateBundles.cs
@@ -1,4 +1,5 @@
using System.IO;
using Cassette.IO;
using Cassette.Manifests;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
Expand All @@ -13,6 +14,9 @@ public class CreateBundles : AppDomainIsolatedTask
[Required]
public string Assembly { get; set; }

[Required]
public string SourceDir { get; set; }

[Required]
public string Output { get; set; }

Expand All @@ -26,12 +30,12 @@ public override bool Execute()
return true;
}

CreateBundlesImplementation CreateTaskImplementation(FileStream outputStream)
CreateBundlesImplementation CreateTaskImplementation(Stream outputStream)
{
var assembly = System.Reflection.Assembly.LoadFrom(Assembly);
var configurationFactory = new AssemblyScanningCassetteConfigurationFactory(new[] { assembly });
var writer = new CassetteManifestWriter(outputStream);
return new CreateBundlesImplementation(configurationFactory, writer);
return new CreateBundlesImplementation(configurationFactory, writer, new FileSystemDirectory(SourceDir));
}
}
}
9 changes: 7 additions & 2 deletions src/Cassette.MSBuild/CreateBundlesImplementation.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using Cassette.Configuration;
using Cassette.IO;
using Cassette.Manifests;

namespace Cassette.MSBuild
Expand All @@ -12,11 +13,15 @@ class CreateBundlesImplementation
readonly BundleCollection bundles;
readonly IEnumerable<ICassetteConfiguration> configurations;

public CreateBundlesImplementation(ICassetteConfigurationFactory configurationFactory, ICassetteManifestWriter manifestWriter)
public CreateBundlesImplementation(ICassetteConfigurationFactory configurationFactory, ICassetteManifestWriter manifestWriter, IDirectory sourceDirectory)
{
this.manifestWriter = manifestWriter;
configurations = configurationFactory.CreateCassetteConfigurations();
settings = new CassetteSettings("");
settings = new CassetteSettings("")
{
SourceDirectory = sourceDirectory,
UrlModifier = new VirtualDirectoryPrepender("/")
};
bundles = new BundleCollection(settings);
}

Expand Down
22 changes: 21 additions & 1 deletion src/Cassette.UnitTests/MSBuild/CreateBundlesImplementation.cs
@@ -1,5 +1,6 @@
using System;
using Cassette.Configuration;
using Cassette.IO;
using Cassette.Manifests;
using Moq;
using Should;
Expand All @@ -14,6 +15,7 @@ public class CreateBundlesImplementation_Execute_Tests : IDisposable
readonly Mock<ICassetteManifestWriter> writer;
Bundle bundle;
CreateBundlesImplementation task;
IDirectory sourceDirectory;

public CreateBundlesImplementation_Execute_Tests()
{
Expand Down Expand Up @@ -64,10 +66,27 @@ public void GivenConfigurationAssignsUrlGenerator_ThenItShouldNotOverwriteUrlGen
configuration.SettingsPassedToConfigure.UrlGenerator.ShouldBeSameAs(customUrlGenerator);
}

[Fact]
public void ItAssignsSettingsUrlModifier()
{
SetupConfig();
task.Execute();
configuration.SettingsPassedToConfigure.UrlModifier.ShouldNotBeNull();
}

[Fact]
public void ItAssignsSettingsSourceDirectory()
{
SetupConfig();
task.Execute();
configuration.SettingsPassedToConfigure.SourceDirectory.ShouldBeSameAs(sourceDirectory);
}

void SetupConfig(Action<MockConfiguration> customize = null)
{
bundle = new TestableBundle("~");
configuration = new MockConfiguration(bundle);
sourceDirectory = Mock.Of<IDirectory>();

if (customize != null) customize(configuration);

Expand All @@ -78,7 +97,8 @@ void SetupConfig(Action<MockConfiguration> customize = null)

task = new CreateBundlesImplementation(
configurationFactory.Object,
writer.Object
writer.Object,
sourceDirectory
);
}

Expand Down

0 comments on commit 4f8cba9

Please sign in to comment.