guard-test 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Rémy Coutable
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,77 @@
1
+ = Guard::Test
2
+
3
+ Test::Unit guard allows to automatically & intelligently launch tests when files are modified.
4
+
5
+ - Compatible with Test::Unit 2.1.1.
6
+ - Tested on Ruby 1.8.6, 1.8.7, REE & 1.9.2 (display a annoying "uninitialized constant Test::Unit::UI::Console::Diff" warning though).
7
+
8
+ == Install
9
+
10
+ Please be sure to have {guard}[http://github.com/guard/guard] installed before continue.
11
+
12
+ Install the gem:
13
+
14
+ gem install guard-test
15
+
16
+ Add it to your Gemfile (inside test group):
17
+
18
+ gem 'guard-test'
19
+
20
+ Add guard definition to your Guardfile by running this command:
21
+
22
+ guard init test
23
+
24
+ == Usage
25
+
26
+ Please read {guard usage doc}[http://github.com/guard/guard#readme]
27
+
28
+ == Guardfile
29
+
30
+ Test::Unit guard can be really be adapted to all kind of projects.
31
+ Please read {guard doc}[http://github.com/guard/guard#readme] for more info about Guardfile DSL.
32
+
33
+ === Standard ruby gems
34
+
35
+ guard 'test' do
36
+ watch('^lib/(.*)\.rb') { |m| "test/lib/#{m[1]}_test.rb" }
37
+ watch('^test/(.*)_test.rb')
38
+ watch('^test/test_helper.rb') { "test" }
39
+ end
40
+
41
+ === Rails app
42
+
43
+ guard 'test' do
44
+ watch('^app/models/(.*)\.rb') { |m| "test/unit/#{m[1]}_test.rb" }
45
+ watch('^app/controllers/(.*)\.rb') { |m| "test/functional/#{m[1]}_test.rb" }
46
+ watch('^app/controllers/application_controller.rb') { "test/functional" }
47
+ watch('^app/controllers/application_controller.rb') { "test/integration" }
48
+ watch('^app/views/(.*)\.rb') { "test/integration" }
49
+ watch('^lib/(.*)\.rb') { |m| "test/lib/#{m[1]}_test.rb" }
50
+ watch('^test/(.*)_test.rb')
51
+ watch('^test/factories.rb') { "test/unit" }
52
+ watch('^test/test_helper.rb') { "test" }
53
+ end
54
+
55
+ == Options
56
+
57
+ Test::Unit guard allow you to choose between two different runners:
58
+
59
+ - 'default' (obviously, guard-test will use this by default): Display progress as chars ('.' for pass, 'F' for fail, 'E' for error) and errors when all the tests are finished.
60
+ - 'fastfail': Display failures/errors messages as they happen, not at the end and passing tests with '.'.
61
+
62
+ Set the desired runner by passing the :runner option to the <tt>guard</tt> method:
63
+
64
+ guard 'test', :runner => 'fastfail' do
65
+ ...
66
+ end
67
+
68
+ == Development
69
+
70
+ - Source hosted at {GitHub}[http://github.com/guard/guard-test]
71
+ - Report issues/Questions/Feature requests on {GitHub Issues}[http://github.com/guard/guard-test/issues]
72
+
73
+ Pull requests are very welcome! Make sure your patches are well tested. Please create a topic branch for every separate change you make.
74
+
75
+ == Authors
76
+
77
+ {Rémy Coutable}[http://github.com/rymai]
@@ -0,0 +1,61 @@
1
+ require "#{File.dirname(__FILE__)}/../test"
2
+
3
+ module Formatter
4
+
5
+ def output_results(test_count, assertion_count, failure_count, error_count, duration, options = {})
6
+ output(duration_text(duration, options)) if options[:with_duration]
7
+ color = (failure_count > 0 ? "failure" : (error_count > 0 ? "error" : "pass"))
8
+ output(results_text(test_count, assertion_count, failure_count, error_count), color)
9
+ end
10
+
11
+ def notify_results(test_count, assertion_count, failure_count, error_count, duration)
12
+ notify(
13
+ results_text(test_count, assertion_count, failure_count, error_count) + duration_text(duration, :short => true),
14
+ image(failure_count)
15
+ )
16
+ end
17
+
18
+ def output_and_notify_results(test_count, assertion_count, failure_count, error_count, duration, options = {})
19
+ output_results(test_count, assertion_count, failure_count, error_count, duration, options)
20
+ notify_results(test_count, assertion_count, failure_count, error_count, duration)
21
+ end
22
+
23
+ def image(failure_count)
24
+ failure_count > 0 ? :failed : :success
25
+ end
26
+
27
+ def notify(message, image)
28
+ Guard::Notifier.notify(message, :title => "Test::Unit results", :image => image)
29
+ end
30
+
31
+ def output_single(something, color_name = "reset")
32
+ something = "%s%s%s" % [color_sequence(color_name), something, color_sequence("reset")]
33
+ $stdout.write(something)
34
+ $stdout.flush
35
+ true
36
+ end
37
+
38
+ def output(something, color_name = "reset")
39
+ output_single(something, color_name)
40
+ $stdout.puts
41
+ end
42
+
43
+ private
44
+
45
+ def color_sequence(color_name = "reset")
46
+ "\e[0#{color_code(color_name)}m"
47
+ end
48
+
49
+ def color_code(name = "reset")
50
+ { "pass" => ";32", "failure" => ";31", "pending" => ";33", "error" => ";35", "reset" => "" }[name]
51
+ end
52
+
53
+ def results_text(test_count, assertion_count, failure_count, error_count)
54
+ "#{test_count} tests, #{assertion_count} asserts, #{failure_count} fails, #{error_count} errors"
55
+ end
56
+
57
+ def duration_text(duration, options = {})
58
+ "\n\n#{"Finished " unless options[:short]}in #{duration} seconds\n"
59
+ end
60
+
61
+ end
@@ -0,0 +1,45 @@
1
+ module Guard
2
+ class Test
3
+ module Inspector
4
+ class << self
5
+
6
+ def clean(paths)
7
+ paths.uniq!
8
+ paths.compact!
9
+ clean_paths = paths.select { |p| test_file?(p) || test_folder?(p) }
10
+
11
+ paths.each do |path|
12
+ if File.directory?(path)
13
+ clean_paths.delete(path)
14
+ clean_paths = clean_paths + Dir.glob("#{path}/**/*_test.rb")
15
+ end
16
+ end
17
+
18
+ clean_paths.uniq!
19
+ clean_paths.compact!
20
+ clear_test_files_list
21
+ clean_paths.sort
22
+ end
23
+
24
+ private
25
+
26
+ def test_folder?(path)
27
+ path.match(/^\/?test/) && !path.match(/\..+$/)
28
+ end
29
+
30
+ def test_file?(path)
31
+ test_files.include?(path)
32
+ end
33
+
34
+ def test_files
35
+ @test_files ||= Dir.glob("test/**/*_test.rb")
36
+ end
37
+
38
+ def clear_test_files_list
39
+ @test_files = nil
40
+ end
41
+
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,34 @@
1
+ module Guard
2
+ class Test
3
+ module Runner
4
+ class << self
5
+ attr_reader :test_unit_runner
6
+
7
+ AVAILABLE_TEST_UNIT_RUNNERS = %w[default fastfail]
8
+
9
+ def set_test_unit_runner(options = {})
10
+ @test_unit_runner = AVAILABLE_TEST_UNIT_RUNNERS.include?(options[:runner]) ? options[:runner] : 'default'
11
+ end
12
+
13
+ def run(paths, options = {})
14
+ message = "\n" + (options[:message] || "Running (#{@test_unit_runner} runner): #{paths.join(' ') }")
15
+ UI.info(message, :reset => true)
16
+ system(test_unit_command(paths))
17
+ end
18
+
19
+ private
20
+
21
+ def test_unit_command(files)
22
+ cmd_parts = ["ruby"]
23
+ cmd_parts << "-r#{File.dirname(__FILE__)}/runners/#{@test_unit_runner}_test_unit_runner"
24
+ cmd_parts << "-Itest"
25
+ cmd_parts << "-e \"%w[#{files.join(' ')}].each { |f| load f }\""
26
+ cmd_parts << files.map { |f| "\"#{f}\"" }.join(' ')
27
+ cmd_parts << "--runner=guard-#{@test_unit_runner}"
28
+ cmd_parts.join(' ')
29
+ end
30
+
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,56 @@
1
+ require "#{File.dirname(__FILE__)}/../formatter"
2
+ require 'test/unit'
3
+ require 'test/unit/testcase'
4
+ require 'test/unit/ui/console/testrunner'
5
+
6
+ # Thanks to Adam Sanderson for the really good starting point:
7
+ # http://endofline.wordpress.com/2008/02/11/a-custom-testrunner-to-scratch-an-itch/
8
+ #
9
+ # This class inherits from Test::Unit' standard console TestRunner
10
+ # I'm just overriding some callbacks methods to display nice results
11
+ class DefaultGuardTestRunner < Test::Unit::UI::Console::TestRunner
12
+ include Formatter
13
+
14
+ def initialize(suite, options = {})
15
+ super
16
+ @use_color = true
17
+ end
18
+
19
+ protected
20
+
21
+ # Test::Unit::UI::Console::TestRunner overrided methods
22
+ def setup_mediator
23
+ @mediator = Test::Unit::UI::TestRunnerMediator.new(@suite)
24
+ end
25
+
26
+ def started(result)
27
+ @result = result
28
+ end
29
+
30
+ def test_started(name) # silence!
31
+ end
32
+
33
+ def add_fault(fault)
34
+ @faults << fault
35
+ output_single(fault.single_character_display, fault_color_name(fault))
36
+ @already_outputted = true
37
+ end
38
+
39
+ def test_finished(name)
40
+ output_single(".", "pass") unless @already_outputted
41
+ @already_outputted = false
42
+ end
43
+
44
+ def finished(elapsed_time)
45
+ nl
46
+ super
47
+ notify_results(@result.run_count, @result.assertion_count, @result.failure_count, @result.error_count, elapsed_time)
48
+ end
49
+
50
+ def fault_color_name(fault)
51
+ fault.class.name.split(/::/).last.downcase
52
+ end
53
+
54
+ end
55
+
56
+ Test::Unit::AutoRunner::RUNNERS["guard-default"] = Proc.new { |r| DefaultGuardTestRunner }
@@ -0,0 +1,24 @@
1
+ require "#{File.dirname(__FILE__)}/default_test_unit_runner"
2
+
3
+ # This class is directly inspired by a blog post by Adam Sanderson:
4
+ # http://endofline.wordpress.com/2008/02/11/a-custom-testrunner-to-scratch-an-itch/
5
+ # It inherits DefaultGuardTestRunner and redefines only 2 methods in order to display failures
6
+ # as they happen (the default display them when all the tests are finished).
7
+ class FastfailGuardTestUnitRunner < DefaultGuardTestRunner
8
+
9
+ private
10
+
11
+ def add_fault(fault)
12
+ @faults << fault
13
+ nl
14
+ output("%3d) %s" % [@faults.length, fault.long_display])
15
+ @already_outputted = true
16
+ end
17
+
18
+ def finished(elapsed_time)
19
+ output_and_notify_results(@result.run_count, @result.assertion_count, @result.failure_count, @result.error_count, elapsed_time, :with_duration => true)
20
+ end
21
+
22
+ end
23
+
24
+ Test::Unit::AutoRunner::RUNNERS["guard-fastfail"] = Proc.new { |r| FastfailGuardTestUnitRunner }
@@ -0,0 +1,13 @@
1
+ guard 'test' do
2
+ watch('^lib/(.*)\.rb') { |m| "test/lib/#{m[1]}_test.rb" }
3
+ watch('^test/(.*)_test.rb')
4
+ watch('^test/test_helper.rb') { "test" }
5
+
6
+ # Rails example
7
+ watch('^app/models/(.*)\.rb') { |m| "test/unit/#{m[1]}_test.rb" }
8
+ watch('^app/controllers/(.*)\.rb') { |m| "test/functional/#{m[1]}_test.rb" }
9
+ watch('^app/controllers/application_controller.rb') { "test/functional" }
10
+ watch('^app/controllers/application_controller.rb') { "test/integration" }
11
+ watch('^app/views/(.*)\.rb') { "test/integration" }
12
+ watch('^test/factories.rb') { "test/unit" }
13
+ end
@@ -0,0 +1,5 @@
1
+ module Guard
2
+ module TestVersion
3
+ VERSION = "0.1.1"
4
+ end
5
+ end
data/lib/guard/test.rb ADDED
@@ -0,0 +1,31 @@
1
+ require 'rubygems'
2
+ require 'guard'
3
+ require 'guard/guard'
4
+
5
+ module Guard
6
+ class Test < Guard
7
+
8
+ autoload :Runner, 'guard/test/runner'
9
+ autoload :Inspector, 'guard/test/inspector'
10
+
11
+ def start
12
+ Runner.set_test_unit_runner(options)
13
+ UI.info "Guard::Test is guarding your tests!"
14
+ end
15
+
16
+ def run_all
17
+ clean_and_run(["test"], :message => "Running all tests")
18
+ end
19
+
20
+ def run_on_change(paths)
21
+ clean_and_run(paths)
22
+ end
23
+
24
+ private
25
+
26
+ def clean_and_run(paths, options = {})
27
+ paths = Inspector.clean(paths)
28
+ Runner.run(paths, options) unless paths.empty?
29
+ end
30
+ end
31
+ end
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: guard-test
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 1
10
+ version: 0.1.1
11
+ platform: ruby
12
+ authors:
13
+ - "R\xC3\xA9my Coutable"
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-10-19 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: guard
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 62196353
30
+ segments:
31
+ - 0
32
+ - 2
33
+ - 0
34
+ - beta
35
+ - 1
36
+ version: 0.2.0.beta.1
37
+ type: :runtime
38
+ version_requirements: *id001
39
+ - !ruby/object:Gem::Dependency
40
+ name: bundler
41
+ prerelease: false
42
+ requirement: &id002 !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ hash: 19
48
+ segments:
49
+ - 1
50
+ - 0
51
+ - 2
52
+ version: 1.0.2
53
+ type: :development
54
+ version_requirements: *id002
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ prerelease: false
58
+ requirement: &id003 !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ~>
62
+ - !ruby/object:Gem::Version
63
+ hash: 15
64
+ segments:
65
+ - 2
66
+ - 0
67
+ - 0
68
+ version: 2.0.0
69
+ type: :development
70
+ version_requirements: *id003
71
+ - !ruby/object:Gem::Dependency
72
+ name: guard-rspec
73
+ prerelease: false
74
+ requirement: &id004 !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ~>
78
+ - !ruby/object:Gem::Version
79
+ hash: 29
80
+ segments:
81
+ - 0
82
+ - 1
83
+ - 3
84
+ version: 0.1.3
85
+ type: :development
86
+ version_requirements: *id004
87
+ - !ruby/object:Gem::Dependency
88
+ name: test-unit
89
+ prerelease: false
90
+ requirement: &id005 !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ~>
94
+ - !ruby/object:Gem::Version
95
+ hash: 9
96
+ segments:
97
+ - 2
98
+ - 1
99
+ - 1
100
+ version: 2.1.1
101
+ type: :development
102
+ version_requirements: *id005
103
+ description: Guard::Test automatically run your tests and notify you of the result when a file is modified.
104
+ email:
105
+ - rymai@rymai.com
106
+ executables: []
107
+
108
+ extensions: []
109
+
110
+ extra_rdoc_files: []
111
+
112
+ files:
113
+ - lib/guard/test/formatter.rb
114
+ - lib/guard/test/inspector.rb
115
+ - lib/guard/test/runner.rb
116
+ - lib/guard/test/runners/default_test_unit_runner.rb
117
+ - lib/guard/test/runners/fastfail_test_unit_runner.rb
118
+ - lib/guard/test/templates/Guardfile
119
+ - lib/guard/test/version.rb
120
+ - lib/guard/test.rb
121
+ - LICENSE
122
+ - README.rdoc
123
+ has_rdoc: true
124
+ homepage: http://rubygems.org/gems/guard-test
125
+ licenses: []
126
+
127
+ post_install_message:
128
+ rdoc_options: []
129
+
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ none: false
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ hash: 3
138
+ segments:
139
+ - 0
140
+ version: "0"
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ none: false
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ hash: 23
147
+ segments:
148
+ - 1
149
+ - 3
150
+ - 6
151
+ version: 1.3.6
152
+ requirements: []
153
+
154
+ rubyforge_project: guard-test
155
+ rubygems_version: 1.3.7
156
+ signing_key:
157
+ specification_version: 3
158
+ summary: Guard gem for Test::Unit
159
+ test_files: []
160
+