funit 0.9.4 → 0.10.0

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.
data/History.txt CHANGED
@@ -1,4 +1,25 @@
1
- === 0.9.4 / 2007-01-08
1
+ === 0.10.0 / 2008-03-30 (all courtesy of Diego Virasoro)
2
+
3
+ * 4 major enchancements
4
+ * User can now use 'funit --clean' to remove the generated files
5
+ * Source directory and test directory can be different: specify
6
+ source dir with -s (or --source) flag
7
+ * Only the minimum number of files that need recompilation are compiled
8
+ via makefile
9
+ * The .fun file name is not constrained anymore, but now each test suite
10
+ must be surrounded by 'test_suite name' and 'end test_suite', where name
11
+ is the name of the module to be tested
12
+ * Multiple test suites can exist inside the same file
13
+
14
+ * 5 minor enchancements
15
+ * Change blocks nomenclature: beginTest -> test and endTest -> end test
16
+ (and similarly for setup and teardown)
17
+ * Change assertions nomenclature (eg. IsEqual -> assert_equal)
18
+ * Added one new assertion: assert_array_equal
19
+ * Added a summary of all the test suites results, printed at the end
20
+ * Minor code clean-up
21
+
22
+ === 0.9.4 / 2008-01-08
2
23
 
3
24
  * 2 minor enhancements
4
25
  * broke up more long conditionals with continuation
data/README.txt CHANGED
@@ -109,11 +109,8 @@ rewrote the framework in Ruby[http://www.ruby-lang.org].
109
109
 
110
110
  == TODO:
111
111
 
112
- * Rename assertions to more consistent with other xUnits.
113
- * Use <tt>test</tt> keyword instead of <tt>beginTest</tt> business.
112
+ * Add --version option.
114
113
  * To avoid Fortran's 32-character limit, don't add test name during translation.
115
- * Add some command line options (especially <tt>clean</tt>), possibly
116
- using CmdParse[http://cmdparse.rubyforge.org].
117
114
  * Add assertions that capture stops, warning messages, and other exits.
118
115
  * For compilation, use internal rake task instead of a single, ordered command line.
119
116
  * Allow users to specify dependency search paths (currently hardwired).
data/Rakefile CHANGED
@@ -3,7 +3,9 @@
3
3
  require 'rubygems'
4
4
  require 'hoe'
5
5
 
6
- require './lib/funit.rb'
6
+ $LOAD_PATH.unshift File.join( File.dirname(__FILE__), 'lib')
7
+
8
+ require 'funit.rb'
7
9
 
8
10
  Hoe.new('funit', Funit::VERSION) do |funit|
9
11
  funit.rubyforge_name = 'nasarb'
@@ -11,10 +13,20 @@ Hoe.new('funit', Funit::VERSION) do |funit|
11
13
  funit.extra_deps << [ 'fortran', '>= 1.0.1' ]
12
14
  funit.spec_extras[:requirements] = "A Fortran compiler."
13
15
  funit.author =
14
- [ 'Karen Bibb','Bil Kleb','Beth Lee-Rausch','Mike Park','Bill Wood']
16
+ [ 'Karen Bibb', 'Bil Kleb', 'Beth Lee-Rausch', 'Mike Park', 'Bill Wood' ]
15
17
  funit.email = 'nasarb-developers@rubyforge.org'
16
- funit.clean_globs.concat %w( **/*_fun.f90 examples/**/TestRunner* **/*.o **/*.mod **/*.MOD )
18
+ funit.clean_globs.
19
+ concat %w[ **/*_fun.f90 **/makeTestRunner examples/**/TestRunner* **/*.o **/*.mod **/*.MOD ]
17
20
  funit.rsync_args = '-rpv --delete' # to preserve group permissions
18
21
  end
19
22
 
23
+ desc "run all examples"
24
+ task :examples do
25
+ Dir['examples/*'].each do |dir|
26
+ cd dir do
27
+ ruby "-Ilib ../../bin/funit"
28
+ end
29
+ end
30
+ end
31
+
20
32
  # vim: syntax=Ruby
data/bin/funit CHANGED
@@ -6,10 +6,57 @@ begin require 'rubygems'; rescue LoadError; end
6
6
 
7
7
  $:.push "#{File.dirname $0}/../lib"
8
8
  require 'funit'
9
+ require 'getoptlong'
9
10
 
10
11
  include Funit
11
12
 
12
- Funit::run_tests
13
+ prog_source_dir = nil
14
+
15
+ opts = GetoptLong.new(
16
+ ['--help', '-h', GetoptLong::NO_ARGUMENT],
17
+ ['--clean', '-c', GetoptLong::NO_ARGUMENT],
18
+ ['--source', '-s', GetoptLong::REQUIRED_ARGUMENT]
19
+ )
20
+
21
+ opts.each do |opt,arg|
22
+ begin
23
+ case opt
24
+ when '--help'
25
+ Funit::print_help
26
+ exit
27
+ when '--clean'
28
+ Funit::clean_genFiles
29
+ exit
30
+ when '--source'
31
+ if(ENV['FSFLAG'].nil?) then
32
+ puts <<-EOF
33
+ No environment variable FSFLAG set.
34
+
35
+ For example for most compilers such as gfortran you will need: -I
36
+ sh: export FSFLAG=-I
37
+ csh: setenv FSFLAG -I
38
+ windows: set FSFLAG=-I
39
+
40
+ but for some such as Sun's f95 compiler you will need: -M
41
+ sh: export FSFLAG=-M
42
+ csh: setenv FSFLAG -M
43
+ windows: set FSFLAG=-M
44
+ EOF
45
+ exit
46
+ end
47
+ prog_source_dir = arg
48
+ end
49
+ rescue => err
50
+ puts err
51
+ break
52
+ end
53
+ end
54
+
55
+ if(prog_source_dir.nil?) then
56
+ Funit::run_tests
57
+ else
58
+ Funit::run_tests(prog_source_dir)
59
+ end
13
60
 
14
61
  #--
15
62
  # Copyright 2006-2007 United States Government as represented by
@@ -1,47 +1,51 @@
1
+ test_suite FluxFunctions
2
+
1
3
  real :: leftState, rightState, interfaceFlux
2
4
 
3
- beginsetup
5
+ setup
4
6
  leftState = 0
5
7
  rightState = 1
6
- endsetup
8
+ end setup
7
9
 
8
- beginTest FluxZero
10
+ test FluxZero
9
11
  real :: state
10
12
  state = 0
11
- IsEqualWithin( 0, Flux(state), 0.00001 )
12
- endTest
13
+ Assert_Equal_Within( 0, Flux(state), 0.00001 )
14
+ end test
13
15
 
14
- beginTest FluxOne
16
+ test FluxOne
15
17
  real :: state = 1
16
- IsEqualWithin( 0.5, Flux(state), 0.00001 )
17
- endTest
18
+ Assert_Equal_Within( 0.5, Flux(state), 0.00001 )
19
+ end test
18
20
 
19
- beginTest RoeAvgZero
20
- IsRealEqual( 0, RoeAvg(0.0,0.0) )
21
- IsFalse( RoeAvg(0.0,0.0)==1 )
22
- endTest
21
+ test RoeAvgZero
22
+ Assert_Real_Equal( 0, RoeAvg(0.0,0.0) )
23
+ Assert_False( RoeAvg(0.0,0.0)==1 )
24
+ end test
23
25
 
24
- beginTest RoeAvgKnown
25
- IsRealEqual( 0.5, RoeAvg(leftState,rightState) )
26
- IsTrue( RoeAvg(leftState,rightState) > 0 )
27
- endTest
26
+ test RoeAvgKnown
27
+ Assert_Real_Equal( 0.5, RoeAvg(leftState,rightState) )
28
+ Assert_True( RoeAvg(leftState,rightState) > 0 )
29
+ end test
28
30
 
29
- beginTest CentralFluxKnown
31
+ test CentralFluxKnown
30
32
  call CentralFlux( leftState, rightState, interfaceFlux )
31
- IsEqualWithin( 0.25, interfaceFlux, 0.001 )
32
- IsEqualWithin( 0.25, interfaceFlux, 0.00000001 )
33
- IsEqual( 0.25, interfaceFlux )
34
- endTest
33
+ Assert_Equal_Within( 0.25, interfaceFlux, 0.001 )
34
+ Assert_Equal_Within( 0.25, interfaceFlux, 0.00000001 )
35
+ Assert_Equal( 0.25, interfaceFlux )
36
+ end test
35
37
 
36
- beginTest RoeFluxExpansionShock
38
+ test RoeFluxExpansionShock
37
39
  leftState = -1
38
40
  call RoeFlux( leftState, rightState, interfaceFlux )
39
- IsEqual( 0.5, interfaceFlux )
40
- endTest
41
+ Assert_Equal( 0.5, interfaceFlux )
42
+ end test
41
43
 
42
- beginTest RoeFluxZero
44
+ test RoeFluxZero
43
45
  rightState = 0
44
46
  call RoeFlux( leftState, rightState, interfaceFlux )
45
- IsRealEqual( 0, interfaceFlux )
46
- IsEqual( 0, interfaceFlux )
47
- endTest
47
+ Assert_Real_Equal( 0, interfaceFlux )
48
+ Assert_Equal( 0, interfaceFlux )
49
+ end test
50
+
51
+ end test_suite
@@ -1,20 +1,24 @@
1
- real :: Pressure, Density, Energy
1
+ test_suite GasModel
2
2
 
3
- beginTest PerfectPZeroed
3
+ real :: Pressure, Density, Energy
4
+
5
+ test PerfectPZeroed
4
6
  real, parameter :: zero = 0
5
7
  call PerfectP (zero, zero, Pressure)
6
- isRealEqual ( 0, Pressure )
7
- IsEqualwithin ( 0, Pressure, 0.0000000001 )
8
- endTest
8
+ Assert_Real_Equal( 0, Pressure )
9
+ Assert_Equal_within( 0, Pressure, 0.0000000001 )
10
+ end test
9
11
 
10
- begintest Warbler
11
- endtest
12
+ test Warbler
13
+ end test
12
14
 
13
- beginTest PerfectPKnown
15
+ test PerfectPKnown
14
16
  real :: Density = 1
15
17
  Energy = 1
16
18
  call PerfectP( Density, Energy, Pressure )
17
- IsRealEqual( 0.4, Pressure )
18
- IsTrue ( Pressure > 0 )
19
- IsFalse( Pressure < 0 )
20
- endTest
19
+ Assert_Real_Equal( 0.4, Pressure )
20
+ Assert_True( Pressure > 0 )
21
+ Assert_False( Pressure < 0 )
22
+ end test
23
+
24
+ end test_suite
@@ -1,28 +1,33 @@
1
- character(len=*), parameter :: FILE = 'values.txt'
1
+ test_suite time_series_data
2
2
 
3
- beginSetup
3
+ character(len=10), parameter :: FILE = 'values.txt'
4
+
5
+ setup
4
6
  open(8, file=FILE)
5
7
  write(8,'(a)'), '200609300000 0.223200546265E+003'
6
8
  write(8,'(a)'), '200609300132 0.226001495361E+003'
7
9
  close(8)
8
- endSetup
10
+ end setup
9
11
 
10
- beginTest load_time_series_data_from_file
12
+ test load_time_series_data_from_file
11
13
  call read_time_series( FILE )
12
- IsEqual( 2006, ts_data(1)%date_time%year )
13
- IsEqual( 9, ts_data(1)%date_time%month )
14
- IsEqual( 30, ts_data(1)%date_time%day )
15
- IsEqual( 0, ts_data(1)%date_time%hour )
16
- IsEqual( 0, ts_data(1)%date_time%minute )
17
- IsEqualWithin( 223.2, ts_data(1)%value, 0.1 )
18
- IsEqual( 2006, ts_data(2)%date_time%year )
19
- IsEqual( 9, ts_data(2)%date_time%month )
20
- IsEqual( 30, ts_data(2)%date_time%day )
21
- IsEqual( 1, ts_data(2)%date_time%hour )
22
- IsEqual( 32, ts_data(2)%date_time%minute )
23
- IsEqualWithin( 226.0, ts_data(2)%value, 0.1 )
24
- endTest
14
+ Assert_Equal( 2006, ts_data(1)%date_time%year )
15
+ Assert_Equal( 9, ts_data(1)%date_time%month )
16
+ Assert_Equal( 30, ts_data(1)%date_time%day )
17
+ Assert_Equal( 0, ts_data(1)%date_time%hour )
18
+ Assert_Equal( 0, ts_data(1)%date_time%minute )
19
+ Assert_Equal_Within( 223.2, ts_data(1)%value, 0.1 )
20
+ Assert_Equal( 2006, ts_data(2)%date_time%year )
21
+ Assert_Equal( 9, ts_data(2)%date_time%month )
22
+ Assert_Equal( 30, ts_data(2)%date_time%day )
23
+ Assert_Equal( 1, ts_data(2)%date_time%hour )
24
+ Assert_Equal( 32, ts_data(2)%date_time%minute )
25
+ Assert_Equal_Within( 226.0, ts_data(2)%value, 0.1 )
26
+ end test
27
+
28
+ teardown
29
+ call system('/bin/rm '//FILE)
30
+ end teardown
31
+
32
+ end test_suite
25
33
 
26
- beginTeardown
27
- call system('rm '//FILE)
28
- endTeardown
@@ -1,49 +1,51 @@
1
+ test_suite StopWatch
2
+
1
3
  integer, dimension(8) :: dateAndTime1, dateAndTime2
2
4
  real :: seconds
3
5
 
4
- beginSetup
6
+ setup
5
7
  NotInitialized = .TRUE.
6
8
  last = 0
7
9
  seconds = HUGE(0.0)
8
- endSetup
10
+ end setup
9
11
 
10
- beginTest SystemDateAndTimeWorks
12
+ test SystemDateAndTimeWorks
11
13
  call date_and_time(values=dateAndTime1)
12
- IsTrue( dateAndTime1(1) /= -huge(0) )
13
- IsTrue( size(dateAndTime1,1) == 8 )
14
- endTest
14
+ Assert_True( dateAndTime1(1) /= -huge(0) )
15
+ Assert_True( size(dateAndTime1,1) == 8 )
16
+ end test
15
17
 
16
18
  ! test secBetween
17
- beginTest OneMSecDifference
19
+ test OneMSecDifference
18
20
  dateAndTime1 = (/ 2000, 1, 1, 0, 0, 0, 0, 0 /)
19
21
  dateAndTime2 = (/ 2000, 1, 1, 0, 0, 0, 0, 1 /)
20
22
  seconds = SecBetween(dateAndTime1, dateAndTime2)
21
- IsRealEqual( 0.001, seconds)
22
- endTest
23
+ Assert_Real_Equal( 0.001, seconds)
24
+ end test
23
25
 
24
- beginTest MinuteRollover
26
+ test MinuteRollover
25
27
  dateAndTime1 = (/ 2000, 1, 1, 0, 0, 0,59, 0 /)
26
28
  dateAndTime2 = (/ 2000, 1, 1, 0, 0, 1, 0, 0 /)
27
29
  seconds = SecBetween(dateAndTime1, dateAndTime2)
28
- IsRealEqual( 1.0, seconds )
29
- endTest
30
+ Assert_Real_Equal( 1.0, seconds )
31
+ end test
30
32
 
31
33
  ! test secSinceLast
32
- beginTest InitializationState
33
- IsTrue(notInitialized)
34
+ test InitializationState
35
+ Assert_True(notInitialized)
34
36
  seconds = secSinceLast()
35
- IsFalse(notInitialized)
37
+ Assert_False(notInitialized)
36
38
  seconds = secSinceLast()
37
- IsFalse(notInitialized)
38
- endTest
39
+ Assert_False(notInitialized)
40
+ end test
39
41
 
40
- beginTest InitiallyReturnsZero
42
+ test InitiallyReturnsZero
41
43
  seconds = secSinceLast()
42
- IsRealEqual( 0.0, seconds )
44
+ Assert_Real_Equal( 0.0, seconds )
43
45
  call timeDelay(seconds)
44
46
  seconds = secSinceLast()
45
- IsTrue( seconds /= 0.0 )
46
- endTest
47
+ Assert_True( seconds /= 0.0 )
48
+ end test
47
49
 
48
50
  subroutine timeDelay (sum)
49
51
  integer :: i
@@ -53,14 +55,14 @@ subroutine timeDelay (sum)
53
55
  enddo
54
56
  end subroutine timeDelay
55
57
 
56
- beginTest ComputesSeconds
58
+ test ComputesSeconds
57
59
  seconds = secSinceLast()
58
60
  call timeDelay (seconds)
59
61
  seconds = secSinceLast()
60
- IsTrue( seconds > 0.0 )
61
- endTest
62
+ Assert_True( seconds > 0.0 )
63
+ end test
62
64
 
63
- beginTest ComputesSecondsSpecial
65
+ test ComputesSecondsSpecial
64
66
  real :: expectedSeconds
65
67
 
66
68
  seconds = secSinceLast()
@@ -69,5 +71,7 @@ beginTest ComputesSecondsSpecial
69
71
  seconds = secSinceLast()
70
72
  dateAndTime2 = last
71
73
  expectedSeconds = secBetween(dateAndTime1,dateAndTime2)
72
- IsRealEqual( expectedSeconds, seconds )
73
- endTest
74
+ Assert_Real_Equal( expectedSeconds, seconds )
75
+ end test
76
+
77
+ end test_suite
data/lib/funit.rb CHANGED
@@ -10,25 +10,62 @@ require 'funit/compiler'
10
10
  require 'funit/functions'
11
11
  require 'funit/assertions'
12
12
  require 'funit/testsuite'
13
+ require 'fileutils'
13
14
 
14
15
  module Funit
15
16
 
16
- ##
17
- # the version of this fUnit
18
-
19
- VERSION = '0.9.4'
17
+ VERSION = '0.10.0'
20
18
 
21
19
  ##
22
20
  # run all tests
23
21
 
24
- def run_tests
22
+ def run_tests(prog_source_dir='.')
25
23
  Compiler.new# a test for compiler env set (FIXME: remove this later)
26
- write_test_runner( test_suites = parse_command_line )
27
- test_suites.each{ |test_suite| TestSuite.new test_suite }
28
- compile_tests test_suites
24
+ write_test_runner( test_files = parse_command_line )
25
+ test_suites = []
26
+ test_files.each{ |test_file|
27
+ tf_content = IO.read(test_file+'.fun')
28
+ tf_content.scan(/test_suite\s+(\w+)(.*?)end\s+test_suite/m).each{|ts|
29
+ ts_name = $1
30
+ if((!File.exist?(ts_name+"_fun.f90")) || File.mtime(ts_name+"_fun.f90") < File.mtime(test_file+".fun")) then
31
+ TestSuite.new(ts_name, $2)
32
+ end
33
+ test_suites.push(ts_name)
34
+ }
35
+ }
36
+ compile_tests(test_suites,prog_source_dir)
29
37
  raise "TestRunner failed to execute." unless system "env PATH='.' TestRunner"
30
38
  end
31
39
 
40
+ ##
41
+ # remove files generated by fUnit
42
+
43
+ def clean_genFiles
44
+ module_names = Dir["**/*.fun"].map{|mn| mn.chomp(".fun")}
45
+ tbCancelled = module_names.map{|mn| mn+"_fun."} + ["TestRunner."]
46
+ tbCancelled = tbCancelled.map{|tbc| [tbc+"f90",tbc+"o",tbc+"MOD"]}.flatten
47
+ tbCancelled += Dir["**/TestRunner"]
48
+ tbCancelled += Dir["**/makeTestRunner"]
49
+ tbCancelled = (tbCancelled+tbCancelled.map{|tbc| tbc.downcase}).uniq
50
+ FileUtils.rm_f(tbCancelled)
51
+ end
52
+
53
+ ##
54
+ # prints a usage help for the user
55
+
56
+ def print_help
57
+ puts <<-END_OF_HELP
58
+ To use fUnit, type:
59
+ funit [-options] [test_file_name(s)]
60
+ The argument(s) is optional. If no argument is given, then all the .fun files inside the working directory will be used.
61
+
62
+ The options are:
63
+ --clean => To remove the files generated by fUnit
64
+ -h, --help => Prints this help
65
+ -s <dir>, --source <dir> => To specify a directory for the non-test source
66
+ END_OF_HELP
67
+ end
68
+
32
69
  end
33
70
 
34
71
  #--
@@ -1,4 +1,3 @@
1
- require 'strscan'
2
1
 
3
2
  module Funit
4
3
 
@@ -7,53 +6,65 @@ module Funit
7
6
 
8
7
  module Assertions
9
8
 
10
- def istrue(line)
9
+ ASSERTION_PATTERN =
10
+ /^\s*?(assert_(array_equal|real_equal|false|true|equal_within|equal))\(.*\)/i
11
+
12
+ def assert_true(line)
11
13
  line.match(/\((.+)\)/)
12
- @type = 'IsTrue'
14
+ @type = 'Assert_True'
13
15
  @condition = ".not.(#$1)"
14
16
  @message = "\"#$1 is not true\""
15
17
  syntax_error("invalid body for #@type",@suite_name) unless $1=~/\S+/
16
18
  write_assert
17
19
  end
18
20
 
19
- def isfalse(line)
21
+ def assert_false(line)
20
22
  line.match(/\((.+)\)/)
21
- @type = 'IsFalse'
23
+ @type = 'Assert_False'
22
24
  @condition = "#$1"
23
25
  @message = "\"#$1 is not false\""
24
26
  syntax_error("invalid body for #@type",@suite_name) unless $1=~/\S+/
25
27
  write_assert
26
28
  end
27
29
 
28
- def isrealequal(line)
30
+ def assert_real_equal(line)
29
31
  line.match(/\((.*)\)/)
30
32
  expected, actual = *(get_args($1))
31
- @type = 'IsRealEqual'
33
+ @type = 'Assert_Real_Equal'
32
34
  @condition = ".not.( (#{expected} &\n +2*spacing(real(#{expected})) ) &\n .ge. &\n (#{actual}) &\n .and. &\n (#{expected} &\n -2*spacing(real(#{expected})) ) &\n .le. &\n (#{actual}) )"
33
35
  @message = "\"#{actual} (\", &\n #{actual}, &\n \") is not\", &\n #{expected},\&\n \"within\", &\n 2*spacing(real(#{expected}))"
34
36
  syntax_error("invalid body for #@type",@suite_name) unless $&
35
37
  write_assert
36
38
  end
37
39
 
38
- def isequalwithin(line)
40
+ def assert_equal_within(line)
39
41
  line.match(/\((.*)\)/)
40
42
  expected, actual, tolerance = *(get_args($1))
41
- @type = 'IsEqualWithin'
43
+ @type = 'Assert_Equal_Within'
42
44
  @condition = ".not.((#{actual} &\n +#{tolerance}) &\n .ge. &\n (#{expected}) &\n .and. &\n (#{actual} &\n -#{tolerance}) &\n .le. &\n (#{expected}) )"
43
45
  @message = "\"#{expected} (\",#{expected},\") is not\", &\n #{actual},\"within\",#{tolerance}"
44
46
  syntax_error("invalid body for #@type",@suite_name) unless $&
45
47
  write_assert
46
48
  end
47
49
 
48
- def isequal(line)
50
+ def assert_equal(line)
49
51
  line.match(/\((\w+\(.*\)|[^,]+),(.+)\)/)
50
- @type = 'IsEqual'
52
+ @type = 'Assert_Equal'
51
53
  @condition = ".not.(#$1==#$2)"
52
54
  @message = "\"#$1 (\",#$1,\") is not\", #$2"
53
55
  syntax_error("invalid body for #@type",@suite_name) unless $&
54
56
  write_assert
55
57
  end
56
58
 
59
+ def assert_array_equal(line)
60
+ line.match(/\((\w+),(\w+)\)/)
61
+ @type = 'Assert_Array_Equal'
62
+ @condition = ".not. all(#$1==#$2)"
63
+ @message = "\"array #$1 is not #$2\""
64
+ syntax_error("invalid body for #@type",@suite_name) unless $&
65
+ write_assert
66
+ end
67
+
57
68
  ##
58
69
  # An argument scanner thanks to James Edward Gray II
59
70
  # by way of ruby-talk mailing list.
@@ -2,31 +2,64 @@ require 'erb'
2
2
 
3
3
  module Funit
4
4
 
5
- TEST_RUNNER = ERB.new %q{
5
+ TEST_RUNNER = ERB.new( %q{
6
6
  ! TestRunner.f90 - runs fUnit test suites
7
7
  !
8
8
  ! <%= File.basename $0 %> generated this file on <%= Time.now %>.
9
9
 
10
10
  program TestRunner
11
- <%= test_suites.inject('') { |result,test_suite| result << "\n use #{test_suite}_fun" } %>
12
11
 
13
- implicit none
12
+ <% test_suites.each do |test_suite| -%>
13
+ use <%= test_suite %>_fun
14
+ <% end -%>
14
15
 
15
- integer :: numTests, numAsserts, numAssertsTested, numFailures
16
+ implicit none
16
17
 
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 *, ""
18
+ integer, dimension(<%=test_suites.size%>) :: numTests, numAsserts, numAssertsTested, numFailures
19
+
20
+ <% test_suites.each_with_index do |test_suite,i| -%>
21
+ write(*,*)
22
+ write(*,*) "<%= test_suite %> test suite:"
23
+ call test_<%= test_suite %> &
24
+ ( numTests(<%= i+1 %>), numAsserts(<%= i+1 %>), numAssertsTested(<%= i+1 %>), numFailures(<%= i+1 %>) )
25
+ write(*,*) "Passed", numAssertsTested(<%= i+1 %>), "of", numAsserts(<%= i+1 %>), &
26
+ "possible asserts comprising", numTests(<%= i+1 %>)-numFailures(<%= i+1 %>), &
27
+ "of", numTests(<%= i+1 %>), "tests."
28
+ <% end -%>
29
+
30
+ write(*,*)
31
+ write(*,'(a)') "==========[ SUMMARY ]=========="
32
+ <% max_length = test_suites.empty? ? 0 : test_suites.max.length -%>
33
+ <% test_suites.each_with_index do |test_suite,i| -%>
34
+ write(*,'(a<%=max_length+2%>)',advance="no") " <%= test_suite %>:"
35
+ if ( numFailures(<%= i+1 %>) == 0 ) then
36
+ write(*,*) " passed"
37
+ else
38
+ write(*,*) " failed <<<<<"
39
+ end if
40
+ <% end -%>
41
+ write(*,*)
27
42
 
28
43
  end program TestRunner
29
- }.gsub(/^/,' '), nil, '<>' # turn off newlines due to <%%>
44
+ }.gsub(/^ /,''), nil, '-' ) # turn off newlines for <% -%>
45
+
46
+ MAKEFILE = ERB.new( %q{
47
+ # makefile to compile TestRunner.f90
48
+ #
49
+ # <%= File.basename $0 %> generated this file on <%= Time.now %>.
50
+
51
+ OBJ=<%= required_objects.join(' ') %>
52
+
53
+ all:testrunner
54
+
55
+ testrunner: $(OBJ)
56
+ <%= "\t#{ENV['FC']} #{ENV['FCFLAGS']}" %> -o TestRunner $(OBJ)
57
+
58
+ <% file_dependencies.each do |source,dep| -%>
59
+ <%= "#{source.sub(/\.f90/i,'.o')}: #{source} #{dep.map{ |d| d.sub(/\.f90/i,'.o') }.join(' ')}" %>
60
+ <%= "\t(cd #{File.dirname(source)}; #{ENV['FC']} #{ENV['FCFLAGS']} #{sourceflag} -c #{File.basename(source)})" %>
61
+ <% end -%>
62
+ }.gsub(/^ /,''), nil, '-' ) # turn off newlines for <% -%>
30
63
 
31
64
  def requested_modules(module_names)
32
65
  if module_names.empty?
@@ -76,13 +109,29 @@ module Funit
76
109
  $stderr.puts "\n *Warning: #{message} [#{test_suite}.fun:#$.]"
77
110
  end
78
111
 
79
- def compile_tests test_suites
112
+ def compile_tests(test_suites,prog_source_dir='.')
80
113
  puts "computing dependencies"
81
- dependencies = Fortran::Dependencies.new
114
+
115
+ # calculates parameters
116
+ if ( prog_source_dir=='.' ) then
117
+ sourceflag = ""
118
+ else
119
+ # prog_source_dir = File.expand_path(prog_source_dir) # commented as it doesn't seem necessary
120
+ sourceflag = " "+ ENV['FSFLAG'] + prog_source_dir
121
+ end
122
+ current_dir = `pwd`.chomp
123
+ sp = ['.'] + (prog_source_dir.empty? ? [] : [prog_source_dir])
124
+
125
+ dependencies = Fortran::Dependencies.new(:search_paths=> sp)
82
126
  puts "locating associated source files and sorting for compilation"
83
- required_sources = dependencies.required_source_files('TestRunner.f90')
127
+ dependencies.source_file_dependencies('TestRunner.f90')
128
+ file_dependencies = dependencies.file_dependencies
129
+ required_objects = file_dependencies.values.flatten.uniq.map{|s|s.sub(/\.f90/i,'.o')}
130
+ required_objects << 'TestRunner.o'
131
+
132
+ File.open("makeTestRunner", "w") {|file| file.puts MAKEFILE.result(binding)}
84
133
 
85
- puts compile = "#{ENV['FC']} #{ENV['FCFLAGS']} -o TestRunner #{required_sources.join(' ')}"
134
+ compile = "make -f makeTestRunner"
86
135
 
87
136
  raise "Compile failed." unless system compile
88
137
  end
@@ -1,6 +1,4 @@
1
- require 'funit/assertions'
2
- require 'funit/functions'
3
- require 'ftools' # FIXME: use fileutils
1
+ require 'funit'
4
2
 
5
3
  module Funit
6
4
 
@@ -11,15 +9,16 @@ module Funit
11
9
 
12
10
  class TestSuite < File
13
11
 
14
- ASSERTION_PATTERN = /Is(RealEqual|False|True|EqualWithin|Equal)\(.*\)/i
15
- KEYWORDS = /(begin|end)(Setup|Teardown|Test)|Is(RealEqual|Equal|False|True|EqualWithin)\(.*\)/i
12
+ KEYWORDS = Regexp.union(/(end\s+)?(setup|teardown|test)/i,
13
+ Assertions::ASSERTION_PATTERN)
16
14
  COMMENT_LINE = /^\s*!/
17
15
 
18
16
  include Funit #FIXME
19
17
 
20
- def initialize suite_name
18
+ def initialize suite_name, suite_content=''
21
19
  @line_number = 'blank'
22
20
  @suite_name = suite_name
21
+ @suite_content = suite_content
23
22
  return nil unless funit_exists?(suite_name)
24
23
  File.delete(suite_name+"_fun.f90") if File.exists?(suite_name+"_fun.f90")
25
24
  super(suite_name+"_fun.f90","w")
@@ -57,10 +56,8 @@ module #{@suite_name}_fun
57
56
  end
58
57
 
59
58
  def expand
60
- funit_file = @suite_name+".fun"
61
- $stderr.print "expanding #{funit_file}..."
62
-
63
- funit_contents = IO.readlines(funit_file)
59
+ $stderr.print "expanding test suite: #{@suite_name}..."
60
+ funit_contents = @suite_content.split("\n")
64
61
  @funit_total_lines = funit_contents.length
65
62
 
66
63
  while (line = funit_contents.shift) && line !~ KEYWORDS
@@ -75,20 +72,20 @@ module #{@suite_name}_fun
75
72
  case line
76
73
  when COMMENT_LINE
77
74
  puts line
78
- when /beginSetup/i
75
+ when /^setup/i
79
76
  add_to_setup funit_contents
80
- when /beginTeardown/i
77
+ when /^teardown/i
81
78
  add_to_teardown funit_contents
82
- when /XbeginTest\s+(\w+)/i
79
+ when /^Xtest\s+(\w+)/i
83
80
  ignore_test($1,funit_contents)
84
- when /beginTest\s+(\w+)/i
81
+ when /^test\s+(\w+)/i
85
82
  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
83
+ when /^test/i
84
+ syntax_error "no name given for test", @suite_name
85
+ when /^end\s+(setup|teardown|test)/i
86
+ syntax_error "no matching #$1 for an #$&", @suite_name
87
+ when Assertions::ASSERTION_PATTERN
88
+ syntax_error "#$1 assertion not in a test block", @suite_name
92
89
  else
93
90
  puts line
94
91
  end
@@ -97,20 +94,20 @@ module #{@suite_name}_fun
97
94
  end
98
95
 
99
96
  def add_to_setup funit_contents
100
- while (line = funit_contents.shift) && line !~ /endSetup/i
97
+ while (line = funit_contents.shift) && line !~ /end\s+setup/i
101
98
  @setup.push line
102
99
  end
103
100
  end
104
101
 
105
102
  def add_to_teardown funit_contents
106
- while (line = funit_contents.shift) && line !~ /endTeardown/i
103
+ while (line = funit_contents.shift) && line !~ /end\s+teardown/i
107
104
  @teardown.push line
108
105
  end
109
106
  end
110
107
 
111
108
  def ignore_test test_name, funit_contents
112
109
  warning("Ignoring test: #{test_name}", @suite_name)
113
- line = funit_contents.shift while line !~ /endTest/i
110
+ line = funit_contents.shift while line !~ /end\s+Test/i
114
111
  end
115
112
 
116
113
  def a_test test_name, funit_contents
@@ -122,14 +119,14 @@ module #{@suite_name}_fun
122
119
 
123
120
  num_of_asserts = 0
124
121
 
125
- while (line = funit_contents.shift) && line !~ /endTest/i
122
+ while (line = funit_contents.shift) && line !~ /end\s+test/i
126
123
  case line
127
124
  when COMMENT_LINE
128
125
  puts line
129
- when /Is(RealEqual|False|True|EqualWithin|Equal)/i
126
+ when Assertions::ASSERTION_PATTERN
130
127
  @line_number = @funit_total_lines - funit_contents.length
131
128
  num_of_asserts += 1
132
- puts send( $&.downcase!, line )
129
+ puts send( $1.downcase, line )
133
130
  else
134
131
  puts line
135
132
  end
@@ -194,4 +191,4 @@ end
194
191
  #
195
192
  # This file is governed by the NASA Open Source Agreement.
196
193
  # See License.txt for details.
197
- #++
194
+ #++
data/test/test_funit.rb CHANGED
@@ -4,106 +4,120 @@ require 'ftools' # FIXME: migrate to fileutils
4
4
 
5
5
  class TestFunit < Test::Unit::TestCase
6
6
 
7
+ alias_method :tu_assert_equal, :assert_equal # avoid collision with test/unit
8
+
7
9
  include Funit # FIXME
8
10
  include Funit::Assertions # FIXME
9
11
 
10
12
  def setup
11
13
  File.rm_f(*Dir["dummyunit*"])
12
14
  File.rm_f(*Dir["unit*"])
15
+ File.rm_f(*Dir["another*"])
13
16
  File.rm_f(*Dir["ydsbe*"])
14
17
  File.rm_f(*Dir["lmzd*"])
15
18
  File.rm_f(*Dir["ldfdl*"])
16
19
  File.rm_f(*Dir["ydsbe*"])
17
- File.rm_f(*Dir["TestRunner*"])
18
- File.rm_f(*Dir["a.out"])
20
+ File.rm_f(*Dir["*TestRunner*"])
19
21
  end
20
22
 
21
23
  def teardown
22
24
  File.rm_f(*Dir["dummyunit*"])
23
25
  File.rm_f(*Dir["unit*"])
26
+ File.rm_f(*Dir["another*"])
24
27
  File.rm_f(*Dir["ydsbe*"])
25
28
  File.rm_f(*Dir["lmzd*"])
26
29
  File.rm_f(*Dir["ldfdl*"])
27
30
  File.rm_f(*Dir["ydsbe*"])
28
- File.rm_f(*Dir["TestRunner*"])
29
- File.rm_f(*Dir["a.out"])
31
+ File.rm_f(*Dir["*TestRunner*"])
30
32
  end
31
33
 
32
- def test_main_driver_compiles
34
+ def test_empty_test_runner_created_and_compilable
33
35
  write_test_runner []
34
- assert File.exists?("TestRunner.f90")
35
- assert system("#{ENV['FC']} TestRunner.f90")
36
- assert File.exists?("a.out")
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.'
37
41
  end
38
42
 
39
43
  def test_is_equal
40
44
  @suite_name = "dummy"
41
45
  @test_name = "dummy"
42
46
  @line_number = "dummy"
43
- isequal("IsEqual(1.0,m(1,1))")
44
- assert_equal '.not.(1.0==m(1,1))', @condition
45
- end
47
+ assert_equal("AssertEqual(1.0,m(1,1))")
48
+ tu_assert_equal '.not.(1.0==m(1,1))', @condition
49
+ end
46
50
 
47
51
  def test_is_real_equal
48
52
  @suite_name = "dummy"
49
53
  @test_name = "dummy"
50
54
  @line_number = "dummy"
51
- isrealequal("IsRealEqual(a,b)")
55
+ assert_real_equal("AssertRealEqual(a,b)")
52
56
  ans = <<-EOF
53
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) )
54
58
  EOF
55
- assert_equal ans.chomp, @condition
56
- assert_equal %|"b (", &\n b, &\n ") is not", &\n a,&\n "within", &\n 2*spacing(real(a))|, @message
57
- isrealequal("IsRealEqual(1.0,m(1,1))")
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))")
58
62
  ans = <<-EOF
59
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)) )
60
64
  EOF
61
- assert_equal ans.chomp, @condition
65
+ tu_assert_equal ans.chomp, @condition
62
66
  end
63
67
 
64
- def test_handles_dependency
68
+ def test_should_accommodate_use_dependency_at_least_one_level_deep
65
69
  File.open('unit.f90','w') do |f|
66
- f.printf "module unit\n use unita, only : a\nend module unit\n"
70
+ f.puts "module unit\n use another, only : a\nend module unit"
67
71
  end
68
- File.open('unita.f90','w') do |f|
69
- f.printf "module unita\n integer :: a = 5\nend module unita\n"
72
+ File.open('another.f90','w') do |f|
73
+ f.puts "module another\n integer :: a = 5\nend module another"
70
74
  end
71
75
  File.open('unit.fun','w') do |f|
72
- f.printf "beginTest a_gets_set\n IsEqual(5, a)\nendTest\n"
76
+ f.puts "test_suite unit\ntest a_gets_set\nAssert_Equal(5,a)\nend test\nend test_suite"
73
77
  end
74
78
  assert_nothing_raised{run_tests}
75
79
  end
76
80
 
77
- def test_embedded_dependencies
81
+ def test_should_accommodate_doubly_embedded_use_dependencies
78
82
  File.open('unit.f90','w') do |f|
79
- f.printf "module unit\n use unita, only : a\nend module unit\n"
83
+ f.puts "module unit\n use unita, only : a\nend module unit"
80
84
  end
81
85
  File.open('unita.f90','w') do |f|
82
- f.printf "module unita\n use unitb, only : b \n integer :: a = b\nend module unita\n"
86
+ f.puts "module unita\n use unitb, only : b\n integer :: a = b\nend module unita"
83
87
  end
84
88
  File.open('unitb.f90','w') do |f|
85
- f.printf "module unitb\n integer,parameter :: b = 5\nend module unitb\n"
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"
86
100
  end
87
101
  File.open('unit.fun','w') do |f|
88
- f.printf "beginTest a_gets_set\n IsEqual(5, a)\nendTest\n"
102
+ f.puts "begin test_suite unit\ntest a_gets_set\n Assert_Equal(1, a)\nend test\nend test_suite"
89
103
  end
90
104
  assert_nothing_raised{run_tests}
91
105
  end
92
106
 
93
107
  def test_requested_modules
94
- assert_equal ["asdfga"], requested_modules(["asdfga"])
95
- assert_equal ["asd","fga"], requested_modules(["asd","fga"])
108
+ tu_assert_equal ["asdfga"], requested_modules(["asdfga"])
109
+ tu_assert_equal ["asd","fga"], requested_modules(["asd","fga"])
96
110
  assert requested_modules([]).empty?
97
111
  modules = %w[ldfdl lmzd]
98
112
  funits = modules.map{|f| f+'.fun'}.join(' ')
99
113
  system "touch "+funits
100
- assert_equal modules, requested_modules([])
114
+ tu_assert_equal modules, requested_modules([])
101
115
  end
102
116
 
103
117
  def test_funit_exists_method
104
118
  module_name = "ydsbe"
105
119
  File.rm_f(module_name+".fun")
106
- assert_equal false, funit_exists?(module_name)
120
+ tu_assert_equal false, funit_exists?(module_name)
107
121
  system "touch "+module_name+".fun"
108
122
  assert funit_exists?(module_name)
109
123
  end
@@ -1,14 +1,19 @@
1
1
  require 'test/unit'
2
2
  require 'funit/testsuite'
3
3
 
4
+ require 'fileutils'
5
+ include FileUtils
6
+
4
7
  class TestTestSuite < Test::Unit::TestCase
5
8
 
6
9
  def setup
7
- File.rm_f(*Dir["dummyf90test*"])
10
+ files = *Dir["dummyf90test*"]
11
+ rm_f files if files
8
12
  end
9
13
 
10
14
  def teardown
11
- File.rm_f(*Dir["dummyf90test*"])
15
+ files = *Dir["dummyf90test*"]
16
+ rm_f files if files
12
17
  end
13
18
 
14
19
  def test_nonexistent_funit_file_is_not_created
@@ -53,7 +58,7 @@ class TestTestSuite < Test::Unit::TestCase
53
58
  end
54
59
 
55
60
  def test_single_assert_test_compiles
56
- create_funit_file "beginTest assertTrue\nIsTrue(.true.)\nendTest"
61
+ create_funit_file "beginTest assertTrue\nAssertTrue(.true.)\nendTest"
57
62
  Funit::TestSuite.new 'dummyf90test'
58
63
  assert system(@@compileCommand)
59
64
  end
@@ -63,7 +68,7 @@ class TestTestSuite < Test::Unit::TestCase
63
68
  beginTest assertTrue
64
69
  integer :: a(2,2)
65
70
  a = 1
66
- IsEqual(1,a(1,1))
71
+ AssertEqual(1,a(1,1))
67
72
  endTest
68
73
  MATRIX
69
74
  Funit::TestSuite.new 'dummyf90test'
@@ -75,7 +80,7 @@ class TestTestSuite < Test::Unit::TestCase
75
80
  beginTest assert_equals
76
81
  real :: real_var
77
82
  real_var = 1.0
78
- IsRealEqual(1.0,real_var)
83
+ AssertRealEqual(1.0,real_var)
79
84
  endTest
80
85
  REALEQUALS
81
86
  Funit::TestSuite.new 'dummyf90test'
@@ -85,7 +90,7 @@ class TestTestSuite < Test::Unit::TestCase
85
90
  def test_real_equals_assert_works_with_function
86
91
  create_funit_file <<-REQUALSFUNC
87
92
  beginTest assert_equals_for_function
88
- IsRealEqual(0.0,balance(0.0,0.0))
93
+ AssertRealEqual(0.0,balance(0.0,0.0))
89
94
  endTest
90
95
  function balance( left, right)
91
96
  real :: balance
@@ -3,18 +3,20 @@
3
3
  (define-generic-mode 'funit-generic-mode
4
4
  (list ?!)
5
5
  (list
6
- "beginTest"
7
- "endTest"
8
- "beginSetup"
9
- "endSetup"
10
- "beginTeardown"
11
- "endTeardown"
6
+ "test_suite"
7
+ "end test_suite"
8
+ "test"
9
+ "end test"
10
+ "setup"
11
+ "end setup"
12
+ "teardown"
13
+ "end teardown"
12
14
  )
13
- '(("\\(IsFalse\\)" 1 'font-lock-function-name-face)
14
- ("\\(IsTrue\\)" 1 'font-lock-function-name-face)
15
- ("\\(IsEqualWithin\\)" 1 'font-lock-function-name-face)
16
- ("\\(IsEqual\\)" 1 'font-lock-function-name-face)
17
- ("\\(IsRealEqual\\)" 1 'font-lock-function-name-face))
15
+ '(("\\(Assert_False\\)" 1 'font-lock-function-name-face)
16
+ ("\\(Assert_True\\)" 1 'font-lock-function-name-face)
17
+ ("\\(Assert_Equal_Within\\)" 1 'font-lock-function-name-face)
18
+ ("\\(Assert_Equal\\)" 1 'font-lock-function-name-face)
19
+ ("\\(Assert_Real_Equal\\)" 1 'font-lock-function-name-face))
18
20
  (list "\\.fun\\'")
19
21
  nil
20
22
  "Generic mode for fUnit files.")
data/utils/funit-mode.el CHANGED
@@ -30,17 +30,19 @@
30
30
 
31
31
  ;; add some new font-locks to f90's extensive list
32
32
  (font-lock-add-keywords 'funit-mode
33
- '(("\\<IsFalse\\>" . font-lock-function-name-face)
34
- ("\\<IsEqual\\>" . font-lock-function-name-face)
35
- ("\\<IsRealEqual\\>" . font-lock-function-name-face)
36
- ("\\<IsTrue\\>" . font-lock-function-name-face)
37
- ("\\<IsEqualWithin\\>" . font-lock-function-name-face)
38
- ("\\<beginTest\\>" . font-lock-builtin-face)
39
- ("\\<endTest\\>" . font-lock-builtin-face)
40
- ("\\<beginTeardown\\>" . font-lock-builtin-face)
41
- ("\\<endTeardown\\>" . font-lock-builtin-face)
42
- ("\\<beginSetup\\>" . font-lock-builtin-face)
43
- ("\\<endSetup\\>" . font-lock-builtin-face))
33
+ '(("\\<Assert_False\\>" . font-lock-function-name-face)
34
+ ("\\<Assert_Equal\\>" . font-lock-function-name-face)
35
+ ("\\<Assert_Real_Equal\\>" . font-lock-function-name-face)
36
+ ("\\<Assert_True\\>" . font-lock-function-name-face)
37
+ ("\\<Assert_Equal_Within\\>" . font-lock-function-name-face)
38
+ ("\\<test_suite\\>" . font-lock-builtin-face)
39
+ ("\\<end test_suite\\>" . font-lock-builtin-face)
40
+ ("\\<test\\>" . font-lock-builtin-face)
41
+ ("\\<end test\\>" . font-lock-builtin-face)
42
+ ("\\<teardown\\>" . font-lock-builtin-face)
43
+ ("\\<end teardown\\>" . font-lock-builtin-face)
44
+ ("\\<setup\\>" . font-lock-builtin-face)
45
+ ("\\<end setup\\>" . font-lock-builtin-face))
44
46
  )
45
47
 
46
48
  (defvar funit-buffer-command "funit"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: funit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.4
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Karen Bibb
@@ -13,7 +13,7 @@ autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
15
 
16
- date: 2008-03-30 00:00:00 -04:00
16
+ date: 2008-03-31 00:00:00 -04:00
17
17
  default_executable:
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency