guard-jasmine 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,22 @@
1
+ Redistribution and use in source and binary forms, with or without
2
+ modification, are permitted provided that the following conditions are met:
3
+
4
+ * Redistributions of source code must retain the above copyright
5
+ notice, this list of conditions and the following disclaimer.
6
+ * Redistributions in binary form must reproduce the above copyright
7
+ notice, this list of conditions and the following disclaimer in the
8
+ documentation and/or other materials provided with the distribution.
9
+ * Neither the name of the <organization> nor the
10
+ names of its contributors may be used to endorse or promote products
11
+ derived from this software without specific prior written permission.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
17
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
File without changes
data/README.md CHANGED
@@ -38,21 +38,15 @@ Please be sure to have [Guard][] installed.
38
38
 
39
39
  Install the gem:
40
40
 
41
- ```bash
42
- $ gem install guard-jasmine
43
- ```
41
+ $ gem install guard-jasmine
44
42
 
45
43
  Add it to your `Gemfile`, preferably inside the development group:
46
44
 
47
- ```ruby
48
- gem 'guard-jasmine'
49
- ```
45
+ gem 'guard-jasmine'
50
46
 
51
47
  Add guard definition to your `Guardfile` by running this command:
52
48
 
53
- ```bash
54
- $ guard init jasmine
55
- ```
49
+ $ guard init jasmine
56
50
 
57
51
  ### Rails 3.1
58
52
 
@@ -63,26 +57,20 @@ Please read the detailed installation and configuration instructions at [Jasmine
63
57
 
64
58
  In short, you add it to your `Gemfile`:
65
59
 
66
- ```ruby
67
- group :development, :test do
68
- gem 'jasmine'
69
- end
70
- ```
60
+ group :development, :test do
61
+ gem 'jasmine'
62
+ end
71
63
 
72
64
  and add a route for the Jasmine Test Runner to `config/routes.rb`:
73
65
 
74
- ```ruby
75
- if ["development", "test"].include? Rails.env
76
- mount Jasminerice::Engine => "/jasmine"
77
- end
78
- ```
66
+ if ["development", "test"].include? Rails.env
67
+ mount Jasminerice::Engine => "/jasmine"
68
+ end
79
69
 
80
70
  Next you create the directory `spec/javascripts` where your CoffeeScript tests go into. You define the Rails 3.1
81
71
  asset pipeline manifest in `spec/javascripts/spec.js.coffee`:
82
72
 
83
- ```ruby
84
- #=require_tree ./
85
- ```
73
+ #=require_tree ./
86
74
 
87
75
  ### Rails 2 & 3
88
76
 
@@ -96,17 +84,13 @@ You need the PhantomJS browser installed on your system. You can download binari
96
84
 
97
85
  Alternatively you can install [Homebrew][] on Mac OS X and install it with:
98
86
 
99
- ```bash
100
- $ brew install phantomjs
101
- ```
87
+ $ brew install phantomjs
102
88
 
103
89
  If you are using Ubuntu 10.10, you can install it with apt:
104
90
 
105
- ```bash
106
- $ sudo add-apt-repository ppa:jerome-etienne/neoip
107
- $ sudo apt-get update
108
- $ sudo apt-get install phantomjs
109
- ```
91
+ $ sudo add-apt-repository ppa:jerome-etienne/neoip
92
+ $ sudo apt-get update
93
+ $ sudo apt-get install phantomjs
110
94
 
111
95
  You can also build it from source for several other operating systems, please consult the
112
96
  [PhantomJS build instructions][].
@@ -122,42 +106,41 @@ Guard::Jasmine can be adapted to all kind of projects. Please read the
122
106
 
123
107
  ### Rails 3.1 with Jasminerice
124
108
 
125
- ```ruby
126
- guard 'jasmine' do
127
- watch(%r{app/assets/javascripts/(.+)\.(js\.coffee|js)}) { |m| "spec/javascripts/#{m[1]}_spec.#{m[2]}" }
128
- watch(%r{spec/javascripts/(.+)_spec\.(js\.coffee|js)}) { |m| "spec/javascripts/#{m[1]}_spec.#{m[2]}" }
129
- watch(%r{spec/javascripts/spec\.(js\.coffee|js)}) { "spec/javascripts" }
130
- end
131
- ```
109
+ guard 'jasmine' do
110
+ watch(%r{app/assets/javascripts/(.+)\.(js\.coffee|js)}) { |m| "spec/javascripts/#{m[1]}_spec.#{m[2]}" }
111
+ watch(%r{spec/javascripts/(.+)_spec\.(js\.coffee|js)}) { |m| "spec/javascripts/#{m[1]}_spec.#{m[2]}" }
112
+ watch(%r{spec/javascripts/spec\.(js\.coffee|js)}) { "spec/javascripts" }
113
+ end
132
114
 
133
115
  ### Rails 2 & 3 with the Jasmine gem
134
116
 
135
- ```ruby
136
- guard 'jasmine', :url => 'http://127.0.0.1:8888' do
137
- watch(%r{public/javascripts/(.+)\.js}) { |m| "spec/javascripts/#{m[1]}_spec.js" }
138
- watch(%r{spec/javascripts/(.+)_spec\.js}) { |m| "spec/javascripts/#{m[1]}_spec.js" }
139
- watch(%r{spec/javascripts/support/jasmine\.yml}) { "spec/javascripts" }
140
- watch(%r{spec/javascripts/support/jasmine_config\.rb}) { "spec/javascripts" }
141
- end
142
- ```
117
+ guard 'jasmine', :url => 'http://127.0.0.1:8888' do
118
+ watch(%r{public/javascripts/(.+)\.js}) { |m| "spec/javascripts/#{m[1]}_spec.js" }
119
+ watch(%r{spec/javascripts/(.+)_spec\.js}) { |m| "spec/javascripts/#{m[1]}_spec.js" }
120
+ watch(%r{spec/javascripts/support/jasmine\.yml}) { "spec/javascripts" }
121
+ watch(%r{spec/javascripts/support/jasmine_config\.rb}) { "spec/javascripts" }
122
+ end
143
123
 
144
124
  ## Options
145
125
 
146
126
  There following options can be passed to Guard::Jasmine:
147
127
 
148
- ```ruby
149
- :jasmine_url => 'http://192.168.1.5/jasmine' # URL where Jasmine is served.
150
- # default: http://127.0.0.1/jasmine
151
128
 
152
- :phantomjs_bin => '~/bin/phantomjs' # Path to phantomjs.
153
- # default: '/usr/local/bin/phantomjs'
129
+ :jasmine_url => 'http://192.168.1.5/jasmine' # URL where Jasmine is served.
130
+ # default: http://127.0.0.1/jasmine
154
131
 
155
- :notifications => false # Show success and error messages.
156
- # default: true
132
+ :phantomjs_bin => '~/bin/phantomjs' # Path to phantomjs.
133
+ # default: '/usr/local/bin/phantomjs'
134
+
135
+ :all_on_start => false # Run all specs on start.
136
+ # default: true
137
+
138
+ :notifications => false # Show success and error messages.
139
+ # default: true
140
+
141
+ :hide_success => true # Disable successful compilation messages.
142
+ # default: false
157
143
 
158
- :hide_success => true # Disable successful compilation messages.
159
- # default: false
160
- ```
161
144
 
162
145
  ## Alternatives
163
146
 
@@ -169,6 +152,7 @@ featured browser environment.
169
152
 
170
153
  ## Development
171
154
 
155
+ - Documentation hosted at [RubyDoc](http://rubydoc.info/gems/guard-jasmine/file/README.md)
172
156
  - Source hosted at [GitHub](https://github.com/netzpirat/guard-Jasmine)
173
157
  - Report issues and feature requests to [GitHub Issues](https://github.com/netzpirat/guard-Jasmine/issues)
174
158
 
@@ -3,28 +3,65 @@ require 'guard/guard'
3
3
  require 'guard/watcher'
4
4
 
5
5
  module Guard
6
+
7
+ # The Jasmine guard that gets notifications about the following
8
+ # Guard events: `start`, `stop`, `reload`, `run_all` and `run_on_change`.
9
+ #
6
10
  class Jasmine < Guard
7
11
 
8
12
  autoload :Formatter, 'guard/jasmine/formatter'
9
13
  autoload :Inspector, 'guard/jasmine/inspector'
10
14
  autoload :Runner, 'guard/jasmine/runner'
11
15
 
16
+ # Initialize Guard::Jasmine.
17
+ #
18
+ # @param [Array<Guard::Watcher>] watchers the watchers in the Guard block
19
+ # @param [Hash] options the options for the Guard
20
+ # @option options [String] :jasmine_url the url of the Jasmine test runner
21
+ # @option options [String] :phantomjs_bin the location of the PhantomJS binary
22
+ # @option options [Boolean] :notification show notifications
23
+ # @option options [Boolean] :hide_success hide success message notification
24
+ # @option options [Boolean] :all_on_start run all suites on start
25
+ #
12
26
  def initialize(watchers = [], options = { })
13
27
  defaults = {
14
28
  :jasmine_url => 'http://localhost:3000/jasmine',
15
29
  :phantomjs_bin => '/usr/local/bin/phantomjs',
16
- :notification => true,
17
- :hide_success => false
30
+ :notification => true,
31
+ :hide_success => false,
32
+ :all_on_start => true
18
33
  }
34
+
19
35
  super(watchers, defaults.merge(options))
20
36
  end
21
37
 
38
+ # Gets called once when Guard starts.
39
+ #
40
+ # @return [Boolean] when the start was successful
41
+ #
42
+ def start
43
+ run_all if options[:all_on_start]
44
+
45
+ true
46
+ end
47
+
48
+ # Gets called when all specs should be run.
49
+ #
50
+ # @return [Boolean] when running all specs was successful
51
+ #
22
52
  def run_all
23
- run_on_change(Watcher.match_files(self, Dir.glob(File.join('spec', '**', '*.js(.coffee)?'))))
53
+ Runner.run(['spec/javascripts'], options)
24
54
  end
25
55
 
56
+ # Gets called when watched paths and files have changes.
57
+ #
58
+ # @param [Array<String>] paths the changed paths and files
59
+ # @return [Boolean] when running the changed specs was successful
60
+ #
26
61
  def run_on_change(paths)
27
62
  Runner.run(Inspector.clean(paths), options)
63
+
64
+ #TODO: Evaluate result
28
65
  end
29
66
 
30
67
  end
@@ -1,8 +1,18 @@
1
1
  module Guard
2
2
  class Jasmine
3
+
4
+ # The inspector verifies of the changed paths are valid
5
+ # for Guard::Jasmine.
6
+ #
3
7
  module Inspector
4
8
  class << self
5
9
 
10
+ # Clean the changed paths and return only valid
11
+ # Jasmine specs in either JavaScript or CoffeeScript.
12
+ #
13
+ # @param [Array<String>] paths the changed paths
14
+ # @return [Array<String>] the valid spec files
15
+ #
6
16
  def clean(paths)
7
17
  paths.uniq!
8
18
  paths.compact!
@@ -13,14 +23,28 @@ module Guard
13
23
 
14
24
  private
15
25
 
26
+ # Tests if the file is valid.
27
+ #
28
+ # @param [String] file the file
29
+ # @return [Boolean] when the file valid
30
+ #
16
31
  def jasmine_spec?(path)
17
32
  jasmine_specs.include?(path)
18
33
  end
19
34
 
35
+ # Scans the project and keeps a list of all
36
+ # JavaScript and CoffeeScript files in the `spec`
37
+ # directory.
38
+ #
39
+ # @see #clear_jasmine_specs
40
+ # @return [Array<String>] the valid files
41
+ #
20
42
  def jasmine_specs
21
43
  @jasmine_specs ||= Dir.glob('spec/**/*_spec.{js,js.coffee}')
22
44
  end
23
45
 
46
+ # Clears the list of Jasmine specs in this project.
47
+ #
24
48
  def clear_jasmine_specs
25
49
  @jasmine_specs = nil
26
50
  end
@@ -2,17 +2,32 @@ require 'multi_json'
2
2
 
3
3
  module Guard
4
4
  class Jasmine
5
+
6
+ # The Jasmine runner handles the execution of the spec through the PhantomJS binary,
7
+ # evaluates the JSON response from the PhantomJS Script `run_jasmine.coffee`,
8
+ # writes the result to the console and triggers optional system notifications.
9
+ #
5
10
  module Runner
6
11
  class << self
7
12
 
8
- def run(files, options = { })
9
- return false if files.empty?
10
-
11
- message = options[:message] || (files == ['spec/javascripts'] ? 'Run all specs' : "Run specs #{ files.join(' ') }")
13
+ # Run the supplied specs.
14
+ #
15
+ # @param [Array<String>] paths the spec files or directories
16
+ # @param [Hash] options the options for the execution
17
+ # @option options [String] :jasmine_url the url of the Jasmine test runner
18
+ # @option options [String] :phantomjs_bin the location of the PhantomJS binary
19
+ # @option options [Boolean] :notification show notifications
20
+ # @option options [Boolean] :hide_success hide success message notification
21
+ # @return [Array<Object>] the result for each suite
22
+ #
23
+ def run(paths, options = { })
24
+ return false if paths.empty?
25
+
26
+ message = options[:message] || (paths == ['spec/javascripts'] ? 'Run all specs' : "Run specs #{ paths.join(' ') }")
12
27
  UI.info message, :reset => true
13
28
 
14
- files.inject([]) do |results, file|
15
- results << notify_result(run_jasmine(file, options), options)
29
+ paths.inject([]) do |results, file|
30
+ results << evaluate_result(run_jasmine_spec(file, options), options)
16
31
 
17
32
  results
18
33
  end.compact
@@ -20,26 +35,55 @@ module Guard
20
35
 
21
36
  private
22
37
 
23
- def run_jasmine(file, options)
24
- suite = jasmine_suite(file, options)
25
- Formatter.info("Run Jasmine tests: #{ suite }")
26
- IO.popen(phantomjs_command(options) + ' ' + suite)
38
+ # Run the Jasmine spec by executing the PhantomJS script.
39
+ #
40
+ # @param [String] path the path of the spec
41
+ #
42
+ def run_jasmine_spec(file, options)
43
+ suite = jasmine_suite(file, options)
44
+ Formatter.info("Run Jasmine tests: #{ suite }")
45
+ IO.popen(phantomjs_command(options) + ' ' + suite)
27
46
  end
28
47
 
48
+ # Get the PhantomJS binary and script to execute.
49
+ #
50
+ # @param [Hash] options the options for the execution
51
+ # @return [String] the command
52
+ #
29
53
  def phantomjs_command(options)
30
- options[:phantomjs_bin] + ' ' + phantomjs_script
54
+ options[:phantomjs_bin] + ' ' + phantomjs_script
31
55
  end
32
56
 
57
+ # Get the Jasmine test runner URL with the appended suite name
58
+ # that acts as the spec filter.
59
+ #
60
+ # @param [Hash] options the options for the execution
61
+ # @return [String] the Jasmine url
62
+ #
33
63
  def jasmine_suite(file, options)
34
- options[:jasmine_url] + suite_query_for(file)
64
+ options[:jasmine_url] + suite_name_for(file)
35
65
  end
36
66
 
67
+ # Get the PhantomJS script that executes the spec and extracts
68
+ # the result from the headless DOM.
69
+ #
70
+ # @return [String] the path to the PhantomJS script
71
+ #
37
72
  def phantomjs_script
38
73
  File.expand_path(File.join(File.dirname(__FILE__), 'phantomjs', 'run-jasmine.coffee'))
39
74
  end
40
75
 
41
- def suite_query_for(file)
76
+ # The suite name must be extracted from the spec that
77
+ # will be run. This is done by parsing from the head of
78
+ # the spec file until the first `describe` function is
79
+ # found.
80
+ #
81
+ # @param [String] file the spec file
82
+ # @return [String] the suite name
83
+ #
84
+ def suite_name_for(file)
42
85
  return '' if file == 'spec/javascripts'
86
+
43
87
  query_string = ''
44
88
 
45
89
  File.foreach(file) do |line|
@@ -52,7 +96,15 @@ module Guard
52
96
  URI.encode(query_string)
53
97
  end
54
98
 
55
- def notify_result(output, options)
99
+ # Evaluates the JSON response that the PhantomJS script
100
+ # writes to stdout. The results triggers further notification
101
+ # actions.
102
+ #
103
+ # @param [String] output the JSON output the spec run
104
+ # @param [Hash] options the options for the execution
105
+ # @return [Hash] the suite result
106
+ #
107
+ def evaluate_result(output, options)
56
108
  result = MultiJson.decode(output.read)
57
109
  output.close
58
110
 
@@ -65,12 +117,27 @@ module Guard
65
117
  result
66
118
  end
67
119
 
120
+ # Notification when a system error happens that
121
+ # prohibits the execution of the Jasmine spec.
122
+ #
123
+ # @param [Hash] the suite result
124
+ # @param [Hash] options the options for the execution
125
+ # @option options [Boolean] :notification show notifications
126
+ #
68
127
  def notify_runtime_error(result, options)
69
128
  message = "An error occurred: #{ result['error'] }"
70
129
  Formatter.error(message)
71
130
  Formatter.notify(message, :title => 'Jasmine error', :image => :failed, :priority => 2) if options[:notification]
72
131
  end
73
132
 
133
+ # Notification about a spec run, success or failure,
134
+ # and some stats.
135
+ #
136
+ # @param [Hash] result the suite result
137
+ # @param [Hash] options the options for the execution
138
+ # @option options [Boolean] :notification show notifications
139
+ # @option options [Boolean] :hide_success hide success message notification
140
+ #
74
141
  def notify_spec_result(result, options)
75
142
  specs = result['stats']['specs']
76
143
  failures = result['stats']['failures']
@@ -87,6 +154,14 @@ module Guard
87
154
  end
88
155
  end
89
156
 
157
+ # Notification about spec failures. This combines the suite
158
+ # error messages into a single notification.
159
+ #
160
+ # @param [Hash] result the suite result
161
+ # @param [String] stats the status information
162
+ # @param [Hash] options the options for the execution
163
+ # @option options [Boolean] :notification show notifications
164
+ #
90
165
  def notify_spec_failures(result, stats, options)
91
166
  messages = result['suites'].inject('') do |messages, suite|
92
167
  suite['specs'].each do |spec|
@@ -1,5 +1,5 @@
1
1
  module Guard
2
2
  module JasmineVersion
3
- VERSION = '0.1.0'
3
+ VERSION = '0.2.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: guard-jasmine
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 0.1.0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Michael Kessler
@@ -93,6 +93,22 @@ dependencies:
93
93
  version: "2.6"
94
94
  type: :development
95
95
  version_requirements: *id005
96
+ - !ruby/object:Gem::Dependency
97
+ name: yard
98
+ prerelease: false
99
+ requirement: &id006 !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ~>
103
+ - !ruby/object:Gem::Version
104
+ hash: 7
105
+ segments:
106
+ - 0
107
+ - 7
108
+ - 2
109
+ version: 0.7.2
110
+ type: :development
111
+ version_requirements: *id006
96
112
  description: Guard::Jasmine automatically tests your Jasmine specs on PhantomJS
97
113
  email:
98
114
  - michi@netzpiraten.ch
@@ -110,7 +126,8 @@ files:
110
126
  - lib/guard/jasmine/templates/Guardfile
111
127
  - lib/guard/jasmine/version.rb
112
128
  - lib/guard/jasmine.rb
113
- - LICENSE
129
+ - LICENSE.MIT
130
+ - LICENSE.BSD
114
131
  - README.md
115
132
  homepage: http://github.com/netzpirat/guard-jasmine
116
133
  licenses: []