aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/WixToolset.Converters/FixupCommandBase.cs18
-rw-r--r--src/WixToolset.Converters/WixConverter.cs160
-rw-r--r--src/test/WixToolsetTest.Converters/CustomTableFixture.cs178
3 files changed, 337 insertions, 19 deletions
diff --git a/src/WixToolset.Converters/FixupCommandBase.cs b/src/WixToolset.Converters/FixupCommandBase.cs
index 7ecce543..21282d07 100644
--- a/src/WixToolset.Converters/FixupCommandBase.cs
+++ b/src/WixToolset.Converters/FixupCommandBase.cs
@@ -29,6 +29,8 @@ namespace WixToolset.Converters
29 29
30 protected bool ShowHelp { get; set; } 30 protected bool ShowHelp { get; set; }
31 31
32 protected CustomTableTarget CustomTableSetting { get; set; }
33
32 protected bool DryRun { get; set; } 34 protected bool DryRun { get; set; }
33 35
34 protected HashSet<string> ErrorsAsWarnings { get; } 36 protected HashSet<string> ErrorsAsWarnings { get; }
@@ -68,6 +70,22 @@ namespace WixToolset.Converters
68 this.StopParsing = true; 70 this.StopParsing = true;
69 return true; 71 return true;
70 72
73 case "-custom-table":
74 var customTableSetting = parser.GetNextArgumentOrError(argument);
75 switch (customTableSetting)
76 {
77 case "bundle":
78 this.CustomTableSetting = CustomTableTarget.Bundle;
79 break;
80 case "msi":
81 this.CustomTableSetting = CustomTableTarget.Msi;
82 break;
83 default:
84 parser.ReportErrorArgument(argument);
85 break;
86 }
87 return true;
88
71 case "n": 89 case "n":
72 case "-dry-run": 90 case "-dry-run":
73 this.DryRun = true; 91 this.DryRun = true;
diff --git a/src/WixToolset.Converters/WixConverter.cs b/src/WixToolset.Converters/WixConverter.cs
index 3348e49c..9ada4745 100644
--- a/src/WixToolset.Converters/WixConverter.cs
+++ b/src/WixToolset.Converters/WixConverter.cs
@@ -15,6 +15,27 @@ namespace WixToolset.Converters
15 using WixToolset.Extensibility.Services; 15 using WixToolset.Extensibility.Services;
16 16
17 /// <summary> 17 /// <summary>
18 /// How to convert CustomTable elements.
19 /// </summary>
20 public enum CustomTableTarget
21 {
22 /// <summary>
23 /// Ambiguous elements will be left alone.
24 /// </summary>
25 Unknown,
26
27 /// <summary>
28 /// Use CustomTable, CustomTableRef, and Unreal.
29 /// </summary>
30 Msi,
31
32 /// <summary>
33 /// Use BundleCustomData and BundleCustomDataRef.
34 /// </summary>
35 Bundle,
36 }
37
38 /// <summary>
18 /// WiX source code converter. 39 /// WiX source code converter.
19 /// </summary> 40 /// </summary>
20 public sealed class WixConverter 41 public sealed class WixConverter
@@ -45,19 +66,25 @@ namespace WixToolset.Converters
45 private static readonly XName BootstrapperApplicationDllElementName = WixNamespace + "BootstrapperApplicationDll"; 66 private static readonly XName BootstrapperApplicationDllElementName = WixNamespace + "BootstrapperApplicationDll";
46 private static readonly XName BootstrapperApplicationRefElementName = WixNamespace + "BootstrapperApplicationRef"; 67 private static readonly XName BootstrapperApplicationRefElementName = WixNamespace + "BootstrapperApplicationRef";
47 private static readonly XName ApprovedExeForElevationElementName = WixNamespace + "ApprovedExeForElevation"; 68 private static readonly XName ApprovedExeForElevationElementName = WixNamespace + "ApprovedExeForElevation";
48 private static readonly XName EmbeddedChainerElementName = WixNamespace + "EmbeddedChainer"; 69 private static readonly XName BundleAttributeElementName = WixNamespace + "BundleAttribute";
70 private static readonly XName BundleAttributeDefinitionElementName = WixNamespace + "BundleAttributeDefinition";
71 private static readonly XName BundleCustomDataElementName = WixNamespace + "BundleCustomData";
72 private static readonly XName BundleCustomDataRefElementName = WixNamespace + "BundleCustomDataRef";
73 private static readonly XName BundleElementElementName = WixNamespace + "BundleElement";
74 private static readonly XName CustomTableElementName = WixNamespace + "CustomTable";
75 private static readonly XName CustomTableRefElementName = WixNamespace + "CustomTableRef";
49 private static readonly XName CatalogElementName = WixNamespace + "Catalog"; 76 private static readonly XName CatalogElementName = WixNamespace + "Catalog";
50 private static readonly XName ColumnElementName = WixNamespace + "Column"; 77 private static readonly XName ColumnElementName = WixNamespace + "Column";
51 private static readonly XName ComponentElementName = WixNamespace + "Component"; 78 private static readonly XName ComponentElementName = WixNamespace + "Component";
52 private static readonly XName ControlElementName = WixNamespace + "Control"; 79 private static readonly XName ControlElementName = WixNamespace + "Control";
53 private static readonly XName ConditionElementName = WixNamespace + "Condition"; 80 private static readonly XName ConditionElementName = WixNamespace + "Condition";
54 private static readonly XName CreateFolderElementName = WixNamespace + "CreateFolder"; 81 private static readonly XName CreateFolderElementName = WixNamespace + "CreateFolder";
55 private static readonly XName CustomTableElementName = WixNamespace + "CustomTable";
56 private static readonly XName DataElementName = WixNamespace + "Data"; 82 private static readonly XName DataElementName = WixNamespace + "Data";
57 private static readonly XName OldProvidesElementName = WixDependencyNamespace + "Provides"; 83 private static readonly XName OldProvidesElementName = WixDependencyNamespace + "Provides";
58 private static readonly XName OldRequiresElementName = WixDependencyNamespace + "Requires"; 84 private static readonly XName OldRequiresElementName = WixDependencyNamespace + "Requires";
59 private static readonly XName OldRequiresRefElementName = WixDependencyNamespace + "RequiresRef"; 85 private static readonly XName OldRequiresRefElementName = WixDependencyNamespace + "RequiresRef";
60 private static readonly XName DirectoryElementName = WixNamespace + "Directory"; 86 private static readonly XName DirectoryElementName = WixNamespace + "Directory";
87 private static readonly XName EmbeddedChainerElementName = WixNamespace + "EmbeddedChainer";
61 private static readonly XName ErrorElementName = WixNamespace + "Error"; 88 private static readonly XName ErrorElementName = WixNamespace + "Error";
62 private static readonly XName FeatureElementName = WixNamespace + "Feature"; 89 private static readonly XName FeatureElementName = WixNamespace + "Feature";
63 private static readonly XName FileElementName = WixNamespace + "File"; 90 private static readonly XName FileElementName = WixNamespace + "File";
@@ -85,6 +112,7 @@ namespace WixToolset.Converters
85 private static readonly XName RemotePayloadElementName = WixNamespace + "RemotePayload"; 112 private static readonly XName RemotePayloadElementName = WixNamespace + "RemotePayload";
86 private static readonly XName RegistrySearchElementName = WixNamespace + "RegistrySearch"; 113 private static readonly XName RegistrySearchElementName = WixNamespace + "RegistrySearch";
87 private static readonly XName RequiredPrivilegeElementName = WixNamespace + "RequiredPrivilege"; 114 private static readonly XName RequiredPrivilegeElementName = WixNamespace + "RequiredPrivilege";
115 private static readonly XName RowElementName = WixNamespace + "Row";
88 private static readonly XName ServiceArgumentElementName = WixNamespace + "ServiceArgument"; 116 private static readonly XName ServiceArgumentElementName = WixNamespace + "ServiceArgument";
89 private static readonly XName SetDirectoryElementName = WixNamespace + "SetDirectory"; 117 private static readonly XName SetDirectoryElementName = WixNamespace + "SetDirectory";
90 private static readonly XName SetPropertyElementName = WixNamespace + "SetProperty"; 118 private static readonly XName SetPropertyElementName = WixNamespace + "SetProperty";
@@ -156,7 +184,8 @@ namespace WixToolset.Converters
156 /// <param name="indentationAmount">Indentation value to use when validating leading whitespace.</param> 184 /// <param name="indentationAmount">Indentation value to use when validating leading whitespace.</param>
157 /// <param name="errorsAsWarnings">Test errors to display as warnings.</param> 185 /// <param name="errorsAsWarnings">Test errors to display as warnings.</param>
158 /// <param name="ignoreErrors">Test errors to ignore.</param> 186 /// <param name="ignoreErrors">Test errors to ignore.</param>
159 public WixConverter(IMessaging messaging, int indentationAmount, IEnumerable<string> errorsAsWarnings = null, IEnumerable<string> ignoreErrors = null) 187 /// <param name="customTableTarget">How to convert CustomTable elements.</param>
188 public WixConverter(IMessaging messaging, int indentationAmount, IEnumerable<string> errorsAsWarnings = null, IEnumerable<string> ignoreErrors = null, CustomTableTarget customTableTarget = CustomTableTarget.Unknown)
160 { 189 {
161 this.ConvertElementMapping = new Dictionary<XName, Action<XElement>> 190 this.ConvertElementMapping = new Dictionary<XName, Action<XElement>>
162 { 191 {
@@ -170,9 +199,10 @@ namespace WixToolset.Converters
170 { WixConverter.ApprovedExeForElevationElementName, this.ConvertApprovedExeForElevationElement }, 199 { WixConverter.ApprovedExeForElevationElementName, this.ConvertApprovedExeForElevationElement },
171 { WixConverter.CatalogElementName, this.ConvertCatalogElement }, 200 { WixConverter.CatalogElementName, this.ConvertCatalogElement },
172 { WixConverter.ColumnElementName, this.ConvertColumnElement }, 201 { WixConverter.ColumnElementName, this.ConvertColumnElement },
173 { WixConverter.CustomTableElementName, this.ConvertCustomTableElement },
174 { WixConverter.ControlElementName, this.ConvertControlElement },
175 { WixConverter.ComponentElementName, this.ConvertComponentElement }, 202 { WixConverter.ComponentElementName, this.ConvertComponentElement },
203 { WixConverter.ControlElementName, this.ConvertControlElement },
204 { WixConverter.CustomActionElementName, this.ConvertCustomActionElement },
205 { WixConverter.CustomTableElementName, this.ConvertCustomTableElement },
176 { WixConverter.DataElementName, this.ConvertDataElement }, 206 { WixConverter.DataElementName, this.ConvertDataElement },
177 { WixConverter.DirectoryElementName, this.ConvertDirectoryElement }, 207 { WixConverter.DirectoryElementName, this.ConvertDirectoryElement },
178 { WixConverter.FeatureElementName, this.ConvertFeatureElement }, 208 { WixConverter.FeatureElementName, this.ConvertFeatureElement },
@@ -198,7 +228,6 @@ namespace WixToolset.Converters
198 { WixConverter.RegistrySearchElementName, this.ConvertRegistrySearchElement }, 228 { WixConverter.RegistrySearchElementName, this.ConvertRegistrySearchElement },
199 { WixConverter.RemotePayloadElementName, this.ConvertRemotePayloadElement }, 229 { WixConverter.RemotePayloadElementName, this.ConvertRemotePayloadElement },
200 { WixConverter.RequiredPrivilegeElementName, this.ConvertRequiredPrivilegeElement }, 230 { WixConverter.RequiredPrivilegeElementName, this.ConvertRequiredPrivilegeElement },
201 { WixConverter.CustomActionElementName, this.ConvertCustomActionElement },
202 { WixConverter.ServiceArgumentElementName, this.ConvertServiceArgumentElement }, 231 { WixConverter.ServiceArgumentElementName, this.ConvertServiceArgumentElement },
203 { WixConverter.SetDirectoryElementName, this.ConvertSetDirectoryElement }, 232 { WixConverter.SetDirectoryElementName, this.ConvertSetDirectoryElement },
204 { WixConverter.SetPropertyElementName, this.ConvertSetPropertyElement }, 233 { WixConverter.SetPropertyElementName, this.ConvertSetPropertyElement },
@@ -224,8 +253,12 @@ namespace WixToolset.Converters
224 this.ErrorsAsWarnings = new HashSet<ConverterTestType>(this.YieldConverterTypes(errorsAsWarnings)); 253 this.ErrorsAsWarnings = new HashSet<ConverterTestType>(this.YieldConverterTypes(errorsAsWarnings));
225 254
226 this.IgnoreErrors = new HashSet<ConverterTestType>(this.YieldConverterTypes(ignoreErrors)); 255 this.IgnoreErrors = new HashSet<ConverterTestType>(this.YieldConverterTypes(ignoreErrors));
256
257 this.CustomTableSetting = customTableTarget;
227 } 258 }
228 259
260 private CustomTableTarget CustomTableSetting { get; }
261
229 private int Errors { get; set; } 262 private int Errors { get; set; }
230 263
231 private HashSet<ConverterTestType> ErrorsAsWarnings { get; set; } 264 private HashSet<ConverterTestType> ErrorsAsWarnings { get; set; }
@@ -717,11 +750,104 @@ namespace WixToolset.Converters
717 private void ConvertCustomTableElement(XElement element) 750 private void ConvertCustomTableElement(XElement element)
718 { 751 {
719 var bootstrapperApplicationData = element.Attribute("BootstrapperApplicationData"); 752 var bootstrapperApplicationData = element.Attribute("BootstrapperApplicationData");
720 if (bootstrapperApplicationData != null 753 if (bootstrapperApplicationData?.Value == "no")
721 && this.OnError(ConverterTestType.BootstrapperApplicationDataDeprecated, element, "The CustomTable element contains deprecated '{0}' attribute. Use the 'Unreal' attribute instead.", bootstrapperApplicationData.Name)) 754 {
755 if (this.OnError(ConverterTestType.BootstrapperApplicationDataDeprecated, element, "The CustomTable element contains deprecated '{0}' attribute. Use the 'Unreal' attribute instead.", bootstrapperApplicationData.Name))
756 {
757 bootstrapperApplicationData.Remove();
758 }
759 }
760 else
761 {
762 if (element.Elements(ColumnElementName).Any() || bootstrapperApplicationData != null)
763 {
764 // Table definition
765 if (bootstrapperApplicationData != null)
766 {
767 switch (this.CustomTableSetting)
768 {
769 case CustomTableTarget.Bundle:
770 if (this.OnError(ConverterTestType.BootstrapperApplicationDataDeprecated, element, "The CustomTable element contains deprecated '{0}' attribute. Use the 'BundleCustomData' element for Bundles.", bootstrapperApplicationData.Name))
771 {
772 element.Name = WixConverter.BundleCustomDataElementName;
773 bootstrapperApplicationData.Remove();
774 this.ConvertCustomTableElementToBundle(element);
775 }
776 break;
777 case CustomTableTarget.Msi:
778 if (this.OnError(ConverterTestType.BootstrapperApplicationDataDeprecated, element, "The CustomTable element contains deprecated '{0}' attribute. Use the 'Unreal' attribute instead.", bootstrapperApplicationData.Name))
779 {
780 element.Add(new XAttribute("Unreal", bootstrapperApplicationData.Value));
781 bootstrapperApplicationData.Remove();
782 }
783 break;
784 default:
785 this.OnError(ConverterTestType.CustomTableNotAlwaysConvertable, element, "The CustomTable element contains deprecated '{0}' attribute so can't be converted. Use the 'Unreal' attribute for MSI. Use the 'BundleCustomData' element for Bundles. Use the --custom-table argument to force conversion to 'msi' or 'bundle'", bootstrapperApplicationData.Name);
786 break;
787 }
788 }
789 }
790 else
791 {
792 // Table ref
793 switch (this.CustomTableSetting)
794 {
795 case CustomTableTarget.Bundle:
796 if (this.OnError(ConverterTestType.CustomTableRef, element, "CustomTable elements that don't contain the table definition are now BundleCustomDataRef for Bundles."))
797 {
798 element.Name = WixConverter.BundleCustomDataRefElementName;
799 this.ConvertCustomTableElementToBundle(element);
800 }
801 break;
802 case CustomTableTarget.Msi:
803 if (this.OnError(ConverterTestType.CustomTableRef, element, "CustomTable elements that don't contain the table definition are now CustomTableRef for MSI."))
804 {
805 element.Name = WixConverter.CustomTableRefElementName;
806 }
807 break;
808 default:
809 this.OnError(ConverterTestType.CustomTableNotAlwaysConvertable, element, "The CustomTable element contains no 'Column' elements so can't be converted. Use the 'CustomTableRef' element for MSI. Use the 'BundleCustomDataRef' element for Bundles. Use the --custom-table argument to force conversion to 'msi' or 'bundle'");
810 break;
811 }
812 }
813 }
814 }
815
816 private void ConvertCustomTableElementToBundle(XElement element)
817 {
818 foreach (var xColumn in element.Elements(ColumnElementName))
722 { 819 {
723 element.Add(new XAttribute("Unreal", bootstrapperApplicationData.Value)); 820 xColumn.Name = WixConverter.BundleAttributeDefinitionElementName;
724 bootstrapperApplicationData.Remove(); 821
822 foreach (var xAttribute in xColumn.Attributes().ToList())
823 {
824 if (xAttribute.Name.LocalName != "Id" &&
825 (xAttribute.Name.Namespace == WixConverter.Wix3Namespace ||
826 xAttribute.Name.Namespace == WixConverter.WixNamespace ||
827 String.IsNullOrEmpty(xAttribute.Name.Namespace.NamespaceName)))
828 {
829 xAttribute.Remove();
830 }
831 }
832 }
833
834 foreach (var xRow in element.Elements(RowElementName))
835 {
836 xRow.Name = WixConverter.BundleElementElementName;
837
838 foreach (var xData in xRow.Elements(DataElementName))
839 {
840 xData.Name = WixConverter.BundleAttributeElementName;
841
842 var xColumn = xData.Attribute("Column");
843 if (xColumn != null)
844 {
845 xData.Add(new XAttribute("Id", xColumn.Value));
846 xColumn.Remove();
847 }
848
849 this.ConvertInnerTextToAttribute(xData, "Value");
850 }
725 } 851 }
726 } 852 }
727 853
@@ -1165,8 +1291,6 @@ namespace WixToolset.Converters
1165 1291
1166 private void ConvertRequiredPrivilegeElement(XElement element) => this.ConvertInnerTextToAttribute(element, "Name"); 1292 private void ConvertRequiredPrivilegeElement(XElement element) => this.ConvertInnerTextToAttribute(element, "Name");
1167 1293
1168 private void ConvertRowElement(XElement element) => this.ConvertInnerTextToAttribute(element, "Value");
1169
1170 private void ConvertDataElement(XElement element) => this.ConvertInnerTextToAttribute(element, "Value"); 1294 private void ConvertDataElement(XElement element) => this.ConvertInnerTextToAttribute(element, "Value");
1171 1295
1172 private void ConvertSequenceElement(XElement element) 1296 private void ConvertSequenceElement(XElement element)
@@ -1854,7 +1978,7 @@ namespace WixToolset.Converters
1854 AssignDirectoryNameFromShortName, 1978 AssignDirectoryNameFromShortName,
1855 1979
1856 /// <summary> 1980 /// <summary>
1857 /// BootstrapperApplicationData attribute is deprecated and replaced with Unreal. 1981 /// BootstrapperApplicationData attribute is deprecated and replaced with Unreal for MSI. Use BundleCustomData element for Bundles.
1858 /// </summary> 1982 /// </summary>
1859 BootstrapperApplicationDataDeprecated, 1983 BootstrapperApplicationDataDeprecated,
1860 1984
@@ -2022,6 +2146,16 @@ namespace WixToolset.Converters
2022 /// The hash algorithm used for bundles changed from SHA1 to SHA512. 2146 /// The hash algorithm used for bundles changed from SHA1 to SHA512.
2023 /// </summary> 2147 /// </summary>
2024 BurnHashAlgorithmChanged, 2148 BurnHashAlgorithmChanged,
2149
2150 /// <summary>
2151 /// CustomTable elements can't always be converted.
2152 /// </summary>
2153 CustomTableNotAlwaysConvertable,
2154
2155 /// <summary>
2156 /// CustomTable elements that don't contain the table definition are now CustomTableRef.
2157 /// </summary>
2158 CustomTableRef,
2025 } 2159 }
2026 } 2160 }
2027} 2161}
diff --git a/src/test/WixToolsetTest.Converters/CustomTableFixture.cs b/src/test/WixToolsetTest.Converters/CustomTableFixture.cs
index c51d1923..2b81a863 100644
--- a/src/test/WixToolsetTest.Converters/CustomTableFixture.cs
+++ b/src/test/WixToolsetTest.Converters/CustomTableFixture.cs
@@ -83,7 +83,7 @@ namespace WixToolsetTest.Converters
83 var converter = new WixConverter(messaging, 2, null, null); 83 var converter = new WixConverter(messaging, 2, null, null);
84 84
85 var errors = converter.ConvertDocument(document); 85 var errors = converter.ConvertDocument(document);
86 Assert.Equal(3, errors); 86 Assert.Equal(4, errors);
87 87
88 var actualLines = UnformattedDocumentLines(document); 88 var actualLines = UnformattedDocumentLines(document);
89 WixAssert.CompareLineByLine(expected, actualLines); 89 WixAssert.CompareLineByLine(expected, actualLines);
@@ -126,7 +126,7 @@ namespace WixToolsetTest.Converters
126 var converter = new WixConverter(messaging, 2, null, null); 126 var converter = new WixConverter(messaging, 2, null, null);
127 127
128 var errors = converter.ConvertDocument(document); 128 var errors = converter.ConvertDocument(document);
129 Assert.Equal(2, errors); 129 Assert.Equal(3, errors);
130 130
131 var actualLines = UnformattedDocumentLines(document); 131 var actualLines = UnformattedDocumentLines(document);
132 WixAssert.CompareLineByLine(expected, actualLines); 132 WixAssert.CompareLineByLine(expected, actualLines);
@@ -162,14 +162,154 @@ namespace WixToolsetTest.Converters
162 var converter = new WixConverter(messaging, 2, null, null); 162 var converter = new WixConverter(messaging, 2, null, null);
163 163
164 var errors = converter.ConvertDocument(document); 164 var errors = converter.ConvertDocument(document);
165 Assert.Equal(2, errors); 165 Assert.Equal(3, errors);
166 166
167 var actualLines = UnformattedDocumentLines(document); 167 var actualLines = UnformattedDocumentLines(document);
168 WixAssert.CompareLineByLine(expected, actualLines); 168 WixAssert.CompareLineByLine(expected, actualLines);
169 } 169 }
170 170
171 [Fact] 171 [Fact]
172 public void CanConvertCustomTableBootstrapperApplicationData() 172 public void CanConvertBundleCustomTableBootstrapperApplicationData()
173 {
174 var parse = String.Join(Environment.NewLine,
175 "<Wix xmlns='http://wixtoolset.org/schemas/v4/wxs'>",
176 " <CustomTable Id='FgAppx' BootstrapperApplicationData='yes'>",
177 " <Column Id='Column1' PrimaryKey='yes' Type='string' Width='0' Category='text' Description='The first custom column.' />",
178 " <Row>",
179 " <Data Column='Column1'>Row1</Data>",
180 " </Row>",
181 " </CustomTable>",
182 "</Wix>");
183
184 var expected = String.Join(Environment.NewLine,
185 "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
186 " <BundleCustomData Id=\"FgAppx\">",
187 " <BundleAttributeDefinition Id=\"Column1\" />",
188 " <BundleElement>",
189 " <BundleAttribute Id=\"Column1\" Value=\"Row1\" />",
190 " </BundleElement>",
191 " </BundleCustomData>",
192 "</Wix>");
193
194 var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
195
196 var messaging = new MockMessaging();
197 var converter = new WixConverter(messaging, 2, customTableTarget: CustomTableTarget.Bundle);
198
199 var errors = converter.ConvertDocument(document);
200
201 var actual = UnformattedDocumentString(document);
202
203 Assert.Equal(2, errors);
204 Assert.Equal(expected, actual);
205 }
206
207 [Fact]
208 public void CanConvertBundleCustomTableRef()
209 {
210 var parse = String.Join(Environment.NewLine,
211 "<Wix xmlns='http://wixtoolset.org/schemas/v4/wxs'>",
212 " <CustomTable Id='FgAppx'>",
213 " <Row>",
214 " <Data Column='Column1'>Row1</Data>",
215 " </Row>",
216 " </CustomTable>",
217 "</Wix>");
218
219 var expected = String.Join(Environment.NewLine,
220 "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
221 " <BundleCustomDataRef Id=\"FgAppx\">",
222 " <BundleElement>",
223 " <BundleAttribute Id=\"Column1\" Value=\"Row1\" />",
224 " </BundleElement>",
225 " </BundleCustomDataRef>",
226 "</Wix>");
227
228 var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
229
230 var messaging = new MockMessaging();
231 var converter = new WixConverter(messaging, 2, customTableTarget: CustomTableTarget.Bundle);
232
233 var errors = converter.ConvertDocument(document);
234
235 var actual = UnformattedDocumentString(document);
236
237 Assert.Equal(2, errors);
238 Assert.Equal(expected, actual);
239 }
240
241 [Fact]
242 public void CanConvertMsiCustomTableBootstrapperApplicationData()
243 {
244 var parse = String.Join(Environment.NewLine,
245 "<Wix xmlns='http://wixtoolset.org/schemas/v4/wxs'>",
246 " <CustomTable Id='FgAppx' BootstrapperApplicationData='yes'>",
247 " <Column Id='Column1' PrimaryKey='yes' Type='string' Width='0' Category='text' Description='The first custom column.' />",
248 " <Row>",
249 " <Data Column='Column1'>Row1</Data>",
250 " </Row>",
251 " </CustomTable>",
252 "</Wix>");
253
254 var expected = String.Join(Environment.NewLine,
255 "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
256 " <CustomTable Id=\"FgAppx\" Unreal=\"yes\">",
257 " <Column Id=\"Column1\" PrimaryKey=\"yes\" Type=\"string\" Width=\"0\" Category=\"text\" Description=\"The first custom column.\" />",
258 " <Row>",
259 " <Data Column=\"Column1\" Value=\"Row1\" />",
260 " </Row>",
261 " </CustomTable>",
262 "</Wix>");
263
264 var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
265
266 var messaging = new MockMessaging();
267 var converter = new WixConverter(messaging, 2, customTableTarget: CustomTableTarget.Msi);
268
269 var errors = converter.ConvertDocument(document);
270
271 var actual = UnformattedDocumentString(document);
272
273 Assert.Equal(2, errors);
274 Assert.Equal(expected, actual);
275 }
276
277 [Fact]
278 public void CanConvertMsiCustomTableRef()
279 {
280 var parse = String.Join(Environment.NewLine,
281 "<Wix xmlns='http://wixtoolset.org/schemas/v4/wxs'>",
282 " <CustomTable Id='FgAppx'>",
283 " <Row>",
284 " <Data Column='Column1'>Row1</Data>",
285 " </Row>",
286 " </CustomTable>",
287 "</Wix>");
288
289 var expected = String.Join(Environment.NewLine,
290 "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
291 " <CustomTableRef Id=\"FgAppx\">",
292 " <Row>",
293 " <Data Column=\"Column1\" Value=\"Row1\" />",
294 " </Row>",
295 " </CustomTableRef>",
296 "</Wix>");
297
298 var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
299
300 var messaging = new MockMessaging();
301 var converter = new WixConverter(messaging, 2, customTableTarget: CustomTableTarget.Msi);
302
303 var errors = converter.ConvertDocument(document);
304
305 var actual = UnformattedDocumentString(document);
306
307 Assert.Equal(2, errors);
308 Assert.Equal(expected, actual);
309 }
310
311 [Fact]
312 public void CanDetectAmbiguousCustomTableBootstrapperApplicationData()
173 { 313 {
174 var parse = String.Join(Environment.NewLine, 314 var parse = String.Join(Environment.NewLine,
175 "<Wix xmlns='http://wixtoolset.org/schemas/v4/wxs'>", 315 "<Wix xmlns='http://wixtoolset.org/schemas/v4/wxs'>",
@@ -178,13 +318,39 @@ namespace WixToolsetTest.Converters
178 318
179 var expected = String.Join(Environment.NewLine, 319 var expected = String.Join(Environment.NewLine,
180 "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">", 320 "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
181 " <CustomTable Id=\"FgAppx\" Unreal=\"yes\" />", 321 " <CustomTable Id=\"FgAppx\" BootstrapperApplicationData=\"yes\" />",
182 "</Wix>"); 322 "</Wix>");
183 323
184 var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo); 324 var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
185 325
186 var messaging = new MockMessaging(); 326 var messaging = new MockMessaging();
187 var converter = new WixConverter(messaging, 2, null, null); 327 var converter = new WixConverter(messaging, 2);
328
329 var errors = converter.ConvertDocument(document);
330
331 var actual = UnformattedDocumentString(document);
332
333 Assert.Equal(1, errors);
334 Assert.Equal(expected, actual);
335 }
336
337 [Fact]
338 public void CanRemoveBootstrapperApplicationDataFromRealCustomTable()
339 {
340 var parse = String.Join(Environment.NewLine,
341 "<Wix xmlns='http://wixtoolset.org/schemas/v4/wxs'>",
342 " <CustomTable Id='FgAppx' BootstrapperApplicationData='no' />",
343 "</Wix>");
344
345 var expected = String.Join(Environment.NewLine,
346 "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
347 " <CustomTable Id=\"FgAppx\" />",
348 "</Wix>");
349
350 var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
351
352 var messaging = new MockMessaging();
353 var converter = new WixConverter(messaging, 2);
188 354
189 var errors = converter.ConvertDocument(document); 355 var errors = converter.ConvertDocument(document);
190 356