aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2018-12-31 20:45:58 -0800
committerRob Mensching <rob@robmensching.com>2018-12-31 20:49:50 -0800
commit6e7a3274a1710a734e5369d0a1703b9c9ac9345b (patch)
tree943e0b3febbaee9188d2c55e8acb58586a4c7b40
parent54b23f4c7f63c92c0cc18ccb5a4cacea1991922d (diff)
downloadwix-6e7a3274a1710a734e5369d0a1703b9c9ac9345b.tar.gz
wix-6e7a3274a1710a734e5369d0a1703b9c9ac9345b.tar.bz2
wix-6e7a3274a1710a734e5369d0a1703b9c9ac9345b.zip
Fix loading custom table definitions and support tupledef revisions
Loading multiple intermediates with the same custom table definition would crash when trying to redefine the definition. Now definitions contain a revision and the highest tuple definition is used when loading multiple intermediates.
-rw-r--r--src/WixToolset.Data/Intermediate.cs117
-rw-r--r--src/WixToolset.Data/IntermediateTupleDefinition.cs24
-rw-r--r--src/WixToolset.Data/SimpleTupleDefinitionCreator.cs7
-rw-r--r--src/test/WixToolsetTest.Data/SerializeFixture.cs124
4 files changed, 253 insertions, 19 deletions
diff --git a/src/WixToolset.Data/Intermediate.cs b/src/WixToolset.Data/Intermediate.cs
index 4914ef88..4b7daa4e 100644
--- a/src/WixToolset.Data/Intermediate.cs
+++ b/src/WixToolset.Data/Intermediate.cs
@@ -17,7 +17,7 @@ namespace WixToolset.Data
17 public const string XmlNamespaceUri = "http://wixtoolset.org/schemas/v4/wixobj"; 17 public const string XmlNamespaceUri = "http://wixtoolset.org/schemas/v4/wixobj";
18 private static readonly Version CurrentVersion = new Version("4.0.0.0"); 18 private static readonly Version CurrentVersion = new Version("4.0.0.0");
19 19
20 private Dictionary<string, Localization> localizationsByCulture; 20 private readonly Dictionary<string, Localization> localizationsByCulture;
21 21
22 /// <summary> 22 /// <summary>
23 /// Instantiate a new Intermediate. 23 /// Instantiate a new Intermediate.
@@ -70,7 +70,7 @@ namespace WixToolset.Data
70 { 70 {
71 var uri = new Uri(Path.GetFullPath(path)); 71 var uri = new Uri(Path.GetFullPath(path));
72 var creator = new SimpleTupleDefinitionCreator(); 72 var creator = new SimpleTupleDefinitionCreator();
73 return Intermediate.Load(stream, uri, creator, suppressVersionCheck); 73 return Intermediate.LoadIntermediate(stream, uri, creator, suppressVersionCheck);
74 } 74 }
75 } 75 }
76 76
@@ -97,13 +97,13 @@ namespace WixToolset.Data
97 /// <returns>Returns the loaded intermediate.</returns> 97 /// <returns>Returns the loaded intermediate.</returns>
98 public static Intermediate Load(Assembly assembly, string resourceName, ITupleDefinitionCreator creator, bool suppressVersionCheck = false) 98 public static Intermediate Load(Assembly assembly, string resourceName, ITupleDefinitionCreator creator, bool suppressVersionCheck = false)
99 { 99 {
100 using (Stream resourceStream = assembly.GetManifestResourceStream(resourceName)) 100 using (var resourceStream = assembly.GetManifestResourceStream(resourceName))
101 { 101 {
102 var uriBuilder = new UriBuilder(assembly.CodeBase); 102 var uriBuilder = new UriBuilder(assembly.CodeBase);
103 uriBuilder.Scheme = "embeddedresource"; 103 uriBuilder.Scheme = "embeddedresource";
104 uriBuilder.Fragment = resourceName; 104 uriBuilder.Fragment = resourceName;
105 105
106 return Intermediate.Load(resourceStream, uriBuilder.Uri, creator, suppressVersionCheck); 106 return Intermediate.LoadIntermediate(resourceStream, uriBuilder.Uri, creator, suppressVersionCheck);
107 } 107 }
108 } 108 }
109 109
@@ -120,11 +120,62 @@ namespace WixToolset.Data
120 { 120 {
121 var uri = new Uri(Path.GetFullPath(path)); 121 var uri = new Uri(Path.GetFullPath(path));
122 122
123 return Intermediate.Load(stream, uri, creator, suppressVersionCheck); 123 return Intermediate.LoadIntermediate(stream, uri, creator, suppressVersionCheck);
124 } 124 }
125 } 125 }
126 126
127 /// <summary> 127 /// <summary>
128 /// Loads several intermediates from paths on disk using the same definitions.
129 /// </summary>
130 /// <param name="intermediateFiles">Paths to intermediate files saved on disk.</param>
131 /// <param name="suppressVersionCheck">Suppress checking for wix.dll version mismatches.</param>
132 /// <returns>Returns the loaded intermediates</returns>
133 public static IEnumerable<Intermediate> Load(IEnumerable<string> intermediateFiles, bool suppressVersionCheck = false)
134 {
135 var creator = new SimpleTupleDefinitionCreator();
136
137 return Intermediate.Load(intermediateFiles, creator);
138 }
139
140 /// <summary>
141 /// Loads several intermediates from paths on disk using the same definitions.
142 /// </summary>
143 /// <param name="intermediateFiles">Paths to intermediate files saved on disk.</param>
144 /// <param name="creator">ITupleDefinitionCreator to use when reconstituting the intermediates.</param>
145 /// <param name="suppressVersionCheck">Suppress checking for wix.dll version mismatches.</param>
146 /// <returns>Returns the loaded intermediates</returns>
147 public static IEnumerable<Intermediate> Load(IEnumerable<string> intermediateFiles, ITupleDefinitionCreator creator, bool suppressVersionCheck = false)
148 {
149 var jsons = new Queue<JsonWithPath>();
150 var intermediates = new List<Intermediate>();
151
152 foreach (var path in intermediateFiles)
153 {
154 using (var stream = File.OpenRead(path))
155 {
156 var uri = new Uri(Path.GetFullPath(path));
157
158 var json = Intermediate.LoadJson(stream, uri, suppressVersionCheck);
159
160 Intermediate.LoadDefinitions(json, creator);
161
162 jsons.Enqueue(new JsonWithPath { Json = json, Path = uri });
163 }
164 }
165
166 while (jsons.Count > 0)
167 {
168 var jsonWithPath = jsons.Dequeue();
169
170 var intermediate = Intermediate.FinalizeLoad(jsonWithPath.Json, jsonWithPath.Path, creator);
171
172 intermediates.Add(intermediate);
173 }
174
175 return intermediates;
176 }
177
178 /// <summary>
128 /// Saves an intermediate to a path on disk. 179 /// Saves an intermediate to a path on disk.
129 /// </summary> 180 /// </summary>
130 /// <param name="path">Path to save intermediate file to disk.</param> 181 /// <param name="path">Path to save intermediate file to disk.</param>
@@ -151,7 +202,7 @@ namespace WixToolset.Data
151 202
152 jsonObject.Add("sections", sectionsJson); 203 jsonObject.Add("sections", sectionsJson);
153 204
154 var customDefinitions = GetCustomDefinitionsInSections(); 205 var customDefinitions = this.GetCustomDefinitionsInSections();
155 206
156 if (customDefinitions.Count > 0) 207 if (customDefinitions.Count > 0)
157 { 208 {
@@ -191,10 +242,25 @@ namespace WixToolset.Data
191 /// <param name="creator">ITupleDefinitionCreator to use when reconstituting the intermediate.</param> 242 /// <param name="creator">ITupleDefinitionCreator to use when reconstituting the intermediate.</param>
192 /// <param name="suppressVersionCheck">Suppress checking for wix.dll version mismatches.</param> 243 /// <param name="suppressVersionCheck">Suppress checking for wix.dll version mismatches.</param>
193 /// <returns>Returns the loaded intermediate.</returns> 244 /// <returns>Returns the loaded intermediate.</returns>
194 private static Intermediate Load(Stream stream, Uri baseUri, ITupleDefinitionCreator creator, bool suppressVersionCheck = false) 245 private static Intermediate LoadIntermediate(Stream stream, Uri baseUri, ITupleDefinitionCreator creator, bool suppressVersionCheck = false)
195 { 246 {
196 JsonObject jsonObject; 247 var json = Intermediate.LoadJson(stream, baseUri, suppressVersionCheck);
197 248
249 Intermediate.LoadDefinitions(json, creator);
250
251 return Intermediate.FinalizeLoad(json, baseUri, creator);
252 }
253
254 /// <summary>
255 /// Loads json form of intermedaite from stream.
256 /// </summary>
257 /// <param name="stream">Stream to intermediate file.</param>
258 /// <param name="baseUri">Path name of intermediate file.</param>
259 /// <param name="suppressVersionCheck">Suppress checking for wix.dll version mismatches.</param>
260 /// <returns>Returns the loaded json.</returns>
261 private static JsonObject LoadJson(Stream stream, Uri baseUri, bool suppressVersionCheck)
262 {
263 JsonObject jsonObject;
198 using (var fs = FileStructure.Read(stream)) 264 using (var fs = FileStructure.Read(stream))
199 { 265 {
200 if (FileFormat.WixIR != fs.FileFormat) 266 if (FileFormat.WixIR != fs.FileFormat)
@@ -216,7 +282,17 @@ namespace WixToolset.Data
216 } 282 }
217 } 283 }
218 284
219 var definitionsJson = jsonObject.GetValueOrDefault<JsonArray>("definitions"); 285 return jsonObject;
286 }
287
288 /// <summary>
289 /// Loads custom definitions in intermediate json into the creator.
290 /// </summary>
291 /// <param name="json">Json version of intermediate.</param>
292 /// <param name="creator">ITupleDefinitionCreator to use when reconstituting the intermediate.</param>
293 private static void LoadDefinitions(JsonObject json, ITupleDefinitionCreator creator)
294 {
295 var definitionsJson = json.GetValueOrDefault<JsonArray>("definitions");
220 296
221 if (definitionsJson != null) 297 if (definitionsJson != null)
222 { 298 {
@@ -226,12 +302,22 @@ namespace WixToolset.Data
226 creator.AddCustomTupleDefinition(definition); 302 creator.AddCustomTupleDefinition(definition);
227 } 303 }
228 } 304 }
305 }
229 306
230 var id = jsonObject.GetValueOrDefault<string>("id"); 307 /// <summary>
308 /// Loads the sections and localization for the intermediate.
309 /// </summary>
310 /// <param name="json">Json version of intermediate.</param>
311 /// <param name="baseUri">Path to the intermediate.</param>
312 /// <param name="creator">ITupleDefinitionCreator to use when reconstituting the intermediate.</param>
313 /// <returns>The finalized intermediate.</returns>
314 private static Intermediate FinalizeLoad(JsonObject json, Uri baseUri, ITupleDefinitionCreator creator)
315 {
316 var id = json.GetValueOrDefault<string>("id");
231 317
232 var sections = new List<IntermediateSection>(); 318 var sections = new List<IntermediateSection>();
233 319
234 var sectionsJson = jsonObject.GetValueOrDefault<JsonArray>("sections"); 320 var sectionsJson = json.GetValueOrDefault<JsonArray>("sections");
235 foreach (JsonObject sectionJson in sectionsJson) 321 foreach (JsonObject sectionJson in sectionsJson)
236 { 322 {
237 var section = IntermediateSection.Deserialize(creator, baseUri, sectionJson); 323 var section = IntermediateSection.Deserialize(creator, baseUri, sectionJson);
@@ -240,7 +326,7 @@ namespace WixToolset.Data
240 326
241 var localizations = new Dictionary<string, Localization>(StringComparer.OrdinalIgnoreCase); 327 var localizations = new Dictionary<string, Localization>(StringComparer.OrdinalIgnoreCase);
242 328
243 var localizationsJson = jsonObject.GetValueOrDefault<JsonArray>("localizations") ?? new JsonArray(); 329 var localizationsJson = json.GetValueOrDefault<JsonArray>("localizations") ?? new JsonArray();
244 foreach (JsonObject localizationJson in localizationsJson) 330 foreach (JsonObject localizationJson in localizationsJson)
245 { 331 {
246 var localization = Localization.Deserialize(localizationJson); 332 var localization = Localization.Deserialize(localizationJson);
@@ -409,5 +495,12 @@ namespace WixToolset.Data
409 495
410 return customDefinitions; 496 return customDefinitions;
411 } 497 }
498
499 private struct JsonWithPath
500 {
501 public JsonObject Json { get; set; }
502
503 public Uri Path { get; set; }
504 }
412 } 505 }
413} 506}
diff --git a/src/WixToolset.Data/IntermediateTupleDefinition.cs b/src/WixToolset.Data/IntermediateTupleDefinition.cs
index eb4ab12e..ea15c2dd 100644
--- a/src/WixToolset.Data/IntermediateTupleDefinition.cs
+++ b/src/WixToolset.Data/IntermediateTupleDefinition.cs
@@ -1,4 +1,4 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. 1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2 2
3namespace WixToolset.Data 3namespace WixToolset.Data
4{ 4{
@@ -8,19 +8,25 @@ namespace WixToolset.Data
8 public class IntermediateTupleDefinition 8 public class IntermediateTupleDefinition
9 { 9 {
10 public IntermediateTupleDefinition(string name, IntermediateFieldDefinition[] fieldDefinitions, Type strongTupleType) 10 public IntermediateTupleDefinition(string name, IntermediateFieldDefinition[] fieldDefinitions, Type strongTupleType)
11 : this(TupleDefinitionType.MustBeFromAnExtension, name, fieldDefinitions, strongTupleType) 11 : this(TupleDefinitionType.MustBeFromAnExtension, name, 0, fieldDefinitions, strongTupleType)
12 {
13 }
14
15 public IntermediateTupleDefinition(string name, int revision, IntermediateFieldDefinition[] fieldDefinitions, Type strongTupleType)
16 : this(TupleDefinitionType.MustBeFromAnExtension, name, revision, fieldDefinitions, strongTupleType)
12 { 17 {
13 } 18 }
14 19
15 internal IntermediateTupleDefinition(TupleDefinitionType type, IntermediateFieldDefinition[] fieldDefinitions, Type strongTupleType) 20 internal IntermediateTupleDefinition(TupleDefinitionType type, IntermediateFieldDefinition[] fieldDefinitions, Type strongTupleType)
16 : this(type, type.ToString(), fieldDefinitions, strongTupleType) 21 : this(type, type.ToString(), 0, fieldDefinitions, strongTupleType)
17 { 22 {
18 } 23 }
19 24
20 private IntermediateTupleDefinition(TupleDefinitionType type, string name, IntermediateFieldDefinition[] fieldDefinitions, Type strongTupleType) 25 private IntermediateTupleDefinition(TupleDefinitionType type, string name, int revision, IntermediateFieldDefinition[] fieldDefinitions, Type strongTupleType)
21 { 26 {
22 this.Type = type; 27 this.Type = type;
23 this.Name = name; 28 this.Name = name;
29 this.Revision = revision;
24 this.FieldDefinitions = fieldDefinitions; 30 this.FieldDefinitions = fieldDefinitions;
25 this.StrongTupleType = strongTupleType ?? typeof(IntermediateTuple); 31 this.StrongTupleType = strongTupleType ?? typeof(IntermediateTuple);
26#if DEBUG 32#if DEBUG
@@ -28,6 +34,8 @@ namespace WixToolset.Data
28#endif 34#endif
29 } 35 }
30 36
37 public int Revision { get; }
38
31 public TupleDefinitionType Type { get; } 39 public TupleDefinitionType Type { get; }
32 40
33 public string Name { get; } 41 public string Name { get; }
@@ -48,6 +56,7 @@ namespace WixToolset.Data
48 internal static IntermediateTupleDefinition Deserialize(JsonObject jsonObject) 56 internal static IntermediateTupleDefinition Deserialize(JsonObject jsonObject)
49 { 57 {
50 var name = jsonObject.GetValueOrDefault<string>("name"); 58 var name = jsonObject.GetValueOrDefault<string>("name");
59 var revision = jsonObject.GetValueOrDefault("rev", 0);
51 var definitionsJson = jsonObject.GetValueOrDefault<JsonArray>("fields"); 60 var definitionsJson = jsonObject.GetValueOrDefault<JsonArray>("fields");
52 61
53 var fieldDefinitions = new IntermediateFieldDefinition[definitionsJson.Count]; 62 var fieldDefinitions = new IntermediateFieldDefinition[definitionsJson.Count];
@@ -60,7 +69,7 @@ namespace WixToolset.Data
60 fieldDefinitions[i] = new IntermediateFieldDefinition(fieldName, fieldType); 69 fieldDefinitions[i] = new IntermediateFieldDefinition(fieldName, fieldType);
61 } 70 }
62 71
63 return new IntermediateTupleDefinition(name, fieldDefinitions, null); 72 return new IntermediateTupleDefinition(name, revision, fieldDefinitions, null);
64 } 73 }
65 74
66 internal JsonObject Serialize() 75 internal JsonObject Serialize()
@@ -70,6 +79,11 @@ namespace WixToolset.Data
70 { "name", this.Name } 79 { "name", this.Name }
71 }; 80 };
72 81
82 if (this.Revision > 0)
83 {
84 jsonObject.Add("rev", this.Revision);
85 }
86
73 var fieldsJson = new JsonArray(this.FieldDefinitions.Length); 87 var fieldsJson = new JsonArray(this.FieldDefinitions.Length);
74 88
75 foreach (var fieldDefinition in this.FieldDefinitions) 89 foreach (var fieldDefinition in this.FieldDefinitions)
diff --git a/src/WixToolset.Data/SimpleTupleDefinitionCreator.cs b/src/WixToolset.Data/SimpleTupleDefinitionCreator.cs
index 6a86639a..257f028c 100644
--- a/src/WixToolset.Data/SimpleTupleDefinitionCreator.cs
+++ b/src/WixToolset.Data/SimpleTupleDefinitionCreator.cs
@@ -1,4 +1,4 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. 1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2 2
3namespace WixToolset.Data 3namespace WixToolset.Data
4{ 4{
@@ -10,7 +10,10 @@ namespace WixToolset.Data
10 10
11 public void AddCustomTupleDefinition(IntermediateTupleDefinition definition) 11 public void AddCustomTupleDefinition(IntermediateTupleDefinition definition)
12 { 12 {
13 this.CustomDefinitionByName.Add(definition.Name, definition); 13 if (!this.CustomDefinitionByName.TryGetValue(definition.Name, out var existing) || definition.Revision > existing.Revision)
14 {
15 this.CustomDefinitionByName[definition.Name] = definition;
16 }
14 } 17 }
15 18
16 public bool TryGetTupleDefinitionByName(string name, out IntermediateTupleDefinition tupleDefinition) 19 public bool TryGetTupleDefinitionByName(string name, out IntermediateTupleDefinition tupleDefinition)
diff --git a/src/test/WixToolsetTest.Data/SerializeFixture.cs b/src/test/WixToolsetTest.Data/SerializeFixture.cs
index 1e03481d..ac2f5454 100644
--- a/src/test/WixToolsetTest.Data/SerializeFixture.cs
+++ b/src/test/WixToolsetTest.Data/SerializeFixture.cs
@@ -42,6 +42,130 @@ namespace WixToolsetTest.Data
42 } 42 }
43 43
44 [Fact] 44 [Fact]
45 public void CanSaveAndLoadIntermediateWithCustomDefinitions()
46 {
47 var sln = new SourceLineNumber("test.wxs", 1);
48
49 var section = new IntermediateSection("test", SectionType.Product, 65001);
50
51 var fieldDefs = new[]
52 {
53 new IntermediateFieldDefinition("A", IntermediateFieldType.String),
54 new IntermediateFieldDefinition("B", IntermediateFieldType.Number),
55 new IntermediateFieldDefinition("C", IntermediateFieldType.Bool),
56 };
57
58 var tupleDef = new IntermediateTupleDefinition("CustomDef", fieldDefs, null);
59
60 var tuple = tupleDef.CreateTuple(sln, new Identifier(AccessModifier.Public, "customT"));
61 tuple.Set(0, "foo");
62 tuple.Set(1, 2);
63 tuple.Set(2, true);
64
65 section.Tuples.Add(tuple);
66
67 var intermediate = new Intermediate("TestIntermediate", new[] { section }, null, null);
68
69 var path = Path.GetTempFileName();
70 try
71 {
72 intermediate.Save(path);
73
74 var loaded = Intermediate.Load(path);
75 var loadedSection = loaded.Sections.Single();
76 var loadedTuple = loadedSection.Tuples.Single();
77
78 Assert.Equal("foo", loadedTuple.AsString(0));
79 Assert.Equal(2, loadedTuple[1].AsNumber());
80 Assert.True(loadedTuple[2].AsBool());
81 }
82 finally
83 {
84 File.Delete(path);
85 }
86 }
87
88 [Fact]
89 public void CanSaveAndLoadMultipleIntermediateWithCustomDefinitions()
90 {
91 var sln = new SourceLineNumber("test.wxs", 1);
92
93 // Intermediate #1
94 var fieldDefs = new[]
95 {
96 new IntermediateFieldDefinition("A", IntermediateFieldType.String),
97 new IntermediateFieldDefinition("B", IntermediateFieldType.Number),
98 new IntermediateFieldDefinition("C", IntermediateFieldType.Bool),
99 };
100
101 var tupleDef = new IntermediateTupleDefinition("CustomDef", fieldDefs, null);
102
103 var tuple = tupleDef.CreateTuple(sln, new Identifier(AccessModifier.Public, "customT"));
104 tuple.Set(0, "foo");
105 tuple.Set(1, 2);
106 tuple.Set(2, true);
107
108 var section = new IntermediateSection("test", SectionType.Product, 65001);
109 section.Tuples.Add(tuple);
110
111 var intermediate1 = new Intermediate("TestIntermediate", new[] { section }, null, null);
112
113 // Intermediate #2
114 var fieldDefs2 = new[]
115 {
116 new IntermediateFieldDefinition("A", IntermediateFieldType.String),
117 new IntermediateFieldDefinition("B", IntermediateFieldType.Number),
118 new IntermediateFieldDefinition("C", IntermediateFieldType.Bool),
119 new IntermediateFieldDefinition("D", IntermediateFieldType.String),
120 };
121
122 var tupleDef2 = new IntermediateTupleDefinition("CustomDef", 1, fieldDefs2, null);
123
124 var tuple2 = tupleDef2.CreateTuple(sln, new Identifier(AccessModifier.Public, "customT2"));
125 tuple2.Set(0, "bar");
126 tuple2.Set(1, 3);
127 tuple2.Set(2, false);
128 tuple2.Set(3, "baz");
129
130 var section2 = new IntermediateSection("test2", SectionType.Fragment, 65001);
131 section2.Tuples.Add(tuple2);
132
133 var intermediate2 = new Intermediate("TestIntermediate2", new[] { section2 }, null, null);
134
135 // Save
136 var path1 = Path.GetTempFileName();
137 var path2 = Path.GetTempFileName();
138 try
139 {
140 intermediate1.Save(path1);
141 intermediate2.Save(path2);
142
143 var loaded = Intermediate.Load(new[] { path1, path2 });
144
145 var loaded1 = loaded.First();
146 var loaded2 = loaded.Skip(1).Single();
147
148 var loadedTuple1 = loaded1.Sections.Single().Tuples.Single();
149 var loadedTuple2 = loaded2.Sections.Single().Tuples.Single();
150
151 Assert.Equal("foo", loadedTuple1.AsString(0));
152 Assert.Equal(2, loadedTuple1[1].AsNumber());
153 Assert.True(loadedTuple1[2].AsBool());
154 Assert.Null(loadedTuple1.AsString(3));
155
156 Assert.Equal("bar", loadedTuple2.AsString(0));
157 Assert.Equal(3, loadedTuple2[1].AsNumber());
158 Assert.False(loadedTuple2[2].AsBool());
159 Assert.Equal("baz", loadedTuple2.AsString(3));
160 }
161 finally
162 {
163 File.Delete(path2);
164 File.Delete(path1);
165 }
166 }
167
168 [Fact]
45 public void CanSaveAndLoadIntermediateWithLocalization() 169 public void CanSaveAndLoadIntermediateWithLocalization()
46 { 170 {
47 var sln = new SourceLineNumber("test.wxs", 10); 171 var sln = new SourceLineNumber("test.wxs", 10);