using Microsoft.Build.Construction; using Microsoft.DotNet.ProjectJsonMigration; using Microsoft.DotNet.Internal.ProjectModel; using Microsoft.DotNet.Tools.Test.Utilities; using NuGet.Frameworks; using System; using System.IO; using System.Linq; using Xunit; using FluentAssertions; using Microsoft.DotNet.ProjectJsonMigration.Rules; using Microsoft.DotNet.Internal.ProjectModel.Files; using System.Collections.Generic; namespace Microsoft.DotNet.ProjectJsonMigration.Tests { public class GivenThatIWantToMigrateBuildOptions : TestBase { [Fact] public void MigratingDeprecatedCompilationOptionsWithEmitEntryPointPopulatesOutputTypeField() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""compilationOptions"": { ""emitEntryPoint"": ""true"" }, ""exclude"": [ ""node_modules"" ] }"); mockProj.Properties.Count(p => p.Name == "OutputType").Should().Be(1); mockProj.Properties.First(p => p.Name == "OutputType").Value.Should().Be("Exe"); mockProj.Items.Count(i => i.ItemType.Equals("Compile", StringComparison.Ordinal)) .Should().Be(1); mockProj.Items.Count(i => i.ItemType.Equals("Compile", StringComparison.Ordinal) && i.Remove.Equals("node_modules")) .Should().Be(1); mockProj.Items.Count(i => i.ItemType.Equals("EmbeddedResource", StringComparison.Ordinal)) .Should().Be(1); mockProj.Items.Count(i => i.ItemType.Equals("EmbeddedResource", StringComparison.Ordinal) && i.Remove.Equals("node_modules")) .Should().Be(1); } [Fact] public void SpecifiedDefaultPropertiesAreRemovedWhenTheyExistInTheCsprojTemplate() { // Setup project with default properties var defaultPropertiesExpectedToBeRemoved = new string[] { "OutputType", "TargetExt" }; var defaultValue = "defaultValue"; var templateProj = ProjectRootElement.Create(); var defaultPropertyGroup = templateProj.AddPropertyGroup(); foreach (var defaultPropertyName in defaultPropertiesExpectedToBeRemoved) { defaultPropertyGroup.AddProperty(defaultPropertyName, defaultValue); } // Setup projectcontext var testProjectDirectory = TestAssetsManager.CreateTestInstance("TestAppWithRuntimeOptions").Path; var projectContext = ProjectContext.Create(testProjectDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10); var testSettings = MigrationSettings.CreateMigrationSettingsTestHook(testProjectDirectory, testProjectDirectory, templateProj); var testInputs = new MigrationRuleInputs(new[] {projectContext}, templateProj, templateProj.AddItemGroup(), templateProj.AddPropertyGroup()); new MigrateBuildOptionsRule().Apply(testSettings, testInputs); defaultPropertyGroup.Properties.Count.Should().Be(0); } [Fact] public void MigratingEmptyBuildOptionsGeneratesAnEmptyCSProj() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { } }"); mockProj.Items.Count().Should().Be(0); } [Fact] public void MigratingWebProjectWithoutCustomSourcesOrResourcesDoesNotEmitCompileAndEmbeddedResource() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""emitEntryPoint"": true }, ""dependencies"": { ""Microsoft.AspNetCore.Mvc"" : { ""version"": ""1.0.0"" } }, ""frameworks"": { ""netcoreapp1.0"": {} } }"); mockProj.Items.Count().Should().Be(0); } [Fact] public void MigratingConsoleProjectWithoutCustomSourcesOrResourcesDoesNotEmitCompileAndEmbeddedResource() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""emitEntryPoint"": true }, ""frameworks"": { ""netcoreapp1.0"": {} } }"); mockProj.Items.Count().Should().Be(0); } public void MigratingOutputNamePopulatesAssemblyName() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""outputName"": ""some name"" } }"); mockProj.Properties.Count(p => p.Name == "AssemblyName").Should().Be(1); mockProj.Properties.First(p => p.Name == "AssemblyName").Value.Should().Be("some name"); } [Fact] public void MigratingOutputNamePopulatesPackageIdWithTheProjectContainingFolderName() { var testDirectoryPath = Temp.CreateDirectory().Path; var testDirectoryName = new DirectoryInfo(testDirectoryPath).Name; var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""outputName"": ""some name"" } }", testDirectoryPath); mockProj.Properties.Count(p => p.Name == "PackageId").Should().Be(1); mockProj.Properties.First(p => p.Name == "PackageId").Value.Should().Be(testDirectoryName); } [Fact] public void MigratingEmitEntryPointTruePopulatesOutputTypeField() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""emitEntryPoint"": ""true"" } }"); mockProj.Properties.Count(p => p.Name == "OutputType").Should().Be(1); mockProj.Properties.First(p => p.Name == "OutputType").Value.Should().Be("Exe"); } [Fact] public void MigratingEmitEntryPointFalsePopulatesOutputTypeFields() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""emitEntryPoint"": ""false"" } }"); mockProj.Properties.Count(p => p.Name == "OutputType").Should().Be(1); mockProj.Properties.First(p => p.Name == "OutputType").Value.Should().Be("Library"); } [Fact] public void MigratingDefinePopulatesDefineConstants() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""define"": [ ""DEBUG"", ""TRACE"" ] } }"); mockProj.Properties.Count(p => p.Name == "DefineConstants").Should().Be(1); mockProj.Properties.First(p => p.Name == "DefineConstants") .Value.Should().Be("$(DefineConstants);DEBUG;TRACE"); } [Fact] public void MigratingNowarnPopulatesNoWarn() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""nowarn"": [ ""CS0168"", ""CS0219"" ] } }"); mockProj.Properties.Count(p => p.Name == "NoWarn").Should().Be(1); mockProj.Properties.First(p => p.Name == "NoWarn").Value.Should().Be("$(NoWarn);CS0168;CS0219"); } [Fact] public void MigratingWarningsAsErrorsPopulatesWarningsAsErrors() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""warningsAsErrors"": ""true"" } }"); mockProj.Properties.Count(p => p.Name == "TreatWarningsAsErrors").Should().Be(1); mockProj.Properties.First(p => p.Name == "TreatWarningsAsErrors").Value.Should().Be("true"); mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""warningsAsErrors"": ""false"" } }"); mockProj.Properties.Count(p => p.Name == "TreatWarningsAsErrors").Should().Be(0); } [Fact] public void MigratingAllowUnsafePopulatesAllowUnsafeBlocks() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""allowUnsafe"": ""true"" } }"); mockProj.Properties.Count(p => p.Name == "AllowUnsafeBlocks").Should().Be(1); mockProj.Properties.First(p => p.Name == "AllowUnsafeBlocks").Value.Should().Be("true"); mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""allowUnsafe"": ""false"" } }"); mockProj.Properties.Count(p => p.Name == "AllowUnsafeBlocks").Should().Be(0); } [Fact] public void MigratingOptimizePopulatesOptimize() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""optimize"": ""true"" } }"); mockProj.Properties.Count(p => p.Name == "Optimize").Should().Be(1); mockProj.Properties.First(p => p.Name == "Optimize").Value.Should().Be("true"); mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""optimize"": ""false"" } }"); mockProj.Properties.Count(p => p.Name == "Optimize").Should().Be(0); } [Fact] public void MigratingPlatformPopulatesPlatformTarget() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""platform"": ""x64"" } }"); mockProj.Properties.Count(p => p.Name == "PlatformTarget").Should().Be(1); mockProj.Properties.First(p => p.Name == "PlatformTarget").Value.Should().Be("x64"); mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""platform"": ""x86"" } }"); mockProj.Properties.Count(p => p.Name == "PlatformTarget").Should().Be(1); mockProj.Properties.First(p => p.Name == "PlatformTarget").Value.Should().Be("x86"); mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""platform"": ""foo"" } }"); mockProj.Properties.Count(p => p.Name == "PlatformTarget").Should().Be(1); mockProj.Properties.First(p => p.Name == "PlatformTarget").Value.Should().Be("foo"); } [Fact] public void MigratingLanguageVersionPopulatesLangVersion() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""languageVersion"": ""5"" } }"); mockProj.Properties.Count(p => p.Name == "LangVersion").Should().Be(1); mockProj.Properties.First(p => p.Name == "LangVersion").Value.Should().Be("5"); } [Fact] public void MigratingLanguageVersionRemovesCsharpInLangVersion() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""languageVersion"": ""csharp5"" } }"); mockProj.Properties.Count(p => p.Name == "LangVersion").Should().Be(1); mockProj.Properties.First(p => p.Name == "LangVersion").Value.Should().Be("5"); } [Fact] public void MigratingKeyFilePopulatesAssemblyOriginatorKeyFileAndSignAssembly() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""keyFile"": ""../keyfile.snk"" } }"); mockProj.Properties.Count(p => p.Name == "AssemblyOriginatorKeyFile").Should().Be(1); mockProj.Properties.First(p => p.Name == "AssemblyOriginatorKeyFile").Value.Should().Be("../keyfile.snk"); mockProj.Properties.Count(p => p.Name == "SignAssembly").Should().Be(1); mockProj.Properties.First(p => p.Name == "SignAssembly").Value.Should().Be("true"); mockProj.Properties.Count(p => p.Name == "PublicSign").Should().Be(1); mockProj.Properties.First(p => p.Name == "PublicSign").Value.Should().Be("true"); mockProj.Properties.First(p => p.Name == "PublicSign").Condition.Should().Be(" '$(OS)' != 'Windows_NT' "); } [Fact] public void MigratingDelaySignPopulatesDelaySign() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""delaySign"": ""true"" } }"); mockProj.Properties.Count(p => p.Name == "DelaySign").Should().Be(1); mockProj.Properties.First(p => p.Name == "DelaySign").Value.Should().Be("true"); mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""delaySign"": ""false"" } }"); mockProj.Properties.Count(p => p.Name == "DelaySign").Should().Be(0); } [Fact] public void MigratingPublicSignPopulatesPublicSign() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""publicSign"": ""true"" } }"); mockProj.Properties.Count(p => p.Name == "PublicSign").Should().Be(1); mockProj.Properties.First(p => p.Name == "PublicSign").Value.Should().Be("true"); mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""publicSign"": ""false"" } }"); mockProj.Properties.Count(p => p.Name == "PublicSign").Should().Be(0); } [Fact] public void MigratingDebugTypePopulatesDebugType() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""debugType"": ""full"" } }"); mockProj.Properties.Count(p => p.Name == "DebugType").Should().Be(1); mockProj.Properties.First(p => p.Name == "DebugType").Value.Should().Be("full"); mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""debugType"": ""foo"" } }"); mockProj.Properties.Count(p => p.Name == "DebugType").Should().Be(1); mockProj.Properties.First(p => p.Name == "DebugType").Value.Should().Be("foo"); } [Fact] public void MigratingXmlDocPopulatesGenerateDocumentationFile() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""xmlDoc"": ""true"" } }"); mockProj.Properties.Count(p => p.Name == "GenerateDocumentationFile").Should().Be(1); mockProj.Properties.First(p => p.Name == "GenerateDocumentationFile").Value.Should().Be("true"); } [Fact] public void ExcludedPatternsAreNotEmittedOnNoneWhenBuildingAWebProject() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""emitEntryPoint"": true, ""copyToOutput"": { ""include"": [""wwwroot"", ""**/*.cshtml"", ""appsettings.json"", ""web.config""], } }, ""dependencies"": { ""Microsoft.AspNetCore.Mvc"" : { ""version"": ""1.0.0"" } }, ""frameworks"": { ""netcoreapp1.0"": {} } }"); mockProj.Items.Count(i => i.ItemType.Equals("None", StringComparison.Ordinal)).Should().Be(0); } [Theory] [InlineData("compile", "Compile", 3, "")] [InlineData("embed", "EmbeddedResource", 3, ";rootfile.cs")] public void MigratingGroupIncludeExcludePopulatesAppropriateProjectItemElement( string group, string itemName, int expectedNumberOfCompileItems, string expectedRootFiles) { var testDirectory = Temp.CreateDirectory().Path; WriteExtraFiles(testDirectory); var pj = @" { ""buildOptions"": { """": { ""include"": [""root"", ""src"", ""rootfile.cs""], ""exclude"": [""src"", ""rootfile.cs""], ""includeFiles"": [""src/file1.cs"", ""src/file2.cs""], ""excludeFiles"": [""src/file2.cs""] } } }".Replace("", group); var mockProj = RunBuildOptionsRuleOnPj(pj, testDirectory: testDirectory); mockProj.Items.Count(i => i.ItemType.Equals(itemName, StringComparison.Ordinal)) .Should().Be(expectedNumberOfCompileItems); var defaultIncludePatterns = GetDefaultIncludePatterns(group); var defaultExcludePatterns = GetDefaultExcludePatterns(group); foreach (var item in mockProj.Items.Where(i => i.ItemType.Equals(itemName, StringComparison.Ordinal))) { VerifyContentMetadata(item); if (string.IsNullOrEmpty(item.Include)) { item.Remove.Should() .Be(@"src\**\*;rootfile.cs;src\file2.cs"); } else if (item.Include.Contains(@"src\file1.cs")) { item.Include.Should().Be(@"src\file1.cs;src\file2.cs"); item.Exclude.Should().Be(@"src\file2.cs"); } else { if (defaultIncludePatterns.Any()) { item.Include.Should() .Be($@"root\**\*;src\**\*{expectedRootFiles};" + string.Join(";", defaultIncludePatterns).Replace("/", "\\")); } else { item.Include.Should() .Be($@"root\**\*;src\**\*{expectedRootFiles}"); } if (defaultExcludePatterns.Any()) { item.Exclude.Should() .Be(@"src\**\*;rootfile.cs;" + string.Join(";", defaultExcludePatterns).Replace("/", "\\") + @";src\file2.cs"); } else { item.Exclude.Should() .Be(@"src\**\*;rootfile.cs;src\file2.cs"); } } } } [Theory] [InlineData("copyToOutput", "None", 2, ";rootfile.cs")] public void MigratingCopyToOutputIncludeExcludePopulatesAppropriateProjectItemElement( string group, string itemName, int expectedNumberOfCompileItems, string expectedRootFiles) { var testDirectory = Temp.CreateDirectory().Path; WriteExtraFiles(testDirectory); var pj = @" { ""buildOptions"": { """": { ""include"": [""root"", ""src"", ""rootfile.cs""], ""exclude"": [""src"", ""rootfile.cs""], ""includeFiles"": [""src/file1.cs"", ""src/file2.cs""], ""excludeFiles"": [""src/file2.cs""] } } }".Replace("", group); var mockProj = RunBuildOptionsRuleOnPj(pj, testDirectory: testDirectory); mockProj.Items.Count(i => i.ItemType.Equals(itemName, StringComparison.Ordinal)) .Should().Be(expectedNumberOfCompileItems); foreach (var item in mockProj.Items.Where(i => i.ItemType.Equals(itemName, StringComparison.Ordinal))) { VerifyContentMetadata(item); if (string.IsNullOrEmpty(item.Update)) { } else if (item.Update.Contains(@"src\file1.cs")) { item.Update.Should().Be(@"src\file1.cs;src\file2.cs"); } else { item.Update.Should().Be(@"root\**\*;src\**\*;rootfile.cs"); } } } [Theory] [InlineData("compile", "Compile", "")] [InlineData("embed", "EmbeddedResource", ";rootfile.cs")] public void MigratingGroupIncludeOnlyPopulatesAppropriateProjectItemElement( string group, string itemName, string expectedRootFiles) { var testDirectory = Temp.CreateDirectory().Path; WriteExtraFiles(testDirectory); var pj = @" { ""buildOptions"": { """": [""root"", ""src"", ""rootfile.cs""] } }".Replace("", group); var mockProj = RunBuildOptionsRuleOnPj(pj, testDirectory: testDirectory); mockProj.Items.Count(i => i.ItemType.Equals(itemName, StringComparison.Ordinal)).Should().Be(1); var defaultIncludePatterns = GetDefaultIncludePatterns(group); var defaultExcludePatterns = GetDefaultExcludePatterns(group); foreach (var item in mockProj.Items.Where(i => i.ItemType.Equals(itemName, StringComparison.Ordinal))) { VerifyContentMetadata(item); if (defaultIncludePatterns.Any()) { item.Include.Should() .Be($@"root\**\*;src\**\*{expectedRootFiles};" + string.Join(";", defaultIncludePatterns).Replace("/", "\\")); } else { item.Include.Should() .Be($@"root\**\*;src\**\*{expectedRootFiles}"); } if (defaultExcludePatterns.Any()) { item.Exclude.Should() .Be(string.Join(";", defaultExcludePatterns).Replace("/", "\\")); } else { item.Exclude.Should() .Be(string.Empty); } } } [Theory] [InlineData("copyToOutput", "None", ";rootfile.cs")] public void MigratingCopyToOutputIncludeOnlyPopulatesAppropriateProjectItemElement( string group, string itemName, string expectedRootFiles) { var testDirectory = Temp.CreateDirectory().Path; WriteExtraFiles(testDirectory); var pj = @" { ""buildOptions"": { """": [""root"", ""src"", ""rootfile.cs""] } }".Replace("", group); var mockProj = RunBuildOptionsRuleOnPj(pj, testDirectory: testDirectory); mockProj.Items.Count(i => i.ItemType.Equals(itemName, StringComparison.Ordinal)).Should().Be(1); mockProj.Items.Single().Update.Should().Be($@"root\**\*;src\**\*{expectedRootFiles}"); } [Fact] public void MigratingTestProjectAddsGenerateRuntimeConfigurationFiles() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""testRunner"": ""xunit"" }"); mockProj.Properties.Count(p => p.Name == "GenerateRuntimeConfigurationFiles").Should().Be(1); mockProj.Properties.First(p => p.Name == "GenerateRuntimeConfigurationFiles").Value.Should().Be("true"); } [Fact] public void MigratingANonTestProjectDoesNotAddGenerateRuntimeConfigurationFiles() { var mockProj = RunBuildOptionsRuleOnPj(@" { }"); mockProj.Properties.Count(p => p.Name == "GenerateRuntimeConfigurationFiles").Should().Be(0); } [Fact] public void MigratingAnAppWithAppConfigAddsItAsNoneToTheCsProj() { var tempDirectory = Temp.CreateDirectory().Path; File.Create(Path.Combine(tempDirectory, "App.config")).Dispose(); var mockProj = RunBuildOptionsRuleOnPj(@" { }", tempDirectory); mockProj.Items.Count(i => i.ItemType == "None").Should().Be(1); mockProj.Items.First(i => i.ItemType == "None").Include.Should().Be("App.config"); } [Fact] public void MigratingCompileIncludeWithPlainFileNamesRemovesThem() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""compile"": { ""include"": [""filename1.cs"", ""filename2.cs""], } } }"); mockProj.Items.Count(i => i.ItemType.Equals("Compile", StringComparison.Ordinal)).Should().Be(0); } [Fact] public void MigratingCompileIncludeFilesWithPlainFileNamesRemovesThem() { var mockProj = RunBuildOptionsRuleOnPj(@" { ""buildOptions"": { ""compile"": { ""includeFiles"": [""filename1.cs"", ""filename2.cs""], } } }"); mockProj.Items.Count(i => i.ItemType.Equals("Compile", StringComparison.Ordinal)).Should().Be(0); } [Fact] public void MigratingProjectWithCompileResourcesPopulatesAppropriateProjectItemElements() { var testDirectory = Temp.CreateDirectory().Path; WriteCompileResourceFiles(testDirectory); var pj = @" { ""version"": ""1.0.0-*"", ""dependencies"": { ""NETStandard.Library"": ""1.6.0"" }, ""frameworks"": { ""netstandard1.5"": {} } }"; var mockProj = RunBuildOptionsRuleOnPj(pj, testDirectory); var compileItems = mockProj.Items.Where(i => i.ItemType.Equals("Compile", StringComparison.Ordinal)); compileItems.Count().Should().Be(1); var compileItem = compileItems.Single(); compileItem.Include.Should().BeEmpty(); compileItem.Exclude.Should().BeEmpty(); compileItem.Remove.Should().Be(@"compiler\resources\*"); var embeddedResourceItems = mockProj.Items.Where( i => i.ItemType.Equals("EmbeddedResource", StringComparison.Ordinal)); embeddedResourceItems.Count().Should().Be(1); var embeddedResourceItem = embeddedResourceItems.Single(); embeddedResourceItem.Include.Should().Be(@"compiler\resources\*"); embeddedResourceItem.Exclude.Should().BeEmpty(); embeddedResourceItem.Remove.Should().BeEmpty(); } [Fact] public void MigratingProjectWithoutCompileResourcesDoesNotAddProjectItemElements() { var testDirectory = Temp.CreateDirectory().Path; var pj = @" { ""version"": ""1.0.0-*"", ""dependencies"": { ""NETStandard.Library"": ""1.6.0"" }, ""frameworks"": { ""netstandard1.5"": {} } }"; var mockProj = RunBuildOptionsRuleOnPj(pj, testDirectory); mockProj.Items.Count.Should().Be(0); } private static IEnumerable GetDefaultExcludePatterns(string group) { var defaultExcludePatterns = new List(group == "copyToOutput" ? Enumerable.Empty() : ProjectFilesCollection.DefaultBuiltInExcludePatterns); if (group == "embed") { defaultExcludePatterns.Add("@(EmbeddedResource)"); } return defaultExcludePatterns; } private static IEnumerable GetDefaultIncludePatterns(string group) { return Enumerable.Empty(); } private static void VerifyContentMetadata(ProjectItemElement item) { if (item.ItemType == "None") { item.Metadata.Count(m => m.Name == "CopyToOutputDirectory").Should().Be(1); } } private void WriteExtraFiles(string directory) { Directory.CreateDirectory(Path.Combine(directory, "root")); Directory.CreateDirectory(Path.Combine(directory, "src")); 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, "rootfile.cs"), "content"); } private void WriteCompileResourceFiles(string directory) { Directory.CreateDirectory(Path.Combine(directory, "compiler")); Directory.CreateDirectory(Path.Combine(directory, "compiler", "resources")); File.WriteAllText(Path.Combine(directory, "compiler", "resources", "file.cs"), "content"); } private ProjectRootElement RunBuildOptionsRuleOnPj(string s, string testDirectory = null) { testDirectory = testDirectory ?? Temp.CreateDirectory().Path; return TemporaryProjectFileRuleRunner.RunRules(new IMigrationRule[] { new MigrateBuildOptionsRule() }, s, testDirectory); } } }