All atomic-powered posts filed in “Tips”:
Testing C# code that is run as the result of a event being fired
Or, How to test your Presenter classes
A couple of colleagues and I recently finished up a project for a client that involved a lot of C# code. Our unit testing tools of choice were NUnit and Rhino Mocks. The NUnit choice was a pretty easy one (although there are other platforms out there), but we spent a little more time choosing a mocking library. Our first choice was NMock, primarily because we had experience using it on previous projects and we knew it could get the job done. Before too long, though, we switched to using Rhino Mocks. The primary reason for the change (if I am remembering correctly) was because of its superior event handling capabilities, and we grew to prefer its explicit use of the record-playback-verify mocking model. Rhino Mocks was one of the first libraries to directly support event registration and event raising by mocks (at least, it was the first we had used). This was a big advantage over having to add a SubscribeEvent() method to our view and model interfaces and having to use syntactically obscure paradigms to capture and fire the event raisers. With Rhino Mocks we could add public events directly to our interfaces and (fairly) explicitly capture the event raisers. Read the rest of this entryAnnouncers: A layer between the controller and rendering
For my last Rails project, we went to a completely Ajax interface for everything. This meant that nearly every action on a controller would result in several lines of RJS calls, along with the logic of which partial to render depending on the state of updating or creating an object.
All that logic and RJS stuff was a pain to test in a controller spec, because so much setup is needed every time you call a controller action in a test (authentication, session, etc). Any branching you have in a controller action really becomes a nuisance to test, and when the customer wants to be able to change what happens on the page when a user saves some object, rewriting those tests and the controller are even less fun.
So we came up with the idea of moving all the presentation related logic out of the controller and into helper objects we call announcers. The purpose of an announcer is to make the actual rendering calls, based on state that is passed to it by the controller.
Read the rest of this entryRolling a JRuby desktop application
- Work on our application as developers
- Distribute our application as a single jar file to our users
- Compile the Ruby source files into Java class files
- Integrate third-party Ruby and Java libraries
This article includes an example project that demonstrates all of the above.
Read the rest of this entryRuby and Unicode Win32 MessageBoxes
Have you ever needed to display Unicode characters in a Win32 MessageBox from a Ruby script? My pair and I needed to do just that and so I thought I would share what we found.
There are a number of ways to access Win32 calls from a Ruby script. The code we were working with did the following:
1 2 3 4 5 6 7 8 9 |
require 'dl' def show_message_box(message, title) mb_ok = 0 mb_iconexclamation = 48 user32 = DL.dlopen("user32") message_box = user32['MessageBoxA', 'ILSSI'] message_box.call(0, message, title, mb_ok | mb_iconexclamation) end |
That works well until you need to display Unicode characters in the MessageBox. It turns out the MessageBoxA version of the function is for ASCII characters. There is another version of the API call, MessageBoxW, that can handle Unicode, or wide characters. So the issue becomes converting your Ruby string into a wide string so it can be passed to MessageBoxW. The MultiByteToWideChar Win32 call can do this for you. And the windows-pr gem (from win32utils) adds a nice ruby wrapper around the function.
gem install windows-pr |
1 2 3 4 5 |
require 'windows/unicode' include Windows::Unicode $KCODE='UTF8' str = multi_to_wide("This is a test") |
This seemed to work quite well for the most part. However, from time to time we would see garbage text showing up at the end of our messages. It could easily be reproduced if the message was very short.

Having done enough C/C++ coding to recognize a string that was not being null terminated, we experimented with adding null characters to the end of the string. It turns out a wide null terminator (”\0\0”) is needed. The following code will properly display Unicode characters in a Win32 MessageBox:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
require 'dl' require 'windows/unicode' include Windows::Unicode $KCODE='UTF8' def win32_wide(text) multi_to_wide(text) + "\0\0" end def show_message_box(message, title) mb_ok = 0 mb_iconexclamation = 48 user32 = DL.dlopen("user32") message_box = user32['MessageBoxW', 'ILSSI'] message_box.call(0, win32_wide(message), win32_wide(title), mb_ok | mb_iconexclamation) end show_message_box "MessageBox displayed from Ρουμπίνι", "¡Alert!" |
Model Generation - Coding for Simplicity
Rails convention calls for test data to be stored in fixtures. This works very well for the first few iterations, but this approach quickly becomes unwieldy. Often, many records are required, which can lead to poor record names like event_46. Even when naming conscientiously, it’s difficult to give each record a meaningful name in a global scope. When adding required fields to models, every record needs to be updated, which can be tedious for large test data sets, and very often the updates have an undesired impact on a broad set of tests.
We’d prefer to build up test data closer to home, in the test itself, so we can see the connection between the data and the expectations. Furthermore, if we structure our tests this way the data is isolated from other tests so we’re free to tinker with it without breaking those other tests. The drawback is that manual creation of ActiveRecord objects in your test code can become as tedious to write and maintain as fixtures.
Enter Generate – a technique that centralizes ActiveRecord model generation for test data, removes the need for fixtures, and avoids the tedium and verbosity of in-test model creation.
Read the rest of this entryTrailing backslash problem and fix for Rails and SQLServer 2005
I came across a problem on project where trying to create a new record with a string attribute that ends in \ (backslash) was causing an OLE error to pop up through the DBI driver.
For example, if you had a model with a string attribute called name and you tried to doModel.create! :name => 'foo\\' you would get the following error:
DBI::DatabaseError: Execute
OLE error code: 80040E14 in Microsoft OLE DB Provider for SQL Server
Incorrect syntax near '\'.
HRESULT error code:0x80020009
Exception occured.: INSERT INTO completables ([project_id], [type],
[description], [completion]) VALUES(2, 'Deliverable', 'bar\', 0)
This happens with Rails 1.2.3 running on Windows Server 2003 talking to SQLServer 2005 using ruby-dbi 0.0.23 and version 0.1 of the ADO driver.
Normally SQLServer allows backslashes anywhere in a string. It uses a single quote as an escape for a single quote. But for some reason a backslash at the end of a string is treated differently.
The following bit of code put into environment.rb will replace backslashes with calls to CHAR. 92 is the ASCII value of backslash.
1 2 3 4 5 6 7 8 9 |
module ActiveRecord module ConnectionAdapters class SQLServerAdapter def quote_string(string) string.gsub(/\'/, "''").gsub(/\\/, "' + CHAR + '") end end end end |
Presenter First: Transient Triads
I recently got an email asking when and where to instantiate MVP triads (and supporting objects) that appear in response to events in the system, but are not to be built at application start time. MDI (multiple document interface) applications are a good illustration of this: when your application starts, you have zero document editors, but as the user opens documents, you will have several editors. Who builds these transient triads?
The Question:
Hi,
... I am writing and application that consists of a Navigation pane which is a TreeView and a pane to display what has been clicked on in the navigator in tab form using a TabControl. I currently have the following triads
NavigatorModel, NavigatorPresenter, NavigatorView TabViewerModel, TabViewerPresenter, TabViewerView Type1Model, Type1Presenter, Type1View Type2Model, Type2Presenter, Type2View
Type1 & Type2 are different types of content that are to be displayed in the TabViewer. I am a bit confused now on where the Type1 & Type2 triads should be instantiated.
... Thanks for your time
Gavin
The Response:
Hi Gavin,
I would probably have a Factory object of some kind composed into the TabViewerModel. It could take some symbolic indicator of which type of thing you need to instantiate and view (Type1 or Type2), and perhaps the fundamental data needed to configure the newly created triad. The Factory then instantiates the requisite model, view, presenter (and any other supporting objects you may need in that little cluster)... then return a tuple containing a reference to both the new Model and View instance.
You need the View instance, obviously, because you’ve got to plug it into the tab view pane, or whatever. You might transfer this from the TabViewerModel through the TabViewerPresenter.
We’ve often needed to retain a reference to the Model in order to communicate with this newly created arm of the application… your needs or design may work differently. In this scenario, the new Model would wither be kept directly by the TabViewerModel, or TabViewerModel might pass it off to some sort of collection manager elsewhere in your system.
We tend to use dependency injection systems like Spring and Spring.NET (DIY for Ruby) to describe our object systems. For the overall system, we have a “main context” that would, in your case, describe the composition of Navigator* and TabViewer*, and also the TypeFactory instance.
Then, we create “sub contexts” to describe Type1 and Type2 MVP triads. The TypeFactory object would use the Spring library to load up a sub context from an XML file dedicated to, say, the Type1 triad.
The Factory approach is probably a better approach than burdening your presenters with the chore of multi-object instantiation and composition. (An alternate approach might be: compose the Factory object into the Presenter…)
One parting tip: Object instantiation, though very small in code, is a serious responsibility for an object to undertake, so don’t feel bad about spending a little extra time and effort to do it right.
Hope this helps! /Dave
Presenter First: Get your triads talking
Today I got an email from Sandro Aloisio asking an important question about the connection of one MVP triad to another. When introducing the basics of Presenter First, one usually runs out of breath before getting to the topic of connecting triads using Managers (or Coordinators, whatever you call them), which is a technique that has grown up a little and proven to have some merit. So here’s a little more discussion on that front:
Q: There should be at least one MVP triad per user story, is that correct?
Yes, at least one triad for a user story is a good way to go, especially at the outset of a project. It’s worth pointing this out, as I have seen code written by folks who interpret Model-View-Controller patterns to mean your application should consist of exactly 3 gigantic classes.
One user story usually involves one or more like-minded statements that start with “when the user clicks Save” and “when the user clicks Cancel”. A subsequent user story might augment a feature by saying “when the user clicks Apply, save changes but don’t dismiss the dialog” which might involve going back to the old Presenter for that feature.
And it could happen that a small handful of innocent, related phrases from the same story are technically separated enough to make you want to compose more than one triad to answer the story. There’s nothing in the pattern (or our experience) that says this is a problem. At worst, you’ve added a little extra interface code. At least you’ve introduced that much more domain language into your code.
That second case comes up often when the actual verbiage from the customer covers a lot of ground, such as “I can double-click the user name in the list, change that user’s password, then save.” This implies a collection of smaller stories, such as an interactive user list, a password editor, etc. Decomposing the larger story into several related smaller stories gets you several related MVP triads which will need to interact according to the overall user story.
Q: What if a model from one MVP needs to know the state of a foreign model (in another MVP)?
The model-to-model communication you’re asking about is something we answer with the loosely-named “manager” pattern (naming of these objects varies from project to project, I’ll discuss that below). A Manager is structurally identical to a Presenter: it acts as an observer on two objects, and channels data and intentions from one to the other. The Manager exists only to do these things, and has no public API (same as Presenter) and nobody holds a direct reference to this object.
Managers come into existence when you recognize that a user story describes the interaction between two other story-level application features. You’ve already got a triad for each feature, and you’ve decided that the models from these features need to talk to each other. Responsibility and testability issues pop up quickly if you simply let the models reference one another directly, and even if you try to wire one model up to observe the other. (We’ve found that subscribing for, reacting to and processing input is indeed too much to do cleanly all in one class… Presenters lift a lot of this burden from our backs.)
A Presenter’s basic event-and-data brokering habits have freed you up to write much simplified View and Model code. Objects get to “wish” for things to make their testing easier, like “I wish someone would send this data to me, instead of my having to retrieve it, and knowing when”. if you take two models and put a Presenter-ish object between them (creating a new triad) you get to connect your models without overloading them too much. Additionally, you’ve got a specific place to transcribe the user story that connects these two features in the first place.
If you still feel like your models in this triad are starting to get somewhat heavy in their dual responsibilities, do not hesitate to elaborate on the relationship between the models by introducing more models, and perhaps more Managers to connect them. Don’t be frightened of the additional classes… if a problem has become complex enough to make you ask yourself if you need another class to get the job done, you probably do.
On naming:
In several large projects, we found that we wanted to reserve the word Presenter for that specific type of object that connects Models to Views (or Adapters, but that’s a different topic). Verbal design sessions are easier when the words always mean the same thing. In our seach for terms that mean “Presenter-like object that connects models to models” we’ve used Manager, Conductor and Coordinator. We tend to refer to this aspect of Presenter First as the “coordinator pattern” or “manager pattern.”
When choosing a specific name for a Manager object, try naming it directly for the feature the object will enabled. Eg, you might connect the UserListModel and PasswordEditorModel via the UserPasswordEditorCoordinator.
The Exceptional Presenter
PresentationObject is an implementation of Jay Fields’ Presenter pattern in Rails. It has familiar declarative style syntax and offers encapsulating presentation logic in a testable object.
Without a presenter-like object it’s easy to spread presentation logic and information across the MVC architecture: models end up with unneeded methods, controllers make unneeded decisions and view templates become corroded by unneeded code. Combined it becomes difficult to test and maintain presentation logic in the application.
Here’s an example of a simple presentation-oriented method existing in a model:
1 2 3 4 5 6 7 8 9 10 |
class Group < ActiveRecord::Base belongs_to :parent has_many :subgroups def show_relationships? return true if parent || subgroups.any? false end end |
The show_relationships? method is only used in a view to determine whether or not it should display the relationships information. It doesn’t really belong on the model.
Here’s an example of a controller making presentation decisions:
1 2 3 4 5 6 7 8 9 10 11 |
class GroupsController < ApplicationController def index if current_user.superuser? @groups = Group.find(:all) else @groups = Group.find_active_groups_with_member(current_user) end end end |
The index action introduces an unneeded branch of logic for a controller to have. It is painful to see this branch sprinkled throughout any controller that has to do with supplying @groups to the view because you will have to test the branch separately for each controller action that includes it. A common mistake made is to make this branch a before filter and define the method inside of the ApplicationController. Before filters can be easily misused and that is a topic for its own post so let’s not discuss that here—just know that using a before filter for this example is not the best thing to do.
Here’s an example of code that should not be in the view:
1 2 3 4 5 6 |
<%= Group::GROUPS_TITLE %> <% Group.find(:all).each do |group| %> <% if group.member?(@current_user) %> <%= link_to h(group.name), group_path(group) %> <% end %> <% end %> |
The first thing to stand out is the Group.find(:all) call. It shouldn’t be there. The second thing to spot is the group.member? call. It doesn’t need to be there. Lastly, the usage of the GROUPS_TITLE constant doesn’t belong in the view.
Rather then sprinkling these presentation-oriented decisions and knowledge across the whole MVC architecture the PresentationObject drops in as an intermediary between the view and the model. It is responsible for knowing that the logic it contains will be presentation logic. This makes it the perfect place to put logic that otherwise shows up in the model, controller or view. A strength of the presenter is that it can mimic the model.
Here’s a GroupPresenter moving code out of the model:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class GroupPresenter < PresentationObject delegate :id, :to_param, :name, :members, :to => :@group def initialize(options) @group = options.delete(:group) end declare :show_relationships? do return true if @group.parent || @group.subgroups.any? false end end # in a controller action that deals with a single group def some_action group = Group.find(params[:id]) @group = GroupPresenter.new group end |
By creating a GroupPresenter we’re able to keep our model responsible and disciplined. It also allows us to make little or no change to the view since the GroupPresenter delegates the necessary methods. Now, moving one method out may or may not be enough motivation for you to create a presenter. That depends on the situation you and your code are in. Unfortunately there’s rarely just one method that doesn’t belong on the model.
Here’s a GroupsPresenter moving code out of the controller:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
class GroupsPresenter < PresentationObject include Enumerable def initialize(options={}) @user = options.delete(:user) end declare :groups do if @user.superuser? Group.find(:all) else Group.find_active_groups_with_member(current_user) end end def each(&blk) groups.each(&blk) end end # in the index controller action def index @groups = GroupsPresenter.new :user => current_user end |
Here the view won’t have to change. You gave it an array of groups before and you are giving it an object which acts exactly the same. The only difference is that your GroupsPresenter will make the right decision on what groups should be iterated over.
Before we look at a cleaned up view template there is more benefit with the PresentationObject and these last two examples.
First, it’s easily testable since all of the work is done in the methods themselves. Here’s a spec example covering the GroupPresenter we extracted from the model:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
describe GroupPresenter, 'delegates' do before do @group = mock('group') @presenter = GroupPresenter.new :group => @group end it_delegates :id, :to_param, :name, :members, :on => :presenter, :to => :group end describe GroupPresenter, 'show_relationships?' do before do @group = mock('Group') @presenter = GroupPresenter.new :group => @group end describe 'when the passed in :group has a parent' do it 'returns true' do @group.should_receive(:parent).and_return(true) @presenter.show_relationships?.should be_true end end describe 'when the passed in :group does not have a parent, but has subgroups' do before do @group.stub!(:parent).and_return(nil) end it 'returns true' do @group.should_receive(:subgroups).and_return([:subgroup]) @presenter.show_relationships?.should be_true end end describe 'when the passed in :group does not have a parent or any subgroups' do before do @group.stub!(:parent).and_return(nil) @group.stub!(:subgroups).and_return([]) end it 'returns false' do @presenter.show_relationships?.should be_false end end end |
The it_delegates spec helper is included at the bottom of this post.
Secondly, the presenter uses lazy evaluation and implements caching. For example the GroupsPresenter declares a :group method which retrieves all groups the user is able to see. This can be called as many times as you want, but it will only execute the first time. Every subsequent call will return a cached result. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
groups = GroupsPresenter.new :user => current_user groups.each { || } # this will call :groups which will make a find call to Group groups.each { || } # this will returned the cached value from the last time :groups was called #likewise for the GroupPresenter group = GroupPresenter.new :group => Group.find(:first) group.show_relationships? # executes our implementing code group.show_relationships? # returns the cached value from the last execution</li> # this works for delegated methods to group = GroupPresenter.new :group => Group.find(:first) group.to_param # executed the delegated call to our group model group.to_param # returns the cached value from the last execution |
So depending on whatever your view ends up actually displaying the minimum number of calls to the database or to complicated methods will be made.
A real-world example of this is implementing a leader board which involves users, scores, games and user play regions. In order to show the leader board a number of computationally heavy algorithms and queries have to execute. These database and CPU intense calculations should happen once. PresentationObject gives you this advantage—for free.
Another advantage that is easy to overlook is where the decision is made that determines which specific query or computation to run. When it’s in a presenter it is isolated in an object which is only concerned with doing the right thing based on what needs to be displayed to the user. This makes it much simpler to comprehend and track down when compared to housing it inside one of the alternatives: the model and the controller.
But back to cleaning up the view template. Here’s what the view template should look like:
1 2 3 4 |
<%= @groups.title %> <% @groups.each do |group| %> <%= link_to h(group.name), group_path(group) %> <% end %> |
We’ve pulled out two important things from the view template: the GROUPS_TITLE constant and the conditional logic checking the current user for group membership.
Here’s the presenter that goes with the new view template:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
class CurrentUserGroupsPresenter < PresentationObject include Enumerable def initialize(options) @user = options.delete(:user) end def each(&blk) groups.each(&blk) end declare :groups do Group.find_active_groups_with_member(@user) end declare :title do Group::GROUPS_TITLE end end # in the index controller action def index @groups = CurrentUserGroupsPresenter.new :user => current_user end |
Pulling out the GROUPS_TITLE constant into a method on our presenter is important because the view template doesn’t need to know what title should be displayed. It just needs a title to display. If we wanted to build a title dynamically there is one single place where we can change that logic without affecting the view or anything else—the presenter.
Pulling out the conditional logic from the view template into our presenter gives us several advantages.
First, the view template is now available to be reused as a partial because it is only displaying the groups it is given. We can make the decision elsewhere on what groups to show and our template will just work.
Second, we’ve removed the urge to add any other conditional statements in that loop. We were just checking for group membership, but maybe we need to see if the user is a superuser. By placing this logic in the presenter we have removed the temptation of just adding more logic to the view template.
Lastly, we have created a single testable object for this presentation logic—our presenter. This greatly simplifies our view tests and the implementation of our views. And it stays consistent with placing this logic in a single object whose responsible for making these presentation-oriented decisions.
An alternative to this approach prior to the refactoring would have been to extract the code into a controller helper. This isn’t the right thing to do in our example. Helpers are too often used to tuck away code that shouldn’t be out in the presentation layer. They appear to add benefit because it’s so simple to move things from a view into a helper, but the long term debt far outweighs this short term gain. Helpers aren’t highly cohesive objects. Their responsibilities tend to be a little bit of everything and this hurts the ability to have simple testable objects that have highly cohesive behavior and responsibility. It also hurts maintainability. And it adds to the temptation that it is ok to put code in a helper that shouldn’t otherwise be there.
The name of this last presenter was CurrentUserGroupsPresenter whereas the earlier examples were GroupPresenter and GroupsPresenter. The goal of a presenter is to reduce the sprinkling of presentation logic throughout the system which in turn reduces complexity. We’ve found that presenters are cheap to create and work with. They usually work best when they focus on a single component in the UI. If we have four different components on the UI which each uniquely display groups on the site there may be four different group presenters, each one focusing on a specific UI component.
This differs from Jay Field’s presenter concept in that it focuses on encapsulating presentation logic rather then just encapsulating actions that operate on a model from the controller. This isn’t to say that these two ideas can’t be combined successfully or that one is better then the other. We have found that encapsulating presentation logic in a presenter is a great win overall and we haven’t had the need to push other responsibilities such as model creation and updates onto the presenter itself. This usually ends up in a manager-like object.
Installing PresentationObject
The current release is a 0.1.0 release:1 2 3 4 5 |
# installing the latest presentation_object (points to 0.1.0) script/plugin install svn://rubyforge.org/var/svn/atomicobjectrb/tags/presentation_object # installing the 0.1.0 release specifically script/plugin install svn://rubyforge.org/var/svn/atomicobjectrb/tags/presentation_object-0.1.0 |
it_delegates
An RSpec helper:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
module Spec::Example::ExampleGroupMethods def it_delegates(*args) options = args.extract_options! methods = args src = options[:on] to = options[:to] raise "Missing an object to call the method on, pass in :on" unless src raise "Missing an object to ensure the method delegated to, pass in :to" unless to method_options = options.reject{|k,v| [:on, :to].include?(k)} methods.each {|m| method_options[m] = m} method_options.each do |source_method, to_method| it "delegates ##{source_method} to @#{to}.#{to_method}" do obj = instance_variable_get "@#{to}" _src = instance_variable_get "@#{src}" return_val = stub("return val") obj.should_receive(to_method).and_return(return_val) _src.send!(source_method).should == return_val end end end end |
Roll Your Own respond_to
While refactoring some ruby code the other day I found myself wanting respond_to-like functionality. Specifically, I was calling a function that would have one of several possible outcomes, and I wanted to handle each in a clean way. Specifically, I wanted syntax like this:
1 2 3 4 5 6 7 8 |
zebra array do |row| row.even do |element| puts "even #{element}" end row.odd do |element| puts "odd #{element}" end end |
I put together a bit of code for doing this, called Multiblock. You could write zebra, with a Multiblock, like so:
1 2 3 4 5 6 |
def zebra(list) list.each_with_index do |element, index| odd_or_even = [:even, &odd][index % 2] yield Multiblock[odd_or_even, element] end end |
Here’s the source code for Multiblock:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
class Multiblock def self.[](*args) new *args end def initialize(*args) _expect *args unless args.empty? end def [](*args) _expect *args self end def method_missing(name, *rest) if !@matched @matched = [@waiting_for, :else].include? name if @waiting_for == name @result = yield *@args elsif :else == name @result = yield @waiting_for, *@args end end @result end private def _expect(waiting_for, *args) @waiting_for = waiting_for.to_sym @args = args @result = nil @matched = false end end |
Some useful selenium helpers
Wouldn’t it be nice if you could evaluate arbitrary javascript in the context of your Rails application’s window when testing it with Selenium? Well, you already can. What Selenium doesn’t do for you, however, is automatically serialize the result of your computation to JSON, then deserialize that JSON into a convenient ruby object. What I want to do is stuff like this:
1 2 3 |
# get the center of the page's google map lat, lng = get_json "[c.lat(), c.lng()]", :c => "googleMap.getCenter()" |
or
1 2 |
positions = get_json "{foo: $('foo').offsetLeft, bar: $('bar').offsetLeft}" assert positions['foo'] < positions['bar'], "bar was too far to the right" |
Here’s the definition of get_json:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# evaluate arbitrary javascript in the context of your page. def eval_js(code) get_eval <<-JS selenium.browserbot.getCurrentWindow().eval("#{ code.gsub('"', '\\\\"').gsub("\\n"," ") }") JS end def get_json(code, objects={}) entries = objects.entries ActiveSupport::JSON.decode( eval_js(" Object.toJSON( (function(#{entries.map (&:first).join(', ')}){ return #{code}; })(#{entries.map(&:last).join(', ')}) ) ") ) end |
Financial Analysis in Software Development
I was struck recently by how rarely software developers and project managers really analyze software development expenses.
Ever been part of a discussion about purchasing a third party library? Ever considered whether to automate a particular task? How often have you or anyone involved estimated how much money the library purchase or automation would save in comparison to the needed developer time?
Read the rest of this entryRuby String#split
Taking a string and splitting it with a delimiter is a very common task in Ruby. The official documentation states that String#splitdivides str into substrings based on a delimiter, returning an array of these substrings.
The delimiter itself can be a string or regular expression:
1 2 3 4 5 6 7 |
#string delimiter "hello".split('') #=> ["h", "e", "l", "l", "o"] "hello".split('ll') #=> ["he", "o"] # regular expression delimiter "hello".split(//) #=> ["h", "e", "l", "l", "o"] "hello".split(/l+/) #=> ["he", "o"] |
String#split takes an optional second parameter representing a limit. From the String#split documentation:
If the limit parameter is omitted, trailing null fields are suppressed.
If limit is a positive number, at most that number of fields will be returned (if limit is 1, the entire string is returned as the only entry in an array).
If negative, there is no limit to the number of fields returned, and trailing null fields are not suppressed.
Here are some examples of how the limit parameter works:
1 2 3 4 5 6 7 8 9 |
# omitting the limit "1234 1234".split('4') # =>["123", " 123"] # positive limit "1234 1234".split('4', 1) # => ["1234 1234"] "1234 1234".split('4', 2) # => ["123", " 1234"] # negative limit<code> "1234 1234".split('4', -1) # => ["123", " 123", ""] |
These examples have been short and simple and in my experience the common usages of String#split will be. When you start to go beyond the short and simple you will find some behavioral oddities with String#split and it will always be with regular expression delimiters.
Read the rest of this entryCode Reviews... Code Reviews...
Code reviews are a common practice intended to catch software flaws by having “more eyes” on a piece of code in order to catch costly software defects. Unfortunately, many people dread code reviews, because they are time consuming and many times are not very fruitful. It takes a lot of discipline and similar mindsets to really get a cost-effective benefit out of code reviews. Not to mention that reviews often get slowed by people nit-picking implementation, code style and even arguing over where a comment, paren or brace should go!
For those of us that practice test driven development, we have an added luxury that all of the functionality in our code is backed up by unit, integration and system tests, or some mix of these. These tests also serve as living documentation of the code at hand.
Therefore, it seems that reviews of tests, which verify requirements, would be a much more suitable and beneficial initiative. After all, aren’t we all most concerned with what the code “does” and not so much “how” it does it? The tests capture the requirements put on a body of code, and that is really what is most important to be sharing with fellow developers. This technique would avoid many of the hurdles that inhibit traditional code reviews. Furthermore, changes to tests or addition of tests (requirements) could be done live in a code review and eliminate another round of reviews to ensure all concerns have been addressed. This all leads to less bookkeeping and happier developers!
Multi-Platform Automated Testing
We recently got a question from one of our customers on writing and running test suites for multi-platform applications (the case in question involves Java). The thread of discussion follows. First, we have Andy’s original question. Next, Karlin and Dave respond…
Read the rest of this entry