Skip to content

Commit

Permalink
Check PhantomJS bin and Jasmine runner status on CI helper (Fixes #33)
Browse files Browse the repository at this point in the history
Refactored the utility methods into an own module, so it can be reused
in the continuous helper executable.
  • Loading branch information
netzpirat committed Feb 11, 2012
1 parent 3616618 commit a8ff361
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 236 deletions.
104 changes: 7 additions & 97 deletions lib/guard/jasmine.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
require 'net/http'

require 'guard'
require 'guard/guard'
require 'guard/watcher'
require 'net/http'

module Guard

Expand All @@ -10,10 +11,12 @@ module Guard
#
class Jasmine < Guard

autoload :Formatter, 'guard/jasmine/formatter'
autoload :Inspector, 'guard/jasmine/inspector'
autoload :Runner, 'guard/jasmine/runner'
autoload :Server, 'guard/jasmine/server'
autoload :Util, 'guard/jasmine/util'

extend Util

attr_accessor :last_run_failed, :last_failed_paths

Expand Down Expand Up @@ -72,11 +75,11 @@ def initialize(watchers = [], options = { })
# @raise [:task_has_failed] when run_on_change has failed
#
def start
if phantomjs_bin_valid?(options[:phantomjs_bin])
if Jasmine.phantomjs_bin_valid?(options[:phantomjs_bin])

Server.start(options[:server], options[:port], options[:server_env]) unless options[:server] == :none

if jasmine_runner_available?(options[:jasmine_url])
if Jasmine.runner_available?(options[:jasmine_url])
run_all if options[:all_on_start]
end
else
Expand Down Expand Up @@ -137,98 +140,5 @@ def run_on_change(paths)
throw :task_has_failed unless passed
end

private

# Verifies if the Jasmine test runner is available.
#
# @param [String] url the location of the test runner
# @return [Boolean] when the runner is available
#
def jasmine_runner_available?(url)
url = URI.parse(url)

begin
Net::HTTP.start(url.host, url.port) do |http|
response = http.request(Net::HTTP::Head.new(url.path))

if response.code.to_i == 200
Formatter.info("Jasmine test runner is available at #{ url }")
else
notify_failure("Jasmine test runner isn't available", "Jasmine test runner isn't available at #{ url }")
end

response.code.to_i == 200
end

rescue
notify_failure("Jasmine test runner isn't available", "Jasmine test runner isn't available at #{ url }")

false
end
end

# Verifies that the phantomjs bin is available and the
# right version is installed.
#
# @param [String] bin the location of the phantomjs bin
# @return [Boolean] when the runner is available
#
def phantomjs_bin_valid?(bin)
if bin && !bin.empty?
version = `#{ bin } --version`

if version
# Remove all but version, e.g. from '1.5 (development)'
version = version.match(/(\d\.)*(\d)/)[0]

if Gem::Version.new(version) < Gem::Version.new('1.3.0')
notify_failure('Wrong PhantomJS version', "PhantomJS executable at #{ bin } must be at least version 1.3.0")
else
true
end
else
notify_failure('PhantomJS executable missing', "PhantomJS executable doesn't exist at #{ bin }")
end
else
notify_failure('PhantomJS executable missing', "PhantomJS executable couldn't be auto detected.")
end
end

# Notify a failure.
#
# @param title [String] the failure title
# @param message [String] the failure message
#
def notify_failure(title, message)
Formatter.error(message)
Formatter.notify(message,
:title => title,
:image => :failed,
:priority => 2) if options[:notification]
false
end

# Cross-platform way of finding an executable in the $PATH.
# http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
#
# @example
# which('ruby') #=> /usr/bin/ruby
#
# @param cmd [String] the executable to find
# @return [String, nil] the path to the executable
#
def self.which(cmd)
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']

ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
exts.each do |ext|
exe = "#{ path }/#{ cmd }#{ ext }"
return exe if File.executable?(exe)
end
end

nil
end

end
end
23 changes: 16 additions & 7 deletions lib/guard/jasmine/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require 'guard/jasmine/runner'
require 'guard/jasmine/formatter'
require 'guard/jasmine/server'
require 'guard/jasmine/util'

module Guard
class Jasmine
Expand All @@ -15,6 +16,7 @@ class Jasmine
# This outputs the specdoc and disables any notifications.
#
class CLI < Thor
extend Util

default_task :spec

Expand All @@ -41,7 +43,6 @@ class CLI < Thor
method_option :bin,
:type => :string,
:aliases => '-b',
:default => '/usr/local/bin/phantomjs',
:desc => 'The location of the PhantomJS binary'

method_option :timeout,
Expand Down Expand Up @@ -72,7 +73,7 @@ def spec(*paths)

runner = {}
runner[:jasmine_url] = options.url
runner[:phantomjs_bin] = options.bin
runner[:phantomjs_bin] = options.bin || CLI.which('phantomjs')
runner[:timeout] = options.timeout
runner[:port] = options.port
runner[:server_env] = options.server_env
Expand All @@ -84,13 +85,21 @@ def spec(*paths)
runner[:max_error_notify] = 0
runner[:specdoc] = :always

::Guard::Jasmine::Server.start(runner[:server], runner[:port], runner[:server_env]) unless runner[:server] == :none
result = ::Guard::Jasmine::Runner.run(paths, runner)
if CLI.phantomjs_bin_valid?(runner[:phantomjs_bin])
::Guard::Jasmine::Server.start(runner[:server], runner[:port], runner[:server_env]) unless runner[:server] == :none

::Guard::Jasmine::Server.stop
if CLI.runner_available?(runner[:jasmine_url])
result = ::Guard::Jasmine::Runner.run(paths, runner)
::Guard::Jasmine::Server.stop

exit_code = result.first ? 0 : 1
Process.exit exit_code
Process.exit result.first ? 0 : 1
else
Process.exit 2
end

else
Process.exit 2
end

rescue Exception => e
raise e if e.is_a?(SystemExit)
Expand Down
90 changes: 90 additions & 0 deletions lib/guard/jasmine/util.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
require 'guard/jasmine/formatter'

module Guard
class Jasmine

# Provider of some shared utility methods.
#
module Util

# Verifies if the Jasmine test runner is available.
#
# @param [String] url the location of the test runner
# @return [Boolean] when the runner is available
#
def runner_available?(url)
url = URI.parse(url)

begin
Net::HTTP.start(url.host, url.port) do |http|
response = http.request(Net::HTTP::Head.new(url.path))

if response.code.to_i == 200
::Guard::Jasmine::Formatter.info "Jasmine test runner is available at #{ url }"
else
::Guard::Jasmine::Formatter.error "Jasmine test runner isn't available at #{ url }"
end

response.code.to_i == 200
end

rescue
::Guard::Jasmine::Formatter.error "Jasmine test runner isn't available at #{ url }"

false
end
end

# Verifies that the phantomjs bin is available and the
# right version is installed.
#
# @param [String] bin the location of the phantomjs bin
# @return [Boolean] when the runner is available
#
def phantomjs_bin_valid?(bin)
if bin && !bin.empty?
version = `#{ bin } --version`

if version
# Remove all but version, e.g. from '1.5 (development)'
version = version.match(/(\d\.)*(\d)/)[0]

if Gem::Version.new(version) < Gem::Version.new('1.3.0')
::Guard::Jasmine::Formatter.error "PhantomJS executable at #{ bin } must be at least version 1.3.0"
else
true
end
else
::Guard::Jasmine::Formatter.error "PhantomJS executable doesn't exist at #{ bin }"
end
else
::Guard::Jasmine::Formatter.error "PhantomJS executable couldn't be auto detected."
end
end

# Cross-platform way of finding an executable in the $PATH.
# http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
#
# @example
# which('ruby') #=> /usr/bin/ruby
#
# @param cmd [String] the executable to find
# @return [String, nil] the path to the executable
#
def which(cmd)
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']

ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
exts.each do |ext|
exe = "#{ path }/#{ cmd }#{ ext }"
return exe if File.executable?(exe)
end
end

nil
end

end

end
end
30 changes: 28 additions & 2 deletions spec/guard/jasmine/cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
runner.stub(:run)
server.stub(:start)
server.stub(:stop)
cli.stub(:which).and_return '/usr/local/bin/phantomjs'
cli.stub(:phantomjs_bin_valid?).and_return true
cli.stub(:runner_available?).and_return true
end

describe '.spec' do
Expand Down Expand Up @@ -89,8 +92,9 @@
cli.start(['spec'])
end

it 'sets the default PhantomJS binary' do
runner.should_receive(:run).with(anything(), hash_including(:phantomjs_bin => '/usr/local/bin/phantomjs')).and_return [true, []]
it 'auto detects the phantomjs binary' do
cli.should_receive(:which).with('phantomjs').and_return '/tmp/phantomjs'
runner.should_receive(:run).with(anything(), hash_including(:phantomjs_bin => '/tmp/phantomjs')).and_return [true, []]
cli.start(['spec'])
end

Expand Down Expand Up @@ -133,6 +137,28 @@
end
end

context 'without a valid phantomjs executable' do
before do
cli.stub(:phantomjs_bin_valid?).and_return false
end

it 'stops with an exit code 2' do
Process.should_receive(:exit).with(2)
cli.start(['spec'])
end
end

context 'without the runner available' do
before do
cli.stub(:runner_available).and_return false
end

it 'stops with an exit code 2' do
Process.should_receive(:exit).with(2)
cli.start(['spec'])
end
end

context 'with a runner exception' do
it 'shows the error message' do
::Guard::UI.should_receive(:error).with('Something went wrong')
Expand Down
Loading

0 comments on commit a8ff361

Please sign in to comment.