funit 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,33 @@
1
+ module Funit
2
+
3
+ ##
4
+ # Fortran compiler
5
+
6
+ class Compiler
7
+
8
+ def initialize
9
+ error_message = <<-COMPILER
10
+ Fortran compiler environment variable 'FC' not set.
11
+
12
+ For example, if you had the g95 compiler:
13
+
14
+ sh: export FC=g95
15
+ csh: setenv FC g95
16
+ windows: set FC=C:\\Program Files\\g95
17
+ COMPILER
18
+ raise error_message unless ENV['FC']
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
25
+ #--
26
+ # Copyright 2006-2007 United States Government as represented by
27
+ # NASA Langley Research Center. No copyright is claimed in
28
+ # the United States under Title 17, U.S. Code. All Other Rights
29
+ # Reserved.
30
+ #
31
+ # This file is governed by the NASA Open Source Agreement.
32
+ # See License.txt for details.
33
+ #++
@@ -0,0 +1,100 @@
1
+ require 'erb'
2
+
3
+ module Funit
4
+
5
+ TEST_RUNNER = ERB.new %q{
6
+ ! TestRunner.f90 - runs fUnit test suites
7
+ !
8
+ ! <%= File.basename $0 %> generated this file on <%= Time.now %>.
9
+
10
+ program TestRunner
11
+ <%= test_suites.inject('') { |result,test_suite| result << "\n use #{test_suite}_fun" } %>
12
+
13
+ implicit none
14
+
15
+ integer :: numTests, numAsserts, numAssertsTested, numFailures
16
+
17
+ <% test_suites.each do |ts| %>
18
+ print *, ""
19
+ print *, "<%= ts %> test suite:"
20
+ call test_<%= ts %> &
21
+ ( numTests, numAsserts, numAssertsTested, numFailures )
22
+ print *, "Passed", numAssertsTested, "of", numAsserts, &
23
+ "possible asserts comprising", &
24
+ numTests-numFailures, "of", numTests, "tests."
25
+ <% end %>
26
+ print *, ""
27
+
28
+ end program TestRunner
29
+ }.gsub(/^/,' '), nil, '<>' # turn off newlines due to <%%>
30
+
31
+ def requested_modules(module_names)
32
+ if (module_names.empty?)
33
+ module_names = Dir["*.fun"].each{ |mod| mod.chomp! ".fun" }
34
+ end
35
+ module_names
36
+ end
37
+
38
+ def funit_exists?(module_name)
39
+ File.exists? "#{module_name}.fun"
40
+ end
41
+
42
+ def parse_command_line
43
+
44
+ module_names = requested_modules(ARGV)
45
+
46
+ if module_names.empty?
47
+ raise " *Error: no test suites found in this directory"
48
+ end
49
+
50
+ module_names.each do |mod|
51
+ unless funit_exists?(mod)
52
+ error_message = <<-FUNITDOESNOTEXIST
53
+ Error: could not find test suite #{mod}.fun
54
+ Test suites available in this directory:
55
+ #{requested_modules([]).join(' ')}
56
+
57
+ Usage: #{File.basename $0} [test names (w/o .fun suffix)]
58
+ FUNITDOESNOTEXIST
59
+ raise error_message
60
+ end
61
+ end
62
+
63
+ end
64
+
65
+ def write_test_runner test_suites
66
+ File.open("TestRunner.f90", "w") do |file|
67
+ file.puts TEST_RUNNER.result(binding)
68
+ end
69
+ end
70
+
71
+ def syntax_error( message, test_suite )
72
+ raise "\n *Error: #{message} [#{test_suite}.fun:#$.]\n\n"
73
+ end
74
+
75
+ def warning( message, test_suite )
76
+ $stderr.puts "\n *Warning: #{message} [#{test_suite}.fun:#$.]"
77
+ end
78
+
79
+ def compile_tests test_suites
80
+ puts "computing dependencies"
81
+ dependencies = Fortran::Dependencies.new
82
+ puts "locating associated source files and sorting for compilation"
83
+ required_sources = dependencies.required_source_files('TestRunner.f90')
84
+
85
+ puts compile = "#{ENV['FC']} #{ENV['FCFLAGS']} -o TestRunner \\\n #{required_sources.join(" \\\n ")}"
86
+
87
+ raise "Compile failed." unless system compile
88
+ end
89
+
90
+ end
91
+
92
+ #--
93
+ # Copyright 2006-2007 United States Government as represented by
94
+ # NASA Langley Research Center. No copyright is claimed in
95
+ # the United States under Title 17, U.S. Code. All Other Rights
96
+ # Reserved.
97
+ #
98
+ # This file is governed by the NASA Open Source Agreement.
99
+ # See License.txt for details.
100
+ #++
@@ -0,0 +1,197 @@
1
+ require 'funit/assertions'
2
+ require 'funit/functions'
3
+ require 'ftools' # FIXME: use fileutils
4
+
5
+ module Funit
6
+
7
+ include Assertions # FIXME
8
+
9
+ ##
10
+ # Create testsuite wrapper code
11
+
12
+ class TestSuite < File
13
+
14
+ ASSERTION_PATTERN = /Is(RealEqual|False|True|EqualWithin|Equal)\(.*\)/i
15
+ KEYWORDS = /(begin|end)(Setup|Teardown|Test)|Is(RealEqual|Equal|False|True|EqualWithin)\(.*\)/i
16
+ COMMENT_LINE = /^\s*!/
17
+
18
+ include Funit #FIXME
19
+
20
+ def initialize suite_name
21
+ @line_number = 'blank'
22
+ @suite_name = suite_name
23
+ return nil unless funit_exists?(suite_name)
24
+ File.delete(suite_name+"_fun.f90") if File.exists?(suite_name+"_fun.f90")
25
+ super(suite_name+"_fun.f90","w")
26
+ @tests, @setup, @teardown = [], [], []
27
+ top_wrapper
28
+ expand
29
+ close
30
+ end
31
+
32
+ def top_wrapper
33
+ puts <<-TOP
34
+ ! #{@suite_name}_fun.f90 - a unit test suite for #{@suite_name}.f90
35
+ !
36
+ ! #{File.basename $0} generated this file from #{@suite_name}.fun
37
+ ! at #{Time.now}
38
+
39
+ module #{@suite_name}_fun
40
+
41
+ use #{@suite_name}
42
+
43
+ implicit none
44
+
45
+ logical :: noAssertFailed
46
+
47
+ public :: test_#@suite_name
48
+
49
+ private
50
+
51
+ integer :: numTests = 0
52
+ integer :: numAsserts = 0
53
+ integer :: numAssertsTested = 0
54
+ integer :: numFailures = 0
55
+
56
+ TOP
57
+ end
58
+
59
+ def expand
60
+ funit_file = @suite_name+".fun"
61
+ $stderr.print "expanding #{funit_file}..."
62
+
63
+ funit_contents = IO.readlines(funit_file)
64
+ @funit_total_lines = funit_contents.length
65
+
66
+ while (line = funit_contents.shift) && line !~ KEYWORDS
67
+ puts line
68
+ end
69
+
70
+ funit_contents.unshift line
71
+
72
+ puts " contains\n\n"
73
+
74
+ while (line = funit_contents.shift)
75
+ case line
76
+ when COMMENT_LINE
77
+ puts line
78
+ when /beginSetup/i
79
+ add_to_setup funit_contents
80
+ when /beginTeardown/i
81
+ add_to_teardown funit_contents
82
+ when /XbeginTest\s+(\w+)/i
83
+ ignore_test($1,funit_contents)
84
+ when /beginTest\s+(\w+)/i
85
+ a_test($1,funit_contents)
86
+ when /beginTest/i
87
+ syntax_error "no name given for beginTest", @suite_name
88
+ when /end(Setup|Teardown|Test)/i
89
+ syntax_error "no matching begin#$1 for an #$&", @suite_name
90
+ when ASSERTION_PATTERN
91
+ syntax_error "#$1 assert not in a test block", @suite_name
92
+ else
93
+ puts line
94
+ end
95
+ end
96
+ $stderr.puts "done."
97
+ end
98
+
99
+ def add_to_setup funit_contents
100
+ while (line = funit_contents.shift) && line !~ /endSetup/i
101
+ @setup.push line
102
+ end
103
+ end
104
+
105
+ def add_to_teardown funit_contents
106
+ while (line = funit_contents.shift) && line !~ /endTeardown/i
107
+ @teardown.push line
108
+ end
109
+ end
110
+
111
+ def ignore_test test_name, funit_contents
112
+ warning("Ignoring test: #{test_name}", @suite_name)
113
+ line = funit_contents.shift while line !~ /endTest/i
114
+ end
115
+
116
+ def a_test test_name, funit_contents
117
+ @test_name = test_name
118
+ @tests.push test_name
119
+ syntax_error("test name #@test_name not unique",@suite_name) if (@tests.uniq!)
120
+
121
+ puts " subroutine #{test_name}\n\n"
122
+
123
+ num_of_asserts = 0
124
+
125
+ while (line = funit_contents.shift) && line !~ /endTest/i
126
+ case line
127
+ when COMMENT_LINE
128
+ puts line
129
+ when /Is(RealEqual|False|True|EqualWithin|Equal)/i
130
+ @line_number = @funit_total_lines - funit_contents.length
131
+ num_of_asserts += 1
132
+ puts send( $&.downcase!, line )
133
+ else
134
+ puts line
135
+ end
136
+ end
137
+ warning("no asserts in test", @suite_name) if num_of_asserts == 0
138
+
139
+ puts "\n numTests = numTests + 1\n\n"
140
+ puts " end subroutine #{test_name}\n\n"
141
+ end
142
+
143
+ def close
144
+ puts "\n subroutine Setup"
145
+ puts @setup
146
+ puts " noAssertFailed = .true."
147
+ puts " end subroutine Setup\n\n"
148
+
149
+ puts "\n subroutine Teardown"
150
+ puts @teardown
151
+ puts " end subroutine Teardown\n\n"
152
+
153
+ puts <<-NEXTONE
154
+
155
+ subroutine test_#{@suite_name}( nTests, nAsserts, nAssertsTested, nFailures )
156
+
157
+ integer :: nTests
158
+ integer :: nAsserts
159
+ integer :: nAssertsTested
160
+ integer :: nFailures
161
+
162
+ continue
163
+ NEXTONE
164
+
165
+ @tests.each do |test_name|
166
+ puts "\n call Setup"
167
+ puts " call #{test_name}"
168
+ puts " call Teardown"
169
+ end
170
+
171
+ puts <<-LASTONE
172
+
173
+ nTests = numTests
174
+ nAsserts = numAsserts
175
+ nAssertsTested = numAssertsTested
176
+ nFailures = numFailures
177
+
178
+ end subroutine test_#{@suite_name}
179
+
180
+ end module #{@suite_name}_fun
181
+ LASTONE
182
+ super
183
+ end
184
+
185
+ end
186
+
187
+ end
188
+
189
+ #--
190
+ # Copyright 2006-2007 United States Government as represented by
191
+ # NASA Langley Research Center. No copyright is claimed in
192
+ # the United States under Title 17, U.S. Code. All Other Rights
193
+ # Reserved.
194
+ #
195
+ # This file is governed by the NASA Open Source Agreement.
196
+ # See License.txt for details.
197
+ #++
@@ -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['FC'] = nil
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,113 @@
1
+ require 'test/unit'
2
+ require 'funit'
3
+ require 'ftools' # FIXME: migrate to fileutils
4
+
5
+ class TestFunit < Test::Unit::TestCase
6
+
7
+ include Funit # FIXME
8
+ include Funit::Assertions # FIXME
9
+
10
+ def setup
11
+ File.rm_f(*Dir["dummyunit*"])
12
+ File.rm_f(*Dir["unit*"])
13
+ File.rm_f(*Dir["ydsbe*"])
14
+ File.rm_f(*Dir["lmzd*"])
15
+ File.rm_f(*Dir["ldfdl*"])
16
+ File.rm_f(*Dir["ydsbe*"])
17
+ File.rm_f(*Dir["TestRunner*"])
18
+ File.rm_f(*Dir["a.out"])
19
+ end
20
+
21
+ def teardown
22
+ File.rm_f(*Dir["dummyunit*"])
23
+ File.rm_f(*Dir["unit*"])
24
+ File.rm_f(*Dir["ydsbe*"])
25
+ File.rm_f(*Dir["lmzd*"])
26
+ File.rm_f(*Dir["ldfdl*"])
27
+ File.rm_f(*Dir["ydsbe*"])
28
+ File.rm_f(*Dir["TestRunner*"])
29
+ File.rm_f(*Dir["a.out"])
30
+ end
31
+
32
+ def test_main_driver_compiles
33
+ write_test_runner []
34
+ assert File.exists?("TestRunner.f90")
35
+ assert system("#{ENV['FC']} TestRunner.f90")
36
+ assert File.exists?("a.out")
37
+ end
38
+
39
+ def test_is_equal
40
+ @suite_name = "dummy"
41
+ @test_name = "dummy"
42
+ @line_number = "dummy"
43
+ isequal("IsEqual(1.0,m(1,1))")
44
+ assert_equal '.not.(1.0==m(1,1))', @condition
45
+ end
46
+
47
+ def test_is_real_equal
48
+ @suite_name = "dummy"
49
+ @test_name = "dummy"
50
+ @line_number = "dummy"
51
+ isrealequal("IsRealEqual(a,b)")
52
+ ans = <<-EOF
53
+ .not.(a+2*spacing(real(a)).ge.b &
54
+ .and.a-2*spacing(real(a)).le.b)
55
+ EOF
56
+ assert_equal ans.chomp, @condition
57
+ assert_equal '"b (",b,") is not",a,"within",2*spacing(real(a))', @message
58
+ isrealequal("IsRealEqual(1.0,m(1,1))")
59
+ ans = <<-EOF
60
+ .not.(1.0+2*spacing(real(1.0)).ge.m(1,1) &
61
+ .and.1.0-2*spacing(real(1.0)).le.m(1,1))
62
+ EOF
63
+ assert_equal ans.chomp, @condition
64
+ end
65
+
66
+ def test_handles_dependency
67
+ File.open('unit.f90','w') do |f|
68
+ f.printf "module unit\n use unita, only : a\nend module unit\n"
69
+ end
70
+ File.open('unita.f90','w') do |f|
71
+ f.printf "module unita\n integer :: a = 5\nend module unita\n"
72
+ end
73
+ File.open('unit.fun','w') do |f|
74
+ f.printf "beginTest a_gets_set\n IsEqual(5, a)\nendTest\n"
75
+ end
76
+ assert_nothing_raised{run_tests}
77
+ end
78
+
79
+ def test_embedded_dependencies
80
+ File.open('unit.f90','w') do |f|
81
+ f.printf "module unit\n use unita, only : a\nend module unit\n"
82
+ end
83
+ File.open('unita.f90','w') do |f|
84
+ f.printf "module unita\n use unitb, only : b \n integer :: a = b\nend module unita\n"
85
+ end
86
+ File.open('unitb.f90','w') do |f|
87
+ f.printf "module unitb\n integer,parameter :: b = 5\nend module unitb\n"
88
+ end
89
+ File.open('unit.fun','w') do |f|
90
+ f.printf "beginTest a_gets_set\n IsEqual(5, a)\nendTest\n"
91
+ end
92
+ assert_nothing_raised{run_tests}
93
+ end
94
+
95
+ def test_requested_modules
96
+ assert_equal ["asdfga"], requested_modules(["asdfga"])
97
+ assert_equal ["asd","fga"], requested_modules(["asd","fga"])
98
+ assert requested_modules([]).empty?
99
+ modules = %w[ldfdl lmzd]
100
+ funits = modules.map{|f| f+'.fun'}.join(' ')
101
+ system "touch "+funits
102
+ assert_equal modules, requested_modules([])
103
+ end
104
+
105
+ def test_funit_exists_method
106
+ module_name = "ydsbe"
107
+ File.rm_f(module_name+".fun")
108
+ assert_equal false, funit_exists?(module_name)
109
+ system "touch "+module_name+".fun"
110
+ assert funit_exists?(module_name)
111
+ end
112
+
113
+ end