| @@ -0,0 +1,315 @@ | ||
| // NAnt - A .NET build tool | ||
| // Copyright (C) 2001-2005 Gert Driesen | ||
| // | ||
| // This program is free software; you can redistribute it and/or modify | ||
| // it under the terms of the GNU General Public License as published by | ||
| // the Free Software Foundation; either version 2 of the License, or | ||
| // (at your option) any later version. | ||
| // | ||
| // This program is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| // GNU General Public License for more details. | ||
| // | ||
| // You should have received a copy of the GNU General Public License | ||
| // along with this program; if not, write to the Free Software | ||
| // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| // | ||
| // Troy Laurin (fiontan@westnet.com.au) | ||
|
|
||
| using System; | ||
|
|
||
| using NAnt.Core; | ||
| using NAnt.Core.Tasks; | ||
| using NAnt.Core.Attributes; | ||
| using NAnt.Core.Util; | ||
|
|
||
| namespace NAnt.Core.Tasks { | ||
| /// <summary> | ||
| /// Executes a set of tasks, and optionally catches a build exception to | ||
| /// allow recovery or rollback steps to be taken, or to define some steps | ||
| /// to be taken regardless if the tasks succeed or fail, or both. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// <para> | ||
| /// The tasks defined in the <c><<see cref="TryBlock" />></c> block | ||
| /// will be executed in turn, as they normally would in a target. | ||
| /// </para> | ||
| /// <para> | ||
| /// If a <c><<see cref="CatchBlock" />></c> block is defined, the | ||
| /// tasks in that block will be executed in turn only if one of the tasks | ||
| /// in the <c><<see cref="TryBlock" />></c> block fails. This | ||
| /// failure will then be suppressed by the <c><<see cref="CatchBlock" />></c> | ||
| /// block. | ||
| /// </para> | ||
| /// <para> | ||
| /// The message associated with the failure can also be caught in a | ||
| /// property for use within the <c><<see cref="CatchBlock" />></c> | ||
| /// block. The original contents of the property will be restored upon | ||
| /// exiting the <c><<see cref="CatchBlock" />></c> block. | ||
| /// </para> | ||
| /// <para> | ||
| /// If a <c><<see cref="FinallyBlock" />></c> block is defined, the | ||
| /// tasks in that block will be executed after the tasks in both the | ||
| /// <c><<see cref="TryBlock" />></c> and <c><<see cref="CatchBlock" />></c> | ||
| /// blocks have been executed, regardless of whether any task fails in | ||
| /// either block. | ||
| /// </para> | ||
| /// </remarks> | ||
| /// <example> | ||
| /// <code> | ||
| /// <![CDATA[ | ||
| /// <trycatch> | ||
| /// <try> | ||
| /// <echo message="In try" /> | ||
| /// <fail message="Failing!" /> | ||
| /// </try> | ||
| /// <catch> | ||
| /// <echo message="In catch" /> | ||
| /// </catch> | ||
| /// <finally> | ||
| /// <echo message="Finally done" /> | ||
| /// </finally> | ||
| /// </trycatch> | ||
| /// ]]> | ||
| /// </code> | ||
| /// <para> | ||
| /// The output of this example will be: | ||
| /// </para> | ||
| /// <code> | ||
| /// In try | ||
| /// In catch | ||
| /// Finally done | ||
| /// </code> | ||
| /// <para> | ||
| /// The failure in the <c><<see cref="TryBlock" />></c> block will | ||
| /// not cause the build to fail. | ||
| /// </para> | ||
| /// </example> | ||
| /// <example> | ||
| /// <code> | ||
| /// <![CDATA[ | ||
| /// <trycatch> | ||
| /// <try> | ||
| /// <echo message="In try" /> | ||
| /// <fail message="Just because..." /> | ||
| /// </try> | ||
| /// <catch property="failure"> | ||
| /// <echo message="Caught failure: ${failure}" /> | ||
| /// <fail message="Bad catch" /> | ||
| /// </catch> | ||
| /// <finally> | ||
| /// <echo message="Finally done" /> | ||
| /// </finally> | ||
| /// </trycatch> | ||
| /// ]]> | ||
| /// </code> | ||
| /// <para> | ||
| /// The output of this example will be: | ||
| /// </para> | ||
| /// <code> | ||
| /// In try | ||
| /// Caught failure: Just because... | ||
| /// Finally done | ||
| /// Build failed: Bad catch | ||
| /// </code> | ||
| /// <para> | ||
| /// Like the above, the failure in the <c><<see cref="TryBlock" />></c> | ||
| /// block does not cause the build to fail. The failure in the | ||
| /// <c><<see cref="CatchBlock" />></c> block does, however. | ||
| /// Note that the <c><<see cref="FinallyBlock" />></c> block is | ||
| /// executed even though the <c><<see cref="CatchBlock" />></c> | ||
| /// block failed. | ||
| /// </para> | ||
| /// </example> | ||
| /// <example> | ||
| /// <code> | ||
| /// <![CDATA[ | ||
| /// <trycatch> | ||
| /// <try> | ||
| /// <echo message="In try" /> | ||
| /// <fail message="yet again" /> | ||
| /// </try> | ||
| /// <catch property="failure"> | ||
| /// <echo message="Caught failure ${failure}" /> | ||
| /// <fail message="Bad catch" /> | ||
| /// </catch> | ||
| /// <finally> | ||
| /// <echo message="Finally done ${failure}" /> | ||
| /// </finally> | ||
| /// </trycatch> | ||
| /// ]]> | ||
| /// </code> | ||
| /// <para> | ||
| /// The output of this example will be: | ||
| /// </para> | ||
| /// <code> | ||
| /// In try | ||
| /// Caught failure yet again | ||
| /// Build failed: Property 'failure' has not been set. | ||
| /// </code> | ||
| /// <para> | ||
| /// The <see cref="EchoTask" /> in the <c><<see cref="FinallyBlock" />></c> | ||
| /// block failed because the "failure" property was not defined | ||
| /// after exiting the <c><<see cref="CatchBlock" />></c> block. | ||
| /// Note that the failure in the <c><<see cref="FinallyBlock" />></c> | ||
| /// block has eclipsed the failure in the <c><<see cref="CatchBlock" />></c> | ||
| /// block. | ||
| /// </para> | ||
| /// </example> | ||
| /// <example> | ||
| /// <code> | ||
| /// <![CDATA[ | ||
| /// <trycatch> | ||
| /// <try> | ||
| /// <property name="temp.file" value="${path::get-temp-file-name()}" /> | ||
| /// <do-stuff to="${temp.file}" /> | ||
| /// <fail message="Oops..." /> | ||
| /// </try> | ||
| /// <finally> | ||
| /// <echo message="Cleaning up..." /> | ||
| /// <if test="${property::exists('temp.file')}"> | ||
| /// <delete file="${temp.file}" /> | ||
| /// </if> | ||
| /// </finally> | ||
| /// </trycatch> | ||
| /// ]]> | ||
| /// </code> | ||
| /// <para> | ||
| /// A more concrete example, that will always clean up the generated | ||
| /// temporary file after it has been created. | ||
| /// </para> | ||
| /// </example> | ||
| [TaskName("trycatch")] | ||
| public class TryCatchTask : Task { | ||
| #region Private Instance Fields | ||
|
|
||
| private TaskContainer _tryBlock; | ||
| private CatchElement _catchBlock; | ||
| private TaskContainer _finallyBlock; | ||
|
|
||
| #endregion Private Instance Fields | ||
|
|
||
| #region Public Instance Properties | ||
|
|
||
| /// <summary> | ||
| /// The tasks in this block will be executed as a normal part of | ||
| /// the build script. | ||
| /// </summary> | ||
| [BuildElement("try", Required=true)] | ||
| public TaskContainer TryBlock { | ||
| get { return _tryBlock; } | ||
| set { _tryBlock = value; } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// The tasks in this block will be executed if any task in the try | ||
| /// block fails. | ||
| /// </summary> | ||
| [BuildElement("catch", Required=false)] | ||
| public CatchElement CatchBlock { | ||
| get { return _catchBlock; } | ||
| set { _catchBlock = value; } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// The tasks in this block will always be executed, regardless of | ||
| /// what happens in the try and catch blocks. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// Note that any failure in any of the tasks in this block will | ||
| /// prevent any subsequent tasks from executing. | ||
| /// </remarks> | ||
| [BuildElement("finally", Required=false)] | ||
| public TaskContainer FinallyBlock { | ||
| get { return _finallyBlock; } | ||
| set { _finallyBlock = value; } | ||
| } | ||
|
|
||
| #endregion Public Instance Properties | ||
|
|
||
| #region Override implementation of Task | ||
|
|
||
| protected override void ExecuteTask() { | ||
| try { | ||
| if (TryBlock != null) { | ||
| TryBlock.Execute(); | ||
| } | ||
| } catch (BuildException be) { | ||
| if (CatchBlock != null) { | ||
| CatchBlock.Catch(be); | ||
| } else { | ||
| throw; | ||
| } | ||
| } finally { | ||
| if (FinallyBlock != null) { | ||
| FinallyBlock.Execute(); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #endregion Override implementation of Task | ||
|
|
||
| public class CatchElement : TaskContainer { | ||
| #region Private Instance Fields | ||
|
|
||
| private string _property; | ||
|
|
||
| #endregion Private Instance Fields | ||
|
|
||
| #region Public Instance Properties | ||
|
|
||
| /// <summary> | ||
| /// Defines the name of the property to save the message describing | ||
| /// the failure that has been caught. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// <para> | ||
| /// The failure message is only available in the context of the catch | ||
| /// block. If you wish to preserve the message, you will need to save | ||
| /// it into another property. | ||
| /// </para> | ||
| /// <para> | ||
| /// Readonly properties cannot be overridden by this mechanism. | ||
| /// </para> | ||
| /// </remarks> | ||
| [TaskAttribute("property", Required=false)] | ||
| [StringValidator(AllowEmpty=false)] | ||
| public string Property { | ||
| get { return _property; } | ||
| set { _property = StringUtils.ConvertEmptyToNull(value); } | ||
| } | ||
|
|
||
| #endregion Public Instance Properties | ||
|
|
||
| #region Public Instance Methods | ||
|
|
||
| public void Catch(BuildException be) { | ||
| bool propertyExists = false; | ||
| string originalPropertyValue = null; | ||
|
|
||
| if (Property != null) { | ||
| propertyExists = Project.Properties.Contains(Property); | ||
| originalPropertyValue = Project.Properties[Property]; | ||
| Project.Properties[Property] = be.RawMessage; | ||
| } | ||
|
|
||
| try { | ||
| Execute(); | ||
| } finally { | ||
| if (Property != null) { | ||
| if (!propertyExists) { | ||
| // if the property did not exist, then remove it again | ||
| Project.Properties.Remove(Property); | ||
| } else { | ||
| // restore original value | ||
| Project.Properties[Property] = originalPropertyValue; | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #endregion Public Instance Methods | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,351 @@ | ||
| // | ||
| // NAntContrib | ||
| // Copyright (C) 2001-2005 Gerry Shaw | ||
| // | ||
| // This library is free software; you can redistribute it and/or | ||
| // modify it under the terms of the GNU Lesser General Public | ||
| // License as published by the Free Software Foundation; either | ||
| // version 2.1 of the License, or (at your option) any later version. | ||
| // | ||
| // This library is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| // Lesser General Public License for more details. | ||
| // | ||
| // You should have received a copy of the GNU Lesser General Public | ||
| // License along with this library; if not, write to the Free Software | ||
| // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| // | ||
| // Gert Driesen (drieseng@users.sourceforge.net) | ||
|
|
||
| using System; | ||
| using System.IO; | ||
| using System.Xml; | ||
| using System.Xml.XPath; | ||
|
|
||
| using NUnit.Framework; | ||
|
|
||
| namespace Tests.NAnt.Core.Tasks { | ||
| [TestFixture] | ||
| public class ChooseTaskTest : BuildTestBase { | ||
| [Test] | ||
| public void Test_ConditionalExecution1() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose> | ||
| <when test=""false""> | ||
| <patternset id=""when1.sources""> | ||
| <include name=""**/*.cs"" /> | ||
| <exclude name=""**/*Test*"" /> | ||
| </patternset> | ||
| <copy todir="".""> | ||
| <fileset> | ||
| <patternset refid=""when1.sources"" /> | ||
| </fileset> | ||
| </copy> | ||
| <property name=""when1"" value=""executed"" /> | ||
| </when> | ||
| <when test=""true""> | ||
| <property name=""when2"" value=""a"" /> | ||
| <patternset id=""when2.sources""> | ||
| <include name=""**/*.cs"" /> | ||
| <exclude name=""**/*Test*"" /> | ||
| </patternset> | ||
| <property name=""when2"" value=""${when2}b"" /> | ||
| <property name=""when2"" value=""${when2}c"" if=""${true == false}"" /> | ||
| <copy todir="".""> | ||
| <fileset> | ||
| <patternset refid=""when2.sources"" /> | ||
| </fileset> | ||
| </copy> | ||
| <property name=""when2"" value=""${when2}d"" /> | ||
| </when> | ||
| <otherwise> | ||
| <patternset id=""otherwise.sources""> | ||
| <include name=""**/*.cs"" /> | ||
| <exclude name=""**/*Test*"" /> | ||
| </patternset> | ||
| <copy todir="".""> | ||
| <fileset> | ||
| <patternset refid=""otherwise.sources"" /> | ||
| </fileset> | ||
| </copy> | ||
| <property name=""otherwise"" value=""executed"" /> | ||
| </otherwise> | ||
| </choose> | ||
| <fail if=""${property::exists('when1')}"">#1</fail> | ||
| <fail unless=""${property::exists('when2')}"">#2</fail> | ||
| <fail unless=""${when2=='abd'}"">#3</fail> | ||
| <fail if=""${property::exists('otherwise')}"">#4</fail> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Test_ConditionalExecution2() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose> | ||
| <when test=""true""> | ||
| <property name=""when1"" value=""executed"" /> | ||
| </when> | ||
| <when test=""false""> | ||
| <property name=""when2"" value=""executed"" /> | ||
| </when> | ||
| </choose> | ||
| <fail unless=""${property::exists('when1')}"">#1</fail> | ||
| <fail if=""${property::exists('when2')}"">#2</fail> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Test_ConditionalExecution3() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose> | ||
| <when test=""false""> | ||
| <property name=""when1"" value=""executed"" /> | ||
| </when> | ||
| <when test=""false""> | ||
| <property name=""when2"" value=""executed"" /> | ||
| </when> | ||
| </choose> | ||
| <fail if=""${property::exists('when1')}"">#1</fail> | ||
| <fail if=""${property::exists('when2')}"">#2</fail> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Test_Fallback() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose> | ||
| <when test=""false""> | ||
| <property name=""when1"" value=""executed"" /> | ||
| </when> | ||
| <otherwise> | ||
| <property name=""otherwise"" value=""executed"" /> | ||
| </otherwise> | ||
| </choose> | ||
| <fail if=""${property::exists('when1')}"">#1</fail> | ||
| <fail unless=""${property::exists('otherwise')}"">#2</fail> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
|
|
||
| [Test] | ||
| [ExpectedException(typeof(TestBuildException))] | ||
| public void Test_ChildOrder1() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose> | ||
| <when test=""false""> | ||
| <property name=""when1"" value=""executed"" /> | ||
| </when> | ||
| <otherwise> | ||
| <property name=""otherwise"" value=""executed"" /> | ||
| </otherwise> | ||
| <when test=""true""> | ||
| <property name=""when2"" value=""executed"" /> | ||
| </when> | ||
| </choose> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
|
|
||
| [Test] | ||
| [ExpectedException(typeof(TestBuildException))] | ||
| public void Test_ChildOrder2() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose> | ||
| <otherwise> | ||
| <property name=""otherwise"" value=""executed"" /> | ||
| </otherwise> | ||
| <when test=""false""> | ||
| <property name=""when1"" value=""executed"" /> | ||
| </when> | ||
| </choose> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Test_EmptyWhenChild() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose> | ||
| <when test=""true"" /> | ||
| </choose> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Test_EmptyOtherwiseChild() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose> | ||
| <when test=""false"" /> | ||
| <otherwise /> | ||
| </choose> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
|
|
||
| [Test] | ||
| [ExpectedException(typeof(TestBuildException))] | ||
| public void Test_MissingWhenChild1() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose /> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
|
|
||
| [Test] | ||
| [ExpectedException(typeof(TestBuildException))] | ||
| public void Test_MissingWhenChild2() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose> | ||
| <otherwise> | ||
| <property name=""otherwise"" value=""executed"" /> | ||
| </otherwise> | ||
| </choose> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
|
|
||
| [Test] | ||
| [ExpectedException(typeof(TestBuildException))] | ||
| public void Test_InvalidWhenCondition() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose> | ||
| <when test=""whatever""> | ||
| <property name=""when1"" value=""executed"" /> | ||
| </when> | ||
| </choose> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
|
|
||
| [Test] | ||
| [ExpectedException(typeof(TestBuildException))] | ||
| public void Test_MissingWhenCondition() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose> | ||
| <when> | ||
| <property name=""when1"" value=""executed"" /> | ||
| </when> | ||
| </choose> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
|
|
||
| [Test] | ||
| [ExpectedException(typeof(TestBuildException))] | ||
| public void Test_EmptyWhenCondition() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose> | ||
| <when test=""""> | ||
| <property name=""when1"" value=""executed"" /> | ||
| </when> | ||
| </choose> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
|
|
||
| [Test] | ||
| [ExpectedException(typeof(TestBuildException))] | ||
| public void Test_InvalidChild() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose> | ||
| <when test=""true""> | ||
| <property name=""when1"" value=""executed"" /> | ||
| </when> | ||
| <if test=""true"" /> | ||
| </choose> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
|
|
||
| [Test] | ||
| [ExpectedException(typeof(TestBuildException))] | ||
| public void Test_InvalidExtension() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose> | ||
| <when test=""true""> | ||
| <doesnotexist /> | ||
| </when> | ||
| </choose> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
|
|
||
| [Test] | ||
| [ExpectedException(typeof(TestBuildException))] | ||
| public void Test_InvalidWhenParameter() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose> | ||
| <when test=""true"" if=""true""> | ||
| <property name=""when1"" value=""executed"" /> | ||
| </when> | ||
| </choose> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
|
|
||
| [Test] | ||
| [ExpectedException(typeof(TestBuildException))] | ||
| public void Test_InvalidOtherwiseParameter() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose> | ||
| <when test=""true""> | ||
| <property name=""when1"" value=""executed"" /> | ||
| </when> | ||
| <otherwise if=""true""> | ||
| <property name=""otherwise"" value=""executed"" /> | ||
| </otherwise> | ||
| </choose> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Test_FailOnError_False() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose failonerror=""false""> | ||
| <when test=""true""> | ||
| <fail>Some reason</fail> | ||
| </when> | ||
| </choose> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
|
|
||
| [Test] | ||
| [ExpectedException(typeof(TestBuildException))] | ||
| public void Test_FailOnError_True() { | ||
| string _xml = @" | ||
| <project> | ||
| <choose> | ||
| <when test=""true""> | ||
| <fail>Some reason</fail> | ||
| </when> | ||
| </choose> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,172 @@ | ||
| // NAnt - A .NET build tool | ||
| // Copyright (C) 2001-2005 Gert Driesen | ||
| // | ||
| // This program is free software; you can redistribute it and/or modify | ||
| // it under the terms of the GNU General Public License as published by | ||
| // the Free Software Foundation; either version 2 of the License, or | ||
| // (at your option) any later version. | ||
| // | ||
| // This program is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| // GNU General Public License for more details. | ||
| // | ||
| // You should have received a copy of the GNU General Public License | ||
| // along with this program; if not, write to the Free Software | ||
| // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| // | ||
| // Troy Laurin (fiontan@westnet.com.au) | ||
|
|
||
| using System; | ||
|
|
||
| using NUnit.Framework; | ||
|
|
||
| namespace Tests.NAnt.Core.Tasks { | ||
| /// <summary> | ||
| /// Tests the TryCatch task. | ||
| /// </summary> | ||
| [TestFixture] | ||
| public class TryCatchTaskTest : BuildTestBase { | ||
| [SetUp] | ||
| protected override void SetUp() { | ||
| base.SetUp(); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Test_CatchExceptionWithoutMessage() { | ||
| string _xml = @" | ||
| <project> | ||
| <trycatch> | ||
| <try> | ||
| <fail message='Exception text' /> | ||
| </try> | ||
| <catch> | ||
| <echo message='Catch!' /> | ||
| </catch> | ||
| </trycatch> | ||
| </project>"; | ||
| string result = RunBuild(_xml); | ||
| Assert.IsTrue(result.IndexOf("Catch!") != -1, "Exception should have been caught"); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Test_CatchExceptionWithMessage() { | ||
| string _xml = @" | ||
| <project> | ||
| <trycatch> | ||
| <try> | ||
| <fail message='Exception text' /> | ||
| </try> | ||
| <catch property='ex'> | ||
| <echo message='Catch: ${ex}' /> | ||
| </catch> | ||
| </trycatch> | ||
| </project>"; | ||
| string result = RunBuild(_xml); | ||
| Assert.IsTrue(result.IndexOf("Catch: Exception text") != -1, "Exception message should have been caught and displayed"); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Test_CatchWithoutFail() { | ||
| string _xml = @" | ||
| <project> | ||
| <trycatch> | ||
| <try> | ||
| <echo message='No exception' /> | ||
| </try> | ||
| <catch> | ||
| <echo message='Catch!' /> | ||
| </catch> | ||
| </trycatch> | ||
| </project>"; | ||
| string result = RunBuild(_xml); | ||
| Assert.IsTrue(result.IndexOf("No exception") != -1, "Try block should have run"); | ||
| Assert.IsTrue(result.IndexOf("Catch!") == -1, "Catch block shouldn't have run"); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Test_CatchExceptionAndFinally() { | ||
| string _xml = @" | ||
| <project> | ||
| <trycatch> | ||
| <try> | ||
| <fail message='Exception text' /> | ||
| </try> | ||
| <catch> | ||
| <echo message='Catch!' /> | ||
| </catch> | ||
| <finally> | ||
| <echo message='Finally!' /> | ||
| </finally> | ||
| </trycatch> | ||
| </project>"; | ||
| string result = RunBuild(_xml); | ||
| Assert.IsTrue(result.IndexOf("Catch!") != -1, "Exception should have been caught"); | ||
| Assert.IsTrue(result.IndexOf("Finally!") != -1, "Finally block should have run"); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Test_CatchWithoutFailAndFinally() { | ||
| string _xml = @" | ||
| <project> | ||
| <trycatch> | ||
| <try> | ||
| <echo message='No exception' /> | ||
| </try> | ||
| <catch> | ||
| <echo message='Catch!' /> | ||
| </catch> | ||
| <finally> | ||
| <echo message='Finally!' /> | ||
| </finally> | ||
| </trycatch> | ||
| </project>"; | ||
| string result = RunBuild(_xml); | ||
| Assert.IsTrue(result.IndexOf("No exception") != -1, "Try block should have run"); | ||
| Assert.IsTrue(result.IndexOf("Catch!") == -1, "Catch block shouldn't have run"); | ||
| Assert.IsTrue(result.IndexOf("Finally!") != -1, "Finally block should have run"); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Test_PropertyScopePreset() { | ||
| string _xml = @" | ||
| <project> | ||
| <property name='ex' value='Original' /> | ||
| <trycatch> | ||
| <try> | ||
| <fail message='Exception text' /> | ||
| </try> | ||
| <catch property='ex'> | ||
| <echo message='Catch: ${ex}' /> | ||
| </catch> | ||
| <finally> | ||
| <echo message='Finally: ${ex}' /> | ||
| </finally> | ||
| </trycatch> | ||
| </project>"; | ||
| string result = RunBuild(_xml); | ||
| Assert.IsTrue(result.IndexOf("Catch: Exception text") != -1, "Exception message should have been caught and displayed"); | ||
| Assert.IsTrue(result.IndexOf("Finally: Original") != -1, "Exception property should be reset outside the catch block"); | ||
| } | ||
|
|
||
| [Test] | ||
| [ExpectedException(typeof(TestBuildException))] | ||
| public void Test_MessagePropertyScopeEmpty() { | ||
| string _xml = @" | ||
| <project> | ||
| <trycatch> | ||
| <try> | ||
| <fail message='Exception text' /> | ||
| </try> | ||
| <catch property='ex'> | ||
| <echo message='Catch: ${ex}' /> | ||
| </catch> | ||
| <finally> | ||
| <echo message='Finally: ${ex}' /> | ||
| </finally> | ||
| </trycatch> | ||
| </project>"; | ||
| RunBuild(_xml); | ||
| } | ||
| } | ||
| } |