Skip to content

Instantly share code, notes, and snippets.

@peterwmwong
Created November 14, 2012 14:34
Show Gist options
  • Save peterwmwong/4072459 to your computer and use it in GitHub Desktop.
Save peterwmwong/4072459 to your computer and use it in GitHub Desktop.
require.js spec plugin
define (require)->
_ = require 'underscore'
modulesConfigString =
"""
require.config({
baseUrl:'src',
paths: {
'backbone-validation': '../node_modules/backbone-validation/dist/backbone-validation-amd',
cell: '../vendor/cell',
backbone: '../node_modules/backbone/backbone',
jquery: '../vendor/jquery/jquery',
'jquery.event.drag': '../vendor/jquery.event.drag',
slickcore: '../vendor/SlickGrid/slick.core',
slickgrid: '../vendor/SlickGrid/slick.grid',
// underscore: '../vendor/lodash.custom',
underscore: '../node_modules/underscore/underscore'
},
shim: {
'backbone': {
'deps': ['underscore', 'jquery'],
'exports': 'Backbone' //attaches 'Backbone' to the window object
},
'jquery.event.drag': {
'deps': ['jquery'],
'exports': '$'
},
'slickcore': {
'deps': ['jquery'],
'exports': 'Slick'
},
'slickgrid': {
'deps': ['slickcore','jquery.event.drag'],
'exports': 'Slick'
},
'underscore': {
'deps': ['jquery'],
'exports': '_'
}
}
});
"""
# The require configuration for the application and will be used to create
# the require for the test. See @createSpecRequire.
# This is to ensure that we have the same configuration in the application
# and the test environment.
modulesConfig = undefined
(new Function 'require', modulesConfigString)
config: (cfg)-> modulesConfig = cfg
modulesConfig.baseUrl = '/src/'
# Create a seperate require to isolate the module being tested
createSpecRequire = (specRequireName)->
contextConfig = _.extend modulesConfig, context: specRequireName
window.require.config contextConfig
# Inject a module into a require context
# This is used to mock modules that are dependencies of the module
# being tested
injectModuleIntoRequireContext = (requireCtx, mockModuleName, mockModule)->
mod_map = requireCtx.makeModuleMap mockModuleName, null, true
(requireCtx.registry[mockModuleName] = new requireCtx.Module mod_map).init [],
-> mockModule
undefined
{enabled: true}
load: (name, specRunnerRequire, load, config)->
# Load Spec Module
specRunnerRequire ["#{name}.spec"], ({spec:Spec})-> load ->
describe name, ->
specRequireCtx = undefined
beforeEach ->
# Loads the module being tested in an isolated require.
# Each spec should call this in a beforeEach() to
# 1) load module being tested
# 2) mock any dependencies that module being tested might have
#
# Example:
# # MyModule.spec.coffee
# define spec: ->
#
# beforeEach ->
#
# # Dependencies of MyModule
# mocks =
# 'deps/Dep1': 'Mock Dep1'
# 'deps/Dep2': 'Mock Dep2'
#
# @loadModule mocks, (module,specRequire)->
# @MyModule = module
#
# it 'is defined', ->
# expect(@MyModule?).toBe true
#
# If mocksHash is supplied, each module is mocked as the key is
# used as module id and the value is the mock module.
#
# @param mocksHash? object Hash of modules to be mocked (module id -> mock module)
# @param cb(module,require) function Called when test module is loaded
@load_module = (mocksHash,cb)->
if not cb? and _.isFunction mocksHash
cb = mocksHash
mocksHash = undefined
throw "Could not load spec for #{name}" if not _.isFunction cb
# Remove all modules loaded from context
$("[data-requirecontext='#{specRequireCtx.contextName}']").remove() if specRequireCtx
# Create a new require context for each spec describe/it
specRequireName = _.uniqueId 'specRequire'
specRequire = createSpecRequire specRequireName
specRequireCtx = window.require.s.contexts[specRequireName]
if mocksHash
_.each mocksHash, (mockModule, mockModuleName)->
injectModuleIntoRequireContext specRequireCtx, mockModuleName, mockModule
module = undefined
# Asynchronously load the module being tested
runs -> specRequire [name], (m)-> module = m
# Waaaiiiit for it
waitsFor (-> module?), "'#{name}' Module to load", 500
# Call the callback and pass the module and spec require
runs -> cb.call this, module, specRequire
# Run Spec
Spec()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment