CommentUnit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2008 Blaine Buxton
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,43 @@
1
+ ### Comment Unit Tests
2
+ ### Author:: Blaine Buxton (mailto:altodorado@blainebuxton.com)
3
+ ### Copyright:: Copyright (c) 2008
4
+ ### License:: See LICENSE
5
+ ###
6
+ ### This is a simple framework that hooks into Test::Unit and RDoc.
7
+ ### It allows you to write arbitrary bits of code in comments that can be
8
+ ### executed and then verified via Test::Unit. It uses the RDoc parser to obtain
9
+ ### the comments.
10
+ ###
11
+ ### Any comments are appreciated (pun not intended)
12
+ ###
13
+ ### To invoke:
14
+ ### require 'comment_unit'
15
+ ### class YourTest < Test::Unit::TestCase
16
+ ### def self.suite
17
+ ### suite=super
18
+ ### suite << RUnitComment.on($0)
19
+ ### suite
20
+ ### end
21
+ ### end
22
+ ###
23
+ ### Examples:
24
+ ### >>> 3 + 4
25
+ ### >>= 7
26
+ ###
27
+ ### >>> 42
28
+ ### >>= 42
29
+ ###
30
+ ### >>> a='i'
31
+ ### >>> b=' love '
32
+ ### >>> c='michelle'
33
+ ### >>> a + b + c
34
+ ### >>= 'i love michelle'
35
+ ###
36
+ ### >>> a + ', robot will never die'
37
+ ### >>= 'i, robot will never die'
38
+ ###
39
+ ### >>> a = 5
40
+ ### >>> b = 4 + 1
41
+ ### >>? a == b
42
+ ###
43
+ ### >>> puts 'Comments Ran'
@@ -0,0 +1,12 @@
1
+ module CommentUnit
2
+ class AssertEqualResultPart < ExecutablePart
3
+ def self.prefix()
4
+ '>>='
5
+ end
6
+
7
+ private
8
+ def assert(test_case, expected, actual)
9
+ test_case.assert_equal(expected, actual, failure_text())
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module CommentUnit
2
+ class AssertResultPart < ExecutablePart
3
+ def self.prefix()
4
+ '>>?'
5
+ end
6
+
7
+ private
8
+ def assert(test_case, expected, actual)
9
+ test_case.assert(actual, failure_text())
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,91 @@
1
+ module CommentUnit
2
+ class CommentPart
3
+ @@mapping=nil
4
+ @@matcher=nil
5
+ @@subclasses=[]
6
+
7
+ attr_reader :content
8
+
9
+ public
10
+ def self.parse(comment_string)
11
+ previous_part = nil
12
+ comment_string.inject([]) do |results, line|
13
+ part = parse_part(line)
14
+ if (!previous_part.nil? && previous_part.can_combine?(part))
15
+ previous_part.combine_with(part)
16
+ else
17
+ unless part.nil?
18
+ results << part
19
+ previous_part = part
20
+ end
21
+ end
22
+ results
23
+ end
24
+ end
25
+
26
+ def to_s
27
+ "#{self.class}[#{@content}]"
28
+ end
29
+
30
+ def can_combine?(another)
31
+ false
32
+ end
33
+
34
+ def combine_with(another)
35
+ @content << ';' << another.content
36
+ end
37
+
38
+ private
39
+ def self.parse_part(line)
40
+ match = self.matcher.match(line)
41
+ if (match)
42
+ create_part(match[1], match[2])
43
+ else
44
+ nil
45
+ end
46
+ end
47
+
48
+ def self.create_part(prefix, content)
49
+ klass = self.mapping[prefix]
50
+ klass.new(content) unless klass.nil?
51
+ end
52
+
53
+ def self.inherited(new_class)
54
+ super
55
+ @@mapping=nil
56
+ @@matcher=nil
57
+ @@subclasses << new_class
58
+ end
59
+
60
+ def self.mapping()
61
+ @@mapping unless @@mapping.nil?
62
+ @@mapping = @@subclasses.inject({}) do |result, each|
63
+ result[each.prefix]=each unless each.prefix.nil?
64
+ result
65
+ end
66
+ end
67
+
68
+ def self.matcher()
69
+ @@matcher unless @@matcher.nil?
70
+ first=true
71
+ matcher_string = @@subclasses.inject('\s*(') do |result, each|
72
+ result << '|' unless first
73
+ unless each.prefix.nil?
74
+ result << each.prefix.gsub(/[\?]/) { |each| "\\" + each }
75
+ first = false
76
+ end
77
+ result
78
+ end
79
+ matcher_string << ')\s*(.*)'
80
+ @@matcher = Regexp.new(matcher_string)
81
+ end
82
+
83
+ def self.prefix()
84
+ nil
85
+ end
86
+
87
+ def initialize(content)
88
+ @content=content
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,58 @@
1
+ ###
2
+ ### Comment Unit Tests
3
+ ### Author:: Blaine Buxton (mailto:altodorado@blainebuxton.com)
4
+ ### Copyright:: Copyright (c) 2005-2006
5
+ ### License:: Distributes under MIT License (See LICENSE file)
6
+ ###
7
+ ### This is a simple framework that hooks into Test::Unit and RDoc.
8
+ ### It allows you to write arbitrary bits of code in comments that can be
9
+ ### executed and then verified via Test::Unit. It uses the RDoc parser to obtain
10
+ ### the comments.
11
+ ###
12
+ ### Any comments are appreciated (pun not intended)
13
+ ###
14
+ ### To invoke:
15
+ ### require 'comment_unit'
16
+ ### class YourTest < Test::Unit::TestCase
17
+ ### def self.suite
18
+ ### suite=super
19
+ ### suite << RUnitComment.on($0)
20
+ ### suite
21
+ ### end
22
+ ### end
23
+ ###
24
+ ### Examples:
25
+ ### >>> 3 + 4
26
+ ### >>= 7
27
+ ###
28
+ ### >>> 42
29
+ ### >>= 42
30
+ ###
31
+ ### >>> a='i'
32
+ ### >>> b=' love '
33
+ ### >>> c='michelle'
34
+ ### >>> a + b + c
35
+ ### >>= 'i love michelle'
36
+ ###
37
+ ### >>> a + ', robot will never die'
38
+ ### >>= 'i, robot will never die'
39
+ ###
40
+ ### >>> a = 5
41
+ ### >>> b = 4 + 1
42
+ ### >>? a == b
43
+ ###
44
+ ### >>> puts 'Comments Ran'
45
+
46
+ require 'rdoc/rdoc'
47
+ require 'test/unit'
48
+
49
+
50
+
51
+ require 'comments'
52
+ require 'comment_part'
53
+ require 'executable_part'
54
+ require 'run_part'
55
+ require 'assert_equal_result_part'
56
+ require 'assert_result_part'
57
+ require 'extensions'
58
+ require 'runit_comment'
data/lib/comments.rb ADDED
@@ -0,0 +1,21 @@
1
+ module CommentUnit
2
+ class Comments
3
+ public
4
+ def self.parse(comment_string)
5
+ new(CommentPart.parse(comment_string))
6
+ end
7
+
8
+ def run_tests(test_case)
9
+ test_binding=blank_binding()
10
+ @parts.inject(nil) {|previous, every| every.run(test_case, previous, test_binding) }
11
+ end
12
+
13
+ private
14
+ def new(*arguments)
15
+ super
16
+ end
17
+ def initialize(parts)
18
+ @parts=parts
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ module CommentUnit
2
+ class ExecutablePart < CommentPart
3
+ def run(test_case, expected, test_binding=blank_binding())
4
+ result = execute(test_binding)
5
+ assert(test_case, expected, result)
6
+ result
7
+ end
8
+
9
+ private
10
+ def assert(test_case, expected, actual)
11
+ end
12
+
13
+ def execute(my_binding=blank_binding())
14
+ eval(@content, my_binding)
15
+ end
16
+
17
+ def failure_text()
18
+ "Failure in #{self.class.prefix} #{@content}"
19
+ end
20
+ end
21
+ end
data/lib/extensions.rb ADDED
@@ -0,0 +1,24 @@
1
+ module RDoc
2
+ class Context
3
+ def each_comment(&proc)
4
+ super
5
+ comment_proc=lambda do |each|
6
+ each.each_comment(&proc) unless each.nil?
7
+ end
8
+ each_classmodule(&comment_proc)
9
+ each_method(&comment_proc)
10
+ each_attribute(&comment_proc)
11
+ each_constant(&comment_proc)
12
+ end
13
+ end
14
+
15
+ class CodeObject
16
+ def each_comment(&proc)
17
+ proc.call(self.comment) unless self.comment.nil? || self.comment.empty?
18
+ end
19
+ end
20
+ end
21
+
22
+ def blank_binding()
23
+ binding().clone()
24
+ end
data/lib/run_part.rb ADDED
@@ -0,0 +1,11 @@
1
+ module CommentUnit
2
+ class RunPart < ExecutablePart
3
+ def self.prefix()
4
+ '>>>'
5
+ end
6
+
7
+ def can_combine?(another)
8
+ another.is_a? self.class
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,31 @@
1
+ class RUnitComment < Test::Unit::TestCase
2
+ attr_accessor :file_name
3
+
4
+ def self.on(file_name)
5
+ result = self.new(:execute_all_comments)
6
+ result.file_name = file_name
7
+ result
8
+ end
9
+
10
+ def run(result)
11
+ return if self.file_name.nil?
12
+ super
13
+ end
14
+
15
+ def execute_all_comments
16
+ self.parse_comments unless @top_level
17
+ @top_level.each_comment do |each|
18
+ CommentUnit::Comments.parse(each).run_tests(self)
19
+ end
20
+ end
21
+
22
+ def parse_comments
23
+ @top_level=RDoc::TopLevel.new(self.file_name)
24
+ stats=RDoc::Stats.new
25
+ options=Options.instance
26
+ options.instance_eval { @tab_width = 2 }
27
+ content=File.open(file_name, 'r') { |file| file.read }
28
+ parser = RDoc::ParserFactory.parser_for(@top_level, self.file_name, content, options, stats)
29
+ parser.scan
30
+ end
31
+ end
@@ -0,0 +1,40 @@
1
+ module CommentUnit
2
+ class CommentPartTest < Test::Unit::TestCase
3
+ def test_simple
4
+ comment = <<DOC
5
+ #blah blah
6
+ #>>>3 + 4
7
+ #>>=7
8
+ #>>?42 == 42
9
+ DOC
10
+ comments = CommentPart.parse(comment)
11
+ assert_equal('3 + 4', comments[0].content)
12
+ assert(comments[0].is_a?(RunPart))
13
+ assert_equal(7, comments[0].run(self, nil))
14
+ assert_equal('7', comments[1].content)
15
+ assert(comments[1].is_a?(AssertEqualResultPart))
16
+ assert_equal(7, comments[1].run(self, 7))
17
+ assert_equal('42 == 42', comments[2].content)
18
+ assert(comments[2].is_a?(AssertResultPart))
19
+ assert_equal(true, comments[2].run(self, nil))
20
+ end
21
+
22
+ def test_combine
23
+ comment = <<DOC
24
+ #>>>a = 3
25
+ #Noise here
26
+ #>>>b = 4
27
+ #>>>a + b
28
+ #the result is here
29
+ #>>=7
30
+ DOC
31
+ comments = CommentPart.parse(comment)
32
+ assert_equal('a = 3;b = 4;a + b', comments[0].content)
33
+ assert(comments[0].is_a?(RunPart))
34
+ assert_equal(7, comments[0].run(self, nil))
35
+ assert_equal('7', comments[1].content)
36
+ assert(comments[1].is_a?(AssertEqualResultPart))
37
+ comments[1].run(self, 7)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,24 @@
1
+ MY_DIR = File.expand_path(File.dirname(__FILE__))
2
+
3
+ def lib_require(name)
4
+ begin
5
+ require name
6
+ rescue LoadError
7
+ $LOAD_PATH << File.expand_path(File.join(MY_DIR, '..', 'lib'))
8
+ require name
9
+ end
10
+ end
11
+
12
+ def tests_require(name)
13
+ begin
14
+ require name
15
+ rescue LoadError
16
+ $LOAD_PATH << MY_DIR
17
+ require name
18
+ end
19
+ end
20
+
21
+ lib_require 'comment_unit'
22
+ tests_require 'comment_part_test'
23
+ tests_require 'comments_test'
24
+ tests_require 'rdoc_test'
@@ -0,0 +1,19 @@
1
+ module CommentUnit
2
+ class CommentsTest < Test::Unit::TestCase
3
+ def test_simple()
4
+ comment = <<DOC
5
+ #>>>a=3
6
+ #>>=3
7
+ #
8
+ #>>>b=4
9
+ #>>=4
10
+ #
11
+ #>>>a + b
12
+ #>>=7
13
+ #>>?(a + b) == 7
14
+ DOC
15
+ comments = Comments.parse(comment)
16
+ comments.run_tests(self)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ class RDocTest < Test::Unit::TestCase
2
+ def test_placebo
3
+ end
4
+
5
+ def self.suite
6
+ suite=super
7
+ my_dir=File.dirname(__FILE__)
8
+ to_run=File.join(my_dir, '..', 'lib', 'comment_unit.rb')
9
+ to_run=File.expand_path(to_run)
10
+ suite << RUnitComment.on(to_run)
11
+ suite
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: CommentUnit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Blaine Buxton
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-06-20 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: altodorado@blainebuxton
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ - LICENSE
25
+ files:
26
+ - tests/comment_part_test.rb
27
+ - tests/comment_unit_test_suite.rb
28
+ - tests/comments_test.rb
29
+ - tests/rdoc_test.rb
30
+ - lib/assert_equal_result_part.rb
31
+ - lib/assert_result_part.rb
32
+ - lib/comment_part.rb
33
+ - lib/comment_unit.rb
34
+ - lib/comments.rb
35
+ - lib/executable_part.rb
36
+ - lib/extensions.rb
37
+ - lib/run_part.rb
38
+ - lib/runit_comment.rb
39
+ - README
40
+ - LICENSE
41
+ has_rdoc: true
42
+ homepage: http://commentunit.rubyforge.org/
43
+ post_install_message:
44
+ rdoc_options: []
45
+
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ requirements: []
61
+
62
+ rubyforge_project: commentunit
63
+ rubygems_version: 1.0.1
64
+ signing_key:
65
+ specification_version: 2
66
+ summary: Write RUnit Tests in Comments
67
+ test_files:
68
+ - tests/comment_unit_test_suite.rb