Re: Automatic functional testing for ajax?

Michael Schuerig
Sun, 18 Sep 2005 09:45:45 -0000

On Friday 16 September 2005 02:56, Michael Schuerig wrote:

> (3) Render all views and collect the [ajax] methods.

> The catch is (3). What I don''t yet see is how to more or less
neuter
> everything apart from the methods I''m interested in. In a tool, I
> can''t provide the same environment for the views that they get
when
> rendered from a controller. Rampant use of method_missing and
> const_missing come to mind, still I doubt this is enough.

The first steps proved easier than expected. My main aim is to check the
ajaxian helper methods I''m using in BoilerPlate. The code below does
this for two methods. Right now it doesn''t do anymore than simply
listing the ajax actions required to support the views. I don''t think
tests can be generated from this automatically, but from the list it is
pretty easy to write tests for the respective actions anyway. Also, the
code is imperfect, it gets thrown off its tracks easily. As all the
stubbed method calls return nil, e.g., operators expecting some other
type will raise an exception.

Michael


require ''erb''
require ''active_support''


class NilClass
  def method_missing(method, *args)
  end
end

class Sandbox
  def initialize(checker)
    @checker = checker
  end

  def _sandbox_binding
    binding
  end

  def method_missing(method, *args)
  end

  def self.const_missing(const)
  end

  def association_target_chooser_widget(object_name, association_name,
options = {}, chooser_options = {})
    controller = chooser_options[:controller]  || association_name.to_s
    action     = chooser_options[:ajax_action] ||
"#{association_name}_candidates"
    @checker.collect_ajax_action(controller, action)
  end

  def tree_navigator_widget(object_name, association_name, options = {},
navigator_options = {})
    controller = navigator_options[:controller]  ||
association_name.to_s
    action     = navigator_options[:ajax_action] ||
"child_#{Inflector.pluralize(association_name)}"
    @checker.collect_ajax_action(controller, action)
  end
end


class Checker
  def initialize
    @ajax_actions = Hash.new([])
  end

  def collect_ajax_actions
    ARGV.each do |view_file|
      begin
        @current_view = view_file
        ERB.new(File.read(view_file), nil,
''-'').result(sandbox_binding)
#      rescue
#        $stderr.puts "Error while looking for calls in #{view_file}:
#{$!}"
      end
    end
  end

  def collect_ajax_action(controller, action)
    ca = [ controller.to_s, action.to_s ]
    @ajax_actions[ca] = @ajax_actions[ca] + [ @current_view ]
  end

  def check_ajax_actions
    @ajax_actions.each do |ca, views|
      controller, action = ca
      puts "CHECKING #{controller}/#{action}: #{views.inspect}"

    end
  end

  def check
    collect_ajax_actions
    check_ajax_actions
  end

  def self.check
    Checker.new.check
  end

  def sandbox_binding
    Sandbox.new(self)._sandbox_binding
  end
end

Checker.check


--
Michael Schuerig                             Those who call the shots
mailto:michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org              Are never in
the line of fire
http://www.schuerig.de/michael/           --Ani DiFranco, Not So Soft