How to install Rails 3.0 and Ruby 1.9.2 on Ubuntu

Published 9/1/2010 7:30 PM by Toran Billups 3 Comments

When ruby on rails 1.0 was released back in 2005 it was all the rage. And being someone who was often distracted by the next great web framework I decided to have a look. So in early 2006 I built a small application to see what all the hype was about. I immediately saw the value of a strongly opinionated framework, something the average asp.net developer like myself didn’t know much about at the time.

Fast-forward to August 29th 2010 - Rails 3.0 was released. Just prior to this release I started looking at the web framework again and because I always strive for the optimal developer experience it meant I would need to quit my windows addiction. Not that you can’t do ruby development on windows, but most of the time it’s not worth the pain.

With that said, I paved my development machine and installed Ubuntu 10.04. But as I started looking around for a "how-to" of sorts on installing rails 3 with ruby 1.9.2 I couldn’t find a simple guide that got me up and running error free. Each time I started with a vanilla install of Ubuntu and ended up with what felt like a "hacked together" development environment. But last night I decided to give it another try and document the steps needed for someone like me coming in with minimal linux experience.

Install RVM 1.0

First be sure to do a quick update before you get started.

sudo apt-get update

Next install curl and git so we can pull down rvm

sudo apt-get install curl git-core

next you need to grab rvm from the url below using curl

bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )

After this is complete you need to edit your .bashrc file. Type "gedit .bashrc" and put the following at the bottom of the file.

[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"

after you complete the above and save your changes, close gedit. Next close your terminal window and re-open it. Now if you type "rvm -v" you should see a valid version 1.x

Install Ruby 1.8.7

First you need to pull down a few development packages

sudo apt-get install libruby1.8 zlib1g-dev libssl-dev libreadline5-dev build-essential

Next you need to install ruby 1.8.7 through rvm

rvm install ruby-1.8.7

After this is complete you need to set ruby 1.8.7 as the default for rvm

rvm use ruby-1.8.7 --default

Install rubygems and other dev essentials

first you need to add the ubuntu-on-rails ppa repository, sometimes they have newer versions of some Ruby components.

sudo add-apt-repository ppa:ubuntu-on-rails

After you add this be sure to do another update

sudo apt-get update

Next install the essential ruby packages

sudo apt-get install ruby rubygems irb ri rdoc rake

And a few more packages, odds are you will need them anyway

sudo apt-get install build-essential ruby1.8-dev libopenssl-ruby

After all the packages above are installed, add the gem path to your global PATH, so that executables new gems can be easily called from the command line.

export PATH=/var/lib/gems/1.8/bin:$PATH

After you run the above command, close the terminal window and re-open it.

Install Sqlite3

Install the sqlite development packages

sudo apt-get install sqlite3 libsqlite3-dev

Install the sqlite gem

gem install sqlite3-ruby

Install Ruby 1.9.2

Next you need to install ruby 1.9.2 through rvm

rvm install ruby-1.9.2

After this is complete you need to set ruby 1.9.2 as the default for rvm.

rvm use ruby-1.9.2 --default

Install Rails 3.0.0

Now install rails but be sure you DON’T use sudo

gem install rails --version 3.0.0

After you have both rails 3 and ruby 1.9.2 up and running, install the sqlite gem again.

gem install sqlite3-ruby

Now you should have a fully functional rails 3 + ruby 1.9.2 development environment! You can verify this by doing a simple "ruby -v" and "rails -v" from the command line.

Tags: ruby rails

Respect encapsulation when you write a unit test

Published 8/5/2010 7:03 PM by Toran Billups 0 Comments

Have you ever written a state based test that required you to examine a private property? Did you determine the best way to get that test passing was to change the declaration from private to public? If so you made a decision to give up the benefits of encapsulation for the sake of unit testing.

Until a month ago I was making this type of decision all the time because I valued testing more than encapsulation. I knew this was a bad idea because everything was exposed and could be harmful if the next developer used it for evil. But because I didn’t know any other way to get at private members I kept making the trade off.

That all changed recently when a friend showed me I could have the best of both worlds. You can tell one assembly that it’s ok for another to view internal members. So the first question was, how do you tell the production assembly that a test assembly can view these? He said to open the AssemblyInfo.cs file found under the project properties and add the following:

[assembly: InternalsVisibleTo("TestProject123", AllInternalsVisible = true)]

You will notice the language used above doesn’t say anything about private or protected, it instead references "internals". So what was an internal and how was it different than private? A simple google search helped me understand that internal means it’s not visible from an external assembly. This is good if you are using multiple assemblies but if you have all your production code inside a single dll you might actually find this switch to be worse because all classes inside that assembly will now have the ability to see these "internal" members.

So on one hand it helps keep encapsulation at the assembly level, but for everything internal you are wide open. The absolute best solution would be to hide these both internally and externally. This is exactly what private is good for, but because you can’t access these from another assembly, your unit test project is also out of luck.

If you decide this is a good solution and you want to move forward, the below example class shows how you might implement this in a production class. Notice the class below now has the field declared as internal instead of private.

public class SuperController
{
	internal string completed;
	
	public void SuperOperationComplete()
	{
	    completed = "yes";
	}
}

Now because my test project was given the right to view internals I could write the following test and it would compile.

[TestFixture]
public class SuperControllerTest
{
    [Test]
	public void CompleteIsValidAfterOperation()
	{
	    var controller = new SuperController();
		
		controller.SuperOperationComplete();
		
		Assert.That(controller.completed, Is.EqualTo("yes"));
	}
}

But if you have just one class library for the majority of your work it might be worse to mark these fields with internal. So instead you could mark these as protected instead. If you make the field protected you could then expose it using a class internal to your test assembly. For example, to test the above using this approach you would first mark the string "completed" as protected.

public class SuperController
{
	protected string completed;
	
	public void SuperOperationComplete()
	{
	    completed = "yes";
	}
}

Now inside your test assembly you would create a class that inherits from SuperController and provide a public method or property that your test can use to verify the expected behavior.

[TestFixture]
public class SuperControllerTest
{
    [Test]
	public void CompleteIsValidAfterOperation()
	{
	    var controller = new TestFriendlySuperController();
		
		controller.SuperOperationComplete();
		
		Assert.That(controller.TestFriendlyCompleted, Is.EqualTo("yes"));
	}
}

public class TestFriendlySuperController : SuperController
{
    public string TestFriendlyCompleted 
	{ 
	    get { return completed; }
		set { completed = value; }
	}
}

Experience has shown me that taking the time to write another class like I’ve done above is worth it to respect the value provided by encapsulation. But if the internal keyword doesn’t have you worried it’s another option (especially if you’re working with a ton of separate projects).

So the next time you think about making a private field public just to verify something in a test, remember that you have a few other options.

Tags: tdd testing

VB finally gets improved lambda support

Published 7/11/2010 8:35 PM by Toran Billups 1 Comments

Last year I was working with Visual Basic a great deal and found the lambda support to be only half baked. For instance if you wrote a lambda expression it required that the expression return a value. But if you wanted to write something for a simple sub routine that had no return value, you had to write some very confusing code to workaround this language limitation.

For example, in the test method below I’m using Rhino Mocks to prove a method called SaveUser was called during the controller action. But because this SaveUser method isn’t a function that returns a value I had to instead create a wrapper function that returned nothing (as object).

 
 _
Public Class UserControllerTest
 
     _
    Public Sub Should_UpdateModel_And_Call_Save_When_ID_Provided_To_The_Controller_Returns_A_Valid_User()
        Dim Service As IUserService = MockRepository.GenerateStub(Of IUserService)()
        Dim Controller As UserController = New UserController(Service)
 
        Dim User = New User()
 
        Service.Stub(Function(x) x.GetUserById(1)).[Return](User)
 
        Dim GetResult As ViewResult = Controller.Edit(1, Nothing)
 
        Dim GetModel As User = DirectCast(GetResult.ViewData.Model, User)
 
        Service.AssertWasCalled(Function(x) Wrap_SaveUser(x, User))
    End Sub
	
    Function Wrap_SaveUser(ByVal Service As IUserService, ByVal User As User) As Object
        Service.SaveUser(User)
 
        Return Nothing
    End Function
 
End Class

But with the latest compiler improvements you no longer need to write this confusing code. And assuming you have Visual Studio 2010 installed, this trick works for both dotnet 3.5 and 4.0!

 
 _
Public Class UserControllerTest
 
     _
    Public Sub Should_UpdateModel_And_Call_Save_When_ID_Provided_To_The_Controller_Returns_A_Valid_User()
        Dim Service As IUserService = MockRepository.GenerateStub(Of IUserService)()
        Dim Controller As UserController = New UserController(Service)
 
        Dim User = New User()
 
        Service.Stub(Function(x) x.GetUserById(1)).[Return](User)
 
        Dim GetResult As ViewResult = Controller.Edit(1, Nothing)
 
        Dim GetModel As User = DirectCast(GetResult.ViewData.Model, User)
 
        Service.AssertWasCalled(Sub(x) x.SaveUser(User))
    End Sub
 
End Class

I wanted to highlight this because I found the workaround above to be very painful in previous versions of VB. Now that is some coevolution that I can get excited about!

Tags: vb

Copyright © 2009 Toran Billups - Valid XHTML & CSS