Created
July 6, 2010 17:40
-
-
Save JulianBirch/465677 to your computer and use it in GitHub Desktop.
RSpecRunner.cs
This file contains 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
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Reflection; | |
using System.Text; | |
using IronRuby.Builtins; | |
using IronRuby.Runtime; | |
using Microsoft.Scripting.Hosting; | |
namespace ColourCoding | |
{ | |
// NOTE That you'll need to have done the follow | |
// $env:HTTP_PROXY = "http://10.132.72.11:8080" | |
// igem install uuidtools | |
// igem install caricature | |
// igem install rspec | |
// igem install gherkin | |
// igem install cucumber | |
public class RSpecRunner | |
{ | |
private readonly string _ironRubyLocation; | |
private readonly string _specFolder; | |
private readonly IEnumerable<string> _paths; | |
public static void Run(string ironRubyLocation) { | |
var runner = new RSpecRunner(ironRubyLocation); | |
// runner.RunCucumber(); | |
runner.RunRSpec(); | |
} | |
public RSpecRunner(string ironRubyLocation) | |
: this(ironRubyLocation, DefaultSpecFolder(), new[] { GetExecutingDirectory() }) | |
{ | |
} | |
public RSpecRunner(string ironRubyLocation, | |
string specFolder, | |
IEnumerable<string> paths) | |
{ | |
_ironRubyLocation = ironRubyLocation; | |
_specFolder = specFolder; | |
_paths = paths; | |
AddFolderLoadPath(GherkinAssemblyFolder()); | |
} | |
IEnumerable<string> RubyPaths() | |
{ | |
return new[] { @"lib\ironruby", @"lib\ruby\1.8", @"Lib\ruby\site_ruby\1.8" } | |
.Select(x => Path.Combine(_ironRubyLocation, x)); | |
} | |
private static string DefaultSpecFolder() { | |
var root = Path.GetDirectoryName(Path.GetDirectoryName(GetExecutingDirectory())); | |
return Path.Combine(root, "Spec"); | |
} | |
IEnumerable<string> RSpecFiles(string directory) | |
{ | |
return Directory.GetFiles(directory, "*_spec.rb") | |
.Union(Directory.GetDirectories(directory).SelectMany(RSpecFiles)); | |
} | |
public void RunRSpec() { | |
var htmlOutput = Path.GetTempFileName() + ".html"; | |
var args = RSpecFiles(_specFolder).Union( | |
new string[] { "--loadby", "mtime", "--format", "html" } | |
).ToList(); | |
ScriptEngine engine = GetEngine(); | |
engine.Runtime.IO.SetOutput(new FileStream(htmlOutput, FileMode.Create), Encoding.UTF8); | |
RunRubyCommandScript(engine, Path.Combine(_ironRubyLocation, @"bin\spec"), args); | |
ShowOutputFile(htmlOutput); | |
} | |
public string GherkinAssemblyFolder() | |
{ | |
var gemFolder = Path.Combine(_ironRubyLocation, @"Lib\ironruby\gems\1.8\gems"); | |
string searchPath = @"gherkin-*-universal-dotnet"; | |
var result = | |
Directory.GetDirectories(gemFolder, searchPath) | |
.LastOrDefault(); | |
if (result == null) | |
{ | |
throw new DirectoryNotFoundException("Gherkin appears to be missing. I was looking for: " | |
+ Path.Combine(_ironRubyLocation, searchPath)); | |
} | |
return Path.Combine(result, "lib"); | |
} | |
public static void AddFolderLoadPath(string folderPath) | |
{ | |
AppDomain currentDomain = AppDomain.CurrentDomain; | |
currentDomain.AssemblyResolve += (sender, args) => { | |
// var name = args.Name == "gherkin" ? "gherkin2" : args.Name; | |
var name = args.Name; | |
string assemblyPath = Path.Combine(folderPath, name + ".dll"); | |
if (File.Exists(assemblyPath)) { | |
Assembly assembly = Assembly.LoadFrom(assemblyPath); | |
return assembly; | |
} | |
return null; | |
}; | |
} | |
string _rspecPattern = "**/*_spec.rb"; | |
public void RunCucumber() { | |
var htmlOutput = Path.GetTempFileName() + ".html"; | |
// var args = new string[] { "--help" }; | |
var args = new[] { _specFolder, "--out", htmlOutput, "--format", "html", "-exclude", _rspecPattern, "--strict" }; | |
ScriptEngine engine = GetEngine(); | |
// engine.Runtime.IO.SetOutput(new FileStream(htmlOutput, FileMode.Create), Encoding.UTF8); | |
RunRubyCommandScript(engine, RubyExecutable("cucumber"), args); | |
ShowOutputFile(htmlOutput); | |
} | |
public string RubyExecutable(string name) | |
{ | |
return Path.Combine(_ironRubyLocation, "bin", name); | |
} | |
private static void ShowOutputFile(string htmlOutput) | |
{ | |
var process = new System.Diagnostics.Process() { | |
StartInfo = new System.Diagnostics.ProcessStartInfo(htmlOutput) { | |
UseShellExecute = true | |
} | |
}; | |
process.Start(); | |
} | |
private ScriptEngine GetEngine() | |
{ | |
var engine = IronRuby.Ruby.CreateEngine(); ; | |
var rubyPaths = RubyPaths().ToList(); | |
rubyPaths.AddRange(_paths); | |
engine.SetSearchPaths(rubyPaths); | |
return engine; | |
} | |
public static void RunRubyCommandScript(ScriptEngine engine, string fileName, IEnumerable<string> rubyArgs) | |
{ | |
SetArguments(engine, fileName, rubyArgs); | |
try { | |
engine.ExecuteFile(fileName); | |
} catch (SystemExit exit) | |
{ | |
if (exit.Status != 0) | |
{ | |
int x = 0; // Purely for breakpoints. | |
} | |
} | |
catch (SyntaxError syntaxError) | |
{ | |
var rex = RubyExceptionData.GetInstance(syntaxError); | |
foreach (System.Collections.DictionaryEntry x in syntaxError.Data) | |
{ | |
Console.WriteLine(string.Format("{0}:{1}", x.Key, x.Value)); | |
} | |
throw; | |
} | |
catch (Exception ex) { | |
var rex = RubyExceptionData.GetInstance(ex); | |
throw; | |
} | |
} | |
private static void SetArguments(ScriptEngine engine, string fileName, IEnumerable<string> args) { | |
// var setup = engine.Setup. | |
dynamic rubyArgs = engine.Execute("$*"); | |
rubyArgs.Clear(); | |
foreach (string arg in args) | |
{ | |
rubyArgs.Add(arg); | |
} | |
engine.Execute(string.Format("$0 = \"{0}\"", Escape(fileName))); | |
} | |
static string Escape(string arg) { | |
return arg | |
.Replace("\"", "\"\"") | |
.Replace("\\", "\\\\"); | |
} | |
private static string GetExecutingDirectory() { | |
var codebase = System.Reflection.Assembly.GetExecutingAssembly().CodeBase; | |
var uri = new Uri(codebase); | |
var fileName = uri.LocalPath + uri.Fragment; | |
return Path.GetDirectoryName(fileName); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment