guard-motion 0.1.0 → 0.1.1

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,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