'use strict';

module.exports = {

    /**
     * Wrapper to easily create unit tests that test Selectivity within a DOM environment.
     *
     * @param modules Array of Selectivity modules to test, e.g. ['base', 'single'].
     * @param options Optional options object. May contain the following properties:
     *                indexResource - Filename of the index resource (default: 'testcase.html').
     *                async - Set to true to indicate the test function is asynchronous and calls
     *                        done() itself.
     * @param fn The actual test function. Receives two arguments:
     *           test - The nodeunit test instance.
     *           $input - jQuery container for the '#selectivity-input' element defined in
     *                    resources/testcase.html.
     */
    createDomTest: function(modules, options, fn) {

        if (options instanceof Function) {
            fn = options;
            options = {};
        }

        var indexResource = options.indexResource || 'testcase.html';

        return function(test) {
            require('jsdom').env('tests/resources/' + indexResource, function(errors, window) {
                test.strictEqual(errors, null);

                test.doesNotThrow(function() {
                    var $ = require('../vendor/jquery')(window);
                    var proxyquire = require('proxyquire').noCallThru();

                    var EventDelegator = proxyquire('../src/event-delegator', { 'jquery': $ });

                    var stubs = { 'jquery': $, './event-delegator': EventDelegator };
                    proxyquire('../src/selectivity-base', stubs);

                    // I wish this could be solved without hard-coding the dependenies here...
                    var dependencies = {
                        'ajax': ['base', 'locale'],
                        'async': ['base'],
                        'base': [],
                        'diacritics': ['base'],
                        'dropdown': ['base'],
                        'email': ['base', 'multiple'],
                        'keyboard': ['base'],
                        'locale': ['base'],
                        'multiple': ['base'],
                        'single': ['base'],
                        'submenu': ['base', 'dropdown'],
                        'templates': ['base', 'locale'],
                        'tokenizer': ['base'],
                        'traditional': ['base']
                    };

                    var orderedModules = [];

                    function insertDependencies(module) {
                        if (dependencies[module]) {
                            dependencies[module].forEach(function(dependency) {
                                insertDependencies(dependency);
                                if (orderedModules.indexOf(dependency) === -1) {
                                    orderedModules.push(dependency);
                                }
                            });
                            if (orderedModules.indexOf(module) === -1) {
                                orderedModules.push(module);
                            }
                        } else {
                            throw new Error('Dependencies for module ' + module + ' not specified');
                        }
                    }

                    modules.forEach(insertDependencies);

                    orderedModules.forEach(function(module) {
                        var selectivityModule = proxyquire('../src/selectivity-' + module, stubs);
                        stubs['./selectivity-' + module] = selectivityModule;
                    });

                    fn(test, window.$('#selectivity-input'), $);
                });

                if (!options.async) {
                    test.done();
                }
            });
        };
    }

};

@@ -8,16 +8,79 @@
 rict';%0A%0A
+var freshy = require('freshy');%0Avar jsdom = require('jsdom');%0A%0A
 module.e
@@ -664,10 +664,12 @@
 es t
-wo
+hree
  arg
@@ -870,16 +870,54 @@
 e.html.%0A
+     *           $ - jQuery instance.%0A
      */%0A
@@ -1194,29 +1194,42 @@
     
-require('
 jsdom
-')
 .env(
+%7B%0A                file: 
 'tes
@@ -1263,521 +1263,105 @@
 rce,
- function(errors, window) %7B%0A                test.strictEqual(errors, null);%0A%0A                test.doesNotThrow(function() %7B%0A                    var $ = require('../vendor/jquery')(window);%0A                    var proxyquire = require('proxyquire').noCallThru();%0A%0A                    var EventDelegator = proxyquire('../src/event-delegator', %7B 'jquery': $ %7D);%0A%0A                    var stubs = %7B 'jquery': $, './event-delegator': EventDelegator %7D;%0A                    proxyquire('../src/selectivity-base', stubs
+%0A                onload: function(window) %7B%0A                    var done = test.done.bind(test
 );%0A
-%0A
     
@@ -1380,744 +1380,72 @@
     
-// I wish this could be solved without hard-coding the dependenies here...%0A                    var dependencies = %7B%0A                        'ajax': %5B'base', 'locale'%5D,%0A                        'async': %5B'base'%5D,%0A                        'base': %5B%5D,%0A                        'diacritics': %5B'base'%5D,%0A                        'dropdown': %5B'base'%5D,%0A                        'email': %5B'base', 'multiple'%5D,%0A                        'keyboard': %5B'base'%5D,%0A                        'locale': %5B'base'%5D,%0A                        'multiple': %5B'base'%5D,%0A                        'single': %5B'base'%5D,%0A                        'submenu': %5B'base', 'dropdown'%5D,%0A                        'templates': %5B'base', 'locale'%5D,%0A                        'tokenizer': %5B'base'%5D,
+test.done = function() %7B%0A                        window.close();
 %0A   
@@ -1469,31 +1469,15 @@
     
-'traditional': %5B'base'%5D
+done();
 %0A   
@@ -1521,827 +1521,211 @@
     
-var orderedModules = %5B%5D;%0A%0A                    function insertDependencies(module) %7B%0A                        if (dependencies%5Bmodule%5D) %7B%0A                            dependencies%5Bmodule%5D.forEach(function(dependency) %7B%0A                                insertDependencies(dependency);%0A                                if (orderedModules.indexOf(dependency) === -1) %7B%0A                                    orderedModules.push(dependency);%0A                                %7D%0A                            %7D);%0A                            if (orderedModules.indexOf(module) === -1) %7B%0A                                orderedModules.push(module);%0A                            %7D%0A                        %7D else %7B%0A                            throw new Error('Dependencies for module ' + module + ' not specified');%0A                        %7D
+global.document = window.document;%0A                    global.window = window;%0A%0A                    window.$ = window.jQuery = freshy.reload('jquery');%0A%0A                    test.doesNotThrow(function() %7B
 %0A   
@@ -1745,69 +1745,54 @@
     
-%7D%0A%0A
     
-                modules.forEach(insertDependencies
+freshy.reload('../src/selectivity-base'
 );%0A
-%0A
     
@@ -1811,16 +1811,13 @@
     
-orderedM
+    m
 odul
@@ -1874,42 +1874,25 @@
     
-var selectivityModule = proxyquire
+    freshy.reload
 ('..
@@ -1922,15 +1922,8 @@
 dule
-, stubs
 );%0A 
@@ -1949,87 +1949,17 @@
     
-stubs%5B'./selectivity-' + module%5D = selectivityModule;%0A                    
 %7D);%0A%0A
+    
     
@@ -2015,16 +2015,23 @@
 nput'), 
+window.
 $);%0A    
@@ -2034,37 +2034,45 @@
                 
+    
 %7D);%0A%0A
+    
                 
@@ -2105,32 +2105,36 @@
                 
+    
 test.done();%0A   
@@ -2122,32 +2122,54 @@
    test.done();%0A
+                    %7D%0A
                 

Simplify DomUtil.