guard-mocha-node 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *~
2
+ *.gem
3
+ .bundle
4
+ Gemfile.lock
5
+ pkg/*
6
+ /.rvmrc
data/CHANGELOG.md ADDED
File without changes
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in guard-mocha-node.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,6 @@
1
+ guard 'rspec', :version => 2 do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
6
+
data/README.md ADDED
@@ -0,0 +1,135 @@
1
+ Guard::MochaNode
2
+ ==================
3
+
4
+ This is a fork of the Great work from [Dave Nolan](https://github.com/textgoeshere)
5
+ with his gem [Guard::JasmineNode](https://github.com/guard/guard-jasmine-node).
6
+ Only modified to work with mocha
7
+
8
+ ... and then I stole it from [[https://github.com/kanzeon/guard-mocha-node|kanzeon]], and I'd welcome them taking it back at any point :)
9
+
10
+ MochaNode guard automatically & intelligently executes mocha node specs when files are modified.
11
+
12
+ * Tested against Node 0.8.14, mocha 1.6.0
13
+
14
+ Requirements
15
+ ------------
16
+
17
+ * [Node](http://nodejs.org/)
18
+ * Mocha
19
+ * [Ruby](http://ruby-lang.org) and rubygems
20
+
21
+ Install
22
+ -------
23
+
24
+ Install the gem:
25
+
26
+ $ gem install guard-mocha-node
27
+
28
+ Add guard definition to your Guardfile by running this command:
29
+
30
+ $ guard init mocha-node
31
+
32
+ Usage
33
+ -----
34
+
35
+ $ guard
36
+
37
+ This will watch your project and execute your specs when files
38
+ change. It's worth checking out [the docs](https://github.com/guard/guard#readme).
39
+
40
+ Options
41
+ -------
42
+
43
+ * `:all_on_start # default => true`
44
+
45
+ Run all the specs as soon as Guard is started.
46
+
47
+ * `:all_after_pass # default => true`
48
+
49
+ When files are modified and the specs covering the modified files
50
+ pass, run all the specs automatically.
51
+
52
+ * `:keep_failed # default => true`
53
+
54
+ When files are modified, run failing specs as well as specs covering
55
+ the modified files.
56
+
57
+ * `:notify # default => true`
58
+
59
+ Display growl/libnotify notifications.
60
+
61
+ * `:coffeescript # default => true`
62
+
63
+ Load coffeescript and all execution of .coffee files.
64
+
65
+ * `:livescript # default => false`
66
+
67
+ Load livescript and all execution of .ls files.
68
+
69
+ * `:reporter # default => "spec"`
70
+
71
+ To select a mocha reporter
72
+
73
+ * `:require # default => nil`
74
+
75
+ Make mocha require the given modules, it should be a string or a array
76
+ of strings if multiple modules are to be required
77
+
78
+ * `:color # default => true`
79
+
80
+ Enable or disable the mocha color output
81
+
82
+ * `:recursive # default => true`
83
+
84
+ Enable or disable the recursive directory mocha option
85
+
86
+ * `:paths_for_all_specs # default => ['spec']`
87
+
88
+ Paths for run all specs
89
+
90
+ * `:globals # default => []`
91
+
92
+ Globals to ignore when performing global leak detection
93
+
94
+ * `:mocha_bin`
95
+
96
+ Specify the path to the jasmine-node binary that will execute your specs.
97
+
98
+ The default `:mocha_bin` in the Guardfile assumes:
99
+
100
+ * you are running guard from the root of the project
101
+ * you installed mocha using npm
102
+ * you installed mocha locally to node_modules
103
+
104
+ If you delete the option completely from the Guardfile, it assumes the
105
+ mocha binary is already in your `$PATH`.
106
+
107
+ So if you have installed jasmine-node globally using e.g. `npm install
108
+ -g mocha`, remove the `:mocha_bin` option from the Guardfile.
109
+
110
+ Guardfile
111
+ ---------
112
+
113
+ Please read the [guard docs](https://github.com/guard/guard#readme) for
114
+ more information about the Guardfile DSL.
115
+
116
+ It's powerful stuff.
117
+
118
+
119
+ TODO
120
+ ----
121
+
122
+ * write a JsonFormatter for jasmine-node so we have finer-grained
123
+ control over rendering output
124
+ * write an RSpec-style progress formatter (aka lots of green dots)
125
+ * patch Guard to locate CamelCased modules correctly
126
+
127
+ Testing
128
+ -------
129
+
130
+ $ rake
131
+
132
+ Author
133
+ ------
134
+
135
+ [Roberto Huelga Díaz](https://github.com/kanzeon)
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "guard/mocha_node/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "guard-mocha-node"
7
+ s.version = Guard::MochaNodeVersion::VERSION
8
+ s.authors = ["dave@kapoq.com", "David Schoen <dave@lyte.id.au>"]
9
+ s.email = ["dave@kapoq.com", "dave@lyte.id.au"]
10
+ s.homepage = "https://github.com/kanzeon/guard-mocha-node"
11
+ s.summary = %q{Guard::MochaNode automatically runs your Mocha Node specs when files are modified}
12
+ s.description = %q{}
13
+
14
+ s.rubyforge_project = "guard-mocha-node"
15
+
16
+ s.add_dependency "guard", ">= 0.4"
17
+
18
+ s.add_development_dependency "rspec"
19
+ s.add_development_dependency "guard-rspec"
20
+ s.add_development_dependency "rake"
21
+ if RUBY_PLATFORM =~ /linux/
22
+ s.add_development_dependency "rb-inotify"
23
+ s.add_development_dependency "libnotify"
24
+ end
25
+
26
+ s.files = `git ls-files`.split("\n")
27
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
28
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
29
+ s.require_paths = ["lib"]
30
+ end
@@ -0,0 +1,25 @@
1
+ require 'guard/mocha_node'
2
+
3
+ Guard::Mochanode = Guard::MochaNode
4
+
5
+ module Guard
6
+ class Mochanode < Guard
7
+ GEM_NAME = "mocha-node"
8
+
9
+ # Guardfile template needed inside guard gem
10
+ def self.init(name)
11
+ if ::Guard::Dsl.guardfile_include?(GEM_NAME)
12
+ ::Guard::UI.info "Guardfile already includes #{GEM_NAME} guard"
13
+ else
14
+ content = File.read('Guardfile')
15
+ guard = File.read("#{::Guard.locate_guard(GEM_NAME)}/lib/guard/mocha_node/templates/Guardfile")
16
+ File.open('Guardfile', 'wb') do |f|
17
+ f.puts(content)
18
+ f.puts("")
19
+ f.puts(guard)
20
+ end
21
+ ::Guard::UI.info "#{name} guard added to Guardfile, feel free to edit it"
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,90 @@
1
+ require 'open3'
2
+ require 'guard/ui'
3
+
4
+ module Guard
5
+ class MochaNode
6
+ module Runner
7
+ def self.run(paths = [], options = {})
8
+ return false if paths.empty?
9
+
10
+ @paths = paths
11
+ @options = options
12
+
13
+ print_message
14
+ execute_mocha_node_command
15
+ end
16
+
17
+ private
18
+
19
+ def self.print_message
20
+ message = @options[:message]
21
+ is_all_specs = @paths.sort == @options[:paths_for_all_specs].sort
22
+ message ||= is_all_specs ? "Running all specs" : "Running: #{@paths.join(' ')}"
23
+ ::Guard::UI.info(message, :reset => true)
24
+ end
25
+
26
+ def self.execute_mocha_node_command
27
+ ::Open3.popen3(*mocha_node_command)
28
+ end
29
+
30
+ def self.mocha_node_command
31
+ argvs = [ @options[:mocha_bin] ]
32
+ argvs += command_line_options
33
+ argvs += @paths
34
+ argvs.map(&:to_s)
35
+ end
36
+
37
+ def self.command_line_options
38
+ options = []
39
+ compilers = []
40
+
41
+ if @options[:coffeescript]
42
+ compilers << "coffee:coffee-script"
43
+ end
44
+
45
+ if @options[:livescript]
46
+ compilers << "ls:LiveScript"
47
+ end
48
+
49
+ if not compilers.empty?
50
+ options << "--compilers"
51
+ options << compilers.join(",")
52
+ end
53
+
54
+ if @options[:recursive]
55
+ options << "--recursive"
56
+ end
57
+
58
+ if @options[:require]
59
+ r = @options[:require]
60
+ r = [r] if not r.instance_of? Array
61
+
62
+ r.each { |e|
63
+ options << "-r"
64
+ options << e
65
+ }
66
+ end
67
+
68
+ if @options[:color]
69
+ options << "-c"
70
+ else
71
+ options << "-C"
72
+ end
73
+
74
+ if @options[:globals] and not @options[:globals].empty?
75
+ options << "--globals"
76
+ options << @options[:globals].join(',')
77
+ end
78
+
79
+ if @options[:reporter]
80
+ options << "--reporter"
81
+ options << @options[:reporter]
82
+ end
83
+
84
+ # puts "---- printing the options"
85
+ # puts options
86
+ options
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,73 @@
1
+ module Guard
2
+ class MochaNode
3
+ class SpecState
4
+ STDIN = 0
5
+ STDOUT = 1
6
+ STDERR = 2
7
+ THREAD = 3
8
+
9
+ SUCCESS_CODE = 0
10
+ ERROR_CODE = 1
11
+
12
+ attr_accessor :failing_paths
13
+
14
+ def initialize
15
+ clear!
16
+ end
17
+
18
+ def update(run_paths = [], options = {})
19
+ @run_paths = run_paths
20
+ @io = Runner.run(@run_paths, options)
21
+ @stdout = @io[STDOUT]
22
+ @stderr = @io[STDERR]
23
+ # stream stdout immediately
24
+ until @stdout.eof?
25
+ line = @stdout.gets
26
+ print line if !line.strip.empty?
27
+ end
28
+ @stderr.lines { |line| print line }
29
+ @exitstatus = @io[THREAD].value rescue ERROR_CODE
30
+ close_io
31
+ update_passed_and_fixed
32
+ update_failing_paths
33
+ passing?
34
+ end
35
+
36
+ def passing?
37
+ @passed
38
+ end
39
+
40
+ def fixed?
41
+ @fixed
42
+ end
43
+
44
+ def clear!
45
+ @passed = true
46
+ @fixed = false
47
+ @failing_paths = []
48
+ end
49
+
50
+ private
51
+
52
+ def close_io
53
+ @io[STDIN..STDERR].each { |s| s.close }
54
+ end
55
+
56
+ def update_passed_and_fixed
57
+ previously_failed = !passing?
58
+ @passed = @exitstatus == SUCCESS_CODE
59
+ @fixed = @passed && previously_failed
60
+ end
61
+
62
+ def update_failing_paths
63
+ if @run_paths.any?
64
+ @failing_paths = if passing?
65
+ @failing_paths - @run_paths
66
+ else
67
+ @failing_paths + @run_paths
68
+ end.uniq
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,17 @@
1
+ # Installed by guard-mocha-node
2
+
3
+ # JavaScript/CoffeeScript watchers
4
+
5
+ guard 'mocha-node', :mocha_bin => File.expand_path(File.dirname(__FILE__) + "/node_modules/mocha/bin/mocha") do
6
+ watch(%r{^spec/(.+)_spec\.(js\.coffee|js|coffee)}) { |m| "spec/#{m[1]}_spec.#{m[2]}" }
7
+ watch(%r{^lib/(.+)\.(js\.coffee|js|coffee)}) { |m| "spec/lib/#{m[1]}_spec.#{m[2]}" }
8
+ watch(%r{spec/spec_helper\.(js\.coffee|js|coffee)}) { "spec" }
9
+ end
10
+
11
+ # JavaScript only watchers
12
+ #
13
+ # guard "mocha-node", :mocha_bin => File.expand_path(File.dirname(__FILE__) + "/node_modules/mocha/bin/mocha") do
14
+ # watch(%r{^spec/.+_spec\.js$})
15
+ # watch(%r{^lib/(.+)\.js$}) { |m| "spec/lib/#{m[1]}_spec.js" }
16
+ # watch('spec/spec_helper.js')
17
+ # end
@@ -0,0 +1,5 @@
1
+ module Guard
2
+ module MochaNodeVersion
3
+ VERSION = "0.0.3"
4
+ end
5
+ end
@@ -0,0 +1,88 @@
1
+ require 'guard'
2
+ require 'guard/guard'
3
+
4
+ module Guard
5
+ class MochaNode < Guard
6
+ DEFAULT_OPTIONS = {
7
+ :mocha_bin => "mocha",
8
+ :all_after_pass => true,
9
+ :all_on_start => true,
10
+ :keep_failed => true,
11
+ :notify => true,
12
+ :coffeescript => true,
13
+ :livescript => false,
14
+ :verbose => true,
15
+ :reporter => "spec",
16
+ :color => true,
17
+ :recursive => true,
18
+ :require => nil,
19
+ :paths_for_all_specs => %w(spec),
20
+ :globals => []
21
+ }
22
+
23
+ autoload :Runner, "guard/mocha_node/runner"
24
+ autoload :SpecState, "guard/mocha_node/spec_state"
25
+
26
+ def initialize(watchers = [], options = {})
27
+ super(watchers, DEFAULT_OPTIONS.merge(options))
28
+ @state = SpecState.new
29
+ end
30
+
31
+ def start
32
+ run_all if options[:all_on_start]
33
+ end
34
+
35
+ def run_all
36
+ run( options[:paths_for_all_specs])
37
+ notify(:all)
38
+ end
39
+
40
+ def run_on_change(changed_paths = [])
41
+ run_paths = if options[:keep_failed]
42
+ failing_paths + changed_paths
43
+ else
44
+ changed_paths
45
+ end
46
+
47
+ run(run_paths)
48
+ notify(:some)
49
+
50
+ run_all if passing? and options[:all_after_pass]
51
+ end
52
+
53
+ def failing_paths
54
+ @state.failing_paths
55
+ end
56
+
57
+ def passing?
58
+ @state.passing?
59
+ end
60
+
61
+ def fixed?
62
+ @state.fixed?
63
+ end
64
+
65
+ private
66
+
67
+ def run(run_paths = [], runner_options = {}, notifications = {})
68
+ ::Guard::Notifier.notify "Guard mocha runs for #{run_paths.join(', ')}"
69
+ @state.update(run_paths, options.merge(runner_options))
70
+ end
71
+
72
+ def notify(scope = :all)
73
+ return unless options[:notify]
74
+
75
+ message = if passing?
76
+ if fixed?
77
+ scope == :all ? "All fixed" : "Specs fixed"
78
+ else
79
+ scope == :all ? "All specs pass" : "Specs pass"
80
+ end
81
+ else
82
+ "Some specs failing"
83
+ end
84
+ image = passing? ? :success : :failed
85
+ ::Guard::Notifier.notify(message, :image => image, :title => "mocha-node")
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,268 @@
1
+ require 'spec_helper'
2
+
3
+ describe Guard::MochaNode do
4
+ let(:state) { Guard::MochaNode::SpecState.new }
5
+ let(:guard) { Guard::MochaNode.new }
6
+
7
+ before do
8
+ Guard::MochaNode::SpecState.stub(:new => state)
9
+ Guard::Notifier.stub(:notify)
10
+ state.stub(:update => true)
11
+ end
12
+
13
+ describe "#initialize" do
14
+ context "when no options are given" do
15
+ it "sets a default path to mocha-node bin" do
16
+ guard.options[:mocha_bin].should eql "mocha"
17
+ end
18
+
19
+ it "sets :notify option to true" do
20
+ guard.options[:notify].should eql true
21
+ end
22
+
23
+ it "sets :all_after_pass option to true" do
24
+ guard.options[:all_after_pass].should be_true
25
+ end
26
+
27
+ it "sets :all_on_start option to true" do
28
+ guard.options[:all_on_start].should be_true
29
+ end
30
+
31
+ it "sets :keep_failed option to true" do
32
+ guard.options[:keep_failed].should be_true
33
+ end
34
+
35
+ it "sets :coffescript option to true" do
36
+ guard.options[:coffeescript].should be_true
37
+ end
38
+
39
+ it "sets :livescript option to true" do
40
+ guard.options[:livescript].should be_false
41
+ end
42
+
43
+ it "sets :verbose option to true" do
44
+ guard.options[:verbose].should be_true
45
+ end
46
+
47
+ it "sets :reporter option to 'spec'" do
48
+ guard.options[:reporter].should eql "spec"
49
+ end
50
+
51
+ it "sets :color option to true" do
52
+ guard.options[:color].should eql true
53
+ end
54
+
55
+ it "sets :recursive option to true" do
56
+ guard.options[:recursive].should eql true
57
+ end
58
+
59
+ it "sets :require option to nil" do
60
+ guard.options[:require].should_not be
61
+ end
62
+
63
+ it "sets :paths_for_all_specs option to ['spec']" do
64
+ guard.options[:paths_for_all_specs].should eql ['spec']
65
+ end
66
+
67
+ it "sets :globals option to []" do
68
+ guard.options[:globals].should eql []
69
+ end
70
+
71
+ it "is passing" do
72
+ guard.should be_passing
73
+ end
74
+
75
+ it "has no failing paths" do
76
+ guard.failing_paths.should be_empty
77
+ end
78
+ end
79
+
80
+ context "when options are given" do
81
+ let(:a_path) { "/foo/bar/mocha-node" }
82
+ let(:guard) { Guard::MochaNode.new([], {
83
+ :mocha_bin => a_path,
84
+ :all_on_start => false,
85
+ :all_after_pass => false,
86
+ :keep_failed => false,
87
+ :notify => false,
88
+ :coffeescript => false,
89
+ :livescript => true,
90
+ :reporter => 'spec',
91
+ :color => false,
92
+ :recursive => false,
93
+ :require => "should",
94
+ :paths_for_all_specs => %w(test),
95
+ :globals => ['Foo']
96
+ }) }
97
+
98
+ it "sets the path to mocha bin" do
99
+ guard.options[:mocha_bin].should eql a_path
100
+ end
101
+
102
+ it "sets the :notify option" do
103
+ guard.options[:notify].should be_false
104
+ end
105
+
106
+ it "sets the :all_after_pass option" do
107
+ guard.options[:all_after_pass].should be_false
108
+ end
109
+
110
+ it "sets the :all_on_start option" do
111
+ guard.options[:all_on_start].should be_false
112
+ end
113
+
114
+ it "sets the :keep_failed option" do
115
+ guard.options[:keep_failed].should be_false
116
+ end
117
+
118
+ it "sets the :coffeescript option" do
119
+ guard.options[:coffeescript].should be_false
120
+ end
121
+
122
+ it "sets the :livescript option" do
123
+ guard.options[:livescript].should be_true
124
+ end
125
+
126
+ it "sets the :reporter option" do
127
+ guard.options[:reporter].should eql 'spec'
128
+ end
129
+ it "sets the :color option" do
130
+ guard.options[:color].should be_false
131
+ end
132
+ it "sets the :recursive option" do
133
+ guard.options[:recursive].should be_false
134
+ end
135
+ it "sets the :require option" do
136
+ guard.options[:require].should eql "should"
137
+ end
138
+ it "sets the :paths_for_all_specs option" do
139
+ guard.options[:paths_for_all_specs].should eql ['test']
140
+ end
141
+ it "sets the :globals option" do
142
+ guard.options[:globals].should eql ['Foo']
143
+ end
144
+ end
145
+ end
146
+
147
+ describe "#start" do
148
+ context "when :all_on_start is true" do
149
+ it "runs all" do
150
+ guard.should_receive(:run_all)
151
+ guard.start
152
+ end
153
+ end
154
+
155
+ context "when :all_on_start is false" do
156
+ let(:guard) { Guard::MochaNode.new([], { :all_on_start => false }) }
157
+
158
+ it "does not run all" do
159
+ guard.should_not_receive(:run_all)
160
+ guard.start
161
+ end
162
+ end
163
+ end
164
+
165
+ describe "#run_all" do
166
+ it "updates the state with the specs in the spec dir" do
167
+ state.should_receive(:update).with(["spec"], anything)
168
+ guard.run_all
169
+ end
170
+
171
+ it "passes the options through to the state" do
172
+ an_option = { :option => "value" }
173
+ guard.options.update(an_option)
174
+ state.should_receive(:update).with(anything, hash_including(an_option))
175
+ guard.run_all
176
+ end
177
+
178
+ it "notifies the user with the outcome of running all specs" do
179
+ guard.should_receive(:notify).with(:all)
180
+ guard.run_all
181
+ end
182
+ end
183
+
184
+ describe "#run_on_change" do
185
+ before do
186
+ guard.options[:all_after_pass] = false
187
+ end
188
+
189
+ it "updates the state with paths" do
190
+ state.should_receive(:update).with(["/a/path"], anything)
191
+ guard.run_on_change(["/a/path"])
192
+ end
193
+
194
+ it "passes options through to the state" do
195
+ an_option = { :option => "value" }
196
+ guard.options.update(an_option)
197
+ state.should_receive(:update).with(anything, hash_including(an_option))
198
+ guard.run_on_change
199
+ end
200
+
201
+ it "notifies the user with the outcome of running the specs" do
202
+ guard.should_receive(:notify).with(:some)
203
+ guard.run_on_change
204
+ end
205
+
206
+ context "when specs pass" do
207
+ before do
208
+ guard.stub(:passing? => true)
209
+ end
210
+
211
+ context "and :all_after_pass is true" do
212
+ before do
213
+ guard.options[:all_after_pass] = true
214
+ end
215
+
216
+ it "runs all" do
217
+ guard.should_receive(:run_all)
218
+ guard.run_on_change
219
+ end
220
+ end
221
+
222
+ context "and :all_after_pass is false" do
223
+ before do
224
+ guard.options[:all_after_pass] = false
225
+ end
226
+
227
+ context "if :all_after_pass is true" do
228
+ it "does not run all" do
229
+ guard.should_not_receive(:run_all)
230
+ guard.run_on_change
231
+ end
232
+ end
233
+ end
234
+ end
235
+
236
+ context "when there are failing paths" do
237
+ let(:failing_paths) { %w(foo/bar zip/zap) }
238
+ let(:changed_paths) { %w(aaa/bbb ccc/ddd) }
239
+ let(:all_paths) { failing_paths + changed_paths }
240
+
241
+ before do
242
+ guard.stub(:failing_paths => failing_paths)
243
+ end
244
+
245
+ context "and :keep_failed is true" do
246
+ before do
247
+ guard.options[:keep_failed] = true
248
+ end
249
+
250
+ it "updates state with failing paths and the changed paths" do
251
+ state.should_receive(:update).with(all_paths, anything)
252
+ guard.run_on_change(changed_paths)
253
+ end
254
+ end
255
+
256
+ context "and :keep_failed is false" do
257
+ before do
258
+ guard.options[:keep_failed] = false
259
+ end
260
+
261
+ it "updates state with only the changed paths" do
262
+ state.should_receive(:update).with(changed_paths, anything)
263
+ guard.run_on_change(changed_paths)
264
+ end
265
+ end
266
+ end
267
+ end
268
+ end
@@ -0,0 +1,231 @@
1
+ require 'spec_helper'
2
+
3
+ describe Guard::MochaNode::Runner do
4
+ let(:runner) { Guard::MochaNode::Runner }
5
+
6
+ before do
7
+ Open3.stub(:popen3 => "response")
8
+ end
9
+
10
+ describe ".run" do
11
+ let(:options) { { :paths_for_all_specs => %w(spec)} }
12
+ context "when passed no paths" do
13
+ it "returns false" do
14
+ runner.run.should be_false
15
+ end
16
+ end
17
+
18
+ context "when passed paths" do
19
+ let(:some_paths) { %w(/foo/bar /zip/zap) }
20
+
21
+ it "executes mocha node" do
22
+ Open3.should_receive(:popen3) do |*args|
23
+ args[0].should eq "__EXECUTABLE__"
24
+ end
25
+ runner.run(some_paths, options.merge({ :mocha_bin => "__EXECUTABLE__"}))
26
+ end
27
+
28
+ it "passes the paths to the executable" do
29
+ Open3.should_receive(:popen3) do |*args|
30
+ last_args = args[(some_paths.length * -1)..(-1)]
31
+ last_args.should eql some_paths
32
+ end
33
+ runner.run(some_paths, options)
34
+ end
35
+
36
+ context "and coffeescript option is true" do
37
+ it "passes the --compilers coffee:coffee-script option to mocha node" do
38
+ Open3.should_receive(:popen3) do |*args|
39
+ index_compilers = args.find_index "--compilers"
40
+ index_compilers.should_not be nil
41
+ args[index_compilers +1].should eql "coffee:coffee-script"
42
+ end
43
+ runner.run(some_paths, options.merge({ :coffeescript => true}))
44
+ end
45
+ end
46
+
47
+ context "and coffeescript option is false" do
48
+ it "does not pass the --compilers coffee:coffee-script option to mocha node" do
49
+ Open3.should_receive(:popen3) do |*args|
50
+ index_compilers = args.find_index "--compilers"
51
+ if index_compilers != nil
52
+ args[index_compilers +1].should_not match /coffee:coffee-script/
53
+ end
54
+ end
55
+ runner.run(some_paths, options.merge({ :coffeescript => false}))
56
+ end
57
+ end
58
+
59
+ context "and livescript option is true" do
60
+ it "passes the --compilers ls:LiveScript option to mocha node" do
61
+ Open3.should_receive(:popen3) do |*args|
62
+ index_compilers = args.find_index "--compilers"
63
+ index_compilers.should_not be nil
64
+ args[index_compilers +1].should eql "ls:LiveScript"
65
+ end
66
+ runner.run(some_paths, options.merge({ :livescript => true}))
67
+ end
68
+ end
69
+
70
+ context "and livescript option is false" do
71
+ it "does not pass the --compilers ls:LiveScript option to mocha node" do
72
+ Open3.should_receive(:popen3) do |*args|
73
+ index_compilers = args.find_index "--compilers"
74
+ if index_compilers != nil
75
+ args[index_compilers +1].should_not match /ls:LiveScript/
76
+ end
77
+ end
78
+ runner.run(some_paths, options.merge({ :livescript => false}))
79
+ end
80
+ end
81
+
82
+ context "and both coffeescript and livescript option are true" do
83
+ it "passes the --compilers coffee:coffee-script,ls:LiveScript option to mocha node" do
84
+ Open3.should_receive(:popen3) do |*args|
85
+ index_compilers = args.find_index "--compilers"
86
+ index_compilers.should_not be nil
87
+ args[index_compilers +1].should eql "coffee:coffee-script,ls:LiveScript"
88
+ end
89
+ runner.run(some_paths, options.merge({ :livescript => true, :coffeescript => true }))
90
+ end
91
+ end
92
+
93
+ context "and color option is true" do
94
+ it "passes the -c option to mocha node" do
95
+ Open3.should_receive(:popen3) do |*args|
96
+ args.should include "-c"
97
+ end
98
+ runner.run(some_paths, options.merge({ :color => true}))
99
+ end
100
+ end
101
+
102
+ context "and color option is false" do
103
+ it "passes the -C option to mocha node" do
104
+ Open3.should_receive(:popen3) do |*args|
105
+ args.should include "-C"
106
+ end
107
+ runner.run(some_paths, options.merge({ :color => false}))
108
+ end
109
+ end
110
+
111
+ context "and globals option is set" do
112
+ it "passes the --globals option to mocha node" do
113
+ Open3.should_receive(:popen3) do |*args|
114
+ args.should include("--globals", "Foo")
115
+ # ensure ordering
116
+ args[args.index("--globals") + 1].should eql("Foo")
117
+ end
118
+ runner.run(some_paths, options.merge({ :globals => ['Foo']}))
119
+ end
120
+ end
121
+
122
+ context "and globals option is empty" do
123
+ it "does not pass the --globals option to mocha node" do
124
+ Open3.should_receive(:popen3) do |*args|
125
+ args.should_not include "--globals"
126
+ end
127
+ runner.run(some_paths, options.merge({ :globals => []}))
128
+ end
129
+ end
130
+
131
+ context "and reporter option is set" do
132
+ it "passes the --reporter option to mocha node" do
133
+ Open3.should_receive(:popen3) do |*args|
134
+ args.should include("--reporter", "Foo")
135
+ # ensure ordering
136
+ args[args.index("--reporter") + 1].should eql("Foo")
137
+ end
138
+ runner.run(some_paths, options.merge({ :reporter => 'Foo' }))
139
+ end
140
+ end
141
+
142
+ context "and reporter option is not set" do
143
+ it "does not pass the --reporter option to mocha node" do
144
+ Open3.should_receive(:popen3) do |*args|
145
+ args.should_not include "--reporter"
146
+ end
147
+ runner.run(some_paths, options)
148
+ end
149
+ end
150
+
151
+ context "and recursive option is true" do
152
+ it "passes the --recursive option to mocha node" do
153
+ Open3.should_receive(:popen3) do |*args|
154
+ args.should include "--recursive"
155
+ end
156
+ runner.run(some_paths, options.merge({ :recursive => true}))
157
+ end
158
+ end
159
+
160
+ context "and recursive option is false" do
161
+ it "does not pass the --recursive option to mocha node" do
162
+ Open3.should_receive(:popen3) do |*args|
163
+ args.should_not include "--recursive"
164
+ end
165
+ runner.run(some_paths, options.merge({ :recursive => false}))
166
+ end
167
+ end
168
+
169
+ context "and require option is 'should'" do
170
+ it "passes the '-r should' option to mocha node" do
171
+ Open3.should_receive(:popen3) do |*args|
172
+ require_index = args.find_index '-r'
173
+ require_index.should_not eq nil
174
+ args[require_index+1].should eql "should"
175
+ end
176
+ runner.run(some_paths, options.merge({ :require => 'should'}))
177
+ end
178
+ end
179
+
180
+ context "and require option is ['should', 'chai']" do
181
+ it "passes the '-r should -r chai' option to mocha node" do
182
+ Open3.should_receive(:popen3) do |*args|
183
+ args.each_with_index.
184
+ reject{ |e,i| e != '-r' }.
185
+ map{ |e,i| args[i+1] }.should eql ["should", "chai"]
186
+
187
+ end
188
+ runner.run(some_paths, options.merge({ :require => ['should', 'chai'] }))
189
+ end
190
+ end
191
+
192
+ context "and require option is nil" do
193
+ it "does not pass the -r option to mocha node" do
194
+ Open3.should_receive(:popen3) do |*args|
195
+ args.should_not include "-r"
196
+ end
197
+ runner.run(some_paths, options.merge({ :require => nil}))
198
+ end
199
+ end
200
+
201
+ it "returns IO object" do
202
+ io_obj = double("io obj")
203
+ Open3.stub(:popen3 => io_obj)
204
+ runner.run(some_paths, options).should eql io_obj
205
+ end
206
+
207
+ context "when message option is given" do
208
+ it "outputs message" do
209
+ Guard::UI.should_receive(:info).with("hello", anything)
210
+ runner.run(some_paths, options.merge({ :message => "hello"}))
211
+ end
212
+ end
213
+
214
+ context "when no message option is given" do
215
+ context "and running all specs" do
216
+ it "outputs message confirming all specs are being run" do
217
+ Guard::UI.should_receive(:info).with("Running all specs", anything)
218
+ runner.run(%w(spec), options )
219
+ end
220
+ end
221
+
222
+ context "and running some specs" do
223
+ it "outputs paths of specs being run" do
224
+ Guard::UI.should_receive(:info).with("Running: /foo/bar /zip/zap", anything)
225
+ runner.run(some_paths, options)
226
+ end
227
+ end
228
+ end
229
+ end
230
+ end
231
+ end
@@ -0,0 +1,127 @@
1
+ require 'spec_helper'
2
+
3
+ describe Guard::MochaNode::SpecState do
4
+ let(:state) { Guard::MochaNode::SpecState.new }
5
+ let(:runner) { Guard::MochaNode::Runner }
6
+
7
+ describe "#initialize" do
8
+ it "is passing" do
9
+ state.should be_passing
10
+ end
11
+
12
+ it "has no failing paths" do
13
+ state.failing_paths.should be_empty
14
+ end
15
+
16
+ it "is has not been fixed" do
17
+ state.should_not be_fixed
18
+ end
19
+ end
20
+
21
+ describe "#update" do
22
+ let(:io) { [
23
+ double("stdin", :close => true),
24
+ double("stdout", :close => true, :lines => [], :eof? => true),
25
+ double("stderr", :close => true, :lines => []),
26
+ double("thread", :value => 0)
27
+ ] }
28
+ let(:some_paths) { %w(some paths) }
29
+ let(:some_options) { double("some options") }
30
+
31
+ before do
32
+ runner.stub(:run => io)
33
+ end
34
+
35
+ it "runs the runner with the paths and options" do
36
+ runner.should_receive(:run).with(some_paths, some_options).and_return(io)
37
+ state.update(some_paths, some_options)
38
+ end
39
+
40
+ it "closes stdin, stdout, and stderr of the subprocess" do
41
+ io[0..2].each { |i| i.should_receive(:close) }
42
+ state.update
43
+ end
44
+
45
+ context "when the runner process exit value is zero" do
46
+ before do
47
+ io[3].stub(:value => 0)
48
+ state.update
49
+ end
50
+
51
+ it "is passing" do
52
+ state.should be_passing
53
+ end
54
+
55
+ context "and there are run paths" do
56
+ it "removes the run paths from the failing paths" do
57
+ state.failing_paths = %w(/keep /remove)
58
+ state.update(%w(/remove))
59
+ state.failing_paths.should eql %w(/keep)
60
+ end
61
+ end
62
+
63
+ context "and there are no run paths" do
64
+ it "does not change the current failing paths" do
65
+ original_failing_paths = %w(/keep1 /keep2)
66
+ state.failing_paths = original_failing_paths
67
+ state.update
68
+ state.failing_paths.should eql original_failing_paths
69
+ end
70
+ end
71
+
72
+ context "and the previous spec failed" do
73
+ before do
74
+ state.stub(:passing? => false)
75
+ state.update
76
+ end
77
+
78
+ it "is fixed" do
79
+ state.should be_fixed
80
+ end
81
+ end
82
+
83
+ context "and the previous spec passed" do
84
+ before do
85
+ state.stub(:passing? => true)
86
+ state.update
87
+ end
88
+
89
+ it "is not fixed" do
90
+ state.should_not be_fixed
91
+ end
92
+ end
93
+ end
94
+
95
+ context "when the runner process exit value is not zero" do
96
+ before do
97
+ io[3].stub(:value => 1)
98
+ state.update(some_paths, some_options)
99
+ end
100
+
101
+ it "is not passing" do
102
+ state.should_not be_passing
103
+ end
104
+
105
+ it "is not fixed" do
106
+ state.should_not be_fixed
107
+ end
108
+
109
+ context "and there are run paths" do
110
+ it "updates the failing paths with the union of the failing paths and the run paths" do
111
+ state.failing_paths = %w(/dupe /other)
112
+ state.update(%w(/dupe /another))
113
+ state.failing_paths.should =~ %w(/dupe /other /another)
114
+ end
115
+ end
116
+
117
+ context "and there are no run paths" do
118
+ it "does not change the current failing paths" do
119
+ original_failing_paths = %w(/keep1 /keep2)
120
+ state.failing_paths = original_failing_paths
121
+ state.update
122
+ state.failing_paths.should eql original_failing_paths
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,17 @@
1
+ require 'rspec'
2
+ require 'guard/mocha_node'
3
+
4
+ RSpec.configure do |config|
5
+ config.color_enabled = true
6
+ config.filter_run :focus => true
7
+ config.run_all_when_everything_filtered = true
8
+
9
+ config.before do
10
+ ENV["GUARD_ENV"] = "test"
11
+ @project_path = Pathname.new(File.expand_path("../../", __FILE__))
12
+ end
13
+
14
+ config.after do
15
+ ENV["GUARD_ENV"] = nil
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: guard-mocha-node
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - dave@kapoq.com
9
+ - David Schoen <dave@lyte.id.au>
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-04-21 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: guard
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0.4'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0.4'
31
+ - !ruby/object:Gem::Dependency
32
+ name: rspec
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :development
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: guard-rspec
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ - !ruby/object:Gem::Dependency
64
+ name: rake
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ - !ruby/object:Gem::Dependency
80
+ name: rb-inotify
81
+ requirement: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ type: :development
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ - !ruby/object:Gem::Dependency
96
+ name: libnotify
97
+ requirement: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: ''
112
+ email:
113
+ - dave@kapoq.com
114
+ - dave@lyte.id.au
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - .gitignore
120
+ - CHANGELOG.md
121
+ - Gemfile
122
+ - Guardfile
123
+ - README.md
124
+ - Rakefile
125
+ - guard-mocha-node.gemspec
126
+ - lib/guard/mocha-node.rb
127
+ - lib/guard/mocha_node.rb
128
+ - lib/guard/mocha_node/runner.rb
129
+ - lib/guard/mocha_node/spec_state.rb
130
+ - lib/guard/mocha_node/templates/Guardfile
131
+ - lib/guard/mocha_node/version.rb
132
+ - spec/lib/mocha_node_spec.rb
133
+ - spec/lib/runner_spec.rb
134
+ - spec/lib/spec_state_spec.rb
135
+ - spec/spec_helper.rb
136
+ homepage: https://github.com/kanzeon/guard-mocha-node
137
+ licenses: []
138
+ post_install_message:
139
+ rdoc_options: []
140
+ require_paths:
141
+ - lib
142
+ required_ruby_version: !ruby/object:Gem::Requirement
143
+ none: false
144
+ requirements:
145
+ - - ! '>='
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ none: false
150
+ requirements:
151
+ - - ! '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ requirements: []
155
+ rubyforge_project: guard-mocha-node
156
+ rubygems_version: 1.8.23
157
+ signing_key:
158
+ specification_version: 3
159
+ summary: Guard::MochaNode automatically runs your Mocha Node specs when files are
160
+ modified
161
+ test_files: []