Getting NUnit to go all STA

As I was trying to help out someone who had trouble with writing a unit test for a data bound WPF Window.. first of all I had to ref WindowsBase, PresentationCore and PresentationFramework and then I ran into a curt warning from WPF when you're trying to instantiate a WPF window in a NUnit test case.. (Grumble Grumble... I hate UI in unit tests)
TestProj.TestBindings.TestTextBoxBinding:System.InvalidOperationException : The calling thread must be STA, because many UI components require this.
What is STA? Something you only wish 'stays out of the way'.
Interesting.. this means... its not running in STA. Elementary. Now how do I get NUnit to go STA. It was a long arduous road.
First up if you have NUnit 2.5 or above,
I believe its as easy as this.



[Test, RequiresMTA]
public void MTA()
{
Assert.AreEqual(ApartmentState.MTA, Thread.CurrentThread.ApartmentState);
}

[Test, RequiresSTA]
public void STA()
{
Assert.AreEqual(ApartmentState.STA, Thread.CurrentThread.ApartmentState);
}


If not, which is where I was. It's slightly more complicated.
First go to
C:\Program Files\NUnit 2.4.8\bin
Look for a file called NUnitTests.config. Next copy this over to your test dll folder which has TestProj.nunit (or make one.. you'll need it). Rename the copy of the file to 'TestProj.config'.. Open it up in an editor.. Time for adding bringing some more XML into the world.


<configuration>
<configSections>
<sectionGroup name="NUnit">
<section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/>
</sectionGroup>
</configSections>

<NUnit>
<TestRunner>
<add key="ApartmentState" value="STA"/>
</TestRunner>
</NUnit>
<!-- all the other fluff stays -->
</configuration>


That's it, fire up NUnit.. if all goes well, you'll be running in STA and WPF will 'show itself'.

Graphs in Ruby On Rails


Well I was building my personal expense tracking web app and soon enough I need to graph the top expense categories... A little searching led to gruff and it worked right outta the box.


First up, Gruff needs RMagick which needs ImageMagick. Tricky.. so go here and I hit Q#7
Soon you should land up
here download the rmagick-win32 gem zip. This archive has both RMagick gem and the install for the right version of ImageMagick. Installing the latest version of ImageMagick may not work.. (I didnt try.. the docs warned me off).
So install ImageMagick first. Next install the gem with 'gem install rmagick --local' in the folder where you unzipped the archive.
Now switch to your Rails Dev Environment. Open up config/environment.rb - Add this line at the end 'require gruff'
Add a new action to the controller of your choice.



  def showTopN
g = Gruff::Bar.new
g.title = "Hello Gruff"
g.theme_37signals

Expense.get_top_n_categories(:limit=>10).each{ |category|
g.data(category.name, category.total_amount.to_f)
}

send_data g.to_blob, :disposition=>'inline', :type=>'image/png', :filename=>'top_n.pdf'
end




Now close all command windows. Restart Webrick (your Rails Web Server) to take into account changes made to your PATH env var.
Fire up a browser.. in my case to http://localhost:3000/outflow/showTopN

Update:Normal people would be overjoyed at this point.. but not me. I wanted to create this graph at runtime .. So when I click on a link that I imagine will be there, I callback on my controller (yes using AJAX), create my graph and then slot it into a div tag on the same page. This will help me chart different sub-sets of data without leaving the page.
But how? so I post a question on stackoverflow
Solution:
report_controller.rb
require 'gruff'
class ReportController < ApplicationController
def showTopNCategories

end

def drawBarChart
g = Gruff::Bar.new
g.title = "Hello Gruff"
g.theme_37signals

Expense.get_top_n_categories(:limit=>10).each{ |category|
g.data(category.name, category.total_amount.to_f)
}
g.write('public/images/top_n.png')
render(:text=>'top_n.png')
end
end



showTopNCategories.rhtml


<%content_for("page_scripts") do -%>
function updateImg(id, imageFile)
{
$(id).innerHTML = '<img src="/images/' + imageFile + '"/>';
}
<% end -%>

<!-- some controls -->
<%= link_to_remote("Refresh Chart",
:complete => "updateImg('div_barchart', request.responseText)",
:url=>{:action=>'drawBarChart'})%>

<div id="div_barchart">

</div>



application.rhtml


<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<!-- the usual -->

<script type="text/javascript"> <%= @content_for_page_scripts %> </script>
</head>
<!-- rest of the usual -->




The quirk here was that
  • gruff considers the Rails Project folder as the base folder.. so you need public/images/FileName.png as the parameter to g.write. Rails views however have public as the base folder. So image paths are relative.. /images/FileName.png
  • the javascript function didn't wire up correctly. It dies silently if you make a typo for instance. Use alert("Hit!"); liberally to know if the function is being hit.