funit-12 0.12.1

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