rdp-rubydoctest 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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.
@@ -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
@@ -0,0 +1,7 @@
1
+
2
+ rubydoctest comes as an executable that takes a list of files:
3
+
4
+ rubydoctest lib/*.rb
5
+ rubydoctest simple.doctest
6
+
7
+
@@ -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.
@@ -0,0 +1,4 @@
1
+ require 'config/requirements'
2
+ require 'config/hoe' # setup Hoe + all gem configuration
3
+
4
+ Dir['tasks/**/*.rake'].each { |rake| load rake }
@@ -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
@@ -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]))
@@ -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
@@ -0,0 +1,3 @@
1
+ def is_doctest_require_successful?
2
+ true
3
+ end
@@ -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