/*************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. This code is licensed under the Visual Studio SDK license terms. THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. ***************************************************************************/ using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using Microsoft.Build.Framework; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Microsoft.VsSDK.UnitTestLibrary { sealed public class MockBuildEngine : IBuildEngine4 { private int messages = 0; private int warnings = 0; private int errors = 0; private string log = ""; private string upperLog = null; private bool logToConsole = false; private MockLogger mockLogger = null; private Dictionary objectCashe = new Dictionary(); public MockBuildEngine() : this(false) { } public int Messages { set { this.messages = value; } get { return this.messages; } } public int Warnings { set { this.warnings = value; } get { return this.warnings; } } public int Errors { set { this.errors = value; } get { return this.errors; } } public MockLogger MockLogger { get { return this.mockLogger; } } public MockBuildEngine(bool logToConsole) { this.mockLogger = new MockLogger(); this.logToConsole = logToConsole; } public void LogErrorEvent(BuildErrorEventArgs eventArgs) { if (eventArgs.File != null && eventArgs.File.Length > 0) { if (this.logToConsole) Console.Write("{0}({1},{2}): ", eventArgs.File, eventArgs.LineNumber, eventArgs.ColumnNumber); this.log += String.Format(CultureInfo.InvariantCulture, "{0}({1},{2}): ", eventArgs.File, eventArgs.LineNumber, eventArgs.ColumnNumber); } if (this.logToConsole) Console.Write("ERROR " + eventArgs.Code + ": "); this.log += "ERROR " + eventArgs.Code + ": "; ++this.errors; if (this.logToConsole) Console.WriteLine(eventArgs.Message); this.log += eventArgs.Message; this.log += "\n"; } public void LogWarningEvent(BuildWarningEventArgs eventArgs) { if (eventArgs.File != null && eventArgs.File.Length > 0) { if (this.logToConsole) Console.Write("{0}({1},{2}): ", eventArgs.File, eventArgs.LineNumber, eventArgs.ColumnNumber); this.log += String.Format(CultureInfo.InvariantCulture, "{0}({1},{2}): ", eventArgs.File, eventArgs.LineNumber, eventArgs.ColumnNumber); } if (this.logToConsole) Console.Write("WARNING " + eventArgs.Code + ": "); this.log += "WARNING " + eventArgs.Code + ": "; ++this.warnings; if (this.logToConsole) Console.WriteLine(eventArgs.Message); this.log += eventArgs.Message; this.log += "\n"; } public void LogCustomEvent(CustomBuildEventArgs eventArgs) { if (this.logToConsole) Console.WriteLine(eventArgs.Message); this.log += eventArgs.Message; this.log += "\n"; } public void LogMessageEvent(BuildMessageEventArgs eventArgs) { if (this.logToConsole) Console.WriteLine(eventArgs.Message); this.log += eventArgs.Message; this.log += "\n"; ++this.messages; } public bool ContinueOnError { get { return false; } } public string ProjectFileOfTaskNode { get { return String.Empty; } } public int LineNumberOfTaskNode { get { return 0; } } public int ColumnNumberOfTaskNode { get { return 0; } } public string Log { set { this.log = value; } get { return this.log; } } public bool IsRunningMultipleNodes { get; set; } public bool BuildProjectFile ( string projectFileName, string[] targetNames, IDictionary globalPropertiesPassedIntoTask, IDictionary targetOutputs ) { return false; } public bool BuildProjectFile ( string projectFileName, string[] targetNames, IDictionary globalPropertiesPassedIntoTask, IDictionary targetOutputs, string toolsVersion ) { return false; } public bool BuildProjectFilesInParallel ( string[] projectFileNames, string[] targetNames, IDictionary[] globalProperties, IDictionary[] targetOutputsPerProject, string[] toolsVersion, bool useResultsCache, bool unloadProjectsOnCompletion ) { return false; } public BuildEngineResult BuildProjectFilesInParallel ( string[] projectFileNames, string[] targetNames, IDictionary[] globalProperties, IList[] undefineProperties, string[] toolsVersion, bool returnTargetOutputs ) { return new BuildEngineResult(); } public void Yield() { } public void Reacquire() { } public bool BuildProjectFile ( string projectFileName ) { return false; } public bool BuildProjectFile ( string projectFileName, string[] targetNames ) { return false; } public bool BuildProjectFile ( string projectFileName, string targetName ) { return false; } public void UnregisterAllLoggers ( ) { } public void UnloadAllProjects ( ) { } /// /// Assert that the mock log in the engine doesn't contain a certain message based on a resource string and some parameters /// public void AssertLogDoesntContainMessageFromResource(GetStringDelegate getString, string resourceName, params string[] parameters) { var resource = getString(resourceName); var stringToSearchFor = String.Format(CultureInfo.CurrentCulture, resource, parameters); this.AssertLogDoesntContain(stringToSearchFor); } /// /// Assert that the mock log in the engine contains a certain message based on a resource string and some parameters /// public void AssertLogContainsMessageFromResource(GetStringDelegate getString, string resourceName, params string[] parameters) { var resource = getString(resourceName); var stringToSearchFor = String.Format(CultureInfo.CurrentCulture, resource, parameters); this.AssertLogContains(stringToSearchFor); } /// /// Assert that the log file contains the given string. /// Case insensitive. /// First check if the string is in the log string. If not /// than make sure it is also check the MockLogger /// /// public void AssertLogContains(string contains) { if (this.upperLog == null) { this.upperLog = this.log; this.upperLog = this.upperLog.ToUpperInvariant(); } // If we do not contain this string than pass it to // MockLogger. Since MockLogger is also registered as // a logger it may have this string. if (!this.upperLog.Contains ( contains.ToUpperInvariant() ) ) { Console.WriteLine(this.log); this.mockLogger.AssertLogContains(contains); } } /// /// Assert that the log doesnt contain the given string. /// First check if the string is in the log string. If not /// than make sure it is also not in the MockLogger /// /// public void AssertLogDoesntContain(string contains) { Console.WriteLine(this.log); if (this.upperLog == null) { this.upperLog = this.log; this.upperLog = this.upperLog.ToUpperInvariant(); } Assert.IsTrue ( !this.upperLog.Contains ( contains.ToUpperInvariant() ) ); // If we do not contain this string than pass it to // MockLogger. Since MockLogger is also registered as // a logger it may have this string. this.mockLogger.AssertLogDoesntContain ( contains ); } /// /// Delegate which will get the resource from the correct resoruce manager /// public delegate string GetStringDelegate(string resourceName); public object GetRegisteredTaskObject(object key, RegisteredTaskObjectLifetime lifetime) { return null; } public void RegisterTaskObject(object key, object obj, RegisteredTaskObjectLifetime lifetime, bool allowEarlyCollection) { } public object UnregisterTaskObject(object key, RegisteredTaskObjectLifetime lifetime) { return null; } } }