Module: Funit

Includes:
Assertions
Included in:
TestSuite
Defined in:
lib/funit.rb,
lib/funit/compiler.rb,
lib/funit/functions.rb,
lib/funit/testsuite.rb,
lib/funit/assertions.rb

Defined Under Namespace

Modules: Assertions Classes: Compiler, TestSuite

Constant Summary collapse

VERSION =
'0.10.3'
TEST_RUNNER =
ERB.new( %q{
! TestRunner.f90 - runs fUnit test suites
!
! <%= File.basename $0 %> generated this file on <%= Time.now %>.

program TestRunner

  <% test_suites.each do |test_suite| -%>
  use <%= test_suite %>_fun
  <% end -%>

  implicit none

  integer, dimension(<%=test_suites.size%>) :: numTests, numAsserts, numAssertsTested, numFailures

  <% test_suites.each_with_index do |test_suite,i| -%>
  write(*,*)
  write(*,*) "<%= test_suite %> test suite:"
  call test_<%= test_suite %> &
    ( numTests(<%= i+1 %>), numAsserts(<%= i+1 %>), numAssertsTested(<%= i+1 %>), numFailures(<%= i+1 %>) )
  write(*,*) "Passed", numAssertsTested(<%= i+1 %>), "of", numAsserts(<%= i+1 %>), &
             "possible asserts comprising", numTests(<%= i+1 %>)-numFailures(<%= i+1 %>), &
             "of", numTests(<%= i+1 %>), "tests."
  <% end -%>

  write(*,*)
  write(*,'(a)') "==========[ SUMMARY ]=========="
  <% max_length = test_suites.empty? ? 0 : test_suites.max.length -%>
  <% test_suites.each_with_index do |test_suite,i| -%>
  write(*,'(a<%=max_length+2%>)',advance="no") " <%= test_suite %>:"
  if ( numFailures(<%= i+1 %>) == 0 ) then
    write(*,*) " passed"
  else
    write(*,*) " failed   <<<<<"
  end if
  <% end -%>
  write(*,*)

  if ( sum(numFailures) /= 0 ) stop 1

end program TestRunner
}.gsub(/^    /,''), nil, '-' )
MAKEFILE =
ERB.new( %q{
  # makefile to compile TestRunner.f90
  #
  # <%= File.basename $0 %> generated this file on <%= Time.now %>.

  OBJ=<%= required_objects.join(' ') %>

  all:testrunner

  testrunner: $(OBJ)
  <%= "\t#{ENV['FC']} #{ENV['FCFLAGS']}" %> -o TestRunner $(OBJ)

  <% file_dependencies.each do |source,dep| -%>
  <%= "#{source.sub(/\.f90/i,'.o')}: #{source} #{dep.map{ |d| d.sub(/\.f90/i,'.o') }.join(' ')}" %>
  <%= "\t(cd #{File.dirname(source)}; #{ENV['FC']} #{ENV['FCFLAGS']} #{sourceflag} -c #{File.basename(source)})" %>
  <% end -%>
}.gsub(/^    /,''), nil, '-' )

Constants included from Assertions

Assertions::ASSERTION_PATTERN

Instance Method Summary collapse

Methods included from Assertions

#assert_array_equal, #assert_equal, #assert_equal_within, #assert_false, #assert_real_equal, #assert_true, #get_args, #write_assert

Instance Method Details

#clean_genFilesObject

remove files generated by fUnit



43
44
45
46
47
48
49
50
51
# File 'lib/funit.rb', line 43

def clean_genFiles
  module_names = Dir["**/*.fun"].map{|mn| mn.chomp(".fun")}
  tbCancelled = module_names.map{|mn| mn+"_fun."} + ["TestRunner."]
  tbCancelled = tbCancelled.map{|tbc| [tbc+"f90",tbc+"o",tbc+"MOD"]}.flatten
  tbCancelled += Dir["**/TestRunner"]
  tbCancelled += Dir["**/makeTestRunner"]
  tbCancelled = (tbCancelled+tbCancelled.map{|tbc| tbc.downcase}).uniq
  FileUtils.rm_f(tbCancelled)
end

#compile_tests(test_suites, prog_source_dirs = ['.']) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/funit/functions.rb', line 114

def compile_tests(test_suites,prog_source_dirs=['.'])
  puts "computing dependencies"

  sourceflag = ''
  if ENV['FSFLAG'] then
    sourceflag = prog_source_dirs.map{|pd| ENV['FSFLAG']+pd }.join(' ')
  end
  dependencies = Fortran::Dependencies.new(:search_paths=>prog_source_dirs)

  puts "locating associated source files and sorting for compilation"
  dependencies.source_file_dependencies('TestRunner.f90')
  file_dependencies = dependencies.file_dependencies
  required_objects = file_dependencies.values.flatten.uniq.map{|s|s.sub(/\.f90/i,'.o')}
  required_objects << 'TestRunner.o'

  File.open("makeTestRunner", "w") {|file| file.puts MAKEFILE.result(binding)}

  compile = "make -f makeTestRunner"

  raise "Compile failed." unless system compile
end

#funit_exists?(module_name) ⇒ Boolean

Returns:

  • (Boolean)


73
74
75
# File 'lib/funit/functions.rb', line 73

def funit_exists?(module_name)
  File.exists? "#{module_name}.fun"
end

#parse_command_lineObject



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/funit/functions.rb', line 77

def parse_command_line

  module_names = requested_modules(ARGV)

  if module_names.empty?
    raise "   *Error: no test suites found in this directory"
  end

  module_names.each do |mod|
    unless funit_exists?(mod) 
      error_message = <<-FUNIT_DOES_NOT_EXIST
 Error: could not find test suite #{mod}.fun
 Test suites available in this directory:
 #{requested_modules([]).join(' ')}

 Usage: #{File.basename $0} [test names (w/o .fun suffix)]
      FUNIT_DOES_NOT_EXIST
      raise error_message
    end
  end

end

prints a usage help for the user



56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/funit.rb', line 56

def print_help
  puts <<-END_OF_HELP
    To use fUnit, type:
      funit [-options] [test_file_name(s)]
    The argument(s) is optional. If no argument is given, then all the .fun files inside the working directory will be used.

    The options are:
      --clean                   => To remove the files generated by fUnit
      -h, --help                => Prints this help
      -s <dir>, --source <dir>  => To specify a directory for the non-test source
  END_OF_HELP
end

#requested_modules(module_names) ⇒ Object



66
67
68
69
70
71
# File 'lib/funit/functions.rb', line 66

def requested_modules(module_names)
  if module_names.empty?
    module_names = Dir["*.fun"].each{ |mod| mod.chomp! ".fun" }
  end
  module_names
end

#run_tests(prog_source_dirs = ['.']) ⇒ Object

run all tests



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/funit.rb', line 22

def run_tests(prog_source_dirs=['.'])
  Compiler.new# a test for compiler env set (FIXME: remove this later)
  write_test_runner( test_files = parse_command_line )
  test_suites = []
  test_files.each{ |test_file|
    tf_content = IO.read(test_file+'.fun')
    tf_content.scan(/test_suite\s+(\w+)(.*?)end\s+test_suite/m).each{|ts|
      ts_name = $1
      if((!File.exist?(ts_name+"_fun.f90")) || File.mtime(ts_name+"_fun.f90") < File.mtime(test_file+".fun")) then
        TestSuite.new(ts_name, $2)
      end
      test_suites.push(ts_name)
    }
  }
  compile_tests(test_suites,prog_source_dirs)
  exit 1 unless system "env PATH='.' TestRunner"
end

#syntax_error(message, test_suite) ⇒ Object



106
107
108
# File 'lib/funit/functions.rb', line 106

def syntax_error( message, test_suite )
  raise "\n   *Error: #{message} [#{test_suite}.fun:#$.]\n\n"
end

#warning(message, test_suite) ⇒ Object



110
111
112
# File 'lib/funit/functions.rb', line 110

def warning( message, test_suite )
  $stderr.puts "\n *Warning: #{message} [#{test_suite}.fun:#$.]"
end

#write_test_runner(test_suites) ⇒ Object



100
101
102
103
104
# File 'lib/funit/functions.rb', line 100

def write_test_runner test_suites
  File.open("TestRunner.f90", "w") do |file|
    file.puts TEST_RUNNER.result(binding)
  end
end