Merge branch 'master' of git://github.com/johnbintz/jasmine-headless-webkit

This commit is contained in:
hysios hu 2012-09-20 13:32:10 +08:00
commit d462bd11b1
33 changed files with 449 additions and 151 deletions

1
.gitignore vendored
View File

@ -16,3 +16,4 @@ _site/
jhw.*.html jhw.*.html
coverage/ coverage/
tmp/ tmp/
cache dir/

View File

@ -15,7 +15,6 @@ gem 'guard-cucumber'
require 'rbconfig' require 'rbconfig'
case RbConfig::CONFIG['host_os'] case RbConfig::CONFIG['host_os']
when /darwin/ when /darwin/
gem 'rb-fsevent'
when /linux/ when /linux/
gem 'libnotify' gem 'libnotify'
end end

View File

@ -1,3 +1,5 @@
_I am looking for a new maintainer for this project. Please contact me via GitHub if you're interested._
# Jasmine Headless WebKit runner # Jasmine Headless WebKit runner
Run your specs at sonic boom speed! No pesky reload button or page rendering slowdowns! Run your specs at sonic boom speed! No pesky reload button or page rendering slowdowns!

View File

@ -14,7 +14,7 @@ require 'jasmine/headless/task'
Jasmine::Headless::Task.new Jasmine::Headless::Task.new
PLATFORMS = %w{1.8.7 1.9.2 ree 1.9.3} PLATFORMS = %w{1.9.2 1.9.3}
def rvm_bundle(command = '') def rvm_bundle(command = '')
Bundler.with_clean_env do Bundler.with_clean_env do

2
config/cucumber.yml Normal file
View File

@ -0,0 +1,2 @@
default: -r features

View File

@ -71,7 +71,9 @@ void Runner::loadSpec()
outputFiles.enqueue(outputFile); outputFiles.enqueue(outputFile);
} }
page.mainFrame()->load(QUrl::fromLocalFile(runnerFiles.dequeue())); QString runnerFile = runnerFiles.dequeue();
page.mainFrame()->load(runnerFile);
ticker.start(); ticker.start();
} }

View File

@ -7,7 +7,9 @@
#include <QTextStream> #include <QTextStream>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <sstream>
#include <QQueue> #include <QQueue>
#include <QApplication>
#include "Page.h" #include "Page.h"

View File

@ -1,7 +1,6 @@
TEMPLATE = app TEMPLATE = app
CONFIG -= app_bundle CONFIG -= app_bundle
QMAKE_INFO_PLIST = Info.plist QMAKE_INFO_PLIST = Info.plist
QMAKESPEC = macx-g++
QT += network webkit QT += network webkit
SOURCES = Page.cpp Runner.cpp SOURCES = Page.cpp Runner.cpp

View File

@ -1,19 +0,0 @@
######################################################################
# Automatically generated by qmake (2.01a) Tue Aug 2 10:37:48 2011
######################################################################
TEMPLATE = app
TARGET =
DEPENDPATH += . HeadlessSpecRunner Test
INCLUDEPATH += . HeadlessSpecRunner Test
# Input
HEADERS += HeadlessSpecRunner/ConsoleOutput.h \
HeadlessSpecRunner/Page.h \
HeadlessSpecRunner/Runner.h \
Test/Page_test.h
SOURCES += specrunner.cpp \
HeadlessSpecRunner/ConsoleOutput.cpp \
HeadlessSpecRunner/Page.cpp \
HeadlessSpecRunner/Runner.cpp \
Test/Page_test.cpp

View File

@ -0,0 +1,11 @@
Feature: Two files from source files
Scenario: Files are ordered directly
Given I have a test suite
When I run `bin/jasmine-headless-webkit -j spec/jasmine/two_files_from_src_files/jasmine.yml -l`
Then the exit status should be 0
And the following files should be loaded in order:
| vendor/vendor-file.js |
| vendor/vendor.js |
| app/app-file.js |
| app/app.js |

View File

@ -0,0 +1,7 @@
Feature: Bin - With Server
Scenario: Run using an HTTP server
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit --use-server -j spec/jasmine/success/success.yml -f File:spec/report.txt`
Then the exit status should be 0
And the report file "spec/report.txt" should have 1 total, 0 failures, no console usage

View File

@ -0,0 +1,10 @@
Then /^the following files should be loaded in order:$/ do |table|
files = table.raw.flatten
@output.lines.collect(&:strip).each do |line|
files.shift if line[files.first]
end
files.should be_empty
end

View File

@ -20,9 +20,11 @@ Gem::Specification.new do |s|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"] s.require_paths = ["lib"]
s.add_runtime_dependency 'jasmine-core', '~> 1.1' s.add_runtime_dependency 'jasmine-core'
s.add_runtime_dependency 'coffee-script' s.add_runtime_dependency 'coffee-script'
s.add_runtime_dependency 'rainbow' s.add_runtime_dependency 'rainbow'
s.add_runtime_dependency 'multi_json' s.add_runtime_dependency 'multi_json', '>= 1.2.0'
s.add_runtime_dependency 'sprockets', '~> 2' s.add_runtime_dependency 'sprockets'
s.add_runtime_dependency 'sprockets-vendor_gems'
end end

View File

@ -54,7 +54,11 @@ module Jasmine::Headless
end end
def cache_file def cache_file
@cache_file ||= File.expand_path(File.join(self.class.cache_dir, self.class.cache_type, file)) + '.js' @cache_file ||= File.expand_path(relative_cache_file) + '.js'
end
def relative_cache_file
File.join(self.class.cache_dir, self.class.cache_type, file.gsub(Dir.pwd + '/', ''))
end end
def fresh? def fresh?

View File

@ -4,6 +4,7 @@ require 'multi_json'
require 'set' require 'set'
require 'sprockets' require 'sprockets'
require 'sprockets/engines' require 'sprockets/engines'
require 'sprockets-vendor_gems'
module Jasmine::Headless module Jasmine::Headless
class FilesList class FilesList
@ -11,33 +12,12 @@ module Jasmine::Headless
class << self class << self
def asset_paths def asset_paths
return @asset_paths if @asset_paths @asset_paths ||= Sprockets.find_gem_vendor_paths(:for => 'javascripts')
require 'rubygems'
raise StandardError.new("A newer version of Rubygems is required to use vendored assets. Please upgrade.") if !Gem::Specification.respond_to?(:each)
@asset_paths = []
Gem::Specification.each { |gemspec| @asset_paths += get_paths_from_gemspec(gemspec) }
@asset_paths
end
def get_paths_from_gemspec(gemspec)
%w{vendor lib app}.collect do |dir|
path = File.join(gemspec.gem_dir, dir, "assets/javascripts")
if File.directory?(path) && !@asset_paths.include?(path)
path
else
nil
end
end.compact
end end
def reset! def reset!
@asset_paths = nil @asset_paths = nil
@registered_engines = {}
# register haml-sprockets and handlebars_assets if it's available... # register haml-sprockets and handlebars_assets if it's available...
%w{haml-sprockets handlebars_assets}.each do |library| %w{haml-sprockets handlebars_assets}.each do |library|
@ -56,16 +36,20 @@ module Jasmine::Headless
end end
end end
# ...and unregister ones we don't want/need @sprockets_environment = nil
Sprockets.instance_eval do end
EXCLUDED_FORMATS.each do |extension|
register_engine ".#{extension}", Jasmine::Headless::NilTemplate
end
register_engine '.coffee', Jasmine::Headless::CoffeeTemplate def registered_engines
register_engine '.js', Jasmine::Headless::JSTemplate @registered_engines ||= {}
register_engine '.css', Jasmine::Headless::CSSTemplate end
register_engine '.jst', Jasmine::Headless::JSTTemplate
def register_engine(file_extension, template_class)
registered_engines[file_extension] = template_class
end
def register_engines!
registered_engines.each do |file_extension, template_class|
Sprockets.register_engine file_extension, template_class
end end
end end
@ -95,11 +79,21 @@ module Jasmine::Headless
@required_files = UniqueAssetList.new @required_files = UniqueAssetList.new
@potential_files_to_filter = [] @potential_files_to_filter = []
register_engines!
load_initial_assets load_initial_assets
use_config if config? use_config if config?
end end
def register_engines!
begin
require spec_helper
rescue LoadError
end
self.class.register_engines!
end
def load_initial_assets def load_initial_assets
self.class.default_files.each do |file| self.class.default_files.each do |file|
begin begin
@ -137,6 +131,7 @@ module Jasmine::Headless
@search_paths += asset_paths.collect { |dir| File.expand_path(dir) } @search_paths += asset_paths.collect { |dir| File.expand_path(dir) }
@search_paths += spec_dir.collect { |dir| File.expand_path(dir) } @search_paths += spec_dir.collect { |dir| File.expand_path(dir) }
@search_paths.uniq!
@search_paths @search_paths
end end
@ -147,6 +142,19 @@ module Jasmine::Headless
search_paths.each { |path| @sprockets_environment.append_path(path) } search_paths.each { |path| @sprockets_environment.append_path(path) }
@sprockets_environment.unregister_postprocessor('application/javascript', Sprockets::SafetyColons) @sprockets_environment.unregister_postprocessor('application/javascript', Sprockets::SafetyColons)
# ...and unregister ones we don't want/need
@sprockets_environment.instance_eval do
EXCLUDED_FORMATS.each do |extension|
register_engine ".#{extension}", Jasmine::Headless::NilTemplate
end
register_engine '.coffee', Jasmine::Headless::CoffeeTemplate
register_engine '.js', Jasmine::Headless::JSTemplate
register_engine '.css', Jasmine::Headless::CSSTemplate
register_engine '.jst', Jasmine::Headless::JSTTemplate
end
@sprockets_environment @sprockets_environment
end end
@ -227,13 +235,13 @@ module Jasmine::Headless
end end
def add_files(patterns, type, dirs) def add_files(patterns, type, dirs)
dirs.product(patterns).each do |search| patterns.each do |pattern|
files = expanded_dir(File.join(*search)) dirs.collect { |dir| expanded_dir(File.join(dir, pattern)) }.each do |files|
files.sort! { |a, b| Kernel.rand(3) - 1 } if type == 'spec_files'
files.sort! { |a, b| Kernel.rand(3) - 1 } if type == 'spec_files' files.each do |path|
add_path(path, type)
files.each do |path| end
add_path(path, type)
end end
end end
@ -247,7 +255,8 @@ module Jasmine::Headless
end end
def expanded_dir(path) def expanded_dir(path)
Dir[path].find_all { |file| file_list = Dir.glob(path).sort
file_list.find_all { |file|
file[extension_filter] && !alert_if_bad_format?(file) file[extension_filter] && !alert_if_bad_format?(file)
}.collect { }.collect {
|file| File.expand_path(file) |file| File.expand_path(file)
@ -271,7 +280,7 @@ module Jasmine::Headless
end end
def src_dir def src_dir
@src_dir ||= config_dir_or_pwd('src_dir') @src_dir ||= config_dir_or_pwd('src_dir') + asset_paths
end end
def spec_dir def spec_dir
@ -279,7 +288,7 @@ module Jasmine::Headless
end end
def asset_paths def asset_paths
@asset_paths ||= config_dir_or_pwd('asset_paths') @asset_paths ||= config_dir('asset_paths')
end end
def spec_file_searches def spec_file_searches
@ -287,9 +296,15 @@ module Jasmine::Headless
end end
def config_dir_or_pwd(dir) def config_dir_or_pwd(dir)
found_dir = (@options[:config] && @options[:config][dir]) || Dir.pwd if (found = config_dir(dir)).empty?
found = [ Dir.pwd ]
end
[ found_dir ].flatten.collect { |dir| File.expand_path(dir) } found
end
def config_dir(dir)
[ @options[:config] && @options[:config][dir] ].flatten.compact.collect { |dir| File.expand_path(dir) }
end end
def filter_for_requested_specs(files) def filter_for_requested_specs(files)
@ -301,5 +316,17 @@ module Jasmine::Headless
end end
end end
end end
def spec_helper
File.join(spec_dir, "helpers", "spec_helper")
end
end
end
module Jasmine::Headless
extend self
def register_engine(file_extension, template_class)
Jasmine::Headless::FilesList.register_engine(file_extension, template_class)
end end
end end

View File

@ -18,7 +18,9 @@ module Jasmine
:enable_cache => true, :enable_cache => true,
:files => [], :files => [],
:reporters => [ [ 'Console' ] ], :reporters => [ [ 'Console' ] ],
:quiet => false :quiet => false,
:use_server => false,
:server_port => nil
} }
DEFAULTS_FILE = File.join(Dir.pwd, '.jasmine-headless-webkit') DEFAULTS_FILE = File.join(Dir.pwd, '.jasmine-headless-webkit')
@ -75,6 +77,10 @@ module Jasmine
@options[:seed] = arg.to_i @options[:seed] = arg.to_i
when '--format', '-f' when '--format', '-f'
add_reporter(arg) add_reporter(arg)
when '--use-server'
@options[:use_server] = true
when '--server-port'
@options[:server_port] = arg.to_i
when '--out' when '--out'
add_reporter_file(arg) add_reporter_file(arg)
when '-h', '--help' when '-h', '--help'
@ -107,6 +113,8 @@ module Jasmine
[ '--seed', GetoptLong::REQUIRED_ARGUMENT ], [ '--seed', GetoptLong::REQUIRED_ARGUMENT ],
[ '--format', '-f', GetoptLong::REQUIRED_ARGUMENT ], [ '--format', '-f', GetoptLong::REQUIRED_ARGUMENT ],
[ '--out', GetoptLong::REQUIRED_ARGUMENT ], [ '--out', GetoptLong::REQUIRED_ARGUMENT ],
[ '--use-server', GetoptLong::NO_ARGUMENT ],
[ '--server-port', GetoptLong::REQUIRED_ARGUMENT ],
[ '-h', '--help', GetoptLong::NO_ARGUMENT ], [ '-h', '--help', GetoptLong::NO_ARGUMENT ],
[ '-q', '--quiet', GetoptLong::NO_ARGUMENT ] [ '-q', '--quiet', GetoptLong::NO_ARGUMENT ]
) )
@ -165,8 +173,9 @@ module Jasmine
[ '--runner-out <filename>', 'Write runner to specified filename' ], [ '--runner-out <filename>', 'Write runner to specified filename' ],
[ '-j, --jasmine-config <config file>', 'Jasmine Yaml config to use' ], [ '-j, --jasmine-config <config file>', 'Jasmine Yaml config to use' ],
[ '--no-full-run', 'Do not perform a full spec run after a successful targeted spec run' ], [ '--no-full-run', 'Do not perform a full spec run after a successful targeted spec run' ],
[ '--use-server', 'Load tests from an HTTP server instead of from filesystem' ],
[ '-l, --list', 'List files in the order they will be required' ], [ '-l, --list', 'List files in the order they will be required' ],
[ '--seed', 'Random order seed for spec file ordering' ], [ '--seed <seed>', 'Random order seed for spec file ordering' ],
[ '-f, --format <reporter<:filename>>', 'Specify an output reporter and possibly output filename' ], [ '-f, --format <reporter<:filename>>', 'Specify an output reporter and possibly output filename' ],
[ '--out <filename>', 'Specify output filename for last defined reporter' ], [ '--out <filename>', 'Specify output filename for last defined reporter' ],
[ '-q, --quiet', "Silence most non-test related warnings" ], [ '-q, --quiet', "Silence most non-test related warnings" ],

View File

@ -7,9 +7,26 @@ require 'yaml'
require 'erb' require 'erb'
require 'sprockets' require 'sprockets'
module Jasmine module Jasmine
module Headless module Headless
class IndexHandler
class << self
attr_accessor :index
end
def initialize(app)
@app = app
end
def call(env)
if env['PATH_INFO'] == '/'
return [ 302, { 'Location' => self.class.index }, [ 'Redirecting...' ] ]
end
@app.call(env)
end
end
class Runner class Runner
JASMINE_DEFAULTS = { JASMINE_DEFAULTS = {
'spec_files' => [ '**/*[sS]pec.js' ], 'spec_files' => [ '**/*[sS]pec.js' ],
@ -26,9 +43,103 @@ module Jasmine
attr_reader :options attr_reader :options
class << self def self.run(options = {})
def run(options = {}) new(options).run
new(options).run end
def self.server_port
return @server_port if @server_port
require 'socket'
count = 100
begin
port = select_server_port
socket = TCPSocket.new(server_interface, port)
socket.close
count -= 1
raise "Could not create server port after 100 attempts!" if count == 0
rescue Errno::ECONNREFUSED
@server_port = port
break
ensure
begin
socket.close if socket
rescue IOError
end
end while true
@server_port
end
def self.server_port=(port)
@server_port = port
end
def self.select_server_port
21000 + rand(10000)
end
def self.server_interface
'127.0.0.1'
end
def self.server_uri
"http://#{server_interface}:#{server_port}"
end
def self.server_spec_path
self.server_uri + '/__JHW__/'
end
def self.ensure_server(options)
return if @server
require 'webrick'
require 'thread'
require 'rack'
require 'net/http'
port = server_port
@server = Thread.new do
Jasmine::Headless.warn "Powering up!"
app = Rack::Builder.new do
use IndexHandler
map '/__JHW__' do
run Rack::File.new(Dir.pwd)
end
map '/' do
run Rack::File.new('/')
end
end
Rack::Handler::WEBrick.run(
app,
:Port => port,
:Logger => Logger.new(StringIO.new),
:AccessLog => [
[ StringIO.new, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
[ StringIO.new, WEBrick::AccessLog::REFERER_LOG_FORMAT ]
]
)
end
while true do
begin
Net::HTTP.get(URI(server_uri))
break
rescue Errno::ECONNREFUSED => e
end
sleep 0.1
end end
end end
@ -63,8 +174,7 @@ module Jasmine
command << "-r #{file}" command << "-r #{file}"
end end
command += targets.flatten.collect { |target| File.expand_path(target) } command += targets
command.compact.join(' ') command.compact.join(' ')
end end
@ -73,9 +183,11 @@ module Jasmine
Jasmine::Headless.show_warnings = !@options[:quiet] Jasmine::Headless.show_warnings = !@options[:quiet]
FilesList.reset! FilesList.reset!
self.class.server_port = options[:server_port]
@_targets = template_writer.write @_targets = template_writer.write
run_targets = @_targets.dup run_targets = absolute_run_targets(@_targets.dup)
if run_targets.length == 2 if run_targets.length == 2
if (!@options[:full_run] && files_list.filtered?) || files_list.has_spec_outside_scope? if (!@options[:full_run] && files_list.filtered?) || files_list.has_spec_outside_scope?
@ -83,7 +195,13 @@ module Jasmine
end end
end end
system jasmine_command(run_targets) runner = lambda { system jasmine_command(run_targets) }
if options[:use_server]
wrap_in_server(run_targets, &runner)
else
runner.call
end
@_status = $?.exitstatus @_status = $?.exitstatus
ensure ensure
@ -92,6 +210,17 @@ module Jasmine
end end
end end
def absolute_run_targets(targets)
targets.flatten.collect do |target|
if options[:use_server]
target = self.class.server_spec_path + target
else
target = "file://" + File.expand_path(target)
end
target
end
end
def runner_filename def runner_filename
options[:runner_output_filename] || begin options[:runner_output_filename] || begin
if (runner_output = jasmine_config['runner_output']) && !runner_output.empty? if (runner_output = jasmine_config['runner_output']) && !runner_output.empty?
@ -111,6 +240,15 @@ module Jasmine
) )
end end
def wrap_in_server(run_targets)
self.class.ensure_server(options)
IndexHandler.index = run_targets.last
Jasmine::Headless.warn "HTTP powered specs! Located at #{run_targets.join(' ')}"
yield
end
private private
def jasmine_config_data def jasmine_config_data
raise JasmineConfigNotFound.new("Jasmine config not found. I tried #{@options[:jasmine_config]}.") if !File.file?(@options[:jasmine_config]) raise JasmineConfigNotFound.new("Jasmine config not found. I tried #{@options[:jasmine_config]}.") if !File.file?(@options[:jasmine_config])

View File

@ -33,11 +33,11 @@ module Jasmine::Headless
end end
def serialize(data) def serialize(data)
MultiJson.encode(data) MultiJson.dump(data)
end end
def unserialize(data) def unserialize(data)
MultiJson.decode(data) MultiJson.load(data)
end end
end end
end end

View File

@ -24,7 +24,9 @@ module Jasmine::Headless
output.unshift([filtered_tests_filename, files_list.filtered_files_to_html ]) if files_list.filtered? output.unshift([filtered_tests_filename, files_list.filtered_files_to_html ]) if files_list.filtered?
output.each do |name, files| output.each do |name, files|
File.open(name, 'w') { |fh| fh.print template_for(files) } template = template_for(files)
File.open(name, 'wb') { |fh| fh.print template }
end end
output.collect(&:first) output.collect(&:first)

View File

@ -1,5 +1,5 @@
module Jasmine module Jasmine
module Headless module Headless
VERSION = "0.8.4" VERSION = "0.9.0.rc.2"
end end
end end

View File

@ -6,7 +6,7 @@
<script type="text/javascript" src="<%= Jasmine::Headless.root.join('vendor/assets/javascripts/prolog.js') %>"></script> <script type="text/javascript" src="<%= Jasmine::Headless.root.join('vendor/assets/javascripts/prolog.js') %>"></script>
<%= files.join("\n") %> <%= files.join("\n") %>
<script type="text/javascript"> <script type="text/javascript">
if (window.JHW) { HeadlessReporterResult.specLineNumbers = <%= MultiJson.encode(spec_lines) %>; } if (window.JHW) { HeadlessReporterResult.specLineNumbers = <%= MultiJson.dump(spec_lines) %>; }
</script> </script>
</head> </head>
<body> <body>
@ -34,6 +34,39 @@
break; break;
} }
} }
var location = window.location.href;
var getLastModified = function(callback) {
var http = new XMLHttpRequest();
var header;
http.open('HEAD', location, true);
http.onreadystatechange = function() {
if(http.readyState === http.DONE) {
callback(http.getResponseHeader('Last-Modified'));
}
};
http.send();
}
getLastModified(function(currentLastModified) {
var checker;
checker = function() {
setTimeout(function() {
getLastModified(function(newLastModified) {
if (currentLastModified != newLastModified) {
setTimeout(function() { window.location.reload(); }, 1000);
} else {
checker();
}
});
}, 3000);
};
checker();
});
} }
jasmine.getEnv().execute(); jasmine.getEnv().execute();

View File

@ -0,0 +1,2 @@
//= require app-file
//

View File

@ -0,0 +1,7 @@
src_dir: spec/jasmine/two_files_from_src_files/app
asset_paths:
- "spec/jasmine/two_files_from_src_files/vendor"
src_files: [ 'vendor.js', 'app.js' ]

View File

@ -0,0 +1,2 @@
//= require vendor-file
//

View File

@ -95,5 +95,28 @@ describe Jasmine::Headless::CacheableAction do
end end
end end
end end
describe '#relative_cache_file' do
context 'file is an absolute windows file' do
let(:current_path) { 'C:/path' }
let(:filename) { "file.coffee" }
let(:windows_path) { File.join(current_path, filename) }
let(:cache_dir) { 'cache dir' }
let(:cache_type) { 'cache type' }
before do
cache_object.stubs(:file).returns(windows_path)
described_class.stubs(:cache_dir).returns(cache_dir)
described_class.stubs(:cache_type).returns(cache_type)
Dir.stubs(:pwd).returns(current_path)
end
subject { cache_object.relative_cache_file }
it { should == File.join(cache_dir, cache_type, filename) }
end
end
end end

View File

@ -5,50 +5,6 @@ require 'coffee-script'
describe Jasmine::Headless::FilesList do describe Jasmine::Headless::FilesList do
let(:files_list) { described_class.new } let(:files_list) { described_class.new }
describe '.get_paths_from_gemspec' do
include FakeFS::SpecHelpers
let(:gem_dir) { "dir" }
let(:gemspec) { stub(:gem_dir => gem_dir) }
let(:paths) do
%w{vendor lib app}.collect do |dir|
File.join(gem_dir, dir, 'assets/javascripts')
end
end
before do
paths.each { |path| FileUtils.mkdir_p path }
described_class.instance_variable_set(:@asset_paths, [])
end
subject { described_class.get_paths_from_gemspec(gemspec) }
it { should =~ paths }
end
describe '.asset_paths' do
include FakeFS::SpecHelpers
let(:dir_one) { 'dir_one' }
let(:dir_two) { 'dir_two' }
let(:gem_one) { stub(:gem_dir => dir_one) }
let(:gem_two) { stub(:gem_dir => dir_two) }
before do
described_class.instance_variable_set(:@asset_paths, nil)
FileUtils.mkdir_p File.join(dir_two, 'vendor/assets/javascripts')
Gem::Specification.stubs(:_all).returns([gem_one, gem_two])
end
it 'should return all matching gems with vendor/assets/javascripts directories' do
described_class.asset_paths.should == [ File.join(dir_two, 'vendor/assets/javascripts') ]
end
end
describe '#initialize' do describe '#initialize' do
before do before do
described_class.any_instance.stubs(:load_initial_assets) described_class.any_instance.stubs(:load_initial_assets)
@ -218,6 +174,21 @@ describe Jasmine::Headless::FilesList do
files_list.files.any? { |file| file['.erb'] }.should be_false files_list.files.any? { |file| file['.erb'] }.should be_false
end end
end end
describe "#register_engine!" do
before(:each) do
Jasmine::Headless::FilesList.reset!
end
it "should register code added via configure blocks" do
template_class = mock()
described_class.register_engine ".foo", template_class
Sprockets.expects(:register_engine).with(".foo", template_class)
described_class.new
end
end
end end
end end

View File

@ -194,4 +194,54 @@ describe Jasmine::Headless::Runner do
subject.options[:reporters].should == reporters subject.options[:reporters].should == reporters
end end
end end
describe '.server_port' do
before do
described_class.instance_variable_set(:@server_port, nil)
end
context 'port in use' do
require 'socket'
before do
described_class.stubs(:select_server_port).returns(5000, 5001)
end
it 'should try another port' do
server = TCPServer.new(described_class.server_interface, 5000)
described_class.server_port.should == 5001
end
end
end
describe '#absolute_run_targets' do
let(:opts) { {} }
subject { runner.absolute_run_targets(targets) }
let(:targets) { [ target ] }
let(:target) { 'target' }
before do
runner.stubs(:options).returns(:use_server => use_server)
end
context 'server' do
let(:use_server) { true }
let(:server_spec_path) { 'server spec path' }
before do
described_class.stubs(:server_spec_path).returns(server_spec_path)
end
it { should == [ server_spec_path + target ] }
end
context 'no server' do
let(:use_server) { false }
it { should == [ 'file://' + File.expand_path(target) ] }
end
end
end end

View File

@ -80,15 +80,18 @@ if window.JHW
puts msg puts msg
JHW.createCoffeeScriptFileException = (e) -> JHW.createCoffeeScriptFileException = (e) ->
if e and e.sourceURL and window.CoffeeScriptToFilename if e and e.sourceURL
filename = e.sourceURL.split('/').pop() filename = e.sourceURL.split('/').pop()
if realFilename = window.CoffeeScriptToFilename[filename]
e = { e =
name: e.name, name: e.name
message: e.message, message: e.message
lineNumber: "~" + String(e.line), sourceURL: e.sourceURL
sourceURL: realFilename lineNumber: e.line
}
if window.CoffeeScriptToFilename and realFilename = window.CoffeeScriptToFilename[filename]
e.sourceURL = realFilename
e.lineNumber = "~" + String(e.line)
e e

View File

@ -11,16 +11,16 @@ window.Intense = {
methods: methods:
foreground: (color) -> foreground: (color) ->
if Intense.useColors if Intense.useColors
"\033[3#{Intense.colors[color]}m#{this}\033[0m" '\x1b' + "[3#{Intense.colors[color]}m#{this}" + '\x1b' + "[0m"
else else
this this
bright: -> bright: ->
if Intense.useColors if Intense.useColors
"\033[1m#{this}\033[0m" '\x1b' + "[1m#{this}" + '\x1b' + "[0m"
else else
this this
useColors: true useColors: true
moveBack: (count = 1) -> "\033[#{count}D" moveBack: (count = 1) -> '\x1b' + "[#{count}D"
} }
for method, code of Intense.methods for method, code of Intense.methods

View File

@ -1,6 +1,8 @@
#= require jasmine.HeadlessReporter.ConsoleBase #= require jasmine.HeadlessReporter.ConsoleBase
# #
class jasmine.HeadlessReporter.Verbose extends jasmine.HeadlessReporter.ConsoleBase class jasmine.HeadlessReporter.Verbose extends jasmine.HeadlessReporter.ConsoleBase
@prereport = false
displaySuccess: (spec) => displaySuccess: (spec) =>
this.displaySpec(spec, 'green') this.displaySpec(spec, 'green')
@ -46,12 +48,17 @@ class jasmine.HeadlessReporter.Verbose extends jasmine.HeadlessReporter.ConsoleB
colorLine: (line, color) => colorLine: (line, color) =>
line.foreground(color) line.foreground(color)
reportSpecStarting: (spec) =>
if jasmine.HeadlessReporter.Verbose.prereport
this.puts(spec.getSpecSplitName().join(' '))
reportException: (e) => reportException: (e) =>
e = JHW.createCoffeeScriptFileException(e) e = JHW.createCoffeeScriptFileException(e)
output = e.message
if e.sourceURL && e.lineNumber if e.sourceURL && e.lineNumber
output = "#{e.sourceURL}:~#{e.lineNumber} #{output}" output = "#{e.sourceURL}:#{e.lineNumber} #{e.message}"
else
output = e.message ? e
this.puts(output.foreground('yellow')) this.puts(output.foreground('yellow'))

View File

@ -84,15 +84,17 @@
}; };
JHW.createCoffeeScriptFileException = function(e) { JHW.createCoffeeScriptFileException = function(e) {
var filename, realFilename; var filename, realFilename;
if (e && e.sourceURL && window.CoffeeScriptToFilename) { if (e && e.sourceURL) {
filename = e.sourceURL.split('/').pop(); filename = e.sourceURL.split('/').pop();
if (realFilename = window.CoffeeScriptToFilename[filename]) { e = {
e = { name: e.name,
name: e.name, message: e.message,
message: e.message, sourceURL: e.sourceURL,
lineNumber: "~" + String(e.line), lineNumber: e.line
sourceURL: realFilename };
}; if (window.CoffeeScriptToFilename && (realFilename = window.CoffeeScriptToFilename[filename])) {
e.sourceURL = realFilename;
e.lineNumber = "~" + String(e.line);
} }
} }
return e; return e;