Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

About this user

Matt Scilipoti

« Newer Snippets
Older Snippets »
Showing 11-14 of 14 total

making functional test failures readable

making functional test failures readable

By zenspider on Rails

Tired of your rails functional test failures being completely unreadable? I'm not terribly fond of rails' assert_tag but it is better than nothing. However, I never like to read something like the following:

expected tag, but no tag found matching {:attributes=>{:action=>"/admin/themes/update/1"}, :tag=>"form"} in:
"<!DOCTYPE [...3k worth of crap cut...]</html>".


Ugh! It just does nothing to help you and since it isn't expressed as a diff, unit_diff is no help in this arena. I have however figured out how to make it much more manageable with the following snippets:

class ApplicationController < ActionController::Base
 def initialize(testing=false)
 super()
 self.class.layout(nil) if testing
 end
 [...]
end

and then in your functional tests:

def setup
 @controller = MyController.new(true)
 [...]
end


Now your failures contain just the content from the page:

expected tag, but no tag found matching {:attributes=>{:action=>"/admin/themes/update/1"}, :tag=>"form"} in:
"\n<ul>\n <li>Name: Blue</li>\n <li>Folder: blue</li>\n <li>Description: A Plain blue theme</li>\n <li>Masthead: Blue</li>\n <li>Editor: n/a</li>\n</ul>\n\n<a href=\"/admin/themes/show/1\">Cancel Editing</a>\n".

Partial Mock Object or mocking an instance of an object.

From: http://www.karmiccoding.com/articles/2006/03/11/under-the-hood-with-ruby-partial-mock-objects-for-unit-testing

"What happens though, if you want to override a class in an instance of an object, and not all of its kind? Typically you would define a mock object, and create an instance of it. But, in Ruby there is an easier and faster way that doesn’t involve writing a different mock class for each different scenario – and it is made possible by the singleton class. This clever bit of ruby hackery lets you override the behaviour of a single instance of a class, creating what I’ve decided to call a partial mock object. To demonstrate, I’ve written a small method called override_method which will override the behaviour of the specified method in the passed object, like so:

# Overrides the method +method_name+ in +obj+ with the passed block
def override_method(obj, method_name, &block)
  # Get the singleton class/eigenclass for 'obj'
  klass = class <<obj; self; end 

  # Undefine the old method (using 'send' since 'undef_method' is protected)
  klass.send(:undef_method, method_name)

  # Create the new method
  klass.send(:define_method, method_name, block)
end

# Just an example class
class Foo 
  def do_stuff
    "I'm okay!" 
  end
end

# Test code
list = []
5.times { list.push(Foo.new) }

# We override the method here!
override_method(list.first, :do_stuff) { "I'm NOT okay!" }

list.each_with_index { |f, i| puts "(#{i}) #{f.do_stuff}" }

Outputs:
(0) I'm NOT okay!
(1) I'm okay!
(2) I'm okay!
(3) I'm okay!
(4) I'm okay!

As you can see, only the first object in the array’s behaviour has been changed – the rest have remained untouched. Because of this, you can embed these partial dynamic mock objects deeply into your code without the need to specially instantiate a mock object deep in your code, or writing a ‘clever mock’ to only trigger the determined behaviour in certain objects.

Where this code comes in really handy is when you need an object to raise a difficult to simulate exception (like a disk full error) on a certain method to test your error handling – simply call override_method and pass in a call to raise and voila! Dynamic partial mock objects on the fly!"

Ruby WEBrick as WebDAV Server

From: http://sg.validcode.at/articles/2006/02/25/vision-everywhere

gem install webrick-webdav


If you have done this dowload webdav.rb.txt rename it to webdav.rb put it into the Vision folder and start it with
ruby PATH/TO/VISION/webdav.rb

Flexible Include: allows rename or exclude specific methods.

From http://eigenclass.org/hiki.rb?Rename+and+reject+methods+from+included+modules:

Daniel Berger blogged about how to make 'include' a little more flexible by allowing to rename or exclude specific methods.

He proposed the following syntax:
module TFoo
    def method_a
       "hello"
    end
    def method_b
       "world"
    end
end

module TBar
    def method_a
       "goodbye"
    end
    def method_b
       "cruel world"
    end
    def method_y
       "huh?"
    end
end

class MyKlass
    include TFoo,
      :alias   => {:method_a, :method_z},
      :exclude => :method_b

    include TBar
end

m = MyKlass.new
m.method_a                                         # => "goodbye"
m.method_b                                         # => "cruel world"
m.method_y                                         # => "huh?"
m.method_z                                         # => "hello"



Mauricio's implementation follows:

This definition of Class#include should be a fairly safe replacement for the default one since I'm not raising an exception when there's a nameclash (which I rather feel is a bad idea, but I haven't given this much thought), but maybe it could make sense to create a new method with those semantics.

The code:

include_and_rename.rb
class Class
  old_include = instance_method(:include)
  define_method(:include) do |*args|
    default = {:alias => {}, :exclude => []}
    hash_arg = (Hash === args.last) ? default.update(args.pop) : default
    m = Module.new
    args.each{|mod| m.module_eval{ include mod } }
    #                            ^^^^^^^^^^^^^^^
    # check for "method shadowing" here and raise an exception or
    # something if you feel like it
    hash_arg[:alias].each_pair do |old, new|
      m.module_eval{ alias_method(new, old); undef_method(old) }
    end
    excluded = (Array === hash_arg[:exclude]) ? hash_arg[:exclude] : [hash_arg[:exclude]]
    # [*hash_arg[:exclude]] won't work on 1.9 cause there's no Object#to_a
    excluded.each{|meth| m.module_eval { undef_method(meth) } }
    old_include.bind(self).call(m)
  end
end

« Newer Snippets
Older Snippets »
Showing 11-14 of 14 total