cgialib 0.0.2 → 0.0.3

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.
@@ -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