cgialib 0.0.1 → 0.0.2
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.
- data/Manifest.txt +7 -2
- data/Rakefile +4 -3
- data/examples/ut/mytest1.c +22 -0
- data/features/language_parser.feature +21 -0
- data/features/steps/language_parser.rb +84 -0
- data/lib/cgialib/lp/JavaDoc.rb +220 -0
- data/lib/cgialib/lp/JavaLanguageScanner.rb +660 -0
- data/lib/cgialib/lp/SQLLanguageScanner.rb +688 -0
- data/lib/cgialib/lp/SQLTokenizer.rb +403 -0
- data/lib/cgialib/lp.rb +5 -0
- data/lib/cgialib/template/ut/c.rb +10 -3
- data/lib/cgialib.rb +1 -1
- data/website/index.html +4 -21
- data/website/index.txt +2 -27
- data/website/template.html.erb +1 -1
- metadata +29 -4
- data/features/development.feature +0 -13
- data/features/steps/common.rb +0 -174
data/Manifest.txt
CHANGED
@@ -5,8 +5,9 @@ README.rdoc
|
|
5
5
|
Rakefile
|
6
6
|
bin/testgen
|
7
7
|
config/website.yml.sample
|
8
|
-
|
9
|
-
features/
|
8
|
+
examples/ut/mytest1.c
|
9
|
+
features/language_parser.feature
|
10
|
+
features/steps/language_parser.rb
|
10
11
|
features/steps/env.rb
|
11
12
|
lib/cgialib.rb
|
12
13
|
lib/testgen/cli.rb
|
@@ -17,6 +18,10 @@ lib/cgialib/lp/Tokenizer.rb
|
|
17
18
|
lib/cgialib/lp/CLanguageScanner.rb
|
18
19
|
lib/cgialib/lp/CPPLanguageScanner.rb
|
19
20
|
lib/cgialib/lp/CTokenizer.rb
|
21
|
+
lib/cgialib/lp/JavaDoc.rb
|
22
|
+
lib/cgialib/lp/JavaLanguageScanner.rb
|
23
|
+
lib/cgialib/lp/SQLTokenizer.rb
|
24
|
+
lib/cgialib/lp/SQLLanguageScanner.rb
|
20
25
|
lib/cgialib/template/ut.rb
|
21
26
|
lib/cgialib/template/ut/c.rb
|
22
27
|
script/console
|
data/Rakefile
CHANGED
@@ -8,9 +8,10 @@ $hoe = Hoe.new('cgialib', Cgialib::VERSION) do |p|
|
|
8
8
|
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
9
9
|
p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
|
10
10
|
p.rubyforge_name = p.name # TODO this is default value
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
p.extra_deps = [
|
12
|
+
['cucumber','>= 0.1.9'],
|
13
|
+
['rspec','>= 1.1.11']
|
14
|
+
]
|
14
15
|
p.extra_dev_deps = [
|
15
16
|
['newgem', ">= #{::Newgem::VERSION}"]
|
16
17
|
]
|
@@ -0,0 +1,22 @@
|
|
1
|
+
// Test case for the test case builder
|
2
|
+
#include <stdio.h>
|
3
|
+
|
4
|
+
// <test result="3"><a>1</a><b>2</b></test>
|
5
|
+
// <test result="6"><a>2</a><b>4</b></test>
|
6
|
+
// <test result="9"><a>3</a><b>6</b></test>
|
7
|
+
int add( int a, int b ) { return a + b; }
|
8
|
+
|
9
|
+
// <test result="3"><a>5</a><b>2</b></test>
|
10
|
+
int minus( int a, int b ) { return a - b; }
|
11
|
+
|
12
|
+
// <test result="30"><a>5</a><b>6</b></test>
|
13
|
+
int multiply( int a, int b ) { return a * b; }
|
14
|
+
|
15
|
+
int main( int argc, char *argv[] )
|
16
|
+
{
|
17
|
+
run_tests();
|
18
|
+
printf( "%d\n", add( 1, 2 ) );
|
19
|
+
return 0;
|
20
|
+
}
|
21
|
+
|
22
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Feature: Generate Unit Test for C by Language Parser
|
2
|
+
|
3
|
+
As a C language designer
|
4
|
+
I want testgen to generate unit tests for C source
|
5
|
+
So that I can spend time on designing code and test, not excessive time on writing test
|
6
|
+
|
7
|
+
Scenario: Generate Unit Test
|
8
|
+
Given this project is active project folder
|
9
|
+
And 'examples/ut/mytest1.c' file is existed
|
10
|
+
And 'examples/ut/mytest1.c' file is copied to 'tmp' folder
|
11
|
+
And file 'tmp/mytest1.c' contains /\/\/ <test.*<\/test>/
|
12
|
+
When command 'testgen -s tmp/mytest1.c' is invoked
|
13
|
+
Then file 'tmp/mytest1.c.bak' is created
|
14
|
+
And file 'tmp/mytest1.c' contains /\/\/ <test_start>.*?\/\/ <\/test_start>/m
|
15
|
+
Scenario: Compile and Run the Unit Test
|
16
|
+
Given this project is active project folder
|
17
|
+
And file 'tmp/mytest1.c' contains /test_start/
|
18
|
+
When command 'gcc tmp/mytest1.c -o tmp/mytest1' is invoked
|
19
|
+
And command 'tmp/mytest1' is invoked
|
20
|
+
Then file 'tmp/tests.out' contains /\(100%\) Unit Test are passed/
|
21
|
+
|
@@ -0,0 +1,84 @@
|
|
1
|
+
def in_project_folder(&block)
|
2
|
+
project_folder = @active_project_folder || @tmp_root
|
3
|
+
FileUtils.chdir(project_folder, &block)
|
4
|
+
end
|
5
|
+
Given %r{^this project is active project folder} do
|
6
|
+
Given "a safe folder"
|
7
|
+
@active_project_folder = File.expand_path(File.dirname(__FILE__) + "/../..")
|
8
|
+
end
|
9
|
+
Given %r{^a safe folder} do
|
10
|
+
#FileUtils.rm_rf @tmp_root = File.dirname(__FILE__) + "/../../tmp"
|
11
|
+
@tmp_root = File.dirname(__FILE__) + "/../../tmp"
|
12
|
+
FileUtils.mkdir_p @tmp_root
|
13
|
+
@lib_path = File.expand_path(File.dirname(__FILE__) + '/../../lib')
|
14
|
+
end
|
15
|
+
Given %r{^env variable \$([\w_]+) set to '(.*)'} do |env_var, value|
|
16
|
+
ENV[env_var] = value
|
17
|
+
end
|
18
|
+
Given %r{'(.*)' folder is deleted} do |folder|
|
19
|
+
in_project_folder do
|
20
|
+
FileUtils.rm_rf folder
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
Given %r{'(.*)' file is copied to '(.*)' folder} do |file, folder|
|
25
|
+
in_project_folder do
|
26
|
+
system "cp #{file} #{folder}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
Given %r{'(.*)' file is existed} do |file|
|
30
|
+
in_project_folder do
|
31
|
+
File.exists?(file).should be_true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
Given %r{'(.*)' file is deleted} do |file|
|
36
|
+
in_project_folder do
|
37
|
+
FileUtils.rm_rf file
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
When %r{^command 'testgen -s (.*\.c)' is invoked$} do |source_file|
|
42
|
+
@stdout = File.expand_path(File.join(@tmp_root, "tests.out"))
|
43
|
+
FileUtils.chdir(@active_project_folder) do
|
44
|
+
system "testgen -s #{source_file} > #{@stdout} 2> #{@stdout}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
When %r{^command 'gcc (.*\.c) (.*)' is invoked$} do |source_file,option|
|
48
|
+
@stdout = File.expand_path(File.join(@tmp_root, "tests.out"))
|
49
|
+
FileUtils.chdir(@active_project_folder) do
|
50
|
+
system "gcc #{source_file} #{option}> #{@stdout} 2> #{@stdout}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
When %r{^command '(tmp.*)' is invoked$} do |command|
|
54
|
+
@stdout = File.expand_path(File.join(@tmp_root, "tests.out"))
|
55
|
+
FileUtils.chdir(@active_project_folder) do
|
56
|
+
system " #{command}> #{@stdout} 2> #{@stdout}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
Then %r{^file '(.*)' contains \/(.*)\/$} do |file, regex|
|
61
|
+
in_project_folder do
|
62
|
+
file_content = File.read(file)
|
63
|
+
file_content.to_s.should match(/#{regex}/)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
Then %r{^file '(.*)' contains \/(.*)\/m$} do |file, regex|
|
67
|
+
in_project_folder do
|
68
|
+
file_content = File.read(file)
|
69
|
+
file_content.to_s.should match(/#{regex}/m)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
Then %r{^folder '(.*)' is created} do |folder|
|
74
|
+
in_project_folder do
|
75
|
+
File.exists?(folder).should be_true
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
Then %r{^file '(.*)' (is|is not) created} do |file, is|
|
80
|
+
in_project_folder do
|
81
|
+
File.exists?(file).should(is == 'is' ? be_true : be_false)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
@@ -0,0 +1,220 @@
|
|
1
|
+
# File: JavaDoc.rb
|
2
|
+
# Author: Jack Herrington
|
3
|
+
# Purpose: Generic class for parsing JavaDoc comments
|
4
|
+
# Date: 12/21/02
|
5
|
+
|
6
|
+
module LanguageParser
|
7
|
+
# class : JavaDoc
|
8
|
+
#
|
9
|
+
# Simple JavaDoc interpreter. This class holds JavaDoc tokens for a series of related JavaDoc
|
10
|
+
# comments. You should use one JavaDoc object per method or class. The JavaDoc object parses the
|
11
|
+
# comments, and stores the JavaDoc data in structured holders for easy access.
|
12
|
+
|
13
|
+
class JavaDoc
|
14
|
+
|
15
|
+
# initialize()
|
16
|
+
#
|
17
|
+
# Builds the JavaDoc class
|
18
|
+
|
19
|
+
def initialize()
|
20
|
+
|
21
|
+
# Hash to hold the @name tags. The default text goes into a tag named
|
22
|
+
# '@desc'.
|
23
|
+
|
24
|
+
@tags = { '@desc' => "" }
|
25
|
+
|
26
|
+
# Special holder for the @param values
|
27
|
+
|
28
|
+
@params = {}
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader :tags # The tag contents
|
33
|
+
|
34
|
+
attr_reader :params # The @param contents
|
35
|
+
|
36
|
+
# to_s()
|
37
|
+
#
|
38
|
+
# Pretty prints the current contents of this JavaDoc object
|
39
|
+
|
40
|
+
def to_s()
|
41
|
+
|
42
|
+
text = ""
|
43
|
+
|
44
|
+
@tags.each_key { |k| text += "#{k} : #{@tags[k]}\n" }
|
45
|
+
|
46
|
+
@params.each_key { |k| text += "param(#{k}) : #{@params[k]}\n" }
|
47
|
+
|
48
|
+
text
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
# parse( text )
|
53
|
+
#
|
54
|
+
# text - The JavaDoc comment
|
55
|
+
#
|
56
|
+
# Parses the JavaDoc comment and stores the contents
|
57
|
+
|
58
|
+
def parse( text )
|
59
|
+
|
60
|
+
# Strip leading and trailing space
|
61
|
+
|
62
|
+
text.strip!
|
63
|
+
|
64
|
+
# Return unless we see the distinctive '/**' JavaDoc beginning
|
65
|
+
# marker
|
66
|
+
|
67
|
+
return unless ( text =~ /^\/\*\*/ || text =~ /^\*/ )
|
68
|
+
|
69
|
+
# This section removes all of the leading stars, the comment lines
|
70
|
+
# and anything around the text
|
71
|
+
|
72
|
+
cleaned = ""
|
73
|
+
text.each_line { |line|
|
74
|
+
|
75
|
+
line.strip!
|
76
|
+
|
77
|
+
line.sub!( /^\/\*\*/, "" )
|
78
|
+
line.sub!( /^\*\//, "" )
|
79
|
+
line.sub!( /^\*\s*/, "" )
|
80
|
+
|
81
|
+
line.strip!
|
82
|
+
|
83
|
+
next if line.length < 1
|
84
|
+
|
85
|
+
cleaned += "#{line}\n"
|
86
|
+
|
87
|
+
}
|
88
|
+
|
89
|
+
# This section is a mini-tokenizer that splits the content of the string
|
90
|
+
# into an array. The delimiter is whitespace. The whitespace is stored
|
91
|
+
# in the array as well as it may be important to some tags.
|
92
|
+
|
93
|
+
in_whitespace = false
|
94
|
+
text = ""
|
95
|
+
tokens = []
|
96
|
+
|
97
|
+
cleaned.each_byte { |ch|
|
98
|
+
|
99
|
+
ch = ch.chr()
|
100
|
+
|
101
|
+
if ( ch =~ /\s/ )
|
102
|
+
|
103
|
+
if ( in_whitespace )
|
104
|
+
|
105
|
+
text += ch
|
106
|
+
|
107
|
+
else
|
108
|
+
|
109
|
+
tokens.push( text ) if ( text.length > 0 )
|
110
|
+
text = ch
|
111
|
+
in_whitespace = true
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
else
|
116
|
+
|
117
|
+
if ( in_whitespace )
|
118
|
+
|
119
|
+
tokens.push( text ) if ( text.length > 0 )
|
120
|
+
text = ch
|
121
|
+
in_whitespace = false
|
122
|
+
|
123
|
+
else
|
124
|
+
|
125
|
+
text += ch
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
}
|
132
|
+
|
133
|
+
tokens.push( text ) if ( text.length > 0 )
|
134
|
+
|
135
|
+
# Now we use our 'tokenized' array and search for the '@tag' items. As
|
136
|
+
# we go through the tokens we are building a buffer. When we reach a
|
137
|
+
# new tag we send the buffer on to add_to_tag.
|
138
|
+
|
139
|
+
cur_name = "@desc"
|
140
|
+
buffer = ""
|
141
|
+
|
142
|
+
tokens.each { |tok|
|
143
|
+
|
144
|
+
if ( tok =~ /^@/ )
|
145
|
+
|
146
|
+
add_to_tag( cur_name, buffer ) if ( buffer.length > 0 )
|
147
|
+
buffer = ""
|
148
|
+
|
149
|
+
cur_name = tok
|
150
|
+
|
151
|
+
else
|
152
|
+
|
153
|
+
buffer += tok
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
}
|
158
|
+
|
159
|
+
# Make sure we get the contents of the buffer at the end
|
160
|
+
|
161
|
+
add_to_tag( cur_name, buffer ) if ( buffer.length > 0 )
|
162
|
+
|
163
|
+
# Invoke the tag cleaner
|
164
|
+
|
165
|
+
clean_tags()
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
protected
|
170
|
+
|
171
|
+
# add_to_tag( key, text )
|
172
|
+
#
|
173
|
+
# key - The tag name (e.g. '@see' )
|
174
|
+
# text - The text of the tag
|
175
|
+
#
|
176
|
+
# This adds some more text to the tag. This is the method you would
|
177
|
+
# override if you wanted to add your own JavaDoc tag to a parser, but
|
178
|
+
# only if that tag had special parsing requirements.
|
179
|
+
|
180
|
+
def add_to_tag( key, text )
|
181
|
+
|
182
|
+
if ( key == "@param" )
|
183
|
+
|
184
|
+
# If this is a param then we handle it seperately
|
185
|
+
# by storing it's contents into a hash
|
186
|
+
|
187
|
+
text.strip!
|
188
|
+
|
189
|
+
text =~ /^(.*?)\s/
|
190
|
+
name = $1
|
191
|
+
text.sub!( /^(.*?)\s/, "" )
|
192
|
+
|
193
|
+
text.strip!
|
194
|
+
|
195
|
+
@params[ name ] = text
|
196
|
+
|
197
|
+
else
|
198
|
+
|
199
|
+
# Otherwise we just append it to the tag text in the
|
200
|
+
# tag hash
|
201
|
+
|
202
|
+
@tags[ key ] = "" unless ( @tags.has_key?( key ) )
|
203
|
+
@tags[ key ] += text
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
208
|
+
|
209
|
+
# clean_tags()
|
210
|
+
#
|
211
|
+
# A process step method that cleans up the tags after they are read in.
|
212
|
+
|
213
|
+
def clean_tags()
|
214
|
+
|
215
|
+
@tags.each_key { |k| @tags[ k ].strip! }
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
220
|
+
end
|