require 'sinatra'
require 'haml'
module Shenandoah
# The server which enables in-browser execution of Screw.Unit specs in
# Shenandoah.
#
# It exposes a list of all the specs at the root of the server,
# organized by subdirectory, with links to individual test fixtures.
# The contents of the +main_path+ and +spec_path+ in the configured locator
# are exposed under /main and /spec respectively.
class Server < Sinatra::Base
set :root, File.dirname(__FILE__) + "/server"
set :port, 4410
enable :logging
get '/' do
section_map = options.locator.spec_files.
collect { |t| t.sub(%r{^#{options.locator.spec_path}/?}, '') }.
collect { |t| [File.dirname(t), File.basename(t).sub(/_spec.js$/, '.html')] }.
inject({}) { |h, (dir, file)| h[dir] ||= []; h[dir] << file; h }
@sections = section_map.collect { |dir, files| [dir, files.sort] }.sort
haml :index
end
get '/main/*' do
map_file(options.locator.main_path, params[:splat].first, "Main")
end
get '/spec/*' do
map_file(options.locator.spec_path, params[:splat].first, "Spec")
end
get '/screw.css' do
screw_css = File.join(options.locator.spec_path, 'screw.css')
unless File.exist?(screw_css)
screw_css = File.join(File.dirname(__FILE__), 'css/screw.css')
end
send_file screw_css
end
get '/shenandoah/browser-runner.js' do
content_type 'text/javascript'
last_modified runner_files.collect { |filename|
File.stat("#{File.dirname(__FILE__)}/#{filename}").mtime
}.max
runner_files.collect { |filename|
[
"\n//////\n////// #{filename}\n//////\n",
File.read("#{File.dirname(__FILE__)}/#{filename}")
]
}.flatten
end
protected
def map_file(path, name, desc) # :nodoc:
file = File.join(path, name)
if File.exist?(file)
headers['Cache-Control'] = 'no-cache'
send_file file
else
halt 404, "#{desc} file not found: #{file}"
end
end
def runner_files # :nodoc:
# Can't just use Dir[] because order is important
[
"javascript/common/jquery-1.3.2.js",
"javascript/common/jquery.fn.js",
"javascript/common/jquery.print.js",
"javascript/common/screw.builder.js",
"javascript/common/screw.matchers.js",
"javascript/common/screw.events.js",
"javascript/common/screw.behaviors.js",
"javascript/common/smoke.core.js",
"javascript/common/smoke.mock.js",
"javascript/common/smoke.stub.js",
"javascript/common/screw.mocking.js",
"javascript/browser/runner.js"
]
end
end
end