funit 0.11.1 → 0.12.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.
- checksums.yaml +7 -0
- data/{History.txt → History.rdoc} +26 -0
- data/Manifest.txt +3 -2
- data/{README.txt → README.rdoc} +14 -13
- data/Rakefile +6 -9
- data/bin/funit +46 -47
- data/examples/StopWatch/StopWatch.fun +8 -7
- data/lib/funit.rb +21 -18
- data/lib/funit/c_tools.rb +205 -0
- data/lib/funit/functions.rb +10 -5
- data/lib/funit/testsuite.rb +1 -3
- data/test/test_funit.rb +31 -27
- data/test/test_testsuite.rb +2 -2
- metadata +98 -61
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d0c1b7e86685588f2c956c94b7db107ad3e5b701
|
4
|
+
data.tar.gz: d67d36f40691f235e6245f4505bad8dcb8400550
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 737765bd524762b7e426851d1cb0108b8d8a0e354c6de3868b006390754fcbb9092246e230436d675e17814679f9074a49c8a8248410c09226591626039334ce
|
7
|
+
data.tar.gz: 86fc8af4c54a5d62ff3c9412472cc46a8516b97b7d68faf707032155cb0b70fc5eb333699b29d3eaa4ce2feb933b02b05a42423ea381eb968a7e03047b710a2a
|
@@ -1,3 +1,29 @@
|
|
1
|
+
=== 0.12.3 / 2016-2-05
|
2
|
+
|
3
|
+
* 1 minor enhancement
|
4
|
+
* Enable funit to track inlined function dependencies in makefile
|
5
|
+
|
6
|
+
* 1 bug fix
|
7
|
+
* reverting back to gem fortran, since access to original gem has been restored
|
8
|
+
|
9
|
+
=== 0.12.2 / 2016-1-20
|
10
|
+
|
11
|
+
* 1 minor enhancement
|
12
|
+
* Enable funit to read files with .F90 extension
|
13
|
+
|
14
|
+
=== 0.12.1 / 2016-1-19
|
15
|
+
|
16
|
+
* 1 bug fix
|
17
|
+
* Changed required gem fortran -> fortran_dependencies to track forked gem of "fortran"
|
18
|
+
|
19
|
+
=== 0.12.0 / 2016-1-14
|
20
|
+
|
21
|
+
* major enhancement
|
22
|
+
* Allow user to specify C/C++ code needed by fortran unit test
|
23
|
+
|
24
|
+
* minor enhancement
|
25
|
+
* Refactored option input using optparse
|
26
|
+
|
1
27
|
=== 0.11.1 / 2009-11-01
|
2
28
|
|
3
29
|
* 1 bug fix
|
data/Manifest.txt
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
History.
|
1
|
+
History.rdoc
|
2
2
|
License.txt
|
3
3
|
Manifest.txt
|
4
|
-
README.
|
4
|
+
README.rdoc
|
5
5
|
Rakefile
|
6
6
|
bin/funit
|
7
7
|
examples/CFD/FluxFunctions.f90
|
@@ -18,6 +18,7 @@ lib/funit/assertions.rb
|
|
18
18
|
lib/funit/compiler.rb
|
19
19
|
lib/funit/functions.rb
|
20
20
|
lib/funit/testsuite.rb
|
21
|
+
lib/funit/c_tools.rb
|
21
22
|
pitch/slides.tex
|
22
23
|
test/test_compiler.rb
|
23
24
|
test/test_functions.rb
|
data/{README.txt → README.rdoc}
RENAMED
@@ -1,21 +1,22 @@
|
|
1
|
-
=
|
1
|
+
= funit
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
home :: https://rubygems.org/gems/funit
|
4
|
+
code :: https://github.com/kleb/nasarb/tree/master/funit
|
5
|
+
bugs :: https://github.com/kleb/nasarb/issues
|
6
|
+
rdoc :: http://www.rubydoc.info/gems/funit
|
6
7
|
|
7
8
|
== DESCRIPTION:
|
8
9
|
|
9
|
-
|
10
|
+
funit is a unit testing framework for Fortran.
|
10
11
|
|
11
12
|
Unit tests are written as Fortran fragments that use a small
|
12
|
-
set of testing-specific keywords and functions.
|
13
|
+
set of testing-specific keywords and functions. funit transforms
|
13
14
|
these fragments into valid Fortran code, compiles, links, and
|
14
15
|
runs them against the code under test.
|
15
16
|
|
16
|
-
|
17
|
+
funit is
|
17
18
|
{opinionated software}[http://www.oreillynet.com/pub/a/network/2005/08/30/ruby-rails-david-heinemeier-hansson.html],
|
18
|
-
which values convention over configuration. Specifically,
|
19
|
+
which values convention over configuration. Specifically, funit requires,
|
19
20
|
|
20
21
|
* a Fortran 95 compiler,
|
21
22
|
* tests to be stored along side the code under test, and
|
@@ -73,15 +74,15 @@ and run the tests, viz,
|
|
73
74
|
gas_physics test suite:
|
74
75
|
Passed 2 of 2 possible asserts comprising 1 of 1 tests.
|
75
76
|
|
76
|
-
This and other examples come with the
|
77
|
+
This and other examples come with the funit distribution in the
|
77
78
|
<tt>examples</tt> directory. There is also an emacs mode in
|
78
|
-
the <tt>utils</tt> directory. If you installed
|
79
|
+
the <tt>utils</tt> directory. If you installed funit via Rubygems,
|
79
80
|
these directories can be found in your Rubygems library directory, e.g., <tt>/usr/local/lib/ruby/gems</tt>.
|
80
81
|
|
81
82
|
== REQUIREMENTS:
|
82
83
|
|
83
|
-
* Fortran
|
84
|
-
* Ruby
|
84
|
+
* Fortran compiler (and setting FC environment variable to point to it)
|
85
|
+
* Ruby
|
85
86
|
* The fortran Rubygem
|
86
87
|
|
87
88
|
== INSTALL:
|
@@ -94,7 +95,7 @@ these directories can be found in your Rubygems library directory, e.g., <tt>/us
|
|
94
95
|
|
95
96
|
== LICENSE:
|
96
97
|
|
97
|
-
|
98
|
+
funit is released under the NASA Open Source Agreement -- see License.txt[link:files/License_txt.html] for details.
|
98
99
|
|
99
100
|
== ORIGIN:
|
100
101
|
|
data/Rakefile
CHANGED
@@ -1,20 +1,17 @@
|
|
1
1
|
# -*- ruby -*-
|
2
2
|
|
3
|
-
require 'rubygems'
|
4
3
|
require 'hoe'
|
4
|
+
#Hoe.plugin :rdoc
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
require 'funit.rb'
|
9
|
-
|
10
|
-
Hoe.new('funit', Funit::VERSION) do |funit|
|
11
|
-
funit.rubyforge_name = 'nasarb'
|
6
|
+
Hoe.spec 'funit' do |funit|
|
7
|
+
funit.group_name = 'nasarb'
|
12
8
|
funit.remote_rdoc_dir = 'funit'
|
13
|
-
funit.
|
9
|
+
funit.licenses = ['NASA-1.3']
|
10
|
+
funit.extra_deps << [ 'fortran', '~> 1.0', '>= 1.3.0' ]
|
14
11
|
funit.spec_extras[:requirements] = "A Fortran compiler."
|
15
12
|
funit.author =
|
16
13
|
[ 'Karen Bibb', 'Bil Kleb', 'Beth Lee-Rausch', 'Mike Park', 'Bill Wood' ]
|
17
|
-
funit.email = '
|
14
|
+
funit.email = [ 'bil.kleb@nasa.gov' ]
|
18
15
|
funit.clean_globs.
|
19
16
|
concat %w[ **/*_fun.f90 **/makeTestRunner examples/**/TestRunner* **/*.o **/*.mod **/*.MOD ]
|
20
17
|
funit.rsync_args = '-rpv --delete' # to preserve group permissions
|
data/bin/funit
CHANGED
@@ -2,63 +2,62 @@
|
|
2
2
|
|
3
3
|
# Main fUnit routine
|
4
4
|
|
5
|
-
begin require 'rubygems'; rescue LoadError; end
|
6
|
-
|
7
5
|
$:.push "#{File.dirname $0}/../lib"
|
8
6
|
require 'funit'
|
9
|
-
require '
|
7
|
+
require 'optparse'
|
8
|
+
require 'ostruct'
|
10
9
|
|
11
10
|
include Funit
|
12
11
|
|
13
|
-
|
12
|
+
funit_data = OpenStruct.new
|
13
|
+
funit_data.prog_source_dirs = ['.']
|
14
|
+
funit_data.c_code = Funit::C_compile.new
|
15
|
+
|
16
|
+
OptionParser.new do |opts|
|
17
|
+
opts.banner = <<-END_OF_HELP
|
18
|
+
To use fUnit, type:
|
19
|
+
funit [-options] [test_file_name(s)]
|
20
|
+
The argument(s) is optional. If no argument is given, then all the .fun files inside the working directory will be used.
|
21
|
+
END_OF_HELP
|
22
|
+
|
23
|
+
opts.separator ""
|
24
|
+
opts.separator "Specific options:"
|
25
|
+
|
26
|
+
opts.on("-s","--source <dir>",String,"Specify a directory for the non-test source") do |dir|
|
27
|
+
funit_data.prog_source_dirs << dir.chomp("/")
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on("-l","--link_c_code <dir>",String,"Specify a directory of C/C++ code that must be compiled/linked") do |dir|
|
31
|
+
funit_data.c_code.compile_library(dir)
|
32
|
+
end
|
14
33
|
|
15
|
-
opts
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
34
|
+
opts.on_tail("--clean","To remove the files generated by funit") do
|
35
|
+
funit_data.c_code.clean_c_code
|
36
|
+
Funit::clean_genFiles
|
37
|
+
exit
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.separator ""
|
41
|
+
opts.separator "Common options:"
|
42
|
+
|
43
|
+
opts.on_tail("-v","--version","Print version") do
|
44
|
+
puts "funit version #{Funit::VERSION}"
|
45
|
+
exit
|
46
|
+
end
|
47
|
+
|
48
|
+
opts.on_tail("-h", "--help", "Detailed overview of funit options") do
|
49
|
+
puts opts
|
50
|
+
exit
|
51
|
+
end
|
21
52
|
|
22
|
-
|
23
|
-
begin
|
24
|
-
case opt
|
25
|
-
when '--help'
|
26
|
-
Funit::print_help
|
27
|
-
exit
|
28
|
-
when '--version'
|
29
|
-
puts Funit::VERSION
|
30
|
-
exit
|
31
|
-
when '--clean'
|
32
|
-
Funit::clean_genFiles
|
33
|
-
exit
|
34
|
-
when '--source'
|
35
|
-
if(ENV['FSFLAG'].nil?) then
|
36
|
-
puts <<-EOF
|
37
|
-
No environment variable FSFLAG set.
|
53
|
+
end.parse!
|
38
54
|
|
39
|
-
|
40
|
-
|
41
|
-
csh: setenv FSFLAG -I
|
42
|
-
windows: set FSFLAG=-I
|
55
|
+
funit_data.prog_source_dirs.flatten!
|
56
|
+
funit_data.prog_source_dirs.uniq!
|
43
57
|
|
44
|
-
|
45
|
-
sh: export FSFLAG=-M
|
46
|
-
csh: setenv FSFLAG -M
|
47
|
-
windows: set FSFLAG=-M
|
48
|
-
EOF
|
49
|
-
exit
|
50
|
-
end
|
51
|
-
prog_source_dirs << arg.split
|
52
|
-
prog_source_dirs.flatten!
|
53
|
-
prog_source_dirs.uniq!
|
54
|
-
end
|
55
|
-
rescue => err
|
56
|
-
puts err
|
57
|
-
break
|
58
|
-
end
|
59
|
-
end
|
58
|
+
Funit::check_for_FSFLAG
|
60
59
|
|
61
|
-
Funit::run_tests(
|
60
|
+
Funit::run_tests(funit_data)
|
62
61
|
|
63
62
|
#--
|
64
63
|
# Copyright 2006-2007 United States Government as represented by
|
@@ -6,7 +6,7 @@ real :: seconds
|
|
6
6
|
setup
|
7
7
|
NotInitialized = .TRUE.
|
8
8
|
last = 0
|
9
|
-
seconds =
|
9
|
+
seconds = 0.0
|
10
10
|
end setup
|
11
11
|
|
12
12
|
test SystemDateAndTimeWorks
|
@@ -42,22 +42,23 @@ end test
|
|
42
42
|
test InitiallyReturnsZero
|
43
43
|
seconds = secSinceLast()
|
44
44
|
Assert_Real_Equal( 0.0, seconds )
|
45
|
-
call timeDelay
|
45
|
+
call timeDelay
|
46
46
|
seconds = secSinceLast()
|
47
47
|
Assert_True( seconds /= 0.0 )
|
48
48
|
end test
|
49
49
|
|
50
|
-
subroutine timeDelay
|
51
|
-
integer :: i
|
52
|
-
real :: sum
|
50
|
+
subroutine timeDelay
|
51
|
+
integer :: i, sum
|
53
52
|
do i = 1, 1000000
|
54
53
|
sum = sum + i
|
55
54
|
enddo
|
55
|
+
print*, sum
|
56
56
|
end subroutine timeDelay
|
57
57
|
|
58
58
|
test ComputesSeconds
|
59
59
|
seconds = secSinceLast()
|
60
|
-
call timeDelay
|
60
|
+
call timeDelay
|
61
|
+
print*, seconds
|
61
62
|
seconds = secSinceLast()
|
62
63
|
Assert_True( seconds > 0.0 )
|
63
64
|
end test
|
@@ -67,7 +68,7 @@ test ComputesSecondsSpecial
|
|
67
68
|
|
68
69
|
seconds = secSinceLast()
|
69
70
|
dateAndTime1 = last
|
70
|
-
call timeDelay
|
71
|
+
call timeDelay
|
71
72
|
seconds = secSinceLast()
|
72
73
|
dateAndTime2 = last
|
73
74
|
expectedSeconds = secBetween(dateAndTime1,dateAndTime2)
|
data/lib/funit.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
begin
|
2
|
-
require 'rubygems'
|
3
2
|
require 'fortran'
|
4
3
|
rescue LoadError
|
5
4
|
STDERR.puts "gem install fortran"
|
@@ -10,16 +9,17 @@ require 'funit/compiler'
|
|
10
9
|
require 'funit/functions'
|
11
10
|
require 'funit/assertions'
|
12
11
|
require 'funit/testsuite'
|
12
|
+
require 'funit/c_tools'
|
13
13
|
require 'fileutils'
|
14
14
|
|
15
15
|
module Funit
|
16
16
|
|
17
|
-
VERSION = '0.
|
17
|
+
VERSION = '0.12.3'
|
18
18
|
|
19
19
|
##
|
20
20
|
# run all tests
|
21
21
|
|
22
|
-
def run_tests(
|
22
|
+
def run_tests(funit_data)
|
23
23
|
Compiler.new# a test for compiler env set (FIXME: remove this later)
|
24
24
|
write_test_runner( test_files = parse_command_line )
|
25
25
|
test_suites = []
|
@@ -29,7 +29,8 @@ module Funit
|
|
29
29
|
ts_name = $1
|
30
30
|
ts_content = $2
|
31
31
|
if((!File.exist?(ts_name+"_fun.f90")) || File.mtime(ts_name+"_fun.f90") < File.mtime(test_file+".fun")) then
|
32
|
-
|
32
|
+
source_file = Dir.glob("#{ts_name}.*90").first
|
33
|
+
if ( File.read(source_file).match(/\s*module\s+#{ts_name}/i) ) then
|
33
34
|
TestSuite.new(ts_name, ts_content, false)
|
34
35
|
else
|
35
36
|
TestSuite.new(ts_name, ts_content, true)
|
@@ -38,7 +39,7 @@ module Funit
|
|
38
39
|
test_suites.push(ts_name)
|
39
40
|
}
|
40
41
|
}
|
41
|
-
compile_tests(test_suites,
|
42
|
+
compile_tests(test_suites,funit_data)
|
42
43
|
exit 1 unless system "env PATH='.' TestRunner"
|
43
44
|
end
|
44
45
|
|
@@ -55,22 +56,24 @@ module Funit
|
|
55
56
|
FileUtils.rm_f(tbCancelled)
|
56
57
|
end
|
57
58
|
|
58
|
-
|
59
|
-
|
59
|
+
def check_for_FSFLAG
|
60
|
+
if(ENV['FSFLAG'].nil?) then
|
61
|
+
puts <<-EOF
|
62
|
+
No environment variable FSFLAG set.
|
60
63
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
The argument(s) is optional. If no argument is given, then all the .fun files inside the working directory will be used.
|
64
|
+
For example for most compilers such as gfortran you will need: -I
|
65
|
+
sh: export FSFLAG=-I
|
66
|
+
csh: setenv FSFLAG -I
|
67
|
+
windows: set FSFLAG=-I
|
66
68
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
69
|
+
but for some such as Sun's f95 compiler you will need: -M
|
70
|
+
sh: export FSFLAG=-M
|
71
|
+
csh: setenv FSFLAG -M
|
72
|
+
windows: set FSFLAG=-M
|
73
|
+
EOF
|
74
|
+
exit
|
75
|
+
end
|
72
76
|
end
|
73
|
-
|
74
77
|
end
|
75
78
|
|
76
79
|
#--
|
@@ -0,0 +1,205 @@
|
|
1
|
+
module Funit
|
2
|
+
class C_compile
|
3
|
+
def initialize
|
4
|
+
check_c_compiler
|
5
|
+
@libraries = {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def check_c_compiler
|
9
|
+
if(ENV['CXX'].nil?) then
|
10
|
+
puts <<-EOF
|
11
|
+
|
12
|
+
You have not specified a C++ compiler. Please specify a compiler via the $(CXX) environment variable.
|
13
|
+
|
14
|
+
In bash, for example:
|
15
|
+
|
16
|
+
export CXX="g++"
|
17
|
+
|
18
|
+
EOF
|
19
|
+
elsif(ENV['CC'].nil?) then
|
20
|
+
puts <<-EOF
|
21
|
+
|
22
|
+
You have not specified a C compiler. Please specify a compiler via the $(CC) environment variable.
|
23
|
+
|
24
|
+
In bash, for example:
|
25
|
+
|
26
|
+
export CC="gcc"
|
27
|
+
|
28
|
+
EOF
|
29
|
+
exit
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def compile_library(dir)
|
34
|
+
puts "building: #{dir}"
|
35
|
+
Dir.chdir(dir) do
|
36
|
+
static_lib = make_objs
|
37
|
+
@libraries[dir]=static_lib.match(/lib(\w+)\.a/).captures.join
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def make_objs(dir=Dir.getwd)
|
42
|
+
if File.exist?("Makefile.am")
|
43
|
+
sources = parse_automake_file
|
44
|
+
static_library = sources[0]
|
45
|
+
File.open("makeTestRunner", "w") {|file| file.puts write_custom_c_makefile(sources)}
|
46
|
+
else
|
47
|
+
static_library = "lib#{File.basename(Dir.getwd)}.a"
|
48
|
+
File.open("makeTestRunner", "w") {|file| file.puts write_generic_c_makefile(static_library)}
|
49
|
+
end
|
50
|
+
compile = "make -f makeTestRunner"
|
51
|
+
raise "Compile failed in #{dir}." unless system compile
|
52
|
+
static_library
|
53
|
+
end
|
54
|
+
|
55
|
+
def parse_automake_file
|
56
|
+
sources = []
|
57
|
+
lines = IO.readlines("Makefile.am")
|
58
|
+
while line = lines.shift
|
59
|
+
sources << $1 if line.match(/^\s*lib_LIBRARIES\s*=\s*(\w+\.a)/)
|
60
|
+
if line.match(/^\s*\w+_SOURCES\s*=/)
|
61
|
+
sources << line.scan(/\w+\.cpp/)
|
62
|
+
while line.match(/\\\s*$/)
|
63
|
+
line = lines.shift
|
64
|
+
sources << line.scan(/(\w+\.cpp)|(\w+\.c)/)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
sources.uniq.flatten.compact
|
69
|
+
end
|
70
|
+
|
71
|
+
def print_linker_flags
|
72
|
+
output_string = ''
|
73
|
+
@libraries.each do |k,v|
|
74
|
+
output_string += " -L#{k} -l#{v}"
|
75
|
+
end
|
76
|
+
output_string += " -lstdc++"
|
77
|
+
end
|
78
|
+
|
79
|
+
def clean_c_code
|
80
|
+
@libraries.keys.each do |k|
|
81
|
+
Dir.chdir(k) do
|
82
|
+
puts "cleaning C code in #{k}"
|
83
|
+
make_clean = "make -f makeTestRunner clean"
|
84
|
+
system make_clean
|
85
|
+
FileUtils.rm "makeTestRunner"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def write_generic_c_makefile(library)
|
91
|
+
c_makefile = %Q{
|
92
|
+
# makefile to compile c++ code
|
93
|
+
# Add .d to Make's recognized suffixes.
|
94
|
+
SUFFIXES += .d
|
95
|
+
|
96
|
+
#Archive command and options
|
97
|
+
AR = ar
|
98
|
+
AR_OPTS = cru
|
99
|
+
|
100
|
+
LIBRARY = #{library}
|
101
|
+
|
102
|
+
#We don't need to clean up when we're making these targets
|
103
|
+
NODEPS:=clean tags svn
|
104
|
+
#Find all the C++ files in this directory
|
105
|
+
SOURCES:=$(shell find . -name "*.cpp")
|
106
|
+
SOURCES+=$(shell find . -name "*.c")
|
107
|
+
|
108
|
+
#These are the dependency files, which make will clean up after it creates them
|
109
|
+
CFILES:=$(SOURCES:.cpp=.c)
|
110
|
+
DEPFILES:=$(CFILES:.c=.d)
|
111
|
+
|
112
|
+
OBJS:=$(CFILES:.c=.o)
|
113
|
+
|
114
|
+
all: $(LIBRARY)
|
115
|
+
|
116
|
+
#Rule to create library archive
|
117
|
+
$(LIBRARY): $(OBJS)
|
118
|
+
\t$(AR) $(AR_OPTS) $@ $^
|
119
|
+
|
120
|
+
#Don't create dependencies when we're cleaning, for instance
|
121
|
+
ifeq (0, $(words $(findstring $(MAKECMDGOALS), $(NODEPS))))
|
122
|
+
#Chances are, these files don't exist. GMake will create them and
|
123
|
+
#clean up automatically afterwards
|
124
|
+
-include $(DEPFILES)
|
125
|
+
endif
|
126
|
+
|
127
|
+
#This is the rule for creating the C++ dependency files
|
128
|
+
%.d: %.cpp
|
129
|
+
\t$(CXX) $(CXXFLAGS) -MM -MT '$(patsubst %.cpp,%.o,$<)' $< -MF $@
|
130
|
+
|
131
|
+
#This is the rule for creating the C dependency files
|
132
|
+
%.d: %.c
|
133
|
+
\t$(CC) $(CFLAGS) -MM -MT '$(patsubst %.c,%.o,$<)' $< -MF $@
|
134
|
+
|
135
|
+
#This rule does the compilation for C++ files
|
136
|
+
%.o: %.cpp %.d %.h
|
137
|
+
\t$(CXX) $(CXXFLAGS) -o $@ -c $<
|
138
|
+
|
139
|
+
#This rule does the compilation for C files
|
140
|
+
%.o: %.c %.d %.h
|
141
|
+
\t$(CC) $(CFLAGS) -o $@ -c $<
|
142
|
+
|
143
|
+
clean:
|
144
|
+
\trm -rf *.o *.d *.a
|
145
|
+
|
146
|
+
}.gsub!(/^ /,'')
|
147
|
+
end
|
148
|
+
|
149
|
+
def write_custom_c_makefile(sources)
|
150
|
+
library = sources.shift
|
151
|
+
source_files = sources.join(" ")
|
152
|
+
c_makefile = %Q{
|
153
|
+
# makefile to compile c++ code
|
154
|
+
# Add .d to Make's recognized suffixes.
|
155
|
+
SUFFIXES += .d
|
156
|
+
|
157
|
+
#Archive command and options
|
158
|
+
AR = ar
|
159
|
+
AR_OPTS = cru
|
160
|
+
|
161
|
+
LIBRARY = #{library}
|
162
|
+
|
163
|
+
SOURCES = #{source_files}
|
164
|
+
|
165
|
+
#These are the dependency files, which make will clean up after it creates them
|
166
|
+
CFILES:=$(SOURCES:.cpp=.c)
|
167
|
+
DEPFILES:=$(CFILES:.c=.d)
|
168
|
+
|
169
|
+
OBJS:=$(CFILES:.c=.o)
|
170
|
+
|
171
|
+
all: $(LIBRARY)
|
172
|
+
|
173
|
+
#Rule to create library archive
|
174
|
+
$(LIBRARY): $(OBJS)
|
175
|
+
\t$(AR) $(AR_OPTS) $@ $^
|
176
|
+
|
177
|
+
#Don't create dependencies when we're cleaning, for instance
|
178
|
+
ifeq (0, $(words $(findstring $(MAKECMDGOALS), $(NODEPS))))
|
179
|
+
#Chances are, these files don't exist. GMake will create them and
|
180
|
+
#clean up automatically afterwards
|
181
|
+
-include $(DEPFILES)
|
182
|
+
endif
|
183
|
+
|
184
|
+
#This is the rule for creating the C++ dependency files
|
185
|
+
%.d: %.cpp
|
186
|
+
\t$(CXX) $(CXXFLAGS) -MM -MT '$(patsubst %.cpp,%.o,$<)' $< -MF $@
|
187
|
+
|
188
|
+
#This is the rule for creating the C dependency files
|
189
|
+
%.d: %.c
|
190
|
+
\t$(CC) $(CFLAGS) -MM -MT '$(patsubst %.c,%.o,$<)' $< -MF $@
|
191
|
+
|
192
|
+
#This rule does the compilation for C++ files
|
193
|
+
%.o: %.cpp %.d %.h
|
194
|
+
\t$(CXX) $(CXXFLAGS) -o $@ -c $<
|
195
|
+
|
196
|
+
#This rule does the compilation for C files
|
197
|
+
%.o: %.c %.d %.h
|
198
|
+
\t$(CC) $(CFLAGS) -o $@ -c $<
|
199
|
+
|
200
|
+
clean:
|
201
|
+
\trm -rf *.o *.d *.a
|
202
|
+
}.gsub!(/^ /,'')
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
data/lib/funit/functions.rb
CHANGED
@@ -24,7 +24,7 @@ module Funit
|
|
24
24
|
( numTests(<%= i+1 %>), numAsserts(<%= i+1 %>), numAssertsTested(<%= i+1 %>), numFailures(<%= i+1 %>) )
|
25
25
|
write(*,1) numAssertsTested(<%= i+1 %>), numAsserts(<%= i+1 %>), &
|
26
26
|
numTests(<%= i+1 %>)-numFailures(<%= i+1 %>), numTests(<%= i+1 %>)
|
27
|
-
|
27
|
+
<%= i+1 %> format('Passed ',i0,' of ',i0,' possible asserts comprising ',i0,' of ',i0,' tests.')
|
28
28
|
<% end -%>
|
29
29
|
|
30
30
|
write(*,*)
|
@@ -51,14 +51,15 @@ module Funit
|
|
51
51
|
# <%= File.basename $0 %> generated this file on <%= Time.now %>.
|
52
52
|
|
53
53
|
OBJ=<%= required_objects.join(' ') %>
|
54
|
+
LDFLAGS=<%= c_code.print_linker_flags %>
|
54
55
|
|
55
56
|
all:testrunner
|
56
57
|
|
57
58
|
testrunner: $(OBJ)
|
58
|
-
<%= "\t#{ENV['FC']} #{ENV['FCFLAGS']} #{ENV['LDFLAGS']}" %> -o TestRunner $(OBJ)
|
59
|
+
<%= "\t#{ENV['FC']} #{ENV['FCFLAGS']} #{ENV['LDFLAGS']}" %> -o TestRunner $(OBJ) $(LDFLAGS)
|
59
60
|
|
60
61
|
<% file_dependencies.each do |source,dep| -%>
|
61
|
-
<%= "#{source.sub(/\.f90/i,'.o')}: #{source} #{dep.map{ |d| d.sub(/\.f90/i,'.o') }.join(' ')}" %>
|
62
|
+
<%= "#{source.sub(/\.f90/i,'.o')}: #{source} #{dep.map{ |d| d.sub(/\.f90/i,'.o') }.join(' ')} #{inlined_dependencies[source].join(' ')}" %>
|
62
63
|
<%= "\t(cd #{File.dirname(source)}; #{ENV['FC']} #{ENV['FCFLAGS']} #{sourceflag} -c #{File.basename(source)})" %>
|
63
64
|
<% end -%>
|
64
65
|
}.gsub(/^ /,''), nil, '-' ) # turn off newlines for <% -%>
|
@@ -71,7 +72,7 @@ module Funit
|
|
71
72
|
end
|
72
73
|
|
73
74
|
def funit_exists?(module_name)
|
74
|
-
File.
|
75
|
+
File.exist? "#{module_name}.fun"
|
75
76
|
end
|
76
77
|
|
77
78
|
def parse_command_line
|
@@ -111,7 +112,10 @@ module Funit
|
|
111
112
|
$stderr.puts "\n *Warning: #{message} [#{test_suite}.fun:#$.]"
|
112
113
|
end
|
113
114
|
|
114
|
-
def compile_tests(test_suites,
|
115
|
+
def compile_tests(test_suites,funit_data)
|
116
|
+
prog_source_dirs = funit_data.prog_source_dirs
|
117
|
+
c_code = funit_data.c_code
|
118
|
+
|
115
119
|
puts "computing dependencies"
|
116
120
|
|
117
121
|
sourceflag = ''
|
@@ -123,6 +127,7 @@ module Funit
|
|
123
127
|
puts "locating associated source files and sorting for compilation"
|
124
128
|
dependencies.source_file_dependencies('TestRunner.f90')
|
125
129
|
file_dependencies = dependencies.file_dependencies
|
130
|
+
inlined_dependencies = dependencies.inlined_dependencies
|
126
131
|
required_objects = file_dependencies.values.flatten.uniq.map{|s|s.sub(/\.f90/i,'.o')}
|
127
132
|
required_objects << 'TestRunner.o'
|
128
133
|
|
data/lib/funit/testsuite.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'funit'
|
2
|
-
|
3
1
|
module Funit
|
4
2
|
|
5
3
|
include Assertions # FIXME
|
@@ -20,7 +18,7 @@ module Funit
|
|
20
18
|
@suite_name = suite_name
|
21
19
|
@suite_content = suite_content
|
22
20
|
return nil unless funit_exists?(suite_name)
|
23
|
-
File.delete(suite_name+"_fun.f90") if File.
|
21
|
+
File.delete(suite_name+"_fun.f90") if File.exist?(suite_name+"_fun.f90")
|
24
22
|
super(suite_name+"_fun.f90","w")
|
25
23
|
@tests, @setup, @teardown = [], [], []
|
26
24
|
header
|
data/test/test_funit.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require 'funit'
|
3
|
-
require '
|
3
|
+
require 'fileutils'
|
4
|
+
require 'ostruct'
|
4
5
|
|
5
6
|
class TestFunit < Test::Unit::TestCase
|
6
7
|
|
@@ -10,34 +11,37 @@ class TestFunit < Test::Unit::TestCase
|
|
10
11
|
include Funit::Assertions # FIXME
|
11
12
|
|
12
13
|
def setup
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
14
|
+
FileUtils.rm_f Dir.glob("dummyunit*")
|
15
|
+
FileUtils.rm_f Dir.glob("unit*")
|
16
|
+
FileUtils.rm_f Dir.glob("another*")
|
17
|
+
FileUtils.rm_f Dir.glob("ydsbe*")
|
18
|
+
FileUtils.rm_f Dir.glob("lmzd*")
|
19
|
+
FileUtils.rm_f Dir.glob("ldfdl*")
|
20
|
+
FileUtils.rm_f Dir.glob("ydsbe*")
|
21
|
+
FileUtils.rm_f Dir.glob("*TestRunner*")
|
22
|
+
@@funit_data = OpenStruct.new
|
23
|
+
@@funit_data.prog_source_dirs = ['.']
|
24
|
+
@@funit_data.c_code = Funit::C_compile.new
|
21
25
|
end
|
22
26
|
|
23
27
|
def teardown
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
FileUtils.rm_f Dir.glob("dummyunit*")
|
29
|
+
FileUtils.rm_f Dir.glob("unit*")
|
30
|
+
FileUtils.rm_f Dir.glob("another*")
|
31
|
+
FileUtils.rm_f Dir.glob("ydsbe*")
|
32
|
+
FileUtils.rm_f Dir.glob("lmzd*")
|
33
|
+
FileUtils.rm_f Dir.glob("ldfdl*")
|
34
|
+
FileUtils.rm_f Dir.glob("ydsbe*")
|
35
|
+
FileUtils.rm_f Dir.glob("*TestRunner*")
|
32
36
|
end
|
33
37
|
|
34
38
|
def test_empty_test_runner_created_and_compilable
|
35
39
|
write_test_runner []
|
36
|
-
assert File.
|
37
|
-
compile_tests
|
38
|
-
assert File.
|
40
|
+
assert File.exist?("TestRunner.f90"), 'TestRunner.f90 not created.'
|
41
|
+
compile_tests([],@@funit_data)
|
42
|
+
assert File.exist?("makeTestRunner"), 'makeTestRunner.f90 not created.'
|
39
43
|
assert system("make -f makeTestRunner"), 'make -f makeTestRunner failed.'
|
40
|
-
assert File.
|
44
|
+
assert File.exist?("TestRunner"), 'TestRunner executable not created.'
|
41
45
|
end
|
42
46
|
|
43
47
|
def test_is_equal
|
@@ -75,7 +79,7 @@ class TestFunit < Test::Unit::TestCase
|
|
75
79
|
File.open('unit.fun','w') do |f|
|
76
80
|
f.puts "test_suite unit\ntest a_gets_set\nAssert_Equal(5,a)\nend test\nend test_suite"
|
77
81
|
end
|
78
|
-
assert_nothing_raised{run_tests}
|
82
|
+
assert_nothing_raised{run_tests(@@funit_data)}
|
79
83
|
end
|
80
84
|
|
81
85
|
def test_should_accommodate_doubly_embedded_use_dependencies
|
@@ -91,8 +95,8 @@ class TestFunit < Test::Unit::TestCase
|
|
91
95
|
File.open('unit.fun','w') do |f|
|
92
96
|
f.puts "begin test_suite unit\ntest a_gets_set\n Assert_Equal(5, a)\nend test\nend test_suite"
|
93
97
|
end
|
94
|
-
assert_nothing_raised{run_tests}
|
95
|
-
|
98
|
+
assert_nothing_raised{run_tests(@@funit_data)}
|
99
|
+
end
|
96
100
|
|
97
101
|
def test_should_accommodate_cap_F_extensions
|
98
102
|
File.open('unit.F90','w') do |f|
|
@@ -101,8 +105,8 @@ class TestFunit < Test::Unit::TestCase
|
|
101
105
|
File.open('unit.fun','w') do |f|
|
102
106
|
f.puts "begin test_suite unit\ntest a_gets_set\n Assert_Equal(1, a)\nend test\nend test_suite"
|
103
107
|
end
|
104
|
-
assert_nothing_raised{run_tests}
|
105
|
-
|
108
|
+
assert_nothing_raised{run_tests(@@funit_data)}
|
109
|
+
end
|
106
110
|
|
107
111
|
def test_requested_modules
|
108
112
|
tu_assert_equal ["asdfga"], requested_modules(["asdfga"])
|
@@ -116,7 +120,7 @@ class TestFunit < Test::Unit::TestCase
|
|
116
120
|
|
117
121
|
def test_funit_exists_method
|
118
122
|
module_name = "ydsbe"
|
119
|
-
|
123
|
+
FileUtils.rm_f module_name+".fun"
|
120
124
|
tu_assert_equal false, funit_exists?(module_name)
|
121
125
|
system "touch "+module_name+".fun"
|
122
126
|
assert funit_exists?(module_name)
|
data/test/test_testsuite.rb
CHANGED
@@ -18,8 +18,8 @@ class TestTestSuite < Test::Unit::TestCase
|
|
18
18
|
|
19
19
|
def test_nonexistent_funit_file_is_not_created
|
20
20
|
Funit::TestSuite.new 'dummyf90test', '', false
|
21
|
-
assert !File.
|
22
|
-
assert !File.
|
21
|
+
assert !File.exist?("dummyf90test.fun")
|
22
|
+
assert !File.exist?("dummyf90test_fun.f90")
|
23
23
|
end
|
24
24
|
|
25
25
|
def create_funit_file funit_contents
|
metadata
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: funit
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.12.3
|
5
5
|
platform: ruby
|
6
|
-
authors:
|
6
|
+
authors:
|
7
7
|
- Karen Bibb
|
8
8
|
- Bil Kleb
|
9
9
|
- Beth Lee-Rausch
|
@@ -12,46 +12,86 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
dependencies:
|
19
|
-
- !ruby/object:Gem::Dependency
|
15
|
+
date: 2016-02-05 00:00:00.000000000 Z
|
16
|
+
dependencies:
|
17
|
+
- !ruby/object:Gem::Dependency
|
20
18
|
name: fortran
|
19
|
+
requirement: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '1.0'
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.3.0
|
21
27
|
type: :runtime
|
22
|
-
|
23
|
-
version_requirements: !ruby/object:Gem::Requirement
|
24
|
-
requirements:
|
25
|
-
- -
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
version: 1.
|
28
|
-
|
29
|
-
- !ruby/object:Gem::
|
28
|
+
prerelease: false
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.0'
|
34
|
+
- - '>='
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 1.3.0
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rdoc
|
39
|
+
requirement: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '4.0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ~>
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '4.0'
|
51
|
+
- !ruby/object:Gem::Dependency
|
30
52
|
name: hoe
|
53
|
+
requirement: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ~>
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '3.14'
|
31
58
|
type: :development
|
32
|
-
|
33
|
-
version_requirements: !ruby/object:Gem::Requirement
|
34
|
-
requirements:
|
35
|
-
- -
|
36
|
-
- !ruby/object:Gem::Version
|
37
|
-
version:
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
59
|
+
prerelease: false
|
60
|
+
version_requirements: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ~>
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '3.14'
|
65
|
+
description: |-
|
66
|
+
funit is a unit testing framework for Fortran.
|
67
|
+
|
68
|
+
Unit tests are written as Fortran fragments that use a small
|
69
|
+
set of testing-specific keywords and functions. funit transforms
|
70
|
+
these fragments into valid Fortran code, compiles, links, and
|
71
|
+
runs them against the code under test.
|
72
|
+
|
73
|
+
funit is
|
74
|
+
{opinionated software}[http://www.oreillynet.com/pub/a/network/2005/08/30/ruby-rails-david-heinemeier-hansson.html],
|
75
|
+
which values convention over configuration. Specifically, funit requires,
|
76
|
+
|
77
|
+
* a Fortran 95 compiler,
|
78
|
+
* tests to be stored along side the code under test, and
|
79
|
+
* test files to be named appropriately.
|
80
|
+
email:
|
81
|
+
- bil.kleb@nasa.gov
|
82
|
+
executables:
|
42
83
|
- funit
|
43
84
|
extensions: []
|
44
|
-
|
45
|
-
|
46
|
-
- History.txt
|
85
|
+
extra_rdoc_files:
|
86
|
+
- History.rdoc
|
47
87
|
- License.txt
|
48
88
|
- Manifest.txt
|
49
|
-
- README.
|
50
|
-
files:
|
51
|
-
- History.
|
89
|
+
- README.rdoc
|
90
|
+
files:
|
91
|
+
- History.rdoc
|
52
92
|
- License.txt
|
53
93
|
- Manifest.txt
|
54
|
-
- README.
|
94
|
+
- README.rdoc
|
55
95
|
- Rakefile
|
56
96
|
- bin/funit
|
57
97
|
- examples/CFD/FluxFunctions.f90
|
@@ -65,6 +105,7 @@ files:
|
|
65
105
|
- examples/StopWatch/StopWatch.fun
|
66
106
|
- lib/funit.rb
|
67
107
|
- lib/funit/assertions.rb
|
108
|
+
- lib/funit/c_tools.rb
|
68
109
|
- lib/funit/compiler.rb
|
69
110
|
- lib/funit/functions.rb
|
70
111
|
- lib/funit/testsuite.rb
|
@@ -76,35 +117,31 @@ files:
|
|
76
117
|
- utils/errorFinder.el
|
77
118
|
- utils/funit-generic-mode.el
|
78
119
|
- utils/funit-mode.el
|
79
|
-
|
80
|
-
|
120
|
+
homepage: https://rubygems.org/gems/funit
|
121
|
+
licenses:
|
122
|
+
- NASA-1.3
|
123
|
+
metadata: {}
|
81
124
|
post_install_message:
|
82
|
-
rdoc_options:
|
125
|
+
rdoc_options:
|
83
126
|
- --main
|
84
|
-
- README.
|
85
|
-
require_paths:
|
127
|
+
- README.rdoc
|
128
|
+
require_paths:
|
86
129
|
- lib
|
87
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
-
requirements:
|
89
|
-
- -
|
90
|
-
- !ruby/object:Gem::Version
|
91
|
-
version:
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
version:
|
99
|
-
requirements:
|
130
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - '>='
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - '>='
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
requirements:
|
100
141
|
- A Fortran compiler.
|
101
|
-
rubyforge_project:
|
102
|
-
rubygems_version:
|
142
|
+
rubyforge_project:
|
143
|
+
rubygems_version: 2.4.8
|
103
144
|
signing_key:
|
104
|
-
specification_version:
|
105
|
-
summary:
|
106
|
-
test_files:
|
107
|
-
- test/test_compiler.rb
|
108
|
-
- test/test_functions.rb
|
109
|
-
- test/test_funit.rb
|
110
|
-
- test/test_testsuite.rb
|
145
|
+
specification_version: 4
|
146
|
+
summary: funit is a unit testing framework for Fortran
|
147
|
+
test_files: []
|