bahuvrihi-tap 0.10.1 → 0.10.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History +9 -0
- data/README +1 -0
- data/bin/tap +1 -1
- data/cmd/run.rb +2 -23
- data/lib/tap/constants.rb +1 -1
- data/lib/tap/exe.rb +71 -11
- data/lib/tap/root.rb +27 -23
- data/lib/tap/spec.rb +67 -0
- data/lib/tap/spec/adapter.rb +48 -0
- data/lib/tap/spec/file_methods.rb +16 -0
- data/lib/tap/spec/file_methods_class.rb +13 -0
- data/lib/tap/spec/subset_methods.rb +14 -0
- data/lib/tap/support/command_line.rb +0 -43
- data/lib/tap/support/command_line/parser.rb +121 -0
- data/lib/tap/support/configurable_class.rb +3 -3
- data/lib/tap/support/declarations.rb +2 -2
- data/lib/tap/support/framework_class.rb +6 -4
- data/lib/tap/support/gems/rake.rb +4 -4
- data/lib/tap/support/lazydoc.rb +10 -1
- data/lib/tap/test.rb +82 -1
- data/lib/tap/test/env_vars.rb +1 -1
- data/lib/tap/test/file_methods.rb +128 -138
- data/lib/tap/test/file_methods_class.rb +26 -0
- data/lib/tap/test/script_methods.rb +7 -24
- data/lib/tap/test/subset_methods.rb +6 -163
- data/lib/tap/test/subset_methods_class.rb +128 -0
- data/lib/tap/test/tap_methods.rb +1 -33
- data/lib/tap/test/utils.rb +118 -0
- metadata +10 -1
@@ -0,0 +1,26 @@
|
|
1
|
+
module Tap
|
2
|
+
module Test
|
3
|
+
module FileMethodsClass
|
4
|
+
|
5
|
+
# Access the test root structure (a Tap::Root)
|
6
|
+
attr_accessor :trs
|
7
|
+
|
8
|
+
# Infers the test root directory from the calling file. Ex:
|
9
|
+
# 'some_class.rb' => 'some_class'
|
10
|
+
# 'some_class_test.rb' => 'some_class'
|
11
|
+
def file_test_root
|
12
|
+
# the calling file is not the direct caller of +method_root+... this method is
|
13
|
+
# only accessed from within another method call, hence the target caller is caller[1]
|
14
|
+
# rather than caller[0].
|
15
|
+
|
16
|
+
# caller[1] is considered the calling file (which should be the test case)
|
17
|
+
# note that the output of calller.first is like:
|
18
|
+
# ./path/to/file.rb:10
|
19
|
+
# ./path/to/file.rb:10:in 'method'
|
20
|
+
calling_file = caller[1].gsub(/:\d+(:in .*)?$/, "")
|
21
|
+
calling_file.chomp!("#{File.extname(calling_file)}")
|
22
|
+
calling_file.chomp("_test")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,32 +1,15 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'tap/test/file_methods'
|
3
1
|
require 'tap/test/subset_methods'
|
4
2
|
require 'tap/test/script_methods/script_test'
|
5
3
|
|
6
|
-
module Test # :nodoc:
|
7
|
-
module Unit # :nodoc:
|
8
|
-
class TestCase
|
9
|
-
class << self
|
10
|
-
|
11
|
-
def acts_as_script_test(options={})
|
12
|
-
options = options.inject({:root => file_test_root}) do |hash, (key, value)|
|
13
|
-
hash[key.to_sym || key] = value
|
14
|
-
hash
|
15
|
-
end
|
16
|
-
acts_as_file_test(options)
|
17
|
-
include Tap::Test::SubsetMethods
|
18
|
-
include Tap::Test::ScriptMethods
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
4
|
module Tap
|
27
5
|
module Test
|
28
6
|
module ScriptMethods
|
29
|
-
|
7
|
+
|
8
|
+
def self.included(base)
|
9
|
+
super
|
10
|
+
base.send(:include, Tap::Test::SubsetMethods)
|
11
|
+
end
|
12
|
+
|
30
13
|
def assert_output_equal(a, b, msg)
|
31
14
|
a = a[1..-1] if a[0] == ?\n
|
32
15
|
if a == b
|
@@ -81,7 +64,7 @@ module Tap
|
|
81
64
|
cmd = ScriptTest.new(default_command_path)
|
82
65
|
yield(cmd)
|
83
66
|
|
84
|
-
Tap::Root.
|
67
|
+
Tap::Root.chdir(test_dir, true) do
|
85
68
|
with_argv do
|
86
69
|
puts "\n# == #{method_name}"
|
87
70
|
|
@@ -1,167 +1,5 @@
|
|
1
|
-
require 'test/unit'
|
2
1
|
require 'benchmark'
|
3
|
-
require '
|
4
|
-
require 'tap/test/env_vars'
|
5
|
-
|
6
|
-
module Test # :nodoc:
|
7
|
-
module Unit # :nodoc:
|
8
|
-
class TestCase
|
9
|
-
class << self
|
10
|
-
include Tap::Test::EnvVars
|
11
|
-
|
12
|
-
# Passes conditions to subclass
|
13
|
-
def inherited(subclass) # :nodoc:
|
14
|
-
super
|
15
|
-
subclass_conditions = conditions.inject({}) do |memo, (key, value)|
|
16
|
-
memo.update(key => (value.dup rescue value))
|
17
|
-
end
|
18
|
-
subclass.instance_variable_set(:@conditions, subclass_conditions)
|
19
|
-
subclass.instance_variable_set(:@run_test_suite, nil)
|
20
|
-
subclass.instance_variable_set(:@skip_messages, [])
|
21
|
-
|
22
|
-
# subclass_inputs = prompt_inputs.inject({}) do |memo, (key, value)|
|
23
|
-
# memo.update(key => (value.dup rescue value))
|
24
|
-
# end
|
25
|
-
# subclass.instance_variable_set("@prompt_inputs", subclass_inputs)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Experimental -- The idea is to provide a way to prompt once for inputs
|
29
|
-
# that get used multiple times in a test. Perhaps create accessors
|
30
|
-
# automatically?
|
31
|
-
|
32
|
-
# def prompt_inputs
|
33
|
-
# @prompt_inputs ||= {}
|
34
|
-
# end
|
35
|
-
|
36
|
-
# def require_inputs(*keys, &block)
|
37
|
-
# if run_subset?("PROMPT")
|
38
|
-
# puts "\n#{name} requires inputs -- Enter values or 'skip'."
|
39
|
-
|
40
|
-
# argv = ARGV.dup
|
41
|
-
# begin
|
42
|
-
# ARGV.clear
|
43
|
-
# keys.collect do |key|
|
44
|
-
# print "#{key}: "
|
45
|
-
# value = gets.strip
|
46
|
-
# if value =~ /skip/i
|
47
|
-
# skip_test "missing inputs"
|
48
|
-
# break
|
49
|
-
# end
|
50
|
-
# prompt_inputs[key] = value
|
51
|
-
# end
|
52
|
-
# ensure
|
53
|
-
# ARGV.clear
|
54
|
-
# ARGV.concat(argv)
|
55
|
-
# end
|
56
|
-
# else
|
57
|
-
# skip_test "prompt test"
|
58
|
-
# end
|
59
|
-
# end
|
60
|
-
|
61
|
-
#
|
62
|
-
# conditions
|
63
|
-
#
|
64
|
-
|
65
|
-
# A hash of defined conditions
|
66
|
-
def conditions
|
67
|
-
@conditions ||= {}
|
68
|
-
end
|
69
|
-
|
70
|
-
# Defines a condition block and associated message.
|
71
|
-
# Raises an error if no condition block is given.
|
72
|
-
def condition(name, msg=nil, &block)
|
73
|
-
raise "no condition block given" unless block_given?
|
74
|
-
conditions[name.to_sym] = [msg, block]
|
75
|
-
end
|
76
|
-
|
77
|
-
# Returns true if the all blocks for the named conditions return true.
|
78
|
-
#
|
79
|
-
# condition(:is_true) { true }
|
80
|
-
# condition(:is_false) { false }
|
81
|
-
# satisfied?(:is_true) # => true
|
82
|
-
# satisfied?(:is_true, :is_false) # => false
|
83
|
-
#
|
84
|
-
def satisfied?(*conditions)
|
85
|
-
unsatisfied_conditions(*conditions).empty?
|
86
|
-
end
|
87
|
-
|
88
|
-
# Returns an array of the unsatified conditions. Raises
|
89
|
-
# an error if the named condition has not been defined.
|
90
|
-
#
|
91
|
-
# condition(:is_true) { true }
|
92
|
-
# condition(:is_false) { false }
|
93
|
-
# unsatisfied_conditions(:is_true, :is_false) # => [:is_false]
|
94
|
-
#
|
95
|
-
def unsatisfied_conditions(*conditions)
|
96
|
-
conditions = self.conditions.keys if conditions.empty?
|
97
|
-
unsatified = []
|
98
|
-
conditions.each do |condition|
|
99
|
-
raise "Unknown condition: #{condition}" unless self.conditions.has_key?(condition)
|
100
|
-
unsatified << condition unless (self.conditions[condition.to_sym].last.call() ? true : false)
|
101
|
-
end
|
102
|
-
unsatified
|
103
|
-
end
|
104
|
-
|
105
|
-
# Returns true if RUBY_PLATFORM matches one of the specfied
|
106
|
-
# platforms. Use the prefix 'non_' to specify any plaform
|
107
|
-
# except the specified platform (ex: 'non_mswin'). Returns
|
108
|
-
# true if no platforms are specified.
|
109
|
-
#
|
110
|
-
# Some common platforms:
|
111
|
-
# mswin Windows
|
112
|
-
# darwin Mac
|
113
|
-
def match_platform?(*platforms)
|
114
|
-
platforms.each do |platform|
|
115
|
-
platform.to_s =~ /^(non_)?(.*)/
|
116
|
-
|
117
|
-
non = true if $1
|
118
|
-
match_platform = !RUBY_PLATFORM.index($2).nil?
|
119
|
-
return false unless (non && !match_platform) || (!non && match_platform)
|
120
|
-
end
|
121
|
-
|
122
|
-
true
|
123
|
-
end
|
124
|
-
|
125
|
-
# Returns true if the subset type or 'ALL' is specified in ENV
|
126
|
-
def run_subset?(type)
|
127
|
-
env_true?(type) || env_true?("ALL") ? true : false
|
128
|
-
end
|
129
|
-
|
130
|
-
#
|
131
|
-
# Methods for skipping a test suite
|
132
|
-
#
|
133
|
-
attr_accessor :run_test_suite
|
134
|
-
|
135
|
-
# Returns run_test_suite, or true if run_test_suite is not set.
|
136
|
-
def run_test_suite?
|
137
|
-
run_test_suite.nil? ? true : run_test_suite
|
138
|
-
end
|
139
|
-
|
140
|
-
# Causes a test suite to be skipped. If a message is given, it will
|
141
|
-
# print and notify the user the test suite has been skipped.
|
142
|
-
def skip_test(msg=nil)
|
143
|
-
self.run_test_suite = false
|
144
|
-
|
145
|
-
# experimental -- perhaps use this so that a test can be skipped
|
146
|
-
# for multiple reasons?
|
147
|
-
@skip_messages << msg unless msg.nil?
|
148
|
-
end
|
149
|
-
|
150
|
-
alias :original_suite :suite
|
151
|
-
|
152
|
-
# Modifies the default suite method to include/exclude tests based on platform.
|
153
|
-
def suite # :nodoc:
|
154
|
-
if run_test_suite?
|
155
|
-
original_suite
|
156
|
-
else
|
157
|
-
puts "Skipping #{name}: #{@skip_messages.join(', ')}" unless @skip_messages.empty?
|
158
|
-
Test::Unit::TestSuite.new(name)
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
2
|
+
require 'tap/test/subset_methods_class'
|
165
3
|
|
166
4
|
module Tap
|
167
5
|
module Test
|
@@ -247,6 +85,11 @@ module Tap
|
|
247
85
|
# See {Test::Unit::TestCase}[link:classes/Test/Unit/TestCase.html] for documentation of the class methods added by SubsetMethods
|
248
86
|
module SubsetMethods
|
249
87
|
include Tap::Test::EnvVars
|
88
|
+
|
89
|
+
def self.included(base)
|
90
|
+
super
|
91
|
+
base.extend SubsetMethodsClass
|
92
|
+
end
|
250
93
|
|
251
94
|
def satisfied?(*conditions)
|
252
95
|
self.class.satisfied?(*conditions)
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'tap/test/env_vars'
|
2
|
+
|
3
|
+
module Tap
|
4
|
+
module Test
|
5
|
+
module SubsetMethodsClass
|
6
|
+
include Tap::Test::EnvVars
|
7
|
+
|
8
|
+
# Passes conditions to subclass
|
9
|
+
def inherited(subclass) # :nodoc:
|
10
|
+
super
|
11
|
+
subclass_conditions = conditions.inject({}) do |memo, (key, value)|
|
12
|
+
memo.update(key => (value.dup rescue value))
|
13
|
+
end
|
14
|
+
subclass.instance_variable_set(:@conditions, subclass_conditions)
|
15
|
+
subclass.instance_variable_set(:@run_test_suite, nil)
|
16
|
+
subclass.instance_variable_set(:@skip_messages, [])
|
17
|
+
|
18
|
+
# subclass_inputs = prompt_inputs.inject({}) do |memo, (key, value)|
|
19
|
+
# memo.update(key => (value.dup rescue value))
|
20
|
+
# end
|
21
|
+
# subclass.instance_variable_set("@prompt_inputs", subclass_inputs)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Experimental -- The idea is to provide a way to prompt once for inputs
|
25
|
+
# that get used multiple times in a test. Perhaps create accessors
|
26
|
+
# automatically?
|
27
|
+
|
28
|
+
# def prompt_inputs
|
29
|
+
# @prompt_inputs ||= {}
|
30
|
+
# end
|
31
|
+
|
32
|
+
# def require_inputs(*keys, &block)
|
33
|
+
# if run_subset?("PROMPT")
|
34
|
+
# puts "\n#{name} requires inputs -- Enter values or 'skip'."
|
35
|
+
|
36
|
+
# argv = ARGV.dup
|
37
|
+
# begin
|
38
|
+
# ARGV.clear
|
39
|
+
# keys.collect do |key|
|
40
|
+
# print "#{key}: "
|
41
|
+
# value = gets.strip
|
42
|
+
# if value =~ /skip/i
|
43
|
+
# skip_test "missing inputs"
|
44
|
+
# break
|
45
|
+
# end
|
46
|
+
# prompt_inputs[key] = value
|
47
|
+
# end
|
48
|
+
# ensure
|
49
|
+
# ARGV.clear
|
50
|
+
# ARGV.concat(argv)
|
51
|
+
# end
|
52
|
+
# else
|
53
|
+
# skip_test "prompt test"
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
|
57
|
+
#
|
58
|
+
# conditions
|
59
|
+
#
|
60
|
+
|
61
|
+
# A hash of defined conditions
|
62
|
+
def conditions
|
63
|
+
@conditions ||= {}
|
64
|
+
end
|
65
|
+
|
66
|
+
# Defines a condition block and associated message.
|
67
|
+
# Raises an error if no condition block is given.
|
68
|
+
def condition(name, msg=nil, &block)
|
69
|
+
raise "no condition block given" unless block_given?
|
70
|
+
conditions[name.to_sym] = [msg, block]
|
71
|
+
end
|
72
|
+
|
73
|
+
# Returns true if the all blocks for the named conditions return true.
|
74
|
+
#
|
75
|
+
# condition(:is_true) { true }
|
76
|
+
# condition(:is_false) { false }
|
77
|
+
# satisfied?(:is_true) # => true
|
78
|
+
# satisfied?(:is_true, :is_false) # => false
|
79
|
+
#
|
80
|
+
def satisfied?(*conditions)
|
81
|
+
unsatisfied_conditions(*conditions).empty?
|
82
|
+
end
|
83
|
+
|
84
|
+
# Returns an array of the unsatified conditions. Raises
|
85
|
+
# an error if the named condition has not been defined.
|
86
|
+
#
|
87
|
+
# condition(:is_true) { true }
|
88
|
+
# condition(:is_false) { false }
|
89
|
+
# unsatisfied_conditions(:is_true, :is_false) # => [:is_false]
|
90
|
+
#
|
91
|
+
def unsatisfied_conditions(*conditions)
|
92
|
+
conditions = self.conditions.keys if conditions.empty?
|
93
|
+
unsatified = []
|
94
|
+
conditions.each do |condition|
|
95
|
+
raise "Unknown condition: #{condition}" unless self.conditions.has_key?(condition)
|
96
|
+
unsatified << condition unless (self.conditions[condition.to_sym].last.call() ? true : false)
|
97
|
+
end
|
98
|
+
unsatified
|
99
|
+
end
|
100
|
+
|
101
|
+
# Returns true if RUBY_PLATFORM matches one of the specfied
|
102
|
+
# platforms. Use the prefix 'non_' to specify any plaform
|
103
|
+
# except the specified platform (ex: 'non_mswin'). Returns
|
104
|
+
# true if no platforms are specified.
|
105
|
+
#
|
106
|
+
# Some common platforms:
|
107
|
+
# mswin Windows
|
108
|
+
# darwin Mac
|
109
|
+
def match_platform?(*platforms)
|
110
|
+
platforms.each do |platform|
|
111
|
+
platform.to_s =~ /^(non_)?(.*)/
|
112
|
+
|
113
|
+
non = true if $1
|
114
|
+
match_platform = !RUBY_PLATFORM.index($2).nil?
|
115
|
+
return false unless (non && !match_platform) || (!non && match_platform)
|
116
|
+
end
|
117
|
+
|
118
|
+
true
|
119
|
+
end
|
120
|
+
|
121
|
+
# Returns true if the subset type or 'ALL' is specified in ENV
|
122
|
+
def run_subset?(type)
|
123
|
+
env_true?(type) || env_true?("ALL") ? true : false
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
end
|
data/lib/tap/test/tap_methods.rb
CHANGED
@@ -1,35 +1,3 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'tap/test/file_methods'
|
3
|
-
require 'tap/test/subset_methods'
|
4
|
-
|
5
|
-
module Test # :nodoc:
|
6
|
-
module Unit # :nodoc:
|
7
|
-
class TestCase
|
8
|
-
class << self
|
9
|
-
# Causes a unit test to act as a tap test -- resulting in the following:
|
10
|
-
# - setup using acts_as_file_test
|
11
|
-
# - inclusion of Tap::Test::SubsetMethods
|
12
|
-
# - inclusion of Tap::Test::InstanceMethods
|
13
|
-
#
|
14
|
-
# Note: Unless otherwise specified, <tt>acts_as_tap_test</tt> infers a root directory
|
15
|
-
# based on the calling file. Be sure to specify the root directory explicitly
|
16
|
-
# if you call acts_as_file_test from a file that is NOT meant to be test file.
|
17
|
-
def acts_as_tap_test(options={})
|
18
|
-
options = options.inject({:root => file_test_root}) do |hash, (key, value)|
|
19
|
-
hash[key.to_sym || key] = value
|
20
|
-
hash
|
21
|
-
end
|
22
|
-
acts_as_file_test(options)
|
23
|
-
|
24
|
-
include Tap::Test::SubsetMethods
|
25
|
-
include Tap::Test::TapMethods
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
1
|
module Tap
|
34
2
|
module Test
|
35
3
|
|
@@ -97,7 +65,7 @@ module Tap
|
|
97
65
|
# Asserts that an array of audits are all equal, basically feeding
|
98
66
|
# each pair of audits to assert_audit_equal.
|
99
67
|
def assert_audits_equal(expected, audits)
|
100
|
-
each_pair_with_index(expected, audits) do |exp, audit, index|
|
68
|
+
Utils.each_pair_with_index(expected, audits) do |exp, audit, index|
|
101
69
|
assert_audit_equal(exp, audit, [index])
|
102
70
|
end
|
103
71
|
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'tap/root'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Tap
|
5
|
+
module Test
|
6
|
+
module Utils
|
7
|
+
module_function
|
8
|
+
|
9
|
+
# Generates an array of [source, reference] pairs mapping source
|
10
|
+
# files to reference files under the source_dir and reference_dir,
|
11
|
+
# respectively. Only files under source dir with the reference_extname
|
12
|
+
# will be mapped; mappings are either:
|
13
|
+
#
|
14
|
+
# - a direct translation from source_dir to reference_dir, minus
|
15
|
+
# the extname
|
16
|
+
# - a path under reference_dir with a matching basename, minus
|
17
|
+
# the extname, so long as the matched path is unique
|
18
|
+
#
|
19
|
+
# If a mapped path cannot be found, dereference raises an ArgumentError.
|
20
|
+
#
|
21
|
+
# === example
|
22
|
+
#
|
23
|
+
# root
|
24
|
+
# |- input
|
25
|
+
# | |- dir.ref
|
26
|
+
# | |- ignored.txt
|
27
|
+
# | |- one.txt.ref
|
28
|
+
# | `- two.txt.ref
|
29
|
+
# `- ref
|
30
|
+
# |- dir
|
31
|
+
# |- one.txt
|
32
|
+
# `- path
|
33
|
+
# `- to
|
34
|
+
# `- two.txt
|
35
|
+
#
|
36
|
+
# reference_map('/root/input', '/root/ref')
|
37
|
+
# # => [
|
38
|
+
# # ['/root/input/dir.ref', '/root/ref/dir'],
|
39
|
+
# # ['/root/input/one.txt.ref', '/root/ref/one.txt'],
|
40
|
+
# # ['/root/input/two.txt.ref', '/root/ref/path/to/two.txt']]
|
41
|
+
#
|
42
|
+
# reference_map(:input, :ref, ".txt") # !> ArgumentError
|
43
|
+
#
|
44
|
+
def reference_map(source_dir, reference_dir, reference_extname='.ref')
|
45
|
+
Dir.glob(File.join(source_dir, "**/*#{reference_extname}")).collect do |path|
|
46
|
+
relative_path = Tap::Root.relative_filepath(source_dir, path).chomp(reference_extname)
|
47
|
+
reference_path = File.join(reference_dir, relative_path)
|
48
|
+
|
49
|
+
unless File.exists?(reference_path)
|
50
|
+
matching_paths = Dir.glob(File.join(reference_dir, "**/#{File.basename(relative_path)}"))
|
51
|
+
|
52
|
+
reference_path = case matching_paths.length
|
53
|
+
when 0 then raise ArgumentError, "no reference found for: #{path}"
|
54
|
+
when 1 then matching_paths[0]
|
55
|
+
else raise ArgumentError, "multiple references found for: #{path} [#{matching_paths.join(', ')}]"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
[path, reference_path]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def dereference(source_dirs, reference_dir, extname='.ref')
|
64
|
+
mapped_paths = []
|
65
|
+
begin
|
66
|
+
[*source_dirs].each do |source_dir|
|
67
|
+
reference_map(source_dir, reference_dir, extname).each do |path, source|
|
68
|
+
FileUtils.rm_r(path)
|
69
|
+
target = path.chomp(extname)
|
70
|
+
FileUtils.cp_r(source, target)
|
71
|
+
mapped_paths << target
|
72
|
+
end
|
73
|
+
end unless reference_dir == nil
|
74
|
+
|
75
|
+
yield
|
76
|
+
|
77
|
+
ensure
|
78
|
+
mapped_paths.each do |path|
|
79
|
+
FileUtils.rm_r(path) if File.exists?(path)
|
80
|
+
FileUtils.touch(path + extname)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Yields to the input block for each pair of entries in the input
|
86
|
+
# arrays. An error is raised if the input arrays do not have equal
|
87
|
+
# numbers of entries.
|
88
|
+
def each_pair(a, b, &block) # :yields: entry_a, entry_b,
|
89
|
+
each_pair_with_index(a,b) do |entry_a, entry_b, index|
|
90
|
+
yield(entry_a, entry_b)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Same as each_pair but yields the index of the entries as well.
|
95
|
+
def each_pair_with_index(a, b, &block) # :yields: entry_a, entry_b, index
|
96
|
+
a = [a] unless a.kind_of?(Array)
|
97
|
+
b = [b] unless b.kind_of?(Array)
|
98
|
+
|
99
|
+
raise ArgumentError, "The input arrays must have an equal number of entries." unless a.length == b.length
|
100
|
+
0.upto(a.length-1) do |index|
|
101
|
+
yield(a[index], b[index], index)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Attempts to remove the specified directory. The root
|
106
|
+
# will not be removed if the directory does not exist, or
|
107
|
+
# is not empty.
|
108
|
+
def try_remove_dir(dir)
|
109
|
+
# Remove the directory if possible
|
110
|
+
begin
|
111
|
+
FileUtils.rmdir(dir) if File.exists?(dir) && Dir.glob(File.join(dir, "*")).empty?
|
112
|
+
rescue
|
113
|
+
# rescue cases where there is a hidden file, for example .svn
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|