Search code examples
ruby-on-railsrubyrcov

How does one collect rcov-style information on the processing of erb templates?


I'm using rcov on a set of tests autogenerated from my rails routes to collect information on dead code (code which is never called in the application). This set up already generates enlightening results for controllers, models, helpers, and lib code. Unfortunately rcov does not track code coverage in erb templates, which makes sense as erb templating is a pretty challenging stretch on the normal concept of execution.

Rails itself can generate good reports on where in templates exceptions are raised and the like, so I feel like this is data that can be harvested.

I'm currently trying to find points in rcov that I can hook onto, but the Ouroboros nature of the system is making it difficult to see what is happening clearly. I also suspect that some amount of monkeypatching of ERB will be necessary.

If you have any ideas for approaches or solutions, I would appreciate it. Once I get the view functionality set up, I'm cleaning up this code and releasing it as an open source Rails plugin.


Solution

  • I only actually absolutely need the view filenames as in most cases they will be executed in their entirety. My purpose is mainly to identify unused partials or templates. The following code outputs these to the screen.

    module DeadCodeDetector                                                          
      module Template
        def set_extension_and_file_name_with_recording(use_full_path)                
          r = set_extension_and_file_name_without_recording(use_full_path)           
          puts "Included Template"
          puts filename
          puts "End Include"                                                         
          puts
          r                                                                          
        end                                                                          
    
        def self.included(base)
          base.class_eval do                                                         
            alias_method_chain :set_extension_and_file_name, :recording              
          end                                                                        
        end                                                                          
      end                                                                            
    end
    
    ActionView::Template.send(:include, DeadCodeDetector::Template)