How to detect whether fileset is defined? - nant

My custom NAnt task relies on a certain fileset. It is considered to be defined by the time the task executes. I'd like to make sure fileset was defined before using it. I'm thinking of something similar to property::exists('property').
I failed to find the appropriate function.
Is it possible with NAnt (or NAntContrib) out of the box?

Generally, tasks should not depend on filesets or properties. Instead, they should take explicit parameters. An existing fileset can be reused using refid, so there's no redeclaration resulting from this. Example syntax:
<myTask><filesetParameter refid="compileUs"/><myTask>
If the referenced fileset is not defined, NAnt will throw an exception - this is proper (expected) behaviour, as the build cannot continue at this point.
Inside your task, the property would be defined as follows:
[TaskName("myTask")]
public class MyTask : Task
{
[TaskAttribute("filesetParameter", Required = true)]
public FileSet FilesetParamter
{ get; set; }
}

Related

How to access the value of a Property argument from nested activities?

I'm sure there's something I'm missing here, but a lot of Googling hasn't uncovered it for me. The situation is like this:
We created a custom workflow designer that allows end users to build workflow definitions from various custom activities we define (Review, Submit, Notify, etc). These definitions (Xaml) get saved off to a Db and used to create workflow instances for long running processes in our system. The users can set properties on each of them (e.g. Review has a property argument: AllowedRoles). The problem is, I'm not able to pass those properties on to nested activities.
For example:
Review has an internal activity 'WriteStatus' that needs access to the 'AllowedRoles' property on Review. If 'AllowedRoles' is defined as a Property, WriteStatus can't "see" it to assign it's value. I can change it from a Property to an InArgument, but then I'm not able to map values to and from the property in the designer (these properties should be part of the definition, and not associated with any specific context).
Has anyone faced this issue or have advice on how I could approach the problem differently?
Thanks in advance!
Royce
I was able to get around the property vs InOurArgument problem by converting the XAML activities to code. This allowed me to set the properties on activities in code, and then pass them to inner activities inline. There may be a better way, but it's working out well so far.
public sealed class Test : Activity
{
public string Stuff { get; set; } // CLR Property
public Test()
{
Implementation = () => new WriteLine {Text = Stuff};
}
}

Custom Phing task with nested elements

I'm creating a custom phing task and trying to pass data to it via nested xml elements. My task executes fine but errors out when it attempts to "create" a nested element. For example:
Portion of xml build file:
<mycustomtask>
<option name="opt1" value="val1"/>
</mycustomtask>
Portion of task class file:
...
public function createOption(){
return new Option;
}
...
Portion of Option class file:
class Option{
...
public function setName($str){
$this->name = $str;
}
public function setValue($str){
$this->value = $str;
}
}
My task always errors out with an exception from the Introspection Helper with "...doesn't support 'name' attribute".
Can anyone show me what I'm doing wrong here? I've started tracing back through the introspection helper class but didn't get very far. I've also tried adding the #return doc directive in my method phpdoc as I can see the introspection helper tries to parse them.
Alternatively, is there another way of passing lots of arguments/options to a custom task in xml?
Your tag class should extend the DataType class. Without that, phing will give you problems.
If that does not help, provide a paste with the minimal (but complete) code to reproduce the problem.

Writing a custom NAnt task able to use filters

I'm trying to write a custom NAnt task that does some file-based operations. One of the things that would be incredibly useful would be the ability to run the <expandproperties> filter on one of the input files.
In the interest of keeping the task suitably generic, I simply want to enable support for the <filterchain> element (similar to how the <copy> task works).
I've been using the source for the <copy> task to guide me, however I keep on running into methods that are internal when it comes to writing the tasks. I know I can use reflection to break encapsulation, but I'm reluctant to do this.
Does anyone know of any useful articles, or have any experience with this?
I started going down the road of creating a private Filter subclass that took a TextReader (basically re-creating the PhysicalTextReader inside the NAnt source). However I realised that, actually, there was a much easier way of reading a file through a filter chain:
[TaskName("mytask")]
public class MyTask : Task
{
/// <summary>
/// Chain of filters used to alter the input file's content as it is read.
/// </summary>
[BuildElement("filterchain")]
public FilterChain Filters { get; set; }
/// <summary>
/// The input file.
/// </summary>
[TaskAttribute("input")]
public FileInfo InputFile { get; set; }
protected override void ExecuteTask()
{
Log(FileUtils.ReadFile(InputFile.FullName, Filters, null));
}
}
Then you can use this exactly as you would expect:
<mytask input="foo.txt">
<filterchain>
<expandproperties />
</filterchain>
</mytask>

How to access the NUnit test name programmatically?

Is there some global state somewhere that I can access the currently-running test name?
I have tests which output files into a directory and read them back in. I'd like each test to create a directory to play in and then clean up after itself, and I don't want to push that name in (I'd have to make it unique, and then make sure each test keeps it unique; ew). I could use a GUID, but I'd like helper methods to be able to assume "this is the place where test files should be stored" without having to push that GUID around to them. Again, this augers for a global state somewhere.
Basically, I want a call like TestRunner.Current.CurrentTest.Name. Does such a thing exist?
(Assuming c#)
NUnit.Framework.TestContext.CurrentContext.Test.Name
or
NUnit.Framework.TestContext.CurrentContext.Test.FullName
or if you are really lazy and aren't driving your tests with TestCaseSource (thanks #aolszowka):
this.GetType().ToString()
I haven't upgraded to 2.5.7 yet myself, but it includes a TestContext class that seems to provide just what you're looking for: http://www.nunit.org/index.php?p=releaseNotes&r=2.5.7
Assuming one method per Test, in your NUnit code, you can use reflection to get the method name from the stacktrace.
If you write a helper method in your NUnit code called by other methods to do this file logging, you can use this syntax to check for the previous method:
string MethodName = new StackFrame(1).GetMethod().Name;
See the answers to question 44153, "Can you use reflection to find the name of the currently executing method?" for more details.
If we are using TestCaseSource tag then above solutions might not give correct answer
Try using TestContext.CurrentContext.Test.MethodName
Follow the below example
namespace NunitTests
{
public class Class1
{
static List<TestData> Data = new List<TestData>()
{
new TestData()
{
...
}
};
[Test]
[TestCaseSource(nameof(TenMBInstance))]
public void TestCase(TestData value)
{
TestContext.CurrentContext.Test.Name; //TestCase(NunitTests..TestData)
TestContext.CurrentContext.Test.MethodName; //TestCase
}
}
}

Ignore all NUnit tests in a file

I can add an attribute on a test to ignore it:
[Test]
[Ignore("Foo Bar")]
Is there a way to ignore all tests in a file (at the TestFixture level)?
[TestFixture, Ignore("reason")]
public class YourTestFixture { }
Or if you prefer to break your attributes out to one per line:
[TestFixture]
[Ignore("reason")]
public class YourTestFixture { }
As suggested, the [Explicit] attribute works well. You can also simply place the [Ignore()] attribute under the [TestFixture] attribute, as shown in the documentation:
http://www.nunit.org/index.php?p=ignore&r=2.5
Use [Ignore()] if you want the test to be flagged as ignored (and therefore you get the yellow bar if all other tests pass). Use [Explicit] if you want the test to be completely discounted (and therefore you get the green bar if all other tests pass).
You can make the whole TestFixture "on-demand" by using the [Explicit] attribute. Then it's there when you want it, but only when you explicitly click on it.
Before NUnit 2.5, removing the [TestFixture] attribute from the class seems like it would work.
This is not the case for NUnit 2.5 and later in which the [TestFixture] attribute is optional for non-parameterized non-generic fixtures. See here for more.
Simply don't apply the TextFixture attribute on the class.