tconsole 1.1.0pre1 → 1.1.0pre2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +10 -0
- data/lib/tconsole.rb +6 -1
- data/lib/tconsole/minitest_handler.rb +76 -1
- data/lib/tconsole/server.rb +25 -0
- data/lib/tconsole/test_result.rb +24 -1
- data/lib/tconsole/util.rb +21 -0
- data/lib/tconsole/version.rb +1 -1
- data/tconsole.gemspec +1 -1
- metadata +15 -3
data/README.md
CHANGED
@@ -106,3 +106,13 @@ Reporting Issues and Contributing
|
|
106
106
|
Feel free to report issues in the issue tracker at https://github.com/commondream/tconsole/issues. Be sure to include the versions of Ruby, Rails, and your operating system. For bonus points, fork the project and send me a pull request with the fix for the issue you're seeing.
|
107
107
|
|
108
108
|
tconsole is just a quick idea I had that I wanted to spike out, so there aren't any tests yet. Hopefully that will change in the near future!
|
109
|
+
|
110
|
+
License
|
111
|
+
-----
|
112
|
+
Copyright (c) 2012 Alan Johnson
|
113
|
+
|
114
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
115
|
+
|
116
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
117
|
+
|
118
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/lib/tconsole.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
require "tconsole/version"
|
2
2
|
require "tconsole/server"
|
3
3
|
require "tconsole/test_result"
|
4
|
+
require "tconsole/util"
|
4
5
|
|
5
6
|
require "readline"
|
6
7
|
require "benchmark"
|
7
8
|
require "drb/drb"
|
9
|
+
require "term/ansicolor"
|
8
10
|
|
9
11
|
Readline.completion_append_character = ""
|
10
12
|
|
@@ -99,7 +101,7 @@ module TConsole
|
|
99
101
|
end
|
100
102
|
|
101
103
|
class Console
|
102
|
-
KNOWN_COMMANDS = ["exit", "reload", "help", "units", "functionals", "integration", "recent", "uncommitted", "all", "info", "!failed"]
|
104
|
+
KNOWN_COMMANDS = ["exit", "reload", "help", "units", "functionals", "integration", "recent", "uncommitted", "all", "info", "!failed", "!timings"]
|
103
105
|
|
104
106
|
def initialize
|
105
107
|
read_history
|
@@ -136,6 +138,8 @@ module TConsole
|
|
136
138
|
server.run_tests(["test/unit/**/*_test.rb", "test/functional/**/*_test.rb", "test/integration/**/*_test.rb"], args[1])
|
137
139
|
elsif args[0] == "!failed"
|
138
140
|
server.run_failed
|
141
|
+
elsif args[0] == "!timings"
|
142
|
+
server.show_performance(args[1])
|
139
143
|
elsif args[0] == "info"
|
140
144
|
server.run_info
|
141
145
|
else
|
@@ -158,6 +162,7 @@ module TConsole
|
|
158
162
|
puts "recent [test_pattern] # Run tests for recently changed files"
|
159
163
|
puts "uncommitted [test_pattern] # Run tests for uncommitted changes"
|
160
164
|
puts "!failed # Runs the last set of failing tests"
|
165
|
+
puts "!timings # Lists the timings for the last test run, sorted."
|
161
166
|
puts "[filename] [test_pattern] # Run the tests contained in the given file"
|
162
167
|
puts "reload # Reload your Rails environment"
|
163
168
|
puts "exit # Exit the console"
|
@@ -41,6 +41,13 @@ module TConsole
|
|
41
41
|
|
42
42
|
# Custom minitest runner for tconsole
|
43
43
|
class MiniTestUnit < ::MiniTest::Unit
|
44
|
+
COLOR_MAP = {
|
45
|
+
"S" => ::Term::ANSIColor.cyan,
|
46
|
+
"E" => ::Term::ANSIColor.red,
|
47
|
+
"F" => ::Term::ANSIColor.red,
|
48
|
+
"P" => ::Term::ANSIColor.green
|
49
|
+
}
|
50
|
+
|
44
51
|
attr_accessor :results
|
45
52
|
|
46
53
|
def initialize
|
@@ -49,6 +56,73 @@ module TConsole
|
|
49
56
|
super
|
50
57
|
end
|
51
58
|
|
59
|
+
def _run_anything(type)
|
60
|
+
suites = TestCase.send "#{type}_suites"
|
61
|
+
return if suites.empty?
|
62
|
+
|
63
|
+
start = Time.now
|
64
|
+
|
65
|
+
@test_count, @assertion_count = 0, 0
|
66
|
+
sync = output.respond_to? :"sync=" # stupid emacs
|
67
|
+
old_sync, output.sync = output.sync, true if sync
|
68
|
+
|
69
|
+
results = _run_suites(suites, type)
|
70
|
+
|
71
|
+
@test_count = results.inject(0) { |sum, (tc, _)| sum + tc }
|
72
|
+
@assertion_count = results.inject(0) { |sum, (_, ac)| sum + ac }
|
73
|
+
|
74
|
+
output.sync = old_sync if sync
|
75
|
+
|
76
|
+
t = Time.now - start
|
77
|
+
|
78
|
+
puts
|
79
|
+
puts
|
80
|
+
puts "Finished #{type}s in %.6fs, %.4f tests/s, %.4f assertions/s." %
|
81
|
+
[t, test_count / t, assertion_count / t]
|
82
|
+
|
83
|
+
report.each_with_index do |msg, i|
|
84
|
+
puts "\n%3d) %s" % [i + 1, msg]
|
85
|
+
end
|
86
|
+
|
87
|
+
puts
|
88
|
+
|
89
|
+
status
|
90
|
+
end
|
91
|
+
|
92
|
+
def status(io = self.output)
|
93
|
+
format = "%d tests, %d assertions, %d failures, %d errors, %d skips"
|
94
|
+
io.puts format % [test_count, assertion_count, failures, errors, skips]
|
95
|
+
end
|
96
|
+
|
97
|
+
def _run_suite(suite, type)
|
98
|
+
filter = options[:filter] || '/./'
|
99
|
+
filter = Regexp.new $1 if filter =~ /\/(.*)\//
|
100
|
+
|
101
|
+
assertions = suite.send("#{type}_methods").grep(filter).map { |method|
|
102
|
+
inst = suite.new method
|
103
|
+
inst._assertions = 0
|
104
|
+
|
105
|
+
# Print the suite name if needed
|
106
|
+
if results.add_suite(suite)
|
107
|
+
print("\n\n", ::Term::ANSIColor.cyan, suite, ::Term::ANSIColor.reset, "\n")
|
108
|
+
end
|
109
|
+
|
110
|
+
@start_time = Time.now
|
111
|
+
result = inst.run self
|
112
|
+
time = Time.now - @start_time
|
113
|
+
results.add_timing(suite, method, time)
|
114
|
+
|
115
|
+
result = "P" if result == "."
|
116
|
+
output = "#{result} #{method}"
|
117
|
+
|
118
|
+
print COLOR_MAP[result], " #{output}", ::Term::ANSIColor.reset, " #{time}s\n"
|
119
|
+
|
120
|
+
inst._assertions
|
121
|
+
}
|
122
|
+
|
123
|
+
return assertions.size, assertions.inject(0) { |sum, n| sum + n }
|
124
|
+
end
|
125
|
+
|
52
126
|
def puke(klass, meth, e)
|
53
127
|
e = case e
|
54
128
|
when MiniTest::Skip then
|
@@ -74,4 +148,5 @@ module TConsole
|
|
74
148
|
end
|
75
149
|
end
|
76
150
|
|
77
|
-
|
151
|
+
# Make sure that output is only colored when it should be
|
152
|
+
Term::ANSIColor::coloring = STDOUT.isatty
|
data/lib/tconsole/server.rb
CHANGED
@@ -93,6 +93,9 @@ module TConsole
|
|
93
93
|
begin
|
94
94
|
self.last_result = Marshal.load(response.unpack("m")[0])
|
95
95
|
rescue
|
96
|
+
puts "ERROR: Unable to process test results."
|
97
|
+
puts
|
98
|
+
|
96
99
|
# Just in case anything crazy goes down with marshalling
|
97
100
|
self.last_result = TConsole::TestResult.new
|
98
101
|
end
|
@@ -179,6 +182,28 @@ module TConsole
|
|
179
182
|
puts
|
180
183
|
end
|
181
184
|
|
185
|
+
def show_performance(limit = nil)
|
186
|
+
|
187
|
+
limit = limit.to_i
|
188
|
+
limit = last_result.timings.length if limit == 0
|
189
|
+
|
190
|
+
sorted_timings = last_result.timings.sort_by { |timing| timing[:time] }
|
191
|
+
|
192
|
+
puts
|
193
|
+
puts "Timings from last run:"
|
194
|
+
puts
|
195
|
+
|
196
|
+
if sorted_timings.length == 0
|
197
|
+
puts "No timing data available. Be sure you've run some tests."
|
198
|
+
else
|
199
|
+
sorted_timings.reverse[0, limit].each do |timing|
|
200
|
+
puts "#{timing[:time]}s #{timing[:suite]}##{timing[:method]}"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
puts
|
205
|
+
end
|
206
|
+
|
182
207
|
def filenameify(klass_name)
|
183
208
|
result = ""
|
184
209
|
first = true
|
data/lib/tconsole/test_result.rb
CHANGED
@@ -12,16 +12,39 @@ module TConsole
|
|
12
12
|
# Details about the failures in the last run
|
13
13
|
attr_accessor :failure_details
|
14
14
|
|
15
|
+
# The suites that we've run
|
16
|
+
attr_accessor :suites
|
17
|
+
|
18
|
+
# The timings for the tests we've run
|
19
|
+
attr_accessor :timings
|
20
|
+
|
15
21
|
def initialize
|
16
22
|
self.failures = 0
|
17
23
|
self.errors = 0
|
18
24
|
self.skips = 0
|
19
25
|
self.failure_details = []
|
26
|
+
self.suites = {}
|
27
|
+
self.timings = []
|
20
28
|
end
|
21
29
|
|
22
30
|
# Adds to the failure details that we know about
|
23
31
|
def append_failure_details(klass, meth)
|
24
|
-
failure_details << { :class => klass.to_s, :method => meth.to_s }
|
32
|
+
self.failure_details << { :class => klass.to_s, :method => meth.to_s }
|
33
|
+
end
|
34
|
+
|
35
|
+
# Records that we've encountered a particular suite. Returns true
|
36
|
+
# if it's new or false otherwise.
|
37
|
+
def add_suite(suite)
|
38
|
+
if suites.has_key?(suite.to_s)
|
39
|
+
false
|
40
|
+
else
|
41
|
+
suites[suite.to_s] = true
|
42
|
+
true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def add_timing(suite, method, time)
|
47
|
+
self.timings << { :suite => suite.to_s, :method => method.to_s, :time => time }
|
25
48
|
end
|
26
49
|
end
|
27
50
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module TConsole
|
2
|
+
class Util
|
3
|
+
# Returns [width, height] of terminal when detected, nil if not detected.
|
4
|
+
# Think of this as a simpler version of Highline's Highline::SystemExtensions.terminal_size()
|
5
|
+
#
|
6
|
+
# This is a copy of HIRB's terminal size detection code: https://github.com/cldwalker/hirb/blob/master/lib/hirb/util.rb
|
7
|
+
def self.detect_terminal_size
|
8
|
+
if (ENV['COLUMNS'] =~ /^\d+$/) && (ENV['LINES'] =~ /^\d+$/)
|
9
|
+
[ENV['COLUMNS'].to_i, ENV['LINES'].to_i]
|
10
|
+
elsif (RUBY_PLATFORM =~ /java/ || (!STDIN.tty? && ENV['TERM'])) && command_exists?('tput')
|
11
|
+
[`tput cols`.to_i, `tput lines`.to_i]
|
12
|
+
elsif STDIN.tty? && command_exists?('stty')
|
13
|
+
`stty size`.scan(/\d+/).map { |s| s.to_i }.reverse
|
14
|
+
else
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
rescue
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/tconsole/version.rb
CHANGED
data/tconsole.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tconsole
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.0pre2
|
5
5
|
prerelease: 5
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,19 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
13
|
-
dependencies:
|
12
|
+
date: 2012-02-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: term-ansicolor
|
16
|
+
requirement: &70111282504820 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.0.7
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70111282504820
|
14
25
|
description: ! " tconsole allows Rails developers to easily and quickly run their
|
15
26
|
tests as a whole or in subsets. It forks the testing processes from\n a preloaded
|
16
27
|
test environment to ensure that developers don't have to reload their entire Rails
|
@@ -32,6 +43,7 @@ files:
|
|
32
43
|
- lib/tconsole/minitest_handler.rb
|
33
44
|
- lib/tconsole/server.rb
|
34
45
|
- lib/tconsole/test_result.rb
|
46
|
+
- lib/tconsole/util.rb
|
35
47
|
- lib/tconsole/version.rb
|
36
48
|
- tconsole.gemspec
|
37
49
|
homepage: ''
|