我开始为我正在构建的项目转移到requireJS。我目前正在使用jasminece,rails 3.2和require rails gem。
我试着实现http://ryantownsend.co.uk/post/31662285280/jasminerice-and-requirejs-rails-fix虽然收效甚微,但这些规格根本无法运行。
我开始想,也许我最好单独使用requirejs,或者茉莉花宝石?
我既不喜欢jasminerice,也不需要rails宝石,所以有人对最好的工具有什么建议,以及如何启动和运行它/好的教程有什么建议吗?
好吧,因为我没有得到任何回应,我设法找到了一种稍微有点技巧的方法来实现它。
如果您在视图文件夹jasminice/spec/index.html.erb(或haml)中创建一个文件,并从jasminice gem中复制html。将spec.js调用替换为:
%script{"data-main"=>"/assets/#{@specenv}", src:"/assets/require.js"}
然后像这样写你的规范文件需要模板:
require.config {
paths:{
'jquery':'/assets/jquery'
'underscore': '/assets/underscore-min'
'sinon':'sinon-1.6.0'
'jasmine-sinon':'jasmine-sinon'
'my_js':'my_js'
'my_spec':'my_spec'
}
}
require ['sinon', 'jasmine-sinon', 'jquery', 'underscore', 'my_js', 'my_spec'], () ->
jasmine.getEnv().execute()
这将防止茉莉酸触发测试
jasmine.rice.autoExecute = false
使用类似的beforeFilter设置测试(取自http://kilon.org/blog/2012/08/testing-backbone-requirejs-applications-with-jasmine/)
describe "MySpec", ->
beforeEach ->
flag = false
@thing = ""
that = @
require ['myjs'], (Myjs) ->
flag = true
that.thing = new Myjs()
waitsFor ->
flag
it 'It should exsist', ->
expect(@thing).toBeDefined()
希望这能帮助任何有类似问题的人,如果有人有更好的解决方案,请发帖!:)
我有同样的设置,以下是我所做的(从最初问题中提到的博客文章开始):
1.创建一个助手来加载所有规范文件
在文件lib/jasminerice/spec_helper.rb
中,输入以下代码:
require "requirejs-rails"
module Jasminerice
module SpecHelper
include RequirejsHelper
def spec_files
Rails.application.assets.each_logical_path.select { |lp| lp =~ %r{^spec/.*.js$} }
end
end
end
这将创建一个辅助方法spec_files
,您可以在Jasmierice runner视图中调用该方法来自动获取所有规格,因此您不需要每次添加新规格时都更新规格列表。
2.覆盖默认的Jasmierice索引视图
使用以下内容创建名为app/views/jasminerice/spec/index.html.erb
的视图:
<!doctype html>
<head>
<title>Jasmine Spec Runner</title>
<%= stylesheet_link_tag "jasmine", "spec" %>
<%= requirejs_include_tag 'application' %>
<%= javascript_include_tag "jasminerice", "spec", :debug => true %>
<script>
jasmine.rice.autoExecute = false;
require([<%= spec_files.map { |f| "'#{f.sub(/.js$/,'')}'" }.join(',').html_safe %>],
function() { jasmine.getEnv().execute() },
function(err) {
var failedId = err.requireModules && err.requireModules[0];
requirejs.undef(failedId);
define(failedId, function() { return function() { console.debug(failedId + ': ' + err); null }; });
require([ failedId ], function() {} );
});
</script>
<%= csrf_meta_tags %>
</head>
<body>
</body>
</html>
在运行Jasmine(带有jasmine.getEnv().execute()
)之前,这将需要所有规格。我有一个丑陋的破解方法,使用规范路径数组,生成一个用引号括起来的模块名称数组,然后传递给require
。
我还包含了一个错误回调,以防加载模块时出现问题——如果不这样做,当模块加载失败时,您的规范将挂起。当你通过guard-jasmine
在命令行上运行它们时,这尤其是一个问题,我就是这么做的
不幸的是,我还没有找到一个很好的方法来处理这些错误——在这里,我向console.debug
写入了一些信息,然后要求使用失败的模块,并在其位置返回一个匿名函数。这允许规范运行,但会产生不可预测的结果(总比没有结果好)。我一直在努力寻找更好的方法来处理这种情况,建议将不胜感激。
3.编写一些规范
我的Jasmine眼镜采用以下形式:
define (require) ->
MyModule = require 'my-module'
# any other dependencies needed to test
describe 'MyModule', ->
it 'exists', ->
expect(MyModule).toBeDefined()
等等。请注意,我在spec.js.coffee
:中加载的所有测试依赖项(jasmine、sinon、jasmine sinon等)都超出了require
#=require sinon
#=require jasmine-sinon
#=require_tree ./helpers/
我把我需要的任何其他助手函数放在helpers
目录中。
4.奖金
另一个提示:如果你有问题,因为你的浏览器即使在模块更改时也不会重新加载模块,我会使用添加一个带有时间戳的伪参数的技巧,这样浏览器就会始终看到一个新文件并正确加载它。
我在ApplicationController
中创建了这个函数,并将其加载到前过滤器中:
before_filter :set_requirejs_config
def set_requirejs_config
opts = { :urlArgs => "bust=#{Time.now.to_i}" }) if Rails.env == "development"
Requirejs::Rails::Engine.config.requirejs.run_config.merge!(opts)
end
如果我们处于开发模式,这会在每个模块名称的末尾添加一个查询参数bust=...
,以便我们始终重新加载模块并获得最新版本。SO上有一篇文章解释了如何在RequireJS中做到这一点,但要让它与RequireJS rails一起工作,你必须将它放入ApplicationController(而不是config/requirejs.yml
)中,这样每次加载页面时都会加载它。
希望这能为其他使用此配置的人提供一些提示!