funit 0.11.1 → 0.12.3
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|