diff options
author | kkm <kkm@smartaction.com> | 2018-10-14 08:31:35 -0700 |
---|---|---|
committer | kkm <kkm@smartaction.com> | 2018-10-14 08:34:03 -0700 |
commit | 5103951117fa4c7350427ecd340031316a15615e (patch) | |
tree | 0662e839f9c5088119df612b5c65c87472e4642f /src/csharp/Grpc.Tools.Tests | |
parent | f626d4618d8ed15853e763e96a23e3635be0c339 (diff) |
Infer coding style, adjust .editorconfig, reformat Tools code
Diffstat (limited to 'src/csharp/Grpc.Tools.Tests')
-rw-r--r-- | src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs | 108 | ||||
-rw-r--r-- | src/csharp/Grpc.Tools.Tests/CppGeneratorTest.cs | 112 | ||||
-rw-r--r-- | src/csharp/Grpc.Tools.Tests/DepFileUtilTest.cs | 208 | ||||
-rw-r--r-- | src/csharp/Grpc.Tools.Tests/GeneratorTest.cs | 51 | ||||
-rw-r--r-- | src/csharp/Grpc.Tools.Tests/NUnitMain.cs | 14 | ||||
-rw-r--r-- | src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs | 84 | ||||
-rw-r--r-- | src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs | 291 | ||||
-rw-r--r-- | src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLinePrinterTest.cs | 48 | ||||
-rw-r--r-- | src/csharp/Grpc.Tools.Tests/ProtoToolsPlatformTaskTest.cs | 199 | ||||
-rw-r--r-- | src/csharp/Grpc.Tools.Tests/Utils.cs | 38 |
10 files changed, 619 insertions, 534 deletions
diff --git a/src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs b/src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs index 654500d53d..e4c9b2fa84 100644 --- a/src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs +++ b/src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs @@ -18,60 +18,68 @@ using NUnit.Framework; -namespace Grpc.Tools.Tests { - public class CSharpGeneratorTest : GeneratorTest { - GeneratorServices _generator; +namespace Grpc.Tools.Tests +{ + public class CSharpGeneratorTest : GeneratorTest + { + GeneratorServices _generator; - [SetUp] - public new void SetUp() { - _generator = GeneratorServices.GetForLanguage("CSharp", _log); - } + [SetUp] + public new void SetUp() + { + _generator = GeneratorServices.GetForLanguage("CSharp", _log); + } - [TestCase("foo.proto", "Foo.cs", "FooGrpc.cs")] - [TestCase("sub/foo.proto", "Foo.cs", "FooGrpc.cs")] - [TestCase("one_two.proto", "OneTwo.cs", "OneTwoGrpc.cs")] - [TestCase("__one_two!.proto", "OneTwo!.cs", "OneTwo!Grpc.cs")] - [TestCase("one(two).proto", "One(two).cs", "One(two)Grpc.cs")] - [TestCase("one_(two).proto", "One(two).cs", "One(two)Grpc.cs")] - [TestCase("one two.proto", "One two.cs", "One twoGrpc.cs")] - [TestCase("one_ two.proto", "One two.cs", "One twoGrpc.cs")] - [TestCase("one .proto", "One .cs", "One Grpc.cs")] - public void NameMangling(string proto, string expectCs, string expectGrpcCs) { - var poss = _generator.GetPossibleOutputs(Utils.MakeItem(proto, "grpcservices", "both")); - Assert.AreEqual(2, poss.Length); - Assert.Contains(expectCs, poss); - Assert.Contains(expectGrpcCs, poss); - } + [TestCase("foo.proto", "Foo.cs", "FooGrpc.cs")] + [TestCase("sub/foo.proto", "Foo.cs", "FooGrpc.cs")] + [TestCase("one_two.proto", "OneTwo.cs", "OneTwoGrpc.cs")] + [TestCase("__one_two!.proto", "OneTwo!.cs", "OneTwo!Grpc.cs")] + [TestCase("one(two).proto", "One(two).cs", "One(two)Grpc.cs")] + [TestCase("one_(two).proto", "One(two).cs", "One(two)Grpc.cs")] + [TestCase("one two.proto", "One two.cs", "One twoGrpc.cs")] + [TestCase("one_ two.proto", "One two.cs", "One twoGrpc.cs")] + [TestCase("one .proto", "One .cs", "One Grpc.cs")] + public void NameMangling(string proto, string expectCs, string expectGrpcCs) + { + var poss = _generator.GetPossibleOutputs(Utils.MakeItem(proto, "grpcservices", "both")); + Assert.AreEqual(2, poss.Length); + Assert.Contains(expectCs, poss); + Assert.Contains(expectGrpcCs, poss); + } - [Test] - public void NoGrpcOneOutput() { - var poss = _generator.GetPossibleOutputs(Utils.MakeItem("foo.proto")); - Assert.AreEqual(1, poss.Length); - } + [Test] + public void NoGrpcOneOutput() + { + var poss = _generator.GetPossibleOutputs(Utils.MakeItem("foo.proto")); + Assert.AreEqual(1, poss.Length); + } - [TestCase("none")] - [TestCase("")] - public void GrpcNoneOneOutput(string grpc) { - var item = Utils.MakeItem("foo.proto", "grpcservices", grpc); - var poss = _generator.GetPossibleOutputs(item); - Assert.AreEqual(1, poss.Length); - } + [TestCase("none")] + [TestCase("")] + public void GrpcNoneOneOutput(string grpc) + { + var item = Utils.MakeItem("foo.proto", "grpcservices", grpc); + var poss = _generator.GetPossibleOutputs(item); + Assert.AreEqual(1, poss.Length); + } - [TestCase("client")] - [TestCase("server")] - [TestCase("both")] - public void GrpcEnabledTwoOutputs(string grpc) { - var item = Utils.MakeItem("foo.proto", "grpcservices", grpc); - var poss = _generator.GetPossibleOutputs(item); - Assert.AreEqual(2, poss.Length); - } + [TestCase("client")] + [TestCase("server")] + [TestCase("both")] + public void GrpcEnabledTwoOutputs(string grpc) + { + var item = Utils.MakeItem("foo.proto", "grpcservices", grpc); + var poss = _generator.GetPossibleOutputs(item); + Assert.AreEqual(2, poss.Length); + } - [Test] - public void OutputDirMetadataRecognized() { - var item = Utils.MakeItem("foo.proto", "OutputDir", "out"); - var poss = _generator.GetPossibleOutputs(item); - Assert.AreEqual(1, poss.Length); - Assert.That(poss[0], Is.EqualTo("out/Foo.cs") | Is.EqualTo("out\\Foo.cs")); - } - }; + [Test] + public void OutputDirMetadataRecognized() + { + var item = Utils.MakeItem("foo.proto", "OutputDir", "out"); + var poss = _generator.GetPossibleOutputs(item); + Assert.AreEqual(1, poss.Length); + Assert.That(poss[0], Is.EqualTo("out/Foo.cs") | Is.EqualTo("out\\Foo.cs")); + } + }; } diff --git a/src/csharp/Grpc.Tools.Tests/CppGeneratorTest.cs b/src/csharp/Grpc.Tools.Tests/CppGeneratorTest.cs index a3450fae17..bd0405a03a 100644 --- a/src/csharp/Grpc.Tools.Tests/CppGeneratorTest.cs +++ b/src/csharp/Grpc.Tools.Tests/CppGeneratorTest.cs @@ -19,62 +19,70 @@ using System.IO; using NUnit.Framework; -namespace Grpc.Tools.Tests { - public class CppGeneratorTest : GeneratorTest { - GeneratorServices _generator; +namespace Grpc.Tools.Tests +{ + public class CppGeneratorTest : GeneratorTest + { + GeneratorServices _generator; - [SetUp] - public new void SetUp() { - _generator = GeneratorServices.GetForLanguage("Cpp", _log); - } + [SetUp] + public new void SetUp() + { + _generator = GeneratorServices.GetForLanguage("Cpp", _log); + } - [TestCase("foo.proto", "", "foo")] - [TestCase("foo.proto", ".", "foo")] - [TestCase("foo.proto", "./", "foo")] - [TestCase("sub/foo.proto", "", "sub/foo")] - [TestCase("root/sub/foo.proto", "root", "sub/foo")] - [TestCase("root/sub/foo.proto", "root", "sub/foo")] - [TestCase("/root/sub/foo.proto", "/root", "sub/foo")] - public void RelativeDirectoryCompute(string proto, string root, string expectStem) { - if (Path.DirectorySeparatorChar == '\\') - expectStem = expectStem.Replace('/', '\\'); - var poss = _generator.GetPossibleOutputs(Utils.MakeItem(proto, "ProtoRoot", root)); - Assert.AreEqual(2, poss.Length); - Assert.Contains(expectStem + ".pb.cc", poss); - Assert.Contains(expectStem + ".pb.h", poss); - } + [TestCase("foo.proto", "", "foo")] + [TestCase("foo.proto", ".", "foo")] + [TestCase("foo.proto", "./", "foo")] + [TestCase("sub/foo.proto", "", "sub/foo")] + [TestCase("root/sub/foo.proto", "root", "sub/foo")] + [TestCase("root/sub/foo.proto", "root", "sub/foo")] + [TestCase("/root/sub/foo.proto", "/root", "sub/foo")] + public void RelativeDirectoryCompute(string proto, string root, string expectStem) + { + if (Path.DirectorySeparatorChar == '\\') + expectStem = expectStem.Replace('/', '\\'); + var poss = _generator.GetPossibleOutputs(Utils.MakeItem(proto, "ProtoRoot", root)); + Assert.AreEqual(2, poss.Length); + Assert.Contains(expectStem + ".pb.cc", poss); + Assert.Contains(expectStem + ".pb.h", poss); + } - [Test] - public void NoGrpcTwoOutputs() { - var poss = _generator.GetPossibleOutputs(Utils.MakeItem("foo.proto")); - Assert.AreEqual(2, poss.Length); - } + [Test] + public void NoGrpcTwoOutputs() + { + var poss = _generator.GetPossibleOutputs(Utils.MakeItem("foo.proto")); + Assert.AreEqual(2, poss.Length); + } - [TestCase("false")] - [TestCase("")] - public void GrpcDisabledTwoOutput(string grpc) { - var item = Utils.MakeItem("foo.proto", "grpcservices", grpc); - var poss = _generator.GetPossibleOutputs(item); - Assert.AreEqual(2, poss.Length); - } + [TestCase("false")] + [TestCase("")] + public void GrpcDisabledTwoOutput(string grpc) + { + var item = Utils.MakeItem("foo.proto", "grpcservices", grpc); + var poss = _generator.GetPossibleOutputs(item); + Assert.AreEqual(2, poss.Length); + } - [TestCase("true")] - public void GrpcEnabledFourOutputs(string grpc) { - var item = Utils.MakeItem("foo.proto", "grpcservices", grpc); - var poss = _generator.GetPossibleOutputs(item); - Assert.AreEqual(4, poss.Length); - Assert.Contains("foo.pb.cc", poss); - Assert.Contains("foo.pb.h", poss); - Assert.Contains("foo_grpc.pb.cc", poss); - Assert.Contains("foo_grpc.pb.h", poss); - } + [TestCase("true")] + public void GrpcEnabledFourOutputs(string grpc) + { + var item = Utils.MakeItem("foo.proto", "grpcservices", grpc); + var poss = _generator.GetPossibleOutputs(item); + Assert.AreEqual(4, poss.Length); + Assert.Contains("foo.pb.cc", poss); + Assert.Contains("foo.pb.h", poss); + Assert.Contains("foo_grpc.pb.cc", poss); + Assert.Contains("foo_grpc.pb.h", poss); + } - [Test] - public void OutputDirMetadataRecognized() { - var item = Utils.MakeItem("foo.proto", "OutputDir", "out"); - var poss = _generator.GetPossibleOutputs(item); - Assert.AreEqual(2, poss.Length); - Assert.That(Path.GetDirectoryName(poss[0]), Is.EqualTo("out")); - } - }; + [Test] + public void OutputDirMetadataRecognized() + { + var item = Utils.MakeItem("foo.proto", "OutputDir", "out"); + var poss = _generator.GetPossibleOutputs(item); + Assert.AreEqual(2, poss.Length); + Assert.That(Path.GetDirectoryName(poss[0]), Is.EqualTo("out")); + } + }; } diff --git a/src/csharp/Grpc.Tools.Tests/DepFileUtilTest.cs b/src/csharp/Grpc.Tools.Tests/DepFileUtilTest.cs index ea34c89921..e89a8f4b5d 100644 --- a/src/csharp/Grpc.Tools.Tests/DepFileUtilTest.cs +++ b/src/csharp/Grpc.Tools.Tests/DepFileUtilTest.cs @@ -21,53 +21,58 @@ using Microsoft.Build.Framework; using Microsoft.Build.Utilities; using NUnit.Framework; -namespace Grpc.Tools.Tests { - public class DepFileUtilTest { - - [Test] - public void HashString64Hex_IsSane() { - string hashFoo1 = DepFileUtil.HashString64Hex("foo"); - string hashEmpty = DepFileUtil.HashString64Hex(""); - string hashFoo2 = DepFileUtil.HashString64Hex("foo"); - - StringAssert.IsMatch("^[a-f0-9]{16}$", hashFoo1); - Assert.AreEqual(hashFoo1, hashFoo2); - Assert.AreNotEqual(hashFoo1, hashEmpty); - } - - [Test] - public void GetDepFilenameForProto_IsSane() { - StringAssert.IsMatch(@"^out[\\/][a-f0-9]{16}_foo.protodep$", - DepFileUtil.GetDepFilenameForProto("out", "foo.proto")); - StringAssert.IsMatch(@"^[a-f0-9]{16}_foo.protodep$", - DepFileUtil.GetDepFilenameForProto("", "foo.proto")); - } - - [Test] - public void GetDepFilenameForProto_HashesDir() { - string PickHash(string fname) => - DepFileUtil.GetDepFilenameForProto("", fname).Substring(0, 16); - - string same1 = PickHash("dir1/dir2/foo.proto"); - string same2 = PickHash("dir1/dir2/proto.foo"); - string same3 = PickHash("dir1/dir2/proto"); - string same4 = PickHash("dir1/dir2/.proto"); - string unsame1 = PickHash("dir2/foo.proto"); - string unsame2 = PickHash("/dir2/foo.proto"); - - Assert.AreEqual(same1, same2); - Assert.AreEqual(same1, same3); - Assert.AreEqual(same1, same4); - Assert.AreNotEqual(same1, unsame1); - Assert.AreNotEqual(unsame1, unsame2); - } - - ////////////////////////////////////////////////////////////////////////// - // Full file reading tests - - // Generated by protoc on Windows. Slashes vary. - const string depFile1 = -@"C:\projects\foo\src\./foo.grpc.pb.cc \ +namespace Grpc.Tools.Tests +{ + public class DepFileUtilTest + { + + [Test] + public void HashString64Hex_IsSane() + { + string hashFoo1 = DepFileUtil.HashString64Hex("foo"); + string hashEmpty = DepFileUtil.HashString64Hex(""); + string hashFoo2 = DepFileUtil.HashString64Hex("foo"); + + StringAssert.IsMatch("^[a-f0-9]{16}$", hashFoo1); + Assert.AreEqual(hashFoo1, hashFoo2); + Assert.AreNotEqual(hashFoo1, hashEmpty); + } + + [Test] + public void GetDepFilenameForProto_IsSane() + { + StringAssert.IsMatch(@"^out[\\/][a-f0-9]{16}_foo.protodep$", + DepFileUtil.GetDepFilenameForProto("out", "foo.proto")); + StringAssert.IsMatch(@"^[a-f0-9]{16}_foo.protodep$", + DepFileUtil.GetDepFilenameForProto("", "foo.proto")); + } + + [Test] + public void GetDepFilenameForProto_HashesDir() + { + string PickHash(string fname) => + DepFileUtil.GetDepFilenameForProto("", fname).Substring(0, 16); + + string same1 = PickHash("dir1/dir2/foo.proto"); + string same2 = PickHash("dir1/dir2/proto.foo"); + string same3 = PickHash("dir1/dir2/proto"); + string same4 = PickHash("dir1/dir2/.proto"); + string unsame1 = PickHash("dir2/foo.proto"); + string unsame2 = PickHash("/dir2/foo.proto"); + + Assert.AreEqual(same1, same2); + Assert.AreEqual(same1, same3); + Assert.AreEqual(same1, same4); + Assert.AreNotEqual(same1, unsame1); + Assert.AreNotEqual(unsame1, unsame2); + } + + ////////////////////////////////////////////////////////////////////////// + // Full file reading tests + + // Generated by protoc on Windows. Slashes vary. + const string depFile1 = + @"C:\projects\foo\src\./foo.grpc.pb.cc \ C:\projects\foo\src\./foo.grpc.pb.h \ C:\projects\foo\src\./foo.pb.cc \ C:\projects\foo\src\./foo.pb.h: C:/usr/include/google/protobuf/wrappers.proto\ @@ -76,57 +81,66 @@ C:/usr/include/google/protobuf/source_context.proto\ C:/usr/include/google/protobuf/type.proto\ foo.proto"; - // This has a nasty output directory with a space. - const string depFile2 = -@"obj\Release x64\net45\/Foo.cs \ + // This has a nasty output directory with a space. + const string depFile2 = + @"obj\Release x64\net45\/Foo.cs \ obj\Release x64\net45\/FooGrpc.cs: C:/usr/include/google/protobuf/wrappers.proto\ C:/projects/foo/src//foo.proto"; - [Test] - public void ReadDependencyInput_FullFile1() { - string[] deps = ReadDependencyInputFromFileData(depFile1, "foo.proto"); - - Assert.NotNull(deps); - Assert.That(deps, Has.Length.InRange(4, 5)); // foo.proto may or may not be listed. - Assert.That(deps, Has.One.EndsWith("wrappers.proto")); - Assert.That(deps, Has.One.EndsWith("type.proto")); - Assert.That(deps, Has.None.StartWith(" ")); - } - - [Test] - public void ReadDependencyInput_FullFile2() { - string[] deps = ReadDependencyInputFromFileData(depFile2, "C:/projects/foo/src/foo.proto"); - - Assert.NotNull(deps); - Assert.That(deps, Has.Length.InRange(1, 2)); - Assert.That(deps, Has.One.EndsWith("wrappers.proto")); - Assert.That(deps, Has.None.StartWith(" ")); - } - - [Test] - public void ReadDependencyInput_FullFileUnparsable() { - string[] deps = ReadDependencyInputFromFileData("a:/foo.proto", "/foo.proto"); - Assert.NotNull(deps); - Assert.Zero(deps.Length); - } - - // NB in our tests files are put into the temp directory but all have - // different names. Avoid adding files with the same directory path and - // name, or add reasonable handling for it if required. Tests are run in - // parallel and will collide otherwise. - private string[] ReadDependencyInputFromFileData(string fileData, string protoName) { - string tempPath = Path.GetTempPath(); - string tempfile = DepFileUtil.GetDepFilenameForProto(tempPath, protoName); - try { - File.WriteAllText(tempfile, fileData); - var mockEng = new Moq.Mock<IBuildEngine>(); - var log = new TaskLoggingHelper(mockEng.Object, "x"); - return DepFileUtil.ReadDependencyInputs(tempPath, protoName, log); - } finally { - try { - File.Delete(tempfile); - } catch { } - } - } - }; + [Test] + public void ReadDependencyInput_FullFile1() + { + string[] deps = ReadDependencyInputFromFileData(depFile1, "foo.proto"); + + Assert.NotNull(deps); + Assert.That(deps, Has.Length.InRange(4, 5)); // foo.proto may or may not be listed. + Assert.That(deps, Has.One.EndsWith("wrappers.proto")); + Assert.That(deps, Has.One.EndsWith("type.proto")); + Assert.That(deps, Has.None.StartWith(" ")); + } + + [Test] + public void ReadDependencyInput_FullFile2() + { + string[] deps = ReadDependencyInputFromFileData(depFile2, "C:/projects/foo/src/foo.proto"); + + Assert.NotNull(deps); + Assert.That(deps, Has.Length.InRange(1, 2)); + Assert.That(deps, Has.One.EndsWith("wrappers.proto")); + Assert.That(deps, Has.None.StartWith(" ")); + } + + [Test] + public void ReadDependencyInput_FullFileUnparsable() + { + string[] deps = ReadDependencyInputFromFileData("a:/foo.proto", "/foo.proto"); + Assert.NotNull(deps); + Assert.Zero(deps.Length); + } + + // NB in our tests files are put into the temp directory but all have + // different names. Avoid adding files with the same directory path and + // name, or add reasonable handling for it if required. Tests are run in + // parallel and will collide otherwise. + private string[] ReadDependencyInputFromFileData(string fileData, string protoName) + { + string tempPath = Path.GetTempPath(); + string tempfile = DepFileUtil.GetDepFilenameForProto(tempPath, protoName); + try + { + File.WriteAllText(tempfile, fileData); + var mockEng = new Moq.Mock<IBuildEngine>(); + var log = new TaskLoggingHelper(mockEng.Object, "x"); + return DepFileUtil.ReadDependencyInputs(tempPath, protoName, log); + } + finally + { + try + { + File.Delete(tempfile); + } + catch { } + } + } + }; } diff --git a/src/csharp/Grpc.Tools.Tests/GeneratorTest.cs b/src/csharp/Grpc.Tools.Tests/GeneratorTest.cs index 52fab1d8ca..8a8fc81aba 100644 --- a/src/csharp/Grpc.Tools.Tests/GeneratorTest.cs +++ b/src/csharp/Grpc.Tools.Tests/GeneratorTest.cs @@ -21,30 +21,35 @@ using Microsoft.Build.Utilities; using Moq; using NUnit.Framework; -namespace Grpc.Tools.Tests { - public class GeneratorTest { - protected Mock<IBuildEngine> _mockEngine; - protected TaskLoggingHelper _log; +namespace Grpc.Tools.Tests +{ + public class GeneratorTest + { + protected Mock<IBuildEngine> _mockEngine; + protected TaskLoggingHelper _log; - [SetUp] - public void SetUp() { - _mockEngine = new Mock<IBuildEngine>(); - _log = new TaskLoggingHelper(_mockEngine.Object, "dummy"); - } + [SetUp] + public void SetUp() + { + _mockEngine = new Mock<IBuildEngine>(); + _log = new TaskLoggingHelper(_mockEngine.Object, "dummy"); + } - [TestCase("csharp")] - [TestCase("CSharp")] - [TestCase("cpp")] - public void ValidLanguages(string lang) { - Assert.IsNotNull(GeneratorServices.GetForLanguage(lang, _log)); - _mockEngine.Verify(me => me.LogErrorEvent(It.IsAny<BuildErrorEventArgs>()), Times.Never); - } + [TestCase("csharp")] + [TestCase("CSharp")] + [TestCase("cpp")] + public void ValidLanguages(string lang) + { + Assert.IsNotNull(GeneratorServices.GetForLanguage(lang, _log)); + _mockEngine.Verify(me => me.LogErrorEvent(It.IsAny<BuildErrorEventArgs>()), Times.Never); + } - [TestCase("")] - [TestCase("COBOL")] - public void InvalidLanguages(string lang) { - Assert.IsNull(GeneratorServices.GetForLanguage(lang, _log)); - _mockEngine.Verify(me => me.LogErrorEvent(It.IsAny<BuildErrorEventArgs>()), Times.Once); - } - }; + [TestCase("")] + [TestCase("COBOL")] + public void InvalidLanguages(string lang) + { + Assert.IsNull(GeneratorServices.GetForLanguage(lang, _log)); + _mockEngine.Verify(me => me.LogErrorEvent(It.IsAny<BuildErrorEventArgs>()), Times.Once); + } + }; } diff --git a/src/csharp/Grpc.Tools.Tests/NUnitMain.cs b/src/csharp/Grpc.Tools.Tests/NUnitMain.cs index 5784cdeac2..418c33820e 100644 --- a/src/csharp/Grpc.Tools.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.Tools.Tests/NUnitMain.cs @@ -19,13 +19,15 @@ using System.Reflection; using NUnitLite; -namespace Grpc.Tools.Tests { - static class NUnitMain { - public static int Main(string[] args) => +namespace Grpc.Tools.Tests +{ + static class NUnitMain + { + public static int Main(string[] args) => #if NETCOREAPP1_0 || NETCOREAPP1_1 - new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args); + new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args); #else - new AutoRun().Execute(args); + new AutoRun().Execute(args); #endif - }; + }; } diff --git a/src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs b/src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs index cf9d210424..ea763f4e40 100644 --- a/src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs +++ b/src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs @@ -21,50 +21,56 @@ using Microsoft.Build.Framework; using Moq; using NUnit.Framework; -namespace Grpc.Tools.Tests { - public class ProtoCompileBasicTest { - // Mock task class that stops right before invoking protoc. - public class ProtoCompileTestable : ProtoCompile { - public string LastPathToTool { get; private set; } - public string[] LastResponseFile { get; private set; } +namespace Grpc.Tools.Tests +{ + public class ProtoCompileBasicTest + { + // Mock task class that stops right before invoking protoc. + public class ProtoCompileTestable : ProtoCompile + { + public string LastPathToTool { get; private set; } + public string[] LastResponseFile { get; private set; } - protected override int ExecuteTool(string pathToTool, - string response, - string commandLine) { - // We should never be using command line commands. - Assert.That(commandLine, Is.Null | Is.Empty); + protected override int ExecuteTool(string pathToTool, + string response, + string commandLine) + { + // We should never be using command line commands. + Assert.That(commandLine, Is.Null | Is.Empty); - // Must receive a path to tool - Assert.That(pathToTool, Is.Not.Null & Is.Not.Empty); - Assert.That(response, Is.Not.Null & Does.EndWith("\n")); + // Must receive a path to tool + Assert.That(pathToTool, Is.Not.Null & Is.Not.Empty); + Assert.That(response, Is.Not.Null & Does.EndWith("\n")); - LastPathToTool = pathToTool; - LastResponseFile = response.Remove(response.Length - 1).Split('\n'); + LastPathToTool = pathToTool; + LastResponseFile = response.Remove(response.Length - 1).Split('\n'); - // Do not run the tool, but pretend it ran successfully. - return 0; - } - }; + // Do not run the tool, but pretend it ran successfully. + return 0; + } + }; - protected Mock<IBuildEngine> _mockEngine; - protected ProtoCompileTestable _task; + protected Mock<IBuildEngine> _mockEngine; + protected ProtoCompileTestable _task; - [SetUp] - public void SetUp() { - _mockEngine = new Mock<IBuildEngine>(); - _task = new ProtoCompileTestable { - BuildEngine = _mockEngine.Object - }; - } + [SetUp] + public void SetUp() + { + _mockEngine = new Mock<IBuildEngine>(); + _task = new ProtoCompileTestable { + BuildEngine = _mockEngine.Object + }; + } - [TestCase("ProtoBuf")] - [TestCase("Generator")] - [TestCase("OutputDir")] - [Description("We trust MSBuild to initialize these properties.")] - public void RequiredAttributePresentOnProperty(string prop) { - var pinfo = _task.GetType()?.GetProperty(prop); - Assert.NotNull(pinfo); - Assert.That(pinfo, Has.Attribute<RequiredAttribute>()); - } - }; + [TestCase("ProtoBuf")] + [TestCase("Generator")] + [TestCase("OutputDir")] + [Description("We trust MSBuild to initialize these properties.")] + public void RequiredAttributePresentOnProperty(string prop) + { + var pinfo = _task.GetType()?.GetProperty(prop); + Assert.NotNull(pinfo); + Assert.That(pinfo, Has.Attribute<RequiredAttribute>()); + } + }; } diff --git a/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs b/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs index 06376f8ef4..cac7146634 100644 --- a/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs +++ b/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs @@ -21,144 +21,159 @@ using Microsoft.Build.Framework; using Moq; using NUnit.Framework; -namespace Grpc.Tools.Tests { - public class ProtoCompileCommandLineGeneratorTest : ProtoCompileBasicTest { - [SetUp] - public new void SetUp() { - _task.Generator = "csharp"; - _task.OutputDir = "outdir"; - _task.ProtoBuf = Utils.MakeSimpleItems("a.proto"); - } - - void ExecuteExpectSuccess() { - _mockEngine - .Setup(me => me.LogErrorEvent(It.IsAny<BuildErrorEventArgs>())) - .Callback((BuildErrorEventArgs e) => - Assert.Fail($"Error logged by build engine:\n{e.Message}")); - bool result = _task.Execute(); - Assert.IsTrue(result); - } - - [Test] - public void MinimalCompile() { - ExecuteExpectSuccess(); - Assert.That(_task.LastPathToTool, Does.Match(@"protoc(.exe)?$")); - Assert.That(_task.LastResponseFile, Is.EqualTo(new[] { - "--csharp_out=outdir", "a.proto" })); - } - - [Test] - public void CompileTwoFiles() { - _task.ProtoBuf = Utils.MakeSimpleItems("a.proto", "foo/b.proto"); - ExecuteExpectSuccess(); - Assert.That(_task.LastResponseFile, Is.EqualTo(new[] { - "--csharp_out=outdir", "a.proto", "foo/b.proto" })); - } - - [Test] - public void CompileWithProtoPaths() { - _task.ProtoPath = new[] { "/path1", "/path2" }; - ExecuteExpectSuccess(); - Assert.That(_task.LastResponseFile, Is.EqualTo(new[] { - "--csharp_out=outdir", "--proto_path=/path1", - "--proto_path=/path2", "a.proto" })); - } - - [TestCase("Cpp")] - [TestCase("CSharp")] - [TestCase("Java")] - [TestCase("Javanano")] - [TestCase("Js")] - [TestCase("Objc")] - [TestCase("Php")] - [TestCase("Python")] - [TestCase("Ruby")] - public void CompileWithOptions(string gen) { - _task.Generator = gen; - _task.OutputOptions = new[] { "foo", "bar" }; - ExecuteExpectSuccess(); - gen = gen.ToLowerInvariant(); - Assert.That(_task.LastResponseFile, Is.EqualTo(new[] { - $"--{gen}_out=outdir", $"--{gen}_opt=foo,bar", "a.proto" })); - } - - [Test] - public void OutputDependencyFile() { - _task.DependencyOut = "foo/my.protodep"; - // Task fails trying to read the non-generated file; we ignore that. - _task.Execute(); - Assert.That(_task.LastResponseFile, - Does.Contain("--dependency_out=foo/my.protodep")); - } - - [Test] - public void OutputDependencyWithProtoDepDir() { - _task.ProtoDepDir = "foo"; - // Task fails trying to read the non-generated file; we ignore that. - _task.Execute(); - Assert.That(_task.LastResponseFile, - Has.One.Match(@"^--dependency_out=foo[/\\].+_a.protodep$")); - } - - [Test] - public void GenerateGrpc() { - _task.GrpcPluginExe = "/foo/grpcgen"; - ExecuteExpectSuccess(); - Assert.That(_task.LastResponseFile, Is.SupersetOf(new[] { - "--csharp_out=outdir", "--grpc_out=outdir", - "--plugin=protoc-gen-grpc=/foo/grpcgen" })); - } - - [Test] - public void GenerateGrpcWithOutDir() { - _task.GrpcPluginExe = "/foo/grpcgen"; - _task.GrpcOutputDir = "gen-out"; - ExecuteExpectSuccess(); - Assert.That(_task.LastResponseFile, Is.SupersetOf(new[] { - "--csharp_out=outdir", "--grpc_out=gen-out" })); - } - - [Test] - public void GenerateGrpcWithOptions() { - _task.GrpcPluginExe = "/foo/grpcgen"; - _task.GrpcOutputOptions = new[] { "baz", "quux" }; - ExecuteExpectSuccess(); - Assert.That(_task.LastResponseFile, - Does.Contain("--grpc_opt=baz,quux")); - } - - [Test] - public void DirectoryArgumentsSlashTrimmed() { - _task.GrpcPluginExe = "/foo/grpcgen"; - _task.GrpcOutputDir = "gen-out/"; - _task.OutputDir = "outdir/"; - _task.ProtoPath = new[] { "/path1/", "/path2/" }; - ExecuteExpectSuccess(); - Assert.That(_task.LastResponseFile, Is.SupersetOf(new[] { +namespace Grpc.Tools.Tests +{ + public class ProtoCompileCommandLineGeneratorTest : ProtoCompileBasicTest + { + [SetUp] + public new void SetUp() + { + _task.Generator = "csharp"; + _task.OutputDir = "outdir"; + _task.ProtoBuf = Utils.MakeSimpleItems("a.proto"); + } + + void ExecuteExpectSuccess() + { + _mockEngine + .Setup(me => me.LogErrorEvent(It.IsAny<BuildErrorEventArgs>())) + .Callback((BuildErrorEventArgs e) => + Assert.Fail($"Error logged by build engine:\n{e.Message}")); + bool result = _task.Execute(); + Assert.IsTrue(result); + } + + [Test] + public void MinimalCompile() + { + ExecuteExpectSuccess(); + Assert.That(_task.LastPathToTool, Does.Match(@"protoc(.exe)?$")); + Assert.That(_task.LastResponseFile, Is.EqualTo(new[] { + "--csharp_out=outdir", "a.proto" })); + } + + [Test] + public void CompileTwoFiles() + { + _task.ProtoBuf = Utils.MakeSimpleItems("a.proto", "foo/b.proto"); + ExecuteExpectSuccess(); + Assert.That(_task.LastResponseFile, Is.EqualTo(new[] { + "--csharp_out=outdir", "a.proto", "foo/b.proto" })); + } + + [Test] + public void CompileWithProtoPaths() + { + _task.ProtoPath = new[] { "/path1", "/path2" }; + ExecuteExpectSuccess(); + Assert.That(_task.LastResponseFile, Is.EqualTo(new[] { + "--csharp_out=outdir", "--proto_path=/path1", + "--proto_path=/path2", "a.proto" })); + } + + [TestCase("Cpp")] + [TestCase("CSharp")] + [TestCase("Java")] + [TestCase("Javanano")] + [TestCase("Js")] + [TestCase("Objc")] + [TestCase("Php")] + [TestCase("Python")] + [TestCase("Ruby")] + public void CompileWithOptions(string gen) + { + _task.Generator = gen; + _task.OutputOptions = new[] { "foo", "bar" }; + ExecuteExpectSuccess(); + gen = gen.ToLowerInvariant(); + Assert.That(_task.LastResponseFile, Is.EqualTo(new[] { + $"--{gen}_out=outdir", $"--{gen}_opt=foo,bar", "a.proto" })); + } + + [Test] + public void OutputDependencyFile() + { + _task.DependencyOut = "foo/my.protodep"; + // Task fails trying to read the non-generated file; we ignore that. + _task.Execute(); + Assert.That(_task.LastResponseFile, + Does.Contain("--dependency_out=foo/my.protodep")); + } + + [Test] + public void OutputDependencyWithProtoDepDir() + { + _task.ProtoDepDir = "foo"; + // Task fails trying to read the non-generated file; we ignore that. + _task.Execute(); + Assert.That(_task.LastResponseFile, + Has.One.Match(@"^--dependency_out=foo[/\\].+_a.protodep$")); + } + + [Test] + public void GenerateGrpc() + { + _task.GrpcPluginExe = "/foo/grpcgen"; + ExecuteExpectSuccess(); + Assert.That(_task.LastResponseFile, Is.SupersetOf(new[] { + "--csharp_out=outdir", "--grpc_out=outdir", + "--plugin=protoc-gen-grpc=/foo/grpcgen" })); + } + + [Test] + public void GenerateGrpcWithOutDir() + { + _task.GrpcPluginExe = "/foo/grpcgen"; + _task.GrpcOutputDir = "gen-out"; + ExecuteExpectSuccess(); + Assert.That(_task.LastResponseFile, Is.SupersetOf(new[] { + "--csharp_out=outdir", "--grpc_out=gen-out" })); + } + + [Test] + public void GenerateGrpcWithOptions() + { + _task.GrpcPluginExe = "/foo/grpcgen"; + _task.GrpcOutputOptions = new[] { "baz", "quux" }; + ExecuteExpectSuccess(); + Assert.That(_task.LastResponseFile, + Does.Contain("--grpc_opt=baz,quux")); + } + + [Test] + public void DirectoryArgumentsSlashTrimmed() + { + _task.GrpcPluginExe = "/foo/grpcgen"; + _task.GrpcOutputDir = "gen-out/"; + _task.OutputDir = "outdir/"; + _task.ProtoPath = new[] { "/path1/", "/path2/" }; + ExecuteExpectSuccess(); + Assert.That(_task.LastResponseFile, Is.SupersetOf(new[] { "--proto_path=/path1", "--proto_path=/path2", "--csharp_out=outdir", "--grpc_out=gen-out" })); - } - - [TestCase("." , ".")] - [TestCase("/" , "/")] - [TestCase("//" , "/")] - [TestCase("/foo/" , "/foo")] - [TestCase("/foo" , "/foo")] - [TestCase("foo/" , "foo")] - [TestCase("foo//" , "foo")] - [TestCase("foo/\\" , "foo")] - [TestCase("foo\\/" , "foo")] - [TestCase("C:\\foo", "C:\\foo")] - [TestCase("C:" , "C:")] - [TestCase("C:\\" , "C:\\")] - [TestCase("C:\\\\" , "C:\\")] - public void DirectorySlashTrimmingCases(string given, string expect) { - if (Path.DirectorySeparatorChar == '/') - expect = expect.Replace('\\', '/'); - _task.OutputDir = given; - ExecuteExpectSuccess(); - Assert.That(_task.LastResponseFile, - Does.Contain("--csharp_out=" + expect)); - } - }; + } + + [TestCase(".", ".")] + [TestCase("/", "/")] + [TestCase("//", "/")] + [TestCase("/foo/", "/foo")] + [TestCase("/foo", "/foo")] + [TestCase("foo/", "foo")] + [TestCase("foo//", "foo")] + [TestCase("foo/\\", "foo")] + [TestCase("foo\\/", "foo")] + [TestCase("C:\\foo", "C:\\foo")] + [TestCase("C:", "C:")] + [TestCase("C:\\", "C:\\")] + [TestCase("C:\\\\", "C:\\")] + public void DirectorySlashTrimmingCases(string given, string expect) + { + if (Path.DirectorySeparatorChar == '/') + expect = expect.Replace('\\', '/'); + _task.OutputDir = given; + ExecuteExpectSuccess(); + Assert.That(_task.LastResponseFile, + Does.Contain("--csharp_out=" + expect)); + } + }; } diff --git a/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLinePrinterTest.cs b/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLinePrinterTest.cs index a0406371dc..1773dcb875 100644 --- a/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLinePrinterTest.cs +++ b/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLinePrinterTest.cs @@ -20,28 +20,32 @@ using Microsoft.Build.Framework; using Moq; using NUnit.Framework; -namespace Grpc.Tools.Tests { - public class ProtoCompileCommandLinePrinterTest : ProtoCompileBasicTest { - [SetUp] - public new void SetUp() { - _task.Generator = "csharp"; - _task.OutputDir = "outdir"; - _task.ProtoBuf = Utils.MakeSimpleItems("a.proto"); +namespace Grpc.Tools.Tests +{ + public class ProtoCompileCommandLinePrinterTest : ProtoCompileBasicTest + { + [SetUp] + public new void SetUp() + { + _task.Generator = "csharp"; + _task.OutputDir = "outdir"; + _task.ProtoBuf = Utils.MakeSimpleItems("a.proto"); - _mockEngine - .Setup(me => me.LogMessageEvent(It.IsAny<BuildMessageEventArgs>())) - .Callback((BuildMessageEventArgs e) => - Assert.Fail($"Error logged by build engine:\n{e.Message}")) - .Verifiable("Command line was not output by the task."); - } + _mockEngine + .Setup(me => me.LogMessageEvent(It.IsAny<BuildMessageEventArgs>())) + .Callback((BuildMessageEventArgs e) => + Assert.Fail($"Error logged by build engine:\n{e.Message}")) + .Verifiable("Command line was not output by the task."); + } - void ExecuteExpectSuccess() { - _mockEngine - .Setup(me => me.LogErrorEvent(It.IsAny<BuildErrorEventArgs>())) - .Callback((BuildErrorEventArgs e) => - Assert.Fail($"Error logged by build engine:\n{e.Message}")); - bool result = _task.Execute(); - Assert.IsTrue(result); - } - }; + void ExecuteExpectSuccess() + { + _mockEngine + .Setup(me => me.LogErrorEvent(It.IsAny<BuildErrorEventArgs>())) + .Callback((BuildErrorEventArgs e) => + Assert.Fail($"Error logged by build engine:\n{e.Message}")); + bool result = _task.Execute(); + Assert.IsTrue(result); + } + }; } diff --git a/src/csharp/Grpc.Tools.Tests/ProtoToolsPlatformTaskTest.cs b/src/csharp/Grpc.Tools.Tests/ProtoToolsPlatformTaskTest.cs index 2380ae8a37..54723b74fc 100644 --- a/src/csharp/Grpc.Tools.Tests/ProtoToolsPlatformTaskTest.cs +++ b/src/csharp/Grpc.Tools.Tests/ProtoToolsPlatformTaskTest.cs @@ -21,102 +21,119 @@ using Microsoft.Build.Framework; using Moq; using NUnit.Framework; -namespace Grpc.Tools.Tests { - public class ProtoToolsPlatformTaskTest { - ProtoToolsPlatform _task; - int _cpuMatched, _osMatched; - - [OneTimeSetUp] - public void SetUp() { - var mockEng = new Mock<IBuildEngine>(); - _task = new ProtoToolsPlatform() { - BuildEngine = mockEng.Object - }; - _task.Execute(); - } - - [OneTimeTearDown] - public void TearDown() { - Assert.AreEqual(1, _cpuMatched, "CPU type detection failed"); - Assert.AreEqual(1, _osMatched, "OS detection failed"); - } +namespace Grpc.Tools.Tests +{ + public class ProtoToolsPlatformTaskTest + { + ProtoToolsPlatform _task; + int _cpuMatched, _osMatched; + + [OneTimeSetUp] + public void SetUp() + { + var mockEng = new Mock<IBuildEngine>(); + _task = new ProtoToolsPlatform() { BuildEngine = mockEng.Object }; + _task.Execute(); + } + + [OneTimeTearDown] + public void TearDown() + { + Assert.AreEqual(1, _cpuMatched, "CPU type detection failed"); + Assert.AreEqual(1, _osMatched, "OS detection failed"); + } #if NETCORE - // PlatformAttribute not yet available in NUnit, coming soon: - // https://github.com/nunit/nunit/pull/3003. - // Use same test case names as under the full framework. - [Test] - public void CpuIsX86() { - if (RuntimeInformation.OSArchitecture == Architecture.X86) { - _cpuMatched++; - Assert.AreEqual("x86", _task.Cpu); - } - } - - [Test] - public void CpuIsX64() { - if (RuntimeInformation.OSArchitecture == Architecture.X64) { - _cpuMatched++; - Assert.AreEqual("x64", _task.Cpu); - } - } - - [Test] - public void OsIsWindows() { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - _osMatched++; - Assert.AreEqual("windows", _task.Os); - } - } - - [Test] - public void OsIsLinux() { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { - _osMatched++; - Assert.AreEqual("linux", _task.Os); - } - } - - [Test] - public void OsIsMacOsX() { - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { - _osMatched++; - Assert.AreEqual("macosx", _task.Os); - } - } + // PlatformAttribute not yet available in NUnit, coming soon: + // https://github.com/nunit/nunit/pull/3003. + // Use same test case names as under the full framework. + [Test] + public void CpuIsX86() + { + if (RuntimeInformation.OSArchitecture == Architecture.X86) + { + _cpuMatched++; + Assert.AreEqual("x86", _task.Cpu); + } + } + + [Test] + public void CpuIsX64() + { + if (RuntimeInformation.OSArchitecture == Architecture.X64) + { + _cpuMatched++; + Assert.AreEqual("x64", _task.Cpu); + } + } + + [Test] + public void OsIsWindows() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + _osMatched++; + Assert.AreEqual("windows", _task.Os); + } + } + + [Test] + public void OsIsLinux() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + _osMatched++; + Assert.AreEqual("linux", _task.Os); + } + } + + [Test] + public void OsIsMacOsX() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + _osMatched++; + Assert.AreEqual("macosx", _task.Os); + } + } #else // !NETCORE, i.e. full framework. - [Test, Platform("32-Bit")] - public void CpuIsX86() { - _cpuMatched++; - Assert.AreEqual("x86", _task.Cpu); - } - - [Test, Platform("64-Bit")] - public void CpuIsX64() { - _cpuMatched++; - Assert.AreEqual("x64", _task.Cpu); - } - - [Test, Platform("Win")] - public void OsIsWindows() { - _osMatched++; - Assert.AreEqual("windows", _task.Os); - } - - [Test, Platform("Linux")] - public void OsIsLinux() { - _osMatched++; - Assert.AreEqual("linux", _task.Os); - } - - [Test, Platform("MacOSX")] - public void OsIsMacOsX() { - _osMatched++; - Assert.AreEqual("macosx", _task.Os); - } + [Test, Platform("32-Bit")] + public void CpuIsX86() + { + _cpuMatched++; + Assert.AreEqual("x86", _task.Cpu); + } + + [Test, Platform("64-Bit")] + public void CpuIsX64() + { + _cpuMatched++; + Assert.AreEqual("x64", _task.Cpu); + } + + [Test, Platform("Win")] + public void OsIsWindows() + { + _osMatched++; + Assert.AreEqual("windows", _task.Os); + } + + [Test, Platform("Linux")] + public void OsIsLinux() + { + _osMatched++; + Assert.AreEqual("linux", _task.Os); + } + + [Test, Platform("MacOSX")] + public void OsIsMacOsX() + { + _osMatched++; + Assert.AreEqual("macosx", _task.Os); + } #endif // NETCORE - }; + }; } diff --git a/src/csharp/Grpc.Tools.Tests/Utils.cs b/src/csharp/Grpc.Tools.Tests/Utils.cs index bb051a4873..6e0f1cffd5 100644 --- a/src/csharp/Grpc.Tools.Tests/Utils.cs +++ b/src/csharp/Grpc.Tools.Tests/Utils.cs @@ -20,21 +20,27 @@ using System.Linq; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; -namespace Grpc.Tools.Tests { - static class Utils { - // Build an item with a name from args[0] and metadata key-value pairs - // from the rest of args, interleaved. - // This does not do any checking, and expects an odd number of args. - public static ITaskItem MakeItem(params string[] args) { - var item = new TaskItem(args[0]); - for (int i = 1; i < args.Length; i += 2) - item.SetMetadata(args[i], args[i + 1]); - return item; - } +namespace Grpc.Tools.Tests +{ + static class Utils + { + // Build an item with a name from args[0] and metadata key-value pairs + // from the rest of args, interleaved. + // This does not do any checking, and expects an odd number of args. + public static ITaskItem MakeItem(params string[] args) + { + var item = new TaskItem(args[0]); + for (int i = 1; i < args.Length; i += 2) + { + item.SetMetadata(args[i], args[i + 1]); + } + return item; + } - // Return an array of items from given itemspecs. - public static ITaskItem[] MakeSimpleItems(params string[] specs) { - return specs.Select(s => new TaskItem(s)).ToArray(); - } - }; + // Return an array of items from given itemspecs. + public static ITaskItem[] MakeSimpleItems(params string[] specs) + { + return specs.Select(s => new TaskItem(s)).ToArray(); + } + }; } |