cgialib 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,3 +2,9 @@
2
2
 
3
3
  * 1 major enhancement:
4
4
  * Initial release
5
+
6
+ == 0.0.3 2008-11-22
7
+ * 2 major enhancement:
8
+ * testgen is available to generate Unit Test for C
9
+ * docgen is available to generate HTML Doc for SQL
10
+
@@ -3,13 +3,18 @@ Manifest.txt
3
3
  PostInstall.txt
4
4
  README.rdoc
5
5
  Rakefile
6
+ bin/docgen
6
7
  bin/testgen
7
8
  config/website.yml.sample
8
9
  examples/ut/mytest1.c
10
+ examples/docgen/tables.sql
11
+ features/docgen.feature
9
12
  features/language_parser.feature
10
13
  features/steps/language_parser.rb
14
+ features/steps/docgen.rb
11
15
  features/steps/env.rb
12
16
  lib/cgialib.rb
17
+ lib/docgen/cli.rb
13
18
  lib/testgen/cli.rb
14
19
  lib/cgialib/lp.rb
15
20
  lib/cgialib/template.rb
@@ -32,6 +37,10 @@ spec/cgialib_spec.rb
32
37
  spec/spec.opts
33
38
  spec/spec_helper.rb
34
39
  spec/testgen_cli_spec.rb
40
+ templates/ut/c.template
41
+ templates/docgen/index.html.template
42
+ templates/docgen/table_page.html.template
43
+ templates/docgen/tables.html.template
35
44
  tasks/rspec.rake
36
45
  website/index.html
37
46
  website/index.txt
@@ -9,11 +9,13 @@ Import the examples in Code Generation In Action
9
9
  == FEATURES/PROBLEMS:
10
10
 
11
11
  * language parsers
12
- * unit test generators
12
+ * unit test generators for C
13
+ * HTML DOC generators for SQL
13
14
 
14
15
  == SYNOPSIS:
15
16
 
16
- testgen test.c
17
+ testgen -s test.c
18
+ docgen -s tables.sql
17
19
 
18
20
  == REQUIREMENTS:
19
21
 
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created on 2008-11-17.
4
+ # Copyright (c) 2008. All rights reserved.
5
+
6
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/cgialib")
7
+
8
+ require "docgen/cli"
9
+
10
+ Docgen::CLI.execute(STDOUT, ARGV)
@@ -0,0 +1,81 @@
1
+ drop table Book;
2
+
3
+ -- Book contains information about each book, the title, the author, the publisher, etc.
4
+ --
5
+ -- @field bookID The primary key id
6
+ -- @field title The title of the book
7
+ -- @field ISBN The ISBN number of the book
8
+ -- @field authorID The author (as a foreign key relation)
9
+ -- @field publisherID The publisher (as a foreign key relation)
10
+ -- @field status The active or inactive state of the record
11
+ -- @field numCompies The number of copies in the library
12
+ -- @relates_to Author
13
+ -- @relates_to Publisher
14
+ create table Book (
15
+ bookID integer not null primary key
16
+ ,title varchar(80) not null
17
+ ,ISBN varchar(80) not null unique
18
+ ,authorID integer not null
19
+ ,publisherID integer not null
20
+ ,status integer not null
21
+ ,numCopies integer not null
22
+ );
23
+
24
+ grant all on Book to public;
25
+
26
+ drop sequence Book_bookID_seq;
27
+
28
+ create sequence Book_bookID_seq start 100;
29
+
30
+ grant all on Book_bookID_seq to public;
31
+
32
+ drop table Author;
33
+
34
+ -- Author contains information about the author of a set of books
35
+ --
36
+ -- @field authorID The primary key id
37
+ -- @field name The name of the author
38
+ -- @field penName The pen name of the author
39
+ create table Author (
40
+ authorID integer not null primary key
41
+ ,name varchar(80) not null unique
42
+ ,penName varchar(80)
43
+ );
44
+
45
+ grant all on Author to public;
46
+
47
+ drop sequence Author_authorID_seq;
48
+
49
+ create sequence Author_authorID_seq start 100;
50
+
51
+ grant all on Author_authorID_seq to public;
52
+
53
+ drop table Publisher;
54
+
55
+ -- Publisher contains information about the author of a set of books
56
+ --
57
+ -- @field publisherID The primary key id
58
+ -- @field name The name of the publisher
59
+ create table Publisher (
60
+ publisherID integer not null primary key
61
+ ,name varchar(80) not null unique
62
+ );
63
+
64
+ grant all on Publisher to public;
65
+
66
+ drop sequence Publisher_publisherID_seq;
67
+
68
+ create sequence Publisher_publisherID_seq start 100;
69
+
70
+ grant all on Publisher_publisherID_seq to public;
71
+
72
+ alter table Book
73
+ add constraint Book_authorID
74
+ foreign key (authorID)
75
+ references Author (authorID);
76
+
77
+
78
+ alter table Book
79
+ add constraint Book_publisherID
80
+ foreign key (publisherID)
81
+ references Publisher (publisherID);
@@ -0,0 +1,17 @@
1
+ Feature: Generate HTML Doc for SQL by Language Parser
2
+
3
+ As a SQL language designer
4
+ I want docgen to generate html doc for SQL table
5
+ So that I can understand the relationships between the tables
6
+
7
+ Scenario: Generate HTML Doc for SQL
8
+ Given this project is active project folder
9
+ And 'examples/docgen/tables.sql' file is existed
10
+ And 'examples/docgen/tables.sql' file is copied to 'tmp' folder
11
+ And file 'tmp/tables.sql' contains /-- @field/
12
+ When command 'ruby bin/docgen -s tmp/tables.sql' is invoked
13
+ Then folder 'tmp/html_doc' is created
14
+ Then file 'tmp/html_doc/index.html' is created
15
+
16
+
17
+
@@ -9,13 +9,13 @@ Feature: Generate Unit Test for C by Language Parser
9
9
  And 'examples/ut/mytest1.c' file is existed
10
10
  And 'examples/ut/mytest1.c' file is copied to 'tmp' folder
11
11
  And file 'tmp/mytest1.c' contains /\/\/ <test.*<\/test>/
12
- When command 'testgen -s tmp/mytest1.c' is invoked
12
+ When command 'ruby bin/testgen -s tmp/mytest1.c' is invoked
13
13
  Then file 'tmp/mytest1.c.bak' is created
14
14
  And file 'tmp/mytest1.c' contains /\/\/ <test_start>.*?\/\/ <\/test_start>/m
15
+
15
16
  Scenario: Compile and Run the Unit Test
16
17
  Given this project is active project folder
17
18
  And file 'tmp/mytest1.c' contains /test_start/
18
19
  When command 'gcc tmp/mytest1.c -o tmp/mytest1' is invoked
19
20
  And command 'tmp/mytest1' is invoked
20
21
  Then file 'tmp/tests.out' contains /\(100%\) Unit Test are passed/
21
-
@@ -0,0 +1,7 @@
1
+ When %r{^command 'ruby bin/docgen -s (.*\.sql)' is invoked$} do |source_file|
2
+ @stdout = File.expand_path(File.join(@tmp_root, "tests.out"))
3
+ FileUtils.chdir(@active_project_folder) do
4
+ system "ruby bin/docgen -s #{source_file} > #{@stdout} 2> #{@stdout}"
5
+ end
6
+ end
7
+
@@ -38,10 +38,10 @@ Given %r{'(.*)' file is deleted} do |file|
38
38
  end
39
39
  end
40
40
 
41
- When %r{^command 'testgen -s (.*\.c)' is invoked$} do |source_file|
41
+ When %r{^command 'ruby bin/testgen -s (.*\.c)' is invoked$} do |source_file|
42
42
  @stdout = File.expand_path(File.join(@tmp_root, "tests.out"))
43
43
  FileUtils.chdir(@active_project_folder) do
44
- system "testgen -s #{source_file} > #{@stdout} 2> #{@stdout}"
44
+ system "ruby bin/testgen -s #{source_file} > #{@stdout} 2> #{@stdout}"
45
45
  end
46
46
  end
47
47
  When %r{^command 'gcc (.*\.c) (.*)' is invoked$} do |source_file,option|
@@ -2,8 +2,8 @@ $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
4
  require 'cgialib/lp'
5
- require 'cgialib/template'
5
+ #require 'cgialib/template'
6
6
 
7
7
  module Cgialib
8
- VERSION = '0.0.2'
8
+ VERSION = '0.0.3'
9
9
  end
@@ -0,0 +1,243 @@
1
+ require 'optparse'
2
+ # Bring in 'ftools' for File.copy
3
+ require "ftools"
4
+ require "fileutils"
5
+ # Bring in REXML and ERb
6
+ require "rexml/document"
7
+ require "erb"
8
+ module Docgen
9
+ include LanguageParser
10
+ # class : ExtendedJavaDoc
11
+ #
12
+ # An extension to JavaDoc to look for our specific JavaDoc markup
13
+
14
+ class ExtendedJavaDoc < JavaDoc
15
+
16
+ # initialize()
17
+ #
18
+ # Constructor
19
+
20
+ def initialize()
21
+
22
+ super()
23
+
24
+ @tableDescription = ""
25
+ @fieldDescriptions = {}
26
+ @relatesTo = []
27
+
28
+ end
29
+
30
+ attr_reader :tableDescription # The table description string
31
+ attr_reader :fieldDescriptions # The hash of descriptions for each field
32
+ attr_reader :relatesTo # The array of tables this table relates to
33
+
34
+ # add_to_tag( key, text )
35
+ #
36
+ # key - The JavaDoc key
37
+ # text - The text associated with the key
38
+ #
39
+ # An override of the JavaDoc handler to look for our markup
40
+
41
+ def add_to_tag( key, text )
42
+
43
+ # Strip any whitespace off the text
44
+
45
+ text.strip!
46
+
47
+ if ( key == "@desc" )
48
+
49
+ # Add to the description any @desc data
50
+
51
+ @tableDescription += text
52
+
53
+ elsif ( key == "@field" )
54
+
55
+ # Parse any @field description data
56
+
57
+ text =~ /(.*?)\s/
58
+ field = $1
59
+
60
+ text.sub!( /^#{field}\s*/, "" )
61
+
62
+ @fieldDescriptions[ field.downcase.strip ] = text
63
+
64
+ elsif ( key == "@relates_to" )
65
+
66
+ # Parse any @relates_to data
67
+
68
+ @relatesTo.push( text )
69
+
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+
76
+
77
+ class CLI
78
+ include LanguageParser
79
+ # run_template( template_name, bind )
80
+ #
81
+ # template_name - The name of the template file
82
+ # bind - The binding to pass to the template
83
+ #
84
+ # This runs the specified template with the bindings and returns the text
85
+ # output.
86
+
87
+ def self.run_template( template_name, bind )
88
+
89
+ erb = ERB.new( File.new( File.dirname(__FILE__)+"/../../templates/docgen/#{template_name}" ).read )
90
+ erb.result( bind )
91
+
92
+ end
93
+
94
+ # convert_comment( comment )
95
+ #
96
+ # comment - An SQL Comment
97
+ #
98
+ # This converts and SQL comment into a JavaDoc style comment
99
+
100
+ def self.convert_comment( comment )
101
+
102
+ # First clean off all of the '--' markers
103
+
104
+ cleaned = ""
105
+
106
+ comment.each_line { |line|
107
+ line.sub!( /\s*\-\-\s*/, "" )
108
+ line.strip!
109
+ cleaned += "#{line}\n" if ( line.length > 0 )
110
+ }
111
+
112
+ # Now create a new buffer with the proper JavaDoc formatting
113
+ # around it
114
+
115
+ converted = "/**\n"
116
+
117
+ cleaned.each_line { |line| converted += " * #{line}" }
118
+
119
+ converted += " */\n"
120
+
121
+ converted
122
+
123
+ end
124
+ # read_sql_file( file_name )
125
+ #
126
+ # file_name - The name of the file
127
+ #
128
+ # This reads and parses the file.
129
+
130
+ def self.read_sql_file( file_name )
131
+
132
+ # Read the file contents
133
+
134
+ print "Parsing #{file_name}...\n"
135
+
136
+ fh = File.open( file_name )
137
+ in_text = fh.read()
138
+ fh.close()
139
+
140
+ # Tokenize the Java
141
+
142
+ tokenizer = SQLTokenizer.new( )
143
+ tokenizer.parse( in_text )
144
+
145
+ # Run it through the language parser
146
+
147
+ languagescanner = SQLLanguageScanner.new()
148
+ languagescanner.parse( tokenizer.tokens )
149
+
150
+ # Get the tables
151
+
152
+ tables = languagescanner.tables
153
+
154
+ @@output_dir = File.expand_path(File.dirname(file_name))+"/html_doc"
155
+ FileUtils.rm_rf @@output_dir
156
+ FileUtils.mkdir_p @@output_dir
157
+
158
+ # Iterate over each table and make the HTML file for it
159
+
160
+ tables.each { |table|
161
+
162
+ # Tell the user what we are building
163
+
164
+ print "Building #{table.name}.html\n"
165
+
166
+ # Parse the JavaDoc in the comments attached to the table
167
+
168
+ jd = ExtendedJavaDoc.new()
169
+ jd.parse( convert_comment( table.comment ) )
170
+
171
+ # Fill the field comment value with the appropriate comment from the
172
+ # JavaDoc
173
+
174
+ table.fields.each { |field|
175
+ field.comment = jd.fieldDescriptions[ field.name.to_s.downcase.strip ]
176
+ }
177
+
178
+ # Setup other locals that the template will use
179
+
180
+ table_comment = jd.tableDescription
181
+ relates_to = jd.relatesTo
182
+
183
+ # Create the HTML file and use the template to build it
184
+
185
+ fh = File.new("#{@@output_dir}/#{table.name}.html", "w" )
186
+ fh.print run_template( "table_page.html.template", binding )
187
+ fh.close()
188
+ }
189
+
190
+ # Build the table index
191
+
192
+ print "Building tables.html\n"
193
+ fh = File.new("#{@@output_dir}/tables.html", "w" )
194
+ fh.print run_template( "tables.html.template", binding )
195
+ fh.close()
196
+
197
+ # Build the main index page
198
+
199
+ print "Building index.html\n"
200
+ fh = File.new("#{@@output_dir}/index.html", "w" )
201
+ fh.print run_template( "index.html.template", binding )
202
+ fh.close()
203
+
204
+ end
205
+
206
+
207
+ def self.execute(stdout, arguments=[])
208
+ # NOTE: the option -p/--path= is given as an example, and should be replaced in your application.
209
+ options = {
210
+ :path => '~'
211
+ }
212
+ mandatory_options = %w( )
213
+ parser = OptionParser.new do |opts|
214
+ opts.banner = <<-BANNER.gsub(/^ /,'')
215
+ Generate HTML Doc for SQL
216
+
217
+ Usage: #{File.basename($0)} [options]
218
+
219
+ Options are:
220
+ BANNER
221
+ opts.separator ""
222
+ opts.on("-s", "--source=Source", String,
223
+ "The input SQL file.") { |arg| options[:source] = arg }
224
+ opts.on("-h", "--help",
225
+ "Show this help message.") { stdout.puts opts; exit }
226
+ opts.parse!(arguments)
227
+
228
+ if mandatory_options && mandatory_options.find { |option| options[option.to_sym].nil? }
229
+ stdout.puts opts; exit
230
+ end
231
+ end
232
+
233
+ source = options[:source]
234
+
235
+ # do stuff
236
+ if source
237
+ read_sql_file( source )
238
+ else
239
+ print "Must specify an input SQL file\n"
240
+ end
241
+ end
242
+ end
243
+ end
@@ -145,8 +145,8 @@ module Testgen
145
145
  # we pass 'binding' into ERb so that the template is evaluated
146
146
  # in our context so that it has access to our locals.
147
147
  prototypes = languagescanner.prototypes
148
- #erb = ERB.new( File.new( "templates/c.template" ).read )
149
- erb = ERB.new(CGIA_UT_Template::C_UT_TEMPLATE)
148
+ erb = ERB.new( File.new( File.dirname(__FILE__)+"/../../templates/ut/c.template" ).read )
149
+ #erb = ERB.new(CGIA_UT_Template::C_UT_TEMPLATE)
150
150
  template_result = erb.result( binding )
151
151
  # Add in the prefix
152
152
  template_result = "// <test_start>\n#{template_result}\n// </test_start>"
@@ -0,0 +1,4 @@
1
+ <frameset cols="20%,*">
2
+ <frame src="tables.html">
3
+ <frame name="main" src="tables.html">
4
+ </frameset>
@@ -0,0 +1,36 @@
1
+ <html><head>
2
+ <title><%= table.name %></title>
3
+ </head>
4
+ <body>
5
+ <table width=100%>
6
+ <tr>
7
+ <td width=10% nowrap valign=top><b>Table Name:</td><td><%= table.name %></td></tr>
8
+ <td width=10% nowrap valign=top><b>Description:</td><td><%= table_comment %></td></tr>
9
+ <td width=10% nowrap valign=top><b>Fields:</td><td>
10
+ <table cellspacing=1 cellpadding=0 bgcolor=#bbbbbb width=100%>
11
+ <tr>
12
+ <td width=20% nowrap valign=top><b>Name</b></td>
13
+ <td width=20% nowrap valign=top><b>Type</b></td>
14
+ <td width=20% nowrap valign=top><b>Constraints</b></td>
15
+ <td width=40% valign=top><b>Comments</b></td>
16
+ </tr>
17
+ <% table.fields.each { |field|
18
+ constraints = []
19
+ constraints.push( "Non-null" ) if ( field.not_null )
20
+ constraints.push( "Unique" ) if ( field.unique )
21
+ constraints.push( "Primary key" ) if ( field.primary_key )
22
+ %><tr>
23
+ <td bgcolor=white valign=top><%= field.name %></td>
24
+ <td bgcolor=white valign=top><%= field.type %></td>
25
+ <td bgcolor=white valign=top><%= constraints.join( ", " ) %></td>
26
+ <td bgcolor=white valign=top><%= field.comment %></td>
27
+ </tr><% } %>
28
+ </table>
29
+ </td></tr>
30
+ <% if ( relates_to.length > 0 )
31
+ rel_text = relates_to.map { |table| "<a href=\"#{table}.html\">#{table}</a>" }.join( ", " )
32
+ %><td width=10% nowrap valign=top><b>Relates To:</td>
33
+ <td valign=top><%= rel_text %></td>
34
+ </tr><% end %></table>
35
+ </body>
36
+ </html>
@@ -0,0 +1,7 @@
1
+ <html>
2
+ <body>
3
+ <% tables.each { |table| %>
4
+ <a href="<%= table.name %>.html" target="main"><%= table.name %></a><br>
5
+ <% } %>
6
+ </body>
7
+ </html>
@@ -0,0 +1,44 @@
1
+ /*
2
+ * ==========================================================================
3
+ * WARNING: This code has been generated by 'testgen'. Any modifications
4
+ * you make to it will be lost when it is regenerated.
5
+ * ==========================================================================
6
+ */
7
+ int run_tests()
8
+ {
9
+ int failed = 0;
10
+ int success = 0;
11
+ <%
12
+ prototypes.each { |proto|
13
+ name = proto.method_name
14
+ proto.tests.each { |test|
15
+ values = []
16
+ proto.arguments.each { |arg|
17
+ values.push( test.arguments[ arg.name.to_s ] )
18
+ }
19
+ args = values.join( ", " )
20
+ result = test.result
21
+ test_name = test.name
22
+ %>
23
+ if ( <%= name %>( <%= args %> ) != <%= result %> )
24
+ {
25
+ failed++;
26
+ printf( "<%= test_name %>: <%= name %>( <%= args %> ) == <%= result%> failed!\n" );
27
+ } else {
28
+ success++;
29
+ printf( "<%= test_name %>: <%= name %>( <%= args %> ) == <%= result%> passed!\n" );
30
+
31
+ }
32
+ <%
33
+ }
34
+ }
35
+ %>
36
+ printf("%d of %d (%d%%) Unit Test are passed\n", success, success+failed,success*100/(success+failed));
37
+ return 1;
38
+ }
39
+ /*
40
+ * ==========================================================================
41
+ * WARNING: This code has been generated by 'testgen'. Any modifications
42
+ * you make to it will be lost when it is regenerated.
43
+ * ==========================================================================
44
+ */
@@ -2,15 +2,24 @@ h1. cgialib
2
2
 
3
3
  h2. What
4
4
 
5
+ Import the examples in Code Generation In Action
6
+
5
7
  h2. Installing
6
8
 
7
9
  <pre syntax="ruby">sudo gem install cgialib</pre>
8
10
 
9
11
  h2. The basics
10
12
 
13
+ Generate Unit Test for C
14
+
15
+ Generate HTML Doc for SQL
11
16
 
12
17
  h2. Demonstration of usage
13
18
 
19
+ testgen -s examples/ut/mytest1.c
20
+
21
+ docgen -s examples/docgen/tables.sql
22
+
14
23
  h2. How to submit patches
15
24
 
16
25
  Read the "8 steps for fixing other people's code":http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/ and for section "8b: Submit patch to Google Groups":http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/#8b-google-groups, use the Google Group above.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cgialib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Ruan
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-11-21 00:00:00 -06:00
12
+ date: 2008-11-22 00:00:00 +08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -56,6 +56,7 @@ description: Import the examples in Code Generation In Action
56
56
  email:
57
57
  - ruanwz@gmail.com
58
58
  executables:
59
+ - docgen
59
60
  - testgen
60
61
  extensions: []
61
62
 
@@ -71,13 +72,18 @@ files:
71
72
  - PostInstall.txt
72
73
  - README.rdoc
73
74
  - Rakefile
75
+ - bin/docgen
74
76
  - bin/testgen
75
77
  - config/website.yml.sample
76
78
  - examples/ut/mytest1.c
79
+ - examples/docgen/tables.sql
80
+ - features/docgen.feature
77
81
  - features/language_parser.feature
78
82
  - features/steps/language_parser.rb
83
+ - features/steps/docgen.rb
79
84
  - features/steps/env.rb
80
85
  - lib/cgialib.rb
86
+ - lib/docgen/cli.rb
81
87
  - lib/testgen/cli.rb
82
88
  - lib/cgialib/lp.rb
83
89
  - lib/cgialib/template.rb
@@ -100,6 +106,10 @@ files:
100
106
  - spec/spec.opts
101
107
  - spec/spec_helper.rb
102
108
  - spec/testgen_cli_spec.rb
109
+ - templates/ut/c.template
110
+ - templates/docgen/index.html.template
111
+ - templates/docgen/table_page.html.template
112
+ - templates/docgen/tables.html.template
103
113
  - tasks/rspec.rake
104
114
  - website/index.html
105
115
  - website/index.txt
@@ -129,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
129
139
  requirements: []
130
140
 
131
141
  rubyforge_project: cgialib
132
- rubygems_version: 1.3.0
142
+ rubygems_version: 1.3.1
133
143
  signing_key:
134
144
  specification_version: 2
135
145
  summary: Import the examples in Code Generation In Action