public void GetBuckets() { ProjectInstance project = ProjectHelpers.CreateEmptyProjectInstance(); List <string> parameters = new List <string>(); parameters.Add("@(File);$(unittests)"); parameters.Add("$(obj)\\%(Filename).ext"); parameters.Add("@(File->'%(extension)')"); // attributes in transforms don't affect batching ItemDictionary <ProjectItemInstance> itemsByType = new ItemDictionary <ProjectItemInstance>(); IList <ProjectItemInstance> items = new List <ProjectItemInstance>(); items.Add(new ProjectItemInstance(project, "File", "a.foo", project.FullPath)); items.Add(new ProjectItemInstance(project, "File", "b.foo", project.FullPath)); items.Add(new ProjectItemInstance(project, "File", "c.foo", project.FullPath)); items.Add(new ProjectItemInstance(project, "File", "d.foo", project.FullPath)); items.Add(new ProjectItemInstance(project, "File", "e.foo", project.FullPath)); itemsByType.ImportItems(items); items = new List <ProjectItemInstance>(); items.Add(new ProjectItemInstance(project, "Doc", "a.doc", project.FullPath)); items.Add(new ProjectItemInstance(project, "Doc", "b.doc", project.FullPath)); items.Add(new ProjectItemInstance(project, "Doc", "c.doc", project.FullPath)); items.Add(new ProjectItemInstance(project, "Doc", "d.doc", project.FullPath)); items.Add(new ProjectItemInstance(project, "Doc", "e.doc", project.FullPath)); itemsByType.ImportItems(items); PropertyDictionary <ProjectPropertyInstance> properties = new PropertyDictionary <ProjectPropertyInstance>(); properties.Set(ProjectPropertyInstance.Create("UnitTests", "unittests.foo")); properties.Set(ProjectPropertyInstance.Create("OBJ", "obj")); List <ItemBucket> buckets = BatchingEngine.PrepareBatchingBuckets(parameters, CreateLookup(itemsByType, properties), MockElementLocation.Instance); Assert.AreEqual(5, buckets.Count); foreach (ItemBucket bucket in buckets) { // non-batching data -- same for all buckets XmlAttribute tempXmlAttribute = (new XmlDocument()).CreateAttribute("attrib"); tempXmlAttribute.Value = "'$(Obj)'=='obj'"; Assert.IsTrue(ConditionEvaluator.EvaluateCondition(tempXmlAttribute.Value, ParserOptions.AllowAll, bucket.Expander, ExpanderOptions.ExpandAll, Environment.CurrentDirectory, MockElementLocation.Instance, null, new BuildEventContext(1, 2, 3, 4))); Assert.AreEqual("a.doc;b.doc;c.doc;d.doc;e.doc", bucket.Expander.ExpandIntoStringAndUnescape("@(doc)", ExpanderOptions.ExpandItems, MockElementLocation.Instance)); Assert.AreEqual("unittests.foo", bucket.Expander.ExpandIntoStringAndUnescape("$(bogus)$(UNITTESTS)", ExpanderOptions.ExpandPropertiesAndMetadata, MockElementLocation.Instance)); } Assert.AreEqual("a.foo", buckets[0].Expander.ExpandIntoStringAndUnescape("@(File)", ExpanderOptions.ExpandItems, MockElementLocation.Instance)); Assert.AreEqual(".foo", buckets[0].Expander.ExpandIntoStringAndUnescape("@(File->'%(Extension)')", ExpanderOptions.ExpandItems, MockElementLocation.Instance)); Assert.AreEqual("obj\\a.ext", buckets[0].Expander.ExpandIntoStringAndUnescape("$(obj)\\%(Filename).ext", ExpanderOptions.ExpandPropertiesAndMetadata, MockElementLocation.Instance)); // we weren't batching on this attribute, so it has no value Assert.AreEqual(String.Empty, buckets[0].Expander.ExpandIntoStringAndUnescape("%(Extension)", ExpanderOptions.ExpandAll, MockElementLocation.Instance)); ProjectItemInstanceFactory factory = new ProjectItemInstanceFactory(project, "i"); items = buckets[0].Expander.ExpandIntoItemsLeaveEscaped("@(file)", factory, ExpanderOptions.ExpandItems, MockElementLocation.Instance); Assert.IsNotNull(items); Assert.AreEqual(1, items.Count); int invalidProjectFileExceptions = 0; try { // This should throw because we don't allow item lists to be concatenated // with other strings. bool throwAway; items = buckets[0].Expander.ExpandSingleItemVectorExpressionIntoItems("@(file)$(unitests)", factory, ExpanderOptions.ExpandItems, false /* no nulls */, out throwAway, MockElementLocation.Instance); } catch (InvalidProjectFileException ex) { // check we don't lose error codes from IPFE's during build Assert.AreEqual(ex.ErrorCode, "MSB4012"); invalidProjectFileExceptions++; } // We do allow separators in item vectors, this results in an item group with a single flattened item items = buckets[0].Expander.ExpandIntoItemsLeaveEscaped("@(file, ',')", factory, ExpanderOptions.ExpandItems, MockElementLocation.Instance); Assert.IsNotNull(items); Assert.AreEqual(1, items.Count); Assert.AreEqual("a.foo", items[0].EvaluatedInclude); Assert.AreEqual(1, invalidProjectFileExceptions); }