Life In The Stack Trace...

TODO: <Insert clever marketing phrase here>

Runnable And Non-Runnable Files

Runnable And Non-Runnable Files

DuckTest automagically runs tests by watching directories and files for changes. You define the files that are watched and ran using directives in a configuration file specific to your environment: test, development, production (BTW, running tests in production is not recommended). All attributes are configured inside a DuckTest.config block.

# config/environments/test.rb  (development.rb, production.rb, etc.)
DuckTest.config do
  runnable "**/*"
  watch "**/*"

Watched files are broken down into two categories: runnable and non-runnable.

  • runnable files are test files such as (Test::Unit, RSpec, etc.) and you define them using {DuckTest::Config#runnable runnable}.
  • non-runnable files are anything except a runnable file and you define them using {DuckTest::Config#watch watch}. Typically, all of the files under the app directory of a Rails application such as models, controllers, view, etc. are non-runnable files The intent is that you can define non-runnable files that are watched and mapped to runnable files that are triggered when non-runnable files are changed.

To understand all of the moving parts, it is important to explain how files are watched. The runnable and watch directives behave in the same manner. In fact, runnable is just a wrapper for the watch method that sets a couple of attributes for you prior to calling the watch method itself. A {DuckTest::FrameWork::WatchConfig} object is created for every runnable and watch directive in a config block and contains all of the attributes you specify within the block: pattern, filters, mappings, paths, etc. Those objects exist for the lifetime of your Rails console session.

During startup, all of the watch config objects are passed to the current {DuckTest::FrameWork::Base framework} object and files are retrieved from the file system by looping thru all of the watch config objects. For each, Dir.glob is called to obtain a set of files as per the patterns you specify and you are allowed to use multiple. Next, the included and excluded filters are applied to each directory and file individually. Directories / files that pass the criteria are added to a "white list" while the ones that fail are added to a "black list".

The purpose of the black and white lists is performance. When a directory / file changes, the black list is searched and if found the directory / file is ignored. A good example of the use of black list would be temporary files created by your editor with the same name that are placed in the same directory as the file you are editing. No sense in running those files. The purpose of the white list is performance as well. If a directory / file is on the white list, then, all of the information is already known, so, we can avoid having to process the file from scratch. New directories / files are processed in the same manner as when the framework session starts, so, all of the same rules apply.