Skip to content

Commit 4ab076e

Browse files
committed
Use T4MultiFile nuget in test project.
* Add nuget * Use nuget's .ttinclude file * Minor clean up
1 parent 4c7f5d9 commit 4ab076e

File tree

5 files changed

+187
-12
lines changed

5 files changed

+187
-12
lines changed

Tests/GeneratedCode/Includes/UnitTestClass.ttinclude

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,11 @@
55
<#@ import namespace="UnitsNet.Units" #>
66
<#@ import namespace="UnitsNet.Attributes" #>
77
<#@ import namespace="UnitsNet.Templating" #>
8-
<#@ include file="..\..\..\Src\UnitsNet\GeneratedCode\Includes\MultipleOutputHelper.ttinclude" once="true"#><#+
8+
<#@ include file="..\..\MultipleOutputHelper.ttinclude" once="true"#><#+
99

10-
private void GenerateTestClass(Manager manager, string className, string baseUnitName, string baseUnitPluralName, ICollection<UnitInfo> orderedClassUnits)
10+
private void GenerateTestClass(string className, string baseUnitName, string baseUnitPluralName, ICollection<UnitInfo> orderedClassUnits)
1111
{
12-
using (manager.StartNewFile(className+"TestsBase.g.cs"))
13-
{
14-
/*object[] orderedClassUnits = unitToAttribute
15-
.Keys
16-
.OrderBy(unit => unit.ToString())
17-
.ToArray();*/
18-
19-
string baseUnitVariableName = baseUnitName.ToLowerInvariant();
12+
string baseUnitVariableName = baseUnitName.ToLowerInvariant();
2013
#>
2114
// Copyright © 2007 by Initial Force AS. All rights reserved.
2215
// https://github.com/InitialForce/SIUnits
@@ -201,6 +194,5 @@ namespace UnitsNet.Tests
201194
}
202195
}
203196
<#+
204-
} // using (manager.StartNewFile(className+"TestsBase.generated.cs"))
205197
} // private void GenerateTestClass(Type unitAttributeType, Manager manager, string className, TUnit baseUnit)
206198
#>

Tests/GeneratedCode/UnitTestClasses.tt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
var m = Manager.Create(Host, GenerationEnvironment);
99
foreach (UnitClassInfo info in infos)
1010
{
11-
GenerateTestClass(m, info.UnitClassName, info.BaseUnitName, info.BaseUnitPluralName, info.OrderedUnits);
11+
m.StartNewFile(info.UnitClassName + "TestsBase.g.cs");
12+
GenerateTestClass(info.UnitClassName, info.BaseUnitName, info.BaseUnitPluralName, info.OrderedUnits);
13+
m.EndBlock();
1214
}
1315

1416
m.Process(split: true);
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
<#@ assembly name="System.Core"
2+
#><#@ assembly name="System.Data.Linq"
3+
#><#@ assembly name="EnvDTE"
4+
#><#@ assembly name="System.Xml"
5+
#><#@ assembly name="System.Xml.Linq"
6+
#><#@ import namespace="System"
7+
#><#@ import namespace="System.CodeDom"
8+
#><#@ import namespace="System.CodeDom.Compiler"
9+
#><#@ import namespace="System.Collections.Generic"
10+
#><#@ import namespace="System.Data.Linq"
11+
#><#@ import namespace="System.Data.Linq.Mapping"
12+
#><#@ import namespace="System.IO"
13+
#><#@ import namespace="System.Linq"
14+
#><#@ import namespace="System.Reflection"
15+
#><#@ import namespace="System.Text"
16+
#><#@ import namespace="System.Xml.Linq"
17+
#><#@ import namespace="Microsoft.VisualStudio.TextTemplating"
18+
#><#+
19+
20+
// Manager class records the various blocks so it can split them up
21+
class Manager {
22+
private class Block {
23+
public String Name;
24+
public int Start, Length;
25+
}
26+
27+
private Block currentBlock;
28+
private List<Block> files = new List<Block>();
29+
private Block footer = new Block();
30+
private Block header = new Block();
31+
private ITextTemplatingEngineHost host;
32+
private StringBuilder template;
33+
protected List<String> generatedFileNames = new List<String>();
34+
35+
public static Manager Create(ITextTemplatingEngineHost host, StringBuilder template) {
36+
return (host is IServiceProvider) ? new VSManager(host, template) : new Manager(host, template);
37+
}
38+
39+
public void StartNewFile(String name) {
40+
if (name == null)
41+
throw new ArgumentNullException("name");
42+
CurrentBlock = new Block { Name = name };
43+
}
44+
45+
public void StartFooter() {
46+
CurrentBlock = footer;
47+
}
48+
49+
public void StartHeader() {
50+
CurrentBlock = header;
51+
}
52+
53+
public void EndBlock() {
54+
if (CurrentBlock == null)
55+
return;
56+
CurrentBlock.Length = template.Length - CurrentBlock.Start;
57+
if (CurrentBlock != header && CurrentBlock != footer)
58+
files.Add(CurrentBlock);
59+
currentBlock = null;
60+
}
61+
62+
public virtual void Process(bool split) {
63+
if (split) {
64+
EndBlock();
65+
String headerText = template.ToString(header.Start, header.Length);
66+
String footerText = template.ToString(footer.Start, footer.Length);
67+
String outputPath = Path.GetDirectoryName(host.TemplateFile);
68+
files.Reverse();
69+
foreach(Block block in files) {
70+
String fileName = Path.Combine(outputPath, block.Name);
71+
String content = headerText + template.ToString(block.Start, block.Length) + footerText;
72+
generatedFileNames.Add(fileName);
73+
CreateFile(fileName, content);
74+
template.Remove(block.Start, block.Length);
75+
}
76+
}
77+
}
78+
79+
protected virtual void CreateFile(String fileName, String content) {
80+
if (IsFileContentDifferent(fileName, content))
81+
File.WriteAllText(fileName, content);
82+
}
83+
84+
public virtual String GetCustomToolNamespace(String fileName) {
85+
return null;
86+
}
87+
88+
public virtual String DefaultProjectNamespace {
89+
get { return null; }
90+
}
91+
92+
protected bool IsFileContentDifferent(String fileName, String newContent) {
93+
return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent);
94+
}
95+
96+
private Manager(ITextTemplatingEngineHost host, StringBuilder template) {
97+
this.host = host;
98+
this.template = template;
99+
}
100+
101+
private Block CurrentBlock {
102+
get { return currentBlock; }
103+
set {
104+
if (CurrentBlock != null)
105+
EndBlock();
106+
if (value != null)
107+
value.Start = template.Length;
108+
currentBlock = value;
109+
}
110+
}
111+
112+
private class VSManager: Manager {
113+
private EnvDTE.ProjectItem templateProjectItem;
114+
private EnvDTE.DTE dte;
115+
private Action<String> checkOutAction;
116+
private Action<IEnumerable<String>> projectSyncAction;
117+
118+
public override String DefaultProjectNamespace {
119+
get {
120+
return templateProjectItem.ContainingProject.Properties.Item("DefaultNamespace").Value.ToString();
121+
}
122+
}
123+
124+
public override String GetCustomToolNamespace(string fileName) {
125+
return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString();
126+
}
127+
128+
public override void Process(bool split) {
129+
if (templateProjectItem.ProjectItems == null)
130+
return;
131+
base.Process(split);
132+
projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null));
133+
}
134+
135+
protected override void CreateFile(String fileName, String content) {
136+
if (IsFileContentDifferent(fileName, content)) {
137+
CheckoutFileIfRequired(fileName);
138+
File.WriteAllText(fileName, content);
139+
}
140+
}
141+
142+
internal VSManager(ITextTemplatingEngineHost host, StringBuilder template)
143+
: base(host, template) {
144+
var hostServiceProvider = (IServiceProvider) host;
145+
if (hostServiceProvider == null)
146+
throw new ArgumentNullException("Could not obtain IServiceProvider");
147+
dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE));
148+
if (dte == null)
149+
throw new ArgumentNullException("Could not obtain DTE from host");
150+
templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);
151+
checkOutAction = (String fileName) => dte.SourceControl.CheckOutItem(fileName);
152+
projectSyncAction = (IEnumerable<String> keepFileNames) => ProjectSync(templateProjectItem, keepFileNames);
153+
}
154+
155+
private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable<String> keepFileNames) {
156+
var keepFileNameSet = new HashSet<String>(keepFileNames);
157+
var projectFiles = new Dictionary<String, EnvDTE.ProjectItem>();
158+
var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.get_FileNames(0)) + ".";
159+
foreach(EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems)
160+
projectFiles.Add(projectItem.get_FileNames(0), projectItem);
161+
162+
// Remove unused items from the project
163+
foreach(var pair in projectFiles)
164+
if (!keepFileNames.Contains(pair.Key) && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalFilePrefix))
165+
pair.Value.Delete();
166+
167+
// Add missing files to the project
168+
foreach(String fileName in keepFileNameSet)
169+
if (!projectFiles.ContainsKey(fileName))
170+
templateProjectItem.ProjectItems.AddFromFile(fileName);
171+
}
172+
173+
private void CheckoutFileIfRequired(String fileName) {
174+
var sc = dte.SourceControl;
175+
if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName))
176+
checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null));
177+
}
178+
}
179+
} #>

Tests/UnitsNet.Tests.net35.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@
124124
<Generator>TextTemplatingFileGenerator</Generator>
125125
<LastGenOutput>UnitTestClasses.txt</LastGenOutput>
126126
</None>
127+
<None Include="MultipleOutputHelper.ttinclude" />
127128
<None Include="packages.config" />
128129
</ItemGroup>
129130
<ItemGroup>

Tests/packages.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
<packages>
33
<package id="morelinq" version="1.0.16006" targetFramework="net35-Client" />
44
<package id="NUnit" version="2.6.2" targetFramework="net45" />
5+
<package id="T4MultiFile" version="0.11" targetFramework="net35-Client" />
56
</packages>

0 commit comments

Comments
 (0)