myronmarston-test_benchmarker 0.9.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/CHANGELOG ADDED
@@ -0,0 +1,3 @@
1
+ == 1.0.0 2009-03-27
2
+
3
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,14 @@
1
+ CHANGELOG
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ lib
6
+ lib/test_benchmarker
7
+ lib/test_benchmarker.rb
8
+ lib/test_benchmarker/core_ext.rb
9
+ lib/test_benchmarker/test_benchmarks.rb
10
+ lib/test_benchmarker/test_suite.rb
11
+ test
12
+ test/test_core_ext.rb
13
+ test/test_helper.rb
14
+ test/test_test_benchmarker.rb
data/README.rdoc ADDED
@@ -0,0 +1,48 @@
1
+ = test_benchmarker
2
+
3
+ * FIX (url)
4
+
5
+ == DESCRIPTION:
6
+
7
+ FIX (describe your package)
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * FIX (list of features or problems)
12
+
13
+ == SYNOPSIS:
14
+
15
+ FIX (code sample of usage)
16
+
17
+ == REQUIREMENTS:
18
+
19
+ * FIX (list of requirements)
20
+
21
+ == INSTALL:
22
+
23
+ * FIX (sudo gem install, anything else)
24
+
25
+ == LICENSE:
26
+
27
+ (The MIT License)
28
+
29
+ Copyright (c) 2009 Myron Marston, Kashless.org
30
+
31
+ Permission is hereby granted, free of charge, to any person obtaining
32
+ a copy of this software and associated documentation files (the
33
+ 'Software'), to deal in the Software without restriction, including
34
+ without limitation the rights to use, copy, modify, merge, publish,
35
+ distribute, sublicense, and/or sell copies of the Software, and to
36
+ permit persons to whom the Software is furnished to do so, subject to
37
+ the following conditions:
38
+
39
+ The above copyright notice and this permission notice shall be
40
+ included in all copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
43
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
45
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
46
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
47
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
48
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,42 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+
6
+ task :default => :test
7
+
8
+ desc "Run All Tests"
9
+ Rake::TestTask.new :test do |test|
10
+ test.test_files = ["test/**/*.rb"]
11
+ test.verbose = true
12
+ end
13
+
14
+ desc %{Update ".manifest" with the latest list of project filenames. Respect\
15
+ .gitignore by excluding everything that git ignores. Update `files` and\
16
+ `test_files` arrays in "*.gemspec" file if it's present.}
17
+ task :manifest do
18
+ list = Dir['**/*'].sort
19
+ spec_file = Dir['*.gemspec'].first
20
+ list -= [spec_file] if spec_file
21
+
22
+ if File.exist?('.gitignore')
23
+ File.read('.gitignore').each_line do |glob|
24
+ glob = glob.chomp.sub(/^\//, '')
25
+ list -= Dir[glob]
26
+ list -= Dir["#{glob}/**/*"] if File.directory?(glob) and !File.symlink?(glob)
27
+ puts "excluding #{glob}"
28
+ end
29
+ end
30
+
31
+ if spec_file
32
+ spec = File.read spec_file
33
+ spec.gsub! /^(\s* s.(test_)?files \s* = \s* )( \[ [^\]]* \] | %w\( [^)]* \) )/mx do
34
+ assignment = $1
35
+ bunch = $2 ? list.grep(/^test\//) : list
36
+ '%s%%w(%s)' % [assignment, bunch.join(' ')]
37
+ end
38
+
39
+ File.open(spec_file, 'w') {|f| f << spec }
40
+ end
41
+ File.open('manifest.txt', 'w') {|f| f << list.join("\n") }
42
+ end
@@ -0,0 +1,7 @@
1
+ module TestBenchmarker
2
+ VERSION = '0.9.1'
3
+ end
4
+
5
+ require 'lib/test_benchmarker/test_benchmarks'
6
+ require 'lib/test_benchmarker/test_suite'
7
+ require 'lib/test_benchmarker/core_ext'
@@ -0,0 +1,25 @@
1
+ class TestBenchmarker::ClassNotFoundError < StandardError
2
+ attr_accessor :class_str
3
+ def initialize(class_str)
4
+ @class_str = class_str
5
+ end
6
+ end
7
+
8
+ class String
9
+ # similar to ActiveSupports constantize, but doesn't require the use of active support.
10
+ def to_class
11
+ ObjectSpace.each_object(Class) do |klass|
12
+ return klass if klass.to_s == self
13
+ end
14
+
15
+ raise TestBenchmarker::ClassNotFoundError.new(self), "A class matching '#{self}' could not be found"
16
+ end
17
+ end
18
+
19
+ class Class
20
+ def is_subclass_of?(klass)
21
+ return false if self == Object && klass != Object
22
+ return true if self == klass
23
+ return self.superclass.is_subclass_of?(klass)
24
+ end
25
+ end
@@ -0,0 +1,67 @@
1
+ require 'ostruct'
2
+
3
+ module TestBenchmarker
4
+ class TestBenchmark
5
+ attr_reader :test_class, :test_name, :benchmark
6
+
7
+ def initialize(test_class, test_name, benchmark)
8
+ @test_class, @test_name, @benchmark = test_class, test_name, benchmark
9
+ TestBenchmarks.add(self)
10
+ end
11
+ end
12
+
13
+ class TestBenchmarks
14
+ def self.clear
15
+ @@classes = {}
16
+ @@tests = []
17
+ end
18
+
19
+ self.clear
20
+
21
+ def self.add(benchmark)
22
+ test_class = benchmark.test_class
23
+
24
+ # ignore some bogus test classes that get passed here when run in the context of a rails app...
25
+ return if test_class =~ /(rake_test_loader|::TestCase|::IntegrationTest)/
26
+
27
+ begin
28
+ test_class = test_class.to_class
29
+ rescue TestBenchmarker::ClassNotFoundError
30
+ return
31
+ end
32
+ return unless test_class.is_subclass_of?(Test::Unit::TestCase)
33
+
34
+ @@classes[test_class] ||= OpenStruct.new
35
+ @@classes[test_class].benchmarks ||= []
36
+ @@classes[test_class].benchmarks << benchmark
37
+ @@tests << benchmark
38
+ end
39
+
40
+ def self.print_results
41
+ return if @@classes.nil? || @@classes.size == 0
42
+
43
+ benchmark_attr = :real
44
+
45
+ class_benchmarks = []
46
+ @@classes.each do |test_class, obj|
47
+ obj.test_count = obj.benchmarks.size
48
+ obj.sum = obj.benchmarks.inject(0) {|sum, bmark| sum + bmark.benchmark.send(benchmark_attr)}
49
+ obj.avg = obj.sum / obj.test_count
50
+ obj.test_class = test_class
51
+ class_benchmarks << obj unless obj.benchmarks.nil? || obj.benchmarks.size == 0
52
+ end
53
+
54
+ puts "\n\n#{'=' * 27} Class Benchmark Results #{'=' * 27}"
55
+ class_benchmarks.sort {|a, b| b.avg <=> a.avg}.each_with_index do |cb, i|
56
+ puts "#{i + 1}.#{' ' * (4 - (i + 1).to_s.length)} #{format("%.3f", cb.avg)} secs avg time, #{format("%.3f", cb.sum)} secs total time, #{cb.test_count} tests for: #{cb.test_class.to_s}"
57
+ end
58
+ puts "#{'=' * 79}\n\n"
59
+
60
+ puts "\n\n#{'=' * 28} Test Benchmark Results #{'=' * 28}"
61
+ @@tests.sort {|a, b| b.benchmark.send(benchmark_attr) <=> a.benchmark.send(benchmark_attr)}.each_with_index do |t, i|
62
+ puts "#{i + 1}.#{' ' * (4 - (i + 1).to_s.length)} #{format("%.3f", t.benchmark.real)} secs total time for: #{t.test_name}"
63
+ end
64
+ puts "#{'=' * 80}\n\n"
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,22 @@
1
+ require 'benchmark'
2
+
3
+ if ENV['BENCHMARK_TESTS']
4
+ class Test::Unit::TestSuite
5
+ @@run_count = 0
6
+
7
+ def run(result, &progress_block)
8
+ @@run_count += 1
9
+ begin
10
+ yield(STARTED, name)
11
+ @tests.each do |test|
12
+ TestBenchmarker::TestBenchmark.new(self.name, test.name, Benchmark.measure { test.run(result, &progress_block) })
13
+ end
14
+ yield(FINISHED, name)
15
+ ensure
16
+ @@run_count -= 1
17
+ # print the results as we're exiting the very last test run...
18
+ TestBenchmarker::TestBenchmarks.print_results if @@run_count == 0
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,32 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class Foo; end
4
+ class FooSubclass < Foo; end
5
+ class FooSubSubclass < FooSubclass; end
6
+ class Bar; end
7
+
8
+ class TestCoreExt < Test::Unit::TestCase
9
+ def test_string_to_class
10
+ assert_equal TestCoreExt, 'TestCoreExt'.to_class
11
+ assert_equal FooSubSubclass, 'FooSubSubclass'.to_class
12
+ end
13
+
14
+ def test_string_to_class_not_found
15
+ assert_raise TestBenchmarker::ClassNotFoundError do
16
+ 'This it not the name of a class!'.to_class
17
+ end
18
+ end
19
+
20
+ def test_class_is_subclass_of
21
+ assert FooSubclass.is_subclass_of?(Foo)
22
+ assert FooSubclass.is_subclass_of?(Object)
23
+
24
+ assert FooSubSubclass.is_subclass_of?(FooSubclass)
25
+ assert FooSubSubclass.is_subclass_of?(Foo)
26
+ assert FooSubSubclass.is_subclass_of?(Object)
27
+ end
28
+
29
+ def test_class_is_not_subclass_of
30
+ assert !Bar.is_subclass_of?(Foo)
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/test_benchmarker'
@@ -0,0 +1,117 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class Foo; end
4
+ class Class1 < Test::Unit::TestCase
5
+ def test_truth; end
6
+ end
7
+
8
+ class Class2 < Test::Unit::TestCase
9
+ def test_truth; end
10
+ end
11
+
12
+ class Class3 < Test::Unit::TestCase
13
+ def test_truth; end
14
+ end
15
+
16
+ class Class4; end
17
+
18
+ class TestTestBenchmarker < Test::Unit::TestCase
19
+ def setup
20
+ 1.upto(3) do |class_speed|
21
+ 1.upto(3) do |test_speed|
22
+ speed = class_speed * 0.01 + test_speed * 0.001
23
+ TestBenchmarker::TestBenchmark.new("Class#{class_speed}", "test_#{test_speed} (Class#{class_speed})", ::Benchmark.measure { sleep speed })
24
+ end
25
+ end
26
+
27
+ TestBenchmarker::TestBenchmark.new("Class4", "test_1 (Class4)", ::Benchmark.measure { sleep 0.01 })
28
+
29
+ @benchmarked_classes = TestBenchmarker::TestBenchmarks.send(:class_variable_get, '@@classes')
30
+ @benchmarked_tests = TestBenchmarker::TestBenchmarks.send(:class_variable_get, '@@tests').map{ |t| t.test_name }
31
+ @out, @err = util_capture { TestBenchmarker::TestBenchmarks.print_results }
32
+ end
33
+
34
+ def teardown
35
+ TestBenchmarker::TestBenchmarks.clear
36
+ end
37
+
38
+ def test_has_expected_benchmarked_classes
39
+ assert_equal 3, @benchmarked_classes.keys.size
40
+
41
+ assert @benchmarked_classes.keys.include?(Class1)
42
+ assert @benchmarked_classes.keys.include?(Class2)
43
+ assert @benchmarked_classes.keys.include?(Class3)
44
+ end
45
+
46
+ def test_does_not_have_classes_not_descended_from_test_unit_testcase
47
+ assert !@benchmarked_classes.keys.include?(Class4)
48
+ end
49
+
50
+ def test_has_expected_benchmarked_tests
51
+ assert_equal 9, @benchmarked_tests.size
52
+
53
+ assert @benchmarked_tests.include?('test_1 (Class1)')
54
+ assert @benchmarked_tests.include?('test_2 (Class1)')
55
+ assert @benchmarked_tests.include?('test_3 (Class1)')
56
+ assert @benchmarked_tests.include?('test_1 (Class2)')
57
+ assert @benchmarked_tests.include?('test_2 (Class2)')
58
+ assert @benchmarked_tests.include?('test_3 (Class2)')
59
+ assert @benchmarked_tests.include?('test_1 (Class3)')
60
+ assert @benchmarked_tests.include?('test_2 (Class3)')
61
+ assert @benchmarked_tests.include?('test_3 (Class3)')
62
+ end
63
+
64
+ def test_does_not_have_tests_not_descended_from_test_unit_testcase
65
+ assert !@benchmarked_tests.include?("test_1 (Class4)")
66
+ end
67
+
68
+ def test_class_benchmark_results
69
+ # should be in order from slowest to fastest
70
+ assert_match class_benchmark_regex('Class3', 1), @out
71
+ assert_match class_benchmark_regex('Class2', 2), @out
72
+ assert_match class_benchmark_regex('Class1', 3), @out
73
+ end
74
+
75
+ def test_test_benchmark_results
76
+ # should be in order from slowest to fastest
77
+ assert_match test_benchmark_regex('test_3 (Class3)', 1), @out
78
+ assert_match test_benchmark_regex('test_2 (Class3)', 2), @out
79
+ assert_match test_benchmark_regex('test_1 (Class3)', 3), @out
80
+ assert_match test_benchmark_regex('test_3 (Class2)', 4), @out
81
+ assert_match test_benchmark_regex('test_2 (Class2)', 5), @out
82
+ assert_match test_benchmark_regex('test_1 (Class2)', 6), @out
83
+ assert_match test_benchmark_regex('test_3 (Class1)', 7), @out
84
+ assert_match test_benchmark_regex('test_2 (Class1)', 8), @out
85
+ assert_match test_benchmark_regex('test_1 (Class1)', 9), @out
86
+ end
87
+
88
+ private
89
+
90
+ # borrowed from zentest assertions...
91
+ def util_capture
92
+ require 'stringio'
93
+ orig_stdout = $stdout.dup
94
+ orig_stderr = $stderr.dup
95
+ captured_stdout = StringIO.new
96
+ captured_stderr = StringIO.new
97
+ $stdout = captured_stdout
98
+ $stderr = captured_stderr
99
+ yield
100
+ captured_stdout.rewind
101
+ captured_stderr.rewind
102
+ return captured_stdout.string, captured_stderr.string
103
+ ensure
104
+ $stdout = orig_stdout
105
+ $stderr = orig_stderr
106
+ end
107
+
108
+ def class_benchmark_regex(class_name, slowness_ranking)
109
+ # http://rubular.com/regexes/6815
110
+ /^#{slowness_ranking}\.\s+[\d\.]+ secs avg time, [\d\.]+ secs total time, [\d]+ tests for: #{Regexp.escape(class_name)}$/
111
+ end
112
+
113
+ def test_benchmark_regex(test_name, slowness_ranking)
114
+ # http://rubular.com/regexes/6816
115
+ /^#{slowness_ranking}.\s+[\d\.]+ secs total time for: #{Regexp.escape(test_name)}$/
116
+ end
117
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: myronmarston-test_benchmarker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.1
5
+ platform: ruby
6
+ authors:
7
+ - Myron Marston
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-27 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: myron.marston@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - CHANGELOG
24
+ - README.rdoc
25
+ files:
26
+ - CHANGELOG
27
+ - Manifest.txt
28
+ - README.rdoc
29
+ - Rakefile
30
+ - lib
31
+ - lib/test_benchmarker
32
+ - lib/test_benchmarker.rb
33
+ - lib/test_benchmarker/core_ext.rb
34
+ - lib/test_benchmarker/test_benchmarks.rb
35
+ - lib/test_benchmarker/test_suite.rb
36
+ - test
37
+ - test/test_core_ext.rb
38
+ - test/test_helper.rb
39
+ - test/test_test_benchmarker.rb
40
+ has_rdoc: true
41
+ homepage: http://github.com/myronmarston/test_benchmarker
42
+ post_install_message:
43
+ rdoc_options:
44
+ - --main
45
+ - README.rdoc
46
+ - --title
47
+ - TestBenchmarker Documentation
48
+ - --charset
49
+ - utf-8
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ requirements: []
65
+
66
+ rubyforge_project:
67
+ rubygems_version: 1.2.0
68
+ signing_key:
69
+ specification_version: 2
70
+ summary: A tool for benchmarking ruby Test::Unit tests
71
+ test_files:
72
+ - test/test_core_ext.rb
73
+ - test/test_helper.rb
74
+ - test/test_test_benchmarker.rb