diff --git a/template_feed/Microsoft.DotNet.Common.ProjectTemplates.6.0/content/ClassLibrary-CSharp/Class1.cs b/template_feed/Microsoft.DotNet.Common.ProjectTemplates.6.0/content/ClassLibrary-CSharp/Class1.cs index 2dcafee5a35a..24e7f1f8fd42 100644 --- a/template_feed/Microsoft.DotNet.Common.ProjectTemplates.6.0/content/ClassLibrary-CSharp/Class1.cs +++ b/template_feed/Microsoft.DotNet.Common.ProjectTemplates.6.0/content/ClassLibrary-CSharp/Class1.cs @@ -2,6 +2,13 @@ using System; #endif +#if (csharpFeature_FileScopedNamespaces) +namespace Company.ClassLibrary1; +public class Class1 +{ + +} +#else namespace Company.ClassLibrary1 { public class Class1 @@ -9,3 +16,4 @@ public class Class1 } } +#endif diff --git a/test/dotnet-new3.UnitTests/CommonTemplatesTests.cs b/test/dotnet-new3.UnitTests/CommonTemplatesTests.cs index ccc22fb52188..fb07d9428990 100644 --- a/test/dotnet-new3.UnitTests/CommonTemplatesTests.cs +++ b/test/dotnet-new3.UnitTests/CommonTemplatesTests.cs @@ -554,6 +554,107 @@ public void ImplicitUsingsSupport(string name, bool buildPass, string? framework Assert.Equal("true", projectXml.Root?.Element(ns + "PropertyGroup")?.Element(ns + "DisableImplicitNamespaceImports")?.Value); } } + + public static IEnumerable FileScopedNamespacesSupport_Data() + { + var templatesToTest = new[] + { + new { Template = "classlib", Frameworks = new[] { null, "net6.0", "netstandard2.0", "netstandard2.1" } } + }; + string[] unsupportedLanguageVersions = { "1", "ISO-1" }; + string?[] supportedLanguageVersions = { null, "ISO-2", "2", "3", "4", "5", "6", "7", "7.1", "7.2", "7.3", "8.0", "9.0", "10.0", "latest", "latestMajor", "default", "preview" }; + + string?[] supportedFrameworks = { null, "net6.0" }; + string?[] fileScopedNamespacesSupportedLanguages = { "10.0", "latest", "latestMajor", "default", "preview" }; + + foreach (var template in templatesToTest) + { + foreach (var langVersion in unsupportedLanguageVersions) + { + foreach (var framework in template.Frameworks) + { + yield return new object?[] { template.Template, false, framework, langVersion, fileScopedNamespacesSupportedLanguages.Contains(langVersion) || langVersion == null && supportedFrameworks.Contains(framework) }; + } + } + foreach (var langVersion in supportedLanguageVersions) + { + foreach (var framework in template.Frameworks) + { + yield return new object?[] { template.Template, true, framework, langVersion, fileScopedNamespacesSupportedLanguages.Contains(langVersion) || langVersion == null && supportedFrameworks.Contains(framework) }; + } + } + } + } + + [Theory] + //creates all possible combinations for supported templates, language versions and frameworks + [MemberData(nameof(FileScopedNamespacesSupport_Data))] + public void FileScopedNamespacesSupport(string name, bool pass, string? framework, string? langVersion, bool supportsFeature) + { + string workingDir = TestUtils.CreateTemporaryFolder(); + + List args = new List() { name, "-o", "MyProject" }; + if (!string.IsNullOrWhiteSpace(framework)) + { + args.Add("--framework"); + args.Add(framework); + } + if (!string.IsNullOrWhiteSpace(langVersion)) + { + args.Add("--langVersion"); + args.Add(langVersion); + } + + new DotnetNewCommand(_log, args.ToArray()) + .WithCustomHive(_fixture.HomeDirectory) + .WithWorkingDirectory(workingDir) + .Execute() + .Should() + .ExitWith(0) + .And.NotHaveStdErr(); + + var buildResult = new DotnetCommand(_log, "build", "MyProject") + .WithWorkingDirectory(workingDir) + .Execute(); + + if (pass) + { + buildResult.Should().ExitWith(0).And.NotHaveStdErr(); + } + else + { + buildResult.Should().Fail(); + return; + } + string codeFileName = name == "console" ? "Program.cs" : "Class1.cs"; + string programFileContent = File.ReadAllText(Path.Combine(workingDir, "MyProject", codeFileName)); + + string supportedContent = +@"namespace MyProject; +public class Class1 +{ + +}"; + string unsupportedContent = +@"namespace MyProject +{ + public class Class1 + { + + } +}"; + + if (supportsFeature) + { + Assert.DoesNotContain(unsupportedContent, programFileContent); + Assert.Contains(supportedContent, programFileContent); + } + else + { + Assert.DoesNotContain(supportedContent, programFileContent); + Assert.Contains(unsupportedContent, programFileContent); + } + } #endregion [Theory]