guard-motion 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,9 @@
1
+ ## 0.1.1 - September 11, 2012
2
+
3
+ ### Improvements
4
+
5
+ - Use PTY and parse results for notification (by [@mattgreen](https://github.com/mattgreen))
6
+
7
+ ## 0.1.0 - August 10, 2012
8
+
9
+ - Initial release
@@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
18
18
  gem.add_dependency 'guard', '>= 1.1.0'
19
19
  gem.add_dependency 'rake', '>= 0.9'
20
20
 
21
- gem.add_development_dependency 'bundler', '~> 1.1.0'
21
+ gem.add_development_dependency 'bundler', '>= 1.1.0'
22
22
  gem.add_development_dependency 'rspec', '~> 2.10'
23
23
  gem.add_development_dependency 'guard-rspec', '~> 1.1'
24
24
  end
@@ -5,7 +5,8 @@ require 'guard/motion/tasks'
5
5
 
6
6
  module Guard
7
7
  class Motion < Guard
8
- autoload :Runner, 'guard/motion/runner'
8
+ autoload :ResultsParser, 'guard/motion/results_parser'
9
+ autoload :Runner, 'guard/motion/runner'
9
10
 
10
11
  # Initialize a Guard.
11
12
  # @param [Array<Guard::Watcher>] watchers the Guard file watchers
@@ -0,0 +1,28 @@
1
+ module Guard
2
+ class Motion
3
+ class ResultsParser
4
+ attr_reader :errors
5
+ attr_reader :failures
6
+ attr_reader :specs
7
+
8
+ def parse(output)
9
+ matched = false
10
+
11
+ stats_regex = /(\d+) (tests|specifications),? \(?\d+ (assertions|requirements)\)?, (\d+) failures, (\d+) errors/
12
+ stats_regex.match(output) do |m|
13
+ matched = true
14
+
15
+ @specs = m[1].to_i
16
+ @failures = m[4].to_i
17
+ @errors = m[5].to_i
18
+ end
19
+
20
+ matched
21
+ end
22
+
23
+ def success?
24
+ errors == 0 && failures == 0
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,7 +1,8 @@
1
+ require 'pty'
2
+
1
3
  module Guard
2
4
  class Motion
3
5
  class Runner
4
-
5
6
  def initialize(options = {})
6
7
  @options = {
7
8
  :bundler => true,
@@ -22,7 +23,27 @@ module Guard
22
23
 
23
24
  UI.info(message, :reset => true)
24
25
 
25
- run_via_shell rake_command(paths)
26
+ output = run_via_pty rake_command(paths)
27
+
28
+ if @options[:notification]
29
+ notify(output)
30
+ end
31
+ end
32
+
33
+ def notify(output)
34
+ message = "Failed"
35
+ type = :failed
36
+
37
+ parser = ResultsParser.new
38
+ if parser.parse(output)
39
+ message = "#{parser.specs} specs, #{parser.failures} failures, #{parser.errors} errors"
40
+ end
41
+
42
+ if parser.success?
43
+ type = :success
44
+ end
45
+
46
+ Notifier.notify(message, :type => type, :image => type, :title => 'RubyMotion Spec Results', :priority => 2)
26
47
  end
27
48
 
28
49
  def rake_executable
@@ -39,14 +60,24 @@ module Guard
39
60
  cmd_parts.compact.join(' ')
40
61
  end
41
62
 
42
- def run_via_shell(command)
43
- success = system(command)
63
+ def run_via_pty(command)
64
+ output = ""
65
+
66
+ PTY.spawn(command) do |r, w, pid|
67
+ begin
68
+ loop do
69
+ chunk = r.readpartial(1024)
70
+ output += chunk
71
+
72
+ print chunk
73
+ end
74
+ rescue EOFError
75
+ end
44
76
 
45
- if @options[:notification] && !success
46
- Notifier.notify("Failed", :title => "Motion spec results", :image => :failed, :priority => 2)
77
+ Process.wait(pid)
47
78
  end
48
79
 
49
- success
80
+ output
50
81
  end
51
82
 
52
83
  def all_spec_paths
@@ -92,4 +123,4 @@ module Guard
92
123
  end
93
124
  end
94
125
  end
95
- end
126
+ end
@@ -1,5 +1,5 @@
1
1
  module Guard
2
2
  module MotionVersion
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.1"
4
4
  end
5
5
  end
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+
3
+ module Guard
4
+ class Motion
5
+ describe ResultsParser do
6
+ describe "#parse" do
7
+ before do
8
+ @result = subject.parse(output)
9
+ end
10
+
11
+ context "when the output contains spec output" do
12
+ context "and specs failed" do
13
+ let(:output) { ".................FFF...\n18 tests, 21 assertions, 3 failures, 1 errors\n" }
14
+
15
+ it "returns true" do
16
+ @result.should be_true
17
+ end
18
+
19
+ it "does not consider it successful" do
20
+ subject.success?.should be_false
21
+ end
22
+
23
+ it "returns the number of tests run" do
24
+ subject.specs.should == 18
25
+ end
26
+
27
+ it "returns the number of failures" do
28
+ subject.failures.should == 3
29
+ end
30
+
31
+ it "returns the number of errors" do
32
+ subject.errors.should == 1
33
+ end
34
+ end
35
+
36
+ context "and specs passed" do
37
+ let(:output) { ".................FFF...\n18 tests, 21 assertions, 0 failures, 0 errors\n" }
38
+
39
+ it "returns true" do
40
+ @result.should be_true
41
+ end
42
+
43
+ it "considers the test run successful" do
44
+ subject.success?.should be_true
45
+ end
46
+
47
+ it "returns the number of tests run" do
48
+ subject.specs.should == 18
49
+ end
50
+
51
+ it "returns the number of failures" do
52
+ subject.failures.should == 0
53
+ end
54
+
55
+ it "returns the number of errors" do
56
+ subject.errors.should == 0
57
+ end
58
+ end
59
+ end
60
+
61
+ context "when the output does not contain spec output" do
62
+ let(:output) { "" }
63
+
64
+ it "returns false" do
65
+ @result.should be_false
66
+ end
67
+
68
+ it "does not consider the test successful" do
69
+ subject.success?.should be_false
70
+ end
71
+
72
+ it "returns nil for test count" do
73
+ subject.specs.should_not be
74
+ end
75
+
76
+ it "returns nil for failure count" do
77
+ subject.failures.should_not be
78
+ end
79
+
80
+ it "returns nil for error count" do
81
+ subject.errors.should_not be
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -6,6 +6,14 @@ module Guard
6
6
  describe Runner do
7
7
  subject { described_class.new }
8
8
 
9
+ let(:output) { "..............................\n\n31 tests, 35 assertions, 2 failures, 0 errors\n" }
10
+
11
+ before do
12
+ PTY.stub(:spawn).and_yield(StringIO.new(output), StringIO.new, 123)
13
+ subject.stub(:print)
14
+ Process.stub(:wait)
15
+ end
16
+
9
17
  describe '#run' do
10
18
  context 'when passed an empty paths list' do
11
19
  it 'returns false' do
@@ -19,9 +27,9 @@ module Guard
19
27
  end
20
28
 
21
29
  it 'runs without bundler' do
22
- subject.should_receive(:system).with(
30
+ PTY.should_receive(:spawn).with(
23
31
  "rake spec:specific[\"something\"]"
24
- ).and_return(true)
32
+ )
25
33
 
26
34
  subject.run(['something'])
27
35
  end
@@ -33,28 +41,47 @@ module Guard
33
41
  end
34
42
 
35
43
  it 'runs with Bundler' do
36
- subject.should_receive(:system).with(
44
+ PTY.should_receive(:spawn).with(
37
45
  "bundle exec rake spec:specific[\"something\"]"
38
- ).and_return(true)
46
+ )
39
47
 
40
48
  subject.run(['something'])
41
49
  end
42
50
 
43
51
  describe 'notification' do
44
- it 'notifies when Motion specs fails to execute' do
45
- subject.should_receive(:rake_command) { "`exit 1`" }
46
- ::Guard::Notifier.should_receive(:notify).with(
47
- 'Failed', :title => 'Motion spec results', :image => :failed, :priority => 2
48
- )
52
+ context "when the specs fail to execute" do
53
+ let(:output) { "" }
54
+
55
+ it "sends a failure notification" do
56
+ ::Guard::Notifier.should_receive(:notify).with(
57
+ 'Failed', :title => 'RubyMotion Spec Results', :type => :failed, :image => :failed, :priority => 2
58
+ )
59
+
60
+ subject.run(['spec'])
61
+ end
62
+ end
49
63
 
50
- subject.run(['spec'])
64
+ context "when the specs fail" do
65
+ let(:output) { "..............................\n\n31 tests, 35 assertions, 2 failures, 0 errors\n" }
66
+
67
+ it "sends a spec failed notification" do
68
+ ::Guard::Notifier.should_receive(:notify).with(
69
+ '31 specs, 2 failures, 0 errors', :title => 'RubyMotion Spec Results', :type => :failed, :image => :failed, :priority => 2)
70
+
71
+ subject.run(["spec"])
72
+ end
51
73
  end
52
74
 
53
- it 'does not notify that Motion specs failed when the specs pass' do
54
- subject.should_receive(:rake_command) { "`exit 0`" }
55
- ::Guard::Notifier.should_not_receive(:notify)
75
+ context "when specs pass" do
76
+ let(:output) { "..............................\n\n31 tests, 35 assertions, 0 failures, 0 errors\n" }
77
+
78
+ it "sends a success notification" do
79
+ ::Guard::Notifier.should_receive(:notify).with(
80
+ '31 specs, 0 failures, 0 errors', :title => 'RubyMotion Spec Results', :type => :success, :image => :success, :priority => 2
81
+ )
56
82
 
57
- subject.run(['spec'])
83
+ subject.run(['spec'])
84
+ end
58
85
  end
59
86
  end
60
87
 
@@ -65,9 +92,9 @@ module Guard
65
92
  subject { described_class.new(:bundler => false) }
66
93
 
67
94
  it 'runs without Bundler' do
68
- subject.should_receive(:system).with(
95
+ PTY.should_receive(:spawn).with(
69
96
  "rake spec:specific[\"spec\"]"
70
- ).and_return(true)
97
+ )
71
98
 
72
99
  subject.run(['spec'])
73
100
  end
@@ -79,9 +106,9 @@ module Guard
79
106
  subject { described_class.new(:bundler => false, :binstubs => true) }
80
107
 
81
108
  it 'runs without Bundler and with binstubs' do
82
- subject.should_receive(:system).with(
109
+ PTY.should_receive(:spawn).with(
83
110
  "bin/rake spec:specific[\"spec\"]"
84
- ).and_return(true)
111
+ )
85
112
 
86
113
  subject.run(['spec'])
87
114
  end
@@ -91,9 +118,9 @@ module Guard
91
118
  subject { described_class.new(:bundler => true, :binstubs => true) }
92
119
 
93
120
  it 'runs without Bundler and binstubs' do
94
- subject.should_receive(:system).with(
121
+ PTY.should_receive(:spawn).with(
95
122
  "bin/rake spec:specific[\"spec\"]"
96
- ).and_return(true)
123
+ )
97
124
 
98
125
  subject.run(['spec'])
99
126
  end
@@ -103,9 +130,9 @@ module Guard
103
130
  subject { described_class.new(:bundler => true, :binstubs => 'dir') }
104
131
 
105
132
  it 'runs without Bundler and binstubs in custom directory' do
106
- subject.should_receive(:system).with(
133
+ PTY.should_receive(:spawn).with(
107
134
  "dir/rake spec:specific[\"spec\"]"
108
- ).and_return(true)
135
+ )
109
136
 
110
137
  subject.run(['spec'])
111
138
  end
@@ -117,15 +144,18 @@ module Guard
117
144
  subject { described_class.new(:notification => false) }
118
145
 
119
146
  it 'runs without notification formatter' do
120
- subject.should_receive(:system).with(
147
+ PTY.should_receive(:spawn).with(
121
148
  "bundle exec rake spec:specific[\"spec\"]"
122
- ).and_return(true)
149
+ )
123
150
 
124
151
  subject.run(['spec'])
125
152
  end
126
153
 
127
154
  it "doesn't notify when specs fails" do
128
- subject.should_receive(:system) { mock('res', :success? => false, :exitstatus => 2) }
155
+ PTY.should_receive(:spawn).with(
156
+ "bundle exec rake spec:specific[\"spec\"]"
157
+ )
158
+
129
159
  ::Guard::Notifier.should_not_receive(:notify)
130
160
 
131
161
  subject.run(['spec'])
@@ -137,4 +167,4 @@ module Guard
137
167
  end
138
168
  end
139
169
  end
140
- end
170
+ end
metadata CHANGED
@@ -1,80 +1,112 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: guard-motion
3
- version: !ruby/object:Gem::Version
4
- version: 0.1.0
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 1
10
+ version: 0.1.1
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - mordaroso
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-08-10 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2012-09-11 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
15
21
  name: guard
16
- requirement: &70212465443740 !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
17
24
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 19
29
+ segments:
30
+ - 1
31
+ - 1
32
+ - 0
21
33
  version: 1.1.0
22
34
  type: :runtime
23
- prerelease: false
24
- version_requirements: *70212465443740
25
- - !ruby/object:Gem::Dependency
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
26
37
  name: rake
27
- requirement: &70212465459540 !ruby/object:Gem::Requirement
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
28
40
  none: false
29
- requirements:
30
- - - ! '>='
31
- - !ruby/object:Gem::Version
32
- version: '0.9'
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 25
45
+ segments:
46
+ - 0
47
+ - 9
48
+ version: "0.9"
33
49
  type: :runtime
34
- prerelease: false
35
- version_requirements: *70212465459540
36
- - !ruby/object:Gem::Dependency
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
37
52
  name: bundler
38
- requirement: &70212465459040 !ruby/object:Gem::Requirement
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
39
55
  none: false
40
- requirements:
41
- - - ~>
42
- - !ruby/object:Gem::Version
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 19
60
+ segments:
61
+ - 1
62
+ - 1
63
+ - 0
43
64
  version: 1.1.0
44
65
  type: :development
45
- prerelease: false
46
- version_requirements: *70212465459040
47
- - !ruby/object:Gem::Dependency
66
+ version_requirements: *id003
67
+ - !ruby/object:Gem::Dependency
48
68
  name: rspec
49
- requirement: &70212465458440 !ruby/object:Gem::Requirement
69
+ prerelease: false
70
+ requirement: &id004 !ruby/object:Gem::Requirement
50
71
  none: false
51
- requirements:
72
+ requirements:
52
73
  - - ~>
53
- - !ruby/object:Gem::Version
54
- version: '2.10'
74
+ - !ruby/object:Gem::Version
75
+ hash: 23
76
+ segments:
77
+ - 2
78
+ - 10
79
+ version: "2.10"
55
80
  type: :development
56
- prerelease: false
57
- version_requirements: *70212465458440
58
- - !ruby/object:Gem::Dependency
81
+ version_requirements: *id004
82
+ - !ruby/object:Gem::Dependency
59
83
  name: guard-rspec
60
- requirement: &70212465457840 !ruby/object:Gem::Requirement
84
+ prerelease: false
85
+ requirement: &id005 !ruby/object:Gem::Requirement
61
86
  none: false
62
- requirements:
87
+ requirements:
63
88
  - - ~>
64
- - !ruby/object:Gem::Version
65
- version: '1.1'
89
+ - !ruby/object:Gem::Version
90
+ hash: 13
91
+ segments:
92
+ - 1
93
+ - 1
94
+ version: "1.1"
66
95
  type: :development
67
- prerelease: false
68
- version_requirements: *70212465457840
96
+ version_requirements: *id005
69
97
  description: Guard::Motion automatically run your specs (much like autotest).
70
- email:
98
+ email:
71
99
  - mordaroso@gmail.com
72
100
  executables: []
101
+
73
102
  extensions: []
103
+
74
104
  extra_rdoc_files: []
75
- files:
105
+
106
+ files:
76
107
  - .gitignore
77
108
  - .travis.yml
109
+ - CHANGELOG.md
78
110
  - Gemfile
79
111
  - Guardfile
80
112
  - LICENSE
@@ -82,40 +114,52 @@ files:
82
114
  - Rakefile
83
115
  - guard-motion.gemspec
84
116
  - lib/guard/motion.rb
117
+ - lib/guard/motion/results_parser.rb
85
118
  - lib/guard/motion/runner.rb
86
119
  - lib/guard/motion/tasks.rb
87
120
  - lib/guard/motion/templates/Guardfile
88
121
  - lib/guard/motion/version.rb
89
122
  - spec/fixtures/bundler/Gemfile
123
+ - spec/guard/motion/results_parser_spec.rb
90
124
  - spec/guard/motion/runner_spec.rb
91
125
  - spec/guard/motion_spec.rb
92
126
  - spec/spec_helper.rb
93
127
  homepage: http://rubygems.org/gems/guard-motion
94
128
  licenses: []
129
+
95
130
  post_install_message:
96
131
  rdoc_options: []
97
- require_paths:
132
+
133
+ require_paths:
98
134
  - lib
99
- required_ruby_version: !ruby/object:Gem::Requirement
135
+ required_ruby_version: !ruby/object:Gem::Requirement
100
136
  none: false
101
- requirements:
102
- - - ! '>='
103
- - !ruby/object:Gem::Version
104
- version: '0'
105
- required_rubygems_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ hash: 3
141
+ segments:
142
+ - 0
143
+ version: "0"
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
145
  none: false
107
- requirements:
108
- - - ! '>='
109
- - !ruby/object:Gem::Version
110
- version: '0'
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ hash: 3
150
+ segments:
151
+ - 0
152
+ version: "0"
111
153
  requirements: []
154
+
112
155
  rubyforge_project:
113
- rubygems_version: 1.8.17
156
+ rubygems_version: 1.8.15
114
157
  signing_key:
115
158
  specification_version: 3
116
159
  summary: Guard gem for RubyMotion
117
- test_files:
160
+ test_files:
118
161
  - spec/fixtures/bundler/Gemfile
162
+ - spec/guard/motion/results_parser_spec.rb
119
163
  - spec/guard/motion/runner_spec.rb
120
164
  - spec/guard/motion_spec.rb
121
165
  - spec/spec_helper.rb