doctest 0.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.
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2008-04-12
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 FIXME full name
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,26 @@
1
+ History.txt
2
+ License.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ bin/doctest
7
+ config/hoe.rb
8
+ config/requirements.rb
9
+ lib/doctest.rb
10
+ lib/doctest/version.rb
11
+ log/debug.log
12
+ script/console
13
+ script/destroy
14
+ script/generate
15
+ script/txt2html
16
+ setup.rb
17
+ tasks/deployment.rake
18
+ tasks/environment.rake
19
+ tasks/website.rake
20
+ test/test_doctest.rb
21
+ test/test_helper.rb
22
+ website/index.html
23
+ website/index.txt
24
+ website/javascripts/rounded_corners_lite.inc.js
25
+ website/stylesheets/screen.css
26
+ website/template.html.erb
@@ -0,0 +1,48 @@
1
+ = doctest
2
+
3
+ * FIX (url)
4
+
5
+ == DESCRIPTION:
6
+
7
+ FIX (describe your package)
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * FIX (list of features or problems)
12
+
13
+ == SYNOPSIS:
14
+
15
+ FIX (code sample of usage)
16
+
17
+ == REQUIREMENTS:
18
+
19
+ * FIX (list of requirements)
20
+
21
+ == INSTALL:
22
+
23
+ * FIX (sudo gem install, anything else)
24
+
25
+ == LICENSE:
26
+
27
+ (The MIT License)
28
+
29
+ Copyright (c) 2008 FIX
30
+
31
+ Permission is hereby granted, free of charge, to any person obtaining
32
+ a copy of this software and associated documentation files (the
33
+ 'Software'), to deal in the Software without restriction, including
34
+ without limitation the rights to use, copy, modify, merge, publish,
35
+ distribute, sublicense, and/or sell copies of the Software, and to
36
+ permit persons to whom the Software is furnished to do so, subject to
37
+ the following conditions:
38
+
39
+ The above copyright notice and this permission notice shall be
40
+ included in all copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
43
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
45
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
46
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
47
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
48
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 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,13 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created on 2008-4-12.
4
+ # Copyright (c) 2008. All rights reserved.
5
+
6
+ begin
7
+ require 'rubygems'
8
+ rescue LoadError
9
+ # no rubygems to load, so we fail silently
10
+ end
11
+
12
+ require 'doctest'
13
+ DocTest.run
@@ -0,0 +1,70 @@
1
+ require 'doctest/version'
2
+
3
+ AUTHOR = 'FIXME full name' # can also be an array of Authors
4
+ EMAIL = "FIXME email"
5
+ DESCRIPTION = "description of gem"
6
+ GEM_NAME = 'doctest' # what ppl will type to install your gem
7
+ RUBYFORGE_PROJECT = 'doctest' # The unix name for your project
8
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
9
+ DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
10
+
11
+ @config_file = "~/.rubyforge/user-config.yml"
12
+ @config = nil
13
+ RUBYFORGE_USERNAME = "unknown"
14
+ def rubyforge_username
15
+ unless @config
16
+ begin
17
+ @config = YAML.load(File.read(File.expand_path(@config_file)))
18
+ rescue
19
+ puts <<-EOS
20
+ ERROR: No rubyforge config file found: #{@config_file}
21
+ Run 'rubyforge setup' to prepare your env for access to Rubyforge
22
+ - See http://newgem.rubyforge.org/rubyforge.html for more details
23
+ EOS
24
+ exit
25
+ end
26
+ end
27
+ RUBYFORGE_USERNAME.replace @config["username"]
28
+ end
29
+
30
+
31
+ REV = nil
32
+ # UNCOMMENT IF REQUIRED:
33
+ # REV = YAML.load(`svn info`)['Revision']
34
+ VERS = Doctest::VERSION::STRING + (REV ? ".#{REV}" : "")
35
+ RDOC_OPTS = ['--quiet', '--title', 'doctest documentation',
36
+ "--opname", "index.html",
37
+ "--line-numbers",
38
+ "--main", "README",
39
+ "--inline-source"]
40
+
41
+ class Hoe
42
+ def extra_deps
43
+ @extra_deps.reject! { |x| Array(x).first == 'hoe' }
44
+ @extra_deps
45
+ end
46
+ end
47
+
48
+ # Generate all the Rake tasks
49
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
50
+ $hoe = Hoe.new(GEM_NAME, VERS) do |p|
51
+ p.developer(AUTHOR, EMAIL)
52
+ p.description = DESCRIPTION
53
+ p.summary = DESCRIPTION
54
+ p.url = HOMEPATH
55
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
56
+ p.test_globs = ["test/**/test_*.rb"]
57
+ p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
58
+
59
+ # == Optional
60
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
61
+ #p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
62
+
63
+ #p.spec_extras = {} # A hash of extra values to set in the gemspec.
64
+
65
+ end
66
+
67
+ CHANGES = $hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
68
+ PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
69
+ $hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
70
+ $hoe.rsync_args = '-av --delete --ignore-errors'
@@ -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,204 @@
1
+ =begin
2
+ A testing module allowing for people to add IRB code snippets to their code descriptions, which IRB code snippets 'second' as tests for the code itself.
3
+ Ex:
4
+ =begin
5
+ # doctest This function adds 2 to its parameters
6
+ >> setup(1)
7
+ #=end
8
+ def setup a
9
+ a + 2
10
+ end
11
+ => 3
12
+ =end
13
+
14
+ # todo:
15
+ # the 'inline for rubydoc' option
16
+ # low priority:
17
+ # make it even more robust to errors--if it errs, look for internal hashes, convert
18
+ # Fix so raising errors validates -- currently ignores
19
+ # multi line strings
20
+ # option to run each in its own directory
21
+ # tell them how to change dirs on their own [add an end guy?]
22
+ # #doctest_end
23
+ # WAY more line logic
24
+ # some way of reusing tests, like classes [?] or functions :) -- this doctest gets this replaced with this :P
25
+ # normal code inline [maybe that can raise if it errs, maybe more]
26
+ # check python's --what they got?
27
+ # use rspec, how can it improve?
28
+ # todo better params
29
+
30
+ if ARGV[0] == '--help'
31
+ print "
32
+ use: doctest file_name.rb (or directory_name): default '.'
33
+ -- note it recurses and scans all .rb in that directory and its subdirectories
34
+ ex: doctest .
35
+ doctest file.rb
36
+ doctest dir #also scans its subdirs
37
+ "
38
+ exit
39
+ end
40
+
41
+ BINDING = binding()
42
+
43
+ class DocTest
44
+ CODE_REGEX = Regexp.new(/^(>>|irb.*?>) (.*)/)
45
+ RESULT_REGEX = Regexp.new(/^=> (.*)/)
46
+ EXCEPTION_REGEX = Regexp.new(/^([A-Z][A-Za-z0-9]*):/)
47
+
48
+ def get_ruby_files(dir_name)
49
+ ruby_file_names = []
50
+
51
+ Dir.foreach(dir_name) do |file_name|
52
+ unless file_name == '.' || file_name == '..'
53
+ full_name = File.join(dir_name, file_name)
54
+ if /.*\.rb$/ =~ full_name
55
+ ruby_file_names << full_name
56
+ elsif File.directory? full_name
57
+ sub_files = get_ruby_files(full_name)
58
+ ruby_file_names.concat(sub_files) unless sub_files.empty?
59
+ end
60
+ end
61
+ end
62
+
63
+ ruby_file_names
64
+ end
65
+ =begin
66
+ #doctest normalize substring
67
+ >> a = DocTest.new
68
+ => #<DocTest:0x37012c>
69
+ >> a.normalize_result('0xtion:0x1876bc0 @@p')
70
+ => "0xtion:0xXXXXXXXX @@p"
71
+ =end
72
+ def normalize_result(input)
73
+ input.gsub(/:0x([a-f0-9]){5,8}/, ':0xXXXXXXXX') # makes them all 8 digits long
74
+ end
75
+
76
+ def failure_report(statement, expected_result, result)
77
+ report = "\n FAILED" #add line number logic here
78
+ report << " Code: " << statement << "\n"
79
+ report << " Expected: " << expected_result << "\n"
80
+ report << " But got: " << result
81
+ end
82
+
83
+ =begin
84
+ #doctest should match with hashes
85
+ >> {1=>1, 2=>2, 3=> 3, 4=>4,5=>5}
86
+ => {5=>5, 1=>1, 2=>2, 3=>3, 4=>4}
87
+ now test with different ordered hashes
88
+ >> {1=>1, 2=>2, 3=> 3, 4=>4,5=>5}
89
+ => {4=>4, 1=>1, 2=>2, 3=>3, 5=>5}
90
+ >> {1=>":0x123456", 2=>2, 3=> 3, 4=>4,5=>5}
91
+ => {4=>4, 1=>":0x123456", 2=>2, 3=>3, 5=>5}
92
+ =end
93
+ def dbg
94
+ require 'rubygems'; require 'ruby-debug'; debugger
95
+ end
96
+
97
+ def run_doc_tests(doc_test)
98
+ statement, report = '', ''
99
+ wrong, passed = 0, 0
100
+ doc_test.split("\n").each do |line|
101
+ case line
102
+ when CODE_REGEX
103
+ statement << CODE_REGEX.match(line)[2]
104
+ when RESULT_REGEX, EXCEPTION_REGEX
105
+ if line =~ RESULT_REGEX
106
+ expected_result_string = normalize_result(RESULT_REGEX.match(line)[1])
107
+ else
108
+ raise unless line =~ EXCEPTION_REGEX
109
+ expected_result_string = $1
110
+ end
111
+
112
+ begin
113
+ result_we_got = eval(statement, BINDING)
114
+ rescue Exception => e
115
+ result_we_got = e.class
116
+ end
117
+
118
+ they_match = false
119
+ if result_we_got.class.ancestors.include? Hash
120
+ # change them to 'kind of real' hashes, so that we cancompare them and have comparison work--hashes sometimes display in different orders when printed
121
+ expected_result = eval(expected_result_string, BINDING)
122
+ if eval(normalize_result(result_we_got.inspect), BINDING) == expected_result # todo some tests for this with whack-o stuff thrown in :)
123
+ # the Hashes matched, string-wise
124
+ they_match = true
125
+ end
126
+ end
127
+
128
+ they_match = true if expected_result_string =~ /#doctest_fail_ok/
129
+ result_string = normalize_result(result_we_got.inspect)
130
+ they_match = true if result_string == expected_result_string
131
+ unless they_match
132
+ report << failure_report(statement, expected_result_string, result_string)
133
+ wrong += 1
134
+ else
135
+ passed += 1
136
+ end
137
+ statement = '' # reset it for the next round
138
+ end
139
+ end
140
+ return passed, wrong, report
141
+ end
142
+
143
+ def process_ruby_file(file_name)
144
+ tests, succeeded, failed = 0, 0, 0
145
+ file_report = ''
146
+ code = File.read file_name
147
+
148
+ startup_code_for_this_file = code.scan(/begin\s#setup_doctest once_per_file(.*?)=end/m)
149
+
150
+ if startup_code_for_this_file.length > 0
151
+ raise 'can only do one_time_file_setup declaration once' if startup_code_for_this_file.length > 1 or startup_code_for_this_file[0].length > 1
152
+ startup_code_for_this_file = startup_code_for_this_file[0][0]
153
+ begin
154
+ eval startup_code_for_this_file, BINDING
155
+ rescue Exception => e
156
+ print "Uh oh unable to execute startup code for #{file_name}...continuing #{e}\n"
157
+ end
158
+ end
159
+
160
+ # todo would be nice to have multiple tests in the same comment block
161
+ # so a scan + sub scan for doctests
162
+ code.scan(/=begin\s#doctest([^\n]*)\n(.*?)=end/m) do |doc_test| # could do--replace default named ones with their line number :)
163
+ require file_name # might as well have its functions available to itself :P
164
+ # todo could tear out anything loaded after each file, I suppose, as active support does
165
+ file_report << "\n Testing '#{doc_test[0]}'..."
166
+ passed, wrong, report = run_doc_tests(doc_test[1])
167
+ file_report += (wrong == 0 ? "OK" : report)
168
+ tests += 1
169
+ succeeded += passed
170
+ failed += wrong
171
+ end
172
+ file_report = "Processing '#{file_name}' from current directory " + file_report unless file_report.empty?
173
+ return tests, succeeded, failed, file_report
174
+ end
175
+ def DocTest.run
176
+ # parse command line--currently just 'filename' or 'directory name'
177
+ runner = DocTest.new
178
+ if File.directory? ARGV[0] || ''
179
+ ruby_file_names = runner.get_ruby_files(ARGV[0])
180
+ elsif File.exist? ARGV[0] || ''
181
+ ruby_file_names = [ARGV[0]]
182
+ else
183
+ ruby_file_names = runner.get_ruby_files('.')
184
+ end
185
+
186
+ total_report = "Looking for doctests in a total of #{ruby_file_names.length} possible files\n"
187
+ total_files, total_tests, total_succeeded, total_failed = 0, 0, 0, 0
188
+ ruby_file_names.each do |ruby_file_name|
189
+ tests, succeeded, failed, report = runner.process_ruby_file(ruby_file_name)
190
+ total_files += 1 if tests > 0
191
+ total_tests += tests
192
+ total_succeeded += succeeded
193
+ total_failed += failed
194
+ total_report << report << "\n" unless report.empty?
195
+ end
196
+ total_report << "Total files: #{total_files}, total tests: #{total_tests}, assertions succeeded: #{total_succeeded}, assertions failed: #{total_failed}"
197
+ puts total_report
198
+ end
199
+
200
+ end
201
+
202
+ if $0 == __FILE__
203
+ DocTest.run
204
+ end
@@ -0,0 +1,9 @@
1
+ module Doctest #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ TINY = 1
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
File without changes
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/doctest.rb'}"
9
+ puts "Loading doctest gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)