Skip to content

Instantly share code, notes, and snippets.

@JakeGinnivan
Created January 16, 2014 17:40
Show Gist options
  • Select an option

  • Save JakeGinnivan/8459629 to your computer and use it in GitHub Desktop.

Select an option

Save JakeGinnivan/8459629 to your computer and use it in GitHub Desktop.
Script to help convert between nUnit and xUnit
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