diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.Internal.ProjectModel/Files/ExcludeContext.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.Internal.ProjectModel/Files/ExcludeContext.cs new file mode 100644 index 000000000..69d2c78ef --- /dev/null +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.Internal.ProjectModel/Files/ExcludeContext.cs @@ -0,0 +1,38 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Newtonsoft.Json.Linq; + +namespace Microsoft.DotNet.Internal.ProjectModel.Files +{ + // Similar to IncludeContext, except that it replaces the include information with the exclude information and clears + // out the exclude information. This is to be used by migration to do CopyToOutput with Never set as its metadata. + internal class ExcludeContext : IncludeContext + { + public ExcludeContext( + string sourceBasePath, + string option, + JObject rawObject, + string[] defaultBuiltInInclude, + string[] defaultBuiltInExclude) : base( + sourceBasePath, + option, + rawObject, + defaultBuiltInInclude, + defaultBuiltInExclude) + { + IncludePatterns = ExcludePatterns; + ExcludePatterns = new List(); + + IncludeFiles = ExcludeFiles; + ExcludeFiles = new List(); + + BuiltInsInclude = BuiltInsExclude; + BuiltInsExclude = new List(); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.Internal.ProjectModel/Files/IncludeContext.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.Internal.ProjectModel/Files/IncludeContext.cs index 7dbf25099..191e6164a 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.Internal.ProjectModel/Files/IncludeContext.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.Internal.ProjectModel/Files/IncludeContext.cs @@ -39,6 +39,7 @@ namespace Microsoft.DotNet.Internal.ProjectModel.Files CustomRemovePatterns = new List(); SourceBasePath = sourceBasePath; Option = option; + RawObject = rawObject; var token = rawObject.Value(option); if (token == null) @@ -117,20 +118,22 @@ namespace Microsoft.DotNet.Internal.ProjectModel.Files public List CustomRemovePatterns { get; } - public List IncludePatterns { get; } + public List IncludePatterns { get; protected set; } - public List ExcludePatterns { get; } + public List ExcludePatterns { get; protected set; } - public List IncludeFiles { get; } + public List IncludeFiles { get; protected set; } - public List ExcludeFiles { get; } + public List ExcludeFiles { get; protected set; } - public List BuiltInsInclude { get; } + public List BuiltInsInclude { get; protected set; } - public List BuiltInsExclude { get; } + public List BuiltInsExclude { get; protected set; } public IDictionary Mappings { get; } + public JObject RawObject { get; } + public override bool Equals(object obj) { var other = obj as IncludeContext; diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateBuildOptionsRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateBuildOptionsRule.cs index 45f1f6583..5139082e6 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateBuildOptionsRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateBuildOptionsRule.cs @@ -150,6 +150,10 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules new UpdateContextTransform("None", transformMappings: true) .WithMetadata("CopyToOutputDirectory", "PreserveNewest"); + private IncludeContextTransform DoNotCopyToOutputFilesTransform => + new UpdateContextTransform("None", transformMappings: true) + .WithMetadata("CopyToOutputDirectory", "Never"); + private IncludeContextTransform CopyToOutputFilesTransformForWeb => new UpdateContextTransform( "None", @@ -197,6 +201,12 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules return copyToOutputFilesTransform.Transform(GetCopyToOutputIncludeContext(compilerOptions, projectDirectory)); }; + private Func> DoNotCopyToOutputFilesTransformExecute => + (compilerOptions, projectDirectory, projectType) => + { + return DoNotCopyToOutputFilesTransform.Transform(GetDoNotCopyToOutputIncludeContext(compilerOptions, projectDirectory)); + }; + private readonly string[] DefaultEmptyExcludeOption = new string[0]; private readonly ProjectPropertyGroupElement _configurationPropertyGroup; @@ -268,7 +278,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules { CompileFilesTransformExecute, EmbedFilesTransformExecute, - CopyToOutputFilesTransformExecute + CopyToOutputFilesTransformExecute, + DoNotCopyToOutputFilesTransformExecute }; } @@ -531,6 +542,28 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules null); } + private IncludeContext GetDoNotCopyToOutputIncludeContext(CommonCompilerOptions compilerOptions, string projectDirectory) + { + // Defaults from src/Microsoft.DotNet.ProjectModel/ProjectReader.cs #608 + var copyToOutputIncludeContext = compilerOptions.CopyToOutputInclude ?? + new IncludeContext( + projectDirectory, + "copyToOutput", + new JObject(), + null, + null); + + var doNotCopyToOutputIncludeContext = + new ExcludeContext( + copyToOutputIncludeContext.SourceBasePath, + copyToOutputIncludeContext.Option, + copyToOutputIncludeContext.RawObject, + copyToOutputIncludeContext.BuiltInsInclude?.ToArray(), + copyToOutputIncludeContext.BuiltInsExclude?.ToArray()); + + return doNotCopyToOutputIncludeContext; + } + private string FormatLanguageVersion(string langVersion) { if (langVersion.StartsWith("csharp", StringComparison.OrdinalIgnoreCase)) diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Transforms/ItemTransformApplicator.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Transforms/ItemTransformApplicator.cs index 26be01e4e..6ddabf3cd 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Transforms/ItemTransformApplicator.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Transforms/ItemTransformApplicator.cs @@ -501,9 +501,13 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Transforms mergedItem.AddMetadata(MergeMetadata(existingItem.Metadata, item.Metadata), MigrationTrace.Instance); + Console.WriteLine($"BEFORE MERGED: {mergedItem.Update}, ITEM: {item.Update}, EXISTING: {existingItem.Update}"); + item.RemoveUpdates(commonUpdates); existingItem.RemoveUpdates(commonUpdates); + Console.WriteLine($"MERGED: {mergedItem.Update}, ITEM: {item.Update}, EXISTING: {existingItem.Update}"); + var mergeResult = new MergeResult { InputItem = string.IsNullOrEmpty(item.Update) ? null : item, @@ -518,7 +522,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Transforms ICollection existingMetadataElements, ICollection newMetadataElements) { - var mergedMetadata = new List(existingMetadataElements); + var mergedMetadata = new List(existingMetadataElements.Select(m => (ProjectMetadataElement) m.Clone())); foreach (var newMetadata in newMetadataElements) { @@ -526,11 +530,11 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Transforms m.Name.Equals(newMetadata.Name, StringComparison.OrdinalIgnoreCase)); if (existingMetadata == null) { - mergedMetadata.Add(newMetadata); + mergedMetadata.Add((ProjectMetadataElement) newMetadata.Clone()); } else { - MergeMetadata(existingMetadata, newMetadata); + MergeMetadata(existingMetadata, (ProjectMetadataElement) newMetadata.Clone()); } } @@ -541,7 +545,25 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Transforms { if (existingMetadata.Value != newMetadata.Value) { - existingMetadata.Value = string.Join(";", new [] { existingMetadata.Value, newMetadata.Value }); + if (existingMetadata.Name == "CopyToOutputDirectory" || + existingMetadata.Name == "CopyToPublishDirectory") + { + existingMetadata.Value = + existingMetadata.Value == "Never" || newMetadata.Value == "Never" ? + "Never" : + "PreserveNewest"; + } + else if (existingMetadata.Name == "Pack") + { + existingMetadata.Value = + existingMetadata.Value == "false" || newMetadata.Value == "false" ? + "false" : + "true"; + } + else + { + existingMetadata.Value = string.Join(";", new [] { existingMetadata.Value, newMetadata.Value }); + } } } diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateBuildOptions.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateBuildOptions.cs index 346dcf04a..988e6f010 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateBuildOptions.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateBuildOptions.cs @@ -549,13 +549,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests } } - [Theory] - [InlineData("copyToOutput", "None", 2, ";rootfile.cs")] - public void MigratingCopyToOutputIncludeExcludePopulatesAppropriateProjectItemElement( - string group, - string itemName, - int expectedNumberOfCompileItems, - string expectedRootFiles) + [Fact] + public void MigratingCopyToOutputIncludeExcludePopulatesAppropriateProjectItemElement() { var testDirectory = Temp.CreateDirectory().Path; WriteExtraFiles(testDirectory); @@ -563,29 +558,38 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var pj = @" { ""buildOptions"": { - """": { + ""copyToOutput"": { ""include"": [""root"", ""src"", ""rootfile.cs""], - ""exclude"": [""src"", ""rootfile.cs""], + ""exclude"": [""anothersource"", ""rootfile1.cs""], ""includeFiles"": [""src/file1.cs"", ""src/file2.cs""], - ""excludeFiles"": [""src/file2.cs""] + ""excludeFiles"": [""src/file3.cs""] } } - }".Replace("", group); + }"; var mockProj = RunBuildOptionsRuleOnPj(pj, testDirectory: testDirectory); - mockProj.Items.Count(i => i.ItemType.Equals(itemName, StringComparison.Ordinal)) - .Should().Be(expectedNumberOfCompileItems); + mockProj.Items.Count(i => i.ItemType.Equals("None", StringComparison.Ordinal)) + .Should().Be(4); - foreach (var item in mockProj.Items.Where(i => i.ItemType.Equals(itemName, StringComparison.Ordinal))) + var copyItems = mockProj.Items.Where(i => + i.ItemType.Equals("None", StringComparison.Ordinal) && + i.Metadata.Any(m => m.Name == "CopyToOutputDirectory" && m.Value == "PreserveNewest")); + + copyItems.Count().Should().Be(2); + + var excludeItems = mockProj.Items.Where(i => + i.ItemType.Equals("None", StringComparison.Ordinal) && + i.Metadata.Any(m => m.Name == "CopyToOutputDirectory" && m.Value == "Never")); + + excludeItems.Count().Should().Be(2); + + foreach (var item in copyItems) { VerifyContentMetadata(item); - if (string.IsNullOrEmpty(item.Update)) - { - } - else if (item.Update.Contains(@"src\file1.cs")) + if (item.Update.Contains(@"src\file1.cs")) { item.Update.Should().Be(@"src\file1.cs;src\file2.cs"); } @@ -594,6 +598,20 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests item.Update.Should().Be(@"root\**\*;src\**\*;rootfile.cs"); } } + + foreach (var item in excludeItems) + { + VerifyContentMetadata(item); + + if (item.Update.Contains(@"src\file3.cs")) + { + item.Update.Should().Be(@"src\file3.cs"); + } + else + { + item.Update.Should().Be(@"anothersource\**\*;rootfile1.cs"); + } + } } [Theory] @@ -827,12 +845,14 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests { Directory.CreateDirectory(Path.Combine(directory, "root")); Directory.CreateDirectory(Path.Combine(directory, "src")); + Directory.CreateDirectory(Path.Combine(directory, "anothersource")); File.WriteAllText(Path.Combine(directory, "root", "file1.txt"), "content"); File.WriteAllText(Path.Combine(directory, "root", "file2.txt"), "content"); File.WriteAllText(Path.Combine(directory, "root", "file3.txt"), "content"); File.WriteAllText(Path.Combine(directory, "src", "file1.cs"), "content"); File.WriteAllText(Path.Combine(directory, "src", "file2.cs"), "content"); File.WriteAllText(Path.Combine(directory, "src", "file3.cs"), "content"); + File.WriteAllText(Path.Combine(directory, "anothersource", "file4.cs"), "content"); File.WriteAllText(Path.Combine(directory, "rootfile.cs"), "content"); } diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateConfigurations.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateConfigurations.cs index 485eb56d8..3ad908b48 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateConfigurations.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateConfigurations.cs @@ -157,9 +157,9 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests ""buildOptions"": { ""copyToOutput"": { ""include"": [""src""], - ""exclude"": [""src"", ""rootfile.cs""], + ""exclude"": [""anothersource"", ""rootfile.cs""], ""includeFiles"": [""src/file1.cs"", ""src/file2.cs""], - ""excludeFiles"": [""src/file2.cs""] + ""excludeFiles"": [""anothersource/file2.cs""] } }, ""configurations"": { @@ -167,9 +167,9 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests ""buildOptions"": { ""copyToOutput"": { ""include"": [""root"", ""src"", ""rootfile.cs""], - ""exclude"": [""src"", ""root/rootfile.cs""], + ""exclude"": [""anothersource"", ""root/rootfile.cs""], ""includeFiles"": [""src/file1.cs"", ""src/file2.cs""], - ""excludeFiles"": [""src/file2.cs""] + ""excludeFiles"": [""src/file3.cs""] } } } @@ -178,23 +178,65 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var contentItems = mockProj.Items.Where(item => item.ItemType == "None"); - contentItems.Count().Should().Be(3); + contentItems.Count().Should().Be(8); - // 2 for Base Build options - contentItems.Where(i => i.ConditionChain().Count() == 0).Should().HaveCount(2); + contentItems.Where(i => i.ConditionChain().Count() == 0).Should().HaveCount(4); - // 2 for Configuration BuildOptions (1 Remove, 1 Update) - contentItems.Where(i => i.ConditionChain().Count() == 1).Should().HaveCount(1); - - var configIncludeContentItem = contentItems.First( - item => item.ConditionChain().Count() > 0 && !string.IsNullOrEmpty(item.Update)); - //var configRemoveContentItem = contentItems.First( - // item => item.ConditionChain().Count() > 0 && !string.IsNullOrEmpty(item.Remove)); + contentItems.Where(i => + i.ConditionChain().Count() == 0 && + i.Metadata.Any(m => m.Value == "PreserveNewest")).Should().HaveCount(2); + contentItems.Where(i => + i.ConditionChain().Count() == 0 && + i.Metadata.Any(m => m.Value == "Never")).Should().HaveCount(2); - // Directories are not converted to globs in the result because we did not write the directory - //configRemoveContentItem.Remove.Should().Be(@"root;src;rootfile.cs"); - configIncludeContentItem.Update.Should().Be(@"root;rootfile.cs"); - //configIncludeContentItem.Exclude.Should().Be(@"src;root\rootfile.cs;src\file2.cs"); + contentItems.Where(i => i.ConditionChain().Count() == 1).Should().HaveCount(4); + contentItems.Where(i => + i.ConditionChain().Count() == 1 && + i.Metadata.Any(m => m.Value == "PreserveNewest")).Should().HaveCount(1); + contentItems.Where(i => + i.ConditionChain().Count() == 1 && + i.Metadata.Any(m => m.Value == "Never")).Should().HaveCount(2); + + contentItems.First(i => + i.ConditionChain().Count() == 1 && + i.Metadata.Any(m => m.Value == "PreserveNewest") && + !string.IsNullOrEmpty(i.Update)).Update.Should().Be(@"root;rootfile.cs"); + + contentItems.First(i => + i.ConditionChain().Count() == 1 && + i.Metadata.Any(m => m.Value == "Never") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Contains(@"src\file3.cs")).Update.Should().Be(@"src\file3.cs"); + + contentItems.First(i => + i.ConditionChain().Count() == 1 && + i.Metadata.Any(m => m.Value == "Never") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Contains(@"root\rootfile.cs")).Update.Should().Be(@"root\rootfile.cs"); + + contentItems.First(i => + i.ConditionChain().Count() == 0 && + i.Metadata.Any(m => m.Value == "PreserveNewest") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Contains(@"src\file1.cs")).Update.Should().Be(@"src\file1.cs;src\file2.cs"); + + contentItems.First(i => + i.ConditionChain().Count() == 0 && + i.Metadata.Any(m => m.Value == "PreserveNewest") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Equals(@"src")).Update.Should().Be(@"src"); + + contentItems.First(i => + i.ConditionChain().Count() == 0 && + i.Metadata.Any(m => m.Value == "Never") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Equals(@"anothersource\file2.cs")).Update.Should().Be(@"anothersource\file2.cs"); + + contentItems.First(i => + i.ConditionChain().Count() == 0 && + i.Metadata.Any(m => m.Value == "Never") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Equals(@"anothersource;rootfile.cs")).Update.Should().Be(@"anothersource;rootfile.cs"); } [Fact] @@ -214,7 +256,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests ""testconfig"": { ""buildOptions"": { ""copyToOutput"": { - ""include"": [""root"", ""src"", ""rootfile.cs""], + ""include"": [""root"", ""anothersource"", ""rootfile.cs""], ""exclude"": [""rootfile.cs"", ""someotherfile.cs""], ""includeFiles"": [""src/file1.cs"", ""src/file2.cs""], ""excludeFiles"": [""src/file2.cs""] @@ -226,46 +268,71 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var contentItems = mockProj.Items.Where(item => item.ItemType == "None"); - foreach(var c in contentItems) - { - Console.WriteLine($"Include: {c.Include}, Update: {c.Update}, Remove: {c.Remove}, Condition: {c.ConditionChain().Count()}"); - } + contentItems.Count().Should().Be(9); + contentItems.Where(i => i.ConditionChain().Count() == 0).Should().HaveCount(4); + contentItems.Where(i => i.ConditionChain().Count() == 1).Should().HaveCount(5); - contentItems.Count().Should().Be(3); + contentItems.Where(i => + i.ConditionChain().Count() == 0 && + i.Metadata.Any(m => m.Value == "PreserveNewest")).Should().HaveCount(2); + contentItems.Where(i => + i.ConditionChain().Count() == 0 && + i.Metadata.Any(m => m.Value == "Never")).Should().HaveCount(2); - // 2 for Base Build options - contentItems.Where(i => i.ConditionChain().Count() == 0).Should().HaveCount(2); + contentItems.Where(i => + i.ConditionChain().Count() == 1 && + i.Metadata.Any(m => m.Value == "PreserveNewest")).Should().HaveCount(1); + contentItems.Where(i => + i.ConditionChain().Count() == 1 && + i.Metadata.Any(m => m.Value == "Never")).Should().HaveCount(3); - // 3 for Configuration BuildOptions (1 Remove, 2 Update) - contentItems.Where(i => i.ConditionChain().Count() == 1).Should().HaveCount(1); + contentItems.First(i => + i.ConditionChain().Count() == 0 && + i.Metadata.Any(m => m.Value == "PreserveNewest") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Contains(@"src\file1.cs")).Update.Should().Be(@"src\file1.cs;src\file2.cs"); - var configIncludeContentItem = contentItems.First( - item => item.ConditionChain().Count() > 0 - && item.Update.Contains("root")); + contentItems.First(i => + i.ConditionChain().Count() == 0 && + i.Metadata.Any(m => m.Value == "PreserveNewest") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Equals(@"src")).Update.Should().Be(@"src"); - var configIncludeContentItem2 = contentItems.First( - item => item.ConditionChain().Count() == 0 - && item.Update.Contains(@"src\file1.cs")); + contentItems.First(i => + i.ConditionChain().Count() == 0 && + i.Metadata.Any(m => m.Value == "Never") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Equals(@"src\file3.cs")).Update.Should().Be(@"src\file3.cs"); - var configIncludeContentItem3 = contentItems.First( - item => item.ConditionChain().Count() == 0 - && item.Update.Equals(@"src")); + contentItems.First(i => + i.ConditionChain().Count() == 0 && + i.Metadata.Any(m => m.Value == "Never") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Equals(@"rootfile.cs")).Update.Should().Be(@"rootfile.cs"); - //var configRemoveContentItem = contentItems.First( - // item => item.ConditionChain().Count() > 0 && !string.IsNullOrEmpty(item.Remove)); + contentItems.First(i => + i.ConditionChain().Count() == 1 && + i.Metadata.Any(m => m.Value == "PreserveNewest") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Contains(@"root;anothersource")).Update.Should().Be(@"root;anothersource"); - // Directories are not converted to globs in the result because we did not write the directory - //configRemoveContentItem.Removes() - // .Should().BeEquivalentTo("root", "src", "rootfile.cs", @"src\file1.cs", @"src\file2.cs"); + contentItems.First(i => + i.ConditionChain().Count() == 1 && + i.Metadata.Any(m => m.Value == "Never") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Contains(@"src\file2.cs")).Update.Should().Be(@"src\file2.cs"); - configIncludeContentItem.Updates().Should().BeEquivalentTo("root", "rootfile.cs"); - //configIncludeContentItem.Excludes() - // .Should().BeEquivalentTo("rootfile.cs", "someotherfile.cs", @"src\file2.cs"); + contentItems.First(i => + i.ConditionChain().Count() == 1 && + i.Metadata.Any(m => m.Value == "Never") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Contains(@"rootfile.cs")).Update.Should().Be(@"rootfile.cs"); - configIncludeContentItem2.Updates().Should().BeEquivalentTo(@"src\file1.cs", @"src\file2.cs"); - //configIncludeContentItem2.Excludes().Should().BeEquivalentTo(@"src\file2.cs"); - - configIncludeContentItem3.Updates().Should().BeEquivalentTo(@"src"); + contentItems.First(i => + i.ConditionChain().Count() == 1 && + i.Metadata.Any(m => m.Value == "Never") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Contains(@"someotherfile.cs")).Update.Should().Be(@"someotherfile.cs"); } [Fact] @@ -293,6 +360,20 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var contentItems = mockProj.Items.Where(item => item.ItemType == "None"); + foreach (var item in mockProj.Items.Where(i => i.ItemType.Equals("None", StringComparison.Ordinal))) + { + Console.WriteLine($"Update: {item.Update}, Include: {item.Include}, Remove: {item.Remove}"); + foreach(var meta in item.Metadata) + { + Console.WriteLine($"\tMetadata: Name: {meta.Name}, Value: {meta.Value}"); + } + + foreach(var condition in item.ConditionChain()) + { + Console.WriteLine($"\tCondition: {condition}"); + } + } + contentItems.Count().Should().Be(2); contentItems.Where(i => i.ConditionChain().Count() == 1).Should().HaveCount(2); @@ -423,16 +504,45 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var contentItems = mockProj.Items.Where(item => item.ItemType == "None"); - contentItems.Count().Should().Be(4); + contentItems.Count().Should().Be(7); var rootBuildOptionsContentItems = contentItems.Where(i => i.ConditionChain().Count() == 0).ToList(); - rootBuildOptionsContentItems.Count().Should().Be(2); + rootBuildOptionsContentItems.Count().Should().Be(5); foreach (var buildOptionContentItem in rootBuildOptionsContentItems) { buildOptionContentItem.GetMetadataWithName("Link").Should().BeNull(); - buildOptionContentItem.GetMetadataWithName("CopyToOutputDirectory").Value.Should().Be("PreserveNewest"); } + contentItems.First(i => + i.ConditionChain().Count() == 0 && + i.Metadata.Any(m => m.Value == "PreserveNewest") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Equals(@"src\file1.cs")).Update.Should().Be(@"src\file1.cs"); + + contentItems.First(i => + i.ConditionChain().Count() == 0 && + i.Metadata.Any(m => m.Value == "PreserveNewest") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Equals(@"root")).Update.Should().Be(@"root"); + + contentItems.First(i => + i.ConditionChain().Count() == 0 && + i.Metadata.Any(m => m.Value == "Never") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Equals(@"src\file2.cs")).Update.Should().Be(@"src\file2.cs"); + + contentItems.First(i => + i.ConditionChain().Count() == 0 && + i.Metadata.Any(m => m.Value == "Never") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Equals(@"src")).Update.Should().Be(@"src"); + + contentItems.First(i => + i.ConditionChain().Count() == 0 && + i.Metadata.Any(m => m.Value == "Never") && + !string.IsNullOrEmpty(i.Update) && + i.Update.Equals(@"rootfile.cs")).Update.Should().Be(@"rootfile.cs"); + var configItems = contentItems.Where(i => i.ConditionChain().Count() == 1); configItems.Should().HaveCount(2); @@ -450,7 +560,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests configIncludeContentItem.GetMetadataWithName("Link").Value.Should().Be("/some/dir/%(FileName)%(Extension)"); configIncludeContentItem.GetMetadataWithName("CopyToOutputDirectory").Should().NotBeNull(); - configIncludeContentItem.GetMetadataWithName("CopyToOutputDirectory").Value.Should().Be("PreserveNewest"); + configIncludeContentItem.GetMetadataWithName("CopyToOutputDirectory").Value.Should().Be("Never"); configRemoveContentItem.Remove.Should().Be("src"); } @@ -490,15 +600,14 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var contentItems = mockProj.Items.Where(item => item.ItemType == "None"); - contentItems.Count().Should().Be(5); + contentItems.Count().Should().Be(8); contentItems.Where(i => i.ConditionChain().Count() == 1).Should().HaveCount(3); var rootBuildOptionsContentItems = contentItems.Where(i => i.ConditionChain().Count() == 0).ToList(); - rootBuildOptionsContentItems.Count().Should().Be(2); + rootBuildOptionsContentItems.Count().Should().Be(5); foreach (var buildOptionContentItem in rootBuildOptionsContentItems) { buildOptionContentItem.GetMetadataWithName("Link").Should().BeNull(); - buildOptionContentItem.GetMetadataWithName("CopyToOutputDirectory").Value.Should().Be("PreserveNewest"); } var configIncludeEncompassedItem = contentItems.FirstOrDefault( @@ -519,16 +628,12 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests && !string.IsNullOrEmpty(item.Remove)); configIncludeContentItem.Update.Should().Be("src"); - //configIncludeContentItem.Excludes().Should().BeEquivalentTo("src", "rootfile.cs", @"src\rootfile.cs", @"src\file2.cs"); - configIncludeContentItem.GetMetadataWithName("Link").Should().NotBeNull(); configIncludeContentItem.GetMetadataWithName("Link").Value.Should().Be("/some/dir/%(FileName)%(Extension)"); configIncludeContentItem.GetMetadataWithName("CopyToOutputDirectory").Should().NotBeNull(); - configIncludeContentItem.GetMetadataWithName("CopyToOutputDirectory").Value.Should().Be("PreserveNewest"); + configIncludeContentItem.GetMetadataWithName("CopyToOutputDirectory").Value.Should().Be("Never"); configIncludeContentItem2.Updates().Should().BeEquivalentTo(@"src\file3.cs"); - //configIncludeContentItem2.Exclude.Should().Be(@"src\file2.cs"); - configIncludeContentItem2.GetMetadataWithName("Link").Should().BeNull(); configIncludeContentItem2.GetMetadataWithName("CopyToOutputDirectory").Should().NotBeNull(); configIncludeContentItem2.GetMetadataWithName("CopyToOutputDirectory").Value.Should().Be("PreserveNewest");