rdp-rubydoctest 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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 +60 -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 +151 -0
- data/lib/result.rb +63 -0
- data/lib/rubydoctest.rb +29 -0
- data/lib/rubydoctest/version.rb +9 -0
- data/lib/runner.rb +393 -0
- data/lib/special_directive.rb +44 -0
- data/lib/statement.rb +75 -0
- data/lib/test.rb +29 -0
- data/rubydoctest.gemspec +32 -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,60 @@
|
|
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) [windows default]
|
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
|
+
|
28
|
+
See http://github.com/tablatom/rubydoctest/wikis for more information.
|
29
|
+
DIRECTIONS
|
30
|
+
exit 0
|
31
|
+
end
|
32
|
+
|
33
|
+
requires = ['rubygems', File.dirname(__FILE__) + "/../lib/rubydoctest"]
|
34
|
+
requires << 'ruby-debug' if options.include?("--debugger")
|
35
|
+
ruby_lines = []
|
36
|
+
ruby_lines << "RubyDocTest.trace = true;" if options.include?("--trace")
|
37
|
+
ruby_lines << "RubyDocTest.ignore_interactive = true;" if options.include?("--ignore-interactive")
|
38
|
+
|
39
|
+
tests = options.map{ |o| o =~ /^-t(\d+)/; $1 }.compact
|
40
|
+
ruby_lines << "RubyDocTest.tests = #{tests.inspect};" if tests.size > 0
|
41
|
+
|
42
|
+
requires = requires.map {|lib| "require '#{lib}'; "}.join
|
43
|
+
|
44
|
+
def files_runner(command, files, requires, lines)
|
45
|
+
files.reverse_each do |f|
|
46
|
+
system %(#{command} -e "#{requires} #{lines.join(" ")} RubyDocTest::Runner.new(File.read('#{f}'), '#{f}').run")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
if options.include?("--plain") or RUBY_PLATFORM =~ /mswin|mingw/
|
51
|
+
ruby_lines << "RubyDocTest.output_format = :plain;"
|
52
|
+
files_runner("ruby", files, requires, ruby_lines)
|
53
|
+
elsif options.include?("--html")
|
54
|
+
ruby_lines << "RubyDocTest.output_format = :html;"
|
55
|
+
puts "<html><body><pre>"
|
56
|
+
files_runner("ruby", files, requires, ruby_lines)
|
57
|
+
puts "</pre></body></html>"
|
58
|
+
else
|
59
|
+
files_runner("ruby", files, requires, ruby_lines)
|
60
|
+
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,151 @@
|
|
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
|
+
if doc_lines[start_index] =~ /<<-([a-zA-Z0-9_])/
|
82
|
+
end_marker = $1
|
83
|
+
remaining_lines(doc_lines, start_index + 1).each do |current_line|
|
84
|
+
end_index += 1
|
85
|
+
break if current_line.strip == end_marker
|
86
|
+
end
|
87
|
+
else
|
88
|
+
idt = indentation(doc_lines, start_index)
|
89
|
+
# Find next lines that are blank, or have indentation more than the first line
|
90
|
+
remaining_lines(doc_lines, start_index + 1).each do |current_line|
|
91
|
+
if current_line =~ /^(#{Regexp.escape(idt)}(\s+|\?>\s?)|\s*$)/
|
92
|
+
end_index += 1
|
93
|
+
else
|
94
|
+
break
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
# Compute the range from what we found
|
99
|
+
start_index..end_index
|
100
|
+
end
|
101
|
+
|
102
|
+
def inspect
|
103
|
+
"#<#{self.class} lines=#{lines.inspect}>"
|
104
|
+
end
|
105
|
+
|
106
|
+
protected
|
107
|
+
|
108
|
+
# === Tests
|
109
|
+
# >> l = RubyDocTest::Lines.new([])
|
110
|
+
#
|
111
|
+
# doctest: Get a whitespace indent from a line with whitespace
|
112
|
+
# >> l.send :indentation, [" a"], 0
|
113
|
+
# => " "
|
114
|
+
#
|
115
|
+
# doctest: Get a whitespace and '#' indent from a comment line
|
116
|
+
# >> l.send :indentation, [" # a"], 0
|
117
|
+
# => " # "
|
118
|
+
def indentation(doc_lines = @doc_lines, line_index = @line_index)
|
119
|
+
if doc_lines[line_index]
|
120
|
+
doc_lines[line_index][/^(\s*#\s*|\s*)(\?>\s?)?/]
|
121
|
+
else
|
122
|
+
""
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
# === Description
|
128
|
+
# Get lines from +start_index+ up to the end of the document.
|
129
|
+
#
|
130
|
+
# === Tests
|
131
|
+
# >> l = RubyDocTest::Lines.new([])
|
132
|
+
#
|
133
|
+
# doctest: Return an empty array if start_index is out of bounds
|
134
|
+
# >> l.send :remaining_lines, [], 1
|
135
|
+
# => []
|
136
|
+
# >> l.send :remaining_lines, [], -1
|
137
|
+
# => []
|
138
|
+
#
|
139
|
+
# doctest: Return the specified line at start_index, up to and including the
|
140
|
+
# last line of +doc_lines+.
|
141
|
+
# >> l.send :remaining_lines, %w(a b c), 1
|
142
|
+
# => %w(b c)
|
143
|
+
# >> l.send :remaining_lines, %w(a b c), 2
|
144
|
+
# => %w(c)
|
145
|
+
#
|
146
|
+
def remaining_lines(doc_lines = @doc_lines, start_index = @line_index)
|
147
|
+
return [] if start_index < 0 or start_index >= doc_lines.size
|
148
|
+
doc_lines[start_index..-1]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|