funit 0.9.4 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
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