rubytest 0.3.0
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/.ruby +45 -0
- data/.test +11 -0
- data/HISTORY.md +43 -0
- data/NOTICE.md +33 -0
- data/README.md +112 -0
- data/bin/rubytest +4 -0
- data/demo/01_test.md +29 -0
- data/demo/02_case.md +34 -0
- data/demo/applique/ruby-test.rb +2 -0
- data/lib/rubytest/autorun.rb +19 -0
- data/lib/rubytest/cli.rb +106 -0
- data/lib/rubytest/code_snippet.rb +93 -0
- data/lib/rubytest/config.rb +106 -0
- data/lib/rubytest/core_ext/assertion.rb +30 -0
- data/lib/rubytest/core_ext/exception.rb +8 -0
- data/lib/rubytest/core_ext/string.rb +30 -0
- data/lib/rubytest/core_ext.rb +9 -0
- data/lib/rubytest/rake.rb +124 -0
- data/lib/rubytest/recorder.rb +53 -0
- data/lib/rubytest/reporters/abstract.rb +261 -0
- data/lib/rubytest/reporters/abstract_hash.rb +224 -0
- data/lib/rubytest/reporters/dotprogress.rb +89 -0
- data/lib/rubytest/reporters/html.rb +155 -0
- data/lib/rubytest/reporters/outline.rb +211 -0
- data/lib/rubytest/reporters/progress.rb +195 -0
- data/lib/rubytest/reporters/summary.rb +145 -0
- data/lib/rubytest/reporters/tap.rb +61 -0
- data/lib/rubytest/reporters/tapj.rb +53 -0
- data/lib/rubytest/reporters/tapy.rb +58 -0
- data/lib/rubytest/reporters/test.rb +51 -0
- data/lib/rubytest/runner.rb +349 -0
- data/lib/rubytest.rb +28 -0
- data/lib/test.rb +8 -0
- data/test/basic_case.rb +11 -0
- metadata +119 -0
data/.ruby
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
---
|
2
|
+
source:
|
3
|
+
- var
|
4
|
+
authors:
|
5
|
+
- name: trans
|
6
|
+
email: transfire@gmail.com
|
7
|
+
copyrights:
|
8
|
+
- holder: RubyWorks
|
9
|
+
year: '2011'
|
10
|
+
license: BSD-2-Clause
|
11
|
+
replacements: []
|
12
|
+
alternatives: []
|
13
|
+
requirements:
|
14
|
+
- name: ansi
|
15
|
+
- name: detroit
|
16
|
+
groups:
|
17
|
+
- build
|
18
|
+
development: true
|
19
|
+
- name: qed
|
20
|
+
groups:
|
21
|
+
- test
|
22
|
+
development: true
|
23
|
+
dependencies: []
|
24
|
+
conflicts: []
|
25
|
+
repositories:
|
26
|
+
- uri: git@github.com:rubyworks/ruby-test.git
|
27
|
+
scm: git
|
28
|
+
name: upstream
|
29
|
+
resources:
|
30
|
+
home: http://rubyworks.github.com/ruby-test
|
31
|
+
code: http://github.com/rubyworks/ruby-test
|
32
|
+
mail: http://groups.google.com/group/rubyworks-mailinglist
|
33
|
+
extra: {}
|
34
|
+
load_path:
|
35
|
+
- lib
|
36
|
+
revision: 0
|
37
|
+
created: '2011-07-23'
|
38
|
+
summary: Ruby Universal Test Harness
|
39
|
+
title: Ruby Test
|
40
|
+
version: 0.3.0
|
41
|
+
name: rubytest
|
42
|
+
description: ! "Ruby Test is a universal test harness for Ruby. It can handle any
|
43
|
+
compliant \ntest framework, even running tests from multiple frameworks in a single
|
44
|
+
pass."
|
45
|
+
date: '2011-12-23'
|
data/.test
ADDED
data/HISTORY.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# RELEASE HISTORY
|
2
|
+
|
3
|
+
## 0.3.0 / 2011-12-22
|
4
|
+
|
5
|
+
Technically this is a fairly minor release that improves backtrace output
|
6
|
+
and prepares the `LOAD_PATH` automtically if a `.ruby` file is present.
|
7
|
+
However, it is significant in that the name of the gem has been changed
|
8
|
+
from `test` to `rubytest`.
|
9
|
+
|
10
|
+
Changes:
|
11
|
+
|
12
|
+
* Change gem name to `rubytest`.
|
13
|
+
* Improve backtrace filtering in reporters.
|
14
|
+
* Setup `LOAD_PATH` based on .ruby file if present.
|
15
|
+
|
16
|
+
|
17
|
+
## 0.2.0 / 2011-08-10
|
18
|
+
|
19
|
+
With this release Ruby Test is essentially feature complete. Of course there
|
20
|
+
are plenty of tweaks and improvements yet to come, but Ruby Test is fully usable
|
21
|
+
at this point. Only one major aspect of the design remains in question --the
|
22
|
+
way per-testcase "before and after all" advice is handled. Other than that
|
23
|
+
the API fairly solid, even as this early state of development. Always helps
|
24
|
+
when you have a spec to go by!
|
25
|
+
|
26
|
+
Changes:
|
27
|
+
|
28
|
+
* Use Config class to look-up .test file.
|
29
|
+
* Support hard testing, topic and pre-case setup.
|
30
|
+
* Add autorun.rb runner script.
|
31
|
+
* Add a test reporter to use for testing Ruby Test itself.
|
32
|
+
* Improved dotprogess reporter's handling of omissions.
|
33
|
+
* Add unit selection to test runner.
|
34
|
+
|
35
|
+
|
36
|
+
## 0.1.0 / 2011-07-30
|
37
|
+
|
38
|
+
First release of Ruby Test.
|
39
|
+
|
40
|
+
Changes:
|
41
|
+
|
42
|
+
* It's Your Birthday!
|
43
|
+
|
data/NOTICE.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# COPYRIGHT NOTICES
|
2
|
+
|
3
|
+
## Ruby Test
|
4
|
+
|
5
|
+
**Project** | Ruby Test
|
6
|
+
--------------|------------------------------------------
|
7
|
+
**Website** | http://rubyworks.github.com/ruby-test
|
8
|
+
**License** | BSD-2-Clause
|
9
|
+
**Copyright** | (c) 2011 Rubyworks
|
10
|
+
|
11
|
+
Copyright 2011 Rubyworks. All rights reserved.
|
12
|
+
|
13
|
+
Redistribution and use in source and binary forms, with or without
|
14
|
+
modification, are permitted provided that the following conditions are met:
|
15
|
+
|
16
|
+
1. Redistributions of source code must retain the above copyright notice,
|
17
|
+
this list of conditions and the following disclaimer.
|
18
|
+
|
19
|
+
2. Redistributions in binary form must reproduce the above copyright
|
20
|
+
notice, this list of conditions and the following disclaimer in the
|
21
|
+
documentation and/or other materials provided with the distribution.
|
22
|
+
|
23
|
+
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
24
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
25
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
26
|
+
COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
27
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
28
|
+
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
29
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
30
|
+
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
31
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
32
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
|
data/README.md
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
# Ruby Test
|
2
|
+
|
3
|
+
[Homepage](http://rubyworks.github.com/rubytest) /
|
4
|
+
[User Guide](http://wiki.github.com/rubyworks/rubytest) /
|
5
|
+
[Development](http://github.com/rubyworks/rubytest) /
|
6
|
+
[Issues](http://github.com/rubyworks/rubytest/issues)
|
7
|
+
|
8
|
+
## Description
|
9
|
+
|
10
|
+
Ruby Test is a universal test harness for Ruby that can be used by any Ruby
|
11
|
+
test framework. Ruby Test defines a simple specification for compliance, which
|
12
|
+
allows tests from various frameworks to all run
|
13
|
+
|
14
|
+
Ruby Test defines a straight-forward specification that any test framework can
|
15
|
+
easily support which allows Ruby Test to run the frameworks tests through a
|
16
|
+
single uniform user interface in a single pass.
|
17
|
+
|
18
|
+
## Specification
|
19
|
+
|
20
|
+
The universal access point for testing is the `$TEST_SUITE` global array. A test
|
21
|
+
framework need only add compliant test objects to `$TEST_SUITE`.
|
22
|
+
Ruby Test will iterate through these objects. If a test object responds to
|
23
|
+
`#call`, it is run as a test procedure. If it responds to `#each` it is iterated
|
24
|
+
over as a test case with each entry handled in the same manner. All test
|
25
|
+
objects must respond to `#to_s` so their description can be used in test
|
26
|
+
reports.
|
27
|
+
|
28
|
+
Any raised exception that responds to `#assertion?` in the affirmative is taken
|
29
|
+
to be a failed assertion rather than simply an error. Ruby Test extends the
|
30
|
+
Exception class to support this method for all exceptions.
|
31
|
+
|
32
|
+
A test framework may raise a `NotImplementedError` to have a test recorded
|
33
|
+
as "pending" --a _todo_ item to remind the developer of tests that still
|
34
|
+
need to be written. The `NotImplementedError` is a standard Ruby exception
|
35
|
+
and a subclass of `ScriptError`.
|
36
|
+
|
37
|
+
If the `NotImplmentedError` responds in the affirmative to `#assertion?` then
|
38
|
+
the test is taken to be a purposeful _omission_, rather than simply pending.
|
39
|
+
|
40
|
+
That is the crux of Ruby Test specification. Ruby Test supports some
|
41
|
+
additional features that can makes its usage even more convenient.
|
42
|
+
See the [Wiki](http://github.com/rubyworks/test/wiki) for further details.
|
43
|
+
|
44
|
+
|
45
|
+
## Usage
|
46
|
+
|
47
|
+
There are a few ways to run tests. First, there is a command line tool:
|
48
|
+
|
49
|
+
$ rubytest
|
50
|
+
|
51
|
+
The command line tool takes various options, use `--help` to see them.
|
52
|
+
Be sure to load in your test framework or framework's Ruby Test adapter.
|
53
|
+
|
54
|
+
Preconfigurations can be defined in a `.test` file, e.g.
|
55
|
+
|
56
|
+
Test.run 'default' do |r|
|
57
|
+
r.format = 'progress'
|
58
|
+
r.requires << 'lemon'
|
59
|
+
r.files << 'test/*_case.rb'
|
60
|
+
end
|
61
|
+
|
62
|
+
There is also a 'rubytest/autorun.rb' library script that can be loaded which
|
63
|
+
creates an `at_exit` runner, for which `test.rb` provides a nice shortcut:
|
64
|
+
|
65
|
+
$ ruby -r test
|
66
|
+
|
67
|
+
There is also a Rake task.
|
68
|
+
|
69
|
+
require 'rubytest/rake'
|
70
|
+
|
71
|
+
Test::Rake::TestTask.new
|
72
|
+
|
73
|
+
A Detroit plugin is in the works and should be available soon.
|
74
|
+
|
75
|
+
|
76
|
+
## Installation
|
77
|
+
|
78
|
+
Ruby Test is available as Gem package.
|
79
|
+
|
80
|
+
$ gem install rubytest
|
81
|
+
|
82
|
+
|
83
|
+
## Requirements
|
84
|
+
|
85
|
+
Ruby Test uses the [ANSI](http://rubyworks.github.com/ansi) gem for color output.
|
86
|
+
|
87
|
+
Because of the "foundational" nature of this library we will look at removing
|
88
|
+
this dependencies for future versions, but for early development the
|
89
|
+
requirements does the job and does it well.
|
90
|
+
|
91
|
+
|
92
|
+
## Development
|
93
|
+
|
94
|
+
Ruby Test is still a "nuby" gem. Please feel OBLIGATED to help improve it ;-)
|
95
|
+
|
96
|
+
Ruby Test is a [RubyWorks](http://rubyworks.github.com) project. If you can't
|
97
|
+
contribue code, you can still help out by contributing to our development fund.
|
98
|
+
|
99
|
+
|
100
|
+
## Reference Material
|
101
|
+
|
102
|
+
[1] [Standard Definition Of Unit Test](http://c2.com/cgi/wiki?StandardDefinitionOfUnitTest)
|
103
|
+
|
104
|
+
|
105
|
+
## Copyrights
|
106
|
+
|
107
|
+
Copyright (c) 2011 Rubyworks
|
108
|
+
|
109
|
+
Made available according to the terms of the <b>FreeBSD license</b>.
|
110
|
+
|
111
|
+
See NOTICE.md for details.
|
112
|
+
|
data/bin/rubytest
ADDED
data/demo/01_test.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
## Defining a Test
|
2
|
+
|
3
|
+
Any object in a test suite that responds to #call, will be executed as
|
4
|
+
a test. For instance, given an abtriray object defined as follows.
|
5
|
+
|
6
|
+
test = Object.new
|
7
|
+
|
8
|
+
def test.okay
|
9
|
+
@okay
|
10
|
+
end
|
11
|
+
|
12
|
+
def test.call
|
13
|
+
@okay = true
|
14
|
+
end
|
15
|
+
|
16
|
+
If we pass this to a test runner as part of a test suite,
|
17
|
+
|
18
|
+
runner = Test::Runner.new(:suite=>[test], :format=>'test')
|
19
|
+
|
20
|
+
success = runner.run
|
21
|
+
|
22
|
+
We will see that the test was called.
|
23
|
+
|
24
|
+
test.assert.okay
|
25
|
+
|
26
|
+
And testing was successful.
|
27
|
+
|
28
|
+
success.assert == true
|
29
|
+
|
data/demo/02_case.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
## Defining a Test Case
|
2
|
+
|
3
|
+
Any object in a test suite that responds to #each, will be iterated over
|
4
|
+
and each entry run a test or another sub-case. For instance, given an abitrary
|
5
|
+
object defined as follows.
|
6
|
+
|
7
|
+
test = Object.new
|
8
|
+
|
9
|
+
def test.okay
|
10
|
+
@okay
|
11
|
+
end
|
12
|
+
|
13
|
+
def test.call
|
14
|
+
@okay = true
|
15
|
+
end
|
16
|
+
|
17
|
+
And placed into an array.
|
18
|
+
|
19
|
+
tests = [test]
|
20
|
+
|
21
|
+
If we pass this to a test runner as part of a test suite,
|
22
|
+
|
23
|
+
runner = Test::Runner.new(:suite=>[tests], :format=>'test')
|
24
|
+
|
25
|
+
success = runner.run
|
26
|
+
|
27
|
+
We will see that the test was called.
|
28
|
+
|
29
|
+
test.assert.okay
|
30
|
+
|
31
|
+
And testing was successful.
|
32
|
+
|
33
|
+
success.assert == true
|
34
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#$TEST_SUITE = [] unless defined?($TEST_SUITE)
|
2
|
+
|
3
|
+
if RUBY_VERSION < '1.9'
|
4
|
+
require 'ruth'
|
5
|
+
else
|
6
|
+
require_relative '../ruth'
|
7
|
+
end
|
8
|
+
|
9
|
+
at_exit {
|
10
|
+
suite = $TEST_SUITE
|
11
|
+
options = {
|
12
|
+
:format => ENV['rubytest-format'] # TODO: better name?
|
13
|
+
}
|
14
|
+
|
15
|
+
runner = Ruth::Test::Runner.new(suite, options)
|
16
|
+
success = runner.run
|
17
|
+
exit -1 unless success
|
18
|
+
}
|
19
|
+
|
data/lib/rubytest/cli.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
module Test
|
2
|
+
|
3
|
+
# Command line interface.
|
4
|
+
class Runner
|
5
|
+
|
6
|
+
# Test runner command line interface.
|
7
|
+
#
|
8
|
+
def self.cli(*argv)
|
9
|
+
runner = Runner.new
|
10
|
+
|
11
|
+
Test::Config.load
|
12
|
+
|
13
|
+
cli_options(runner, argv)
|
14
|
+
|
15
|
+
Test::Config.load_path_setup #unless runner.autopath == false
|
16
|
+
|
17
|
+
begin
|
18
|
+
success = runner.run
|
19
|
+
exit -1 unless success
|
20
|
+
rescue => error
|
21
|
+
raise error if $DEBUG
|
22
|
+
$stderr.puts('ERROR: ' + error.to_s)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
def self.cli_options(runner, argv)
|
28
|
+
require 'optparse'
|
29
|
+
|
30
|
+
config = Test.config.dup
|
31
|
+
config_loaded = false
|
32
|
+
|
33
|
+
common = config.delete('common')
|
34
|
+
default = config.delete('default')
|
35
|
+
|
36
|
+
common.call(runner) if common
|
37
|
+
|
38
|
+
OptionParser.new do |opt|
|
39
|
+
opt.banner = "Usage: #{$0} [options] [files ...]"
|
40
|
+
|
41
|
+
unless config.empty?
|
42
|
+
opt.separator "PRESET OPTIONS:"
|
43
|
+
config.each do |name, block|
|
44
|
+
opt.on("--#{name}") do
|
45
|
+
block.call(runner)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
opt.separator "CONFIG OPTIONS:"
|
51
|
+
|
52
|
+
opt.on '-f', '--format NAME', 'report format' do |name|
|
53
|
+
runner.format = name
|
54
|
+
end
|
55
|
+
opt.on '-y', '--tapy', 'shortcut for -f tapy' do
|
56
|
+
runner.format = 'tapy'
|
57
|
+
end
|
58
|
+
opt.on '-j', '--tapj', 'shortcut for -f tapj' do
|
59
|
+
runner.format = 'tapj'
|
60
|
+
end
|
61
|
+
|
62
|
+
opt.on '-t', '--tag TAG', 'select tests by tag' do |tag|
|
63
|
+
runner.tags << tag
|
64
|
+
end
|
65
|
+
opt.on '-u', '--unit TAG', 'select tests by software unit' do |unit|
|
66
|
+
runner.units << unit
|
67
|
+
end
|
68
|
+
opt.on '-m', '--match TEXT', 'select tests by description' do |text|
|
69
|
+
runner.match << text
|
70
|
+
end
|
71
|
+
|
72
|
+
opt.on '-I', '--loadpath PATH', 'add to $LOAD_PATH' do |paths|
|
73
|
+
paths.split(/[:;]/).reverse_each do |path|
|
74
|
+
$LOAD_PATH.unshift path
|
75
|
+
end
|
76
|
+
end
|
77
|
+
opt.on '-r', '--require FILE', 'require file' do |file|
|
78
|
+
require file
|
79
|
+
end
|
80
|
+
opt.on '-v' , '--verbose', 'provide extra detailed report' do
|
81
|
+
runner.verbose = true
|
82
|
+
end
|
83
|
+
#opt.on('--log DIRECTORY', 'log directory'){ |dir|
|
84
|
+
# options[:log] = dir
|
85
|
+
#}
|
86
|
+
opt.on_tail("--[no-]ansi" , 'turn on/off ANSI colors'){ |v| $ansi = v }
|
87
|
+
opt.on_tail("--debug" , 'turn on debugging mode'){ $DEBUG = true }
|
88
|
+
#opt.on_tail("--about" , 'display information about lemon'){
|
89
|
+
# puts "Ruby Test v#{VERSION}"
|
90
|
+
# puts "#{COPYRIGHT}"
|
91
|
+
# exit
|
92
|
+
#}
|
93
|
+
opt.on_tail('-h', '--help', 'display this help message'){
|
94
|
+
puts opt
|
95
|
+
exit
|
96
|
+
}
|
97
|
+
end.parse!(argv)
|
98
|
+
|
99
|
+
default.call(runner) if default && !config_loaded
|
100
|
+
|
101
|
+
runner.files.replace(argv) unless argv.empty?
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module Test
|
2
|
+
|
3
|
+
# Thanks goes to Suraj N. Kurapati for the origins of this code.
|
4
|
+
#
|
5
|
+
class CodeSnippet
|
6
|
+
|
7
|
+
def self.cache(file)
|
8
|
+
@cache ||= {}
|
9
|
+
@cache[file] ||= File.exist?(file) ? File.readlines(file) : ['(N/A)']
|
10
|
+
end
|
11
|
+
|
12
|
+
#
|
13
|
+
def self.from_backtrace(backtrace)
|
14
|
+
backtrace.first =~ /(.+?):(\d+(?=:|\z))/ or return nil
|
15
|
+
file, line = $1, $2.to_i
|
16
|
+
new(file, line)
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
def self.from_error(exception)
|
21
|
+
backtrace = exception.backtrace
|
22
|
+
from_backtrace(backtrace)
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
def initialize(file, line)
|
27
|
+
@file = file
|
28
|
+
@line = line || 1
|
29
|
+
@code = CodeSnippet.cache(file)
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
attr :file
|
34
|
+
|
35
|
+
#
|
36
|
+
attr :line
|
37
|
+
|
38
|
+
#
|
39
|
+
attr :code
|
40
|
+
|
41
|
+
#
|
42
|
+
alias :source :code
|
43
|
+
|
44
|
+
#
|
45
|
+
def to_str
|
46
|
+
code[line-1].strip
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
#--
|
51
|
+
# TODO: ensure proper alignment by zero-padding line numbers
|
52
|
+
#++
|
53
|
+
def to_s(radius=2)
|
54
|
+
r = range(radius)
|
55
|
+
f = " %2s %0#{r.last.to_s.length}d %s"
|
56
|
+
r.map do |n|
|
57
|
+
f % [('=>' if n == line), n, code[n-1].chomp]
|
58
|
+
end.join("\n")
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
def to_a(radius=2)
|
63
|
+
r = range(radius)
|
64
|
+
r.map do |n|
|
65
|
+
code[n-1].chomp
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
def to_omap(radius=2)
|
71
|
+
a = []
|
72
|
+
r = range(radius)
|
73
|
+
r.each do |n|
|
74
|
+
a << {n => code[n-1].chomp}
|
75
|
+
end
|
76
|
+
a
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
def succ
|
81
|
+
line += 1
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
#
|
87
|
+
def range(radius)
|
88
|
+
[line - radius, 1].max..[line + radius, source.length].min
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module Test
|
2
|
+
|
3
|
+
#
|
4
|
+
def self.run(name=:default, &block)
|
5
|
+
@config ||= {}
|
6
|
+
@config[name.to_s] = block
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.config
|
10
|
+
@config ||= {}
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
class Config
|
15
|
+
|
16
|
+
# Test configuration file.
|
17
|
+
#
|
18
|
+
# The name of the file is an ode to the original Ruby cli test tool.
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# .test
|
22
|
+
# .testrb
|
23
|
+
# .test.rb
|
24
|
+
# .config/test.rb
|
25
|
+
#
|
26
|
+
# @todo Too many options for ruby-test configuration file.
|
27
|
+
GLOB_RC = '{.testrb,.test.rb,.test,.config/test.rb,config/test.rb}'
|
28
|
+
|
29
|
+
#
|
30
|
+
GLOB_ROOT = '{.ruby,.git,.hg}'
|
31
|
+
|
32
|
+
#
|
33
|
+
def self.load
|
34
|
+
super(rc_file) if rc_file
|
35
|
+
#Ruth.module_eval(File.read(rc_file)) if rc_file
|
36
|
+
end
|
37
|
+
|
38
|
+
# Find rc file.
|
39
|
+
def self.rc_file
|
40
|
+
@rc_file ||= (
|
41
|
+
glob = GLOB_RC
|
42
|
+
stop = root
|
43
|
+
default = nil
|
44
|
+
dir = Dir.pwd
|
45
|
+
file = nil
|
46
|
+
loop do
|
47
|
+
file = Dir[File.join(dir, glob)].first
|
48
|
+
break file if file
|
49
|
+
break if dir == stop
|
50
|
+
dir = File.dirname(dir)
|
51
|
+
break if dir == '/'
|
52
|
+
end
|
53
|
+
file ? file : default
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Find and cache project root directory.
|
58
|
+
#
|
59
|
+
# @return [String] Project's root path.
|
60
|
+
def self.root
|
61
|
+
@root ||= (
|
62
|
+
glob = GLOB_ROOT
|
63
|
+
stop = '/'
|
64
|
+
default = Dir.pwd
|
65
|
+
dir = Dir.pwd
|
66
|
+
until dir == stop
|
67
|
+
break dir if Dir[File.join(dir, glob)].first
|
68
|
+
dir = File.dirname(dir)
|
69
|
+
end
|
70
|
+
dir == stop ? default : dir
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Load and cache a project's `.ruby` file.
|
75
|
+
#
|
76
|
+
# @return [Hash] Project's loaded `.ruby` file, if it has one.
|
77
|
+
def self.dotruby
|
78
|
+
@dotruby ||= (
|
79
|
+
drfile = File.join(root, '.ruby')
|
80
|
+
if File.exist?(drfile)
|
81
|
+
YAML.load_file(drfile)
|
82
|
+
else
|
83
|
+
{}
|
84
|
+
end
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Setup $LOAD_PATH based on .ruby file.
|
89
|
+
#
|
90
|
+
# @todo Maybe we should not fallback to typical load path?
|
91
|
+
def self.load_path_setup
|
92
|
+
if load_paths = dotruby['load_path']
|
93
|
+
load_paths.each do |path|
|
94
|
+
$LOAD_PATH.unshift(File.join(root, path))
|
95
|
+
end
|
96
|
+
else
|
97
|
+
typical_load_path = File.join(root, 'lib')
|
98
|
+
if File.directory?(typical_load_path)
|
99
|
+
$LOAD_PATH.unshift(typical_load_path)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class Assertion < Exception
|
2
|
+
|
3
|
+
# New assertion (failure).
|
4
|
+
#
|
5
|
+
# @param message [String] the failure message
|
6
|
+
# @param options [Hash] options such as :backtrace
|
7
|
+
#
|
8
|
+
def initialize(message=nil, options={})
|
9
|
+
super(message)
|
10
|
+
backtrace = options[:backtrace]
|
11
|
+
set_backtrace(backtrace) if backtrace
|
12
|
+
@assertion = true
|
13
|
+
end
|
14
|
+
|
15
|
+
# Technically any object that affirmatively responds to #assertion?
|
16
|
+
# can be taken to be an Assertion. This makes it easier for various
|
17
|
+
# libraries to work together without having to depend upon a common
|
18
|
+
# Assertion base class.
|
19
|
+
def assertion?
|
20
|
+
true # @assertion
|
21
|
+
end
|
22
|
+
|
23
|
+
# Parents error message prefixed with "(assertion)".
|
24
|
+
#
|
25
|
+
# @return [String] error message
|
26
|
+
def to_s
|
27
|
+
'(assertion) ' + super
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|