cgialib 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,210 @@
1
+ require 'optparse'
2
+ # Bring in 'ftools' for File.copy
3
+ require "ftools"
4
+ # Bring in REXML and ERb
5
+ require "rexml/document"
6
+ require "erb"
7
+ module Testgen
8
+ include LanguageParser
9
+ class PrototypeWithTests < Prototype
10
+ # initialize()
11
+ #
12
+ # Initializes the object
13
+ def initialize()
14
+ # Initialize the base class
15
+ super()
16
+ # Create the array of tests
17
+ @tests = []
18
+ end
19
+ attr_reader :tests # The array of tests
20
+ # add_tests( tests )
21
+ #
22
+ # tests - An array of TestData objects
23
+ #
24
+ # Adds an array of tests to the prototype
25
+ def add_tests( tests )
26
+ tests.each { |test| @tests.push( test ); }
27
+ end
28
+ end
29
+ # class : TestData
30
+ #
31
+ # Objects of type TestData hold the data for a single test
32
+ class TestData
33
+ # initialize()
34
+ #
35
+ # Constructs the TestData object
36
+ def initialize()
37
+ @name = ""
38
+ @result = ""
39
+ @arguments = {}
40
+ end
41
+ attr_accessor :name # The name of the test
42
+ attr_accessor :result # The expected result
43
+ attr_reader :arguments # The test data (a hash)
44
+ # add_argument( name, value )
45
+ #
46
+ # name - The name of the argument
47
+ # value - The test data value
48
+ #
49
+ # This adds data to the test
50
+ def add_argument( name, value )
51
+ @arguments[ name ] = value
52
+ end
53
+ end
54
+
55
+ class CLI
56
+ include LanguageParser
57
+ # parse_data( text )
58
+ #
59
+ # text - The text of the comment
60
+ #
61
+ # This builds a TestData object from a text string
62
+ def self.parse_data( text )
63
+ begin
64
+ # Create the new test data
65
+ data = TestData.new()
66
+ # Parse the XML of the comment
67
+ doc = REXML::Document.new( text )
68
+ # Get the result and name
69
+ data.result = doc.root.attributes[ 'result' ]
70
+ data.name = doc.root.attributes[ 'name' ]
71
+ # Get the test data
72
+ doc.root.elements.each { |elem|
73
+ data.add_argument( elem.name, elem.text.strip )
74
+ }
75
+ # Return the new TestData object
76
+ data
77
+ rescue
78
+ nil
79
+ end
80
+ end
81
+ # find_tests( comments )
82
+ #
83
+ # comments - The array of comments returned from the Prototype object
84
+ #
85
+ # This finds all of the tests in all of the comments and returns
86
+ # an array of TestData objects. One for each test.
87
+ def self.find_tests( comments )
88
+ tests = []
89
+ # Iterate through the comments
90
+ comments.each { |comment|
91
+ # Search for the test data block XML
92
+ found = comment.to_s.scan( /(<test.*?<\/test>)/ )
93
+ # If we found some then use them to create the TestData objects
94
+ if ( found )
95
+ found.each { |items|
96
+ data = parse_data( items[0] )
97
+ tests.push( data ) if ( data )
98
+ }
99
+ end
100
+ }
101
+ # Return the comments
102
+ tests
103
+ end
104
+ # generate_tests( file_name )
105
+ #
106
+ # file_name - The name of the file to scan and alter
107
+ #
108
+ # This generates test case running code from test case comments around
109
+ # the function prototypes.
110
+ def self.generate_tests( file_name )
111
+ # Read the file contents
112
+ fh = File.open( file_name )
113
+ c_text = fh.read()
114
+ fh.close()
115
+ # Tokenize the file
116
+ tokenizer = CTokenizer.new( )
117
+ tokenizer.parse( c_text )
118
+ # Build the language scanner
119
+ languagescanner = CLanguageScanner.new()
120
+ # Use our prototype class when prototypes are built instead
121
+ # of the base class
122
+ languagescanner.prototypeClass = PrototypeWithTests
123
+ # Get the prototypes
124
+ languagescanner.parse( tokenizer.tokens )
125
+ # Iterate through the prototypes and turn the comments
126
+ # into tests
127
+ count = 0
128
+ languagescanner.prototypes.each { |proto|
129
+ # Parse the comments into tests and add them
130
+ tests = find_tests( proto.comments )
131
+ proto.add_tests( tests )
132
+ # Create unique names for the tests that don't
133
+ # have them
134
+ index = 1
135
+ proto.tests.each { |item|
136
+ name = "#{proto.method_name}_#{index}"
137
+ item.name = name unless ( item.name )
138
+ index += 1
139
+ count += 1
140
+ }
141
+ }
142
+
143
+ # Create the testing code by calling the template. The
144
+ # templates reference 'prototypes'. They can do this because
145
+ # we pass 'binding' into ERb so that the template is evaluated
146
+ # in our context so that it has access to our locals.
147
+ prototypes = languagescanner.prototypes
148
+ #erb = ERB.new( File.new( "templates/c.template" ).read )
149
+ erb = ERB.new(CGIA_UT_Template::C_UT_TEMPLATE)
150
+ template_result = erb.result( binding )
151
+ # Add in the prefix
152
+ template_result = "// <test_start>\n#{template_result}\n// </test_start>"
153
+ # Backup the original file
154
+ File.copy file_name, "#{file_name}.bak"
155
+ # Insert the new template result
156
+ if ( c_text =~ /\/\/ <test_start>.*?\/\/ <\/test_start>/m )
157
+ c_text.sub!( /\/\/ <test_start>.*?\/\/ <\/test_start>/m, template_result )
158
+ else
159
+ c_text += template_result
160
+ end
161
+ # Output the finished code
162
+ File.open( file_name, "w" ).write( c_text )
163
+ # Tell the user what we did
164
+ print "#{file_name}: #{count} tests found\n"
165
+ end
166
+ def self.execute(stdout, arguments=[])
167
+ # NOTE: the option -p/--path= is given as an example, and should be replaced in your application.
168
+ options = {
169
+ :path => '~'
170
+ }
171
+ mandatory_options = %w( )
172
+ parser = OptionParser.new do |opts|
173
+ opts.banner = <<-BANNER.gsub(/^ /,'')
174
+ This application is wonderful because...
175
+
176
+ Usage: #{File.basename($0)} [options]
177
+
178
+ Options are:
179
+ BANNER
180
+ opts.separator ""
181
+ opts.on("-p", "--path=PATH", String,
182
+ "This is a sample message.",
183
+ "For multiple lines, add more strings.",
184
+ "Default: ~") { |arg| options[:path] = arg }
185
+ opts.on("-s", "--source=Source", String,
186
+ "The source file.") { |arg| options[:source] = arg }
187
+ opts.on("-t", "--template=Template", String,
188
+ "The template file for the Unit Test.") { |arg| options[:template] = arg }
189
+ opts.on("-h", "--help",
190
+ "Show this help message.") { stdout.puts opts; exit }
191
+ opts.parse!(arguments)
192
+
193
+ if mandatory_options && mandatory_options.find { |option| options[option.to_sym].nil? }
194
+ stdout.puts opts; exit
195
+ end
196
+ end
197
+
198
+ path = options[:path]
199
+ source = options[:source]
200
+ template = options[:template]
201
+
202
+ # do stuff
203
+ if source
204
+ generate_tests( source )
205
+ else
206
+ print "Must specify an input C file\n"
207
+ end
208
+ end
209
+ end
210
+ end
data/script/console ADDED
@@ -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/cgialib.rb'}"
9
+ puts "Loading cgialib gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -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)
data/script/generate ADDED
@@ -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/generate'
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::Generate.new.run(ARGV)
data/script/txt2html ADDED
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ GEM_NAME = 'cgialib' # what ppl will type to install your gem
4
+ RUBYFORGE_PROJECT = 'cgialib'
5
+
6
+ require 'rubygems'
7
+ begin
8
+ require 'newgem'
9
+ require 'rubyforge'
10
+ rescue LoadError
11
+ puts "\n\nGenerating the website requires the newgem RubyGem"
12
+ puts "Install: gem install newgem\n\n"
13
+ exit(1)
14
+ end
15
+ require 'redcloth'
16
+ require 'syntax/convertors/html'
17
+ require 'erb'
18
+ require File.dirname(__FILE__) + "/../lib/#{GEM_NAME}.rb"
19
+
20
+ version = Cgialib::VERSION
21
+ download = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
22
+
23
+ def rubyforge_project_id
24
+ RubyForge.new.autoconfig["group_ids"][RUBYFORGE_PROJECT]
25
+ end
26
+
27
+ class Fixnum
28
+ def ordinal
29
+ # teens
30
+ return 'th' if (10..19).include?(self % 100)
31
+ # others
32
+ case self % 10
33
+ when 1: return 'st'
34
+ when 2: return 'nd'
35
+ when 3: return 'rd'
36
+ else return 'th'
37
+ end
38
+ end
39
+ end
40
+
41
+ class Time
42
+ def pretty
43
+ return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
44
+ end
45
+ end
46
+
47
+ def convert_syntax(syntax, source)
48
+ return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
49
+ end
50
+
51
+ if ARGV.length >= 1
52
+ src, template = ARGV
53
+ template ||= File.join(File.dirname(__FILE__), '/../website/template.html.erb')
54
+ else
55
+ puts("Usage: #{File.split($0).last} source.txt [template.html.erb] > output.html")
56
+ exit!
57
+ end
58
+
59
+ template = ERB.new(File.open(template).read)
60
+
61
+ title = nil
62
+ body = nil
63
+ File.open(src) do |fsrc|
64
+ title_text = fsrc.readline
65
+ body_text_template = fsrc.read
66
+ body_text = ERB.new(body_text_template).result(binding)
67
+ syntax_items = []
68
+ body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
69
+ ident = syntax_items.length
70
+ element, syntax, source = $1, $2, $3
71
+ syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
72
+ "syntax-temp-#{ident}"
73
+ }
74
+ title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
75
+ body = RedCloth.new(body_text).to_html
76
+ body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
77
+ end
78
+ stat = File.stat(src)
79
+ created = stat.ctime
80
+ modified = stat.mtime
81
+
82
+ $stdout << template.result(binding)
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ # Time to add your specs!
4
+ # http://rspec.info/
5
+ describe "Place your specs here" do
6
+
7
+ it "find this spec in spec directory" do
8
+ violated "Be sure to write your specs"
9
+ end
10
+
11
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,10 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+
9
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
10
+ require 'cgialib'
@@ -0,0 +1,15 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'testgen/cli'
3
+
4
+ describe Testgen::CLI, "execute" do
5
+ before(:each) do
6
+ @stdout_io = StringIO.new
7
+ Testgen::CLI.execute(@stdout_io, [])
8
+ @stdout_io.rewind
9
+ @stdout = @stdout_io.read
10
+ end
11
+
12
+ it "should do something" do
13
+ @stdout.should_not =~ /To update this executable/
14
+ end
15
+ end
data/tasks/rspec.rake ADDED
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require 'spec'
6
+ end
7
+ begin
8
+ require 'spec/rake/spectask'
9
+ rescue LoadError
10
+ puts <<-EOS
11
+ To use rspec for testing you must install rspec gem:
12
+ gem install rspec
13
+ EOS
14
+ exit(0)
15
+ end
16
+
17
+ desc "Run the specs under spec/models"
18
+ Spec::Rake::SpecTask.new do |t|
19
+ t.spec_opts = ['--options', "spec/spec.opts"]
20
+ t.spec_files = FileList['spec/**/*_spec.rb']
21
+ end
@@ -0,0 +1,86 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <link rel="stylesheet" href="stylesheets/screen.css" type="text/css" media="screen" />
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
+ <title>
8
+ cgialib
9
+ </title>
10
+ <script src="javascripts/rounded_corners_lite.inc.js" type="text/javascript"></script>
11
+ <style>
12
+
13
+ </style>
14
+ <script type="text/javascript">
15
+ window.onload = function() {
16
+ settings = {
17
+ tl: { radius: 10 },
18
+ tr: { radius: 10 },
19
+ bl: { radius: 10 },
20
+ br: { radius: 10 },
21
+ antiAlias: true,
22
+ autoPad: true,
23
+ validTags: ["div"]
24
+ }
25
+ var versionBox = new curvyCorners(settings, document.getElementById("version"));
26
+ versionBox.applyCornersToAll();
27
+ }
28
+ </script>
29
+ </head>
30
+ <body>
31
+ <div id="main">
32
+
33
+ <h1>cgialib</h1>
34
+ <div class="sidebar">
35
+ <div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/cgialib"; return false'>
36
+ <p>Get Version</p>
37
+ <a href="http://rubyforge.org/projects/cgialib" class="numbers">0.0.1</a>
38
+ </div>
39
+ </div>
40
+ <h2>What</h2>
41
+ <h2>Installing</h2>
42
+ <p><pre class='syntax'><span class="ident">sudo</span> <span class="ident">gem</span> <span class="ident">install</span> <span class="ident">cgialib</span></pre></p>
43
+ <h2>The basics</h2>
44
+ <h2>Demonstration of usage</h2>
45
+ <h2>Forum</h2>
46
+ <p><a href="http://groups.google.com/group/cgialib">http://groups.google.com/group/cgialib</a></p>
47
+ <p><span class="caps">TODO</span> &#8211; create Google Group &#8211; cgialib</p>
48
+ <h2>How to submit patches</h2>
49
+ <p>Read the <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/">8 steps for fixing other people&#8217;s code</a> and for section <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/#8b-google-groups">8b: Submit patch to Google Groups</a>, use the Google Group above.</p>
50
+ <p><span class="caps">TODO</span> &#8211; pick <span class="caps">SVN</span> or Git instructions</p>
51
+ <p>The trunk repository is <code>svn://rubyforge.org/var/svn/cgialib/trunk</code> for anonymous access.</p>
52
+ <p><span class="caps">OOOORRRR</span></p>
53
+ <p>You can fetch the source from either:</p>
54
+ <ul>
55
+ <li>rubyforge: <span class="caps">MISSING</span> IN <span class="caps">ACTION</span></li>
56
+ </ul>
57
+ <p><span class="caps">TODO</span> &#8211; You can not created a RubyForge project, OR have not run <code>rubyforge config</code><br />
58
+ yet to refresh your local rubyforge data with this projects&#8217; id information.</p>
59
+ <p>When you do this, this message will magically disappear!</p>
60
+ <p>Or you can hack website/index.txt and make it all go away!!</p>
61
+ <ul>
62
+ <li>github: <a href="http://github.com/ruanwz/cgialib/tree/master">http://github.com/ruanwz/cgialib/tree/master</a></li>
63
+ </ul>
64
+ <pre>git clone git://github.com/ruanwz/cgialib.git</pre>
65
+ <ul>
66
+ <li>gitorious: <a href="git://gitorious.org/cgialib/mainline.git">git://gitorious.org/cgialib/mainline.git</a></li>
67
+ </ul>
68
+ <pre>git clone git://gitorious.org/cgialib/mainline.git</pre>
69
+ <h3>Build and test instructions</h3>
70
+ <pre>cd cgialib
71
+ rake test
72
+ rake install_gem</pre>
73
+ <h2>License</h2>
74
+ <p>This code is free to use under the terms of the <span class="caps">MIT</span> license.</p>
75
+ <h2>Contact</h2>
76
+ <p>Comments are welcome. Send an email to <a href="mailto:FIXME"><span class="caps">FIXME</span> full name</a> email via the <a href="http://groups.google.com/group/cgialib">forum</a></p>
77
+ <p class="coda">
78
+ <a href="FIXME email">FIXME full name</a>, 19th November 2008<br>
79
+ Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
80
+ </p>
81
+ </div>
82
+
83
+ <!-- insert site tracking codes here, like Google Urchin -->
84
+
85
+ </body>
86
+ </html>
data/website/index.txt ADDED
@@ -0,0 +1,79 @@
1
+ h1. cgialib
2
+
3
+
4
+ h2. What
5
+
6
+
7
+ h2. Installing
8
+
9
+ <pre syntax="ruby">sudo gem install cgialib</pre>
10
+
11
+ h2. The basics
12
+
13
+
14
+ h2. Demonstration of usage
15
+
16
+
17
+
18
+ h2. Forum
19
+
20
+ "http://groups.google.com/group/cgialib":http://groups.google.com/group/cgialib
21
+
22
+ TODO - create Google Group - cgialib
23
+
24
+ h2. How to submit patches
25
+
26
+ 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.
27
+
28
+ TODO - pick SVN or Git instructions
29
+
30
+ The trunk repository is <code>svn://rubyforge.org/var/svn/cgialib/trunk</code> for anonymous access.
31
+
32
+ OOOORRRR
33
+
34
+ You can fetch the source from either:
35
+
36
+ <% if rubyforge_project_id %>
37
+
38
+ * rubyforge: "http://rubyforge.org/scm/?group_id=<%= rubyforge_project_id %>":http://rubyforge.org/scm/?group_id=<%= rubyforge_project_id %>
39
+
40
+ <pre>git clone git://rubyforge.org/cgialib.git</pre>
41
+
42
+ <% else %>
43
+
44
+ * rubyforge: MISSING IN ACTION
45
+
46
+ TODO - You can not created a RubyForge project, OR have not run <code>rubyforge config</code>
47
+ yet to refresh your local rubyforge data with this projects' id information.
48
+
49
+ When you do this, this message will magically disappear!
50
+
51
+ Or you can hack website/index.txt and make it all go away!!
52
+
53
+ <% end %>
54
+
55
+ * github: "http://github.com/ruanwz/cgialib/tree/master":http://github.com/ruanwz/cgialib/tree/master
56
+
57
+ <pre>git clone git://github.com/ruanwz/cgialib.git</pre>
58
+
59
+
60
+
61
+ * gitorious: "git://gitorious.org/cgialib/mainline.git":git://gitorious.org/cgialib/mainline.git
62
+
63
+ <pre>git clone git://gitorious.org/cgialib/mainline.git</pre>
64
+
65
+ h3. Build and test instructions
66
+
67
+ <pre>cd cgialib
68
+ rake test
69
+ rake install_gem</pre>
70
+
71
+
72
+ h2. License
73
+
74
+ This code is free to use under the terms of the MIT license.
75
+
76
+ h2. Contact
77
+
78
+ Comments are welcome. Send an email to "FIXME full name":mailto:FIXME email via the "forum":http://groups.google.com/group/cgialib
79
+