//
// Items.cs
//
// Author:
// Marek Sieradzki (marek.sieradzki@gmail.com)
// Ankit Jain (jankit@novell.com)
//
// (C) 2006 Marek Sieradzki
// Copyright 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
using System.Text;
using System.Xml;
using Microsoft.Build.BuildEngine;
using NUnit.Framework;
namespace MonoTests.Microsoft.Build.BuildEngine.Various {
[TestFixture]
public class Items {
private string GetItems (Project proj, string name)
{
BuildItemGroup big = proj.GetEvaluatedItemsByName (name);
string str = String.Empty;
if (big == null)
return str;
foreach (BuildItem bi in big) {
if (str == String.Empty)
str = bi.FinalItemSpec;
else
str += ";" + bi.FinalItemSpec;
}
return str;
}
private void CheckItems (Project proj, string name, string prefix, params string [] values)
{
BuildItemGroup big = proj.GetEvaluatedItemsByName (name);
if (big == null) {
Assert.Fail ("{0}: Item corresponding '{1}' not found.", prefix, name);
return;
}
if (values.Length != big.Count) {
Console.Write ("Expected> ");
foreach (string s in values)
Console.Write ("{0}|", s);
Console.WriteLine ();
Console.Write ("Actual> ");
foreach (BuildItem item in big)
Console.Write ("{0}|", item.FinalItemSpec);
Console.WriteLine ();
Assert.AreEqual (values.Length, big.Count, String.Format ("{0}: Number of items", prefix));
}
for (int i = 0; i < values.Length; i ++)
Assert.AreEqual (values [i], big [i].FinalItemSpec,
String.Format ("{0}: Item named {1}, numbered {2}", prefix, name, i));
}
[Test]
public void TestItems1 ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
";
proj.LoadXml (documentString);
CheckItems (proj, "Item0", "A1", "A");
CheckItems (proj, "Item1", "A2", "A", "B", "C");
CheckItems (proj, "Item2", "A3", "A", "B", "C", "A", "D");
CheckItems (proj, "Item3", "A4", "B", "C", "D");
CheckItems (proj, "Item4", "A5", "Q");
CheckItems (proj, "Item5", "A6");
CheckItems (proj, "Item6", "A7", "D");
CheckItems (proj, "Item7", "A8");
}
[Test]
public void TestItems2 ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
";
proj.LoadXml (documentString);
CheckItems (proj, "Item2", "A1", "A-B-C");
CheckItems (proj, "Item3", "A2", "AxxBxxC");
}
[Test]
public void TestItems3 ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
";
proj.LoadXml (documentString);
CheckItems (proj, "Item2", "A1", "A-B-C");
}
[Test]
public void TestItems4 ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
'%(Identity)')"" />
'%(Identity)%(Identity)')"" />
'(-%(Identity)-)')"" />
'%(Extension)')"" />
'%(Filename)/%(Extension)')"" />
";
proj.LoadXml (documentString);
CheckItems (proj, "ItemT1", "A1", "A", "B", "C");
CheckItems (proj, "ItemT2", "A2", "AA", "BB", "CC");
CheckItems (proj, "ItemT3", "A3", "(-A-)", "(-B-)", "(-C-)");
CheckItems (proj, "ItemT4", "A4", ".txt", ".txt", ".zip", ".zip");
CheckItems (proj, "ItemT5", "A5", "B/.txt", "C/.txt", "B/.zip", "C/.zip");
}
[Test]
[Category ("NotWorking")]
public void TestItems5 ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
'%(RelativeDir)X/%(Filename)')"" />
";
proj.LoadXml (documentString);
CheckItems (proj, "ItemT", "A1", @"A\X/B", @"A\X/C", @"B\X/B", @"B\X/C");
}
[Test]
[Category ("NotWorking")]
public void TestItems6 ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
A
'%(Filename)')"" />
";
proj.LoadXml (documentString);
CheckItems (proj, "Item2", "A1", "%(A.B)");
CheckItems (proj, "Item3", "A2");
CheckItems (proj, "Item4", "A3", "AABAC");
CheckItems (proj, "Item5", "A4", "A%(A)B%(A)C");
CheckItems (proj, "Item6", "A6", "A@(A)B@(A)C");
CheckItems (proj, "Item7", "A6", "A", "B", "C");
}
[Test]
[ExpectedException (typeof (InvalidProjectFileException),
"The expression \"@(Item1, '@(A,'')')\" cannot be used in this context. " +
"Item lists cannot be concatenated with other strings where an item list is expected. " +
"Use a semicolon to separate multiple item lists. ")]
[Category ("NotWorking")]
public void TestItems7 ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
";
proj.LoadXml (documentString);
}
[Test]
[ExpectedException (typeof (InvalidProjectFileException),
"The expression \"@(Item1, '@(A->'')')\" cannot be used in this context. " +
"Item lists cannot be concatenated with other strings where an item list is expected. " +
"Use a semicolon to separate multiple item lists. ")]
[Category ("NotWorking")]
public void TestItems8 ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
'')')"" />
";
proj.LoadXml (documentString);
}
[Test]
[ExpectedException (typeof (InvalidProjectFileException),
"The expression \"@(Item1, '@(A->'','')')\" cannot be used in this context. " +
"Item lists cannot be concatenated with other strings where an item list is expected. " +
"Use a semicolon to separate multiple item lists. ")]
[Category ("NotWorking")]
public void TestItems9 ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
'','')')"" />
";
proj.LoadXml (documentString);
}
[Test]
public void TestItemsInTarget1 ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
A
";
proj.LoadXml (documentString);
Assert.IsTrue (proj.Build ("1"), "A0, Build failed");
Assert.AreEqual ("A;B;C", proj.GetEvaluatedProperty ("P1"), "A1");
Assert.AreEqual ("ABC", proj.GetEvaluatedProperty ("P2"), "A2");
Assert.AreEqual ("A@(A)B@(A)C", proj.GetEvaluatedProperty ("P3"), "A3");
Assert.AreEqual ("AABAC", proj.GetEvaluatedProperty ("P4"), "A4");
Assert.AreEqual ("@(A,'ABC')", proj.GetEvaluatedProperty ("P5"), "A5");
CheckItems (proj, "I1", "A6", "A", "B", "C");
CheckItems (proj, "I2", "A7", "A A", "B B", "C C");
}
[Test]
[Category ("NotWorking")]
public void TestItemsInTarget2 ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
";
proj.LoadXml (documentString);
Assert.IsFalse (proj.Build ("1"), "A1");
}
[Test]
public void TestItemsInTarget3 ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
A
A;B
A;;
";
documentString += CreateTargetFragment ("StringTestTask", "Array", "Array", "I",
new string [] {
"$(A)$(A)",
"$(B)$(B)",
"$(C)",
"$(C)$(C)",
"@(A);$(C)",
"@(A);A;B;C",
"Foo;@(A)",
"@(A);Foo"
}) + "";
proj.LoadXml (documentString);
Assert.IsTrue (proj.Build ("1"), "Build failed");
CheckItems (proj, "I0", "A0", "AA");
CheckItems (proj, "I1", "A1", "A", "BA", "B");
CheckItems (proj, "I2", "A2", "A");
CheckItems (proj, "I3", "A3", "A", "A");
CheckItems (proj, "I4", "A4", "A", "B", "C", "A");
CheckItems (proj, "I5", "A5", "A", "B", "C", "A", "B", "C");
CheckItems (proj, "I6", "A6", "Foo", "A", "B", "C");
CheckItems (proj, "I7", "A7", "A", "B", "C", "Foo");
}
[Test]
//Test with ITaskItem[]
public void TestItemsInTarget3a ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
A
A;B
A;;
";
documentString += CreateTargetFragment ("BatchingTestTask", "Sources", "Output", "I",
new string [] {
"$(A)$(A)",
"$(B)$(B)",
"$(C)",
"$(C)$(C)",
"$(C) $(C)",
" $(C) Foo $(C) Bar ; $(B) ",
"@(A);$(C)",
"@(A);A;B;C",
}) + "";
proj.LoadXml (documentString);
Assert.IsTrue (proj.Build ("1"), "Build failed");
CheckItems (proj, "I0", "A0", "AA");
CheckItems (proj, "I1", "A1", "A", "BA", "B");
CheckItems (proj, "I2", "A2", "A");
CheckItems (proj, "I3", "A3", "A", "A");
CheckItems (proj, "I4", "A4", "A", "A");
CheckItems (proj, "I5", "A5", "A", "Foo A", "Bar", "A", "B");
CheckItems (proj, "I6", "A6", "A", "B", "C", "A");
CheckItems (proj, "I7", "A7", "A", "B", "C", "A", "B", "C");
}
[Test]
//Test with string[]
public void TestItemsInTarget3b ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
A
A;B
A;;
";
documentString += CreateTargetFragment ("BatchingTestTask", "Strings", "StringsOutput", "I",
new string [] {
"$(A)$(A)",
"$(B)$(B)",
"$(C)",
"$(C)$(C)",
"$(C) $(C) $(C)Bar$(C)",
"@(A);$(C)",
"@(A);A;B;C"
}) + "";
proj.LoadXml (documentString);
Assert.IsTrue (proj.Build ("1"), "Build failed");
CheckItems (proj, "I0", "A0", "AA");
CheckItems (proj, "I1", "A1", "A", "BA", "B");
CheckItems (proj, "I2", "A2", "A");
CheckItems (proj, "I3", "A3", "A", "A");
CheckItems (proj, "I4", "A4", "A", "A", "A", "BarA");
CheckItems (proj, "I5", "A5", "A", "B", "C", "A");
CheckItems (proj, "I6", "A6", "A", "B", "C", "A", "B", "C");
}
[Test]
//Test with string
public void TestItemsInTarget3c ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
A
A;B
A;;
$(C);Foo
";
documentString += CreateTargetFragment ("BatchingTestTask", "SingleString", "SingleStringOutput", "I",
new string [] {
"$(A)$(A)",
"$(B)$(B)",
"$(C)",
"$(C)$(C)",
"$(C) $(C)",
"@(A);$(C)",
"@(A);A;B;C",
"@(A) $(C) @(A)"
}) + "";
proj.LoadXml (documentString);
Assert.IsTrue (proj.Build ("1"), "Build failed");
BuildProperty bp = proj.EvaluatedProperties ["D"];
Assert.AreEqual ("$(C);Foo", bp.Value, "B0");
Assert.AreEqual ("A;;;Foo", bp.FinalValue, "B1");
bp = proj.EvaluatedProperties ["C"];
Assert.AreEqual ("A;;", bp.Value, "B3");
Assert.AreEqual ("A;;", bp.FinalValue, "B4");
CheckItems (proj, "I0", "A0", "AA");
CheckItems (proj, "I1", "A1", "A;BA;B");
CheckItems (proj, "I2", "A2", "A;;");
CheckItems (proj, "I3", "A3", "A;;A;;");
CheckItems (proj, "I4", "A4", "A;; A;;");
CheckItems (proj, "I5", "A5", "A;B;C;A;;");
CheckItems (proj, "I6", "A6", "A;B;C;A;B;C");
CheckItems (proj, "I7", "A7", "A;B;C A;; A;B;C");
}
[Test]
public void TestSingleTaskItemError1 ()
{
CheckSingleTaskItemProject ("$(B)$(B)");
}
[Test]
public void TestSingleTaskItemError2 ()
{
CheckSingleTaskItemProject ("$(C)$(C)");
}
[Test]
public void TestSingleTaskItemError3 ()
{
CheckSingleTaskItemProject ("$(C) $(C)");
}
[Test]
public void TestSingleTaskItemError4 ()
{
CheckSingleTaskItemProject ("@(A)");
}
[Test]
public void TestSingleTaskItemError5 ()
{
CheckSingleTaskItemProject ("@(A);$(C))");
}
[Test]
public void TestSingleTaskItemError6 ()
{
CheckSingleTaskItemProject ("@(A);A;B;C");
}
[Test]
public void TestSingleTaskItemError7 ()
{
CheckSingleTaskItemProject ("@(Item1)$(C)");
}
[Test]
public void TestSingleTaskItemError8 ()
{
CheckSingleTaskItemProject ("$(B).foo");
}
[Test]
public void TestSingleTaskItem1 ()
{
Project proj = BuildProjectForSingleTaskItem ("$(D)$(C)");
CheckItems (proj, "I0", "A0", "A");
}
[Test]
public void TestSingleTaskItem2 ()
{
Project proj = BuildProjectForSingleTaskItem ("@(Item1)");
CheckItems (proj, "I0", "A0", "F");
}
[Test]
public void TestSingleTaskItem3 ()
{
Project proj = BuildProjectForSingleTaskItem ("$(A).foo");
CheckItems (proj, "I0", "A0", "A.foo");
}
[Test]
public void TestSingleTaskItem4 ()
{
Project proj = BuildProjectForSingleTaskItem ("$(C)");
CheckItems (proj, "I0", "A0", "A");
}
void CheckSingleTaskItemProject (string expression)
{
string documentString = CreateProjectForSingleTaskItem (expression);
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
proj.LoadXml (documentString);
Assert.IsFalse (proj.Build ("1"), "Build should've failed");
}
Project BuildProjectForSingleTaskItem (string expression)
{
string documentString = CreateProjectForSingleTaskItem (expression);
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
proj.LoadXml (documentString);
Assert.IsTrue (proj.Build ("1"), "Build failed");
return proj;
}
string CreateProjectForSingleTaskItem (string expression)
{
return @"
A
A;B
A;;
";
}
string CreateTargetFragment (string taskname, string task_param_in, string task_param_out, string item_prefix,
string [] args)
{
StringBuilder sb = new StringBuilder ();
sb.Append ("");
for (int i = 0; i < args.Length; i ++) {
sb.AppendFormat ("<{0} {1}='{2}'>\n", taskname, task_param_in, args [i]);
sb.AppendFormat ("\t\n", task_param_out, item_prefix, i);
sb.AppendFormat ("{0}>\n", taskname);
}
sb.Append ("");
return sb.ToString ();
}
[Test]
public void TestItemsInTarget4 ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
";
proj.LoadXml (documentString);
Assert.IsFalse (proj.Build ("1"));
}
[Test]
public void TestItemsInTarget5 ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
";
proj.LoadXml (documentString);
Assert.IsFalse (proj.Build ("1"));
}
[Test]
public void TestItemsInTarget6 ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
A
";
proj.LoadXml (documentString);
Assert.IsFalse (proj.Build ("1"));
}
[Test]
public void TestItemsInTarget7 ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
";
proj.LoadXml (documentString);
Assert.IsFalse (proj.Build ("1"));
}
[Test]
public void TestItemsInTarget8 ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
Five
True
False
";
proj.LoadXml (documentString);
Assert.AreEqual (1, proj.EvaluatedItems.Count, "A1");
BuildItem bi = proj.EvaluatedItems [0];
Assert.AreEqual ("False", bi.GetMetadata ("M"), "A2");
}
[Test]
public void TestItemsInTarget9 ()
{
Engine engine = new Engine (Consts.BinPath);
Project proj = engine.CreateNewProject ();
string documentString = @"
Five
True
False
";
proj.LoadXml (documentString);
Assert.AreEqual (1, proj.EvaluatedItems.Count, "A1");
BuildItem bi = proj.EvaluatedItems [0];
Assert.AreEqual ("True", bi.GetMetadata ("M"), "A2");
Assert.AreEqual (0, bi.Condition.Length, "A3");
BuildItemGroup big = proj.GetEvaluatedItemsByNameIgnoringCondition ("A");
Assert.AreEqual (1, big.Count, "A4");
bi = big [0];
Assert.AreEqual ("True", bi.GetMetadata ("M"), "A5");
Assert.AreEqual ("True", bi.GetEvaluatedMetadata ("M"), "A6");
/*proj.SetProperty ("Foo", "Six");
proj.Build ();
bi = proj.GetEvaluatedItemsByName ("A") [0];
Assert.AreEqual ("False", bi.GetMetadata ("M"), "A7");
Assert.AreEqual ("False", bi.GetEvaluatedMetadata ("M"), "A7a");
Assert.AreEqual (0, bi.Condition.Length, "A8");
big = proj.GetEvaluatedItemsByNameIgnoringCondition ("A");
Assert.AreEqual (1, big.Count, "A9");
bi = big [0];
Assert.AreEqual ("True", bi.GetMetadata ("M"), "A10");
Assert.AreEqual ("True", bi.GetEvaluatedMetadata ("M"), "A11");*/
}
}
}