public void when_none_file_has_link_then_package_path_is_relative_to_link()
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem(@"..\..\readme.txt", new Metadata
                    {
                        { "Link", @"docs\readme.txt" },
                        { "PackageId", "A" },
                        { "Kind", "None" },
                        { "TargetFramework", "any" },
                    })
                }
            };

            Assert.True(task.Execute());

            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                TargetPath  = @"docs\readme.txt",
                PackagePath = @"docs\readme.txt",
            }));
        }
        public void when_file_has_tfm_then_assigned_file_contains_target_framework(string targetFrameworkMoniker, string expectedTargetFramework)
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("library.dll", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", targetFrameworkMoniker },
                        { "Kind", "Lib" }
                    })
                }
            };

            Assert.True(task.Execute());

            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                PackageFolder   = "lib",
                PackagePath     = $"lib\\{ expectedTargetFramework}\\library.dll",
                TargetFramework = expectedTargetFramework,
            }));
        }
        public void when_content_is_not_framework_specific_then_has_any_lang_and_tfm()
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("readme.txt", new Metadata
                    {
                        { "PackageId", "A" },
                        { "Kind", "Content" },
                        { "FrameworkSpecific", "false" },
                        { "TargetFrameworkMoniker", "MonoAndroid,Version=v2.5" },
                    })
                }
            };

            Assert.True(task.Execute());

            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                CodeLanguage    = "any",
                TargetFramework = "any",
                PackagePath     = @"contentFiles\any\any\readme.txt"
            }));
        }
        public void when_assigning_content_file_with_additional_metadata_then_preserves_metadata()
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("Sample.cs", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "Kind", "Content" },
                        { MetadataName.ContentFile.CodeLanguage, "cs" },
                        { MetadataName.ContentFile.BuildAction, "EmbeddedResource" },
                        { MetadataName.ContentFile.CopyToOutput, "true" },
                        { MetadataName.ContentFile.Flatten, "true" },
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                BuildAction  = "EmbeddedResource",
                CodeLanguage = "cs",
                CopyToOutput = "true",
                Flatten      = "true",
            }));
        }
        public void when_file_has_target_framework_and_tfm_then_existing_value_is_preserved()
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("library.dll", new Metadata
                    {
                        { "PackageId", "A" },
                        { "Kind", "ContentFiles" },
                        { "TargetFramework", "any" },
                        { "TargetFrameworkMoniker", "MonoAndroid,Version=v2.5" },
                    })
                }
            };

            Assert.True(task.Execute());

            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                TargetFramework = "any",
            }));
        }
        public void assigned_files_contains_all_files()
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("a.dll", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "Kind", "Lib" }
                    }),
                    new TaskItem("a.pdb", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "Kind", "Symbols" }
                    })
                }
            };

            Assert.True(task.Execute());

            Assert.Equal(task.Files.Length, task.AssignedFiles.Length);
        }
        public void when_file_has_relative_target_path_without_non_framework_specific_then_package_path_has_relative_path()
        {
            var task = new AssignPackagePath
            {
                BuildEngine  = engine,
                KnownFolders = Kinds,
                Files        = new ITaskItem[]
                {
                    new TaskItem("sdk/bin/tool.exe", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", ".NET,Version=v5.0" },
                        { "PackFolder", "tool" },
                        { "FrameworkSpecific", "false" },
                        { "TargetPath", "sdk/bin/tool.exe" }
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                PackagePath = @"tools/sdk/bin/tool.exe",
            }));
        }
        public void when_file_has_none_kind_with_target_path_then_assigned_file_has_empty_package_folder_with_relative_package_path()
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("library.dll", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "Kind", "None" },
                        { "TargetPath", "workbook\\library.dll" }
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                PackageFolder = "",
                PackagePath   = @"workbook\library.dll",
            }));
        }
        public void when_tool_has_relative_target_path_with_framework_specific_true_then_package_path_has_relative_path_with_target_framework()
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("sdk\\bin\\tool.exe", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "Kind", "Tool" },
                        { "FrameworkSpecific", "true" },
                        { "TargetPath", "sdk\\bin\\tool.exe" }
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                PackagePath = @"tools\net45\sdk\bin\tool.exe",
            }));
        }
        public void when_package_file_has_directory_package_path_then_appends_file_and_extension()
        {
            var task = new AssignPackagePath
            {
                BuildEngine  = engine,
                KnownFolders = Kinds,
                Files        = new ITaskItem[]
                {
                    new TaskItem(@"readme.txt", new Metadata
                    {
                        { "PackageId", "A" },
                        { "PackFolder", "none" },
                        { "PackagePath", @"build/" },
                    }),
                    new TaskItem(@"readme.txt", new Metadata
                    {
                        { "PackageId", "A" },
                        { "PackFolder", "none" },
                        { "PackagePath", @"docs/quickstart/" },
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                PackagePath = @"build/readme.txt",
            }));
            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                PackagePath = @"docs/quickstart/readme.txt",
            }));
        }
        public void when_content_file_has_link_then_package_path_is_relative_to_link()
        {
            var task = new AssignPackagePath
            {
                BuildEngine  = engine,
                KnownFolders = Kinds,
                Files        = new ITaskItem[]
                {
                    new TaskItem(@"../../readme.txt", new Metadata
                    {
                        { "Link", @"docs/readme.txt" },
                        { "PackageId", "A" },
                        { "PackFolder", "content" },
                        { "TargetFramework", "any" },
                    })
                }
            };

            Assert.True(task.Execute());

            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                TargetPath  = @"docs/readme.txt",
                PackagePath = @"contentFiles/any/any/docs/readme.txt",
            }));
        }
        public void when_file_has_explicit_package_path_then_calculated_package_folder_is_empty_and_preserves_package_path()
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("readme.txt", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "Kind", "None" },
                        { "PackagePath", "docs\\readme.txt" }
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                PackageFolder = "",
                PackagePath   = "docs\\readme.txt"
            }));
        }
        public void when_file_has_known_kind_then_assigned_file_contains_mapped_package_folder(string packageFileKind, string mappedPackageFolder, string frameworkSpecific)
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("library.dll", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "Kind", packageFileKind }
                    })
                }
            };

            var isFrameworkSpecific = true;

            bool.TryParse(frameworkSpecific, out isFrameworkSpecific);

            Assert.True(task.Execute());
            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                PackageFolder = mappedPackageFolder,
                PackagePath   = $"{mappedPackageFolder}{(isFrameworkSpecific ? "\\net45" : "")}\\library.dll",
            }));
        }
        public void when_file_has_no_kind_then_logs_error_code()
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("library.dll", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" }
                    })
                }
            };

            Assert.False(task.Execute());
            Assert.Equal(nameof(ErrorCode.NG0010), engine.LoggedErrorEvents[0].Code);
        }
        public void when_file_has_no_package_id_then_package_path_is_not_specified()
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("library.dll", new Metadata
                    {
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "Kind", "Lib" }
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.Equal("", task.AssignedFiles[0].GetMetadata(MetadataName.PackagePath));
        }
        public void when_file_has_no_package_id_but_is_packaging_true_then_package_path_is_specified()
        {
            var task = new AssignPackagePath
            {
                IsPackaging  = "true",
                BuildEngine  = engine,
                KnownFolders = Kinds,
                Files        = new ITaskItem[]
                {
                    new TaskItem("library.dll", new Metadata
                    {
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "PackFolder", "lib" }
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.Equal(@"lib/net45/library.dll", task.AssignedFiles[0].GetMetadata(MetadataName.PackagePath));
        }
        public void when_file_has_none_kind_then_assigned_file_has_no_target_framework_in_package_path()
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("library.dll", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "Kind", "None" }
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.NotEqual("net45", task.AssignedFiles[0].GetMetadata(MetadataName.PackagePath).Split(Path.DirectorySeparatorChar)[0]);
        }
        public void when_assigning_content_file_with_reserved_dir_then_fails()
        {
            var task = new AssignPackagePath
            {
                BuildEngine  = engine,
                KnownFolders = Kinds,
                Files        = new ITaskItem[]
                {
                    new TaskItem(@"contentFiles/cs/monodroid/content.cs", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "TargetPath", @"contentFiles/cs/monodroid/content.cs" },
                        { "PackFolder", "content" },
                    })
                }
            };

            Assert.False(task.Execute());
            Assert.Contains(engine.LoggedErrorEvents, e => e.Code == nameof(ThisAssembly.Strings.ErrorCode.NG0013));
        }
        public void when_assigning_content_file_with_reserved_dir_then_fails()
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem(@"contentFiles\cs\monodroid\content.cs", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "TargetPath", @"contentFiles\cs\monodroid\content.cs" },
                        { "Kind", "Content" },
                    })
                }
            };

            Assert.False(task.Execute());
            Assert.True(engine.LoggedErrorEvents.Any(e => e.Code == nameof(Strings.ErrorCode.NG0013)));
        }
        public void when_file_has_no_package_id_then_package_folder_is_calculated_anyway()
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("library.dll", new Metadata
                    {
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "Kind", "Lib" }
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                PackageFolder = "lib"
            }));
        }
        public void when_file_has_relative_target_path_without_tfm_then_package_path_has_relative_path()
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("sdk\\bin\\tool.exe", new Metadata
                    {
                        { "PackageId", "A" },
                        { "Kind", "Tool" },
                        { "TargetPath", "sdk\\bin\\tool.exe" }
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                PackagePath = @"tools\sdk\bin\tool.exe",
            }));
        }
        public void when_file_has_no_kind_and_no_framework_specific_then_it_is_not_assigned_target_framework()
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("library.dll", new Metadata
                    {
                        { "PackagePath", "workbooks\\library.dll" },
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" }
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                PackagePath     = "workbooks\\library.dll",
                TargetFramework = ""
            }));
        }
        public void when_assigning_content_file_then_applies_tfm_and_language(string tfm, string lang, string expectedPath)
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("Sample.cs", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", tfm },
                        { "Kind", "Content" },
                        { "CodeLanguage", lang }
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.Equal("contentFiles", task.AssignedFiles[0].GetMetadata(MetadataName.PackageFolder));
            Assert.True(task.AssignedFiles[0].GetMetadata("PackagePath").StartsWith(expectedPath),
                        $"'{task.AssignedFiles[0].GetMetadata("PackagePath")}' does not start with expected '{expectedPath}'");
        }
        public void when_file_has_known_kind_with_no_package_folder_then_package_path_is_empty(string packageFileKind)
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("Foo", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "Kind", packageFileKind }
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                PackagePath = "",
            }));
        }
        public void when_file_is_not_framework_specific_then_it_is_not_assigned_target_framework()
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("tools\\foo.exe", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "Kind", "Tools" },
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                PackagePath     = @"tools\foo.exe",
                TargetFramework = "",
            }));
        }
        public void when_lib_has_framework_specific_false_then_package_path_does_not_have_target_framework()
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("console.exe", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "Kind", "Lib" },
                        { "FrameworkSpecific", "false" },
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                PackagePath = @"lib\console.exe",
            }));
        }
        public void when_file_has_inferred_folder_from_kind_then_assigned_file_contains_inferred_package_folder(string packageFileKind, string inferredPackageFolder)
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem("library.dll", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "Kind", packageFileKind }
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                PackageFolder = inferredPackageFolder,
                PackagePath   = $"{inferredPackageFolder}\\library.dll",
            }));
        }
        public void when_packing_tool_then_it_is_framework_specific_and_any()
        {
            var task = new AssignPackagePath
            {
                BuildEngine  = engine,
                KnownFolders = Kinds,
                Files        = new ITaskItem[]
                {
                    new TaskItem("tools/foo.exe", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "PackFolder", "tools" },
                    }),
                }
            };

            Assert.True(task.Execute());
            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                PackagePath     = @"tools/net45/any/foo.exe",
                TargetFramework = "net45",
            }));
        }
        public void when_file_has_none_kind_then_assigned_file_has_empty_package_folder_and_relative_package_path()
        {
            var task = new AssignPackagePath
            {
                BuildEngine = engine,
                Kinds       = kinds,
                Files       = new ITaskItem[]
                {
                    new TaskItem(@"content\docs\readme.txt", new Metadata
                    {
                        { "PackageId", "A" },
                        { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
                        { "Kind", "None" },
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                PackageFolder = "",
                PackagePath   = @"content\docs\readme.txt",
            }));
        }
        public void when_file_has_no_tfm_then_assigned_file_contains_no_target_framework()
        {
            var task = new AssignPackagePath
            {
                BuildEngine  = engine,
                KnownFolders = Kinds,
                Files        = new ITaskItem[]
                {
                    new TaskItem("library.dll", new Metadata
                    {
                        { "PackageId", "A" },
                        { "PackFolder", "lib" }
                    })
                }
            };

            Assert.True(task.Execute());
            Assert.Contains(task.AssignedFiles, item => item.Matches(new
            {
                PackageFolder   = "lib",
                PackagePath     = "lib/library.dll",
                TargetFramework = ""
            }));
        }