dohtest 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/bin/dohtest +18 -0
- data/lib/doh/test/assertions.rb +55 -0
- data/lib/doh/test/backtrace_parser.rb +64 -0
- data/lib/doh/test/configure.rb +18 -0
- data/lib/doh/test/group_runner.rb +79 -0
- data/lib/doh/test/master_runner.rb +31 -0
- data/lib/doh/test/require_paths.rb +13 -0
- data/lib/doh/test/stream_output.rb +67 -0
- data/lib/doh/test/test_group.rb +17 -0
- data/test/test_backtrace_parser.rb +77 -0
- metadata +75 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2007 Makani Mason, Kem Mason
|
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/bin/dohtest
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'doh/options'
|
3
|
+
require 'doh/test/master_runner'
|
4
|
+
require 'doh/test/stream_output'
|
5
|
+
|
6
|
+
opts = Doh::Options.new(
|
7
|
+
{'grep' => [nil, "-g", "--grep <name>", "only execute tests with name that include the given value"] \
|
8
|
+
,'glob' => ['*.dt.rb', "-b", "--glob <string>", "glob string to find test files"] \
|
9
|
+
,'seed' => [nil, "-v", "--seed <number>", "random seed"] \
|
10
|
+
}, true, 'Files or directories may be specified to run tests on. Directories will be treated recursively. Defaults to the current directory.')
|
11
|
+
|
12
|
+
config = {}
|
13
|
+
config[:grep] = opts.grep if opts.grep
|
14
|
+
config[:glob] = opts.glob
|
15
|
+
config[:seed] = opts.seed.to_i if opts.seed
|
16
|
+
config[:paths] = (if opts.varargs.empty? then ['.'] else opts.varargs end)
|
17
|
+
|
18
|
+
exit DohTest::MasterRunner.new(DohTest::StreamOutput.new, config).run
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module DohTest
|
2
|
+
|
3
|
+
AssertionFailed = Class.new(StandardError)
|
4
|
+
|
5
|
+
class TestGroup
|
6
|
+
def assert(condition, msg = nil)
|
7
|
+
if condition
|
8
|
+
@runner.assertion_passed
|
9
|
+
else
|
10
|
+
raise DohTest::AssertionFailed, msg || "Assertion failed."
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def build_equal_msg(expected, actual)
|
15
|
+
if (expected.to_s.size + actual.to_s.size) < 50
|
16
|
+
"expected: #{expected}; actual: #{actual}"
|
17
|
+
else
|
18
|
+
"\nexpected: #{expected}\n actual: #{actual}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def assert_equal(expected, actual, msg = nil)
|
23
|
+
assert(expected == actual, msg || build_equal_msg(expected, actual))
|
24
|
+
end
|
25
|
+
|
26
|
+
def assert_raises(*args)
|
27
|
+
msg = args.pop if args.last.is_a?(String)
|
28
|
+
|
29
|
+
begin
|
30
|
+
yield
|
31
|
+
no_exception = true
|
32
|
+
rescue Exception => excpt
|
33
|
+
assert(args.include?(excpt.class), msg || "expected: #{args}; actual: #{excpt}")
|
34
|
+
return
|
35
|
+
end
|
36
|
+
|
37
|
+
if no_exception
|
38
|
+
raise DohTest::AssertionFailed, msg || "expected: #{args}, but no exception was raised"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def assert_instance_of(expected_class, actual_object, msg = nil)
|
43
|
+
assert(actual_object.instance_of?(expected_class), msg || "expected class: #{expected_class}; actual: #{actual_object.class}")
|
44
|
+
end
|
45
|
+
|
46
|
+
def assert_match(expected_regex, actual_str, msg = nil)
|
47
|
+
assert(actual_str.match(expected_regex), msg || "expected regex #{expected_regex} to match str: #{actual_str}")
|
48
|
+
end
|
49
|
+
|
50
|
+
def assert_not_equal(expected, actual, msg = nil)
|
51
|
+
assert(expected != actual, msg || "expected unequal values")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module DohTest
|
2
|
+
|
3
|
+
class BacktraceParser
|
4
|
+
def initialize(backtrace)
|
5
|
+
@backtrace = backtrace
|
6
|
+
end
|
7
|
+
|
8
|
+
def relevant_stack
|
9
|
+
@relevant_stack ||= find_relevant_stack
|
10
|
+
end
|
11
|
+
|
12
|
+
def summary
|
13
|
+
@summary ||= build_summary
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def find_relevant_stack
|
18
|
+
retval = []
|
19
|
+
found_start = false
|
20
|
+
@backtrace.each do |location|
|
21
|
+
has_doh_test = location.index('doh/test')
|
22
|
+
if found_start && has_doh_test
|
23
|
+
break
|
24
|
+
elsif has_doh_test
|
25
|
+
# just ignore it and continue
|
26
|
+
else
|
27
|
+
found_start = true
|
28
|
+
info = location.rpartition(':in').first
|
29
|
+
retval << info
|
30
|
+
end
|
31
|
+
end
|
32
|
+
retval
|
33
|
+
end
|
34
|
+
|
35
|
+
def build_summary
|
36
|
+
retval = ''
|
37
|
+
prev_filename = ''
|
38
|
+
prev_simplified = ''
|
39
|
+
relevant_stack.each do |location|
|
40
|
+
parts = location.partition(':')
|
41
|
+
filename = File.basename(parts.first)
|
42
|
+
simplified = "#{filename}:#{parts.last}"
|
43
|
+
raise "unexpected location format: #{location}" unless filename
|
44
|
+
if simplified == prev_simplified
|
45
|
+
# ignore it
|
46
|
+
elsif filename == prev_filename
|
47
|
+
retval += ",#{parts.last}"
|
48
|
+
elsif retval.empty?
|
49
|
+
retval = simplified
|
50
|
+
else
|
51
|
+
retval += ";#{simplified}"
|
52
|
+
end
|
53
|
+
prev_filename = filename
|
54
|
+
prev_simplified = simplified
|
55
|
+
end
|
56
|
+
retval
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.backtrace_summary(excpt)
|
61
|
+
BacktraceParser.new(excpt.backtrace).summary
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'doh/root'
|
2
|
+
|
3
|
+
module DohTest
|
4
|
+
|
5
|
+
def self.configure(start_path)
|
6
|
+
start_directory = File.dirname(start_path)
|
7
|
+
|
8
|
+
root_directory = Doh::find_root(start_directory)
|
9
|
+
if root_directory
|
10
|
+
root_filename = File.join(root_directory, 'config', 'dohtest.rb')
|
11
|
+
require(root_filename) if File.exist?(root_filename)
|
12
|
+
end
|
13
|
+
|
14
|
+
local_filename = Doh::findup(start_directory, 'configure_dohtest.rb')
|
15
|
+
require(local_filename) if local_filename && File.exist?(local_filename)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'doh/test/test_group'
|
2
|
+
|
3
|
+
module DohTest
|
4
|
+
|
5
|
+
class GroupRunner
|
6
|
+
def initialize(group_class, output, config = nil)
|
7
|
+
@group_class,@output = group_class,output
|
8
|
+
@config = config || {}
|
9
|
+
@group_name = @group_class.to_s
|
10
|
+
@group_failed = false
|
11
|
+
end
|
12
|
+
|
13
|
+
def run
|
14
|
+
@output.group_begin(@group_name)
|
15
|
+
create_group
|
16
|
+
run_before_all unless @group_failed
|
17
|
+
run_tests unless @group_failed
|
18
|
+
run_after_all unless @group_failed
|
19
|
+
@output.group_end(@group_name)
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_group
|
23
|
+
@group = @group_class.new
|
24
|
+
rescue => error
|
25
|
+
@group_failed = true
|
26
|
+
@output.test_error(@group_name, 'initialize', error)
|
27
|
+
else
|
28
|
+
@group.runner = self
|
29
|
+
end
|
30
|
+
|
31
|
+
def run_before_all
|
32
|
+
@group.before_all if @group.respond_to?(:before_all)
|
33
|
+
rescue => error
|
34
|
+
@group_failed = true
|
35
|
+
@output.test_error(@group_name, 'before_all', error)
|
36
|
+
end
|
37
|
+
|
38
|
+
def run_after_all
|
39
|
+
@group.after_all if @group.respond_to?(:after_all)
|
40
|
+
rescue => error
|
41
|
+
@output.test_error(@group_name, 'after_all', error)
|
42
|
+
end
|
43
|
+
|
44
|
+
def run_tests
|
45
|
+
determine_test_methods
|
46
|
+
has_before_each = @group.respond_to?(:before_each)
|
47
|
+
has_after_each = @group.respond_to?(:after_each)
|
48
|
+
|
49
|
+
@test_methods.each do |method_name|
|
50
|
+
@test_name = method_name
|
51
|
+
begin
|
52
|
+
@group.send(:before_each) if has_before_each
|
53
|
+
@output.test_begin(@group_name, @test_name)
|
54
|
+
@group.send(@test_name)
|
55
|
+
@output.test_end(@group_name, @test_name)
|
56
|
+
@group.send(:after_each) if has_after_each
|
57
|
+
rescue DohTest::AssertionFailed => failure
|
58
|
+
@output.assertion_failed(@group_name, @test_name, failure)
|
59
|
+
rescue => error
|
60
|
+
@output.test_error(@group_name, @test_name, error)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def determine_test_methods
|
66
|
+
@test_methods = @group_class.public_instance_methods.grep(/^test/)
|
67
|
+
original_test_count = @test_methods.size
|
68
|
+
return unless @config.key?(:grep)
|
69
|
+
grep_filter = Regexp.new(@config[:grep])
|
70
|
+
@test_methods.select! { |method| name.to_s =~ grep_filter }
|
71
|
+
@output.tests_skipped(@group_name, original_test_count - @test_methods.size)
|
72
|
+
end
|
73
|
+
|
74
|
+
def assertion_passed
|
75
|
+
@output.assertion_passed(@group_name, @test_name)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'doh/test/configure'
|
2
|
+
require 'doh/test/group_runner'
|
3
|
+
require 'doh/test/require_paths'
|
4
|
+
|
5
|
+
module DohTest
|
6
|
+
|
7
|
+
class MasterRunner
|
8
|
+
def initialize(output, config)
|
9
|
+
@output, @config = output, config
|
10
|
+
add_missing_config
|
11
|
+
end
|
12
|
+
|
13
|
+
def run
|
14
|
+
paths = @config[:paths]
|
15
|
+
DohTest::configure(paths[0])
|
16
|
+
DohTest::require_paths(@config[:glob], paths)
|
17
|
+
srand(@config[:seed])
|
18
|
+
@output.run_begin(@config)
|
19
|
+
TestGroup.descendants.each { |group_class| GroupRunner.new(group_class, @output, @config).run }
|
20
|
+
@output.run_end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def add_missing_config
|
25
|
+
@config[:glob] ||= '*.dt.rb'
|
26
|
+
@config[:seed] ||= (Time.new.to_f * 1000).to_i
|
27
|
+
@config[:paths] ||= ['.']
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module DohTest
|
2
|
+
|
3
|
+
def self.require_paths(glob, paths)
|
4
|
+
paths.collect {|elem| File.expand_path(elem) }.each do |onepath|
|
5
|
+
if File.directory?(onepath)
|
6
|
+
Dir.glob(File.join(onepath, '**', glob)).each {|filename| require(filename)}
|
7
|
+
else
|
8
|
+
require(File.expand_path(onepath))
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'doh/test/backtrace_parser'
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
module DohTest
|
5
|
+
|
6
|
+
class StreamOutput
|
7
|
+
def initialize
|
8
|
+
@error_count = @group_cnt = @tests_ran = @tests_skipped = @assertions_failed = @assertions_passed = 0
|
9
|
+
@badness = Set.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def run_begin(config)
|
13
|
+
puts "running tests with config: #{config}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def run_end
|
17
|
+
total_assertions = @assertions_passed + @assertions_failed
|
18
|
+
puts "\n\n#@error_count errors, #@group_cnt groups, #@tests_ran tests, #{@tests_skipped} skipped, #{total_assertions} assertions, #@assertions_passed passed, #@assertions_failed failed"
|
19
|
+
puts "completed in 0.043702s, 22.8822 tests/s, 45.7645 assertions/s <TODO: put real values here>"
|
20
|
+
# this is to generate an exit code; true translates to 0, false to 1
|
21
|
+
@error_count == 0 && @assertions_failed == 0
|
22
|
+
end
|
23
|
+
|
24
|
+
def group_begin(group_name)
|
25
|
+
@group_cnt += 1
|
26
|
+
end
|
27
|
+
|
28
|
+
def group_end(group_name)
|
29
|
+
puts "success in #{group_name}" unless @badness.include?(group_name)
|
30
|
+
end
|
31
|
+
|
32
|
+
def tests_skipped(group_name, count)
|
33
|
+
@tests_skipped += count
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_begin(group_name, test_name)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_end(group_name, test_name)
|
40
|
+
@tests_ran += 1
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_error(group_name, test_name, error)
|
44
|
+
@badness.add(group_name)
|
45
|
+
@error_count += 1
|
46
|
+
display_badness('error', group_name, test_name, error, true)
|
47
|
+
end
|
48
|
+
|
49
|
+
def assertion_failed(group_name, test_name, failure)
|
50
|
+
@badness.add(group_name)
|
51
|
+
@assertions_failed += 1
|
52
|
+
display_badness('failure', group_name, test_name, failure, false)
|
53
|
+
end
|
54
|
+
|
55
|
+
def assertion_passed(group_name, test_name)
|
56
|
+
@assertions_passed += 1
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
def display_badness(title, group_name, test_name, excpt, display_name)
|
61
|
+
warn "#{title} in #{group_name}.#{test_name} at #{DohTest::backtrace_summary(excpt)}"
|
62
|
+
badname = if display_name then "#{excpt.class}: " else '' end
|
63
|
+
warn "=> #{badname}#{excpt}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require_relative '../lib/doh/test/backtrace_parser'
|
3
|
+
|
4
|
+
module DohTest
|
5
|
+
|
6
|
+
class TestBacktraceParser < MiniTest::Unit::TestCase
|
7
|
+
def create_single_stack
|
8
|
+
retval = []
|
9
|
+
retval << "/Users/somebody/dohtest/lib/doh/test/assertions.rb:10:in `assert'"
|
10
|
+
retval << "/Users/somebody/dohtest/lib/doh/test/assertions.rb:15:in `assert_equal'"
|
11
|
+
retval << "/Users/somebody/tinker/test/frog.rb:12:in `test_thing'"
|
12
|
+
retval << "/Users/somebody/dohtest/lib/doh/test/group_runner.rb:28:in `block in run_group'"
|
13
|
+
retval << "/Users/somebody/dohtest/lib/doh/test/group_runner.rb:12:in `each'"
|
14
|
+
retval << "/Users/somebody/dohtest/lib/doh/test/group_runner.rb:12:in `run'"
|
15
|
+
retval << "/Users/somebody/dohtest/bin/dohtest:24:in `<main>'"
|
16
|
+
retval
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_single_stack
|
20
|
+
location = DohTest::BacktraceParser.new(create_single_stack).summary
|
21
|
+
assert_equal("frog.rb:12", location)
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_double_stack
|
25
|
+
retval = []
|
26
|
+
retval << "/Users/somebody/dohtest/lib/doh/test/assertions.rb:10:in `assert'"
|
27
|
+
retval << "/Users/somebody/tinker/test/frog.rb:5:in `verify_sum'"
|
28
|
+
retval << "/Users/somebody/tinker/test/frog.rb:12:in `test_thing'"
|
29
|
+
retval << "/Users/somebody/dohtest/lib/doh/test/group_runner.rb:28:in `block in run_group'"
|
30
|
+
retval
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_double_stack
|
34
|
+
location = DohTest::BacktraceParser.new(create_double_stack).summary
|
35
|
+
assert_equal("frog.rb:5,12", location)
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_multifile_stack
|
39
|
+
retval = []
|
40
|
+
retval << "/Users/somebody/dohtest/lib/doh/test/assertions.rb:10:in `assert'"
|
41
|
+
retval << "/Users/somebody/tinker/helpers/toad.rb:8:in `verify_sum'"
|
42
|
+
retval << "/Users/somebody/tinker/test/frog.rb:11:in `test_thing'"
|
43
|
+
retval << "/Users/somebody/dohtest/lib/doh/test/group_runner.rb:28:in `block in run_group'"
|
44
|
+
retval
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_multifile_stack
|
48
|
+
location = DohTest::BacktraceParser.new(create_multifile_stack).summary
|
49
|
+
assert_equal("toad.rb:8;frog.rb:11", location)
|
50
|
+
end
|
51
|
+
|
52
|
+
def create_duplicate_stack
|
53
|
+
retval = []
|
54
|
+
retval << "/Users/somebody/tinker/dtest/blee.rb:30:in `/'"
|
55
|
+
retval << "/Users/somebody/tinker/dtest/blee.rb:30:in `test_silly_error'"
|
56
|
+
retval << "/Users/somebody/dohtest/lib/doh/test/group_runner.rb:28:in `block in run_group'"
|
57
|
+
retval
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_duplicate_stack
|
61
|
+
location = DohTest::BacktraceParser.new(create_duplicate_stack).summary
|
62
|
+
assert_equal("blee.rb:30", location)
|
63
|
+
end
|
64
|
+
|
65
|
+
def create_block_stack
|
66
|
+
retval = []
|
67
|
+
retval << "/Users/somebody/tinker/dtest/kblah.rb:3:in `block in <class:TestKblah>'"
|
68
|
+
retval
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_block_stack
|
72
|
+
location = DohTest::BacktraceParser.new(create_block_stack).summary
|
73
|
+
assert_equal("kblah.rb:3", location)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dohtest
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Makani Mason
|
9
|
+
- Kem Mason
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2012-01-27 00:00:00.000000000Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: dohutil
|
17
|
+
requirement: &70176037590840 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.1.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *70176037590840
|
26
|
+
description: This is a fairly straight forward replacement for minitest, though some
|
27
|
+
changes to test code are required. Code is meant to be easy to understand and extend.
|
28
|
+
Includes dohtest to make execution convenient. Designed for speed, including running
|
29
|
+
tests concurrently (though as of this version that's not implemented).
|
30
|
+
email:
|
31
|
+
- gitauthor@pqmland.com
|
32
|
+
executables:
|
33
|
+
- dohtest
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files:
|
36
|
+
- MIT-LICENSE
|
37
|
+
files:
|
38
|
+
- bin/dohtest
|
39
|
+
- lib/doh/test/assertions.rb
|
40
|
+
- lib/doh/test/backtrace_parser.rb
|
41
|
+
- lib/doh/test/configure.rb
|
42
|
+
- lib/doh/test/group_runner.rb
|
43
|
+
- lib/doh/test/master_runner.rb
|
44
|
+
- lib/doh/test/require_paths.rb
|
45
|
+
- lib/doh/test/stream_output.rb
|
46
|
+
- lib/doh/test/test_group.rb
|
47
|
+
- test/test_backtrace_parser.rb
|
48
|
+
- MIT-LICENSE
|
49
|
+
homepage: https://github.com/pquimo/dohtest
|
50
|
+
licenses:
|
51
|
+
- MIT
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.9.2
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
requirements: []
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.8.10
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: Minimalist unit test framework.
|
74
|
+
test_files:
|
75
|
+
- test/test_backtrace_parser.rb
|