aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2020-03-27 13:54:56 +1000
committerSean Hall <r.sean.hall@gmail.com>2020-03-30 21:30:04 +1000
commit0baf6e26ec7ab2ff0b6ad36e9d44f3d68819b5d6 (patch)
tree1ef577d0246b662f4a8bda0ed935e987f03562a0 /src/test
parentafbc6889c73d58136cb8851858ca3c17f41dc2c5 (diff)
downloadwix-0baf6e26ec7ab2ff0b6ad36e9d44f3d68819b5d6.tar.gz
wix-0baf6e26ec7ab2ff0b6ad36e9d44f3d68819b5d6.tar.bz2
wix-0baf6e26ec7ab2ff0b6ad36e9d44f3d68819b5d6.zip
Add ability for extensions to create custom bundle searches.
This required creating BundleExtensionData.xml.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/Example.Extension/Data/example.wxs3
-rw-r--r--src/test/Example.Extension/ExampleCompilerExtension.cs104
-rw-r--r--src/test/Example.Extension/ExampleExtensionData.cs6
-rw-r--r--src/test/Example.Extension/ExampleSearchTuple.cs31
-rw-r--r--src/test/Example.Extension/ExampleTupleDefinitions.cs17
-rw-r--r--src/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs56
-rw-r--r--src/test/WixToolsetTest.CoreIntegration/TestData/BundleExtension/BundleExtensionSearches.wxs8
-rw-r--r--src/test/WixToolsetTest.CoreIntegration/TestData/BundleExtension/BundleWithSearches.wxs11
-rw-r--r--src/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj2
9 files changed, 236 insertions, 2 deletions
diff --git a/src/test/Example.Extension/Data/example.wxs b/src/test/Example.Extension/Data/example.wxs
index cb100adf..cd17d478 100644
--- a/src/test/Example.Extension/Data/example.wxs
+++ b/src/test/Example.Extension/Data/example.wxs
@@ -8,4 +8,7 @@
8 <Fragment> 8 <Fragment>
9 <BootstrapperApplication Id="fakeba" SourceFile="example.txt" /> 9 <BootstrapperApplication Id="fakeba" SourceFile="example.txt" />
10 </Fragment> 10 </Fragment>
11 <Fragment>
12 <BundleExtension Id="ExampleBundleExtension" SourceFile="example.txt" />
13 </Fragment>
11</Wix> 14</Wix>
diff --git a/src/test/Example.Extension/ExampleCompilerExtension.cs b/src/test/Example.Extension/ExampleCompilerExtension.cs
index 5efb428f..543b4165 100644
--- a/src/test/Example.Extension/ExampleCompilerExtension.cs
+++ b/src/test/Example.Extension/ExampleCompilerExtension.cs
@@ -11,6 +11,7 @@ namespace Example.Extension
11 internal class ExampleCompilerExtension : BaseCompilerExtension 11 internal class ExampleCompilerExtension : BaseCompilerExtension
12 { 12 {
13 public override XNamespace Namespace => "http://www.example.com/scheams/v1/wxs"; 13 public override XNamespace Namespace => "http://www.example.com/scheams/v1/wxs";
14 public string BundleExtensionId => "ExampleBundleExtension";
14 15
15 public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context) 16 public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
16 { 17 {
@@ -18,6 +19,20 @@ namespace Example.Extension
18 19
19 switch (parentElement.Name.LocalName) 20 switch (parentElement.Name.LocalName)
20 { 21 {
22 case "Bundle":
23 case "Fragment":
24 switch (element.Name.LocalName)
25 {
26 case "ExampleSearch":
27 this.ParseExampleSearchElement(intermediate, section, element);
28 processed = true;
29 break;
30 case "ExampleSearchRef":
31 this.ParseExampleSearchRefElement(intermediate, section, element);
32 processed = true;
33 break;
34 }
35 break;
21 case "Component": 36 case "Component":
22 switch (element.Name.LocalName) 37 switch (element.Name.LocalName)
23 { 38 {
@@ -77,5 +92,94 @@ namespace Example.Extension
77 tuple.Set(1, value); 92 tuple.Set(1, value);
78 } 93 }
79 } 94 }
95
96 private void ParseExampleSearchElement(Intermediate intermediate, IntermediateSection section, XElement element)
97 {
98 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
99 Identifier id = null;
100 string searchFor = null;
101 string variable = null;
102 string condition = null;
103 string after = null;
104
105 foreach (var attrib in element.Attributes())
106 {
107 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
108 {
109 switch (attrib.Name.LocalName)
110 {
111 case "Id":
112 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
113 break;
114 case "Variable":
115 variable = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
116 break;
117 case "Condition":
118 condition = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
119 break;
120 case "After":
121 after = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
122 break;
123 case "SearchFor":
124 searchFor = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
125 break;
126
127 default:
128 this.ParseHelper.UnexpectedAttribute(element, attrib);
129 break;
130 }
131 }
132 else
133 {
134 this.ParseAttribute(intermediate, section, element, attrib, null);
135 }
136 }
137
138 if (null == id)
139 {
140 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id"));
141 }
142
143 if (!this.Messaging.EncounteredError)
144 {
145 this.ParseHelper.CreateWixSearchTuple(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, this.BundleExtensionId);
146 }
147
148 if (!this.Messaging.EncounteredError)
149 {
150
151 var tuple = new ExampleSearchTuple(sourceLineNumbers, id);
152 section.Tuples.Add(tuple);
153 tuple.SearchFor = searchFor;
154 }
155 }
156
157 private void ParseExampleSearchRefElement(Intermediate intermediate, IntermediateSection section, XElement element)
158 {
159 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
160
161 foreach (var attrib in element.Attributes())
162 {
163 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
164 {
165 switch (attrib.Name.LocalName)
166 {
167 case "Id":
168 var refId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
169 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "ExampleSearch", refId);
170 break;
171 default:
172 this.ParseHelper.UnexpectedAttribute(element, attrib);
173 break;
174 }
175 }
176 else
177 {
178 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
179 }
180 }
181
182 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
183 }
80 } 184 }
81} 185}
diff --git a/src/test/Example.Extension/ExampleExtensionData.cs b/src/test/Example.Extension/ExampleExtensionData.cs
index de0b8899..b38eb2a2 100644
--- a/src/test/Example.Extension/ExampleExtensionData.cs
+++ b/src/test/Example.Extension/ExampleExtensionData.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 Example.Extension 3namespace Example.Extension
4{ 4{
@@ -22,6 +22,10 @@ namespace Example.Extension
22 tupleDefinition = ExampleTupleDefinitions.Example; 22 tupleDefinition = ExampleTupleDefinitions.Example;
23 break; 23 break;
24 24
25 case "ExampleSearch":
26 tupleDefinition = ExampleTupleDefinitions.ExampleSearch;
27 break;
28
25 default: 29 default:
26 tupleDefinition = null; 30 tupleDefinition = null;
27 break; 31 break;
diff --git a/src/test/Example.Extension/ExampleSearchTuple.cs b/src/test/Example.Extension/ExampleSearchTuple.cs
new file mode 100644
index 00000000..df34f0af
--- /dev/null
+++ b/src/test/Example.Extension/ExampleSearchTuple.cs
@@ -0,0 +1,31 @@
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
3namespace Example.Extension
4{
5 using WixToolset.Data;
6
7 public enum ExampleSearchTupleFields
8 {
9 Example,
10 SearchFor,
11 }
12
13 public class ExampleSearchTuple : IntermediateTuple
14 {
15 public ExampleSearchTuple() : base(ExampleTupleDefinitions.ExampleSearch, null, null)
16 {
17 }
18
19 public ExampleSearchTuple(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ExampleTupleDefinitions.ExampleSearch, sourceLineNumber, id)
20 {
21 }
22
23 public IntermediateField this[ExampleTupleFields index] => this.Fields[(int)index];
24
25 public string SearchFor
26 {
27 get => this.Fields[(int)ExampleSearchTupleFields.SearchFor]?.AsString();
28 set => this.Set((int)ExampleSearchTupleFields.SearchFor, value);
29 }
30 }
31}
diff --git a/src/test/Example.Extension/ExampleTupleDefinitions.cs b/src/test/Example.Extension/ExampleTupleDefinitions.cs
index 4775b827..b2c8c484 100644
--- a/src/test/Example.Extension/ExampleTupleDefinitions.cs
+++ b/src/test/Example.Extension/ExampleTupleDefinitions.cs
@@ -1,8 +1,9 @@
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 Example.Extension 3namespace Example.Extension
4{ 4{
5 using WixToolset.Data; 5 using WixToolset.Data;
6 using WixToolset.Data.Burn;
6 7
7 public static class ExampleTupleDefinitions 8 public static class ExampleTupleDefinitions
8 { 9 {
@@ -16,5 +17,19 @@ namespace Example.Extension
16 new IntermediateFieldDefinition(nameof(ExampleTupleFields.Value), IntermediateFieldType.String), 17 new IntermediateFieldDefinition(nameof(ExampleTupleFields.Value), IntermediateFieldType.String),
17 }, 18 },
18 typeof(ExampleTuple)); 19 typeof(ExampleTuple));
20
21 public static readonly IntermediateTupleDefinition ExampleSearch = new IntermediateTupleDefinition(
22 nameof(ExampleSearch),
23 new[]
24 {
25 new IntermediateFieldDefinition(nameof(ExampleTupleFields.Example), IntermediateFieldType.String),
26 new IntermediateFieldDefinition(nameof(ExampleSearchTupleFields.SearchFor), IntermediateFieldType.String),
27 },
28 typeof(ExampleSearchTuple));
29
30 static ExampleTupleDefinitions()
31 {
32 ExampleSearch.AddTag(BurnConstants.BundleExtensionSearchTupleDefinitionTag);
33 }
19 } 34 }
20} 35}
diff --git a/src/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs b/src/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs
index da4482ff..80f7b875 100644
--- a/src/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs
+++ b/src/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs
@@ -2,8 +2,10 @@
2 2
3namespace WixToolsetTest.CoreIntegration 3namespace WixToolsetTest.CoreIntegration
4{ 4{
5 using System;
5 using System.Collections.Generic; 6 using System.Collections.Generic;
6 using System.IO; 7 using System.IO;
8 using Example.Extension;
7 using WixBuildTools.TestSupport; 9 using WixBuildTools.TestSupport;
8 using WixToolset.Core.TestPackage; 10 using WixToolset.Core.TestPackage;
9 using Xunit; 11 using Xunit;
@@ -57,5 +59,59 @@ namespace WixToolsetTest.CoreIntegration
57 Assert.Equal("<Payload Id='ExampleBext' FilePath='fakebext.dll' FileSize='*' Hash='*' Packaging='embedded' SourcePath='*' />", bundleExtensionPayloads[0].GetTestXml(ignored)); 59 Assert.Equal("<Payload Id='ExampleBext' FilePath='fakebext.dll' FileSize='*' Hash='*' Packaging='embedded' SourcePath='*' />", bundleExtensionPayloads[0].GetTestXml(ignored));
58 } 60 }
59 } 61 }
62
63 [Fact]
64 public void PopulatesManifestWithBundleExtensionSearches()
65 {
66 var burnStubPath = TestData.Get(@"TestData\.Data\burn.exe");
67 var extensionPath = Path.GetFullPath(new Uri(typeof(ExampleExtensionFactory).Assembly.CodeBase).LocalPath);
68 var folder = TestData.Get(@"TestData");
69
70 using (var fs = new DisposableFileSystem())
71 {
72 var baseFolder = fs.GetFolder();
73 var intermediateFolder = Path.Combine(baseFolder, "obj");
74 var bundlePath = Path.Combine(baseFolder, @"bin\test.exe");
75 var baFolderPath = Path.Combine(baseFolder, "ba");
76 var extractFolderPath = Path.Combine(baseFolder, "extract");
77
78 var result = WixRunner.Execute(new[]
79 {
80 "build",
81 Path.Combine(folder, "BundleExtension", "BundleExtensionSearches.wxs"),
82 Path.Combine(folder, "BundleExtension", "BundleWithSearches.wxs"),
83 Path.Combine(folder, "BundleWithPackageGroupRef", "MinimalPackageGroup.wxs"),
84 Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"),
85 "-ext", extensionPath,
86 "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
87 "-intermediateFolder", intermediateFolder,
88 "-burnStub", burnStubPath,
89 "-o", bundlePath
90 });
91
92 result.AssertSuccess();
93
94 Assert.True(File.Exists(bundlePath));
95
96 var extractResult = BundleExtractor.ExtractBAContainer(null, bundlePath, baFolderPath, extractFolderPath);
97 extractResult.AssertSuccess();
98
99 var bundleExtensions = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:BundleExtension");
100 Assert.Equal(1, bundleExtensions.Count);
101 Assert.Equal("<BundleExtension Id='ExampleBundleExtension' EntryPayloadId='ExampleBundleExtension' />", bundleExtensions[0].GetTestXml());
102
103 var extensionSearches = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:ExtensionSearch");
104 Assert.Equal(2, extensionSearches.Count);
105 Assert.Equal("<ExtensionSearch Id='ExampleSearchBar' Variable='SearchBar' Condition='WixBundleInstalled' ExtensionId='ExampleBundleExtension' />", extensionSearches[0].GetTestXml());
106 Assert.Equal("<ExtensionSearch Id='ExampleSearchFoo' Variable='SearchFoo' ExtensionId='ExampleBundleExtension' />", extensionSearches[1].GetTestXml());
107
108 var bundleExtensionDatas = extractResult.SelectBundleExtensionDataNodes("/be:BundleExtensionData/be:BundleExtension[@Id='ExampleBundleExtension']");
109 Assert.Equal(1, bundleExtensionDatas.Count);
110 Assert.Equal("<BundleExtension Id='ExampleBundleExtension'>" +
111 "<ExampleSearch Id='ExampleSearchBar' SearchFor='Bar' />" +
112 "<ExampleSearch Id='ExampleSearchFoo' SearchFor='Foo' />" +
113 "</BundleExtension>", bundleExtensionDatas[0].GetTestXml());
114 }
115 }
60 } 116 }
61} 117}
diff --git a/src/test/WixToolsetTest.CoreIntegration/TestData/BundleExtension/BundleExtensionSearches.wxs b/src/test/WixToolsetTest.CoreIntegration/TestData/BundleExtension/BundleExtensionSearches.wxs
new file mode 100644
index 00000000..fd8d3698
--- /dev/null
+++ b/src/test/WixToolsetTest.CoreIntegration/TestData/BundleExtension/BundleExtensionSearches.wxs
@@ -0,0 +1,8 @@
1<?xml version="1.0" encoding="utf-8"?>
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
3 xmlns:ex="http://www.example.com/scheams/v1/wxs">
4 <Fragment>
5 <ex:ExampleSearch Id="ExampleSearchBar" Variable="SearchBar" Condition="WixBundleInstalled" SearchFor="Bar" />
6 <ex:ExampleSearch Id="ExampleSearchFoo" Variable="SearchFoo" SearchFor="Foo" />
7 </Fragment>
8</Wix>
diff --git a/src/test/WixToolsetTest.CoreIntegration/TestData/BundleExtension/BundleWithSearches.wxs b/src/test/WixToolsetTest.CoreIntegration/TestData/BundleExtension/BundleWithSearches.wxs
new file mode 100644
index 00000000..c5a93eb3
--- /dev/null
+++ b/src/test/WixToolsetTest.CoreIntegration/TestData/BundleExtension/BundleWithSearches.wxs
@@ -0,0 +1,11 @@
1<?xml version="1.0" encoding="utf-8"?>
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
3 xmlns:ex="http://www.example.com/scheams/v1/wxs">
4 <Fragment>
5 <PackageGroup Id="BundlePackages">
6 <PackageGroupRef Id="MinimalPackageGroup" />
7 </PackageGroup>
8
9 <ex:ExampleSearchRef Id="ExampleSearchFoo" />
10 </Fragment>
11</Wix>
diff --git a/src/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj b/src/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj
index 85538b79..324d04ff 100644
--- a/src/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj
+++ b/src/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj
@@ -22,6 +22,8 @@
22 <Content Include="TestData\AppSearch\NestedDirSearchUnderRegSearch.msi" CopyToOutputDirectory="PreserveNewest" /> 22 <Content Include="TestData\AppSearch\NestedDirSearchUnderRegSearch.msi" CopyToOutputDirectory="PreserveNewest" />
23 <Content Include="TestData\AppSearch\RegistrySearch.wxs" CopyToOutputDirectory="PreserveNewest" /> 23 <Content Include="TestData\AppSearch\RegistrySearch.wxs" CopyToOutputDirectory="PreserveNewest" />
24 <Content Include="TestData\BundleExtension\BundleExtension.wxs" CopyToOutputDirectory="PreserveNewest" /> 24 <Content Include="TestData\BundleExtension\BundleExtension.wxs" CopyToOutputDirectory="PreserveNewest" />
25 <Content Include="TestData\BundleExtension\BundleExtensionSearches.wxs" CopyToOutputDirectory="PreserveNewest" />
26 <Content Include="TestData\BundleExtension\BundleWithSearches.wxs" CopyToOutputDirectory="PreserveNewest" />
25 <Content Include="TestData\BundleExtension\SimpleBundleExtension.wxs" CopyToOutputDirectory="PreserveNewest" /> 27 <Content Include="TestData\BundleExtension\SimpleBundleExtension.wxs" CopyToOutputDirectory="PreserveNewest" />
26 <Content Include="TestData\BundleWithPackageGroupRef\Bundle.wxs" CopyToOutputDirectory="PreserveNewest" /> 28 <Content Include="TestData\BundleWithPackageGroupRef\Bundle.wxs" CopyToOutputDirectory="PreserveNewest" />
27 <Content Include="TestData\BundleWithPackageGroupRef\MinimalPackageGroup.wxs" CopyToOutputDirectory="PreserveNewest" /> 29 <Content Include="TestData\BundleWithPackageGroupRef\MinimalPackageGroup.wxs" CopyToOutputDirectory="PreserveNewest" />