Created
January 16, 2014 17:40
-
-
Save JakeGinnivan/8459629 to your computer and use it in GitHub Desktop.
Script to help convert between nUnit and xUnit
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Settings | |
| { | |
| public static string SolutionPath = @"C:\_code\foo\src"; | |
| } | |
| /* | |
| Helper classes (to replace certain things in nUnit) | |
| // Replaces implicit attribute (kinda, instead only runs when debugger is attached) | |
| public class RunnableInDebugOnlyAttribute : FactAttribute | |
| { | |
| private string _skip; | |
| public override string Skip | |
| { | |
| get | |
| { | |
| return Debugger.IsAttached | |
| ? _skip | |
| : "Only running in interactive mode."; | |
| } | |
| set { _skip = value; } | |
| } | |
| } | |
| // A wrapper around traits to create categories | |
| public class CategoryAttribute : TraitAttribute | |
| { | |
| public CategoryAttribute(string category) | |
| : base("Category", category) { } | |
| } | |
| */ | |
| Regex testFixture = new Regex(@" *?\[TestFixture(\(.*?\))?(, *(?<AdditionalAttributes>.*?))?\]\r?\n", RegexOptions.Compiled); | |
| Regex test = new Regex(@"\[Test\]", RegexOptions.Compiled); | |
| Regex testIgnore = new Regex(@"\[Test, Ignore\(", RegexOptions.Compiled); | |
| Regex testWithTimeout = new Regex(@"\[Test, Timeout\(", RegexOptions.Compiled); | |
| Regex explicitTest = new Regex(@"\[Explicit\]", RegexOptions.Compiled); | |
| Regex testWithExplicit = new Regex(@"\[Test, Explicit\]", RegexOptions.Compiled); | |
| Regex testCaseWithTestAttribute = new Regex(@"\[Fact\]\r?\n\s*?\[TestCase\(", RegexOptions.Compiled | RegexOptions.Multiline); | |
| Regex testCaseToTheory = new Regex(@"(^[}\s\r]+\n\s*?\[TestCase\()", RegexOptions.Compiled | RegexOptions.Multiline); | |
| Regex testCase = new Regex(@"\[TestCase(", RegexOptions.Compiled); | |
| Regex asyncVoidFix = new Regex(@"(?<Match>(\[Theory|\[Fact|\[InlineData).*\r?\n\s*)public async void", RegexOptions.Compiled | RegexOptions.Multiline); | |
| Regex setUp = new Regex(@"public class (?<classname>\w+)(?<stuff>.*?)\[SetUp\]\r?\n *?public void \w+", RegexOptions.Compiled | RegexOptions.Singleline); | |
| Regex tearDown = new Regex(@"public class (?<classname>\w+)(?<stuff>.*?)\[SetUp\]\r?\n *?public void \w+", RegexOptions.Compiled | RegexOptions.Singleline); | |
| Regex classInherits = new Regex(@"public (abstract )?class \w+.*?(?<inherits>:.*?)?$", RegexOptions.Compiled | RegexOptions.Multiline); | |
| Regex fixTearDown = new Regex(@"\[TearDown\]\w*?\r?\n\s*?public void \w+", RegexOptions.Compiled); | |
| void Main() | |
| { | |
| var allCsFiles = Directory.GetFiles(Settings.SolutionPath, "*.cs", SearchOption.AllDirectories); | |
| foreach (var csFile in allCsFiles) | |
| { | |
| var originalFileContents = File.ReadAllText(csFile); | |
| var fileContents = originalFileContents; | |
| if (!fileContents.Contains("using NUnit.Framework;")) continue; | |
| // Remove [TestFixture] | |
| if (!string.IsNullOrEmpty(testFixture.Match(fileContents).Groups["AdditionalAttributes"].Value)) | |
| fileContents = testFixture.Replace(fileContents, " [${AdditionalAttributes}]\r\n"); | |
| else | |
| fileContents = testFixture.Replace(fileContents, string.Empty); | |
| fileContents = test.Replace(fileContents, "[Fact]"); | |
| fileContents = testIgnore.Replace(fileContents, "[Fact(Skip="); | |
| fileContents = testWithTimeout.Replace(fileContents, "[Fact(Timeout="); | |
| fileContents = explicitTest.Replace(fileContents, "[RunnableInDebugOnlyAttribute]"); | |
| fileContents = testWithExplicit.Replace(fileContents, "[RunnableInDebugOnlyAttribute]"); | |
| fileContents = testCaseWithTestAttribute.Replace(fileContents, "[Theory]\r\n [InlineData("); | |
| fileContents = testCaseToTheory.Replace(fileContents, "[Theory] $1"); | |
| fileContents = testCase.Replace(fileContents, "[InlineData("); | |
| fileContents = asyncVoidFix.Replace(fileContents, "${Match}public async Task"); | |
| fileContents = setUp.Replace(fileContents, "public class ${classname}${stuff}public ${classname}"); | |
| if (fileContents.Contains("[TearDown]")) | |
| { | |
| var classDefinition = classInherits.Match(fileContents); | |
| if (classDefinition.Groups["inherits"].Success) | |
| fileContents = fileContents.Replace(classDefinition.Value, classDefinition.Value.TrimEnd('\r', '\n') + ", IDisposable"); | |
| else | |
| fileContents = fileContents.Replace(classDefinition.Value, classDefinition.Value.TrimEnd('\r', '\n') + " : IDisposable"); | |
| fileContents = fixTearDown.Replace(fileContents, "public void Dispose"); | |
| } | |
| fileContents = fileContents.Replace("using NUnit.Framework;", "using Xunit;"); | |
| if (fileContents == originalFileContents) continue; | |
| csFile.Dump(); | |
| File.WriteAllText(csFile, fileContents); | |
| } | |
| } | |
| // Define other methods and classes here |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment