Skip to content
Open
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
2 changes: 1 addition & 1 deletion src/Onion.SolutionParser.Parser/GlobalSectionParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public GlobalSectionParser(string solutionContents) : base (solutionContents)

}

public new IEnumerable<GlobalSection> Parse()
public override IEnumerable<GlobalSection> Parse()
{
var match = GlobalPattern.Match(SolutionContents);
while (match.Success)
Expand Down
35 changes: 35 additions & 0 deletions src/Onion.SolutionParser.Parser/HeaderParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Collections.Generic;
using System.IO;

namespace Onion.SolutionParser.Parser
{
public class HeaderParser
{
private readonly string _solutionContents;

public HeaderParser(string solutionContents)
{
_solutionContents = solutionContents;
}

public IEnumerable<string> Parse()
{
var result = new List<string>();
using (var sr = new StringReader(_solutionContents))
{
var line = sr.ReadLine();
while (line != null)
{
if (line.TrimStart().StartsWith("Project(") || line.TrimStart().StartsWith("Global("))
{
break;
}
result.Add(line);
line = sr.ReadLine();
}
}
return result;
}

}
}
7 changes: 7 additions & 0 deletions src/Onion.SolutionParser.Parser/ISolutionRenderer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Onion.SolutionParser.Parser
{
public interface ISolutionRenderer
{
string Render();
}
}
1 change: 1 addition & 0 deletions src/Onion.SolutionParser.Parser/Model/ISolution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace Onion.SolutionParser.Parser.Model
{
public interface ISolution
{
IEnumerable<string> Header { get; }
IEnumerable<GlobalSection> Global { get; }
IEnumerable<Project> Projects { get; }
}
Expand Down
1 change: 1 addition & 0 deletions src/Onion.SolutionParser.Parser/Model/Solution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace Onion.SolutionParser.Parser.Model
{
public class Solution : ISolution
{
public IEnumerable<string> Header { get; set; }
public IEnumerable<GlobalSection> Global { get; set; }
public IEnumerable<Project> Projects { get; set; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@
</ItemGroup>
<ItemGroup>
<Compile Include="GlobalSectionParser.cs" />
<Compile Include="HeaderParser.cs" />
<Compile Include="ISolutionItemParser.cs" />
<Compile Include="ISolutionParser.cs" />
<Compile Include="ISolutionRenderer.cs" />
<Compile Include="Model\GlobalSection.cs" />
<Compile Include="Model\ISolution.cs" />
<Compile Include="Model\ISolutionItem.cs" />
Expand All @@ -52,6 +54,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SolutionItemParserBase.cs" />
<Compile Include="SolutionParser.cs" />
<Compile Include="SolutionRenderer.cs" />
</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 Down
2 changes: 1 addition & 1 deletion src/Onion.SolutionParser.Parser/ProjectParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public ProjectParser(string solutionContents) : base(solutionContents)

}

public new IEnumerable<Project> Parse()
public override IEnumerable<Project> Parse()
{
var match = ProjectPattern.Match(SolutionContents);
while (match.Success)
Expand Down
2 changes: 1 addition & 1 deletion src/Onion.SolutionParser.Parser/SolutionItemParserBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ protected SolutionItemParserBase(string solutionContents)
SolutionContents = solutionContents;
}

public new IEnumerable<T> Parse()
public virtual IEnumerable<T> Parse()
{
throw new System.NotImplementedException();
}
Expand Down
37 changes: 36 additions & 1 deletion src/Onion.SolutionParser.Parser/SolutionParser.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.IO;
using System;
using System.IO;
using Onion.SolutionParser.Parser.Model;

namespace Onion.SolutionParser.Parser
Expand All @@ -17,10 +18,32 @@ public SolutionParser(string path)
}
}

public SolutionParser(Stream stream)
{
if (stream == null)
{
throw new ArgumentNullException("stream");
}
using (var reader = new StreamReader(stream))
{
_solutionContents = reader.ReadToEnd();
}
}

public SolutionParser(TextReader reader)
{
if (reader == null)
{
throw new ArgumentNullException("reader");
}
_solutionContents = reader.ReadToEnd();
}

public ISolution Parse()
{
return new Solution
{
Header = (new HeaderParser(_solutionContents)).Parse(),
Global = (new GlobalSectionParser(_solutionContents)).Parse(),
Projects = (new ProjectParser(_solutionContents)).Parse()
};
Expand All @@ -31,5 +54,17 @@ public static ISolution Parse(string path)
var parser = new SolutionParser(path);
return parser.Parse();
}

public static ISolution Parse(Stream stream)
{
var parser = new SolutionParser(stream);
return parser.Parse();
}

public static ISolution Parse(TextReader reader)
{
var parser = new SolutionParser(reader);
return parser.Parse();
}
}
}
111 changes: 111 additions & 0 deletions src/Onion.SolutionParser.Parser/SolutionRenderer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using System.IO;
using Onion.SolutionParser.Parser.Model;

namespace Onion.SolutionParser.Parser
{
public class SolutionRenderer : ISolutionRenderer
{
private readonly ISolution _solution;

public SolutionRenderer(ISolution solution)
{
if (solution == null)
{
throw new ArgumentNullException("solution");
}
_solution = solution;
}

public string Render()
{
using (var sb = new StringWriter())
{
foreach (var header in _solution.Header)
{
sb.WriteLine(header);
}
RenderProjects(_solution.Projects, sb);
RenderGlobal(_solution.Global, sb);
return sb.ToString();
}
}

private void RenderProjects(IEnumerable<Project> projects, StringWriter sb)
{
foreach (var project in _solution.Projects)
{
RenderProject(project, sb);
}
}

private void RenderProject(Project project, StringWriter sb)
{
sb.WriteLine("Project(\"{0}\") = \"{1}\", \"{2}\", \"{3}\"", project.TypeGuid.ToString("B").ToUpperInvariant(), project.Name, project.Path, project.Guid.ToString("B").ToUpperInvariant());
if (project.ProjectSection != null)
{
sb.WriteLine("\tProjectSection({0}) = {1}", project.ProjectSection.Name, Render(project.ProjectSection.Type));
foreach (var entry in project.ProjectSection.Entries)
{
sb.WriteLine("\t\t{0} = {1}", entry.Key, entry.Value);

}
sb.WriteLine("\tEndProjectSection");
}
sb.WriteLine("EndProject");
}

private void RenderGlobal(IEnumerable<GlobalSection> global, StringWriter sb)
{
sb.WriteLine("Global");
foreach (var globalSection in _solution.Global)
{
RenderGlobalSection(globalSection, sb);
}
sb.WriteLine("EndGlobal");
}

private void RenderGlobalSection(GlobalSection globalSection, StringWriter sb)
{
sb.WriteLine("\tGlobalSection({0}) = {1}", globalSection.Name, Render(globalSection.Type));
foreach (var entry in globalSection.Entries)
{
sb.WriteLine("\t\t{0} = {1}", entry.Key, entry.Value);
}
sb.WriteLine("\tEndGlobalSection");
}

private string Render(ProjectSectionType type)
{
switch (type)
{
case ProjectSectionType.PostProject:
return "postProject";
case ProjectSectionType.PreProject:
return "preProject";
default:
throw new ArgumentOutOfRangeException("type", type, null);
}
}

private string Render(GlobalSectionType type)
{
switch (type)
{
case GlobalSectionType.PostSolution:
return "postSolution";
case GlobalSectionType.PreSolution:
return "preSolution";
default:
throw new ArgumentOutOfRangeException("type", type, null);
}
}

public static string Render(ISolution solution)
{
var renderer = new SolutionRenderer(solution);
return renderer.Render();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Parser\GlobalSectionParserTest.cs" />
<Compile Include="Parser\HeaderParserTest.cs" />
<Compile Include="Parser\ProjectParserTest.cs" />
<Compile Include="Parser\SolutionParserTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Renderer\SolutionRendererTest.cs" />
<Compile Include="Utility.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
44 changes: 44 additions & 0 deletions tests/Onion.SolutionParser.Tests/Parser/HeaderParserTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using Onion.SolutionParser.Parser;

namespace Onion.SolutionParser.Tests.Parser
{
[TestFixture]
public class HeaderParserTest
{
public HeaderParser Parser { get; set; }
public string SolutionContents { get; set; }

[TestFixtureSetUp]
public void BeforeAll()
{
SolutionContents = Utility.GetFixtureContents("NDriven.sln");
}

[SetUp]
public void BeforeEach()
{
Parser = new HeaderParser(SolutionContents);
}

[Test]
public void Parse_should_return_IEnumerable_of_string_with_correct_count()
{
var lines = Parser.Parse();
var count = lines.Count();
Assert.IsInstanceOf<IEnumerable<string>>(lines);
Assert.AreEqual(3, count);
}

[Test]
public void Parse_should_return_correct_lines()
{
var lines = Parser.Parse();
Assert.AreEqual("", lines.ElementAt(0));
Assert.AreEqual("Microsoft Visual Studio Solution File, Format Version 12.00", lines.ElementAt(1));
Assert.AreEqual("# Visual Studio 2012", lines.ElementAt(2));
}
}
}
34 changes: 34 additions & 0 deletions tests/Onion.SolutionParser.Tests/Renderer/SolutionRendererTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using NUnit.Framework;
using Onion.SolutionParser.Parser;
using RealParser = Onion.SolutionParser.Parser;

namespace Onion.SolutionParser.Tests.Renderer
{
[TestFixture]
public class SolutionRendererTest
{

[Test]
public void Renderer1_should_render_same_contents()
{
var contents = Utility.GetFixtureContents("NDriven.sln");
var parser = new RealParser.SolutionParser(Utility.GetFixturePath("NDriven.sln"));
var solution = parser.Parse();
var renderer = new SolutionRenderer(solution);
var rendered = renderer.Render();
Assert.AreEqual(contents, rendered);
}

[Test]
public void Renderer2_should_render_same_contents()
{
var contents = Utility.GetFixtureContents("Microsoft.AspNet.SignalR.sln");
var parser = new RealParser.SolutionParser(Utility.GetFixturePath("Microsoft.AspNet.SignalR.sln"));
var solution = parser.Parse();
var renderer = new SolutionRenderer(solution);
var rendered = renderer.Render();
Assert.AreEqual(contents, rendered);
}

}
}