ZenTest 3.4.3 → 3.5.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.
- data/History.txt +46 -3
- data/Manifest.txt +13 -0
- data/README.txt +1 -0
- data/Rakefile +20 -3
- data/bin/autotest +23 -37
- data/bin/multiruby +13 -7
- data/bin/unit_diff +1 -1
- data/example_dot_autotest.rb +14 -0
- data/lib/autotest.rb +77 -30
- data/lib/autotest/autoupdate.rb +26 -0
- data/lib/autotest/emacs.rb +29 -0
- data/lib/autotest/fixtures.rb +12 -0
- data/lib/autotest/growl.rb +7 -17
- data/lib/autotest/heckle.rb +14 -0
- data/lib/autotest/migrate.rb +7 -0
- data/lib/autotest/notify.rb +38 -0
- data/lib/autotest/redgreen.rb +7 -4
- data/lib/autotest/screen.rb +77 -0
- data/lib/autotest/shame.rb +45 -0
- data/lib/autotest/timestamp.rb +3 -1
- data/lib/camping_autotest.rb +37 -0
- data/lib/functional_test_matrix.rb +85 -0
- data/lib/rails_autotest.rb +49 -41
- data/lib/rspec_rails_autotest.rb +119 -0
- data/lib/test/rails.rb +28 -1
- data/lib/test/rails/controller_test_case.rb +27 -6
- data/lib/test/rails/functional_test_case.rb +3 -0
- data/lib/test/rails/helper_test_case.rb +3 -0
- data/lib/test/rails/view_test_case.rb +13 -5
- data/lib/test/zentest_assertions.rb +42 -23
- data/lib/unit_diff.rb +86 -69
- data/lib/zentest.rb +58 -87
- data/lib/zentest_mapping.rb +97 -0
- data/test/test_autotest.rb +23 -3
- data/test/test_help.rb +10 -4
- data/test/test_rails_autotest.rb +6 -4
- data/test/test_rails_controller_test_case.rb +10 -2
- data/test/test_ruby_fork.rb +12 -12
- data/test/test_unit_diff.rb +37 -33
- data/test/test_zentest.rb +15 -141
- data/test/test_zentest_assertions.rb +38 -18
- data/test/test_zentest_mapping.rb +213 -0
- metadata +18 -4
@@ -0,0 +1,26 @@
|
|
1
|
+
module Autotest::AutoUpdate
|
2
|
+
@@sleep_time, @@update_cmd, @@updater = 60, "svn up", nil
|
3
|
+
|
4
|
+
def self.sleep_time= o
|
5
|
+
@@sleep_time = o
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.update_cmd= o
|
9
|
+
@@update_cmd = o
|
10
|
+
end
|
11
|
+
|
12
|
+
Autotest.add_hook :run_command do |at|
|
13
|
+
@@updater.kill if @@updater
|
14
|
+
end
|
15
|
+
|
16
|
+
Autotest.add_hook :ran_command do |at|
|
17
|
+
@@updater = Thread.start do
|
18
|
+
loop do
|
19
|
+
puts "# Waiting for #{@@sleep_time} seconds before updating"
|
20
|
+
sleep @@sleep_time
|
21
|
+
puts "# Running #{@@update_cmd}"
|
22
|
+
system @@update_cmd
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#
|
2
|
+
# Get autotest.el from http://www.emacswiki.org/cgi-bin/wiki/RyanDavis
|
3
|
+
#
|
4
|
+
|
5
|
+
module Autotest::Emacs
|
6
|
+
def self.emacs_autotest status
|
7
|
+
`emacsclient -e \"(autotest-update '#{status})\"`
|
8
|
+
end
|
9
|
+
|
10
|
+
Autotest.add_hook :run_command do |at|
|
11
|
+
emacs_autotest :running
|
12
|
+
end
|
13
|
+
|
14
|
+
Autotest.add_hook :green do |at|
|
15
|
+
emacs_autotest :passed
|
16
|
+
end
|
17
|
+
|
18
|
+
Autotest.add_hook :all_good do |at|
|
19
|
+
emacs_autotest :passed
|
20
|
+
end
|
21
|
+
|
22
|
+
Autotest.add_hook :red do |at|
|
23
|
+
emacs_autotest :failed
|
24
|
+
end
|
25
|
+
|
26
|
+
Autotest.add_hook :quit do |at|
|
27
|
+
emacs_autotest :quit
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
# This is an example of how to change the mappings of file that
|
4
|
+
# changed to tests to run for a project.
|
5
|
+
|
6
|
+
module Autotest::Fixtures
|
7
|
+
Autotest.add_hook :initialize do |at|
|
8
|
+
at.test_mappings['^test/fixtures/(.*)s.yml'] = proc { |filename, matches|
|
9
|
+
at.files_matching /test\/\w+\/#{matches[1]}(_\w+)?.*_test.rb$/
|
10
|
+
}
|
11
|
+
end
|
12
|
+
end
|
data/lib/autotest/growl.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
-
# -*-
|
1
|
+
# -*- ruby -*-
|
2
2
|
|
3
3
|
module Autotest::Growl
|
4
4
|
def self.growl title, msg, pri=0
|
5
|
+
title += " in #{Dir.pwd}"
|
6
|
+
msg += " at #{Time.now}"
|
5
7
|
system "growlnotify -n autotest --image /Applications/Mail.app/Contents/Resources/Caution.tiff -p #{pri} -m #{msg.inspect} #{title}"
|
6
8
|
end
|
7
9
|
|
8
10
|
Autotest.add_hook :run do |at|
|
9
|
-
growl "
|
11
|
+
growl "autotest running", "Started"
|
10
12
|
end
|
11
13
|
|
12
14
|
Autotest.add_hook :red do |at|
|
@@ -14,22 +16,10 @@ module Autotest::Growl
|
|
14
16
|
end
|
15
17
|
|
16
18
|
Autotest.add_hook :green do |at|
|
17
|
-
growl "Tests Passed", "
|
19
|
+
growl "Tests Passed", "Tests passed", -2 if at.tainted
|
18
20
|
end
|
19
21
|
|
20
|
-
Autotest.add_hook :
|
21
|
-
growl "
|
22
|
-
end
|
23
|
-
|
24
|
-
Autotest.add_hook :interrupt do |at|
|
25
|
-
growl "autotest", "autotest was reset" unless $TESTING
|
26
|
-
end
|
27
|
-
|
28
|
-
Autotest.add_hook :quit do |at|
|
29
|
-
growl "autotest", "autotest is exiting" unless $TESTING
|
30
|
-
end
|
31
|
-
|
32
|
-
Autotest.add_hook :all do |at|_hook
|
33
|
-
growl "autotest", "Tests have fully passed", -2 unless $TESTING
|
22
|
+
Autotest.add_hook :all_good do |at|
|
23
|
+
growl "Tests Passed", "All tests passed", -2 if at.tainted
|
34
24
|
end
|
35
25
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
module Autotest::Heckle
|
4
|
+
@@flags = []
|
5
|
+
@@klasses = []
|
6
|
+
def self.flags; @@flags; end
|
7
|
+
def self.klasses; @@klasses; end
|
8
|
+
|
9
|
+
Autotest.add_hook :all_good do |at|
|
10
|
+
heckle = "heckle" + (@@flags.empty? ? '' : " #{flags.join(' ')}")
|
11
|
+
cmd = @@klasses.map { |klass| "#{heckle} #{klass}" }.join(" && ")
|
12
|
+
system cmd
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# libnotify plugin for autotest
|
2
|
+
|
3
|
+
begin require 'rubygems'; rescue LoadError; end
|
4
|
+
require 'libnotify'
|
5
|
+
|
6
|
+
module Autotest::LibNotify
|
7
|
+
|
8
|
+
LibNotify.init("autotest")
|
9
|
+
|
10
|
+
def self.notify title, msg, ico = :info
|
11
|
+
LibNotify::Notification.new(title, msg, "gtk-#{ico}", nil).show
|
12
|
+
end
|
13
|
+
|
14
|
+
Autotest.add_hook :red do |at|
|
15
|
+
failed_tests = at.files_to_test.inject(0){ |s,a| k,v = a; s + v.size}
|
16
|
+
notify "Tests Failed", "#{failed_tests} tests failed", :no
|
17
|
+
end
|
18
|
+
|
19
|
+
Autotest.add_hook :green do |at|
|
20
|
+
notify "Tests Passed", "All tests passed", :yes
|
21
|
+
end
|
22
|
+
|
23
|
+
Autotest.add_hook :run do |at|
|
24
|
+
notify "autotest", "autotest was started" unless $TESTING
|
25
|
+
end
|
26
|
+
|
27
|
+
Autotest.add_hook :interrupt do |at|
|
28
|
+
notify "autotest", "autotest was reset" unless $TESTING
|
29
|
+
end
|
30
|
+
|
31
|
+
Autotest.add_hook :quit do |at|
|
32
|
+
notify "autotest", "autotest is exiting" unless $TESTING
|
33
|
+
end
|
34
|
+
|
35
|
+
Autotest.add_hook :all do |at|_hook
|
36
|
+
notify "autotest", "Tests have fully passed", :yes unless $TESTING
|
37
|
+
end
|
38
|
+
end
|
data/lib/autotest/redgreen.rb
CHANGED
@@ -5,9 +5,12 @@ module Autotest::RedGreen
|
|
5
5
|
BAR = "=" * 80
|
6
6
|
|
7
7
|
Autotest.add_hook :ran_command do |at|
|
8
|
-
at.results.
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
output = at.results.join
|
9
|
+
at.results.each do |line|
|
10
|
+
line.gsub!(/^.* (\d+) failures, (\d+) errors$/) { |match|
|
11
|
+
code = ($1 != "0" or $2 != "0") ? 31 : 32
|
12
|
+
"\e[#{code}m#{BAR}\n#{match}\e[0m\n\n"
|
13
|
+
}
|
14
|
+
end
|
12
15
|
end
|
13
16
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
class Autotest::Screen
|
2
|
+
# Autotest::Screen is test result notify GUN Screen's statusline.
|
3
|
+
#
|
4
|
+
# === screenshots
|
5
|
+
# * <img src="http://f.hatena.ne.jp/images/fotolife/s/secondlife/20061109/20061109015543.png" />
|
6
|
+
# * <img src="http://f.hatena.ne.jp/images/fotolife/s/secondlife/20061109/20061109015522.png" />
|
7
|
+
#
|
8
|
+
# == SYNOPSIS
|
9
|
+
# require 'autotest/screen'
|
10
|
+
# # Autotest::Screen.statusline = '%H %`%-w%{=b bw}%n %t%{-}%+w (your statusline)'
|
11
|
+
#
|
12
|
+
|
13
|
+
DEFAULT_STATUSLINE = '%H %`%-w%{=b bw}%n %t%{-}%+w'
|
14
|
+
DEFAULT_SCREEN_CMD = 'screen'
|
15
|
+
|
16
|
+
SCREEN_COLOR = {
|
17
|
+
:black => 'dd',
|
18
|
+
:green => 'gk',
|
19
|
+
:red => 'rw',
|
20
|
+
}
|
21
|
+
|
22
|
+
def self.message(msg, color = :black)
|
23
|
+
col = SCREEN_COLOR[color]
|
24
|
+
msg = %Q[ %{=b #{col}} #{msg} %{-}]
|
25
|
+
send_cmd(msg)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.clear
|
29
|
+
send_cmd('')
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.run_screen_session?
|
33
|
+
str = `#{screen_cmd} -ls`
|
34
|
+
str.match(/(\d+) Socket/) && ($1.to_i > 0)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.execute?
|
38
|
+
!($TESTING || !run_screen_session?)
|
39
|
+
end
|
40
|
+
|
41
|
+
@statusline, @screen_cmd = nil
|
42
|
+
def self.statusline; @statusline || DEFAULT_STATUSLINE.dup; end
|
43
|
+
def self.statusline=(a); @statusline = a; end
|
44
|
+
def self.screen_cmd; @screen_cmd || DEFAULT_SCREEN_CMD.dup; end
|
45
|
+
def self.screen_cmd=(a); @screen_cmd = a; end
|
46
|
+
|
47
|
+
def self.send_cmd(msg)
|
48
|
+
cmd = %(#{screen_cmd} -X eval 'hardstatus alwayslastline "#{(statusline + msg).gsub('"', '\"')}"') #' stupid ruby-mode
|
49
|
+
system cmd
|
50
|
+
end
|
51
|
+
|
52
|
+
Autotest.add_hook :run do |at|
|
53
|
+
message 'Run Tests' if execute?
|
54
|
+
end
|
55
|
+
|
56
|
+
Autotest.add_hook :interrupt do |at|
|
57
|
+
message 'Run Tests' if execute?
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
Autotest.add_hook :quit do |at|
|
62
|
+
clear if execute?
|
63
|
+
end
|
64
|
+
|
65
|
+
Autotest.add_hook :ran_command do |at|
|
66
|
+
if execute? then
|
67
|
+
output = at.results.join
|
68
|
+
failed = output.scan(/^\s+\d+\) (?:Failure|Error):\n(.*?)\((.*?)\)/)
|
69
|
+
if failed.size == 0 then
|
70
|
+
message "All Green", :green
|
71
|
+
else
|
72
|
+
f,e = failed.partition { |s| s =~ /Failure/ }
|
73
|
+
message "Red F:#{f.size} E:#{e.size}", :red
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'code_statistics'
|
2
|
+
require 'rbosa'
|
3
|
+
|
4
|
+
module Autotest::Shame
|
5
|
+
@@chat_app = :adium
|
6
|
+
|
7
|
+
def self.chat_app= o
|
8
|
+
@@chat_app = o
|
9
|
+
end
|
10
|
+
|
11
|
+
# Until the rails team learns how to write modular code... I must steal :/
|
12
|
+
STATS_DIRECTORIES = [
|
13
|
+
%w(Controllers app/controllers),
|
14
|
+
%w(Helpers app/helpers),
|
15
|
+
%w(Models app/models),
|
16
|
+
%w(Libraries lib/),
|
17
|
+
%w(APIs app/apis),
|
18
|
+
%w(Components components),
|
19
|
+
%w(Integration\ tests test/integration),
|
20
|
+
%w(Functional\ tests test/functional),
|
21
|
+
%w(Unit\ tests test/unit),
|
22
|
+
].select { |name, dir| File.directory?(dir) }
|
23
|
+
|
24
|
+
def self.shame
|
25
|
+
stats = CodeStatistics.new(*STATS_DIRECTORIES)
|
26
|
+
code = stats.send :calculate_code
|
27
|
+
tests = stats.send :calculate_tests
|
28
|
+
msg = "Code To Test Ratio: 1:#{sprintf("%.2f", tests.to_f/code)}"
|
29
|
+
$-w = ! $-w
|
30
|
+
case @@chat_app
|
31
|
+
when :adium then
|
32
|
+
OSA.app('Adium').adium_controller.my_status_message = msg
|
33
|
+
when :ichat then
|
34
|
+
OSA.app('ichat').status_message = msg
|
35
|
+
else
|
36
|
+
raise "huh?"
|
37
|
+
end
|
38
|
+
$-w = ! $-w
|
39
|
+
$stderr.puts "Status set to: #{msg.inspect}"
|
40
|
+
end
|
41
|
+
|
42
|
+
Autotest.add_hook(:all_good) do |autotest|
|
43
|
+
shame
|
44
|
+
end
|
45
|
+
end
|
data/lib/autotest/timestamp.rb
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'autotest'
|
2
|
+
|
3
|
+
##
|
4
|
+
# CampingAutotest is an Autotest subclass designed for use with Camping projects.
|
5
|
+
#
|
6
|
+
# To use CampingAutotest pass the -camping flag to autotest.
|
7
|
+
#
|
8
|
+
# Contributed by Geoffrey Grosenbach http://nubyonrails.com
|
9
|
+
|
10
|
+
class CampingAutotest < Autotest
|
11
|
+
|
12
|
+
def initialize # :nodoc:
|
13
|
+
super
|
14
|
+
@exceptions = %r%\.(log|db)$%
|
15
|
+
|
16
|
+
@test_mappings = {
|
17
|
+
%r%^test/fixtures/([^_]+)_.*s\.yml% => proc { |_, m|
|
18
|
+
"test/#{m[1]}_test.rb"
|
19
|
+
},
|
20
|
+
%r%^test/.*rb$% => proc { |filename, m|
|
21
|
+
filename
|
22
|
+
},
|
23
|
+
%r%^public/([^\/]+)/(models|controllers|views)\.rb$% => proc { |_, m|
|
24
|
+
"test/#{m[1]}_test.rb"
|
25
|
+
},
|
26
|
+
%r%^public/(.*)\.rb$% => proc { |_, m|
|
27
|
+
"test/#{m[1]}_test.rb"
|
28
|
+
},
|
29
|
+
}
|
30
|
+
|
31
|
+
return functional_tests
|
32
|
+
end
|
33
|
+
|
34
|
+
def tests_for_file(filename)
|
35
|
+
super.select { |f| @files.has_key? f }
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
|
2
|
+
########################################################################
|
3
|
+
# The Idea:
|
4
|
+
#
|
5
|
+
# This is supposed to get us thinking about the various dimensions our
|
6
|
+
# testing should address. If there are states orthogonal to each other
|
7
|
+
# (eg. readable vs unreadable, logged in vs not logged in) each of
|
8
|
+
# those states should comprise a dimension in the matrix. By
|
9
|
+
# addressing it this way, we should be able to minimize the amount of
|
10
|
+
# setup/teardown code and get full coverage across our actions for all
|
11
|
+
# these edge cases and as a result have extremely clear tests.
|
12
|
+
#
|
13
|
+
########################################################################
|
14
|
+
# Example Test Matrix Specification:
|
15
|
+
#
|
16
|
+
# matrix :example, :edge1, edge2, :edge3, ...
|
17
|
+
# action :action1, :new, :err, :err, ...
|
18
|
+
# action :action2, :del, :err, :na, ...
|
19
|
+
# action ...
|
20
|
+
#
|
21
|
+
########################################################################
|
22
|
+
# Matrix:
|
23
|
+
#
|
24
|
+
# I envision the setups being a code that combines the different
|
25
|
+
# dimensions of edge case state.
|
26
|
+
#
|
27
|
+
# Something for a CMS might look like: `[df]_[ugo]_[rRwW]` where:
|
28
|
+
#
|
29
|
+
# + `[df]` for dir/file.
|
30
|
+
# + and the rest is in the style of symbolic args to chmod:
|
31
|
+
# + u/g/o = user, group, or other
|
32
|
+
# + lowercase `X` == `X`able, uppercase `X` == un`X`able, where `X`
|
33
|
+
# is read/write.
|
34
|
+
#
|
35
|
+
########################################################################
|
36
|
+
# Action:
|
37
|
+
#
|
38
|
+
# :new/:err/:del are just examples, they should have semantic info
|
39
|
+
# attached to them.
|
40
|
+
#
|
41
|
+
# Use :na to specify an inapplicable edge case for that action.
|
42
|
+
#
|
43
|
+
# Edge cases specific to an action that fall outside the matrix are
|
44
|
+
# regular tests.
|
45
|
+
#
|
46
|
+
########################################################################
|
47
|
+
# Matrix Methods (the legos):
|
48
|
+
#
|
49
|
+
# Everything else basically equates to lego pieces:
|
50
|
+
#
|
51
|
+
# + There is one "init" method per matrix: matrix_init_#{descr}(setup_args)
|
52
|
+
# + There is one "setup" method per action: matrix_setup_#{action}(setup, expect)
|
53
|
+
# + There is one "test" method per result: matrix_test_#{result}(setup)
|
54
|
+
#
|
55
|
+
# Thus, for the example above, the top left-most test will end up calling:
|
56
|
+
#
|
57
|
+
# matrix_init_example(:edge1)
|
58
|
+
# matrix_setup_action1(:edge1, :new)
|
59
|
+
# matrix_test_new(:edge1)
|
60
|
+
#
|
61
|
+
# Read the action method for exact details.
|
62
|
+
########################################################################
|
63
|
+
|
64
|
+
module FunctionalTestMatrix
|
65
|
+
def matrix(name, *setups)
|
66
|
+
@@matrix, @@setups = name, setups
|
67
|
+
end
|
68
|
+
|
69
|
+
def action(action, *results)
|
70
|
+
testcases = @@setups.zip(results).reject { |a,b| b == :na }
|
71
|
+
testcases = Hash[*testcases.flatten]
|
72
|
+
matrix = @@matrix # bind to local scope for define_method closure
|
73
|
+
|
74
|
+
testcases.each do |setup, expected|
|
75
|
+
define_method "test_#{action}_#{setup}" do
|
76
|
+
@action = action
|
77
|
+
send "matrix_init_#{matrix}", *setup.to_s.split(/_/).map {|c| c.intern }
|
78
|
+
send "matrix_setup_#{action}", setup, expected
|
79
|
+
send "matrix_test_#{expected}", setup
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
module_function :matrix, :action
|
85
|
+
end
|