Module: Tap::Test::Utils
- Defined in:
- lib/tap/test/utils.rb
Defined Under Namespace
Classes: DereferenceError
Class Method Summary collapse
-
.clear_dir(dir) ⇒ Object
Attempts to recursively remove the specified method directory and all files within it.
-
.dereference(source_dirs, reference_dir, pattern = '**/*.ref', tempdir = Dir::tmpdir) ⇒ Object
Dereferences source files with reference files for the duration of the block.
-
.each_pair(a, b, &block) ⇒ Object
Yields to the input block for each pair of entries in the input arrays.
-
.each_pair_with_index(a, b, error_msg = nil, &block) ⇒ Object
Same as each_pair but yields the index of the entries as well.
-
.reference_map(source_dir, reference_dir, pattern = '**/*.ref') ⇒ Object
Generates an array of [source, reference] pairs mapping source files to reference files under the source and reference dirs, respectively.
-
.template(paths, attributes = {}, tempdir = Dir::tmpdir) ⇒ Object
Uses a Tap::Support::Templater to template and replace the contents of path, for the duration of the block.
-
.try_remove_dir(dir) ⇒ Object
Attempts to remove the specified directory.
- .whitespace_escape(str) ⇒ Object
-
.with_argv(argv = []) ⇒ Object
Sets ARGV to the input argv for the duration of the block.
Class Method Details
.clear_dir(dir) ⇒ Object
Attempts to recursively remove the specified method directory and all files within it. Raises an error if the removal does not succeed.
182 183 184 185 |
# File 'lib/tap/test/utils.rb', line 182 def clear_dir(dir) # clear out the folder if it exists FileUtils.rm_r(dir) if File.exists?(dir) end |
.dereference(source_dirs, reference_dir, pattern = '**/*.ref', tempdir = Dir::tmpdir) ⇒ Object
Dereferences source files with reference files for the duration of the block. The mappings of source to reference files are determined using reference_map; dereferenced files are at the same location as the source files, but with the ‘.ref’ extname removed.
Notes:
-
The reference extname is implicitly specified in pattern; the final extname of the source file is removed during dereferencing regardless of what it is.
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/tap/test/utils.rb', line 95 def dereference(source_dirs, reference_dir, pattern='**/*.ref', tempdir=Dir::tmpdir) mapped_paths = [] begin [*source_dirs].each do |source_dir| reference_map(source_dir, reference_dir, pattern).each do |source, reference| # move the source file to a temporary location tempfile = Tempfile.new(File.basename(source), tempdir) tempfile.close FileUtils.mv(source, tempfile.path) # copy the reference to the target target = source.chomp(File.extname(source)) FileUtils.cp_r(reference, target) mapped_paths << [target, source, tempfile] end end unless reference_dir == nil yield ensure mapped_paths.each do |target, source, tempfile| # remove the target and restore the original source file FileUtils.rm_r(target) if File.exists?(target) FileUtils.mv(tempfile.path, source) end end end |
.each_pair(a, b, &block) ⇒ Object
Yields to the input block for each pair of entries in the input arrays. An error is raised if the input arrays do not have equal numbers of entries.
160 161 162 163 164 |
# File 'lib/tap/test/utils.rb', line 160 def each_pair(a, b, &block) # :yields: entry_a, entry_b, each_pair_with_index(a,b) do |entry_a, entry_b, index| yield(entry_a, entry_b) end end |
.each_pair_with_index(a, b, error_msg = nil, &block) ⇒ Object
Same as each_pair but yields the index of the entries as well.
167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/tap/test/utils.rb', line 167 def each_pair_with_index(a, b, error_msg=nil, &block) # :yields: entry_a, entry_b, index a = [a] unless a.kind_of?(Array) b = [b] unless b.kind_of?(Array) unless a.length == b.length raise ArgumentError, (error_msg || "The input arrays must have an equal number of entries.") end 0.upto(a.length-1) do |index| yield(a[index], b[index], index) end end |
.reference_map(source_dir, reference_dir, pattern = '**/*.ref') ⇒ Object
Generates an array of [source, reference] pairs mapping source files to reference files under the source and reference dirs, respectively. Only files under source dir matching the pattern will be mapped. Mappings are either (in this order):
-
the path under reference_dir contained in the source file
-
a direct translation of the source file from the source to the reference dir, minus the extname
Notes:
-
Source files may contain comments but should otherwise consist only of indentation (which is stripped) and the reference path.
-
If a mapped path cannot be found, dereference raises
a DereferenceError.
example
root
|- input
| |- dir.ref
| |- ignored.txt
| |- one.txt.ref
| `- two.txt.ref
`- ref
|- dir
|- one.txt
`- path
`- to
`- two.txt
The ‘two.txt.ref’ file contains a reference path:
File.read('/root/input/two.txt.ref') # => 'path/to/two.txt'
Now:
reference_map('/root/input', '/root/ref')
# => [
# ['/root/input/dir.ref', '/root/ref/dir'],
# ['/root/input/one.txt.ref', '/root/ref/one.txt'],
# ['/root/input/two.txt.ref', '/root/ref/path/to/two.txt']]
And since no path matches ‘ignored.txt’:
reference_map('/root/input', '/root/ref', '**/*.txt')
# !> DereferenceError
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/tap/test/utils.rb', line 62 def reference_map(source_dir, reference_dir, pattern='**/*.ref') Dir.glob(File.join(source_dir, pattern)).sort.collect do |source| # use the path specified in the source file relative_path = File.read(source).gsub(/#.*$/, "").strip # use the relative filepath of the source file to the # source dir (minus the extname) if no path is specified if relative_path.empty? relative_path = Tap::Root.relative_filepath(source_dir, source).chomp(File.extname(source)) end reference = File.join(reference_dir, relative_path) # raise an error if no reference file is found unless File.exists?(reference) raise DereferenceError, "no reference found for: #{source}" end [source, reference] end end |
.template(paths, attributes = {}, tempdir = Dir::tmpdir) ⇒ Object
Uses a Tap::Support::Templater to template and replace the contents of path, for the duration of the block. The attributes will be available in the template context.
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/tap/test/utils.rb', line 128 def template(paths, attributes={}, tempdir=Dir::tmpdir) mapped_paths = [] begin [*paths].each do |path| # move the source file to a temporary location tempfile = Tempfile.new(File.basename(path), tempdir) tempfile.close FileUtils.cp(path, tempfile.path) # template the source file content = File.read(path) File.open(path, "wb") do |file| file << Support::Templater.new(content, attributes).build end mapped_paths << [path, tempfile] end yield ensure mapped_paths.each do |path, tempfile| # restore the original source file FileUtils.rm(path) if File.exists?(path) FileUtils.mv(tempfile.path, path) end end end |
.try_remove_dir(dir) ⇒ Object
Attempts to remove the specified directory. The root will not be removed if the directory does not exist, or is not empty.
190 191 192 193 194 195 196 197 |
# File 'lib/tap/test/utils.rb', line 190 def try_remove_dir(dir) # Remove the directory if possible begin FileUtils.rmdir(dir) if File.exists?(dir) && Dir.glob(File.join(dir, "*")).empty? rescue # rescue cases where there is a hidden file, for example .svn end end |
.whitespace_escape(str) ⇒ Object
214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/tap/test/utils.rb', line 214 def whitespace_escape(str) str.to_s.gsub(/\s/) do |match| case match when "\n" then "\\n\n" when "\t" then "\\t" when "\r" then "\\r" when "\f" then "\\f" else match end end end |
.with_argv(argv = []) ⇒ Object
Sets ARGV to the input argv for the duration of the block.
200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/tap/test/utils.rb', line 200 def with_argv(argv=[]) current_argv = ARGV.dup begin ARGV.clear ARGV.concat(argv) yield ensure ARGV.clear ARGV.concat(current_argv) end end |