Skip to content

Commit ca40a1b

Browse files
committed
migrated the Project file base conventions
They are pretty nasty to look at, since we're pretty much dealing with raw XML of the .csproj. We probably want to build some sort of abstraction over that (or use the existing one from Microsoft.MsBuild.something.dll
1 parent 3ba784c commit ca40a1b

File tree

6 files changed

+75
-141
lines changed

6 files changed

+75
-141
lines changed
Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
namespace TestStack.ConventionTests.Tests
22
{
33
using System.Xml.Linq;
4-
using ApprovalTests;
54
using ApprovalTests.Reporters;
65
using NSubstitute;
76
using NUnit.Framework;
@@ -10,49 +9,42 @@
109
using TestStack.ConventionTests.Tests.Properties;
1110

1211
[TestFixture]
13-
[UseReporter(typeof(DiffReporter))]
12+
[UseReporter(typeof (DiffReporter))]
1413
public class ProjectBasedConventions
1514
{
15+
public ProjectBasedConventions()
16+
{
17+
Convention.Settings.AssertInclunclusive = Assert.Inconclusive;
18+
Convention.Settings.AssertZero = (v, m) => Assert.AreEqual(0, v, m);
19+
}
20+
1621
[Test]
1722
public void ReferencingBinObj()
1823
{
19-
// Actual syntax will be (when not testing):
20-
//
21-
// Convention.Is<ProjectDoesNotReferenceDllsFromBinOrObjDirectories>(new[] { typeof(ProjectBasedConventions).Assembly });
22-
//
23-
2424
var projectProvider = Substitute.For<IProjectProvider>();
2525
var projectLocator = Substitute.For<IProjectLocator>();
2626
projectProvider
2727
.LoadProjectDocument(Arg.Any<string>())
2828
.Returns(XDocument.Parse(Resources.ProjectFileWithBinReference));
2929

30-
var convention = new ProjectDoesNotReferenceDllsFromBinOrObjDirectories(projectLocator, projectProvider);
31-
32-
var exception = Assert.Throws<ConventionFailedException>(() =>
33-
Convention.Is(convention, new[] { typeof(ProjectBasedConventions).Assembly }));
34-
Approvals.Verify(exception.Message);
30+
Convention.Is(new ProjectDoesNotReferenceDllsFromBinOrObjDirectories(),
31+
new Project(typeof (ProjectBasedConventions).Assembly, projectProvider, projectLocator));
3532
}
36-
33+
3734
[Test]
3835
public void ScriptsNotEmbeddedResources()
3936
{
40-
// Actual syntax will be (when not testing):
41-
//
42-
// Convention.Is<FilesAreEmbeddedResources>(new[] { typeof(ProjectBasedConventions).Assembly }, i => i.EndsWith(".sql"));
43-
//
44-
4537
var projectProvider = Substitute.For<IProjectProvider>();
4638
var projectLocator = Substitute.For<IProjectLocator>();
4739
projectProvider
4840
.LoadProjectDocument(Arg.Any<string>())
4941
.Returns(XDocument.Parse(Resources.ProjectFileWithInvalidSqlScriptFile));
5042

51-
var convention = new FilesAreEmbeddedResources(projectLocator, projectProvider);
52-
53-
var exception = Assert.Throws<ConventionFailedException>(() =>
54-
Convention.Is(convention, new[] { typeof(ProjectBasedConventions).Assembly }, i => i.EndsWith(".sql")));
55-
Approvals.Verify(exception.Message);
43+
Convention.Is(new FilesAreEmbeddedResources(),
44+
new Project(typeof (ProjectBasedConventions).Assembly, projectProvider, projectLocator)
45+
{
46+
Includes = i => i.EndsWith(".sql")
47+
});
5648
}
5749
}
5850
}

TestStack.ConventionTests/Convention.cs

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -34,48 +34,6 @@ public static void Is<TData>(IConvention<TData> convention, TData data) where TD
3434
Settings.AssertZero(result.InvalidResultsCount, result.Message);
3535
}
3636

37-
public static void Is<T, T2>(IEnumerable<T2> itemsToVerify) where T : ConventionData<T2>, new()
38-
{
39-
Is(new T(), itemsToVerify);
40-
}
41-
public static void Is<T, T2>(IEnumerable<T2> itemsToVerify, Func<string, bool> filter)
42-
where T : ConventionData<T2>, IRuntimeFilter<string>, new()
43-
{
44-
Is(new T(), itemsToVerify);
45-
}
46-
public static void Is<T, T2, TItem>(IEnumerable<T2> itemsToVerify, Func<TItem, bool> filter)
47-
where T : ConventionData<T2>, IRuntimeFilter<TItem>, new()
48-
{
49-
Is(new T(), itemsToVerify);
50-
}
51-
52-
//Item.Is<ConventionData<Type>>
53-
public static void Is<T>(IEnumerable<Type> itemsToVerify) where T : ConventionData<Type>, new()
54-
{
55-
Is(new T(), itemsToVerify);
56-
}
57-
public static void Is<T>(IEnumerable<Type> itemsToVerify, Func<string, bool> filter) where T : ConventionData<Type>, IRuntimeFilter<string>, new()
58-
{
59-
Is(new T(), itemsToVerify, filter);
60-
}
61-
public static void Is<T, TItem>(IEnumerable<Type> itemsToVerify, Func<TItem, bool> filter) where T : ConventionData<Type>, IRuntimeFilter<TItem>, new()
62-
{
63-
Is(new T(), itemsToVerify, filter);
64-
}
65-
66-
//Item.Is<ConventionData<Assembly>>
67-
public static void Is<T>(IEnumerable<Assembly> itemsToVerify) where T : ConventionData<Assembly>, new()
68-
{
69-
Is(new T(), itemsToVerify);
70-
}
71-
public static void Is<T>(IEnumerable<Assembly> itemsToVerify, Func<string, bool> filter) where T : ConventionData<Assembly>, IRuntimeFilter<string>, new()
72-
{
73-
Is(new T(), itemsToVerify, filter);
74-
}
75-
public static void Is<T, TItem>(IEnumerable<Assembly> itemsToVerify, Func<TItem, bool> filter) where T : ConventionData<Assembly>, IRuntimeFilter<TItem>, new()
76-
{
77-
Is(new T(), itemsToVerify, filter);
78-
}
7937

8038
public static void Is<T>(ConventionData<T> convention, IEnumerable<T> itemsToVerify)
8139
{

TestStack.ConventionTests/Conventions/FilesAreEmbeddedResources.cs

Lines changed: 12 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,66 +3,33 @@
33
using System;
44
using System.Collections.Generic;
55
using System.Linq;
6-
using System.Reflection;
76
using System.Xml.Linq;
8-
using TestStack.ConventionTests.Helpers;
7+
using TestStack.ConventionTests.Internal;
98

10-
public class FilesAreEmbeddedResources : ConventionData<Assembly>, IRuntimeFilter<string>
9+
public class FilesAreEmbeddedResources : IConvention<Project>
1110
{
12-
readonly IProjectLocator projectLocator;
13-
readonly IProjectProvider projectProvider;
14-
Func<string, bool> itemFilter;
15-
16-
public FilesAreEmbeddedResources() : this(new AssemblyProjectLocator(), new ProjectProvider()) { }
17-
public FilesAreEmbeddedResources(IProjectLocator projectLocator, IProjectProvider projectProvider)
11+
public ConventionResult Execute(Project data)
1812
{
19-
this.projectLocator = projectLocator;
20-
this.projectProvider = projectProvider;
21-
22-
Must = assembly =>
23-
{
24-
var references = GetProjectFiles(assembly);
25-
26-
return references.All(s => s.Item1 == "EmbeddedResource");
27-
};
28-
ItemDescription = (assembly, builder) =>
29-
{
30-
var filesNotEmbedded = GetProjectFiles(assembly)
31-
.Where(r => r.Item1 != "EmbeddedResource");
32-
33-
34-
builder.AppendLine(string.Format("{0} has the following files which should be embedded resources:",
35-
assembly.GetName().Name));
36-
foreach (var error in filesNotEmbedded.Select(m => m.Item2 + " which currently has a build action of '" + m.Item1 + "'"))
37-
{
38-
builder.Append('\t');
39-
builder.AppendLine(error);
40-
}
41-
};
13+
return ConventionResult.For(GetProjectFiles(data).Where(s => s.Item1 != "EmbeddedResource"),
14+
"The following files which should be embedded resources:",
15+
(t, m) => m.AppendLine("\t" + t.Item2));
4216
}
4317

44-
IEnumerable<Tuple<string, string>> GetProjectFiles(Assembly assembly)
18+
IEnumerable<Tuple<string, string>> GetProjectFiles(Project project)
4519
{
46-
//TODO Not sure about filters, we can interate on this...
47-
if (itemFilter == null)
48-
throw new InvalidOperationException("This convention requires you to provide a filter, which is an overload on Convention.Is");
49-
20+
if (project.Includes == null)
21+
throw new InvalidOperationException(
22+
"This convention requires you to provide a filter on the convention data");
5023
const string msbuild = "http://schemas.microsoft.com/developer/msbuild/2003";
51-
var resolveProjectFilePath = projectLocator.ResolveProjectFilePath(assembly);
52-
XDocument projDefinition = projectProvider.LoadProjectDocument(resolveProjectFilePath);
24+
var projDefinition = project.GetProject();
5325
var references = projDefinition
5426
.Element(XName.Get("Project", msbuild))
5527
.Elements(XName.Get("ItemGroup", msbuild))
5628
.Elements()
5729
.Select(refElem => Tuple.Create(refElem.Name.LocalName, refElem.Attribute("Include").Value))
58-
.Where(i => itemFilter(i.Item2));
30+
.Where(i => project.Includes(i.Item2));
5931

6032
return references;
6133
}
62-
63-
public void SetFilter(Func<string, bool> filter)
64-
{
65-
itemFilter = filter;
66-
}
6734
}
6835
}

TestStack.ConventionTests/Conventions/ProjectDoesNotReferenceDllsFromBinOrObjDirectories.cs

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,30 @@
22
{
33
using System.Collections.Generic;
44
using System.Linq;
5-
using System.Reflection;
65
using System.Text.RegularExpressions;
76
using System.Xml.Linq;
8-
using TestStack.ConventionTests.Helpers;
7+
using TestStack.ConventionTests.Internal;
98

10-
public class ProjectDoesNotReferenceDllsFromBinOrObjDirectories : ConventionData<Assembly>
9+
public class ProjectDoesNotReferenceDllsFromBinOrObjDirectories : IConvention<Project>
1110
{
1211
const string AssemblyReferencingObjRegex = @"^(?<assembly>.*?(obj|bin).*?)$";
1312

14-
public ProjectDoesNotReferenceDllsFromBinOrObjDirectories()
15-
: this(new AssemblyProjectLocator(), new ProjectProvider())
13+
public ConventionResult Execute(Project data)
1614
{
15+
var invalid = AllProjectReferences(data.GetProject()).Where(IsBinOrObjReference);
16+
return ConventionResult.For(invalid, "Some invalid references found.", (r, m) => m.AppendLine("\t" + r));
1717
}
1818

19-
public ProjectDoesNotReferenceDllsFromBinOrObjDirectories(IProjectLocator projectLocator, IProjectProvider projectProvider)
20-
{
21-
Must = assembly =>
22-
{
23-
var references = GetProjectReferences(projectLocator, projectProvider, assembly);
24-
25-
return references.All(s => !Regex.IsMatch(s, AssemblyReferencingObjRegex, RegexOptions.IgnoreCase));
26-
};
27-
ItemDescription = (assembly, builder) =>
28-
{
29-
var matches = GetProjectReferences(projectLocator, projectProvider, assembly)
30-
.Select(r => Regex.Match(r, AssemblyReferencingObjRegex, RegexOptions.IgnoreCase))
31-
.Where(r => r.Success);
3219

33-
builder.AppendLine(string.Format("{0} is referencing assemblies in the bin or obj folders:",
34-
assembly.GetName().Name));
35-
foreach (var match in matches.Select(m=>m.Groups["assembly"].Value))
36-
{
37-
builder.Append('\t');
38-
builder.AppendLine(match);
39-
}
40-
};
20+
static bool IsBinOrObjReference(string reference)
21+
{
22+
return Regex.IsMatch(reference, AssemblyReferencingObjRegex, RegexOptions.IgnoreCase);
4123
}
4224

43-
static IEnumerable<string> GetProjectReferences(IProjectLocator projectLocator, IProjectProvider projectProvider,
44-
Assembly assembly)
25+
static IEnumerable<string> AllProjectReferences(XDocument projDefinition)
4526
{
4627
XNamespace msbuild = "http://schemas.microsoft.com/developer/msbuild/2003";
47-
var resolveProjectFilePath = projectLocator.ResolveProjectFilePath(assembly);
48-
XDocument projDefinition = projectProvider.LoadProjectDocument(resolveProjectFilePath);
49-
IEnumerable<string> references = projDefinition
28+
var references = projDefinition
5029
.Element(msbuild + "Project")
5130
.Elements(msbuild + "ItemGroup")
5231
.Elements(msbuild + "Reference")
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
namespace TestStack.ConventionTests
2+
{
3+
using System;
4+
using System.Reflection;
5+
using System.Xml.Linq;
6+
using TestStack.ConventionTests.Helpers;
7+
8+
public class Project : IConventionData
9+
{
10+
readonly Assembly assembly;
11+
readonly IProjectLocator projectLocator;
12+
readonly IProjectProvider projectProvider;
13+
14+
public Project(Assembly assembly, IProjectProvider projectProvider, IProjectLocator projectLocator)
15+
{
16+
this.assembly = assembly;
17+
this.projectProvider = projectProvider;
18+
this.projectLocator = projectLocator;
19+
}
20+
21+
public bool HasValidSource
22+
{
23+
get { return projectLocator.ResolveProjectFilePath(assembly) != null; }
24+
}
25+
26+
public bool HasApprovedExceptions { get; set; }
27+
28+
public XDocument GetProject()
29+
{
30+
var location = projectLocator.ResolveProjectFilePath(assembly);
31+
var project = projectProvider.LoadProjectDocument(location);
32+
return project;
33+
}
34+
35+
public Func<string, bool> Includes;
36+
}
37+
}

TestStack.ConventionTests/TestStack.ConventionTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
<Compile Include="Helpers\AssemblyProjectLocator.cs" />
6969
<Compile Include="Convention.cs" />
7070
<Compile Include="IConvention.cs" />
71+
<Compile Include="Project.cs" />
7172
<Compile Include="Types.cs" />
7273
<Compile Include="ConventionData`1.cs" />
7374
<Compile Include="Helpers\IProjectLocator.cs" />

0 commit comments

Comments
 (0)