Gettextgenerators update

Posted by Bart ten Brinke Mon, 31 Mar 2008 18:29:05 GMT

Gettext generators for rails 2.0 is out. It was available from the trunk for a long time, but now it was actually tagged. Note that it should work with the latest Gettext (1.90), but I have not yet tested this myself.

Posted in  | no comments

Old style alarm clock

Posted by Andre Foeken Fri, 07 Mar 2008 13:58:42 GMT

We wanted to show how many hours were going through our application on a big flat screen at our office. So I whipped up a small javascript/html page that could show a neat animation. I borrowed the raw images from this blog. The end result can be downloaded from here.

Posted in  | Tags , , , ,  | no comments

attr_accessor_with_default

Posted by Andre Foeken Wed, 05 Mar 2008 08:53:39 GMT

What a marvelous feature, but be wary! It can cause some unexpected behavior if you don't know what you are doing.

This morning we found a rather suspicious bug that lead to unexpected things. Here is an example:

class Person ; attr_accessor_with_default :things, {} ; end
john = Person.new
john.things[:table] = true
...
jim = Person.new
jim.things => {:table => true} # huh??

As it would seem attr_accessor_with_default has some problems with collections. Since we are sharing the instance over the entire class. Peter Williams noted this problem several month ago in his article (which we didn't read until it was too late), however the solution he provided still left us with some very undesireable behaviour.

class Person ; attr_accessor_with_default :things, {{}} ; end # note the extra brackets!


john = Person.new
john.things[:table] = true

...

jim = Person.new
jim.things => {} # okay!
john.things => {} # uhm... not okay!

The variable would only stick if we actually assigned it.

john.things = {:table => true}
john.things => {:table => true} # yay!

But doing this every time is not only a pain but also introduces very hard to debug errors, since the assignment does not fail...it just doesn't work!

We solved it by going old-school. Back to the normal accessor for collections.

class Person
attr_accessor :things

 def initialize attributes=nil
  super
  self.things = {}
 end

end

Now the code works as expected and we can use all operators (like >>, []) from the get go.

Update: It seems this had no effect on ActiveRecord objects that were created using finders so here is the fix for any those:

class Person < ActiveRecord::Base
attr_accessor :things

 def after_initialize
  self.things = {}
 end

end

Posted in ,  | Tags , ,  | no comments

Javascript testing problems

Posted by Steven van der Vegt Tue, 04 Mar 2008 16:03:16 GMT

A few months ago I got the assignment to set up and build javascripts-tests for the scheduling view of moves. At first I had to select a testing-framework where the test would be written in. The framework had to be able to run both unit and integrations tests. Also it would be very nice if we can run these test automatically through the command-line instead of clicking around in the browser (autotest).

After reviewing some frameworks, I chose the Crosscheck framework (http://www.thefrontside.net/crosscheck). Crosscheck is a javascript-testing-framework written in java. It is crossplatform and you can control it from the command-line. It is even able to emulate the behavior of multiple popular browsers like ie6, Firefox 1.0 and Firefox 1.5. Sounds like the ultimate testing framework!

So after my decision I started playing around and implementing tests. However, when the tests became more complex I ran into trouble. Some basic browser features like document.write() (ie6) and the Option object where missing. I was able to work around these problems, but the real trouble began with the integration tests. As our application relies heavily on ajax through the prototype framework, testing this functionality is crucial. However, I was not able to do this. Performing one hack after another, I finally gave up.

The crosscheck framework was clearly not mature enough to satisfy my needs. My conclusion is: Using crosscheck for unit-testing is doable, but the framework is not mature enough for the use of integration tests. So what are the problems with crosscheck? As mentioned earlier, it is written in Java, so it tries to emulate the browser behavior based on it's specifications. The advantages of this approach is that you can emulate more than one browser, the disadvantages are that the emulation is an approach, so you will never really get the real behavior of the browser.

If a browser changes its implementation, the framework is always outdated. You don't get the browsers quirks, so if it your tests pass in the test framework, there is no guarantee it will work in the real-browser world. Another problem with crosscheck is that is seems to be abandoned. The last changes are from end-2007 and as far as I can see none of the reported bugs have been fixed yet. Firefox 3.x and ie7 are becoming standard, but these browsers are not available as a test-browser in crosscheck (and there are no clues they will be soon).

What can we expect from the continuity of crosscheck? If you, like us, want to be able to test a long-term project, then it is important that your test-framework is long-term too. So what does my ideal javascript-test-framework look like?

It should:

  • Run from the command line
  • Represent the browser realistically
  • Emulate ajax responses
  • Mock objects
  • Run implementation tests

As far as I know, no such framework exists. However, in my view, it shouldn't be too hard to realize. We could embed the mozilla tree in an application. That way we always have the latest version of the mozilla engine and an exact copy of the behavior including it's quirks. Through the Mozilla API we can access the DOM and other functions. The framework should be able to easily load tests and run them (for this part it's important to take a good look at the x-unit patterns).

At this moment I don't have a clue how easy it is to emulate the ajax responses through mozilla API calls. Furthermore the framework should be give a rich toolkit for testing including abilities to mock objects. You start the framework via the command-line for easy integration with test-runners like autotest. Of course this application should be released under the GPL-licence. Now we only need someone to implement this for us!

Steven van der Vegt (s.vandervegt TA student.utwente.nl)

Ps we are offering an internship for the development of the described plugin at Nedap healthcare. Interrested? bart.tenbrinke@movesonrails.com International students welcome!

Posted in , ,  | Tags , , ,  | 4 comments

libXML for Active Resource 2.0

Posted by Bart ten Brinke Mon, 25 Feb 2008 08:19:39 GMT

I received an email from Stevie Clifton today, asking about our libXML patch for rails 2.0. As we have been running 2.0 for quite some time now, I never realised I forgot to post the new overrides.

The file below goes into /config/initializers/libxml.rb

# This is actally a fix for activeresource as it
# will behave incorrectly when it encounters
# Complex xml files. This override fixes this,
# but it should be submitted to rails trunk.
module ActiveResource
  module Formats
    module XmlFormat
      private
      def from_xml_data(data)
          if data.is_a?(Hash) && data.keys.size == 1
            from_xml_data(data.values.first)
          else
            data
          end
        end      
    end
  end
end

module Nedap #:nodoc:
  module Hash #:nodoc:
    module Conversions

      def self.included(klass)
        require 'xml/libxml'
        klass.extend(ClassMethods)
      end

      module ClassMethods

        # Hash from_xml mixin that uses libxml.
        # This ensures a 20x speed increase
        # Compared to libxml. Plus it is less ugly.
        def from_xml(xml) 
          result = XML::Parser.string(xml).parse 
          return { result.root.name.to_s => xml_node_to_hash(result.root)} 
        end 

        def xml_node_to_hash(node) 
          # If we are at the root of the document, start the hash 
          if node.element? 
           if node.children? 
              result_hash = {} 

              node.each_child do |child| 
                result = xml_node_to_hash(child) 

              if child.name == "text"
                if !child.next? and !child.prev?
                  return result
                end
              elsif result_hash[child.name] 
                  if result_hash[child.name].is_a?(Object::Array) 
                    result_hash[child.name] << result 
                  else 
                    result_hash[child.name] = [result_hash[child.name]] << result 
                  end 
                else 
                  result_hash[child.name] = result 
                end              
              end 

              return result_hash 
            else 
              return nil 
           end 
           else 
            return node.content.to_s 
          end 
        end          

      end        
    end
  end
end 

Hash.send :include, Nedap::Hash::Conversions

There you go. You now have a blazingly fast active resource! If you want some more bang out of your resource, add the following mixins to the initializer too:

# Add inflate to NET class (zLib support)
module Net
  class HTTPResponse
     def inflate!
       require 'zlib'
       @body = Zlib::Inflate.inflate(@body)
     end
   end
 end

# Increase timeout and buffersize for big XML files
module Net
  class BufferedIO 
    def rbuf_fill
      timeout(3000) { 
        @rbuf << @io.sysread(32768) 
      }
    end 
  end
end

Posted in  | Tags , , ,  | no comments

Autotest 100% CPU solution

Posted by Bart ten Brinke Wed, 06 Feb 2008 08:48:27 GMT

Autotest is great, but when it is waiting for test, my MacBook turns into a whirlwind as autotest takes 100% CPU. After looking at autotest.rb, we easily find the waiting function:

def wait_for_changes
  hook :waiting
  Kernel.sleep self.sleep until find_files_to_test
end

As self.sleep is defaulted to 1 it means that my laptop does not sleep at all. Changing this is quite easy, as you can just add this to your .autotest file in your home directory:

Autotest.add_hook :initialize do |at|
  at.sleep = 5
end

Experiment with the amount to determine what works for you. Offcourse autotest will now react slower to you changes, but hey: you can't have everything. Enjoy the silence!

Posted in , ,  | Tags , , ,  | no comments

The new programmers excuse for slacking of

Posted by Bart ten Brinke Thu, 31 Jan 2008 13:40:26 GMT

Original by XKCD.

Posted in , ,  | Tags ,  | 4 comments

Cha-Ching and dutch banks

Posted by Andre Foeken Wed, 23 Jan 2008 19:38:23 GMT

Like lots of you I bought the incredible MacHeist app bundle last week. One of the appz was Cha-Ching, a finance program to keep track of your money.

One of the most useful features is the import. You can simply import all of your bank's records and be done with it. Unfortunately the dutch banks (or at least the Rabobank and Postbank) don't support the same formats Cha-Ching supports (like OFX/QIF).

I wrote a small ruby script to convert the banks CSV files to OFX files. There are two separate files below (one for each bank):

CSV convertor - Postbank (Ruby)

CSV convertor - Rabobank (Ruby)

Before you can run the files you need two additional gems (if you haven't got them already).

sudo gem install extensions
sudo gem install builder

After this you can use the scripts like this:

ruby csv_convert.rb [CSV FILE] > export.ofx
ruby csv_rabo_convert.rb [CSV FILE] > export.ofx

Update: Now supports Tiger using PHP version of script and (optional) automator

For the next files you don't need anything else than a vanilla Tiger install of OSX.

CSV convertor - Postbank (PHP)

CSV convertor - Rabobank (PHP)

You can use them like this:

php csv_convert.php [CSV FILE] > export.ofx
php csv_rabo_convert.php [CSV FILE] > export.ofx

For the simple version, use the automator zip file! Read the README to get it to work.

CSV convertor - Postbank/Rabobank (PHP/Automator)

Posted in ,  | Tags , , , , ,  | 15 comments

Testing your Application Controller with rSpec

Posted by Bart ten Brinke Wed, 23 Jan 2008 13:35:15 GMT

I was trying to create a function that would check the enforcement of the before filters in my application controller. After going through a lot of rspec documentation and examples, I found nothing that really suited my needs. After a long google, I found a mention in the rspec mailing list and a hint to a solution for this. This is a working example of this idea.

I have in my application controller the following code:

class ApplicationController < ActionController::Base
  before_filter :check_authorization
   ....
  # Checks if a user is authorized
  def check_authorization
    User.check_authorization(controller_name, action_name)
  end
end

And in spec/controllers/application/application_spec.rb the following description.

describe "an authorized controller", :shared => true do

  it "should have the check_authorization set in the before filter" do
    ApplicationController.before_filters.should \
      include(:check_authorization)
  end   
end

In all other controller specs I can now do this:

require 'application_controller_spec'

describe UnitsController, "in general" do
  it_should_behave_like "an authorized controller"
end

By doing this I now have a spec that ensures that every controller checks authorizations before doing anything else. How cool is that :)!

It would be nicer if the test handled skip before_filters in some nice way like: it_should_behave_like "a monkey".except_for_action('show'). Has anyone got any ideas for that?

Special thanks to Matthijs Langenberg for his insights.

Posted in  | Tags , ,  | 13 comments

Our product site is online!

Posted by Bart ten Brinke Mon, 14 Jan 2008 10:42:11 GMT

Nedap Moves. Unfortunately for you it is all in dutch, but you can still look at the pretty pictures.

Posted in ,  | Tags  | no comments

Older posts: 1 2 3 4 ... 7