matthewrudy-rubydoctest 1.0.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 +24 -0
- data/License.txt +19 -0
- data/Manifest.txt +38 -0
- data/PostInstall.txt +7 -0
- data/README.txt +100 -0
- data/Rakefile +4 -0
- data/bin/rubydoctest +66 -0
- data/config/hoe.rb +72 -0
- data/config/requirements.rb +15 -0
- data/lib/code_block.rb +68 -0
- data/lib/doctest_require.rb +3 -0
- data/lib/lines.rb +143 -0
- data/lib/result.rb +63 -0
- data/lib/rubydoctest.rb +29 -0
- data/lib/rubydoctest/version.rb +9 -0
- data/lib/runner.rb +377 -0
- data/lib/special_directive.rb +44 -0
- data/lib/statement.rb +75 -0
- data/lib/test.rb +29 -0
- data/rubydoctest.gemspec +72 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/rstakeout +92 -0
- data/script/txt2html +82 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/doctests.rake +29 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +17 -0
- data/textmate/DocTest (Markdown).textmate +7 -0
- data/textmate/DocTest (Ruby).textmate +65 -0
- data/textmate/DocTest (Text).textmate +66 -0
- data/website/index.html +94 -0
- data/website/index.txt +37 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +138 -0
- data/website/template.html.erb +48 -0
- metadata +106 -0
data/History.txt
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
== 1.0.0 2008-06-23
|
2
|
+
|
3
|
+
* Added doctest: and doctest_require: special directives.
|
4
|
+
* Bug fixes.
|
5
|
+
* Documentation and wiki.
|
6
|
+
|
7
|
+
== 0.3.0 2008-06-17
|
8
|
+
|
9
|
+
* Added ability to put doctest code within .rb file comments
|
10
|
+
|
11
|
+
== 0.2.1 2008-05-26
|
12
|
+
|
13
|
+
* Adding self-doctesting doctests
|
14
|
+
|
15
|
+
== 0.2.0 2008-05-25
|
16
|
+
|
17
|
+
* Initial changes by Dr Nic
|
18
|
+
* __FILE__ is changed to the explicit file path (since it was eval'ing to the code, not the test file)
|
19
|
+
* Starting to write doctests for the project itself
|
20
|
+
|
21
|
+
== 0.1.0 2008-05-25
|
22
|
+
|
23
|
+
* 1 major enhancement:
|
24
|
+
* Initial release from Tom's personal stash of code
|
data/License.txt
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2008 Tom Locke, Nic Williams, Duane Johnson
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/Manifest.txt
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
History.txt
|
2
|
+
License.txt
|
3
|
+
Manifest.txt
|
4
|
+
PostInstall.txt
|
5
|
+
README.txt
|
6
|
+
Rakefile
|
7
|
+
bin/rubydoctest
|
8
|
+
config/hoe.rb
|
9
|
+
config/requirements.rb
|
10
|
+
lib/code_block.rb
|
11
|
+
lib/doctest_require.rb
|
12
|
+
lib/lines.rb
|
13
|
+
lib/result.rb
|
14
|
+
lib/rubydoctest.rb
|
15
|
+
lib/rubydoctest/version.rb
|
16
|
+
lib/runner.rb
|
17
|
+
lib/special_directive.rb
|
18
|
+
lib/statement.rb
|
19
|
+
lib/test.rb
|
20
|
+
rubydoctest.gemspec
|
21
|
+
script/console
|
22
|
+
script/destroy
|
23
|
+
script/generate
|
24
|
+
script/rstakeout
|
25
|
+
script/txt2html
|
26
|
+
setup.rb
|
27
|
+
tasks/deployment.rake
|
28
|
+
tasks/doctests.rake
|
29
|
+
tasks/environment.rake
|
30
|
+
tasks/website.rake
|
31
|
+
textmate/DocTest (Markdown).textmate
|
32
|
+
textmate/DocTest (Ruby).textmate
|
33
|
+
textmate/DocTest (Text).textmate
|
34
|
+
website/index.html
|
35
|
+
website/index.txt
|
36
|
+
website/javascripts/rounded_corners_lite.inc.js
|
37
|
+
website/stylesheets/screen.css
|
38
|
+
website/template.html.erb
|
data/PostInstall.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
= Ruby DocTest
|
2
|
+
|
3
|
+
Official repository:
|
4
|
+
* http://github.com/tablatom/rubydoctest
|
5
|
+
|
6
|
+
Wiki documentation:
|
7
|
+
* http://github.com/tablatom/rubydoctest/wikis
|
8
|
+
|
9
|
+
== Description:
|
10
|
+
|
11
|
+
Ruby version of Python's doctest tool, but a bit different. Ruby DocTest
|
12
|
+
allows you to:
|
13
|
+
|
14
|
+
1. Write tests in irb format and keep them as comments next to your Ruby code.
|
15
|
+
2. Write markdown documents with irb format tests embedded in them.
|
16
|
+
|
17
|
+
== Synopsis:
|
18
|
+
|
19
|
+
rubydoctest comes as an executable that takes a list of files:
|
20
|
+
|
21
|
+
rubydoctest lib/*.rb
|
22
|
+
rubydoctest simple.doctest
|
23
|
+
|
24
|
+
== Examples:
|
25
|
+
|
26
|
+
Here is how you might use RubyDocTest within a ruby source file (say called five.rb):
|
27
|
+
|
28
|
+
# doctest: Add 5 and 5 to get 10
|
29
|
+
# >> five_and_five
|
30
|
+
# => 10
|
31
|
+
def five_and_five
|
32
|
+
5 + 5
|
33
|
+
end
|
34
|
+
|
35
|
+
Here is an example doctest file (say called simple.doctest):
|
36
|
+
|
37
|
+
# Simple test of RubyDocTest
|
38
|
+
|
39
|
+
This is an example test
|
40
|
+
|
41
|
+
>> 1 + 2
|
42
|
+
=> 3
|
43
|
+
|
44
|
+
And here's a test that will fail
|
45
|
+
|
46
|
+
>> 1 + 2
|
47
|
+
=> 4
|
48
|
+
|
49
|
+
See the doc directory of this project for more .doctest examples and documentation.
|
50
|
+
|
51
|
+
== Installation:
|
52
|
+
|
53
|
+
Major releases:
|
54
|
+
|
55
|
+
sudo gem install rubydoctest
|
56
|
+
|
57
|
+
Build from source:
|
58
|
+
|
59
|
+
git clone git://github.com/tablatom/rubydoctest.git
|
60
|
+
cd rubydoctest
|
61
|
+
rake manifest:refresh && rake install
|
62
|
+
|
63
|
+
== Testing DocTest:
|
64
|
+
|
65
|
+
Ruby DocTest uses itself to test and document itself.
|
66
|
+
|
67
|
+
rake test:doctest
|
68
|
+
|
69
|
+
In development of Ruby DocTest, there is an autotest system in-built
|
70
|
+
using script/rstakeout
|
71
|
+
|
72
|
+
rake test:doctest:auto
|
73
|
+
|
74
|
+
== TextMate Bundle:
|
75
|
+
|
76
|
+
See http://github.com/drnic/ruby-doctest-tmbundle
|
77
|
+
|
78
|
+
== License:
|
79
|
+
|
80
|
+
(The MIT License)
|
81
|
+
|
82
|
+
Copyright (c) 2008 Tom Locke, Nic Williams, Duane Johnson
|
83
|
+
|
84
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
85
|
+
of this software and associated documentation files (the 'Software'), to deal
|
86
|
+
in the Software without restriction, including without limitation the rights
|
87
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
88
|
+
copies of the Software, and to permit persons to whom the Software is
|
89
|
+
furnished to do so, subject to the following conditions:
|
90
|
+
|
91
|
+
The above copyright notice and this permission notice shall be included in all
|
92
|
+
copies or substantial portions of the Software.
|
93
|
+
|
94
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
95
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
96
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
97
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
98
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
99
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
100
|
+
SOFTWARE.
|
data/Rakefile
ADDED
data/bin/rubydoctest
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
options, files = ARGV.partition{ |a| a =~ /^-/ }
|
4
|
+
|
5
|
+
if ARGV.empty? or options.include?("-h") or options.include?("--help")
|
6
|
+
require 'rubydoctest/version'
|
7
|
+
puts <<-DIRECTIONS
|
8
|
+
Ruby DocTest #{Rubydoctest::VERSION::STRING}
|
9
|
+
USAGE: rubydoctest [options] <files>
|
10
|
+
|
11
|
+
rubydoctest parses Ruby files (.rb) or DocTest files (.doctest) for irb-style
|
12
|
+
sessions in comments, and runs the commented sessions as tests.
|
13
|
+
|
14
|
+
Options:
|
15
|
+
General:
|
16
|
+
--help - show this usage / help information
|
17
|
+
-t<n> - only run test number n, e.g. -t1 -t3
|
18
|
+
|
19
|
+
Output Format:
|
20
|
+
--html - output in HTML format
|
21
|
+
--plain - force output in plain text (no Ansi colors)
|
22
|
+
|
23
|
+
Debug:
|
24
|
+
--ignore-interactive - do not heed !!! special directives
|
25
|
+
--trace - turn backtrace on to debug Ruby DocTest
|
26
|
+
--debugger - include ruby-debug library / gem
|
27
|
+
--require=</path/to/require>,</another/path/to/require> - eg. --require=config/environment.rb
|
28
|
+
|
29
|
+
See http://github.com/tablatom/rubydoctest/wikis for more information.
|
30
|
+
DIRECTIONS
|
31
|
+
exit 0
|
32
|
+
end
|
33
|
+
|
34
|
+
requires = ['rubygems', File.dirname(__FILE__) + "/../lib/rubydoctest"]
|
35
|
+
requires << 'ruby-debug' if options.include?("--debugger")
|
36
|
+
|
37
|
+
if options.detect {|opt| opt =~ /^--require=(.+)/}
|
38
|
+
requires << $1.split(",")
|
39
|
+
end
|
40
|
+
|
41
|
+
ruby_lines = []
|
42
|
+
ruby_lines << "RubyDocTest.trace = true;" if options.include?("--trace")
|
43
|
+
ruby_lines << "RubyDocTest.ignore_interactive = true;" if options.include?("--ignore-interactive")
|
44
|
+
|
45
|
+
tests = options.map{ |o| o =~ /^-t(\d+)/; $1 }.compact
|
46
|
+
ruby_lines << "RubyDocTest.tests = #{tests.inspect};" if tests.size > 0
|
47
|
+
|
48
|
+
requires = requires.map {|lib| "require '#{lib}'; "}.join
|
49
|
+
|
50
|
+
def files_runner(command, files, requires, lines)
|
51
|
+
files.reverse_each do |f|
|
52
|
+
system %(#{command} -e "#{requires} #{lines.join(" ")} RubyDocTest::Runner.new(File.read('#{f}'), '#{f}').run")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
if options.include?("--plain")
|
57
|
+
ruby_lines << "RubyDocTest.output_format = :plain;"
|
58
|
+
files_runner("ruby", files, requires, ruby_lines)
|
59
|
+
elsif options.include?("--html")
|
60
|
+
ruby_lines << "RubyDocTest.output_format = :html;"
|
61
|
+
puts "<html><body><pre>"
|
62
|
+
files_runner("ruby", files, requires, ruby_lines)
|
63
|
+
puts "</pre></body></html>"
|
64
|
+
else
|
65
|
+
files_runner("ruby", files, requires, ruby_lines)
|
66
|
+
end
|
data/config/hoe.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'rubydoctest/version'
|
2
|
+
|
3
|
+
AUTHOR = ['Duane Johnson', 'Tom Locke', 'Dr Nic Williams'] # can also be an array of Authors
|
4
|
+
EMAIL = "duane.johnson@gmail.com"
|
5
|
+
DESCRIPTION = "Ruby version of Python's doctest tool, but a bit different."
|
6
|
+
GEM_NAME = 'rubydoctest' # what ppl will type to install your gem
|
7
|
+
RUBYFORGE_PROJECT = 'rubydoctest' # The unix name for your project
|
8
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
9
|
+
DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
|
10
|
+
EXTRA_DEPENDENCIES = []
|
11
|
+
|
12
|
+
@config_file = "~/.rubyforge/user-config.yml"
|
13
|
+
@config = nil
|
14
|
+
RUBYFORGE_USERNAME = "unknown"
|
15
|
+
def rubyforge_username
|
16
|
+
unless @config
|
17
|
+
begin
|
18
|
+
@config = YAML.load(File.read(File.expand_path(@config_file)))
|
19
|
+
rescue
|
20
|
+
puts <<-EOS
|
21
|
+
ERROR: No rubyforge config file found: #{@config_file}
|
22
|
+
Run 'rubyforge setup' to prepare your env for access to Rubyforge
|
23
|
+
- See http://newgem.rubyforge.org/rubyforge.html for more details
|
24
|
+
EOS
|
25
|
+
exit
|
26
|
+
end
|
27
|
+
end
|
28
|
+
RUBYFORGE_USERNAME.replace @config["username"]
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
REV = nil
|
33
|
+
# UNCOMMENT IF REQUIRED:
|
34
|
+
# REV = YAML.load(`svn info`)['Revision']
|
35
|
+
VERS = Rubydoctest::VERSION::STRING + (REV ? ".#{REV}" : "")
|
36
|
+
RDOC_OPTS = ['--quiet', '--title', 'rubydoctest documentation',
|
37
|
+
"--opname", "index.html",
|
38
|
+
"--line-numbers",
|
39
|
+
"--main", "README",
|
40
|
+
"--inline-source"]
|
41
|
+
|
42
|
+
class Hoe
|
43
|
+
def extra_deps
|
44
|
+
@extra_deps.reject! { |x| Array(x).first == 'hoe' }
|
45
|
+
@extra_deps
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Generate all the Rake tasks
|
50
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
51
|
+
$hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
52
|
+
p.author = AUTHOR
|
53
|
+
p.email = EMAIL
|
54
|
+
p.description = DESCRIPTION
|
55
|
+
p.summary = DESCRIPTION
|
56
|
+
p.url = HOMEPATH
|
57
|
+
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
58
|
+
p.test_globs = ["test/**/test_*.rb"]
|
59
|
+
p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
|
60
|
+
|
61
|
+
# == Optional
|
62
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
63
|
+
#p.extra_deps = EXTRA_DEPENDENCIES
|
64
|
+
|
65
|
+
#p.spec_extras = {} # A hash of extra values to set in the gemspec.
|
66
|
+
end
|
67
|
+
|
68
|
+
CHANGES = $hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
|
69
|
+
PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
|
70
|
+
$hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
|
71
|
+
$hoe.rsync_args = '-av --delete --ignore-errors'
|
72
|
+
$hoe.spec.post_install_message = File.open(File.dirname(__FILE__) + "/../PostInstall.txt").read rescue ""
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
include FileUtils
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
%w[rake hoe newgem rubigen].each do |req_gem|
|
6
|
+
begin
|
7
|
+
require req_gem
|
8
|
+
rescue LoadError
|
9
|
+
puts "This Rakefile requires the '#{req_gem}' RubyGem."
|
10
|
+
puts "Installation: gem install #{req_gem} -y"
|
11
|
+
exit
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
$:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
|
data/lib/code_block.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
require 'statement'
|
5
|
+
require 'result'
|
6
|
+
|
7
|
+
module RubyDocTest
|
8
|
+
# A +CodeBlock+ is a group of one or more ruby statements, followed by an optional result.
|
9
|
+
# For example:
|
10
|
+
# >> a = 1 + 1
|
11
|
+
# >> a - 3
|
12
|
+
# => -1
|
13
|
+
class CodeBlock
|
14
|
+
attr_reader :statements, :result, :passed
|
15
|
+
|
16
|
+
def initialize(statements = [], result = nil)
|
17
|
+
@statements = statements
|
18
|
+
@result = result
|
19
|
+
end
|
20
|
+
|
21
|
+
# === Tests
|
22
|
+
# doctest: Single statement with result should pass
|
23
|
+
# >> ss = [RubyDocTest::Statement.new([">> a = 1"])]
|
24
|
+
# >> r = RubyDocTest::Result.new(["=> 1"])
|
25
|
+
# >> cb = RubyDocTest::CodeBlock.new(ss, r)
|
26
|
+
# >> cb.pass?
|
27
|
+
# => true
|
28
|
+
#
|
29
|
+
# doctest: Single statement without result should pass by default
|
30
|
+
# >> ss = [RubyDocTest::Statement.new([">> a = 1"])]
|
31
|
+
# >> cb = RubyDocTest::CodeBlock.new(ss)
|
32
|
+
# >> cb.pass?
|
33
|
+
# => true
|
34
|
+
#
|
35
|
+
# doctest: Multi-line statement with result should pass
|
36
|
+
# >> ss = [RubyDocTest::Statement.new([">> a = 1"]),
|
37
|
+
# RubyDocTest::Statement.new([">> 'a' + a.to_s"])]
|
38
|
+
# >> r = RubyDocTest::Result.new(["=> 'a1'"])
|
39
|
+
# >> cb = RubyDocTest::CodeBlock.new(ss, r)
|
40
|
+
# >> cb.pass?
|
41
|
+
# => true
|
42
|
+
def pass?
|
43
|
+
if @computed
|
44
|
+
@passed
|
45
|
+
else
|
46
|
+
@computed = true
|
47
|
+
@passed =
|
48
|
+
begin
|
49
|
+
actual_results = @statements.map{ |s| s.evaluate }
|
50
|
+
@result ? @result.matches?(actual_results.last) : true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def actual_result
|
56
|
+
@statements.last.actual_result
|
57
|
+
end
|
58
|
+
|
59
|
+
def expected_result
|
60
|
+
@result.expected_result
|
61
|
+
end
|
62
|
+
|
63
|
+
def lines
|
64
|
+
@statements.map{ |s| s.lines }.flatten +
|
65
|
+
@result.lines
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/lines.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
module RubyDocTest
|
2
|
+
# === Description
|
3
|
+
# Keeps track of which lines within a document belong to a group. Line groups are
|
4
|
+
# determined by their indentation level, as in the Python programming language.
|
5
|
+
#
|
6
|
+
# === Example
|
7
|
+
# This line and the next one
|
8
|
+
# are part of the same group
|
9
|
+
#
|
10
|
+
# But this line is separate from
|
11
|
+
# this line.
|
12
|
+
#
|
13
|
+
# === Note
|
14
|
+
# This class also considers one '#' character (comment) as an indentation character,
|
15
|
+
# i.e. similar to how whitespace is treated.
|
16
|
+
class Lines
|
17
|
+
def initialize(doc_lines, line_index = 0)
|
18
|
+
@doc_lines, @line_index = doc_lines, line_index
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def line_number
|
23
|
+
@line_index + 1
|
24
|
+
end
|
25
|
+
|
26
|
+
# === Tests
|
27
|
+
# doctest: Return an array of 1 line if there is only one line
|
28
|
+
# >> l = RubyDocTest::Lines.new(["line 1"])
|
29
|
+
# >> l.lines
|
30
|
+
# => ["line 1"]
|
31
|
+
#
|
32
|
+
# doctest: Remove indentation from lines 2 to the end of this Lines group.
|
33
|
+
# >> l = RubyDocTest::Lines.new(["line 1", " line 2", " line 3", " line 4"])
|
34
|
+
# >> l.lines
|
35
|
+
# => ["line 1", "line 2", "line 3", " line 4"]
|
36
|
+
def lines
|
37
|
+
r = range
|
38
|
+
size = r.last - r.first + 1
|
39
|
+
if size > 1
|
40
|
+
# Remove indentation from all lines after the first,
|
41
|
+
# as measured from the 2nd line's indentation level
|
42
|
+
idt2 = indentation(@doc_lines, @line_index + 1)
|
43
|
+
[@doc_lines[range.first]] +
|
44
|
+
@doc_lines[(range.first + 1)..(range.last)].
|
45
|
+
map{ |l| $1 if l =~ /^#{Regexp.escape(idt2)}(.*)/ }
|
46
|
+
else
|
47
|
+
@doc_lines[range]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
# === Description
|
53
|
+
# Calculate the range of python-like indentation within this Lines group
|
54
|
+
#
|
55
|
+
# === Tests
|
56
|
+
# >> l = RubyDocTest::Lines.new([])
|
57
|
+
#
|
58
|
+
# doctest: Return a range of one line when there is only one line to begin with
|
59
|
+
# >> l.range %w(a), 0
|
60
|
+
# => 0..0
|
61
|
+
#
|
62
|
+
# doctest: Return a range of one line when there are two lines, side by side
|
63
|
+
# >> l.range %w(a b), 0
|
64
|
+
# => 0..0
|
65
|
+
# >> l.range %w(a b), 1
|
66
|
+
# => 1..1
|
67
|
+
#
|
68
|
+
# doctest: Return a range of two lines when there are two lines, the second blank
|
69
|
+
# >> l.range ["a", ""], 0
|
70
|
+
# => 0..1
|
71
|
+
#
|
72
|
+
# doctest: Return a range of two lines when the second is indented
|
73
|
+
# >> l.range ["a", " b"], 0
|
74
|
+
# => 0..1
|
75
|
+
#
|
76
|
+
# doctest: Indentation can also include the ?> marker
|
77
|
+
# >> l.range [">> 1 +", "?> 2"], 0
|
78
|
+
# => 0..1
|
79
|
+
def range(doc_lines = @doc_lines, start_index = @line_index)
|
80
|
+
end_index = start_index
|
81
|
+
idt = indentation(doc_lines, start_index)
|
82
|
+
# Find next lines that are blank, or have indentation more than the first line
|
83
|
+
remaining_lines(doc_lines, start_index + 1).each do |current_line|
|
84
|
+
if current_line =~ /^(#{Regexp.escape(idt)}(\s+|\?>\s)|\s*$)/
|
85
|
+
end_index += 1
|
86
|
+
else
|
87
|
+
break
|
88
|
+
end
|
89
|
+
end
|
90
|
+
# Compute the range from what we found
|
91
|
+
start_index..end_index
|
92
|
+
end
|
93
|
+
|
94
|
+
def inspect
|
95
|
+
"#<#{self.class} lines=#{lines.inspect}>"
|
96
|
+
end
|
97
|
+
|
98
|
+
protected
|
99
|
+
|
100
|
+
# === Tests
|
101
|
+
# >> l = RubyDocTest::Lines.new([])
|
102
|
+
#
|
103
|
+
# doctest: Get a whitespace indent from a line with whitespace
|
104
|
+
# >> l.send :indentation, [" a"], 0
|
105
|
+
# => " "
|
106
|
+
#
|
107
|
+
# doctest: Get a whitespace and '#' indent from a comment line
|
108
|
+
# >> l.send :indentation, [" # a"], 0
|
109
|
+
# => " # "
|
110
|
+
def indentation(doc_lines = @doc_lines, line_index = @line_index)
|
111
|
+
if doc_lines[line_index]
|
112
|
+
doc_lines[line_index][/^(\s*#\s*|\s*)(\?>\s)?/]
|
113
|
+
else
|
114
|
+
""
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
# === Description
|
120
|
+
# Get lines from +start_index+ up to the end of the document.
|
121
|
+
#
|
122
|
+
# === Tests
|
123
|
+
# >> l = RubyDocTest::Lines.new([])
|
124
|
+
#
|
125
|
+
# doctest: Return an empty array if start_index is out of bounds
|
126
|
+
# >> l.send :remaining_lines, [], 1
|
127
|
+
# => []
|
128
|
+
# >> l.send :remaining_lines, [], -1
|
129
|
+
# => []
|
130
|
+
#
|
131
|
+
# doctest: Return the specified line at start_index, up to and including the
|
132
|
+
# last line of +doc_lines+.
|
133
|
+
# >> l.send :remaining_lines, %w(a b c), 1
|
134
|
+
# => %w(b c)
|
135
|
+
# >> l.send :remaining_lines, %w(a b c), 2
|
136
|
+
# => %w(c)
|
137
|
+
#
|
138
|
+
def remaining_lines(doc_lines = @doc_lines, start_index = @line_index)
|
139
|
+
return [] if start_index < 0 or start_index >= doc_lines.size
|
140
|
+
doc_lines[start_index..-1]
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|