Skip to content

Commit

Permalink
Allow the Jasmine spec dir to be configured.
Browse files Browse the repository at this point in the history
  • Loading branch information
netzpirat committed Mar 7, 2012
1 parent 4ced959 commit 7eb3db0
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 40 deletions.
20 changes: 13 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,6 @@ If you're setting the `:server` option to `:none`, you can supply the Jasmine ru
```ruby
:jasmine_url => 'http://192.168.1.5/jasmine' # URL where Jasmine is served.
# default: http://127.0.0.1:8888/jasmine

:clean => false # Clean the spec list by only keep Jasmine specs within the project.
# default: true
```

Detecting the server with the `auto` option does only detect the jasmine gem or webrick. If you want to use mongrel or
Expand All @@ -247,15 +244,20 @@ The reason why the Server environment is set to `development` by default is that
the asset pipeline doesn't concatenate the JavaScripts and you'll see the line number in the real file,
instead of a ridiculous high line number in a single, very large JavaScript.

In general you want to leave the `:clean` flag on, which ensures that only Jasmine specs (files ending with `_spec.js`,
`_spec.coffee` and `_spec.js.coffee` inside your project are passed to the runner. If you have a custom project
structure or spec naming convention, you can set `:clean` to false to skip that file filter.

### Spec runner options

The spec runner options configures the behavior driven development (or BDD) cycle:

```ruby
:spec_dir => false # Directory with the Jasmine specs.
# default: 'spec/javascripts'

:clean => false # Clean the spec list by only keep Jasmine specs within the project.
# default: true

:all_on_start => false # Run all suites on start.
# default: true

:all_on_start => false # Run all suites on start.
# default: true

Expand All @@ -271,6 +273,10 @@ The `:keep_failed` failed option remembers failed suites and not failed specs. T
avoid additional round trip time to request the Jasmine test runner for each single spec, which is mostly more expensive
than running a whole suite.

In general you want to leave the `:clean` flag on, which ensures that only Jasmine specs (files ending with `_spec.js`,
`_spec.coffee` and `_spec.js.coffee` inside your project are passed to the runner. If you have a custom project
structure or spec naming convention, you can set `:clean` to false to skip that file filter.

### Specdoc options

Guard::Jasmine can generate an RSpec like specdoc in the console after running the specs and you can set when it will
Expand Down
1 change: 1 addition & 0 deletions guard-jasmine.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Gem::Specification.new do |s|
s.add_development_dependency 'yard'
s.add_development_dependency 'redcarpet'
s.add_development_dependency 'pry'
s.add_development_dependency 'yajl-ruby'

s.files = Dir.glob('{bin,lib}/**/*') + %w[LICENSE README.md]
s.executables = ['guard-jasmine', 'guard-jasmine-debug']
Expand Down
6 changes: 4 additions & 2 deletions lib/guard/jasmine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class Jasmine < Guard
:port => 8888,
:jasmine_url => 'http://localhost:8888/jasmine',
:timeout => 10000,
:spec_dir => 'spec/javascripts',
:notification => true,
:hide_success => false,
:all_on_start => true,
Expand All @@ -48,6 +49,7 @@ class Jasmine < Guard
# @option options [String] :jasmine_url the url of the Jasmine test runner
# @option options [String] :phantomjs_bin the location of the PhantomJS binary
# @option options [Integer] :timeout the maximum time in milliseconds to wait for the spec runner to finish
# @option options [String] :spec_dir the directory with the Jasmine specs
# @option options [Boolean] :notification show notifications
# @option options [Boolean] :hide_success hide success message notification
# @option options [Integer] :max_error_notify maximum error notifications to show
Expand Down Expand Up @@ -111,7 +113,7 @@ def reload
# @raise [:task_has_failed] when run_on_change has failed
#
def run_all
passed, failed_specs = Runner.run(['spec/javascripts'], options)
passed, failed_specs = Runner.run([options[:spec_dir]], options)

self.last_failed_paths = failed_specs
self.last_run_failed = !passed
Expand All @@ -126,7 +128,7 @@ def run_all
#
def run_on_change(paths)
specs = options[:keep_failed] ? paths + self.last_failed_paths : paths
specs = Inspector.clean(specs) if options[:clean]
specs = Inspector.clean(specs, options) if options[:clean]
return false if specs.empty?

passed, failed_specs = Runner.run(specs, options)
Expand Down
9 changes: 8 additions & 1 deletion lib/guard/jasmine/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,27 @@ class CLI < Thor
:default => 'test',
:desc => 'The server environment to use, for example `development`, `test` etc.'

method_option :spec_dir,
:type => :string,
:aliases => '-d',
:default => 'spec/javascripts',
:desc => 'The directory with the Jasmine specs'

# Run the Guard::Jasmine::Runner with options from
# the command line.
#
# @param [Array<String>] paths the name of the specs to run
#
def spec(*paths)
paths = ['spec/javascripts'] if paths.empty?
paths = [options.spec_dir] if paths.empty?

runner = {}
runner[:jasmine_url] = options.url
runner[:phantomjs_bin] = options.bin || CLI.which('phantomjs')
runner[:timeout] = options.timeout
runner[:port] = options.port
runner[:server_env] = options.server_env
runner[:spec_dir] = options.spec_dir
runner[:console] = [:always, :never, :failure].include?(options.console.to_sym) ? options.console.to_sym : :failure
runner[:server] = [:auto, :none, :webrick, :mongrel, :thin, :jasmine_gem].include?(options.server.to_sym) ? options.server.to_sym : :auto

Expand Down
8 changes: 5 additions & 3 deletions lib/guard/jasmine/inspector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ class << self
# Jasmine specs in either JavaScript or CoffeeScript.
#
# @param [Array<String>] paths the changed paths
# @param [Hash] options the options for the Guard
# @option options [String] :spec_dir the directory with the Jasmine specs
# @return [Array<String>] the valid spec files
#
def clean(paths)
def clean(paths, options)
paths.uniq!
paths.compact!

if paths.include?('spec/javascripts')
paths = ['spec/javascripts']
if paths.include?(options[:spec_dir])
paths = [options[:spec_dir]]
else
paths = paths.select { |p| jasmine_spec?(p) }
end
Expand Down
19 changes: 13 additions & 6 deletions lib/guard/jasmine/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,19 @@ class << self
# @option options [String] :jasmine_url the url of the Jasmine test runner
# @option options [String] :phantomjs_bin the location of the PhantomJS binary
# @option options [Integer] :timeout the maximum time in milliseconds to wait for the spec runner to finish
# @option options [String] :spec_dir the directory with the Jasmine specs
# @option options [Boolean] :notification show notifications
# @option options [Boolean] :hide_success hide success message notification
# @option options [Integer] :max_error_notify maximum error notifications to show
# @option options [Symbol] :specdoc options for the specdoc output, either :always, :never
# @option options [Symbol] :console options for the console.log output, either :always, :never or :failure
# @option options [String] :spec_dir the directory with the Jasmine specs
# @return [Boolean, Array<String>] the status of the run and the failed files
#
def run(paths, options = { })
return [false, []] if paths.empty?

notify_start_message(paths)
notify_start_message(paths, options)

results = paths.inject([]) do |results, file|
results << evaluate_response(run_jasmine_spec(file, options), file, options)
Expand All @@ -45,9 +47,11 @@ def run(paths, options = { })
# Shows a notification in the console that the runner starts.
#
# @param [Array<String>] paths the spec files or directories
# @param [Hash] options the options for the execution
# @option options [String] :spec_dir the directory with the Jasmine specs
#
def notify_start_message(paths)
message = if paths == ['spec/javascripts']
def notify_start_message(paths, options)
message = if paths == [options[:spec_dir]]
'Run all Jasmine suites'
else
"Run Jasmine suite#{ paths.size == 1 ? '' : 's' } #{ paths.join(' ') }"
Expand Down Expand Up @@ -99,12 +103,13 @@ def phantomjs_command(options)
# Get the Jasmine test runner URL with the appended suite name
# that acts as the spec filter.
#
# @param [String] file the spec file
# @param [Hash] options the options for the execution
# @option options [String] :jasmine_url the url of the Jasmine test runner
# @return [String] the Jasmine url
#
def jasmine_suite(file, options)
options[:jasmine_url] + query_string_for_suite(file)
options[:jasmine_url] + query_string_for_suite(file, options)
end

# Get the PhantomJS script that executes the spec and extracts
Expand All @@ -122,10 +127,12 @@ def phantomjs_script
# found.
#
# @param [String] file the spec file
# @param [Hash] options the options for the execution
# @option options [String] :spec_dir the directory with the Jasmine specs
# @return [String] the suite name
#
def query_string_for_suite(file)
return '' if file == 'spec/javascripts'
def query_string_for_suite(file, options)
return '' if file == options[:spec_dir]

query_string = ''

Expand Down
23 changes: 21 additions & 2 deletions spec/guard/jasmine/cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@
cli.start(['spec', 'spec/javascripts/a_spec.js', 'spec/javascripts/another_spec.js'])
end

it 'sets the spec dir' do
runner.should_receive(:run).with(anything(), hash_including(:spec_dir => 'specs')).and_return [true, []]
cli.start(['spec', '--spec_dir', 'specs'])
end

it 'sets the jasmine url' do
runner.should_receive(:run).with(anything(), hash_including(:jasmine_url => 'http://smackaho.st:3000/jasmine')).and_return [true, []]
cli.start(['spec', '--url', 'http://smackaho.st:3000/jasmine'])
Expand Down Expand Up @@ -82,8 +87,22 @@
end

context 'for the runner' do
it 'runs all specs when the paths are empty' do
runner.should_receive(:run).with(['spec/javascripts'], anything()).and_return [true, []]
context 'without a specific spec dir' do
it 'runs all default specs when the paths are empty' do
runner.should_receive(:run).with(['spec/javascripts'], anything()).and_return [true, []]
cli.start(['spec'])
end
end

context 'with a specific spec dir' do
it 'runs all specs when the paths are empty' do
runner.should_receive(:run).with(['specs'], anything()).and_return [true, []]
cli.start(['spec', '-d', 'specs'])
end
end

it 'sets the spec dir' do
runner.should_receive(:run).with(anything(), hash_including(:spec_dir => 'spec/javascripts')).and_return [true, []]
cli.start(['spec'])
end

Expand Down
10 changes: 6 additions & 4 deletions spec/guard/jasmine/inspector_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,27 @@

subject { Guard::Jasmine::Inspector }

let(:options) { { :spec_dir => 'spec/javascripts' }}

describe 'clean' do
it 'allows the Jasmine spec dir' do
subject.clean(['spec/javascripts', 'spec/javascripts/a.js.coffee']).should == ['spec/javascripts']
subject.clean(['spec/javascripts', 'spec/javascripts/a.js.coffee'], options).should == ['spec/javascripts']
end

it 'removes duplicate files' do
subject.clean(['spec/javascripts/a_spec.js.coffee', 'spec/javascripts/a_spec.js.coffee']).should == ['spec/javascripts/a_spec.js.coffee']
subject.clean(['spec/javascripts/a_spec.js.coffee', 'spec/javascripts/a_spec.js.coffee'], options).should == ['spec/javascripts/a_spec.js.coffee']
end

it 'remove nil files' do
subject.clean(['spec/javascripts/a_spec.js.coffee', nil]).should == ['spec/javascripts/a_spec.js.coffee']
subject.clean(['spec/javascripts/a_spec.js.coffee', nil], options).should == ['spec/javascripts/a_spec.js.coffee']
end

it 'removes files that are no javascript specs' do
subject.clean(['spec/javascripts/a_spec.js.coffee',
'spec/javascripts/b_spec.js',
'app/assets/javascripts/a.js.coffee',
'b.txt',
'c_spec.coffee']).should == ['spec/javascripts/a_spec.js.coffee', 'spec/javascripts/b_spec.js', 'c_spec.coffee']
'c_spec.coffee'], options).should == ['spec/javascripts/a_spec.js.coffee', 'spec/javascripts/b_spec.js', 'c_spec.coffee']
end

end
Expand Down
Loading

0 comments on commit 7eb3db0

Please sign in to comment.