funit-12 0.12.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,211 @@
1
+ require 'funit'
2
+
3
+ module Funit
4
+
5
+ include Assertions # FIXME
6
+
7
+ ##
8
+ # Create testsuite wrapper code
9
+
10
+ class TestSuite < File
11
+
12
+ KEYWORDS = Regexp.union(/(end\s+)?(setup|teardown|test)/i,
13
+ Assertions::ASSERTION_PATTERN)
14
+ COMMENT_LINE = /^\s*!/
15
+
16
+ include Funit #FIXME
17
+
18
+ def initialize( suite_name, suite_content, wrap_with_module )
19
+ @line_number = 'blank'
20
+ @suite_name = suite_name
21
+ @suite_content = suite_content
22
+ return nil unless funit_exists?(suite_name)
23
+ File.delete(suite_name+"_fun.f90") if File.exists?(suite_name+"_fun.f90")
24
+ super(suite_name+"_fun.f90","w")
25
+ @tests, @setup, @teardown = [], [], []
26
+ header
27
+ @wrap_with_module = wrap_with_module
28
+ module_wrapper if @wrap_with_module
29
+ top_wrapper
30
+ expand
31
+ close
32
+ end
33
+
34
+ def header
35
+ puts <<-HEADER
36
+ ! #{@suite_name}_fun.f90 - a unit test suite for #{@suite_name}.f90
37
+ !
38
+ ! #{File.basename $0} generated this file from #{@suite_name}.fun
39
+
40
+ HEADER
41
+ end
42
+
43
+ def module_wrapper
44
+ puts <<-MODULE_WRAPPER
45
+ module #{@suite_name}_mod
46
+ contains
47
+ include '#@suite_name.f90'
48
+ end module #{@suite_name}_mod
49
+
50
+ MODULE_WRAPPER
51
+ end
52
+
53
+ def top_wrapper
54
+ puts <<-TOP
55
+ module #{@suite_name}_fun
56
+
57
+ use #{ @wrap_with_module ? @suite_name+'_mod' : @suite_name }
58
+
59
+ implicit none
60
+
61
+ logical :: noAssertFailed
62
+
63
+ public :: test_#@suite_name
64
+
65
+ private
66
+
67
+ integer :: numTests = 0
68
+ integer :: numAsserts = 0
69
+ integer :: numAssertsTested = 0
70
+ integer :: numFailures = 0
71
+
72
+ TOP
73
+ end
74
+
75
+ def expand
76
+ $stderr.print "expanding test suite: #{@suite_name}..."
77
+ funit_contents = @suite_content.split("\n")
78
+ @funit_total_lines = funit_contents.length
79
+
80
+ while (line = funit_contents.shift) && line !~ KEYWORDS
81
+ puts line
82
+ end
83
+
84
+ funit_contents.unshift line
85
+
86
+ puts " contains\n\n"
87
+
88
+ while (line = funit_contents.shift)
89
+ case line
90
+ when COMMENT_LINE
91
+ puts line
92
+ when /^setup/i
93
+ add_to_setup funit_contents
94
+ when /^teardown/i
95
+ add_to_teardown funit_contents
96
+ when /^Xtest\s+(\w+)/i
97
+ ignore_test($1,funit_contents)
98
+ when /^test\s+(\w+)/i
99
+ a_test($1,funit_contents)
100
+ when /^test/i
101
+ syntax_error "no name given for test", @suite_name
102
+ when /^end\s+(setup|teardown|test)/i
103
+ syntax_error "no matching #$1 for an #$&", @suite_name
104
+ when Assertions::ASSERTION_PATTERN
105
+ syntax_error "#$1 assertion not in a test block", @suite_name
106
+ else
107
+ puts line
108
+ end
109
+ end
110
+ $stderr.puts "done."
111
+ end
112
+
113
+ def add_to_setup funit_contents
114
+ while (line = funit_contents.shift) && line !~ /end\s+setup/i
115
+ @setup.push line
116
+ end
117
+ end
118
+
119
+ def add_to_teardown funit_contents
120
+ while (line = funit_contents.shift) && line !~ /end\s+teardown/i
121
+ @teardown.push line
122
+ end
123
+ end
124
+
125
+ def ignore_test test_name, funit_contents
126
+ warning("Ignoring test: #{test_name}", @suite_name)
127
+ line = funit_contents.shift while line !~ /end\s+Test/i
128
+ end
129
+
130
+ def a_test test_name, funit_contents
131
+ @test_name = test_name
132
+ @tests.push test_name
133
+ syntax_error("test name #@test_name not unique",@suite_name) if (@tests.uniq!)
134
+
135
+ puts " subroutine #{test_name}\n\n"
136
+
137
+ num_of_asserts = 0
138
+
139
+ while (line = funit_contents.shift) && line !~ /end\s+test/i
140
+ case line
141
+ when COMMENT_LINE
142
+ puts line
143
+ when Assertions::ASSERTION_PATTERN
144
+ @line_number = @funit_total_lines - funit_contents.length
145
+ num_of_asserts += 1
146
+ puts send( $1.downcase, line )
147
+ else
148
+ puts line
149
+ end
150
+ end
151
+ warning("no asserts in test", @suite_name) if num_of_asserts == 0
152
+
153
+ puts "\n numTests = numTests + 1\n\n"
154
+ puts " end subroutine #{test_name}\n\n"
155
+ end
156
+
157
+ def close
158
+ puts "\n subroutine funit_setup"
159
+ puts @setup
160
+ puts " noAssertFailed = .true."
161
+ puts " end subroutine funit_setup\n\n"
162
+
163
+ puts "\n subroutine funit_teardown"
164
+ puts @teardown
165
+ puts " end subroutine funit_teardown\n\n"
166
+
167
+ puts <<-NEXTONE
168
+
169
+ subroutine test_#{@suite_name}( nTests, nAsserts, nAssertsTested, nFailures )
170
+
171
+ integer :: nTests
172
+ integer :: nAsserts
173
+ integer :: nAssertsTested
174
+ integer :: nFailures
175
+
176
+ continue
177
+ NEXTONE
178
+
179
+ @tests.each do |test_name|
180
+ puts "\n call funit_setup"
181
+ puts " call #{test_name}"
182
+ puts " call funit_teardown"
183
+ end
184
+
185
+ puts <<-LASTONE
186
+
187
+ nTests = numTests
188
+ nAsserts = numAsserts
189
+ nAssertsTested = numAssertsTested
190
+ nFailures = numFailures
191
+
192
+ end subroutine test_#{@suite_name}
193
+
194
+ end module #{@suite_name}_fun
195
+ LASTONE
196
+ super
197
+ end
198
+
199
+ end
200
+
201
+ end
202
+
203
+ #--
204
+ # Copyright 2006-2007 United States Government as represented by
205
+ # NASA Langley Research Center. No copyright is claimed in
206
+ # the United States under Title 17, U.S. Code. All Other Rights
207
+ # Reserved.
208
+ #
209
+ # This file is governed by the NASA Open Source Agreement.
210
+ # See License.txt for details.
211
+ #++
data/pitch/slides.tex ADDED
@@ -0,0 +1,138 @@
1
+ % pdflatex slides
2
+
3
+ \documentclass[landscape]{slides}
4
+ \usepackage{url}
5
+ \pagestyle{empty}
6
+ \hoffset 1in
7
+ \begin{document}
8
+ \begin{slide}
9
+ \begin{center}
10
+ {\bf\Large F90 Testkit}\\
11
+ \vspace{0.5in}
12
+ \begin{minipage}{6.5in}
13
+ {\bf Goal:} to make Fortran~90 unit/\-mobility/\-developer testing
14
+ as painless as possible.
15
+ \end{minipage}
16
+ \end{center}
17
+ \end{slide}
18
+ \begin{slide}
19
+ \begin{center}
20
+ {\bf\Large Why write tests?}\\
21
+ \vspace{0.5in}
22
+ \begin{minipage}[t]{3in}
23
+ \begin{itemize}
24
+ \item Shame
25
+ \item Embarrassment
26
+ \item Speed
27
+ \item Confidence
28
+ \end{itemize}
29
+ \end{minipage}
30
+ \begin{minipage}[t]{3in}
31
+ \begin{itemize}
32
+ \item Trust
33
+ \item Change
34
+ \item Documentation
35
+ \end{itemize}
36
+ \end{minipage}
37
+ \end{center}
38
+ \end{slide}
39
+ \begin{slide}
40
+ \begin{center}
41
+ {\bf\Large Why write tests first?}\\
42
+ \vspace{0.5in}
43
+ \begin{minipage}{3in}
44
+ \begin{itemize}
45
+ \item Tests get written
46
+ \item Succinctness
47
+ \item Clarity
48
+ \item Closure
49
+ \end{itemize}
50
+ \end{minipage}\\
51
+ \vspace{1in}
52
+ \begin{minipage}{5.7in}\raggedright
53
+ ``No code should be written or changed unless there is a failing
54
+ test.''
55
+ \end{minipage}
56
+ \end{center}
57
+ \end{slide}
58
+ \begin{slide}
59
+ \begin{center}
60
+ {\bf\Large How do I add tests to legacy code?}\\
61
+ \vspace{0.5in}
62
+ \begin{minipage}{6in}
63
+ \begin{itemize}
64
+ \item Fixing Bugs
65
+ \begin{itemize}
66
+ \item write test for bug {\small (which fails)}
67
+ \item write code to satisfy failing test
68
+ \item write tests/code for similar cases
69
+ \end{itemize}
70
+ \vspace{8pt}
71
+ \item Adding Features
72
+ \begin{itemize}
73
+ \item write test for feature {\small (which better fail)}
74
+ \item write code to satisfy failing test
75
+ \end{itemize}
76
+ \vspace{8pt}
77
+ \item Refactoring ``Bad Smells''
78
+ \begin{itemize}
79
+ \item write tests to cover existing code
80
+ \item update/add tests for new structure
81
+ \item change code to satisfy failing tests
82
+ \end{itemize}
83
+ \end{itemize}
84
+ \end{minipage}
85
+ \end{center}
86
+ \end{slide}
87
+ \begin{slide}
88
+ \begin{center}
89
+ {\bf\Large Crazy enough to learn more?}\\
90
+ \vspace{0.5in}
91
+ \begin{minipage}{6in}
92
+ \begin{itemize}
93
+ \item \url{http://c2.com/cgi/wiki?UnitTests}\\[-10pt]
94
+ \item \url{http://xprogramming.com/software.htm}
95
+ \end{itemize}
96
+ \end{minipage}
97
+ \end{center}
98
+ \end{slide}
99
+ \begin{slide}
100
+ \begin{center}
101
+ {\bf\Large Want to try F90 testkit?}\\
102
+ \vspace{0.5in}
103
+ \begin{minipage}{9in}
104
+ \begin{itemize}
105
+ \item Have your SA install Ruby {\small(or install it yourself)}\\[5pt]
106
+ \hspace*{1em}\url{http://www.ruby-lang.org/}\\[5pt]
107
+ \item Check out the FTK repository\\[5pt]
108
+ \hspace*{1em}\verb+cvs -d :pserver:[username]@abnode3:/usr/local/cvsroot \+\\
109
+ \hspace*{1em}\verb+checkout -P FTK+\\[5pt]
110
+ where \verb+[username]+ is your CVS username on \verb+abnode3+
111
+ \end{itemize}
112
+ \end{minipage}
113
+ \end{center}
114
+ \end{slide}
115
+ \begin{slide}
116
+ \begin{center}
117
+ {\bf\Large Who does what?}\\
118
+ \vspace{0.5in}
119
+ {\bf You:}
120
+ \begin{minipage}[t]{6.5in}\raggedright
121
+ \begin{enumerate}
122
+ \item Create testsuite file, e.g., \verb+RoutineTS.ftk+
123
+ \item Write test in Fortran with embedded assert macros, .e.g,
124
+ \verb+IsTrue(x>2)+
125
+ \item Run testsuite {\small (it should fail)}
126
+ \item Write \verb+Routine.f90+ to satisfy test
127
+ \end{enumerate}
128
+ \vspace{10pt}
129
+ Repeat steps 2, 3, and 4 until your objective is met.
130
+ \end{minipage}\\
131
+ \vspace{0.8in}
132
+ {\bf It:}
133
+ \begin{minipage}[t]{6in}\raggedright
134
+ Translates, compiles, links, and runs tests.
135
+ \end{minipage}
136
+ \end{center}
137
+ \end{slide}
138
+ \end{document}
@@ -0,0 +1,16 @@
1
+ require 'test/unit'
2
+ require 'funit/compiler'
3
+
4
+ class TestCompiler < Test::Unit::TestCase
5
+
6
+ def test_no_environment_compiler_name
7
+ begin
8
+ orig_FC = ENV['FC']
9
+ ENV.delete 'FC'
10
+ assert_raises(RuntimeError) {Funit::Compiler.new}
11
+ ensure
12
+ ENV['FC'] = orig_FC
13
+ end
14
+ end
15
+
16
+ end
@@ -0,0 +1,10 @@
1
+ require 'test/unit'
2
+ require 'funit/functions'
3
+
4
+ class TestFunctions < Test::Unit::TestCase
5
+
6
+ def test_something
7
+ # FIXME
8
+ end
9
+
10
+ end
@@ -0,0 +1,125 @@
1
+ require 'test/unit'
2
+ require 'funit'
3
+ require 'ftools' # FIXME: migrate to fileutils
4
+
5
+ class TestFunit < Test::Unit::TestCase
6
+
7
+ alias_method :tu_assert_equal, :assert_equal # avoid collision with test/unit
8
+
9
+ include Funit # FIXME
10
+ include Funit::Assertions # FIXME
11
+
12
+ def setup
13
+ File.rm_f(*Dir["dummyunit*"])
14
+ File.rm_f(*Dir["unit*"])
15
+ File.rm_f(*Dir["another*"])
16
+ File.rm_f(*Dir["ydsbe*"])
17
+ File.rm_f(*Dir["lmzd*"])
18
+ File.rm_f(*Dir["ldfdl*"])
19
+ File.rm_f(*Dir["ydsbe*"])
20
+ File.rm_f(*Dir["*TestRunner*"])
21
+ end
22
+
23
+ def teardown
24
+ File.rm_f(*Dir["dummyunit*"])
25
+ File.rm_f(*Dir["unit*"])
26
+ File.rm_f(*Dir["another*"])
27
+ File.rm_f(*Dir["ydsbe*"])
28
+ File.rm_f(*Dir["lmzd*"])
29
+ File.rm_f(*Dir["ldfdl*"])
30
+ File.rm_f(*Dir["ydsbe*"])
31
+ File.rm_f(*Dir["*TestRunner*"])
32
+ end
33
+
34
+ def test_empty_test_runner_created_and_compilable
35
+ write_test_runner []
36
+ assert File.exists?("TestRunner.f90"), 'TestRunner.f90 not created.'
37
+ compile_tests []
38
+ assert File.exists?("makeTestRunner"), 'makeTestRunner.f90 not created.'
39
+ assert system("make -f makeTestRunner"), 'make -f makeTestRunner failed.'
40
+ assert File.exists?("TestRunner"), 'TestRunner executable not created.'
41
+ end
42
+
43
+ def test_is_equal
44
+ @suite_name = "dummy"
45
+ @test_name = "dummy"
46
+ @line_number = "dummy"
47
+ assert_equal("AssertEqual(1.0,m(1,1))")
48
+ tu_assert_equal '.not.(1.0==m(1,1))', @condition
49
+ end
50
+
51
+ def test_is_real_equal
52
+ @suite_name = "dummy"
53
+ @test_name = "dummy"
54
+ @line_number = "dummy"
55
+ assert_real_equal("AssertRealEqual(a,b)")
56
+ ans = <<-EOF
57
+ .not.( (a &\n +2*spacing(real(a)) ) &\n .ge. &\n (b) &\n .and. &\n (a &\n -2*spacing(real(a)) ) &\n .le. &\n (b) )
58
+ EOF
59
+ tu_assert_equal ans.chomp, @condition
60
+ tu_assert_equal %|"b (", &\n b, &\n ") is not", &\n a,&\n "within", &\n 2*spacing(real(a))|, @message
61
+ assert_real_equal("AssertRealEqual(1.0,m(1,1))")
62
+ ans = <<-EOF
63
+ .not.( (1.0 &\n +2*spacing(real(1.0)) ) &\n .ge. &\n (m(1,1)) &\n .and. &\n (1.0 &\n -2*spacing(real(1.0)) ) &\n .le. &\n (m(1,1)) )
64
+ EOF
65
+ tu_assert_equal ans.chomp, @condition
66
+ end
67
+
68
+ def test_should_accommodate_use_dependency_at_least_one_level_deep
69
+ File.open('unit.f90','w') do |f|
70
+ f.puts "module unit\n use another, only : a\nend module unit"
71
+ end
72
+ File.open('another.f90','w') do |f|
73
+ f.puts "module another\n integer :: a = 5\nend module another"
74
+ end
75
+ File.open('unit.fun','w') do |f|
76
+ f.puts "test_suite unit\ntest a_gets_set\nAssert_Equal(5,a)\nend test\nend test_suite"
77
+ end
78
+ assert_nothing_raised{run_tests}
79
+ end
80
+
81
+ def test_should_accommodate_doubly_embedded_use_dependencies
82
+ File.open('unit.f90','w') do |f|
83
+ f.puts "module unit\n use unita, only : a\nend module unit"
84
+ end
85
+ File.open('unita.f90','w') do |f|
86
+ f.puts "module unita\n use unitb, only : b\n integer :: a = b\nend module unita"
87
+ end
88
+ File.open('unitb.f90','w') do |f|
89
+ f.puts "module unitb\n integer, parameter :: b = 5\nend module unitb"
90
+ end
91
+ File.open('unit.fun','w') do |f|
92
+ f.puts "begin test_suite unit\ntest a_gets_set\n Assert_Equal(5, a)\nend test\nend test_suite"
93
+ end
94
+ assert_nothing_raised{run_tests}
95
+ end
96
+
97
+ def test_should_accommodate_cap_F_extensions
98
+ File.open('unit.F90','w') do |f|
99
+ f.puts "module unit\n integer :: a = 1\nend module unit"
100
+ end
101
+ File.open('unit.fun','w') do |f|
102
+ f.puts "begin test_suite unit\ntest a_gets_set\n Assert_Equal(1, a)\nend test\nend test_suite"
103
+ end
104
+ assert_nothing_raised{run_tests}
105
+ end
106
+
107
+ def test_requested_modules
108
+ tu_assert_equal ["asdfga"], requested_modules(["asdfga"])
109
+ tu_assert_equal ["asd","fga"], requested_modules(["asd","fga"])
110
+ assert requested_modules([]).empty?
111
+ modules = %w[ldfdl lmzd]
112
+ funits = modules.map{|f| f+'.fun'}.join(' ')
113
+ system "touch "+funits
114
+ tu_assert_equal modules, requested_modules([])
115
+ end
116
+
117
+ def test_funit_exists_method
118
+ module_name = "ydsbe"
119
+ File.rm_f(module_name+".fun")
120
+ tu_assert_equal false, funit_exists?(module_name)
121
+ system "touch "+module_name+".fun"
122
+ assert funit_exists?(module_name)
123
+ end
124
+
125
+ end