tablatom-rubydoctest 0.2.1 → 1.0.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.
@@ -0,0 +1,44 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'lines'
5
+
6
+ module RubyDocTest
7
+ class SpecialDirective < Lines
8
+ NAMES = ["doctest:", "!!!", "doctest_require:"]
9
+ NAMES_FOR_RX = NAMES.map{ |n| Regexp.escape(n) }.join("|")
10
+
11
+ # === Test
12
+ #
13
+ # doctest: The name of the directive should be detected in the first line
14
+ # >> s = RubyDocTest::SpecialDirective.new(["doctest: Testing Stuff", "Other Stuff"])
15
+ # >> s.name
16
+ # => "doctest:"
17
+ def name
18
+ if m = lines.first.match(/^#{Regexp.escape(indentation)}(#{NAMES_FOR_RX})/)
19
+ m[1]
20
+ end
21
+ end
22
+
23
+ # === Test
24
+ #
25
+ # doctest: The value of the directive should be detected in the first line
26
+ # >> s = RubyDocTest::SpecialDirective.new(["doctest: Testing Stuff", "Other Stuff"])
27
+ # >> s.value
28
+ # => "Testing Stuff"
29
+ #
30
+ # >> s = RubyDocTest::SpecialDirective.new([" # doctest: Testing Stuff", " # Other Stuff"])
31
+ # >> s.value
32
+ # => "Testing Stuff"
33
+ #
34
+ # doctest: Multiple lines for the directive value should work as well
35
+ # >> s = RubyDocTest::SpecialDirective.new(["doctest: Testing Stuff", " On Two Lines"])
36
+ # >> s.value
37
+ # => "Testing Stuff\nOn Two Lines"
38
+ def value
39
+ if m = lines.join("\n").match(/^#{Regexp.escape(indentation)}(#{NAMES_FOR_RX})(.*)/m)
40
+ m[2].strip
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,75 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'rubydoctest'
5
+ require 'lines'
6
+
7
+ module RubyDocTest
8
+ class EvaluationError < Exception
9
+ attr_reader :statement, :original_exception
10
+ def initialize(statement, original_exception)
11
+ @statement, @original_exception = statement, original_exception
12
+ end
13
+ end
14
+
15
+ class Statement < Lines
16
+
17
+ attr_reader :actual_result
18
+
19
+ # === Tests
20
+ #
21
+ # doctest: The FILENAME ruby constant should be replaced by the name of the file
22
+ # >> __FILE__[/statement\.rb$/]
23
+ # => "statement.rb"
24
+ def initialize(doc_lines, line_index = 0, file_name = nil)
25
+ @file_name = file_name
26
+ super(doc_lines, line_index)
27
+ end
28
+
29
+ # === Tests
30
+ #
31
+ # doctest: A statement should parse out a '>>' irb prompt
32
+ # >> s = RubyDocTest::Statement.new([">> a = 1"])
33
+ # >> s.source_code
34
+ # => "a = 1"
35
+ #
36
+ # doctest: More than one line should get included, if indentation so indicates
37
+ # >> s = RubyDocTest::Statement.new([">> b = 1 +", " 1", "not part of the statement"])
38
+ # >> s.source_code
39
+ # => "b = 1 +\n1"
40
+ #
41
+ # doctest: Lines indented by ?> should have the ?> removed.
42
+ # >> s = RubyDocTest::Statement.new([">> b = 1 +", "?> 1"])
43
+ # >> s.source_code
44
+ # => "b = 1 +\n1"
45
+ def source_code
46
+ lines.first =~ /^#{Regexp.escape(indentation)}>>\s(.*)$/
47
+ first = [$1]
48
+ remaining = (lines[1..-1] || [])
49
+ (first + remaining).join("\n")
50
+ end
51
+
52
+ # === Test
53
+ #
54
+ # doctest: Evaluating a multi-line statement should be ok
55
+ # >> s = RubyDocTest::Statement.new([">> b = 1 +", " 1", "not part of the statement"])
56
+ # >> s.evaluate
57
+ # => 2
58
+ #
59
+ # doctest: Evaluating a syntax error should raise an EvaluationError
60
+ # >> s = RubyDocTest::Statement.new([">> b = 1 +"])
61
+ # >> begin s.evaluate; :fail; rescue RubyDocTest::EvaluationError; :ok end
62
+ # => :ok
63
+ def evaluate
64
+ sc = source_code.gsub("__FILE__", @file_name.inspect)
65
+ # puts "EVAL: #{sc}"
66
+ @actual_result = eval(sc, TOPLEVEL_BINDING, __FILE__, __LINE__)
67
+ rescue Exception => e
68
+ if RubyDocTest.trace
69
+ raise e.class, e.to_s + "\n" + e.backtrace.first
70
+ else
71
+ raise EvaluationError.new(self, e)
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,29 @@
1
+ module RubyDocTest
2
+ # This is the top-level 'test' container that holds an optional description and one
3
+ # or more CodeBlock objects.
4
+ class Test
5
+ attr_accessor :description
6
+ attr_reader :code_blocks, :passed
7
+
8
+ def initialize(description, code_blocks)
9
+ @description, @code_blocks = description, code_blocks
10
+ end
11
+
12
+ def pass?
13
+ @passed = @code_blocks.all?{ |c| c.pass? }
14
+ end
15
+
16
+ def first_failed
17
+ @code_blocks.detect{ |cb| !cb.pass? }
18
+ end
19
+
20
+ def actual_result
21
+ first_failed.actual_result.inspect
22
+ end
23
+
24
+ def expected_result
25
+ first_failed.expected_result
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,32 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = %q{rubydoctest}
3
+ s.version = "1.0.0"
4
+
5
+ s.specification_version = 2 if s.respond_to? :specification_version=
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Duane Johnson", "Tom Locke", "Dr Nic Williams"]
9
+ s.date = %q{2008-06-21}
10
+ s.default_executable = %q{rubydoctest}
11
+ s.description = %q{Ruby version of Python's doctest tool, but a bit different.}
12
+ s.email = ["duane.johnson@gmail.com"]
13
+ s.executables = ["rubydoctest"]
14
+ s.extra_rdoc_files = ["History.txt", "License.txt", "Manifest.txt", "PostInstall.txt", "README.txt", "website/index.txt"]
15
+ s.files = IO.read("Manifest.txt").split("\n")
16
+ s.has_rdoc = true
17
+ s.homepage = %q{http://rubydoctest.rubyforge.org}
18
+ s.post_install_message = %q{
19
+ rubydoctest comes as an executable that takes a file or directory:
20
+
21
+ rubydoctest .
22
+ rubydoctest simple.doctest
23
+
24
+
25
+ }
26
+ s.rdoc_options = ["--main", "README.txt"]
27
+ s.require_paths = ["lib"]
28
+ s.rubyforge_project = %q{rubydoctest}
29
+ s.rubygems_version = %q{1.1.1}
30
+ s.summary = %q{Ruby version of Python's doctest tool, but a bit different.}
31
+ s.test_files = []
32
+ end
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ##
4
+ # Originally by Mike Clark.
5
+ #
6
+ # From http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Monitor/StakingOutFileChanges.rdoc
7
+ #
8
+ # Runs a user-defined command when files are modified.
9
+ #
10
+ # Like autotest, but more customizable. This is useful when you want to do
11
+ # something other than run tests. For example, generate a PDF book, run
12
+ # a single test, or run a legacy Test::Unit suite in an app that also
13
+ # has an rSpec suite.
14
+ #
15
+ # Can use Ruby's Dir[] to get file glob. Quote your args to take advantage of this.
16
+ #
17
+ # rstakeout 'rake test:recent' **/*.rb
18
+ # => Only watches Ruby files one directory down (no quotes)
19
+ #
20
+ # rstakeout 'rake test:recent' '**/*.rb'
21
+ # => Watches all Ruby files in all directories and subdirectories
22
+ #
23
+ # Modified (with permission) by Geoffrey Grosenbach to call growlnotify for
24
+ # rspec and Test::Unit output.
25
+ #
26
+ # See the PeepCode screencast on rSpec or other blog articles for instructions on
27
+ # setting up growlnotify.
28
+
29
+ def growl(title, msg, img, pri=0, sticky="")
30
+ system "growlnotify -n autotest --image ~/.autotest_images/#{img} -p #{pri} -m #{msg.inspect} #{title} #{sticky}"
31
+ end
32
+
33
+ def self.growl_fail(output)
34
+ growl "FAIL", "#{output}", "fail.png", 2
35
+ end
36
+
37
+ def self.growl_pass(output)
38
+ growl "Pass", "#{output}", "pass.png"
39
+ end
40
+
41
+ command = ARGV.shift
42
+ files = {}
43
+
44
+ ARGV.each do |arg|
45
+ Dir[arg].each { |file|
46
+ files[file] = File.mtime(file)
47
+ }
48
+ end
49
+
50
+ puts "Watching #{files.keys.join(', ')}\n\nFiles: #{files.keys.length}"
51
+
52
+ trap('INT') do
53
+ puts "\nQuitting..."
54
+ exit
55
+ end
56
+
57
+
58
+ loop do
59
+
60
+ sleep 1
61
+
62
+ changed_file, last_changed = files.find { |file, last_changed|
63
+ File.mtime(file) > last_changed
64
+ }
65
+
66
+ if changed_file
67
+ files[changed_file] = File.mtime(changed_file)
68
+ puts "=> #{changed_file} changed, running #{command}"
69
+ args = ""
70
+ args += ARGV.last == '--pass-as-arg' ? changed_file : ""
71
+ args += ARGV.last == '--pass-as-env' ? "CHANGED=#{changed_file}" : ""
72
+ puts "Executing: #{command} #{args}"
73
+ results = `#{command} #{args}`
74
+ puts results
75
+
76
+ if results.include? 'tests'
77
+ output = results.slice(/(\d+)\s+tests?,\s*(\d+)\s+assertions?,\s*(\d+)\s+failures?(,\s*(\d+)\s+errors)?/)
78
+ if output
79
+ $~[3].to_i + $~[5].to_i > 0 ? growl_fail(output) : growl_pass(output)
80
+ end
81
+ else
82
+ output = results.slice(/(\d+)\s+examples?,\s*(\d+)\s+failures?(,\s*(\d+)\s+not implemented)?/)
83
+ if output
84
+ $~[2].to_i > 0 ? growl_fail(output) : growl_pass(output)
85
+ end
86
+ end
87
+ # TODO Generic growl notification for other actions
88
+
89
+ puts "=> done"
90
+ end
91
+
92
+ end
@@ -0,0 +1,29 @@
1
+ namespace :test do
2
+ desc "Run doctests"
3
+ task :doctest do
4
+ sh "ruby #{File.dirname(__FILE__)}/../bin/rubydoctest #{File.dirname(__FILE__)}/../lib/*.rb"
5
+ sh "ruby #{File.dirname(__FILE__)}/../bin/rubydoctest #{File.dirname(__FILE__)}/../doc/*.doctest"
6
+ end
7
+
8
+ namespace :doctest do
9
+ desc "Run rstakeout on test/doctest files"
10
+ task :auto do
11
+ tests = "#{File.dirname(__FILE__)}/../test/doctest/*"
12
+ tests_path = File.dirname(tests)
13
+ files = "#{File.dirname(__FILE__)}/../lib/*.rb #{File.dirname(__FILE__)}/../bin/*"
14
+ sh "#{File.dirname(__FILE__)}/../script/rstakeout 'rake test:doctest:changed DOCTESTS=#{tests_path}' #{tests} #{files} --pass-as-env"
15
+ end
16
+
17
+ desc "Run doctest(s) based on a specific file that changed"
18
+ task :changed do
19
+ file = ENV['CHANGED']
20
+ doctests = ENV['DOCTESTS']
21
+ unless file && doctests
22
+ puts "Requires ENV['CHANGED']=file_path and ENV['DOCTESTS']=some/path/**/*.doctest"
23
+ exit
24
+ end
25
+ tests = File.basename(file) =~ %r{\..*doctest\Z} ? file : doctests
26
+ sh "ruby #{File.dirname(__FILE__)}/../bin/rubydoctest #{tests}"
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,7 @@
1
+ { scopeName = 'text.html.markdown.ruby.doctest';
2
+ fileTypes = ( 'doctest', 'rdoctest' );
3
+ patterns = (
4
+ { include = 'text.ruby.doctest'; },
5
+ { include = 'text.html.markdown'; }
6
+ );
7
+ }
@@ -0,0 +1,55 @@
1
+ { scopeName = 'source.ruby.doctest';
2
+ patterns = (
3
+ { name = 'comment.block.documentation.ruby';
4
+ comment = 'multiline comments';
5
+ begin = '^=begin';
6
+ end = '^=end';
7
+ captures = { 0 = { name = 'punctuation.definition.comment.ruby'; }; };
8
+ patterns = (
9
+ { include = "text.ruby.doctest"; }
10
+ );
11
+ },
12
+ {
13
+ name = 'source.ruby.doctest.description.commented';
14
+ begin = '^([ \t]*(#)\s+)(doctest:)(.*)';
15
+ end = '^(?!\1)|^(?=\1[^\s])|^(?=\1$)';
16
+ captures = {
17
+ 2 = { name = 'comment.line.number-sign.ruby';};
18
+ 3 = { name = 'keyword.ruby.doctest'; };
19
+ 4 = { name = 'comment.ruby.doctest'; };
20
+ };
21
+ patterns = (
22
+ { include = '#indented_description'; }
23
+ );
24
+ },
25
+ {
26
+ name = 'source.ruby.doctest.statement.commented';
27
+ begin = '^([ \t]*(#)\s+)(>>|=>|doctest_require:)';
28
+ end = '^(?!\1)|^(?=\1[^\s])|^(?=\1$)';
29
+ captures = {
30
+ 2 = { name = 'comment.line.number-sign.ruby'; };
31
+ 3 = { name = 'keyword.ruby.doctest'; };
32
+ };
33
+ patterns = (
34
+ { include = 'source.ruby.rails'; }
35
+ );
36
+ },
37
+ {
38
+ name = 'source.ruby.doctest.directive';
39
+ begin = '^([ \t]*(#)\s+)(\!\!\!)\s*$';
40
+ end = '\n';
41
+ captures = {
42
+ 2 = { name = 'comment.line.number-sign.ruby'; };
43
+ 3 = { name = 'keyword.ruby.doctest'; };
44
+ };
45
+ },
46
+ { include = 'source.ruby'; }
47
+ );
48
+ repository = {
49
+ indented_description = {
50
+ name = 'comment.ruby.doctest';
51
+ begin = '^([ \t]*#\s+)(.+)';
52
+ end = '^(?!\1)';
53
+ };
54
+ };
55
+ }
@@ -0,0 +1,66 @@
1
+ { scopeName = 'text.ruby.doctest';
2
+ fileTypes = ( 'txt', 'text' );
3
+ patterns = (
4
+ {
5
+ name = 'source.ruby.doctest.description.unindented';
6
+ begin = '^(doctest:)(.*)';
7
+ end = '^(?=[^\s]|$)';
8
+ captures = {
9
+ 1 = { name = 'keyword.ruby.doctest'; };
10
+ 2 = { name = 'comment.ruby.doctest'; };
11
+ };
12
+ patterns = (
13
+ { include = '#indented_description'; }
14
+ );
15
+ },
16
+ {
17
+ name = 'source.ruby.doctest.description.indented';
18
+ begin = '^(\s+)(doctest:)(.*)';
19
+ end = '^(?!\1)|^(?=\1[^\s])|^(?=\1$)';
20
+ captures = {
21
+ 2 = { name = 'keyword.ruby.doctest'; };
22
+ 3 = { name = 'comment.ruby.doctest'; };
23
+ };
24
+ patterns = (
25
+ { include = '#indented_description'; }
26
+ );
27
+ },
28
+ {
29
+ name = 'source.ruby.doctest.statement.unindented';
30
+ begin = '^(>>|=>|doctest_require:)';
31
+ end = '^(?=[^\s]|$)';
32
+ captures = {
33
+ 1 = { name = 'keyword.ruby.doctest'; };
34
+ };
35
+ patterns = (
36
+ { include = 'source.ruby.rails'; }
37
+ );
38
+ },
39
+ {
40
+ name = 'source.ruby.doctest.statement.indented';
41
+ begin = '^(\s+)(>>|=>|doctest_require:)';
42
+ end = '^(?!\1)|^(?=\1[^\s])|^(?=\1$)';
43
+ captures = {
44
+ 2 = { name = 'keyword.ruby.doctest'; };
45
+ };
46
+ patterns = (
47
+ { include = 'source.ruby.rails'; }
48
+ );
49
+ },
50
+ {
51
+ name = 'source.ruby.doctest.directive';
52
+ begin = '^(\s*)(\!\!\!)\s*$';
53
+ end = '\n';
54
+ captures = {
55
+ 2 = { name = 'keyword.ruby.doctest'; };
56
+ };
57
+ }
58
+ );
59
+ repository = {
60
+ indented_description = {
61
+ name = 'comment.ruby.doctest';
62
+ begin = '^(\s+)(.+)';
63
+ end = '^(?!\1)';
64
+ };
65
+ };
66
+ }
@@ -1,11 +1,141 @@
1
- <html>
2
- <head>
3
- <meta http-equiv="Content-type" content="text/html; charset=utf-8">
4
- <title>rubydoctest</title>
5
-
6
- </head>
7
- <body id="body">
8
- <p>This page has not yet been created for RubyGem <code>rubydoctest</code></p>
9
- <p>To the developer: To generate it, update website/index.txt and run the rake task <code>website</code> to generate this <code>index.html</code> file.</p>
10
- </body>
11
- </html>
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <link rel="stylesheet" href="stylesheets/screen.css" type="text/css" media="screen" />
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
+ <title>
8
+ rubydoctest
9
+ </title>
10
+ <script src="javascripts/rounded_corners_lite.inc.js" type="text/javascript"></script>
11
+ <style>
12
+
13
+ </style>
14
+ <script type="text/javascript">
15
+ window.onload = function() {
16
+ settings = {
17
+ tl: { radius: 10 },
18
+ tr: { radius: 10 },
19
+ bl: { radius: 10 },
20
+ br: { radius: 10 },
21
+ antiAlias: true,
22
+ autoPad: true,
23
+ validTags: ["div"]
24
+ }
25
+ var versionBox = new curvyCorners(settings, document.getElementById("version"));
26
+ versionBox.applyCornersToAll();
27
+ }
28
+ </script>
29
+ </head>
30
+ <body>
31
+ <div id="main">
32
+
33
+ <h1>rubydoctest</h1>
34
+ <div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/rubydoctest"; return false'>
35
+ <p>Get Version</p>
36
+ <a href="http://rubyforge.org/projects/rubydoctest" class="numbers">1.0.0</a>
37
+ </div>
38
+ <h1>&#x2192; &#8216;rubydoctest&#8217;</h1>
39
+
40
+
41
+ <h2>What</h2>
42
+
43
+
44
+ <h2>Installing</h2>
45
+
46
+
47
+ <p><pre class='syntax'><span class="ident">sudo</span> <span class="ident">gem</span> <span class="ident">install</span> <span class="ident">rubydoctest</span></pre></p>
48
+
49
+
50
+ <h2>The basics</h2>
51
+
52
+
53
+ <h2>Demonstration of usage</h2>
54
+
55
+
56
+ <h2>Forum</h2>
57
+
58
+
59
+ <p><a href="http://groups.google.com/group/rubydoctest">http://groups.google.com/group/rubydoctest</a></p>
60
+
61
+
62
+ <p><span class="caps">TODO</span> &#8211; create Google Group &#8211; rubydoctest</p>
63
+
64
+
65
+ <h2>How to submit patches</h2>
66
+
67
+
68
+ <p>Read the <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/">8 steps for fixing other people&#8217;s code</a> and for section <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/#8b-google-groups">8b: Submit patch to Google Groups</a>, use the Google Group above.</p>
69
+
70
+
71
+ <p><span class="caps">TODO</span> &#8211; pick <span class="caps">SVN</span> or Git instructions</p>
72
+
73
+
74
+ <p>The trunk repository is <code>svn://rubyforge.org/var/svn/rubydoctest/trunk</code> for anonymous access.</p>
75
+
76
+
77
+ <p><span class="caps">OOOORRRR</span></p>
78
+
79
+
80
+ <p>You can fetch the source from either:</p>
81
+
82
+
83
+ <ul>
84
+ <li>rubyforge: <span class="caps">MISSING IN ACTION</span></li>
85
+ </ul>
86
+
87
+
88
+ <p><span class="caps">TODO</span> &#8211; You can not created a RubyForge project, OR have not run <code>rubyforge config</code>
89
+ yet to refresh your local rubyforge data with this projects&#8217; id information.</p>
90
+
91
+
92
+ <p>When you do this, this message will magically disappear!</p>
93
+
94
+
95
+ <p>Or you can hack website/index.txt and make it all go away!!</p>
96
+
97
+
98
+ <ul>
99
+ <li>github: <a href="http://github.com/GITHUB_USERNAME/rubydoctest/tree/master">http://github.com/GITHUB_USERNAME/rubydoctest/tree/master</a></li>
100
+ </ul>
101
+
102
+
103
+ <pre>git clone git://github.com/GITHUB_USERNAME/rubydoctest.git</pre>
104
+
105
+ <p><span class="caps">TODO</span> &#8211; add &#8220;github_username: username&#8221; to ~/.rubyforge/user-config.yml and newgem will reuse it for future projects.</p>
106
+
107
+
108
+ <ul>
109
+ <li>gitorious: <a href="git://gitorious.org/rubydoctest/mainline.git">git://gitorious.org/rubydoctest/mainline.git</a></li>
110
+ </ul>
111
+
112
+
113
+ <pre>git clone git://gitorious.org/rubydoctest/mainline.git</pre>
114
+
115
+ <h3>Build and test instructions</h3>
116
+
117
+
118
+ <pre>cd rubydoctest
119
+ rake test
120
+ rake install_gem</pre>
121
+
122
+ <h2>License</h2>
123
+
124
+
125
+ <p>This code is free to use under the terms of the <span class="caps">MIT</span> license.</p>
126
+
127
+
128
+ <h2>Contact</h2>
129
+
130
+
131
+ <p>Comments are welcome. Send an email to <a href="mailto:FIXME"><span class="caps">FIXME</span> full name</a> email via the <a href="http://groups.google.com/group/rubydoctest">forum</a></p>
132
+ <p class="coda">
133
+ <a href="mailto:duane.johnson@gmail.com">Duane Johnson</a>, 17th June 2008<br>
134
+ Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
135
+ </p>
136
+ </div>
137
+
138
+ <!-- insert site tracking codes here, like Google Urchin -->
139
+
140
+ </body>
141
+ </html>