/// <summary> /// Run a Compare unit test. /// </summary> /// <param name="element">The unit test element.</param> /// <param name="previousUnitResults">The previous unit test results.</param> /// <param name="update">Indicates whether to give the user the option to fix a failing test.</param> /// <param name="args">The command arguments passed to WixUnit.</param> public static void RunUnitTest(XmlElement element, UnitResults previousUnitResults, bool update, ICommandArgs args) { string file1 = Environment.ExpandEnvironmentVariables(element.GetAttribute("File1")); string file2 = Environment.ExpandEnvironmentVariables(element.GetAttribute("File2")); string testName = element.ParentNode.Attributes["Name"].Value; // Check the results ArrayList differences = CompareUnit.CompareResults(file1, file2, testName, update); previousUnitResults.Errors.AddRange(differences); previousUnitResults.Output.AddRange(differences); }
/// <summary> /// Compare two result files and update the expected result if specified /// </summary> /// <param name="expectedResult">The expected result file.</param> /// <param name="actualResult">The actual result file.</param> /// <param name="testName">The name of the test.</param> /// <param name="update">If true, update the expected result with the actual result.</param> /// <returns>Any differences found</returns> public static ArrayList CompareResults(string expectedResult, string actualResult, string testName, bool update) { ArrayList differences = CompareUnit.CompareResults(expectedResult, actualResult); // Update the test if (0 < differences.Count && update) { bool isUpdated = CompareUnit.UpdateTest(expectedResult, actualResult, testName, differences); if (isUpdated) { // CompareResults again to verify that there are now no differences differences = CompareResults(expectedResult, actualResult); } } return(differences); }
/// <summary> /// Run a Wixproj unit test. /// </summary> /// <param name="element">The unit test element.</param> /// <param name="previousUnitResults">The previous unit test results.</param> /// <param name="verbose">The level of verbosity for the MSBuild logging.</param> /// <param name="skipValidation">Tells light to skip validation.</param> /// <param name="update">Indicates whether to give the user the option to fix a failing test.</param> /// <param name="args">The command arguments passed to WixUnit.</param> public static void RunUnitTest(XmlElement element, UnitResults previousUnitResults, bool verbose, bool skipValidation, bool update, ICommandArgs args) { string arguments = element.GetAttribute("Arguments"); string expectedErrors = element.GetAttribute("ExpectedErrors"); string expectedResult = element.GetAttribute("ExpectedResult"); string expectedWarnings = element.GetAttribute("ExpectedWarnings"); string extensions = element.GetAttribute("Extensions"); bool noOutputName = XmlConvert.ToBoolean(element.GetAttribute("NoOutputName")); bool noOutputPath = XmlConvert.ToBoolean(element.GetAttribute("NoOutputPath")); bool defineSolutionProperties = XmlConvert.ToBoolean(element.GetAttribute("DefineSolutionProperties")); string suppressExtensions = element.GetAttribute("SuppressExtensions"); string tempDirectory = element.GetAttribute("TempDirectory"); string testName = element.ParentNode.Attributes["Name"].Value; string toolsDirectory = element.GetAttribute("ToolsDirectory"); string msBuildDirectory = Environment.GetEnvironmentVariable("WixTestMSBuildDirectory"); string msBuildToolsVersion = Environment.GetEnvironmentVariable("WixTestMSBuildToolsVersion"); // check the combinations of attributes if (expectedErrors.Length > 0 && expectedResult.Length > 0) { throw new WixException(WixErrors.IllegalAttributeWithOtherAttribute(null, element.Name, "ExpectedErrors", "ExpectedResult")); } // we'll run MSBuild on the .wixproj to generate the output if (null == msBuildDirectory) { msBuildDirectory = Path.Combine(Environment.GetEnvironmentVariable("SystemRoot"), @"Microsoft.NET\Framework\v3.5"); } string toolFile = Path.Combine(msBuildDirectory, "MSBuild.exe"); StringBuilder commandLine = new StringBuilder(arguments); // rebuild by default commandLine.AppendFormat(" /target:Rebuild /verbosity:{0}", verbose ? "detailed" : "normal"); if (skipValidation) { commandLine.Append(" /property:SuppressValidation=true"); } // add DefineSolutionProperties commandLine.AppendFormat(" /property:DefineSolutionProperties={0}", defineSolutionProperties); // make sure the tools directory ends in a single backslash if (toolsDirectory[toolsDirectory.Length - 1] != Path.DirectorySeparatorChar) { toolsDirectory = String.Concat(toolsDirectory, Path.DirectorySeparatorChar); } // handle the wix-specific directories and files commandLine.AppendFormat(" /property:WixToolPath=\"{0}\\\"", toolsDirectory); commandLine.AppendFormat(" /property:WixExtDir=\"{0}\\\"", toolsDirectory); commandLine.AppendFormat(" /property:WixTargetsPath=\"{0}\"", Path.Combine(toolsDirectory, "wix.targets")); commandLine.AppendFormat(" /property:WixTasksPath=\"{0}\"", Path.Combine(toolsDirectory, "WixTasks.dll")); commandLine.AppendFormat(" /property:BaseIntermediateOutputPath=\"{0}\\\\\"", Path.Combine(tempDirectory, "obj")); // handle extensions string[] suppressedExtensionArray = suppressExtensions.Split(';'); StringBuilder extensionsToUse = new StringBuilder(); foreach (string extension in extensions.Split(';')) { if (0 > Array.BinarySearch(suppressedExtensionArray, extension)) { if (extensionsToUse.Length > 0) { extensionsToUse.Append(";"); } extensionsToUse.Append(extension); } } commandLine.AppendFormat(" /property:WixExtension=\"{0}\"", extensionsToUse.ToString()); previousUnitResults.OutputFiles.Clear(); // handle the source file string sourceFile = element.GetAttribute("SourceFile").Trim(); // handle the expected result output file string outputFile; if (expectedResult.Length > 0) { outputFile = Path.Combine(tempDirectory, Path.GetFileName(expectedResult)); } else { outputFile = Path.Combine(tempDirectory, "ShouldNotBeCreated.msi"); } if (!noOutputName) { commandLine.AppendFormat(" /property:OutputName=\"{0}\"", Path.GetFileNameWithoutExtension(outputFile)); } if (!noOutputPath) { commandLine.AppendFormat(" /property:OutputPath=\"{0}\\\\\"", Path.GetDirectoryName(outputFile)); } previousUnitResults.OutputFiles.Add(outputFile); if (!String.IsNullOrEmpty(msBuildToolsVersion)) { commandLine.AppendFormat(" /tv:{0}", msBuildToolsVersion); } // add the source file as the last parameter commandLine.AppendFormat(" \"{0}\"", sourceFile); // run one msbuild process at a time due to multiproc issues ArrayList output = null; try { mutex.WaitOne(); output = ToolUtility.RunTool(toolFile, commandLine.ToString()); } finally { mutex.ReleaseMutex(); } previousUnitResults.Errors.AddRange(ToolUtility.GetErrors(output, expectedErrors, expectedWarnings)); previousUnitResults.Output.AddRange(output); // check the output file if (previousUnitResults.Errors.Count == 0) { if (expectedResult.Length > 0) { ArrayList differences = CompareUnit.CompareResults(expectedResult, outputFile, testName, update); previousUnitResults.Errors.AddRange(differences); previousUnitResults.Output.AddRange(differences); } else if (expectedErrors.Length > 0 && File.Exists(outputFile)) // ensure the output doesn't exist { string error = String.Format(CultureInfo.InvariantCulture, "Expected failure, but the unit test created output file \"{0}\".", outputFile); previousUnitResults.Errors.Add(error); previousUnitResults.Output.Add(error); } } }
/// <summary> /// Run a Pyro unit test. /// </summary> /// <param name="element">The unit test element.</param> /// <param name="previousUnitResults">The previous unit test results.</param> /// <param name="update">Indicates whether to give the user the option to fix a failing test.</param> /// <param name="args">The command arguments passed to WixUnit.</param> public static void RunUnitTest(XmlElement element, UnitResults previousUnitResults, bool update, ICommandArgs args) { string arguments = element.GetAttribute("Arguments"); string expectedErrors = element.GetAttribute("ExpectedErrors"); string expectedResult = element.GetAttribute("ExpectedResult"); string expectedWarnings = element.GetAttribute("ExpectedWarnings"); string extensions = element.GetAttribute("Extensions"); string inputFile = element.GetAttribute("InputFile"); string outputFile = element.GetAttribute("OutputFile"); string tempDirectory = element.GetAttribute("TempDirectory"); string testName = element.ParentNode.Attributes["Name"].Value; string toolsDirectory = element.GetAttribute("ToolsDirectory"); if (null == inputFile || String.Empty == inputFile) { throw new WixException(WixErrors.IllegalEmptyAttributeValue(null, element.Name, "InputFile")); } if (null == outputFile || String.Empty == outputFile) { throw new WixException(WixErrors.IllegalEmptyAttributeValue(null, element.Name, "OutputFile")); } // After Pyro is run, verify that this file was not created if (0 < expectedErrors.Length) { outputFile = Path.Combine(tempDirectory, "ShouldNotBeCreated.msp"); } string toolFile = Path.Combine(toolsDirectory, "pyro.exe"); StringBuilder commandLine = new StringBuilder(arguments); commandLine.AppendFormat(" \"{0}\" -out \"{1}\"", inputFile, outputFile); previousUnitResults.OutputFiles.Add(outputFile); // handle extensions if (!String.IsNullOrEmpty(extensions)) { foreach (string extension in extensions.Split(';')) { commandLine.AppendFormat(" -ext \"{0}\"", extension); } } // handle wixunit arguments if (args.NoTidy) { commandLine.Append(" -notidy"); } // handle child elements foreach (XmlNode node in element.ChildNodes) { if (node.NodeType == XmlNodeType.Element) { switch (node.LocalName) { case "Transform": string transformFile = node.Attributes["File"].Value; string baseline = node.Attributes["Baseline"].Value; commandLine.AppendFormat(" -t {0} \"{1}\"", baseline, transformFile); break; default: break; } } } // run the tool ArrayList output = ToolUtility.RunTool(toolFile, commandLine.ToString()); previousUnitResults.Errors.AddRange(ToolUtility.GetErrors(output, expectedErrors, expectedWarnings)); previousUnitResults.Output.AddRange(output); // check the output file if (0 == previousUnitResults.Errors.Count) { if (0 < expectedResult.Length) { ArrayList differences = CompareUnit.CompareResults(expectedResult, outputFile, testName, update); previousUnitResults.Errors.AddRange(differences); previousUnitResults.Output.AddRange(differences); } else if (0 < expectedErrors.Length && File.Exists(outputFile)) // ensure the output doesn't exist { string error = String.Format(CultureInfo.InvariantCulture, "Expected failure, but the unit test created output file \"{0}\".", outputFile); previousUnitResults.Errors.Add(error); previousUnitResults.Output.Add(error); } } }
/// <summary> /// Compare two result files. /// </summary> /// <param name="expectedResult">The expected result file.</param> /// <param name="actualResult">The actual result file.</param> /// <returns>Any differences found.</returns> public static ArrayList CompareResults(string expectedResult, string actualResult) { ArrayList differences = new ArrayList(); Output targetOutput; Output updatedOutput; OutputType outputType; string extension = Path.GetExtension(expectedResult); if (String.Compare(extension, ".msi", true, CultureInfo.InvariantCulture) == 0) { outputType = OutputType.Product; } else if (String.Compare(extension, ".msm", true, CultureInfo.InvariantCulture) == 0) { outputType = OutputType.Module; } else if (String.Compare(extension, ".msp", true, CultureInfo.InvariantCulture) == 0) { outputType = OutputType.Patch; } else if (String.Compare(extension, ".mst", true, CultureInfo.InvariantCulture) == 0) { outputType = OutputType.Transform; } else if (String.Compare(extension, ".pcp", true, CultureInfo.InvariantCulture) == 0) { outputType = OutputType.PatchCreation; } else if (String.Compare(extension, ".wixout", true, CultureInfo.InvariantCulture) == 0) { outputType = OutputType.Unknown; } else { throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Cannot determine the type of msi database file based on file extension '{0}'.", extension)); } if (outputType != OutputType.Unknown) { Unbinder unbinder = new Unbinder(); unbinder.SuppressDemodularization = true; // don't allow concurrent calls to Unbind try { mutex.WaitOne(); targetOutput = unbinder.Unbind(expectedResult, outputType, null); updatedOutput = unbinder.Unbind(actualResult, outputType, null); unbinder.DeleteTempFiles(); } finally { mutex.ReleaseMutex(); } } else { targetOutput = Output.Load(expectedResult, false, false); updatedOutput = Output.Load(actualResult, false, false); } differences.AddRange(CompareOutput(targetOutput, updatedOutput)); // If the Output type is a Patch, then compare the patch's transforms if (outputType == OutputType.Patch) { // Compare transforms foreach (SubStorage targetTransform in targetOutput.SubStorages) { SubStorage updatedTransform = null; // Find the same transform in the other patch foreach (SubStorage transform in updatedOutput.SubStorages) { if (transform.Name == targetTransform.Name) { updatedTransform = transform; break; } } if (null != updatedTransform) { // Both patch's have this transform ArrayList transformDifferences = CompareUnit.CompareOutput(targetTransform.Data, updatedTransform.Data); // add a description of the transforms being compared if (0 < transformDifferences.Count) { transformDifferences.Insert(0, String.Concat("Differences found while comparing the transform ", targetTransform.Name, " from the two patches")); differences.AddRange(transformDifferences); } } else { differences.Add(String.Format("The {0} tranform has been dropped", targetTransform.Name)); } } // Check if the updated patch has had transforms added foreach (SubStorage updatedTransform in updatedOutput.SubStorages) { SubStorage targetTransform = null; foreach (SubStorage transform in targetOutput.SubStorages) { if (transform.Name == updatedTransform.Name) { targetTransform = transform; break; } } if (targetTransform == null) { differences.Add(String.Format("The {0} tranform has been added", updatedTransform.Name)); } } } // add a description of the files being compared if (0 < differences.Count) { differences.Insert(0, "Differences found while comparing:"); differences.Insert(1, expectedResult); differences.Insert(2, actualResult); } return(differences); }
/// <summary> /// Run a Light unit test. /// </summary> /// <param name="element">The unit test element.</param> /// <param name="previousUnitResults">The previous unit test results.</param> /// <param name="update">Indicates whether to give the user the option to fix a failing test.</param> /// <param name="args">The command arguments passed to WixUnit.</param> public static void RunUnitTest(XmlElement element, UnitResults previousUnitResults, bool update, ICommandArgs args) { string arguments = element.GetAttribute("Arguments"); string expectedErrors = element.GetAttribute("ExpectedErrors"); string expectedResult = element.GetAttribute("ExpectedResult"); string expectedWarnings = element.GetAttribute("ExpectedWarnings"); string extensions = element.GetAttribute("Extensions"); string outputFile = element.GetAttribute("OutputFile"); string intermediateOutputType = element.GetAttribute("IntermediateOutputType"); string suppressExtensions = element.GetAttribute("SuppressExtensions"); string tempDirectory = element.GetAttribute("TempDirectory"); string testName = element.ParentNode.Attributes["Name"].Value; string toolsDirectory = element.GetAttribute("ToolsDirectory"); bool usePreviousOutput = ("true" == element.GetAttribute("UsePreviousOutput")); if (expectedErrors.Length == 0 && expectedResult.Length == 0 && intermediateOutputType.Length == 0 && outputFile.Length == 0) { throw new WixException(WixErrors.ExpectedAttributes(null, element.Name, "ExpectedErrors", "ExpectedResult", "IntermediateOutputType", "OutputFile", null)); } if (expectedErrors.Length > 0 && (expectedResult.Length > 0 || intermediateOutputType.Length > 0 || outputFile.Length > 0)) { throw new WixException(WixErrors.IllegalAttributeWithOtherAttributes(null, element.Name, "ExpectedErrors", "ExpectedResult", "IntermediateOutputType", "OutputFile", null)); } else if (expectedResult.Length > 0 && (intermediateOutputType.Length > 0 || outputFile.Length > 0)) { throw new WixException(WixErrors.IllegalAttributeWithOtherAttributes(null, element.Name, "ExpectedResult", "IntermediateOutputType", "OutputFile")); } else if (intermediateOutputType.Length > 0 && outputFile.Length > 0) { throw new WixException(WixErrors.IllegalAttributeWithOtherAttributes(null, element.Name, "IntermediateOutputType", "OutputFile", null)); } string toolFile = Path.Combine(toolsDirectory, "light.exe"); StringBuilder commandLine = new StringBuilder(arguments); commandLine.Append(" -b \"%WIX%\\examples\\data\""); // handle wixunit arguments if (args.NoTidy) { commandLine.Append(" -notidy"); } // handle extensions if (!String.IsNullOrEmpty(extensions)) { string[] suppressedExtensionArray = suppressExtensions.Split(';'); foreach (string extension in extensions.Split(';')) { if (0 > Array.BinarySearch(suppressedExtensionArray, extension)) { commandLine.AppendFormat(" -ext \"{0}\"", extension); } } } // handle any previous outputs if (usePreviousOutput) { foreach (string inputFile in previousUnitResults.OutputFiles) { commandLine.AppendFormat(" \"{0}\"", inputFile); } } previousUnitResults.OutputFiles.Clear(); // handle child elements foreach (XmlNode node in element.ChildNodes) { if (node.NodeType == XmlNodeType.Element) { switch (node.LocalName) { case "LibraryFile": string libraryFile = node.InnerText.Trim(); commandLine.AppendFormat(" \"{0}\"", libraryFile); break; case "LocalizationFile": string localizationFile = node.InnerText.Trim(); commandLine.AppendFormat(" -loc \"{0}\"", localizationFile); break; } } } if (outputFile.Length > 0) { // outputFile has been explicitly set } else if (expectedResult.Length > 0) { outputFile = Path.Combine(tempDirectory, Path.GetFileName(expectedResult)); } else if (intermediateOutputType.Length > 0) { string intermediateFile = String.Concat("intermediate.", intermediateOutputType); outputFile = Path.Combine(tempDirectory, intermediateFile); } else { outputFile = Path.Combine(tempDirectory, "ShouldNotBeCreated.msi"); } commandLine.AppendFormat("{0} -out \"{1}\"", (Path.GetExtension(outputFile) == ".wixout" ? " -xo" : String.Empty), outputFile); previousUnitResults.OutputFiles.Add(outputFile); // run the tool ArrayList output = ToolUtility.RunTool(toolFile, commandLine.ToString()); previousUnitResults.Errors.AddRange(ToolUtility.GetErrors(output, expectedErrors, expectedWarnings)); previousUnitResults.Output.AddRange(output); // check the output file if (previousUnitResults.Errors.Count == 0) { if (expectedResult.Length > 0) { ArrayList differences = CompareUnit.CompareResults(expectedResult, outputFile, testName, update); previousUnitResults.Errors.AddRange(differences); previousUnitResults.Output.AddRange(differences); } else if (expectedErrors.Length > 0 && File.Exists(outputFile)) // ensure the output doesn't exist { string error = String.Format(CultureInfo.InvariantCulture, "Expected failure, but the unit test created output file \"{0}\".", outputFile); previousUnitResults.Errors.Add(error); previousUnitResults.Output.Add(error); } } }
/// <summary> /// Run a Torch unit test. /// </summary> /// <param name="element">The unit test element.</param> /// <param name="previousUnitResults">The previous unit test results.</param> /// <param name="update">Indicates whether to give the user the option to fix a failing test.</param> /// <param name="args">The command arguments passed to WixUnit.</param> public static void RunUnitTest(XmlElement element, UnitResults previousUnitResults, bool update, ICommandArgs args) { string arguments = element.GetAttribute("Arguments"); string expectedErrors = element.GetAttribute("ExpectedErrors"); string expectedWarnings = element.GetAttribute("ExpectedWarnings"); string extensions = element.GetAttribute("Extensions"); string outputFile = element.GetAttribute("OutputFile"); string targetDatabase = element.GetAttribute("TargetDatabase"); string tempDirectory = element.GetAttribute("TempDirectory"); string testName = element.ParentNode.Attributes["Name"].Value; string toolsDirectory = element.GetAttribute("ToolsDirectory"); string updatedDatabase = element.GetAttribute("UpdatedDatabase"); bool usePreviousOutput = ("true" == element.GetAttribute("UsePreviousOutput")); bool verifyTransform = ("true" == element.GetAttribute("VerifyTransform")); string toolFile = Path.Combine(toolsDirectory, "torch.exe"); StringBuilder commandLine = new StringBuilder(arguments); // handle extensions if (!String.IsNullOrEmpty(extensions)) { foreach (string extension in extensions.Split(';')) { commandLine.AppendFormat(" -ext \"{0}\"", extension); } } // handle wixunit arguments if (args.NoTidy) { commandLine.Append(" -notidy"); } // handle any previous outputs if (0 < previousUnitResults.OutputFiles.Count && usePreviousOutput) { commandLine.AppendFormat(" \"{0}\"", previousUnitResults.OutputFiles[0]); previousUnitResults.OutputFiles.Clear(); } else // diff database files to create transform { commandLine.AppendFormat(" \"{0}\" \"{1}\"", targetDatabase, updatedDatabase); } if (null == outputFile || String.Empty == outputFile) { outputFile = Path.Combine(tempDirectory, "transform.mst"); } commandLine.AppendFormat(" -out \"{0}\"", outputFile); previousUnitResults.OutputFiles.Add(outputFile); // run the tool ArrayList output = ToolUtility.RunTool(toolFile, commandLine.ToString()); previousUnitResults.Errors.AddRange(ToolUtility.GetErrors(output, expectedErrors, expectedWarnings)); previousUnitResults.Output.AddRange(output); // check the results if (verifyTransform && 0 == expectedErrors.Length && 0 == previousUnitResults.Errors.Count) { string actualDatabase = Path.Combine(tempDirectory, String.Concat(Guid.NewGuid(), ".msi")); File.Copy(targetDatabase, actualDatabase); File.SetAttributes(actualDatabase, File.GetAttributes(actualDatabase) & ~FileAttributes.ReadOnly); using (Database database = new Database(actualDatabase, OpenDatabase.Direct)) { // use transform validation bits set in the transform (if any; defaults to None). database.ApplyTransform(outputFile); database.Commit(); } // check the output file ArrayList differences = CompareUnit.CompareResults(updatedDatabase, actualDatabase, testName, update); previousUnitResults.Errors.AddRange(differences); previousUnitResults.Output.AddRange(differences); } }
/// <summary> /// Run a unit test. /// </summary> /// <param name="unitTestElement">The unit test to run.</param> private void RunUnitTest(XmlElement unitTestElement) { string name = unitTestElement.GetAttribute("Name"); string tempDirectory = Path.Combine(unitTestElement.GetAttribute("TempDirectory"), name); UnitResults unitResults = new UnitResults(); try { // ensure the temp directory exists Directory.CreateDirectory(tempDirectory); foreach (XmlNode node in unitTestElement.ChildNodes) { if (XmlNodeType.Element == node.NodeType) { XmlElement unitElement = (XmlElement)node; // add inherited attributes from the parent "UnitTest" element foreach (XmlAttribute attribute in unitTestElement.Attributes) { if (attribute.NamespaceURI.Length == 0) { unitElement.SetAttribute(attribute.Name, attribute.Value); } } // add inherited attributes from the grandparent "UnitTests" element foreach (XmlAttribute attribute in unitTestElement.ParentNode.Attributes) { if (attribute.NamespaceURI.Length == 0) { unitElement.SetAttribute(attribute.Name, attribute.Value); } } unitElement.SetAttribute("TempDirectory", tempDirectory); switch (node.LocalName) { case "Candle": CandleUnit.RunUnitTest(unitElement, unitResults, this); break; case "Compare": CompareUnit.RunUnitTest(unitElement, unitResults, this.updateTests, this); break; case "Dark": DarkUnit.RunUnitTest(unitElement, unitResults, this); break; case "Heat": HeatUnit.RunUnitTest(unitElement, unitResults, this); break; case "Insignia": InsigniaUnit.RunUnitTest(unitElement, unitResults, this); break; case "Light": // If WixUnit was not run with -val then suppress MSI validation if (!this.validate && ("true" != unitElement.GetAttribute("ForceValidation"))) { string arguments = unitElement.GetAttribute("Arguments"); if (!arguments.Contains("-sval")) { unitElement.SetAttribute("Arguments", String.Concat(arguments, " -sval")); } } LightUnit.RunUnitTest(unitElement, unitResults, this.updateTests, this); break; case "Lit": LitUnit.RunUnitTest(unitElement, unitResults, this); break; case "Process": ProcessUnit.RunUnitTest(unitElement, unitResults, this); break; case "Pyro": PyroUnit.RunUnitTest(unitElement, unitResults, this.updateTests, this); break; case "Torch": TorchUnit.RunUnitTest(unitElement, unitResults, this.updateTests, this); break; case "WixProj": bool skipValidation = (!this.validate); WixProjUnit.RunUnitTest(unitElement, unitResults, this.verbose, skipValidation, this.updateTests, this); break; case "Smoke": SmokeUnit.RunUnitTest(unitElement, unitResults, this); break; } // check for errors if (unitResults.Errors.Count > 0) { break; } } } } catch (WixException we) { string message = this.messageHandler.GetMessageString(this, we.Error); if (null != message) { unitResults.Errors.Add(message); unitResults.Output.Add(message); } } catch (Exception e) { string message = this.messageHandler.GetMessageString(this, WixErrors.UnexpectedException(e.Message, e.GetType().ToString(), e.StackTrace)); if (null != message) { unitResults.Errors.Add(message); unitResults.Output.Add(message); } } lock (this.lockObject) { Console.Write("{0} of {1} - {2}: ", ++this.completedUnitTests, this.totalUnitTests, name.PadRight(30, '.')); if (unitResults.Errors.Count > 0) { this.failedUnitTests.Add(name, this.completedUnitTests); Console.WriteLine("Failed"); if (this.verbose) { foreach (string line in unitResults.Output) { Console.WriteLine(line); } Console.WriteLine(); } else { foreach (string line in unitResults.Errors) { Console.WriteLine(line); } Console.WriteLine(); } } else { Console.WriteLine("Success"); if (this.verbose) { foreach (string line in unitResults.Output) { Console.WriteLine(line); } Console.WriteLine(); } } if (this.totalUnitTests == this.completedUnitTests) { this.unitTestsComplete.Set(); } } }